./PaxHeaders.16287/sssd-1.13.40000644000000000000000000000013212703463557012414 xustar0030 mtime=1460561775.065795022 30 atime=1460561776.117798589 30 ctime=1460561775.065795022 sssd-1.13.4/0000755002412700241270000000000012703463557014010 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/PaxHeaders.16287/configure0000644000000000000000000000013112703463541014230 xustar0030 mtime=1460561761.204748023 29 atime=1460561764.69575986 30 ctime=1460561774.280792361 sssd-1.13.4/configure0000755002412700241270000305716612703463541015732 0ustar00jhrozekjhrozek00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for sssd 1.13.4. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: sssd-devel@lists.fedorahosted.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sssd' PACKAGE_TARNAME='sssd' PACKAGE_VERSION='1.13.4' PACKAGE_STRING='sssd 1.13.4' PACKAGE_BUGREPORT='sssd-devel@lists.fedorahosted.org' PACKAGE_URL='' ac_unique_file="BUILD.txt" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS abs_builddir HAVE_POLKIT_RULES_D_FALSE HAVE_POLKIT_RULES_D_TRUE polkitdir HAVE_DEVSHM_FALSE HAVE_DEVSHM_TRUE HAVE_NSS_WRAPPER_FALSE HAVE_NSS_WRAPPER_TRUE HAVE_NSS_WRAPPER HAVE_UID_WRAPPER_FALSE HAVE_UID_WRAPPER_TRUE HAVE_UID_WRAPPER HAVE_CMOCKA_FALSE HAVE_CMOCKA_TRUE CMOCKA_LIBS CMOCKA_CFLAGS HAVE_CHECK_FALSE HAVE_CHECK_TRUE HAVE_DOXYGEN_FALSE HAVE_DOXYGEN_TRUE DOXYGEN CHECK_LIBS CHECK_CFLAGS INOTIFY_LIBS CRYPTO_LIBS CRYPTO_CFLAGS NSS_LIBS NSS_CFLAGS JOURNALD_LIBS JOURNALD_CFLAGS HAVE_SYSTEMD SEMANAGE_LIBS SELINUX_LIBS BUILD_PYTHON_BINDINGS_FALSE BUILD_PYTHON_BINDINGS_TRUE PYTHON3_EXEC_PREFIX PYTHON3_PREFIX PYTHON3_VERSION PYTHON3_INCLUDES PYTHON3_LIBS PYTHON3_CFLAGS python3dir py3execdir PYTHON2_EXEC_PREFIX PYTHON2_PREFIX PYTHON2_VERSION PYTHON2_INCLUDES PYTHON2_LIBS PYTHON2_CFLAGS python2dir py2execdir PYTHON_CONFIG pkgpyexecdir pyexecdir pkgpythondir pythondir PYTHON_PLATFORM PYTHON_EXEC_PREFIX PYTHON_PREFIX PYTHON_VERSION PYTHON PYTHON3 HAVE_PYTHON3 PYTHON2 HAVE_PYTHON2 HAVE_PO4A_FALSE HAVE_PO4A_TRUE HAVE_MANPAGES_FALSE HAVE_MANPAGES_TRUE HAVE_PROFILE_CATALOGS_FALSE HAVE_PROFILE_CATALOGS_TRUE DOCBOOK_XSLT PO4A XMLLINT XSLTPROC DBUS_LIBS DBUS_CFLAGS systemdconfdir systemdunitdir HAVE_SYSTEMD_UNIT_FALSE HAVE_SYSTEMD_UNIT_TRUE HAVE_SYSV_FALSE HAVE_SYSV_TRUE LIBNL1_LIBS LIBNL1_CFLAGS LIBNL_LIBS LIBNL_CFLAGS LIBNL3_LIBS LIBNL3_CFLAGS UNICODE_LIBS GLIB2_LIBS GLIB2_CFLAGS WITH_GLIB_FALSE WITH_GLIB_TRUE WITH_LIBUNISTRING_FALSE WITH_LIBUNISTRING_TRUE AUGEAS_LIBS AUGEAS_CFLAGS PYTEST HAVE_FAKEROOT HAVE_LIBRESOLV_FALSE HAVE_LIBRESOLV_TRUE RESOLV_LIBS RESOLV_CFLAGS NFSIDMAP_LIBS NFSIDMAP_CFLAGS NFSIDMAP_OBJ BUILD_CONFIG_LIB_FALSE BUILD_CONFIG_LIB_TRUE SASL_CFLAGS SASL_LIBS SMBCLIENT_LIBS SMBCLIENT_CFLAGS NDR_NBT_LIBS NDR_NBT_CFLAGS BUILD_CIFS_IDMAP_PLUGIN_FALSE BUILD_CIFS_IDMAP_PLUGIN_TRUE BUILD_PAC_RESPONDER_FALSE BUILD_PAC_RESPONDER_TRUE NDR_KRB5PAC_LIBS NDR_KRB5PAC_CFLAGS SYSTEMD_LOGIN_LIBS SYSTEMD_LOGIN_CFLAGS KEYUTILS_LIBS NSUPDATE NSCD CARES_CFLAGS CARES_LIBS BUILD_KRB5_LOCALAUTH_PLUGIN_FALSE BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE BUILD_KRB5_LOCATOR_PLUGIN_FALSE BUILD_KRB5_LOCATOR_PLUGIN_TRUE KRB5_CONFIG KRB5_LIBS KRB5_CFLAGS PCRE_CFLAGS PCRE_LIBS HAVE_LDAPMODIFY SLAPD OPENLDAP_CFLAGS OPENLDAP_LIBS PAM_MISC_LIBS PAM_LIBS INI_CONFIG_LIBS INI_CONFIG_CFLAGS INI_CONFIG_V1_1_LIBS INI_CONFIG_V1_1_CFLAGS INI_CONFIG_V1_LIBS INI_CONFIG_V1_CFLAGS INI_CONFIG_V0_LIBS INI_CONFIG_V0_CFLAGS COLLECTION_LIBS COLLECTION_CFLAGS DHASH_LIBS DHASH_CFLAGS ldblibdir LDB_LIBS LDB_CFLAGS TEVENT_LIBS TEVENT_CFLAGS TDB_LIBS TDB_CFLAGS TALLOC_LIBS TALLOC_CFLAGS PKG_CONFIG POPT_CFLAGS POPT_LIBS SSSD_USER_FALSE SSSD_USER_TRUE SSSD_USER BUILD_LIBWBCLIENT_FALSE BUILD_LIBWBCLIENT_TRUE libwbclient_version_info libwbclient_version nfslibpath BUILD_NFS_IDMAP_FALSE BUILD_NFS_IDMAP_TRUE BUILD_SAMBA_FALSE BUILD_SAMBA_TRUE WITH_JOURNALD_FALSE WITH_JOURNALD_TRUE HAVE_LIBCRYPTO_FALSE HAVE_LIBCRYPTO_TRUE HAVE_NSS_FALSE HAVE_NSS_TRUE BUILD_IFP_FALSE BUILD_IFP_TRUE BUILD_SSH_FALSE BUILD_SSH_TRUE BUILD_AUTOFS_FALSE BUILD_AUTOFS_TRUE sudolibpath BUILD_SUDO_FALSE BUILD_SUDO_TRUE appmodpath gpocachepath GPO_DEFAULT_ENFORCING_FALSE GPO_DEFAULT_ENFORCING_TRUE GPO_DEFAULT BUILD_SEMANAGE_FALSE BUILD_SEMANAGE_TRUE HAVE_SEMANAGE NSCD_PATH BUILD_SELINUX_FALSE BUILD_SELINUX_TRUE HAVE_SELINUX cifspluginpath BUILD_PYTHON3_BINDINGS_FALSE BUILD_PYTHON3_BINDINGS_TRUE HAVE_PYTHON3_BINDINGS BUILD_PYTHON2_BINDINGS_FALSE BUILD_PYTHON2_BINDINGS_TRUE HAVE_PYTHON2_BINDINGS krb5authdatapluginpath krb5rcachedir krb5pluginpath SGML_CATALOG_FILES HAVE_MANPAGES TEST_DIR initdir environment_file config_def_ccname_template config_def_ccache_dir mcpath pipepath pubconfpath logpath pidpath pluginpath dbpath BUILD_DBUS_TESTS_FALSE BUILD_DBUS_TESTS_TRUE BUILD_MANPAGES_FALSE BUILD_MANPAGES_TRUE HAVE_GENTOO_FALSE HAVE_GENTOO_TRUE HAVE_DEBIAN_FALSE HAVE_DEBIAN_TRUE HAVE_SUSE_FALSE HAVE_SUSE_TRUE HAVE_REDHAT_FALSE HAVE_REDHAT_TRUE HAVE_FEDORA_FALSE HAVE_FEDORA_TRUE nfsidmaplibdir pammoddir nsslibdir HAVE_PTHREAD_FALSE HAVE_PTHREAD_TRUE sharedbuilddir WANT_AUX_INFO_FALSE WANT_AUX_INFO_TRUE HAVE_GCC_FALSE HAVE_GCC_TRUE GIT_CHECKOUT_FALSE GIT_CHECKOUT_TRUE PRERELEASE_VERSION POSUB LTLIBINTL LIBINTL INTLLIBS LTLIBICONV LIBICONV INTL_MACOSX_LIBS MSGMERGE XGETTEXT GMSGFMT MSGFMT USE_NLS MKINSTALLDIRS LIBADD_DL LT_DLPREOPEN LIBADD_DLD_LINK LIBADD_SHL_LOAD LIBADD_DLOPEN LT_DLLOADERS OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP SED host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL ac_ct_AR AR AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM EGREP GREP CPP OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_dependency_tracking enable_silent_rules enable_static enable_shared with_pic enable_fast_install with_gnu_ld with_sysroot enable_libtool_lock enable_nls enable_rpath with_libiconv_prefix with_libintl_prefix with_shared_build_dir enable_nsslibdir enable_pammoddir enable_nfsidmaplibdir with_os enable_all_experimental_features enable_dbus_tests enable_sss_default_nss_plugin with_db_path with_plugin_path with_pid_path with_log_path with_pubconf_path with_pipe_path with_mcache_path with_default_ccache_dir with_default_ccname_template with_environment_file with_init_dir with_test_dir with_manpages with_xml_catalog_path with_krb5_plugin_path with_krb5_rcache_dir with_krb5authdata_plugin_path with_krb5_conf with_python2_bindings with_python3_bindings with_cifs_plugin_path with_selinux with_nscd with_ipa_getkeytab with_semanage with_ad_gpo_default with_gpo_cache_path with_nologin_shell with_app_libs with_sudo with_sudo_lib_path with_autofs with_ssh with_infopipe with_crypto with_syslog with_samba with_nfsv4_idmapd_plugin with_nfs_lib_path with_libwbclient with_sssd_user with_ldb_lib_dir enable_ldb_version_check enable_krb5_locator_plugin enable_pac_responder enable_cifs_idmap_plugin enable_config_lib with_unicode_lib with_libnl with_nscd_conf with_initscript with_systemdunitdir with_systemdconfdir enable_intgcheck_reqs enable_polkit_rules_path ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP PKG_CONFIG POPT_CFLAGS POPT_LIBS TALLOC_CFLAGS TALLOC_LIBS TDB_CFLAGS TDB_LIBS TEVENT_CFLAGS TEVENT_LIBS LDB_CFLAGS LDB_LIBS DHASH_CFLAGS DHASH_LIBS COLLECTION_CFLAGS COLLECTION_LIBS INI_CONFIG_V0_CFLAGS INI_CONFIG_V0_LIBS INI_CONFIG_V1_CFLAGS INI_CONFIG_V1_LIBS INI_CONFIG_V1_1_CFLAGS INI_CONFIG_V1_1_LIBS PCRE_CFLAGS PCRE_LIBS KRB5_CFLAGS KRB5_LIBS CARES_CFLAGS CARES_LIBS SYSTEMD_LOGIN_CFLAGS SYSTEMD_LOGIN_LIBS NDR_KRB5PAC_CFLAGS NDR_KRB5PAC_LIBS NDR_NBT_CFLAGS NDR_NBT_LIBS SMBCLIENT_CFLAGS SMBCLIENT_LIBS SASL_CFLAGS SASL_LIBS NFSIDMAP_CFLAGS NFSIDMAP_LIBS AUGEAS_CFLAGS AUGEAS_LIBS GLIB2_CFLAGS GLIB2_LIBS LIBNL3_CFLAGS LIBNL3_LIBS LIBNL1_CFLAGS LIBNL1_LIBS DBUS_CFLAGS DBUS_LIBS PYTHON JOURNALD_CFLAGS JOURNALD_LIBS NSS_CFLAGS NSS_LIBS CRYPTO_CFLAGS CRYPTO_LIBS CHECK_CFLAGS CHECK_LIBS CMOCKA_CFLAGS CMOCKA_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures sssd 1.13.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/sssd] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of sssd 1.13.4:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-static[=PKGS] build static libraries [default=no] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-nls do not use Native Language Support --disable-rpath do not hardcode runtime library paths --enable-nsslibdir Where to install nss libraries ($libdir) --enable-pammoddir Where to install pam modules ($libdir/security) --enable-nfsidmaplibdir Where to install libnfsidmap libraries ($libdir/libnfsidmap) --enable-all-experimental-features build all experimental features --enable-dbus-tests enable running tests using a dbus server instance [default=yes] --enable-sss-default-nss-plugin This option change standard behaviour of sss nss plugin. If this option is enabled the sss nss plugin will behave as it was not in nsswitch.conf when sssd is not running. [default=no] --enable-ldb-version-check compile with ldb runtime version check [default=no] --disable-krb5-locator-plugin do not build Kerberos locator plugin --enable-pac-responder build pac responder --disable-cifs-idmap-plugin do not build CIFS idmap plugin --disable-config-lib do not build internal config library --enable-intgcheck-reqs enable checking for integration test requirements [default=no] --enable-polkit-rules-path=PATH Path to store polkit rules at. Use --disable to not install the rules at all. [/usr/share/polkit-1/rules.d] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-gnu-ld assume the C compiler uses GNU ld default=no --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib --without-libiconv-prefix don't search for libiconv in includedir and libdir --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib --without-libintl-prefix don't search for libintl in includedir and libdir --with-shared-build-dir=DIR temporary build directory where libraries are installed [$srcdir/sharedbuild] --with-os=OS_TYPE Type of your operation system (fedora|redhat|suse|gentoo) --with-db-path=PATH Path to the SSSD databases [/var/lib/sss/db] --with-plugin-path=PATH Path to the SSSD data provider plugins [/usr/lib/sssd] --with-pid-path=PATH Where to store pid files for the SSSD [/var/run] --with-log-path=PATH Where to store log files for the SSSD [/var/log/sssd] --with-pubconf-path=PATH Where to store pubconf files for the SSSD [/var/lib/sss/pubconf] --with-pipe-path=PATH Where to store pipe files for the SSSD interconnects [/var/lib/sss/pipes] --with-mcache-path=PATH Where to store mmap cache files for the SSSD interconnects [/var/lib/sss/mc] --with-default-ccache-dir=CCACHEDIR The default value of krb5_ccachedir [/tmp] --with-default-ccname-template=CCACHE The default fallback value of krb5_ccname_template [FILE:%d/krb5cc_%U_XXXXXX] --with-environment-file=PATH Path to environment file [/etc/sysconfig/sssd] --with-init-dir=DIR Where to store init script for sssd [/etc/rc.d/init.d] --with-test-dir=PATH Directory used for make check temporary files [$builddir] --with-manpages Whether to regenerate man pages from DocBook sources [yes] --with-xml-catalog-path=PATH Where to look for XML catalog [/etc/xml/catalog] --with-krb5-plugin-path=PATH Path to kerberos plugin store [/usr/lib/krb5/plugins/libkrb5] --with-krb5-rcache-dir=PATH Path to store Kerberos replay caches [__LIBKRB5_DEFAULTS__] --with-krb5authdata-plugin-path=PATH Path to kerberos authdata plugin store [/usr/lib/krb5/plugins/authdata] --with-krb5-conf=PATH Path to krb5.conf file [/etc/krb5.conf] --with-python2-bindings Whether to build python2 bindings [yes] --with-python3-bindings Whether to build python3 bindings [yes] --with-cifs-plugin-path=PATH Path to cifs-utils plugin store [/usr/lib/cifs-utils] --with-selinux Whether to build with SELinux support [yes] --with-nscd=PATH Path to nscd binary to attempt to flush nscd cache after local domain operations [/usr/sbin/nscd] --with-ipa-getkeytab=PATH Path to ipa_getkeytab binary to retrieve keytabs from FreeIPA server [/usr/sbin/ipa-getkeytab] --with-semanage Whether to build with SELinux user management support [yes] --with-ad-gpo-default=enforcing|permissive Default enforcing level for AD GPO access-control (enforcing) --with-gpo-cache-path=PATH Where to store GPO policy files [/var/lib/sss/gpo_cache] --with-nologin-shell=PATH The shell used to deny access to users [/sbin/nologin] --with-app-libs= Path to the 3rd party application plugins [/usr/lib/sssd/modules] --with-sudo Whether to build with sudo support [yes] --with-sudo-lib-path= Path to the sudo library [/usr/lib/] --with-autofs Whether to build with autofs support [yes] --with-ssh Whether to build with SSH support [yes] --with-infopipe Whether to build with InfoPipe support [yes] --with-crypto=CRYPTO_LIB The cryptographic library to use (nss|libcrypto). The default is nss. --with-syslog=SYSLOG_TYPE Type of your system logger (syslog|journald). [syslog] --with-samba Whether to build with samba4 libraries [yes] --with-nfsv4-idmapd-plugin Whether to build with NFSv4 IDMAP support [yes] --with-nfs-lib-path= Path to the nfs library [${libdir}] --with-libwbclient Whether to build SSSD implementation of libwbclient [yes] --with-sssd-user= User for running SSSD (root) --with-ldb-lib-dir=PATH Path to store ldb modules [${libdir}/ldb] --with-unicode-lib= Which library to use for unicode processing (libunistring, glib2) [glib2] --with-libnl Whether to build with libnetlink support (libnl3, libnl1, no) [auto] --with-nscd-conf=PATH Path to nscd.conf file [/etc/nscd.conf] --with-initscript=INITSCRIPT_TYPE Type of your init script (sysv|systemd). [sysv] --with-systemdunitdir=DIR Directory for systemd service files [Auto], --with-systemdconfdir=DIR Directory for systemd service file overrides [Auto], Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor PKG_CONFIG path to pkg-config utility POPT_CFLAGS C compiler flags for POPT, overriding pkg-config POPT_LIBS linker flags for POPT, overriding pkg-config TALLOC_CFLAGS C compiler flags for TALLOC, overriding pkg-config TALLOC_LIBS linker flags for TALLOC, overriding pkg-config TDB_CFLAGS C compiler flags for TDB, overriding pkg-config TDB_LIBS linker flags for TDB, overriding pkg-config TEVENT_CFLAGS C compiler flags for TEVENT, overriding pkg-config TEVENT_LIBS linker flags for TEVENT, overriding pkg-config LDB_CFLAGS C compiler flags for LDB, overriding pkg-config LDB_LIBS linker flags for LDB, overriding pkg-config DHASH_CFLAGS C compiler flags for DHASH, overriding pkg-config DHASH_LIBS linker flags for DHASH, overriding pkg-config COLLECTION_CFLAGS C compiler flags for COLLECTION, overriding pkg-config COLLECTION_LIBS linker flags for COLLECTION, overriding pkg-config INI_CONFIG_V0_CFLAGS C compiler flags for INI_CONFIG_V0, overriding pkg-config INI_CONFIG_V0_LIBS linker flags for INI_CONFIG_V0, overriding pkg-config INI_CONFIG_V1_CFLAGS C compiler flags for INI_CONFIG_V1, overriding pkg-config INI_CONFIG_V1_LIBS linker flags for INI_CONFIG_V1, overriding pkg-config INI_CONFIG_V1_1_CFLAGS C compiler flags for INI_CONFIG_V1_1, overriding pkg-config INI_CONFIG_V1_1_LIBS linker flags for INI_CONFIG_V1_1, overriding pkg-config PCRE_CFLAGS C compiler flags for PCRE, overriding pkg-config PCRE_LIBS linker flags for PCRE, overriding pkg-config KRB5_CFLAGS C compiler flags for kerberos, overriding krb5-config KRB5_LIBS linker flags for kerberos, overriding krb5-config CARES_CFLAGS C compiler flags for CARES, overriding pkg-config CARES_LIBS linker flags for CARES, overriding pkg-config SYSTEMD_LOGIN_CFLAGS C compiler flags for SYSTEMD_LOGIN, overriding pkg-config SYSTEMD_LOGIN_LIBS linker flags for SYSTEMD_LOGIN, overriding pkg-config NDR_KRB5PAC_CFLAGS C compiler flags for NDR_KRB5PAC, overriding pkg-config NDR_KRB5PAC_LIBS linker flags for NDR_KRB5PAC, overriding pkg-config NDR_NBT_CFLAGS C compiler flags for NDR_NBT, overriding pkg-config NDR_NBT_LIBS linker flags for NDR_NBT, overriding pkg-config SMBCLIENT_CFLAGS C compiler flags for SMBCLIENT, overriding pkg-config SMBCLIENT_LIBS linker flags for SMBCLIENT, overriding pkg-config SASL_CFLAGS C compiler flags for SASL, overriding pkg-config SASL_LIBS linker flags for SASL, overriding pkg-config NFSIDMAP_CFLAGS C compiler flags for NFSIDMAP, overriding pkg-config NFSIDMAP_LIBS linker flags for NFSIDMAP, overriding pkg-config AUGEAS_CFLAGS C compiler flags for AUGEAS, overriding pkg-config AUGEAS_LIBS linker flags for AUGEAS, overriding pkg-config GLIB2_CFLAGS C compiler flags for GLIB2, overriding pkg-config GLIB2_LIBS linker flags for GLIB2, overriding pkg-config LIBNL3_CFLAGS C compiler flags for LIBNL3, overriding pkg-config LIBNL3_LIBS linker flags for LIBNL3, overriding pkg-config LIBNL1_CFLAGS C compiler flags for LIBNL1, overriding pkg-config LIBNL1_LIBS linker flags for LIBNL1, overriding pkg-config DBUS_CFLAGS C compiler flags for DBUS, overriding pkg-config DBUS_LIBS linker flags for DBUS, overriding pkg-config PYTHON the Python interpreter JOURNALD_CFLAGS C compiler flags for JOURNALD, overriding pkg-config JOURNALD_LIBS linker flags for JOURNALD, overriding pkg-config NSS_CFLAGS C compiler flags for NSS, overriding pkg-config NSS_LIBS linker flags for NSS, overriding pkg-config CRYPTO_CFLAGS C compiler flags for CRYPTO, overriding pkg-config CRYPTO_LIBS linker flags for CRYPTO, overriding pkg-config CHECK_CFLAGS C compiler flags for CHECK, overriding pkg-config CHECK_LIBS linker flags for CHECK, overriding pkg-config CMOCKA_CFLAGS C compiler flags for CMOCKA, overriding pkg-config CMOCKA_LIBS linker flags for CMOCKA, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF sssd configure 1.13.4 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ------------------------------------------------ ## ## Report this to sssd-devel@lists.fedorahosted.org ## ## ------------------------------------------------ ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES # --------------------------------------------- # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. ac_fn_c_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 $as_echo_n "checking whether $as_decl_name is declared... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_decl # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- # Tries to find if the field MEMBER exists in type AGGR, after including # INCLUDES, setting cache variable VAR accordingly. ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 $as_echo_n "checking for $2.$3... " >&6; } if eval \${$4+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int main () { static $2 ac_aggr; if (sizeof ac_aggr.$3) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$4=yes" else eval "$4=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$4 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by sssd $as_me 1.13.4, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_aux_dir= for ac_dir in build "$srcdir"/build; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in build \"$srcdir\"/build" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" if test "x$ac_cv_header_minix_config_h" = xyes; then : MINIX=yes else MINIX= fi if test "$MINIX" = yes; then $as_echo "#define _POSIX_SOURCE 1" >>confdefs.h $as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h $as_echo "#define _MINIX 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 $as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } if ${ac_cv_safe_to_define___extensions__+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # define __EXTENSIONS__ 1 $ac_includes_default int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_safe_to_define___extensions__=yes else ac_cv_safe_to_define___extensions__=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 $as_echo "$ac_cv_safe_to_define___extensions__" >&6; } test $ac_cv_safe_to_define___extensions__ = yes && $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h $as_echo "#define _ALL_SOURCE 1" >>confdefs.h $as_echo "#define _GNU_SOURCE 1" >>confdefs.h $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE" am__api_version='1.15' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='sssd' VERSION='1.13.4' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a pax tar archive" >&5 $as_echo_n "checking how to create a pax tar archive... " >&6; } # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_pax-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do { echo "$as_me:$LINENO: $_am_tar --version" >&5 ($_am_tar --version) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && break done am__tar="$_am_tar --format=posix -chf - "'"$$tardir"' am__tar_="$_am_tar --format=posix -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x pax -w "$$tardir"' am__tar_='pax -L -x pax -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H pax -L' am__tar_='find "$tardir" -print | cpio -o -H pax -L' am__untar='cpio -i -H pax -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_pax}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5 (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } rm -rf conftest.dir if test -s conftest.tar; then { echo "$as_me:$LINENO: $am__untar &5 ($am__untar &5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { echo "$as_me:$LINENO: cat conftest.dir/file" >&5 (cat conftest.dir/file) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } grep GrepMe conftest.dir/file >/dev/null 2>&1 && break fi done rm -rf conftest.dir if ${am_cv_prog_tar_pax+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_prog_tar_pax=$_am_tool fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_pax" >&5 $as_echo "$am_cv_prog_tar_pax" >&6; } depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi if test -n "$ac_tool_prefix"; then for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar lib "link -lib" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} { $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 $as_echo_n "checking the archiver ($AR) interface... " >&6; } if ${am_cv_ar_interface+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am_cv_ar_interface=ar cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int some_variable = 0; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 $as_echo "$am_cv_ar_interface" >&6; } case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) as_fn_error $? "could not determine $AR interface" "$LINENO" 5 ;; esac # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=no fi case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_dlopen=no enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" ac_config_commands="$ac_config_commands libtool" # Only expand once: LT_DLLOADERS= ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu LIBADD_DLOPEN= { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 $as_echo_n "checking for library containing dlopen... " >&6; } if ${ac_cv_search_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF for ac_lib in '' dl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_c_try_link "$LINENO"; then : ac_cv_search_dlopen=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if ${ac_cv_search_dlopen+:} false; then : break fi done if ${ac_cv_search_dlopen+:} false; then : else ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 $as_echo "$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen if test "$ac_res" != no; then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" $as_echo "#define HAVE_LIBDL 1" >>confdefs.h if test "$ac_cv_search_dlopen" != "none required" ; then LIBADD_DLOPEN="-ldl" fi libltdl_cv_lib_dl_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if HAVE_DLFCN_H # include #endif int main () { dlopen(0, 0); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : $as_echo "#define HAVE_LIBDL 1" >>confdefs.h libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : $as_echo "#define HAVE_LIBDL 1" >>confdefs.h LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la" fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes then lt_save_LIBS="$LIBS" LIBS="$LIBS $LIBADD_DLOPEN" for ac_func in dlerror do : ac_fn_c_check_func "$LINENO" "dlerror" "ac_cv_func_dlerror" if test "x$ac_cv_func_dlerror" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLERROR 1 _ACEOF fi done LIBS="$lt_save_LIBS" fi LIBADD_SHL_LOAD= ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : $as_echo "#define HAVE_SHL_LOAD 1" >>confdefs.h LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : $as_echo "#define HAVE_SHL_LOAD 1" >>confdefs.h LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" LIBADD_SHL_LOAD="-ldld" fi fi case $host_os in darwin[1567].*) # We only want this for pre-Mac OS X 10.4. ac_fn_c_check_func "$LINENO" "_dyld_func_lookup" "ac_cv_func__dyld_func_lookup" if test "x$ac_cv_func__dyld_func_lookup" = xyes; then : $as_echo "#define HAVE_DYLD 1" >>confdefs.h LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la" fi ;; beos*) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la" ;; cygwin* | mingw* | os2* | pw32*) ac_fn_c_check_decl "$LINENO" "cygwin_conv_path" "ac_cv_have_decl_cygwin_conv_path" "#include " if test "x$ac_cv_have_decl_cygwin_conv_path" = xyes; then : ac_have_decl=1 else ac_have_decl=0 fi cat >>confdefs.h <<_ACEOF #define HAVE_DECL_CYGWIN_CONV_PATH $ac_have_decl _ACEOF LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : $as_echo "#define HAVE_DLD 1" >>confdefs.h LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la" fi LT_DLPREOPEN= if test -n "$LT_DLLOADERS" then for lt_loader in $LT_DLLOADERS; do LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader " done $as_echo "#define HAVE_LIBDLLOADER 1" >>confdefs.h fi LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu MKINSTALLDIRS= if test -n "$ac_aux_dir"; then case "$ac_aux_dir" in /*) MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" ;; *) MKINSTALLDIRS="\$(top_builddir)/$ac_aux_dir/mkinstalldirs" ;; esac fi if test -z "$MKINSTALLDIRS"; then MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 $as_echo_n "checking whether NLS is requested... " >&6; } # Check whether --enable-nls was given. if test "${enable_nls+set}" = set; then : enableval=$enable_nls; USE_NLS=$enableval else USE_NLS=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 $as_echo "$USE_NLS" >&6; } # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case "$MSGFMT" in [\\/]* | ?:[\\/]*) ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" ;; esac fi MSGFMT="$ac_cv_path_MSGFMT" if test "$MSGFMT" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 $as_echo "$MSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GMSGFMT+:} false; then : $as_echo_n "(cached) " >&6 else case $GMSGFMT in [\\/]* | ?:[\\/]*) ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" ;; esac fi GMSGFMT=$ac_cv_path_GMSGFMT if test -n "$GMSGFMT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 $as_echo "$GMSGFMT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XGETTEXT+:} false; then : $as_echo_n "(cached) " >&6 else case "$XGETTEXT" in [\\/]* | ?:[\\/]*) ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" ;; esac fi XGETTEXT="$ac_cv_path_XGETTEXT" if test "$XGETTEXT" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 $as_echo "$XGETTEXT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f messages.po # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "msgmerge", so it can be a program name with args. set dummy msgmerge; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MSGMERGE+:} false; then : $as_echo_n "(cached) " >&6 else case "$MSGMERGE" in [\\/]* | ?:[\\/]*) ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" ;; esac fi MSGMERGE="$ac_cv_path_MSGMERGE" if test "$MSGMERGE" != ":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 $as_echo "$MSGMERGE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "$GMSGFMT" != ":"; then if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $GMSGFMT program is not GNU msgfmt; ignore it" >&5 $as_echo "found $GMSGFMT program is not GNU msgfmt; ignore it" >&6; } GMSGFMT=":" fi fi if test "$XGETTEXT" != ":"; then if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >/dev/null 2>&1 && (if $XGETTEXT --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then : ; else { $as_echo "$as_me:${as_lineno-$LINENO}: result: found xgettext program is not GNU xgettext; ignore it" >&5 $as_echo "found xgettext program is not GNU xgettext; ignore it" >&6; } XGETTEXT=":" fi rm -f messages.po fi ac_config_commands="$ac_config_commands default-1" if test "X$prefix" = "XNONE"; then acl_final_prefix="$ac_default_prefix" else acl_final_prefix="$prefix" fi if test "X$exec_prefix" = "XNONE"; then acl_final_exec_prefix='${prefix}' else acl_final_exec_prefix="$exec_prefix" fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" prefix="$acl_save_prefix" # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 $as_echo_n "checking for ld used by GCC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | [A-Za-z]:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the path of ld ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${acl_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" for ac_dir in $PATH; do test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then acl_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some GNU ld's only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in *GNU* | *'with BFD'*) test "$with_gnu_ld" != no && break ;; *) test "$with_gnu_ld" != yes && break ;; esac fi done IFS="$ac_save_ifs" else acl_cv_path_LD="$LD" # Let the user override the test with a path. fi fi LD="$acl_cv_path_LD" if test -n "$LD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${acl_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU ld's only accept -v. case `$LD -v 2>&1 &5 $as_echo "$acl_cv_prog_gnu_ld" >&6; } with_gnu_ld=$acl_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 $as_echo_n "checking for shared library run path origin... " >&6; } if ${acl_cv_rpath+:} false; then : $as_echo_n "(cached) " >&6 else CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh . ./conftest.sh rm -f ./conftest.sh acl_cv_rpath=done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 $as_echo "$acl_cv_rpath" >&6; } wl="$acl_cv_wl" libext="$acl_cv_libext" shlibext="$acl_cv_shlibext" hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" hardcode_direct="$acl_cv_hardcode_direct" hardcode_minus_L="$acl_cv_hardcode_minus_L" # Check whether --enable-rpath was given. if test "${enable_rpath+set}" = set; then : enableval=$enable_rpath; : else enable_rpath=yes fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libiconv-prefix was given. if test "${with_libiconv_prefix+set}" = set; then : withval=$with_libiconv_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi fi LIBICONV= LTLIBICONV= INCICONV= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='iconv ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" else : fi else found_dir= found_la= found_so= found_a= if test $use_additional = yes; then if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then found_dir="$additional_libdir" found_so="$additional_libdir/lib$name.$shlibext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi else if test -f "$additional_libdir/lib$name.$libext"; then found_dir="$additional_libdir" found_a="$additional_libdir/lib$name.$libext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then found_dir="$dir" found_so="$dir/lib$name.$shlibext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi else if test -f "$dir/lib$name.$libext"; then found_dir="$dir" found_a="$dir/lib$name.$libext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$hardcode_direct" = yes; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" else LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" else LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */lib | */lib/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/lib"; then haveit= if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBICONV; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" ;; esac done fi else LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5 $as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; } if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" gt_save_LIBS="$LIBS" LIBS="$LIBS -framework CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CFPreferencesCopyAppValue(NULL, NULL) ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_CFPreferencesCopyAppValue=yes else gt_cv_func_CFPreferencesCopyAppValue=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 $as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; } if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then $as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5 $as_echo_n "checking for CFLocaleCopyCurrent... " >&6; } if ${gt_cv_func_CFLocaleCopyCurrent+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I/System/Library/Frameworks/CoreFoundation.framework/Headers" gt_save_LIBS="$LIBS" LIBS="$LIBS -framework CoreFoundation" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { CFLocaleCopyCurrent(); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_CFLocaleCopyCurrent=yes else gt_cv_func_CFLocaleCopyCurrent=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5 $as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; } if test $gt_cv_func_CFLocaleCopyCurrent = yes; then $as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h fi INTL_MACOSX_LIBS= if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 $as_echo_n "checking whether NLS is requested... " >&6; } # Check whether --enable-nls was given. if test "${enable_nls+set}" = set; then : enableval=$enable_nls; USE_NLS=$enableval else USE_NLS=yes fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 $as_echo "$USE_NLS" >&6; } LIBINTL= LTLIBINTL= POSUB= if test "$USE_NLS" = "yes"; then gt_use_preinstalled_gnugettext=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5 $as_echo_n "checking for GNU gettext in libc... " >&6; } if ${gt_cv_func_gnugettext1_libc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; int main () { bindtextdomain ("", ""); return * gettext ("") + _nl_msg_cat_cntr + *_nl_domain_bindings ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_gnugettext1_libc=yes else gt_cv_func_gnugettext1_libc=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_gnugettext1_libc" >&5 $as_echo "$gt_cv_func_gnugettext1_libc" >&6; } if test "$gt_cv_func_gnugettext1_libc" != "yes"; then am_save_CPPFLAGS="$CPPFLAGS" for element in $INCICONV; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 $as_echo_n "checking for iconv... " >&6; } if ${am_cv_func_iconv+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_func_iconv="no, consider installing GNU libiconv" am_cv_lib_iconv=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$am_cv_func_iconv" != yes; then am_save_LIBS="$LIBS" LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { iconv_t cd = iconv_open("",""); iconv(cd,NULL,NULL,NULL,NULL); iconv_close(cd); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : am_cv_lib_iconv=yes am_cv_func_iconv=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS="$am_save_LIBS" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 $as_echo "$am_cv_func_iconv" >&6; } if test "$am_cv_func_iconv" = yes; then $as_echo "#define HAVE_ICONV 1" >>confdefs.h fi if test "$am_cv_lib_iconv" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 $as_echo_n "checking how to link with libiconv... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 $as_echo "$LIBICONV" >&6; } else CPPFLAGS="$am_save_CPPFLAGS" LIBICONV= LTLIBICONV= fi use_additional=yes acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" # Check whether --with-libintl-prefix was given. if test "${with_libintl_prefix+set}" = set; then : withval=$with_libintl_prefix; if test "X$withval" = "Xno"; then use_additional=no else if test "X$withval" = "X"; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_includedir=\"$includedir\" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" else additional_includedir="$withval/include" additional_libdir="$withval/lib" fi fi fi LIBINTL= LTLIBINTL= INCINTL= rpathdirs= ltrpathdirs= names_already_handled= names_next_round='intl ' while test -n "$names_next_round"; do names_this_round="$names_next_round" names_next_round= for name in $names_this_round; do already_handled= for n in $names_already_handled; do if test "$n" = "$name"; then already_handled=yes break fi done if test -z "$already_handled"; then names_already_handled="$names_already_handled $name" uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` eval value=\"\$HAVE_LIB$uppername\" if test -n "$value"; then if test "$value" = yes; then eval value=\"\$LIB$uppername\" test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" eval value=\"\$LTLIB$uppername\" test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" else : fi else found_dir= found_la= found_so= found_a= if test $use_additional = yes; then if test -n "$shlibext" && test -f "$additional_libdir/lib$name.$shlibext"; then found_dir="$additional_libdir" found_so="$additional_libdir/lib$name.$shlibext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi else if test -f "$additional_libdir/lib$name.$libext"; then found_dir="$additional_libdir" found_a="$additional_libdir/lib$name.$libext" if test -f "$additional_libdir/lib$name.la"; then found_la="$additional_libdir/lib$name.la" fi fi fi fi if test "X$found_dir" = "X"; then for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" case "$x" in -L*) dir=`echo "X$x" | sed -e 's/^X-L//'` if test -n "$shlibext" && test -f "$dir/lib$name.$shlibext"; then found_dir="$dir" found_so="$dir/lib$name.$shlibext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi else if test -f "$dir/lib$name.$libext"; then found_dir="$dir" found_a="$dir/lib$name.$libext" if test -f "$dir/lib$name.la"; then found_la="$dir/lib$name.la" fi fi fi ;; esac if test "X$found_dir" != "X"; then break fi done fi if test "X$found_dir" != "X"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" if test "X$found_so" != "X"; then if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/lib"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else haveit= for x in $ltrpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $found_dir" fi if test "$hardcode_direct" = yes; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else if test -n "$hardcode_libdir_flag_spec" && test "$hardcode_minus_L" = no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" haveit= for x in $rpathdirs; do if test "X$x" = "X$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $found_dir" fi else haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$found_dir"; then haveit=yes break fi done if test -z "$haveit"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" fi if test "$hardcode_minus_L" != no; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" fi fi fi fi else if test "X$found_a" != "X"; then LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" else LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" fi fi additional_includedir= case "$found_dir" in */lib | */lib/) basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e 's,/lib/*$,,'` additional_includedir="$basedir/include" ;; esac if test "X$additional_includedir" != "X"; then if test "X$additional_includedir" != "X/usr/include"; then haveit= if test "X$additional_includedir" = "X/usr/local/include"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then for x in $CPPFLAGS $INCINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-I$additional_includedir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_includedir"; then INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" fi fi fi fi fi if test -n "$found_la"; then save_libdir="$libdir" case "$found_la" in */* | *\\*) . "$found_la" ;; *) . "./$found_la" ;; esac libdir="$save_libdir" for dep in $dependency_libs; do case "$dep" in -L*) additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` if test "X$additional_libdir" != "X/usr/lib"; then haveit= if test "X$additional_libdir" = "X/usr/local/lib"; then if test -n "$GCC"; then case $host_os in linux* | gnu* | k*bsd*-gnu) haveit=yes;; esac fi fi if test -z "$haveit"; then haveit= for x in $LDFLAGS $LIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir" fi fi haveit= for x in $LDFLAGS $LTLIBINTL; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X-L$additional_libdir"; then haveit=yes break fi done if test -z "$haveit"; then if test -d "$additional_libdir"; then LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir" fi fi fi fi ;; -R*) dir=`echo "X$dep" | sed -e 's/^X-R//'` if test "$enable_rpath" != no; then haveit= for x in $rpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then rpathdirs="$rpathdirs $dir" fi haveit= for x in $ltrpathdirs; do if test "X$x" = "X$dir"; then haveit=yes break fi done if test -z "$haveit"; then ltrpathdirs="$ltrpathdirs $dir" fi fi ;; -l*) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` ;; *.la) names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` ;; *) LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" ;; esac done fi else LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" fi fi fi done done if test "X$rpathdirs" != "X"; then if test -n "$hardcode_libdir_separator"; then alldirs= for found_dir in $rpathdirs; do alldirs="${alldirs}${alldirs:+$hardcode_libdir_separator}$found_dir" done acl_save_libdir="$libdir" libdir="$alldirs" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" else for found_dir in $rpathdirs; do acl_save_libdir="$libdir" libdir="$found_dir" eval flag=\"$hardcode_libdir_flag_spec\" libdir="$acl_save_libdir" LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" done fi fi if test "X$ltrpathdirs" != "X"; then for found_dir in $ltrpathdirs; do LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" done fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5 $as_echo_n "checking for GNU gettext in libintl... " >&6; } if ${gt_cv_func_gnugettext1_libintl+:} false; then : $as_echo_n "(cached) " >&6 else gt_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $INCINTL" gt_save_LIBS="$LIBS" LIBS="$LIBS $LIBINTL" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); int main () { bindtextdomain ("", ""); return * gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias ("") ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : gt_cv_func_gnugettext1_libintl=yes else gt_cv_func_gnugettext1_libintl=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test "$gt_cv_func_gnugettext1_libintl" != yes && test -n "$LIBICONV"; then LIBS="$LIBS $LIBICONV" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); int main () { bindtextdomain ("", ""); return * gettext ("") + _nl_msg_cat_cntr + *_nl_expand_alias ("") ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : LIBINTL="$LIBINTL $LIBICONV" LTLIBINTL="$LTLIBINTL $LTLIBICONV" gt_cv_func_gnugettext1_libintl=yes fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi CPPFLAGS="$gt_save_CPPFLAGS" LIBS="$gt_save_LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_gnugettext1_libintl" >&5 $as_echo "$gt_cv_func_gnugettext1_libintl" >&6; } fi if test "$gt_cv_func_gnugettext1_libc" = "yes" \ || { test "$gt_cv_func_gnugettext1_libintl" = "yes" \ && test "$PACKAGE" != gettext-runtime \ && test "$PACKAGE" != gettext-tools; }; then gt_use_preinstalled_gnugettext=yes else LIBINTL= LTLIBINTL= INCINTL= fi if test -n "$INTL_MACOSX_LIBS"; then if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" fi fi if test "$gt_use_preinstalled_gnugettext" = "yes" \ || test "$nls_cv_use_gnu_gettext" = "yes"; then $as_echo "#define ENABLE_NLS 1" >>confdefs.h else USE_NLS=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5 $as_echo_n "checking whether to use NLS... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 $as_echo "$USE_NLS" >&6; } if test "$USE_NLS" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5 $as_echo_n "checking where the gettext function comes from... " >&6; } if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then gt_source="external libintl" else gt_source="libc" fi else gt_source="included intl directory" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5 $as_echo "$gt_source" >&6; } fi if test "$USE_NLS" = "yes"; then if test "$gt_use_preinstalled_gnugettext" = "yes"; then if test "$gt_cv_func_gnugettext1_libintl" = "yes"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5 $as_echo_n "checking how to link with libintl... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5 $as_echo "$LIBINTL" >&6; } for element in $INCINTL; do haveit= for x in $CPPFLAGS; do acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval x=\"$x\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" if test "X$x" = "X$element"; then haveit=yes break fi done if test -z "$haveit"; then CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" fi done fi $as_echo "#define HAVE_GETTEXT 1" >>confdefs.h $as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h fi POSUB=po fi INTLLIBS="$LIBINTL" $as_echo "#define PRERELEASE_VERSION \"\"" >>confdefs.h if git log -1 >/dev/null 2>&1; then GIT_CHECKOUT_TRUE= GIT_CHECKOUT_FALSE='#' else GIT_CHECKOUT_TRUE='#' GIT_CHECKOUT_FALSE= fi # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "$ac_cv_c_compiler_gnu" = yes; then HAVE_GCC_TRUE= HAVE_GCC_FALSE='#' else HAVE_GCC_TRUE='#' HAVE_GCC_FALSE= fi for ac_header in stdint.h dlfcn.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_config_headers="$ac_config_headers config.h" ac_fn_c_check_type "$LINENO" "errno_t" "ac_cv_type_errno_t" "#include " if test "x$ac_cv_type_errno_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ERRNO_T 1 _ACEOF fi if test x$with_aux_info = xyes; then WANT_AUX_INFO_TRUE= WANT_AUX_INFO_FALSE='#' else WANT_AUX_INFO_TRUE='#' WANT_AUX_INFO_FALSE= fi # Check whether --with-shared-build-dir was given. if test "${with_shared_build_dir+set}" = set; then : withval=$with_shared_build_dir; fi sharedbuilddir="$srcdir/sharedbuild" if test x"$with_shared_build_dir" != x; then sharedbuilddir=$with_shared_build_dir CFLAGS="$CFLAGS -I$with_shared_build_dir/include" CPPFLAGS="$CPPFLAGS -I$with_shared_build_dir/include" LDFLAGS="$LDFLAGS -L$with_shared_build_dir/lib" fi cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; (void) m; /* unused */ ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h HAVE_PTHREAD=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Pthread library not found! Clients will not be thread safe..." >&5 $as_echo "$as_me: WARNING: Pthread library not found! Clients will not be thread safe..." >&2;} fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test x"$HAVE_PTHREAD" != "x"; then HAVE_PTHREAD_TRUE= HAVE_PTHREAD_FALSE='#' else HAVE_PTHREAD_TRUE='#' HAVE_PTHREAD_FALSE= fi SAVE_LIBS=$LIBS LIBS="$LIBS -lpthread" for ac_func in pthread_mutexattr_setrobust \ pthread_mutex_consistent \ pthread_mutexattr_setrobust_np \ pthread_mutex_consistent_np do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done LIBS=$SAVE_LIBS # Check for presence of modern functions for setting file timestamps for ac_func in utimensat \ futimens do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done #Check for endian headers for ac_header in endian.h sys/endian.h byteswap.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 $as_echo_n "checking whether byte ordering is bigendian... " >&6; } if ${ac_cv_c_bigendian+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes; then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main () { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 $as_echo "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) $as_echo "#define HAVE_BIG_ENDIAN 1" >>confdefs.h ;; #( no) $as_echo "#define HAVE_LITTLE_ENDIAN 1" >>confdefs.h ;; #( universal) $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac #Set the NSS library install path # Check whether --enable-nsslibdir was given. if test "${enable_nsslibdir+set}" = set; then : enableval=$enable_nsslibdir; nsslibdir=$enableval else nsslibdir=$libdir fi #Set the PAM module install path # Check whether --enable-pammoddir was given. if test "${enable_pammoddir+set}" = set; then : enableval=$enable_pammoddir; pammoddir=$enableval else pammoddir=$libdir/security fi #Set the NFSv4 idmapd library install path # Check whether --enable-nfsidmaplibdir was given. if test "${enable_nfsidmaplibdir+set}" = set; then : enableval=$enable_nfsidmaplibdir; nfsidmaplibdir=$enableval else nfsidmaplibdir=$libdir/libnfsidmap fi #Include here cause WITH_INIT_DIR requires $osname set in platform.m4 # Check whether --with-os was given. if test "${with_os+set}" = set; then : withval=$with_os; fi osname="" if test x"$with_os" != x ; then if test x"$with_os" = xfedora || \ test x"$with_os" = xredhat || \ test x"$with_os" = xsuse || \ test x"$with_os" = xgentoo || \ test x"$with_os" = xdebian ; then osname=$with_os else as_fn_error $? "Illegal value -$with_os- for option --with-os" "$LINENO" 5 fi fi if test x"$osname" = x ; then if test -f /etc/fedora-release ; then osname="fedora" elif test -f /etc/redhat-release ; then osname="redhat" elif test -f /etc/SuSE-release ; then osname="suse" elif test -f /etc/debian_version ; then osname="debian" elif test -f /etc/gentoo-release ; then osname="gentoo" fi { $as_echo "$as_me:${as_lineno-$LINENO}: Detected operating system type: $osname" >&5 $as_echo "$as_me: Detected operating system type: $osname" >&6;} fi if test x"$osname" = xfedora; then HAVE_FEDORA_TRUE= HAVE_FEDORA_FALSE='#' else HAVE_FEDORA_TRUE='#' HAVE_FEDORA_FALSE= fi if test x"$osname" = xredhat; then HAVE_REDHAT_TRUE= HAVE_REDHAT_FALSE='#' else HAVE_REDHAT_TRUE='#' HAVE_REDHAT_FALSE= fi if test x"$osname" = xsuse; then HAVE_SUSE_TRUE= HAVE_SUSE_FALSE='#' else HAVE_SUSE_TRUE='#' HAVE_SUSE_FALSE= fi if test x"$osname" = xdebian; then HAVE_DEBIAN_TRUE= HAVE_DEBIAN_FALSE='#' else HAVE_DEBIAN_TRUE='#' HAVE_DEBIAN_FALSE= fi if test x"$osname" = xgentoo; then HAVE_GENTOO_TRUE= HAVE_GENTOO_FALSE='#' else HAVE_GENTOO_TRUE='#' HAVE_GENTOO_FALSE= fi ac_fn_c_check_member "$LINENO" "struct ucred" "pid" "ac_cv_member_struct_ucred_pid" "#include " if test "x$ac_cv_member_struct_ucred_pid" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_UCRED_PID 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct ucred" "uid" "ac_cv_member_struct_ucred_uid" "#include " if test "x$ac_cv_member_struct_ucred_uid" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_UCRED_UID 1 _ACEOF fi ac_fn_c_check_member "$LINENO" "struct ucred" "gid" "ac_cv_member_struct_ucred_gid" "#include " if test "x$ac_cv_member_struct_ucred_gid" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_UCRED_GID 1 _ACEOF fi if test x"$ac_cv_member_struct_ucred_pid" = xyes -a \ x"$ac_cv_member_struct_ucred_uid" = xyes -a \ x"$ac_cv_member_struct_ucred_gid" = xyes ; then $as_echo "#define HAVE_UCRED 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: struct ucred is not available" >&5 $as_echo "$as_me: WARNING: struct ucred is not available" >&2;} fi if test x$with_manpages = xyes; then BUILD_MANPAGES_TRUE= BUILD_MANPAGES_FALSE='#' else BUILD_MANPAGES_TRUE='#' BUILD_MANPAGES_FALSE= fi # Check whether --enable-all-experimental-features was given. if test "${enable_all_experimental_features+set}" = set; then : enableval=$enable_all_experimental_features; build_all_experimental_features=$enableval else build_all_experimental_features=no fi # Check whether --enable-dbus-tests was given. if test "${enable_dbus_tests+set}" = set; then : enableval=$enable_dbus_tests; build_dbus_tests=$enableval else build_dbus_tests=yes fi if test x$build_dbus_tests = xyes; then BUILD_DBUS_TESTS_TRUE= BUILD_DBUS_TESTS_FALSE='#' else BUILD_DBUS_TESTS_TRUE='#' BUILD_DBUS_TESTS_FALSE= fi # Check whether --enable-sss-default-nss-plugin was given. if test "${enable_sss_default_nss_plugin+set}" = set; then : enableval=$enable_sss_default_nss_plugin; enable_sss_default_nss_plugin=$enableval else enable_sss_default_nss_plugin=no fi if test x$enable_sss_default_nss_plugin = xyes; then : cat >>confdefs.h <<_ACEOF #define NONSTANDARD_SSS_NSS_BEHAVIOUR 1 _ACEOF fi # Check whether --with-db-path was given. if test "${with_db_path+set}" = set; then : withval=$with_db_path; fi config_dbpath="\"SSS_STATEDIR\"/db" dbpath="${localstatedir}/lib/sss/db" if test x"$with_db_path" != x; then config_dbpath=$with_db_path dbpath=$with_db_path fi cat >>confdefs.h <<_ACEOF #define DB_PATH "$config_dbpath" _ACEOF # Check whether --with-plugin-path was given. if test "${with_plugin_path+set}" = set; then : withval=$with_plugin_path; fi pluginpath="${libdir}/sssd" config_pluginpath="\"LIBDIR\"/sssd" if test x"$with_plugin_path" != x; then pluginpath=$with_plugin_path config_pluginpath=$with_plugin_path fi cat >>confdefs.h <<_ACEOF #define DATA_PROVIDER_PLUGINS_PATH "$config_pluginpath" _ACEOF # Check whether --with-pid-path was given. if test "${with_pid_path+set}" = set; then : withval=$with_pid_path; fi config_pidpath="\"VARDIR\"/run" pidpath="${localstatedir}/run" if test x"$with_pid_path" != x; then config_pidpath=$with_pid_path pidpath=$with_pid_path fi cat >>confdefs.h <<_ACEOF #define PID_PATH "$config_pidpath" _ACEOF # Check whether --with-log-path was given. if test "${with_log_path+set}" = set; then : withval=$with_log_path; fi config_logpath="\"VARDIR\"/log/sssd" logpath="${localstatedir}/log/sssd" if test x"$with_log_path" != x; then config_logpath=$with_log_path logpath=$with_log_path fi cat >>confdefs.h <<_ACEOF #define LOG_PATH "$config_logpath" _ACEOF # Check whether --with-pubconf-path was given. if test "${with_pubconf_path+set}" = set; then : withval=$with_pubconf_path; fi config_pubconfpath="\"SSS_STATEDIR\"/pubconf" pubconfpath="${localstatedir}/lib/sss/pubconf" if test x"$with_pubconf_path" != x; then config_pubconfpath=$with_pubconf_path pubconfpath=$with_pubconf_path fi cat >>confdefs.h <<_ACEOF #define PUBCONF_PATH "$config_pubconfpath" _ACEOF # Check whether --with-pipe-path was given. if test "${with_pipe_path+set}" = set; then : withval=$with_pipe_path; fi config_pipepath="\"SSS_STATEDIR\"/pipes" pipepath="${localstatedir}/lib/sss/pipes" if test x"$with_pipe_path" != x; then config_pipepath=$with_pipe_path pipepath=$with_pipe_path fi cat >>confdefs.h <<_ACEOF #define PIPE_PATH "$config_pipepath" _ACEOF # Check whether --with-mcache-path was given. if test "${with_mcache_path+set}" = set; then : withval=$with_mcache_path; fi config_mcpath="\"SSS_STATEDIR\"/mc" mcpath="${localstatedir}/lib/sss/mc" if test x"$with_mcache_path" != x; then config_mcpath=$with_mcache_path mcpath=$with_mcache_path fi cat >>confdefs.h <<_ACEOF #define MCACHE_PATH "$config_mcpath" _ACEOF # Check whether --with-default-ccache-dir was given. if test "${with_default_ccache_dir+set}" = set; then : withval=$with_default_ccache_dir; fi config_def_ccache_dir="/tmp" if test x"$with_default_ccache_dir" != x; then config_def_ccache_dir=$with_default_ccache_dir fi cat >>confdefs.h <<_ACEOF #define DEFAULT_CCACHE_DIR "$config_def_ccache_dir" _ACEOF # Check whether --with-default-ccname-template was given. if test "${with_default_ccname_template+set}" = set; then : withval=$with_default_ccname_template; fi config_def_ccname_template="FILE:%d/krb5cc_%U_XXXXXX" if test x"$with_default_ccname_template" != x; then config_def_ccname_template=$with_default_ccname_template fi cat >>confdefs.h <<_ACEOF #define DEFAULT_CCNAME_TEMPLATE "$config_def_ccname_template" _ACEOF # Check whether --with-environment_file was given. if test "${with_environment_file+set}" = set; then : withval=$with_environment_file; fi ENVIRONMENT_FILE_PATH="${sysconfdir}/sysconfig/sssd" if test x"$with_environment_file" != x; then ENVIRONMENT_FILE_PATH=$with_environment_file fi environment_file=$ENVIRONMENT_FILE_PATH # Check whether --with-init-dir was given. if test "${with_init_dir+set}" = set; then : withval=$with_init_dir; fi initdir="${sysconfdir}/rc.d/init.d" if test x$osname = xgentoo; then initdir="${sysconfdir}/init.d" fi if test x"$with_init_dir" != x; then initdir=$with_init_dir fi # Check whether --with-test-dir was given. if test "${with_test_dir+set}" = set; then : withval=$with_test_dir; TEST_DIR=$withval else TEST_DIR="." fi cat >>confdefs.h <<_ACEOF #define TEST_DIR "$TEST_DIR" _ACEOF # Check whether --with-manpages was given. if test "${with_manpages+set}" = set; then : withval=$with_manpages; else with_manpages=yes fi if test x"$with_manpages" = xyes; then HAVE_MANPAGES=1 fi # Check whether --with-xml-catalog-path was given. if test "${with_xml_catalog_path+set}" = set; then : withval=$with_xml_catalog_path; fi SGML_CATALOG_FILES="/etc/xml/catalog" if test x"$with_xml_catalog_path" != x; then SGML_CATALOG_FILES="$with_xml_catalog_path" fi # Check whether --with-krb5-plugin-path was given. if test "${with_krb5_plugin_path+set}" = set; then : withval=$with_krb5_plugin_path; fi krb5pluginpath="${libdir}/krb5/plugins/libkrb5" if test x"$with_krb5_plugin_path" != x; then krb5pluginpath=$with_krb5_plugin_path fi # Check whether --with-krb5-rcache-dir was given. if test "${with_krb5_rcache_dir+set}" = set; then : withval=$with_krb5_rcache_dir; fi krb5rcachedir="__LIBKRB5_DEFAULTS__" if test x"$with_krb5_rcache_dir" != x; then krb5rcachedir=$with_krb5_rcache_dir fi cat >>confdefs.h <<_ACEOF #define KRB5_RCACHE_DIR "$krb5rcachedir" _ACEOF # Check whether --with-krb5authdata-plugin-path was given. if test "${with_krb5authdata_plugin_path+set}" = set; then : withval=$with_krb5authdata_plugin_path; fi krb5authdatapluginpath="${libdir}/krb5/plugins/authdata" if test x"$with_krb5authdata_plugin_path" != x; then krb5authdatapluginpath=$with_krb5authdata_plugin_path fi # Check whether --with-krb5_conf was given. if test "${with_krb5_conf+set}" = set; then : withval=$with_krb5_conf; fi KRB5_CONF_PATH="\"SYSCONFDIR\"/krb5.conf" if test x"$with_krb5_conf" != x; then KRB5_CONF_PATH=$with_krb5_conf fi cat >>confdefs.h <<_ACEOF #define KRB5_CONF_PATH "$KRB5_CONF_PATH" _ACEOF # Check whether --with-python2-bindings was given. if test "${with_python2_bindings+set}" = set; then : withval=$with_python2_bindings; else with_python2_bindings=yes fi if test x"$with_python2_bindings" = xyes; then HAVE_PYTHON2_BINDINGS=1 cat >>confdefs.h <<_ACEOF #define HAVE_PYTHON2_BINDINGS 1 _ACEOF fi if test x"$with_python2_bindings" = xyes; then BUILD_PYTHON2_BINDINGS_TRUE= BUILD_PYTHON2_BINDINGS_FALSE='#' else BUILD_PYTHON2_BINDINGS_TRUE='#' BUILD_PYTHON2_BINDINGS_FALSE= fi # Check whether --with-python3-bindings was given. if test "${with_python3_bindings+set}" = set; then : withval=$with_python3_bindings; else with_python3_bindings=yes fi if test x"$with_python3_bindings" = xyes; then HAVE_PYTHON3_BINDINGS=1 cat >>confdefs.h <<_ACEOF #define HAVE_PYTHON3_BINDINGS 1 _ACEOF fi if test x"$with_python3_bindings" = xyes; then BUILD_PYTHON3_BINDINGS_TRUE= BUILD_PYTHON3_BINDINGS_FALSE='#' else BUILD_PYTHON3_BINDINGS_TRUE='#' BUILD_PYTHON3_BINDINGS_FALSE= fi # Check whether --with-cifs-plugin-path was given. if test "${with_cifs_plugin_path+set}" = set; then : withval=$with_cifs_plugin_path; fi cifspluginpath="${libdir}/cifs-utils" if test x"$with_cifs_plugin_path" != x; then cifspluginpath=$with_cifs_plugin_path fi # Check whether --with-selinux was given. if test "${with_selinux+set}" = set; then : withval=$with_selinux; else with_selinux=yes fi if test x"$with_selinux" = xyes; then HAVE_SELINUX=1 cat >>confdefs.h <<_ACEOF #define HAVE_SELINUX 1 _ACEOF fi if test x"$with_selinux" = xyes; then BUILD_SELINUX_TRUE= BUILD_SELINUX_FALSE='#' else BUILD_SELINUX_TRUE='#' BUILD_SELINUX_FALSE= fi # Check whether --with-nscd was given. if test "${with_nscd+set}" = set; then : withval=$with_nscd; fi NSCD_PATH="/usr/sbin/nscd" if test x"$with_nscd" != x; then NSCD_PATH=$with_nscd fi cat >>confdefs.h <<_ACEOF #define HAVE_NSCD $NSCD_PATH _ACEOF # Check whether --with-ipa_getkeytab was given. if test "${with_ipa_getkeytab+set}" = set; then : withval=$with_ipa_getkeytab; fi IPA_GETKEYTAB_PATH="/usr/sbin/ipa-getkeytab" if test x"$with_ipa_getkeytab" != x; then IPA_GETKEYTAB_PATH=$with_ipa_getkeytab fi cat >>confdefs.h <<_ACEOF #define IPA_GETKEYTAB_PATH "$IPA_GETKEYTAB_PATH" _ACEOF # Check whether --with-semanage was given. if test "${with_semanage+set}" = set; then : withval=$with_semanage; else with_semanage=yes fi if test x"$with_semanage" = xyes; then HAVE_SEMANAGE=1 cat >>confdefs.h <<_ACEOF #define HAVE_SEMANAGE 1 _ACEOF fi if test x"$with_semanage" = xyes; then BUILD_SEMANAGE_TRUE= BUILD_SEMANAGE_FALSE='#' else BUILD_SEMANAGE_TRUE='#' BUILD_SEMANAGE_FALSE= fi # Check whether --with-ad-gpo-default was given. if test "${with_ad_gpo_default+set}" = set; then : withval=$with_ad_gpo_default; fi GPO_DEFAULT=enforcing if test x"$with_ad_gpo_default" != x; then if test ! "$with_ad_gpo_default" = "enforcing" -a ! "$with_ad_gpo_default" = "permissive"; then as_fn_error $? "\"GPO Default must be either \"enforcing\" or \"permissive\"" "$LINENO" 5 else GPO_DEFAULT=$with_ad_gpo_default fi fi cat >>confdefs.h <<_ACEOF #define AD_GPO_ACCESS_MODE_DEFAULT "$GPO_DEFAULT" _ACEOF if test x"$GPO_DEFAULT" = xenforcing; then GPO_DEFAULT_ENFORCING_TRUE= GPO_DEFAULT_ENFORCING_FALSE='#' else GPO_DEFAULT_ENFORCING_TRUE='#' GPO_DEFAULT_ENFORCING_FALSE= fi # Check whether --with-gpo-cache-path was given. if test "${with_gpo_cache_path+set}" = set; then : withval=$with_gpo_cache_path; fi config_gpocachepath="\"SSS_STATEDIR\"/gpo_cache" gpocachepath="${localstatedir}/lib/sss/gpo_cache" if test x"$with_gpo_cache_path" != x; then config_gpocachepath=$with_gpo_cache_path gpocachepath=$with_gpo_cache_path fi cat >>confdefs.h <<_ACEOF #define GPO_CACHE_PATH "$config_gpocachepath" _ACEOF # Check whether --with-nologin-shell was given. if test "${with_nologin_shell+set}" = set; then : withval=$with_nologin_shell; fi nologin_shell="/sbin/nologin" if test x"$with_nologin_shell" != x; then nologin_shell=$with_nologin_shell fi cat >>confdefs.h <<_ACEOF #define NOLOGIN_SHELL "$nologin_shell" _ACEOF # Check whether --with-app-libs was given. if test "${with_app_libs+set}" = set; then : withval=$with_app_libs; fi appmodpath="${libdir}/sssd/modules" config_appmodpath="\"LIBDIR\"/sssd/modules" if test x"$with_app_libs" != x; then appmodpath=$with_app_libs config_appmodpath=$with_app_libs fi cat >>confdefs.h <<_ACEOF #define APP_MODULES_PATH "$config_appmodpath" _ACEOF # Check whether --with-sudo was given. if test "${with_sudo+set}" = set; then : withval=$with_sudo; with_sudo=$withval else with_sudo=yes fi if test x"$with_sudo" = xyes; then $as_echo "#define BUILD_SUDO 1" >>confdefs.h fi if test x"$with_sudo" = xyes; then BUILD_SUDO_TRUE= BUILD_SUDO_FALSE='#' else BUILD_SUDO_TRUE='#' BUILD_SUDO_FALSE= fi # Check whether --with-sudo-lib-path was given. if test "${with_sudo_lib_path+set}" = set; then : withval=$with_sudo_lib_path; fi sudolibpath="${libdir}" if test x"$with_sudo_lib_path" != x; then sudolibpath=$with_sudo_lib_path fi # Check whether --with-autofs was given. if test "${with_autofs+set}" = set; then : withval=$with_autofs; with_autofs=$withval else with_autofs=yes fi if test x"$with_autofs" = xyes; then $as_echo "#define BUILD_AUTOFS 1" >>confdefs.h fi if test x"$with_autofs" = xyes; then BUILD_AUTOFS_TRUE= BUILD_AUTOFS_FALSE='#' else BUILD_AUTOFS_TRUE='#' BUILD_AUTOFS_FALSE= fi # Check whether --with-ssh was given. if test "${with_ssh+set}" = set; then : withval=$with_ssh; with_ssh=$withval else with_ssh=yes fi if test x"$with_ssh" = xyes; then $as_echo "#define BUILD_SSH 1" >>confdefs.h fi if test x"$with_ssh" = xyes; then BUILD_SSH_TRUE= BUILD_SSH_FALSE='#' else BUILD_SSH_TRUE='#' BUILD_SSH_FALSE= fi # Check whether --with-infopipe was given. if test "${with_infopipe+set}" = set; then : withval=$with_infopipe; with_infopipe=$withval else with_infopipe=yes fi if test x"$with_infopipe" = xyes; then $as_echo "#define BUILD_IFP 1" >>confdefs.h fi if test x"$with_infopipe" = xyes; then BUILD_IFP_TRUE= BUILD_IFP_FALSE='#' else BUILD_IFP_TRUE='#' BUILD_IFP_FALSE= fi # Check whether --with-crypto was given. if test "${with_crypto+set}" = set; then : withval=$with_crypto; else with_crypto=nss fi cryptolib="" if test x"$with_crypto" != x; then if test x"$with_crypto" = xnss || \ test x"$with_crypto" = xlibcrypto; then cryptolib="$with_crypto"; else as_fn_error $? "Illegal value -$with_crypto- for option --with-crypto" "$LINENO" 5 fi fi if test x"$cryptolib" = xnss; then HAVE_NSS_TRUE= HAVE_NSS_FALSE='#' else HAVE_NSS_TRUE='#' HAVE_NSS_FALSE= fi if test x"$cryptolib" = xlibcrypto; then HAVE_LIBCRYPTO_TRUE= HAVE_LIBCRYPTO_FALSE='#' else HAVE_LIBCRYPTO_TRUE='#' HAVE_LIBCRYPTO_FALSE= fi # Check whether --with-syslog was given. if test "${with_syslog+set}" = set; then : withval=$with_syslog; else with_syslog="syslog" fi if test x"$with_syslog" = xsyslog || \ test x"$with_syslog" = xjournald; then syslog=$with_syslog else as_fn_error $? "Uknown syslog type, supported types are syslog and journald" "$LINENO" 5 fi if test x"$syslog" = xjournald; then WITH_JOURNALD_TRUE= WITH_JOURNALD_FALSE='#' else WITH_JOURNALD_TRUE='#' WITH_JOURNALD_FALSE= fi # Check whether --with-samba was given. if test "${with_samba+set}" = set; then : withval=$with_samba; with_samba=$withval else with_samba=yes fi if test x"$with_samba" = xyes; then $as_echo "#define BUILD_SAMBA 1" >>confdefs.h fi if test x"$with_samba" = xyes; then BUILD_SAMBA_TRUE= BUILD_SAMBA_FALSE='#' else BUILD_SAMBA_TRUE='#' BUILD_SAMBA_FALSE= fi # Check whether --with-nfsv4-idmapd-plugin was given. if test "${with_nfsv4_idmapd_plugin+set}" = set; then : withval=$with_nfsv4_idmapd_plugin; with_nfsv4_idmap=$withval else with_nfsv4_idmap=yes fi if test x"$with_nfsv4_idmap" = xyes; then $as_echo "#define BUILD_NFS_IDMAP 1" >>confdefs.h fi if test x"$with_nfsv4_idmap" = xyes; then BUILD_NFS_IDMAP_TRUE= BUILD_NFS_IDMAP_FALSE='#' else BUILD_NFS_IDMAP_TRUE='#' BUILD_NFS_IDMAP_FALSE= fi # Check whether --with-nfs-lib-path was given. if test "${with_nfs_lib_path+set}" = set; then : withval=$with_nfs_lib_path; fi nfslibpath="${libdir}" if test x"$with_nfs_lib_path" != x; then nfslibpath=$with_nfs_lib_path fi # Check whether --with-libwbclient was given. if test "${with_libwbclient+set}" = set; then : withval=$with_libwbclient; with_libwbclient=$withval else with_libwbclient=yes fi if test x"$with_libwbclient" = xyes; then $as_echo "#define BUILD_LIBWBCLIENT 1" >>confdefs.h libwbclient_version="0.12" libwbclient_version_info="12:0:12" fi if test x"$with_libwbclient" = xyes; then BUILD_LIBWBCLIENT_TRUE= BUILD_LIBWBCLIENT_FALSE='#' else BUILD_LIBWBCLIENT_TRUE='#' BUILD_LIBWBCLIENT_FALSE= fi # Check whether --with-sssd-user was given. if test "${with_sssd_user+set}" = set; then : withval=$with_sssd_user; fi SSSD_USER=root if test x"$with_sssd_user" != x; then SSSD_USER=$with_sssd_user fi cat >>confdefs.h <<_ACEOF #define SSSD_USER "$SSSD_USER" _ACEOF if test x"$with_sssd_user" != x; then SSSD_USER_TRUE= SSSD_USER_FALSE='#' else SSSD_USER_TRUE='#' SSSD_USER_FALSE= fi # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # # Copyright © 2004 Scott James Remnant . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- # PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # # Similar to PKG_CHECK_MODULES, make sure that the first instance of # this or PKG_CHECK_MODULES is called, or make sure to call # PKG_CHECK_EXISTS manually # -------------------------------------------------------------- # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- # _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- # _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- # PKG_CHECK_MODULES if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for POPT" >&5 $as_echo_n "checking for POPT... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$POPT_CFLAGS"; then pkg_cv_POPT_CFLAGS="$POPT_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"popt\""; } >&5 ($PKG_CONFIG --exists --print-errors "popt") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_POPT_CFLAGS=`$PKG_CONFIG --cflags "popt" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$POPT_LIBS"; then pkg_cv_POPT_LIBS="$POPT_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"popt\""; } >&5 ($PKG_CONFIG --exists --print-errors "popt") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_POPT_LIBS=`$PKG_CONFIG --libs "popt" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then POPT_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "popt"` else POPT_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "popt"` fi # Put the nasty error message in config.log where it belongs echo "$POPT_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } found_popt=no elif test $pkg_failed = untried; then found_popt=no else POPT_CFLAGS=$pkg_cv_POPT_CFLAGS POPT_LIBS=$pkg_cv_POPT_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } found_popt=yes fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" sss_extra_libdir="$additional_libdir" if test x"$found_popt" != xyes; then : for ac_header in popt.h do : ac_fn_c_check_header_mongrel "$LINENO" "popt.h" "ac_cv_header_popt_h" "$ac_includes_default" if test "x$ac_cv_header_popt_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_POPT_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for poptGetContext in -lpopt" >&5 $as_echo_n "checking for poptGetContext in -lpopt... " >&6; } if ${ac_cv_lib_popt_poptGetContext+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpopt -L$sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char poptGetContext (); int main () { return poptGetContext (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_popt_poptGetContext=yes else ac_cv_lib_popt_poptGetContext=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_popt_poptGetContext" >&5 $as_echo "$ac_cv_lib_popt_poptGetContext" >&6; } if test "x$ac_cv_lib_popt_poptGetContext" = xyes; then : POPT_LIBS="-L$sss_extra_libdir -lpopt" else as_fn_error $? "POPT library must support poptGetContext" "$LINENO" 5 fi else as_fn_error $? "POPT header files are not installed" "$LINENO" 5 fi done fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TALLOC" >&5 $as_echo_n "checking for TALLOC... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$TALLOC_CFLAGS"; then pkg_cv_TALLOC_CFLAGS="$TALLOC_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"talloc\""; } >&5 ($PKG_CONFIG --exists --print-errors "talloc") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TALLOC_CFLAGS=`$PKG_CONFIG --cflags "talloc" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$TALLOC_LIBS"; then pkg_cv_TALLOC_LIBS="$TALLOC_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"talloc\""; } >&5 ($PKG_CONFIG --exists --print-errors "talloc") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TALLOC_LIBS=`$PKG_CONFIG --libs "talloc" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then TALLOC_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "talloc"` else TALLOC_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "talloc"` fi # Put the nasty error message in config.log where it belongs echo "$TALLOC_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } found_talloc=no elif test $pkg_failed = untried; then found_talloc=no else TALLOC_CFLAGS=$pkg_cv_TALLOC_CFLAGS TALLOC_LIBS=$pkg_cv_TALLOC_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } found_talloc=yes fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" sss_extra_libdir="$additional_libdir" if test x"$found_talloc" != xyes; then : ac_fn_c_check_header_mongrel "$LINENO" "talloc.h" "ac_cv_header_talloc_h" "$ac_includes_default" if test "x$ac_cv_header_talloc_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for talloc_init in -ltalloc" >&5 $as_echo_n "checking for talloc_init in -ltalloc... " >&6; } if ${ac_cv_lib_talloc_talloc_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltalloc -L$sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char talloc_init (); int main () { return talloc_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_talloc_talloc_init=yes else ac_cv_lib_talloc_talloc_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_talloc_talloc_init" >&5 $as_echo "$ac_cv_lib_talloc_talloc_init" >&6; } if test "x$ac_cv_lib_talloc_talloc_init" = xyes; then : TALLOC_LIBS="-L$sss_extra_libdir -ltalloc" else as_fn_error $? "libtalloc missing talloc_init" "$LINENO" 5 fi else as_fn_error $? "libtalloc header files are not installed" "$LINENO" 5 fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TDB" >&5 $as_echo_n "checking for TDB... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$TDB_CFLAGS"; then pkg_cv_TDB_CFLAGS="$TDB_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tdb >= 1.1.3\""; } >&5 ($PKG_CONFIG --exists --print-errors "tdb >= 1.1.3") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TDB_CFLAGS=`$PKG_CONFIG --cflags "tdb >= 1.1.3" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$TDB_LIBS"; then pkg_cv_TDB_LIBS="$TDB_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tdb >= 1.1.3\""; } >&5 ($PKG_CONFIG --exists --print-errors "tdb >= 1.1.3") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TDB_LIBS=`$PKG_CONFIG --libs "tdb >= 1.1.3" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then TDB_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "tdb >= 1.1.3"` else TDB_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "tdb >= 1.1.3"` fi # Put the nasty error message in config.log where it belongs echo "$TDB_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } found_tdb=no elif test $pkg_failed = untried; then found_tdb=no else TDB_CFLAGS=$pkg_cv_TDB_CFLAGS TDB_LIBS=$pkg_cv_TDB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } found_tdb=yes fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" sss_extra_libdir="$additional_libdir" if test x"$found_tdb" != xyes; then : for ac_header in tdb.h do : ac_fn_c_check_header_mongrel "$LINENO" "tdb.h" "ac_cv_header_tdb_h" "$ac_includes_default" if test "x$ac_cv_header_tdb_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TDB_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tdb_repack in -ltdb" >&5 $as_echo_n "checking for tdb_repack in -ltdb... " >&6; } if ${ac_cv_lib_tdb_tdb_repack+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltdb -L$sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tdb_repack (); int main () { return tdb_repack (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_tdb_tdb_repack=yes else ac_cv_lib_tdb_tdb_repack=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tdb_tdb_repack" >&5 $as_echo "$ac_cv_lib_tdb_tdb_repack" >&6; } if test "x$ac_cv_lib_tdb_tdb_repack" = xyes; then : TDB_LIBS="-L$sss_extra_libdir -ltdb" else as_fn_error $? "library TDB must support tdb_repack" "$LINENO" 5 fi else as_fn_error $? "tdb header files are not installed" "$LINENO" 5 fi done fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for TEVENT" >&5 $as_echo_n "checking for TEVENT... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$TEVENT_CFLAGS"; then pkg_cv_TEVENT_CFLAGS="$TEVENT_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tevent\""; } >&5 ($PKG_CONFIG --exists --print-errors "tevent") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TEVENT_CFLAGS=`$PKG_CONFIG --cflags "tevent" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$TEVENT_LIBS"; then pkg_cv_TEVENT_LIBS="$TEVENT_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"tevent\""; } >&5 ($PKG_CONFIG --exists --print-errors "tevent") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TEVENT_LIBS=`$PKG_CONFIG --libs "tevent" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then TEVENT_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "tevent"` else TEVENT_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "tevent"` fi # Put the nasty error message in config.log where it belongs echo "$TEVENT_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } found_tevent=no elif test $pkg_failed = untried; then found_tevent=no else TEVENT_CFLAGS=$pkg_cv_TEVENT_CFLAGS TEVENT_LIBS=$pkg_cv_TEVENT_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } found_tevent=yes fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" sss_extra_libdir="$additional_libdir" if test x"$found_tevent" != xyes; then : ac_fn_c_check_header_mongrel "$LINENO" "tevent.h" "ac_cv_header_tevent_h" "$ac_includes_default" if test "x$ac_cv_header_tevent_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tevent_context_init in -ltevent" >&5 $as_echo_n "checking for tevent_context_init in -ltevent... " >&6; } if ${ac_cv_lib_tevent_tevent_context_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltevent -L$sss_extra_libdir -ltalloc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tevent_context_init (); int main () { return tevent_context_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_tevent_tevent_context_init=yes else ac_cv_lib_tevent_tevent_context_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tevent_tevent_context_init" >&5 $as_echo "$ac_cv_lib_tevent_tevent_context_init" >&6; } if test "x$ac_cv_lib_tevent_tevent_context_init" = xyes; then : TEVENT_LIBS="-L$sss_extra_libdir -ltevent -ltalloc" else as_fn_error $? "libtevent missing tevent_context_init" "$LINENO" 5 fi else as_fn_error $? "tevent header files are not installed" "$LINENO" 5 fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LDB" >&5 $as_echo_n "checking for LDB... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$LDB_CFLAGS"; then pkg_cv_LDB_CFLAGS="$LDB_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ldb >= 0.9.2\""; } >&5 ($PKG_CONFIG --exists --print-errors "ldb >= 0.9.2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LDB_CFLAGS=`$PKG_CONFIG --cflags "ldb >= 0.9.2" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$LDB_LIBS"; then pkg_cv_LDB_LIBS="$LDB_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ldb >= 0.9.2\""; } >&5 ($PKG_CONFIG --exists --print-errors "ldb >= 0.9.2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LDB_LIBS=`$PKG_CONFIG --libs "ldb >= 0.9.2" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then LDB_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "ldb >= 0.9.2"` else LDB_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "ldb >= 0.9.2"` fi # Put the nasty error message in config.log where it belongs echo "$LDB_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (ldb >= 0.9.2) were not met: $LDB_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables LDB_CFLAGS and LDB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " "$LINENO" 5 elif test $pkg_failed = untried; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables LDB_CFLAGS and LDB_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else LDB_CFLAGS=$pkg_cv_LDB_CFLAGS LDB_LIBS=$pkg_cv_LDB_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi for ac_header in ldb.h ldb_module.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldb_init in -lldb" >&5 $as_echo_n "checking for ldb_init in -lldb... " >&6; } if ${ac_cv_lib_ldb_ldb_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lldb -ltevent -ltdb -ldl -lldap $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ldb_init (); int main () { return ldb_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ldb_ldb_init=yes else ac_cv_lib_ldb_ldb_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldb_ldb_init" >&5 $as_echo "$ac_cv_lib_ldb_ldb_init" >&6; } if test "x$ac_cv_lib_ldb_ldb_init" = xyes; then : LDB_LIBS="-lldb" fi else as_fn_error $? "LDB header files are not installed" "$LINENO" 5 fi done # Check whether --with-ldb-lib-dir was given. if test "${with_ldb_lib_dir+set}" = set; then : withval=$with_ldb_lib_dir; fi if test x"$with_ldb_lib_dir" != x; then ldblibdir=$with_ldb_lib_dir else ldblibdir="`$PKG_CONFIG --variable=modulesdir ldb`" if ! test -d $ldblibdir; then ldblibdir="${libdir}/ldb" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking feature ldb runtime version check" >&5 $as_echo_n "checking feature ldb runtime version check... " >&6; } # Check whether --enable-ldb-version-check was given. if test "${enable_ldb_version_check+set}" = set; then : enableval=$enable_ldb_version_check; enable_ldb_version_check="$enableval" else enable_ldb_version_check="no" fi if test x"$enable_ldb_version_check" = xyes ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define SSS_LDB_VERSION_CHECK 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: ldb lib directory: $ldblibdir" >&5 $as_echo "$as_me: ldb lib directory: $ldblibdir" >&6;} pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DHASH" >&5 $as_echo_n "checking for DHASH... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$DHASH_CFLAGS"; then pkg_cv_DHASH_CFLAGS="$DHASH_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dhash >= 0.4.2\""; } >&5 ($PKG_CONFIG --exists --print-errors "dhash >= 0.4.2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DHASH_CFLAGS=`$PKG_CONFIG --cflags "dhash >= 0.4.2" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$DHASH_LIBS"; then pkg_cv_DHASH_LIBS="$DHASH_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dhash >= 0.4.2\""; } >&5 ($PKG_CONFIG --exists --print-errors "dhash >= 0.4.2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DHASH_LIBS=`$PKG_CONFIG --libs "dhash >= 0.4.2" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then DHASH_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "dhash >= 0.4.2"` else DHASH_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "dhash >= 0.4.2"` fi # Put the nasty error message in config.log where it belongs echo "$DHASH_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "\"Please install libdhash-devel\"" "$LINENO" 5 elif test $pkg_failed = untried; then as_fn_error $? "\"Please install libdhash-devel\"" "$LINENO" 5 else DHASH_CFLAGS=$pkg_cv_DHASH_CFLAGS DHASH_LIBS=$pkg_cv_DHASH_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for COLLECTION" >&5 $as_echo_n "checking for COLLECTION... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$COLLECTION_CFLAGS"; then pkg_cv_COLLECTION_CFLAGS="$COLLECTION_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"collection >= 0.5.1\""; } >&5 ($PKG_CONFIG --exists --print-errors "collection >= 0.5.1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_COLLECTION_CFLAGS=`$PKG_CONFIG --cflags "collection >= 0.5.1" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$COLLECTION_LIBS"; then pkg_cv_COLLECTION_LIBS="$COLLECTION_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"collection >= 0.5.1\""; } >&5 ($PKG_CONFIG --exists --print-errors "collection >= 0.5.1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_COLLECTION_LIBS=`$PKG_CONFIG --libs "collection >= 0.5.1" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then COLLECTION_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "collection >= 0.5.1"` else COLLECTION_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "collection >= 0.5.1"` fi # Put the nasty error message in config.log where it belongs echo "$COLLECTION_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "\"Please install libcollection-devel\"" "$LINENO" 5 elif test $pkg_failed = untried; then as_fn_error $? "\"Please install libcollection-devel\"" "$LINENO" 5 else COLLECTION_CFLAGS=$pkg_cv_COLLECTION_CFLAGS COLLECTION_LIBS=$pkg_cv_COLLECTION_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for INI_CONFIG_V0" >&5 $as_echo_n "checking for INI_CONFIG_V0... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$INI_CONFIG_V0_CFLAGS"; then pkg_cv_INI_CONFIG_V0_CFLAGS="$INI_CONFIG_V0_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" ini_config >= 0.6.1\""; } >&5 ($PKG_CONFIG --exists --print-errors " ini_config >= 0.6.1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_INI_CONFIG_V0_CFLAGS=`$PKG_CONFIG --cflags " ini_config >= 0.6.1" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$INI_CONFIG_V0_LIBS"; then pkg_cv_INI_CONFIG_V0_LIBS="$INI_CONFIG_V0_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" ini_config >= 0.6.1\""; } >&5 ($PKG_CONFIG --exists --print-errors " ini_config >= 0.6.1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_INI_CONFIG_V0_LIBS=`$PKG_CONFIG --libs " ini_config >= 0.6.1" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then INI_CONFIG_V0_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors " ini_config >= 0.6.1"` else INI_CONFIG_V0_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors " ini_config >= 0.6.1"` fi # Put the nasty error message in config.log where it belongs echo "$INI_CONFIG_V0_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Please install libini_config-devel" "$LINENO" 5 elif test $pkg_failed = untried; then as_fn_error $? "Please install libini_config-devel" "$LINENO" 5 else INI_CONFIG_V0_CFLAGS=$pkg_cv_INI_CONFIG_V0_CFLAGS INI_CONFIG_V0_LIBS=$pkg_cv_INI_CONFIG_V0_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } INI_CONFIG_CFLAGS="$INI_CONFIG_V0_CFLAGS" INI_CONFIG_LIBS="$INI_CONFIG_V0_LIBS" HAVE_LIBINI_CONFIG_V0=1 cat >>confdefs.h <<_ACEOF #define HAVE_LIBINI_CONFIG_V0 1 _ACEOF pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for INI_CONFIG_V1" >&5 $as_echo_n "checking for INI_CONFIG_V1... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$INI_CONFIG_V1_CFLAGS"; then pkg_cv_INI_CONFIG_V1_CFLAGS="$INI_CONFIG_V1_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" ini_config >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors " ini_config >= 1.0.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_INI_CONFIG_V1_CFLAGS=`$PKG_CONFIG --cflags " ini_config >= 1.0.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$INI_CONFIG_V1_LIBS"; then pkg_cv_INI_CONFIG_V1_LIBS="$INI_CONFIG_V1_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" ini_config >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors " ini_config >= 1.0.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_INI_CONFIG_V1_LIBS=`$PKG_CONFIG --libs " ini_config >= 1.0.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then INI_CONFIG_V1_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors " ini_config >= 1.0.0"` else INI_CONFIG_V1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors " ini_config >= 1.0.0"` fi # Put the nasty error message in config.log where it belongs echo "$INI_CONFIG_V1_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libini_config-devel >= 1.0.0 not available, using older version" >&5 $as_echo "$as_me: WARNING: libini_config-devel >= 1.0.0 not available, using older version" >&2;} elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libini_config-devel >= 1.0.0 not available, using older version" >&5 $as_echo "$as_me: WARNING: libini_config-devel >= 1.0.0 not available, using older version" >&2;} else INI_CONFIG_V1_CFLAGS=$pkg_cv_INI_CONFIG_V1_CFLAGS INI_CONFIG_V1_LIBS=$pkg_cv_INI_CONFIG_V1_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } INI_CONFIG_CFLAGS="$INI_CONFIG_V1_CFLAGS" INI_CONFIG_LIBS="$INI_CONFIG_V1_LIBS" HAVE_LIBINI_CONFIG_V1=1 cat >>confdefs.h <<_ACEOF #define HAVE_LIBINI_CONFIG_V1 1 _ACEOF pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for INI_CONFIG_V1_1" >&5 $as_echo_n "checking for INI_CONFIG_V1_1... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$INI_CONFIG_V1_1_CFLAGS"; then pkg_cv_INI_CONFIG_V1_1_CFLAGS="$INI_CONFIG_V1_1_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" ini_config >= 1.1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors " ini_config >= 1.1.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_INI_CONFIG_V1_1_CFLAGS=`$PKG_CONFIG --cflags " ini_config >= 1.1.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$INI_CONFIG_V1_1_LIBS"; then pkg_cv_INI_CONFIG_V1_1_LIBS="$INI_CONFIG_V1_1_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" ini_config >= 1.1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors " ini_config >= 1.1.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_INI_CONFIG_V1_1_LIBS=`$PKG_CONFIG --libs " ini_config >= 1.1.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then INI_CONFIG_V1_1_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors " ini_config >= 1.1.0"` else INI_CONFIG_V1_1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors " ini_config >= 1.1.0"` fi # Put the nasty error message in config.log where it belongs echo "$INI_CONFIG_V1_1_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libini_config-devel >= 1.1.0 not available, using older version" >&5 $as_echo "$as_me: WARNING: libini_config-devel >= 1.1.0 not available, using older version" >&2;} elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libini_config-devel >= 1.1.0 not available, using older version" >&5 $as_echo "$as_me: WARNING: libini_config-devel >= 1.1.0 not available, using older version" >&2;} else INI_CONFIG_V1_1_CFLAGS=$pkg_cv_INI_CONFIG_V1_1_CFLAGS INI_CONFIG_V1_1_LIBS=$pkg_cv_INI_CONFIG_V1_1_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } INI_CONFIG_CFLAGS="$INI_CONFIG_V1_1_CFLAGS" INI_CONFIG_LIBS="$INI_CONFIG_V1_1_LIBS" HAVE_LIBINI_CONFIG_V1_1=1 cat >>confdefs.h <<_ACEOF #define HAVE_LIBINI_CONFIG_V1_1 1 _ACEOF fi fi fi for ac_header in security/pam_appl.h security/pam_modules.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pam_get_item in -lpam" >&5 $as_echo_n "checking for pam_get_item in -lpam... " >&6; } if ${ac_cv_lib_pam_pam_get_item+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pam_get_item (); int main () { return pam_get_item (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pam_pam_get_item=yes else ac_cv_lib_pam_pam_get_item=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_pam_get_item" >&5 $as_echo "$ac_cv_lib_pam_pam_get_item" >&6; } if test "x$ac_cv_lib_pam_pam_get_item" = xyes; then : PAM_LIBS="-lpam" else as_fn_error $? "PAM must support pam_get_item" "$LINENO" 5 fi else as_fn_error $? "PAM development libraries not installed" "$LINENO" 5 fi done for ac_header in security/pam_ext.h security/pam_modutil.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in security/pam_misc.h security/_pam_macros.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in security/openpam.h do : ac_fn_c_check_header_compile "$LINENO" "security/openpam.h" "ac_cv_header_security_openpam_h" " #ifdef HAVE_SECURITY_PAM_APPL_H #include #endif " if test "x$ac_cv_header_security_openpam_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SECURITY_OPENPAM_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for misc_conv in -lpam_misc" >&5 $as_echo_n "checking for misc_conv in -lpam_misc... " >&6; } if ${ac_cv_lib_pam_misc_misc_conv+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpam_misc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char misc_conv (); int main () { return misc_conv (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pam_misc_misc_conv=yes else ac_cv_lib_pam_misc_misc_conv=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pam_misc_misc_conv" >&5 $as_echo "$ac_cv_lib_pam_misc_misc_conv" >&6; } if test "x$ac_cv_lib_pam_misc_misc_conv" = xyes; then : PAM_MISC_LIBS="-lpam_misc" fi save_LIBS="$LIBS" LIBS="$PAM_LIBS" for ac_func in pam_modutil_getlogin pam_vsyslog do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done LIBS="$save_LIBS" for p in /usr/include/openldap24 /usr/local/include; do if test -f "${p}/ldap.h"; then OPENLDAP_CFLAGS="${OPENLDAP_CFLAGS} -I${p}" break; fi done for p in /usr/lib64/openldap24 /usr/lib/openldap24 /usr/local/lib ; do if test -f "${p}/libldap.so"; then OPENLDAP_LIBS="${OPENLDAP_LIBS} -L${p}" break; fi done SAVE_CFLAGS=$CFLAGS SAVE_LIBS=$LIBS CFLAGS="$CFLAGS $OPENLDAP_CFLAGS" LIBS="$LIBS $OPENLDAP_LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap_search in -lldap" >&5 $as_echo_n "checking for ldap_search in -lldap... " >&6; } if ${ac_cv_lib_ldap_ldap_search+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lldap $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ldap_search (); int main () { return ldap_search (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ldap_ldap_search=yes else ac_cv_lib_ldap_ldap_search=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_search" >&5 $as_echo "$ac_cv_lib_ldap_ldap_search" >&6; } if test "x$ac_cv_lib_ldap_ldap_search" = xyes; then : with_ldap=yes fi test "$with_ldap" != "yes" && { { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap_open in -lldap" >&5 $as_echo_n "checking for ldap_open in -lldap... " >&6; } if ${ac_cv_lib_ldap_ldap_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lldap -llber $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ldap_open (); int main () { return ldap_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ldap_ldap_open=yes else ac_cv_lib_ldap_ldap_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_open" >&5 $as_echo "$ac_cv_lib_ldap_ldap_open" >&6; } if test "x$ac_cv_lib_ldap_ldap_open" = xyes; then : with_ldap=yes with_ldap_lber=yes fi } test "$with_ldap" != "yes" && { { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap_open in -lldap" >&5 $as_echo_n "checking for ldap_open in -lldap... " >&6; } if ${ac_cv_lib_ldap_ldap_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lldap -llber -lkrb $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ldap_open (); int main () { return ldap_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ldap_ldap_open=yes else ac_cv_lib_ldap_ldap_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_open" >&5 $as_echo "$ac_cv_lib_ldap_ldap_open" >&6; } if test "x$ac_cv_lib_ldap_ldap_open" = xyes; then : with_ldap=yes with_ldap_lber=yes with_ldap_krb=yes fi } test "$with_ldap" != "yes" && { { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ldap_open in -lldap" >&5 $as_echo_n "checking for ldap_open in -lldap... " >&6; } if ${ac_cv_lib_ldap_ldap_open+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lldap -llber -lkrb -ldes $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ldap_open (); int main () { return ldap_open (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ldap_ldap_open=yes else ac_cv_lib_ldap_ldap_open=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ldap_ldap_open" >&5 $as_echo "$ac_cv_lib_ldap_ldap_open" >&6; } if test "x$ac_cv_lib_ldap_ldap_open" = xyes; then : with_ldap=yes with_ldap_lber=yes with_ldap_krb=yes with_ldap_des=yes fi } CFLAGS=$SAVE_CFLAGS LIBS=$SAVE_LIBS test "$with_ldap_lber" != "yes" && { { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ber_pvt_opt_on in -llber" >&5 $as_echo_n "checking for ber_pvt_opt_on in -llber... " >&6; } if ${ac_cv_lib_lber_ber_pvt_opt_on+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-llber $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ber_pvt_opt_on (); int main () { return ber_pvt_opt_on (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_lber_ber_pvt_opt_on=yes else ac_cv_lib_lber_ber_pvt_opt_on=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lber_ber_pvt_opt_on" >&5 $as_echo "$ac_cv_lib_lber_ber_pvt_opt_on" >&6; } if test "x$ac_cv_lib_lber_ber_pvt_opt_on" = xyes; then : with_ldap_lber=yes fi } if test "$with_ldap" = "yes"; then if test "$with_ldap_des" = "yes" ; then OPENLDAP_LIBS="${OPENLDAP_LIBS} -ldes" fi if test "$with_ldap_krb" = "yes" ; then OPENLDAP_LIBS="${OPENLDAP_LIBS} -lkrb" fi if test "$with_ldap_lber" = "yes" ; then OPENLDAP_LIBS="${OPENLDAP_LIBS} -llber" fi OPENLDAP_LIBS="${OPENLDAP_LIBS} -lldap" else as_fn_error $? "OpenLDAP not found" "$LINENO" 5 fi SAVE_CFLAGS=$CFLAGS SAVE_LIBS=$LIBS CFLAGS="$CFLAGS $OPENLDAP_CFLAGS" LIBS="$LIBS $OPENLDAP_LIBS" for ac_func in ldap_control_create ldap_init_fd \ ldap_create_deref_control_value \ ldap_parse_derefresponse_control \ ldap_derefresponse_free do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_member "$LINENO" "struct ldap_conncb" "lc_arg" "ac_cv_member_struct_ldap_conncb_lc_arg" "#include " if test "x$ac_cv_member_struct_ldap_conncb_lc_arg" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_STRUCT_LDAP_CONNCB_LC_ARG 1 _ACEOF if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { struct ldap_conncb cb; return ldap_set_option(NULL, LDAP_OPT_CONNECT_CB, &cb); ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : $as_echo "#define HAVE_LDAP_CONNCB 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Found broken callback implementation" >&5 $as_echo "$as_me: WARNING: Found broken callback implementation" >&2;} fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi ac_fn_c_check_type "$LINENO" "LDAPDerefRes" "ac_cv_type_LDAPDerefRes" "#include " if test "x$ac_cv_type_LDAPDerefRes" = xyes; then : else as_fn_error $? "The OpenLDAP version found does not contain the required type LDAPDerefRes" "$LINENO" 5 fi CFLAGS=$SAVE_CFLAGS LIBS=$SAVE_LIBS # Extract the first word of "slapd", so it can be a program name with args. set dummy slapd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_SLAPD+:} false; then : $as_echo_n "(cached) " >&6 else case $SLAPD in [\\/]* | ?:[\\/]*) ac_cv_path_SLAPD="$SLAPD" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SLAPD="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SLAPD=$ac_cv_path_SLAPD if test -n "$SLAPD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SLAPD" >&5 $as_echo "$SLAPD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -n "$SLAPD"; then : HAVE_SLAPD=yes else HAVE_SLAPD=no fi # Extract the first word of "ldapmodify", so it can be a program name with args. set dummy ldapmodify; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_LDAPMODIFY+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_LDAPMODIFY"; then ac_cv_prog_HAVE_LDAPMODIFY="$HAVE_LDAPMODIFY" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_LDAPMODIFY="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_HAVE_LDAPMODIFY" && ac_cv_prog_HAVE_LDAPMODIFY="no" fi fi HAVE_LDAPMODIFY=$ac_cv_prog_HAVE_LDAPMODIFY if test -n "$HAVE_LDAPMODIFY"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_LDAPMODIFY" >&5 $as_echo "$HAVE_LDAPMODIFY" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PCRE" >&5 $as_echo_n "checking for PCRE... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$PCRE_CFLAGS"; then pkg_cv_PCRE_CFLAGS="$PCRE_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpcre\""; } >&5 ($PKG_CONFIG --exists --print-errors "libpcre") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PCRE_CFLAGS=`$PKG_CONFIG --cflags "libpcre" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$PCRE_LIBS"; then pkg_cv_PCRE_LIBS="$PCRE_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpcre\""; } >&5 ($PKG_CONFIG --exists --print-errors "libpcre") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PCRE_LIBS=`$PKG_CONFIG --libs "libpcre" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then PCRE_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libpcre"` else PCRE_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libpcre"` fi # Put the nasty error message in config.log where it belongs echo "$PCRE_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } found_libpcre=no elif test $pkg_failed = untried; then found_libpcre=no else PCRE_CFLAGS=$pkg_cv_PCRE_CFLAGS PCRE_LIBS=$pkg_cv_PCRE_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } found_libpcre=yes fi if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpcre >= 7\""; } >&5 ($PKG_CONFIG --exists --print-errors "libpcre >= 7") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then { $as_echo "$as_me:${as_lineno-$LINENO}: PCRE version is 7 or higher" >&5 $as_echo "$as_me: PCRE version is 7 or higher" >&6;} else { $as_echo "$as_me:${as_lineno-$LINENO}: PCRE version is below 7" >&5 $as_echo "$as_me: PCRE version is below 7" >&6;} $as_echo "#define HAVE_LIBPCRE_LESSER_THAN_7 1" >>confdefs.h fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" sss_extra_libdir="$additional_libdir" if test x"$found_libpcre" != xyes; then : for ac_header in pcre.h do : ac_fn_c_check_header_mongrel "$LINENO" "pcre.h" "ac_cv_header_pcre_h" "$ac_includes_default" if test "x$ac_cv_header_pcre_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PCRE_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcre_compile in -lpcre" >&5 $as_echo_n "checking for pcre_compile in -lpcre... " >&6; } if ${ac_cv_lib_pcre_pcre_compile+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpcre -L$sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pcre_compile (); int main () { return pcre_compile (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_pcre_pcre_compile=yes else ac_cv_lib_pcre_pcre_compile=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcre_pcre_compile" >&5 $as_echo "$ac_cv_lib_pcre_pcre_compile" >&6; } if test "x$ac_cv_lib_pcre_pcre_compile" = xyes; then : PCRE_LIBS="-L$sss_extra_libdir -lpcre" else as_fn_error $? "No usable PCRE library found" "$LINENO" 5 fi else as_fn_error $? "pcre header files are not installed" "$LINENO" 5 fi done fi if test x$KRB5_LIBS != x; then KRB5_PASSED_LIBS=$KRB5_LIBS fi if test x$KRB5_CFLAGS != x; then KRB5_PASSED_CFLAGS=$KRB5_CFLAGS fi # Extract the first word of "krb5-config", so it can be a program name with args. set dummy krb5-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_KRB5_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $KRB5_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_KRB5_CONFIG="$KRB5_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_KRB5_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi KRB5_CONFIG=$ac_cv_path_KRB5_CONFIG if test -n "$KRB5_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KRB5_CONFIG" >&5 $as_echo "$KRB5_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working krb5-config" >&5 $as_echo_n "checking for working krb5-config... " >&6; } if test -x "$KRB5_CONFIG"; then KRB5_CFLAGS="`$KRB5_CONFIG --cflags`" KRB5_LIBS="`$KRB5_CONFIG --libs`" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if test x$KRB5_PASSED_LIBS = x; then as_fn_error $? "Please install MIT kerberos devel package" "$LINENO" 5 fi fi if test x$KRB5_PASSED_LIBS != x; then KRB5_LIBS=$KRB5_PASSED_LIBS fi if test x$KRB5_PASSED_CFLAGS != x; then KRB5_CFLAGS=$KRB5_PASSED_CFLAGS fi SAVE_CFLAGS=$CFLAGS SAVE_LIBS=$LIBS CFLAGS="$CFLAGS $KRB5_CFLAGS" LIBS="$LIBS $KRB5_LIBS" for ac_header in krb5.h krb5/krb5.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done ac_fn_c_check_type "$LINENO" "krb5_ticket_times" "ac_cv_type_krb5_ticket_times" " #ifdef HAVE_KRB5_KRB5_H #include #else #include #endif " if test "x$ac_cv_type_krb5_ticket_times" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_KRB5_TICKET_TIMES 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "krb5_times" "ac_cv_type_krb5_times" " #ifdef HAVE_KRB5_KRB5_H #include #else #include #endif " if test "x$ac_cv_type_krb5_times" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_KRB5_TIMES 1 _ACEOF fi ac_fn_c_check_type "$LINENO" "krb5_trace_info" "ac_cv_type_krb5_trace_info" " #ifdef HAVE_KRB5_KRB5_H #include #else #include #endif " if test "x$ac_cv_type_krb5_trace_info" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_KRB5_TRACE_INFO 1 _ACEOF fi for ac_func in krb5_get_init_creds_opt_alloc krb5_get_error_message \ krb5_free_unparsed_name \ krb5_get_init_creds_opt_set_expire_callback \ krb5_get_init_creds_opt_set_fast_ccache_name \ krb5_get_init_creds_opt_set_fast_flags \ krb5_get_init_creds_opt_set_canonicalize \ krb5_get_init_creds_opt_set_responder \ krb5_parse_name_flags \ krb5_unparse_name_flags \ krb5_get_init_creds_opt_set_change_password_prompt \ krb5_free_keytab_entry_contents \ krb5_kt_free_entry \ krb5_princ_realm \ krb5_get_time_offsets \ krb5_principal_get_realm \ krb5_cc_cache_match \ krb5_timestamp_to_sfstring \ krb5_set_trace_callback \ krb5_find_authdata \ krb5_kt_have_content \ krb5_cc_get_full_name do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done CFLAGS=$SAVE_CFLAGS LIBS=$SAVE_LIBS CFLAGS="$CFLAGS $KRB5_CFLAGS" LIBS="$LIBS $KRB5_LIBS" if test x$ac_cv_header_krb5_h != xyes -a x$ac_cv_header_krb5_krb5_h != xyes then as_fn_error $? "you must have Kerberos 5 header files to build sssd" "$LINENO" 5 fi # Check whether --enable-krb5-locator-plugin was given. if test "${enable_krb5_locator_plugin+set}" = set; then : enableval=$enable_krb5_locator_plugin; build_locator=$enableval else build_locator=yes fi ac_fn_c_check_header_compile "$LINENO" "krb5/locate_plugin.h" "ac_cv_header_krb5_locate_plugin_h" " #ifdef HAVE_KRB5_KRB5_H #include #else #include #endif " if test "x$ac_cv_header_krb5_locate_plugin_h" = xyes; then : have_locate_plugin=yes else have_locate_plugin=no { $as_echo "$as_me:${as_lineno-$LINENO}: Kerberos locator plugin cannot be built" >&5 $as_echo "$as_me: Kerberos locator plugin cannot be built" >&6;} fi if test x$have_locate_plugin = xyes -a x$build_locator = xyes; then BUILD_KRB5_LOCATOR_PLUGIN_TRUE= BUILD_KRB5_LOCATOR_PLUGIN_FALSE='#' else BUILD_KRB5_LOCATOR_PLUGIN_TRUE='#' BUILD_KRB5_LOCATOR_PLUGIN_FALSE= fi if test -z "$BUILD_KRB5_LOCATOR_PLUGIN_TRUE"; then : cat >>confdefs.h <<_ACEOF #define HAVE_KRB5_LOCATOR_PLUGIN 1 _ACEOF fi ac_fn_c_check_header_compile "$LINENO" "krb5/localauth_plugin.h" "ac_cv_header_krb5_localauth_plugin_h" " #ifdef HAVE_KRB5_KRB5_H #include #else #include #endif " if test "x$ac_cv_header_krb5_localauth_plugin_h" = xyes; then : have_localauth_plugin=yes else have_localauth_plugin=no { $as_echo "$as_me:${as_lineno-$LINENO}: Kerberos localauth plugin cannot be built" >&5 $as_echo "$as_me: Kerberos localauth plugin cannot be built" >&6;} fi if test x$have_localauth_plugin = xyes; then BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE= BUILD_KRB5_LOCALAUTH_PLUGIN_FALSE='#' else BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE='#' BUILD_KRB5_LOCALAUTH_PLUGIN_FALSE= fi if test -z "$BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE"; then : cat >>confdefs.h <<_ACEOF #define HAVE_KRB5_LOCALAUTH_PLUGIN 1 _ACEOF fi CFLAGS=$SAVE_CFLAGS LIBS=$SAVE_LIBS pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CARES" >&5 $as_echo_n "checking for CARES... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$CARES_CFLAGS"; then pkg_cv_CARES_CFLAGS="$CARES_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcares\""; } >&5 ($PKG_CONFIG --exists --print-errors "libcares") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CARES_CFLAGS=`$PKG_CONFIG --cflags "libcares" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$CARES_LIBS"; then pkg_cv_CARES_LIBS="$CARES_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcares\""; } >&5 ($PKG_CONFIG --exists --print-errors "libcares") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CARES_LIBS=`$PKG_CONFIG --libs "libcares" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then CARES_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libcares"` else CARES_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libcares"` fi # Put the nasty error message in config.log where it belongs echo "$CARES_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } found_libcares=no elif test $pkg_failed = untried; then found_libcares=no else CARES_CFLAGS=$pkg_cv_CARES_CFLAGS CARES_LIBS=$pkg_cv_CARES_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } found_libcares=yes fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" sss_extra_libdir="$additional_libdir" if test x"$found_libcares" != xyes; then : for ac_header in ares.h do : ac_fn_c_check_header_mongrel "$LINENO" "ares.h" "ac_cv_header_ares_h" "$ac_includes_default" if test "x$ac_cv_header_ares_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_ARES_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ares_init in -lcares" >&5 $as_echo_n "checking for ares_init in -lcares... " >&6; } if ${ac_cv_lib_cares_ares_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcares -L$sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ares_init (); int main () { return ares_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_cares_ares_init=yes else ac_cv_lib_cares_ares_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cares_ares_init" >&5 $as_echo "$ac_cv_lib_cares_ares_init" >&6; } if test "x$ac_cv_lib_cares_ares_init" = xyes; then : CARES_LIBS="-L$sss_extra_libdir -lcares" else as_fn_error $? "No usable c-ares library found" "$LINENO" 5 fi else as_fn_error $? "c-ares header files are not installed" "$LINENO" 5 fi done fi # Solaris needs HAVE_LONG_LONG defined ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default" if test "x$ac_cv_type_long_long" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LONG_LONG 1 _ACEOF fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 $as_echo_n "checking size of int... " >&6; } if ${ac_cv_sizeof_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : else if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 $as_echo "$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5 $as_echo_n "checking size of char... " >&6; } if ${ac_cv_sizeof_char+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default"; then : else if test "$ac_cv_type_char" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (char) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_char=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5 $as_echo "$ac_cv_sizeof_char" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_CHAR $ac_cv_sizeof_char _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 $as_echo_n "checking size of short... " >&6; } if ${ac_cv_sizeof_short+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : else if test "$ac_cv_type_short" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (short) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_short=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 $as_echo "$ac_cv_sizeof_short" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT $ac_cv_sizeof_short _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 $as_echo_n "checking size of long... " >&6; } if ${ac_cv_sizeof_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : else if test "$ac_cv_type_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 $as_echo "$ac_cv_sizeof_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 $as_echo_n "checking size of long long... " >&6; } if ${ac_cv_sizeof_long_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then : else if test "$ac_cv_type_long_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 $as_echo "$ac_cv_sizeof_long_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uid_t" >&5 $as_echo_n "checking size of uid_t... " >&6; } if ${ac_cv_sizeof_uid_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uid_t))" "ac_cv_sizeof_uid_t" "$ac_includes_default"; then : else if test "$ac_cv_type_uid_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (uid_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_uid_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uid_t" >&5 $as_echo "$ac_cv_sizeof_uid_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_UID_T $ac_cv_sizeof_uid_t _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of gid_t" >&5 $as_echo_n "checking size of gid_t... " >&6; } if ${ac_cv_sizeof_gid_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (gid_t))" "ac_cv_sizeof_gid_t" "$ac_includes_default"; then : else if test "$ac_cv_type_gid_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (gid_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_gid_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_gid_t" >&5 $as_echo "$ac_cv_sizeof_gid_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_GID_T $ac_cv_sizeof_gid_t _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of id_t" >&5 $as_echo_n "checking size of id_t... " >&6; } if ${ac_cv_sizeof_id_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (id_t))" "ac_cv_sizeof_id_t" "$ac_includes_default"; then : else if test "$ac_cv_type_id_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (id_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_id_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_id_t" >&5 $as_echo "$ac_cv_sizeof_id_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_ID_T $ac_cv_sizeof_id_t _ACEOF if test $ac_cv_sizeof_long_long -lt 8 ; then as_fn_error $? "SSSD requires long long of 64-bits" "$LINENO" 5 fi ac_fn_c_check_type "$LINENO" "uint_t" "ac_cv_type_uint_t" "$ac_includes_default" if test "x$ac_cv_type_uint_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uint_t unsigned int _ACEOF fi ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default" if test "x$ac_cv_type_int8_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define int8_t char _ACEOF fi ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default" if test "x$ac_cv_type_uint8_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uint8_t unsigned char _ACEOF fi ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default" if test "x$ac_cv_type_int16_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define int16_t short _ACEOF fi ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "$ac_includes_default" if test "x$ac_cv_type_uint16_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uint16_t unsigned short _ACEOF fi if test $ac_cv_sizeof_int -eq 4 ; then ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default" if test "x$ac_cv_type_int32_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define int32_t int _ACEOF fi ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default" if test "x$ac_cv_type_uint32_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uint32_t unsigned int _ACEOF fi elif test $ac_cv_size_long -eq 4 ; then ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default" if test "x$ac_cv_type_int32_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define int32_t long _ACEOF fi ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default" if test "x$ac_cv_type_uint32_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uint32_t unsigned long _ACEOF fi else as_fn_error $? "LIBREPLACE no 32-bit type found" "$LINENO" 5 fi ac_fn_c_check_type "$LINENO" "int64_t" "ac_cv_type_int64_t" "$ac_includes_default" if test "x$ac_cv_type_int64_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define int64_t long long _ACEOF fi ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "$ac_includes_default" if test "x$ac_cv_type_uint64_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uint64_t unsigned long long _ACEOF fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" if test "x$ac_cv_type_ssize_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define ssize_t int _ACEOF fi # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5 $as_echo_n "checking size of off_t... " >&6; } if ${ac_cv_sizeof_off_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t" "$ac_includes_default"; then : else if test "$ac_cv_type_off_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (off_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_off_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5 $as_echo "$ac_cv_sizeof_off_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_OFF_T $ac_cv_sizeof_off_t _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 $as_echo_n "checking size of size_t... " >&6; } if ${ac_cv_sizeof_size_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then : else if test "$ac_cv_type_size_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (size_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_size_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 $as_echo "$ac_cv_sizeof_size_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SIZE_T $ac_cv_sizeof_size_t _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of ssize_t" >&5 $as_echo_n "checking size of ssize_t... " >&6; } if ${ac_cv_sizeof_ssize_t+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (ssize_t))" "ac_cv_sizeof_ssize_t" "$ac_includes_default"; then : else if test "$ac_cv_type_ssize_t" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (ssize_t) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_ssize_t=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_ssize_t" >&5 $as_echo "$ac_cv_sizeof_ssize_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SSIZE_T $ac_cv_sizeof_ssize_t _ACEOF ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" if test "x$ac_cv_type_intptr_t" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INTPTR_T 1 _ACEOF else cat >>confdefs.h <<_ACEOF #define intptr_t long long _ACEOF fi ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" if test "x$ac_cv_type_uintptr_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define uintptr_t unsigned long long _ACEOF fi ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" if test "x$ac_cv_type_ptrdiff_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define ptrdiff_t unsigned long long _ACEOF fi # Extract the first word of "nscd", so it can be a program name with args. set dummy nscd; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_NSCD+:} false; then : $as_echo_n "(cached) " >&6 else case $NSCD in [\\/]* | ?:[\\/]*) ac_cv_path_NSCD="$NSCD" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_NSCD="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_NSCD" && ac_cv_path_NSCD="$NSCD_PATH" ;; esac fi NSCD=$ac_cv_path_NSCD if test -n "$NSCD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NSCD" >&5 $as_echo "$NSCD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nscd" >&5 $as_echo_n "checking for nscd... " >&6; } cat >>confdefs.h <<_ACEOF #define NSCD_PATH "$NSCD" _ACEOF if test -x "$NSCD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not installed, assuming standard location" >&5 $as_echo "not installed, assuming standard location" >&6; } fi # Extract the first word of "nsupdate", so it can be a program name with args. set dummy nsupdate; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_NSUPDATE+:} false; then : $as_echo_n "(cached) " >&6 else case $NSUPDATE in [\\/]* | ?:[\\/]*) ac_cv_path_NSUPDATE="$NSUPDATE" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_NSUPDATE="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi NSUPDATE=$ac_cv_path_NSUPDATE if test -n "$NSUPDATE"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NSUPDATE" >&5 $as_echo "$NSUPDATE" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for executable nsupdate" >&5 $as_echo_n "checking for executable nsupdate... " >&6; } if test -x "$NSUPDATE"; then cat >>confdefs.h <<_ACEOF #define NSUPDATE_PATH "$NSUPDATE" _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nsupdate 'realm' support'" >&5 $as_echo_n "checking for nsupdate 'realm' support'... " >&6; } if { { $as_echo "$as_me:${as_lineno-$LINENO}: echo realm |\$NSUPDATE >&2"; } >&5 (echo realm |$NSUPDATE >&2) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_NSUPDATE_REALM 1 _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Will build without the 'realm' directive" >&5 $as_echo "$as_me: WARNING: Will build without the 'realm' directive" >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "nsupdate is not available" "$LINENO" 5 fi for ac_header in keyutils.h do : ac_fn_c_check_header_mongrel "$LINENO" "keyutils.h" "ac_cv_header_keyutils_h" "$ac_includes_default" if test "x$ac_cv_header_keyutils_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_KEYUTILS_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for add_key in -lkeyutils" >&5 $as_echo_n "checking for add_key in -lkeyutils... " >&6; } if ${ac_cv_lib_keyutils_add_key+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lkeyutils $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char add_key (); int main () { return add_key (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_keyutils_add_key=yes else ac_cv_lib_keyutils_add_key=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_keyutils_add_key" >&5 $as_echo "$ac_cv_lib_keyutils_add_key" >&6; } if test "x$ac_cv_lib_keyutils_add_key" = xyes; then : $as_echo "#define USE_KEYRING 1" >>confdefs.h KEYUTILS_LIBS="-lkeyutils" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No usable keyutils library found" >&5 $as_echo "$as_me: WARNING: No usable keyutils library found" >&2;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: keyutils header files are not available" >&5 $as_echo "$as_me: WARNING: keyutils header files are not available" >&2;} fi done if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5 ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then HAVE_LIBSYSTEMD=yes else HAVE_LIBSYSTEMD=no fi if test x$HAVE_LIBSYSTEMD = xyes; then : login_lib_name=libsystemd else login_lib_name=libsystemd-login fi if test -z "$HAVE_SYSTEMD_TRUE"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD_LOGIN" >&5 $as_echo_n "checking for SYSTEMD_LOGIN... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$SYSTEMD_LOGIN_CFLAGS"; then pkg_cv_SYSTEMD_LOGIN_CFLAGS="$SYSTEMD_LOGIN_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$login_lib_name\""; } >&5 ($PKG_CONFIG --exists --print-errors "$login_lib_name") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SYSTEMD_LOGIN_CFLAGS=`$PKG_CONFIG --cflags "$login_lib_name" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$SYSTEMD_LOGIN_LIBS"; then pkg_cv_SYSTEMD_LOGIN_LIBS="$SYSTEMD_LOGIN_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$login_lib_name\""; } >&5 ($PKG_CONFIG --exists --print-errors "$login_lib_name") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SYSTEMD_LOGIN_LIBS=`$PKG_CONFIG --libs "$login_lib_name" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SYSTEMD_LOGIN_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$login_lib_name"` else SYSTEMD_LOGIN_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$login_lib_name"` fi # Put the nasty error message in config.log where it belongs echo "$SYSTEMD_LOGIN_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: Build without libsystemd-login support" >&5 $as_echo "$as_me: Build without libsystemd-login support" >&6;} elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: Build without libsystemd-login support" >&5 $as_echo "$as_me: Build without libsystemd-login support" >&6;} else SYSTEMD_LOGIN_CFLAGS=$pkg_cv_SYSTEMD_LOGIN_CFLAGS SYSTEMD_LOGIN_LIBS=$pkg_cv_SYSTEMD_LOGIN_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<_ACEOF #define HAVE_SYSTEMD_LOGIN 1 _ACEOF fi fi # Check whether --enable-pac-responder was given. if test "${enable_pac_responder+set}" = set; then : enableval=$enable_pac_responder; build_pac_responder=$enableval else build_pac_responder=yes fi ndr_krb5pac_ok=no krb5_version_ok=no if test x$build_pac_responder = xyes then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NDR_KRB5PAC" >&5 $as_echo_n "checking for NDR_KRB5PAC... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$NDR_KRB5PAC_CFLAGS"; then pkg_cv_NDR_KRB5PAC_CFLAGS="$NDR_KRB5PAC_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ndr_krb5pac\""; } >&5 ($PKG_CONFIG --exists --print-errors "ndr_krb5pac") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_NDR_KRB5PAC_CFLAGS=`$PKG_CONFIG --cflags "ndr_krb5pac" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$NDR_KRB5PAC_LIBS"; then pkg_cv_NDR_KRB5PAC_LIBS="$NDR_KRB5PAC_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ndr_krb5pac\""; } >&5 ($PKG_CONFIG --exists --print-errors "ndr_krb5pac") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_NDR_KRB5PAC_LIBS=`$PKG_CONFIG --libs "ndr_krb5pac" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then NDR_KRB5PAC_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "ndr_krb5pac"` else NDR_KRB5PAC_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "ndr_krb5pac"` fi # Put the nasty error message in config.log where it belongs echo "$NDR_KRB5PAC_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot build pac responder without libndr_krb5pac" >&5 $as_echo "$as_me: WARNING: Cannot build pac responder without libndr_krb5pac" >&2;} elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot build pac responder without libndr_krb5pac" >&5 $as_echo "$as_me: WARNING: Cannot build pac responder without libndr_krb5pac" >&2;} else NDR_KRB5PAC_CFLAGS=$pkg_cv_NDR_KRB5PAC_CFLAGS NDR_KRB5PAC_LIBS=$pkg_cv_NDR_KRB5PAC_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ndr_krb5pac_ok=yes fi # Extract the first word of "krb5-config", so it can be a program name with args. set dummy krb5-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_KRB5_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $KRB5_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_KRB5_CONFIG="$KRB5_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_KRB5_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi KRB5_CONFIG=$ac_cv_path_KRB5_CONFIG if test -n "$KRB5_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $KRB5_CONFIG" >&5 $as_echo "$KRB5_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for supported MIT krb5 version" >&5 $as_echo_n "checking for supported MIT krb5 version... " >&6; } KRB5_VERSION="`$KRB5_CONFIG --version`" case $KRB5_VERSION in Kerberos\ 5\ release\ 1.9* | \ Kerberos\ 5\ release\ 1.10* | \ Kerberos\ 5\ release\ 1.11* | \ Kerberos\ 5\ release\ 1.12* | \ Kerberos\ 5\ release\ 1.13* | \ Kerberos\ 5\ release\ 1.14*) krb5_version_ok=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot build authdata plugin with this version of MIT Kerberos, please use 1.9.x or later" >&5 $as_echo "$as_me: WARNING: Cannot build authdata plugin with this version of MIT Kerberos, please use 1.9.x or later" >&2;} esac fi if test x$build_pac_responder = xyes -a x$ndr_krb5pac_ok = xyes -a x$krb5_version_ok = xyes ; then BUILD_PAC_RESPONDER_TRUE= BUILD_PAC_RESPONDER_FALSE='#' else BUILD_PAC_RESPONDER_TRUE='#' BUILD_PAC_RESPONDER_FALSE= fi if test -z "$BUILD_PAC_RESPONDER_TRUE"; then : cat >>confdefs.h <<_ACEOF #define HAVE_PAC_RESPONDER 1 _ACEOF fi # Check whether --enable-cifs-idmap-plugin was given. if test "${enable_cifs_idmap_plugin+set}" = set; then : enableval=$enable_cifs_idmap_plugin; build_cifs_idmap_plugin=$enableval else build_cifs_idmap_plugin=yes fi if test x$build_cifs_idmap_plugin = xyes; then : ac_fn_c_check_header_mongrel "$LINENO" "cifsidmap.h" "ac_cv_header_cifsidmap_h" "$ac_includes_default" if test "x$ac_cv_header_cifsidmap_h" = xyes; then : else as_fn_error $? " You must have the cifsidmap header installed to build the idmap plugin. If you want to build sssd withoud cifsidmap plugin then specify --disable-cifs-idmap-plugin when running configure." "$LINENO" 5 fi fi if test x$build_cifs_idmap_plugin = xyes; then BUILD_CIFS_IDMAP_PLUGIN_TRUE= BUILD_CIFS_IDMAP_PLUGIN_FALSE='#' else BUILD_CIFS_IDMAP_PLUGIN_TRUE='#' BUILD_CIFS_IDMAP_PLUGIN_FALSE= fi if test -z "$BUILD_CIFS_IDMAP_PLUGIN_TRUE"; then : cat >>confdefs.h <<_ACEOF #define HAVE_CIFS_IDMAP_PLUGIN 1 _ACEOF fi for ac_func in sigprocmask sigblock sigaction getpgrp prctl do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test x"$with_samba" = xyes; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NDR_NBT" >&5 $as_echo_n "checking for NDR_NBT... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$NDR_NBT_CFLAGS"; then pkg_cv_NDR_NBT_CFLAGS="$NDR_NBT_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ndr_nbt\""; } >&5 ($PKG_CONFIG --exists --print-errors "ndr_nbt") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_NDR_NBT_CFLAGS=`$PKG_CONFIG --cflags "ndr_nbt" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$NDR_NBT_LIBS"; then pkg_cv_NDR_NBT_LIBS="$NDR_NBT_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ndr_nbt\""; } >&5 ($PKG_CONFIG --exists --print-errors "ndr_nbt") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_NDR_NBT_LIBS=`$PKG_CONFIG --libs "ndr_nbt" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then NDR_NBT_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "ndr_nbt"` else NDR_NBT_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "ndr_nbt"` fi # Put the nasty error message in config.log where it belongs echo "$NDR_NBT_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Please install Samba 4 development libraries. Samba 4 libraries are necessary for building ad and ipa provider. If you do not want to build these providers it is possible to build SSSD without them. In this case, you will need to execute configure script with argument --without-samba " "$LINENO" 5 elif test $pkg_failed = untried; then as_fn_error $? "Please install Samba 4 development libraries. Samba 4 libraries are necessary for building ad and ipa provider. If you do not want to build these providers it is possible to build SSSD without them. In this case, you will need to execute configure script with argument --without-samba " "$LINENO" 5 else NDR_NBT_CFLAGS=$pkg_cv_NDR_NBT_CFLAGS NDR_NBT_LIBS=$pkg_cv_NDR_NBT_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SMBCLIENT" >&5 $as_echo_n "checking for SMBCLIENT... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$SMBCLIENT_CFLAGS"; then pkg_cv_SMBCLIENT_CFLAGS="$SMBCLIENT_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"smbclient\""; } >&5 ($PKG_CONFIG --exists --print-errors "smbclient") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SMBCLIENT_CFLAGS=`$PKG_CONFIG --cflags "smbclient" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$SMBCLIENT_LIBS"; then pkg_cv_SMBCLIENT_LIBS="$SMBCLIENT_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"smbclient\""; } >&5 ($PKG_CONFIG --exists --print-errors "smbclient") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SMBCLIENT_LIBS=`$PKG_CONFIG --libs "smbclient" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SMBCLIENT_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "smbclient"` else SMBCLIENT_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "smbclient"` fi # Put the nasty error message in config.log where it belongs echo "$SMBCLIENT_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Please install libsmbclient development libraries. libsmbclient libraries are necessary for building ad and ipa provider. If you do not want to build these providers it is possible to build SSSD without them. In this case, you will need to execute configure script with argument --without-samba " "$LINENO" 5 elif test $pkg_failed = untried; then as_fn_error $? "Please install libsmbclient development libraries. libsmbclient libraries are necessary for building ad and ipa provider. If you do not want to build these providers it is possible to build SSSD without them. In this case, you will need to execute configure script with argument --without-samba " "$LINENO" 5 else SMBCLIENT_CFLAGS=$pkg_cv_SMBCLIENT_CFLAGS SMBCLIENT_LIBS=$pkg_cv_SMBCLIENT_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi if test x"$HAVE_LIBINI_CONFIG_V1_1" != x1; then as_fn_error $? "Please install libini_config development libraries v1.1.0, or newer. libini_config libraries are necessary for building ipa provider, as well as for building gpo-based access control in ad provider. If you do not want to build these providers it is possible to build SSSD without them. In this case, you will need to execute configure script with argument --without-samba " "$LINENO" 5 fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SASL" >&5 $as_echo_n "checking for SASL... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$SASL_CFLAGS"; then pkg_cv_SASL_CFLAGS="$SASL_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsasl2\""; } >&5 ($PKG_CONFIG --exists --print-errors "libsasl2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SASL_CFLAGS=`$PKG_CONFIG --cflags "libsasl2" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$SASL_LIBS"; then pkg_cv_SASL_LIBS="$SASL_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsasl2\""; } >&5 ($PKG_CONFIG --exists --print-errors "libsasl2") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SASL_LIBS=`$PKG_CONFIG --libs "libsasl2" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SASL_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libsasl2"` else SASL_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libsasl2"` fi # Put the nasty error message in config.log where it belongs echo "$SASL_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } found_sasl=no elif test $pkg_failed = untried; then found_sasl=no else SASL_CFLAGS=$pkg_cv_SASL_CFLAGS SASL_LIBS=$pkg_cv_SASL_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } found_sasl=yes fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" sss_extra_libdir="$additional_libdir" if test x"$found_sasl" != xyes; then : for ac_header in sasl/sasl.h do : ac_fn_c_check_header_mongrel "$LINENO" "sasl/sasl.h" "ac_cv_header_sasl_sasl_h" "$ac_includes_default" if test "x$ac_cv_header_sasl_sasl_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SASL_SASL_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sasl_client_init in -lsasl2" >&5 $as_echo_n "checking for sasl_client_init in -lsasl2... " >&6; } if ${ac_cv_lib_sasl2_sasl_client_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsasl2 -L$sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sasl_client_init (); int main () { return sasl_client_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_sasl2_sasl_client_init=yes else ac_cv_lib_sasl2_sasl_client_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sasl2_sasl_client_init" >&5 $as_echo "$ac_cv_lib_sasl2_sasl_client_init" >&6; } if test "x$ac_cv_lib_sasl2_sasl_client_init" = xyes; then : SASL_LIBS="-L$sss_extra_libdir -lsasl2" else as_fn_error $? "SASL library must support sasl_client_init" "$LINENO" 5 fi else as_fn_error $? "SASL header files are not installed" "$LINENO" 5 fi done fi # Check whether --enable-config-lib was given. if test "${enable_config_lib+set}" = set; then : enableval=$enable_config_lib; build_config_lib=$enableval else build_config_lib=yes fi if test x$build_config_lib = xyes; then BUILD_CONFIG_LIB_TRUE= BUILD_CONFIG_LIB_FALSE='#' else BUILD_CONFIG_LIB_TRUE='#' BUILD_CONFIG_LIB_FALSE= fi if test -z "$BUILD_CONFIG_LIB_TRUE"; then : cat >>confdefs.h <<_ACEOF #define HAVE_CONFIG_LIB 1 _ACEOF fi if test x"$with_nfsv4_idmap" = xyes; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NFSIDMAP" >&5 $as_echo_n "checking for NFSIDMAP... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$NFSIDMAP_CFLAGS"; then pkg_cv_NFSIDMAP_CFLAGS="$NFSIDMAP_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnfsidmap\""; } >&5 ($PKG_CONFIG --exists --print-errors "libnfsidmap") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_NFSIDMAP_CFLAGS=`$PKG_CONFIG --cflags "libnfsidmap" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$NFSIDMAP_LIBS"; then pkg_cv_NFSIDMAP_LIBS="$NFSIDMAP_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnfsidmap\""; } >&5 ($PKG_CONFIG --exists --print-errors "libnfsidmap") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_NFSIDMAP_LIBS=`$PKG_CONFIG --libs "libnfsidmap" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then NFSIDMAP_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libnfsidmap"` else NFSIDMAP_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libnfsidmap"` fi # Put the nasty error message in config.log where it belongs echo "$NFSIDMAP_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } found_nfsidmap=no elif test $pkg_failed = untried; then found_nfsidmap=no else NFSIDMAP_CFLAGS=$pkg_cv_NFSIDMAP_CFLAGS NFSIDMAP_LIBS=$pkg_cv_NFSIDMAP_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } found_nfsidmap=yes fi acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" sss_extra_libdir="$additional_libdir" if test x"$found_nfsidmap" != xyes; then : ac_fn_c_check_header_mongrel "$LINENO" "nfsidmap.h" "ac_cv_header_nfsidmap_h" "$ac_includes_default" if test "x$ac_cv_header_nfsidmap_h" = xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nfs4_init_name_mapping in -lnfsidmap" >&5 $as_echo_n "checking for nfs4_init_name_mapping in -lnfsidmap... " >&6; } if ${ac_cv_lib_nfsidmap_nfs4_init_name_mapping+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnfsidmap -L$sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nfs4_init_name_mapping (); int main () { return nfs4_init_name_mapping (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nfsidmap_nfs4_init_name_mapping=yes else ac_cv_lib_nfsidmap_nfs4_init_name_mapping=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nfsidmap_nfs4_init_name_mapping" >&5 $as_echo "$ac_cv_lib_nfsidmap_nfs4_init_name_mapping" >&6; } if test "x$ac_cv_lib_nfsidmap_nfs4_init_name_mapping" = xyes; then : NFSIDMAP_LIBS="-L$sss_extra_libdir -lnfsidmap" else as_fn_error $? "libnfsidmap missing nfs4_init_name_mapping" "$LINENO" 5 fi else as_fn_error $? "libnfsidmap header files are not installed If you want to build sssd without nfs idmap pluging then specify --without-nfsv4-idmapd-plugin when running configure." "$LINENO" 5 fi fi fi # Some unit tests require libresolv to fake DNS packets acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" sss_extra_libdir="$additional_libdir" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ns_name_compress in -lresolv" >&5 $as_echo_n "checking for ns_name_compress in -lresolv... " >&6; } if ${ac_cv_lib_resolv_ns_name_compress+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv -L$sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ns_name_compress (); int main () { return ns_name_compress (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_resolv_ns_name_compress=yes else ac_cv_lib_resolv_ns_name_compress=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_ns_name_compress" >&5 $as_echo "$ac_cv_lib_resolv_ns_name_compress" >&6; } if test "x$ac_cv_lib_resolv_ns_name_compress" = xyes; then : RESOLV_LIBS="-L$sss_extra_libdir -lresolv" else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No libresolv detected, some tests will not run" >&5 $as_echo "$as_me: WARNING: No libresolv detected, some tests will not run" >&2;} fi if test x"$RESOLV_LIBS" != "x"; then HAVE_LIBRESOLV_TRUE= HAVE_LIBRESOLV_FALSE='#' else HAVE_LIBRESOLV_TRUE='#' HAVE_LIBRESOLV_FALSE= fi # Extract the first word of "fakeroot", so it can be a program name with args. set dummy fakeroot; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_FAKEROOT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_FAKEROOT"; then ac_cv_prog_HAVE_FAKEROOT="$HAVE_FAKEROOT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_FAKEROOT="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_HAVE_FAKEROOT" && ac_cv_prog_HAVE_FAKEROOT="no" fi fi HAVE_FAKEROOT=$ac_cv_prog_HAVE_FAKEROOT if test -n "$HAVE_FAKEROOT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_FAKEROOT" >&5 $as_echo "$HAVE_FAKEROOT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "py.test", so it can be a program name with args. set dummy py.test; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTEST+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTEST in [\\/]* | ?:[\\/]*) ac_cv_path_PYTEST="$PYTEST" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTEST="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTEST=$ac_cv_path_PYTEST if test -n "$PYTEST"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTEST" >&5 $as_echo "$PYTEST" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -n "$PYTEST"; then : HAVE_PYTEST=yes else HAVE_PYTEST=no fi if test x$build_config_lib = xyes; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AUGEAS" >&5 $as_echo_n "checking for AUGEAS... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$AUGEAS_CFLAGS"; then pkg_cv_AUGEAS_CFLAGS="$AUGEAS_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"augeas >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "augeas >= 1.0.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_AUGEAS_CFLAGS=`$PKG_CONFIG --cflags "augeas >= 1.0.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$AUGEAS_LIBS"; then pkg_cv_AUGEAS_LIBS="$AUGEAS_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"augeas >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "augeas >= 1.0.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_AUGEAS_LIBS=`$PKG_CONFIG --libs "augeas >= 1.0.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then AUGEAS_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "augeas >= 1.0.0"` else AUGEAS_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "augeas >= 1.0.0"` fi # Put the nasty error message in config.log where it belongs echo "$AUGEAS_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? " Please install augeas-devel or disable this dependency by specifying --disable-config-lib when running configure." "$LINENO" 5 elif test $pkg_failed = untried; then as_fn_error $? " Please install augeas-devel or disable this dependency by specifying --disable-config-lib when running configure." "$LINENO" 5 else AUGEAS_CFLAGS=$pkg_cv_AUGEAS_CFLAGS AUGEAS_LIBS=$pkg_cv_AUGEAS_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi fi # Check whether --with-unicode-lib was given. if test "${with_unicode_lib+set}" = set; then : withval=$with_unicode_lib; fi unicode_lib="glib2" if test x"$with_unicode_lib" != x; then unicode_lib=$with_unicode_lib fi if test x"$unicode_lib" != x"libunistring" -a x"$unicode_lib" != x"glib2"; then as_fn_error $? "Unsupported unicode library" "$LINENO" 5 fi if test x"$unicode_lib" = x"libunistring"; then WITH_LIBUNISTRING_TRUE= WITH_LIBUNISTRING_FALSE='#' else WITH_LIBUNISTRING_TRUE='#' WITH_LIBUNISTRING_FALSE= fi if test x"$unicode_lib" = x"glib2"; then WITH_GLIB_TRUE= WITH_GLIB_FALSE='#' else WITH_GLIB_TRUE='#' WITH_GLIB_FALSE= fi if test x$unicode_lib = xlibunistring; then acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" sss_extra_libdir="$additional_libdir" for ac_header in unistr.h do : ac_fn_c_check_header_mongrel "$LINENO" "unistr.h" "ac_cv_header_unistr_h" "$ac_includes_default" if test "x$ac_cv_header_unistr_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNISTR_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u8_strlen in -lunistring" >&5 $as_echo_n "checking for u8_strlen in -lunistring... " >&6; } if ${ac_cv_lib_unistring_u8_strlen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lunistring -L$sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char u8_strlen (); int main () { return u8_strlen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_unistring_u8_strlen=yes else ac_cv_lib_unistring_u8_strlen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_unistring_u8_strlen" >&5 $as_echo "$ac_cv_lib_unistring_u8_strlen" >&6; } if test "x$ac_cv_lib_unistring_u8_strlen" = xyes; then : UNISTRING_LIBS="-lunistring" else as_fn_error $? "No usable libunistring library found" "$LINENO" 5 fi else as_fn_error $? "libunistring header files are not installed" "$LINENO" 5 fi done for ac_header in unicase.h do : ac_fn_c_check_header_mongrel "$LINENO" "unicase.h" "ac_cv_header_unicase_h" "$ac_includes_default" if test "x$ac_cv_header_unicase_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNICASE_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u8_casecmp in -lunistring" >&5 $as_echo_n "checking for u8_casecmp in -lunistring... " >&6; } if ${ac_cv_lib_unistring_u8_casecmp+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lunistring -L$sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char u8_casecmp (); int main () { return u8_casecmp (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_unistring_u8_casecmp=yes else ac_cv_lib_unistring_u8_casecmp=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_unistring_u8_casecmp" >&5 $as_echo "$ac_cv_lib_unistring_u8_casecmp" >&6; } if test "x$ac_cv_lib_unistring_u8_casecmp" = xyes; then : UNISTRING_LIBS="-lunistring" else as_fn_error $? "No usable libunistring library found" "$LINENO" 5 fi else as_fn_error $? "libunistring header files are not installed" "$LINENO" 5 fi done for ac_header in unistr.h do : ac_fn_c_check_header_mongrel "$LINENO" "unistr.h" "ac_cv_header_unistr_h" "$ac_includes_default" if test "x$ac_cv_header_unistr_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_UNISTR_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u8_check in -lunistring" >&5 $as_echo_n "checking for u8_check in -lunistring... " >&6; } if ${ac_cv_lib_unistring_u8_check+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lunistring -L$sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char u8_check (); int main () { return u8_check (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_unistring_u8_check=yes else ac_cv_lib_unistring_u8_check=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_unistring_u8_check" >&5 $as_echo "$ac_cv_lib_unistring_u8_check" >&6; } if test "x$ac_cv_lib_unistring_u8_check" = xyes; then : UNISTRING_LIBS="-lunistring" else as_fn_error $? "No usable libunistring library found" "$LINENO" 5 fi else as_fn_error $? "libunistring header files are not installed" "$LINENO" 5 fi done UNISTRING_LIBS="-L$sss_extra_libdir $UNISTRING_LIBS " cat >>confdefs.h <<_ACEOF #define HAVE_LIBUNISTRING 1 _ACEOF UNICODE_LIBS=$UNISTRING_LIBS else pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLIB2" >&5 $as_echo_n "checking for GLIB2... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$GLIB2_CFLAGS"; then pkg_cv_GLIB2_CFLAGS="$GLIB2_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "glib-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GLIB2_CFLAGS=`$PKG_CONFIG --cflags "glib-2.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$GLIB2_LIBS"; then pkg_cv_GLIB2_LIBS="$GLIB2_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"glib-2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "glib-2.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GLIB2_LIBS=`$PKG_CONFIG --libs "glib-2.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GLIB2_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "glib-2.0"` else GLIB2_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "glib-2.0"` fi # Put the nasty error message in config.log where it belongs echo "$GLIB2_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (glib-2.0) were not met: $GLIB2_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GLIB2_CFLAGS and GLIB2_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " "$LINENO" 5 elif test $pkg_failed = untried; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GLIB2_CFLAGS and GLIB2_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else GLIB2_CFLAGS=$pkg_cv_GLIB2_CFLAGS GLIB2_LIBS=$pkg_cv_GLIB2_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi if test x$has_glib2 != xno; then SAFE_LIBS="$LIBS" LIBS="$GLIB2_LIBS" ac_fn_c_check_func "$LINENO" "g_utf8_validate" "ac_cv_func_g_utf8_validate" if test "x$ac_cv_func_g_utf8_validate" = xyes; then : $as_echo "#define HAVE_G_UTF8_VALIDATE 1" >>confdefs.h fi LIBS="$SAFE_LIBS" fi cat >>confdefs.h <<_ACEOF #define HAVE_GLIB2 1 _ACEOF UNICODE_LIBS=$GLIB2_LIBS fi # Check whether --with-libnl was given. if test "${with_libnl+set}" = set; then : withval=$with_libnl; else with_libnl=yes fi if test x"$with_libnl" = xyes; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNL3" >&5 $as_echo_n "checking for LIBNL3... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$LIBNL3_CFLAGS"; then pkg_cv_LIBNL3_CFLAGS="$LIBNL3_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0\""; } >&5 ($PKG_CONFIG --exists --print-errors " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBNL3_CFLAGS=`$PKG_CONFIG --cflags " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$LIBNL3_LIBS"; then pkg_cv_LIBNL3_LIBS="$LIBNL3_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0\""; } >&5 ($PKG_CONFIG --exists --print-errors " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBNL3_LIBS=`$PKG_CONFIG --libs " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then LIBNL3_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0"` else LIBNL3_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0"` fi # Put the nasty error message in config.log where it belongs echo "$LIBNL3_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Netlink v3 support unavailable or too old" >&5 $as_echo "$as_me: WARNING: Netlink v3 support unavailable or too old" >&2;} elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Netlink v3 support unavailable or too old" >&5 $as_echo "$as_me: WARNING: Netlink v3 support unavailable or too old" >&2;} else LIBNL3_CFLAGS=$pkg_cv_LIBNL3_CFLAGS LIBNL3_LIBS=$pkg_cv_LIBNL3_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } HAVE_LIBNL=1 HAVE_LIBNL3=1 LIBNL_CFLAGS="$LIBNL3_CFLAGS" LIBNL_LIBS="$LIBNL3_LIBS" cat >>confdefs.h <<_ACEOF #define HAVE_LIBNL 1 _ACEOF cat >>confdefs.h <<_ACEOF #define HAVE_LIBNL3 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: Building with libnl3" >&5 $as_echo "$as_me: Building with libnl3" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_add_membership in -lnl-3" >&5 $as_echo_n "checking for nl_socket_add_membership in -lnl-3... " >&6; } if ${ac_cv_lib_nl_3_nl_socket_add_membership+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl-3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_add_membership (); int main () { return nl_socket_add_membership (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_3_nl_socket_add_membership=yes else ac_cv_lib_nl_3_nl_socket_add_membership=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_nl_socket_add_membership" >&5 $as_echo "$ac_cv_lib_nl_3_nl_socket_add_membership" >&6; } if test "x$ac_cv_lib_nl_3_nl_socket_add_membership" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_ADD_MEMBERSHIP 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_modify_cb in -lnl-3" >&5 $as_echo_n "checking for nl_socket_modify_cb in -lnl-3... " >&6; } if ${ac_cv_lib_nl_3_nl_socket_modify_cb+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl-3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_modify_cb (); int main () { return nl_socket_modify_cb (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_3_nl_socket_modify_cb=yes else ac_cv_lib_nl_3_nl_socket_modify_cb=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_nl_socket_modify_cb" >&5 $as_echo "$ac_cv_lib_nl_3_nl_socket_modify_cb" >&6; } if test "x$ac_cv_lib_nl_3_nl_socket_modify_cb" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_MODIFY_CB 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rtnl_route_get_oif in -lnl-3" >&5 $as_echo_n "checking for rtnl_route_get_oif in -lnl-3... " >&6; } if ${ac_cv_lib_nl_3_rtnl_route_get_oif+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl-3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char rtnl_route_get_oif (); int main () { return rtnl_route_get_oif (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_3_rtnl_route_get_oif=yes else ac_cv_lib_nl_3_rtnl_route_get_oif=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_rtnl_route_get_oif" >&5 $as_echo "$ac_cv_lib_nl_3_rtnl_route_get_oif" >&6; } if test "x$ac_cv_lib_nl_3_rtnl_route_get_oif" = xyes; then : $as_echo "#define HAVE_RTNL_ROUTE_GET_OIF 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_set_passcred in -lnl-3" >&5 $as_echo_n "checking for nl_set_passcred in -lnl-3... " >&6; } if ${ac_cv_lib_nl_3_nl_set_passcred+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl-3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_set_passcred (); int main () { return nl_set_passcred (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_3_nl_set_passcred=yes else ac_cv_lib_nl_3_nl_set_passcred=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_nl_set_passcred" >&5 $as_echo "$ac_cv_lib_nl_3_nl_set_passcred" >&6; } if test "x$ac_cv_lib_nl_3_nl_set_passcred" = xyes; then : $as_echo "#define HAVE_NL_SET_PASSCRED 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_set_passcred in -lnl-3" >&5 $as_echo_n "checking for nl_socket_set_passcred in -lnl-3... " >&6; } if ${ac_cv_lib_nl_3_nl_socket_set_passcred+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl-3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_set_passcred (); int main () { return nl_socket_set_passcred (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_3_nl_socket_set_passcred=yes else ac_cv_lib_nl_3_nl_socket_set_passcred=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_nl_socket_set_passcred" >&5 $as_echo "$ac_cv_lib_nl_3_nl_socket_set_passcred" >&6; } if test "x$ac_cv_lib_nl_3_nl_socket_set_passcred" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_SET_PASSCRED 1" >>confdefs.h fi fi if test x"$HAVE_LIBNL" != x1; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNL1" >&5 $as_echo_n "checking for LIBNL1... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$LIBNL1_CFLAGS"; then pkg_cv_LIBNL1_CFLAGS="$LIBNL1_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-1 >= 1.1\""; } >&5 ($PKG_CONFIG --exists --print-errors "libnl-1 >= 1.1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBNL1_CFLAGS=`$PKG_CONFIG --cflags "libnl-1 >= 1.1" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$LIBNL1_LIBS"; then pkg_cv_LIBNL1_LIBS="$LIBNL1_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-1 >= 1.1\""; } >&5 ($PKG_CONFIG --exists --print-errors "libnl-1 >= 1.1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBNL1_LIBS=`$PKG_CONFIG --libs "libnl-1 >= 1.1" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then LIBNL1_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libnl-1 >= 1.1"` else LIBNL1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libnl-1 >= 1.1"` fi # Put the nasty error message in config.log where it belongs echo "$LIBNL1_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Netlink v1 support unavailable or too old" >&5 $as_echo "$as_me: WARNING: Netlink v1 support unavailable or too old" >&2;} elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Netlink v1 support unavailable or too old" >&5 $as_echo "$as_me: WARNING: Netlink v1 support unavailable or too old" >&2;} else LIBNL1_CFLAGS=$pkg_cv_LIBNL1_CFLAGS LIBNL1_LIBS=$pkg_cv_LIBNL1_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } HAVE_LIBNL=1 HAVE_LIBNL1=1 LIBNL_CFLAGS="$LIBNL1_CFLAGS" LIBNL_LIBS="$LIBNL1_LIBS" cat >>confdefs.h <<_ACEOF #define HAVE_LIBNL 1 _ACEOF cat >>confdefs.h <<_ACEOF #define HAVE_LIBNL1 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: Building with libnl" >&5 $as_echo "$as_me: Building with libnl" >&6;} for ac_header in netlink.h do : ac_fn_c_check_header_mongrel "$LINENO" "netlink.h" "ac_cv_header_netlink_h" "$ac_includes_default" if test "x$ac_cv_header_netlink_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NETLINK_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_connect in -lnl" >&5 $as_echo_n "checking for nl_connect in -lnl... " >&6; } if ${ac_cv_lib_nl_nl_connect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_connect (); int main () { return nl_connect (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_nl_connect=yes else ac_cv_lib_nl_nl_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_nl_connect" >&5 $as_echo "$ac_cv_lib_nl_nl_connect" >&6; } if test "x$ac_cv_lib_nl_nl_connect" = xyes; then : LIBNL_LIBS="-lnl" else as_fn_error $? "libnl is required" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_add_membership in -lnl" >&5 $as_echo_n "checking for nl_socket_add_membership in -lnl... " >&6; } if ${ac_cv_lib_nl_nl_socket_add_membership+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_add_membership (); int main () { return nl_socket_add_membership (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_nl_socket_add_membership=yes else ac_cv_lib_nl_nl_socket_add_membership=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_nl_socket_add_membership" >&5 $as_echo "$ac_cv_lib_nl_nl_socket_add_membership" >&6; } if test "x$ac_cv_lib_nl_nl_socket_add_membership" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_ADD_MEMBERSHIP 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_modify_cb in -lnl" >&5 $as_echo_n "checking for nl_socket_modify_cb in -lnl... " >&6; } if ${ac_cv_lib_nl_nl_socket_modify_cb+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_modify_cb (); int main () { return nl_socket_modify_cb (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_nl_socket_modify_cb=yes else ac_cv_lib_nl_nl_socket_modify_cb=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_nl_socket_modify_cb" >&5 $as_echo "$ac_cv_lib_nl_nl_socket_modify_cb" >&6; } if test "x$ac_cv_lib_nl_nl_socket_modify_cb" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_MODIFY_CB 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rtnl_route_get_oif in -lnl" >&5 $as_echo_n "checking for rtnl_route_get_oif in -lnl... " >&6; } if ${ac_cv_lib_nl_rtnl_route_get_oif+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char rtnl_route_get_oif (); int main () { return rtnl_route_get_oif (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_rtnl_route_get_oif=yes else ac_cv_lib_nl_rtnl_route_get_oif=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_rtnl_route_get_oif" >&5 $as_echo "$ac_cv_lib_nl_rtnl_route_get_oif" >&6; } if test "x$ac_cv_lib_nl_rtnl_route_get_oif" = xyes; then : $as_echo "#define HAVE_RTNL_ROUTE_GET_OIF 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_set_passcred in -lnl" >&5 $as_echo_n "checking for nl_set_passcred in -lnl... " >&6; } if ${ac_cv_lib_nl_nl_set_passcred+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_set_passcred (); int main () { return nl_set_passcred (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_nl_set_passcred=yes else ac_cv_lib_nl_nl_set_passcred=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_nl_set_passcred" >&5 $as_echo "$ac_cv_lib_nl_nl_set_passcred" >&6; } if test "x$ac_cv_lib_nl_nl_set_passcred" = xyes; then : $as_echo "#define HAVE_NL_SET_PASSCRED 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_set_passcred in -lnl" >&5 $as_echo_n "checking for nl_socket_set_passcred in -lnl... " >&6; } if ${ac_cv_lib_nl_nl_socket_set_passcred+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_set_passcred (); int main () { return nl_socket_set_passcred (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_nl_socket_set_passcred=yes else ac_cv_lib_nl_nl_socket_set_passcred=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_nl_socket_set_passcred" >&5 $as_echo "$ac_cv_lib_nl_nl_socket_set_passcred" >&6; } if test "x$ac_cv_lib_nl_nl_socket_set_passcred" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_SET_PASSCRED 1" >>confdefs.h fi fi fi if test x"$HAVE_LIBNL" != x1; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Building without netlink" >&5 $as_echo "$as_me: WARNING: Building without netlink" >&2;} fi elif test x"$with_libnl" = xlibnl3; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNL3" >&5 $as_echo_n "checking for LIBNL3... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$LIBNL3_CFLAGS"; then pkg_cv_LIBNL3_CFLAGS="$LIBNL3_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0\""; } >&5 ($PKG_CONFIG --exists --print-errors " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBNL3_CFLAGS=`$PKG_CONFIG --cflags " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$LIBNL3_LIBS"; then pkg_cv_LIBNL3_LIBS="$LIBNL3_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0\""; } >&5 ($PKG_CONFIG --exists --print-errors " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBNL3_LIBS=`$PKG_CONFIG --libs " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then LIBNL3_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0"` else LIBNL3_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors " libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0"` fi # Put the nasty error message in config.log where it belongs echo "$LIBNL3_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Netlink v3 support unavailable or too old" >&5 $as_echo "$as_me: WARNING: Netlink v3 support unavailable or too old" >&2;} elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Netlink v3 support unavailable or too old" >&5 $as_echo "$as_me: WARNING: Netlink v3 support unavailable or too old" >&2;} else LIBNL3_CFLAGS=$pkg_cv_LIBNL3_CFLAGS LIBNL3_LIBS=$pkg_cv_LIBNL3_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } HAVE_LIBNL=1 HAVE_LIBNL3=1 LIBNL_CFLAGS="$LIBNL3_CFLAGS" LIBNL_LIBS="$LIBNL3_LIBS" cat >>confdefs.h <<_ACEOF #define HAVE_LIBNL 1 _ACEOF cat >>confdefs.h <<_ACEOF #define HAVE_LIBNL3 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: Building with libnl3" >&5 $as_echo "$as_me: Building with libnl3" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_add_membership in -lnl-3" >&5 $as_echo_n "checking for nl_socket_add_membership in -lnl-3... " >&6; } if ${ac_cv_lib_nl_3_nl_socket_add_membership+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl-3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_add_membership (); int main () { return nl_socket_add_membership (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_3_nl_socket_add_membership=yes else ac_cv_lib_nl_3_nl_socket_add_membership=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_nl_socket_add_membership" >&5 $as_echo "$ac_cv_lib_nl_3_nl_socket_add_membership" >&6; } if test "x$ac_cv_lib_nl_3_nl_socket_add_membership" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_ADD_MEMBERSHIP 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_modify_cb in -lnl-3" >&5 $as_echo_n "checking for nl_socket_modify_cb in -lnl-3... " >&6; } if ${ac_cv_lib_nl_3_nl_socket_modify_cb+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl-3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_modify_cb (); int main () { return nl_socket_modify_cb (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_3_nl_socket_modify_cb=yes else ac_cv_lib_nl_3_nl_socket_modify_cb=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_nl_socket_modify_cb" >&5 $as_echo "$ac_cv_lib_nl_3_nl_socket_modify_cb" >&6; } if test "x$ac_cv_lib_nl_3_nl_socket_modify_cb" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_MODIFY_CB 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rtnl_route_get_oif in -lnl-3" >&5 $as_echo_n "checking for rtnl_route_get_oif in -lnl-3... " >&6; } if ${ac_cv_lib_nl_3_rtnl_route_get_oif+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl-3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char rtnl_route_get_oif (); int main () { return rtnl_route_get_oif (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_3_rtnl_route_get_oif=yes else ac_cv_lib_nl_3_rtnl_route_get_oif=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_rtnl_route_get_oif" >&5 $as_echo "$ac_cv_lib_nl_3_rtnl_route_get_oif" >&6; } if test "x$ac_cv_lib_nl_3_rtnl_route_get_oif" = xyes; then : $as_echo "#define HAVE_RTNL_ROUTE_GET_OIF 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_set_passcred in -lnl-3" >&5 $as_echo_n "checking for nl_set_passcred in -lnl-3... " >&6; } if ${ac_cv_lib_nl_3_nl_set_passcred+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl-3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_set_passcred (); int main () { return nl_set_passcred (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_3_nl_set_passcred=yes else ac_cv_lib_nl_3_nl_set_passcred=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_nl_set_passcred" >&5 $as_echo "$ac_cv_lib_nl_3_nl_set_passcred" >&6; } if test "x$ac_cv_lib_nl_3_nl_set_passcred" = xyes; then : $as_echo "#define HAVE_NL_SET_PASSCRED 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_set_passcred in -lnl-3" >&5 $as_echo_n "checking for nl_socket_set_passcred in -lnl-3... " >&6; } if ${ac_cv_lib_nl_3_nl_socket_set_passcred+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl-3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_set_passcred (); int main () { return nl_socket_set_passcred (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_3_nl_socket_set_passcred=yes else ac_cv_lib_nl_3_nl_socket_set_passcred=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_3_nl_socket_set_passcred" >&5 $as_echo "$ac_cv_lib_nl_3_nl_socket_set_passcred" >&6; } if test "x$ac_cv_lib_nl_3_nl_socket_set_passcred" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_SET_PASSCRED 1" >>confdefs.h fi fi if test x"$HAVE_LIBNL" != x1; then as_fn_error $? "Libnl3 required, but not available" "$LINENO" 5 fi elif test x"$with_libnl" = xlibnl1; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNL1" >&5 $as_echo_n "checking for LIBNL1... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$LIBNL1_CFLAGS"; then pkg_cv_LIBNL1_CFLAGS="$LIBNL1_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-1 >= 1.1\""; } >&5 ($PKG_CONFIG --exists --print-errors "libnl-1 >= 1.1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBNL1_CFLAGS=`$PKG_CONFIG --cflags "libnl-1 >= 1.1" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$LIBNL1_LIBS"; then pkg_cv_LIBNL1_LIBS="$LIBNL1_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-1 >= 1.1\""; } >&5 ($PKG_CONFIG --exists --print-errors "libnl-1 >= 1.1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBNL1_LIBS=`$PKG_CONFIG --libs "libnl-1 >= 1.1" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then LIBNL1_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libnl-1 >= 1.1"` else LIBNL1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libnl-1 >= 1.1"` fi # Put the nasty error message in config.log where it belongs echo "$LIBNL1_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Netlink v1 support unavailable or too old" >&5 $as_echo "$as_me: WARNING: Netlink v1 support unavailable or too old" >&2;} elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Netlink v1 support unavailable or too old" >&5 $as_echo "$as_me: WARNING: Netlink v1 support unavailable or too old" >&2;} else LIBNL1_CFLAGS=$pkg_cv_LIBNL1_CFLAGS LIBNL1_LIBS=$pkg_cv_LIBNL1_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } HAVE_LIBNL=1 HAVE_LIBNL1=1 LIBNL_CFLAGS="$LIBNL1_CFLAGS" LIBNL_LIBS="$LIBNL1_LIBS" cat >>confdefs.h <<_ACEOF #define HAVE_LIBNL 1 _ACEOF cat >>confdefs.h <<_ACEOF #define HAVE_LIBNL1 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: Building with libnl" >&5 $as_echo "$as_me: Building with libnl" >&6;} for ac_header in netlink.h do : ac_fn_c_check_header_mongrel "$LINENO" "netlink.h" "ac_cv_header_netlink_h" "$ac_includes_default" if test "x$ac_cv_header_netlink_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NETLINK_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_connect in -lnl" >&5 $as_echo_n "checking for nl_connect in -lnl... " >&6; } if ${ac_cv_lib_nl_nl_connect+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_connect (); int main () { return nl_connect (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_nl_connect=yes else ac_cv_lib_nl_nl_connect=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_nl_connect" >&5 $as_echo "$ac_cv_lib_nl_nl_connect" >&6; } if test "x$ac_cv_lib_nl_nl_connect" = xyes; then : LIBNL_LIBS="-lnl" else as_fn_error $? "libnl is required" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_add_membership in -lnl" >&5 $as_echo_n "checking for nl_socket_add_membership in -lnl... " >&6; } if ${ac_cv_lib_nl_nl_socket_add_membership+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_add_membership (); int main () { return nl_socket_add_membership (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_nl_socket_add_membership=yes else ac_cv_lib_nl_nl_socket_add_membership=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_nl_socket_add_membership" >&5 $as_echo "$ac_cv_lib_nl_nl_socket_add_membership" >&6; } if test "x$ac_cv_lib_nl_nl_socket_add_membership" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_ADD_MEMBERSHIP 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_modify_cb in -lnl" >&5 $as_echo_n "checking for nl_socket_modify_cb in -lnl... " >&6; } if ${ac_cv_lib_nl_nl_socket_modify_cb+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_modify_cb (); int main () { return nl_socket_modify_cb (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_nl_socket_modify_cb=yes else ac_cv_lib_nl_nl_socket_modify_cb=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_nl_socket_modify_cb" >&5 $as_echo "$ac_cv_lib_nl_nl_socket_modify_cb" >&6; } if test "x$ac_cv_lib_nl_nl_socket_modify_cb" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_MODIFY_CB 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rtnl_route_get_oif in -lnl" >&5 $as_echo_n "checking for rtnl_route_get_oif in -lnl... " >&6; } if ${ac_cv_lib_nl_rtnl_route_get_oif+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char rtnl_route_get_oif (); int main () { return rtnl_route_get_oif (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_rtnl_route_get_oif=yes else ac_cv_lib_nl_rtnl_route_get_oif=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_rtnl_route_get_oif" >&5 $as_echo "$ac_cv_lib_nl_rtnl_route_get_oif" >&6; } if test "x$ac_cv_lib_nl_rtnl_route_get_oif" = xyes; then : $as_echo "#define HAVE_RTNL_ROUTE_GET_OIF 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_set_passcred in -lnl" >&5 $as_echo_n "checking for nl_set_passcred in -lnl... " >&6; } if ${ac_cv_lib_nl_nl_set_passcred+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_set_passcred (); int main () { return nl_set_passcred (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_nl_set_passcred=yes else ac_cv_lib_nl_nl_set_passcred=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_nl_set_passcred" >&5 $as_echo "$ac_cv_lib_nl_nl_set_passcred" >&6; } if test "x$ac_cv_lib_nl_nl_set_passcred" = xyes; then : $as_echo "#define HAVE_NL_SET_PASSCRED 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_socket_set_passcred in -lnl" >&5 $as_echo_n "checking for nl_socket_set_passcred in -lnl... " >&6; } if ${ac_cv_lib_nl_nl_socket_set_passcred+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nl_socket_set_passcred (); int main () { return nl_socket_set_passcred (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nl_nl_socket_set_passcred=yes else ac_cv_lib_nl_nl_socket_set_passcred=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nl_nl_socket_set_passcred" >&5 $as_echo "$ac_cv_lib_nl_nl_socket_set_passcred" >&6; } if test "x$ac_cv_lib_nl_nl_socket_set_passcred" = xyes; then : $as_echo "#define HAVE_NL_SOCKET_SET_PASSCRED 1" >>confdefs.h fi fi if test x"$HAVE_LIBNL" != x1; then as_fn_error $? "Libnl required, but not available" "$LINENO" 5 fi fi if test x$HAVE_NSCD; then # Check whether --with-nscd_conf was given. if test "${with_nscd_conf+set}" = set; then : withval=$with_nscd_conf; fi NSCD_CONF_PATH="/etc/nscd.conf" if test x"$with_nscd_conf" != x; then NSCD_CONF_PATH=$with_nscd_conf fi cat >>confdefs.h <<_ACEOF #define NSCD_CONF_PATH "$NSCD_CONF_PATH" _ACEOF fi # Check whether --with-initscript was given. if test "${with_initscript+set}" = set; then : withval=$with_initscript; fi default_initscript=sysv if test x"$with_initscript" = x; then with_initscript=$default_initscript fi if test x"$with_initscript" = xsysv || \ test x"$with_initscript" = xsystemd; then initscript=$with_initscript else as_fn_error $? "Illegal value -$with_initscript- for option --with-initscript" "$LINENO" 5 fi if test x"$initscript" = xsysv; then HAVE_SYSV_TRUE= HAVE_SYSV_FALSE='#' else HAVE_SYSV_TRUE='#' HAVE_SYSV_FALSE= fi if test x"$initscript" = xsystemd; then HAVE_SYSTEMD_UNIT_TRUE= HAVE_SYSTEMD_UNIT_FALSE='#' else HAVE_SYSTEMD_UNIT_TRUE='#' HAVE_SYSTEMD_UNIT_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: Will use init script type: $initscript" >&5 $as_echo "$as_me: Will use init script type: $initscript" >&6;} if test x$initscript = xsystemd; then # Check whether --with-systemdunitdir was given. if test "${with_systemdunitdir+set}" = set; then : withval=$with_systemdunitdir; fi if test x"$with_systemdunitdir" != x; then systemdunitdir=$with_systemdunitdir else systemdunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd) if test x"$systemdunitdir" = x; then as_fn_error $? "Could not detect systemd unit directory" "$LINENO" 5 fi fi # Check whether --with-systemdconfdir was given. if test "${with_systemdconfdir+set}" = set; then : withval=$with_systemdconfdir; fi if test x"$with_systemdconfdir" != x; then systemdconfdir=$with_systemdconfdir else systemdconfdir=$($PKG_CONFIG --variable=systemdsystemconfdir systemd) if test x"$systemdconfdir" = x; then as_fn_error $? "Could not detect systemd config directory" "$LINENO" 5 fi fi systemdconfdir=$systemdconfdir/sssd.service.d fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DBUS" >&5 $as_echo_n "checking for DBUS... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$DBUS_CFLAGS"; then pkg_cv_DBUS_CFLAGS="$DBUS_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5 ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DBUS_CFLAGS=`$PKG_CONFIG --cflags "dbus-1" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$DBUS_LIBS"; then pkg_cv_DBUS_LIBS="$DBUS_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"dbus-1\""; } >&5 ($PKG_CONFIG --exists --print-errors "dbus-1") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_DBUS_LIBS=`$PKG_CONFIG --libs "dbus-1" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then DBUS_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "dbus-1"` else DBUS_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "dbus-1"` fi # Put the nasty error message in config.log where it belongs echo "$DBUS_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (dbus-1) were not met: $DBUS_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables DBUS_CFLAGS and DBUS_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " "$LINENO" 5 elif test $pkg_failed = untried; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables DBUS_CFLAGS and DBUS_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else DBUS_CFLAGS=$pkg_cv_DBUS_CFLAGS DBUS_LIBS=$pkg_cv_DBUS_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi if ! $PKG_CONFIG --atleast-version 1.0.0 dbus-1; then DBUS_CFLAGS="$DBUS_CFLAGS -DDBUS_API_SUBJECT_TO_CHANGE" { $as_echo "$as_me:${as_lineno-$LINENO}: result: setting -DDBUS_API_SUBJECT_TO_CHANGE" >&5 $as_echo "setting -DDBUS_API_SUBJECT_TO_CHANGE" >&6; } fi if test x$has_dbus != xno; then SAFE_LIBS="$LIBS" LIBS="$DBUS_LIBS" SAFE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS $DBUS_CFLAGS" ac_fn_c_check_func "$LINENO" "dbus_watch_get_unix_fd" "ac_cv_func_dbus_watch_get_unix_fd" if test "x$ac_cv_func_dbus_watch_get_unix_fd" = xyes; then : $as_echo "#define HAVE_DBUS_WATCH_GET_UNIX_FD 1" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "DBusBasicValue" "ac_cv_type_DBusBasicValue" " #include " if test "x$ac_cv_type_DBusBasicValue" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DBUSBASICVALUE 1 _ACEOF fi LIBS="$SAFE_LIBS" CFLAGS=$SAFE_CFLAGS fi # work around a bug in cov-build from Coverity test -n "$XML_CATALOG_FILES" || unset XML_CATALOG_FILES if test x$HAVE_MANPAGES != x; then # Extract the first word of "xsltproc", so it can be a program name with args. set dummy xsltproc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XSLTPROC+:} false; then : $as_echo_n "(cached) " >&6 else case $XSLTPROC in [\\/]* | ?:[\\/]*) ac_cv_path_XSLTPROC="$XSLTPROC" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_XSLTPROC="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi XSLTPROC=$ac_cv_path_XSLTPROC if test -n "$XSLTPROC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XSLTPROC" >&5 $as_echo "$XSLTPROC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test ! -x "$XSLTPROC"; then as_fn_error $? "Could not find xsltproc" "$LINENO" 5 fi # Extract the first word of "xmllint", so it can be a program name with args. set dummy xmllint; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_XMLLINT+:} false; then : $as_echo_n "(cached) " >&6 else case $XMLLINT in [\\/]* | ?:[\\/]*) ac_cv_path_XMLLINT="$XMLLINT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_XMLLINT="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi XMLLINT=$ac_cv_path_XMLLINT if test -n "$XMLLINT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XMLLINT" >&5 $as_echo "$XMLLINT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test ! -x "$XMLLINT"; then as_fn_error $? "Could not find xmllint" "$LINENO" 5 fi DOCBOOK_XSLT=http://docbook.sourceforge.net/release/xsl/current/manpages/profile-docbook.xsl as_ac_File=`$as_echo "ac_cv_file_$SGML_CATALOG_FILES" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $SGML_CATALOG_FILES" >&5 $as_echo_n "checking for $SGML_CATALOG_FILES... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$SGML_CATALOG_FILES"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : else as_fn_error $? "could not find XML catalog" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Docbook XSL profiling templates in XML catalog" >&5 $as_echo_n "checking for Docbook XSL profiling templates in XML catalog... " >&6; } if { { $as_echo "$as_me:${as_lineno-$LINENO}: \$XSLTPROC --catalogs --nonet --noout \"\$DOCBOOK_XSLT\" >&2"; } >&5 ($XSLTPROC --catalogs --nonet --noout "$DOCBOOK_XSLT" >&2) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } HAVE_PROFILE_CATALOGS=1 else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Man pages might contain documentation for experimental features" >&5 $as_echo "$as_me: WARNING: Man pages might contain documentation for experimental features" >&2;} fi if test x$HAVE_PROFILE_CATALOGS = x; then DOCBOOK_XSLT=http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl as_ac_File=`$as_echo "ac_cv_file_$SGML_CATALOG_FILES" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $SGML_CATALOG_FILES" >&5 $as_echo_n "checking for $SGML_CATALOG_FILES... " >&6; } if eval \${$as_ac_File+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$SGML_CATALOG_FILES"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : else as_fn_error $? "could not find XML catalog" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Docbook XSL templates in XML catalog" >&5 $as_echo_n "checking for Docbook XSL templates in XML catalog... " >&6; } if { { $as_echo "$as_me:${as_lineno-$LINENO}: \$XSLTPROC --catalogs --nonet --noout \"\$DOCBOOK_XSLT\" >&2"; } >&5 ($XSLTPROC --catalogs --nonet --noout "$DOCBOOK_XSLT" >&2) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "could not find the docbook xsl catalog" "$LINENO" 5 fi fi # Extract the first word of "po4a", so it can be a program name with args. set dummy po4a; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_PO4A+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$PO4A"; then ac_cv_prog_PO4A="$PO4A" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_PO4A="po4a" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_PO4A" && ac_cv_prog_PO4A="no" fi fi PO4A=$ac_cv_prog_PO4A if test -n "$PO4A"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PO4A" >&5 $as_echo "$PO4A" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test "x$HAVE_PROFILE_CATALOGS" != "x"; then HAVE_PROFILE_CATALOGS_TRUE= HAVE_PROFILE_CATALOGS_FALSE='#' else HAVE_PROFILE_CATALOGS_TRUE='#' HAVE_PROFILE_CATALOGS_FALSE= fi if test "x$HAVE_MANPAGES" != "x"; then HAVE_MANPAGES_TRUE= HAVE_MANPAGES_FALSE='#' else HAVE_MANPAGES_TRUE='#' HAVE_MANPAGES_FALSE= fi if test "x$PO4A" != "xno"; then HAVE_PO4A_TRUE= HAVE_PO4A_FALSE='#' else HAVE_PO4A_TRUE='#' HAVE_PO4A_FALSE= fi # Extract the first word of "python2", so it can be a program name with args. set dummy python2; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_PYTHON2+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_PYTHON2"; then ac_cv_prog_HAVE_PYTHON2="$HAVE_PYTHON2" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_PYTHON2="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_HAVE_PYTHON2" && ac_cv_prog_HAVE_PYTHON2="no" fi fi HAVE_PYTHON2=$ac_cv_prog_HAVE_PYTHON2 if test -n "$HAVE_PYTHON2"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_PYTHON2" >&5 $as_echo "$HAVE_PYTHON2" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x$HAVE_PYTHON2 = xyes; then : # Extract the first word of "python2", so it can be a program name with args. set dummy python2; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON2+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON2 in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON2="$PYTHON2" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON2="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON2=$ac_cv_path_PYTHON2 if test -n "$PYTHON2"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON2" >&5 $as_echo "$PYTHON2" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi # Extract the first word of "python3", so it can be a program name with args. set dummy python3; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_HAVE_PYTHON3+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$HAVE_PYTHON3"; then ac_cv_prog_HAVE_PYTHON3="$HAVE_PYTHON3" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_HAVE_PYTHON3="yes" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_HAVE_PYTHON3" && ac_cv_prog_HAVE_PYTHON3="no" fi fi HAVE_PYTHON3=$ac_cv_prog_HAVE_PYTHON3 if test -n "$HAVE_PYTHON3"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_PYTHON3" >&5 $as_echo "$HAVE_PYTHON3" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x$HAVE_PYTHON3 = xyes; then : # Extract the first word of "python3", so it can be a program name with args. set dummy python3; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON3+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON3 in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON3="$PYTHON3" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON3="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON3=$ac_cv_path_PYTHON3 if test -n "$PYTHON3"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON3" >&5 $as_echo "$PYTHON3" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test x$HAVE_PYTHON2_BINDINGS = x1; then if test x$HAVE_PYTHON2 != xyes; then : as_fn_error $? " The program python2 was not found in search path. Please ensure that it is installed and its directory is included in the search path. It is required for building python2 bindings. If you do not want to build them please use argument --without-python2-bindings when running configure." "$LINENO" 5 fi PYTHON=$PYTHON2 if test -n "$PYTHON"; then # If the user set $PYTHON, use it and don't search something else. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 2.6" >&5 $as_echo_n "checking whether $PYTHON version is >= 2.6... " >&6; } prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '2.6'.split('.'))) + [0, 0, 0] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] sys.exit(sys.hexversion < minverhex)" if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 ($PYTHON -c "$prog") >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Python interpreter is too old" "$LINENO" 5 fi am_display_PYTHON=$PYTHON else # Otherwise, try each interpreter until we find one that satisfies # VERSION. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 2.6" >&5 $as_echo_n "checking for a Python interpreter with version >= 2.6... " >&6; } if ${am_cv_pathless_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do test "$am_cv_pathless_PYTHON" = none && break prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '2.6'.split('.'))) + [0, 0, 0] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] sys.exit(sys.hexversion < minverhex)" if { echo "$as_me:$LINENO: $am_cv_pathless_PYTHON -c "$prog"" >&5 ($am_cv_pathless_PYTHON -c "$prog") >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then : break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5 $as_echo "$am_cv_pathless_PYTHON" >&6; } # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. if test "$am_cv_pathless_PYTHON" = none; then PYTHON=: else # Extract the first word of "$am_cv_pathless_PYTHON", so it can be a program name with args. set dummy $am_cv_pathless_PYTHON; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 $as_echo "$PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi am_display_PYTHON=$am_cv_pathless_PYTHON fi if test "$PYTHON" = :; then as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5 $as_echo_n "checking for $am_display_PYTHON version... " >&6; } if ${am_cv_python_version+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 $as_echo "$am_cv_python_version" >&6; } PYTHON_VERSION=$am_cv_python_version PYTHON_PREFIX='${prefix}' PYTHON_EXEC_PREFIX='${exec_prefix}' { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5 $as_echo_n "checking for $am_display_PYTHON platform... " >&6; } if ${am_cv_python_platform+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 $as_echo "$am_cv_python_platform" >&6; } PYTHON_PLATFORM=$am_cv_python_platform # Just factor out some code duplication. am_python_setup_sysconfig="\ import sys # Prefer sysconfig over distutils.sysconfig, for better compatibility # with python 3.x. See automake bug#10227. try: import sysconfig except ImportError: can_use_sysconfig = 0 else: can_use_sysconfig = 1 # Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: # try: from platform import python_implementation if python_implementation() == 'CPython' and sys.version[:3] == '2.7': can_use_sysconfig = 0 except ImportError: pass" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5 $as_echo_n "checking for $am_display_PYTHON script directory... " >&6; } if ${am_cv_python_pythondir+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$prefix" = xNONE then am_py_prefix=$ac_default_prefix else am_py_prefix=$prefix fi am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` case $am_cv_python_pythondir in $am_py_prefix*) am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` ;; *) case $am_py_prefix in /usr|/System*) ;; *) am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 $as_echo "$am_cv_python_pythondir" >&6; } pythondir=$am_cv_python_pythondir pkgpythondir=\${pythondir}/$PACKAGE { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5 $as_echo_n "checking for $am_display_PYTHON extension module directory... " >&6; } if ${am_cv_python_pyexecdir+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$exec_prefix" = xNONE then am_py_exec_prefix=$am_py_prefix else am_py_exec_prefix=$exec_prefix fi am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` case $am_cv_python_pyexecdir in $am_py_exec_prefix*) am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` ;; *) case $am_py_exec_prefix in /usr|/System*) ;; *) am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 $as_echo "$am_cv_python_pyexecdir" >&6; } pyexecdir=$am_cv_python_pyexecdir pkgpyexecdir=\${pyexecdir}/$PACKAGE fi # Extract the first word of "python$PYTHON_VERSION-config", so it can be a program name with args. set dummy python$PYTHON_VERSION-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON_CONFIG="$PYTHON_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON_CONFIG=$ac_cv_path_PYTHON_CONFIG if test -n "$PYTHON_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CONFIG" >&5 $as_echo "$PYTHON_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$PYTHON_CONFIG" = x; then : as_fn_error $? " The program python$PYTHON_VERSION-config was not found in search path. Please ensure that it is installed and its directory is included in the search path. If you want to build sssd without python2 bindings then specify --without-python2-bindings when running configure." "$LINENO" 5 fi PYTHON_CFLAGS="` $PYTHON_CONFIG --cflags`" PYTHON_LIBS="` $PYTHON_CONFIG --libs`" PYTHON_INCLUDES="` $PYTHON_CONFIG --includes`" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for headers required to compile python extensions" >&5 $as_echo_n "checking for headers required to compile python extensions... " >&6; } save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 $as_echo "found" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "Could not find python2 headers" "$LINENO" 5 fi rm -f conftest.err conftest.i conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LIBS="$LIBS" CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" LIBS="$LIBS $PYTHON_LIBS" for ac_func in PyErr_NewExceptionWithDoc do : ac_fn_c_check_func "$LINENO" "PyErr_NewExceptionWithDoc" "ac_cv_func_PyErr_NewExceptionWithDoc" if test "x$ac_cv_func_PyErr_NewExceptionWithDoc" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PYERR_NEWEXCEPTIONWITHDOC 1 _ACEOF fi done CPPFLAGS="$save_CPPFLAGS" LIBS="$save_LIBS" py2execdir=$pyexecdir python2dir=$pythondir PYTHON2_CFLAGS=$PYTHON_CFLAGS PYTHON2_LIBS=$PYTHON_LIBS PYTHON2_INCLUDES=$PYTHON_INCLUDES PYTHON2_VERSION=$PYTHON_VERSION PYTHON2_PREFIX=$PYTHON_PREFIX PYTHON2_EXEC_PREFIX=$PYTHON_EXEC_PREFIX unset pyexecdir pkgpyexecdir pythondir pgkpythondir unset PYTHON PYTHON_CFLAGS PYTHON_LIBS PYTHON_INCLUDES unset PYTHON_PREFIX PYTHON_EXEC_PREFIX PYTHON_VERSION PYTHON_CONFIG unset am_cv_pathless_PYTHON ac_cv_path_PYTHON am_cv_python_version unset am_cv_python_platform am_cv_python_pythondir am_cv_python_pyexecdir unset ac_cv_path_PYTHON_CONFIG fi if test x$HAVE_PYTHON3_BINDINGS = x1; then if test x$HAVE_PYTHON3 != xyes; then : as_fn_error $? " The program python3 was not found in search path. Please ensure that it is installed and its directory is included in the search path. It is required for building python3 bindings. If you do not want to build them please use argument --without-python3-bindings when running configure." "$LINENO" 5 fi PYTHON=$PYTHON3 if test -n "$PYTHON"; then # If the user set $PYTHON, use it and don't search something else. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 3.3" >&5 $as_echo_n "checking whether $PYTHON version is >= 3.3... " >&6; } prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '3.3'.split('.'))) + [0, 0, 0] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] sys.exit(sys.hexversion < minverhex)" if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 ($PYTHON -c "$prog") >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } as_fn_error $? "Python interpreter is too old" "$LINENO" 5 fi am_display_PYTHON=$PYTHON else # Otherwise, try each interpreter until we find one that satisfies # VERSION. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 3.3" >&5 $as_echo_n "checking for a Python interpreter with version >= 3.3... " >&6; } if ${am_cv_pathless_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do test "$am_cv_pathless_PYTHON" = none && break prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '3.3'.split('.'))) + [0, 0, 0] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] sys.exit(sys.hexversion < minverhex)" if { echo "$as_me:$LINENO: $am_cv_pathless_PYTHON -c "$prog"" >&5 ($am_cv_pathless_PYTHON -c "$prog") >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then : break fi done fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5 $as_echo "$am_cv_pathless_PYTHON" >&6; } # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. if test "$am_cv_pathless_PYTHON" = none; then PYTHON=: else # Extract the first word of "$am_cv_pathless_PYTHON", so it can be a program name with args. set dummy $am_cv_pathless_PYTHON; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON=$ac_cv_path_PYTHON if test -n "$PYTHON"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 $as_echo "$PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi am_display_PYTHON=$am_cv_pathless_PYTHON fi if test "$PYTHON" = :; then as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5 $as_echo_n "checking for $am_display_PYTHON version... " >&6; } if ${am_cv_python_version+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 $as_echo "$am_cv_python_version" >&6; } PYTHON_VERSION=$am_cv_python_version PYTHON_PREFIX='${prefix}' PYTHON_EXEC_PREFIX='${exec_prefix}' { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5 $as_echo_n "checking for $am_display_PYTHON platform... " >&6; } if ${am_cv_python_platform+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 $as_echo "$am_cv_python_platform" >&6; } PYTHON_PLATFORM=$am_cv_python_platform # Just factor out some code duplication. am_python_setup_sysconfig="\ import sys # Prefer sysconfig over distutils.sysconfig, for better compatibility # with python 3.x. See automake bug#10227. try: import sysconfig except ImportError: can_use_sysconfig = 0 else: can_use_sysconfig = 1 # Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: # try: from platform import python_implementation if python_implementation() == 'CPython' and sys.version[:3] == '2.7': can_use_sysconfig = 0 except ImportError: pass" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5 $as_echo_n "checking for $am_display_PYTHON script directory... " >&6; } if ${am_cv_python_pythondir+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$prefix" = xNONE then am_py_prefix=$ac_default_prefix else am_py_prefix=$prefix fi am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` case $am_cv_python_pythondir in $am_py_prefix*) am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` ;; *) case $am_py_prefix in /usr|/System*) ;; *) am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 $as_echo "$am_cv_python_pythondir" >&6; } pythondir=$am_cv_python_pythondir pkgpythondir=\${pythondir}/$PACKAGE { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5 $as_echo_n "checking for $am_display_PYTHON extension module directory... " >&6; } if ${am_cv_python_pyexecdir+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$exec_prefix" = xNONE then am_py_exec_prefix=$am_py_prefix else am_py_exec_prefix=$exec_prefix fi am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` case $am_cv_python_pyexecdir in $am_py_exec_prefix*) am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` ;; *) case $am_py_exec_prefix in /usr|/System*) ;; *) am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 $as_echo "$am_cv_python_pyexecdir" >&6; } pyexecdir=$am_cv_python_pyexecdir pkgpyexecdir=\${pyexecdir}/$PACKAGE fi # Extract the first word of "python$PYTHON_VERSION-config", so it can be a program name with args. set dummy python$PYTHON_VERSION-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PYTHON_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PYTHON_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON_CONFIG="$PYTHON_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PYTHON_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PYTHON_CONFIG=$ac_cv_path_PYTHON_CONFIG if test -n "$PYTHON_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_CONFIG" >&5 $as_echo "$PYTHON_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x"$PYTHON_CONFIG" = x; then : as_fn_error $? " The program python$PYTHON_VERSION-config was not found in search path. Please ensure that it is installed and its directory is included in the search path. If you want to build sssd without python3 bindings then specify --without-python3-bindings when running configure." "$LINENO" 5 fi PYTHON_CFLAGS="` $PYTHON_CONFIG --cflags`" PYTHON_LIBS="` $PYTHON_CONFIG --libs`" PYTHON_INCLUDES="` $PYTHON_CONFIG --includes`" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for headers required to compile python extensions" >&5 $as_echo_n "checking for headers required to compile python extensions... " >&6; } save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5 $as_echo "found" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5 $as_echo "not found" >&6; } as_fn_error $? "Could not find python3 headers" "$LINENO" 5 fi rm -f conftest.err conftest.i conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" save_CPPFLAGS="$CPPFLAGS" save_LIBS="$LIBS" CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" LIBS="$LIBS $PYTHON_LIBS" for ac_func in PyErr_NewExceptionWithDoc do : ac_fn_c_check_func "$LINENO" "PyErr_NewExceptionWithDoc" "ac_cv_func_PyErr_NewExceptionWithDoc" if test "x$ac_cv_func_PyErr_NewExceptionWithDoc" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_PYERR_NEWEXCEPTIONWITHDOC 1 _ACEOF fi done CPPFLAGS="$save_CPPFLAGS" LIBS="$save_LIBS" py3execdir=$pyexecdir python3dir=$pythondir PYTHON3_CFLAGS=$PYTHON_CFLAGS PYTHON3_LIBS=$PYTHON_LIBS PYTHON3_INCLUDES=$PYTHON_INCLUDES PYTHON3_VERSION=$PYTHON_VERSION PYTHON3_PREFIX=$PYTHON_PREFIX PYTHON3_EXEC_PREFIX=$PYTHON_EXEC_PREFIX unset pyexecdir pkgpyexecdir pythondir pgkpythondir unset PYTHON PYTHON_CFLAGS PYTHON_LIBS PYTHON_INCLUDES unset PYTHON_PREFIX PYTHON_EXEC_PREFIX PYTHON_VERSION PYTHON_CONFIG unset am_cv_pathless_PYTHON ac_cv_path_PYTHON am_cv_python_version unset am_cv_python_platform am_cv_python_pythondir am_cv_python_pyexecdir unset ac_cv_path_PYTHON_CONFIG fi if test x"$with_python2_bindings" = xyes \ -o x"$with_python3_bindings" = xyes; then BUILD_PYTHON_BINDINGS_TRUE= BUILD_PYTHON_BINDINGS_FALSE='#' else BUILD_PYTHON_BINDINGS_TRUE='#' BUILD_PYTHON_BINDINGS_FALSE= fi if test x"$PYTHON2" = x; then if test -n ""; then as_fn_error $? "cannot look for ldap module: Python 2 not found" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: cannot look for ldap module: Python 2 not found" >&5 $as_echo "$as_me: cannot look for ldap module: Python 2 not found" >&6;} eval HAVE_PY2MOD_LDAP=no fi else { $as_echo "$as_me:${as_lineno-$LINENO}: checking $(basename $PYTHON2) module: ldap" >&5 $as_echo_n "checking $(basename $PYTHON2) module: ldap... " >&6; } $PYTHON2 -c "import ldap" 2>/dev/null if test $? -eq 0; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } eval HAVE_PY2MOD_LDAP=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } eval HAVE_PY2MOD_LDAP=no # if test -n "" then as_fn_error $? "failed to find required module ldap" "$LINENO" 5 exit 1 fi fi fi if test x$HAVE_SELINUX != x; then for ac_header in selinux/selinux.h do : ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default" if test "x$ac_cv_header_selinux_selinux_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SELINUX_SELINUX_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for is_selinux_enabled in -lselinux" >&5 $as_echo_n "checking for is_selinux_enabled in -lselinux... " >&6; } if ${ac_cv_lib_selinux_is_selinux_enabled+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lselinux $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char is_selinux_enabled (); int main () { return is_selinux_enabled (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_selinux_is_selinux_enabled=yes else ac_cv_lib_selinux_is_selinux_enabled=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_is_selinux_enabled" >&5 $as_echo "$ac_cv_lib_selinux_is_selinux_enabled" >&6; } if test "x$ac_cv_lib_selinux_is_selinux_enabled" = xyes; then : SELINUX_LIBS="-lselinux" else as_fn_error $? "SELinux library is missing" "$LINENO" 5 fi else as_fn_error $? "SELinux headers are missing" "$LINENO" 5 fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /etc/selinux/targeted/logins/" >&5 $as_echo_n "checking for /etc/selinux/targeted/logins/... " >&6; } if ${ac_cv_file__etc_selinux_targeted_logins_+:} false; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "/etc/selinux/targeted/logins/"; then ac_cv_file__etc_selinux_targeted_logins_=yes else ac_cv_file__etc_selinux_targeted_logins_=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__etc_selinux_targeted_logins_" >&5 $as_echo "$ac_cv_file__etc_selinux_targeted_logins_" >&6; } if test "x$ac_cv_file__etc_selinux_targeted_logins_" = xyes; then : $as_echo "#define HAVE_SELINUX_LOGIN_DIR 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: SELinux login directory is not available" >&5 $as_echo "$as_me: WARNING: SELinux login directory is not available" >&2;} fi fi if test x$HAVE_SEMANAGE != x -a x$HAVE_SELINUX != x; then for ac_header in semanage/semanage.h do : ac_fn_c_check_header_mongrel "$LINENO" "semanage/semanage.h" "ac_cv_header_semanage_semanage_h" "$ac_includes_default" if test "x$ac_cv_header_semanage_semanage_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SEMANAGE_SEMANAGE_H 1 _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for semanage_handle_create in -lsemanage" >&5 $as_echo_n "checking for semanage_handle_create in -lsemanage... " >&6; } if ${ac_cv_lib_semanage_semanage_handle_create+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsemanage $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char semanage_handle_create (); int main () { return semanage_handle_create (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_semanage_semanage_handle_create=yes else ac_cv_lib_semanage_semanage_handle_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_semanage_semanage_handle_create" >&5 $as_echo "$ac_cv_lib_semanage_semanage_handle_create" >&6; } if test "x$ac_cv_lib_semanage_semanage_handle_create" = xyes; then : SEMANAGE_LIBS="-lsemanage" else as_fn_error $? "libsemanage is missing" "$LINENO" 5 fi else as_fn_error $? "libsemanage is missing" "$LINENO" 5 fi done fi if test x$HAVE_SYSTEMD_UNIT != x; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"systemd\""; } >&5 ($PKG_CONFIG --exists --print-errors "systemd") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then HAVE_SYSTEMD=1, else as_fn_error $? "Could not detect systemd presence" "$LINENO" 5 fi fi if test x$syslog = xjournald; then if test x$HAVE_LIBSYSTEMD = xyes; then : journal_lib_name=libsystemd else journal_lib_name=libsystemd-journal fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JOURNALD" >&5 $as_echo_n "checking for JOURNALD... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$JOURNALD_CFLAGS"; then pkg_cv_JOURNALD_CFLAGS="$JOURNALD_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$journal_lib_name\""; } >&5 ($PKG_CONFIG --exists --print-errors "$journal_lib_name") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_JOURNALD_CFLAGS=`$PKG_CONFIG --cflags "$journal_lib_name" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$JOURNALD_LIBS"; then pkg_cv_JOURNALD_LIBS="$JOURNALD_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$journal_lib_name\""; } >&5 ($PKG_CONFIG --exists --print-errors "$journal_lib_name") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_JOURNALD_LIBS=`$PKG_CONFIG --libs "$journal_lib_name" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then JOURNALD_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$journal_lib_name"` else JOURNALD_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$journal_lib_name"` fi # Put the nasty error message in config.log where it belongs echo "$JOURNALD_PKG_ERRORS" >&5 as_fn_error $? "Package requirements ($journal_lib_name) were not met: $JOURNALD_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables JOURNALD_CFLAGS and JOURNALD_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " "$LINENO" 5 elif test $pkg_failed = untried; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables JOURNALD_CFLAGS and JOURNALD_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else JOURNALD_CFLAGS=$pkg_cv_JOURNALD_CFLAGS JOURNALD_LIBS=$pkg_cv_JOURNALD_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } cat >>confdefs.h <<_ACEOF #define WITH_JOURNALD 1 _ACEOF fi fi if test x$cryptolib = xnss; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for NSS" >&5 $as_echo_n "checking for NSS... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$NSS_CFLAGS"; then pkg_cv_NSS_CFLAGS="$NSS_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nss\""; } >&5 ($PKG_CONFIG --exists --print-errors "nss") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_NSS_CFLAGS=`$PKG_CONFIG --cflags "nss" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$NSS_LIBS"; then pkg_cv_NSS_LIBS="$NSS_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nss\""; } >&5 ($PKG_CONFIG --exists --print-errors "nss") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_NSS_LIBS=`$PKG_CONFIG --libs "nss" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then NSS_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "nss"` else NSS_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "nss"` fi # Put the nasty error message in config.log where it belongs echo "$NSS_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (nss) were not met: $NSS_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables NSS_CFLAGS and NSS_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " "$LINENO" 5 elif test $pkg_failed = untried; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables NSS_CFLAGS and NSS_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else NSS_CFLAGS=$pkg_cv_NSS_CFLAGS NSS_LIBS=$pkg_cv_NSS_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi cat >>confdefs.h <<_ACEOF #define HAVE_NSS 1 _ACEOF fi if test x$cryptolib = xlibcrypto; then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO" >&5 $as_echo_n "checking for CRYPTO... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$CRYPTO_CFLAGS"; then pkg_cv_CRYPTO_CFLAGS="$CRYPTO_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcrypto\""; } >&5 ($PKG_CONFIG --exists --print-errors "libcrypto") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CRYPTO_CFLAGS=`$PKG_CONFIG --cflags "libcrypto" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$CRYPTO_LIBS"; then pkg_cv_CRYPTO_LIBS="$CRYPTO_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcrypto\""; } >&5 ($PKG_CONFIG --exists --print-errors "libcrypto") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CRYPTO_LIBS=`$PKG_CONFIG --libs "libcrypto" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then CRYPTO_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "libcrypto"` else CRYPTO_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "libcrypto"` fi # Put the nasty error message in config.log where it belongs echo "$CRYPTO_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (libcrypto) were not met: $CRYPTO_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables CRYPTO_CFLAGS and CRYPTO_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " "$LINENO" 5 elif test $pkg_failed = untried; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables CRYPTO_CFLAGS and CRYPTO_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else CRYPTO_CFLAGS=$pkg_cv_CRYPTO_CFLAGS CRYPTO_LIBS=$pkg_cv_CRYPTO_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } : fi cat >>confdefs.h <<_ACEOF #define HAVE_LIBCRYPTO 1 _ACEOF fi for ac_header in sys/inotify.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/inotify.h" "ac_cv_header_sys_inotify_h" "$ac_includes_default" if test "x$ac_cv_header_sys_inotify_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_INOTIFY_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sys/inotify.h actually works" >&5 $as_echo_n "checking whether sys/inotify.h actually works... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef HAVE_SYS_INOTITY_H #include , #endif int main () { return (-1 == inotify_init()); } _ACEOF if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; inotify_works=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext acl_save_prefix="$prefix" prefix="$acl_final_prefix" acl_save_exec_prefix="$exec_prefix" exec_prefix="$acl_final_exec_prefix" eval additional_libdir=\"$libdir\" exec_prefix="$acl_save_exec_prefix" prefix="$acl_save_prefix" sss_extra_libdir="$additional_libdir" if test x"$inotify_works" != xyes; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inotify_init in -linotify" >&5 $as_echo_n "checking for inotify_init in -linotify... " >&6; } if ${ac_cv_lib_inotify_inotify_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-linotify $sss_extra_libdir $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inotify_init (); int main () { return inotify_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_inotify_inotify_init=yes else ac_cv_lib_inotify_inotify_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inotify_inotify_init" >&5 $as_echo "$ac_cv_lib_inotify_inotify_init" >&6; } if test "x$ac_cv_lib_inotify_inotify_init" = xyes; then : INOTIFY_LIBS="$sss_extra_libdir -linotify" inotify_works=yes else inotify_works=no fi fi if test x"$inotify_works" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_INOTIFY 1 _ACEOF fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports __attribute__((destructor))" >&5 $as_echo_n "checking whether compiler supports __attribute__((destructor))... " >&6; } if ${sss_client_cv_attribute_destructor+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ __attribute__((destructor)) static void cleanup(void) { } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sss_client_cv_attribute_destructor=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sss_client_cv_attribute_destructor" >&5 $as_echo "$sss_client_cv_attribute_destructor" >&6; } if test x"$sss_client_cv_attribute_destructor" = xyes ; then $as_echo "#define HAVE_FUNCTION_ATTRIBUTE_DESTRUCTOR 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports __attribute__((format))" >&5 $as_echo_n "checking whether compiler supports __attribute__((format))... " >&6; } if ${sss_cv_attribute_format+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ void debug_fn(const char *format, ...) __attribute__ ((format (printf, 1, 2))); _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sss_cv_attribute_format=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: compiler does NOT support __attribute__((format))" >&5 $as_echo "$as_me: WARNING: compiler does NOT support __attribute__((format))" >&2;} fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sss_cv_attribute_format" >&5 $as_echo "$sss_cv_attribute_format" >&6; } if test x"$sss_cv_attribute_format" = xyes ; then $as_echo "#define HAVE_FUNCTION_ATTRIBUTE_FORMAT 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports __attribute__((warn_unused_result))" >&5 $as_echo_n "checking whether compiler supports __attribute__((warn_unused_result))... " >&6; } if ${sss_cv_attribute_warn_unused_result+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ char _check_leaks(int bytes) __attribute__ ((warn_unused_result)); _ACEOF if ac_fn_c_try_compile "$LINENO"; then : sss_cv_attribute_warn_unused_result=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: compiler does NOT support __attribute__((warn_unused_result))" >&5 $as_echo "$as_me: WARNING: compiler does NOT support __attribute__((warn_unused_result))" >&2;} fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sss_cv_attribute_warn_unused_result" >&5 $as_echo "$sss_cv_attribute_warn_unused_result" >&6; } if test x"$sss_cv_attribute_warn_unused_result" = xyes ; then $as_echo "#define HAVE_FUNCTION_ATTRIBUTE_WARN_UNUSED_RESULT 1" >>confdefs.h fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CHECK" >&5 $as_echo_n "checking for CHECK... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$CHECK_CFLAGS"; then pkg_cv_CHECK_CFLAGS="$CHECK_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"check >= 0.9.5\""; } >&5 ($PKG_CONFIG --exists --print-errors "check >= 0.9.5") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CHECK_CFLAGS=`$PKG_CONFIG --cflags "check >= 0.9.5" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$CHECK_LIBS"; then pkg_cv_CHECK_LIBS="$CHECK_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"check >= 0.9.5\""; } >&5 ($PKG_CONFIG --exists --print-errors "check >= 0.9.5") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CHECK_LIBS=`$PKG_CONFIG --libs "check >= 0.9.5" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then CHECK_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "check >= 0.9.5"` else CHECK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "check >= 0.9.5"` fi # Put the nasty error message in config.log where it belongs echo "$CHECK_PKG_ERRORS" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } have_check= elif test $pkg_failed = untried; then have_check= else CHECK_CFLAGS=$pkg_cv_CHECK_CFLAGS CHECK_LIBS=$pkg_cv_CHECK_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_check=1 fi if test x$have_check = x; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Without the 'CHECK' libraries, you will be unable to run all tests in the 'make check' suite" >&5 $as_echo "$as_me: WARNING: Without the 'CHECK' libraries, you will be unable to run all tests in the 'make check' suite" >&2;} else for ac_header in check.h do : ac_fn_c_check_header_mongrel "$LINENO" "check.h" "ac_cv_header_check_h" "$ac_includes_default" if test "x$ac_cv_header_check_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_CHECK_H 1 _ACEOF else as_fn_error $? "Could not find CHECK headers" "$LINENO" 5 fi done fi # Extract the first word of "doxygen", so it can be a program name with args. set dummy doxygen; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_DOXYGEN+:} false; then : $as_echo_n "(cached) " >&6 else case $DOXYGEN in [\\/]* | ?:[\\/]*) ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_DOXYGEN" && ac_cv_path_DOXYGEN="false" ;; esac fi DOXYGEN=$ac_cv_path_DOXYGEN if test -n "$DOXYGEN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 $as_echo "$DOXYGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test x$DOXYGEN != xfalse ; then HAVE_DOXYGEN_TRUE= HAVE_DOXYGEN_FALSE='#' else HAVE_DOXYGEN_TRUE='#' HAVE_DOXYGEN_FALSE= fi if test x$have_check != x; then HAVE_CHECK_TRUE= HAVE_CHECK_FALSE='#' else HAVE_CHECK_TRUE='#' HAVE_CHECK_FALSE= fi if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cmocka >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "cmocka >= 1.0.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then for ac_header in stdarg.h stddef.h setjmp.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Header files stdarg.h stddef.h setjmp.h are required by cmocka" >&5 $as_echo "$as_me: WARNING: Header files stdarg.h stddef.h setjmp.h are required by cmocka" >&2;} cmocka_required_headers="no" fi done if test x"$cmocka_required_headers" != x"no"; then : pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CMOCKA" >&5 $as_echo_n "checking for CMOCKA... " >&6; } if test -n "$PKG_CONFIG"; then if test -n "$CMOCKA_CFLAGS"; then pkg_cv_CMOCKA_CFLAGS="$CMOCKA_CFLAGS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cmocka\""; } >&5 ($PKG_CONFIG --exists --print-errors "cmocka") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CMOCKA_CFLAGS=`$PKG_CONFIG --cflags "cmocka" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test -n "$PKG_CONFIG"; then if test -n "$CMOCKA_LIBS"; then pkg_cv_CMOCKA_LIBS="$CMOCKA_LIBS" else if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"cmocka\""; } >&5 ($PKG_CONFIG --exists --print-errors "cmocka") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_CMOCKA_LIBS=`$PKG_CONFIG --libs "cmocka" 2>/dev/null` else pkg_failed=yes fi fi else pkg_failed=untried fi if test $pkg_failed = yes; then if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then CMOCKA_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "cmocka"` else CMOCKA_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "cmocka"` fi # Put the nasty error message in config.log where it belongs echo "$CMOCKA_PKG_ERRORS" >&5 as_fn_error $? "Package requirements (cmocka) were not met: $CMOCKA_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables CMOCKA_CFLAGS and CMOCKA_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. " "$LINENO" 5 elif test $pkg_failed = untried; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables CMOCKA_CFLAGS and CMOCKA_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else CMOCKA_CFLAGS=$pkg_cv_CMOCKA_CFLAGS CMOCKA_LIBS=$pkg_cv_CMOCKA_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } have_cmocka="yes" fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No libcmocka-1.0.0 or newer library found, cmocka tests will not be built" >&5 $as_echo "$as_me: WARNING: No libcmocka-1.0.0 or newer library found, cmocka tests will not be built" >&2;} fi if test x$have_cmocka = xyes; then HAVE_CMOCKA_TRUE= HAVE_CMOCKA_FALSE='#' else HAVE_CMOCKA_TRUE='#' HAVE_CMOCKA_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_wrapper" >&5 $as_echo_n "checking for uid_wrapper... " >&6; } if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uid_wrapper\""; } >&5 ($PKG_CONFIG --exists --print-errors "uid_wrapper") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } HAVE_UID_WRAPPER=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } HAVE_UID_WRAPPER=no { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cwrap library uid_wrapper not found, some tests will not run" >&5 $as_echo "$as_me: WARNING: cwrap library uid_wrapper not found, some tests will not run" >&2;} fi if test x$HAVE_UID_WRAPPER = xyes; then HAVE_UID_WRAPPER_TRUE= HAVE_UID_WRAPPER_FALSE='#' else HAVE_UID_WRAPPER_TRUE='#' HAVE_UID_WRAPPER_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nss_wrapper" >&5 $as_echo_n "checking for nss_wrapper... " >&6; } if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"nss_wrapper\""; } >&5 ($PKG_CONFIG --exists --print-errors "nss_wrapper") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } HAVE_NSS_WRAPPER=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } HAVE_NSS_WRAPPER=no { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cwrap library nss_wrapper not found, some tests will not run" >&5 $as_echo "$as_me: WARNING: cwrap library nss_wrapper not found, some tests will not run" >&2;} fi if test x$HAVE_NSS_WRAPPER = xyes; then HAVE_NSS_WRAPPER_TRUE= HAVE_NSS_WRAPPER_FALSE='#' else HAVE_NSS_WRAPPER_TRUE='#' HAVE_NSS_WRAPPER_FALSE= fi # Check whether --enable-intgcheck-reqs was given. if test "${enable_intgcheck_reqs+set}" = set; then : enableval=$enable_intgcheck_reqs; enable_intgcheck_reqs="$enableval" else enable_intgcheck_reqs="no" fi if test x"$enable_intgcheck_reqs" = xyes; then if test x$HAVE_UID_WRAPPER = xyes; then : else as_fn_error $? "cannot enable integration tests: uid_wrapper not found" "$LINENO" 5 fi if test x$HAVE_NSS_WRAPPER = xyes; then : else as_fn_error $? "cannot enable integration tests: nss_wrapper not found" "$LINENO" 5 fi if test x$HAVE_SLAPD = xyes; then : else as_fn_error $? "cannot enable integration tests: slapd not found" "$LINENO" 5 fi if test x$HAVE_LDAPMODIFY = xyes; then : else as_fn_error $? "cannot enable integration tests: ldapmodify not found" "$LINENO" 5 fi if test x$HAVE_FAKEROOT = xyes; then : else as_fn_error $? "cannot enable integration tests: fakeroot not found" "$LINENO" 5 fi if test x$HAVE_PYTHON2 = xyes; then : else as_fn_error $? "cannot enable integration tests: python2 not found" "$LINENO" 5 fi if test x$HAVE_PYTEST = xyes; then : else as_fn_error $? "cannot enable integration tests: pytest not found" "$LINENO" 5 fi if test x$HAVE_PY2MOD_LDAP = xyes; then : else as_fn_error $? "cannot enable integration tests: python-ldap not found" "$LINENO" 5 fi fi if test -d /dev/shm; then HAVE_DEVSHM_TRUE= HAVE_DEVSHM_FALSE='#' else HAVE_DEVSHM_TRUE='#' HAVE_DEVSHM_FALSE= fi # Check if we should install polkit rules polkitdir="/usr/share/polkit-1/rules.d" # Check whether --enable-polkit-rules-path was given. if test "${enable_polkit_rules_path+set}" = set; then : enableval=$enable_polkit_rules_path; polkitdir=$enableval fi if test x"$polkitdir" != xno; then HAVE_POLKIT_RULES_D=1 fi if test x$HAVE_POLKIT_RULES_D != x; then HAVE_POLKIT_RULES_D_TRUE= HAVE_POLKIT_RULES_D_FALSE='#' else HAVE_POLKIT_RULES_D_TRUE='#' HAVE_POLKIT_RULES_D_FALSE= fi if test x$HAVE_POLKIT_RULES_D != x; then HAVE_POLKIT_RULES_D_TRUE= HAVE_POLKIT_RULES_D_FALSE='#' else HAVE_POLKIT_RULES_D_TRUE='#' HAVE_POLKIT_RULES_D_FALSE= fi abs_build_dir=`pwd` cat >>confdefs.h <<_ACEOF #define ABS_BUILD_DIR "$abs_build_dir" _ACEOF abs_builddir=$abs_build_dir my_srcdir=`readlink -f $srcdir` cat >>confdefs.h <<_ACEOF #define ABS_SRC_DIR "$my_srcdir" _ACEOF ac_config_files="$ac_config_files Makefile contrib/sssd.spec src/examples/rwtab src/doxy.config contrib/sssd-pcsc.rules src/sysv/sssd src/sysv/gentoo/sssd src/sysv/SUSE/sssd po/Makefile.in src/man/Makefile src/tests/cwrap/Makefile src/tests/intg/Makefile src/providers/ipa/ipa_hbac.pc src/providers/ipa/ipa_hbac.doxy src/lib/idmap/sss_idmap.pc src/lib/idmap/sss_idmap.doxy src/sss_client/sudo/sss_sudo.doxy src/sss_client/idmap/sss_nss_idmap.pc src/sss_client/idmap/sss_nss_idmap.doxy src/sss_client/libwbclient/wbclient_sssd.pc src/lib/sifp/sss_simpleifp.pc src/lib/sifp/sss_simpleifp.doxy src/config/setup.py src/responder/ifp/org.freedesktop.sssd.infopipe.service src/config/SSSDConfig/__init__.py" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${GIT_CHECKOUT_TRUE}" && test -z "${GIT_CHECKOUT_FALSE}"; then as_fn_error $? "conditional \"GIT_CHECKOUT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_GCC_TRUE}" && test -z "${HAVE_GCC_FALSE}"; then as_fn_error $? "conditional \"HAVE_GCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WANT_AUX_INFO_TRUE}" && test -z "${WANT_AUX_INFO_FALSE}"; then as_fn_error $? "conditional \"WANT_AUX_INFO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_PTHREAD_TRUE}" && test -z "${HAVE_PTHREAD_FALSE}"; then as_fn_error $? "conditional \"HAVE_PTHREAD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_FEDORA_TRUE}" && test -z "${HAVE_FEDORA_FALSE}"; then as_fn_error $? "conditional \"HAVE_FEDORA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_REDHAT_TRUE}" && test -z "${HAVE_REDHAT_FALSE}"; then as_fn_error $? "conditional \"HAVE_REDHAT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SUSE_TRUE}" && test -z "${HAVE_SUSE_FALSE}"; then as_fn_error $? "conditional \"HAVE_SUSE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DEBIAN_TRUE}" && test -z "${HAVE_DEBIAN_FALSE}"; then as_fn_error $? "conditional \"HAVE_DEBIAN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_GENTOO_TRUE}" && test -z "${HAVE_GENTOO_FALSE}"; then as_fn_error $? "conditional \"HAVE_GENTOO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_MANPAGES_TRUE}" && test -z "${BUILD_MANPAGES_FALSE}"; then as_fn_error $? "conditional \"BUILD_MANPAGES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_DBUS_TESTS_TRUE}" && test -z "${BUILD_DBUS_TESTS_FALSE}"; then as_fn_error $? "conditional \"BUILD_DBUS_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_PYTHON2_BINDINGS_TRUE}" && test -z "${BUILD_PYTHON2_BINDINGS_FALSE}"; then as_fn_error $? "conditional \"BUILD_PYTHON2_BINDINGS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_PYTHON3_BINDINGS_TRUE}" && test -z "${BUILD_PYTHON3_BINDINGS_FALSE}"; then as_fn_error $? "conditional \"BUILD_PYTHON3_BINDINGS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_SELINUX_TRUE}" && test -z "${BUILD_SELINUX_FALSE}"; then as_fn_error $? "conditional \"BUILD_SELINUX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_SEMANAGE_TRUE}" && test -z "${BUILD_SEMANAGE_FALSE}"; then as_fn_error $? "conditional \"BUILD_SEMANAGE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${GPO_DEFAULT_ENFORCING_TRUE}" && test -z "${GPO_DEFAULT_ENFORCING_FALSE}"; then as_fn_error $? "conditional \"GPO_DEFAULT_ENFORCING\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_SUDO_TRUE}" && test -z "${BUILD_SUDO_FALSE}"; then as_fn_error $? "conditional \"BUILD_SUDO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_AUTOFS_TRUE}" && test -z "${BUILD_AUTOFS_FALSE}"; then as_fn_error $? "conditional \"BUILD_AUTOFS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_SSH_TRUE}" && test -z "${BUILD_SSH_FALSE}"; then as_fn_error $? "conditional \"BUILD_SSH\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_IFP_TRUE}" && test -z "${BUILD_IFP_FALSE}"; then as_fn_error $? "conditional \"BUILD_IFP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_NSS_TRUE}" && test -z "${HAVE_NSS_FALSE}"; then as_fn_error $? "conditional \"HAVE_NSS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_LIBCRYPTO_TRUE}" && test -z "${HAVE_LIBCRYPTO_FALSE}"; then as_fn_error $? "conditional \"HAVE_LIBCRYPTO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_JOURNALD_TRUE}" && test -z "${WITH_JOURNALD_FALSE}"; then as_fn_error $? "conditional \"WITH_JOURNALD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_SAMBA_TRUE}" && test -z "${BUILD_SAMBA_FALSE}"; then as_fn_error $? "conditional \"BUILD_SAMBA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_NFS_IDMAP_TRUE}" && test -z "${BUILD_NFS_IDMAP_FALSE}"; then as_fn_error $? "conditional \"BUILD_NFS_IDMAP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_LIBWBCLIENT_TRUE}" && test -z "${BUILD_LIBWBCLIENT_FALSE}"; then as_fn_error $? "conditional \"BUILD_LIBWBCLIENT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${SSSD_USER_TRUE}" && test -z "${SSSD_USER_FALSE}"; then as_fn_error $? "conditional \"SSSD_USER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_KRB5_LOCATOR_PLUGIN_TRUE}" && test -z "${BUILD_KRB5_LOCATOR_PLUGIN_FALSE}"; then as_fn_error $? "conditional \"BUILD_KRB5_LOCATOR_PLUGIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE}" && test -z "${BUILD_KRB5_LOCALAUTH_PLUGIN_FALSE}"; then as_fn_error $? "conditional \"BUILD_KRB5_LOCALAUTH_PLUGIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_PAC_RESPONDER_TRUE}" && test -z "${BUILD_PAC_RESPONDER_FALSE}"; then as_fn_error $? "conditional \"BUILD_PAC_RESPONDER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_CIFS_IDMAP_PLUGIN_TRUE}" && test -z "${BUILD_CIFS_IDMAP_PLUGIN_FALSE}"; then as_fn_error $? "conditional \"BUILD_CIFS_IDMAP_PLUGIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_CONFIG_LIB_TRUE}" && test -z "${BUILD_CONFIG_LIB_FALSE}"; then as_fn_error $? "conditional \"BUILD_CONFIG_LIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_LIBRESOLV_TRUE}" && test -z "${HAVE_LIBRESOLV_FALSE}"; then as_fn_error $? "conditional \"HAVE_LIBRESOLV\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_LIBUNISTRING_TRUE}" && test -z "${WITH_LIBUNISTRING_FALSE}"; then as_fn_error $? "conditional \"WITH_LIBUNISTRING\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${WITH_GLIB_TRUE}" && test -z "${WITH_GLIB_FALSE}"; then as_fn_error $? "conditional \"WITH_GLIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SYSV_TRUE}" && test -z "${HAVE_SYSV_FALSE}"; then as_fn_error $? "conditional \"HAVE_SYSV\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SYSTEMD_UNIT_TRUE}" && test -z "${HAVE_SYSTEMD_UNIT_FALSE}"; then as_fn_error $? "conditional \"HAVE_SYSTEMD_UNIT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_PROFILE_CATALOGS_TRUE}" && test -z "${HAVE_PROFILE_CATALOGS_FALSE}"; then as_fn_error $? "conditional \"HAVE_PROFILE_CATALOGS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_MANPAGES_TRUE}" && test -z "${HAVE_MANPAGES_FALSE}"; then as_fn_error $? "conditional \"HAVE_MANPAGES\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_PO4A_TRUE}" && test -z "${HAVE_PO4A_FALSE}"; then as_fn_error $? "conditional \"HAVE_PO4A\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_PYTHON_BINDINGS_TRUE}" && test -z "${BUILD_PYTHON_BINDINGS_FALSE}"; then as_fn_error $? "conditional \"BUILD_PYTHON_BINDINGS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_CHECK_TRUE}" && test -z "${HAVE_CHECK_FALSE}"; then as_fn_error $? "conditional \"HAVE_CHECK\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_CMOCKA_TRUE}" && test -z "${HAVE_CMOCKA_FALSE}"; then as_fn_error $? "conditional \"HAVE_CMOCKA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_UID_WRAPPER_TRUE}" && test -z "${HAVE_UID_WRAPPER_FALSE}"; then as_fn_error $? "conditional \"HAVE_UID_WRAPPER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_NSS_WRAPPER_TRUE}" && test -z "${HAVE_NSS_WRAPPER_FALSE}"; then as_fn_error $? "conditional \"HAVE_NSS_WRAPPER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DEVSHM_TRUE}" && test -z "${HAVE_DEVSHM_FALSE}"; then as_fn_error $? "conditional \"HAVE_DEVSHM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_POLKIT_RULES_D_TRUE}" && test -z "${HAVE_POLKIT_RULES_D_FALSE}"; then as_fn_error $? "conditional \"HAVE_POLKIT_RULES_D\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_POLKIT_RULES_D_TRUE}" && test -z "${HAVE_POLKIT_RULES_D_FALSE}"; then as_fn_error $? "conditional \"HAVE_POLKIT_RULES_D\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by sssd $as_me 1.13.4, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ sssd config.status 1.13.4 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' # Capture the value of obsolete ALL_LINGUAS because we need it to compute # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it # from automake. eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' # Capture the value of LINGUAS because we need it to compute CATALOGS. LINGUAS="${LINGUAS-%UNSET%}" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;; "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "contrib/sssd.spec") CONFIG_FILES="$CONFIG_FILES contrib/sssd.spec" ;; "src/examples/rwtab") CONFIG_FILES="$CONFIG_FILES src/examples/rwtab" ;; "src/doxy.config") CONFIG_FILES="$CONFIG_FILES src/doxy.config" ;; "contrib/sssd-pcsc.rules") CONFIG_FILES="$CONFIG_FILES contrib/sssd-pcsc.rules" ;; "src/sysv/sssd") CONFIG_FILES="$CONFIG_FILES src/sysv/sssd" ;; "src/sysv/gentoo/sssd") CONFIG_FILES="$CONFIG_FILES src/sysv/gentoo/sssd" ;; "src/sysv/SUSE/sssd") CONFIG_FILES="$CONFIG_FILES src/sysv/SUSE/sssd" ;; "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; "src/man/Makefile") CONFIG_FILES="$CONFIG_FILES src/man/Makefile" ;; "src/tests/cwrap/Makefile") CONFIG_FILES="$CONFIG_FILES src/tests/cwrap/Makefile" ;; "src/tests/intg/Makefile") CONFIG_FILES="$CONFIG_FILES src/tests/intg/Makefile" ;; "src/providers/ipa/ipa_hbac.pc") CONFIG_FILES="$CONFIG_FILES src/providers/ipa/ipa_hbac.pc" ;; "src/providers/ipa/ipa_hbac.doxy") CONFIG_FILES="$CONFIG_FILES src/providers/ipa/ipa_hbac.doxy" ;; "src/lib/idmap/sss_idmap.pc") CONFIG_FILES="$CONFIG_FILES src/lib/idmap/sss_idmap.pc" ;; "src/lib/idmap/sss_idmap.doxy") CONFIG_FILES="$CONFIG_FILES src/lib/idmap/sss_idmap.doxy" ;; "src/sss_client/sudo/sss_sudo.doxy") CONFIG_FILES="$CONFIG_FILES src/sss_client/sudo/sss_sudo.doxy" ;; "src/sss_client/idmap/sss_nss_idmap.pc") CONFIG_FILES="$CONFIG_FILES src/sss_client/idmap/sss_nss_idmap.pc" ;; "src/sss_client/idmap/sss_nss_idmap.doxy") CONFIG_FILES="$CONFIG_FILES src/sss_client/idmap/sss_nss_idmap.doxy" ;; "src/sss_client/libwbclient/wbclient_sssd.pc") CONFIG_FILES="$CONFIG_FILES src/sss_client/libwbclient/wbclient_sssd.pc" ;; "src/lib/sifp/sss_simpleifp.pc") CONFIG_FILES="$CONFIG_FILES src/lib/sifp/sss_simpleifp.pc" ;; "src/lib/sifp/sss_simpleifp.doxy") CONFIG_FILES="$CONFIG_FILES src/lib/sifp/sss_simpleifp.doxy" ;; "src/config/setup.py") CONFIG_FILES="$CONFIG_FILES src/config/setup.py" ;; "src/responder/ifp/org.freedesktop.sssd.infopipe.service") CONFIG_FILES="$CONFIG_FILES src/responder/ifp/org.freedesktop.sssd.infopipe.service" ;; "src/config/SSSDConfig/__init__.py") CONFIG_FILES="$CONFIG_FILES src/config/SSSDConfig/__init__.py" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="" # ### BEGIN LIBTOOL CONFIG # Whether or not to build static libraries. build_old_libs=$enable_static # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; "default-1":C) for ac_file in $CONFIG_FILES; do # Support "outfile[:infile[:infile...]]" case "$ac_file" in *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; esac # PO directories have a Makefile.in generated from Makefile.in.in. case "$ac_file" in */Makefile.in) # Adjust a relative srcdir. ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` # In autoconf-2.13 it is called $ac_given_srcdir. # In autoconf-2.50 it is called $srcdir. test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" case "$ac_given_srcdir" in .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; /*) top_srcdir="$ac_given_srcdir" ;; *) top_srcdir="$ac_dots$ac_given_srcdir" ;; esac # Treat a directory as a PO directory if and only if it has a # POTFILES.in file. This allows packages to have multiple PO # directories under different names or in different locations. if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then rm -f "$ac_dir/POTFILES" test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" POMAKEFILEDEPS="POTFILES.in" # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend # on $ac_dir but don't depend on user-specified configuration # parameters. if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then # The LINGUAS file contains the set of available languages. if test -n "$OBSOLETE_ALL_LINGUAS"; then test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" fi ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` # Hide the ALL_LINGUAS assigment from automake. eval 'ALL_LINGUAS''=$ALL_LINGUAS_' POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" else # The set of available languages was given in configure.in. eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' fi # Compute POFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) # Compute UPDATEPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) # Compute DUMMYPOFILES # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) # Compute GMOFILES # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) case "$ac_given_srcdir" in .) srcdirpre= ;; *) srcdirpre='$(srcdir)/' ;; esac POFILES= UPDATEPOFILES= DUMMYPOFILES= GMOFILES= for lang in $ALL_LINGUAS; do POFILES="$POFILES $srcdirpre$lang.po" UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" DUMMYPOFILES="$DUMMYPOFILES $lang.nop" GMOFILES="$GMOFILES $srcdirpre$lang.gmo" done # CATALOGS depends on both $ac_dir and the user's LINGUAS # environment variable. INST_LINGUAS= if test -n "$ALL_LINGUAS"; then for presentlang in $ALL_LINGUAS; do useit=no if test "%UNSET%" != "$LINGUAS"; then desiredlanguages="$LINGUAS" else desiredlanguages="$ALL_LINGUAS" fi for desiredlang in $desiredlanguages; do # Use the presentlang catalog if desiredlang is # a. equal to presentlang, or # b. a variant of presentlang (because in this case, # presentlang can be used as a fallback for messages # which are not translated in the desiredlang catalog). case "$desiredlang" in "$presentlang"*) useit=yes;; esac done if test $useit = yes; then INST_LINGUAS="$INST_LINGUAS $presentlang" fi done fi CATALOGS= if test -n "$INST_LINGUAS"; then for lang in $INST_LINGUAS; do CATALOGS="$CATALOGS $lang.gmo" done fi test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do if test -f "$f"; then case "$f" in *.orig | *.bak | *~) ;; *) cat "$f" >> "$ac_dir/Makefile" ;; esac fi done fi ;; esac done ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi sssd-1.13.4/PaxHeaders.16287/Makefile.in0000644000000000000000000000013112703463544014374 xustar0030 mtime=1460561764.358758717 30 atime=1460561772.459786186 29 ctime=1460561774.61079348 sssd-1.13.4/Makefile.in0000644002412700241270000770267512703463544016101 0ustar00jhrozekjhrozek00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_DEVSHM_TRUE@am__append_1 = --with-test-dir=/dev/shm @WITH_JOURNALD_TRUE@am__append_2 = --with-syslog=journald @HAVE_MANPAGES_TRUE@am__append_3 = src/man @HAVE_DEBIAN_TRUE@am__append_4 = --install-layout=deb @WANT_AUX_INFO_TRUE@am__append_5 = -aux-info $@.X @HAVE_GCC_TRUE@am__append_6 = -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith \ @HAVE_GCC_TRUE@ -Wcast-qual -Wcast-align -Wwrite-strings -Wundef \ @HAVE_GCC_TRUE@ -Werror-implicit-function-declaration -Winit-self \ @HAVE_GCC_TRUE@ -fno-strict-aliasing \ @HAVE_GCC_TRUE@ -std=gnu99 @BUILD_SSH_TRUE@bin_PROGRAMS = sss_ssh_authorizedkeys$(EXEEXT) \ @BUILD_SSH_TRUE@ sss_ssh_knownhostsproxy$(EXEEXT) sbin_PROGRAMS = sssd$(EXEEXT) sss_useradd$(EXEEXT) \ sss_userdel$(EXEEXT) sss_groupadd$(EXEEXT) \ sss_groupdel$(EXEEXT) sss_usermod$(EXEEXT) \ sss_groupmod$(EXEEXT) sss_groupshow$(EXEEXT) \ sss_cache$(EXEEXT) sss_debuglevel$(EXEEXT) \ sss_override$(EXEEXT) sss_seed$(EXEEXT) sssdlibexec_PROGRAMS = sssd_nss$(EXEEXT) sssd_pam$(EXEEXT) \ sssd_be$(EXEEXT) krb5_child$(EXEEXT) ldap_child$(EXEEXT) \ proxy_child$(EXEEXT) sss_signal$(EXEEXT) $(am__EXEEXT_12) \ $(am__EXEEXT_13) $(am__EXEEXT_14) $(am__EXEEXT_15) \ $(am__EXEEXT_16) $(am__EXEEXT_17) $(am__EXEEXT_18) \ $(am__EXEEXT_19) @BUILD_SUDO_TRUE@am__append_7 = sssd_sudo @BUILD_AUTOFS_TRUE@am__append_8 = sssd_autofs @BUILD_SSH_TRUE@am__append_9 = sssd_ssh @BUILD_IFP_TRUE@am__append_10 = sssd_ifp @BUILD_SAMBA_TRUE@am__append_11 = gpo_child @BUILD_SEMANAGE_TRUE@am__append_12 = selinux_child @HAVE_NSS_TRUE@am__append_13 = p11_child @BUILD_PAC_RESPONDER_TRUE@am__append_14 = sssd_pac @BUILD_SSH_TRUE@@HAVE_CHECK_TRUE@am__append_15 = sysdb_ssh-tests @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@@HAVE_CHECK_TRUE@am__append_16 = sss_config-tests @BUILD_DBUS_TESTS_TRUE@@HAVE_CHECK_TRUE@am__append_17 = \ @BUILD_DBUS_TESTS_TRUE@@HAVE_CHECK_TRUE@ sbus_tests \ @BUILD_DBUS_TESTS_TRUE@@HAVE_CHECK_TRUE@ sbus_codegen_tests @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@am__append_18 = test_resolv_fake @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@am__append_19 = ifp_tests @BUILD_SAMBA_TRUE@@HAVE_CMOCKA_TRUE@am__append_20 = \ @BUILD_SAMBA_TRUE@@HAVE_CMOCKA_TRUE@ ad_access_filter_tests \ @BUILD_SAMBA_TRUE@@HAVE_CMOCKA_TRUE@ ad_gpo_tests check_PROGRAMS = stress-tests$(EXEEXT) krb5-child-test$(EXEEXT) \ $(am__EXEEXT_4) $(am__EXEEXT_8) $(am__EXEEXT_9) @HAVE_CMOCKA_TRUE@am__append_21 = dummy-child @BUILD_PYTHON2_BINDINGS_TRUE@am__append_22 = src/config/SSSDConfigTest.py2.sh \ @BUILD_PYTHON2_BINDINGS_TRUE@ src/tests/pyhbac-test.py2.sh \ @BUILD_PYTHON2_BINDINGS_TRUE@ src/tests/pysss_murmur-test.py2.sh \ @BUILD_PYTHON2_BINDINGS_TRUE@ $(NULL) @BUILD_PYTHON3_BINDINGS_TRUE@am__append_23 = src/config/SSSDConfigTest.py3.sh \ @BUILD_PYTHON3_BINDINGS_TRUE@ src/tests/pyhbac-test.py3.sh \ @BUILD_PYTHON3_BINDINGS_TRUE@ src/tests/pysss_murmur-test.py3.sh \ @BUILD_PYTHON3_BINDINGS_TRUE@ $(NULL) TESTS = $(am__EXEEXT_22) $(am__EXEEXT_4) $(am__EXEEXT_8) \ src/tests/whitespace_test @BUILD_SAMBA_TRUE@am__append_24 = \ @BUILD_SAMBA_TRUE@ libsss_ipa.la \ @BUILD_SAMBA_TRUE@ libsss_ad.la @BUILD_SELINUX_TRUE@am__append_25 = $(SELINUX_LIBS) @BUILD_SELINUX_TRUE@am__append_26 = $(SELINUX_LIBS) @HAVE_NSS_TRUE@am__append_27 = src/util/crypto/nss/nss_util.h @BUILD_SUDO_TRUE@am__append_28 = libsss_sudo_doc @BUILD_IFP_TRUE@am__append_29 = sss_simpleifp_doc @HAVE_PTHREAD_TRUE@am__append_30 = -lpthread @BUILD_SUDO_TRUE@am__append_31 = src/db/sysdb_sudo.c @BUILD_SSH_TRUE@am__append_32 = \ @BUILD_SSH_TRUE@ src/db/sysdb_ssh.c \ @BUILD_SSH_TRUE@ src/util/sss_ssh.c @BUILD_SEMANAGE_TRUE@am__append_33 = $(SEMANAGE_LIBS) @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@am__append_34 = libsss_config.la @BUILD_LIBWBCLIENT_TRUE@am__append_35 = src/sss_client/libwbclient/wbclient_sssd.pc @BUILD_LIBWBCLIENT_TRUE@am__append_36 = src/sss_client/libwbclient/wbclient.exports \ @BUILD_LIBWBCLIENT_TRUE@ $(NULL) @BUILD_LIBWBCLIENT_TRUE@am__append_37 = src/sss_client/libwbclient/wbclient_sssd.h @BUILD_IFP_TRUE@am__append_38 = libsss_simpleifp.la @BUILD_IFP_TRUE@am__append_39 = src/lib/sifp/sss_simpleifp.pc @BUILD_IFP_TRUE@am__append_40 = src/lib/sifp/sss_simpleifp.exports @BUILD_IFP_TRUE@am__append_41 = \ @BUILD_IFP_TRUE@ src/lib/sifp/sss_sifp.h \ @BUILD_IFP_TRUE@ src/lib/sifp/sss_sifp_dbus.h @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@am__append_42 = libsss_config.la @HAVE_CHECK_TRUE@am__append_43 = \ @HAVE_CHECK_TRUE@ src/tests/common_check.c @HAVE_CHECK_TRUE@am__append_44 = \ @HAVE_CHECK_TRUE@ libdlopen_test_providers.la \ @HAVE_CHECK_TRUE@ libsss_nss_idmap_tests.la \ @HAVE_CHECK_TRUE@ $(NULL) @BUILD_SAMBA_TRUE@@HAVE_CHECK_TRUE@am__append_45 = libsss_ad_tests.la @HAVE_CHECK_TRUE@am__append_46 = src/sss_client/idmap/sss_nss_idmap.unit_tests @BUILD_SELINUX_TRUE@@HAVE_CHECK_TRUE@am__append_47 = $(SELINUX_LIBS) @BUILD_SEMANAGE_TRUE@@HAVE_CHECK_TRUE@am__append_48 = $(SEMANAGE_LIBS) noinst_PROGRAMS = pam_test_client$(EXEEXT) $(am__EXEEXT_10) \ $(am__EXEEXT_11) @BUILD_SUDO_TRUE@am__append_49 = sss_sudo_cli @BUILD_AUTOFS_TRUE@am__append_50 = autofs_test_client @BUILD_SUDO_TRUE@am__append_51 = src/sss_client/sss_sudo.exports @BUILD_AUTOFS_TRUE@am__append_52 = src/sss_client/autofs/sss_autofs.exports @BUILD_SUDO_TRUE@am__append_53 = \ @BUILD_SUDO_TRUE@ src/providers/ldap/sdap_async_sudo.c \ @BUILD_SUDO_TRUE@ src/providers/ldap/sdap_async_sudo_hostinfo.c \ @BUILD_SUDO_TRUE@ src/providers/ldap/sdap_sudo_refresh.c \ @BUILD_SUDO_TRUE@ src/providers/ldap/sdap_sudo_shared.c \ @BUILD_SUDO_TRUE@ src/providers/ldap/sdap_sudo.c @BUILD_AUTOFS_TRUE@am__append_54 = \ @BUILD_AUTOFS_TRUE@ src/providers/ldap/sdap_autofs.c \ @BUILD_AUTOFS_TRUE@ src/providers/ldap/sdap_async_autofs.c @BUILD_AUTOFS_TRUE@am__append_55 = \ @BUILD_AUTOFS_TRUE@ src/providers/ipa/ipa_autofs.c @BUILD_SUDO_TRUE@am__append_56 = \ @BUILD_SUDO_TRUE@ src/providers/ipa/ipa_sudo.c \ @BUILD_SUDO_TRUE@ src/providers/ipa/ipa_sudo_refresh.c \ @BUILD_SUDO_TRUE@ src/providers/ipa/ipa_sudo_conversion.c \ @BUILD_SUDO_TRUE@ src/providers/ipa/ipa_sudo_async.c @BUILD_SSH_TRUE@am__append_57 = src/providers/ipa/ipa_hostid.c @BUILD_SUDO_TRUE@am__append_58 = \ @BUILD_SUDO_TRUE@ src/providers/ad/ad_sudo.c @BUILD_AUTOFS_TRUE@am__append_59 = \ @BUILD_AUTOFS_TRUE@ src/providers/ad/ad_autofs.c @HAVE_SYSTEMD_UNIT_TRUE@am__append_60 = \ @HAVE_SYSTEMD_UNIT_TRUE@ src/sysv/systemd/sssd.service @HAVE_SYSTEMD_UNIT_TRUE@@WITH_JOURNALD_TRUE@am__append_61 = \ @HAVE_SYSTEMD_UNIT_TRUE@@WITH_JOURNALD_TRUE@ src/sysv/systemd/journal.conf @HAVE_SUSE_TRUE@@HAVE_SYSTEMD_UNIT_FALSE@am__append_62 = \ @HAVE_SUSE_TRUE@@HAVE_SYSTEMD_UNIT_FALSE@ src/sysv/SUSE/sssd @HAVE_GENTOO_TRUE@@HAVE_SUSE_FALSE@@HAVE_SYSTEMD_UNIT_FALSE@am__append_63 = \ @HAVE_GENTOO_TRUE@@HAVE_SUSE_FALSE@@HAVE_SYSTEMD_UNIT_FALSE@ src/sysv/gentoo/sssd @HAVE_GENTOO_FALSE@@HAVE_SUSE_FALSE@@HAVE_SYSTEMD_UNIT_FALSE@am__append_64 = \ @HAVE_GENTOO_FALSE@@HAVE_SUSE_FALSE@@HAVE_SYSTEMD_UNIT_FALSE@ src/sysv/sssd subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ $(top_srcdir)/version.m4 $(top_srcdir)/src/build_macros.m4 \ $(top_srcdir)/src/external/platform.m4 \ $(top_srcdir)/src/conf_macros.m4 \ $(top_srcdir)/src/external/pkg.m4 \ $(top_srcdir)/src/external/libpopt.m4 \ $(top_srcdir)/src/external/libtalloc.m4 \ $(top_srcdir)/src/external/libtdb.m4 \ $(top_srcdir)/src/external/libtevent.m4 \ $(top_srcdir)/src/external/libldb.m4 \ $(top_srcdir)/src/external/libdhash.m4 \ $(top_srcdir)/src/external/libcollection.m4 \ $(top_srcdir)/src/external/libini_config.m4 \ $(top_srcdir)/src/external/pam.m4 \ $(top_srcdir)/src/external/ldap.m4 \ $(top_srcdir)/src/external/libpcre.m4 \ $(top_srcdir)/src/external/krb5.m4 \ $(top_srcdir)/src/external/libcares.m4 \ $(top_srcdir)/src/external/libcmocka.m4 \ $(top_srcdir)/src/external/docbook.m4 \ $(top_srcdir)/src/external/sizes.m4 \ $(top_srcdir)/src/external/python.m4 \ $(top_srcdir)/src/external/selinux.m4 \ $(top_srcdir)/src/external/crypto.m4 \ $(top_srcdir)/src/external/nscd.m4 \ $(top_srcdir)/src/external/nsupdate.m4 \ $(top_srcdir)/src/external/libkeyutils.m4 \ $(top_srcdir)/src/external/libnl.m4 \ $(top_srcdir)/src/external/systemd.m4 \ $(top_srcdir)/src/external/pac_responder.m4 \ $(top_srcdir)/src/external/cifsidmap.m4 \ $(top_srcdir)/src/external/signal.m4 \ $(top_srcdir)/src/external/inotify.m4 \ $(top_srcdir)/src/external/samba.m4 \ $(top_srcdir)/src/external/sasl.m4 \ $(top_srcdir)/src/external/configlib.m4 \ $(top_srcdir)/src/external/libnfsidmap.m4 \ $(top_srcdir)/src/external/cwrap.m4 \ $(top_srcdir)/src/external/libresolv.m4 \ $(top_srcdir)/src/external/intgcheck.m4 \ $(top_srcdir)/src/external/libaugeas.m4 \ $(top_srcdir)/src/external/libunistring.m4 \ $(top_srcdir)/src/external/glib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(dist_noinst_SCRIPTS) \ $(am__dist_sss_obfuscate_python_SCRIPTS_DIST) \ $(am__dist_dbuspolicy_DATA_DIST) \ $(am__dist_dbusservice_DATA_DIST) $(am__dist_noinst_DATA_DIST) \ $(am__dist_polkit_rules_DATA_DIST) $(dist_sssdapiplugin_DATA) \ $(dist_sssddata_DATA) $(am__dist_noinst_HEADERS_DIST) \ $(am__include_HEADERS_DIST) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = contrib/sssd.spec src/examples/rwtab \ src/doxy.config contrib/sssd-pcsc.rules src/sysv/sssd \ src/sysv/gentoo/sssd src/sysv/SUSE/sssd \ src/providers/ipa/ipa_hbac.pc src/providers/ipa/ipa_hbac.doxy \ src/lib/idmap/sss_idmap.pc src/lib/idmap/sss_idmap.doxy \ src/sss_client/sudo/sss_sudo.doxy \ src/sss_client/idmap/sss_nss_idmap.pc \ src/sss_client/idmap/sss_nss_idmap.doxy \ src/sss_client/libwbclient/wbclient_sssd.pc \ src/lib/sifp/sss_simpleifp.pc src/lib/sifp/sss_simpleifp.doxy \ src/config/setup.py \ src/responder/ifp/org.freedesktop.sssd.infopipe.service \ src/config/SSSDConfig/__init__.py CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(autofslibdir)" \ "$(DESTDIR)$(cifsplugindir)" \ "$(DESTDIR)$(krb5authdata_plugindir)" \ "$(DESTDIR)$(krb5localauth_plugindir)" \ "$(DESTDIR)$(krb5plugindir)" "$(DESTDIR)$(ldblibdir)" \ "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libwbclientdir)" \ "$(DESTDIR)$(nfslibdir)" "$(DESTDIR)$(nsslibdir)" \ "$(DESTDIR)$(pamlibdir)" "$(DESTDIR)$(pkglibdir)" \ "$(DESTDIR)$(py2execdir)" "$(DESTDIR)$(py3execdir)" \ "$(DESTDIR)$(sssdlibdir)" "$(DESTDIR)$(sudolibdir)" \ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" \ "$(DESTDIR)$(sssdlibexecdir)" \ "$(DESTDIR)$(sss_obfuscate_pythondir)" "$(DESTDIR)$(initdir)" \ "$(DESTDIR)$(dbuspolicydir)" "$(DESTDIR)$(dbusservicedir)" \ "$(DESTDIR)$(polkit_rulesdir)" "$(DESTDIR)$(sssdapiplugindir)" \ "$(DESTDIR)$(sssddatadir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(systemdconfdir)" "$(DESTDIR)$(systemdunitdir)" \ "$(DESTDIR)$(includedir)" LTLIBRARIES = $(autofslib_LTLIBRARIES) $(cifsplugin_LTLIBRARIES) \ $(krb5authdata_plugin_LTLIBRARIES) \ $(krb5localauth_plugin_LTLIBRARIES) $(krb5plugin_LTLIBRARIES) \ $(ldblib_LTLIBRARIES) $(lib_LTLIBRARIES) \ $(libwbclient_LTLIBRARIES) $(nfslib_LTLIBRARIES) \ $(noinst_LTLIBRARIES) $(nsslib_LTLIBRARIES) \ $(pamlib_LTLIBRARIES) $(pkglib_LTLIBRARIES) \ $(py2exec_LTLIBRARIES) $(py3exec_LTLIBRARIES) \ $(sssdlib_LTLIBRARIES) $(sudolib_LTLIBRARIES) am__DEPENDENCIES_1 = _py2hbac_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libipa_hbac.la am__dirstamp = $(am__leading_dot)dirstamp am__objects_1 = src/python/_py2hbac_la-pyhbac.lo \ src/util/_py2hbac_la-sss_python.lo am__py2hbac_la_OBJECTS = $(am__objects_1) _py2hbac_la_OBJECTS = $(am__py2hbac_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = _py2hbac_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(_py2hbac_la_CFLAGS) \ $(CFLAGS) $(_py2hbac_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_PYTHON2_BINDINGS_TRUE@am__py2hbac_la_rpath = -rpath \ @BUILD_PYTHON2_BINDINGS_TRUE@ $(py2execdir) am__DEPENDENCIES_2 = libsss_util.la libsss_crypt.la libsss_debug.la \ libsss_child.la @BUILD_SELINUX_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_3) _py2sss_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_4) \ $(am__DEPENDENCIES_1) am__objects_2 = src/tools/_py2sss_la-sss_sync_ops.lo \ src/tools/_py2sss_la-tools_util.lo \ src/tools/_py2sss_la-files.lo src/tools/_py2sss_la-selinux.lo \ src/tools/common/_py2sss_la-sss_tools.lo \ src/util/_py2sss_la-nscd.lo am__objects_3 = $(am__objects_2) src/python/_py2sss_la-pysss.lo am__py2sss_la_OBJECTS = $(am__objects_3) _py2sss_la_OBJECTS = $(am__py2sss_la_OBJECTS) _py2sss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(_py2sss_la_CFLAGS) \ $(CFLAGS) $(_py2sss_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_PYTHON2_BINDINGS_TRUE@am__py2sss_la_rpath = -rpath \ @BUILD_PYTHON2_BINDINGS_TRUE@ $(py2execdir) _py2sss_murmur_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__objects_4 = src/python/_py2sss_murmur_la-pysss_murmur.lo \ src/util/_py2sss_murmur_la-murmurhash3.lo am__py2sss_murmur_la_OBJECTS = $(am__objects_4) _py2sss_murmur_la_OBJECTS = $(am__py2sss_murmur_la_OBJECTS) _py2sss_murmur_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(_py2sss_murmur_la_CFLAGS) $(CFLAGS) \ $(_py2sss_murmur_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_PYTHON2_BINDINGS_TRUE@am__py2sss_murmur_la_rpath = -rpath \ @BUILD_PYTHON2_BINDINGS_TRUE@ $(py2execdir) _py2sss_nss_idmap_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ libsss_nss_idmap.la am__objects_5 = src/python/_py2sss_nss_idmap_la-pysss_nss_idmap.lo am__py2sss_nss_idmap_la_OBJECTS = $(am__objects_5) _py2sss_nss_idmap_la_OBJECTS = $(am__py2sss_nss_idmap_la_OBJECTS) _py2sss_nss_idmap_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(_py2sss_nss_idmap_la_CFLAGS) $(CFLAGS) \ $(_py2sss_nss_idmap_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_PYTHON2_BINDINGS_TRUE@am__py2sss_nss_idmap_la_rpath = -rpath \ @BUILD_PYTHON2_BINDINGS_TRUE@ $(py2execdir) _py3hbac_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libipa_hbac.la am__objects_6 = src/python/_py3hbac_la-pyhbac.lo \ src/util/_py3hbac_la-sss_python.lo am__py3hbac_la_OBJECTS = $(am__objects_6) _py3hbac_la_OBJECTS = $(am__py3hbac_la_OBJECTS) _py3hbac_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(_py3hbac_la_CFLAGS) \ $(CFLAGS) $(_py3hbac_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_PYTHON3_BINDINGS_TRUE@am__py3hbac_la_rpath = -rpath \ @BUILD_PYTHON3_BINDINGS_TRUE@ $(py3execdir) _py3sss_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_4) \ $(am__DEPENDENCIES_1) am__objects_7 = src/tools/_py3sss_la-sss_sync_ops.lo \ src/tools/_py3sss_la-tools_util.lo \ src/tools/_py3sss_la-files.lo src/tools/_py3sss_la-selinux.lo \ src/tools/common/_py3sss_la-sss_tools.lo \ src/util/_py3sss_la-nscd.lo am__objects_8 = $(am__objects_7) src/python/_py3sss_la-pysss.lo am__py3sss_la_OBJECTS = $(am__objects_8) _py3sss_la_OBJECTS = $(am__py3sss_la_OBJECTS) _py3sss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(_py3sss_la_CFLAGS) \ $(CFLAGS) $(_py3sss_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_PYTHON3_BINDINGS_TRUE@am__py3sss_la_rpath = -rpath \ @BUILD_PYTHON3_BINDINGS_TRUE@ $(py3execdir) _py3sss_murmur_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__objects_9 = src/python/_py3sss_murmur_la-pysss_murmur.lo \ src/util/_py3sss_murmur_la-murmurhash3.lo am__py3sss_murmur_la_OBJECTS = $(am__objects_9) _py3sss_murmur_la_OBJECTS = $(am__py3sss_murmur_la_OBJECTS) _py3sss_murmur_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(_py3sss_murmur_la_CFLAGS) $(CFLAGS) \ $(_py3sss_murmur_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_PYTHON3_BINDINGS_TRUE@am__py3sss_murmur_la_rpath = -rpath \ @BUILD_PYTHON3_BINDINGS_TRUE@ $(py3execdir) _py3sss_nss_idmap_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ libsss_nss_idmap.la am__objects_10 = src/python/_py3sss_nss_idmap_la-pysss_nss_idmap.lo am__py3sss_nss_idmap_la_OBJECTS = $(am__objects_10) _py3sss_nss_idmap_la_OBJECTS = $(am__py3sss_nss_idmap_la_OBJECTS) _py3sss_nss_idmap_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(_py3sss_nss_idmap_la_CFLAGS) $(CFLAGS) \ $(_py3sss_nss_idmap_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_PYTHON3_BINDINGS_TRUE@am__py3sss_nss_idmap_la_rpath = -rpath \ @BUILD_PYTHON3_BINDINGS_TRUE@ $(py3execdir) @BUILD_CIFS_IDMAP_PLUGIN_TRUE@cifs_idmap_sss_la_DEPENDENCIES = \ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@ libsss_idmap.la \ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@ libsss_nss_idmap.la am__cifs_idmap_sss_la_SOURCES_DIST = \ src/lib/cifs_idmap_sss/cifs_idmap_sss.c @BUILD_CIFS_IDMAP_PLUGIN_TRUE@am_cifs_idmap_sss_la_OBJECTS = src/lib/cifs_idmap_sss/cifs_idmap_sss_la-cifs_idmap_sss.lo cifs_idmap_sss_la_OBJECTS = $(am_cifs_idmap_sss_la_OBJECTS) cifs_idmap_sss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(cifs_idmap_sss_la_CFLAGS) $(CFLAGS) \ $(cifs_idmap_sss_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@am_cifs_idmap_sss_la_rpath = -rpath \ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@ $(cifsplugindir) am__DEPENDENCIES_5 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) @HAVE_CHECK_TRUE@libdlopen_test_providers_la_DEPENDENCIES = \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) am__libdlopen_test_providers_la_SOURCES_DIST = \ src/providers/data_provider_be.c \ src/providers/data_provider_req.c \ src/providers/data_provider_fo.c \ src/providers/data_provider_opts.c \ src/providers/data_provider_callbacks.c \ src/providers/dp_dyndns.c src/providers/dp_ptask.c \ src/providers/dp_refresh.c \ src/monitor/monitor_iface_generated.c \ src/monitor/monitor_iface_generated.h \ src/providers/data_provider_iface_generated.c \ src/providers/data_provider_iface_generated.h \ src/providers/fail_over.c src/providers/fail_over_srv.c \ src/resolv/async_resolv.c src/resolv/async_resolv_utils.c am__objects_11 = \ src/resolv/libdlopen_test_providers_la-async_resolv.lo \ src/resolv/libdlopen_test_providers_la-async_resolv_utils.lo am__objects_12 = \ src/providers/libdlopen_test_providers_la-fail_over.lo \ src/providers/libdlopen_test_providers_la-fail_over_srv.lo \ $(am__objects_11) am__objects_13 = \ src/providers/libdlopen_test_providers_la-data_provider_be.lo \ src/providers/libdlopen_test_providers_la-data_provider_req.lo \ src/providers/libdlopen_test_providers_la-data_provider_fo.lo \ src/providers/libdlopen_test_providers_la-data_provider_opts.lo \ src/providers/libdlopen_test_providers_la-data_provider_callbacks.lo \ src/providers/libdlopen_test_providers_la-dp_dyndns.lo \ src/providers/libdlopen_test_providers_la-dp_ptask.lo \ src/providers/libdlopen_test_providers_la-dp_refresh.lo \ src/monitor/libdlopen_test_providers_la-monitor_iface_generated.lo \ src/providers/libdlopen_test_providers_la-data_provider_iface_generated.lo \ $(am__objects_12) @HAVE_CHECK_TRUE@am_libdlopen_test_providers_la_OBJECTS = \ @HAVE_CHECK_TRUE@ $(am__objects_13) libdlopen_test_providers_la_OBJECTS = \ $(am_libdlopen_test_providers_la_OBJECTS) libdlopen_test_providers_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) \ $(libdlopen_test_providers_la_LDFLAGS) $(LDFLAGS) -o $@ @HAVE_CHECK_TRUE@am_libdlopen_test_providers_la_rpath = am_libipa_hbac_la_OBJECTS = src/providers/ipa/hbac_evaluator.lo \ src/util/sss_utf8.lo libipa_hbac_la_OBJECTS = $(am_libipa_hbac_la_OBJECTS) libipa_hbac_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libipa_hbac_la_LDFLAGS) $(LDFLAGS) -o \ $@ am__DEPENDENCIES_6 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) libnss_sss_la_DEPENDENCIES = $(am__DEPENDENCIES_6) am_libnss_sss_la_OBJECTS = src/sss_client/common.lo \ src/sss_client/nss_passwd.lo src/sss_client/nss_group.lo \ src/sss_client/nss_netgroup.lo src/sss_client/nss_services.lo \ src/sss_client/nss_mc_common.lo src/util/io.lo \ src/util/murmurhash3.lo src/sss_client/nss_mc_passwd.lo \ src/sss_client/nss_mc_group.lo src/sss_client/nss_mc_initgr.lo libnss_sss_la_OBJECTS = $(am_libnss_sss_la_OBJECTS) libnss_sss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libnss_sss_la_LDFLAGS) $(LDFLAGS) -o $@ libsss_ad_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \ libsss_ldap_common.la libsss_krb5_common.la libsss_idmap.la am__libsss_ad_la_SOURCES_DIST = src/providers/ad/ad_opts.c \ src/providers/ad/ad_common.c src/providers/ad/ad_common.h \ src/providers/ad/ad_init.c src/providers/ad/ad_dyndns.c \ src/providers/ad/ad_machine_pw_renewal.c \ src/providers/ad/ad_id.c src/providers/ad/ad_id.h \ src/providers/ad/ad_access.c src/providers/ad/ad_access.h \ src/providers/ad/ad_gpo.c src/providers/ad/ad_gpo.h \ src/providers/ad/ad_gpo_ndr.c src/providers/ad/ad_opts.h \ src/providers/ad/ad_srv.c src/providers/ad/ad_subdomains.c \ src/providers/ad/ad_subdomains.h \ src/providers/ad/ad_domain_info.c \ src/providers/ad/ad_domain_info.h src/providers/ad/ad_sudo.c \ src/providers/ad/ad_autofs.c @BUILD_SUDO_TRUE@am__objects_14 = \ @BUILD_SUDO_TRUE@ src/providers/ad/libsss_ad_la-ad_sudo.lo @BUILD_AUTOFS_TRUE@am__objects_15 = \ @BUILD_AUTOFS_TRUE@ src/providers/ad/libsss_ad_la-ad_autofs.lo am_libsss_ad_la_OBJECTS = src/providers/ad/libsss_ad_la-ad_opts.lo \ src/providers/ad/libsss_ad_la-ad_common.lo \ src/providers/ad/libsss_ad_la-ad_init.lo \ src/providers/ad/libsss_ad_la-ad_dyndns.lo \ src/providers/ad/libsss_ad_la-ad_machine_pw_renewal.lo \ src/providers/ad/libsss_ad_la-ad_id.lo \ src/providers/ad/libsss_ad_la-ad_access.lo \ src/providers/ad/libsss_ad_la-ad_gpo.lo \ src/providers/ad/libsss_ad_la-ad_gpo_ndr.lo \ src/providers/ad/libsss_ad_la-ad_srv.lo \ src/providers/ad/libsss_ad_la-ad_subdomains.lo \ src/providers/ad/libsss_ad_la-ad_domain_info.lo \ $(am__objects_14) $(am__objects_15) libsss_ad_la_OBJECTS = $(am_libsss_ad_la_OBJECTS) libsss_ad_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libsss_ad_la_CFLAGS) \ $(CFLAGS) $(libsss_ad_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_SAMBA_TRUE@am_libsss_ad_la_rpath = -rpath $(sssdlibdir) am__DEPENDENCIES_7 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_1) libsss_ldap_common.la \ libsss_krb5_common.la libsss_idmap.la @HAVE_CHECK_TRUE@libsss_ad_tests_la_DEPENDENCIES = \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_7) am__libsss_ad_tests_la_SOURCES_DIST = src/providers/ad/ad_opts.c \ src/providers/ad/ad_common.c src/providers/ad/ad_common.h \ src/providers/ad/ad_init.c src/providers/ad/ad_dyndns.c \ src/providers/ad/ad_machine_pw_renewal.c \ src/providers/ad/ad_id.c src/providers/ad/ad_id.h \ src/providers/ad/ad_access.c src/providers/ad/ad_access.h \ src/providers/ad/ad_gpo.c src/providers/ad/ad_gpo.h \ src/providers/ad/ad_gpo_ndr.c src/providers/ad/ad_opts.h \ src/providers/ad/ad_srv.c src/providers/ad/ad_subdomains.c \ src/providers/ad/ad_subdomains.h \ src/providers/ad/ad_domain_info.c \ src/providers/ad/ad_domain_info.h src/providers/ad/ad_sudo.c \ src/providers/ad/ad_autofs.c @BUILD_SUDO_TRUE@am__objects_16 = src/providers/ad/libsss_ad_tests_la-ad_sudo.lo @BUILD_AUTOFS_TRUE@am__objects_17 = src/providers/ad/libsss_ad_tests_la-ad_autofs.lo am__objects_18 = src/providers/ad/libsss_ad_tests_la-ad_opts.lo \ src/providers/ad/libsss_ad_tests_la-ad_common.lo \ src/providers/ad/libsss_ad_tests_la-ad_init.lo \ src/providers/ad/libsss_ad_tests_la-ad_dyndns.lo \ src/providers/ad/libsss_ad_tests_la-ad_machine_pw_renewal.lo \ src/providers/ad/libsss_ad_tests_la-ad_id.lo \ src/providers/ad/libsss_ad_tests_la-ad_access.lo \ src/providers/ad/libsss_ad_tests_la-ad_gpo.lo \ src/providers/ad/libsss_ad_tests_la-ad_gpo_ndr.lo \ src/providers/ad/libsss_ad_tests_la-ad_srv.lo \ src/providers/ad/libsss_ad_tests_la-ad_subdomains.lo \ src/providers/ad/libsss_ad_tests_la-ad_domain_info.lo \ $(am__objects_16) $(am__objects_17) @HAVE_CHECK_TRUE@am_libsss_ad_tests_la_OBJECTS = $(am__objects_18) libsss_ad_tests_la_OBJECTS = $(am_libsss_ad_tests_la_OBJECTS) libsss_ad_tests_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) \ $(libsss_ad_tests_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_SAMBA_TRUE@@HAVE_CHECK_TRUE@am_libsss_ad_tests_la_rpath = @BUILD_AUTOFS_TRUE@libsss_autofs_la_DEPENDENCIES = \ @BUILD_AUTOFS_TRUE@ $(am__DEPENDENCIES_6) am__libsss_autofs_la_SOURCES_DIST = src/sss_client/common.c \ src/sss_client/sss_cli.h src/sss_client/autofs/sss_autofs.c \ src/sss_client/autofs/sss_autofs_private.h @BUILD_AUTOFS_TRUE@am_libsss_autofs_la_OBJECTS = \ @BUILD_AUTOFS_TRUE@ src/sss_client/common.lo \ @BUILD_AUTOFS_TRUE@ src/sss_client/autofs/sss_autofs.lo libsss_autofs_la_OBJECTS = $(am_libsss_autofs_la_OBJECTS) libsss_autofs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libsss_autofs_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILD_AUTOFS_TRUE@am_libsss_autofs_la_rpath = -rpath $(autofslibdir) @HAVE_NSS_FALSE@am__DEPENDENCIES_8 = $(am__DEPENDENCIES_1) @HAVE_NSS_TRUE@am__DEPENDENCIES_8 = $(am__DEPENDENCIES_1) libsss_cert_la_DEPENDENCIES = $(am__DEPENDENCIES_8) \ $(am__DEPENDENCIES_1) libsss_crypt.la libsss_debug.la am__libsss_cert_la_SOURCES_DIST = src/util/cert/cert_common.c \ src/util/cert/libcrypto/cert.c src/util/cert/nss/cert.c @HAVE_NSS_FALSE@am__objects_19 = \ @HAVE_NSS_FALSE@ src/util/cert/libsss_cert_la-cert_common.lo \ @HAVE_NSS_FALSE@ src/util/cert/libcrypto/libsss_cert_la-cert.lo @HAVE_NSS_TRUE@am__objects_19 = \ @HAVE_NSS_TRUE@ src/util/cert/libsss_cert_la-cert_common.lo \ @HAVE_NSS_TRUE@ src/util/cert/nss/libsss_cert_la-cert.lo am_libsss_cert_la_OBJECTS = $(am__objects_19) libsss_cert_la_OBJECTS = $(am_libsss_cert_la_OBJECTS) libsss_cert_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_cert_la_CFLAGS) $(CFLAGS) $(libsss_cert_la_LDFLAGS) \ $(LDFLAGS) -o $@ libsss_child_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) libsss_debug.la am_libsss_child_la_OBJECTS = src/util/child_common.lo libsss_child_la_OBJECTS = $(am_libsss_child_la_OBJECTS) libsss_child_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libsss_child_la_LDFLAGS) $(LDFLAGS) \ -o $@ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@libsss_config_la_DEPENDENCIES = \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(am__DEPENDENCIES_2) am__libsss_config_la_SOURCES_DIST = src/util/sss_config.c @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@am_libsss_config_la_OBJECTS = src/util/libsss_config_la-sss_config.lo libsss_config_la_OBJECTS = $(am_libsss_config_la_OBJECTS) libsss_config_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_config_la_CFLAGS) $(CFLAGS) \ $(libsss_config_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@am_libsss_config_la_rpath = \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ -rpath $(pkglibdir) libsss_crypt_la_DEPENDENCIES = $(am__DEPENDENCIES_8) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) libsss_debug.la am__libsss_crypt_la_SOURCES_DIST = \ src/util/crypto/libcrypto/crypto_base64.c \ src/util/crypto/libcrypto/crypto_hmac_sha1.c \ src/util/crypto/libcrypto/crypto_sha512crypt.c \ src/util/crypto/libcrypto/crypto_obfuscate.c \ src/util/crypto/nss/nss_base64.c \ src/util/crypto/nss/nss_hmac_sha1.c \ src/util/crypto/nss/nss_sha512crypt.c \ src/util/crypto/nss/nss_obfuscate.c \ src/util/crypto/nss/nss_util.c @HAVE_NSS_FALSE@am__objects_20 = src/util/crypto/libcrypto/libsss_crypt_la-crypto_base64.lo \ @HAVE_NSS_FALSE@ src/util/crypto/libcrypto/libsss_crypt_la-crypto_hmac_sha1.lo \ @HAVE_NSS_FALSE@ src/util/crypto/libcrypto/libsss_crypt_la-crypto_sha512crypt.lo \ @HAVE_NSS_FALSE@ src/util/crypto/libcrypto/libsss_crypt_la-crypto_obfuscate.lo @HAVE_NSS_TRUE@am__objects_20 = src/util/crypto/nss/libsss_crypt_la-nss_base64.lo \ @HAVE_NSS_TRUE@ src/util/crypto/nss/libsss_crypt_la-nss_hmac_sha1.lo \ @HAVE_NSS_TRUE@ src/util/crypto/nss/libsss_crypt_la-nss_sha512crypt.lo \ @HAVE_NSS_TRUE@ src/util/crypto/nss/libsss_crypt_la-nss_obfuscate.lo \ @HAVE_NSS_TRUE@ src/util/crypto/nss/libsss_crypt_la-nss_util.lo am_libsss_crypt_la_OBJECTS = $(am__objects_20) libsss_crypt_la_OBJECTS = $(am_libsss_crypt_la_OBJECTS) libsss_crypt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_crypt_la_CFLAGS) $(CFLAGS) $(libsss_crypt_la_LDFLAGS) \ $(LDFLAGS) -o $@ @WITH_JOURNALD_TRUE@am__DEPENDENCIES_9 = $(am__DEPENDENCIES_1) libsss_debug_la_DEPENDENCIES = $(am__DEPENDENCIES_9) am_libsss_debug_la_OBJECTS = src/util/debug.lo src/util/sss_log.lo \ src/util/sss_cli_cmd.lo libsss_debug_la_OBJECTS = $(am_libsss_debug_la_OBJECTS) libsss_debug_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libsss_debug_la_LDFLAGS) $(LDFLAGS) \ -o $@ libsss_idmap_la_LIBADD = am_libsss_idmap_la_OBJECTS = src/lib/idmap/sss_idmap.lo \ src/lib/idmap/sss_idmap_conv.lo src/util/murmurhash3.lo libsss_idmap_la_OBJECTS = $(am_libsss_idmap_la_OBJECTS) libsss_idmap_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libsss_idmap_la_LDFLAGS) $(LDFLAGS) \ -o $@ libsss_ipa_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) libsss_ldap_common.la \ libsss_krb5_common.la libipa_hbac.la libsss_idmap.la \ libsss_semanage.la am__libsss_ipa_la_SOURCES_DIST = src/providers/ipa/ipa_init.c \ src/providers/ipa/ipa_opts.c src/providers/ipa/ipa_common.c \ src/providers/ipa/ipa_config.c src/providers/ipa/ipa_id.c \ src/providers/ipa/ipa_netgroups.c src/providers/ipa/ipa_auth.c \ src/providers/ipa/ipa_access.c src/providers/ipa/ipa_dyndns.c \ src/providers/ipa/ipa_hosts.c \ src/providers/ipa/ipa_subdomains.c \ src/providers/ipa/ipa_subdomains_id.c \ src/providers/ipa/ipa_subdomains_server.c \ src/providers/ipa/ipa_subdomains_utils.c \ src/providers/ipa/ipa_subdomains_ext_groups.c \ src/providers/ipa/ipa_views.c src/providers/ipa/ipa_utils.c \ src/providers/ipa/ipa_s2n_exop.c \ src/providers/ipa/ipa_hbac_hosts.c \ src/providers/ipa/ipa_hbac_private.h \ src/providers/ipa/ipa_hbac_rules.c \ src/providers/ipa/ipa_hbac_rules.h \ src/providers/ipa/ipa_hbac_services.c \ src/providers/ipa/ipa_hbac_users.c \ src/providers/ipa/ipa_hbac_common.c \ src/providers/ipa/ipa_selinux.c \ src/providers/ipa/ipa_selinux_maps.c \ src/providers/ipa/ipa_srv.c src/providers/ipa/ipa_idmap.c \ src/providers/ipa/ipa_dn.c src/providers/ad/ad_opts.c \ src/providers/ad/ad_common.c src/providers/ad/ad_common.h \ src/providers/ad/ad_dyndns.c src/providers/ad/ad_id.c \ src/providers/ad/ad_srv.c src/providers/ad/ad_domain_info.c \ src/providers/ipa/ipa_autofs.c src/providers/ipa/ipa_sudo.c \ src/providers/ipa/ipa_sudo_refresh.c \ src/providers/ipa/ipa_sudo_conversion.c \ src/providers/ipa/ipa_sudo_async.c \ src/providers/ipa/ipa_hostid.c @BUILD_AUTOFS_TRUE@am__objects_21 = src/providers/ipa/libsss_ipa_la-ipa_autofs.lo @BUILD_SUDO_TRUE@am__objects_22 = \ @BUILD_SUDO_TRUE@ src/providers/ipa/libsss_ipa_la-ipa_sudo.lo \ @BUILD_SUDO_TRUE@ src/providers/ipa/libsss_ipa_la-ipa_sudo_refresh.lo \ @BUILD_SUDO_TRUE@ src/providers/ipa/libsss_ipa_la-ipa_sudo_conversion.lo \ @BUILD_SUDO_TRUE@ src/providers/ipa/libsss_ipa_la-ipa_sudo_async.lo @BUILD_SSH_TRUE@am__objects_23 = \ @BUILD_SSH_TRUE@ src/providers/ipa/libsss_ipa_la-ipa_hostid.lo am_libsss_ipa_la_OBJECTS = \ src/providers/ipa/libsss_ipa_la-ipa_init.lo \ src/providers/ipa/libsss_ipa_la-ipa_opts.lo \ src/providers/ipa/libsss_ipa_la-ipa_common.lo \ src/providers/ipa/libsss_ipa_la-ipa_config.lo \ src/providers/ipa/libsss_ipa_la-ipa_id.lo \ src/providers/ipa/libsss_ipa_la-ipa_netgroups.lo \ src/providers/ipa/libsss_ipa_la-ipa_auth.lo \ src/providers/ipa/libsss_ipa_la-ipa_access.lo \ src/providers/ipa/libsss_ipa_la-ipa_dyndns.lo \ src/providers/ipa/libsss_ipa_la-ipa_hosts.lo \ src/providers/ipa/libsss_ipa_la-ipa_subdomains.lo \ src/providers/ipa/libsss_ipa_la-ipa_subdomains_id.lo \ src/providers/ipa/libsss_ipa_la-ipa_subdomains_server.lo \ src/providers/ipa/libsss_ipa_la-ipa_subdomains_utils.lo \ src/providers/ipa/libsss_ipa_la-ipa_subdomains_ext_groups.lo \ src/providers/ipa/libsss_ipa_la-ipa_views.lo \ src/providers/ipa/libsss_ipa_la-ipa_utils.lo \ src/providers/ipa/libsss_ipa_la-ipa_s2n_exop.lo \ src/providers/ipa/libsss_ipa_la-ipa_hbac_hosts.lo \ src/providers/ipa/libsss_ipa_la-ipa_hbac_rules.lo \ src/providers/ipa/libsss_ipa_la-ipa_hbac_services.lo \ src/providers/ipa/libsss_ipa_la-ipa_hbac_users.lo \ src/providers/ipa/libsss_ipa_la-ipa_hbac_common.lo \ src/providers/ipa/libsss_ipa_la-ipa_selinux.lo \ src/providers/ipa/libsss_ipa_la-ipa_selinux_maps.lo \ src/providers/ipa/libsss_ipa_la-ipa_srv.lo \ src/providers/ipa/libsss_ipa_la-ipa_idmap.lo \ src/providers/ipa/libsss_ipa_la-ipa_dn.lo \ src/providers/ad/libsss_ipa_la-ad_opts.lo \ src/providers/ad/libsss_ipa_la-ad_common.lo \ src/providers/ad/libsss_ipa_la-ad_dyndns.lo \ src/providers/ad/libsss_ipa_la-ad_id.lo \ src/providers/ad/libsss_ipa_la-ad_srv.lo \ src/providers/ad/libsss_ipa_la-ad_domain_info.lo \ $(am__objects_21) $(am__objects_22) $(am__objects_23) libsss_ipa_la_OBJECTS = $(am_libsss_ipa_la_OBJECTS) libsss_ipa_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libsss_ipa_la_CFLAGS) \ $(CFLAGS) $(libsss_ipa_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_SAMBA_TRUE@am_libsss_ipa_la_rpath = -rpath $(sssdlibdir) libsss_krb5_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ libsss_krb5_common.la am_libsss_krb5_la_OBJECTS = \ src/providers/krb5/libsss_krb5_la-krb5_init.lo libsss_krb5_la_OBJECTS = $(am_libsss_krb5_la_OBJECTS) libsss_krb5_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_krb5_la_CFLAGS) $(CFLAGS) $(libsss_krb5_la_LDFLAGS) \ $(LDFLAGS) -o $@ libsss_krb5_common_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libsss_krb5_common_la_OBJECTS = \ src/providers/krb5/libsss_krb5_common_la-krb5_utils.lo \ src/providers/krb5/libsss_krb5_common_la-krb5_delayed_online_authentication.lo \ src/providers/krb5/libsss_krb5_common_la-krb5_renew_tgt.lo \ src/providers/krb5/libsss_krb5_common_la-krb5_wait_queue.lo \ src/providers/krb5/libsss_krb5_common_la-krb5_common.lo \ src/providers/krb5/libsss_krb5_common_la-krb5_opts.lo \ src/providers/krb5/libsss_krb5_common_la-krb5_auth.lo \ src/providers/krb5/libsss_krb5_common_la-krb5_access.lo \ src/providers/krb5/libsss_krb5_common_la-krb5_child_handler.lo \ src/providers/krb5/libsss_krb5_common_la-krb5_init_shared.lo \ src/providers/krb5/libsss_krb5_common_la-krb5_ccache.lo \ src/util/libsss_krb5_common_la-sss_krb5.lo \ src/util/libsss_krb5_common_la-become_user.lo libsss_krb5_common_la_OBJECTS = $(am_libsss_krb5_common_la_OBJECTS) libsss_krb5_common_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) \ $(libsss_krb5_common_la_LDFLAGS) $(LDFLAGS) -o $@ libsss_ldap_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) libsss_ldap_common.la \ libsss_krb5_common.la am_libsss_ldap_la_OBJECTS = \ src/providers/ldap/libsss_ldap_la-ldap_init.lo \ src/providers/ldap/libsss_ldap_la-ldap_access.lo libsss_ldap_la_OBJECTS = $(am_libsss_ldap_la_OBJECTS) libsss_ldap_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_ldap_la_CFLAGS) $(CFLAGS) $(libsss_ldap_la_LDFLAGS) \ $(LDFLAGS) -o $@ libsss_ldap_common_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) libsss_krb5_common.la libsss_idmap.la \ libsss_util.la am__libsss_ldap_common_la_SOURCES_DIST = src/providers/ldap/ldap_id.c \ src/providers/ldap/ldap_id_enum.c \ src/providers/ldap/sdap_async_enum.c \ src/providers/ldap/ldap_id_cleanup.c \ src/providers/ldap/ldap_id_netgroup.c \ src/providers/ldap/ldap_id_services.c \ src/providers/ldap/ldap_auth.c \ src/providers/ldap/ldap_common.c \ src/providers/ldap/ldap_options.c \ src/providers/ldap/ldap_opts.c \ src/providers/ldap/sdap_access.c \ src/providers/ldap/sdap_async.c \ src/providers/ldap/sdap_async_users.c \ src/providers/ldap/sdap_async_groups.c \ src/providers/ldap/sdap_async_nested_groups.c \ src/providers/ldap/sdap_async_groups_ad.c \ src/providers/ldap/sdap_async_initgroups.c \ src/providers/ldap/sdap_async_initgroups_ad.c \ src/providers/ldap/sdap_async_connection.c \ src/providers/ldap/sdap_async_netgroups.c \ src/providers/ldap/sdap_async_services.c \ src/providers/ldap/sdap_ad_groups.c \ src/providers/ldap/sdap_child_helpers.c \ src/providers/ldap/sdap_fd_events.c \ src/providers/ldap/sdap_id_op.c \ src/providers/ldap/sdap_idmap.c \ src/providers/ldap/sdap_idmap.h \ src/providers/ldap/sdap_range.c \ src/providers/ldap/sdap_reinit.c \ src/providers/ldap/sdap_dyndns.c \ src/providers/ldap/sdap_refresh.c \ src/providers/ldap/sdap_utils.c \ src/providers/ldap/sdap_domain.c src/providers/ldap/sdap_ops.c \ src/providers/ldap/sdap.c src/providers/ipa/ipa_dn.c \ src/util/user_info_msg.c src/util/sss_ldap.c \ src/providers/ldap/sdap_async_sudo.c \ src/providers/ldap/sdap_async_sudo_hostinfo.c \ src/providers/ldap/sdap_sudo_refresh.c \ src/providers/ldap/sdap_sudo_shared.c \ src/providers/ldap/sdap_sudo.c \ src/providers/ldap/sdap_autofs.c \ src/providers/ldap/sdap_async_autofs.c @BUILD_SUDO_TRUE@am__objects_24 = src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo.lo \ @BUILD_SUDO_TRUE@ src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo_hostinfo.lo \ @BUILD_SUDO_TRUE@ src/providers/ldap/libsss_ldap_common_la-sdap_sudo_refresh.lo \ @BUILD_SUDO_TRUE@ src/providers/ldap/libsss_ldap_common_la-sdap_sudo_shared.lo \ @BUILD_SUDO_TRUE@ src/providers/ldap/libsss_ldap_common_la-sdap_sudo.lo @BUILD_AUTOFS_TRUE@am__objects_25 = src/providers/ldap/libsss_ldap_common_la-sdap_autofs.lo \ @BUILD_AUTOFS_TRUE@ src/providers/ldap/libsss_ldap_common_la-sdap_async_autofs.lo am_libsss_ldap_common_la_OBJECTS = \ src/providers/ldap/libsss_ldap_common_la-ldap_id.lo \ src/providers/ldap/libsss_ldap_common_la-ldap_id_enum.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_async_enum.lo \ src/providers/ldap/libsss_ldap_common_la-ldap_id_cleanup.lo \ src/providers/ldap/libsss_ldap_common_la-ldap_id_netgroup.lo \ src/providers/ldap/libsss_ldap_common_la-ldap_id_services.lo \ src/providers/ldap/libsss_ldap_common_la-ldap_auth.lo \ src/providers/ldap/libsss_ldap_common_la-ldap_common.lo \ src/providers/ldap/libsss_ldap_common_la-ldap_options.lo \ src/providers/ldap/libsss_ldap_common_la-ldap_opts.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_access.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_async.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_async_users.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_async_groups.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_async_nested_groups.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_async_groups_ad.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups_ad.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_async_connection.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_async_netgroups.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_async_services.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_ad_groups.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_child_helpers.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_fd_events.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_id_op.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_idmap.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_range.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_reinit.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_dyndns.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_refresh.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_utils.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_domain.lo \ src/providers/ldap/libsss_ldap_common_la-sdap_ops.lo \ src/providers/ldap/libsss_ldap_common_la-sdap.lo \ src/providers/ipa/libsss_ldap_common_la-ipa_dn.lo \ src/util/libsss_ldap_common_la-user_info_msg.lo \ src/util/libsss_ldap_common_la-sss_ldap.lo $(am__objects_24) \ $(am__objects_25) libsss_ldap_common_la_OBJECTS = $(am_libsss_ldap_common_la_OBJECTS) libsss_ldap_common_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) \ $(libsss_ldap_common_la_LDFLAGS) $(LDFLAGS) -o $@ am_libsss_nss_idmap_la_OBJECTS = \ src/sss_client/idmap/sss_nss_idmap.lo src/sss_client/common.lo \ src/util/strtonum.lo libsss_nss_idmap_la_OBJECTS = $(am_libsss_nss_idmap_la_OBJECTS) libsss_nss_idmap_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libsss_nss_idmap_la_LDFLAGS) \ $(LDFLAGS) -o $@ am__DEPENDENCIES_10 = $(am__DEPENDENCIES_6) @HAVE_CHECK_TRUE@libsss_nss_idmap_tests_la_DEPENDENCIES = \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_10) am__libsss_nss_idmap_tests_la_SOURCES_DIST = \ src/sss_client/idmap/sss_nss_idmap.c src/sss_client/common.c \ src/util/strtonum.c am__objects_26 = src/sss_client/idmap/sss_nss_idmap.lo \ src/sss_client/common.lo src/util/strtonum.lo @HAVE_CHECK_TRUE@am_libsss_nss_idmap_tests_la_OBJECTS = \ @HAVE_CHECK_TRUE@ $(am__objects_26) libsss_nss_idmap_tests_la_OBJECTS = \ $(am_libsss_nss_idmap_tests_la_OBJECTS) libsss_nss_idmap_tests_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libsss_nss_idmap_tests_la_LDFLAGS) \ $(LDFLAGS) -o $@ @HAVE_CHECK_TRUE@am_libsss_nss_idmap_tests_la_rpath = libsss_proxy_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am_libsss_proxy_la_OBJECTS = \ src/providers/proxy/libsss_proxy_la-proxy_init.lo \ src/providers/proxy/libsss_proxy_la-proxy_id.lo \ src/providers/proxy/libsss_proxy_la-proxy_netgroup.lo \ src/providers/proxy/libsss_proxy_la-proxy_services.lo \ src/providers/proxy/libsss_proxy_la-proxy_auth.lo \ src/providers/libsss_proxy_la-data_provider_iface_generated.lo libsss_proxy_la_OBJECTS = $(am_libsss_proxy_la_OBJECTS) libsss_proxy_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_proxy_la_CFLAGS) $(CFLAGS) $(libsss_proxy_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILD_SEMANAGE_TRUE@am__DEPENDENCIES_11 = $(am__DEPENDENCIES_1) libsss_semanage_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ libsss_debug.la $(am__DEPENDENCIES_11) am_libsss_semanage_la_OBJECTS = \ src/util/libsss_semanage_la-sss_semanage.lo libsss_semanage_la_OBJECTS = $(am_libsss_semanage_la_OBJECTS) libsss_semanage_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_semanage_la_CFLAGS) $(CFLAGS) \ $(libsss_semanage_la_LDFLAGS) $(LDFLAGS) -o $@ libsss_simple_la_LIBADD = am_libsss_simple_la_OBJECTS = \ src/providers/simple/libsss_simple_la-simple_access_check.lo \ src/providers/simple/libsss_simple_la-simple_access.lo libsss_simple_la_OBJECTS = $(am_libsss_simple_la_OBJECTS) libsss_simple_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_simple_la_CFLAGS) $(CFLAGS) \ $(libsss_simple_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_IFP_TRUE@libsss_simpleifp_la_DEPENDENCIES = \ @BUILD_IFP_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am__libsss_simpleifp_la_SOURCES_DIST = src/lib/sifp/sss_sifp.c \ src/lib/sifp/sss_sifp_dbus.c src/lib/sifp/sss_sifp_attrs.c \ src/lib/sifp/sss_sifp_common.c src/lib/sifp/sss_sifp_parser.c \ src/lib/sifp/sss_sifp_utils.c @BUILD_IFP_TRUE@am_libsss_simpleifp_la_OBJECTS = \ @BUILD_IFP_TRUE@ src/lib/sifp/libsss_simpleifp_la-sss_sifp.lo \ @BUILD_IFP_TRUE@ src/lib/sifp/libsss_simpleifp_la-sss_sifp_dbus.lo \ @BUILD_IFP_TRUE@ src/lib/sifp/libsss_simpleifp_la-sss_sifp_attrs.lo \ @BUILD_IFP_TRUE@ src/lib/sifp/libsss_simpleifp_la-sss_sifp_common.lo \ @BUILD_IFP_TRUE@ src/lib/sifp/libsss_simpleifp_la-sss_sifp_parser.lo \ @BUILD_IFP_TRUE@ src/lib/sifp/libsss_simpleifp_la-sss_sifp_utils.lo libsss_simpleifp_la_OBJECTS = $(am_libsss_simpleifp_la_OBJECTS) libsss_simpleifp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) \ $(libsss_simpleifp_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_IFP_TRUE@am_libsss_simpleifp_la_rpath = -rpath $(libdir) @BUILD_SUDO_TRUE@libsss_sudo_la_DEPENDENCIES = $(am__DEPENDENCIES_6) am__libsss_sudo_la_SOURCES_DIST = src/sss_client/common.c \ src/sss_client/sss_cli.h \ src/sss_client/sudo/sss_sudo_response.c \ src/sss_client/sudo/sss_sudo.c src/sss_client/sudo/sss_sudo.h \ src/sss_client/sudo/sss_sudo_private.h @BUILD_SUDO_TRUE@am_libsss_sudo_la_OBJECTS = src/sss_client/common.lo \ @BUILD_SUDO_TRUE@ src/sss_client/sudo/sss_sudo_response.lo \ @BUILD_SUDO_TRUE@ src/sss_client/sudo/sss_sudo.lo libsss_sudo_la_OBJECTS = $(am_libsss_sudo_la_OBJECTS) libsss_sudo_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libsss_sudo_la_LDFLAGS) $(LDFLAGS) -o \ $@ @BUILD_SUDO_TRUE@am_libsss_sudo_la_rpath = -rpath $(sudolibdir) libsss_test_common_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am__libsss_test_common_la_SOURCES_DIST = src/tests/common_tev.c \ src/tests/common_dom.c src/tests/leak_check.c \ src/tests/common.c src/tests/common_check.c @HAVE_CHECK_TRUE@am__objects_27 = src/tests/common_check.lo am_libsss_test_common_la_OBJECTS = src/tests/common_tev.lo \ src/tests/common_dom.lo src/tests/leak_check.lo \ src/tests/common.lo $(am__objects_27) libsss_test_common_la_OBJECTS = $(am_libsss_test_common_la_OBJECTS) libsss_util_la_DEPENDENCIES = $(am__DEPENDENCIES_5) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) libsss_debug.la \ libsss_child.la libsss_crypt.la libsss_cert.la am__libsss_util_la_SOURCES_DIST = src/confdb/confdb.c src/db/sysdb.c \ src/db/sysdb_ops.c src/db/sysdb_search.c \ src/db/sysdb_selinux.c src/db/sysdb_upgrade.c \ src/db/sysdb_services.c src/db/sysdb_autofs.c \ src/db/sysdb_subdomains.c src/db/sysdb_views.c \ src/db/sysdb_ranges.c src/db/sysdb_idmap.c src/db/sysdb_gpo.c \ src/monitor/monitor_sbus.c src/providers/dp_auth_util.c \ src/providers/dp_pam_data_util.c src/providers/dp_sbus.c \ src/sbus/sbus_client.c src/sbus/sssd_dbus_common.c \ src/sbus/sssd_dbus_connection.c src/sbus/sssd_dbus_meta.c \ src/sbus/sssd_dbus_interface.c src/sbus/sssd_dbus_introspect.c \ src/sbus/sssd_dbus_invokers.c src/sbus/sssd_dbus_properties.c \ src/sbus/sssd_dbus_request.c src/sbus/sssd_dbus_server.c \ src/sbus/sssd_dbus_signals.c \ src/sbus/sssd_dbus_common_signals.c src/util/util.c \ src/util/memory.c src/util/safe-format-string.c \ src/util/server.c src/util/signal.c src/util/usertools.c \ src/util/backup_file.c src/util/strtonum.c \ src/util/check_and_open.c src/util/refcount.c \ src/util/sss_nss.c src/util/sss_utf8.c src/util/sss_tc_utf8.c \ src/util/murmurhash3.c src/util/atomic_io.c src/util/authtok.c \ src/util/authtok-utils.c src/util/sss_selinux.c \ src/util/domain_info_utils.c src/util/util_lock.c \ src/util/util_errors.c src/util/find_uid.c src/util/sss_ini.c \ src/util/io.c src/util/util_sss_idmap.c \ src/util/well_known_sids.c src/util/string_utils.c \ src/util/become_user.c src/db/sysdb_sudo.c src/db/sysdb_ssh.c \ src/util/sss_ssh.c @BUILD_SUDO_TRUE@am__objects_28 = src/db/libsss_util_la-sysdb_sudo.lo @BUILD_SSH_TRUE@am__objects_29 = src/db/libsss_util_la-sysdb_ssh.lo \ @BUILD_SSH_TRUE@ src/util/libsss_util_la-sss_ssh.lo am_libsss_util_la_OBJECTS = src/confdb/libsss_util_la-confdb.lo \ src/db/libsss_util_la-sysdb.lo \ src/db/libsss_util_la-sysdb_ops.lo \ src/db/libsss_util_la-sysdb_search.lo \ src/db/libsss_util_la-sysdb_selinux.lo \ src/db/libsss_util_la-sysdb_upgrade.lo \ src/db/libsss_util_la-sysdb_services.lo \ src/db/libsss_util_la-sysdb_autofs.lo \ src/db/libsss_util_la-sysdb_subdomains.lo \ src/db/libsss_util_la-sysdb_views.lo \ src/db/libsss_util_la-sysdb_ranges.lo \ src/db/libsss_util_la-sysdb_idmap.lo \ src/db/libsss_util_la-sysdb_gpo.lo \ src/monitor/libsss_util_la-monitor_sbus.lo \ src/providers/libsss_util_la-dp_auth_util.lo \ src/providers/libsss_util_la-dp_pam_data_util.lo \ src/providers/libsss_util_la-dp_sbus.lo \ src/sbus/libsss_util_la-sbus_client.lo \ src/sbus/libsss_util_la-sssd_dbus_common.lo \ src/sbus/libsss_util_la-sssd_dbus_connection.lo \ src/sbus/libsss_util_la-sssd_dbus_meta.lo \ src/sbus/libsss_util_la-sssd_dbus_interface.lo \ src/sbus/libsss_util_la-sssd_dbus_introspect.lo \ src/sbus/libsss_util_la-sssd_dbus_invokers.lo \ src/sbus/libsss_util_la-sssd_dbus_properties.lo \ src/sbus/libsss_util_la-sssd_dbus_request.lo \ src/sbus/libsss_util_la-sssd_dbus_server.lo \ src/sbus/libsss_util_la-sssd_dbus_signals.lo \ src/sbus/libsss_util_la-sssd_dbus_common_signals.lo \ src/util/libsss_util_la-util.lo \ src/util/libsss_util_la-memory.lo \ src/util/libsss_util_la-safe-format-string.lo \ src/util/libsss_util_la-server.lo \ src/util/libsss_util_la-signal.lo \ src/util/libsss_util_la-usertools.lo \ src/util/libsss_util_la-backup_file.lo \ src/util/libsss_util_la-strtonum.lo \ src/util/libsss_util_la-check_and_open.lo \ src/util/libsss_util_la-refcount.lo \ src/util/libsss_util_la-sss_nss.lo \ src/util/libsss_util_la-sss_utf8.lo \ src/util/libsss_util_la-sss_tc_utf8.lo \ src/util/libsss_util_la-murmurhash3.lo \ src/util/libsss_util_la-atomic_io.lo \ src/util/libsss_util_la-authtok.lo \ src/util/libsss_util_la-authtok-utils.lo \ src/util/libsss_util_la-sss_selinux.lo \ src/util/libsss_util_la-domain_info_utils.lo \ src/util/libsss_util_la-util_lock.lo \ src/util/libsss_util_la-util_errors.lo \ src/util/libsss_util_la-find_uid.lo \ src/util/libsss_util_la-sss_ini.lo \ src/util/libsss_util_la-io.lo \ src/util/libsss_util_la-util_sss_idmap.lo \ src/util/libsss_util_la-well_known_sids.lo \ src/util/libsss_util_la-string_utils.lo \ src/util/libsss_util_la-become_user.lo $(am__objects_28) \ $(am__objects_29) libsss_util_la_OBJECTS = $(am_libsss_util_la_OBJECTS) libsss_util_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(libsss_util_la_CFLAGS) $(CFLAGS) $(libsss_util_la_LDFLAGS) \ $(LDFLAGS) -o $@ @BUILD_LIBWBCLIENT_TRUE@libwbclient_la_DEPENDENCIES = \ @BUILD_LIBWBCLIENT_TRUE@ libsss_nss_idmap.la \ @BUILD_LIBWBCLIENT_TRUE@ $(am__DEPENDENCIES_6) am__libwbclient_la_SOURCES_DIST = \ src/sss_client/libwbclient/wbc_guid.c \ src/sss_client/libwbclient/wbc_idmap_common.c \ src/sss_client/libwbclient/wbc_idmap_sssd.c \ src/sss_client/libwbclient/wbclient_common.c \ src/sss_client/libwbclient/wbclient_sssd.c \ src/sss_client/libwbclient/wbc_pam_sssd.c \ src/sss_client/libwbclient/wbc_pwd_sssd.c \ src/sss_client/libwbclient/wbc_sid_common.c \ src/sss_client/libwbclient/wbc_sid_sssd.c \ src/sss_client/libwbclient/wbc_sssd_internal.h \ src/sss_client/libwbclient/wbc_util_common.c \ src/sss_client/libwbclient/wbc_util_sssd.c \ src/sss_client/libwbclient/wbc_ctx_sssd.c @BUILD_LIBWBCLIENT_TRUE@am_libwbclient_la_OBJECTS = src/sss_client/libwbclient/wbc_guid.lo \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_idmap_common.lo \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_idmap_sssd.lo \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbclient_common.lo \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbclient_sssd.lo \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_pam_sssd.lo \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_pwd_sssd.lo \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_sid_common.lo \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_sid_sssd.lo \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_util_common.lo \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_util_sssd.lo \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_ctx_sssd.lo libwbclient_la_OBJECTS = $(am_libwbclient_la_OBJECTS) libwbclient_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libwbclient_la_LDFLAGS) $(LDFLAGS) -o \ $@ @BUILD_LIBWBCLIENT_TRUE@am_libwbclient_la_rpath = -rpath \ @BUILD_LIBWBCLIENT_TRUE@ $(libwbclientdir) memberof_la_DEPENDENCIES = libsss_debug.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am_memberof_la_OBJECTS = src/ldb_modules/memberof_la-memberof.lo \ src/util/memberof_la-util.lo memberof_la_OBJECTS = $(am_memberof_la_OBJECTS) memberof_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(memberof_la_CFLAGS) \ $(CFLAGS) $(memberof_la_LDFLAGS) $(LDFLAGS) -o $@ pam_sss_la_DEPENDENCIES = $(am__DEPENDENCIES_6) $(am__DEPENDENCIES_1) am_pam_sss_la_OBJECTS = src/sss_client/pam_sss.lo \ src/sss_client/pam_message.lo src/sss_client/common.lo \ src/util/atomic_io.lo src/util/authtok-utils.lo pam_sss_la_OBJECTS = $(am_pam_sss_la_OBJECTS) pam_sss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pam_sss_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_NFS_IDMAP_TRUE@sss_la_DEPENDENCIES = $(am__DEPENDENCIES_6) \ @BUILD_NFS_IDMAP_TRUE@ $(am__DEPENDENCIES_1) am__sss_la_SOURCES_DIST = src/sss_client/common.c \ src/sss_client/nss_mc_common.c src/util/io.c \ src/util/murmurhash3.c src/sss_client/nss_mc_passwd.c \ src/sss_client/nss_mc_group.c \ src/sss_client/nfs/sss_nfs_client.c @BUILD_NFS_IDMAP_TRUE@am_sss_la_OBJECTS = \ @BUILD_NFS_IDMAP_TRUE@ src/sss_client/sss_la-common.lo \ @BUILD_NFS_IDMAP_TRUE@ src/sss_client/sss_la-nss_mc_common.lo \ @BUILD_NFS_IDMAP_TRUE@ src/util/sss_la-io.lo \ @BUILD_NFS_IDMAP_TRUE@ src/util/sss_la-murmurhash3.lo \ @BUILD_NFS_IDMAP_TRUE@ src/sss_client/sss_la-nss_mc_passwd.lo \ @BUILD_NFS_IDMAP_TRUE@ src/sss_client/sss_la-nss_mc_group.lo \ @BUILD_NFS_IDMAP_TRUE@ src/sss_client/nfs/sss_la-sss_nfs_client.lo sss_la_OBJECTS = $(am_sss_la_OBJECTS) sss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sss_la_CFLAGS) $(CFLAGS) \ $(sss_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_NFS_IDMAP_TRUE@am_sss_la_rpath = -rpath $(nfslibdir) @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@sssd_krb5_localauth_plugin_la_DEPENDENCIES = \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ $(am__DEPENDENCIES_1) am__sssd_krb5_localauth_plugin_la_SOURCES_DIST = \ src/krb5_plugin/sssd_krb5_localauth_plugin.c \ src/util/murmurhash3.c src/util/io.c src/sss_client/common.c \ src/sss_client/nss_mc_common.c src/sss_client/nss_mc_passwd.c \ src/sss_client/nss_passwd.c @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@am_sssd_krb5_localauth_plugin_la_OBJECTS = src/krb5_plugin/sssd_krb5_localauth_plugin_la-sssd_krb5_localauth_plugin.lo \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/util/sssd_krb5_localauth_plugin_la-murmurhash3.lo \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/util/sssd_krb5_localauth_plugin_la-io.lo \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/sss_client/sssd_krb5_localauth_plugin_la-common.lo \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_common.lo \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_passwd.lo \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/sss_client/sssd_krb5_localauth_plugin_la-nss_passwd.lo sssd_krb5_localauth_plugin_la_OBJECTS = \ $(am_sssd_krb5_localauth_plugin_la_OBJECTS) sssd_krb5_localauth_plugin_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) \ $(sssd_krb5_localauth_plugin_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@am_sssd_krb5_localauth_plugin_la_rpath = \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ -rpath \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ $(krb5localauth_plugindir) sssd_krb5_locator_plugin_la_LIBADD = am__sssd_krb5_locator_plugin_la_SOURCES_DIST = \ src/krb5_plugin/sssd_krb5_locator_plugin.c \ src/util/atomic_io.c @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@am_sssd_krb5_locator_plugin_la_OBJECTS = src/krb5_plugin/sssd_krb5_locator_plugin_la-sssd_krb5_locator_plugin.lo \ @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@ src/util/sssd_krb5_locator_plugin_la-atomic_io.lo sssd_krb5_locator_plugin_la_OBJECTS = \ $(am_sssd_krb5_locator_plugin_la_OBJECTS) sssd_krb5_locator_plugin_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sssd_krb5_locator_plugin_la_CFLAGS) $(CFLAGS) \ $(sssd_krb5_locator_plugin_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@am_sssd_krb5_locator_plugin_la_rpath = \ @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@ -rpath $(krb5plugindir) sssd_pac_plugin_la_DEPENDENCIES = $(am__DEPENDENCIES_6) \ $(am__DEPENDENCIES_1) am_sssd_pac_plugin_la_OBJECTS = \ src/sss_client/sssd_pac_plugin_la-sssd_pac.lo \ src/sss_client/sssd_pac_plugin_la-common.lo sssd_pac_plugin_la_OBJECTS = $(am_sssd_pac_plugin_la_OBJECTS) sssd_pac_plugin_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sssd_pac_plugin_la_CFLAGS) $(CFLAGS) \ $(sssd_pac_plugin_la_LDFLAGS) $(LDFLAGS) -o $@ @BUILD_PAC_RESPONDER_TRUE@am_sssd_pac_plugin_la_rpath = -rpath \ @BUILD_PAC_RESPONDER_TRUE@ $(krb5authdata_plugindir) @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@am__EXEEXT_1 = test_resolv_fake$(EXEEXT) @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@am__EXEEXT_2 = ifp_tests$(EXEEXT) @BUILD_SAMBA_TRUE@@HAVE_CMOCKA_TRUE@am__EXEEXT_3 = ad_access_filter_tests$(EXEEXT) \ @BUILD_SAMBA_TRUE@@HAVE_CMOCKA_TRUE@ ad_gpo_tests$(EXEEXT) @HAVE_CMOCKA_TRUE@am__EXEEXT_4 = nss-srv-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test-find-uid$(EXEEXT) test-io$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test-negcache$(EXEEXT) test-authtok$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ sss_nss_idmap-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ dyndns-tests$(EXEEXT) fqnames-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ nestedgroups-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_sss_idmap$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_ipa_idmap$(EXEEXT) test_utils$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ ad_common_tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ dp_opt_tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ responder-get-domains-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ sbus-internal-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ sss_sifp-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_search_bases$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_ldap_auth$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_sdap_access$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ sdap-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_sysdb_views$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_sysdb_subdomains$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_sysdb_utils$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_be_ptask$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_copy_ccache$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_copy_keytab$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_child_common$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ responder_cache_req-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_sbus_opath$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_fo_srv$(EXEEXT) pam-srv-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_ipa_subdom_util$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_ipa_subdom_server$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_tools_colondb$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_krb5_wait_queue$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_cert_utils$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_ldap_id_cleanup$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_data_provider_be$(EXEEXT) \ @HAVE_CMOCKA_TRUE@ test_ipa_dn$(EXEEXT) $(am__EXEEXT_1) \ @HAVE_CMOCKA_TRUE@ $(am__EXEEXT_2) $(am__EXEEXT_3) @BUILD_SSH_TRUE@@HAVE_CHECK_TRUE@am__EXEEXT_5 = \ @BUILD_SSH_TRUE@@HAVE_CHECK_TRUE@ sysdb_ssh-tests$(EXEEXT) @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@@HAVE_CHECK_TRUE@am__EXEEXT_6 = sss_config-tests$(EXEEXT) @BUILD_DBUS_TESTS_TRUE@@HAVE_CHECK_TRUE@am__EXEEXT_7 = \ @BUILD_DBUS_TESTS_TRUE@@HAVE_CHECK_TRUE@ sbus_tests$(EXEEXT) \ @BUILD_DBUS_TESTS_TRUE@@HAVE_CHECK_TRUE@ sbus_codegen_tests$(EXEEXT) @HAVE_CHECK_TRUE@am__EXEEXT_8 = dlopen-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ sysdb-tests$(EXEEXT) strtonum-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ resolv-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ krb5-utils-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ check_and_open-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ files-tests$(EXEEXT) refcount-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ fail_over-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ find_uid-tests$(EXEEXT) auth-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ ipa_ldap_opt-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ ad_ldap_opt-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ simple_access-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ crypto-tests$(EXEEXT) util-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ debug-tests$(EXEEXT) ipa_hbac-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ sss_idmap-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ responder_socket_access-tests$(EXEEXT) \ @HAVE_CHECK_TRUE@ safe-format-tests$(EXEEXT) $(am__EXEEXT_5) \ @HAVE_CHECK_TRUE@ $(am__EXEEXT_6) $(am__EXEEXT_7) @HAVE_CMOCKA_TRUE@am__EXEEXT_9 = dummy-child$(EXEEXT) @BUILD_SUDO_TRUE@am__EXEEXT_10 = sss_sudo_cli$(EXEEXT) @BUILD_AUTOFS_TRUE@am__EXEEXT_11 = autofs_test_client$(EXEEXT) @BUILD_SUDO_TRUE@am__EXEEXT_12 = sssd_sudo$(EXEEXT) @BUILD_AUTOFS_TRUE@am__EXEEXT_13 = sssd_autofs$(EXEEXT) @BUILD_SSH_TRUE@am__EXEEXT_14 = sssd_ssh$(EXEEXT) @BUILD_IFP_TRUE@am__EXEEXT_15 = sssd_ifp$(EXEEXT) @BUILD_SAMBA_TRUE@am__EXEEXT_16 = gpo_child$(EXEEXT) @BUILD_SEMANAGE_TRUE@am__EXEEXT_17 = selinux_child$(EXEEXT) @HAVE_NSS_TRUE@am__EXEEXT_18 = p11_child$(EXEEXT) @BUILD_PAC_RESPONDER_TRUE@am__EXEEXT_19 = sssd_pac$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) \ $(sssdlibexec_PROGRAMS) am__ad_access_filter_tests_SOURCES_DIST = \ src/tests/cmocka/test_ad_access_filter.c @HAVE_CMOCKA_TRUE@am_ad_access_filter_tests_OBJECTS = src/tests/cmocka/test_ad_access_filter.$(OBJEXT) ad_access_filter_tests_OBJECTS = $(am_ad_access_filter_tests_OBJECTS) @HAVE_CMOCKA_TRUE@ad_access_filter_tests_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_ad_tests.la libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la am__ad_common_tests_SOURCES_DIST = src/providers/krb5/krb5_utils.c \ src/providers/krb5/krb5_delayed_online_authentication.c \ src/providers/krb5/krb5_renew_tgt.c \ src/providers/krb5/krb5_wait_queue.c \ src/providers/krb5/krb5_common.c \ src/providers/krb5/krb5_opts.c src/providers/krb5/krb5_auth.c \ src/providers/krb5/krb5_access.c \ src/providers/krb5/krb5_child_handler.c \ src/providers/krb5/krb5_init_shared.c \ src/providers/krb5/krb5_ccache.c src/util/sss_krb5.c \ src/util/become_user.c src/tests/cmocka/common_mock_krb5.c \ src/tests/cmocka/test_ad_common.c src/providers/ad/ad_opts.c am__objects_30 = src/providers/krb5/krb5_utils.$(OBJEXT) \ src/providers/krb5/krb5_delayed_online_authentication.$(OBJEXT) \ src/providers/krb5/krb5_renew_tgt.$(OBJEXT) \ src/providers/krb5/krb5_wait_queue.$(OBJEXT) \ src/providers/krb5/krb5_common.$(OBJEXT) \ src/providers/krb5/krb5_opts.$(OBJEXT) \ src/providers/krb5/krb5_auth.$(OBJEXT) \ src/providers/krb5/krb5_access.$(OBJEXT) \ src/providers/krb5/krb5_child_handler.$(OBJEXT) \ src/providers/krb5/krb5_init_shared.$(OBJEXT) \ src/providers/krb5/krb5_ccache.$(OBJEXT) \ src/util/sss_krb5.$(OBJEXT) src/util/become_user.$(OBJEXT) @HAVE_CMOCKA_TRUE@am_ad_common_tests_OBJECTS = $(am__objects_30) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_krb5.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ad_common.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ad/ad_opts.$(OBJEXT) ad_common_tests_OBJECTS = $(am_ad_common_tests_OBJECTS) @HAVE_CMOCKA_TRUE@ad_common_tests_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la ad_common_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(ad_common_tests_LDFLAGS) $(LDFLAGS) \ -o $@ am__ad_gpo_tests_SOURCES_DIST = src/tests/cmocka/test_ad_gpo.c @HAVE_CMOCKA_TRUE@am_ad_gpo_tests_OBJECTS = src/tests/cmocka/ad_gpo_tests-test_ad_gpo.$(OBJEXT) ad_gpo_tests_OBJECTS = $(am_ad_gpo_tests_OBJECTS) @HAVE_CMOCKA_TRUE@ad_gpo_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_idmap.la libsss_krb5_common.la \ @HAVE_CMOCKA_TRUE@ libsss_ad_tests.la libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la ad_gpo_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ad_gpo_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__ad_ldap_opt_tests_SOURCES_DIST = src/providers/ldap/ldap_opts.c \ src/providers/ad/ad_opts.c src/providers/krb5/krb5_opts.c \ src/tests/ad_ldap_opt-tests.c @HAVE_CHECK_TRUE@am_ad_ldap_opt_tests_OBJECTS = src/providers/ldap/ad_ldap_opt_tests-ldap_opts.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/ad/ad_ldap_opt_tests-ad_opts.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/krb5/ad_ldap_opt_tests-krb5_opts.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.$(OBJEXT) ad_ldap_opt_tests_OBJECTS = $(am_ad_ldap_opt_tests_OBJECTS) @HAVE_CHECK_TRUE@ad_ldap_opt_tests_DEPENDENCIES = \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ libsss_test_common.la ad_ldap_opt_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__auth_tests_SOURCES_DIST = src/tests/auth-tests.c @HAVE_CHECK_TRUE@am_auth_tests_OBJECTS = \ @HAVE_CHECK_TRUE@ src/tests/auth_tests-auth-tests.$(OBJEXT) auth_tests_OBJECTS = $(am_auth_tests_OBJECTS) @HAVE_CHECK_TRUE@auth_tests_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ @HAVE_CHECK_TRUE@ libsss_test_common.la auth_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(auth_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__autofs_test_client_SOURCES_DIST = \ src/sss_client/autofs/autofs_test_client.c \ src/sss_client/autofs/sss_autofs.c src/sss_client/common.c @BUILD_AUTOFS_TRUE@am_autofs_test_client_OBJECTS = src/sss_client/autofs/autofs_test_client-autofs_test_client.$(OBJEXT) \ @BUILD_AUTOFS_TRUE@ src/sss_client/autofs/autofs_test_client-sss_autofs.$(OBJEXT) \ @BUILD_AUTOFS_TRUE@ src/sss_client/autofs_test_client-common.$(OBJEXT) autofs_test_client_OBJECTS = $(am_autofs_test_client_OBJECTS) @BUILD_AUTOFS_TRUE@autofs_test_client_DEPENDENCIES = \ @BUILD_AUTOFS_TRUE@ $(am__DEPENDENCIES_6) autofs_test_client_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(autofs_test_client_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__check_and_open_tests_SOURCES_DIST = \ src/tests/check_and_open-tests.c src/util/check_and_open.c @HAVE_CHECK_TRUE@am_check_and_open_tests_OBJECTS = src/tests/check_and_open_tests-check_and_open-tests.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/util/check_and_open_tests-check_and_open.$(OBJEXT) check_and_open_tests_OBJECTS = $(am_check_and_open_tests_OBJECTS) @HAVE_CHECK_TRUE@check_and_open_tests_DEPENDENCIES = libsss_debug.la \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) libsss_test_common.la check_and_open_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(check_and_open_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__crypto_tests_SOURCES_DIST = src/tests/crypto-tests.c @HAVE_CHECK_TRUE@am_crypto_tests_OBJECTS = src/tests/crypto_tests-crypto-tests.$(OBJEXT) crypto_tests_OBJECTS = $(am_crypto_tests_OBJECTS) @HAVE_CHECK_TRUE@crypto_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ libsss_crypt.la libsss_debug.la \ @HAVE_CHECK_TRUE@ libsss_test_common.la crypto_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(crypto_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__debug_tests_SOURCES_DIST = src/tests/debug-tests.c \ src/tests/common.c @HAVE_CHECK_TRUE@am_debug_tests_OBJECTS = \ @HAVE_CHECK_TRUE@ src/tests/debug_tests-debug-tests.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/tests/debug_tests-common.$(OBJEXT) debug_tests_OBJECTS = $(am_debug_tests_OBJECTS) @HAVE_CHECK_TRUE@debug_tests_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) libsss_debug.la debug_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(debug_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__dlopen_tests_SOURCES_DIST = src/tests/dlopen-tests.c @HAVE_CHECK_TRUE@am_dlopen_tests_OBJECTS = src/tests/dlopen_tests-dlopen-tests.$(OBJEXT) dlopen_tests_OBJECTS = $(am_dlopen_tests_OBJECTS) @HAVE_CHECK_TRUE@dlopen_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) dlopen_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dlopen_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__dp_opt_tests_SOURCES_DIST = src/providers/data_provider_opts.c \ src/tests/cmocka/test_dp_opts.c @HAVE_CMOCKA_TRUE@am_dp_opt_tests_OBJECTS = src/providers/dp_opt_tests-data_provider_opts.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/dp_opt_tests-test_dp_opts.$(OBJEXT) dp_opt_tests_OBJECTS = $(am_dp_opt_tests_OBJECTS) @HAVE_CMOCKA_TRUE@dp_opt_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la dp_opt_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dp_opt_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__dummy_child_SOURCES_DIST = src/tests/cmocka/dummy_child.c @HAVE_CMOCKA_TRUE@am_dummy_child_OBJECTS = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/dummy_child.$(OBJEXT) dummy_child_OBJECTS = $(am_dummy_child_OBJECTS) @HAVE_CMOCKA_TRUE@dummy_child_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) am__dyndns_tests_SOURCES_DIST = src/resolv/async_resolv.c \ src/resolv/async_resolv_utils.c \ src/tests/cmocka/common_mock_be.c \ src/tests/cmocka/test_dyndns.c \ src/providers/data_provider_opts.c am__objects_31 = src/resolv/dyndns_tests-async_resolv.$(OBJEXT) \ src/resolv/dyndns_tests-async_resolv_utils.$(OBJEXT) @HAVE_CMOCKA_TRUE@am_dyndns_tests_OBJECTS = $(am__objects_31) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/dyndns_tests-common_mock_be.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/dyndns_tests-test_dyndns.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/dyndns_tests-data_provider_opts.$(OBJEXT) dyndns_tests_OBJECTS = $(am_dyndns_tests_OBJECTS) @HAVE_CMOCKA_TRUE@dyndns_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la dyndns_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dyndns_tests_CFLAGS) \ $(CFLAGS) $(dyndns_tests_LDFLAGS) $(LDFLAGS) -o $@ am__fail_over_tests_SOURCES_DIST = src/tests/fail_over-tests.c \ src/providers/fail_over.c src/providers/fail_over_srv.c \ src/resolv/async_resolv.c src/resolv/async_resolv_utils.c am__objects_32 = src/resolv/fail_over_tests-async_resolv.$(OBJEXT) \ src/resolv/fail_over_tests-async_resolv_utils.$(OBJEXT) am__objects_33 = src/providers/fail_over_tests-fail_over.$(OBJEXT) \ src/providers/fail_over_tests-fail_over_srv.$(OBJEXT) \ $(am__objects_32) @HAVE_CHECK_TRUE@am_fail_over_tests_OBJECTS = src/tests/fail_over_tests-fail_over-tests.$(OBJEXT) \ @HAVE_CHECK_TRUE@ $(am__objects_33) fail_over_tests_OBJECTS = $(am_fail_over_tests_OBJECTS) @HAVE_CHECK_TRUE@fail_over_tests_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la fail_over_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(fail_over_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__files_tests_SOURCES_DIST = src/tests/files-tests.c \ src/util/check_and_open.c src/util/atomic_io.c \ src/tools/selinux.c src/tools/files.c @HAVE_CHECK_TRUE@am_files_tests_OBJECTS = \ @HAVE_CHECK_TRUE@ src/tests/files_tests-files-tests.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/util/files_tests-check_and_open.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/util/files_tests-atomic_io.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/tools/files_tests-selinux.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/tools/files_tests-files.$(OBJEXT) files_tests_OBJECTS = $(am_files_tests_OBJECTS) @BUILD_SELINUX_TRUE@@HAVE_CHECK_TRUE@am__DEPENDENCIES_12 = \ @BUILD_SELINUX_TRUE@@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) @BUILD_SEMANAGE_TRUE@@HAVE_CHECK_TRUE@am__DEPENDENCIES_13 = \ @BUILD_SEMANAGE_TRUE@@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) @HAVE_CHECK_TRUE@am__DEPENDENCIES_14 = $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ libsss_test_common.la $(am__DEPENDENCIES_12) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_13) @HAVE_CHECK_TRUE@files_tests_DEPENDENCIES = $(am__DEPENDENCIES_14) \ @HAVE_CHECK_TRUE@ libsss_test_common.la $(am__DEPENDENCIES_2) files_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(files_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__find_uid_tests_SOURCES_DIST = src/tests/find_uid-tests.c \ src/util/find_uid.c src/util/atomic_io.c src/util/strtonum.c @HAVE_CHECK_TRUE@am_find_uid_tests_OBJECTS = src/tests/find_uid_tests-find_uid-tests.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/util/find_uid_tests-find_uid.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/util/find_uid_tests-atomic_io.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/util/find_uid_tests-strtonum.$(OBJEXT) find_uid_tests_OBJECTS = $(am_find_uid_tests_OBJECTS) @HAVE_CHECK_TRUE@find_uid_tests_DEPENDENCIES = libsss_debug.la \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ libsss_test_common.la find_uid_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(find_uid_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ $@ am__fqnames_tests_SOURCES_DIST = src/tests/cmocka/test_fqnames.c @HAVE_CMOCKA_TRUE@am_fqnames_tests_OBJECTS = src/tests/cmocka/fqnames_tests-test_fqnames.$(OBJEXT) fqnames_tests_OBJECTS = $(am_fqnames_tests_OBJECTS) @HAVE_CMOCKA_TRUE@fqnames_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la fqnames_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(fqnames_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_gpo_child_OBJECTS = \ src/providers/ad/gpo_child-ad_gpo_child.$(OBJEXT) \ src/util/gpo_child-atomic_io.$(OBJEXT) \ src/util/gpo_child-util.$(OBJEXT) \ src/util/gpo_child-signal.$(OBJEXT) gpo_child_OBJECTS = $(am_gpo_child_OBJECTS) gpo_child_DEPENDENCIES = libsss_debug.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) gpo_child_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(gpo_child_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__ifp_tests_SOURCES_DIST = src/tests/cmocka/common_mock_resp.c \ src/tests/cmocka/common_mock_resp_dp.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_cmd.c \ src/responder/common/negcache.c \ src/responder/common/responder_common.c \ src/responder/common/responder_cache_req.c \ src/tests/cmocka/test_ifp.c src/responder/ifp/ifpsrv_cmd.c \ src/responder/ifp/ifp_iface_generated.c \ src/responder/ifp/ifpsrv_util.c \ src/responder/common/responder_utils.c @HAVE_CMOCKA_TRUE@am__objects_34 = src/tests/cmocka/ifp_tests-common_mock_resp.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/ifp_tests-common_mock_resp_dp.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/ifp_tests-responder_packet.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/ifp_tests-responder_cmd.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/ifp_tests-negcache.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/ifp_tests-responder_common.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/ifp_tests-responder_cache_req.$(OBJEXT) @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@am_ifp_tests_OBJECTS = \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(am__objects_34) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/tests/cmocka/ifp_tests-test_ifp.$(OBJEXT) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/responder/ifp/ifp_tests-ifpsrv_cmd.$(OBJEXT) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/responder/ifp/ifp_tests-ifp_iface_generated.$(OBJEXT) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/responder/ifp/ifp_tests-ifpsrv_util.$(OBJEXT) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/responder/common/ifp_tests-responder_utils.$(OBJEXT) ifp_tests_OBJECTS = $(am_ifp_tests_OBJECTS) @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ifp_tests_DEPENDENCIES = \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_5) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ libsss_test_common.la ifp_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ifp_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__ipa_hbac_tests_SOURCES_DIST = src/tests/ipa_hbac-tests.c @HAVE_CHECK_TRUE@am_ipa_hbac_tests_OBJECTS = src/tests/ipa_hbac_tests-ipa_hbac-tests.$(OBJEXT) ipa_hbac_tests_OBJECTS = $(am_ipa_hbac_tests_OBJECTS) @HAVE_CHECK_TRUE@ipa_hbac_tests_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) libsss_test_common.la \ @HAVE_CHECK_TRUE@ libipa_hbac.la ipa_hbac_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(ipa_hbac_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ $@ am__ipa_ldap_opt_tests_SOURCES_DIST = \ src/providers/data_provider_opts.c src/providers/ldap/sdap.c \ src/providers/ldap/sdap_range.c \ src/providers/ldap/sdap_domain.c \ src/providers/ldap/ldap_opts.c src/providers/ad/ad_opts.c \ src/providers/ipa/ipa_opts.c src/providers/krb5/krb5_opts.c \ src/util/sss_ldap.c src/tests/ipa_ldap_opt-tests.c @HAVE_CHECK_TRUE@am_ipa_ldap_opt_tests_OBJECTS = src/providers/ipa_ldap_opt_tests-data_provider_opts.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/ldap/ipa_ldap_opt_tests-sdap.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/ldap/ipa_ldap_opt_tests-sdap_range.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/ad/ipa_ldap_opt_tests-ad_opts.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/util/ipa_ldap_opt_tests-sss_ldap.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.$(OBJEXT) ipa_ldap_opt_tests_OBJECTS = $(am_ipa_ldap_opt_tests_OBJECTS) @HAVE_CHECK_TRUE@ipa_ldap_opt_tests_DEPENDENCIES = \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) libsss_test_common.la ipa_ldap_opt_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__objects_35 = src/resolv/krb5_child_test-async_resolv.$(OBJEXT) \ src/resolv/krb5_child_test-async_resolv_utils.$(OBJEXT) am__objects_36 = src/providers/krb5_child_test-fail_over.$(OBJEXT) \ src/providers/krb5_child_test-fail_over_srv.$(OBJEXT) \ $(am__objects_35) am_krb5_child_test_OBJECTS = \ src/tests/krb5_child_test-krb5_child-test.$(OBJEXT) \ src/providers/krb5/krb5_child_test-krb5_utils.$(OBJEXT) \ src/providers/krb5/krb5_child_test-krb5_ccache.$(OBJEXT) \ src/providers/krb5/krb5_child_test-krb5_child_handler.$(OBJEXT) \ src/providers/krb5/krb5_child_test-krb5_common.$(OBJEXT) \ src/providers/krb5/krb5_child_test-krb5_opts.$(OBJEXT) \ src/util/krb5_child_test-sss_krb5.$(OBJEXT) \ src/providers/krb5_child_test-data_provider_fo.$(OBJEXT) \ src/providers/krb5_child_test-data_provider_opts.$(OBJEXT) \ src/providers/krb5_child_test-data_provider_callbacks.$(OBJEXT) \ src/util/krb5_child_test-become_user.$(OBJEXT) \ $(am__objects_36) krb5_child_test_OBJECTS = $(am_krb5_child_test_OBJECTS) krb5_child_test_DEPENDENCIES = $(am__DEPENDENCIES_5) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ libsss_test_common.la krb5_child_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(krb5_child_test_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__krb5_utils_tests_SOURCES_DIST = src/tests/krb5_utils-tests.c \ src/providers/krb5/krb5_utils.c \ src/providers/krb5/krb5_ccache.c \ src/providers/krb5/krb5_common.c \ src/providers/krb5/krb5_opts.c src/util/sss_krb5.c \ src/providers/data_provider_fo.c \ src/providers/data_provider_opts.c \ src/providers/data_provider_callbacks.c src/util/become_user.c \ src/providers/fail_over.c src/providers/fail_over_srv.c \ src/resolv/async_resolv.c src/resolv/async_resolv_utils.c am__objects_37 = src/resolv/krb5_utils_tests-async_resolv.$(OBJEXT) \ src/resolv/krb5_utils_tests-async_resolv_utils.$(OBJEXT) am__objects_38 = src/providers/krb5_utils_tests-fail_over.$(OBJEXT) \ src/providers/krb5_utils_tests-fail_over_srv.$(OBJEXT) \ $(am__objects_37) @HAVE_CHECK_TRUE@am_krb5_utils_tests_OBJECTS = src/tests/krb5_utils_tests-krb5_utils-tests.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/krb5/krb5_utils_tests-krb5_utils.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/krb5/krb5_utils_tests-krb5_ccache.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/krb5/krb5_utils_tests-krb5_common.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/krb5/krb5_utils_tests-krb5_opts.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/util/krb5_utils_tests-sss_krb5.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/krb5_utils_tests-data_provider_fo.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/krb5_utils_tests-data_provider_opts.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/krb5_utils_tests-data_provider_callbacks.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/util/krb5_utils_tests-become_user.$(OBJEXT) \ @HAVE_CHECK_TRUE@ $(am__objects_38) krb5_utils_tests_OBJECTS = $(am_krb5_utils_tests_OBJECTS) @HAVE_CHECK_TRUE@krb5_utils_tests_DEPENDENCIES = \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la krb5_utils_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(krb5_utils_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am_krb5_child_OBJECTS = \ src/providers/krb5/krb5_child-krb5_child.$(OBJEXT) \ src/providers/krb5/krb5_child-krb5_ccache.$(OBJEXT) \ src/providers/krb5/krb5_child-krb5_keytab.$(OBJEXT) \ src/providers/krb5_child-dp_pam_data_util.$(OBJEXT) \ src/util/krb5_child-user_info_msg.$(OBJEXT) \ src/util/krb5_child-sss_krb5.$(OBJEXT) \ src/util/krb5_child-find_uid.$(OBJEXT) \ src/util/krb5_child-atomic_io.$(OBJEXT) \ src/util/krb5_child-authtok.$(OBJEXT) \ src/util/krb5_child-authtok-utils.$(OBJEXT) \ src/util/krb5_child-util.$(OBJEXT) \ src/util/krb5_child-signal.$(OBJEXT) \ src/util/krb5_child-strtonum.$(OBJEXT) \ src/util/krb5_child-become_user.$(OBJEXT) \ src/util/krb5_child-util_errors.$(OBJEXT) \ src/sss_client/krb5_child-common.$(OBJEXT) krb5_child_OBJECTS = $(am_krb5_child_OBJECTS) krb5_child_DEPENDENCIES = libsss_debug.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_6) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) krb5_child_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(krb5_child_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_ldap_child_OBJECTS = \ src/providers/ldap/ldap_child-ldap_child.$(OBJEXT) \ src/providers/krb5/ldap_child-krb5_keytab.$(OBJEXT) \ src/util/ldap_child-sss_krb5.$(OBJEXT) \ src/util/ldap_child-atomic_io.$(OBJEXT) \ src/util/ldap_child-authtok.$(OBJEXT) \ src/util/ldap_child-authtok-utils.$(OBJEXT) \ src/util/ldap_child-util.$(OBJEXT) \ src/util/ldap_child-signal.$(OBJEXT) \ src/util/ldap_child-become_user.$(OBJEXT) ldap_child_OBJECTS = $(am_ldap_child_OBJECTS) ldap_child_DEPENDENCIES = libsss_debug.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) ldap_child_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ldap_child_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__nestedgroups_tests_SOURCES_DIST = src/util/sss_ldap.c \ src/providers/data_provider_opts.c \ src/providers/ldap/ldap_opts.c \ src/providers/ldap/ldap_options.c \ src/providers/ldap/sdap_domain.c src/providers/ldap/sdap.c \ src/providers/ldap/sdap_utils.c \ src/providers/ldap/sdap_range.c \ src/tests/cmocka/common_mock_sdap.c \ src/tests/cmocka/common_mock_sysdb_objects.c \ src/providers/ldap/sdap_idmap.c \ src/tests/cmocka/test_nested_groups.c \ src/tests/cmocka/common_mock_be.c \ src/providers/ldap/sdap_async_nested_groups.c \ src/providers/ldap/sdap_ad_groups.c src/providers/ipa/ipa_dn.c @HAVE_CMOCKA_TRUE@am__objects_39 = src/util/nestedgroups_tests-sss_ldap.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/nestedgroups_tests-data_provider_opts.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/nestedgroups_tests-ldap_opts.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/nestedgroups_tests-ldap_options.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/nestedgroups_tests-sdap_domain.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/nestedgroups_tests-sdap.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/nestedgroups_tests-sdap_utils.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/nestedgroups_tests-sdap_range.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/nestedgroups_tests-common_mock_sdap.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.$(OBJEXT) @HAVE_CMOCKA_TRUE@am_nestedgroups_tests_OBJECTS = $(am__objects_39) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/nestedgroups_tests-sdap_idmap.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/nestedgroups_tests-test_nested_groups.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/nestedgroups_tests-common_mock_be.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/nestedgroups_tests-sdap_ad_groups.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/nestedgroups_tests-ipa_dn.$(OBJEXT) nestedgroups_tests_OBJECTS = $(am_nestedgroups_tests_OBJECTS) @HAVE_CMOCKA_TRUE@nestedgroups_tests_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_idmap.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la nestedgroups_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(nestedgroups_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__nss_srv_tests_SOURCES_DIST = src/tests/cmocka/common_mock_resp.c \ src/tests/cmocka/common_mock_resp_dp.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_cmd.c \ src/responder/common/negcache.c \ src/responder/common/responder_common.c \ src/responder/common/responder_cache_req.c \ src/tests/cmocka/test_nss_srv.c src/responder/nss/nsssrv_cmd.c \ src/responder/nss/nsssrv_netgroup.c \ src/responder/nss/nsssrv_services.c \ src/responder/nss/nsssrv_mmap_cache.c @HAVE_CMOCKA_TRUE@am__objects_40 = src/tests/cmocka/nss_srv_tests-common_mock_resp.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/nss_srv_tests-responder_packet.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/nss_srv_tests-responder_cmd.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/nss_srv_tests-negcache.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/nss_srv_tests-responder_common.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/nss_srv_tests-responder_cache_req.$(OBJEXT) @HAVE_CMOCKA_TRUE@am_nss_srv_tests_OBJECTS = $(am__objects_40) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/nss_srv_tests-test_nss_srv.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/nss/nss_srv_tests-nsssrv_cmd.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/nss/nss_srv_tests-nsssrv_netgroup.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/nss/nss_srv_tests-nsssrv_services.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.$(OBJEXT) nss_srv_tests_OBJECTS = $(am_nss_srv_tests_OBJECTS) @HAVE_CMOCKA_TRUE@nss_srv_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la libsss_idmap.la nss_srv_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(nss_srv_tests_CFLAGS) \ $(CFLAGS) $(nss_srv_tests_LDFLAGS) $(LDFLAGS) -o $@ am_p11_child_OBJECTS = \ src/p11_child/p11_child-p11_child_nss.$(OBJEXT) \ src/util/p11_child-atomic_io.$(OBJEXT) \ src/util/p11_child-util.$(OBJEXT) p11_child_OBJECTS = $(am_p11_child_OBJECTS) p11_child_DEPENDENCIES = libsss_debug.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) libsss_crypt.la p11_child_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(p11_child_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__pam_srv_tests_SOURCES_DIST = src/tests/cmocka/common_mock_resp.c \ src/tests/cmocka/common_mock_resp_dp.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_cmd.c \ src/responder/common/negcache.c \ src/responder/common/responder_common.c \ src/responder/common/responder_cache_req.c \ src/tests/cmocka/test_pam_srv.c src/sss_client/pam_message.c \ src/responder/pam/pamsrv_cmd.c src/responder/pam/pamsrv_p11.c \ src/responder/pam/pam_helpers.c src/responder/pam/pamsrv_dp.c \ src/responder/pam/pam_LOCAL_domain.c @HAVE_CMOCKA_TRUE@am__objects_41 = src/tests/cmocka/pam_srv_tests-common_mock_resp.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/pam_srv_tests-responder_packet.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/pam_srv_tests-responder_cmd.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/pam_srv_tests-negcache.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/pam_srv_tests-responder_common.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/pam_srv_tests-responder_cache_req.$(OBJEXT) @HAVE_CMOCKA_TRUE@am_pam_srv_tests_OBJECTS = $(am__objects_41) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/pam_srv_tests-test_pam_srv.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/sss_client/pam_srv_tests-pam_message.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/pam/pam_srv_tests-pamsrv_cmd.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/pam/pam_srv_tests-pamsrv_p11.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/pam/pam_srv_tests-pam_helpers.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/pam/pam_srv_tests-pamsrv_dp.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/pam/pam_srv_tests-pam_LOCAL_domain.$(OBJEXT) pam_srv_tests_OBJECTS = $(am_pam_srv_tests_OBJECTS) @HAVE_CMOCKA_TRUE@pam_srv_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libsss_idmap.la pam_srv_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(pam_srv_tests_CFLAGS) \ $(CFLAGS) $(pam_srv_tests_LDFLAGS) $(LDFLAGS) -o $@ am_pam_test_client_OBJECTS = src/sss_client/pam_test_client.$(OBJEXT) pam_test_client_OBJECTS = $(am_pam_test_client_OBJECTS) pam_test_client_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) am_proxy_child_OBJECTS = \ src/providers/proxy/proxy_child-proxy_child.$(OBJEXT) \ src/providers/proxy_child-data_provider_iface_generated.$(OBJEXT) proxy_child_OBJECTS = $(am_proxy_child_OBJECTS) proxy_child_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ $(am__DEPENDENCIES_2) proxy_child_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(proxy_child_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__refcount_tests_SOURCES_DIST = src/tests/refcount-tests.c @HAVE_CHECK_TRUE@am_refcount_tests_OBJECTS = src/tests/refcount_tests-refcount-tests.$(OBJEXT) refcount_tests_OBJECTS = $(am_refcount_tests_OBJECTS) @HAVE_CHECK_TRUE@refcount_tests_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ @HAVE_CHECK_TRUE@ libsss_test_common.la refcount_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(refcount_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ $@ am__resolv_tests_SOURCES_DIST = src/tests/resolv-tests.c \ src/tests/common.c src/resolv/async_resolv.c \ src/resolv/async_resolv_utils.c am__objects_42 = src/resolv/resolv_tests-async_resolv.$(OBJEXT) \ src/resolv/resolv_tests-async_resolv_utils.$(OBJEXT) @HAVE_CHECK_TRUE@am__objects_43 = $(am__objects_42) @HAVE_CHECK_TRUE@am_resolv_tests_OBJECTS = src/tests/resolv_tests-resolv-tests.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/tests/resolv_tests-common.$(OBJEXT) \ @HAVE_CHECK_TRUE@ $(am__objects_43) resolv_tests_OBJECTS = $(am_resolv_tests_OBJECTS) @HAVE_CHECK_TRUE@resolv_tests_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ libsss_debug.la libsss_test_common.la resolv_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(resolv_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__responder_get_domains_tests_SOURCES_DIST = \ src/responder/common/responder_get_domains.c \ src/tests/cmocka/test_responder_common.c \ src/tests/cmocka/common_mock_resp.c @HAVE_CMOCKA_TRUE@am_responder_get_domains_tests_OBJECTS = src/responder/common/responder_get_domains_tests-responder_get_domains.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/responder_get_domains_tests-test_responder_common.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/responder_get_domains_tests-common_mock_resp.$(OBJEXT) responder_get_domains_tests_OBJECTS = \ $(am_responder_get_domains_tests_OBJECTS) @HAVE_CMOCKA_TRUE@responder_get_domains_tests_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la responder_get_domains_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(responder_get_domains_tests_CFLAGS) $(CFLAGS) \ $(responder_get_domains_tests_LDFLAGS) $(LDFLAGS) -o $@ am__responder_cache_req_tests_SOURCES_DIST = \ src/tests/cmocka/common_mock_resp.c \ src/tests/cmocka/common_mock_resp_dp.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_cmd.c \ src/responder/common/negcache.c \ src/responder/common/responder_common.c \ src/responder/common/responder_cache_req.c \ src/tests/cmocka/test_responder_cache_req.c @HAVE_CMOCKA_TRUE@am__objects_44 = src/tests/cmocka/responder_cache_req_tests-common_mock_resp.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/responder_cache_req_tests-responder_packet.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/responder_cache_req_tests-responder_cmd.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/responder_cache_req_tests-negcache.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/responder_cache_req_tests-responder_common.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/responder/common/responder_cache_req_tests-responder_cache_req.$(OBJEXT) @HAVE_CMOCKA_TRUE@am_responder_cache_req_tests_OBJECTS = \ @HAVE_CMOCKA_TRUE@ $(am__objects_44) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.$(OBJEXT) responder_cache_req_tests_OBJECTS = \ $(am_responder_cache_req_tests_OBJECTS) @HAVE_CMOCKA_TRUE@responder_cache_req_tests_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la responder_cache_req_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(responder_cache_req_tests_CFLAGS) $(CFLAGS) \ $(responder_cache_req_tests_LDFLAGS) $(LDFLAGS) -o $@ am__responder_socket_access_tests_SOURCES_DIST = \ src/tests/responder_socket_access-tests.c \ src/responder/common/responder_common.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_cmd.c @HAVE_CHECK_TRUE@am_responder_socket_access_tests_OBJECTS = src/tests/responder_socket_access_tests-responder_socket_access-tests.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/responder/common/responder_socket_access_tests-responder_common.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/responder/common/responder_socket_access_tests-responder_packet.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/responder/common/responder_socket_access_tests-responder_cmd.$(OBJEXT) responder_socket_access_tests_OBJECTS = \ $(am_responder_socket_access_tests_OBJECTS) @HAVE_CHECK_TRUE@responder_socket_access_tests_DEPENDENCIES = \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la responder_socket_access_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(responder_socket_access_tests_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__safe_format_tests_SOURCES_DIST = src/tests/safe-format-tests.c @HAVE_CHECK_TRUE@am_safe_format_tests_OBJECTS = src/tests/safe_format_tests-safe-format-tests.$(OBJEXT) safe_format_tests_OBJECTS = $(am_safe_format_tests_OBJECTS) @HAVE_CHECK_TRUE@safe_format_tests_DEPENDENCIES = \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la safe_format_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(safe_format_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__sbus_internal_tests_SOURCES_DIST = \ src/tests/cmocka/sbus_internal_tests.c \ src/sbus/sssd_dbus_request.c @HAVE_CMOCKA_TRUE@am_sbus_internal_tests_OBJECTS = src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/sbus/sbus_internal_tests-sssd_dbus_request.$(OBJEXT) sbus_internal_tests_OBJECTS = $(am_sbus_internal_tests_OBJECTS) @HAVE_CMOCKA_TRUE@sbus_internal_tests_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ @HAVE_CMOCKA_TRUE@ libsss_util.la libsss_crypt.la \ @HAVE_CMOCKA_TRUE@ libsss_debug.la libsss_test_common.la sbus_internal_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sbus_internal_tests_CFLAGS) $(CFLAGS) \ $(sbus_internal_tests_LDFLAGS) $(LDFLAGS) -o $@ am__sbus_codegen_tests_SOURCES_DIST = src/tests/common_dbus.c \ src/tests/sbus_codegen_tests.c \ src/tests/sbus_codegen_tests_generated.c \ src/tests/sbus_codegen_tests_generated.h @BUILD_DBUS_TESTS_TRUE@am_sbus_codegen_tests_OBJECTS = src/tests/sbus_codegen_tests-common_dbus.$(OBJEXT) \ @BUILD_DBUS_TESTS_TRUE@ src/tests/sbus_codegen_tests-sbus_codegen_tests.$(OBJEXT) \ @BUILD_DBUS_TESTS_TRUE@ src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.$(OBJEXT) sbus_codegen_tests_OBJECTS = $(am_sbus_codegen_tests_OBJECTS) @BUILD_DBUS_TESTS_TRUE@sbus_codegen_tests_DEPENDENCIES = \ @BUILD_DBUS_TESTS_TRUE@ $(am__DEPENDENCIES_2) \ @BUILD_DBUS_TESTS_TRUE@ $(am__DEPENDENCIES_5) \ @BUILD_DBUS_TESTS_TRUE@ $(am__DEPENDENCIES_1) sbus_codegen_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sbus_codegen_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__sbus_tests_SOURCES_DIST = src/tests/common_dbus.c \ src/tests/sbus_tests.c @BUILD_DBUS_TESTS_TRUE@am_sbus_tests_OBJECTS = src/tests/sbus_tests-common_dbus.$(OBJEXT) \ @BUILD_DBUS_TESTS_TRUE@ src/tests/sbus_tests-sbus_tests.$(OBJEXT) sbus_tests_OBJECTS = $(am_sbus_tests_OBJECTS) @BUILD_DBUS_TESTS_TRUE@sbus_tests_DEPENDENCIES = \ @BUILD_DBUS_TESTS_TRUE@ $(am__DEPENDENCIES_2) \ @BUILD_DBUS_TESTS_TRUE@ $(am__DEPENDENCIES_5) \ @BUILD_DBUS_TESTS_TRUE@ $(am__DEPENDENCIES_1) sbus_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sbus_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__sdap_tests_SOURCES_DIST = src/providers/data_provider_opts.c \ src/providers/ldap/sdap_domain.c src/providers/ldap/sdap.c \ src/providers/ldap/sdap_range.c src/providers/ldap/ldap_opts.c \ src/providers/ipa/ipa_opts.c src/util/sss_ldap.c \ src/tests/cmocka/test_sdap.c @HAVE_CMOCKA_TRUE@am_sdap_tests_OBJECTS = src/providers/sdap_tests-data_provider_opts.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_tests-sdap_domain.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_tests-sdap.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_tests-sdap_range.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_tests-ldap_opts.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/sdap_tests-ipa_opts.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/sdap_tests-sss_ldap.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/sdap_tests-test_sdap.$(OBJEXT) sdap_tests_OBJECTS = $(am_sdap_tests_OBJECTS) @HAVE_CMOCKA_TRUE@sdap_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) libsss_test_common.la sdap_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sdap_tests_CFLAGS) \ $(CFLAGS) $(sdap_tests_LDFLAGS) $(LDFLAGS) -o $@ am__selinux_child_SOURCES_DIST = src/providers/ipa/selinux_child.c \ src/util/sss_semanage.c src/util/atomic_io.c src/util/util.c @BUILD_SEMANAGE_TRUE@am_selinux_child_OBJECTS = src/providers/ipa/selinux_child-selinux_child.$(OBJEXT) \ @BUILD_SEMANAGE_TRUE@ src/util/selinux_child-sss_semanage.$(OBJEXT) \ @BUILD_SEMANAGE_TRUE@ src/util/selinux_child-atomic_io.$(OBJEXT) \ @BUILD_SEMANAGE_TRUE@ src/util/selinux_child-util.$(OBJEXT) selinux_child_OBJECTS = $(am_selinux_child_OBJECTS) @BUILD_SEMANAGE_TRUE@selinux_child_DEPENDENCIES = libsss_debug.la \ @BUILD_SEMANAGE_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_SEMANAGE_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_SEMANAGE_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_SEMANAGE_TRUE@ $(am__DEPENDENCIES_1) selinux_child_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(selinux_child_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__simple_access_tests_SOURCES_DIST = \ src/tests/simple_access-tests.c \ src/providers/simple/simple_access.c \ src/providers/simple/simple_access_check.c @HAVE_CHECK_TRUE@am_simple_access_tests_OBJECTS = \ @HAVE_CHECK_TRUE@ src/tests/simple_access-tests.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/simple/simple_access.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/providers/simple/simple_access_check.$(OBJEXT) simple_access_tests_OBJECTS = $(am_simple_access_tests_OBJECTS) @HAVE_CHECK_TRUE@simple_access_tests_DEPENDENCIES = \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \ @HAVE_CHECK_TRUE@ libsss_test_common.la \ @HAVE_CHECK_TRUE@ libdlopen_test_providers.la am__objects_45 = src/tools/sss_cache-sss_sync_ops.$(OBJEXT) \ src/tools/sss_cache-tools_util.$(OBJEXT) \ src/tools/sss_cache-files.$(OBJEXT) \ src/tools/sss_cache-selinux.$(OBJEXT) \ src/tools/common/sss_cache-sss_tools.$(OBJEXT) \ src/util/sss_cache-nscd.$(OBJEXT) am__objects_46 = src/sss_client/sss_cache-common.$(OBJEXT) \ src/tools/sss_cache-tools_mc_util.$(OBJEXT) $(am__objects_45) am_sss_cache_OBJECTS = src/tools/sss_cache-sss_cache.$(OBJEXT) \ $(am__objects_46) sss_cache_OBJECTS = $(am_sss_cache_OBJECTS) am__DEPENDENCIES_15 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_3) sss_cache_DEPENDENCIES = $(am__DEPENDENCIES_15) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_6) sss_cache_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sss_cache_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__sss_config_tests_SOURCES_DIST = src/tests/sss_config-tests.c \ src/tests/common.c @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@am_sss_config_tests_OBJECTS = src/tests/sss_config_tests-sss_config-tests.$(OBJEXT) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ src/tests/sss_config_tests-common.$(OBJEXT) sss_config_tests_OBJECTS = $(am_sss_config_tests_OBJECTS) @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@sss_config_tests_DEPENDENCIES = \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(am__DEPENDENCIES_5) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(am__DEPENDENCIES_2) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ libsss_config.la \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ libsss_test_common.la sss_config_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sss_config_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__objects_47 = src/tools/sss_sync_ops.$(OBJEXT) \ src/tools/tools_util.$(OBJEXT) src/tools/files.$(OBJEXT) \ src/tools/selinux.$(OBJEXT) \ src/tools/common/sss_tools.$(OBJEXT) src/util/nscd.$(OBJEXT) am_sss_debuglevel_OBJECTS = src/tools/sss_debuglevel.$(OBJEXT) \ $(am__objects_47) sss_debuglevel_OBJECTS = $(am_sss_debuglevel_OBJECTS) sss_debuglevel_DEPENDENCIES = $(am__DEPENDENCIES_15) \ $(am__DEPENDENCIES_2) am_sss_groupadd_OBJECTS = src/tools/sss_groupadd.$(OBJEXT) \ $(am__objects_47) sss_groupadd_OBJECTS = $(am_sss_groupadd_OBJECTS) sss_groupadd_DEPENDENCIES = $(am__DEPENDENCIES_15) \ $(am__DEPENDENCIES_2) am__objects_48 = src/tools/sss_groupdel-sss_sync_ops.$(OBJEXT) \ src/tools/sss_groupdel-tools_util.$(OBJEXT) \ src/tools/sss_groupdel-files.$(OBJEXT) \ src/tools/sss_groupdel-selinux.$(OBJEXT) \ src/tools/common/sss_groupdel-sss_tools.$(OBJEXT) \ src/util/sss_groupdel-nscd.$(OBJEXT) am__objects_49 = src/sss_client/sss_groupdel-common.$(OBJEXT) \ src/tools/sss_groupdel-tools_mc_util.$(OBJEXT) \ $(am__objects_48) am_sss_groupdel_OBJECTS = \ src/tools/sss_groupdel-sss_groupdel.$(OBJEXT) \ $(am__objects_49) sss_groupdel_OBJECTS = $(am_sss_groupdel_OBJECTS) sss_groupdel_DEPENDENCIES = $(am__DEPENDENCIES_15) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_6) sss_groupdel_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sss_groupdel_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__objects_50 = src/tools/sss_groupmod-sss_sync_ops.$(OBJEXT) \ src/tools/sss_groupmod-tools_util.$(OBJEXT) \ src/tools/sss_groupmod-files.$(OBJEXT) \ src/tools/sss_groupmod-selinux.$(OBJEXT) \ src/tools/common/sss_groupmod-sss_tools.$(OBJEXT) \ src/util/sss_groupmod-nscd.$(OBJEXT) am__objects_51 = src/sss_client/sss_groupmod-common.$(OBJEXT) \ src/tools/sss_groupmod-tools_mc_util.$(OBJEXT) \ $(am__objects_50) am_sss_groupmod_OBJECTS = \ src/tools/sss_groupmod-sss_groupmod.$(OBJEXT) \ $(am__objects_51) sss_groupmod_OBJECTS = $(am_sss_groupmod_OBJECTS) sss_groupmod_DEPENDENCIES = $(am__DEPENDENCIES_15) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_6) sss_groupmod_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sss_groupmod_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_sss_groupshow_OBJECTS = src/tools/sss_groupshow.$(OBJEXT) \ $(am__objects_47) sss_groupshow_OBJECTS = $(am_sss_groupshow_OBJECTS) sss_groupshow_DEPENDENCIES = $(am__DEPENDENCIES_15) \ $(am__DEPENDENCIES_2) am__sss_idmap_tests_SOURCES_DIST = src/tests/sss_idmap-tests.c @HAVE_CHECK_TRUE@am_sss_idmap_tests_OBJECTS = src/tests/sss_idmap_tests-sss_idmap-tests.$(OBJEXT) sss_idmap_tests_OBJECTS = $(am_sss_idmap_tests_OBJECTS) @HAVE_CHECK_TRUE@sss_idmap_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) libsss_test_common.la \ @HAVE_CHECK_TRUE@ libsss_idmap.la sss_idmap_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sss_idmap_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__sss_nss_idmap_tests_SOURCES_DIST = \ src/tests/cmocka/sss_nss_idmap-tests.c @HAVE_CMOCKA_TRUE@am_sss_nss_idmap_tests_OBJECTS = src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.$(OBJEXT) sss_nss_idmap_tests_OBJECTS = $(am_sss_nss_idmap_tests_OBJECTS) @HAVE_CMOCKA_TRUE@sss_nss_idmap_tests_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ libsss_nss_idmap_tests.la sss_nss_idmap_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sss_nss_idmap_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__objects_52 = src/tools/sss_override-sss_sync_ops.$(OBJEXT) \ src/tools/sss_override-tools_util.$(OBJEXT) \ src/tools/sss_override-files.$(OBJEXT) \ src/tools/sss_override-selinux.$(OBJEXT) \ src/tools/common/sss_override-sss_tools.$(OBJEXT) \ src/util/sss_override-nscd.$(OBJEXT) am_sss_override_OBJECTS = \ src/tools/sss_override-sss_override.$(OBJEXT) \ src/tools/common/sss_override-sss_colondb.$(OBJEXT) \ $(am__objects_52) sss_override_OBJECTS = $(am_sss_override_OBJECTS) sss_override_DEPENDENCIES = $(am__DEPENDENCIES_15) \ $(am__DEPENDENCIES_2) sss_override_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sss_override_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_sss_seed_OBJECTS = src/tools/sss_seed.$(OBJEXT) $(am__objects_47) sss_seed_OBJECTS = $(am_sss_seed_OBJECTS) sss_seed_DEPENDENCIES = $(am__DEPENDENCIES_15) $(am__DEPENDENCIES_2) am__sss_sifp_tests_SOURCES_DIST = src/tests/cmocka/test_sss_sifp.c \ src/lib/sifp/sss_sifp_attrs.c src/lib/sifp/sss_sifp_common.c \ src/lib/sifp/sss_sifp_parser.c src/lib/sifp/sss_sifp_utils.c \ src/lib/sifp/sss_sifp_dbus.c src/lib/sifp/sss_sifp.c @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@am_sss_sifp_tests_OBJECTS = src/tests/cmocka/sss_sifp_tests-test_sss_sifp.$(OBJEXT) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.$(OBJEXT) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp_tests-sss_sifp_common.$(OBJEXT) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp_tests-sss_sifp_parser.$(OBJEXT) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp_tests-sss_sifp_utils.$(OBJEXT) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.$(OBJEXT) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp_tests-sss_sifp.$(OBJEXT) sss_sifp_tests_OBJECTS = $(am_sss_sifp_tests_OBJECTS) @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@sss_sifp_tests_DEPENDENCIES = \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) sss_sifp_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sss_sifp_tests_CFLAGS) $(CFLAGS) $(sss_sifp_tests_LDFLAGS) \ $(LDFLAGS) -o $@ am_sss_signal_OBJECTS = src/tools/sss_signal.$(OBJEXT) \ $(am__objects_47) sss_signal_OBJECTS = $(am_sss_signal_OBJECTS) sss_signal_DEPENDENCIES = $(am__DEPENDENCIES_15) $(am__DEPENDENCIES_2) am__sss_ssh_authorizedkeys_SOURCES_DIST = src/sss_client/common.c \ src/sss_client/ssh/sss_ssh_client.c \ src/sss_client/ssh/sss_ssh_authorizedkeys.c @BUILD_SSH_TRUE@am_sss_ssh_authorizedkeys_OBJECTS = src/sss_client/sss_ssh_authorizedkeys-common.$(OBJEXT) \ @BUILD_SSH_TRUE@ src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.$(OBJEXT) \ @BUILD_SSH_TRUE@ src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.$(OBJEXT) sss_ssh_authorizedkeys_OBJECTS = $(am_sss_ssh_authorizedkeys_OBJECTS) @BUILD_SSH_TRUE@sss_ssh_authorizedkeys_DEPENDENCIES = \ @BUILD_SSH_TRUE@ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_6) \ @BUILD_SSH_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) sss_ssh_authorizedkeys_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__sss_ssh_knownhostsproxy_SOURCES_DIST = src/sss_client/common.c \ src/sss_client/ssh/sss_ssh_client.c \ src/sss_client/ssh/sss_ssh_knownhostsproxy.c @BUILD_SSH_TRUE@am_sss_ssh_knownhostsproxy_OBJECTS = src/sss_client/sss_ssh_knownhostsproxy-common.$(OBJEXT) \ @BUILD_SSH_TRUE@ src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.$(OBJEXT) \ @BUILD_SSH_TRUE@ src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.$(OBJEXT) sss_ssh_knownhostsproxy_OBJECTS = \ $(am_sss_ssh_knownhostsproxy_OBJECTS) @BUILD_SSH_TRUE@sss_ssh_knownhostsproxy_DEPENDENCIES = \ @BUILD_SSH_TRUE@ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_6) \ @BUILD_SSH_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) sss_ssh_knownhostsproxy_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__sss_sudo_cli_SOURCES_DIST = src/sss_client/common.c \ src/sss_client/sudo/sss_sudo.c \ src/sss_client/sudo/sss_sudo_response.c \ src/sss_client/sudo_testcli/sudo_testcli.c @BUILD_SUDO_TRUE@am_sss_sudo_cli_OBJECTS = \ @BUILD_SUDO_TRUE@ src/sss_client/sss_sudo_cli-common.$(OBJEXT) \ @BUILD_SUDO_TRUE@ src/sss_client/sudo/sss_sudo_cli-sss_sudo.$(OBJEXT) \ @BUILD_SUDO_TRUE@ src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.$(OBJEXT) \ @BUILD_SUDO_TRUE@ src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.$(OBJEXT) sss_sudo_cli_OBJECTS = $(am_sss_sudo_cli_OBJECTS) @BUILD_SUDO_TRUE@sss_sudo_cli_DEPENDENCIES = $(am__DEPENDENCIES_6) sss_sudo_cli_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sss_sudo_cli_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_sss_useradd_OBJECTS = src/tools/sss_useradd.$(OBJEXT) \ $(am__objects_47) sss_useradd_OBJECTS = $(am_sss_useradd_OBJECTS) sss_useradd_DEPENDENCIES = $(am__DEPENDENCIES_15) \ $(am__DEPENDENCIES_2) libsss_semanage.la am__objects_53 = src/tools/sss_userdel-sss_sync_ops.$(OBJEXT) \ src/tools/sss_userdel-tools_util.$(OBJEXT) \ src/tools/sss_userdel-files.$(OBJEXT) \ src/tools/sss_userdel-selinux.$(OBJEXT) \ src/tools/common/sss_userdel-sss_tools.$(OBJEXT) \ src/util/sss_userdel-nscd.$(OBJEXT) am__objects_54 = src/sss_client/sss_userdel-common.$(OBJEXT) \ src/tools/sss_userdel-tools_mc_util.$(OBJEXT) \ $(am__objects_53) am_sss_userdel_OBJECTS = src/tools/sss_userdel-sss_userdel.$(OBJEXT) \ $(am__objects_54) sss_userdel_OBJECTS = $(am_sss_userdel_OBJECTS) sss_userdel_DEPENDENCIES = $(am__DEPENDENCIES_15) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_6) libsss_semanage.la sss_userdel_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sss_userdel_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__objects_55 = src/tools/sss_usermod-sss_sync_ops.$(OBJEXT) \ src/tools/sss_usermod-tools_util.$(OBJEXT) \ src/tools/sss_usermod-files.$(OBJEXT) \ src/tools/sss_usermod-selinux.$(OBJEXT) \ src/tools/common/sss_usermod-sss_tools.$(OBJEXT) \ src/util/sss_usermod-nscd.$(OBJEXT) am__objects_56 = src/sss_client/sss_usermod-common.$(OBJEXT) \ src/tools/sss_usermod-tools_mc_util.$(OBJEXT) \ $(am__objects_55) am_sss_usermod_OBJECTS = src/tools/sss_usermod-sss_usermod.$(OBJEXT) \ $(am__objects_56) sss_usermod_OBJECTS = $(am_sss_usermod_OBJECTS) sss_usermod_DEPENDENCIES = $(am__DEPENDENCIES_15) \ $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_6) libsss_semanage.la sss_usermod_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sss_usermod_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_sssd_OBJECTS = src/monitor/monitor.$(OBJEXT) \ src/monitor/monitor_netlink.$(OBJEXT) \ src/confdb/confdb_setup.$(OBJEXT) src/util/nscd.$(OBJEXT) \ src/monitor/monitor_iface_generated.$(OBJEXT) sssd_OBJECTS = $(am_sssd_OBJECTS) sssd_DEPENDENCIES = $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) am__sssd_autofs_SOURCES_DIST = src/responder/autofs/autofssrv.c \ src/responder/autofs/autofssrv_cmd.c \ src/responder/autofs/autofssrv_dp.c \ src/responder/common/negcache.c \ src/responder/common/responder_cmd.c \ src/responder/common/responder_common.c \ src/responder/common/responder_dp.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_get_domains.c \ src/responder/common/responder_utils.c \ src/responder/common/responder_cache_req.c \ src/monitor/monitor_iface_generated.c \ src/monitor/monitor_iface_generated.h \ src/providers/data_provider_iface_generated.c \ src/providers/data_provider_iface_generated.h \ src/providers/data_provider_req.c am__objects_57 = src/responder/common/negcache.$(OBJEXT) \ src/responder/common/responder_cmd.$(OBJEXT) \ src/responder/common/responder_common.$(OBJEXT) \ src/responder/common/responder_dp.$(OBJEXT) \ src/responder/common/responder_packet.$(OBJEXT) \ src/responder/common/responder_get_domains.$(OBJEXT) \ src/responder/common/responder_utils.$(OBJEXT) \ src/responder/common/responder_cache_req.$(OBJEXT) \ src/monitor/monitor_iface_generated.$(OBJEXT) \ src/providers/data_provider_iface_generated.$(OBJEXT) \ src/providers/data_provider_req.$(OBJEXT) @BUILD_AUTOFS_TRUE@am_sssd_autofs_OBJECTS = \ @BUILD_AUTOFS_TRUE@ src/responder/autofs/autofssrv.$(OBJEXT) \ @BUILD_AUTOFS_TRUE@ src/responder/autofs/autofssrv_cmd.$(OBJEXT) \ @BUILD_AUTOFS_TRUE@ src/responder/autofs/autofssrv_dp.$(OBJEXT) \ @BUILD_AUTOFS_TRUE@ $(am__objects_57) sssd_autofs_OBJECTS = $(am_sssd_autofs_OBJECTS) @BUILD_AUTOFS_TRUE@sssd_autofs_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @BUILD_AUTOFS_TRUE@ $(am__DEPENDENCIES_2) am__objects_58 = src/resolv/async_resolv.$(OBJEXT) \ src/resolv/async_resolv_utils.$(OBJEXT) am__objects_59 = src/providers/fail_over.$(OBJEXT) \ src/providers/fail_over_srv.$(OBJEXT) $(am__objects_58) am_sssd_be_OBJECTS = src/providers/data_provider_be.$(OBJEXT) \ src/providers/data_provider_req.$(OBJEXT) \ src/providers/data_provider_fo.$(OBJEXT) \ src/providers/data_provider_opts.$(OBJEXT) \ src/providers/data_provider_callbacks.$(OBJEXT) \ src/providers/dp_dyndns.$(OBJEXT) \ src/providers/dp_ptask.$(OBJEXT) \ src/providers/dp_refresh.$(OBJEXT) \ src/monitor/monitor_iface_generated.$(OBJEXT) \ src/providers/data_provider_iface_generated.$(OBJEXT) \ $(am__objects_59) sssd_be_OBJECTS = $(am_sssd_be_OBJECTS) sssd_be_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) sssd_be_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(sssd_be_LDFLAGS) $(LDFLAGS) -o $@ am__sssd_ifp_SOURCES_DIST = src/responder/ifp/ifpsrv.c \ src/responder/ifp/ifpsrv_cmd.c \ src/responder/ifp/ifp_iface_generated.c \ src/responder/ifp/ifp_iface_generated.h \ src/responder/ifp/ifp_iface.c \ src/responder/ifp/ifp_iface_nodes.c \ src/responder/ifp/ifpsrv_util.c \ src/responder/ifp/ifp_domains.c \ src/responder/ifp/ifp_components.c \ src/responder/ifp/ifp_users.c src/responder/ifp/ifp_groups.c \ src/responder/ifp/ifp_cache.c src/responder/common/negcache.c \ src/responder/common/responder_cmd.c \ src/responder/common/responder_common.c \ src/responder/common/responder_dp.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_get_domains.c \ src/responder/common/responder_utils.c \ src/responder/common/responder_cache_req.c \ src/monitor/monitor_iface_generated.c \ src/monitor/monitor_iface_generated.h \ src/providers/data_provider_iface_generated.c \ src/providers/data_provider_iface_generated.h \ src/providers/data_provider_req.c am__objects_60 = src/responder/common/sssd_ifp-negcache.$(OBJEXT) \ src/responder/common/sssd_ifp-responder_cmd.$(OBJEXT) \ src/responder/common/sssd_ifp-responder_common.$(OBJEXT) \ src/responder/common/sssd_ifp-responder_dp.$(OBJEXT) \ src/responder/common/sssd_ifp-responder_packet.$(OBJEXT) \ src/responder/common/sssd_ifp-responder_get_domains.$(OBJEXT) \ src/responder/common/sssd_ifp-responder_utils.$(OBJEXT) \ src/responder/common/sssd_ifp-responder_cache_req.$(OBJEXT) \ src/monitor/sssd_ifp-monitor_iface_generated.$(OBJEXT) \ src/providers/sssd_ifp-data_provider_iface_generated.$(OBJEXT) \ src/providers/sssd_ifp-data_provider_req.$(OBJEXT) @BUILD_IFP_TRUE@am_sssd_ifp_OBJECTS = \ @BUILD_IFP_TRUE@ src/responder/ifp/sssd_ifp-ifpsrv.$(OBJEXT) \ @BUILD_IFP_TRUE@ src/responder/ifp/sssd_ifp-ifpsrv_cmd.$(OBJEXT) \ @BUILD_IFP_TRUE@ src/responder/ifp/sssd_ifp-ifp_iface_generated.$(OBJEXT) \ @BUILD_IFP_TRUE@ src/responder/ifp/sssd_ifp-ifp_iface.$(OBJEXT) \ @BUILD_IFP_TRUE@ src/responder/ifp/sssd_ifp-ifp_iface_nodes.$(OBJEXT) \ @BUILD_IFP_TRUE@ src/responder/ifp/sssd_ifp-ifpsrv_util.$(OBJEXT) \ @BUILD_IFP_TRUE@ src/responder/ifp/sssd_ifp-ifp_domains.$(OBJEXT) \ @BUILD_IFP_TRUE@ src/responder/ifp/sssd_ifp-ifp_components.$(OBJEXT) \ @BUILD_IFP_TRUE@ src/responder/ifp/sssd_ifp-ifp_users.$(OBJEXT) \ @BUILD_IFP_TRUE@ src/responder/ifp/sssd_ifp-ifp_groups.$(OBJEXT) \ @BUILD_IFP_TRUE@ src/responder/ifp/sssd_ifp-ifp_cache.$(OBJEXT) \ @BUILD_IFP_TRUE@ $(am__objects_60) sssd_ifp_OBJECTS = $(am_sssd_ifp_OBJECTS) @BUILD_IFP_TRUE@sssd_ifp_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @BUILD_IFP_TRUE@ $(am__DEPENDENCIES_2) libsss_cert.la \ @BUILD_IFP_TRUE@ $(am__append_42) sssd_ifp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sssd_ifp_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_sssd_nss_OBJECTS = src/responder/nss/nsssrv.$(OBJEXT) \ src/responder/nss/nsssrv_cmd.$(OBJEXT) \ src/responder/nss/nsssrv_netgroup.$(OBJEXT) \ src/responder/nss/nsssrv_services.$(OBJEXT) \ src/responder/nss/nsssrv_mmap_cache.$(OBJEXT) \ $(am__objects_57) sssd_nss_OBJECTS = $(am_sssd_nss_OBJECTS) sssd_nss_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ libsss_idmap.la $(am__DEPENDENCIES_2) am__objects_61 = src/responder/common/sssd_pac-negcache.$(OBJEXT) \ src/responder/common/sssd_pac-responder_cmd.$(OBJEXT) \ src/responder/common/sssd_pac-responder_common.$(OBJEXT) \ src/responder/common/sssd_pac-responder_dp.$(OBJEXT) \ src/responder/common/sssd_pac-responder_packet.$(OBJEXT) \ src/responder/common/sssd_pac-responder_get_domains.$(OBJEXT) \ src/responder/common/sssd_pac-responder_utils.$(OBJEXT) \ src/responder/common/sssd_pac-responder_cache_req.$(OBJEXT) \ src/monitor/sssd_pac-monitor_iface_generated.$(OBJEXT) \ src/providers/sssd_pac-data_provider_iface_generated.$(OBJEXT) \ src/providers/sssd_pac-data_provider_req.$(OBJEXT) am_sssd_pac_OBJECTS = src/responder/pac/sssd_pac-pacsrv.$(OBJEXT) \ src/responder/pac/sssd_pac-pacsrv_cmd.$(OBJEXT) \ src/responder/pac/sssd_pac-pacsrv_utils.$(OBJEXT) \ $(am__objects_61) sssd_pac_OBJECTS = $(am_sssd_pac_OBJECTS) sssd_pac_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_5) libsss_idmap.la $(am__DEPENDENCIES_2) sssd_pac_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sssd_pac_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_sssd_pam_OBJECTS = src/responder/pam/pam_LOCAL_domain.$(OBJEXT) \ src/responder/pam/pamsrv.$(OBJEXT) \ src/responder/pam/pamsrv_cmd.$(OBJEXT) \ src/responder/pam/pamsrv_p11.$(OBJEXT) \ src/responder/pam/pamsrv_dp.$(OBJEXT) \ src/responder/pam/pam_helpers.$(OBJEXT) $(am__objects_57) sssd_pam_OBJECTS = $(am_sssd_pam_OBJECTS) sssd_pam_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_2) am__sssd_ssh_SOURCES_DIST = src/responder/ssh/sshsrv.c \ src/responder/ssh/sshsrv_dp.c src/responder/ssh/sshsrv_cmd.c \ src/responder/common/negcache.c \ src/responder/common/responder_cmd.c \ src/responder/common/responder_common.c \ src/responder/common/responder_dp.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_get_domains.c \ src/responder/common/responder_utils.c \ src/responder/common/responder_cache_req.c \ src/monitor/monitor_iface_generated.c \ src/monitor/monitor_iface_generated.h \ src/providers/data_provider_iface_generated.c \ src/providers/data_provider_iface_generated.h \ src/providers/data_provider_req.c @BUILD_SSH_TRUE@am_sssd_ssh_OBJECTS = \ @BUILD_SSH_TRUE@ src/responder/ssh/sshsrv.$(OBJEXT) \ @BUILD_SSH_TRUE@ src/responder/ssh/sshsrv_dp.$(OBJEXT) \ @BUILD_SSH_TRUE@ src/responder/ssh/sshsrv_cmd.$(OBJEXT) \ @BUILD_SSH_TRUE@ $(am__objects_57) sssd_ssh_OBJECTS = $(am_sssd_ssh_OBJECTS) @BUILD_SSH_TRUE@sssd_ssh_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @BUILD_SSH_TRUE@ $(am__DEPENDENCIES_2) libsss_cert.la am__sssd_sudo_SOURCES_DIST = src/responder/sudo/sudosrv.c \ src/responder/sudo/sudosrv_cmd.c \ src/responder/sudo/sudosrv_get_sudorules.c \ src/responder/sudo/sudosrv_query.c \ src/responder/sudo/sudosrv_dp.c \ src/responder/common/negcache.c \ src/responder/common/responder_cmd.c \ src/responder/common/responder_common.c \ src/responder/common/responder_dp.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_get_domains.c \ src/responder/common/responder_utils.c \ src/responder/common/responder_cache_req.c \ src/monitor/monitor_iface_generated.c \ src/monitor/monitor_iface_generated.h \ src/providers/data_provider_iface_generated.c \ src/providers/data_provider_iface_generated.h \ src/providers/data_provider_req.c @BUILD_SUDO_TRUE@am_sssd_sudo_OBJECTS = \ @BUILD_SUDO_TRUE@ src/responder/sudo/sudosrv.$(OBJEXT) \ @BUILD_SUDO_TRUE@ src/responder/sudo/sudosrv_cmd.$(OBJEXT) \ @BUILD_SUDO_TRUE@ src/responder/sudo/sudosrv_get_sudorules.$(OBJEXT) \ @BUILD_SUDO_TRUE@ src/responder/sudo/sudosrv_query.$(OBJEXT) \ @BUILD_SUDO_TRUE@ src/responder/sudo/sudosrv_dp.$(OBJEXT) \ @BUILD_SUDO_TRUE@ $(am__objects_57) sssd_sudo_OBJECTS = $(am_sssd_sudo_OBJECTS) @BUILD_SUDO_TRUE@sssd_sudo_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @BUILD_SUDO_TRUE@ $(am__DEPENDENCIES_2) am_stress_tests_OBJECTS = src/tests/stress-tests.$(OBJEXT) stress_tests_OBJECTS = $(am_stress_tests_OBJECTS) stress_tests_DEPENDENCIES = $(am__DEPENDENCIES_5) \ libsss_test_common.la am__strtonum_tests_SOURCES_DIST = src/tests/strtonum-tests.c \ src/util/strtonum.c @HAVE_CHECK_TRUE@am_strtonum_tests_OBJECTS = src/tests/strtonum_tests-strtonum-tests.$(OBJEXT) \ @HAVE_CHECK_TRUE@ src/util/strtonum_tests-strtonum.$(OBJEXT) strtonum_tests_OBJECTS = $(am_strtonum_tests_OBJECTS) @HAVE_CHECK_TRUE@strtonum_tests_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) libsss_debug.la \ @HAVE_CHECK_TRUE@ libsss_test_common.la strtonum_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(strtonum_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ $@ am__sysdb_tests_SOURCES_DIST = src/tests/sysdb-tests.c @HAVE_CHECK_TRUE@am_sysdb_tests_OBJECTS = \ @HAVE_CHECK_TRUE@ src/tests/sysdb_tests-sysdb-tests.$(OBJEXT) sysdb_tests_OBJECTS = $(am_sysdb_tests_OBJECTS) @HAVE_CHECK_TRUE@sysdb_tests_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ @HAVE_CHECK_TRUE@ libsss_test_common.la sysdb_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(sysdb_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__sysdb_ssh_tests_SOURCES_DIST = src/tests/sysdb_ssh-tests.c @HAVE_CHECK_TRUE@am_sysdb_ssh_tests_OBJECTS = src/tests/sysdb_ssh_tests-sysdb_ssh-tests.$(OBJEXT) sysdb_ssh_tests_OBJECTS = $(am_sysdb_ssh_tests_OBJECTS) @HAVE_CHECK_TRUE@sysdb_ssh_tests_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ @HAVE_CHECK_TRUE@ libsss_test_common.la sysdb_ssh_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(sysdb_ssh_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__test_authtok_SOURCES_DIST = src/tests/cmocka/test_authtok.c \ src/util/authtok.c src/util/authtok-utils.c src/util/util.c @HAVE_CMOCKA_TRUE@am_test_authtok_OBJECTS = src/tests/cmocka/test_authtok-test_authtok.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_authtok-authtok.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_authtok-authtok-utils.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_authtok-util.$(OBJEXT) test_authtok_OBJECTS = $(am_test_authtok_OBJECTS) @HAVE_CMOCKA_TRUE@test_authtok_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libsss_debug.la test_authtok_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_authtok_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__test_find_uid_SOURCES_DIST = src/tests/cmocka/test_find_uid.c \ src/util/find_uid.c src/util/atomic_io.c src/util/strtonum.c @HAVE_CMOCKA_TRUE@am_test_find_uid_OBJECTS = src/tests/cmocka/test_find_uid-test_find_uid.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_find_uid-find_uid.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_find_uid-atomic_io.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_find_uid-strtonum.$(OBJEXT) test_find_uid_OBJECTS = $(am_test_find_uid_OBJECTS) @HAVE_CMOCKA_TRUE@test_find_uid_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) libsss_debug.la test_find_uid_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_find_uid_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__test_io_SOURCES_DIST = src/tests/cmocka/test_io.c src/util/io.c \ src/tests/common.c @HAVE_CMOCKA_TRUE@am_test_io_OBJECTS = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_io-test_io.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_io-io.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/test_io-common.$(OBJEXT) test_io_OBJECTS = $(am_test_io_OBJECTS) @HAVE_CMOCKA_TRUE@test_io_DEPENDENCIES = $(am__DEPENDENCIES_1) test_io_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_io_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__test_negcache_SOURCES_DIST = src/responder/common/negcache.c \ src/responder/common/responder_cmd.c \ src/responder/common/responder_common.c \ src/responder/common/responder_dp.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_get_domains.c \ src/responder/common/responder_utils.c \ src/responder/common/responder_cache_req.c \ src/monitor/monitor_iface_generated.c \ src/monitor/monitor_iface_generated.h \ src/providers/data_provider_iface_generated.c \ src/providers/data_provider_iface_generated.h \ src/providers/data_provider_req.c \ src/tests/cmocka/test_negcache.c am__objects_62 = \ src/responder/common/test_negcache-negcache.$(OBJEXT) \ src/responder/common/test_negcache-responder_cmd.$(OBJEXT) \ src/responder/common/test_negcache-responder_common.$(OBJEXT) \ src/responder/common/test_negcache-responder_dp.$(OBJEXT) \ src/responder/common/test_negcache-responder_packet.$(OBJEXT) \ src/responder/common/test_negcache-responder_get_domains.$(OBJEXT) \ src/responder/common/test_negcache-responder_utils.$(OBJEXT) \ src/responder/common/test_negcache-responder_cache_req.$(OBJEXT) \ src/monitor/test_negcache-monitor_iface_generated.$(OBJEXT) \ src/providers/test_negcache-data_provider_iface_generated.$(OBJEXT) \ src/providers/test_negcache-data_provider_req.$(OBJEXT) @HAVE_CMOCKA_TRUE@am_test_negcache_OBJECTS = $(am__objects_62) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_negcache-test_negcache.$(OBJEXT) test_negcache_OBJECTS = $(am_test_negcache_OBJECTS) @HAVE_CMOCKA_TRUE@test_negcache_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la libsss_idmap.la test_negcache_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_negcache_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__test_be_ptask_SOURCES_DIST = src/tests/cmocka/common_mock_be.c \ src/tests/cmocka/test_be_ptask.c src/providers/dp_ptask.c @HAVE_CMOCKA_TRUE@am_test_be_ptask_OBJECTS = src/tests/cmocka/test_be_ptask-common_mock_be.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_be_ptask-test_be_ptask.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/test_be_ptask-dp_ptask.$(OBJEXT) test_be_ptask_OBJECTS = $(am_test_be_ptask_OBJECTS) @HAVE_CMOCKA_TRUE@test_be_ptask_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la test_be_ptask_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_be_ptask_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__test_cert_utils_SOURCES_DIST = src/tests/cmocka/test_cert_utils.c @HAVE_CMOCKA_TRUE@am_test_cert_utils_OBJECTS = src/tests/cmocka/test_cert_utils-test_cert_utils.$(OBJEXT) test_cert_utils_OBJECTS = $(am_test_cert_utils_OBJECTS) @HAVE_CMOCKA_TRUE@test_cert_utils_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ libsss_debug.la libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libsss_cert.la libsss_crypt.la test_cert_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_cert_utils_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__test_child_common_SOURCES_DIST = \ src/tests/cmocka/test_child_common.c src/util/child_common.c \ src/util/signal.c src/util/atomic_io.c src/util/util_errors.c \ src/util/util.c @HAVE_CMOCKA_TRUE@am_test_child_common_OBJECTS = src/tests/cmocka/test_child_common-test_child_common.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_child_common-child_common.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_child_common-signal.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_child_common-atomic_io.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_child_common-util_errors.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_child_common-util.$(OBJEXT) test_child_common_OBJECTS = $(am_test_child_common_OBJECTS) @HAVE_CMOCKA_TRUE@test_child_common_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ libsss_debug.la libsss_test_common.la test_child_common_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_child_common_CFLAGS) $(CFLAGS) \ $(test_child_common_LDFLAGS) $(LDFLAGS) -o $@ am__test_copy_ccache_SOURCES_DIST = \ src/tests/cmocka/test_copy_ccache.c \ src/providers/krb5/krb5_ccache.c src/util/sss_krb5.c @HAVE_CMOCKA_TRUE@am_test_copy_ccache_OBJECTS = src/tests/cmocka/test_copy_ccache-test_copy_ccache.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/krb5/test_copy_ccache-krb5_ccache.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_copy_ccache-sss_krb5.$(OBJEXT) test_copy_ccache_OBJECTS = $(am_test_copy_ccache_OBJECTS) @HAVE_CMOCKA_TRUE@test_copy_ccache_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la test_copy_ccache_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_copy_ccache_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__test_copy_keytab_SOURCES_DIST = \ src/tests/cmocka/common_mock_krb5.c \ src/tests/cmocka/test_copy_keytab.c \ src/providers/krb5/krb5_keytab.c src/util/sss_krb5.c @HAVE_CMOCKA_TRUE@am_test_copy_keytab_OBJECTS = src/tests/cmocka/test_copy_keytab-common_mock_krb5.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_copy_keytab-test_copy_keytab.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/krb5/test_copy_keytab-krb5_keytab.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/util/test_copy_keytab-sss_krb5.$(OBJEXT) test_copy_keytab_OBJECTS = $(am_test_copy_keytab_OBJECTS) @HAVE_CMOCKA_TRUE@test_copy_keytab_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la test_copy_keytab_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_copy_keytab_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__test_data_provider_be_SOURCES_DIST = \ src/providers/data_provider_be.c \ src/tests/cmocka/test_data_provider_be.c \ src/tests/cmocka/common_mock_be.c @HAVE_CMOCKA_TRUE@am_test_data_provider_be_OBJECTS = src/providers/test_data_provider_be-data_provider_be.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_data_provider_be-test_data_provider_be.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_data_provider_be-common_mock_be.$(OBJEXT) test_data_provider_be_OBJECTS = $(am_test_data_provider_be_OBJECTS) @HAVE_CMOCKA_TRUE@test_data_provider_be_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la test_data_provider_be_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_data_provider_be_CFLAGS) $(CFLAGS) \ $(test_data_provider_be_LDFLAGS) $(LDFLAGS) -o $@ am__test_fo_srv_SOURCES_DIST = src/tests/cmocka/test_fo_srv.c \ src/providers/fail_over.c src/providers/fail_over_srv.c @HAVE_CMOCKA_TRUE@am_test_fo_srv_OBJECTS = src/tests/cmocka/test_fo_srv-test_fo_srv.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/test_fo_srv-fail_over.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/test_fo_srv-fail_over_srv.$(OBJEXT) test_fo_srv_OBJECTS = $(am_test_fo_srv_OBJECTS) @HAVE_CMOCKA_TRUE@test_fo_srv_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la test_fo_srv_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_fo_srv_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__test_ipa_dn_SOURCES_DIST = src/providers/ipa/ipa_dn.c \ src/tests/cmocka/test_ipa_dn.c @HAVE_CMOCKA_TRUE@am_test_ipa_dn_OBJECTS = src/providers/ipa/test_ipa_dn-ipa_dn.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ipa_dn-test_ipa_dn.$(OBJEXT) test_ipa_dn_OBJECTS = $(am_test_ipa_dn_OBJECTS) @HAVE_CMOCKA_TRUE@test_ipa_dn_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_5) $(am__DEPENDENCIES_2) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) libsss_test_common.la test_ipa_dn_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_ipa_dn_CFLAGS) \ $(CFLAGS) $(test_ipa_dn_LDFLAGS) $(LDFLAGS) -o $@ am__test_ipa_idmap_SOURCES_DIST = src/tests/cmocka/test_ipa_idmap.c \ src/providers/ipa/ipa_idmap.c @HAVE_CMOCKA_TRUE@am_test_ipa_idmap_OBJECTS = src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/test_ipa_idmap-ipa_idmap.$(OBJEXT) test_ipa_idmap_OBJECTS = $(am_test_ipa_idmap_OBJECTS) @HAVE_CMOCKA_TRUE@test_ipa_idmap_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) libsss_idmap.la \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la test_ipa_idmap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_ipa_idmap_CFLAGS) $(CFLAGS) $(test_ipa_idmap_LDFLAGS) \ $(LDFLAGS) -o $@ am__test_ipa_subdom_server_SOURCES_DIST = \ src/providers/krb5/krb5_utils.c \ src/providers/krb5/krb5_delayed_online_authentication.c \ src/providers/krb5/krb5_renew_tgt.c \ src/providers/krb5/krb5_wait_queue.c \ src/providers/krb5/krb5_common.c \ src/providers/krb5/krb5_opts.c src/providers/krb5/krb5_auth.c \ src/providers/krb5/krb5_access.c \ src/providers/krb5/krb5_child_handler.c \ src/providers/krb5/krb5_init_shared.c \ src/providers/krb5/krb5_ccache.c src/util/sss_krb5.c \ src/util/become_user.c src/tests/cmocka/common_mock_sdap.c \ src/tests/cmocka/common_mock_be.c \ src/tests/cmocka/common_mock_krb5.c \ src/tests/cmocka/test_ipa_subdomains_server.c \ src/providers/ipa/ipa_subdomains_server.c \ src/providers/ipa/ipa_subdomains_utils.c \ src/providers/ipa/ipa_opts.c am__objects_63 = src/providers/krb5/test_ipa_subdom_server-krb5_utils.$(OBJEXT) \ src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.$(OBJEXT) \ src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.$(OBJEXT) \ src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.$(OBJEXT) \ src/providers/krb5/test_ipa_subdom_server-krb5_common.$(OBJEXT) \ src/providers/krb5/test_ipa_subdom_server-krb5_opts.$(OBJEXT) \ src/providers/krb5/test_ipa_subdom_server-krb5_auth.$(OBJEXT) \ src/providers/krb5/test_ipa_subdom_server-krb5_access.$(OBJEXT) \ src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.$(OBJEXT) \ src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.$(OBJEXT) \ src/providers/krb5/test_ipa_subdom_server-krb5_ccache.$(OBJEXT) \ src/util/test_ipa_subdom_server-sss_krb5.$(OBJEXT) \ src/util/test_ipa_subdom_server-become_user.$(OBJEXT) @HAVE_CMOCKA_TRUE@am_test_ipa_subdom_server_OBJECTS = \ @HAVE_CMOCKA_TRUE@ $(am__objects_63) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ipa_subdom_server-common_mock_be.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/test_ipa_subdom_server-ipa_opts.$(OBJEXT) test_ipa_subdom_server_OBJECTS = $(am_test_ipa_subdom_server_OBJECTS) @HAVE_CMOCKA_TRUE@test_ipa_subdom_server_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_ad_tests.la libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la test_ipa_subdom_server_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) \ $(test_ipa_subdom_server_LDFLAGS) $(LDFLAGS) -o $@ am__test_ipa_subdom_util_SOURCES_DIST = \ src/tests/cmocka/test_ipa_subdomains_utils.c \ src/providers/ipa/ipa_subdomains_utils.c @HAVE_CMOCKA_TRUE@am_test_ipa_subdom_util_OBJECTS = src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.$(OBJEXT) test_ipa_subdom_util_OBJECTS = $(am_test_ipa_subdom_util_OBJECTS) @HAVE_CMOCKA_TRUE@test_ipa_subdom_util_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la test_ipa_subdom_util_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_ipa_subdom_util_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__test_krb5_wait_queue_SOURCES_DIST = \ src/tests/cmocka/common_mock_be.c \ src/tests/cmocka/test_krb5_wait_queue.c \ src/providers/krb5/krb5_wait_queue.c @HAVE_CMOCKA_TRUE@am_test_krb5_wait_queue_OBJECTS = src/tests/cmocka/test_krb5_wait_queue-common_mock_be.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.$(OBJEXT) test_krb5_wait_queue_OBJECTS = $(am_test_krb5_wait_queue_OBJECTS) @HAVE_CMOCKA_TRUE@test_krb5_wait_queue_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la test_krb5_wait_queue_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__test_ldap_auth_SOURCES_DIST = src/tests/cmocka/test_ldap_auth.c \ src/tests/cmocka/test_expire_common.c @HAVE_CMOCKA_TRUE@am_test_ldap_auth_OBJECTS = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ldap_auth.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_expire_common.$(OBJEXT) test_ldap_auth_OBJECTS = $(am_test_ldap_auth_OBJECTS) @HAVE_CMOCKA_TRUE@test_ldap_auth_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la am__test_ldap_id_cleanup_SOURCES_DIST = \ src/tests/cmocka/test_ldap_id_cleanup.c @HAVE_CMOCKA_TRUE@am_test_ldap_id_cleanup_OBJECTS = src/tests/cmocka/test_ldap_id_cleanup.$(OBJEXT) test_ldap_id_cleanup_OBJECTS = $(am_test_ldap_id_cleanup_OBJECTS) @HAVE_CMOCKA_TRUE@test_ldap_id_cleanup_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la am__test_resolv_fake_SOURCES_DIST = \ src/tests/cmocka/test_resolv_fake.c src/resolv/async_resolv.c @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@am_test_resolv_fake_OBJECTS = src/tests/cmocka/test_resolv_fake-test_resolv_fake.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ src/resolv/test_resolv_fake-async_resolv.$(OBJEXT) test_resolv_fake_OBJECTS = $(am_test_resolv_fake_OBJECTS) @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@test_resolv_fake_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ libsss_debug.la \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ libsss_test_common.la test_resolv_fake_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_resolv_fake_CFLAGS) $(CFLAGS) \ $(test_resolv_fake_LDFLAGS) $(LDFLAGS) -o $@ am__test_sbus_opath_SOURCES_DIST = src/tests/cmocka/test_sbus_opath.c @HAVE_CMOCKA_TRUE@am_test_sbus_opath_OBJECTS = src/tests/cmocka/test_sbus_opath-test_sbus_opath.$(OBJEXT) test_sbus_opath_OBJECTS = $(am_test_sbus_opath_OBJECTS) @HAVE_CMOCKA_TRUE@test_sbus_opath_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_5) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_debug.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la test_sbus_opath_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_sbus_opath_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__test_sdap_access_SOURCES_DIST = \ src/tests/cmocka/test_sdap_access.c \ src/tests/cmocka/test_expire_common.c @HAVE_CMOCKA_TRUE@am_test_sdap_access_OBJECTS = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_sdap_access.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_expire_common.$(OBJEXT) test_sdap_access_OBJECTS = $(am_test_sdap_access_OBJECTS) @HAVE_CMOCKA_TRUE@test_sdap_access_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ libsss_ldap_common.la libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la am__test_search_bases_SOURCES_DIST = \ src/tests/cmocka/test_search_bases.c @HAVE_CMOCKA_TRUE@am_test_search_bases_OBJECTS = src/tests/cmocka/test_search_bases.$(OBJEXT) test_search_bases_OBJECTS = $(am_test_search_bases_OBJECTS) @HAVE_CMOCKA_TRUE@test_search_bases_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la am__test_sss_idmap_SOURCES_DIST = src/tests/cmocka/test_sss_idmap.c @HAVE_CMOCKA_TRUE@am_test_sss_idmap_OBJECTS = src/tests/cmocka/test_sss_idmap-test_sss_idmap.$(OBJEXT) test_sss_idmap_OBJECTS = $(am_test_sss_idmap_OBJECTS) @HAVE_CMOCKA_TRUE@test_sss_idmap_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) libsss_idmap.la \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la test_sss_idmap_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_sss_idmap_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o \ $@ am__test_sysdb_subdomains_SOURCES_DIST = \ src/tests/cmocka/test_sysdb_subdomains.c @HAVE_CMOCKA_TRUE@am_test_sysdb_subdomains_OBJECTS = src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.$(OBJEXT) test_sysdb_subdomains_OBJECTS = $(am_test_sysdb_subdomains_OBJECTS) @HAVE_CMOCKA_TRUE@test_sysdb_subdomains_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la test_sysdb_subdomains_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_sysdb_subdomains_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am__test_sysdb_utils_SOURCES_DIST = \ src/tests/cmocka/test_sysdb_utils.c @HAVE_CMOCKA_TRUE@am_test_sysdb_utils_OBJECTS = src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.$(OBJEXT) test_sysdb_utils_OBJECTS = $(am_test_sysdb_utils_OBJECTS) @HAVE_CMOCKA_TRUE@test_sysdb_utils_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la test_sysdb_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_sysdb_utils_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__test_sysdb_views_SOURCES_DIST = \ src/tests/cmocka/test_sysdb_views.c \ src/providers/ipa/ipa_utils.c @HAVE_CMOCKA_TRUE@am_test_sysdb_views_OBJECTS = src/tests/cmocka/test_sysdb_views-test_sysdb_views.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/test_sysdb_views-ipa_utils.$(OBJEXT) test_sysdb_views_OBJECTS = $(am_test_sysdb_views_OBJECTS) @HAVE_CMOCKA_TRUE@test_sysdb_views_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_2) libsss_test_common.la test_sysdb_views_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_sysdb_views_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__test_tools_colondb_SOURCES_DIST = \ src/tests/cmocka/test_tools_colondb.c \ src/tools/common/sss_colondb.c @HAVE_CMOCKA_TRUE@am_test_tools_colondb_OBJECTS = src/tests/cmocka/test_tools_colondb-test_tools_colondb.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tools/common/test_tools_colondb-sss_colondb.$(OBJEXT) test_tools_colondb_OBJECTS = $(am_test_tools_colondb_OBJECTS) @HAVE_CMOCKA_TRUE@test_tools_colondb_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) libsss_test_common.la test_tools_colondb_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(test_tools_colondb_CFLAGS) $(CFLAGS) \ $(test_tools_colondb_LDFLAGS) $(LDFLAGS) -o $@ am__test_utils_SOURCES_DIST = src/tests/cmocka/test_utils.c \ src/tests/cmocka/test_sss_ssh.c \ src/tests/cmocka/test_string_utils.c @HAVE_CMOCKA_TRUE@am_test_utils_OBJECTS = src/tests/cmocka/test_utils-test_utils.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_utils-test_sss_ssh.$(OBJEXT) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_utils-test_string_utils.$(OBJEXT) test_utils_OBJECTS = $(am_test_utils_OBJECTS) @HAVE_CMOCKA_TRUE@test_utils_DEPENDENCIES = $(am__DEPENDENCIES_1) \ @HAVE_CMOCKA_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la test_utils_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(test_utils_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__util_tests_SOURCES_DIST = src/tests/util-tests.c @HAVE_CHECK_TRUE@am_util_tests_OBJECTS = \ @HAVE_CHECK_TRUE@ src/tests/util_tests-util-tests.$(OBJEXT) util_tests_OBJECTS = $(am_util_tests_OBJECTS) @HAVE_CHECK_TRUE@util_tests_DEPENDENCIES = $(am__DEPENDENCIES_5) \ @HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ @HAVE_CHECK_TRUE@ libsss_test_common.la util_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(util_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am__dist_sss_obfuscate_python_SCRIPTS_DIST = src/tools/sss_obfuscate SCRIPTS = $(dist_noinst_SCRIPTS) $(dist_sss_obfuscate_python_SCRIPTS) \ $(init_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/build/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(_py2hbac_la_SOURCES) $(_py2sss_la_SOURCES) \ $(_py2sss_murmur_la_SOURCES) $(_py2sss_nss_idmap_la_SOURCES) \ $(_py3hbac_la_SOURCES) $(_py3sss_la_SOURCES) \ $(_py3sss_murmur_la_SOURCES) $(_py3sss_nss_idmap_la_SOURCES) \ $(cifs_idmap_sss_la_SOURCES) \ $(libdlopen_test_providers_la_SOURCES) \ $(libipa_hbac_la_SOURCES) $(libnss_sss_la_SOURCES) \ $(libsss_ad_la_SOURCES) $(libsss_ad_tests_la_SOURCES) \ $(libsss_autofs_la_SOURCES) $(libsss_cert_la_SOURCES) \ $(libsss_child_la_SOURCES) $(libsss_config_la_SOURCES) \ $(libsss_crypt_la_SOURCES) $(libsss_debug_la_SOURCES) \ $(libsss_idmap_la_SOURCES) $(libsss_ipa_la_SOURCES) \ $(libsss_krb5_la_SOURCES) $(libsss_krb5_common_la_SOURCES) \ $(libsss_ldap_la_SOURCES) $(libsss_ldap_common_la_SOURCES) \ $(libsss_nss_idmap_la_SOURCES) \ $(libsss_nss_idmap_tests_la_SOURCES) \ $(libsss_proxy_la_SOURCES) $(libsss_semanage_la_SOURCES) \ $(libsss_simple_la_SOURCES) $(libsss_simpleifp_la_SOURCES) \ $(libsss_sudo_la_SOURCES) $(libsss_test_common_la_SOURCES) \ $(libsss_util_la_SOURCES) $(libwbclient_la_SOURCES) \ $(memberof_la_SOURCES) $(pam_sss_la_SOURCES) $(sss_la_SOURCES) \ $(sssd_krb5_localauth_plugin_la_SOURCES) \ $(sssd_krb5_locator_plugin_la_SOURCES) \ $(sssd_pac_plugin_la_SOURCES) \ $(ad_access_filter_tests_SOURCES) $(ad_common_tests_SOURCES) \ $(ad_gpo_tests_SOURCES) $(ad_ldap_opt_tests_SOURCES) \ $(auth_tests_SOURCES) $(autofs_test_client_SOURCES) \ $(check_and_open_tests_SOURCES) $(crypto_tests_SOURCES) \ $(debug_tests_SOURCES) $(dlopen_tests_SOURCES) \ $(dp_opt_tests_SOURCES) $(dummy_child_SOURCES) \ $(dyndns_tests_SOURCES) $(fail_over_tests_SOURCES) \ $(files_tests_SOURCES) $(find_uid_tests_SOURCES) \ $(fqnames_tests_SOURCES) $(gpo_child_SOURCES) \ $(ifp_tests_SOURCES) $(ipa_hbac_tests_SOURCES) \ $(ipa_ldap_opt_tests_SOURCES) $(krb5_child_test_SOURCES) \ $(krb5_utils_tests_SOURCES) $(krb5_child_SOURCES) \ $(ldap_child_SOURCES) $(nestedgroups_tests_SOURCES) \ $(nss_srv_tests_SOURCES) $(p11_child_SOURCES) \ $(pam_srv_tests_SOURCES) $(pam_test_client_SOURCES) \ $(proxy_child_SOURCES) $(refcount_tests_SOURCES) \ $(resolv_tests_SOURCES) $(responder_get_domains_tests_SOURCES) \ $(responder_cache_req_tests_SOURCES) \ $(responder_socket_access_tests_SOURCES) \ $(safe_format_tests_SOURCES) $(sbus_internal_tests_SOURCES) \ $(sbus_codegen_tests_SOURCES) $(sbus_tests_SOURCES) \ $(sdap_tests_SOURCES) $(selinux_child_SOURCES) \ $(simple_access_tests_SOURCES) $(sss_cache_SOURCES) \ $(sss_config_tests_SOURCES) $(sss_debuglevel_SOURCES) \ $(sss_groupadd_SOURCES) $(sss_groupdel_SOURCES) \ $(sss_groupmod_SOURCES) $(sss_groupshow_SOURCES) \ $(sss_idmap_tests_SOURCES) $(sss_nss_idmap_tests_SOURCES) \ $(sss_override_SOURCES) $(sss_seed_SOURCES) \ $(sss_sifp_tests_SOURCES) $(sss_signal_SOURCES) \ $(sss_ssh_authorizedkeys_SOURCES) \ $(sss_ssh_knownhostsproxy_SOURCES) $(sss_sudo_cli_SOURCES) \ $(sss_useradd_SOURCES) $(sss_userdel_SOURCES) \ $(sss_usermod_SOURCES) $(sssd_SOURCES) $(sssd_autofs_SOURCES) \ $(sssd_be_SOURCES) $(sssd_ifp_SOURCES) $(sssd_nss_SOURCES) \ $(sssd_pac_SOURCES) $(sssd_pam_SOURCES) $(sssd_ssh_SOURCES) \ $(sssd_sudo_SOURCES) $(stress_tests_SOURCES) \ $(strtonum_tests_SOURCES) $(sysdb_tests_SOURCES) \ $(sysdb_ssh_tests_SOURCES) $(test_authtok_SOURCES) \ $(test_find_uid_SOURCES) $(test_io_SOURCES) \ $(test_negcache_SOURCES) $(test_be_ptask_SOURCES) \ $(test_cert_utils_SOURCES) $(test_child_common_SOURCES) \ $(test_copy_ccache_SOURCES) $(test_copy_keytab_SOURCES) \ $(test_data_provider_be_SOURCES) $(test_fo_srv_SOURCES) \ $(test_ipa_dn_SOURCES) $(test_ipa_idmap_SOURCES) \ $(test_ipa_subdom_server_SOURCES) \ $(test_ipa_subdom_util_SOURCES) \ $(test_krb5_wait_queue_SOURCES) $(test_ldap_auth_SOURCES) \ $(test_ldap_id_cleanup_SOURCES) $(test_resolv_fake_SOURCES) \ $(test_sbus_opath_SOURCES) $(test_sdap_access_SOURCES) \ $(test_search_bases_SOURCES) $(test_sss_idmap_SOURCES) \ $(test_sysdb_subdomains_SOURCES) $(test_sysdb_utils_SOURCES) \ $(test_sysdb_views_SOURCES) $(test_tools_colondb_SOURCES) \ $(test_utils_SOURCES) $(util_tests_SOURCES) DIST_SOURCES = $(_py2hbac_la_SOURCES) $(_py2sss_la_SOURCES) \ $(_py2sss_murmur_la_SOURCES) $(_py2sss_nss_idmap_la_SOURCES) \ $(_py3hbac_la_SOURCES) $(_py3sss_la_SOURCES) \ $(_py3sss_murmur_la_SOURCES) $(_py3sss_nss_idmap_la_SOURCES) \ $(am__cifs_idmap_sss_la_SOURCES_DIST) \ $(am__libdlopen_test_providers_la_SOURCES_DIST) \ $(libipa_hbac_la_SOURCES) $(libnss_sss_la_SOURCES) \ $(am__libsss_ad_la_SOURCES_DIST) \ $(am__libsss_ad_tests_la_SOURCES_DIST) \ $(am__libsss_autofs_la_SOURCES_DIST) \ $(am__libsss_cert_la_SOURCES_DIST) $(libsss_child_la_SOURCES) \ $(am__libsss_config_la_SOURCES_DIST) \ $(am__libsss_crypt_la_SOURCES_DIST) $(libsss_debug_la_SOURCES) \ $(libsss_idmap_la_SOURCES) $(am__libsss_ipa_la_SOURCES_DIST) \ $(libsss_krb5_la_SOURCES) $(libsss_krb5_common_la_SOURCES) \ $(libsss_ldap_la_SOURCES) \ $(am__libsss_ldap_common_la_SOURCES_DIST) \ $(libsss_nss_idmap_la_SOURCES) \ $(am__libsss_nss_idmap_tests_la_SOURCES_DIST) \ $(libsss_proxy_la_SOURCES) $(libsss_semanage_la_SOURCES) \ $(libsss_simple_la_SOURCES) \ $(am__libsss_simpleifp_la_SOURCES_DIST) \ $(am__libsss_sudo_la_SOURCES_DIST) \ $(am__libsss_test_common_la_SOURCES_DIST) \ $(am__libsss_util_la_SOURCES_DIST) \ $(am__libwbclient_la_SOURCES_DIST) $(memberof_la_SOURCES) \ $(pam_sss_la_SOURCES) $(am__sss_la_SOURCES_DIST) \ $(am__sssd_krb5_localauth_plugin_la_SOURCES_DIST) \ $(am__sssd_krb5_locator_plugin_la_SOURCES_DIST) \ $(sssd_pac_plugin_la_SOURCES) \ $(am__ad_access_filter_tests_SOURCES_DIST) \ $(am__ad_common_tests_SOURCES_DIST) \ $(am__ad_gpo_tests_SOURCES_DIST) \ $(am__ad_ldap_opt_tests_SOURCES_DIST) \ $(am__auth_tests_SOURCES_DIST) \ $(am__autofs_test_client_SOURCES_DIST) \ $(am__check_and_open_tests_SOURCES_DIST) \ $(am__crypto_tests_SOURCES_DIST) \ $(am__debug_tests_SOURCES_DIST) \ $(am__dlopen_tests_SOURCES_DIST) \ $(am__dp_opt_tests_SOURCES_DIST) \ $(am__dummy_child_SOURCES_DIST) \ $(am__dyndns_tests_SOURCES_DIST) \ $(am__fail_over_tests_SOURCES_DIST) \ $(am__files_tests_SOURCES_DIST) \ $(am__find_uid_tests_SOURCES_DIST) \ $(am__fqnames_tests_SOURCES_DIST) $(gpo_child_SOURCES) \ $(am__ifp_tests_SOURCES_DIST) \ $(am__ipa_hbac_tests_SOURCES_DIST) \ $(am__ipa_ldap_opt_tests_SOURCES_DIST) \ $(krb5_child_test_SOURCES) \ $(am__krb5_utils_tests_SOURCES_DIST) $(krb5_child_SOURCES) \ $(ldap_child_SOURCES) $(am__nestedgroups_tests_SOURCES_DIST) \ $(am__nss_srv_tests_SOURCES_DIST) $(p11_child_SOURCES) \ $(am__pam_srv_tests_SOURCES_DIST) $(pam_test_client_SOURCES) \ $(proxy_child_SOURCES) $(am__refcount_tests_SOURCES_DIST) \ $(am__resolv_tests_SOURCES_DIST) \ $(am__responder_get_domains_tests_SOURCES_DIST) \ $(am__responder_cache_req_tests_SOURCES_DIST) \ $(am__responder_socket_access_tests_SOURCES_DIST) \ $(am__safe_format_tests_SOURCES_DIST) \ $(am__sbus_internal_tests_SOURCES_DIST) \ $(am__sbus_codegen_tests_SOURCES_DIST) \ $(am__sbus_tests_SOURCES_DIST) $(am__sdap_tests_SOURCES_DIST) \ $(am__selinux_child_SOURCES_DIST) \ $(am__simple_access_tests_SOURCES_DIST) $(sss_cache_SOURCES) \ $(am__sss_config_tests_SOURCES_DIST) $(sss_debuglevel_SOURCES) \ $(sss_groupadd_SOURCES) $(sss_groupdel_SOURCES) \ $(sss_groupmod_SOURCES) $(sss_groupshow_SOURCES) \ $(am__sss_idmap_tests_SOURCES_DIST) \ $(am__sss_nss_idmap_tests_SOURCES_DIST) \ $(sss_override_SOURCES) $(sss_seed_SOURCES) \ $(am__sss_sifp_tests_SOURCES_DIST) $(sss_signal_SOURCES) \ $(am__sss_ssh_authorizedkeys_SOURCES_DIST) \ $(am__sss_ssh_knownhostsproxy_SOURCES_DIST) \ $(am__sss_sudo_cli_SOURCES_DIST) $(sss_useradd_SOURCES) \ $(sss_userdel_SOURCES) $(sss_usermod_SOURCES) $(sssd_SOURCES) \ $(am__sssd_autofs_SOURCES_DIST) $(sssd_be_SOURCES) \ $(am__sssd_ifp_SOURCES_DIST) $(sssd_nss_SOURCES) \ $(sssd_pac_SOURCES) $(sssd_pam_SOURCES) \ $(am__sssd_ssh_SOURCES_DIST) $(am__sssd_sudo_SOURCES_DIST) \ $(stress_tests_SOURCES) $(am__strtonum_tests_SOURCES_DIST) \ $(am__sysdb_tests_SOURCES_DIST) \ $(am__sysdb_ssh_tests_SOURCES_DIST) \ $(am__test_authtok_SOURCES_DIST) \ $(am__test_find_uid_SOURCES_DIST) $(am__test_io_SOURCES_DIST) \ $(am__test_negcache_SOURCES_DIST) \ $(am__test_be_ptask_SOURCES_DIST) \ $(am__test_cert_utils_SOURCES_DIST) \ $(am__test_child_common_SOURCES_DIST) \ $(am__test_copy_ccache_SOURCES_DIST) \ $(am__test_copy_keytab_SOURCES_DIST) \ $(am__test_data_provider_be_SOURCES_DIST) \ $(am__test_fo_srv_SOURCES_DIST) \ $(am__test_ipa_dn_SOURCES_DIST) \ $(am__test_ipa_idmap_SOURCES_DIST) \ $(am__test_ipa_subdom_server_SOURCES_DIST) \ $(am__test_ipa_subdom_util_SOURCES_DIST) \ $(am__test_krb5_wait_queue_SOURCES_DIST) \ $(am__test_ldap_auth_SOURCES_DIST) \ $(am__test_ldap_id_cleanup_SOURCES_DIST) \ $(am__test_resolv_fake_SOURCES_DIST) \ $(am__test_sbus_opath_SOURCES_DIST) \ $(am__test_sdap_access_SOURCES_DIST) \ $(am__test_search_bases_SOURCES_DIST) \ $(am__test_sss_idmap_SOURCES_DIST) \ $(am__test_sysdb_subdomains_SOURCES_DIST) \ $(am__test_sysdb_utils_SOURCES_DIST) \ $(am__test_sysdb_views_SOURCES_DIST) \ $(am__test_tools_colondb_SOURCES_DIST) \ $(am__test_utils_SOURCES_DIST) $(am__util_tests_SOURCES_DIST) RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__dist_dbuspolicy_DATA_DIST = \ src/responder/ifp/org.freedesktop.sssd.infopipe.conf am__dist_dbusservice_DATA_DIST = \ src/responder/ifp/org.freedesktop.sssd.infopipe.service am__dist_noinst_DATA_DIST = src/config/testconfigs/sssd-valid.conf \ src/config/testconfigs/noparse.api.conf \ src/config/testconfigs/sssd-noversion.conf \ src/config/testconfigs/sssd-badversion.conf \ src/config/testconfigs/sssd-invalid.conf \ src/config/testconfigs/sssd-invalid-badbool.conf \ src/config/etc/sssd.api.d/crash_test_dummy \ contrib/ci/README.md contrib/ci/configure.sh \ contrib/ci/deps.sh contrib/ci/distro.sh contrib/ci/misc.sh \ contrib/ci/sssd.supp src/tests/cmocka/p11_nssdb/cert9.db \ src/tests/cmocka/p11_nssdb/key4.db \ src/providers/ipa/ipa_hbac.exports \ src/lib/idmap/sss_idmap.exports \ src/sss_client/idmap/sss_nss_idmap.exports \ src/sss_client/libwbclient/wbclient.exports \ src/lib/sifp/sss_simpleifp.exports \ src/examples/sssd-example.conf src/examples/sssdproxytest \ src/examples/sudo src/examples/logrotate \ src/providers/sssd_be.exports src/sss_client/COPYING \ src/sss_client/COPYING.LESSER src/m4 \ src/sss_client/idmap/sss_nss_idmap.unit_tests \ src/sss_client/sss_nss.exports src/sss_client/sss_pam.exports \ src/sss_client/sss_sudo.exports \ src/sss_client/autofs/sss_autofs.exports m4 \ contrib/sssd.spec.in BUILD.txt COPYING am__dist_polkit_rules_DATA_DIST = contrib/sssd-pcsc.rules DATA = $(dist_dbuspolicy_DATA) $(dist_dbusservice_DATA) \ $(dist_noinst_DATA) $(dist_polkit_rules_DATA) \ $(dist_sssdapiplugin_DATA) $(dist_sssddata_DATA) \ $(pkgconfig_DATA) $(systemdconf_DATA) $(systemdunit_DATA) am__dist_noinst_HEADERS_DIST = src/monitor/monitor.h \ src/util/crypto/sss_crypto.h src/util/cert.h \ src/util/dlinklist.h src/util/debug.h src/util/util.h \ src/util/io.h src/util/util_errors.h \ src/util/safe-format-string.h src/util/strtonum.h \ src/util/sss_cli_cmd.h src/util/sss_endian.h \ src/util/sss_nss.h src/util/sss_ldap.h src/util/sss_python.h \ src/util/sss_krb5.h src/util/sss_selinux.h src/util/sss_utf8.h \ src/util/sss_ssh.h src/util/sss_ini.h src/util/sss_format.h \ src/util/sss_config.h src/util/refcount.h src/util/find_uid.h \ src/util/user_info_msg.h src/util/murmurhash3.h \ src/util/mmap_cache.h src/util/atomic_io.h \ src/util/auth_utils.h src/util/authtok.h \ src/util/authtok-utils.h src/util/util_safealign.h \ src/util/util_sss_idmap.h src/monitor/monitor_interfaces.h \ src/responder/common/responder.h \ src/responder/common/responder_packet.h \ src/responder/common/responder_sbus.h \ src/responder/common/responder_cache_req.h \ src/responder/pam/pamsrv.h src/responder/pam/pam_helpers.h \ src/responder/nss/nsssrv.h src/responder/nss/nsssrv_private.h \ src/responder/nss/nsssrv_netgroup.h \ src/responder/nss/nsssrv_services.h \ src/responder/nss/nsssrv_mmap_cache.h \ src/responder/pac/pacsrv.h src/responder/common/negcache.h \ src/responder/sudo/sudosrv_private.h \ src/responder/autofs/autofs_private.h \ src/responder/ssh/sshsrv_private.h \ src/responder/ifp/ifp_private.h \ src/responder/ifp/ifp_domains.h \ src/responder/ifp/ifp_components.h \ src/responder/ifp/ifp_users.h src/responder/ifp/ifp_groups.h \ src/responder/ifp/ifp_cache.h src/sbus/sbus_client.h \ src/sbus/sssd_dbus.h src/sbus/sssd_dbus_meta.h \ src/sbus/sssd_dbus_private.h src/sbus/sssd_dbus_invokers.h \ src/sbus/sssd_dbus_errors.h src/db/sysdb.h src/db/sysdb_sudo.h \ src/db/sysdb_autofs.h src/db/sysdb_selinux.h \ src/db/sysdb_private.h src/db/sysdb_services.h \ src/db/sysdb_ssh.h src/confdb/confdb.h \ src/confdb/confdb_private.h src/confdb/confdb_setup.h \ src/providers/data_provider.h \ src/providers/data_provider_req.h src/providers/dp_backend.h \ src/providers/dp_dyndns.h src/providers/dp_ptask_private.h \ src/providers/dp_ptask.h src/providers/dp_refresh.h \ src/providers/fail_over.h src/providers/fail_over_srv.h \ src/util/child_common.h src/providers/simple/simple_access.h \ src/providers/krb5/krb5_auth.h \ src/providers/krb5/krb5_common.h \ src/providers/krb5/krb5_utils.h \ src/providers/krb5/krb5_init_shared.h \ src/providers/krb5/krb5_opts.h \ src/providers/krb5/krb5_ccache.h \ src/providers/ldap/ldap_common.h src/providers/ldap/sdap.h \ src/providers/ldap/sdap_access.h \ src/providers/ldap/sdap_async.h \ src/providers/ldap/sdap_async_private.h \ src/providers/ldap/sdap_sudo.h \ src/providers/ldap/sdap_sudo_shared.h \ src/providers/ldap/sdap_autofs.h \ src/providers/ldap/sdap_id_op.h src/providers/ldap/ldap_opts.h \ src/providers/ldap/ldap_auth.h src/providers/ldap/sdap_range.h \ src/providers/ldap/sdap_users.h \ src/providers/ldap/sdap_dyndns.h \ src/providers/ldap/sdap_async_enum.h \ src/providers/ldap/sdap_ops.h src/providers/ipa/ipa_common.h \ src/providers/ipa/ipa_config.h src/providers/ipa/ipa_access.h \ src/providers/ipa/ipa_selinux.h src/providers/ipa/ipa_hosts.h \ src/providers/ipa/ipa_selinux_maps.h \ src/providers/ipa/ipa_auth.h src/providers/ipa/ipa_dyndns.h \ src/providers/ipa/ipa_subdomains.h src/providers/ipa/ipa_id.h \ src/providers/ipa/ipa_hostid.h src/providers/ipa/ipa_opts.h \ src/providers/ipa/ipa_srv.h src/providers/ipa/ipa_dn.h \ src/providers/ipa/ipa_sudo.h src/providers/ad/ad_srv.h \ src/providers/proxy/proxy.h src/tools/tools_util.h \ src/tools/sss_sync_ops.h src/resolv/async_resolv.h \ src/tests/common.h src/tests/common_check.h \ src/tests/cmocka/common_mock.h \ src/tests/cmocka/common_mock_resp.h \ src/tests/cmocka/common_mock_sdap.h \ src/tests/cmocka/common_mock_sysdb_objects.h \ src/tests/cmocka/common_mock_krb5.h \ src/tests/cmocka/common_mock_be.h \ src/tests/cmocka/test_expire_common.h \ src/sss_client/pam_message.h \ src/sss_client/ssh/sss_ssh_client.h \ src/sss_client/sudo/sss_sudo.h \ src/sss_client/libwbclient/libwbclient.h \ src/sss_client/libwbclient/wbc_err_internal.h \ src/sss_client/libwbclient/wbclient_internal.h \ src/sss_client/libwbclient/wbc_sssd_internal.h \ src/sss_client/nfs/nfsidmap_internal.h \ src/lib/idmap/sss_idmap_private.h \ src/lib/sifp/sss_sifp_private.h src/tests/cmocka/test_utils.h \ src/tools/common/sss_tools.h src/tools/common/sss_colondb.h \ src/util/crypto/nss/nss_util.h am__include_HEADERS_DIST = src/providers/ipa/ipa_hbac.h \ src/lib/idmap/sss_idmap.h src/sss_client/idmap/sss_nss_idmap.h \ src/sss_client/libwbclient/wbclient_sssd.h \ src/lib/sifp/sss_sifp.h src/lib/sifp/sss_sifp_dbus.h HEADERS = $(dist_noinst_HEADERS) $(include_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope check recheck distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ $(LISP)config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) @BUILD_PYTHON2_BINDINGS_TRUE@am__EXEEXT_20 = \ @BUILD_PYTHON2_BINDINGS_TRUE@ src/config/SSSDConfigTest.py2.sh \ @BUILD_PYTHON2_BINDINGS_TRUE@ src/tests/pyhbac-test.py2.sh \ @BUILD_PYTHON2_BINDINGS_TRUE@ src/tests/pysss_murmur-test.py2.sh @BUILD_PYTHON3_BINDINGS_TRUE@am__EXEEXT_21 = \ @BUILD_PYTHON3_BINDINGS_TRUE@ src/config/SSSDConfigTest.py3.sh \ @BUILD_PYTHON3_BINDINGS_TRUE@ src/tests/pyhbac-test.py3.sh \ @BUILD_PYTHON3_BINDINGS_TRUE@ src/tests/pysss_murmur-test.py3.sh am__EXEEXT_22 = $(am__EXEEXT_20) $(am__EXEEXT_21) TEST_SUITE_LOG = test-suite.log LOG_DRIVER = $(SHELL) $(top_srcdir)/build/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.sh.log=.log) SH_LOG_DRIVER = $(SHELL) $(top_srcdir)/build/test-driver SH_LOG_COMPILE = $(SH_LOG_COMPILER) $(AM_SH_LOG_FLAGS) $(SH_LOG_FLAGS) DIST_SUBDIRS = po src/man . src/tests/cwrap src/tests/intg am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/build/ar-lib $(top_srcdir)/build/compile \ $(top_srcdir)/build/config.guess \ $(top_srcdir)/build/config.rpath \ $(top_srcdir)/build/config.sub $(top_srcdir)/build/depcomp \ $(top_srcdir)/build/install-sh $(top_srcdir)/build/ltmain.sh \ $(top_srcdir)/build/missing $(top_srcdir)/build/mkinstalldirs \ $(top_srcdir)/build/test-driver \ $(top_srcdir)/contrib/sssd-pcsc.rules.in \ $(top_srcdir)/contrib/sssd.spec.in \ $(top_srcdir)/src/config/SSSDConfig/__init__.py.in \ $(top_srcdir)/src/config/setup.py.in \ $(top_srcdir)/src/doxy.config.in \ $(top_srcdir)/src/examples/rwtab.in \ $(top_srcdir)/src/lib/idmap/sss_idmap.doxy.in \ $(top_srcdir)/src/lib/idmap/sss_idmap.pc.in \ $(top_srcdir)/src/lib/sifp/sss_simpleifp.doxy.in \ $(top_srcdir)/src/lib/sifp/sss_simpleifp.pc.in \ $(top_srcdir)/src/providers/ipa/ipa_hbac.doxy.in \ $(top_srcdir)/src/providers/ipa/ipa_hbac.pc.in \ $(top_srcdir)/src/responder/ifp/org.freedesktop.sssd.infopipe.service.in \ $(top_srcdir)/src/sss_client/idmap/sss_nss_idmap.doxy.in \ $(top_srcdir)/src/sss_client/idmap/sss_nss_idmap.pc.in \ $(top_srcdir)/src/sss_client/libwbclient/wbclient_sssd.pc.in \ $(top_srcdir)/src/sss_client/sudo/sss_sudo.doxy.in \ $(top_srcdir)/src/sysv/SUSE/sssd.in \ $(top_srcdir)/src/sysv/gentoo/sssd.in \ $(top_srcdir)/src/sysv/sssd.in ABOUT-NLS COPYING README \ build/ar-lib build/compile build/config.guess \ build/config.rpath build/config.sub build/depcomp \ build/install-sh build/ltmain.sh build/missing \ build/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUGEAS_CFLAGS = @AUGEAS_CFLAGS@ AUGEAS_LIBS = @AUGEAS_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CARES_CFLAGS = @CARES_CFLAGS@ CARES_LIBS = @CARES_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CMOCKA_CFLAGS = @CMOCKA_CFLAGS@ CMOCKA_LIBS = @CMOCKA_LIBS@ COLLECTION_CFLAGS = @COLLECTION_CFLAGS@ COLLECTION_LIBS = @COLLECTION_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPTO_CFLAGS = @CRYPTO_CFLAGS@ CRYPTO_LIBS = @CRYPTO_LIBS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHASH_CFLAGS = @DHASH_CFLAGS@ DHASH_LIBS = @DHASH_LIBS@ DLLTOOL = @DLLTOOL@ DOCBOOK_XSLT = @DOCBOOK_XSLT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB2_CFLAGS = @GLIB2_CFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMSGFMT = @GMSGFMT@ GPO_DEFAULT = @GPO_DEFAULT@ GREP = @GREP@ HAVE_FAKEROOT = @HAVE_FAKEROOT@ HAVE_LDAPMODIFY = @HAVE_LDAPMODIFY@ HAVE_MANPAGES = @HAVE_MANPAGES@ HAVE_NSS_WRAPPER = @HAVE_NSS_WRAPPER@ HAVE_PYTHON2 = @HAVE_PYTHON2@ HAVE_PYTHON2_BINDINGS = @HAVE_PYTHON2_BINDINGS@ HAVE_PYTHON3 = @HAVE_PYTHON3@ HAVE_PYTHON3_BINDINGS = @HAVE_PYTHON3_BINDINGS@ HAVE_SELINUX = @HAVE_SELINUX@ HAVE_SEMANAGE = @HAVE_SEMANAGE@ HAVE_SYSTEMD = @HAVE_SYSTEMD@ HAVE_UID_WRAPPER = @HAVE_UID_WRAPPER@ INI_CONFIG_CFLAGS = @INI_CONFIG_CFLAGS@ INI_CONFIG_LIBS = @INI_CONFIG_LIBS@ INI_CONFIG_V0_CFLAGS = @INI_CONFIG_V0_CFLAGS@ INI_CONFIG_V0_LIBS = @INI_CONFIG_V0_LIBS@ INI_CONFIG_V1_1_CFLAGS = @INI_CONFIG_V1_1_CFLAGS@ INI_CONFIG_V1_1_LIBS = @INI_CONFIG_V1_1_LIBS@ INI_CONFIG_V1_CFLAGS = @INI_CONFIG_V1_CFLAGS@ INI_CONFIG_V1_LIBS = @INI_CONFIG_V1_LIBS@ INOTIFY_LIBS = @INOTIFY_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ JOURNALD_CFLAGS = @JOURNALD_CFLAGS@ JOURNALD_LIBS = @JOURNALD_LIBS@ KEYUTILS_LIBS = @KEYUTILS_LIBS@ KRB5_CFLAGS = @KRB5_CFLAGS@ KRB5_CONFIG = @KRB5_CONFIG@ KRB5_LIBS = @KRB5_LIBS@ LD = @LD@ LDB_CFLAGS = @LDB_CFLAGS@ LDB_LIBS = @LDB_LIBS@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ LIBADD_DLOPEN = @LIBADD_DLOPEN@ LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ LIBNL1_LIBS = @LIBNL1_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ NDR_KRB5PAC_CFLAGS = @NDR_KRB5PAC_CFLAGS@ NDR_KRB5PAC_LIBS = @NDR_KRB5PAC_LIBS@ NDR_NBT_CFLAGS = @NDR_NBT_CFLAGS@ NDR_NBT_LIBS = @NDR_NBT_LIBS@ NFSIDMAP_CFLAGS = @NFSIDMAP_CFLAGS@ NFSIDMAP_LIBS = @NFSIDMAP_LIBS@ NFSIDMAP_OBJ = @NFSIDMAP_OBJ@ NM = @NM@ NMEDIT = @NMEDIT@ NSCD = @NSCD@ NSCD_PATH = @NSCD_PATH@ NSS_CFLAGS = @NSS_CFLAGS@ NSS_LIBS = @NSS_LIBS@ NSUPDATE = @NSUPDATE@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENLDAP_CFLAGS = @OPENLDAP_CFLAGS@ OPENLDAP_LIBS = @OPENLDAP_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_LIBS = @PAM_LIBS@ PAM_MISC_LIBS = @PAM_MISC_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PO4A = @PO4A@ POPT_CFLAGS = @POPT_CFLAGS@ POPT_LIBS = @POPT_LIBS@ POSUB = @POSUB@ PRERELEASE_VERSION = @PRERELEASE_VERSION@ PYTEST = @PYTEST@ PYTHON = @PYTHON@ PYTHON2 = @PYTHON2@ PYTHON2_CFLAGS = @PYTHON2_CFLAGS@ PYTHON2_EXEC_PREFIX = @PYTHON2_EXEC_PREFIX@ PYTHON2_INCLUDES = @PYTHON2_INCLUDES@ PYTHON2_LIBS = @PYTHON2_LIBS@ PYTHON2_PREFIX = @PYTHON2_PREFIX@ PYTHON2_VERSION = @PYTHON2_VERSION@ PYTHON3 = @PYTHON3@ PYTHON3_CFLAGS = @PYTHON3_CFLAGS@ PYTHON3_EXEC_PREFIX = @PYTHON3_EXEC_PREFIX@ PYTHON3_INCLUDES = @PYTHON3_INCLUDES@ PYTHON3_LIBS = @PYTHON3_LIBS@ PYTHON3_PREFIX = @PYTHON3_PREFIX@ PYTHON3_VERSION = @PYTHON3_VERSION@ PYTHON_CONFIG = @PYTHON_CONFIG@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RESOLV_CFLAGS = @RESOLV_CFLAGS@ RESOLV_LIBS = @RESOLV_LIBS@ SASL_CFLAGS = @SASL_CFLAGS@ SASL_LIBS = @SASL_LIBS@ SED = @SED@ SELINUX_LIBS = @SELINUX_LIBS@ SEMANAGE_LIBS = @SEMANAGE_LIBS@ SET_MAKE = @SET_MAKE@ SGML_CATALOG_FILES = @SGML_CATALOG_FILES@ SHELL = @SHELL@ SLAPD = @SLAPD@ SMBCLIENT_CFLAGS = @SMBCLIENT_CFLAGS@ SMBCLIENT_LIBS = @SMBCLIENT_LIBS@ SSSD_USER = @SSSD_USER@ STRIP = @STRIP@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ TALLOC_CFLAGS = @TALLOC_CFLAGS@ TALLOC_LIBS = @TALLOC_LIBS@ TDB_CFLAGS = @TDB_CFLAGS@ TDB_LIBS = @TDB_LIBS@ TEST_DIR = @TEST_DIR@ TEVENT_CFLAGS = @TEVENT_CFLAGS@ TEVENT_LIBS = @TEVENT_LIBS@ UNICODE_LIBS = @UNICODE_LIBS@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ XMLLINT = @XMLLINT@ XSLTPROC = @XSLTPROC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appmodpath = @appmodpath@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cifspluginpath = @cifspluginpath@ config_def_ccache_dir = @config_def_ccache_dir@ config_def_ccname_template = @config_def_ccname_template@ datadir = @datadir@ datarootdir = @datarootdir@ dbpath = @dbpath@ docdir = @docdir@ dvidir = @dvidir@ environment_file = @environment_file@ exec_prefix = @exec_prefix@ gpocachepath = @gpocachepath@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ krb5authdatapluginpath = @krb5authdatapluginpath@ krb5pluginpath = @krb5pluginpath@ krb5rcachedir = @krb5rcachedir@ ldblibdir = @ldblibdir@ libdir = @libdir@ libexecdir = @libexecdir@ libwbclient_version = @libwbclient_version@ libwbclient_version_info = @libwbclient_version_info@ localedir = @localedir@ localstatedir = @localstatedir@ logpath = @logpath@ mandir = @mandir@ mcpath = @mcpath@ mkdir_p = @mkdir_p@ nfsidmaplibdir = @nfsidmaplibdir@ nfslibpath = @nfslibpath@ nsslibdir = @nsslibdir@ oldincludedir = @oldincludedir@ pammoddir = @pammoddir@ pdfdir = @pdfdir@ pidpath = @pidpath@ pipepath = @pipepath@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ pluginpath = @pluginpath@ polkitdir = @polkitdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pubconfpath = @pubconfpath@ py2execdir = @py2execdir@ py3execdir = @py3execdir@ pyexecdir = @pyexecdir@ python2dir = @python2dir@ python3dir = @python3dir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedbuilddir = @sharedbuilddir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sudolibpath = @sudolibpath@ sysconfdir = @sysconfdir@ systemdconfdir = @systemdconfdir@ systemdunitdir = @systemdunitdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ extra_distcheck_flags = $(am__append_1) $(am__append_2) DISTCHECK_CONFIGURE_FLAGS = --with-ldb-lib-dir="$$dc_install_base"/lib/ldb \ --disable-dbus-tests \ --enable-all-experimental-features \ $(extra_distcheck_flags) \ $(AUX_DISTCHECK_CONFIGURE_FLAGS) SUBDIRS = po $(am__append_3) . src/tests/cwrap src/tests/intg DISTSETUPOPTS = $(am__append_4) sssdlibexecdir = $(libexecdir)/sssd sssdlibdir = $(libdir)/sssd @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@krb5plugindir = @krb5pluginpath@ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@krb5localauth_plugindir = @appmodpath@ @BUILD_PAC_RESPONDER_TRUE@krb5authdata_plugindir = @krb5authdatapluginpath@ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@cifsplugindir = @cifspluginpath@ @BUILD_LIBWBCLIENT_TRUE@libwbclientdir = @appmodpath@ sssdconfdir = $(sysconfdir)/sssd sssddatadir = $(datadir)/sssd sssdapiplugindir = $(sssddatadir)/sssd.api.d dbuspolicydir = $(sysconfdir)/dbus-1/system.d dbusservicedir = $(datadir)/dbus-1/system-services sss_statedir = $(localstatedir)/lib/sss pamlibdir = @pammoddir@ autofslibdir = @appmodpath@ nfslibdir = @nfsidmaplibdir@ keytabdir = $(sss_statedir)/keytabs pkgconfigdir = $(libdir)/pkgconfig sudolibdir = @sudolibpath@ AM_CFLAGS = $(am__append_5) $(am__append_6) pkgconfig_DATA = src/providers/ipa/ipa_hbac.pc \ src/lib/idmap/sss_idmap.pc \ src/sss_client/idmap/sss_nss_idmap.pc $(am__append_35) \ $(am__append_39) ACLOCAL_AMFLAGS = -I m4 -I . @HAVE_NSS_TRUE@@HAVE_POLKIT_RULES_D_TRUE@@SSSD_USER_TRUE@polkit_rulesdir = $(polkitdir) @HAVE_NSS_TRUE@@HAVE_POLKIT_RULES_D_TRUE@@SSSD_USER_TRUE@dist_polkit_rules_DATA = contrib/sssd-pcsc.rules @HAVE_CHECK_TRUE@non_interactive_check_based_tests = dlopen-tests \ @HAVE_CHECK_TRUE@ sysdb-tests strtonum-tests resolv-tests \ @HAVE_CHECK_TRUE@ krb5-utils-tests check_and_open-tests \ @HAVE_CHECK_TRUE@ files-tests refcount-tests fail_over-tests \ @HAVE_CHECK_TRUE@ find_uid-tests auth-tests ipa_ldap_opt-tests \ @HAVE_CHECK_TRUE@ ad_ldap_opt-tests simple_access-tests \ @HAVE_CHECK_TRUE@ crypto-tests util-tests debug-tests \ @HAVE_CHECK_TRUE@ ipa_hbac-tests sss_idmap-tests \ @HAVE_CHECK_TRUE@ responder_socket_access-tests \ @HAVE_CHECK_TRUE@ safe-format-tests $(am__append_15) \ @HAVE_CHECK_TRUE@ $(am__append_16) $(am__append_17) @HAVE_CMOCKA_TRUE@non_interactive_cmocka_based_tests = nss-srv-tests \ @HAVE_CMOCKA_TRUE@ test-find-uid test-io test-negcache \ @HAVE_CMOCKA_TRUE@ test-authtok sss_nss_idmap-tests \ @HAVE_CMOCKA_TRUE@ dyndns-tests fqnames-tests \ @HAVE_CMOCKA_TRUE@ nestedgroups-tests test_sss_idmap \ @HAVE_CMOCKA_TRUE@ test_ipa_idmap test_utils ad_common_tests \ @HAVE_CMOCKA_TRUE@ dp_opt_tests responder-get-domains-tests \ @HAVE_CMOCKA_TRUE@ sbus-internal-tests sss_sifp-tests \ @HAVE_CMOCKA_TRUE@ test_search_bases test_ldap_auth \ @HAVE_CMOCKA_TRUE@ test_sdap_access sdap-tests test_sysdb_views \ @HAVE_CMOCKA_TRUE@ test_sysdb_subdomains test_sysdb_utils \ @HAVE_CMOCKA_TRUE@ test_be_ptask test_copy_ccache \ @HAVE_CMOCKA_TRUE@ test_copy_keytab test_child_common \ @HAVE_CMOCKA_TRUE@ responder_cache_req-tests test_sbus_opath \ @HAVE_CMOCKA_TRUE@ test_fo_srv pam-srv-tests \ @HAVE_CMOCKA_TRUE@ test_ipa_subdom_util test_ipa_subdom_server \ @HAVE_CMOCKA_TRUE@ test_tools_colondb test_krb5_wait_queue \ @HAVE_CMOCKA_TRUE@ test_cert_utils test_ldap_id_cleanup \ @HAVE_CMOCKA_TRUE@ test_data_provider_be test_ipa_dn $(NULL) \ @HAVE_CMOCKA_TRUE@ $(am__append_18) $(am__append_19) \ @HAVE_CMOCKA_TRUE@ $(am__append_20) PYTHON_TESTS = $(am__append_22) $(am__append_23) TEST_EXTENSIONS = .sh sssdlib_LTLIBRARIES = libsss_ldap.la libsss_krb5.la libsss_proxy.la \ libsss_simple.la $(am__append_24) ldblib_LTLIBRARIES = \ memberof.la @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@krb5plugin_LTLIBRARIES = \ @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@ sssd_krb5_locator_plugin.la @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@krb5localauth_plugin_LTLIBRARIES = \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ sssd_krb5_localauth_plugin.la @BUILD_PAC_RESPONDER_TRUE@krb5authdata_plugin_LTLIBRARIES = \ @BUILD_PAC_RESPONDER_TRUE@ sssd_pac_plugin.la @BUILD_CIFS_IDMAP_PLUGIN_TRUE@cifsplugin_LTLIBRARIES = \ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@ cifs_idmap_sss.la noinst_LTLIBRARIES = ##################### # Utility libraries # ##################### #################### # Plugin Libraries # #################### # libsss_krb5_common must be installed before libsss_ldap_common # because libtool tries to relink libsss_ldap_common when installing # libsss_ldap_common and therefore make distcheck fails pkglib_LTLIBRARIES = libsss_debug.la libsss_child.la libsss_crypt.la \ libsss_cert.la libsss_util.la libsss_semanage.la \ $(am__append_34) libsss_krb5_common.la libsss_ldap_common.la @BUILD_PYTHON2_BINDINGS_TRUE@py2exec_LTLIBRARIES = \ @BUILD_PYTHON2_BINDINGS_TRUE@ _py2sss.la \ @BUILD_PYTHON2_BINDINGS_TRUE@ _py2hbac.la \ @BUILD_PYTHON2_BINDINGS_TRUE@ _py2sss_murmur.la \ @BUILD_PYTHON2_BINDINGS_TRUE@ _py2sss_nss_idmap.la \ @BUILD_PYTHON2_BINDINGS_TRUE@ $(NULL) @BUILD_PYTHON3_BINDINGS_TRUE@py3exec_LTLIBRARIES = \ @BUILD_PYTHON3_BINDINGS_TRUE@ _py3sss.la \ @BUILD_PYTHON3_BINDINGS_TRUE@ _py3hbac.la \ @BUILD_PYTHON3_BINDINGS_TRUE@ _py3sss_murmur.la \ @BUILD_PYTHON3_BINDINGS_TRUE@ _py3sss_nss_idmap.la \ @BUILD_PYTHON3_BINDINGS_TRUE@ $(NULL) dist_noinst_SCRIPTS = \ $(EXTRA_SCRIPTS) \ src/config/setup.py \ src/config/SSSDConfig/ipachangeconf.py \ src/config/SSSDConfig/__init__.py \ src/config/SSSDConfigTest.py \ src/config/SSSDConfigTest.py2.sh \ src/config/SSSDConfigTest.py3.sh \ src/config/SSSDConfig/sssd_upgrade_config.py \ contrib/rhel/update_debug_levels.py \ contrib/fedora/bashrc_sssd \ contrib/fedora/make_srpm.sh \ contrib/ci/clean \ contrib/ci/rpm-spec-builddeps \ contrib/ci/run \ contrib/ci/valgrind-condense \ src/tests/pyhbac-test.py \ src/tests/pyhbac-test.py2.sh \ src/tests/pyhbac-test.py3.sh \ src/tests/pysss_murmur-test.py \ src/tests/pysss_murmur-test.py2.sh \ src/tests/pysss_murmur-test.py3.sh \ src/tests/python-test.py \ src/tests/whitespace_test \ src/tests/krb5_proxy_check_test_data.conf \ $(NULL) dist_noinst_DATA = src/config/testconfigs/sssd-valid.conf \ src/config/testconfigs/noparse.api.conf \ src/config/testconfigs/sssd-noversion.conf \ src/config/testconfigs/sssd-badversion.conf \ src/config/testconfigs/sssd-invalid.conf \ src/config/testconfigs/sssd-invalid-badbool.conf \ src/config/etc/sssd.api.d/crash_test_dummy \ contrib/ci/README.md contrib/ci/configure.sh \ contrib/ci/deps.sh contrib/ci/distro.sh contrib/ci/misc.sh \ contrib/ci/sssd.supp src/tests/cmocka/p11_nssdb/cert9.db \ src/tests/cmocka/p11_nssdb/key4.db $(NULL) \ src/providers/ipa/ipa_hbac.exports \ src/lib/idmap/sss_idmap.exports \ src/sss_client/idmap/sss_nss_idmap.exports $(am__append_36) \ $(am__append_40) src/examples/sssd-example.conf \ src/examples/sssdproxytest src/examples/sudo \ src/examples/logrotate src/providers/sssd_be.exports \ src/sss_client/COPYING src/sss_client/COPYING.LESSER src/m4 \ $(am__append_46) src/sss_client/sss_nss.exports \ src/sss_client/sss_pam.exports $(am__append_51) \ $(am__append_52) m4 contrib/sssd.spec.in BUILD.txt COPYING ############################### # Global compilation settings # ############################### AM_CPPFLAGS = \ -Wall \ -Iinclude \ -I.. \ -I$(srcdir)/include \ -I$(srcdir)/src/sss_client \ -I$(srcdir)/src \ -Iinclude \ -I. \ $(POPT_CFLAGS) \ $(TALLOC_CFLAGS) \ $(TDB_CFLAGS) \ $(TEVENT_CFLAGS) \ $(LDB_CFLAGS) \ $(DBUS_CFLAGS) \ $(PCRE_CFLAGS) \ $(COLLECTION_CFLAGS) \ $(INI_CONFIG_CFLAGS) \ $(DHASH_CFLAGS) \ $(LIBNL_CFLAGS) \ $(OPENLDAP_CFLAGS) \ $(GLIB2_CFLAGS) \ $(JOURNALD_CFLAGS) \ -DLIBDIR=\"$(libdir)\" \ -DVARDIR=\"$(localstatedir)\" \ -DSSS_STATEDIR=\"$(sss_statedir)\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \ -DSHLIBEXT=\"$(SHLIBEXT)\" \ -DSSSD_LIBEXEC_PATH=\"$(sssdlibexecdir)\" \ -DSSSD_CONF_DIR=\"$(sssdconfdir)\" \ -DSSS_NSS_MCACHE_DIR=\"$(mcpath)\" \ -DSSS_NSS_SOCKET_NAME=\"$(pipepath)/nss\" \ -DSSS_PAM_SOCKET_NAME=\"$(pipepath)/pam\" \ -DSSS_PAC_SOCKET_NAME=\"$(pipepath)/pac\" \ -DSSS_PAM_PRIV_SOCKET_NAME=\"$(pipepath)/private/pam\" \ -DSSS_SUDO_SOCKET_NAME=\"$(pipepath)/sudo\" \ -DSSS_AUTOFS_SOCKET_NAME=\"$(pipepath)/autofs\" \ -DSSS_SSH_SOCKET_NAME=\"$(pipepath)/ssh\" \ -DLOCALEDIR=\"$(localedir)\" \ -DBASE_FILE_STEM=\"$(*F)\" \ $(NULL) EXTRA_DIST = $(SBUS_CODEGEN) $(CODEGEN_XML) \ src/sysv/systemd/sssd.service.in \ src/sysv/systemd/journal.conf.in SSSD_RESPONDER_OBJ = \ src/responder/common/negcache.c \ src/responder/common/responder_cmd.c \ src/responder/common/responder_common.c \ src/responder/common/responder_dp.c \ src/responder/common/responder_packet.c \ src/responder/common/responder_get_domains.c \ src/responder/common/responder_utils.c \ src/responder/common/responder_cache_req.c \ src/monitor/monitor_iface_generated.c \ src/monitor/monitor_iface_generated.h \ src/providers/data_provider_iface_generated.c \ src/providers/data_provider_iface_generated.h \ src/providers/data_provider_req.c SSSD_TOOLS_OBJ = \ src/tools/sss_sync_ops.c \ src/tools/tools_util.c \ src/tools/files.c \ src/tools/selinux.c \ src/tools/common/sss_tools.c \ src/util/nscd.c \ $(NULL) SSSD_LCL_TOOLS_OBJ = \ src/sss_client/common.c \ src/tools/tools_mc_util.c \ $(SSSD_TOOLS_OBJ) SSSD_RESOLV_OBJ = \ src/resolv/async_resolv.c \ src/resolv/async_resolv_utils.c SSSD_FAILOVER_OBJ = \ src/providers/fail_over.c \ src/providers/fail_over_srv.c \ $(SSSD_RESOLV_OBJ) SSSD_LIBS = \ $(TALLOC_LIBS) \ $(TEVENT_LIBS) \ $(POPT_LIBS) \ $(LDB_LIBS) \ $(DBUS_LIBS) \ $(PCRE_LIBS) \ $(INI_CONFIG_LIBS) \ $(COLLECTION_LIBS) \ $(DHASH_LIBS) \ $(OPENLDAP_LIBS) \ $(TDB_LIBS) PYTHON_BINDINGS_LIBS = $(TALLOC_LIBS) $(POPT_LIBS) $(LDB_LIBS) $(NULL) \ $(am__append_25) TOOLS_LIBS = $(LTLIBINTL) $(TALLOC_LIBS) $(TEVENT_LIBS) $(POPT_LIBS) \ $(LDB_LIBS) $(DBUS_LIBS) $(PCRE_LIBS) $(INI_CONFIG_LIBS) \ $(COLLECTION_LIBS) $(DHASH_LIBS) $(OPENLDAP_LIBS) $(TDB_LIBS) \ $(am__append_26) dist_noinst_HEADERS = src/monitor/monitor.h \ src/util/crypto/sss_crypto.h src/util/cert.h \ src/util/dlinklist.h src/util/debug.h src/util/util.h \ src/util/io.h src/util/util_errors.h \ src/util/safe-format-string.h src/util/strtonum.h \ src/util/sss_cli_cmd.h src/util/sss_endian.h \ src/util/sss_nss.h src/util/sss_ldap.h src/util/sss_python.h \ src/util/sss_krb5.h src/util/sss_selinux.h src/util/sss_utf8.h \ src/util/sss_ssh.h src/util/sss_ini.h src/util/sss_format.h \ src/util/sss_config.h src/util/refcount.h src/util/find_uid.h \ src/util/user_info_msg.h src/util/murmurhash3.h \ src/util/mmap_cache.h src/util/atomic_io.h \ src/util/auth_utils.h src/util/authtok.h \ src/util/authtok-utils.h src/util/util_safealign.h \ src/util/util_sss_idmap.h src/monitor/monitor.h \ src/monitor/monitor_interfaces.h \ src/responder/common/responder.h \ src/responder/common/responder_packet.h \ src/responder/common/responder_sbus.h \ src/responder/common/responder_cache_req.h \ src/responder/pam/pamsrv.h src/responder/pam/pam_helpers.h \ src/responder/nss/nsssrv.h src/responder/nss/nsssrv_private.h \ src/responder/nss/nsssrv_netgroup.h \ src/responder/nss/nsssrv_services.h \ src/responder/nss/nsssrv_mmap_cache.h \ src/responder/pac/pacsrv.h src/responder/common/negcache.h \ src/responder/sudo/sudosrv_private.h \ src/responder/autofs/autofs_private.h \ src/responder/ssh/sshsrv_private.h \ src/responder/ifp/ifp_private.h \ src/responder/ifp/ifp_domains.h \ src/responder/ifp/ifp_components.h \ src/responder/ifp/ifp_users.h src/responder/ifp/ifp_groups.h \ src/responder/ifp/ifp_cache.h src/sbus/sbus_client.h \ src/sbus/sssd_dbus.h src/sbus/sssd_dbus_meta.h \ src/sbus/sssd_dbus_private.h src/sbus/sssd_dbus_invokers.h \ src/sbus/sssd_dbus_errors.h src/db/sysdb.h src/db/sysdb_sudo.h \ src/db/sysdb_autofs.h src/db/sysdb_selinux.h \ src/db/sysdb_private.h src/db/sysdb_services.h \ src/db/sysdb_ssh.h src/confdb/confdb.h \ src/confdb/confdb_private.h src/confdb/confdb_setup.h \ src/providers/data_provider.h \ src/providers/data_provider_req.h src/providers/dp_backend.h \ src/providers/dp_dyndns.h src/providers/dp_ptask_private.h \ src/providers/dp_ptask.h src/providers/dp_refresh.h \ src/providers/fail_over.h src/providers/fail_over_srv.h \ src/util/child_common.h src/providers/simple/simple_access.h \ src/providers/krb5/krb5_auth.h \ src/providers/krb5/krb5_common.h \ src/providers/krb5/krb5_utils.h \ src/providers/krb5/krb5_init_shared.h \ src/providers/krb5/krb5_opts.h \ src/providers/krb5/krb5_ccache.h \ src/providers/ldap/ldap_common.h src/providers/ldap/sdap.h \ src/providers/ldap/sdap_access.h \ src/providers/ldap/sdap_async.h \ src/providers/ldap/sdap_async_private.h \ src/providers/ldap/sdap_sudo.h \ src/providers/ldap/sdap_sudo_shared.h \ src/providers/ldap/sdap_autofs.h \ src/providers/ldap/sdap_id_op.h src/providers/ldap/ldap_opts.h \ src/providers/ldap/ldap_auth.h src/providers/ldap/sdap_range.h \ src/providers/ldap/sdap_users.h \ src/providers/ldap/sdap_dyndns.h \ src/providers/ldap/sdap_async_enum.h \ src/providers/ldap/sdap_ops.h src/providers/ipa/ipa_common.h \ src/providers/ipa/ipa_config.h src/providers/ipa/ipa_access.h \ src/providers/ipa/ipa_selinux.h src/providers/ipa/ipa_hosts.h \ src/providers/ipa/ipa_selinux_maps.h \ src/providers/ipa/ipa_auth.h src/providers/ipa/ipa_dyndns.h \ src/providers/ipa/ipa_subdomains.h src/providers/ipa/ipa_id.h \ src/providers/ipa/ipa_hostid.h src/providers/ipa/ipa_opts.h \ src/providers/ipa/ipa_srv.h src/providers/ipa/ipa_dn.h \ src/providers/ipa/ipa_sudo.h src/providers/ad/ad_srv.h \ src/providers/proxy/proxy.h src/tools/tools_util.h \ src/tools/sss_sync_ops.h src/resolv/async_resolv.h \ src/tests/common.h src/tests/common_check.h \ src/tests/cmocka/common_mock.h \ src/tests/cmocka/common_mock_resp.h \ src/tests/cmocka/common_mock_sdap.h \ src/tests/cmocka/common_mock_sysdb_objects.h \ src/tests/cmocka/common_mock_krb5.h \ src/tests/cmocka/common_mock_be.h \ src/tests/cmocka/test_expire_common.h \ src/sss_client/pam_message.h \ src/sss_client/ssh/sss_ssh_client.h \ src/sss_client/sudo/sss_sudo.h \ src/sss_client/libwbclient/libwbclient.h \ src/sss_client/libwbclient/wbc_err_internal.h \ src/sss_client/libwbclient/wbclient_internal.h \ src/sss_client/libwbclient/wbc_sssd_internal.h \ src/sss_client/nfs/nfsidmap_internal.h \ src/lib/idmap/sss_idmap_private.h \ src/lib/sifp/sss_sifp_private.h src/tests/cmocka/test_utils.h \ src/tools/common/sss_tools.h src/tools/common/sss_colondb.h \ $(NULL) $(am__append_27) SSSD_DOCS = doc hbac_doc idmap_doc nss_idmap_doc $(am__append_28) \ $(am__append_29) CLIENT_LIBS = $(LTLIBINTL) $(am__append_30) @WITH_JOURNALD_TRUE@SYSLOG_LIBS = $(JOURNALD_LIBS) libsss_debug_la_SOURCES = \ src/util/debug.c \ src/util/sss_log.c \ src/util/sss_cli_cmd.c \ $(NULL) libsss_debug_la_LIBADD = \ $(SYSLOG_LIBS) libsss_debug_la_LDFLAGS = \ -avoid-version libsss_child_la_SOURCES = src/util/child_common.c libsss_child_la_LIBADD = \ $(TALLOC_LIBS) \ $(TEVENT_LIBS) \ $(DHASH_LIBS) \ libsss_debug.la \ $(NULL) libsss_child_la_LDFLAGS = -avoid-version @HAVE_NSS_FALSE@SSS_CRYPT_SOURCES = src/util/crypto/libcrypto/crypto_base64.c \ @HAVE_NSS_FALSE@ src/util/crypto/libcrypto/crypto_hmac_sha1.c \ @HAVE_NSS_FALSE@ src/util/crypto/libcrypto/crypto_sha512crypt.c \ @HAVE_NSS_FALSE@ src/util/crypto/libcrypto/crypto_obfuscate.c # NOTE: # Please try to avoid using SSS_CRYPT_{CFLAGS,LIBS} directly for compiling and # linking programs or libraries. This is purpose of wrapper library # libsss_crypt.so to hide internals. SSS_CRYPT_{CFLAGS,LIBS} might be used # in unit tests if you directly uses functions from underlining crypto libraries @HAVE_NSS_TRUE@SSS_CRYPT_SOURCES = src/util/crypto/nss/nss_base64.c \ @HAVE_NSS_TRUE@ src/util/crypto/nss/nss_hmac_sha1.c \ @HAVE_NSS_TRUE@ src/util/crypto/nss/nss_sha512crypt.c \ @HAVE_NSS_TRUE@ src/util/crypto/nss/nss_obfuscate.c \ @HAVE_NSS_TRUE@ src/util/crypto/nss/nss_util.c @HAVE_NSS_FALSE@SSS_CRYPT_CFLAGS = $(CRYPTO_CFLAGS) @HAVE_NSS_TRUE@SSS_CRYPT_CFLAGS = $(NSS_CFLAGS) @HAVE_NSS_FALSE@SSS_CRYPT_LIBS = $(CRYPTO_LIBS) @HAVE_NSS_TRUE@SSS_CRYPT_LIBS = $(NSS_LIBS) @HAVE_NSS_FALSE@SSS_CERT_SOURCES = \ @HAVE_NSS_FALSE@ src/util/cert/cert_common.c \ @HAVE_NSS_FALSE@ src/util/cert/libcrypto/cert.c \ @HAVE_NSS_FALSE@ $(NULL) @HAVE_NSS_TRUE@SSS_CERT_SOURCES = \ @HAVE_NSS_TRUE@ src/util/cert/cert_common.c \ @HAVE_NSS_TRUE@ src/util/cert/nss/cert.c \ @HAVE_NSS_TRUE@ $(NULL) @HAVE_NSS_FALSE@SSS_CERT_CFLAGS = \ @HAVE_NSS_FALSE@ $(CRYPTO_CFLAGS) \ @HAVE_NSS_FALSE@ $(NULL) @HAVE_NSS_TRUE@SSS_CERT_CFLAGS = \ @HAVE_NSS_TRUE@ $(NSS_CFLAGS) \ @HAVE_NSS_TRUE@ $(NULL) @HAVE_NSS_FALSE@SSS_CERT_LIBS = \ @HAVE_NSS_FALSE@ $(CRYPTO_LIBS) \ @HAVE_NSS_FALSE@ $(NULL) @HAVE_NSS_TRUE@SSS_CERT_LIBS = \ @HAVE_NSS_TRUE@ $(NSS_LIBS) \ @HAVE_NSS_TRUE@ $(NULL) libsss_crypt_la_SOURCES = \ $(SSS_CRYPT_SOURCES) libsss_crypt_la_CFLAGS = \ $(AM_CFLAGS) \ $(SSS_CRYPT_CFLAGS) \ $(DHASH_CFLAGS) libsss_crypt_la_LIBADD = \ $(SSS_CRYPT_LIBS) \ $(DHASH_LIBS) \ $(TALLOC_LIBS) \ libsss_debug.la \ $(NULL) libsss_crypt_la_LDFLAGS = \ -avoid-version libsss_cert_la_SOURCES = \ $(SSS_CERT_SOURCES) \ $(NULL) libsss_cert_la_CFLAGS = \ $(AM_CFLAGS) \ $(SSS_CERT_CFLAGS) \ $(NULL) libsss_cert_la_LIBADD = \ $(SSS_CERT_LIBS) \ $(TALLOC_LIBS) \ libsss_crypt.la \ libsss_debug.la \ $(NULL) libsss_cert_la_LDFLAGS = \ -avoid-version \ $(NULL) libsss_util_la_SOURCES = src/confdb/confdb.c src/db/sysdb.c \ src/db/sysdb_ops.c src/db/sysdb_search.c \ src/db/sysdb_selinux.c src/db/sysdb_upgrade.c \ src/db/sysdb_services.c src/db/sysdb_autofs.c \ src/db/sysdb_subdomains.c src/db/sysdb_views.c \ src/db/sysdb_ranges.c src/db/sysdb_idmap.c src/db/sysdb_gpo.c \ src/monitor/monitor_sbus.c src/providers/dp_auth_util.c \ src/providers/dp_pam_data_util.c src/providers/dp_sbus.c \ src/sbus/sbus_client.c src/sbus/sssd_dbus_common.c \ src/sbus/sssd_dbus_connection.c src/sbus/sssd_dbus_meta.c \ src/sbus/sssd_dbus_interface.c src/sbus/sssd_dbus_introspect.c \ src/sbus/sssd_dbus_invokers.c src/sbus/sssd_dbus_properties.c \ src/sbus/sssd_dbus_request.c src/sbus/sssd_dbus_server.c \ src/sbus/sssd_dbus_signals.c \ src/sbus/sssd_dbus_common_signals.c src/util/util.c \ src/util/memory.c src/util/safe-format-string.c \ src/util/server.c src/util/signal.c src/util/usertools.c \ src/util/backup_file.c src/util/strtonum.c \ src/util/check_and_open.c src/util/refcount.c \ src/util/sss_nss.c src/util/sss_utf8.c src/util/sss_tc_utf8.c \ src/util/murmurhash3.c src/util/atomic_io.c src/util/authtok.c \ src/util/authtok-utils.c src/util/sss_selinux.c \ src/util/domain_info_utils.c src/util/util_lock.c \ src/util/util_errors.c src/util/find_uid.c src/util/sss_ini.c \ src/util/io.c src/util/util_sss_idmap.c \ src/util/well_known_sids.c src/util/string_utils.c \ src/util/become_user.c $(NULL) $(am__append_31) \ $(am__append_32) libsss_util_la_CFLAGS = \ $(AM_CFLAGS) \ $(SYSTEMD_LOGIN_CFLAGS) \ $(NULL) libsss_util_la_LIBADD = \ $(SSSD_LIBS) \ $(SYSTEMD_LOGIN_LIBS) \ $(UNICODE_LIBS) \ libsss_debug.la \ libsss_child.la \ libsss_crypt.la \ libsss_cert.la \ $(NULL) libsss_util_la_LDFLAGS = -avoid-version libsss_semanage_la_CFLAGS = \ $(AM_CFLAGS) \ $(TALLOC_CFLAGS) \ $(NULL) libsss_semanage_la_SOURCES = \ src/util/sss_semanage.c \ $(NULL) libsss_semanage_la_LIBADD = $(TALLOC_LIBS) libsss_debug.la $(NULL) \ $(am__append_33) libsss_semanage_la_LDFLAGS = \ -avoid-version SSSD_INTERNAL_LTLIBS = \ libsss_util.la \ libsss_crypt.la \ libsss_debug.la \ libsss_child.la \ $(NULL) @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@libsss_config_la_SOURCES = \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ src/util/sss_config.c @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@libsss_config_la_CFLAGS = \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(AM_CFLAGS) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(AUGEAS_CFLAGS) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(TALLOC_CFLAGS) @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@libsss_config_la_LIBADD = \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(AUGEAS_LIBS) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(TALLOC_LIBS) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(SSSD_INTERNAL_LTLIBS) @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@libsss_config_la_LDFLAGS = \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ -avoid-version lib_LTLIBRARIES = libipa_hbac.la libsss_idmap.la libsss_nss_idmap.la \ $(NULL) $(am__append_38) libipa_hbac_la_DEPENDENCIES = src/providers/ipa/ipa_hbac.exports libipa_hbac_la_SOURCES = \ src/providers/ipa/hbac_evaluator.c \ src/util/sss_utf8.c libipa_hbac_la_LIBADD = \ $(UNICODE_LIBS) libipa_hbac_la_LDFLAGS = \ -Wl,--version-script,$(srcdir)/src/providers/ipa/ipa_hbac.exports \ -version-info 0:1:0 libsss_idmap_la_DEPENDENCIES = src/lib/idmap/sss_idmap.exports libsss_idmap_la_SOURCES = \ src/lib/idmap/sss_idmap.c \ src/lib/idmap/sss_idmap_conv.c \ src/util/murmurhash3.c libsss_idmap_la_LDFLAGS = \ -Wl,--version-script,$(srcdir)/src/lib/idmap/sss_idmap.exports \ -version-info 5:0:5 libsss_nss_idmap_la_DEPENDENCIES = src/sss_client/idmap/sss_nss_idmap.exports libsss_nss_idmap_la_SOURCES = \ src/sss_client/idmap/sss_nss_idmap.c \ src/sss_client/common.c \ src/util/strtonum.c libsss_nss_idmap_la_LIBADD = \ $(CLIENT_LIBS) libsss_nss_idmap_la_LDFLAGS = \ -Wl,--version-script,$(srcdir)/src/sss_client/idmap/sss_nss_idmap.exports \ -version-info 1:0:1 include_HEADERS = src/providers/ipa/ipa_hbac.h \ src/lib/idmap/sss_idmap.h src/sss_client/idmap/sss_nss_idmap.h \ $(NULL) $(am__append_37) $(am__append_41) @BUILD_LIBWBCLIENT_TRUE@libwbclient_LTLIBRARIES = libwbclient.la @BUILD_LIBWBCLIENT_TRUE@EXTRA_libwbclient_la_DEPENDENCIES = \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbclient.exports \ @BUILD_LIBWBCLIENT_TRUE@ $(NULL) @BUILD_LIBWBCLIENT_TRUE@libwbclient_la_SOURCES = \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_guid.c \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_idmap_common.c \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_idmap_sssd.c \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbclient_common.c \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbclient_sssd.c \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_pam_sssd.c \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_pwd_sssd.c \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_sid_common.c \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_sid_sssd.c \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_sssd_internal.h \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_util_common.c \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_util_sssd.c \ @BUILD_LIBWBCLIENT_TRUE@ src/sss_client/libwbclient/wbc_ctx_sssd.c \ @BUILD_LIBWBCLIENT_TRUE@ $(NULL) @BUILD_LIBWBCLIENT_TRUE@libwbclient_la_LIBADD = \ @BUILD_LIBWBCLIENT_TRUE@ libsss_nss_idmap.la \ @BUILD_LIBWBCLIENT_TRUE@ $(CLIENT_LIBS) \ @BUILD_LIBWBCLIENT_TRUE@ $(NULL) @BUILD_LIBWBCLIENT_TRUE@libwbclient_la_LDFLAGS = \ @BUILD_LIBWBCLIENT_TRUE@ -Wl,--version-script,$(srcdir)/src/sss_client/libwbclient/wbclient.exports \ @BUILD_LIBWBCLIENT_TRUE@ -version-info @libwbclient_version_info@ \ @BUILD_LIBWBCLIENT_TRUE@ $(NULL) @BUILD_IFP_TRUE@libsss_simpleifp_la_SOURCES = \ @BUILD_IFP_TRUE@ src/lib/sifp/sss_sifp.c \ @BUILD_IFP_TRUE@ src/lib/sifp/sss_sifp_dbus.c \ @BUILD_IFP_TRUE@ src/lib/sifp/sss_sifp_attrs.c \ @BUILD_IFP_TRUE@ src/lib/sifp/sss_sifp_common.c \ @BUILD_IFP_TRUE@ src/lib/sifp/sss_sifp_parser.c \ @BUILD_IFP_TRUE@ src/lib/sifp/sss_sifp_utils.c @BUILD_IFP_TRUE@libsss_simpleifp_la_CFLAGS = \ @BUILD_IFP_TRUE@ $(AM_CFLAGS) \ @BUILD_IFP_TRUE@ -I$(top_srcdir)/src/lib/sifp @BUILD_IFP_TRUE@libsss_simpleifp_la_LIBADD = \ @BUILD_IFP_TRUE@ $(DBUS_LIBS) \ @BUILD_IFP_TRUE@ $(DHASH_LIBS) @BUILD_IFP_TRUE@libsss_simpleifp_la_LDFLAGS = \ @BUILD_IFP_TRUE@ -Wl,--version-script,$(srcdir)/src/lib/sifp/sss_simpleifp.exports \ @BUILD_IFP_TRUE@ -version-info 0:1:0 #################### # Sbus Codegen # #################### # Yes, the goal here is that the generated files end up in $(srcdir) # not $(builddir). Always use $(srcdir) here. CODEGEN_XML = \ $(srcdir)/src/tests/sbus_codegen_tests.xml \ $(srcdir)/src/monitor/monitor_iface.xml \ $(srcdir)/src/providers/data_provider_iface.xml \ $(srcdir)/src/responder/ifp/ifp_iface.xml SBUS_CODEGEN = src/sbus/sbus_codegen SUFFIXES = .xml _generated.h _generated.c # Regenerate when codegen changes CODEGEN_CODE = \ $(CODEGEN_XML:.xml=_generated.c) \ $(CODEGEN_XML:.xml=_generated.h) BUILT_SOURCES = $(CODEGEN_CODE) #################### # Program Binaries # #################### sssd_SOURCES = \ src/monitor/monitor.c \ src/monitor/monitor_netlink.c \ src/confdb/confdb_setup.c \ src/util/nscd.c \ src/monitor/monitor_iface_generated.c \ src/monitor/monitor_iface_generated.h sssd_LDADD = \ $(SSSD_LIBS) \ $(INOTIFY_LIBS) \ $(LIBNL_LIBS) \ $(KEYUTILS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) sssd_nss_SOURCES = \ src/responder/nss/nsssrv.c \ src/responder/nss/nsssrv_cmd.c \ src/responder/nss/nsssrv_netgroup.c \ src/responder/nss/nsssrv_services.c \ src/responder/nss/nsssrv_mmap_cache.c \ $(SSSD_RESPONDER_OBJ) sssd_nss_LDADD = \ $(TDB_LIBS) \ $(SSSD_LIBS) \ libsss_idmap.la \ $(SSSD_INTERNAL_LTLIBS) sssd_pam_SOURCES = \ src/responder/pam/pam_LOCAL_domain.c \ src/responder/pam/pamsrv.c \ src/responder/pam/pamsrv_cmd.c \ src/responder/pam/pamsrv_p11.c \ src/responder/pam/pamsrv_dp.c \ src/responder/pam/pam_helpers.c \ $(SSSD_RESPONDER_OBJ) sssd_pam_LDADD = \ $(TDB_LIBS) \ $(SSSD_LIBS) \ $(SELINUX_LIBS) \ $(PAM_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ $(NULL) @BUILD_SUDO_TRUE@sssd_sudo_SOURCES = \ @BUILD_SUDO_TRUE@ src/responder/sudo/sudosrv.c \ @BUILD_SUDO_TRUE@ src/responder/sudo/sudosrv_cmd.c \ @BUILD_SUDO_TRUE@ src/responder/sudo/sudosrv_get_sudorules.c \ @BUILD_SUDO_TRUE@ src/responder/sudo/sudosrv_query.c \ @BUILD_SUDO_TRUE@ src/responder/sudo/sudosrv_dp.c \ @BUILD_SUDO_TRUE@ $(SSSD_RESPONDER_OBJ) @BUILD_SUDO_TRUE@sssd_sudo_LDADD = \ @BUILD_SUDO_TRUE@ $(SSSD_LIBS) \ @BUILD_SUDO_TRUE@ $(SSSD_INTERNAL_LTLIBS) @BUILD_AUTOFS_TRUE@sssd_autofs_SOURCES = \ @BUILD_AUTOFS_TRUE@ src/responder/autofs/autofssrv.c \ @BUILD_AUTOFS_TRUE@ src/responder/autofs/autofssrv_cmd.c \ @BUILD_AUTOFS_TRUE@ src/responder/autofs/autofssrv_dp.c \ @BUILD_AUTOFS_TRUE@ $(SSSD_RESPONDER_OBJ) @BUILD_AUTOFS_TRUE@sssd_autofs_LDADD = \ @BUILD_AUTOFS_TRUE@ $(SSSD_LIBS) \ @BUILD_AUTOFS_TRUE@ $(SSSD_INTERNAL_LTLIBS) @BUILD_SSH_TRUE@sssd_ssh_SOURCES = \ @BUILD_SSH_TRUE@ src/responder/ssh/sshsrv.c \ @BUILD_SSH_TRUE@ src/responder/ssh/sshsrv_dp.c \ @BUILD_SSH_TRUE@ src/responder/ssh/sshsrv_cmd.c \ @BUILD_SSH_TRUE@ $(SSSD_RESPONDER_OBJ) \ @BUILD_SSH_TRUE@ $(NULL) @BUILD_SSH_TRUE@sssd_ssh_LDADD = \ @BUILD_SSH_TRUE@ $(SSSD_LIBS) \ @BUILD_SSH_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @BUILD_SSH_TRUE@ libsss_cert.la \ @BUILD_SSH_TRUE@ $(NULL) sssd_pac_SOURCES = \ src/responder/pac/pacsrv.c \ src/responder/pac/pacsrv_cmd.c \ src/responder/pac/pacsrv_utils.c \ $(SSSD_RESPONDER_OBJ) sssd_pac_CFLAGS = \ $(AM_CFLAGS) \ $(NDR_KRB5PAC_CFLAGS) sssd_pac_LDADD = \ $(NDR_KRB5PAC_LIBS) \ $(TDB_LIBS) \ $(SSSD_LIBS) \ libsss_idmap.la \ $(SSSD_INTERNAL_LTLIBS) @BUILD_IFP_TRUE@sssd_ifp_SOURCES = \ @BUILD_IFP_TRUE@ src/responder/ifp/ifpsrv.c \ @BUILD_IFP_TRUE@ src/responder/ifp/ifpsrv_cmd.c \ @BUILD_IFP_TRUE@ src/responder/ifp/ifp_iface_generated.c \ @BUILD_IFP_TRUE@ src/responder/ifp/ifp_iface_generated.h \ @BUILD_IFP_TRUE@ src/responder/ifp/ifp_iface.c \ @BUILD_IFP_TRUE@ src/responder/ifp/ifp_iface_nodes.c \ @BUILD_IFP_TRUE@ src/responder/ifp/ifpsrv_util.c \ @BUILD_IFP_TRUE@ src/responder/ifp/ifp_domains.c \ @BUILD_IFP_TRUE@ src/responder/ifp/ifp_components.c \ @BUILD_IFP_TRUE@ src/responder/ifp/ifp_users.c \ @BUILD_IFP_TRUE@ src/responder/ifp/ifp_groups.c \ @BUILD_IFP_TRUE@ src/responder/ifp/ifp_cache.c \ @BUILD_IFP_TRUE@ $(SSSD_RESPONDER_OBJ) @BUILD_IFP_TRUE@sssd_ifp_CFLAGS = \ @BUILD_IFP_TRUE@ $(AM_CFLAGS) @BUILD_IFP_TRUE@sssd_ifp_LDADD = $(SSSD_LIBS) $(SSSD_INTERNAL_LTLIBS) \ @BUILD_IFP_TRUE@ libsss_cert.la $(NULL) $(am__append_42) @BUILD_IFP_TRUE@dist_dbuspolicy_DATA = \ @BUILD_IFP_TRUE@ src/responder/ifp/org.freedesktop.sssd.infopipe.conf @BUILD_IFP_TRUE@dist_dbusservice_DATA = \ @BUILD_IFP_TRUE@ src/responder/ifp/org.freedesktop.sssd.infopipe.service sssd_be_SOURCES = \ src/providers/data_provider_be.c \ src/providers/data_provider_req.c \ src/providers/data_provider_fo.c \ src/providers/data_provider_opts.c \ src/providers/data_provider_callbacks.c \ src/providers/dp_dyndns.c \ src/providers/dp_ptask.c \ src/providers/dp_refresh.c \ src/monitor/monitor_iface_generated.c \ src/monitor/monitor_iface_generated.h \ src/providers/data_provider_iface_generated.c \ src/providers/data_provider_iface_generated.h \ $(SSSD_FAILOVER_OBJ) sssd_be_LDADD = \ $(LIBADD_DL) \ $(SSSD_LIBS) \ $(CARES_LIBS) \ $(PAM_LIBS) \ $(SSSD_INTERNAL_LTLIBS) sssd_be_LDFLAGS = \ -Wl,--version-script,$(srcdir)/src/providers/sssd_be.exports \ -export-dynamic @BUILD_PYTHON_BINDINGS_TRUE@sss_obfuscate_pythondir = $(sbindir) @BUILD_PYTHON_BINDINGS_TRUE@dist_sss_obfuscate_python_SCRIPTS = \ @BUILD_PYTHON_BINDINGS_TRUE@ src/tools/sss_obfuscate ###################### # Command-line Tools # ###################### sss_useradd_SOURCES = \ src/tools/sss_useradd.c \ $(SSSD_TOOLS_OBJ) sss_useradd_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ libsss_semanage.la \ $(NULL) sss_userdel_SOURCES = \ src/tools/sss_userdel.c \ $(SSSD_LCL_TOOLS_OBJ) sss_userdel_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ $(CLIENT_LIBS) \ libsss_semanage.la \ $(NULL) sss_userdel_CFLAGS = \ $(AM_CFLAGS) sss_groupadd_SOURCES = \ src/tools/sss_groupadd.c \ $(SSSD_TOOLS_OBJ) sss_groupadd_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) sss_groupdel_SOURCES = \ src/tools/sss_groupdel.c \ $(SSSD_LCL_TOOLS_OBJ) sss_groupdel_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ $(CLIENT_LIBS) sss_groupdel_CFLAGS = $(AM_CFLAGS) sss_usermod_SOURCES = \ src/tools/sss_usermod.c \ $(SSSD_LCL_TOOLS_OBJ) sss_usermod_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ $(CLIENT_LIBS) \ libsss_semanage.la \ $(NULL) sss_usermod_CFLAGS = $(AM_CFLAGS) sss_groupmod_SOURCES = \ src/tools/sss_groupmod.c \ $(SSSD_LCL_TOOLS_OBJ) sss_groupmod_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ $(CLIENT_LIBS) sss_groupmod_CFLAGS = $(AM_CFLAGS) sss_groupshow_SOURCES = \ src/tools/sss_groupshow.c \ $(SSSD_TOOLS_OBJ) sss_groupshow_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) sss_cache_SOURCES = \ src/tools/sss_cache.c \ $(SSSD_LCL_TOOLS_OBJ) sss_cache_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ $(CLIENT_LIBS) sss_cache_CFLAGS = $(AM_CFLAGS) sss_debuglevel_SOURCES = \ src/tools/sss_debuglevel.c \ $(SSSD_TOOLS_OBJ) sss_debuglevel_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) sss_seed_SOURCES = \ src/tools/sss_seed.c \ $(SSSD_TOOLS_OBJ) sss_seed_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) sss_signal_SOURCES = \ src/tools/sss_signal.c \ $(SSSD_TOOLS_OBJ) \ $(NULL) sss_signal_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ $(NULL) sss_override_SOURCES = \ src/tools/sss_override.c \ src/tools/common/sss_colondb.c \ $(SSSD_TOOLS_OBJ) \ $(NULL) sss_override_LDADD = \ $(TOOLS_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ $(NULL) sss_override_CFLAGS = \ $(AM_CFLAGS) \ $(NULL) @BUILD_SUDO_TRUE@sss_sudo_cli_SOURCES = \ @BUILD_SUDO_TRUE@ src/sss_client/common.c \ @BUILD_SUDO_TRUE@ src/sss_client/sudo/sss_sudo.c \ @BUILD_SUDO_TRUE@ src/sss_client/sudo/sss_sudo_response.c \ @BUILD_SUDO_TRUE@ src/sss_client/sudo_testcli/sudo_testcli.c @BUILD_SUDO_TRUE@sss_sudo_cli_CFLAGS = $(AM_CFLAGS) @BUILD_SUDO_TRUE@sss_sudo_cli_LDADD = $(CLIENT_LIBS) @BUILD_SSH_TRUE@sss_ssh_authorizedkeys_SOURCES = \ @BUILD_SSH_TRUE@ src/sss_client/common.c \ @BUILD_SSH_TRUE@ src/sss_client/ssh/sss_ssh_client.c \ @BUILD_SSH_TRUE@ src/sss_client/ssh/sss_ssh_authorizedkeys.c @BUILD_SSH_TRUE@sss_ssh_authorizedkeys_CFLAGS = $(AM_CFLAGS) @BUILD_SSH_TRUE@sss_ssh_authorizedkeys_LDADD = \ @BUILD_SSH_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @BUILD_SSH_TRUE@ $(CLIENT_LIBS) $(TALLOC_LIBS) $(POPT_LIBS) @BUILD_SSH_TRUE@sss_ssh_knownhostsproxy_SOURCES = \ @BUILD_SSH_TRUE@ src/sss_client/common.c \ @BUILD_SSH_TRUE@ src/sss_client/ssh/sss_ssh_client.c \ @BUILD_SSH_TRUE@ src/sss_client/ssh/sss_ssh_knownhostsproxy.c @BUILD_SSH_TRUE@sss_ssh_knownhostsproxy_CFLAGS = $(AM_CFLAGS) @BUILD_SSH_TRUE@sss_ssh_knownhostsproxy_LDADD = \ @BUILD_SSH_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @BUILD_SSH_TRUE@ $(CLIENT_LIBS) $(TALLOC_LIBS) $(POPT_LIBS) ################# # Feature Tests # ################# TESTS_ENVIRONMENT = LDB_MODULES_PATH=$(abs_top_builddir)/ldb_mod_test_dir \ SSS_TEST_DIR=$(TEST_DIR) \ ABS_TOP_SRCDIR=$(abs_top_srcdir) \ $(AUX_TESTS_ENVIRONMENT) check_LTLIBRARIES = libsss_test_common.la $(am__append_44) \ $(am__append_45) libsss_test_common_la_SOURCES = src/tests/common_tev.c \ src/tests/common_dom.c src/tests/leak_check.c \ src/tests/common.c $(am__append_43) libsss_test_common_la_LIBADD = \ $(TALLOC_LIBS) \ $(TEVENT_LIBS) @HAVE_CHECK_TRUE@libdlopen_test_providers_la_SOURCES = \ @HAVE_CHECK_TRUE@ $(sssd_be_SOURCES) @HAVE_CHECK_TRUE@libdlopen_test_providers_la_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) \ @HAVE_CHECK_TRUE@ -DUNIT_TESTING @HAVE_CHECK_TRUE@libdlopen_test_providers_la_LIBADD = \ @HAVE_CHECK_TRUE@ $(PAM_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CARES_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) @HAVE_CHECK_TRUE@libdlopen_test_providers_la_LDFLAGS = \ @HAVE_CHECK_TRUE@ -shared \ @HAVE_CHECK_TRUE@ -avoid-version \ @HAVE_CHECK_TRUE@ -Wl,--version-script,$(srcdir)/src/providers/sssd_be.exports \ @HAVE_CHECK_TRUE@ -rpath $(abs_top_builddir) \ @HAVE_CHECK_TRUE@ -export-dynamic @HAVE_CHECK_TRUE@libsss_nss_idmap_tests_la_SOURCES = $(libsss_nss_idmap_la_SOURCES) @HAVE_CHECK_TRUE@libsss_nss_idmap_tests_la_LIBADD = $(libsss_nss_idmap_la_LIBADD) @HAVE_CHECK_TRUE@libsss_nss_idmap_tests_la_LDFLAGS = \ @HAVE_CHECK_TRUE@ $(libsss_nss_idmap_la_LDFLAGS) \ @HAVE_CHECK_TRUE@ -shared \ @HAVE_CHECK_TRUE@ -rpath $(libdir) \ @HAVE_CHECK_TRUE@ -Wl,--version-script,$(srcdir)/src/sss_client/idmap/sss_nss_idmap.unit_tests @HAVE_CHECK_TRUE@libsss_ad_tests_la_SOURCES = $(libsss_ad_la_SOURCES) @HAVE_CHECK_TRUE@libsss_ad_tests_la_CFLAGS = $(libsss_ad_la_CFLAGS) @HAVE_CHECK_TRUE@libsss_ad_tests_la_LIBADD = $(libsss_ad_la_LIBADD) @HAVE_CHECK_TRUE@libsss_ad_tests_la_LDFLAGS = \ @HAVE_CHECK_TRUE@ -shared \ @HAVE_CHECK_TRUE@ -rpath $(abs_top_builddir) \ @HAVE_CHECK_TRUE@ $(NULL) @HAVE_CHECK_TRUE@dlopen_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/dlopen-tests.c @HAVE_CHECK_TRUE@dlopen_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@dlopen_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(LIBADD_DL) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) @HAVE_CHECK_TRUE@EXTRA_sysdb_tests_DEPENDENCIES = \ @HAVE_CHECK_TRUE@ $(ldblib_LTLIBRARIES) @HAVE_CHECK_TRUE@sysdb_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/sysdb-tests.c @HAVE_CHECK_TRUE@sysdb_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@sysdb_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@EXTRA_sysdb_ssh_tests_DEPENDENCIES = \ @HAVE_CHECK_TRUE@ $(ldblib_LTLIBRARIES) @HAVE_CHECK_TRUE@sysdb_ssh_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/sysdb_ssh-tests.c @HAVE_CHECK_TRUE@sysdb_ssh_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS)\ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@sysdb_ssh_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@strtonum_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/strtonum-tests.c \ @HAVE_CHECK_TRUE@ src/util/strtonum.c @HAVE_CHECK_TRUE@strtonum_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@strtonum_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ libsss_debug.la \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@krb5_utils_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/krb5_utils-tests.c \ @HAVE_CHECK_TRUE@ src/providers/krb5/krb5_utils.c \ @HAVE_CHECK_TRUE@ src/providers/krb5/krb5_ccache.c \ @HAVE_CHECK_TRUE@ src/providers/krb5/krb5_common.c \ @HAVE_CHECK_TRUE@ src/providers/krb5/krb5_opts.c \ @HAVE_CHECK_TRUE@ src/util/sss_krb5.c \ @HAVE_CHECK_TRUE@ src/providers/data_provider_fo.c \ @HAVE_CHECK_TRUE@ src/providers/data_provider_opts.c \ @HAVE_CHECK_TRUE@ src/providers/data_provider_callbacks.c \ @HAVE_CHECK_TRUE@ src/util/become_user.c \ @HAVE_CHECK_TRUE@ $(SSSD_FAILOVER_OBJ) \ @HAVE_CHECK_TRUE@ $(NULL) @HAVE_CHECK_TRUE@krb5_utils_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(KRB5_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@krb5_utils_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS)\ @HAVE_CHECK_TRUE@ $(CARES_LIBS) \ @HAVE_CHECK_TRUE@ $(KRB5_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@check_and_open_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/check_and_open-tests.c \ @HAVE_CHECK_TRUE@ src/util/check_and_open.c @HAVE_CHECK_TRUE@check_and_open_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@check_and_open_tests_LDADD = \ @HAVE_CHECK_TRUE@ libsss_debug.la \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@FILES_TESTS_LIBS = $(CHECK_LIBS) $(POPT_LIBS) \ @HAVE_CHECK_TRUE@ $(TALLOC_LIBS) libsss_test_common.la \ @HAVE_CHECK_TRUE@ $(am__append_47) $(am__append_48) @HAVE_CHECK_TRUE@files_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/files-tests.c \ @HAVE_CHECK_TRUE@ src/util/check_and_open.c \ @HAVE_CHECK_TRUE@ src/util/atomic_io.c \ @HAVE_CHECK_TRUE@ src/tools/selinux.c \ @HAVE_CHECK_TRUE@ src/tools/files.c @HAVE_CHECK_TRUE@files_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@files_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(FILES_TESTS_LIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) @HAVE_CHECK_TRUE@SSSD_RESOLV_TESTS_OBJ = \ @HAVE_CHECK_TRUE@ $(SSSD_RESOLV_OBJ) @HAVE_CHECK_TRUE@resolv_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/resolv-tests.c \ @HAVE_CHECK_TRUE@ src/tests/common.c \ @HAVE_CHECK_TRUE@ $(SSSD_RESOLV_TESTS_OBJ) @HAVE_CHECK_TRUE@resolv_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) \ @HAVE_CHECK_TRUE@ -DBUILD_TXT @HAVE_CHECK_TRUE@resolv_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(CARES_LIBS) \ @HAVE_CHECK_TRUE@ libsss_debug.la \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@refcount_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/refcount-tests.c \ @HAVE_CHECK_TRUE@ $(NULL) @HAVE_CHECK_TRUE@refcount_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@refcount_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@fail_over_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/fail_over-tests.c \ @HAVE_CHECK_TRUE@ $(SSSD_FAILOVER_OBJ) \ @HAVE_CHECK_TRUE@ $(NULL) @HAVE_CHECK_TRUE@fail_over_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@fail_over_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(CARES_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@find_uid_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/find_uid-tests.c \ @HAVE_CHECK_TRUE@ src/util/find_uid.c \ @HAVE_CHECK_TRUE@ src/util/atomic_io.c \ @HAVE_CHECK_TRUE@ src/util/strtonum.c @HAVE_CHECK_TRUE@find_uid_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(TALLOC_CFLAGS) \ @HAVE_CHECK_TRUE@ $(DHASH_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) \ @HAVE_CHECK_TRUE@ $(SYSTEMD_LOGIN_CFLAGS) @HAVE_CHECK_TRUE@find_uid_tests_LDADD = \ @HAVE_CHECK_TRUE@ libsss_debug.la \ @HAVE_CHECK_TRUE@ $(TALLOC_LIBS) \ @HAVE_CHECK_TRUE@ $(DHASH_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(SYSTEMD_LOGIN_LIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@auth_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/auth-tests.c @HAVE_CHECK_TRUE@auth_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@auth_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@ipa_ldap_opt_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/providers/data_provider_opts.c \ @HAVE_CHECK_TRUE@ src/providers/ldap/sdap.c \ @HAVE_CHECK_TRUE@ src/providers/ldap/sdap_range.c \ @HAVE_CHECK_TRUE@ src/providers/ldap/sdap_domain.c \ @HAVE_CHECK_TRUE@ src/providers/ldap/ldap_opts.c \ @HAVE_CHECK_TRUE@ src/providers/ad/ad_opts.c \ @HAVE_CHECK_TRUE@ src/providers/ipa/ipa_opts.c \ @HAVE_CHECK_TRUE@ src/providers/krb5/krb5_opts.c \ @HAVE_CHECK_TRUE@ src/util/sss_ldap.c \ @HAVE_CHECK_TRUE@ src/tests/ipa_ldap_opt-tests.c @HAVE_CHECK_TRUE@ipa_ldap_opt_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@ipa_ldap_opt_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(TALLOC_LIBS) \ @HAVE_CHECK_TRUE@ $(LDB_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CHECK_TRUE@ $(OPENLDAP_LIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@ad_ldap_opt_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/providers/ldap/ldap_opts.c \ @HAVE_CHECK_TRUE@ src/providers/ad/ad_opts.c \ @HAVE_CHECK_TRUE@ src/providers/krb5/krb5_opts.c \ @HAVE_CHECK_TRUE@ src/tests/ad_ldap_opt-tests.c @HAVE_CHECK_TRUE@ad_ldap_opt_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@ad_ldap_opt_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(TALLOC_LIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@simple_access_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/simple_access-tests.c \ @HAVE_CHECK_TRUE@ src/providers/simple/simple_access.c \ @HAVE_CHECK_TRUE@ src/providers/simple/simple_access_check.c \ @HAVE_CHECK_TRUE@ $(NULL) @HAVE_CHECK_TRUE@simple_access_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(LIBADD_DL) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la \ @HAVE_CHECK_TRUE@ libdlopen_test_providers.la \ @HAVE_CHECK_TRUE@ $(NULL) @HAVE_CHECK_TRUE@util_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/util-tests.c \ @HAVE_CHECK_TRUE@ $(NULL) @HAVE_CHECK_TRUE@util_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) \ @HAVE_CHECK_TRUE@ $(NULL) @HAVE_CHECK_TRUE@util_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la \ @HAVE_CHECK_TRUE@ $(NULL) @HAVE_CHECK_TRUE@safe_format_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/safe-format-tests.c @HAVE_CHECK_TRUE@safe_format_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@safe_format_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@debug_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/debug-tests.c \ @HAVE_CHECK_TRUE@ src/tests/common.c @HAVE_CHECK_TRUE@debug_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@debug_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ libsss_debug.la @HAVE_CHECK_TRUE@crypto_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/crypto-tests.c @HAVE_CHECK_TRUE@crypto_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@crypto_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(POPT_LIBS) \ @HAVE_CHECK_TRUE@ $(TALLOC_LIBS) \ @HAVE_CHECK_TRUE@ libsss_crypt.la \ @HAVE_CHECK_TRUE@ libsss_debug.la \ @HAVE_CHECK_TRUE@ libsss_test_common.la @HAVE_CHECK_TRUE@ipa_hbac_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/ipa_hbac-tests.c @HAVE_CHECK_TRUE@ipa_hbac_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@ipa_hbac_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la \ @HAVE_CHECK_TRUE@ libipa_hbac.la @HAVE_CHECK_TRUE@sss_idmap_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/sss_idmap-tests.c @HAVE_CHECK_TRUE@sss_idmap_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@sss_idmap_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(TALLOC_LIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la \ @HAVE_CHECK_TRUE@ libsss_idmap.la @HAVE_CHECK_TRUE@responder_socket_access_tests_SOURCES = \ @HAVE_CHECK_TRUE@ src/tests/responder_socket_access-tests.c \ @HAVE_CHECK_TRUE@ src/responder/common/responder_common.c \ @HAVE_CHECK_TRUE@ src/responder/common/responder_packet.c \ @HAVE_CHECK_TRUE@ src/responder/common/responder_cmd.c @HAVE_CHECK_TRUE@responder_socket_access_tests_CFLAGS = \ @HAVE_CHECK_TRUE@ $(AM_CFLAGS) \ @HAVE_CHECK_TRUE@ $(CHECK_CFLAGS) @HAVE_CHECK_TRUE@responder_socket_access_tests_LDADD = \ @HAVE_CHECK_TRUE@ $(CHECK_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_LIBS) \ @HAVE_CHECK_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CHECK_TRUE@ libsss_test_common.la stress_tests_SOURCES = \ src/tests/stress-tests.c stress_tests_LDADD = \ $(SSSD_LIBS) \ libsss_test_common.la krb5_child_test_SOURCES = \ src/tests/krb5_child-test.c \ src/providers/krb5/krb5_utils.c \ src/providers/krb5/krb5_ccache.c \ src/providers/krb5/krb5_child_handler.c \ src/providers/krb5/krb5_common.c \ src/providers/krb5/krb5_opts.c \ src/util/sss_krb5.c \ src/providers/data_provider_fo.c \ src/providers/data_provider_opts.c \ src/providers/data_provider_callbacks.c \ src/util/become_user.c \ $(SSSD_FAILOVER_OBJ) \ $(NULL) krb5_child_test_CFLAGS = \ $(AM_CFLAGS) \ -DKRB5_CHILD_DIR=\"$(builddir)\" \ $(KRB5_CFLAGS) \ $(CHECK_CFLAGS) krb5_child_test_LDADD = \ $(SSSD_LIBS) \ $(CARES_LIBS) \ $(KRB5_LIBS) \ $(CHECK_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ libsss_test_common.la @BUILD_DBUS_TESTS_TRUE@sbus_tests_SOURCES = \ @BUILD_DBUS_TESTS_TRUE@ src/tests/common_dbus.c \ @BUILD_DBUS_TESTS_TRUE@ src/tests/sbus_tests.c @BUILD_DBUS_TESTS_TRUE@sbus_tests_CFLAGS = \ @BUILD_DBUS_TESTS_TRUE@ $(CHECK_CFLAGS) @BUILD_DBUS_TESTS_TRUE@sbus_tests_LDADD = \ @BUILD_DBUS_TESTS_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @BUILD_DBUS_TESTS_TRUE@ $(SSSD_LIBS) \ @BUILD_DBUS_TESTS_TRUE@ $(CHECK_LIBS) @BUILD_DBUS_TESTS_TRUE@sbus_codegen_tests_SOURCES = \ @BUILD_DBUS_TESTS_TRUE@ src/tests/common_dbus.c \ @BUILD_DBUS_TESTS_TRUE@ src/tests/sbus_codegen_tests.c \ @BUILD_DBUS_TESTS_TRUE@ src/tests/sbus_codegen_tests_generated.c \ @BUILD_DBUS_TESTS_TRUE@ src/tests/sbus_codegen_tests_generated.h @BUILD_DBUS_TESTS_TRUE@sbus_codegen_tests_CFLAGS = \ @BUILD_DBUS_TESTS_TRUE@ $(CHECK_CFLAGS) @BUILD_DBUS_TESTS_TRUE@sbus_codegen_tests_LDADD = \ @BUILD_DBUS_TESTS_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @BUILD_DBUS_TESTS_TRUE@ $(SSSD_LIBS) \ @BUILD_DBUS_TESTS_TRUE@ $(CHECK_LIBS) @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@sss_config_tests_SOURCES = \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ src/tests/sss_config-tests.c \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ src/tests/common.c @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@sss_config_tests_CFLAGS = \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(AM_CFLAGS) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(CHECK_CFLAGS) @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@sss_config_tests_LDADD = \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(SSSD_LIBS) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(CHECK_LIBS) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ libsss_config.la \ @BUILD_CONFIG_LIB_TRUE@@BUILD_IFP_TRUE@ libsss_test_common.la @HAVE_CMOCKA_TRUE@TEST_MOCK_RESP_OBJ = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_resp.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_resp_dp.c \ @HAVE_CMOCKA_TRUE@ src/responder/common/responder_packet.c \ @HAVE_CMOCKA_TRUE@ src/responder/common/responder_cmd.c \ @HAVE_CMOCKA_TRUE@ src/responder/common/negcache.c \ @HAVE_CMOCKA_TRUE@ src/responder/common/responder_common.c \ @HAVE_CMOCKA_TRUE@ src/responder/common/responder_cache_req.c @HAVE_CMOCKA_TRUE@TEST_MOCK_PROVIDER_OBJ = \ @HAVE_CMOCKA_TRUE@ src/util/sss_ldap.c \ @HAVE_CMOCKA_TRUE@ src/providers/data_provider_opts.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/ldap_opts.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/ldap_options.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_domain.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_utils.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_range.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_sdap.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_sysdb_objects.c @HAVE_CMOCKA_TRUE@EXTRA_nss_srv_tests_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(ldblib_LTLIBRARIES) @HAVE_CMOCKA_TRUE@nss_srv_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ $(TEST_MOCK_RESP_OBJ) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_nss_srv.c \ @HAVE_CMOCKA_TRUE@ src/responder/nss/nsssrv_cmd.c \ @HAVE_CMOCKA_TRUE@ src/responder/nss/nsssrv_netgroup.c \ @HAVE_CMOCKA_TRUE@ src/responder/nss/nsssrv_services.c \ @HAVE_CMOCKA_TRUE@ src/responder/nss/nsssrv_mmap_cache.c @HAVE_CMOCKA_TRUE@nss_srv_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @HAVE_CMOCKA_TRUE@nss_srv_tests_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_ncache_check_user \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_ncache_check_uid \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_ncache_check_sid \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_packet_get_body \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_packet_get_cmd \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_cmd_send_empty \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_cmd_done @HAVE_CMOCKA_TRUE@nss_srv_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libsss_idmap.la @HAVE_CMOCKA_TRUE@EXTRA_pam_srv_tests_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(ldblib_LTLIBRARIES) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@pam_srv_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ $(TEST_MOCK_RESP_OBJ) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_pam_srv.c \ @HAVE_CMOCKA_TRUE@ src/sss_client/pam_message.c \ @HAVE_CMOCKA_TRUE@ src/responder/pam/pamsrv_cmd.c \ @HAVE_CMOCKA_TRUE@ src/responder/pam/pamsrv_p11.c \ @HAVE_CMOCKA_TRUE@ src/responder/pam/pam_helpers.c \ @HAVE_CMOCKA_TRUE@ src/responder/pam/pamsrv_dp.c \ @HAVE_CMOCKA_TRUE@ src/responder/pam/pam_LOCAL_domain.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@pam_srv_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ -U SSSD_LIBEXEC_PATH -DSSSD_LIBEXEC_PATH=\"$(abs_builddir)\" \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@pam_srv_tests_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_packet_get_body \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_packet_get_cmd \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_cmd_send_empty \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_cmd_done \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,pam_dp_send_req \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@pam_srv_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(PAM_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libsss_idmap.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@EXTRA_responder_get_domains_tests_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(ldblib_LTLIBRARIES) @HAVE_CMOCKA_TRUE@responder_get_domains_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/responder/common/responder_get_domains.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_responder_common.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_resp.c @HAVE_CMOCKA_TRUE@responder_get_domains_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @HAVE_CMOCKA_TRUE@responder_get_domains_tests_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_parse_name_for_domains @HAVE_CMOCKA_TRUE@responder_get_domains_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la @HAVE_CMOCKA_TRUE@sbus_internal_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/sbus_internal_tests.c \ @HAVE_CMOCKA_TRUE@ src/sbus/sssd_dbus_request.c @HAVE_CMOCKA_TRUE@sbus_internal_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @HAVE_CMOCKA_TRUE@sbus_internal_tests_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,dbus_bus_get \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,dbus_pending_call_steal_reply \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,dbus_pending_call_unref \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,dbus_message_unref \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,dbus_connection_unref \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,dbus_connection_set_exit_on_disconnect \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,hash_lookup @HAVE_CMOCKA_TRUE@sbus_internal_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_util.la \ @HAVE_CMOCKA_TRUE@ libsss_crypt.la \ @HAVE_CMOCKA_TRUE@ libsss_debug.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la @HAVE_CMOCKA_TRUE@test_find_uid_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_find_uid.c \ @HAVE_CMOCKA_TRUE@ src/util/find_uid.c \ @HAVE_CMOCKA_TRUE@ src/util/atomic_io.c \ @HAVE_CMOCKA_TRUE@ src/util/strtonum.c @HAVE_CMOCKA_TRUE@test_find_uid_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(DHASH_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(SYSTEMD_LOGIN_CFLAGS) @HAVE_CMOCKA_TRUE@test_find_uid_LDADD = \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(DHASH_LIBS) \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SYSTEMD_LOGIN_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_debug.la @HAVE_CMOCKA_TRUE@test_io_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_io.c \ @HAVE_CMOCKA_TRUE@ src/util/io.c \ @HAVE_CMOCKA_TRUE@ src/tests/common.c @HAVE_CMOCKA_TRUE@test_io_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @HAVE_CMOCKA_TRUE@test_io_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) @HAVE_CMOCKA_TRUE@EXTRA_test_negcache_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(ldblib_LTLIBRARIES) @HAVE_CMOCKA_TRUE@test_negcache_SOURCES = \ @HAVE_CMOCKA_TRUE@ $(SSSD_RESPONDER_OBJ) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_negcache.c @HAVE_CMOCKA_TRUE@test_negcache_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(DHASH_CFLAGS) @HAVE_CMOCKA_TRUE@test_negcache_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libsss_idmap.la @HAVE_CMOCKA_TRUE@test_authtok_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_authtok.c \ @HAVE_CMOCKA_TRUE@ src/util/authtok.c \ @HAVE_CMOCKA_TRUE@ src/util/authtok-utils.c \ @HAVE_CMOCKA_TRUE@ src/util/util.c @HAVE_CMOCKA_TRUE@test_authtok_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(POPT_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(DHASH_CFLAGS) @HAVE_CMOCKA_TRUE@test_authtok_LDADD = \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(DHASH_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libsss_debug.la @HAVE_CMOCKA_TRUE@sss_nss_idmap_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/sss_nss_idmap-tests.c @HAVE_CMOCKA_TRUE@sss_nss_idmap_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @HAVE_CMOCKA_TRUE@sss_nss_idmap_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_nss_idmap_tests.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@EXTRA_dyndns_tests_DEPENDENCIES = \ @HAVE_CMOCKA_TRUE@ $(ldblib_LTLIBRARIES) @HAVE_CMOCKA_TRUE@dyndns_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ $(SSSD_RESOLV_OBJ) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_be.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_dyndns.c \ @HAVE_CMOCKA_TRUE@ src/providers/data_provider_opts.c @HAVE_CMOCKA_TRUE@dyndns_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ -DDYNDNS_TIMEOUT=2 @HAVE_CMOCKA_TRUE@dyndns_tests_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,execv \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,getifaddrs \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,freeifaddrs @HAVE_CMOCKA_TRUE@dyndns_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CARES_LIBS) \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la @HAVE_CMOCKA_TRUE@fqnames_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_fqnames.c @HAVE_CMOCKA_TRUE@fqnames_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @HAVE_CMOCKA_TRUE@fqnames_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la @HAVE_CMOCKA_TRUE@nestedgroups_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ $(TEST_MOCK_PROVIDER_OBJ) \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_idmap.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_nested_groups.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_be.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_async_nested_groups.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_ad_groups.c \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/ipa_dn.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@nestedgroups_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ -DEXTERNAL_MEMBERS_CHUNK=1 \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@nestedgroups_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_idmap.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sss_idmap_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_sss_idmap.c @HAVE_CMOCKA_TRUE@test_sss_idmap_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @HAVE_CMOCKA_TRUE@test_sss_idmap_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_idmap.la \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la @HAVE_CMOCKA_TRUE@test_ipa_idmap_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ipa_idmap.c \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/ipa_idmap.c @HAVE_CMOCKA_TRUE@test_ipa_idmap_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @HAVE_CMOCKA_TRUE@test_ipa_idmap_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sysdb_get_ranges @HAVE_CMOCKA_TRUE@test_ipa_idmap_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_idmap.la \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la @HAVE_CMOCKA_TRUE@test_utils_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_utils.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_sss_ssh.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_string_utils.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_utils_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @HAVE_CMOCKA_TRUE@test_utils_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la @HAVE_CMOCKA_TRUE@test_search_bases_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_search_bases.c @HAVE_CMOCKA_TRUE@test_search_bases_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ldap_auth_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ldap_auth.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_expire_common.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ldap_auth_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ldap_id_cleanup_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ldap_id_cleanup.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ldap_id_cleanup_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TEVENT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sdap_access_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_sdap_access.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_expire_common.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sdap_access_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@ad_access_filter_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ad_access_filter.c @HAVE_CMOCKA_TRUE@ad_access_filter_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TEVENT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_ad_tests.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@ad_gpo_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ad_gpo.c @HAVE_CMOCKA_TRUE@ad_gpo_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NDR_NBT_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@ad_gpo_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ $(NDR_NBT_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_idmap.la \ @HAVE_CMOCKA_TRUE@ libsss_krb5_common.la \ @HAVE_CMOCKA_TRUE@ libsss_ad_tests.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@ad_common_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ $(libsss_krb5_common_la_SOURCES) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_krb5.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ad_common.c \ @HAVE_CMOCKA_TRUE@ src/providers/ad/ad_opts.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@ad_common_tests_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sdap_set_sasl_options \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,krb5_kt_default \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@ad_common_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(KEYUTILS_LIBS) \ @HAVE_CMOCKA_TRUE@ $(KRB5_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@dp_opt_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/providers/data_provider_opts.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_dp_opts.c @HAVE_CMOCKA_TRUE@dp_opt_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @HAVE_CMOCKA_TRUE@dp_opt_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la @HAVE_CMOCKA_TRUE@sdap_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/providers/data_provider_opts.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_domain.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/sdap_range.c \ @HAVE_CMOCKA_TRUE@ src/providers/ldap/ldap_opts.c \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/ipa_opts.c \ @HAVE_CMOCKA_TRUE@ src/util/sss_ldap.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_sdap.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@sdap_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@sdap_tests_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,ldap_set_option \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,ldap_get_dn \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,ldap_memfree \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,ldap_get_values_len \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,ldap_value_free_len \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,ldap_first_attribute \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,ldap_next_attribute \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@sdap_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(LDB_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ $(OPENLDAP_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ifp_tests_SOURCES = \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(TEST_MOCK_RESP_OBJ) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ifp.c \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/responder/ifp/ifpsrv_cmd.c \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/responder/ifp/ifp_iface_generated.c \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/responder/ifp/ifpsrv_util.c \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/responder/common/responder_utils.c \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(NULL) @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ifp_tests_CFLAGS = \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ifp_tests_LDADD = \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ libsss_test_common.la @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@sss_sifp_tests_SOURCES = \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_sss_sifp.c \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp_attrs.c \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp_common.c \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp_parser.c \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp_utils.c \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp_dbus.c \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ src/lib/sifp/sss_sifp.c @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@sss_sifp_tests_CFLAGS = \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ -I$(top_srcdir)/src/lib/sifp @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@sss_sifp_tests_LDFLAGS = \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ -Wl,-wrap,dbus_bus_get \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ -Wl,-wrap,dbus_connection_send_with_reply_and_block @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@sss_sifp_tests_LDADD = \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(DBUS_LIBS) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(DHASH_LIBS) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @BUILD_IFP_TRUE@@HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) @HAVE_CMOCKA_TRUE@test_sysdb_views_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_sysdb_views.c \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/ipa_utils.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sysdb_views_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sysdb_views_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(LDB_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sysdb_subdomains_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_sysdb_subdomains.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sysdb_subdomains_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sysdb_subdomains_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(LDB_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sysdb_utils_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_sysdb_utils.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sysdb_utils_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sysdb_utils_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(LDB_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_be_ptask_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_be.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_be_ptask.c \ @HAVE_CMOCKA_TRUE@ src/providers/dp_ptask.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_be_ptask_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_be_ptask_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_copy_ccache_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_copy_ccache.c \ @HAVE_CMOCKA_TRUE@ src/providers/krb5/krb5_ccache.c \ @HAVE_CMOCKA_TRUE@ src/util/sss_krb5.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_copy_ccache_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_copy_ccache_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(KRB5_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_copy_keytab_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_krb5.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_copy_keytab.c \ @HAVE_CMOCKA_TRUE@ src/providers/krb5/krb5_keytab.c \ @HAVE_CMOCKA_TRUE@ src/util/sss_krb5.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_copy_keytab_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_copy_keytab_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(KRB5_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@dummy_child_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/dummy_child.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@dummy_child_LDADD = \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_child_common_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_child_common.c \ @HAVE_CMOCKA_TRUE@ src/util/child_common.c \ @HAVE_CMOCKA_TRUE@ src/util/signal.c \ @HAVE_CMOCKA_TRUE@ src/util/atomic_io.c \ @HAVE_CMOCKA_TRUE@ src/util/util_errors.c \ @HAVE_CMOCKA_TRUE@ src/util/util.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_child_common_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ -DCHILD_DIR=\"$(builddir)\" \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_child_common_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,child_io_destructor \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_child_common_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(DHASH_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_debug.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@responder_cache_req_tests_SOURCES = \ @HAVE_CMOCKA_TRUE@ $(TEST_MOCK_RESP_OBJ) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_responder_cache_req.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@responder_cache_req_tests_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@responder_cache_req_tests_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_dp_get_account_send \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@responder_cache_req_tests_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sbus_opath_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_sbus_opath.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_sbus_opath_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) @HAVE_CMOCKA_TRUE@test_sbus_opath_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_debug.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@test_resolv_fake_SOURCES = \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ src/tests/cmocka/test_resolv_fake.c \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ src/resolv/async_resolv.c \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@test_resolv_fake_CFLAGS = \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@test_resolv_fake_LDFLAGS = \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ -Wl,-wrap,ares_query \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@test_resolv_fake_LDADD = \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(CARES_LIBS) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(DHASH_LIBS) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(RESOLV_LIBS) \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ libsss_debug.la \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@@HAVE_LIBRESOLV_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_fo_srv_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_fo_srv.c \ @HAVE_CMOCKA_TRUE@ src/providers/fail_over.c \ @HAVE_CMOCKA_TRUE@ src/providers/fail_over_srv.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_fo_srv_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_fo_srv_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(CARES_LIBS) \ @HAVE_CMOCKA_TRUE@ $(DHASH_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ipa_subdom_util_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ipa_subdomains_utils.c \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/ipa_subdomains_utils.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ipa_subdom_util_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ipa_subdom_util_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(LDB_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ipa_subdom_server_SOURCES = \ @HAVE_CMOCKA_TRUE@ $(libsss_krb5_common_la_SOURCES) \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_sdap.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_be.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_krb5.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ipa_subdomains_server.c \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/ipa_subdomains_server.c \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/ipa_subdomains_utils.c \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/ipa_opts.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ipa_subdom_server_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ -DIPA_TRUST_KEYTAB_DIR=TEST_DIR\"/tp_test_ipa_subdom_server-test_ipa_subdomains_server\" \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ipa_subdom_server_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,krb5_kt_default \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,execle \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,execve \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,rename \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,sss_unique_filename \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ipa_subdom_server_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(KEYUTILS_LIBS) \ @HAVE_CMOCKA_TRUE@ $(KRB5_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_ldap_common.la \ @HAVE_CMOCKA_TRUE@ libsss_ad_tests.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_tools_colondb_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_tools_colondb.c \ @HAVE_CMOCKA_TRUE@ src/tools/common/sss_colondb.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_tools_colondb_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_tools_colondb_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_tools_colondb_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_krb5_wait_queue_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_be.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_krb5_wait_queue.c \ @HAVE_CMOCKA_TRUE@ src/providers/krb5/krb5_wait_queue.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_krb5_wait_queue_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_krb5_wait_queue_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(DHASH_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_cert_utils_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_cert_utils.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_cert_utils_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(CRYPTO_CFLAGS) \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_cert_utils_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(POPT_LIBS) \ @HAVE_CMOCKA_TRUE@ $(TALLOC_LIBS) \ @HAVE_CMOCKA_TRUE@ $(CRYPTO_LIBS) \ @HAVE_CMOCKA_TRUE@ libsss_debug.la \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libsss_cert.la \ @HAVE_CMOCKA_TRUE@ libsss_crypt.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_data_provider_be_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/providers/data_provider_be.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_data_provider_be.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/common_mock_be.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_data_provider_be_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ -DUNIT_TESTING \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_data_provider_be_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,_tevent_add_timer \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_data_provider_be_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(PAM_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ $(LIBADD_DL) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ libdlopen_test_providers.la \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ipa_dn_SOURCES = \ @HAVE_CMOCKA_TRUE@ src/providers/ipa/ipa_dn.c \ @HAVE_CMOCKA_TRUE@ src/tests/cmocka/test_ipa_dn.c \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ipa_dn_CFLAGS = \ @HAVE_CMOCKA_TRUE@ $(AM_CFLAGS) \ @HAVE_CMOCKA_TRUE@ -DUNIT_TESTING \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ipa_dn_LDFLAGS = \ @HAVE_CMOCKA_TRUE@ -Wl,-wrap,_tevent_add_timer \ @HAVE_CMOCKA_TRUE@ $(NULL) @HAVE_CMOCKA_TRUE@test_ipa_dn_LDADD = \ @HAVE_CMOCKA_TRUE@ $(CMOCKA_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_LIBS) \ @HAVE_CMOCKA_TRUE@ $(SSSD_INTERNAL_LTLIBS) \ @HAVE_CMOCKA_TRUE@ $(LIBADD_DL) \ @HAVE_CMOCKA_TRUE@ libsss_test_common.la \ @HAVE_CMOCKA_TRUE@ $(NULL) pam_test_client_SOURCES = src/sss_client/pam_test_client.c pam_test_client_LDADD = $(PAM_LIBS) $(PAM_MISC_LIBS) @BUILD_AUTOFS_TRUE@autofs_test_client_SOURCES = \ @BUILD_AUTOFS_TRUE@ src/sss_client/autofs/autofs_test_client.c \ @BUILD_AUTOFS_TRUE@ src/sss_client/autofs/sss_autofs.c \ @BUILD_AUTOFS_TRUE@ src/sss_client/common.c @BUILD_AUTOFS_TRUE@autofs_test_client_CFLAGS = $(AM_CFLAGS) @BUILD_AUTOFS_TRUE@autofs_test_client_LDADD = -lpopt $(CLIENT_LIBS) #################### # Client Libraries # #################### nsslib_LTLIBRARIES = libnss_sss.la libnss_sss_la_SOURCES = \ src/sss_client/common.c \ src/sss_client/nss_passwd.c \ src/sss_client/nss_group.c \ src/sss_client/nss_netgroup.c \ src/sss_client/nss_services.c \ src/sss_client/sss_cli.h \ src/sss_client/nss_compat.h \ src/sss_client/nss_mc_common.c \ src/util/io.c \ src/util/murmurhash3.c \ src/sss_client/nss_mc_passwd.c \ src/sss_client/nss_mc_group.c \ src/sss_client/nss_mc_initgr.c \ src/sss_client/nss_mc.h libnss_sss_la_LIBADD = \ $(CLIENT_LIBS) libnss_sss_la_LDFLAGS = \ -module \ -version-info 2:0:0 \ -Wl,--version-script,$(srcdir)/src/sss_client/sss_nss.exports @BUILD_NFS_IDMAP_TRUE@nfslib_LTLIBRARIES = sss.la @BUILD_NFS_IDMAP_TRUE@sss_la_SOURCES = \ @BUILD_NFS_IDMAP_TRUE@ src/sss_client/common.c \ @BUILD_NFS_IDMAP_TRUE@ src/sss_client/nss_mc_common.c \ @BUILD_NFS_IDMAP_TRUE@ src/util/io.c \ @BUILD_NFS_IDMAP_TRUE@ src/util/murmurhash3.c \ @BUILD_NFS_IDMAP_TRUE@ src/sss_client/nss_mc_passwd.c \ @BUILD_NFS_IDMAP_TRUE@ src/sss_client/nss_mc_group.c \ @BUILD_NFS_IDMAP_TRUE@ src/sss_client/nfs/sss_nfs_client.c \ @BUILD_NFS_IDMAP_TRUE@ $(NULL) @BUILD_NFS_IDMAP_TRUE@sss_la_CFLAGS = $(AM_CFLAGS) @BUILD_NFS_IDMAP_TRUE@sss_la_LIBADD = \ @BUILD_NFS_IDMAP_TRUE@ $(CLIENT_LIBS) \ @BUILD_NFS_IDMAP_TRUE@ $(NFSIDMAP_LIBS) \ @BUILD_NFS_IDMAP_TRUE@ $(NULL) @BUILD_NFS_IDMAP_TRUE@sss_la_LDFLAGS = \ @BUILD_NFS_IDMAP_TRUE@ -module \ @BUILD_NFS_IDMAP_TRUE@ -avoid-version \ @BUILD_NFS_IDMAP_TRUE@ $(NULL) pamlib_LTLIBRARIES = pam_sss.la pam_sss_la_SOURCES = \ src/sss_client/pam_sss.c \ src/sss_client/pam_message.c \ src/sss_client/common.c \ src/sss_client/sss_cli.h \ src/util/atomic_io.c \ src/util/authtok-utils.c \ src/sss_client/sss_pam_macros.h \ src/sss_client/sss_pam_compat.h pam_sss_la_LIBADD = \ $(CLIENT_LIBS) \ $(PAM_LIBS) pam_sss_la_LDFLAGS = \ -module \ -avoid-version \ -Wl,--version-script,$(srcdir)/src/sss_client/sss_pam.exports @BUILD_SUDO_TRUE@libsss_sudo_la_SOURCES = \ @BUILD_SUDO_TRUE@ src/sss_client/common.c \ @BUILD_SUDO_TRUE@ src/sss_client/sss_cli.h \ @BUILD_SUDO_TRUE@ src/sss_client/sudo/sss_sudo_response.c \ @BUILD_SUDO_TRUE@ src/sss_client/sudo/sss_sudo.c \ @BUILD_SUDO_TRUE@ src/sss_client/sudo/sss_sudo.h \ @BUILD_SUDO_TRUE@ src/sss_client/sudo/sss_sudo_private.h @BUILD_SUDO_TRUE@libsss_sudo_la_LIBADD = \ @BUILD_SUDO_TRUE@ $(CLIENT_LIBS) @BUILD_SUDO_TRUE@libsss_sudo_la_LDFLAGS = \ @BUILD_SUDO_TRUE@ -Wl,--version-script,$(srcdir)/src/sss_client/sss_sudo.exports \ @BUILD_SUDO_TRUE@ -module \ @BUILD_SUDO_TRUE@ -avoid-version @BUILD_SUDO_TRUE@sudolib_LTLIBRARIES = libsss_sudo.la @BUILD_AUTOFS_TRUE@autofslib_LTLIBRARIES = libsss_autofs.la @BUILD_AUTOFS_TRUE@libsss_autofs_la_SOURCES = \ @BUILD_AUTOFS_TRUE@ src/sss_client/common.c \ @BUILD_AUTOFS_TRUE@ src/sss_client/sss_cli.h \ @BUILD_AUTOFS_TRUE@ src/sss_client/autofs/sss_autofs.c \ @BUILD_AUTOFS_TRUE@ src/sss_client/autofs/sss_autofs_private.h @BUILD_AUTOFS_TRUE@libsss_autofs_la_LIBADD = \ @BUILD_AUTOFS_TRUE@ $(CLIENT_LIBS) @BUILD_AUTOFS_TRUE@libsss_autofs_la_LDFLAGS = \ @BUILD_AUTOFS_TRUE@ -module \ @BUILD_AUTOFS_TRUE@ -avoid-version \ @BUILD_AUTOFS_TRUE@ -Wl,--version-script,$(srcdir)/src/sss_client/autofs/sss_autofs.exports libsss_ldap_common_la_SOURCES = src/providers/ldap/ldap_id.c \ src/providers/ldap/ldap_id_enum.c \ src/providers/ldap/sdap_async_enum.c \ src/providers/ldap/ldap_id_cleanup.c \ src/providers/ldap/ldap_id_netgroup.c \ src/providers/ldap/ldap_id_services.c \ src/providers/ldap/ldap_auth.c \ src/providers/ldap/ldap_common.c \ src/providers/ldap/ldap_options.c \ src/providers/ldap/ldap_opts.c \ src/providers/ldap/sdap_access.c \ src/providers/ldap/sdap_async.c \ src/providers/ldap/sdap_async_users.c \ src/providers/ldap/sdap_async_groups.c \ src/providers/ldap/sdap_async_nested_groups.c \ src/providers/ldap/sdap_async_groups_ad.c \ src/providers/ldap/sdap_async_initgroups.c \ src/providers/ldap/sdap_async_initgroups_ad.c \ src/providers/ldap/sdap_async_connection.c \ src/providers/ldap/sdap_async_netgroups.c \ src/providers/ldap/sdap_async_services.c \ src/providers/ldap/sdap_ad_groups.c \ src/providers/ldap/sdap_child_helpers.c \ src/providers/ldap/sdap_fd_events.c \ src/providers/ldap/sdap_id_op.c \ src/providers/ldap/sdap_idmap.c \ src/providers/ldap/sdap_idmap.h \ src/providers/ldap/sdap_range.c \ src/providers/ldap/sdap_reinit.c \ src/providers/ldap/sdap_dyndns.c \ src/providers/ldap/sdap_refresh.c \ src/providers/ldap/sdap_utils.c \ src/providers/ldap/sdap_domain.c src/providers/ldap/sdap_ops.c \ src/providers/ldap/sdap.c src/providers/ipa/ipa_dn.c \ src/util/user_info_msg.c src/util/sss_ldap.c $(NULL) \ $(am__append_53) $(am__append_54) libsss_ldap_common_la_CFLAGS = \ $(AM_CFLAGS) \ $(KRB5_CFLAGS) \ $(NULL) libsss_ldap_common_la_LIBADD = \ $(OPENLDAP_LIBS) \ $(KRB5_LIBS) \ libsss_krb5_common.la \ libsss_idmap.la \ libsss_util.la \ $(NULL) libsss_ldap_common_la_LDFLAGS = \ -avoid-version \ $(NULL) libsss_krb5_common_la_SOURCES = \ src/providers/krb5/krb5_utils.c \ src/providers/krb5/krb5_delayed_online_authentication.c \ src/providers/krb5/krb5_renew_tgt.c \ src/providers/krb5/krb5_wait_queue.c \ src/providers/krb5/krb5_common.c \ src/providers/krb5/krb5_opts.c \ src/providers/krb5/krb5_auth.c \ src/providers/krb5/krb5_access.c \ src/providers/krb5/krb5_child_handler.c \ src/providers/krb5/krb5_init_shared.c \ src/providers/krb5/krb5_ccache.c \ src/util/sss_krb5.c \ src/util/become_user.c \ $(NULL) libsss_krb5_common_la_CFLAGS = \ $(AM_CFLAGS) \ $(KRB5_CFLAGS) libsss_krb5_common_la_LIBADD = \ $(KEYUTILS_LIBS) \ $(DHASH_LIBS) \ $(KRB5_LIBS) libsss_krb5_common_la_LDFLAGS = \ -avoid-version libsss_ldap_la_SOURCES = \ src/providers/ldap/ldap_init.c \ src/providers/ldap/ldap_access.c libsss_ldap_la_CFLAGS = \ $(AM_CFLAGS) \ $(OPENLDAP_CFLAGS) libsss_ldap_la_LIBADD = \ $(OPENLDAP_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ libsss_ldap_common.la \ libsss_krb5_common.la libsss_ldap_la_LDFLAGS = \ -avoid-version \ -module libsss_proxy_la_SOURCES = \ src/providers/proxy/proxy_init.c \ src/providers/proxy/proxy_id.c \ src/providers/proxy/proxy_netgroup.c \ src/providers/proxy/proxy_services.c \ src/providers/proxy/proxy_auth.c \ src/providers/data_provider_iface_generated.c \ src/providers/data_provider_iface_generated.h libsss_proxy_la_CFLAGS = \ $(AM_CFLAGS) libsss_proxy_la_LIBADD = \ $(PAM_LIBS) libsss_proxy_la_LDFLAGS = \ -avoid-version \ -module libsss_simple_la_SOURCES = \ src/providers/simple/simple_access_check.c \ src/providers/simple/simple_access.c libsss_simple_la_CFLAGS = \ $(AM_CFLAGS) libsss_simple_la_LDFLAGS = \ -avoid-version \ -module libsss_krb5_la_SOURCES = \ src/providers/krb5/krb5_init.c libsss_krb5_la_CFLAGS = \ $(AM_CFLAGS) \ $(DHASH_CFLAGS) \ $(KRB5_CFLAGS) libsss_krb5_la_LIBADD = \ $(DHASH_LIBS) \ $(KRB5_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ libsss_krb5_common.la libsss_krb5_la_LDFLAGS = \ -avoid-version \ -module libsss_ipa_la_SOURCES = src/providers/ipa/ipa_init.c \ src/providers/ipa/ipa_opts.c src/providers/ipa/ipa_common.c \ src/providers/ipa/ipa_config.c src/providers/ipa/ipa_id.c \ src/providers/ipa/ipa_netgroups.c src/providers/ipa/ipa_auth.c \ src/providers/ipa/ipa_access.c src/providers/ipa/ipa_dyndns.c \ src/providers/ipa/ipa_hosts.c \ src/providers/ipa/ipa_subdomains.c \ src/providers/ipa/ipa_subdomains_id.c \ src/providers/ipa/ipa_subdomains_server.c \ src/providers/ipa/ipa_subdomains_utils.c \ src/providers/ipa/ipa_subdomains_ext_groups.c \ src/providers/ipa/ipa_views.c src/providers/ipa/ipa_utils.c \ src/providers/ipa/ipa_s2n_exop.c \ src/providers/ipa/ipa_hbac_hosts.c \ src/providers/ipa/ipa_hbac_private.h \ src/providers/ipa/ipa_hbac_rules.c \ src/providers/ipa/ipa_hbac_rules.h \ src/providers/ipa/ipa_hbac_services.c \ src/providers/ipa/ipa_hbac_users.c \ src/providers/ipa/ipa_hbac_common.c \ src/providers/ipa/ipa_selinux.c \ src/providers/ipa/ipa_selinux_maps.c \ src/providers/ipa/ipa_srv.c src/providers/ipa/ipa_idmap.c \ src/providers/ipa/ipa_dn.c src/providers/ad/ad_opts.c \ src/providers/ad/ad_common.c src/providers/ad/ad_common.h \ src/providers/ad/ad_dyndns.c src/providers/ad/ad_id.c \ src/providers/ad/ad_srv.c src/providers/ad/ad_domain_info.c \ $(am__append_55) $(am__append_56) $(am__append_57) libsss_ipa_la_CFLAGS = \ $(AM_CFLAGS) \ $(OPENLDAP_CFLAGS) \ $(DHASH_CFLAGS) \ $(NDR_NBT_CFLAGS) \ $(KRB5_CFLAGS) libsss_ipa_la_LIBADD = \ $(OPENLDAP_LIBS) \ $(DHASH_LIBS) \ $(NDR_NBT_LIBS) \ $(KRB5_LIBS) \ $(SELINUX_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ libsss_ldap_common.la \ libsss_krb5_common.la \ libipa_hbac.la \ libsss_idmap.la \ libsss_semanage.la \ $(NULL) libsss_ipa_la_LDFLAGS = \ -avoid-version \ -module libsss_ad_la_SOURCES = src/providers/ad/ad_opts.c \ src/providers/ad/ad_common.c src/providers/ad/ad_common.h \ src/providers/ad/ad_init.c src/providers/ad/ad_dyndns.c \ src/providers/ad/ad_machine_pw_renewal.c \ src/providers/ad/ad_id.c src/providers/ad/ad_id.h \ src/providers/ad/ad_access.c src/providers/ad/ad_access.h \ src/providers/ad/ad_gpo.c src/providers/ad/ad_gpo.h \ src/providers/ad/ad_gpo_ndr.c src/providers/ad/ad_opts.h \ src/providers/ad/ad_srv.c src/providers/ad/ad_subdomains.c \ src/providers/ad/ad_subdomains.h \ src/providers/ad/ad_domain_info.c \ src/providers/ad/ad_domain_info.h $(am__append_58) \ $(am__append_59) libsss_ad_la_CFLAGS = \ $(AM_CFLAGS) \ $(OPENLDAP_CFLAGS) \ $(SASL_CFLAGS) \ $(DHASH_CFLAGS) \ $(KRB5_CFLAGS) \ $(NDR_NBT_CFLAGS) \ $(SMBCLIENT_CFLAGS) libsss_ad_la_LIBADD = \ $(OPENLDAP_LIBS) \ $(SASL_LIBS) \ $(DHASH_LIBS) \ $(KRB5_LIBS) \ $(NDR_NBT_LIBS) \ $(SSSD_INTERNAL_LTLIBS) \ $(SMBCLIENT_LIBS) \ libsss_ldap_common.la \ libsss_krb5_common.la \ libsss_idmap.la libsss_ad_la_LDFLAGS = \ -avoid-version \ -module krb5_child_SOURCES = \ src/providers/krb5/krb5_child.c \ src/providers/krb5/krb5_ccache.c \ src/providers/krb5/krb5_keytab.c \ src/providers/dp_pam_data_util.c \ src/util/user_info_msg.c \ src/util/sss_krb5.c \ src/util/find_uid.c \ src/util/atomic_io.c \ src/util/authtok.c \ src/util/authtok-utils.c \ src/util/util.c \ src/util/signal.c \ src/util/strtonum.c \ src/util/become_user.c \ src/util/util_errors.c \ src/sss_client/common.c \ $(NULL) krb5_child_CFLAGS = \ $(AM_CFLAGS) \ $(POPT_CFLAGS) \ $(KRB5_CFLAGS) \ $(PCRE_CFLAGS) \ $(SYSTEMD_LOGIN_CFLAGS) \ $(NULL) krb5_child_LDADD = \ libsss_debug.la \ $(TALLOC_LIBS) \ $(POPT_LIBS) \ $(DHASH_LIBS) \ $(KRB5_LIBS) \ $(CLIENT_LIBS) \ $(PCRE_LIBS) \ $(SYSTEMD_LOGIN_LIBS) \ $(NULL) ldap_child_SOURCES = \ src/providers/ldap/ldap_child.c \ src/providers/krb5/krb5_keytab.c \ src/util/sss_krb5.c \ src/util/atomic_io.c \ src/util/authtok.c \ src/util/authtok-utils.c \ src/util/util.c \ src/util/signal.c \ src/util/become_user.c \ $(NULL) ldap_child_CFLAGS = \ $(AM_CFLAGS) \ $(POPT_CFLAGS) \ $(KRB5_CFLAGS) ldap_child_LDADD = \ libsss_debug.la \ $(TALLOC_LIBS) \ $(POPT_LIBS) \ $(DHASH_LIBS) \ $(KRB5_LIBS) @BUILD_SEMANAGE_TRUE@selinux_child_SOURCES = \ @BUILD_SEMANAGE_TRUE@ src/providers/ipa/selinux_child.c \ @BUILD_SEMANAGE_TRUE@ src/util/sss_semanage.c \ @BUILD_SEMANAGE_TRUE@ src/util/atomic_io.c \ @BUILD_SEMANAGE_TRUE@ src/util/util.c \ @BUILD_SEMANAGE_TRUE@ $(NULL) @BUILD_SEMANAGE_TRUE@selinux_child_CFLAGS = \ @BUILD_SEMANAGE_TRUE@ $(AM_CFLAGS) \ @BUILD_SEMANAGE_TRUE@ $(POPT_CFLAGS) \ @BUILD_SEMANAGE_TRUE@ $(NULL) @BUILD_SEMANAGE_TRUE@selinux_child_LDADD = \ @BUILD_SEMANAGE_TRUE@ libsss_debug.la \ @BUILD_SEMANAGE_TRUE@ $(TALLOC_LIBS) \ @BUILD_SEMANAGE_TRUE@ $(POPT_LIBS) \ @BUILD_SEMANAGE_TRUE@ $(DHASH_LIBS) \ @BUILD_SEMANAGE_TRUE@ $(SEMANAGE_LIBS) \ @BUILD_SEMANAGE_TRUE@ $(NULL) gpo_child_SOURCES = \ src/providers/ad/ad_gpo_child.c \ src/util/atomic_io.c \ src/util/util.c \ src/util/signal.c gpo_child_CFLAGS = \ $(AM_CFLAGS) \ $(POPT_CFLAGS) \ $(KRB5_CFLAGS) \ $(INI_CONFIG_CFLAGS) \ $(SMBCLIENT_CFLAGS) gpo_child_LDADD = \ libsss_debug.la \ $(TALLOC_LIBS) \ $(POPT_LIBS) \ $(DHASH_LIBS) \ $(INI_CONFIG_LIBS) \ $(SMBCLIENT_LIBS) proxy_child_SOURCES = \ src/providers/proxy/proxy_child.c \ src/providers/data_provider_iface_generated.c \ src/providers/data_provider_iface_generated.h proxy_child_CFLAGS = \ $(AM_CFLAGS) \ $(POPT_CFLAGS) proxy_child_LDADD = \ $(PAM_LIBS) \ $(SSSD_LIBS) \ $(SSSD_INTERNAL_LTLIBS) p11_child_SOURCES = \ src/p11_child/p11_child_nss.c \ src/util/atomic_io.c \ src/util/util.c \ $(NULL) p11_child_CFLAGS = \ $(AM_CFLAGS) \ $(POPT_CFLAGS) \ $(NSS_CFLAGS) \ $(NULL) p11_child_LDADD = \ libsss_debug.la \ $(TALLOC_LIBS) \ $(DHASH_LIBS) \ $(POPT_LIBS) \ $(NSS_LIBS) \ libsss_crypt.la \ $(NULL) memberof_la_SOURCES = \ src/ldb_modules/memberof.c \ src/util/util.c memberof_la_CFLAGS = \ $(AM_CFLAGS) memberof_la_LIBADD = \ libsss_debug.la \ $(LDB_LIBS) \ $(DHASH_LIBS) memberof_la_LDFLAGS = \ -avoid-version \ -module @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@sssd_krb5_locator_plugin_la_SOURCES = \ @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@ src/krb5_plugin/sssd_krb5_locator_plugin.c \ @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@ src/util/atomic_io.c @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@sssd_krb5_locator_plugin_la_CFLAGS = \ @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@ $(AM_CFLAGS) \ @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@ $(KRB5_CFLAGS) @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@sssd_krb5_locator_plugin_la_LDFLAGS = \ @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@ -avoid-version \ @BUILD_KRB5_LOCATOR_PLUGIN_TRUE@ -module @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@sssd_krb5_localauth_plugin_la_SOURCES = \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/krb5_plugin/sssd_krb5_localauth_plugin.c \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/util/murmurhash3.c \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/util/io.c \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/sss_client/common.c \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/sss_client/nss_mc_common.c \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/sss_client/nss_mc_passwd.c \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ src/sss_client/nss_passwd.c @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@sssd_krb5_localauth_plugin_la_CFLAGS = \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ $(AM_CFLAGS) \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ $(KRB5_CFLAGS) @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@sssd_krb5_localauth_plugin_la_LIBADD = \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ $(KRB5_LIBS) @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@sssd_krb5_localauth_plugin_la_LDFLAGS = \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ -avoid-version \ @BUILD_KRB5_LOCALAUTH_PLUGIN_TRUE@ -module sssd_pac_plugin_la_SOURCES = \ src/sss_client/sssd_pac.c \ src/sss_client/common.c \ src/sss_client/sss_cli.h \ src/sss_client/krb5_authdata_int.h sssd_pac_plugin_la_CFLAGS = \ $(AM_CFLAGS) \ $(KRB5_CFLAGS) sssd_pac_plugin_la_LIBADD = \ $(CLIENT_LIBS) \ $(KRB5_LIBS) sssd_pac_plugin_la_LDFLAGS = \ -avoid-version \ -module # python[23] bindings pysss_la_SOURCES = \ $(SSSD_TOOLS_OBJ) \ src/python/pysss.c pysss_la_LDFLAGS = \ -avoid-version \ -module _py2sss_la_SOURCES = $(pysss_la_SOURCES) _py2sss_la_CFLAGS = \ $(AM_CFLAGS) \ $(PYTHON2_CFLAGS) _py2sss_la_LIBADD = \ $(SSSD_INTERNAL_LTLIBS) \ $(PYTHON_BINDINGS_LIBS) \ $(PYTHON2_LIBS) _py2sss_la_LDFLAGS = $(pysss_la_LDFLAGS) _py3sss_la_SOURCES = $(pysss_la_SOURCES) _py3sss_la_CFLAGS = \ $(AM_CFLAGS) \ $(PYTHON3_CFLAGS) _py3sss_la_LIBADD = \ $(SSSD_INTERNAL_LTLIBS) \ $(PYTHON_BINDINGS_LIBS) \ $(PYTHON3_LIBS) _py3sss_la_LDFLAGS = $(pysss_la_LDFLAGS) pyhbac_la_SOURCES = \ src/python/pyhbac.c \ src/util/sss_python.c pyhbac_la_LDFLAGS = \ -avoid-version \ -module _py2hbac_la_SOURCES = $(pyhbac_la_SOURCES) _py2hbac_la_CFLAGS = \ $(AM_CFLAGS) \ $(PYTHON2_CFLAGS) _py2hbac_la_LIBADD = \ $(PYTHON2_LIBS) \ libipa_hbac.la _py2hbac_la_LDFLAGS = $(pyhbac_la_LDFLAGS) _py3hbac_la_SOURCES = $(pyhbac_la_SOURCES) _py3hbac_la_CFLAGS = \ $(AM_CFLAGS) \ $(PYTHON3_CFLAGS) _py3hbac_la_LIBADD = \ $(PYTHON3_LIBS) \ libipa_hbac.la _py3hbac_la_LDFLAGS = $(pyhbac_la_LDFLAGS) pysss_murmur_la_SOURCES = \ src/python/pysss_murmur.c \ src/util/murmurhash3.c pysss_murmur_la_LDFLAGS = \ -avoid-version \ -module _py2sss_murmur_la_SOURCES = $(pysss_murmur_la_SOURCES) _py2sss_murmur_la_CFLAGS = \ $(AM_CFLAGS) \ $(PYTHON2_CFLAGS) _py2sss_murmur_la_LIBADD = \ $(PYTHON2_LIBS) _py2sss_murmur_la_LDFLAGS = $(pysss_murmur_la_LDFLAGS) _py3sss_murmur_la_SOURCES = $(pysss_murmur_la_SOURCES) _py3sss_murmur_la_CFLAGS = \ $(AM_CFLAGS) \ $(PYTHON3_CFLAGS) _py3sss_murmur_la_LIBADD = \ $(PYTHON3_LIBS) _py3sss_murmur_la_LDFLAGS = $(pysss_murmur_la_LDFLAGS) pysss_nss_idmap_la_SOURCES = \ src/python/pysss_nss_idmap.c pysss_nss_idmap_la_LDFLAGS = \ -avoid-version \ -module _py2sss_nss_idmap_la_SOURCES = $(pysss_nss_idmap_la_SOURCES) _py2sss_nss_idmap_la_CFLAGS = \ $(AM_CFLAGS) \ $(PYTHON2_CFLAGS) _py2sss_nss_idmap_la_LIBADD = \ $(PYTHON2_LIBS) \ libsss_nss_idmap.la _py2sss_nss_idmap_la_LDFLAGS = $(pysss_nss_idmap_la_LDFLAGS) _py3sss_nss_idmap_la_SOURCES = $(pysss_nss_idmap_la_SOURCES) _py3sss_nss_idmap_la_CFLAGS = \ $(AM_CFLAGS) \ $(PYTHON3_CFLAGS) _py3sss_nss_idmap_la_LIBADD = \ $(PYTHON3_LIBS) \ libsss_nss_idmap.la _py3sss_nss_idmap_la_LDFLAGS = $(pysss_nss_idmap_la_LDFLAGS) # end of python[23] bindings @BUILD_CIFS_IDMAP_PLUGIN_TRUE@cifs_idmap_sss_la_SOURCES = \ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@ src/lib/cifs_idmap_sss/cifs_idmap_sss.c @BUILD_CIFS_IDMAP_PLUGIN_TRUE@cifs_idmap_sss_la_LIBADD = \ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@ libsss_idmap.la \ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@ libsss_nss_idmap.la @BUILD_CIFS_IDMAP_PLUGIN_TRUE@cifs_idmap_sss_la_CFLAGS = \ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@ $(AM_CFLAGS) @BUILD_CIFS_IDMAP_PLUGIN_TRUE@cifs_idmap_sss_la_LDFLAGS = \ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@ -avoid-version \ @BUILD_CIFS_IDMAP_PLUGIN_TRUE@ -module ####################### # Installation Extras # ####################### init_SCRIPTS = $(am__append_62) $(am__append_63) $(am__append_64) systemdunit_DATA = $(am__append_60) systemdconf_DATA = $(am__append_61) dist_sssddata_DATA = \ src/config/etc/sssd.api.conf dist_sssdapiplugin_DATA = \ src/config/etc/sssd.api.d/sssd-ipa.conf \ src/config/etc/sssd.api.d/sssd-ad.conf \ src/config/etc/sssd.api.d/sssd-krb5.conf \ src/config/etc/sssd.api.d/sssd-ldap.conf \ src/config/etc/sssd.api.d/sssd-local.conf \ src/config/etc/sssd.api.d/sssd-proxy.conf \ src/config/etc/sssd.api.d/sssd-simple.conf edit_cmd = $(SED) \ -e 's|@sbindir[@]|$(sbindir)|g' \ -e 's|@environment_file[@]|$(environment_file)|g' \ -e 's|@localstatedir[@]|$(localstatedir)|g' \ -e 's|@prefix[@]|$(prefix)|g' replace_script = \ @rm -f $@ $@.tmp; \ srcdir=''; \ test -f ./$@.in || srcdir=$(srcdir)/; \ $(edit_cmd) $${srcdir}$@.in >$@.tmp; \ mv $@.tmp $@ SSSD_USER_DIRS = \ $(DESTDIR)$(dbpath) \ $(DESTDIR)$(keytabdir) \ $(DESTDIR)$(mcpath) \ $(DESTDIR)$(pipepath) \ $(DESTDIR)$(pipepath)/private \ $(DESTDIR)$(pubconfpath) \ $(DESTDIR)$(pubconfpath)/krb5.include.d \ $(DESTDIR)$(gpocachepath) \ $(DESTDIR)$(sssdconfdir) \ $(DESTDIR)$(logpath) \ $(NULL) @BUILD_PYTHON_BINDINGS_TRUE@SSSDCONFIG_MODULES = \ @BUILD_PYTHON_BINDINGS_TRUE@ $(abs_builddir)/src/config/SSSDConfig/ipachangeconf.py \ @BUILD_PYTHON_BINDINGS_TRUE@ $(abs_builddir)/src/config/SSSDConfig/sssd_upgrade_config.py @BUILD_PYTHON_BINDINGS_FALSE@SSSSCONFIG_MODULES = CLEANFILES = *.X */*.X */*/*.X all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .xml _generated.h _generated.c .c .lo .log .o .obj .sh .sh$(EXEEXT) .trs am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 contrib/sssd.spec: $(top_builddir)/config.status $(top_srcdir)/contrib/sssd.spec.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/examples/rwtab: $(top_builddir)/config.status $(top_srcdir)/src/examples/rwtab.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/doxy.config: $(top_builddir)/config.status $(top_srcdir)/src/doxy.config.in cd $(top_builddir) && $(SHELL) ./config.status $@ contrib/sssd-pcsc.rules: $(top_builddir)/config.status $(top_srcdir)/contrib/sssd-pcsc.rules.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/sysv/sssd: $(top_builddir)/config.status $(top_srcdir)/src/sysv/sssd.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/sysv/gentoo/sssd: $(top_builddir)/config.status $(top_srcdir)/src/sysv/gentoo/sssd.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/sysv/SUSE/sssd: $(top_builddir)/config.status $(top_srcdir)/src/sysv/SUSE/sssd.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/providers/ipa/ipa_hbac.pc: $(top_builddir)/config.status $(top_srcdir)/src/providers/ipa/ipa_hbac.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/providers/ipa/ipa_hbac.doxy: $(top_builddir)/config.status $(top_srcdir)/src/providers/ipa/ipa_hbac.doxy.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/lib/idmap/sss_idmap.pc: $(top_builddir)/config.status $(top_srcdir)/src/lib/idmap/sss_idmap.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/lib/idmap/sss_idmap.doxy: $(top_builddir)/config.status $(top_srcdir)/src/lib/idmap/sss_idmap.doxy.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/sss_client/sudo/sss_sudo.doxy: $(top_builddir)/config.status $(top_srcdir)/src/sss_client/sudo/sss_sudo.doxy.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/sss_client/idmap/sss_nss_idmap.pc: $(top_builddir)/config.status $(top_srcdir)/src/sss_client/idmap/sss_nss_idmap.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/sss_client/idmap/sss_nss_idmap.doxy: $(top_builddir)/config.status $(top_srcdir)/src/sss_client/idmap/sss_nss_idmap.doxy.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/sss_client/libwbclient/wbclient_sssd.pc: $(top_builddir)/config.status $(top_srcdir)/src/sss_client/libwbclient/wbclient_sssd.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/lib/sifp/sss_simpleifp.pc: $(top_builddir)/config.status $(top_srcdir)/src/lib/sifp/sss_simpleifp.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/lib/sifp/sss_simpleifp.doxy: $(top_builddir)/config.status $(top_srcdir)/src/lib/sifp/sss_simpleifp.doxy.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/config/setup.py: $(top_builddir)/config.status $(top_srcdir)/src/config/setup.py.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/responder/ifp/org.freedesktop.sssd.infopipe.service: $(top_builddir)/config.status $(top_srcdir)/src/responder/ifp/org.freedesktop.sssd.infopipe.service.in cd $(top_builddir) && $(SHELL) ./config.status $@ src/config/SSSDConfig/__init__.py: $(top_builddir)/config.status $(top_srcdir)/src/config/SSSDConfig/__init__.py.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-autofslibLTLIBRARIES: $(autofslib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(autofslib_LTLIBRARIES)'; test -n "$(autofslibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(autofslibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(autofslibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(autofslibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(autofslibdir)"; \ } uninstall-autofslibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(autofslib_LTLIBRARIES)'; test -n "$(autofslibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(autofslibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(autofslibdir)/$$f"; \ done clean-autofslibLTLIBRARIES: -test -z "$(autofslib_LTLIBRARIES)" || rm -f $(autofslib_LTLIBRARIES) @list='$(autofslib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } clean-checkLTLIBRARIES: -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) @list='$(check_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-cifspluginLTLIBRARIES: $(cifsplugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(cifsplugin_LTLIBRARIES)'; test -n "$(cifsplugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(cifsplugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(cifsplugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(cifsplugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(cifsplugindir)"; \ } uninstall-cifspluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(cifsplugin_LTLIBRARIES)'; test -n "$(cifsplugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(cifsplugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(cifsplugindir)/$$f"; \ done clean-cifspluginLTLIBRARIES: -test -z "$(cifsplugin_LTLIBRARIES)" || rm -f $(cifsplugin_LTLIBRARIES) @list='$(cifsplugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-krb5authdata_pluginLTLIBRARIES: $(krb5authdata_plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(krb5authdata_plugin_LTLIBRARIES)'; test -n "$(krb5authdata_plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(krb5authdata_plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(krb5authdata_plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(krb5authdata_plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(krb5authdata_plugindir)"; \ } uninstall-krb5authdata_pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(krb5authdata_plugin_LTLIBRARIES)'; test -n "$(krb5authdata_plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(krb5authdata_plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(krb5authdata_plugindir)/$$f"; \ done clean-krb5authdata_pluginLTLIBRARIES: -test -z "$(krb5authdata_plugin_LTLIBRARIES)" || rm -f $(krb5authdata_plugin_LTLIBRARIES) @list='$(krb5authdata_plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-krb5localauth_pluginLTLIBRARIES: $(krb5localauth_plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(krb5localauth_plugin_LTLIBRARIES)'; test -n "$(krb5localauth_plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(krb5localauth_plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(krb5localauth_plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(krb5localauth_plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(krb5localauth_plugindir)"; \ } uninstall-krb5localauth_pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(krb5localauth_plugin_LTLIBRARIES)'; test -n "$(krb5localauth_plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(krb5localauth_plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(krb5localauth_plugindir)/$$f"; \ done clean-krb5localauth_pluginLTLIBRARIES: -test -z "$(krb5localauth_plugin_LTLIBRARIES)" || rm -f $(krb5localauth_plugin_LTLIBRARIES) @list='$(krb5localauth_plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-krb5pluginLTLIBRARIES: $(krb5plugin_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(krb5plugin_LTLIBRARIES)'; test -n "$(krb5plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(krb5plugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(krb5plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(krb5plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(krb5plugindir)"; \ } uninstall-krb5pluginLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(krb5plugin_LTLIBRARIES)'; test -n "$(krb5plugindir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(krb5plugindir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(krb5plugindir)/$$f"; \ done clean-krb5pluginLTLIBRARIES: -test -z "$(krb5plugin_LTLIBRARIES)" || rm -f $(krb5plugin_LTLIBRARIES) @list='$(krb5plugin_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-ldblibLTLIBRARIES: $(ldblib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(ldblib_LTLIBRARIES)'; test -n "$(ldblibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(ldblibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(ldblibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(ldblibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ldblibdir)"; \ } uninstall-ldblibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(ldblib_LTLIBRARIES)'; test -n "$(ldblibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ldblibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ldblibdir)/$$f"; \ done clean-ldblibLTLIBRARIES: -test -z "$(ldblib_LTLIBRARIES)" || rm -f $(ldblib_LTLIBRARIES) @list='$(ldblib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-libwbclientLTLIBRARIES: $(libwbclient_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(libwbclient_LTLIBRARIES)'; test -n "$(libwbclientdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libwbclientdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libwbclientdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libwbclientdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libwbclientdir)"; \ } uninstall-libwbclientLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(libwbclient_LTLIBRARIES)'; test -n "$(libwbclientdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libwbclientdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libwbclientdir)/$$f"; \ done clean-libwbclientLTLIBRARIES: -test -z "$(libwbclient_LTLIBRARIES)" || rm -f $(libwbclient_LTLIBRARIES) @list='$(libwbclient_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-nfslibLTLIBRARIES: $(nfslib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(nfslib_LTLIBRARIES)'; test -n "$(nfslibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(nfslibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(nfslibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(nfslibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(nfslibdir)"; \ } uninstall-nfslibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(nfslib_LTLIBRARIES)'; test -n "$(nfslibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(nfslibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(nfslibdir)/$$f"; \ done clean-nfslibLTLIBRARIES: -test -z "$(nfslib_LTLIBRARIES)" || rm -f $(nfslib_LTLIBRARIES) @list='$(nfslib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-nsslibLTLIBRARIES: $(nsslib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(nsslib_LTLIBRARIES)'; test -n "$(nsslibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(nsslibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(nsslibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(nsslibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(nsslibdir)"; \ } uninstall-nsslibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(nsslib_LTLIBRARIES)'; test -n "$(nsslibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(nsslibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(nsslibdir)/$$f"; \ done clean-nsslibLTLIBRARIES: -test -z "$(nsslib_LTLIBRARIES)" || rm -f $(nsslib_LTLIBRARIES) @list='$(nsslib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-pamlibLTLIBRARIES: $(pamlib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pamlib_LTLIBRARIES)'; test -n "$(pamlibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pamlibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pamlibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pamlibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pamlibdir)"; \ } uninstall-pamlibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pamlib_LTLIBRARIES)'; test -n "$(pamlibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pamlibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pamlibdir)/$$f"; \ done clean-pamlibLTLIBRARIES: -test -z "$(pamlib_LTLIBRARIES)" || rm -f $(pamlib_LTLIBRARIES) @list='$(pamlib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-pkglibLTLIBRARIES: $(pkglib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(pkglibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkglibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkglibdir)"; \ } uninstall-pkglibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(pkglib_LTLIBRARIES)'; test -n "$(pkglibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \ done clean-pkglibLTLIBRARIES: -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-py2execLTLIBRARIES: $(py2exec_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(py2exec_LTLIBRARIES)'; test -n "$(py2execdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(py2execdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(py2execdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(py2execdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(py2execdir)"; \ } uninstall-py2execLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(py2exec_LTLIBRARIES)'; test -n "$(py2execdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(py2execdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(py2execdir)/$$f"; \ done clean-py2execLTLIBRARIES: -test -z "$(py2exec_LTLIBRARIES)" || rm -f $(py2exec_LTLIBRARIES) @list='$(py2exec_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-py3execLTLIBRARIES: $(py3exec_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(py3exec_LTLIBRARIES)'; test -n "$(py3execdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(py3execdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(py3execdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(py3execdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(py3execdir)"; \ } uninstall-py3execLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(py3exec_LTLIBRARIES)'; test -n "$(py3execdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(py3execdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(py3execdir)/$$f"; \ done clean-py3execLTLIBRARIES: -test -z "$(py3exec_LTLIBRARIES)" || rm -f $(py3exec_LTLIBRARIES) @list='$(py3exec_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-sssdlibLTLIBRARIES: $(sssdlib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(sssdlib_LTLIBRARIES)'; test -n "$(sssdlibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(sssdlibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sssdlibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(sssdlibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(sssdlibdir)"; \ } uninstall-sssdlibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(sssdlib_LTLIBRARIES)'; test -n "$(sssdlibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(sssdlibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(sssdlibdir)/$$f"; \ done clean-sssdlibLTLIBRARIES: -test -z "$(sssdlib_LTLIBRARIES)" || rm -f $(sssdlib_LTLIBRARIES) @list='$(sssdlib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } install-sudolibLTLIBRARIES: $(sudolib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(sudolib_LTLIBRARIES)'; test -n "$(sudolibdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(sudolibdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sudolibdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(sudolibdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(sudolibdir)"; \ } uninstall-sudolibLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(sudolib_LTLIBRARIES)'; test -n "$(sudolibdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(sudolibdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(sudolibdir)/$$f"; \ done clean-sudolibLTLIBRARIES: -test -z "$(sudolib_LTLIBRARIES)" || rm -f $(sudolib_LTLIBRARIES) @list='$(sudolib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } src/python/$(am__dirstamp): @$(MKDIR_P) src/python @: > src/python/$(am__dirstamp) src/python/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/python/$(DEPDIR) @: > src/python/$(DEPDIR)/$(am__dirstamp) src/python/_py2hbac_la-pyhbac.lo: src/python/$(am__dirstamp) \ src/python/$(DEPDIR)/$(am__dirstamp) src/util/$(am__dirstamp): @$(MKDIR_P) src/util @: > src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/util/$(DEPDIR) @: > src/util/$(DEPDIR)/$(am__dirstamp) src/util/_py2hbac_la-sss_python.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) _py2hbac.la: $(_py2hbac_la_OBJECTS) $(_py2hbac_la_DEPENDENCIES) $(EXTRA__py2hbac_la_DEPENDENCIES) $(AM_V_CCLD)$(_py2hbac_la_LINK) $(am__py2hbac_la_rpath) $(_py2hbac_la_OBJECTS) $(_py2hbac_la_LIBADD) $(LIBS) src/tools/$(am__dirstamp): @$(MKDIR_P) src/tools @: > src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/tools/$(DEPDIR) @: > src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/_py2sss_la-sss_sync_ops.lo: src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/_py2sss_la-tools_util.lo: src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/_py2sss_la-files.lo: src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/_py2sss_la-selinux.lo: src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/common/$(am__dirstamp): @$(MKDIR_P) src/tools/common @: > src/tools/common/$(am__dirstamp) src/tools/common/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/tools/common/$(DEPDIR) @: > src/tools/common/$(DEPDIR)/$(am__dirstamp) src/tools/common/_py2sss_la-sss_tools.lo: \ src/tools/common/$(am__dirstamp) \ src/tools/common/$(DEPDIR)/$(am__dirstamp) src/util/_py2sss_la-nscd.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/python/_py2sss_la-pysss.lo: src/python/$(am__dirstamp) \ src/python/$(DEPDIR)/$(am__dirstamp) _py2sss.la: $(_py2sss_la_OBJECTS) $(_py2sss_la_DEPENDENCIES) $(EXTRA__py2sss_la_DEPENDENCIES) $(AM_V_CCLD)$(_py2sss_la_LINK) $(am__py2sss_la_rpath) $(_py2sss_la_OBJECTS) $(_py2sss_la_LIBADD) $(LIBS) src/python/_py2sss_murmur_la-pysss_murmur.lo: \ src/python/$(am__dirstamp) \ src/python/$(DEPDIR)/$(am__dirstamp) src/util/_py2sss_murmur_la-murmurhash3.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) _py2sss_murmur.la: $(_py2sss_murmur_la_OBJECTS) $(_py2sss_murmur_la_DEPENDENCIES) $(EXTRA__py2sss_murmur_la_DEPENDENCIES) $(AM_V_CCLD)$(_py2sss_murmur_la_LINK) $(am__py2sss_murmur_la_rpath) $(_py2sss_murmur_la_OBJECTS) $(_py2sss_murmur_la_LIBADD) $(LIBS) src/python/_py2sss_nss_idmap_la-pysss_nss_idmap.lo: \ src/python/$(am__dirstamp) \ src/python/$(DEPDIR)/$(am__dirstamp) _py2sss_nss_idmap.la: $(_py2sss_nss_idmap_la_OBJECTS) $(_py2sss_nss_idmap_la_DEPENDENCIES) $(EXTRA__py2sss_nss_idmap_la_DEPENDENCIES) $(AM_V_CCLD)$(_py2sss_nss_idmap_la_LINK) $(am__py2sss_nss_idmap_la_rpath) $(_py2sss_nss_idmap_la_OBJECTS) $(_py2sss_nss_idmap_la_LIBADD) $(LIBS) src/python/_py3hbac_la-pyhbac.lo: src/python/$(am__dirstamp) \ src/python/$(DEPDIR)/$(am__dirstamp) src/util/_py3hbac_la-sss_python.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) _py3hbac.la: $(_py3hbac_la_OBJECTS) $(_py3hbac_la_DEPENDENCIES) $(EXTRA__py3hbac_la_DEPENDENCIES) $(AM_V_CCLD)$(_py3hbac_la_LINK) $(am__py3hbac_la_rpath) $(_py3hbac_la_OBJECTS) $(_py3hbac_la_LIBADD) $(LIBS) src/tools/_py3sss_la-sss_sync_ops.lo: src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/_py3sss_la-tools_util.lo: src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/_py3sss_la-files.lo: src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/_py3sss_la-selinux.lo: src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/common/_py3sss_la-sss_tools.lo: \ src/tools/common/$(am__dirstamp) \ src/tools/common/$(DEPDIR)/$(am__dirstamp) src/util/_py3sss_la-nscd.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/python/_py3sss_la-pysss.lo: src/python/$(am__dirstamp) \ src/python/$(DEPDIR)/$(am__dirstamp) _py3sss.la: $(_py3sss_la_OBJECTS) $(_py3sss_la_DEPENDENCIES) $(EXTRA__py3sss_la_DEPENDENCIES) $(AM_V_CCLD)$(_py3sss_la_LINK) $(am__py3sss_la_rpath) $(_py3sss_la_OBJECTS) $(_py3sss_la_LIBADD) $(LIBS) src/python/_py3sss_murmur_la-pysss_murmur.lo: \ src/python/$(am__dirstamp) \ src/python/$(DEPDIR)/$(am__dirstamp) src/util/_py3sss_murmur_la-murmurhash3.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) _py3sss_murmur.la: $(_py3sss_murmur_la_OBJECTS) $(_py3sss_murmur_la_DEPENDENCIES) $(EXTRA__py3sss_murmur_la_DEPENDENCIES) $(AM_V_CCLD)$(_py3sss_murmur_la_LINK) $(am__py3sss_murmur_la_rpath) $(_py3sss_murmur_la_OBJECTS) $(_py3sss_murmur_la_LIBADD) $(LIBS) src/python/_py3sss_nss_idmap_la-pysss_nss_idmap.lo: \ src/python/$(am__dirstamp) \ src/python/$(DEPDIR)/$(am__dirstamp) _py3sss_nss_idmap.la: $(_py3sss_nss_idmap_la_OBJECTS) $(_py3sss_nss_idmap_la_DEPENDENCIES) $(EXTRA__py3sss_nss_idmap_la_DEPENDENCIES) $(AM_V_CCLD)$(_py3sss_nss_idmap_la_LINK) $(am__py3sss_nss_idmap_la_rpath) $(_py3sss_nss_idmap_la_OBJECTS) $(_py3sss_nss_idmap_la_LIBADD) $(LIBS) src/lib/cifs_idmap_sss/$(am__dirstamp): @$(MKDIR_P) src/lib/cifs_idmap_sss @: > src/lib/cifs_idmap_sss/$(am__dirstamp) src/lib/cifs_idmap_sss/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/lib/cifs_idmap_sss/$(DEPDIR) @: > src/lib/cifs_idmap_sss/$(DEPDIR)/$(am__dirstamp) src/lib/cifs_idmap_sss/cifs_idmap_sss_la-cifs_idmap_sss.lo: \ src/lib/cifs_idmap_sss/$(am__dirstamp) \ src/lib/cifs_idmap_sss/$(DEPDIR)/$(am__dirstamp) cifs_idmap_sss.la: $(cifs_idmap_sss_la_OBJECTS) $(cifs_idmap_sss_la_DEPENDENCIES) $(EXTRA_cifs_idmap_sss_la_DEPENDENCIES) $(AM_V_CCLD)$(cifs_idmap_sss_la_LINK) $(am_cifs_idmap_sss_la_rpath) $(cifs_idmap_sss_la_OBJECTS) $(cifs_idmap_sss_la_LIBADD) $(LIBS) src/providers/$(am__dirstamp): @$(MKDIR_P) src/providers @: > src/providers/$(am__dirstamp) src/providers/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/providers/$(DEPDIR) @: > src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libdlopen_test_providers_la-data_provider_be.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libdlopen_test_providers_la-data_provider_req.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libdlopen_test_providers_la-data_provider_fo.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libdlopen_test_providers_la-data_provider_opts.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libdlopen_test_providers_la-data_provider_callbacks.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libdlopen_test_providers_la-dp_dyndns.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libdlopen_test_providers_la-dp_ptask.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libdlopen_test_providers_la-dp_refresh.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/monitor/$(am__dirstamp): @$(MKDIR_P) src/monitor @: > src/monitor/$(am__dirstamp) src/monitor/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/monitor/$(DEPDIR) @: > src/monitor/$(DEPDIR)/$(am__dirstamp) src/monitor/libdlopen_test_providers_la-monitor_iface_generated.lo: \ src/monitor/$(am__dirstamp) \ src/monitor/$(DEPDIR)/$(am__dirstamp) src/providers/libdlopen_test_providers_la-data_provider_iface_generated.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libdlopen_test_providers_la-fail_over.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libdlopen_test_providers_la-fail_over_srv.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/resolv/$(am__dirstamp): @$(MKDIR_P) src/resolv @: > src/resolv/$(am__dirstamp) src/resolv/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/resolv/$(DEPDIR) @: > src/resolv/$(DEPDIR)/$(am__dirstamp) src/resolv/libdlopen_test_providers_la-async_resolv.lo: \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) src/resolv/libdlopen_test_providers_la-async_resolv_utils.lo: \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) libdlopen_test_providers.la: $(libdlopen_test_providers_la_OBJECTS) $(libdlopen_test_providers_la_DEPENDENCIES) $(EXTRA_libdlopen_test_providers_la_DEPENDENCIES) $(AM_V_CCLD)$(libdlopen_test_providers_la_LINK) $(am_libdlopen_test_providers_la_rpath) $(libdlopen_test_providers_la_OBJECTS) $(libdlopen_test_providers_la_LIBADD) $(LIBS) src/providers/ipa/$(am__dirstamp): @$(MKDIR_P) src/providers/ipa @: > src/providers/ipa/$(am__dirstamp) src/providers/ipa/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/providers/ipa/$(DEPDIR) @: > src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/hbac_evaluator.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/util/sss_utf8.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) libipa_hbac.la: $(libipa_hbac_la_OBJECTS) $(libipa_hbac_la_DEPENDENCIES) $(EXTRA_libipa_hbac_la_DEPENDENCIES) $(AM_V_CCLD)$(libipa_hbac_la_LINK) -rpath $(libdir) $(libipa_hbac_la_OBJECTS) $(libipa_hbac_la_LIBADD) $(LIBS) src/sss_client/$(am__dirstamp): @$(MKDIR_P) src/sss_client @: > src/sss_client/$(am__dirstamp) src/sss_client/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/sss_client/$(DEPDIR) @: > src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/common.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/nss_passwd.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/nss_group.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/nss_netgroup.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/nss_services.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/nss_mc_common.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/util/io.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/murmurhash3.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/sss_client/nss_mc_passwd.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/nss_mc_group.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/nss_mc_initgr.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) libnss_sss.la: $(libnss_sss_la_OBJECTS) $(libnss_sss_la_DEPENDENCIES) $(EXTRA_libnss_sss_la_DEPENDENCIES) $(AM_V_CCLD)$(libnss_sss_la_LINK) -rpath $(nsslibdir) $(libnss_sss_la_OBJECTS) $(libnss_sss_la_LIBADD) $(LIBS) src/providers/ad/$(am__dirstamp): @$(MKDIR_P) src/providers/ad @: > src/providers/ad/$(am__dirstamp) src/providers/ad/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/providers/ad/$(DEPDIR) @: > src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_opts.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_common.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_init.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_dyndns.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_machine_pw_renewal.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_id.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_access.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_gpo.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_gpo_ndr.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_srv.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_subdomains.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_domain_info.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_sudo.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_la-ad_autofs.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) libsss_ad.la: $(libsss_ad_la_OBJECTS) $(libsss_ad_la_DEPENDENCIES) $(EXTRA_libsss_ad_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_ad_la_LINK) $(am_libsss_ad_la_rpath) $(libsss_ad_la_OBJECTS) $(libsss_ad_la_LIBADD) $(LIBS) src/providers/ad/libsss_ad_tests_la-ad_opts.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_common.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_init.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_dyndns.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_machine_pw_renewal.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_id.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_access.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_gpo.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_gpo_ndr.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_srv.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_subdomains.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_domain_info.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_sudo.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ad_tests_la-ad_autofs.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) libsss_ad_tests.la: $(libsss_ad_tests_la_OBJECTS) $(libsss_ad_tests_la_DEPENDENCIES) $(EXTRA_libsss_ad_tests_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_ad_tests_la_LINK) $(am_libsss_ad_tests_la_rpath) $(libsss_ad_tests_la_OBJECTS) $(libsss_ad_tests_la_LIBADD) $(LIBS) src/sss_client/autofs/$(am__dirstamp): @$(MKDIR_P) src/sss_client/autofs @: > src/sss_client/autofs/$(am__dirstamp) src/sss_client/autofs/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/sss_client/autofs/$(DEPDIR) @: > src/sss_client/autofs/$(DEPDIR)/$(am__dirstamp) src/sss_client/autofs/sss_autofs.lo: \ src/sss_client/autofs/$(am__dirstamp) \ src/sss_client/autofs/$(DEPDIR)/$(am__dirstamp) libsss_autofs.la: $(libsss_autofs_la_OBJECTS) $(libsss_autofs_la_DEPENDENCIES) $(EXTRA_libsss_autofs_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_autofs_la_LINK) $(am_libsss_autofs_la_rpath) $(libsss_autofs_la_OBJECTS) $(libsss_autofs_la_LIBADD) $(LIBS) src/util/cert/$(am__dirstamp): @$(MKDIR_P) src/util/cert @: > src/util/cert/$(am__dirstamp) src/util/cert/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/util/cert/$(DEPDIR) @: > src/util/cert/$(DEPDIR)/$(am__dirstamp) src/util/cert/libsss_cert_la-cert_common.lo: \ src/util/cert/$(am__dirstamp) \ src/util/cert/$(DEPDIR)/$(am__dirstamp) src/util/cert/libcrypto/$(am__dirstamp): @$(MKDIR_P) src/util/cert/libcrypto @: > src/util/cert/libcrypto/$(am__dirstamp) src/util/cert/libcrypto/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/util/cert/libcrypto/$(DEPDIR) @: > src/util/cert/libcrypto/$(DEPDIR)/$(am__dirstamp) src/util/cert/libcrypto/libsss_cert_la-cert.lo: \ src/util/cert/libcrypto/$(am__dirstamp) \ src/util/cert/libcrypto/$(DEPDIR)/$(am__dirstamp) src/util/cert/nss/$(am__dirstamp): @$(MKDIR_P) src/util/cert/nss @: > src/util/cert/nss/$(am__dirstamp) src/util/cert/nss/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/util/cert/nss/$(DEPDIR) @: > src/util/cert/nss/$(DEPDIR)/$(am__dirstamp) src/util/cert/nss/libsss_cert_la-cert.lo: \ src/util/cert/nss/$(am__dirstamp) \ src/util/cert/nss/$(DEPDIR)/$(am__dirstamp) libsss_cert.la: $(libsss_cert_la_OBJECTS) $(libsss_cert_la_DEPENDENCIES) $(EXTRA_libsss_cert_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_cert_la_LINK) -rpath $(pkglibdir) $(libsss_cert_la_OBJECTS) $(libsss_cert_la_LIBADD) $(LIBS) src/util/child_common.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) libsss_child.la: $(libsss_child_la_OBJECTS) $(libsss_child_la_DEPENDENCIES) $(EXTRA_libsss_child_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_child_la_LINK) -rpath $(pkglibdir) $(libsss_child_la_OBJECTS) $(libsss_child_la_LIBADD) $(LIBS) src/util/libsss_config_la-sss_config.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) libsss_config.la: $(libsss_config_la_OBJECTS) $(libsss_config_la_DEPENDENCIES) $(EXTRA_libsss_config_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_config_la_LINK) $(am_libsss_config_la_rpath) $(libsss_config_la_OBJECTS) $(libsss_config_la_LIBADD) $(LIBS) src/util/crypto/libcrypto/$(am__dirstamp): @$(MKDIR_P) src/util/crypto/libcrypto @: > src/util/crypto/libcrypto/$(am__dirstamp) src/util/crypto/libcrypto/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/util/crypto/libcrypto/$(DEPDIR) @: > src/util/crypto/libcrypto/$(DEPDIR)/$(am__dirstamp) src/util/crypto/libcrypto/libsss_crypt_la-crypto_base64.lo: \ src/util/crypto/libcrypto/$(am__dirstamp) \ src/util/crypto/libcrypto/$(DEPDIR)/$(am__dirstamp) src/util/crypto/libcrypto/libsss_crypt_la-crypto_hmac_sha1.lo: \ src/util/crypto/libcrypto/$(am__dirstamp) \ src/util/crypto/libcrypto/$(DEPDIR)/$(am__dirstamp) src/util/crypto/libcrypto/libsss_crypt_la-crypto_sha512crypt.lo: \ src/util/crypto/libcrypto/$(am__dirstamp) \ src/util/crypto/libcrypto/$(DEPDIR)/$(am__dirstamp) src/util/crypto/libcrypto/libsss_crypt_la-crypto_obfuscate.lo: \ src/util/crypto/libcrypto/$(am__dirstamp) \ src/util/crypto/libcrypto/$(DEPDIR)/$(am__dirstamp) src/util/crypto/nss/$(am__dirstamp): @$(MKDIR_P) src/util/crypto/nss @: > src/util/crypto/nss/$(am__dirstamp) src/util/crypto/nss/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/util/crypto/nss/$(DEPDIR) @: > src/util/crypto/nss/$(DEPDIR)/$(am__dirstamp) src/util/crypto/nss/libsss_crypt_la-nss_base64.lo: \ src/util/crypto/nss/$(am__dirstamp) \ src/util/crypto/nss/$(DEPDIR)/$(am__dirstamp) src/util/crypto/nss/libsss_crypt_la-nss_hmac_sha1.lo: \ src/util/crypto/nss/$(am__dirstamp) \ src/util/crypto/nss/$(DEPDIR)/$(am__dirstamp) src/util/crypto/nss/libsss_crypt_la-nss_sha512crypt.lo: \ src/util/crypto/nss/$(am__dirstamp) \ src/util/crypto/nss/$(DEPDIR)/$(am__dirstamp) src/util/crypto/nss/libsss_crypt_la-nss_obfuscate.lo: \ src/util/crypto/nss/$(am__dirstamp) \ src/util/crypto/nss/$(DEPDIR)/$(am__dirstamp) src/util/crypto/nss/libsss_crypt_la-nss_util.lo: \ src/util/crypto/nss/$(am__dirstamp) \ src/util/crypto/nss/$(DEPDIR)/$(am__dirstamp) libsss_crypt.la: $(libsss_crypt_la_OBJECTS) $(libsss_crypt_la_DEPENDENCIES) $(EXTRA_libsss_crypt_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_crypt_la_LINK) -rpath $(pkglibdir) $(libsss_crypt_la_OBJECTS) $(libsss_crypt_la_LIBADD) $(LIBS) src/util/debug.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/sss_log.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/sss_cli_cmd.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) libsss_debug.la: $(libsss_debug_la_OBJECTS) $(libsss_debug_la_DEPENDENCIES) $(EXTRA_libsss_debug_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_debug_la_LINK) -rpath $(pkglibdir) $(libsss_debug_la_OBJECTS) $(libsss_debug_la_LIBADD) $(LIBS) src/lib/idmap/$(am__dirstamp): @$(MKDIR_P) src/lib/idmap @: > src/lib/idmap/$(am__dirstamp) src/lib/idmap/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/lib/idmap/$(DEPDIR) @: > src/lib/idmap/$(DEPDIR)/$(am__dirstamp) src/lib/idmap/sss_idmap.lo: src/lib/idmap/$(am__dirstamp) \ src/lib/idmap/$(DEPDIR)/$(am__dirstamp) src/lib/idmap/sss_idmap_conv.lo: src/lib/idmap/$(am__dirstamp) \ src/lib/idmap/$(DEPDIR)/$(am__dirstamp) libsss_idmap.la: $(libsss_idmap_la_OBJECTS) $(libsss_idmap_la_DEPENDENCIES) $(EXTRA_libsss_idmap_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_idmap_la_LINK) -rpath $(libdir) $(libsss_idmap_la_OBJECTS) $(libsss_idmap_la_LIBADD) $(LIBS) src/providers/ipa/libsss_ipa_la-ipa_init.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_opts.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_common.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_config.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_id.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_netgroups.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_auth.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_access.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_dyndns.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_hosts.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_subdomains.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_subdomains_id.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_subdomains_server.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_subdomains_utils.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_subdomains_ext_groups.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_views.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_utils.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_s2n_exop.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_hbac_hosts.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_hbac_rules.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_hbac_services.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_hbac_users.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_hbac_common.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_selinux.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_selinux_maps.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_srv.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_idmap.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_dn.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ipa_la-ad_opts.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ipa_la-ad_common.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ipa_la-ad_dyndns.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ipa_la-ad_id.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ipa_la-ad_srv.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ad/libsss_ipa_la-ad_domain_info.lo: \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_autofs.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_sudo.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_sudo_refresh.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_sudo_conversion.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_sudo_async.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ipa_la-ipa_hostid.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) libsss_ipa.la: $(libsss_ipa_la_OBJECTS) $(libsss_ipa_la_DEPENDENCIES) $(EXTRA_libsss_ipa_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_ipa_la_LINK) $(am_libsss_ipa_la_rpath) $(libsss_ipa_la_OBJECTS) $(libsss_ipa_la_LIBADD) $(LIBS) src/providers/krb5/$(am__dirstamp): @$(MKDIR_P) src/providers/krb5 @: > src/providers/krb5/$(am__dirstamp) src/providers/krb5/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/providers/krb5/$(DEPDIR) @: > src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/libsss_krb5_la-krb5_init.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) libsss_krb5.la: $(libsss_krb5_la_OBJECTS) $(libsss_krb5_la_DEPENDENCIES) $(EXTRA_libsss_krb5_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_krb5_la_LINK) -rpath $(sssdlibdir) $(libsss_krb5_la_OBJECTS) $(libsss_krb5_la_LIBADD) $(LIBS) src/providers/krb5/libsss_krb5_common_la-krb5_utils.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/libsss_krb5_common_la-krb5_delayed_online_authentication.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/libsss_krb5_common_la-krb5_renew_tgt.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/libsss_krb5_common_la-krb5_wait_queue.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/libsss_krb5_common_la-krb5_common.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/libsss_krb5_common_la-krb5_opts.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/libsss_krb5_common_la-krb5_auth.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/libsss_krb5_common_la-krb5_access.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/libsss_krb5_common_la-krb5_child_handler.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/libsss_krb5_common_la-krb5_init_shared.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/libsss_krb5_common_la-krb5_ccache.lo: \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/util/libsss_krb5_common_la-sss_krb5.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_krb5_common_la-become_user.lo: \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) libsss_krb5_common.la: $(libsss_krb5_common_la_OBJECTS) $(libsss_krb5_common_la_DEPENDENCIES) $(EXTRA_libsss_krb5_common_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_krb5_common_la_LINK) -rpath $(pkglibdir) $(libsss_krb5_common_la_OBJECTS) $(libsss_krb5_common_la_LIBADD) $(LIBS) src/providers/ldap/$(am__dirstamp): @$(MKDIR_P) src/providers/ldap @: > src/providers/ldap/$(am__dirstamp) src/providers/ldap/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/providers/ldap/$(DEPDIR) @: > src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_la-ldap_init.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_la-ldap_access.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) libsss_ldap.la: $(libsss_ldap_la_OBJECTS) $(libsss_ldap_la_DEPENDENCIES) $(EXTRA_libsss_ldap_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_ldap_la_LINK) -rpath $(sssdlibdir) $(libsss_ldap_la_OBJECTS) $(libsss_ldap_la_LIBADD) $(LIBS) src/providers/ldap/libsss_ldap_common_la-ldap_id.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-ldap_id_enum.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_enum.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-ldap_id_cleanup.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-ldap_id_netgroup.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-ldap_id_services.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-ldap_auth.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-ldap_common.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-ldap_options.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-ldap_opts.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_access.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_users.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_groups.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_nested_groups.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_groups_ad.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups_ad.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_connection.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_netgroups.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_services.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_ad_groups.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_child_helpers.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_fd_events.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_id_op.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_idmap.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_range.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_reinit.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_dyndns.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_refresh.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_utils.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_domain.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_ops.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/libsss_ldap_common_la-ipa_dn.lo: \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/util/libsss_ldap_common_la-user_info_msg.lo: \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_ldap_common_la-sss_ldap.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo_hostinfo.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_sudo_refresh.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_sudo_shared.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_sudo.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_autofs.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/libsss_ldap_common_la-sdap_async_autofs.lo: \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) libsss_ldap_common.la: $(libsss_ldap_common_la_OBJECTS) $(libsss_ldap_common_la_DEPENDENCIES) $(EXTRA_libsss_ldap_common_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_ldap_common_la_LINK) -rpath $(pkglibdir) $(libsss_ldap_common_la_OBJECTS) $(libsss_ldap_common_la_LIBADD) $(LIBS) src/sss_client/idmap/$(am__dirstamp): @$(MKDIR_P) src/sss_client/idmap @: > src/sss_client/idmap/$(am__dirstamp) src/sss_client/idmap/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/sss_client/idmap/$(DEPDIR) @: > src/sss_client/idmap/$(DEPDIR)/$(am__dirstamp) src/sss_client/idmap/sss_nss_idmap.lo: \ src/sss_client/idmap/$(am__dirstamp) \ src/sss_client/idmap/$(DEPDIR)/$(am__dirstamp) src/util/strtonum.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) libsss_nss_idmap.la: $(libsss_nss_idmap_la_OBJECTS) $(libsss_nss_idmap_la_DEPENDENCIES) $(EXTRA_libsss_nss_idmap_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_nss_idmap_la_LINK) -rpath $(libdir) $(libsss_nss_idmap_la_OBJECTS) $(libsss_nss_idmap_la_LIBADD) $(LIBS) libsss_nss_idmap_tests.la: $(libsss_nss_idmap_tests_la_OBJECTS) $(libsss_nss_idmap_tests_la_DEPENDENCIES) $(EXTRA_libsss_nss_idmap_tests_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_nss_idmap_tests_la_LINK) $(am_libsss_nss_idmap_tests_la_rpath) $(libsss_nss_idmap_tests_la_OBJECTS) $(libsss_nss_idmap_tests_la_LIBADD) $(LIBS) src/providers/proxy/$(am__dirstamp): @$(MKDIR_P) src/providers/proxy @: > src/providers/proxy/$(am__dirstamp) src/providers/proxy/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/providers/proxy/$(DEPDIR) @: > src/providers/proxy/$(DEPDIR)/$(am__dirstamp) src/providers/proxy/libsss_proxy_la-proxy_init.lo: \ src/providers/proxy/$(am__dirstamp) \ src/providers/proxy/$(DEPDIR)/$(am__dirstamp) src/providers/proxy/libsss_proxy_la-proxy_id.lo: \ src/providers/proxy/$(am__dirstamp) \ src/providers/proxy/$(DEPDIR)/$(am__dirstamp) src/providers/proxy/libsss_proxy_la-proxy_netgroup.lo: \ src/providers/proxy/$(am__dirstamp) \ src/providers/proxy/$(DEPDIR)/$(am__dirstamp) src/providers/proxy/libsss_proxy_la-proxy_services.lo: \ src/providers/proxy/$(am__dirstamp) \ src/providers/proxy/$(DEPDIR)/$(am__dirstamp) src/providers/proxy/libsss_proxy_la-proxy_auth.lo: \ src/providers/proxy/$(am__dirstamp) \ src/providers/proxy/$(DEPDIR)/$(am__dirstamp) src/providers/libsss_proxy_la-data_provider_iface_generated.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) libsss_proxy.la: $(libsss_proxy_la_OBJECTS) $(libsss_proxy_la_DEPENDENCIES) $(EXTRA_libsss_proxy_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_proxy_la_LINK) -rpath $(sssdlibdir) $(libsss_proxy_la_OBJECTS) $(libsss_proxy_la_LIBADD) $(LIBS) src/util/libsss_semanage_la-sss_semanage.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) libsss_semanage.la: $(libsss_semanage_la_OBJECTS) $(libsss_semanage_la_DEPENDENCIES) $(EXTRA_libsss_semanage_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_semanage_la_LINK) -rpath $(pkglibdir) $(libsss_semanage_la_OBJECTS) $(libsss_semanage_la_LIBADD) $(LIBS) src/providers/simple/$(am__dirstamp): @$(MKDIR_P) src/providers/simple @: > src/providers/simple/$(am__dirstamp) src/providers/simple/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/providers/simple/$(DEPDIR) @: > src/providers/simple/$(DEPDIR)/$(am__dirstamp) src/providers/simple/libsss_simple_la-simple_access_check.lo: \ src/providers/simple/$(am__dirstamp) \ src/providers/simple/$(DEPDIR)/$(am__dirstamp) src/providers/simple/libsss_simple_la-simple_access.lo: \ src/providers/simple/$(am__dirstamp) \ src/providers/simple/$(DEPDIR)/$(am__dirstamp) libsss_simple.la: $(libsss_simple_la_OBJECTS) $(libsss_simple_la_DEPENDENCIES) $(EXTRA_libsss_simple_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_simple_la_LINK) -rpath $(sssdlibdir) $(libsss_simple_la_OBJECTS) $(libsss_simple_la_LIBADD) $(LIBS) src/lib/sifp/$(am__dirstamp): @$(MKDIR_P) src/lib/sifp @: > src/lib/sifp/$(am__dirstamp) src/lib/sifp/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/lib/sifp/$(DEPDIR) @: > src/lib/sifp/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/libsss_simpleifp_la-sss_sifp.lo: \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/libsss_simpleifp_la-sss_sifp_dbus.lo: \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/libsss_simpleifp_la-sss_sifp_attrs.lo: \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/libsss_simpleifp_la-sss_sifp_common.lo: \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/libsss_simpleifp_la-sss_sifp_parser.lo: \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/libsss_simpleifp_la-sss_sifp_utils.lo: \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) libsss_simpleifp.la: $(libsss_simpleifp_la_OBJECTS) $(libsss_simpleifp_la_DEPENDENCIES) $(EXTRA_libsss_simpleifp_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_simpleifp_la_LINK) $(am_libsss_simpleifp_la_rpath) $(libsss_simpleifp_la_OBJECTS) $(libsss_simpleifp_la_LIBADD) $(LIBS) src/sss_client/sudo/$(am__dirstamp): @$(MKDIR_P) src/sss_client/sudo @: > src/sss_client/sudo/$(am__dirstamp) src/sss_client/sudo/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/sss_client/sudo/$(DEPDIR) @: > src/sss_client/sudo/$(DEPDIR)/$(am__dirstamp) src/sss_client/sudo/sss_sudo_response.lo: \ src/sss_client/sudo/$(am__dirstamp) \ src/sss_client/sudo/$(DEPDIR)/$(am__dirstamp) src/sss_client/sudo/sss_sudo.lo: src/sss_client/sudo/$(am__dirstamp) \ src/sss_client/sudo/$(DEPDIR)/$(am__dirstamp) libsss_sudo.la: $(libsss_sudo_la_OBJECTS) $(libsss_sudo_la_DEPENDENCIES) $(EXTRA_libsss_sudo_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_sudo_la_LINK) $(am_libsss_sudo_la_rpath) $(libsss_sudo_la_OBJECTS) $(libsss_sudo_la_LIBADD) $(LIBS) src/tests/$(am__dirstamp): @$(MKDIR_P) src/tests @: > src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/tests/$(DEPDIR) @: > src/tests/$(DEPDIR)/$(am__dirstamp) src/tests/common_tev.lo: src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) src/tests/common_dom.lo: src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) src/tests/leak_check.lo: src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) src/tests/common.lo: src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) src/tests/common_check.lo: src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) libsss_test_common.la: $(libsss_test_common_la_OBJECTS) $(libsss_test_common_la_DEPENDENCIES) $(EXTRA_libsss_test_common_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libsss_test_common_la_OBJECTS) $(libsss_test_common_la_LIBADD) $(LIBS) src/confdb/$(am__dirstamp): @$(MKDIR_P) src/confdb @: > src/confdb/$(am__dirstamp) src/confdb/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/confdb/$(DEPDIR) @: > src/confdb/$(DEPDIR)/$(am__dirstamp) src/confdb/libsss_util_la-confdb.lo: src/confdb/$(am__dirstamp) \ src/confdb/$(DEPDIR)/$(am__dirstamp) src/db/$(am__dirstamp): @$(MKDIR_P) src/db @: > src/db/$(am__dirstamp) src/db/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/db/$(DEPDIR) @: > src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_ops.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_search.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_selinux.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_upgrade.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_services.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_autofs.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_subdomains.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_views.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_ranges.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_idmap.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_gpo.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/monitor/libsss_util_la-monitor_sbus.lo: \ src/monitor/$(am__dirstamp) \ src/monitor/$(DEPDIR)/$(am__dirstamp) src/providers/libsss_util_la-dp_auth_util.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libsss_util_la-dp_pam_data_util.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/libsss_util_la-dp_sbus.lo: \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/sbus/$(am__dirstamp): @$(MKDIR_P) src/sbus @: > src/sbus/$(am__dirstamp) src/sbus/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/sbus/$(DEPDIR) @: > src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sbus_client.lo: src/sbus/$(am__dirstamp) \ src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sssd_dbus_common.lo: src/sbus/$(am__dirstamp) \ src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sssd_dbus_connection.lo: \ src/sbus/$(am__dirstamp) src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sssd_dbus_meta.lo: src/sbus/$(am__dirstamp) \ src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sssd_dbus_interface.lo: \ src/sbus/$(am__dirstamp) src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sssd_dbus_introspect.lo: \ src/sbus/$(am__dirstamp) src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sssd_dbus_invokers.lo: \ src/sbus/$(am__dirstamp) src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sssd_dbus_properties.lo: \ src/sbus/$(am__dirstamp) src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sssd_dbus_request.lo: \ src/sbus/$(am__dirstamp) src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sssd_dbus_server.lo: src/sbus/$(am__dirstamp) \ src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sssd_dbus_signals.lo: \ src/sbus/$(am__dirstamp) src/sbus/$(DEPDIR)/$(am__dirstamp) src/sbus/libsss_util_la-sssd_dbus_common_signals.lo: \ src/sbus/$(am__dirstamp) src/sbus/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-util.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-memory.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-safe-format-string.lo: \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-server.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-signal.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-usertools.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-backup_file.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-strtonum.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-check_and_open.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-refcount.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-sss_nss.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-sss_utf8.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-sss_tc_utf8.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-murmurhash3.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-atomic_io.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-authtok.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-authtok-utils.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-sss_selinux.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-domain_info_utils.lo: \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-util_lock.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-util_errors.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-find_uid.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-sss_ini.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-io.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-util_sss_idmap.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-well_known_sids.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-string_utils.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-become_user.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_sudo.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/db/libsss_util_la-sysdb_ssh.lo: src/db/$(am__dirstamp) \ src/db/$(DEPDIR)/$(am__dirstamp) src/util/libsss_util_la-sss_ssh.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) libsss_util.la: $(libsss_util_la_OBJECTS) $(libsss_util_la_DEPENDENCIES) $(EXTRA_libsss_util_la_DEPENDENCIES) $(AM_V_CCLD)$(libsss_util_la_LINK) -rpath $(pkglibdir) $(libsss_util_la_OBJECTS) $(libsss_util_la_LIBADD) $(LIBS) src/sss_client/libwbclient/$(am__dirstamp): @$(MKDIR_P) src/sss_client/libwbclient @: > src/sss_client/libwbclient/$(am__dirstamp) src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/sss_client/libwbclient/$(DEPDIR) @: > src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbc_guid.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbc_idmap_common.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbc_idmap_sssd.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbclient_common.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbclient_sssd.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbc_pam_sssd.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbc_pwd_sssd.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbc_sid_common.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbc_sid_sssd.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbc_util_common.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbc_util_sssd.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) src/sss_client/libwbclient/wbc_ctx_sssd.lo: \ src/sss_client/libwbclient/$(am__dirstamp) \ src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) libwbclient.la: $(libwbclient_la_OBJECTS) $(libwbclient_la_DEPENDENCIES) $(EXTRA_libwbclient_la_DEPENDENCIES) $(AM_V_CCLD)$(libwbclient_la_LINK) $(am_libwbclient_la_rpath) $(libwbclient_la_OBJECTS) $(libwbclient_la_LIBADD) $(LIBS) src/ldb_modules/$(am__dirstamp): @$(MKDIR_P) src/ldb_modules @: > src/ldb_modules/$(am__dirstamp) src/ldb_modules/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/ldb_modules/$(DEPDIR) @: > src/ldb_modules/$(DEPDIR)/$(am__dirstamp) src/ldb_modules/memberof_la-memberof.lo: \ src/ldb_modules/$(am__dirstamp) \ src/ldb_modules/$(DEPDIR)/$(am__dirstamp) src/util/memberof_la-util.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) memberof.la: $(memberof_la_OBJECTS) $(memberof_la_DEPENDENCIES) $(EXTRA_memberof_la_DEPENDENCIES) $(AM_V_CCLD)$(memberof_la_LINK) -rpath $(ldblibdir) $(memberof_la_OBJECTS) $(memberof_la_LIBADD) $(LIBS) src/sss_client/pam_sss.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/pam_message.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/util/atomic_io.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/authtok-utils.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) pam_sss.la: $(pam_sss_la_OBJECTS) $(pam_sss_la_DEPENDENCIES) $(EXTRA_pam_sss_la_DEPENDENCIES) $(AM_V_CCLD)$(pam_sss_la_LINK) -rpath $(pamlibdir) $(pam_sss_la_OBJECTS) $(pam_sss_la_LIBADD) $(LIBS) src/sss_client/sss_la-common.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/sss_la-nss_mc_common.lo: \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/util/sss_la-io.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/sss_la-murmurhash3.lo: src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/sss_client/sss_la-nss_mc_passwd.lo: \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/sss_la-nss_mc_group.lo: src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/nfs/$(am__dirstamp): @$(MKDIR_P) src/sss_client/nfs @: > src/sss_client/nfs/$(am__dirstamp) src/sss_client/nfs/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/sss_client/nfs/$(DEPDIR) @: > src/sss_client/nfs/$(DEPDIR)/$(am__dirstamp) src/sss_client/nfs/sss_la-sss_nfs_client.lo: \ src/sss_client/nfs/$(am__dirstamp) \ src/sss_client/nfs/$(DEPDIR)/$(am__dirstamp) sss.la: $(sss_la_OBJECTS) $(sss_la_DEPENDENCIES) $(EXTRA_sss_la_DEPENDENCIES) $(AM_V_CCLD)$(sss_la_LINK) $(am_sss_la_rpath) $(sss_la_OBJECTS) $(sss_la_LIBADD) $(LIBS) src/krb5_plugin/$(am__dirstamp): @$(MKDIR_P) src/krb5_plugin @: > src/krb5_plugin/$(am__dirstamp) src/krb5_plugin/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/krb5_plugin/$(DEPDIR) @: > src/krb5_plugin/$(DEPDIR)/$(am__dirstamp) src/krb5_plugin/sssd_krb5_localauth_plugin_la-sssd_krb5_localauth_plugin.lo: \ src/krb5_plugin/$(am__dirstamp) \ src/krb5_plugin/$(DEPDIR)/$(am__dirstamp) src/util/sssd_krb5_localauth_plugin_la-murmurhash3.lo: \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/util/sssd_krb5_localauth_plugin_la-io.lo: \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/sss_client/sssd_krb5_localauth_plugin_la-common.lo: \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_common.lo: \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_passwd.lo: \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/sssd_krb5_localauth_plugin_la-nss_passwd.lo: \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) sssd_krb5_localauth_plugin.la: $(sssd_krb5_localauth_plugin_la_OBJECTS) $(sssd_krb5_localauth_plugin_la_DEPENDENCIES) $(EXTRA_sssd_krb5_localauth_plugin_la_DEPENDENCIES) $(AM_V_CCLD)$(sssd_krb5_localauth_plugin_la_LINK) $(am_sssd_krb5_localauth_plugin_la_rpath) $(sssd_krb5_localauth_plugin_la_OBJECTS) $(sssd_krb5_localauth_plugin_la_LIBADD) $(LIBS) src/krb5_plugin/sssd_krb5_locator_plugin_la-sssd_krb5_locator_plugin.lo: \ src/krb5_plugin/$(am__dirstamp) \ src/krb5_plugin/$(DEPDIR)/$(am__dirstamp) src/util/sssd_krb5_locator_plugin_la-atomic_io.lo: \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) sssd_krb5_locator_plugin.la: $(sssd_krb5_locator_plugin_la_OBJECTS) $(sssd_krb5_locator_plugin_la_DEPENDENCIES) $(EXTRA_sssd_krb5_locator_plugin_la_DEPENDENCIES) $(AM_V_CCLD)$(sssd_krb5_locator_plugin_la_LINK) $(am_sssd_krb5_locator_plugin_la_rpath) $(sssd_krb5_locator_plugin_la_OBJECTS) $(sssd_krb5_locator_plugin_la_LIBADD) $(LIBS) src/sss_client/sssd_pac_plugin_la-sssd_pac.lo: \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/sssd_pac_plugin_la-common.lo: \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) sssd_pac_plugin.la: $(sssd_pac_plugin_la_OBJECTS) $(sssd_pac_plugin_la_DEPENDENCIES) $(EXTRA_sssd_pac_plugin_la_DEPENDENCIES) $(AM_V_CCLD)$(sssd_pac_plugin_la_LINK) $(am_sssd_pac_plugin_la_rpath) $(sssd_pac_plugin_la_OBJECTS) $(sssd_pac_plugin_la_LIBADD) $(LIBS) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ } \ ; done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sbindir)" && rm -f $$files clean-sbinPROGRAMS: @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list install-sssdlibexecPROGRAMS: $(sssdlibexec_PROGRAMS) @$(NORMAL_INSTALL) @list='$(sssdlibexec_PROGRAMS)'; test -n "$(sssdlibexecdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sssdlibexecdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sssdlibexecdir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sssdlibexecdir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sssdlibexecdir)$$dir" || exit $$?; \ } \ ; done uninstall-sssdlibexecPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sssdlibexec_PROGRAMS)'; test -n "$(sssdlibexecdir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sssdlibexecdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sssdlibexecdir)" && rm -f $$files clean-sssdlibexecPROGRAMS: @list='$(sssdlibexec_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list src/tests/cmocka/$(am__dirstamp): @$(MKDIR_P) src/tests/cmocka @: > src/tests/cmocka/$(am__dirstamp) src/tests/cmocka/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/tests/cmocka/$(DEPDIR) @: > src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_ad_access_filter.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) ad_access_filter_tests$(EXEEXT): $(ad_access_filter_tests_OBJECTS) $(ad_access_filter_tests_DEPENDENCIES) $(EXTRA_ad_access_filter_tests_DEPENDENCIES) @rm -f ad_access_filter_tests$(EXEEXT) $(AM_V_CCLD)$(LINK) $(ad_access_filter_tests_OBJECTS) $(ad_access_filter_tests_LDADD) $(LIBS) src/providers/krb5/krb5_utils.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_delayed_online_authentication.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_renew_tgt.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_wait_queue.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_common.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_opts.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_auth.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_access.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_child_handler.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_init_shared.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_ccache.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/util/sss_krb5.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/become_user.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/common_mock_krb5.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_ad_common.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/ad/ad_opts.$(OBJEXT): src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) ad_common_tests$(EXEEXT): $(ad_common_tests_OBJECTS) $(ad_common_tests_DEPENDENCIES) $(EXTRA_ad_common_tests_DEPENDENCIES) @rm -f ad_common_tests$(EXEEXT) $(AM_V_CCLD)$(ad_common_tests_LINK) $(ad_common_tests_OBJECTS) $(ad_common_tests_LDADD) $(LIBS) src/tests/cmocka/ad_gpo_tests-test_ad_gpo.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) ad_gpo_tests$(EXEEXT): $(ad_gpo_tests_OBJECTS) $(ad_gpo_tests_DEPENDENCIES) $(EXTRA_ad_gpo_tests_DEPENDENCIES) @rm -f ad_gpo_tests$(EXEEXT) $(AM_V_CCLD)$(ad_gpo_tests_LINK) $(ad_gpo_tests_OBJECTS) $(ad_gpo_tests_LDADD) $(LIBS) src/providers/ldap/ad_ldap_opt_tests-ldap_opts.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ad/ad_ldap_opt_tests-ad_opts.$(OBJEXT): \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/ad_ldap_opt_tests-krb5_opts.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) ad_ldap_opt-tests$(EXEEXT): $(ad_ldap_opt_tests_OBJECTS) $(ad_ldap_opt_tests_DEPENDENCIES) $(EXTRA_ad_ldap_opt_tests_DEPENDENCIES) @rm -f ad_ldap_opt-tests$(EXEEXT) $(AM_V_CCLD)$(ad_ldap_opt_tests_LINK) $(ad_ldap_opt_tests_OBJECTS) $(ad_ldap_opt_tests_LDADD) $(LIBS) src/tests/auth_tests-auth-tests.$(OBJEXT): src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) auth-tests$(EXEEXT): $(auth_tests_OBJECTS) $(auth_tests_DEPENDENCIES) $(EXTRA_auth_tests_DEPENDENCIES) @rm -f auth-tests$(EXEEXT) $(AM_V_CCLD)$(auth_tests_LINK) $(auth_tests_OBJECTS) $(auth_tests_LDADD) $(LIBS) src/sss_client/autofs/autofs_test_client-autofs_test_client.$(OBJEXT): \ src/sss_client/autofs/$(am__dirstamp) \ src/sss_client/autofs/$(DEPDIR)/$(am__dirstamp) src/sss_client/autofs/autofs_test_client-sss_autofs.$(OBJEXT): \ src/sss_client/autofs/$(am__dirstamp) \ src/sss_client/autofs/$(DEPDIR)/$(am__dirstamp) src/sss_client/autofs_test_client-common.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) autofs_test_client$(EXEEXT): $(autofs_test_client_OBJECTS) $(autofs_test_client_DEPENDENCIES) $(EXTRA_autofs_test_client_DEPENDENCIES) @rm -f autofs_test_client$(EXEEXT) $(AM_V_CCLD)$(autofs_test_client_LINK) $(autofs_test_client_OBJECTS) $(autofs_test_client_LDADD) $(LIBS) src/tests/check_and_open_tests-check_and_open-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/util/check_and_open_tests-check_and_open.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) check_and_open-tests$(EXEEXT): $(check_and_open_tests_OBJECTS) $(check_and_open_tests_DEPENDENCIES) $(EXTRA_check_and_open_tests_DEPENDENCIES) @rm -f check_and_open-tests$(EXEEXT) $(AM_V_CCLD)$(check_and_open_tests_LINK) $(check_and_open_tests_OBJECTS) $(check_and_open_tests_LDADD) $(LIBS) src/tests/crypto_tests-crypto-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) crypto-tests$(EXEEXT): $(crypto_tests_OBJECTS) $(crypto_tests_DEPENDENCIES) $(EXTRA_crypto_tests_DEPENDENCIES) @rm -f crypto-tests$(EXEEXT) $(AM_V_CCLD)$(crypto_tests_LINK) $(crypto_tests_OBJECTS) $(crypto_tests_LDADD) $(LIBS) src/tests/debug_tests-debug-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/tests/debug_tests-common.$(OBJEXT): src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) debug-tests$(EXEEXT): $(debug_tests_OBJECTS) $(debug_tests_DEPENDENCIES) $(EXTRA_debug_tests_DEPENDENCIES) @rm -f debug-tests$(EXEEXT) $(AM_V_CCLD)$(debug_tests_LINK) $(debug_tests_OBJECTS) $(debug_tests_LDADD) $(LIBS) src/tests/dlopen_tests-dlopen-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) dlopen-tests$(EXEEXT): $(dlopen_tests_OBJECTS) $(dlopen_tests_DEPENDENCIES) $(EXTRA_dlopen_tests_DEPENDENCIES) @rm -f dlopen-tests$(EXEEXT) $(AM_V_CCLD)$(dlopen_tests_LINK) $(dlopen_tests_OBJECTS) $(dlopen_tests_LDADD) $(LIBS) src/providers/dp_opt_tests-data_provider_opts.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/dp_opt_tests-test_dp_opts.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) dp_opt_tests$(EXEEXT): $(dp_opt_tests_OBJECTS) $(dp_opt_tests_DEPENDENCIES) $(EXTRA_dp_opt_tests_DEPENDENCIES) @rm -f dp_opt_tests$(EXEEXT) $(AM_V_CCLD)$(dp_opt_tests_LINK) $(dp_opt_tests_OBJECTS) $(dp_opt_tests_LDADD) $(LIBS) src/tests/cmocka/dummy_child.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) dummy-child$(EXEEXT): $(dummy_child_OBJECTS) $(dummy_child_DEPENDENCIES) $(EXTRA_dummy_child_DEPENDENCIES) @rm -f dummy-child$(EXEEXT) $(AM_V_CCLD)$(LINK) $(dummy_child_OBJECTS) $(dummy_child_LDADD) $(LIBS) src/resolv/dyndns_tests-async_resolv.$(OBJEXT): \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) src/resolv/dyndns_tests-async_resolv_utils.$(OBJEXT): \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/dyndns_tests-common_mock_be.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/dyndns_tests-test_dyndns.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/dyndns_tests-data_provider_opts.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) dyndns-tests$(EXEEXT): $(dyndns_tests_OBJECTS) $(dyndns_tests_DEPENDENCIES) $(EXTRA_dyndns_tests_DEPENDENCIES) @rm -f dyndns-tests$(EXEEXT) $(AM_V_CCLD)$(dyndns_tests_LINK) $(dyndns_tests_OBJECTS) $(dyndns_tests_LDADD) $(LIBS) src/tests/fail_over_tests-fail_over-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/providers/fail_over_tests-fail_over.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/fail_over_tests-fail_over_srv.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/resolv/fail_over_tests-async_resolv.$(OBJEXT): \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) src/resolv/fail_over_tests-async_resolv_utils.$(OBJEXT): \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) fail_over-tests$(EXEEXT): $(fail_over_tests_OBJECTS) $(fail_over_tests_DEPENDENCIES) $(EXTRA_fail_over_tests_DEPENDENCIES) @rm -f fail_over-tests$(EXEEXT) $(AM_V_CCLD)$(fail_over_tests_LINK) $(fail_over_tests_OBJECTS) $(fail_over_tests_LDADD) $(LIBS) src/tests/files_tests-files-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/util/files_tests-check_and_open.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/util/files_tests-atomic_io.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/tools/files_tests-selinux.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/files_tests-files.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) files-tests$(EXEEXT): $(files_tests_OBJECTS) $(files_tests_DEPENDENCIES) $(EXTRA_files_tests_DEPENDENCIES) @rm -f files-tests$(EXEEXT) $(AM_V_CCLD)$(files_tests_LINK) $(files_tests_OBJECTS) $(files_tests_LDADD) $(LIBS) src/tests/find_uid_tests-find_uid-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/util/find_uid_tests-find_uid.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/find_uid_tests-atomic_io.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/find_uid_tests-strtonum.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) find_uid-tests$(EXEEXT): $(find_uid_tests_OBJECTS) $(find_uid_tests_DEPENDENCIES) $(EXTRA_find_uid_tests_DEPENDENCIES) @rm -f find_uid-tests$(EXEEXT) $(AM_V_CCLD)$(find_uid_tests_LINK) $(find_uid_tests_OBJECTS) $(find_uid_tests_LDADD) $(LIBS) src/tests/cmocka/fqnames_tests-test_fqnames.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) fqnames-tests$(EXEEXT): $(fqnames_tests_OBJECTS) $(fqnames_tests_DEPENDENCIES) $(EXTRA_fqnames_tests_DEPENDENCIES) @rm -f fqnames-tests$(EXEEXT) $(AM_V_CCLD)$(fqnames_tests_LINK) $(fqnames_tests_OBJECTS) $(fqnames_tests_LDADD) $(LIBS) src/providers/ad/gpo_child-ad_gpo_child.$(OBJEXT): \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/util/gpo_child-atomic_io.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/gpo_child-util.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/gpo_child-signal.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) gpo_child$(EXEEXT): $(gpo_child_OBJECTS) $(gpo_child_DEPENDENCIES) $(EXTRA_gpo_child_DEPENDENCIES) @rm -f gpo_child$(EXEEXT) $(AM_V_CCLD)$(gpo_child_LINK) $(gpo_child_OBJECTS) $(gpo_child_LDADD) $(LIBS) src/tests/cmocka/ifp_tests-common_mock_resp.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/ifp_tests-common_mock_resp_dp.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/responder/common/$(am__dirstamp): @$(MKDIR_P) src/responder/common @: > src/responder/common/$(am__dirstamp) src/responder/common/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/responder/common/$(DEPDIR) @: > src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/ifp_tests-responder_packet.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/ifp_tests-responder_cmd.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/ifp_tests-negcache.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/ifp_tests-responder_common.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/ifp_tests-responder_cache_req.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/ifp_tests-test_ifp.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/$(am__dirstamp): @$(MKDIR_P) src/responder/ifp @: > src/responder/ifp/$(am__dirstamp) src/responder/ifp/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/responder/ifp/$(DEPDIR) @: > src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/ifp_tests-ifpsrv_cmd.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/ifp_tests-ifp_iface_generated.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/ifp_tests-ifpsrv_util.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/common/ifp_tests-responder_utils.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) ifp_tests$(EXEEXT): $(ifp_tests_OBJECTS) $(ifp_tests_DEPENDENCIES) $(EXTRA_ifp_tests_DEPENDENCIES) @rm -f ifp_tests$(EXEEXT) $(AM_V_CCLD)$(ifp_tests_LINK) $(ifp_tests_OBJECTS) $(ifp_tests_LDADD) $(LIBS) src/tests/ipa_hbac_tests-ipa_hbac-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) ipa_hbac-tests$(EXEEXT): $(ipa_hbac_tests_OBJECTS) $(ipa_hbac_tests_DEPENDENCIES) $(EXTRA_ipa_hbac_tests_DEPENDENCIES) @rm -f ipa_hbac-tests$(EXEEXT) $(AM_V_CCLD)$(ipa_hbac_tests_LINK) $(ipa_hbac_tests_OBJECTS) $(ipa_hbac_tests_LDADD) $(LIBS) src/providers/ipa_ldap_opt_tests-data_provider_opts.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/ipa_ldap_opt_tests-sdap.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/ipa_ldap_opt_tests-sdap_range.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ad/ipa_ldap_opt_tests-ad_opts.$(OBJEXT): \ src/providers/ad/$(am__dirstamp) \ src/providers/ad/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.$(OBJEXT): \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/util/ipa_ldap_opt_tests-sss_ldap.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) ipa_ldap_opt-tests$(EXEEXT): $(ipa_ldap_opt_tests_OBJECTS) $(ipa_ldap_opt_tests_DEPENDENCIES) $(EXTRA_ipa_ldap_opt_tests_DEPENDENCIES) @rm -f ipa_ldap_opt-tests$(EXEEXT) $(AM_V_CCLD)$(ipa_ldap_opt_tests_LINK) $(ipa_ldap_opt_tests_OBJECTS) $(ipa_ldap_opt_tests_LDADD) $(LIBS) src/tests/krb5_child_test-krb5_child-test.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_child_test-krb5_utils.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_child_test-krb5_ccache.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_child_test-krb5_child_handler.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_child_test-krb5_common.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_child_test-krb5_opts.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child_test-sss_krb5.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/providers/krb5_child_test-data_provider_fo.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/krb5_child_test-data_provider_opts.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/krb5_child_test-data_provider_callbacks.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child_test-become_user.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/providers/krb5_child_test-fail_over.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/krb5_child_test-fail_over_srv.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/resolv/krb5_child_test-async_resolv.$(OBJEXT): \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) src/resolv/krb5_child_test-async_resolv_utils.$(OBJEXT): \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) krb5-child-test$(EXEEXT): $(krb5_child_test_OBJECTS) $(krb5_child_test_DEPENDENCIES) $(EXTRA_krb5_child_test_DEPENDENCIES) @rm -f krb5-child-test$(EXEEXT) $(AM_V_CCLD)$(krb5_child_test_LINK) $(krb5_child_test_OBJECTS) $(krb5_child_test_LDADD) $(LIBS) src/tests/krb5_utils_tests-krb5_utils-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_utils_tests-krb5_utils.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_utils_tests-krb5_ccache.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_utils_tests-krb5_common.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_utils_tests-krb5_opts.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/util/krb5_utils_tests-sss_krb5.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/providers/krb5_utils_tests-data_provider_fo.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/krb5_utils_tests-data_provider_opts.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/krb5_utils_tests-data_provider_callbacks.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/util/krb5_utils_tests-become_user.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/providers/krb5_utils_tests-fail_over.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/krb5_utils_tests-fail_over_srv.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/resolv/krb5_utils_tests-async_resolv.$(OBJEXT): \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) src/resolv/krb5_utils_tests-async_resolv_utils.$(OBJEXT): \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) krb5-utils-tests$(EXEEXT): $(krb5_utils_tests_OBJECTS) $(krb5_utils_tests_DEPENDENCIES) $(EXTRA_krb5_utils_tests_DEPENDENCIES) @rm -f krb5-utils-tests$(EXEEXT) $(AM_V_CCLD)$(krb5_utils_tests_LINK) $(krb5_utils_tests_OBJECTS) $(krb5_utils_tests_LDADD) $(LIBS) src/providers/krb5/krb5_child-krb5_child.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_child-krb5_ccache.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/krb5_child-krb5_keytab.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5_child-dp_pam_data_util.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child-user_info_msg.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child-sss_krb5.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child-find_uid.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child-atomic_io.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child-authtok.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child-authtok-utils.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child-util.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child-signal.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child-strtonum.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child-become_user.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/krb5_child-util_errors.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/sss_client/krb5_child-common.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) krb5_child$(EXEEXT): $(krb5_child_OBJECTS) $(krb5_child_DEPENDENCIES) $(EXTRA_krb5_child_DEPENDENCIES) @rm -f krb5_child$(EXEEXT) $(AM_V_CCLD)$(krb5_child_LINK) $(krb5_child_OBJECTS) $(krb5_child_LDADD) $(LIBS) src/providers/ldap/ldap_child-ldap_child.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/ldap_child-krb5_keytab.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/util/ldap_child-sss_krb5.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/ldap_child-atomic_io.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/ldap_child-authtok.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/ldap_child-authtok-utils.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/ldap_child-util.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/ldap_child-signal.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/ldap_child-become_user.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) ldap_child$(EXEEXT): $(ldap_child_OBJECTS) $(ldap_child_DEPENDENCIES) $(EXTRA_ldap_child_DEPENDENCIES) @rm -f ldap_child$(EXEEXT) $(AM_V_CCLD)$(ldap_child_LINK) $(ldap_child_OBJECTS) $(ldap_child_LDADD) $(LIBS) src/util/nestedgroups_tests-sss_ldap.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/providers/nestedgroups_tests-data_provider_opts.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/nestedgroups_tests-ldap_opts.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/nestedgroups_tests-ldap_options.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/nestedgroups_tests-sdap_domain.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/nestedgroups_tests-sdap.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/nestedgroups_tests-sdap_utils.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/nestedgroups_tests-sdap_range.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/nestedgroups_tests-common_mock_sdap.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/nestedgroups_tests-sdap_idmap.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/nestedgroups_tests-test_nested_groups.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/nestedgroups_tests-common_mock_be.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/nestedgroups_tests-sdap_ad_groups.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/nestedgroups_tests-ipa_dn.$(OBJEXT): \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) nestedgroups-tests$(EXEEXT): $(nestedgroups_tests_OBJECTS) $(nestedgroups_tests_DEPENDENCIES) $(EXTRA_nestedgroups_tests_DEPENDENCIES) @rm -f nestedgroups-tests$(EXEEXT) $(AM_V_CCLD)$(nestedgroups_tests_LINK) $(nestedgroups_tests_OBJECTS) $(nestedgroups_tests_LDADD) $(LIBS) src/tests/cmocka/nss_srv_tests-common_mock_resp.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/responder/common/nss_srv_tests-responder_packet.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/nss_srv_tests-responder_cmd.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/nss_srv_tests-negcache.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/nss_srv_tests-responder_common.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/nss_srv_tests-responder_cache_req.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/nss_srv_tests-test_nss_srv.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/responder/nss/$(am__dirstamp): @$(MKDIR_P) src/responder/nss @: > src/responder/nss/$(am__dirstamp) src/responder/nss/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/responder/nss/$(DEPDIR) @: > src/responder/nss/$(DEPDIR)/$(am__dirstamp) src/responder/nss/nss_srv_tests-nsssrv_cmd.$(OBJEXT): \ src/responder/nss/$(am__dirstamp) \ src/responder/nss/$(DEPDIR)/$(am__dirstamp) src/responder/nss/nss_srv_tests-nsssrv_netgroup.$(OBJEXT): \ src/responder/nss/$(am__dirstamp) \ src/responder/nss/$(DEPDIR)/$(am__dirstamp) src/responder/nss/nss_srv_tests-nsssrv_services.$(OBJEXT): \ src/responder/nss/$(am__dirstamp) \ src/responder/nss/$(DEPDIR)/$(am__dirstamp) src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.$(OBJEXT): \ src/responder/nss/$(am__dirstamp) \ src/responder/nss/$(DEPDIR)/$(am__dirstamp) nss-srv-tests$(EXEEXT): $(nss_srv_tests_OBJECTS) $(nss_srv_tests_DEPENDENCIES) $(EXTRA_nss_srv_tests_DEPENDENCIES) @rm -f nss-srv-tests$(EXEEXT) $(AM_V_CCLD)$(nss_srv_tests_LINK) $(nss_srv_tests_OBJECTS) $(nss_srv_tests_LDADD) $(LIBS) src/p11_child/$(am__dirstamp): @$(MKDIR_P) src/p11_child @: > src/p11_child/$(am__dirstamp) src/p11_child/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/p11_child/$(DEPDIR) @: > src/p11_child/$(DEPDIR)/$(am__dirstamp) src/p11_child/p11_child-p11_child_nss.$(OBJEXT): \ src/p11_child/$(am__dirstamp) \ src/p11_child/$(DEPDIR)/$(am__dirstamp) src/util/p11_child-atomic_io.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/p11_child-util.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) p11_child$(EXEEXT): $(p11_child_OBJECTS) $(p11_child_DEPENDENCIES) $(EXTRA_p11_child_DEPENDENCIES) @rm -f p11_child$(EXEEXT) $(AM_V_CCLD)$(p11_child_LINK) $(p11_child_OBJECTS) $(p11_child_LDADD) $(LIBS) src/tests/cmocka/pam_srv_tests-common_mock_resp.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/responder/common/pam_srv_tests-responder_packet.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/pam_srv_tests-responder_cmd.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/pam_srv_tests-negcache.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/pam_srv_tests-responder_common.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/pam_srv_tests-responder_cache_req.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/pam_srv_tests-test_pam_srv.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/sss_client/pam_srv_tests-pam_message.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/responder/pam/$(am__dirstamp): @$(MKDIR_P) src/responder/pam @: > src/responder/pam/$(am__dirstamp) src/responder/pam/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/responder/pam/$(DEPDIR) @: > src/responder/pam/$(DEPDIR)/$(am__dirstamp) src/responder/pam/pam_srv_tests-pamsrv_cmd.$(OBJEXT): \ src/responder/pam/$(am__dirstamp) \ src/responder/pam/$(DEPDIR)/$(am__dirstamp) src/responder/pam/pam_srv_tests-pamsrv_p11.$(OBJEXT): \ src/responder/pam/$(am__dirstamp) \ src/responder/pam/$(DEPDIR)/$(am__dirstamp) src/responder/pam/pam_srv_tests-pam_helpers.$(OBJEXT): \ src/responder/pam/$(am__dirstamp) \ src/responder/pam/$(DEPDIR)/$(am__dirstamp) src/responder/pam/pam_srv_tests-pamsrv_dp.$(OBJEXT): \ src/responder/pam/$(am__dirstamp) \ src/responder/pam/$(DEPDIR)/$(am__dirstamp) src/responder/pam/pam_srv_tests-pam_LOCAL_domain.$(OBJEXT): \ src/responder/pam/$(am__dirstamp) \ src/responder/pam/$(DEPDIR)/$(am__dirstamp) pam-srv-tests$(EXEEXT): $(pam_srv_tests_OBJECTS) $(pam_srv_tests_DEPENDENCIES) $(EXTRA_pam_srv_tests_DEPENDENCIES) @rm -f pam-srv-tests$(EXEEXT) $(AM_V_CCLD)$(pam_srv_tests_LINK) $(pam_srv_tests_OBJECTS) $(pam_srv_tests_LDADD) $(LIBS) src/sss_client/pam_test_client.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) pam_test_client$(EXEEXT): $(pam_test_client_OBJECTS) $(pam_test_client_DEPENDENCIES) $(EXTRA_pam_test_client_DEPENDENCIES) @rm -f pam_test_client$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pam_test_client_OBJECTS) $(pam_test_client_LDADD) $(LIBS) src/providers/proxy/proxy_child-proxy_child.$(OBJEXT): \ src/providers/proxy/$(am__dirstamp) \ src/providers/proxy/$(DEPDIR)/$(am__dirstamp) src/providers/proxy_child-data_provider_iface_generated.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) proxy_child$(EXEEXT): $(proxy_child_OBJECTS) $(proxy_child_DEPENDENCIES) $(EXTRA_proxy_child_DEPENDENCIES) @rm -f proxy_child$(EXEEXT) $(AM_V_CCLD)$(proxy_child_LINK) $(proxy_child_OBJECTS) $(proxy_child_LDADD) $(LIBS) src/tests/refcount_tests-refcount-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) refcount-tests$(EXEEXT): $(refcount_tests_OBJECTS) $(refcount_tests_DEPENDENCIES) $(EXTRA_refcount_tests_DEPENDENCIES) @rm -f refcount-tests$(EXEEXT) $(AM_V_CCLD)$(refcount_tests_LINK) $(refcount_tests_OBJECTS) $(refcount_tests_LDADD) $(LIBS) src/tests/resolv_tests-resolv-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/tests/resolv_tests-common.$(OBJEXT): src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) src/resolv/resolv_tests-async_resolv.$(OBJEXT): \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) src/resolv/resolv_tests-async_resolv_utils.$(OBJEXT): \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) resolv-tests$(EXEEXT): $(resolv_tests_OBJECTS) $(resolv_tests_DEPENDENCIES) $(EXTRA_resolv_tests_DEPENDENCIES) @rm -f resolv-tests$(EXEEXT) $(AM_V_CCLD)$(resolv_tests_LINK) $(resolv_tests_OBJECTS) $(resolv_tests_LDADD) $(LIBS) src/responder/common/responder_get_domains_tests-responder_get_domains.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/responder_get_domains_tests-test_responder_common.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/responder_get_domains_tests-common_mock_resp.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) responder-get-domains-tests$(EXEEXT): $(responder_get_domains_tests_OBJECTS) $(responder_get_domains_tests_DEPENDENCIES) $(EXTRA_responder_get_domains_tests_DEPENDENCIES) @rm -f responder-get-domains-tests$(EXEEXT) $(AM_V_CCLD)$(responder_get_domains_tests_LINK) $(responder_get_domains_tests_OBJECTS) $(responder_get_domains_tests_LDADD) $(LIBS) src/tests/cmocka/responder_cache_req_tests-common_mock_resp.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_cache_req_tests-responder_packet.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_cache_req_tests-responder_cmd.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_cache_req_tests-negcache.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_cache_req_tests-responder_common.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_cache_req_tests-responder_cache_req.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) responder_cache_req-tests$(EXEEXT): $(responder_cache_req_tests_OBJECTS) $(responder_cache_req_tests_DEPENDENCIES) $(EXTRA_responder_cache_req_tests_DEPENDENCIES) @rm -f responder_cache_req-tests$(EXEEXT) $(AM_V_CCLD)$(responder_cache_req_tests_LINK) $(responder_cache_req_tests_OBJECTS) $(responder_cache_req_tests_LDADD) $(LIBS) src/tests/responder_socket_access_tests-responder_socket_access-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_socket_access_tests-responder_common.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_socket_access_tests-responder_packet.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_socket_access_tests-responder_cmd.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) responder_socket_access-tests$(EXEEXT): $(responder_socket_access_tests_OBJECTS) $(responder_socket_access_tests_DEPENDENCIES) $(EXTRA_responder_socket_access_tests_DEPENDENCIES) @rm -f responder_socket_access-tests$(EXEEXT) $(AM_V_CCLD)$(responder_socket_access_tests_LINK) $(responder_socket_access_tests_OBJECTS) $(responder_socket_access_tests_LDADD) $(LIBS) src/tests/safe_format_tests-safe-format-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) safe-format-tests$(EXEEXT): $(safe_format_tests_OBJECTS) $(safe_format_tests_DEPENDENCIES) $(EXTRA_safe_format_tests_DEPENDENCIES) @rm -f safe-format-tests$(EXEEXT) $(AM_V_CCLD)$(safe_format_tests_LINK) $(safe_format_tests_OBJECTS) $(safe_format_tests_LDADD) $(LIBS) src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/sbus/sbus_internal_tests-sssd_dbus_request.$(OBJEXT): \ src/sbus/$(am__dirstamp) src/sbus/$(DEPDIR)/$(am__dirstamp) sbus-internal-tests$(EXEEXT): $(sbus_internal_tests_OBJECTS) $(sbus_internal_tests_DEPENDENCIES) $(EXTRA_sbus_internal_tests_DEPENDENCIES) @rm -f sbus-internal-tests$(EXEEXT) $(AM_V_CCLD)$(sbus_internal_tests_LINK) $(sbus_internal_tests_OBJECTS) $(sbus_internal_tests_LDADD) $(LIBS) src/tests/sbus_codegen_tests-common_dbus.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/tests/sbus_codegen_tests-sbus_codegen_tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) sbus_codegen_tests$(EXEEXT): $(sbus_codegen_tests_OBJECTS) $(sbus_codegen_tests_DEPENDENCIES) $(EXTRA_sbus_codegen_tests_DEPENDENCIES) @rm -f sbus_codegen_tests$(EXEEXT) $(AM_V_CCLD)$(sbus_codegen_tests_LINK) $(sbus_codegen_tests_OBJECTS) $(sbus_codegen_tests_LDADD) $(LIBS) src/tests/sbus_tests-common_dbus.$(OBJEXT): src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) src/tests/sbus_tests-sbus_tests.$(OBJEXT): src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) sbus_tests$(EXEEXT): $(sbus_tests_OBJECTS) $(sbus_tests_DEPENDENCIES) $(EXTRA_sbus_tests_DEPENDENCIES) @rm -f sbus_tests$(EXEEXT) $(AM_V_CCLD)$(sbus_tests_LINK) $(sbus_tests_OBJECTS) $(sbus_tests_LDADD) $(LIBS) src/providers/sdap_tests-data_provider_opts.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/sdap_tests-sdap_domain.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/sdap_tests-sdap.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/sdap_tests-sdap_range.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ldap/sdap_tests-ldap_opts.$(OBJEXT): \ src/providers/ldap/$(am__dirstamp) \ src/providers/ldap/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/sdap_tests-ipa_opts.$(OBJEXT): \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/util/sdap_tests-sss_ldap.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/sdap_tests-test_sdap.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) sdap-tests$(EXEEXT): $(sdap_tests_OBJECTS) $(sdap_tests_DEPENDENCIES) $(EXTRA_sdap_tests_DEPENDENCIES) @rm -f sdap-tests$(EXEEXT) $(AM_V_CCLD)$(sdap_tests_LINK) $(sdap_tests_OBJECTS) $(sdap_tests_LDADD) $(LIBS) src/providers/ipa/selinux_child-selinux_child.$(OBJEXT): \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/util/selinux_child-sss_semanage.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/util/selinux_child-atomic_io.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/selinux_child-util.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) selinux_child$(EXEEXT): $(selinux_child_OBJECTS) $(selinux_child_DEPENDENCIES) $(EXTRA_selinux_child_DEPENDENCIES) @rm -f selinux_child$(EXEEXT) $(AM_V_CCLD)$(selinux_child_LINK) $(selinux_child_OBJECTS) $(selinux_child_LDADD) $(LIBS) src/tests/simple_access-tests.$(OBJEXT): src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) src/providers/simple/simple_access.$(OBJEXT): \ src/providers/simple/$(am__dirstamp) \ src/providers/simple/$(DEPDIR)/$(am__dirstamp) src/providers/simple/simple_access_check.$(OBJEXT): \ src/providers/simple/$(am__dirstamp) \ src/providers/simple/$(DEPDIR)/$(am__dirstamp) simple_access-tests$(EXEEXT): $(simple_access_tests_OBJECTS) $(simple_access_tests_DEPENDENCIES) $(EXTRA_simple_access_tests_DEPENDENCIES) @rm -f simple_access-tests$(EXEEXT) $(AM_V_CCLD)$(LINK) $(simple_access_tests_OBJECTS) $(simple_access_tests_LDADD) $(LIBS) src/tools/sss_cache-sss_cache.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/sss_client/sss_cache-common.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/tools/sss_cache-tools_mc_util.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_cache-sss_sync_ops.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_cache-tools_util.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_cache-files.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_cache-selinux.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/common/sss_cache-sss_tools.$(OBJEXT): \ src/tools/common/$(am__dirstamp) \ src/tools/common/$(DEPDIR)/$(am__dirstamp) src/util/sss_cache-nscd.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) sss_cache$(EXEEXT): $(sss_cache_OBJECTS) $(sss_cache_DEPENDENCIES) $(EXTRA_sss_cache_DEPENDENCIES) @rm -f sss_cache$(EXEEXT) $(AM_V_CCLD)$(sss_cache_LINK) $(sss_cache_OBJECTS) $(sss_cache_LDADD) $(LIBS) src/tests/sss_config_tests-sss_config-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/tests/sss_config_tests-common.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) sss_config-tests$(EXEEXT): $(sss_config_tests_OBJECTS) $(sss_config_tests_DEPENDENCIES) $(EXTRA_sss_config_tests_DEPENDENCIES) @rm -f sss_config-tests$(EXEEXT) $(AM_V_CCLD)$(sss_config_tests_LINK) $(sss_config_tests_OBJECTS) $(sss_config_tests_LDADD) $(LIBS) src/tools/sss_debuglevel.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_sync_ops.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/tools_util.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/files.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/selinux.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/common/sss_tools.$(OBJEXT): \ src/tools/common/$(am__dirstamp) \ src/tools/common/$(DEPDIR)/$(am__dirstamp) src/util/nscd.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) sss_debuglevel$(EXEEXT): $(sss_debuglevel_OBJECTS) $(sss_debuglevel_DEPENDENCIES) $(EXTRA_sss_debuglevel_DEPENDENCIES) @rm -f sss_debuglevel$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sss_debuglevel_OBJECTS) $(sss_debuglevel_LDADD) $(LIBS) src/tools/sss_groupadd.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) sss_groupadd$(EXEEXT): $(sss_groupadd_OBJECTS) $(sss_groupadd_DEPENDENCIES) $(EXTRA_sss_groupadd_DEPENDENCIES) @rm -f sss_groupadd$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sss_groupadd_OBJECTS) $(sss_groupadd_LDADD) $(LIBS) src/tools/sss_groupdel-sss_groupdel.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/sss_client/sss_groupdel-common.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/tools/sss_groupdel-tools_mc_util.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_groupdel-sss_sync_ops.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_groupdel-tools_util.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_groupdel-files.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_groupdel-selinux.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/common/sss_groupdel-sss_tools.$(OBJEXT): \ src/tools/common/$(am__dirstamp) \ src/tools/common/$(DEPDIR)/$(am__dirstamp) src/util/sss_groupdel-nscd.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) sss_groupdel$(EXEEXT): $(sss_groupdel_OBJECTS) $(sss_groupdel_DEPENDENCIES) $(EXTRA_sss_groupdel_DEPENDENCIES) @rm -f sss_groupdel$(EXEEXT) $(AM_V_CCLD)$(sss_groupdel_LINK) $(sss_groupdel_OBJECTS) $(sss_groupdel_LDADD) $(LIBS) src/tools/sss_groupmod-sss_groupmod.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/sss_client/sss_groupmod-common.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/tools/sss_groupmod-tools_mc_util.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_groupmod-sss_sync_ops.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_groupmod-tools_util.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_groupmod-files.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_groupmod-selinux.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/common/sss_groupmod-sss_tools.$(OBJEXT): \ src/tools/common/$(am__dirstamp) \ src/tools/common/$(DEPDIR)/$(am__dirstamp) src/util/sss_groupmod-nscd.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) sss_groupmod$(EXEEXT): $(sss_groupmod_OBJECTS) $(sss_groupmod_DEPENDENCIES) $(EXTRA_sss_groupmod_DEPENDENCIES) @rm -f sss_groupmod$(EXEEXT) $(AM_V_CCLD)$(sss_groupmod_LINK) $(sss_groupmod_OBJECTS) $(sss_groupmod_LDADD) $(LIBS) src/tools/sss_groupshow.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) sss_groupshow$(EXEEXT): $(sss_groupshow_OBJECTS) $(sss_groupshow_DEPENDENCIES) $(EXTRA_sss_groupshow_DEPENDENCIES) @rm -f sss_groupshow$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sss_groupshow_OBJECTS) $(sss_groupshow_LDADD) $(LIBS) src/tests/sss_idmap_tests-sss_idmap-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) sss_idmap-tests$(EXEEXT): $(sss_idmap_tests_OBJECTS) $(sss_idmap_tests_DEPENDENCIES) $(EXTRA_sss_idmap_tests_DEPENDENCIES) @rm -f sss_idmap-tests$(EXEEXT) $(AM_V_CCLD)$(sss_idmap_tests_LINK) $(sss_idmap_tests_OBJECTS) $(sss_idmap_tests_LDADD) $(LIBS) src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) sss_nss_idmap-tests$(EXEEXT): $(sss_nss_idmap_tests_OBJECTS) $(sss_nss_idmap_tests_DEPENDENCIES) $(EXTRA_sss_nss_idmap_tests_DEPENDENCIES) @rm -f sss_nss_idmap-tests$(EXEEXT) $(AM_V_CCLD)$(sss_nss_idmap_tests_LINK) $(sss_nss_idmap_tests_OBJECTS) $(sss_nss_idmap_tests_LDADD) $(LIBS) src/tools/sss_override-sss_override.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/common/sss_override-sss_colondb.$(OBJEXT): \ src/tools/common/$(am__dirstamp) \ src/tools/common/$(DEPDIR)/$(am__dirstamp) src/tools/sss_override-sss_sync_ops.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_override-tools_util.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_override-files.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_override-selinux.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/common/sss_override-sss_tools.$(OBJEXT): \ src/tools/common/$(am__dirstamp) \ src/tools/common/$(DEPDIR)/$(am__dirstamp) src/util/sss_override-nscd.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) sss_override$(EXEEXT): $(sss_override_OBJECTS) $(sss_override_DEPENDENCIES) $(EXTRA_sss_override_DEPENDENCIES) @rm -f sss_override$(EXEEXT) $(AM_V_CCLD)$(sss_override_LINK) $(sss_override_OBJECTS) $(sss_override_LDADD) $(LIBS) src/tools/sss_seed.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) sss_seed$(EXEEXT): $(sss_seed_OBJECTS) $(sss_seed_DEPENDENCIES) $(EXTRA_sss_seed_DEPENDENCIES) @rm -f sss_seed$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sss_seed_OBJECTS) $(sss_seed_LDADD) $(LIBS) src/tests/cmocka/sss_sifp_tests-test_sss_sifp.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.$(OBJEXT): \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/sss_sifp_tests-sss_sifp_common.$(OBJEXT): \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/sss_sifp_tests-sss_sifp_parser.$(OBJEXT): \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/sss_sifp_tests-sss_sifp_utils.$(OBJEXT): \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.$(OBJEXT): \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) src/lib/sifp/sss_sifp_tests-sss_sifp.$(OBJEXT): \ src/lib/sifp/$(am__dirstamp) \ src/lib/sifp/$(DEPDIR)/$(am__dirstamp) sss_sifp-tests$(EXEEXT): $(sss_sifp_tests_OBJECTS) $(sss_sifp_tests_DEPENDENCIES) $(EXTRA_sss_sifp_tests_DEPENDENCIES) @rm -f sss_sifp-tests$(EXEEXT) $(AM_V_CCLD)$(sss_sifp_tests_LINK) $(sss_sifp_tests_OBJECTS) $(sss_sifp_tests_LDADD) $(LIBS) src/tools/sss_signal.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) sss_signal$(EXEEXT): $(sss_signal_OBJECTS) $(sss_signal_DEPENDENCIES) $(EXTRA_sss_signal_DEPENDENCIES) @rm -f sss_signal$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sss_signal_OBJECTS) $(sss_signal_LDADD) $(LIBS) src/sss_client/sss_ssh_authorizedkeys-common.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/ssh/$(am__dirstamp): @$(MKDIR_P) src/sss_client/ssh @: > src/sss_client/ssh/$(am__dirstamp) src/sss_client/ssh/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/sss_client/ssh/$(DEPDIR) @: > src/sss_client/ssh/$(DEPDIR)/$(am__dirstamp) src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.$(OBJEXT): \ src/sss_client/ssh/$(am__dirstamp) \ src/sss_client/ssh/$(DEPDIR)/$(am__dirstamp) src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.$(OBJEXT): \ src/sss_client/ssh/$(am__dirstamp) \ src/sss_client/ssh/$(DEPDIR)/$(am__dirstamp) sss_ssh_authorizedkeys$(EXEEXT): $(sss_ssh_authorizedkeys_OBJECTS) $(sss_ssh_authorizedkeys_DEPENDENCIES) $(EXTRA_sss_ssh_authorizedkeys_DEPENDENCIES) @rm -f sss_ssh_authorizedkeys$(EXEEXT) $(AM_V_CCLD)$(sss_ssh_authorizedkeys_LINK) $(sss_ssh_authorizedkeys_OBJECTS) $(sss_ssh_authorizedkeys_LDADD) $(LIBS) src/sss_client/sss_ssh_knownhostsproxy-common.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.$(OBJEXT): \ src/sss_client/ssh/$(am__dirstamp) \ src/sss_client/ssh/$(DEPDIR)/$(am__dirstamp) src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.$(OBJEXT): \ src/sss_client/ssh/$(am__dirstamp) \ src/sss_client/ssh/$(DEPDIR)/$(am__dirstamp) sss_ssh_knownhostsproxy$(EXEEXT): $(sss_ssh_knownhostsproxy_OBJECTS) $(sss_ssh_knownhostsproxy_DEPENDENCIES) $(EXTRA_sss_ssh_knownhostsproxy_DEPENDENCIES) @rm -f sss_ssh_knownhostsproxy$(EXEEXT) $(AM_V_CCLD)$(sss_ssh_knownhostsproxy_LINK) $(sss_ssh_knownhostsproxy_OBJECTS) $(sss_ssh_knownhostsproxy_LDADD) $(LIBS) src/sss_client/sss_sudo_cli-common.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/sss_client/sudo/sss_sudo_cli-sss_sudo.$(OBJEXT): \ src/sss_client/sudo/$(am__dirstamp) \ src/sss_client/sudo/$(DEPDIR)/$(am__dirstamp) src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.$(OBJEXT): \ src/sss_client/sudo/$(am__dirstamp) \ src/sss_client/sudo/$(DEPDIR)/$(am__dirstamp) src/sss_client/sudo_testcli/$(am__dirstamp): @$(MKDIR_P) src/sss_client/sudo_testcli @: > src/sss_client/sudo_testcli/$(am__dirstamp) src/sss_client/sudo_testcli/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/sss_client/sudo_testcli/$(DEPDIR) @: > src/sss_client/sudo_testcli/$(DEPDIR)/$(am__dirstamp) src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.$(OBJEXT): \ src/sss_client/sudo_testcli/$(am__dirstamp) \ src/sss_client/sudo_testcli/$(DEPDIR)/$(am__dirstamp) sss_sudo_cli$(EXEEXT): $(sss_sudo_cli_OBJECTS) $(sss_sudo_cli_DEPENDENCIES) $(EXTRA_sss_sudo_cli_DEPENDENCIES) @rm -f sss_sudo_cli$(EXEEXT) $(AM_V_CCLD)$(sss_sudo_cli_LINK) $(sss_sudo_cli_OBJECTS) $(sss_sudo_cli_LDADD) $(LIBS) src/tools/sss_useradd.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) sss_useradd$(EXEEXT): $(sss_useradd_OBJECTS) $(sss_useradd_DEPENDENCIES) $(EXTRA_sss_useradd_DEPENDENCIES) @rm -f sss_useradd$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sss_useradd_OBJECTS) $(sss_useradd_LDADD) $(LIBS) src/tools/sss_userdel-sss_userdel.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/sss_client/sss_userdel-common.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/tools/sss_userdel-tools_mc_util.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_userdel-sss_sync_ops.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_userdel-tools_util.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_userdel-files.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_userdel-selinux.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/common/sss_userdel-sss_tools.$(OBJEXT): \ src/tools/common/$(am__dirstamp) \ src/tools/common/$(DEPDIR)/$(am__dirstamp) src/util/sss_userdel-nscd.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) sss_userdel$(EXEEXT): $(sss_userdel_OBJECTS) $(sss_userdel_DEPENDENCIES) $(EXTRA_sss_userdel_DEPENDENCIES) @rm -f sss_userdel$(EXEEXT) $(AM_V_CCLD)$(sss_userdel_LINK) $(sss_userdel_OBJECTS) $(sss_userdel_LDADD) $(LIBS) src/tools/sss_usermod-sss_usermod.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/sss_client/sss_usermod-common.$(OBJEXT): \ src/sss_client/$(am__dirstamp) \ src/sss_client/$(DEPDIR)/$(am__dirstamp) src/tools/sss_usermod-tools_mc_util.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_usermod-sss_sync_ops.$(OBJEXT): \ src/tools/$(am__dirstamp) src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_usermod-tools_util.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_usermod-files.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/sss_usermod-selinux.$(OBJEXT): src/tools/$(am__dirstamp) \ src/tools/$(DEPDIR)/$(am__dirstamp) src/tools/common/sss_usermod-sss_tools.$(OBJEXT): \ src/tools/common/$(am__dirstamp) \ src/tools/common/$(DEPDIR)/$(am__dirstamp) src/util/sss_usermod-nscd.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) sss_usermod$(EXEEXT): $(sss_usermod_OBJECTS) $(sss_usermod_DEPENDENCIES) $(EXTRA_sss_usermod_DEPENDENCIES) @rm -f sss_usermod$(EXEEXT) $(AM_V_CCLD)$(sss_usermod_LINK) $(sss_usermod_OBJECTS) $(sss_usermod_LDADD) $(LIBS) src/monitor/monitor.$(OBJEXT): src/monitor/$(am__dirstamp) \ src/monitor/$(DEPDIR)/$(am__dirstamp) src/monitor/monitor_netlink.$(OBJEXT): src/monitor/$(am__dirstamp) \ src/monitor/$(DEPDIR)/$(am__dirstamp) src/confdb/confdb_setup.$(OBJEXT): src/confdb/$(am__dirstamp) \ src/confdb/$(DEPDIR)/$(am__dirstamp) src/monitor/monitor_iface_generated.$(OBJEXT): \ src/monitor/$(am__dirstamp) \ src/monitor/$(DEPDIR)/$(am__dirstamp) sssd$(EXEEXT): $(sssd_OBJECTS) $(sssd_DEPENDENCIES) $(EXTRA_sssd_DEPENDENCIES) @rm -f sssd$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sssd_OBJECTS) $(sssd_LDADD) $(LIBS) src/responder/autofs/$(am__dirstamp): @$(MKDIR_P) src/responder/autofs @: > src/responder/autofs/$(am__dirstamp) src/responder/autofs/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/responder/autofs/$(DEPDIR) @: > src/responder/autofs/$(DEPDIR)/$(am__dirstamp) src/responder/autofs/autofssrv.$(OBJEXT): \ src/responder/autofs/$(am__dirstamp) \ src/responder/autofs/$(DEPDIR)/$(am__dirstamp) src/responder/autofs/autofssrv_cmd.$(OBJEXT): \ src/responder/autofs/$(am__dirstamp) \ src/responder/autofs/$(DEPDIR)/$(am__dirstamp) src/responder/autofs/autofssrv_dp.$(OBJEXT): \ src/responder/autofs/$(am__dirstamp) \ src/responder/autofs/$(DEPDIR)/$(am__dirstamp) src/responder/common/negcache.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_cmd.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_common.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_dp.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_packet.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_get_domains.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_utils.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/responder_cache_req.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/providers/data_provider_iface_generated.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/data_provider_req.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) sssd_autofs$(EXEEXT): $(sssd_autofs_OBJECTS) $(sssd_autofs_DEPENDENCIES) $(EXTRA_sssd_autofs_DEPENDENCIES) @rm -f sssd_autofs$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sssd_autofs_OBJECTS) $(sssd_autofs_LDADD) $(LIBS) src/providers/data_provider_be.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/data_provider_fo.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/data_provider_opts.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/data_provider_callbacks.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/dp_dyndns.$(OBJEXT): src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/dp_ptask.$(OBJEXT): src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/dp_refresh.$(OBJEXT): src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/fail_over.$(OBJEXT): src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/fail_over_srv.$(OBJEXT): src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/resolv/async_resolv.$(OBJEXT): src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) src/resolv/async_resolv_utils.$(OBJEXT): src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) sssd_be$(EXEEXT): $(sssd_be_OBJECTS) $(sssd_be_DEPENDENCIES) $(EXTRA_sssd_be_DEPENDENCIES) @rm -f sssd_be$(EXEEXT) $(AM_V_CCLD)$(sssd_be_LINK) $(sssd_be_OBJECTS) $(sssd_be_LDADD) $(LIBS) src/responder/ifp/sssd_ifp-ifpsrv.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/sssd_ifp-ifpsrv_cmd.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/sssd_ifp-ifp_iface_generated.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/sssd_ifp-ifp_iface.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/sssd_ifp-ifp_iface_nodes.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/sssd_ifp-ifpsrv_util.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/sssd_ifp-ifp_domains.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/sssd_ifp-ifp_components.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/sssd_ifp-ifp_users.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/sssd_ifp-ifp_groups.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/ifp/sssd_ifp-ifp_cache.$(OBJEXT): \ src/responder/ifp/$(am__dirstamp) \ src/responder/ifp/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_ifp-negcache.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_ifp-responder_cmd.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_ifp-responder_common.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_ifp-responder_dp.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_ifp-responder_packet.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_ifp-responder_get_domains.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_ifp-responder_utils.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_ifp-responder_cache_req.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/monitor/sssd_ifp-monitor_iface_generated.$(OBJEXT): \ src/monitor/$(am__dirstamp) \ src/monitor/$(DEPDIR)/$(am__dirstamp) src/providers/sssd_ifp-data_provider_iface_generated.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/sssd_ifp-data_provider_req.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) sssd_ifp$(EXEEXT): $(sssd_ifp_OBJECTS) $(sssd_ifp_DEPENDENCIES) $(EXTRA_sssd_ifp_DEPENDENCIES) @rm -f sssd_ifp$(EXEEXT) $(AM_V_CCLD)$(sssd_ifp_LINK) $(sssd_ifp_OBJECTS) $(sssd_ifp_LDADD) $(LIBS) src/responder/nss/nsssrv.$(OBJEXT): src/responder/nss/$(am__dirstamp) \ src/responder/nss/$(DEPDIR)/$(am__dirstamp) src/responder/nss/nsssrv_cmd.$(OBJEXT): \ src/responder/nss/$(am__dirstamp) \ src/responder/nss/$(DEPDIR)/$(am__dirstamp) src/responder/nss/nsssrv_netgroup.$(OBJEXT): \ src/responder/nss/$(am__dirstamp) \ src/responder/nss/$(DEPDIR)/$(am__dirstamp) src/responder/nss/nsssrv_services.$(OBJEXT): \ src/responder/nss/$(am__dirstamp) \ src/responder/nss/$(DEPDIR)/$(am__dirstamp) src/responder/nss/nsssrv_mmap_cache.$(OBJEXT): \ src/responder/nss/$(am__dirstamp) \ src/responder/nss/$(DEPDIR)/$(am__dirstamp) sssd_nss$(EXEEXT): $(sssd_nss_OBJECTS) $(sssd_nss_DEPENDENCIES) $(EXTRA_sssd_nss_DEPENDENCIES) @rm -f sssd_nss$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sssd_nss_OBJECTS) $(sssd_nss_LDADD) $(LIBS) src/responder/pac/$(am__dirstamp): @$(MKDIR_P) src/responder/pac @: > src/responder/pac/$(am__dirstamp) src/responder/pac/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/responder/pac/$(DEPDIR) @: > src/responder/pac/$(DEPDIR)/$(am__dirstamp) src/responder/pac/sssd_pac-pacsrv.$(OBJEXT): \ src/responder/pac/$(am__dirstamp) \ src/responder/pac/$(DEPDIR)/$(am__dirstamp) src/responder/pac/sssd_pac-pacsrv_cmd.$(OBJEXT): \ src/responder/pac/$(am__dirstamp) \ src/responder/pac/$(DEPDIR)/$(am__dirstamp) src/responder/pac/sssd_pac-pacsrv_utils.$(OBJEXT): \ src/responder/pac/$(am__dirstamp) \ src/responder/pac/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_pac-negcache.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_pac-responder_cmd.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_pac-responder_common.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_pac-responder_dp.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_pac-responder_packet.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_pac-responder_get_domains.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_pac-responder_utils.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/sssd_pac-responder_cache_req.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/monitor/sssd_pac-monitor_iface_generated.$(OBJEXT): \ src/monitor/$(am__dirstamp) \ src/monitor/$(DEPDIR)/$(am__dirstamp) src/providers/sssd_pac-data_provider_iface_generated.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/sssd_pac-data_provider_req.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) sssd_pac$(EXEEXT): $(sssd_pac_OBJECTS) $(sssd_pac_DEPENDENCIES) $(EXTRA_sssd_pac_DEPENDENCIES) @rm -f sssd_pac$(EXEEXT) $(AM_V_CCLD)$(sssd_pac_LINK) $(sssd_pac_OBJECTS) $(sssd_pac_LDADD) $(LIBS) src/responder/pam/pam_LOCAL_domain.$(OBJEXT): \ src/responder/pam/$(am__dirstamp) \ src/responder/pam/$(DEPDIR)/$(am__dirstamp) src/responder/pam/pamsrv.$(OBJEXT): src/responder/pam/$(am__dirstamp) \ src/responder/pam/$(DEPDIR)/$(am__dirstamp) src/responder/pam/pamsrv_cmd.$(OBJEXT): \ src/responder/pam/$(am__dirstamp) \ src/responder/pam/$(DEPDIR)/$(am__dirstamp) src/responder/pam/pamsrv_p11.$(OBJEXT): \ src/responder/pam/$(am__dirstamp) \ src/responder/pam/$(DEPDIR)/$(am__dirstamp) src/responder/pam/pamsrv_dp.$(OBJEXT): \ src/responder/pam/$(am__dirstamp) \ src/responder/pam/$(DEPDIR)/$(am__dirstamp) src/responder/pam/pam_helpers.$(OBJEXT): \ src/responder/pam/$(am__dirstamp) \ src/responder/pam/$(DEPDIR)/$(am__dirstamp) sssd_pam$(EXEEXT): $(sssd_pam_OBJECTS) $(sssd_pam_DEPENDENCIES) $(EXTRA_sssd_pam_DEPENDENCIES) @rm -f sssd_pam$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sssd_pam_OBJECTS) $(sssd_pam_LDADD) $(LIBS) src/responder/ssh/$(am__dirstamp): @$(MKDIR_P) src/responder/ssh @: > src/responder/ssh/$(am__dirstamp) src/responder/ssh/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/responder/ssh/$(DEPDIR) @: > src/responder/ssh/$(DEPDIR)/$(am__dirstamp) src/responder/ssh/sshsrv.$(OBJEXT): src/responder/ssh/$(am__dirstamp) \ src/responder/ssh/$(DEPDIR)/$(am__dirstamp) src/responder/ssh/sshsrv_dp.$(OBJEXT): \ src/responder/ssh/$(am__dirstamp) \ src/responder/ssh/$(DEPDIR)/$(am__dirstamp) src/responder/ssh/sshsrv_cmd.$(OBJEXT): \ src/responder/ssh/$(am__dirstamp) \ src/responder/ssh/$(DEPDIR)/$(am__dirstamp) sssd_ssh$(EXEEXT): $(sssd_ssh_OBJECTS) $(sssd_ssh_DEPENDENCIES) $(EXTRA_sssd_ssh_DEPENDENCIES) @rm -f sssd_ssh$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sssd_ssh_OBJECTS) $(sssd_ssh_LDADD) $(LIBS) src/responder/sudo/$(am__dirstamp): @$(MKDIR_P) src/responder/sudo @: > src/responder/sudo/$(am__dirstamp) src/responder/sudo/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) src/responder/sudo/$(DEPDIR) @: > src/responder/sudo/$(DEPDIR)/$(am__dirstamp) src/responder/sudo/sudosrv.$(OBJEXT): \ src/responder/sudo/$(am__dirstamp) \ src/responder/sudo/$(DEPDIR)/$(am__dirstamp) src/responder/sudo/sudosrv_cmd.$(OBJEXT): \ src/responder/sudo/$(am__dirstamp) \ src/responder/sudo/$(DEPDIR)/$(am__dirstamp) src/responder/sudo/sudosrv_get_sudorules.$(OBJEXT): \ src/responder/sudo/$(am__dirstamp) \ src/responder/sudo/$(DEPDIR)/$(am__dirstamp) src/responder/sudo/sudosrv_query.$(OBJEXT): \ src/responder/sudo/$(am__dirstamp) \ src/responder/sudo/$(DEPDIR)/$(am__dirstamp) src/responder/sudo/sudosrv_dp.$(OBJEXT): \ src/responder/sudo/$(am__dirstamp) \ src/responder/sudo/$(DEPDIR)/$(am__dirstamp) sssd_sudo$(EXEEXT): $(sssd_sudo_OBJECTS) $(sssd_sudo_DEPENDENCIES) $(EXTRA_sssd_sudo_DEPENDENCIES) @rm -f sssd_sudo$(EXEEXT) $(AM_V_CCLD)$(LINK) $(sssd_sudo_OBJECTS) $(sssd_sudo_LDADD) $(LIBS) src/tests/stress-tests.$(OBJEXT): src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) stress-tests$(EXEEXT): $(stress_tests_OBJECTS) $(stress_tests_DEPENDENCIES) $(EXTRA_stress_tests_DEPENDENCIES) @rm -f stress-tests$(EXEEXT) $(AM_V_CCLD)$(LINK) $(stress_tests_OBJECTS) $(stress_tests_LDADD) $(LIBS) src/tests/strtonum_tests-strtonum-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) src/util/strtonum_tests-strtonum.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) strtonum-tests$(EXEEXT): $(strtonum_tests_OBJECTS) $(strtonum_tests_DEPENDENCIES) $(EXTRA_strtonum_tests_DEPENDENCIES) @rm -f strtonum-tests$(EXEEXT) $(AM_V_CCLD)$(strtonum_tests_LINK) $(strtonum_tests_OBJECTS) $(strtonum_tests_LDADD) $(LIBS) src/tests/sysdb_tests-sysdb-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) sysdb-tests$(EXEEXT): $(sysdb_tests_OBJECTS) $(sysdb_tests_DEPENDENCIES) $(EXTRA_sysdb_tests_DEPENDENCIES) @rm -f sysdb-tests$(EXEEXT) $(AM_V_CCLD)$(sysdb_tests_LINK) $(sysdb_tests_OBJECTS) $(sysdb_tests_LDADD) $(LIBS) src/tests/sysdb_ssh_tests-sysdb_ssh-tests.$(OBJEXT): \ src/tests/$(am__dirstamp) src/tests/$(DEPDIR)/$(am__dirstamp) sysdb_ssh-tests$(EXEEXT): $(sysdb_ssh_tests_OBJECTS) $(sysdb_ssh_tests_DEPENDENCIES) $(EXTRA_sysdb_ssh_tests_DEPENDENCIES) @rm -f sysdb_ssh-tests$(EXEEXT) $(AM_V_CCLD)$(sysdb_ssh_tests_LINK) $(sysdb_ssh_tests_OBJECTS) $(sysdb_ssh_tests_LDADD) $(LIBS) src/tests/cmocka/test_authtok-test_authtok.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/util/test_authtok-authtok.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/test_authtok-authtok-utils.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/util/test_authtok-util.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) test-authtok$(EXEEXT): $(test_authtok_OBJECTS) $(test_authtok_DEPENDENCIES) $(EXTRA_test_authtok_DEPENDENCIES) @rm -f test-authtok$(EXEEXT) $(AM_V_CCLD)$(test_authtok_LINK) $(test_authtok_OBJECTS) $(test_authtok_LDADD) $(LIBS) src/tests/cmocka/test_find_uid-test_find_uid.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/util/test_find_uid-find_uid.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/test_find_uid-atomic_io.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/test_find_uid-strtonum.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) test-find-uid$(EXEEXT): $(test_find_uid_OBJECTS) $(test_find_uid_DEPENDENCIES) $(EXTRA_test_find_uid_DEPENDENCIES) @rm -f test-find-uid$(EXEEXT) $(AM_V_CCLD)$(test_find_uid_LINK) $(test_find_uid_OBJECTS) $(test_find_uid_LDADD) $(LIBS) src/tests/cmocka/test_io-test_io.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/util/test_io-io.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/tests/test_io-common.$(OBJEXT): src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) test-io$(EXEEXT): $(test_io_OBJECTS) $(test_io_DEPENDENCIES) $(EXTRA_test_io_DEPENDENCIES) @rm -f test-io$(EXEEXT) $(AM_V_CCLD)$(test_io_LINK) $(test_io_OBJECTS) $(test_io_LDADD) $(LIBS) src/responder/common/test_negcache-negcache.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/test_negcache-responder_cmd.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/test_negcache-responder_common.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/test_negcache-responder_dp.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/test_negcache-responder_packet.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/test_negcache-responder_get_domains.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/test_negcache-responder_utils.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/responder/common/test_negcache-responder_cache_req.$(OBJEXT): \ src/responder/common/$(am__dirstamp) \ src/responder/common/$(DEPDIR)/$(am__dirstamp) src/monitor/test_negcache-monitor_iface_generated.$(OBJEXT): \ src/monitor/$(am__dirstamp) \ src/monitor/$(DEPDIR)/$(am__dirstamp) src/providers/test_negcache-data_provider_iface_generated.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/test_negcache-data_provider_req.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_negcache-test_negcache.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test-negcache$(EXEEXT): $(test_negcache_OBJECTS) $(test_negcache_DEPENDENCIES) $(EXTRA_test_negcache_DEPENDENCIES) @rm -f test-negcache$(EXEEXT) $(AM_V_CCLD)$(test_negcache_LINK) $(test_negcache_OBJECTS) $(test_negcache_LDADD) $(LIBS) src/tests/cmocka/test_be_ptask-common_mock_be.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_be_ptask-test_be_ptask.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/test_be_ptask-dp_ptask.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) test_be_ptask$(EXEEXT): $(test_be_ptask_OBJECTS) $(test_be_ptask_DEPENDENCIES) $(EXTRA_test_be_ptask_DEPENDENCIES) @rm -f test_be_ptask$(EXEEXT) $(AM_V_CCLD)$(test_be_ptask_LINK) $(test_be_ptask_OBJECTS) $(test_be_ptask_LDADD) $(LIBS) src/tests/cmocka/test_cert_utils-test_cert_utils.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_cert_utils$(EXEEXT): $(test_cert_utils_OBJECTS) $(test_cert_utils_DEPENDENCIES) $(EXTRA_test_cert_utils_DEPENDENCIES) @rm -f test_cert_utils$(EXEEXT) $(AM_V_CCLD)$(test_cert_utils_LINK) $(test_cert_utils_OBJECTS) $(test_cert_utils_LDADD) $(LIBS) src/tests/cmocka/test_child_common-test_child_common.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/util/test_child_common-child_common.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/util/test_child_common-signal.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) src/util/test_child_common-atomic_io.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/util/test_child_common-util_errors.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/util/test_child_common-util.$(OBJEXT): src/util/$(am__dirstamp) \ src/util/$(DEPDIR)/$(am__dirstamp) test_child_common$(EXEEXT): $(test_child_common_OBJECTS) $(test_child_common_DEPENDENCIES) $(EXTRA_test_child_common_DEPENDENCIES) @rm -f test_child_common$(EXEEXT) $(AM_V_CCLD)$(test_child_common_LINK) $(test_child_common_OBJECTS) $(test_child_common_LDADD) $(LIBS) src/tests/cmocka/test_copy_ccache-test_copy_ccache.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_copy_ccache-krb5_ccache.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/util/test_copy_ccache-sss_krb5.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) test_copy_ccache$(EXEEXT): $(test_copy_ccache_OBJECTS) $(test_copy_ccache_DEPENDENCIES) $(EXTRA_test_copy_ccache_DEPENDENCIES) @rm -f test_copy_ccache$(EXEEXT) $(AM_V_CCLD)$(test_copy_ccache_LINK) $(test_copy_ccache_OBJECTS) $(test_copy_ccache_LDADD) $(LIBS) src/tests/cmocka/test_copy_keytab-common_mock_krb5.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_copy_keytab-test_copy_keytab.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_copy_keytab-krb5_keytab.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/util/test_copy_keytab-sss_krb5.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) test_copy_keytab$(EXEEXT): $(test_copy_keytab_OBJECTS) $(test_copy_keytab_DEPENDENCIES) $(EXTRA_test_copy_keytab_DEPENDENCIES) @rm -f test_copy_keytab$(EXEEXT) $(AM_V_CCLD)$(test_copy_keytab_LINK) $(test_copy_keytab_OBJECTS) $(test_copy_keytab_LDADD) $(LIBS) src/providers/test_data_provider_be-data_provider_be.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_data_provider_be-test_data_provider_be.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_data_provider_be-common_mock_be.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_data_provider_be$(EXEEXT): $(test_data_provider_be_OBJECTS) $(test_data_provider_be_DEPENDENCIES) $(EXTRA_test_data_provider_be_DEPENDENCIES) @rm -f test_data_provider_be$(EXEEXT) $(AM_V_CCLD)$(test_data_provider_be_LINK) $(test_data_provider_be_OBJECTS) $(test_data_provider_be_LDADD) $(LIBS) src/tests/cmocka/test_fo_srv-test_fo_srv.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/test_fo_srv-fail_over.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) src/providers/test_fo_srv-fail_over_srv.$(OBJEXT): \ src/providers/$(am__dirstamp) \ src/providers/$(DEPDIR)/$(am__dirstamp) test_fo_srv$(EXEEXT): $(test_fo_srv_OBJECTS) $(test_fo_srv_DEPENDENCIES) $(EXTRA_test_fo_srv_DEPENDENCIES) @rm -f test_fo_srv$(EXEEXT) $(AM_V_CCLD)$(test_fo_srv_LINK) $(test_fo_srv_OBJECTS) $(test_fo_srv_LDADD) $(LIBS) src/providers/ipa/test_ipa_dn-ipa_dn.$(OBJEXT): \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_ipa_dn-test_ipa_dn.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_ipa_dn$(EXEEXT): $(test_ipa_dn_OBJECTS) $(test_ipa_dn_DEPENDENCIES) $(EXTRA_test_ipa_dn_DEPENDENCIES) @rm -f test_ipa_dn$(EXEEXT) $(AM_V_CCLD)$(test_ipa_dn_LINK) $(test_ipa_dn_OBJECTS) $(test_ipa_dn_LDADD) $(LIBS) src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/test_ipa_idmap-ipa_idmap.$(OBJEXT): \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) test_ipa_idmap$(EXEEXT): $(test_ipa_idmap_OBJECTS) $(test_ipa_idmap_DEPENDENCIES) $(EXTRA_test_ipa_idmap_DEPENDENCIES) @rm -f test_ipa_idmap$(EXEEXT) $(AM_V_CCLD)$(test_ipa_idmap_LINK) $(test_ipa_idmap_OBJECTS) $(test_ipa_idmap_LDADD) $(LIBS) src/providers/krb5/test_ipa_subdom_server-krb5_utils.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_ipa_subdom_server-krb5_common.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_ipa_subdom_server-krb5_opts.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_ipa_subdom_server-krb5_auth.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_ipa_subdom_server-krb5_access.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_ipa_subdom_server-krb5_ccache.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) src/util/test_ipa_subdom_server-sss_krb5.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/util/test_ipa_subdom_server-become_user.$(OBJEXT): \ src/util/$(am__dirstamp) src/util/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_ipa_subdom_server-common_mock_be.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.$(OBJEXT): \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.$(OBJEXT): \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/test_ipa_subdom_server-ipa_opts.$(OBJEXT): \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) test_ipa_subdom_server$(EXEEXT): $(test_ipa_subdom_server_OBJECTS) $(test_ipa_subdom_server_DEPENDENCIES) $(EXTRA_test_ipa_subdom_server_DEPENDENCIES) @rm -f test_ipa_subdom_server$(EXEEXT) $(AM_V_CCLD)$(test_ipa_subdom_server_LINK) $(test_ipa_subdom_server_OBJECTS) $(test_ipa_subdom_server_LDADD) $(LIBS) src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.$(OBJEXT): \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) test_ipa_subdom_util$(EXEEXT): $(test_ipa_subdom_util_OBJECTS) $(test_ipa_subdom_util_DEPENDENCIES) $(EXTRA_test_ipa_subdom_util_DEPENDENCIES) @rm -f test_ipa_subdom_util$(EXEEXT) $(AM_V_CCLD)$(test_ipa_subdom_util_LINK) $(test_ipa_subdom_util_OBJECTS) $(test_ipa_subdom_util_LDADD) $(LIBS) src/tests/cmocka/test_krb5_wait_queue-common_mock_be.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.$(OBJEXT): \ src/providers/krb5/$(am__dirstamp) \ src/providers/krb5/$(DEPDIR)/$(am__dirstamp) test_krb5_wait_queue$(EXEEXT): $(test_krb5_wait_queue_OBJECTS) $(test_krb5_wait_queue_DEPENDENCIES) $(EXTRA_test_krb5_wait_queue_DEPENDENCIES) @rm -f test_krb5_wait_queue$(EXEEXT) $(AM_V_CCLD)$(test_krb5_wait_queue_LINK) $(test_krb5_wait_queue_OBJECTS) $(test_krb5_wait_queue_LDADD) $(LIBS) src/tests/cmocka/test_ldap_auth.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_expire_common.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_ldap_auth$(EXEEXT): $(test_ldap_auth_OBJECTS) $(test_ldap_auth_DEPENDENCIES) $(EXTRA_test_ldap_auth_DEPENDENCIES) @rm -f test_ldap_auth$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_ldap_auth_OBJECTS) $(test_ldap_auth_LDADD) $(LIBS) src/tests/cmocka/test_ldap_id_cleanup.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_ldap_id_cleanup$(EXEEXT): $(test_ldap_id_cleanup_OBJECTS) $(test_ldap_id_cleanup_DEPENDENCIES) $(EXTRA_test_ldap_id_cleanup_DEPENDENCIES) @rm -f test_ldap_id_cleanup$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_ldap_id_cleanup_OBJECTS) $(test_ldap_id_cleanup_LDADD) $(LIBS) src/tests/cmocka/test_resolv_fake-test_resolv_fake.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/resolv/test_resolv_fake-async_resolv.$(OBJEXT): \ src/resolv/$(am__dirstamp) \ src/resolv/$(DEPDIR)/$(am__dirstamp) test_resolv_fake$(EXEEXT): $(test_resolv_fake_OBJECTS) $(test_resolv_fake_DEPENDENCIES) $(EXTRA_test_resolv_fake_DEPENDENCIES) @rm -f test_resolv_fake$(EXEEXT) $(AM_V_CCLD)$(test_resolv_fake_LINK) $(test_resolv_fake_OBJECTS) $(test_resolv_fake_LDADD) $(LIBS) src/tests/cmocka/test_sbus_opath-test_sbus_opath.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_sbus_opath$(EXEEXT): $(test_sbus_opath_OBJECTS) $(test_sbus_opath_DEPENDENCIES) $(EXTRA_test_sbus_opath_DEPENDENCIES) @rm -f test_sbus_opath$(EXEEXT) $(AM_V_CCLD)$(test_sbus_opath_LINK) $(test_sbus_opath_OBJECTS) $(test_sbus_opath_LDADD) $(LIBS) src/tests/cmocka/test_sdap_access.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_sdap_access$(EXEEXT): $(test_sdap_access_OBJECTS) $(test_sdap_access_DEPENDENCIES) $(EXTRA_test_sdap_access_DEPENDENCIES) @rm -f test_sdap_access$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_sdap_access_OBJECTS) $(test_sdap_access_LDADD) $(LIBS) src/tests/cmocka/test_search_bases.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_search_bases$(EXEEXT): $(test_search_bases_OBJECTS) $(test_search_bases_DEPENDENCIES) $(EXTRA_test_search_bases_DEPENDENCIES) @rm -f test_search_bases$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_search_bases_OBJECTS) $(test_search_bases_LDADD) $(LIBS) src/tests/cmocka/test_sss_idmap-test_sss_idmap.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_sss_idmap$(EXEEXT): $(test_sss_idmap_OBJECTS) $(test_sss_idmap_DEPENDENCIES) $(EXTRA_test_sss_idmap_DEPENDENCIES) @rm -f test_sss_idmap$(EXEEXT) $(AM_V_CCLD)$(test_sss_idmap_LINK) $(test_sss_idmap_OBJECTS) $(test_sss_idmap_LDADD) $(LIBS) src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_sysdb_subdomains$(EXEEXT): $(test_sysdb_subdomains_OBJECTS) $(test_sysdb_subdomains_DEPENDENCIES) $(EXTRA_test_sysdb_subdomains_DEPENDENCIES) @rm -f test_sysdb_subdomains$(EXEEXT) $(AM_V_CCLD)$(test_sysdb_subdomains_LINK) $(test_sysdb_subdomains_OBJECTS) $(test_sysdb_subdomains_LDADD) $(LIBS) src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_sysdb_utils$(EXEEXT): $(test_sysdb_utils_OBJECTS) $(test_sysdb_utils_DEPENDENCIES) $(EXTRA_test_sysdb_utils_DEPENDENCIES) @rm -f test_sysdb_utils$(EXEEXT) $(AM_V_CCLD)$(test_sysdb_utils_LINK) $(test_sysdb_utils_OBJECTS) $(test_sysdb_utils_LDADD) $(LIBS) src/tests/cmocka/test_sysdb_views-test_sysdb_views.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/providers/ipa/test_sysdb_views-ipa_utils.$(OBJEXT): \ src/providers/ipa/$(am__dirstamp) \ src/providers/ipa/$(DEPDIR)/$(am__dirstamp) test_sysdb_views$(EXEEXT): $(test_sysdb_views_OBJECTS) $(test_sysdb_views_DEPENDENCIES) $(EXTRA_test_sysdb_views_DEPENDENCIES) @rm -f test_sysdb_views$(EXEEXT) $(AM_V_CCLD)$(test_sysdb_views_LINK) $(test_sysdb_views_OBJECTS) $(test_sysdb_views_LDADD) $(LIBS) src/tests/cmocka/test_tools_colondb-test_tools_colondb.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tools/common/test_tools_colondb-sss_colondb.$(OBJEXT): \ src/tools/common/$(am__dirstamp) \ src/tools/common/$(DEPDIR)/$(am__dirstamp) test_tools_colondb$(EXEEXT): $(test_tools_colondb_OBJECTS) $(test_tools_colondb_DEPENDENCIES) $(EXTRA_test_tools_colondb_DEPENDENCIES) @rm -f test_tools_colondb$(EXEEXT) $(AM_V_CCLD)$(test_tools_colondb_LINK) $(test_tools_colondb_OBJECTS) $(test_tools_colondb_LDADD) $(LIBS) src/tests/cmocka/test_utils-test_utils.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_utils-test_sss_ssh.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) src/tests/cmocka/test_utils-test_string_utils.$(OBJEXT): \ src/tests/cmocka/$(am__dirstamp) \ src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) test_utils$(EXEEXT): $(test_utils_OBJECTS) $(test_utils_DEPENDENCIES) $(EXTRA_test_utils_DEPENDENCIES) @rm -f test_utils$(EXEEXT) $(AM_V_CCLD)$(test_utils_LINK) $(test_utils_OBJECTS) $(test_utils_LDADD) $(LIBS) src/tests/util_tests-util-tests.$(OBJEXT): src/tests/$(am__dirstamp) \ src/tests/$(DEPDIR)/$(am__dirstamp) util-tests$(EXEEXT): $(util_tests_OBJECTS) $(util_tests_DEPENDENCIES) $(EXTRA_util_tests_DEPENDENCIES) @rm -f util-tests$(EXEEXT) $(AM_V_CCLD)$(util_tests_LINK) $(util_tests_OBJECTS) $(util_tests_LDADD) $(LIBS) install-dist_sss_obfuscate_pythonSCRIPTS: $(dist_sss_obfuscate_python_SCRIPTS) @$(NORMAL_INSTALL) @list='$(dist_sss_obfuscate_python_SCRIPTS)'; test -n "$(sss_obfuscate_pythondir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sss_obfuscate_pythondir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sss_obfuscate_pythondir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(sss_obfuscate_pythondir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(sss_obfuscate_pythondir)$$dir" || exit $$?; \ } \ ; done uninstall-dist_sss_obfuscate_pythonSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(dist_sss_obfuscate_python_SCRIPTS)'; test -n "$(sss_obfuscate_pythondir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(sss_obfuscate_pythondir)'; $(am__uninstall_files_from_dir) install-initSCRIPTS: $(init_SCRIPTS) @$(NORMAL_INSTALL) @list='$(init_SCRIPTS)'; test -n "$(initdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(initdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(initdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(initdir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(initdir)$$dir" || exit $$?; \ } \ ; done uninstall-initSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(init_SCRIPTS)'; test -n "$(initdir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(initdir)'; $(am__uninstall_files_from_dir) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f src/confdb/*.$(OBJEXT) -rm -f src/confdb/*.lo -rm -f src/db/*.$(OBJEXT) -rm -f src/db/*.lo -rm -f src/krb5_plugin/*.$(OBJEXT) -rm -f src/krb5_plugin/*.lo -rm -f src/ldb_modules/*.$(OBJEXT) -rm -f src/ldb_modules/*.lo -rm -f src/lib/cifs_idmap_sss/*.$(OBJEXT) -rm -f src/lib/cifs_idmap_sss/*.lo -rm -f src/lib/idmap/*.$(OBJEXT) -rm -f src/lib/idmap/*.lo -rm -f src/lib/sifp/*.$(OBJEXT) -rm -f src/lib/sifp/*.lo -rm -f src/monitor/*.$(OBJEXT) -rm -f src/monitor/*.lo -rm -f src/p11_child/*.$(OBJEXT) -rm -f src/providers/*.$(OBJEXT) -rm -f src/providers/*.lo -rm -f src/providers/ad/*.$(OBJEXT) -rm -f src/providers/ad/*.lo -rm -f src/providers/ipa/*.$(OBJEXT) -rm -f src/providers/ipa/*.lo -rm -f src/providers/krb5/*.$(OBJEXT) -rm -f src/providers/krb5/*.lo -rm -f src/providers/ldap/*.$(OBJEXT) -rm -f src/providers/ldap/*.lo -rm -f src/providers/proxy/*.$(OBJEXT) -rm -f src/providers/proxy/*.lo -rm -f src/providers/simple/*.$(OBJEXT) -rm -f src/providers/simple/*.lo -rm -f src/python/*.$(OBJEXT) -rm -f src/python/*.lo -rm -f src/resolv/*.$(OBJEXT) -rm -f src/resolv/*.lo -rm -f src/responder/autofs/*.$(OBJEXT) -rm -f src/responder/common/*.$(OBJEXT) -rm -f src/responder/ifp/*.$(OBJEXT) -rm -f src/responder/nss/*.$(OBJEXT) -rm -f src/responder/pac/*.$(OBJEXT) -rm -f src/responder/pam/*.$(OBJEXT) -rm -f src/responder/ssh/*.$(OBJEXT) -rm -f src/responder/sudo/*.$(OBJEXT) -rm -f src/sbus/*.$(OBJEXT) -rm -f src/sbus/*.lo -rm -f src/sss_client/*.$(OBJEXT) -rm -f src/sss_client/*.lo -rm -f src/sss_client/autofs/*.$(OBJEXT) -rm -f src/sss_client/autofs/*.lo -rm -f src/sss_client/idmap/*.$(OBJEXT) -rm -f src/sss_client/idmap/*.lo -rm -f src/sss_client/libwbclient/*.$(OBJEXT) -rm -f src/sss_client/libwbclient/*.lo -rm -f src/sss_client/nfs/*.$(OBJEXT) -rm -f src/sss_client/nfs/*.lo -rm -f src/sss_client/ssh/*.$(OBJEXT) -rm -f src/sss_client/sudo/*.$(OBJEXT) -rm -f src/sss_client/sudo/*.lo -rm -f src/sss_client/sudo_testcli/*.$(OBJEXT) -rm -f src/tests/*.$(OBJEXT) -rm -f src/tests/*.lo -rm -f src/tests/cmocka/*.$(OBJEXT) -rm -f src/tools/*.$(OBJEXT) -rm -f src/tools/*.lo -rm -f src/tools/common/*.$(OBJEXT) -rm -f src/tools/common/*.lo -rm -f src/util/*.$(OBJEXT) -rm -f src/util/*.lo -rm -f src/util/cert/*.$(OBJEXT) -rm -f src/util/cert/*.lo -rm -f src/util/cert/libcrypto/*.$(OBJEXT) -rm -f src/util/cert/libcrypto/*.lo -rm -f src/util/cert/nss/*.$(OBJEXT) -rm -f src/util/cert/nss/*.lo -rm -f src/util/crypto/libcrypto/*.$(OBJEXT) -rm -f src/util/crypto/libcrypto/*.lo -rm -f src/util/crypto/nss/*.$(OBJEXT) -rm -f src/util/crypto/nss/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@src/confdb/$(DEPDIR)/confdb_setup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/confdb/$(DEPDIR)/libsss_util_la-confdb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_autofs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_gpo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_idmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_ops.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_ranges.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_search.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_selinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_services.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_ssh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_subdomains.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_sudo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_upgrade.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/db/$(DEPDIR)/libsss_util_la-sysdb_views.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/krb5_plugin/$(DEPDIR)/sssd_krb5_localauth_plugin_la-sssd_krb5_localauth_plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/krb5_plugin/$(DEPDIR)/sssd_krb5_locator_plugin_la-sssd_krb5_locator_plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/ldb_modules/$(DEPDIR)/memberof_la-memberof.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/cifs_idmap_sss/$(DEPDIR)/cifs_idmap_sss_la-cifs_idmap_sss.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/idmap/$(DEPDIR)/sss_idmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/idmap/$(DEPDIR)/sss_idmap_conv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_attrs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_dbus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_parser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_attrs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_dbus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_parser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/monitor/$(DEPDIR)/libdlopen_test_providers_la-monitor_iface_generated.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/monitor/$(DEPDIR)/libsss_util_la-monitor_sbus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/monitor/$(DEPDIR)/monitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/monitor/$(DEPDIR)/monitor_iface_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/monitor/$(DEPDIR)/monitor_netlink.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/monitor/$(DEPDIR)/sssd_ifp-monitor_iface_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/monitor/$(DEPDIR)/sssd_pac-monitor_iface_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/monitor/$(DEPDIR)/test_negcache-monitor_iface_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/p11_child/$(DEPDIR)/p11_child-p11_child_nss.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/data_provider_be.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/data_provider_callbacks.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/data_provider_fo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/data_provider_iface_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/data_provider_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/data_provider_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/dp_dyndns.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/dp_opt_tests-data_provider_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/dp_ptask.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/dp_refresh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/dyndns_tests-data_provider_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/fail_over.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/fail_over_srv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/fail_over_tests-fail_over.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/fail_over_tests-fail_over_srv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/ipa_ldap_opt_tests-data_provider_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/krb5_child-dp_pam_data_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/krb5_child_test-data_provider_callbacks.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/krb5_child_test-data_provider_fo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/krb5_child_test-data_provider_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/krb5_child_test-fail_over.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/krb5_child_test-fail_over_srv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_callbacks.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_fo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/krb5_utils_tests-fail_over.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/krb5_utils_tests-fail_over_srv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_be.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_callbacks.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_fo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_iface_generated.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_opts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_req.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_dyndns.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_ptask.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_refresh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libdlopen_test_providers_la-fail_over.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libdlopen_test_providers_la-fail_over_srv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libsss_proxy_la-data_provider_iface_generated.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libsss_util_la-dp_auth_util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libsss_util_la-dp_pam_data_util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/libsss_util_la-dp_sbus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/nestedgroups_tests-data_provider_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/proxy_child-data_provider_iface_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/sdap_tests-data_provider_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/sssd_ifp-data_provider_iface_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/sssd_ifp-data_provider_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/sssd_pac-data_provider_iface_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/sssd_pac-data_provider_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/test_be_ptask-dp_ptask.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/test_data_provider_be-data_provider_be.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/test_fo_srv-fail_over.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/test_fo_srv-fail_over_srv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/test_negcache-data_provider_iface_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/$(DEPDIR)/test_negcache-data_provider_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/ad_ldap_opt_tests-ad_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/ad_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/gpo_child-ad_gpo_child.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/ipa_ldap_opt_tests-ad_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_access.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_autofs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_domain_info.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_dyndns.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_gpo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_gpo_ndr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_id.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_machine_pw_renewal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_opts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_srv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_subdomains.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_sudo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_access.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_autofs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_domain_info.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_dyndns.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_gpo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_gpo_ndr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_id.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_machine_pw_renewal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_opts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_srv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_subdomains.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_sudo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_domain_info.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_dyndns.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_id.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_opts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_srv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/hbac_evaluator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/ipa_ldap_opt_tests-ipa_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_access.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_auth.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_autofs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_dn.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_dyndns.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_hosts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_rules.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_services.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_users.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hostid.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hosts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_id.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_idmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_netgroups.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_opts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_s2n_exop.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_selinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_selinux_maps.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_srv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_ext_groups.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_id.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_server.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_async.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_conversion.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_refresh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_views.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/libsss_ldap_common_la-ipa_dn.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/nestedgroups_tests-ipa_dn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/sdap_tests-ipa_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/selinux_child-selinux_child.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/test_ipa_dn-ipa_dn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/test_ipa_idmap-ipa_idmap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_server.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/test_ipa_subdom_util-ipa_subdomains_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ipa/$(DEPDIR)/test_sysdb_views-ipa_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/ad_ldap_opt_tests-krb5_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/ipa_ldap_opt_tests-krb5_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_access.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_ccache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_child-krb5_ccache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_child-krb5_child.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_child-krb5_keytab.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_child_handler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_ccache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_child_handler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_delayed_online_authentication.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_init_shared.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_renew_tgt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_ccache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/krb5_wait_queue.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/ldap_child-krb5_keytab.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_access.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_auth.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_ccache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_child_handler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_delayed_online_authentication.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_init_shared.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_opts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_renew_tgt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_wait_queue.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/libsss_krb5_la-krb5_init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_copy_ccache-krb5_ccache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_copy_keytab-krb5_keytab.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_access.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_ccache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_child_handler.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_delayed_online_authentication.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_init_shared.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_renew_tgt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_wait_queue.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/krb5/$(DEPDIR)/test_krb5_wait_queue-krb5_wait_queue.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/ad_ldap_opt_tests-ldap_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-ldap_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_domain.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_range.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/ldap_child-ldap_child.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_auth.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_cleanup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_enum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_netgroup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_services.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_options.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_opts.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_access.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_ad_groups.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_autofs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_enum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_groups.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_groups_ad.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_initgroups.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_initgroups_ad.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_nested_groups.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_netgroups.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_services.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_sudo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_sudo_hostinfo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_users.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_autofs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_child_helpers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_domain.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_dyndns.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_fd_events.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_id_op.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_idmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_ops.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_range.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_refresh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_reinit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo_refresh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo_shared.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_la-ldap_access.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/libsss_ldap_la-ldap_init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_options.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_ad_groups.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_async_nested_groups.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_domain.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_idmap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_range.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/sdap_tests-ldap_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/sdap_tests-sdap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_domain.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_range.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_auth.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_id.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_init.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_netgroup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_services.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/proxy/$(DEPDIR)/proxy_child-proxy_child.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/simple/$(DEPDIR)/libsss_simple_la-simple_access.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/simple/$(DEPDIR)/libsss_simple_la-simple_access_check.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/simple/$(DEPDIR)/simple_access.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/providers/simple/$(DEPDIR)/simple_access_check.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/python/$(DEPDIR)/_py2hbac_la-pyhbac.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/python/$(DEPDIR)/_py2sss_la-pysss.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/python/$(DEPDIR)/_py2sss_murmur_la-pysss_murmur.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/python/$(DEPDIR)/_py2sss_nss_idmap_la-pysss_nss_idmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/python/$(DEPDIR)/_py3hbac_la-pyhbac.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/python/$(DEPDIR)/_py3sss_la-pysss.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/python/$(DEPDIR)/_py3sss_murmur_la-pysss_murmur.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/python/$(DEPDIR)/_py3sss_nss_idmap_la-pysss_nss_idmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/async_resolv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/async_resolv_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/dyndns_tests-async_resolv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/dyndns_tests-async_resolv_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/fail_over_tests-async_resolv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/fail_over_tests-async_resolv_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/krb5_child_test-async_resolv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/krb5_child_test-async_resolv_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/libdlopen_test_providers_la-async_resolv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/libdlopen_test_providers_la-async_resolv_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/resolv_tests-async_resolv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/resolv_tests-async_resolv_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/resolv/$(DEPDIR)/test_resolv_fake-async_resolv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/autofs/$(DEPDIR)/autofssrv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/autofs/$(DEPDIR)/autofssrv_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/autofs/$(DEPDIR)/autofssrv_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/ifp_tests-negcache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/ifp_tests-responder_cache_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/ifp_tests-responder_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/ifp_tests-responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/ifp_tests-responder_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/ifp_tests-responder_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/negcache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/nss_srv_tests-negcache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cache_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/nss_srv_tests-responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/nss_srv_tests-responder_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/pam_srv_tests-negcache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cache_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/pam_srv_tests-responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/pam_srv_tests-responder_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_cache_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_cache_req_tests-negcache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cache_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_get_domains.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_get_domains_tests-responder_get_domains.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/responder_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_ifp-negcache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_ifp-responder_cache_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_ifp-responder_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_ifp-responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_ifp-responder_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_ifp-responder_get_domains.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_ifp-responder_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_ifp-responder_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_pac-negcache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_pac-responder_cache_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_pac-responder_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_pac-responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_pac-responder_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_pac-responder_get_domains.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_pac-responder_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/sssd_pac-responder_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/test_negcache-negcache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/test_negcache-responder_cache_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/test_negcache-responder_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/test_negcache-responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/test_negcache-responder_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/test_negcache-responder_get_domains.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/test_negcache-responder_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/common/$(DEPDIR)/test_negcache-responder_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/ifp_tests-ifp_iface_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_components.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_domains.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_groups.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_nodes.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_users.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_mmap_cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_netgroup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_services.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/nss/$(DEPDIR)/nsssrv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/nss/$(DEPDIR)/nsssrv_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/nss/$(DEPDIR)/nsssrv_mmap_cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/nss/$(DEPDIR)/nsssrv_netgroup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/nss/$(DEPDIR)/nsssrv_services.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pam/$(DEPDIR)/pam_LOCAL_domain.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pam/$(DEPDIR)/pam_helpers.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_LOCAL_domain.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_helpers.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_p11.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pam/$(DEPDIR)/pamsrv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pam/$(DEPDIR)/pamsrv_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pam/$(DEPDIR)/pamsrv_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/pam/$(DEPDIR)/pamsrv_p11.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ssh/$(DEPDIR)/sshsrv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ssh/$(DEPDIR)/sshsrv_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/ssh/$(DEPDIR)/sshsrv_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/sudo/$(DEPDIR)/sudosrv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/sudo/$(DEPDIR)/sudosrv_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/sudo/$(DEPDIR)/sudosrv_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/sudo/$(DEPDIR)/sudosrv_get_sudorules.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/responder/sudo/$(DEPDIR)/sudosrv_query.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sbus_client.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_common_signals.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_connection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_interface.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_introspect.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_invokers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_meta.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_properties.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_request.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_server.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_signals.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sbus/$(DEPDIR)/sbus_internal_tests-sssd_dbus_request.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/autofs_test_client-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/krb5_child-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/nss_group.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/nss_mc_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/nss_mc_group.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/nss_mc_initgr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/nss_mc_passwd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/nss_netgroup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/nss_passwd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/nss_services.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/pam_message.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/pam_srv_tests-pam_message.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/pam_sss.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/pam_test_client.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_cache-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_groupdel-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_groupmod-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_la-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_la-nss_mc_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_la-nss_mc_group.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_la-nss_mc_passwd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_ssh_authorizedkeys-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_ssh_knownhostsproxy-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_sudo_cli-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_userdel-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sss_usermod-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_mc_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_mc_passwd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_passwd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sssd_pac_plugin_la-common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/$(DEPDIR)/sssd_pac_plugin_la-sssd_pac.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/autofs/$(DEPDIR)/autofs_test_client-autofs_test_client.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/autofs/$(DEPDIR)/autofs_test_client-sss_autofs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/autofs/$(DEPDIR)/sss_autofs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/idmap/$(DEPDIR)/sss_nss_idmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbc_ctx_sssd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbc_guid.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbc_idmap_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbc_idmap_sssd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbc_pam_sssd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbc_pwd_sssd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbc_sid_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbc_sid_sssd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbc_util_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbc_util_sssd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbclient_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/libwbclient/$(DEPDIR)/wbclient_sssd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/nfs/$(DEPDIR)/sss_la-sss_nfs_client.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_client.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_client.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/sudo/$(DEPDIR)/sss_sudo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo_response.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/sudo/$(DEPDIR)/sss_sudo_response.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sss_client/sudo_testcli/$(DEPDIR)/sss_sudo_cli-sudo_testcli.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/ad_ldap_opt_tests-ad_ldap_opt-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/auth_tests-auth-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/check_and_open_tests-check_and_open-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/common_check.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/common_dom.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/common_tev.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/crypto_tests-crypto-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/debug_tests-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/debug_tests-debug-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/dlopen_tests-dlopen-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/fail_over_tests-fail_over-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/files_tests-files-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/find_uid_tests-find_uid-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/ipa_hbac_tests-ipa_hbac-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/ipa_ldap_opt_tests-ipa_ldap_opt-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/krb5_child_test-krb5_child-test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/krb5_utils_tests-krb5_utils-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/leak_check.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/refcount_tests-refcount-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/resolv_tests-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/resolv_tests-resolv-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/responder_socket_access_tests-responder_socket_access-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/safe_format_tests-safe-format-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/sbus_codegen_tests-common_dbus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests_generated.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/sbus_tests-common_dbus.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/sbus_tests-sbus_tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/simple_access-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/sss_config_tests-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/sss_config_tests-sss_config-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/sss_idmap_tests-sss_idmap-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/stress-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/strtonum_tests-strtonum-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/sysdb_ssh_tests-sysdb_ssh-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/sysdb_tests-sysdb-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/test_io-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/$(DEPDIR)/util_tests-util-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/ad_gpo_tests-test_ad_gpo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/common_mock_krb5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/dp_opt_tests-test_dp_opts.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/dummy_child.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/dyndns_tests-common_mock_be.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/dyndns_tests-test_dyndns.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/fqnames_tests-test_fqnames.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/ifp_tests-test_ifp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_be.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sdap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sysdb_objects.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-test_nested_groups.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/nss_srv_tests-test_nss_srv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/pam_srv_tests-test_pam_srv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp_dp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-test_responder_cache_req.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-common_mock_resp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-test_responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/sbus_internal_tests-sbus_internal_tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/sdap_tests-test_sdap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/sss_nss_idmap_tests-sss_nss_idmap-tests.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/sss_sifp_tests-test_sss_sifp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_ad_access_filter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_ad_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_authtok-test_authtok.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_be_ptask-common_mock_be.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_be_ptask-test_be_ptask.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_cert_utils-test_cert_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_child_common-test_child_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_copy_ccache-test_copy_ccache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_copy_keytab-common_mock_krb5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_copy_keytab-test_copy_keytab.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_data_provider_be-common_mock_be.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_data_provider_be-test_data_provider_be.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_expire_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_find_uid-test_find_uid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_fo_srv-test_fo_srv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_io-test_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_ipa_dn-test_ipa_dn.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_ipa_idmap-test_ipa_idmap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_be.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_krb5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_sdap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-test_ipa_subdomains_server.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_util-test_ipa_subdomains_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-common_mock_be.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-test_krb5_wait_queue.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_ldap_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_ldap_id_cleanup.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_negcache-test_negcache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_resolv_fake-test_resolv_fake.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_sbus_opath-test_sbus_opath.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_sdap_access.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_search_bases.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_sss_idmap-test_sss_idmap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_sysdb_subdomains-test_sysdb_subdomains.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_sysdb_utils-test_sysdb_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_sysdb_views-test_sysdb_views.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_tools_colondb-test_tools_colondb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_utils-test_sss_ssh.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_utils-test_string_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tests/cmocka/$(DEPDIR)/test_utils-test_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/_py2sss_la-files.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/_py2sss_la-selinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/_py2sss_la-sss_sync_ops.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/_py2sss_la-tools_util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/_py3sss_la-files.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/_py3sss_la-selinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/_py3sss_la-sss_sync_ops.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/_py3sss_la-tools_util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/files.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/files_tests-files.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/files_tests-selinux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/selinux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_cache-files.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_cache-selinux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_cache-sss_cache.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_cache-sss_sync_ops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_cache-tools_mc_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_cache-tools_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_debuglevel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupadd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupdel-files.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupdel-selinux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupdel-sss_groupdel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupdel-sss_sync_ops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupdel-tools_mc_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupdel-tools_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupmod-files.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupmod-selinux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupmod-sss_groupmod.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupmod-sss_sync_ops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupmod-tools_mc_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupmod-tools_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_groupshow.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_override-files.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_override-selinux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_override-sss_override.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_override-sss_sync_ops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_override-tools_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_seed.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_signal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_sync_ops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_useradd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_userdel-files.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_userdel-selinux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_userdel-sss_sync_ops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_userdel-sss_userdel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_userdel-tools_mc_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_userdel-tools_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_usermod-files.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_usermod-selinux.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_usermod-sss_sync_ops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_usermod-sss_usermod.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_usermod-tools_mc_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/sss_usermod-tools_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/$(DEPDIR)/tools_util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/common/$(DEPDIR)/_py2sss_la-sss_tools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/common/$(DEPDIR)/_py3sss_la-sss_tools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/common/$(DEPDIR)/sss_cache-sss_tools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/common/$(DEPDIR)/sss_groupdel-sss_tools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/common/$(DEPDIR)/sss_groupmod-sss_tools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/common/$(DEPDIR)/sss_override-sss_colondb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/common/$(DEPDIR)/sss_override-sss_tools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/common/$(DEPDIR)/sss_tools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/common/$(DEPDIR)/sss_userdel-sss_tools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/common/$(DEPDIR)/sss_usermod-sss_tools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/tools/common/$(DEPDIR)/test_tools_colondb-sss_colondb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/_py2hbac_la-sss_python.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/_py2sss_la-nscd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/_py2sss_murmur_la-murmurhash3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/_py3hbac_la-sss_python.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/_py3sss_la-nscd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/_py3sss_murmur_la-murmurhash3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/atomic_io.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/authtok-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/become_user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/check_and_open_tests-check_and_open.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/child_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/debug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/files_tests-atomic_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/files_tests-check_and_open.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/find_uid_tests-atomic_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/find_uid_tests-find_uid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/find_uid_tests-strtonum.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/gpo_child-atomic_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/gpo_child-signal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/gpo_child-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/io.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/ipa_ldap_opt_tests-sss_ldap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child-atomic_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child-authtok-utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child-authtok.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child-become_user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child-find_uid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child-signal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child-sss_krb5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child-strtonum.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child-user_info_msg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child-util_errors.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child_test-become_user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_child_test-sss_krb5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_utils_tests-become_user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/krb5_utils_tests-sss_krb5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/ldap_child-atomic_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/ldap_child-authtok-utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/ldap_child-authtok.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/ldap_child-become_user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/ldap_child-signal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/ldap_child-sss_krb5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/ldap_child-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_config_la-sss_config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_krb5_common_la-become_user.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_krb5_common_la-sss_krb5.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_ldap_common_la-sss_ldap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_ldap_common_la-user_info_msg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_semanage_la-sss_semanage.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-atomic_io.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-authtok-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-authtok.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-backup_file.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-become_user.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-check_and_open.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-domain_info_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-find_uid.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-io.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-memory.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-murmurhash3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-refcount.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-safe-format-string.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-server.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-signal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-sss_ini.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-sss_nss.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-sss_selinux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-sss_ssh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-sss_tc_utf8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-sss_utf8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-string_utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-strtonum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-usertools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-util_errors.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-util_lock.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-util_sss_idmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/libsss_util_la-well_known_sids.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/memberof_la-util.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/murmurhash3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/nestedgroups_tests-sss_ldap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/nscd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/p11_child-atomic_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/p11_child-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sdap_tests-sss_ldap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/selinux_child-atomic_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/selinux_child-sss_semanage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/selinux_child-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_cache-nscd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_cli_cmd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_groupdel-nscd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_groupmod-nscd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_krb5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_la-io.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_la-murmurhash3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_log.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_override-nscd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_userdel-nscd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_usermod-nscd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sss_utf8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sssd_krb5_localauth_plugin_la-io.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sssd_krb5_localauth_plugin_la-murmurhash3.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/sssd_krb5_locator_plugin_la-atomic_io.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/strtonum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/strtonum_tests-strtonum.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_authtok-authtok-utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_authtok-authtok.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_authtok-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_child_common-atomic_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_child_common-child_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_child_common-signal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_child_common-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_child_common-util_errors.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_copy_ccache-sss_krb5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_copy_keytab-sss_krb5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_find_uid-atomic_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_find_uid-find_uid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_find_uid-strtonum.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_io-io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_ipa_subdom_server-become_user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/$(DEPDIR)/test_ipa_subdom_server-sss_krb5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/cert/$(DEPDIR)/libsss_cert_la-cert_common.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/cert/libcrypto/$(DEPDIR)/libsss_cert_la-cert.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/cert/nss/$(DEPDIR)/libsss_cert_la-cert.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_base64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_hmac_sha1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_obfuscate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_sha512crypt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_base64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_hmac_sha1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_obfuscate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_sha512crypt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_util.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< src/python/_py2hbac_la-pyhbac.lo: src/python/pyhbac.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2hbac_la_CFLAGS) $(CFLAGS) -MT src/python/_py2hbac_la-pyhbac.lo -MD -MP -MF src/python/$(DEPDIR)/_py2hbac_la-pyhbac.Tpo -c -o src/python/_py2hbac_la-pyhbac.lo `test -f 'src/python/pyhbac.c' || echo '$(srcdir)/'`src/python/pyhbac.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/python/$(DEPDIR)/_py2hbac_la-pyhbac.Tpo src/python/$(DEPDIR)/_py2hbac_la-pyhbac.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/python/pyhbac.c' object='src/python/_py2hbac_la-pyhbac.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2hbac_la_CFLAGS) $(CFLAGS) -c -o src/python/_py2hbac_la-pyhbac.lo `test -f 'src/python/pyhbac.c' || echo '$(srcdir)/'`src/python/pyhbac.c src/util/_py2hbac_la-sss_python.lo: src/util/sss_python.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2hbac_la_CFLAGS) $(CFLAGS) -MT src/util/_py2hbac_la-sss_python.lo -MD -MP -MF src/util/$(DEPDIR)/_py2hbac_la-sss_python.Tpo -c -o src/util/_py2hbac_la-sss_python.lo `test -f 'src/util/sss_python.c' || echo '$(srcdir)/'`src/util/sss_python.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/_py2hbac_la-sss_python.Tpo src/util/$(DEPDIR)/_py2hbac_la-sss_python.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_python.c' object='src/util/_py2hbac_la-sss_python.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2hbac_la_CFLAGS) $(CFLAGS) -c -o src/util/_py2hbac_la-sss_python.lo `test -f 'src/util/sss_python.c' || echo '$(srcdir)/'`src/util/sss_python.c src/tools/_py2sss_la-sss_sync_ops.lo: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -MT src/tools/_py2sss_la-sss_sync_ops.lo -MD -MP -MF src/tools/$(DEPDIR)/_py2sss_la-sss_sync_ops.Tpo -c -o src/tools/_py2sss_la-sss_sync_ops.lo `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/_py2sss_la-sss_sync_ops.Tpo src/tools/$(DEPDIR)/_py2sss_la-sss_sync_ops.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/_py2sss_la-sss_sync_ops.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -c -o src/tools/_py2sss_la-sss_sync_ops.lo `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c src/tools/_py2sss_la-tools_util.lo: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -MT src/tools/_py2sss_la-tools_util.lo -MD -MP -MF src/tools/$(DEPDIR)/_py2sss_la-tools_util.Tpo -c -o src/tools/_py2sss_la-tools_util.lo `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/_py2sss_la-tools_util.Tpo src/tools/$(DEPDIR)/_py2sss_la-tools_util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/_py2sss_la-tools_util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -c -o src/tools/_py2sss_la-tools_util.lo `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c src/tools/_py2sss_la-files.lo: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -MT src/tools/_py2sss_la-files.lo -MD -MP -MF src/tools/$(DEPDIR)/_py2sss_la-files.Tpo -c -o src/tools/_py2sss_la-files.lo `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/_py2sss_la-files.Tpo src/tools/$(DEPDIR)/_py2sss_la-files.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/_py2sss_la-files.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -c -o src/tools/_py2sss_la-files.lo `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c src/tools/_py2sss_la-selinux.lo: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -MT src/tools/_py2sss_la-selinux.lo -MD -MP -MF src/tools/$(DEPDIR)/_py2sss_la-selinux.Tpo -c -o src/tools/_py2sss_la-selinux.lo `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/_py2sss_la-selinux.Tpo src/tools/$(DEPDIR)/_py2sss_la-selinux.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/_py2sss_la-selinux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -c -o src/tools/_py2sss_la-selinux.lo `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c src/tools/common/_py2sss_la-sss_tools.lo: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -MT src/tools/common/_py2sss_la-sss_tools.lo -MD -MP -MF src/tools/common/$(DEPDIR)/_py2sss_la-sss_tools.Tpo -c -o src/tools/common/_py2sss_la-sss_tools.lo `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/_py2sss_la-sss_tools.Tpo src/tools/common/$(DEPDIR)/_py2sss_la-sss_tools.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/_py2sss_la-sss_tools.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -c -o src/tools/common/_py2sss_la-sss_tools.lo `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c src/util/_py2sss_la-nscd.lo: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -MT src/util/_py2sss_la-nscd.lo -MD -MP -MF src/util/$(DEPDIR)/_py2sss_la-nscd.Tpo -c -o src/util/_py2sss_la-nscd.lo `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/_py2sss_la-nscd.Tpo src/util/$(DEPDIR)/_py2sss_la-nscd.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/_py2sss_la-nscd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -c -o src/util/_py2sss_la-nscd.lo `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c src/python/_py2sss_la-pysss.lo: src/python/pysss.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -MT src/python/_py2sss_la-pysss.lo -MD -MP -MF src/python/$(DEPDIR)/_py2sss_la-pysss.Tpo -c -o src/python/_py2sss_la-pysss.lo `test -f 'src/python/pysss.c' || echo '$(srcdir)/'`src/python/pysss.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/python/$(DEPDIR)/_py2sss_la-pysss.Tpo src/python/$(DEPDIR)/_py2sss_la-pysss.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/python/pysss.c' object='src/python/_py2sss_la-pysss.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_la_CFLAGS) $(CFLAGS) -c -o src/python/_py2sss_la-pysss.lo `test -f 'src/python/pysss.c' || echo '$(srcdir)/'`src/python/pysss.c src/python/_py2sss_murmur_la-pysss_murmur.lo: src/python/pysss_murmur.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_murmur_la_CFLAGS) $(CFLAGS) -MT src/python/_py2sss_murmur_la-pysss_murmur.lo -MD -MP -MF src/python/$(DEPDIR)/_py2sss_murmur_la-pysss_murmur.Tpo -c -o src/python/_py2sss_murmur_la-pysss_murmur.lo `test -f 'src/python/pysss_murmur.c' || echo '$(srcdir)/'`src/python/pysss_murmur.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/python/$(DEPDIR)/_py2sss_murmur_la-pysss_murmur.Tpo src/python/$(DEPDIR)/_py2sss_murmur_la-pysss_murmur.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/python/pysss_murmur.c' object='src/python/_py2sss_murmur_la-pysss_murmur.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_murmur_la_CFLAGS) $(CFLAGS) -c -o src/python/_py2sss_murmur_la-pysss_murmur.lo `test -f 'src/python/pysss_murmur.c' || echo '$(srcdir)/'`src/python/pysss_murmur.c src/util/_py2sss_murmur_la-murmurhash3.lo: src/util/murmurhash3.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_murmur_la_CFLAGS) $(CFLAGS) -MT src/util/_py2sss_murmur_la-murmurhash3.lo -MD -MP -MF src/util/$(DEPDIR)/_py2sss_murmur_la-murmurhash3.Tpo -c -o src/util/_py2sss_murmur_la-murmurhash3.lo `test -f 'src/util/murmurhash3.c' || echo '$(srcdir)/'`src/util/murmurhash3.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/_py2sss_murmur_la-murmurhash3.Tpo src/util/$(DEPDIR)/_py2sss_murmur_la-murmurhash3.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/murmurhash3.c' object='src/util/_py2sss_murmur_la-murmurhash3.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_murmur_la_CFLAGS) $(CFLAGS) -c -o src/util/_py2sss_murmur_la-murmurhash3.lo `test -f 'src/util/murmurhash3.c' || echo '$(srcdir)/'`src/util/murmurhash3.c src/python/_py2sss_nss_idmap_la-pysss_nss_idmap.lo: src/python/pysss_nss_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_nss_idmap_la_CFLAGS) $(CFLAGS) -MT src/python/_py2sss_nss_idmap_la-pysss_nss_idmap.lo -MD -MP -MF src/python/$(DEPDIR)/_py2sss_nss_idmap_la-pysss_nss_idmap.Tpo -c -o src/python/_py2sss_nss_idmap_la-pysss_nss_idmap.lo `test -f 'src/python/pysss_nss_idmap.c' || echo '$(srcdir)/'`src/python/pysss_nss_idmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/python/$(DEPDIR)/_py2sss_nss_idmap_la-pysss_nss_idmap.Tpo src/python/$(DEPDIR)/_py2sss_nss_idmap_la-pysss_nss_idmap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/python/pysss_nss_idmap.c' object='src/python/_py2sss_nss_idmap_la-pysss_nss_idmap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py2sss_nss_idmap_la_CFLAGS) $(CFLAGS) -c -o src/python/_py2sss_nss_idmap_la-pysss_nss_idmap.lo `test -f 'src/python/pysss_nss_idmap.c' || echo '$(srcdir)/'`src/python/pysss_nss_idmap.c src/python/_py3hbac_la-pyhbac.lo: src/python/pyhbac.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3hbac_la_CFLAGS) $(CFLAGS) -MT src/python/_py3hbac_la-pyhbac.lo -MD -MP -MF src/python/$(DEPDIR)/_py3hbac_la-pyhbac.Tpo -c -o src/python/_py3hbac_la-pyhbac.lo `test -f 'src/python/pyhbac.c' || echo '$(srcdir)/'`src/python/pyhbac.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/python/$(DEPDIR)/_py3hbac_la-pyhbac.Tpo src/python/$(DEPDIR)/_py3hbac_la-pyhbac.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/python/pyhbac.c' object='src/python/_py3hbac_la-pyhbac.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3hbac_la_CFLAGS) $(CFLAGS) -c -o src/python/_py3hbac_la-pyhbac.lo `test -f 'src/python/pyhbac.c' || echo '$(srcdir)/'`src/python/pyhbac.c src/util/_py3hbac_la-sss_python.lo: src/util/sss_python.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3hbac_la_CFLAGS) $(CFLAGS) -MT src/util/_py3hbac_la-sss_python.lo -MD -MP -MF src/util/$(DEPDIR)/_py3hbac_la-sss_python.Tpo -c -o src/util/_py3hbac_la-sss_python.lo `test -f 'src/util/sss_python.c' || echo '$(srcdir)/'`src/util/sss_python.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/_py3hbac_la-sss_python.Tpo src/util/$(DEPDIR)/_py3hbac_la-sss_python.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_python.c' object='src/util/_py3hbac_la-sss_python.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3hbac_la_CFLAGS) $(CFLAGS) -c -o src/util/_py3hbac_la-sss_python.lo `test -f 'src/util/sss_python.c' || echo '$(srcdir)/'`src/util/sss_python.c src/tools/_py3sss_la-sss_sync_ops.lo: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -MT src/tools/_py3sss_la-sss_sync_ops.lo -MD -MP -MF src/tools/$(DEPDIR)/_py3sss_la-sss_sync_ops.Tpo -c -o src/tools/_py3sss_la-sss_sync_ops.lo `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/_py3sss_la-sss_sync_ops.Tpo src/tools/$(DEPDIR)/_py3sss_la-sss_sync_ops.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/_py3sss_la-sss_sync_ops.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -c -o src/tools/_py3sss_la-sss_sync_ops.lo `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c src/tools/_py3sss_la-tools_util.lo: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -MT src/tools/_py3sss_la-tools_util.lo -MD -MP -MF src/tools/$(DEPDIR)/_py3sss_la-tools_util.Tpo -c -o src/tools/_py3sss_la-tools_util.lo `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/_py3sss_la-tools_util.Tpo src/tools/$(DEPDIR)/_py3sss_la-tools_util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/_py3sss_la-tools_util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -c -o src/tools/_py3sss_la-tools_util.lo `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c src/tools/_py3sss_la-files.lo: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -MT src/tools/_py3sss_la-files.lo -MD -MP -MF src/tools/$(DEPDIR)/_py3sss_la-files.Tpo -c -o src/tools/_py3sss_la-files.lo `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/_py3sss_la-files.Tpo src/tools/$(DEPDIR)/_py3sss_la-files.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/_py3sss_la-files.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -c -o src/tools/_py3sss_la-files.lo `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c src/tools/_py3sss_la-selinux.lo: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -MT src/tools/_py3sss_la-selinux.lo -MD -MP -MF src/tools/$(DEPDIR)/_py3sss_la-selinux.Tpo -c -o src/tools/_py3sss_la-selinux.lo `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/_py3sss_la-selinux.Tpo src/tools/$(DEPDIR)/_py3sss_la-selinux.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/_py3sss_la-selinux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -c -o src/tools/_py3sss_la-selinux.lo `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c src/tools/common/_py3sss_la-sss_tools.lo: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -MT src/tools/common/_py3sss_la-sss_tools.lo -MD -MP -MF src/tools/common/$(DEPDIR)/_py3sss_la-sss_tools.Tpo -c -o src/tools/common/_py3sss_la-sss_tools.lo `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/_py3sss_la-sss_tools.Tpo src/tools/common/$(DEPDIR)/_py3sss_la-sss_tools.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/_py3sss_la-sss_tools.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -c -o src/tools/common/_py3sss_la-sss_tools.lo `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c src/util/_py3sss_la-nscd.lo: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -MT src/util/_py3sss_la-nscd.lo -MD -MP -MF src/util/$(DEPDIR)/_py3sss_la-nscd.Tpo -c -o src/util/_py3sss_la-nscd.lo `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/_py3sss_la-nscd.Tpo src/util/$(DEPDIR)/_py3sss_la-nscd.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/_py3sss_la-nscd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -c -o src/util/_py3sss_la-nscd.lo `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c src/python/_py3sss_la-pysss.lo: src/python/pysss.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -MT src/python/_py3sss_la-pysss.lo -MD -MP -MF src/python/$(DEPDIR)/_py3sss_la-pysss.Tpo -c -o src/python/_py3sss_la-pysss.lo `test -f 'src/python/pysss.c' || echo '$(srcdir)/'`src/python/pysss.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/python/$(DEPDIR)/_py3sss_la-pysss.Tpo src/python/$(DEPDIR)/_py3sss_la-pysss.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/python/pysss.c' object='src/python/_py3sss_la-pysss.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_la_CFLAGS) $(CFLAGS) -c -o src/python/_py3sss_la-pysss.lo `test -f 'src/python/pysss.c' || echo '$(srcdir)/'`src/python/pysss.c src/python/_py3sss_murmur_la-pysss_murmur.lo: src/python/pysss_murmur.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_murmur_la_CFLAGS) $(CFLAGS) -MT src/python/_py3sss_murmur_la-pysss_murmur.lo -MD -MP -MF src/python/$(DEPDIR)/_py3sss_murmur_la-pysss_murmur.Tpo -c -o src/python/_py3sss_murmur_la-pysss_murmur.lo `test -f 'src/python/pysss_murmur.c' || echo '$(srcdir)/'`src/python/pysss_murmur.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/python/$(DEPDIR)/_py3sss_murmur_la-pysss_murmur.Tpo src/python/$(DEPDIR)/_py3sss_murmur_la-pysss_murmur.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/python/pysss_murmur.c' object='src/python/_py3sss_murmur_la-pysss_murmur.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_murmur_la_CFLAGS) $(CFLAGS) -c -o src/python/_py3sss_murmur_la-pysss_murmur.lo `test -f 'src/python/pysss_murmur.c' || echo '$(srcdir)/'`src/python/pysss_murmur.c src/util/_py3sss_murmur_la-murmurhash3.lo: src/util/murmurhash3.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_murmur_la_CFLAGS) $(CFLAGS) -MT src/util/_py3sss_murmur_la-murmurhash3.lo -MD -MP -MF src/util/$(DEPDIR)/_py3sss_murmur_la-murmurhash3.Tpo -c -o src/util/_py3sss_murmur_la-murmurhash3.lo `test -f 'src/util/murmurhash3.c' || echo '$(srcdir)/'`src/util/murmurhash3.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/_py3sss_murmur_la-murmurhash3.Tpo src/util/$(DEPDIR)/_py3sss_murmur_la-murmurhash3.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/murmurhash3.c' object='src/util/_py3sss_murmur_la-murmurhash3.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_murmur_la_CFLAGS) $(CFLAGS) -c -o src/util/_py3sss_murmur_la-murmurhash3.lo `test -f 'src/util/murmurhash3.c' || echo '$(srcdir)/'`src/util/murmurhash3.c src/python/_py3sss_nss_idmap_la-pysss_nss_idmap.lo: src/python/pysss_nss_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_nss_idmap_la_CFLAGS) $(CFLAGS) -MT src/python/_py3sss_nss_idmap_la-pysss_nss_idmap.lo -MD -MP -MF src/python/$(DEPDIR)/_py3sss_nss_idmap_la-pysss_nss_idmap.Tpo -c -o src/python/_py3sss_nss_idmap_la-pysss_nss_idmap.lo `test -f 'src/python/pysss_nss_idmap.c' || echo '$(srcdir)/'`src/python/pysss_nss_idmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/python/$(DEPDIR)/_py3sss_nss_idmap_la-pysss_nss_idmap.Tpo src/python/$(DEPDIR)/_py3sss_nss_idmap_la-pysss_nss_idmap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/python/pysss_nss_idmap.c' object='src/python/_py3sss_nss_idmap_la-pysss_nss_idmap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_py3sss_nss_idmap_la_CFLAGS) $(CFLAGS) -c -o src/python/_py3sss_nss_idmap_la-pysss_nss_idmap.lo `test -f 'src/python/pysss_nss_idmap.c' || echo '$(srcdir)/'`src/python/pysss_nss_idmap.c src/lib/cifs_idmap_sss/cifs_idmap_sss_la-cifs_idmap_sss.lo: src/lib/cifs_idmap_sss/cifs_idmap_sss.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cifs_idmap_sss_la_CFLAGS) $(CFLAGS) -MT src/lib/cifs_idmap_sss/cifs_idmap_sss_la-cifs_idmap_sss.lo -MD -MP -MF src/lib/cifs_idmap_sss/$(DEPDIR)/cifs_idmap_sss_la-cifs_idmap_sss.Tpo -c -o src/lib/cifs_idmap_sss/cifs_idmap_sss_la-cifs_idmap_sss.lo `test -f 'src/lib/cifs_idmap_sss/cifs_idmap_sss.c' || echo '$(srcdir)/'`src/lib/cifs_idmap_sss/cifs_idmap_sss.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/cifs_idmap_sss/$(DEPDIR)/cifs_idmap_sss_la-cifs_idmap_sss.Tpo src/lib/cifs_idmap_sss/$(DEPDIR)/cifs_idmap_sss_la-cifs_idmap_sss.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/cifs_idmap_sss/cifs_idmap_sss.c' object='src/lib/cifs_idmap_sss/cifs_idmap_sss_la-cifs_idmap_sss.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cifs_idmap_sss_la_CFLAGS) $(CFLAGS) -c -o src/lib/cifs_idmap_sss/cifs_idmap_sss_la-cifs_idmap_sss.lo `test -f 'src/lib/cifs_idmap_sss/cifs_idmap_sss.c' || echo '$(srcdir)/'`src/lib/cifs_idmap_sss/cifs_idmap_sss.c src/providers/libdlopen_test_providers_la-data_provider_be.lo: src/providers/data_provider_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/providers/libdlopen_test_providers_la-data_provider_be.lo -MD -MP -MF src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_be.Tpo -c -o src/providers/libdlopen_test_providers_la-data_provider_be.lo `test -f 'src/providers/data_provider_be.c' || echo '$(srcdir)/'`src/providers/data_provider_be.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_be.Tpo src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_be.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_be.c' object='src/providers/libdlopen_test_providers_la-data_provider_be.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/providers/libdlopen_test_providers_la-data_provider_be.lo `test -f 'src/providers/data_provider_be.c' || echo '$(srcdir)/'`src/providers/data_provider_be.c src/providers/libdlopen_test_providers_la-data_provider_req.lo: src/providers/data_provider_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/providers/libdlopen_test_providers_la-data_provider_req.lo -MD -MP -MF src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_req.Tpo -c -o src/providers/libdlopen_test_providers_la-data_provider_req.lo `test -f 'src/providers/data_provider_req.c' || echo '$(srcdir)/'`src/providers/data_provider_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_req.Tpo src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_req.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_req.c' object='src/providers/libdlopen_test_providers_la-data_provider_req.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/providers/libdlopen_test_providers_la-data_provider_req.lo `test -f 'src/providers/data_provider_req.c' || echo '$(srcdir)/'`src/providers/data_provider_req.c src/providers/libdlopen_test_providers_la-data_provider_fo.lo: src/providers/data_provider_fo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/providers/libdlopen_test_providers_la-data_provider_fo.lo -MD -MP -MF src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_fo.Tpo -c -o src/providers/libdlopen_test_providers_la-data_provider_fo.lo `test -f 'src/providers/data_provider_fo.c' || echo '$(srcdir)/'`src/providers/data_provider_fo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_fo.Tpo src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_fo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_fo.c' object='src/providers/libdlopen_test_providers_la-data_provider_fo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/providers/libdlopen_test_providers_la-data_provider_fo.lo `test -f 'src/providers/data_provider_fo.c' || echo '$(srcdir)/'`src/providers/data_provider_fo.c src/providers/libdlopen_test_providers_la-data_provider_opts.lo: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/providers/libdlopen_test_providers_la-data_provider_opts.lo -MD -MP -MF src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_opts.Tpo -c -o src/providers/libdlopen_test_providers_la-data_provider_opts.lo `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_opts.Tpo src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_opts.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/libdlopen_test_providers_la-data_provider_opts.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/providers/libdlopen_test_providers_la-data_provider_opts.lo `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c src/providers/libdlopen_test_providers_la-data_provider_callbacks.lo: src/providers/data_provider_callbacks.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/providers/libdlopen_test_providers_la-data_provider_callbacks.lo -MD -MP -MF src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_callbacks.Tpo -c -o src/providers/libdlopen_test_providers_la-data_provider_callbacks.lo `test -f 'src/providers/data_provider_callbacks.c' || echo '$(srcdir)/'`src/providers/data_provider_callbacks.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_callbacks.Tpo src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_callbacks.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_callbacks.c' object='src/providers/libdlopen_test_providers_la-data_provider_callbacks.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/providers/libdlopen_test_providers_la-data_provider_callbacks.lo `test -f 'src/providers/data_provider_callbacks.c' || echo '$(srcdir)/'`src/providers/data_provider_callbacks.c src/providers/libdlopen_test_providers_la-dp_dyndns.lo: src/providers/dp_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/providers/libdlopen_test_providers_la-dp_dyndns.lo -MD -MP -MF src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_dyndns.Tpo -c -o src/providers/libdlopen_test_providers_la-dp_dyndns.lo `test -f 'src/providers/dp_dyndns.c' || echo '$(srcdir)/'`src/providers/dp_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_dyndns.Tpo src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_dyndns.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/dp_dyndns.c' object='src/providers/libdlopen_test_providers_la-dp_dyndns.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/providers/libdlopen_test_providers_la-dp_dyndns.lo `test -f 'src/providers/dp_dyndns.c' || echo '$(srcdir)/'`src/providers/dp_dyndns.c src/providers/libdlopen_test_providers_la-dp_ptask.lo: src/providers/dp_ptask.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/providers/libdlopen_test_providers_la-dp_ptask.lo -MD -MP -MF src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_ptask.Tpo -c -o src/providers/libdlopen_test_providers_la-dp_ptask.lo `test -f 'src/providers/dp_ptask.c' || echo '$(srcdir)/'`src/providers/dp_ptask.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_ptask.Tpo src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_ptask.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/dp_ptask.c' object='src/providers/libdlopen_test_providers_la-dp_ptask.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/providers/libdlopen_test_providers_la-dp_ptask.lo `test -f 'src/providers/dp_ptask.c' || echo '$(srcdir)/'`src/providers/dp_ptask.c src/providers/libdlopen_test_providers_la-dp_refresh.lo: src/providers/dp_refresh.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/providers/libdlopen_test_providers_la-dp_refresh.lo -MD -MP -MF src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_refresh.Tpo -c -o src/providers/libdlopen_test_providers_la-dp_refresh.lo `test -f 'src/providers/dp_refresh.c' || echo '$(srcdir)/'`src/providers/dp_refresh.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_refresh.Tpo src/providers/$(DEPDIR)/libdlopen_test_providers_la-dp_refresh.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/dp_refresh.c' object='src/providers/libdlopen_test_providers_la-dp_refresh.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/providers/libdlopen_test_providers_la-dp_refresh.lo `test -f 'src/providers/dp_refresh.c' || echo '$(srcdir)/'`src/providers/dp_refresh.c src/monitor/libdlopen_test_providers_la-monitor_iface_generated.lo: src/monitor/monitor_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/monitor/libdlopen_test_providers_la-monitor_iface_generated.lo -MD -MP -MF src/monitor/$(DEPDIR)/libdlopen_test_providers_la-monitor_iface_generated.Tpo -c -o src/monitor/libdlopen_test_providers_la-monitor_iface_generated.lo `test -f 'src/monitor/monitor_iface_generated.c' || echo '$(srcdir)/'`src/monitor/monitor_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/monitor/$(DEPDIR)/libdlopen_test_providers_la-monitor_iface_generated.Tpo src/monitor/$(DEPDIR)/libdlopen_test_providers_la-monitor_iface_generated.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/monitor/monitor_iface_generated.c' object='src/monitor/libdlopen_test_providers_la-monitor_iface_generated.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/monitor/libdlopen_test_providers_la-monitor_iface_generated.lo `test -f 'src/monitor/monitor_iface_generated.c' || echo '$(srcdir)/'`src/monitor/monitor_iface_generated.c src/providers/libdlopen_test_providers_la-data_provider_iface_generated.lo: src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/providers/libdlopen_test_providers_la-data_provider_iface_generated.lo -MD -MP -MF src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_iface_generated.Tpo -c -o src/providers/libdlopen_test_providers_la-data_provider_iface_generated.lo `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_iface_generated.Tpo src/providers/$(DEPDIR)/libdlopen_test_providers_la-data_provider_iface_generated.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_iface_generated.c' object='src/providers/libdlopen_test_providers_la-data_provider_iface_generated.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/providers/libdlopen_test_providers_la-data_provider_iface_generated.lo `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c src/providers/libdlopen_test_providers_la-fail_over.lo: src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/providers/libdlopen_test_providers_la-fail_over.lo -MD -MP -MF src/providers/$(DEPDIR)/libdlopen_test_providers_la-fail_over.Tpo -c -o src/providers/libdlopen_test_providers_la-fail_over.lo `test -f 'src/providers/fail_over.c' || echo '$(srcdir)/'`src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libdlopen_test_providers_la-fail_over.Tpo src/providers/$(DEPDIR)/libdlopen_test_providers_la-fail_over.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over.c' object='src/providers/libdlopen_test_providers_la-fail_over.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/providers/libdlopen_test_providers_la-fail_over.lo `test -f 'src/providers/fail_over.c' || echo '$(srcdir)/'`src/providers/fail_over.c src/providers/libdlopen_test_providers_la-fail_over_srv.lo: src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/providers/libdlopen_test_providers_la-fail_over_srv.lo -MD -MP -MF src/providers/$(DEPDIR)/libdlopen_test_providers_la-fail_over_srv.Tpo -c -o src/providers/libdlopen_test_providers_la-fail_over_srv.lo `test -f 'src/providers/fail_over_srv.c' || echo '$(srcdir)/'`src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libdlopen_test_providers_la-fail_over_srv.Tpo src/providers/$(DEPDIR)/libdlopen_test_providers_la-fail_over_srv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over_srv.c' object='src/providers/libdlopen_test_providers_la-fail_over_srv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/providers/libdlopen_test_providers_la-fail_over_srv.lo `test -f 'src/providers/fail_over_srv.c' || echo '$(srcdir)/'`src/providers/fail_over_srv.c src/resolv/libdlopen_test_providers_la-async_resolv.lo: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/resolv/libdlopen_test_providers_la-async_resolv.lo -MD -MP -MF src/resolv/$(DEPDIR)/libdlopen_test_providers_la-async_resolv.Tpo -c -o src/resolv/libdlopen_test_providers_la-async_resolv.lo `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/libdlopen_test_providers_la-async_resolv.Tpo src/resolv/$(DEPDIR)/libdlopen_test_providers_la-async_resolv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/libdlopen_test_providers_la-async_resolv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/resolv/libdlopen_test_providers_la-async_resolv.lo `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c src/resolv/libdlopen_test_providers_la-async_resolv_utils.lo: src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -MT src/resolv/libdlopen_test_providers_la-async_resolv_utils.lo -MD -MP -MF src/resolv/$(DEPDIR)/libdlopen_test_providers_la-async_resolv_utils.Tpo -c -o src/resolv/libdlopen_test_providers_la-async_resolv_utils.lo `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/libdlopen_test_providers_la-async_resolv_utils.Tpo src/resolv/$(DEPDIR)/libdlopen_test_providers_la-async_resolv_utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv_utils.c' object='src/resolv/libdlopen_test_providers_la-async_resolv_utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdlopen_test_providers_la_CFLAGS) $(CFLAGS) -c -o src/resolv/libdlopen_test_providers_la-async_resolv_utils.lo `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c src/providers/ad/libsss_ad_la-ad_opts.lo: src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_opts.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_opts.Tpo -c -o src/providers/ad/libsss_ad_la-ad_opts.lo `test -f 'src/providers/ad/ad_opts.c' || echo '$(srcdir)/'`src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_opts.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_opts.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_opts.c' object='src/providers/ad/libsss_ad_la-ad_opts.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_opts.lo `test -f 'src/providers/ad/ad_opts.c' || echo '$(srcdir)/'`src/providers/ad/ad_opts.c src/providers/ad/libsss_ad_la-ad_common.lo: src/providers/ad/ad_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_common.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_common.Tpo -c -o src/providers/ad/libsss_ad_la-ad_common.lo `test -f 'src/providers/ad/ad_common.c' || echo '$(srcdir)/'`src/providers/ad/ad_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_common.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_common.c' object='src/providers/ad/libsss_ad_la-ad_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_common.lo `test -f 'src/providers/ad/ad_common.c' || echo '$(srcdir)/'`src/providers/ad/ad_common.c src/providers/ad/libsss_ad_la-ad_init.lo: src/providers/ad/ad_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_init.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_init.Tpo -c -o src/providers/ad/libsss_ad_la-ad_init.lo `test -f 'src/providers/ad/ad_init.c' || echo '$(srcdir)/'`src/providers/ad/ad_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_init.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_init.c' object='src/providers/ad/libsss_ad_la-ad_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_init.lo `test -f 'src/providers/ad/ad_init.c' || echo '$(srcdir)/'`src/providers/ad/ad_init.c src/providers/ad/libsss_ad_la-ad_dyndns.lo: src/providers/ad/ad_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_dyndns.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_dyndns.Tpo -c -o src/providers/ad/libsss_ad_la-ad_dyndns.lo `test -f 'src/providers/ad/ad_dyndns.c' || echo '$(srcdir)/'`src/providers/ad/ad_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_dyndns.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_dyndns.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_dyndns.c' object='src/providers/ad/libsss_ad_la-ad_dyndns.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_dyndns.lo `test -f 'src/providers/ad/ad_dyndns.c' || echo '$(srcdir)/'`src/providers/ad/ad_dyndns.c src/providers/ad/libsss_ad_la-ad_machine_pw_renewal.lo: src/providers/ad/ad_machine_pw_renewal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_machine_pw_renewal.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_machine_pw_renewal.Tpo -c -o src/providers/ad/libsss_ad_la-ad_machine_pw_renewal.lo `test -f 'src/providers/ad/ad_machine_pw_renewal.c' || echo '$(srcdir)/'`src/providers/ad/ad_machine_pw_renewal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_machine_pw_renewal.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_machine_pw_renewal.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_machine_pw_renewal.c' object='src/providers/ad/libsss_ad_la-ad_machine_pw_renewal.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_machine_pw_renewal.lo `test -f 'src/providers/ad/ad_machine_pw_renewal.c' || echo '$(srcdir)/'`src/providers/ad/ad_machine_pw_renewal.c src/providers/ad/libsss_ad_la-ad_id.lo: src/providers/ad/ad_id.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_id.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_id.Tpo -c -o src/providers/ad/libsss_ad_la-ad_id.lo `test -f 'src/providers/ad/ad_id.c' || echo '$(srcdir)/'`src/providers/ad/ad_id.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_id.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_id.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_id.c' object='src/providers/ad/libsss_ad_la-ad_id.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_id.lo `test -f 'src/providers/ad/ad_id.c' || echo '$(srcdir)/'`src/providers/ad/ad_id.c src/providers/ad/libsss_ad_la-ad_access.lo: src/providers/ad/ad_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_access.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_access.Tpo -c -o src/providers/ad/libsss_ad_la-ad_access.lo `test -f 'src/providers/ad/ad_access.c' || echo '$(srcdir)/'`src/providers/ad/ad_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_access.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_access.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_access.c' object='src/providers/ad/libsss_ad_la-ad_access.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_access.lo `test -f 'src/providers/ad/ad_access.c' || echo '$(srcdir)/'`src/providers/ad/ad_access.c src/providers/ad/libsss_ad_la-ad_gpo.lo: src/providers/ad/ad_gpo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_gpo.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_gpo.Tpo -c -o src/providers/ad/libsss_ad_la-ad_gpo.lo `test -f 'src/providers/ad/ad_gpo.c' || echo '$(srcdir)/'`src/providers/ad/ad_gpo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_gpo.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_gpo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_gpo.c' object='src/providers/ad/libsss_ad_la-ad_gpo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_gpo.lo `test -f 'src/providers/ad/ad_gpo.c' || echo '$(srcdir)/'`src/providers/ad/ad_gpo.c src/providers/ad/libsss_ad_la-ad_gpo_ndr.lo: src/providers/ad/ad_gpo_ndr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_gpo_ndr.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_gpo_ndr.Tpo -c -o src/providers/ad/libsss_ad_la-ad_gpo_ndr.lo `test -f 'src/providers/ad/ad_gpo_ndr.c' || echo '$(srcdir)/'`src/providers/ad/ad_gpo_ndr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_gpo_ndr.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_gpo_ndr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_gpo_ndr.c' object='src/providers/ad/libsss_ad_la-ad_gpo_ndr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_gpo_ndr.lo `test -f 'src/providers/ad/ad_gpo_ndr.c' || echo '$(srcdir)/'`src/providers/ad/ad_gpo_ndr.c src/providers/ad/libsss_ad_la-ad_srv.lo: src/providers/ad/ad_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_srv.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_srv.Tpo -c -o src/providers/ad/libsss_ad_la-ad_srv.lo `test -f 'src/providers/ad/ad_srv.c' || echo '$(srcdir)/'`src/providers/ad/ad_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_srv.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_srv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_srv.c' object='src/providers/ad/libsss_ad_la-ad_srv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_srv.lo `test -f 'src/providers/ad/ad_srv.c' || echo '$(srcdir)/'`src/providers/ad/ad_srv.c src/providers/ad/libsss_ad_la-ad_subdomains.lo: src/providers/ad/ad_subdomains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_subdomains.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_subdomains.Tpo -c -o src/providers/ad/libsss_ad_la-ad_subdomains.lo `test -f 'src/providers/ad/ad_subdomains.c' || echo '$(srcdir)/'`src/providers/ad/ad_subdomains.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_subdomains.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_subdomains.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_subdomains.c' object='src/providers/ad/libsss_ad_la-ad_subdomains.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_subdomains.lo `test -f 'src/providers/ad/ad_subdomains.c' || echo '$(srcdir)/'`src/providers/ad/ad_subdomains.c src/providers/ad/libsss_ad_la-ad_domain_info.lo: src/providers/ad/ad_domain_info.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_domain_info.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_domain_info.Tpo -c -o src/providers/ad/libsss_ad_la-ad_domain_info.lo `test -f 'src/providers/ad/ad_domain_info.c' || echo '$(srcdir)/'`src/providers/ad/ad_domain_info.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_domain_info.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_domain_info.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_domain_info.c' object='src/providers/ad/libsss_ad_la-ad_domain_info.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_domain_info.lo `test -f 'src/providers/ad/ad_domain_info.c' || echo '$(srcdir)/'`src/providers/ad/ad_domain_info.c src/providers/ad/libsss_ad_la-ad_sudo.lo: src/providers/ad/ad_sudo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_sudo.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_sudo.Tpo -c -o src/providers/ad/libsss_ad_la-ad_sudo.lo `test -f 'src/providers/ad/ad_sudo.c' || echo '$(srcdir)/'`src/providers/ad/ad_sudo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_sudo.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_sudo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_sudo.c' object='src/providers/ad/libsss_ad_la-ad_sudo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_sudo.lo `test -f 'src/providers/ad/ad_sudo.c' || echo '$(srcdir)/'`src/providers/ad/ad_sudo.c src/providers/ad/libsss_ad_la-ad_autofs.lo: src/providers/ad/ad_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_la-ad_autofs.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_autofs.Tpo -c -o src/providers/ad/libsss_ad_la-ad_autofs.lo `test -f 'src/providers/ad/ad_autofs.c' || echo '$(srcdir)/'`src/providers/ad/ad_autofs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_autofs.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_la-ad_autofs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_autofs.c' object='src/providers/ad/libsss_ad_la-ad_autofs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_la-ad_autofs.lo `test -f 'src/providers/ad/ad_autofs.c' || echo '$(srcdir)/'`src/providers/ad/ad_autofs.c src/providers/ad/libsss_ad_tests_la-ad_opts.lo: src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_opts.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_opts.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_opts.lo `test -f 'src/providers/ad/ad_opts.c' || echo '$(srcdir)/'`src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_opts.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_opts.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_opts.c' object='src/providers/ad/libsss_ad_tests_la-ad_opts.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_opts.lo `test -f 'src/providers/ad/ad_opts.c' || echo '$(srcdir)/'`src/providers/ad/ad_opts.c src/providers/ad/libsss_ad_tests_la-ad_common.lo: src/providers/ad/ad_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_common.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_common.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_common.lo `test -f 'src/providers/ad/ad_common.c' || echo '$(srcdir)/'`src/providers/ad/ad_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_common.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_common.c' object='src/providers/ad/libsss_ad_tests_la-ad_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_common.lo `test -f 'src/providers/ad/ad_common.c' || echo '$(srcdir)/'`src/providers/ad/ad_common.c src/providers/ad/libsss_ad_tests_la-ad_init.lo: src/providers/ad/ad_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_init.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_init.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_init.lo `test -f 'src/providers/ad/ad_init.c' || echo '$(srcdir)/'`src/providers/ad/ad_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_init.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_init.c' object='src/providers/ad/libsss_ad_tests_la-ad_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_init.lo `test -f 'src/providers/ad/ad_init.c' || echo '$(srcdir)/'`src/providers/ad/ad_init.c src/providers/ad/libsss_ad_tests_la-ad_dyndns.lo: src/providers/ad/ad_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_dyndns.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_dyndns.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_dyndns.lo `test -f 'src/providers/ad/ad_dyndns.c' || echo '$(srcdir)/'`src/providers/ad/ad_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_dyndns.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_dyndns.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_dyndns.c' object='src/providers/ad/libsss_ad_tests_la-ad_dyndns.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_dyndns.lo `test -f 'src/providers/ad/ad_dyndns.c' || echo '$(srcdir)/'`src/providers/ad/ad_dyndns.c src/providers/ad/libsss_ad_tests_la-ad_machine_pw_renewal.lo: src/providers/ad/ad_machine_pw_renewal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_machine_pw_renewal.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_machine_pw_renewal.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_machine_pw_renewal.lo `test -f 'src/providers/ad/ad_machine_pw_renewal.c' || echo '$(srcdir)/'`src/providers/ad/ad_machine_pw_renewal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_machine_pw_renewal.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_machine_pw_renewal.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_machine_pw_renewal.c' object='src/providers/ad/libsss_ad_tests_la-ad_machine_pw_renewal.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_machine_pw_renewal.lo `test -f 'src/providers/ad/ad_machine_pw_renewal.c' || echo '$(srcdir)/'`src/providers/ad/ad_machine_pw_renewal.c src/providers/ad/libsss_ad_tests_la-ad_id.lo: src/providers/ad/ad_id.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_id.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_id.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_id.lo `test -f 'src/providers/ad/ad_id.c' || echo '$(srcdir)/'`src/providers/ad/ad_id.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_id.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_id.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_id.c' object='src/providers/ad/libsss_ad_tests_la-ad_id.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_id.lo `test -f 'src/providers/ad/ad_id.c' || echo '$(srcdir)/'`src/providers/ad/ad_id.c src/providers/ad/libsss_ad_tests_la-ad_access.lo: src/providers/ad/ad_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_access.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_access.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_access.lo `test -f 'src/providers/ad/ad_access.c' || echo '$(srcdir)/'`src/providers/ad/ad_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_access.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_access.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_access.c' object='src/providers/ad/libsss_ad_tests_la-ad_access.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_access.lo `test -f 'src/providers/ad/ad_access.c' || echo '$(srcdir)/'`src/providers/ad/ad_access.c src/providers/ad/libsss_ad_tests_la-ad_gpo.lo: src/providers/ad/ad_gpo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_gpo.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_gpo.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_gpo.lo `test -f 'src/providers/ad/ad_gpo.c' || echo '$(srcdir)/'`src/providers/ad/ad_gpo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_gpo.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_gpo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_gpo.c' object='src/providers/ad/libsss_ad_tests_la-ad_gpo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_gpo.lo `test -f 'src/providers/ad/ad_gpo.c' || echo '$(srcdir)/'`src/providers/ad/ad_gpo.c src/providers/ad/libsss_ad_tests_la-ad_gpo_ndr.lo: src/providers/ad/ad_gpo_ndr.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_gpo_ndr.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_gpo_ndr.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_gpo_ndr.lo `test -f 'src/providers/ad/ad_gpo_ndr.c' || echo '$(srcdir)/'`src/providers/ad/ad_gpo_ndr.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_gpo_ndr.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_gpo_ndr.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_gpo_ndr.c' object='src/providers/ad/libsss_ad_tests_la-ad_gpo_ndr.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_gpo_ndr.lo `test -f 'src/providers/ad/ad_gpo_ndr.c' || echo '$(srcdir)/'`src/providers/ad/ad_gpo_ndr.c src/providers/ad/libsss_ad_tests_la-ad_srv.lo: src/providers/ad/ad_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_srv.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_srv.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_srv.lo `test -f 'src/providers/ad/ad_srv.c' || echo '$(srcdir)/'`src/providers/ad/ad_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_srv.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_srv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_srv.c' object='src/providers/ad/libsss_ad_tests_la-ad_srv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_srv.lo `test -f 'src/providers/ad/ad_srv.c' || echo '$(srcdir)/'`src/providers/ad/ad_srv.c src/providers/ad/libsss_ad_tests_la-ad_subdomains.lo: src/providers/ad/ad_subdomains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_subdomains.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_subdomains.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_subdomains.lo `test -f 'src/providers/ad/ad_subdomains.c' || echo '$(srcdir)/'`src/providers/ad/ad_subdomains.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_subdomains.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_subdomains.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_subdomains.c' object='src/providers/ad/libsss_ad_tests_la-ad_subdomains.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_subdomains.lo `test -f 'src/providers/ad/ad_subdomains.c' || echo '$(srcdir)/'`src/providers/ad/ad_subdomains.c src/providers/ad/libsss_ad_tests_la-ad_domain_info.lo: src/providers/ad/ad_domain_info.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_domain_info.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_domain_info.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_domain_info.lo `test -f 'src/providers/ad/ad_domain_info.c' || echo '$(srcdir)/'`src/providers/ad/ad_domain_info.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_domain_info.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_domain_info.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_domain_info.c' object='src/providers/ad/libsss_ad_tests_la-ad_domain_info.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_domain_info.lo `test -f 'src/providers/ad/ad_domain_info.c' || echo '$(srcdir)/'`src/providers/ad/ad_domain_info.c src/providers/ad/libsss_ad_tests_la-ad_sudo.lo: src/providers/ad/ad_sudo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_sudo.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_sudo.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_sudo.lo `test -f 'src/providers/ad/ad_sudo.c' || echo '$(srcdir)/'`src/providers/ad/ad_sudo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_sudo.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_sudo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_sudo.c' object='src/providers/ad/libsss_ad_tests_la-ad_sudo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_sudo.lo `test -f 'src/providers/ad/ad_sudo.c' || echo '$(srcdir)/'`src/providers/ad/ad_sudo.c src/providers/ad/libsss_ad_tests_la-ad_autofs.lo: src/providers/ad/ad_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ad_tests_la-ad_autofs.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_autofs.Tpo -c -o src/providers/ad/libsss_ad_tests_la-ad_autofs.lo `test -f 'src/providers/ad/ad_autofs.c' || echo '$(srcdir)/'`src/providers/ad/ad_autofs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_autofs.Tpo src/providers/ad/$(DEPDIR)/libsss_ad_tests_la-ad_autofs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_autofs.c' object='src/providers/ad/libsss_ad_tests_la-ad_autofs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ad_tests_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ad_tests_la-ad_autofs.lo `test -f 'src/providers/ad/ad_autofs.c' || echo '$(srcdir)/'`src/providers/ad/ad_autofs.c src/util/cert/libsss_cert_la-cert_common.lo: src/util/cert/cert_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_cert_la_CFLAGS) $(CFLAGS) -MT src/util/cert/libsss_cert_la-cert_common.lo -MD -MP -MF src/util/cert/$(DEPDIR)/libsss_cert_la-cert_common.Tpo -c -o src/util/cert/libsss_cert_la-cert_common.lo `test -f 'src/util/cert/cert_common.c' || echo '$(srcdir)/'`src/util/cert/cert_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/cert/$(DEPDIR)/libsss_cert_la-cert_common.Tpo src/util/cert/$(DEPDIR)/libsss_cert_la-cert_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/cert/cert_common.c' object='src/util/cert/libsss_cert_la-cert_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_cert_la_CFLAGS) $(CFLAGS) -c -o src/util/cert/libsss_cert_la-cert_common.lo `test -f 'src/util/cert/cert_common.c' || echo '$(srcdir)/'`src/util/cert/cert_common.c src/util/cert/libcrypto/libsss_cert_la-cert.lo: src/util/cert/libcrypto/cert.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_cert_la_CFLAGS) $(CFLAGS) -MT src/util/cert/libcrypto/libsss_cert_la-cert.lo -MD -MP -MF src/util/cert/libcrypto/$(DEPDIR)/libsss_cert_la-cert.Tpo -c -o src/util/cert/libcrypto/libsss_cert_la-cert.lo `test -f 'src/util/cert/libcrypto/cert.c' || echo '$(srcdir)/'`src/util/cert/libcrypto/cert.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/cert/libcrypto/$(DEPDIR)/libsss_cert_la-cert.Tpo src/util/cert/libcrypto/$(DEPDIR)/libsss_cert_la-cert.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/cert/libcrypto/cert.c' object='src/util/cert/libcrypto/libsss_cert_la-cert.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_cert_la_CFLAGS) $(CFLAGS) -c -o src/util/cert/libcrypto/libsss_cert_la-cert.lo `test -f 'src/util/cert/libcrypto/cert.c' || echo '$(srcdir)/'`src/util/cert/libcrypto/cert.c src/util/cert/nss/libsss_cert_la-cert.lo: src/util/cert/nss/cert.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_cert_la_CFLAGS) $(CFLAGS) -MT src/util/cert/nss/libsss_cert_la-cert.lo -MD -MP -MF src/util/cert/nss/$(DEPDIR)/libsss_cert_la-cert.Tpo -c -o src/util/cert/nss/libsss_cert_la-cert.lo `test -f 'src/util/cert/nss/cert.c' || echo '$(srcdir)/'`src/util/cert/nss/cert.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/cert/nss/$(DEPDIR)/libsss_cert_la-cert.Tpo src/util/cert/nss/$(DEPDIR)/libsss_cert_la-cert.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/cert/nss/cert.c' object='src/util/cert/nss/libsss_cert_la-cert.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_cert_la_CFLAGS) $(CFLAGS) -c -o src/util/cert/nss/libsss_cert_la-cert.lo `test -f 'src/util/cert/nss/cert.c' || echo '$(srcdir)/'`src/util/cert/nss/cert.c src/util/libsss_config_la-sss_config.lo: src/util/sss_config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_config_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_config_la-sss_config.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_config_la-sss_config.Tpo -c -o src/util/libsss_config_la-sss_config.lo `test -f 'src/util/sss_config.c' || echo '$(srcdir)/'`src/util/sss_config.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_config_la-sss_config.Tpo src/util/$(DEPDIR)/libsss_config_la-sss_config.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_config.c' object='src/util/libsss_config_la-sss_config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_config_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_config_la-sss_config.lo `test -f 'src/util/sss_config.c' || echo '$(srcdir)/'`src/util/sss_config.c src/util/crypto/libcrypto/libsss_crypt_la-crypto_base64.lo: src/util/crypto/libcrypto/crypto_base64.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -MT src/util/crypto/libcrypto/libsss_crypt_la-crypto_base64.lo -MD -MP -MF src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_base64.Tpo -c -o src/util/crypto/libcrypto/libsss_crypt_la-crypto_base64.lo `test -f 'src/util/crypto/libcrypto/crypto_base64.c' || echo '$(srcdir)/'`src/util/crypto/libcrypto/crypto_base64.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_base64.Tpo src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_base64.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/crypto/libcrypto/crypto_base64.c' object='src/util/crypto/libcrypto/libsss_crypt_la-crypto_base64.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -c -o src/util/crypto/libcrypto/libsss_crypt_la-crypto_base64.lo `test -f 'src/util/crypto/libcrypto/crypto_base64.c' || echo '$(srcdir)/'`src/util/crypto/libcrypto/crypto_base64.c src/util/crypto/libcrypto/libsss_crypt_la-crypto_hmac_sha1.lo: src/util/crypto/libcrypto/crypto_hmac_sha1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -MT src/util/crypto/libcrypto/libsss_crypt_la-crypto_hmac_sha1.lo -MD -MP -MF src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_hmac_sha1.Tpo -c -o src/util/crypto/libcrypto/libsss_crypt_la-crypto_hmac_sha1.lo `test -f 'src/util/crypto/libcrypto/crypto_hmac_sha1.c' || echo '$(srcdir)/'`src/util/crypto/libcrypto/crypto_hmac_sha1.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_hmac_sha1.Tpo src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_hmac_sha1.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/crypto/libcrypto/crypto_hmac_sha1.c' object='src/util/crypto/libcrypto/libsss_crypt_la-crypto_hmac_sha1.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -c -o src/util/crypto/libcrypto/libsss_crypt_la-crypto_hmac_sha1.lo `test -f 'src/util/crypto/libcrypto/crypto_hmac_sha1.c' || echo '$(srcdir)/'`src/util/crypto/libcrypto/crypto_hmac_sha1.c src/util/crypto/libcrypto/libsss_crypt_la-crypto_sha512crypt.lo: src/util/crypto/libcrypto/crypto_sha512crypt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -MT src/util/crypto/libcrypto/libsss_crypt_la-crypto_sha512crypt.lo -MD -MP -MF src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_sha512crypt.Tpo -c -o src/util/crypto/libcrypto/libsss_crypt_la-crypto_sha512crypt.lo `test -f 'src/util/crypto/libcrypto/crypto_sha512crypt.c' || echo '$(srcdir)/'`src/util/crypto/libcrypto/crypto_sha512crypt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_sha512crypt.Tpo src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_sha512crypt.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/crypto/libcrypto/crypto_sha512crypt.c' object='src/util/crypto/libcrypto/libsss_crypt_la-crypto_sha512crypt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -c -o src/util/crypto/libcrypto/libsss_crypt_la-crypto_sha512crypt.lo `test -f 'src/util/crypto/libcrypto/crypto_sha512crypt.c' || echo '$(srcdir)/'`src/util/crypto/libcrypto/crypto_sha512crypt.c src/util/crypto/libcrypto/libsss_crypt_la-crypto_obfuscate.lo: src/util/crypto/libcrypto/crypto_obfuscate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -MT src/util/crypto/libcrypto/libsss_crypt_la-crypto_obfuscate.lo -MD -MP -MF src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_obfuscate.Tpo -c -o src/util/crypto/libcrypto/libsss_crypt_la-crypto_obfuscate.lo `test -f 'src/util/crypto/libcrypto/crypto_obfuscate.c' || echo '$(srcdir)/'`src/util/crypto/libcrypto/crypto_obfuscate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_obfuscate.Tpo src/util/crypto/libcrypto/$(DEPDIR)/libsss_crypt_la-crypto_obfuscate.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/crypto/libcrypto/crypto_obfuscate.c' object='src/util/crypto/libcrypto/libsss_crypt_la-crypto_obfuscate.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -c -o src/util/crypto/libcrypto/libsss_crypt_la-crypto_obfuscate.lo `test -f 'src/util/crypto/libcrypto/crypto_obfuscate.c' || echo '$(srcdir)/'`src/util/crypto/libcrypto/crypto_obfuscate.c src/util/crypto/nss/libsss_crypt_la-nss_base64.lo: src/util/crypto/nss/nss_base64.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -MT src/util/crypto/nss/libsss_crypt_la-nss_base64.lo -MD -MP -MF src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_base64.Tpo -c -o src/util/crypto/nss/libsss_crypt_la-nss_base64.lo `test -f 'src/util/crypto/nss/nss_base64.c' || echo '$(srcdir)/'`src/util/crypto/nss/nss_base64.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_base64.Tpo src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_base64.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/crypto/nss/nss_base64.c' object='src/util/crypto/nss/libsss_crypt_la-nss_base64.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -c -o src/util/crypto/nss/libsss_crypt_la-nss_base64.lo `test -f 'src/util/crypto/nss/nss_base64.c' || echo '$(srcdir)/'`src/util/crypto/nss/nss_base64.c src/util/crypto/nss/libsss_crypt_la-nss_hmac_sha1.lo: src/util/crypto/nss/nss_hmac_sha1.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -MT src/util/crypto/nss/libsss_crypt_la-nss_hmac_sha1.lo -MD -MP -MF src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_hmac_sha1.Tpo -c -o src/util/crypto/nss/libsss_crypt_la-nss_hmac_sha1.lo `test -f 'src/util/crypto/nss/nss_hmac_sha1.c' || echo '$(srcdir)/'`src/util/crypto/nss/nss_hmac_sha1.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_hmac_sha1.Tpo src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_hmac_sha1.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/crypto/nss/nss_hmac_sha1.c' object='src/util/crypto/nss/libsss_crypt_la-nss_hmac_sha1.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -c -o src/util/crypto/nss/libsss_crypt_la-nss_hmac_sha1.lo `test -f 'src/util/crypto/nss/nss_hmac_sha1.c' || echo '$(srcdir)/'`src/util/crypto/nss/nss_hmac_sha1.c src/util/crypto/nss/libsss_crypt_la-nss_sha512crypt.lo: src/util/crypto/nss/nss_sha512crypt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -MT src/util/crypto/nss/libsss_crypt_la-nss_sha512crypt.lo -MD -MP -MF src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_sha512crypt.Tpo -c -o src/util/crypto/nss/libsss_crypt_la-nss_sha512crypt.lo `test -f 'src/util/crypto/nss/nss_sha512crypt.c' || echo '$(srcdir)/'`src/util/crypto/nss/nss_sha512crypt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_sha512crypt.Tpo src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_sha512crypt.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/crypto/nss/nss_sha512crypt.c' object='src/util/crypto/nss/libsss_crypt_la-nss_sha512crypt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -c -o src/util/crypto/nss/libsss_crypt_la-nss_sha512crypt.lo `test -f 'src/util/crypto/nss/nss_sha512crypt.c' || echo '$(srcdir)/'`src/util/crypto/nss/nss_sha512crypt.c src/util/crypto/nss/libsss_crypt_la-nss_obfuscate.lo: src/util/crypto/nss/nss_obfuscate.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -MT src/util/crypto/nss/libsss_crypt_la-nss_obfuscate.lo -MD -MP -MF src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_obfuscate.Tpo -c -o src/util/crypto/nss/libsss_crypt_la-nss_obfuscate.lo `test -f 'src/util/crypto/nss/nss_obfuscate.c' || echo '$(srcdir)/'`src/util/crypto/nss/nss_obfuscate.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_obfuscate.Tpo src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_obfuscate.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/crypto/nss/nss_obfuscate.c' object='src/util/crypto/nss/libsss_crypt_la-nss_obfuscate.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -c -o src/util/crypto/nss/libsss_crypt_la-nss_obfuscate.lo `test -f 'src/util/crypto/nss/nss_obfuscate.c' || echo '$(srcdir)/'`src/util/crypto/nss/nss_obfuscate.c src/util/crypto/nss/libsss_crypt_la-nss_util.lo: src/util/crypto/nss/nss_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -MT src/util/crypto/nss/libsss_crypt_la-nss_util.lo -MD -MP -MF src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_util.Tpo -c -o src/util/crypto/nss/libsss_crypt_la-nss_util.lo `test -f 'src/util/crypto/nss/nss_util.c' || echo '$(srcdir)/'`src/util/crypto/nss/nss_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_util.Tpo src/util/crypto/nss/$(DEPDIR)/libsss_crypt_la-nss_util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/crypto/nss/nss_util.c' object='src/util/crypto/nss/libsss_crypt_la-nss_util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_crypt_la_CFLAGS) $(CFLAGS) -c -o src/util/crypto/nss/libsss_crypt_la-nss_util.lo `test -f 'src/util/crypto/nss/nss_util.c' || echo '$(srcdir)/'`src/util/crypto/nss/nss_util.c src/providers/ipa/libsss_ipa_la-ipa_init.lo: src/providers/ipa/ipa_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_init.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_init.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_init.lo `test -f 'src/providers/ipa/ipa_init.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_init.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_init.c' object='src/providers/ipa/libsss_ipa_la-ipa_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_init.lo `test -f 'src/providers/ipa/ipa_init.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_init.c src/providers/ipa/libsss_ipa_la-ipa_opts.lo: src/providers/ipa/ipa_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_opts.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_opts.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_opts.lo `test -f 'src/providers/ipa/ipa_opts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_opts.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_opts.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_opts.c' object='src/providers/ipa/libsss_ipa_la-ipa_opts.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_opts.lo `test -f 'src/providers/ipa/ipa_opts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_opts.c src/providers/ipa/libsss_ipa_la-ipa_common.lo: src/providers/ipa/ipa_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_common.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_common.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_common.lo `test -f 'src/providers/ipa/ipa_common.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_common.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_common.c' object='src/providers/ipa/libsss_ipa_la-ipa_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_common.lo `test -f 'src/providers/ipa/ipa_common.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_common.c src/providers/ipa/libsss_ipa_la-ipa_config.lo: src/providers/ipa/ipa_config.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_config.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_config.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_config.lo `test -f 'src/providers/ipa/ipa_config.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_config.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_config.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_config.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_config.c' object='src/providers/ipa/libsss_ipa_la-ipa_config.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_config.lo `test -f 'src/providers/ipa/ipa_config.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_config.c src/providers/ipa/libsss_ipa_la-ipa_id.lo: src/providers/ipa/ipa_id.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_id.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_id.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_id.lo `test -f 'src/providers/ipa/ipa_id.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_id.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_id.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_id.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_id.c' object='src/providers/ipa/libsss_ipa_la-ipa_id.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_id.lo `test -f 'src/providers/ipa/ipa_id.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_id.c src/providers/ipa/libsss_ipa_la-ipa_netgroups.lo: src/providers/ipa/ipa_netgroups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_netgroups.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_netgroups.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_netgroups.lo `test -f 'src/providers/ipa/ipa_netgroups.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_netgroups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_netgroups.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_netgroups.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_netgroups.c' object='src/providers/ipa/libsss_ipa_la-ipa_netgroups.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_netgroups.lo `test -f 'src/providers/ipa/ipa_netgroups.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_netgroups.c src/providers/ipa/libsss_ipa_la-ipa_auth.lo: src/providers/ipa/ipa_auth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_auth.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_auth.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_auth.lo `test -f 'src/providers/ipa/ipa_auth.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_auth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_auth.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_auth.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_auth.c' object='src/providers/ipa/libsss_ipa_la-ipa_auth.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_auth.lo `test -f 'src/providers/ipa/ipa_auth.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_auth.c src/providers/ipa/libsss_ipa_la-ipa_access.lo: src/providers/ipa/ipa_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_access.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_access.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_access.lo `test -f 'src/providers/ipa/ipa_access.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_access.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_access.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_access.c' object='src/providers/ipa/libsss_ipa_la-ipa_access.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_access.lo `test -f 'src/providers/ipa/ipa_access.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_access.c src/providers/ipa/libsss_ipa_la-ipa_dyndns.lo: src/providers/ipa/ipa_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_dyndns.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_dyndns.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_dyndns.lo `test -f 'src/providers/ipa/ipa_dyndns.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_dyndns.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_dyndns.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_dyndns.c' object='src/providers/ipa/libsss_ipa_la-ipa_dyndns.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_dyndns.lo `test -f 'src/providers/ipa/ipa_dyndns.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_dyndns.c src/providers/ipa/libsss_ipa_la-ipa_hosts.lo: src/providers/ipa/ipa_hosts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_hosts.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hosts.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_hosts.lo `test -f 'src/providers/ipa/ipa_hosts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hosts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hosts.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hosts.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_hosts.c' object='src/providers/ipa/libsss_ipa_la-ipa_hosts.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_hosts.lo `test -f 'src/providers/ipa/ipa_hosts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hosts.c src/providers/ipa/libsss_ipa_la-ipa_subdomains.lo: src/providers/ipa/ipa_subdomains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_subdomains.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_subdomains.lo `test -f 'src/providers/ipa/ipa_subdomains.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_subdomains.c' object='src/providers/ipa/libsss_ipa_la-ipa_subdomains.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_subdomains.lo `test -f 'src/providers/ipa/ipa_subdomains.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains.c src/providers/ipa/libsss_ipa_la-ipa_subdomains_id.lo: src/providers/ipa/ipa_subdomains_id.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_subdomains_id.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_id.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_subdomains_id.lo `test -f 'src/providers/ipa/ipa_subdomains_id.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_id.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_id.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_id.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_subdomains_id.c' object='src/providers/ipa/libsss_ipa_la-ipa_subdomains_id.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_subdomains_id.lo `test -f 'src/providers/ipa/ipa_subdomains_id.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_id.c src/providers/ipa/libsss_ipa_la-ipa_subdomains_server.lo: src/providers/ipa/ipa_subdomains_server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_subdomains_server.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_server.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_subdomains_server.lo `test -f 'src/providers/ipa/ipa_subdomains_server.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_server.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_server.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_server.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_subdomains_server.c' object='src/providers/ipa/libsss_ipa_la-ipa_subdomains_server.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_subdomains_server.lo `test -f 'src/providers/ipa/ipa_subdomains_server.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_server.c src/providers/ipa/libsss_ipa_la-ipa_subdomains_utils.lo: src/providers/ipa/ipa_subdomains_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_subdomains_utils.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_utils.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_subdomains_utils.lo `test -f 'src/providers/ipa/ipa_subdomains_utils.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_utils.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_subdomains_utils.c' object='src/providers/ipa/libsss_ipa_la-ipa_subdomains_utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_subdomains_utils.lo `test -f 'src/providers/ipa/ipa_subdomains_utils.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_utils.c src/providers/ipa/libsss_ipa_la-ipa_subdomains_ext_groups.lo: src/providers/ipa/ipa_subdomains_ext_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_subdomains_ext_groups.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_ext_groups.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_subdomains_ext_groups.lo `test -f 'src/providers/ipa/ipa_subdomains_ext_groups.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_ext_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_ext_groups.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_subdomains_ext_groups.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_subdomains_ext_groups.c' object='src/providers/ipa/libsss_ipa_la-ipa_subdomains_ext_groups.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_subdomains_ext_groups.lo `test -f 'src/providers/ipa/ipa_subdomains_ext_groups.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_ext_groups.c src/providers/ipa/libsss_ipa_la-ipa_views.lo: src/providers/ipa/ipa_views.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_views.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_views.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_views.lo `test -f 'src/providers/ipa/ipa_views.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_views.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_views.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_views.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_views.c' object='src/providers/ipa/libsss_ipa_la-ipa_views.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_views.lo `test -f 'src/providers/ipa/ipa_views.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_views.c src/providers/ipa/libsss_ipa_la-ipa_utils.lo: src/providers/ipa/ipa_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_utils.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_utils.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_utils.lo `test -f 'src/providers/ipa/ipa_utils.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_utils.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_utils.c' object='src/providers/ipa/libsss_ipa_la-ipa_utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_utils.lo `test -f 'src/providers/ipa/ipa_utils.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_utils.c src/providers/ipa/libsss_ipa_la-ipa_s2n_exop.lo: src/providers/ipa/ipa_s2n_exop.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_s2n_exop.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_s2n_exop.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_s2n_exop.lo `test -f 'src/providers/ipa/ipa_s2n_exop.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_s2n_exop.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_s2n_exop.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_s2n_exop.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_s2n_exop.c' object='src/providers/ipa/libsss_ipa_la-ipa_s2n_exop.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_s2n_exop.lo `test -f 'src/providers/ipa/ipa_s2n_exop.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_s2n_exop.c src/providers/ipa/libsss_ipa_la-ipa_hbac_hosts.lo: src/providers/ipa/ipa_hbac_hosts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_hbac_hosts.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_hosts.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_hbac_hosts.lo `test -f 'src/providers/ipa/ipa_hbac_hosts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hbac_hosts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_hosts.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_hosts.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_hbac_hosts.c' object='src/providers/ipa/libsss_ipa_la-ipa_hbac_hosts.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_hbac_hosts.lo `test -f 'src/providers/ipa/ipa_hbac_hosts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hbac_hosts.c src/providers/ipa/libsss_ipa_la-ipa_hbac_rules.lo: src/providers/ipa/ipa_hbac_rules.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_hbac_rules.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_rules.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_hbac_rules.lo `test -f 'src/providers/ipa/ipa_hbac_rules.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hbac_rules.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_rules.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_rules.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_hbac_rules.c' object='src/providers/ipa/libsss_ipa_la-ipa_hbac_rules.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_hbac_rules.lo `test -f 'src/providers/ipa/ipa_hbac_rules.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hbac_rules.c src/providers/ipa/libsss_ipa_la-ipa_hbac_services.lo: src/providers/ipa/ipa_hbac_services.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_hbac_services.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_services.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_hbac_services.lo `test -f 'src/providers/ipa/ipa_hbac_services.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hbac_services.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_services.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_services.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_hbac_services.c' object='src/providers/ipa/libsss_ipa_la-ipa_hbac_services.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_hbac_services.lo `test -f 'src/providers/ipa/ipa_hbac_services.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hbac_services.c src/providers/ipa/libsss_ipa_la-ipa_hbac_users.lo: src/providers/ipa/ipa_hbac_users.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_hbac_users.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_users.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_hbac_users.lo `test -f 'src/providers/ipa/ipa_hbac_users.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hbac_users.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_users.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_users.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_hbac_users.c' object='src/providers/ipa/libsss_ipa_la-ipa_hbac_users.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_hbac_users.lo `test -f 'src/providers/ipa/ipa_hbac_users.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hbac_users.c src/providers/ipa/libsss_ipa_la-ipa_hbac_common.lo: src/providers/ipa/ipa_hbac_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_hbac_common.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_common.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_hbac_common.lo `test -f 'src/providers/ipa/ipa_hbac_common.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hbac_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_common.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hbac_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_hbac_common.c' object='src/providers/ipa/libsss_ipa_la-ipa_hbac_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_hbac_common.lo `test -f 'src/providers/ipa/ipa_hbac_common.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hbac_common.c src/providers/ipa/libsss_ipa_la-ipa_selinux.lo: src/providers/ipa/ipa_selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_selinux.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_selinux.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_selinux.lo `test -f 'src/providers/ipa/ipa_selinux.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_selinux.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_selinux.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_selinux.c' object='src/providers/ipa/libsss_ipa_la-ipa_selinux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_selinux.lo `test -f 'src/providers/ipa/ipa_selinux.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_selinux.c src/providers/ipa/libsss_ipa_la-ipa_selinux_maps.lo: src/providers/ipa/ipa_selinux_maps.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_selinux_maps.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_selinux_maps.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_selinux_maps.lo `test -f 'src/providers/ipa/ipa_selinux_maps.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_selinux_maps.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_selinux_maps.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_selinux_maps.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_selinux_maps.c' object='src/providers/ipa/libsss_ipa_la-ipa_selinux_maps.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_selinux_maps.lo `test -f 'src/providers/ipa/ipa_selinux_maps.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_selinux_maps.c src/providers/ipa/libsss_ipa_la-ipa_srv.lo: src/providers/ipa/ipa_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_srv.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_srv.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_srv.lo `test -f 'src/providers/ipa/ipa_srv.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_srv.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_srv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_srv.c' object='src/providers/ipa/libsss_ipa_la-ipa_srv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_srv.lo `test -f 'src/providers/ipa/ipa_srv.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_srv.c src/providers/ipa/libsss_ipa_la-ipa_idmap.lo: src/providers/ipa/ipa_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_idmap.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_idmap.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_idmap.lo `test -f 'src/providers/ipa/ipa_idmap.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_idmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_idmap.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_idmap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_idmap.c' object='src/providers/ipa/libsss_ipa_la-ipa_idmap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_idmap.lo `test -f 'src/providers/ipa/ipa_idmap.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_idmap.c src/providers/ipa/libsss_ipa_la-ipa_dn.lo: src/providers/ipa/ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_dn.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_dn.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_dn.lo `test -f 'src/providers/ipa/ipa_dn.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_dn.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_dn.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_dn.c' object='src/providers/ipa/libsss_ipa_la-ipa_dn.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_dn.lo `test -f 'src/providers/ipa/ipa_dn.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_dn.c src/providers/ad/libsss_ipa_la-ad_opts.lo: src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ipa_la-ad_opts.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_opts.Tpo -c -o src/providers/ad/libsss_ipa_la-ad_opts.lo `test -f 'src/providers/ad/ad_opts.c' || echo '$(srcdir)/'`src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_opts.Tpo src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_opts.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_opts.c' object='src/providers/ad/libsss_ipa_la-ad_opts.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ipa_la-ad_opts.lo `test -f 'src/providers/ad/ad_opts.c' || echo '$(srcdir)/'`src/providers/ad/ad_opts.c src/providers/ad/libsss_ipa_la-ad_common.lo: src/providers/ad/ad_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ipa_la-ad_common.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_common.Tpo -c -o src/providers/ad/libsss_ipa_la-ad_common.lo `test -f 'src/providers/ad/ad_common.c' || echo '$(srcdir)/'`src/providers/ad/ad_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_common.Tpo src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_common.c' object='src/providers/ad/libsss_ipa_la-ad_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ipa_la-ad_common.lo `test -f 'src/providers/ad/ad_common.c' || echo '$(srcdir)/'`src/providers/ad/ad_common.c src/providers/ad/libsss_ipa_la-ad_dyndns.lo: src/providers/ad/ad_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ipa_la-ad_dyndns.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_dyndns.Tpo -c -o src/providers/ad/libsss_ipa_la-ad_dyndns.lo `test -f 'src/providers/ad/ad_dyndns.c' || echo '$(srcdir)/'`src/providers/ad/ad_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_dyndns.Tpo src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_dyndns.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_dyndns.c' object='src/providers/ad/libsss_ipa_la-ad_dyndns.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ipa_la-ad_dyndns.lo `test -f 'src/providers/ad/ad_dyndns.c' || echo '$(srcdir)/'`src/providers/ad/ad_dyndns.c src/providers/ad/libsss_ipa_la-ad_id.lo: src/providers/ad/ad_id.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ipa_la-ad_id.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_id.Tpo -c -o src/providers/ad/libsss_ipa_la-ad_id.lo `test -f 'src/providers/ad/ad_id.c' || echo '$(srcdir)/'`src/providers/ad/ad_id.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_id.Tpo src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_id.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_id.c' object='src/providers/ad/libsss_ipa_la-ad_id.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ipa_la-ad_id.lo `test -f 'src/providers/ad/ad_id.c' || echo '$(srcdir)/'`src/providers/ad/ad_id.c src/providers/ad/libsss_ipa_la-ad_srv.lo: src/providers/ad/ad_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ipa_la-ad_srv.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_srv.Tpo -c -o src/providers/ad/libsss_ipa_la-ad_srv.lo `test -f 'src/providers/ad/ad_srv.c' || echo '$(srcdir)/'`src/providers/ad/ad_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_srv.Tpo src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_srv.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_srv.c' object='src/providers/ad/libsss_ipa_la-ad_srv.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ipa_la-ad_srv.lo `test -f 'src/providers/ad/ad_srv.c' || echo '$(srcdir)/'`src/providers/ad/ad_srv.c src/providers/ad/libsss_ipa_la-ad_domain_info.lo: src/providers/ad/ad_domain_info.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ad/libsss_ipa_la-ad_domain_info.lo -MD -MP -MF src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_domain_info.Tpo -c -o src/providers/ad/libsss_ipa_la-ad_domain_info.lo `test -f 'src/providers/ad/ad_domain_info.c' || echo '$(srcdir)/'`src/providers/ad/ad_domain_info.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_domain_info.Tpo src/providers/ad/$(DEPDIR)/libsss_ipa_la-ad_domain_info.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_domain_info.c' object='src/providers/ad/libsss_ipa_la-ad_domain_info.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ad/libsss_ipa_la-ad_domain_info.lo `test -f 'src/providers/ad/ad_domain_info.c' || echo '$(srcdir)/'`src/providers/ad/ad_domain_info.c src/providers/ipa/libsss_ipa_la-ipa_autofs.lo: src/providers/ipa/ipa_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_autofs.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_autofs.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_autofs.lo `test -f 'src/providers/ipa/ipa_autofs.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_autofs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_autofs.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_autofs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_autofs.c' object='src/providers/ipa/libsss_ipa_la-ipa_autofs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_autofs.lo `test -f 'src/providers/ipa/ipa_autofs.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_autofs.c src/providers/ipa/libsss_ipa_la-ipa_sudo.lo: src/providers/ipa/ipa_sudo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_sudo.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_sudo.lo `test -f 'src/providers/ipa/ipa_sudo.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_sudo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_sudo.c' object='src/providers/ipa/libsss_ipa_la-ipa_sudo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_sudo.lo `test -f 'src/providers/ipa/ipa_sudo.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_sudo.c src/providers/ipa/libsss_ipa_la-ipa_sudo_refresh.lo: src/providers/ipa/ipa_sudo_refresh.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_sudo_refresh.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_refresh.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_sudo_refresh.lo `test -f 'src/providers/ipa/ipa_sudo_refresh.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_sudo_refresh.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_refresh.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_refresh.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_sudo_refresh.c' object='src/providers/ipa/libsss_ipa_la-ipa_sudo_refresh.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_sudo_refresh.lo `test -f 'src/providers/ipa/ipa_sudo_refresh.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_sudo_refresh.c src/providers/ipa/libsss_ipa_la-ipa_sudo_conversion.lo: src/providers/ipa/ipa_sudo_conversion.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_sudo_conversion.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_conversion.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_sudo_conversion.lo `test -f 'src/providers/ipa/ipa_sudo_conversion.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_sudo_conversion.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_conversion.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_conversion.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_sudo_conversion.c' object='src/providers/ipa/libsss_ipa_la-ipa_sudo_conversion.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_sudo_conversion.lo `test -f 'src/providers/ipa/ipa_sudo_conversion.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_sudo_conversion.c src/providers/ipa/libsss_ipa_la-ipa_sudo_async.lo: src/providers/ipa/ipa_sudo_async.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_sudo_async.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_async.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_sudo_async.lo `test -f 'src/providers/ipa/ipa_sudo_async.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_sudo_async.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_async.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_sudo_async.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_sudo_async.c' object='src/providers/ipa/libsss_ipa_la-ipa_sudo_async.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_sudo_async.lo `test -f 'src/providers/ipa/ipa_sudo_async.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_sudo_async.c src/providers/ipa/libsss_ipa_la-ipa_hostid.lo: src/providers/ipa/ipa_hostid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ipa_la-ipa_hostid.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hostid.Tpo -c -o src/providers/ipa/libsss_ipa_la-ipa_hostid.lo `test -f 'src/providers/ipa/ipa_hostid.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hostid.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hostid.Tpo src/providers/ipa/$(DEPDIR)/libsss_ipa_la-ipa_hostid.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_hostid.c' object='src/providers/ipa/libsss_ipa_la-ipa_hostid.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ipa_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ipa_la-ipa_hostid.lo `test -f 'src/providers/ipa/ipa_hostid.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_hostid.c src/providers/krb5/libsss_krb5_la-krb5_init.lo: src/providers/krb5/krb5_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_la-krb5_init.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_la-krb5_init.Tpo -c -o src/providers/krb5/libsss_krb5_la-krb5_init.lo `test -f 'src/providers/krb5/krb5_init.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_la-krb5_init.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_la-krb5_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_init.c' object='src/providers/krb5/libsss_krb5_la-krb5_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_la-krb5_init.lo `test -f 'src/providers/krb5/krb5_init.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_init.c src/providers/krb5/libsss_krb5_common_la-krb5_utils.lo: src/providers/krb5/krb5_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_common_la-krb5_utils.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_utils.Tpo -c -o src/providers/krb5/libsss_krb5_common_la-krb5_utils.lo `test -f 'src/providers/krb5/krb5_utils.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_utils.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_utils.c' object='src/providers/krb5/libsss_krb5_common_la-krb5_utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_common_la-krb5_utils.lo `test -f 'src/providers/krb5/krb5_utils.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_utils.c src/providers/krb5/libsss_krb5_common_la-krb5_delayed_online_authentication.lo: src/providers/krb5/krb5_delayed_online_authentication.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_common_la-krb5_delayed_online_authentication.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_delayed_online_authentication.Tpo -c -o src/providers/krb5/libsss_krb5_common_la-krb5_delayed_online_authentication.lo `test -f 'src/providers/krb5/krb5_delayed_online_authentication.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_delayed_online_authentication.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_delayed_online_authentication.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_delayed_online_authentication.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_delayed_online_authentication.c' object='src/providers/krb5/libsss_krb5_common_la-krb5_delayed_online_authentication.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_common_la-krb5_delayed_online_authentication.lo `test -f 'src/providers/krb5/krb5_delayed_online_authentication.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_delayed_online_authentication.c src/providers/krb5/libsss_krb5_common_la-krb5_renew_tgt.lo: src/providers/krb5/krb5_renew_tgt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_common_la-krb5_renew_tgt.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_renew_tgt.Tpo -c -o src/providers/krb5/libsss_krb5_common_la-krb5_renew_tgt.lo `test -f 'src/providers/krb5/krb5_renew_tgt.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_renew_tgt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_renew_tgt.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_renew_tgt.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_renew_tgt.c' object='src/providers/krb5/libsss_krb5_common_la-krb5_renew_tgt.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_common_la-krb5_renew_tgt.lo `test -f 'src/providers/krb5/krb5_renew_tgt.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_renew_tgt.c src/providers/krb5/libsss_krb5_common_la-krb5_wait_queue.lo: src/providers/krb5/krb5_wait_queue.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_common_la-krb5_wait_queue.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_wait_queue.Tpo -c -o src/providers/krb5/libsss_krb5_common_la-krb5_wait_queue.lo `test -f 'src/providers/krb5/krb5_wait_queue.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_wait_queue.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_wait_queue.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_wait_queue.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_wait_queue.c' object='src/providers/krb5/libsss_krb5_common_la-krb5_wait_queue.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_common_la-krb5_wait_queue.lo `test -f 'src/providers/krb5/krb5_wait_queue.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_wait_queue.c src/providers/krb5/libsss_krb5_common_la-krb5_common.lo: src/providers/krb5/krb5_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_common_la-krb5_common.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_common.Tpo -c -o src/providers/krb5/libsss_krb5_common_la-krb5_common.lo `test -f 'src/providers/krb5/krb5_common.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_common.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_common.c' object='src/providers/krb5/libsss_krb5_common_la-krb5_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_common_la-krb5_common.lo `test -f 'src/providers/krb5/krb5_common.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_common.c src/providers/krb5/libsss_krb5_common_la-krb5_opts.lo: src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_common_la-krb5_opts.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_opts.Tpo -c -o src/providers/krb5/libsss_krb5_common_la-krb5_opts.lo `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_opts.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_opts.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_opts.c' object='src/providers/krb5/libsss_krb5_common_la-krb5_opts.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_common_la-krb5_opts.lo `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c src/providers/krb5/libsss_krb5_common_la-krb5_auth.lo: src/providers/krb5/krb5_auth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_common_la-krb5_auth.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_auth.Tpo -c -o src/providers/krb5/libsss_krb5_common_la-krb5_auth.lo `test -f 'src/providers/krb5/krb5_auth.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_auth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_auth.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_auth.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_auth.c' object='src/providers/krb5/libsss_krb5_common_la-krb5_auth.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_common_la-krb5_auth.lo `test -f 'src/providers/krb5/krb5_auth.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_auth.c src/providers/krb5/libsss_krb5_common_la-krb5_access.lo: src/providers/krb5/krb5_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_common_la-krb5_access.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_access.Tpo -c -o src/providers/krb5/libsss_krb5_common_la-krb5_access.lo `test -f 'src/providers/krb5/krb5_access.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_access.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_access.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_access.c' object='src/providers/krb5/libsss_krb5_common_la-krb5_access.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_common_la-krb5_access.lo `test -f 'src/providers/krb5/krb5_access.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_access.c src/providers/krb5/libsss_krb5_common_la-krb5_child_handler.lo: src/providers/krb5/krb5_child_handler.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_common_la-krb5_child_handler.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_child_handler.Tpo -c -o src/providers/krb5/libsss_krb5_common_la-krb5_child_handler.lo `test -f 'src/providers/krb5/krb5_child_handler.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_child_handler.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_child_handler.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_child_handler.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_child_handler.c' object='src/providers/krb5/libsss_krb5_common_la-krb5_child_handler.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_common_la-krb5_child_handler.lo `test -f 'src/providers/krb5/krb5_child_handler.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_child_handler.c src/providers/krb5/libsss_krb5_common_la-krb5_init_shared.lo: src/providers/krb5/krb5_init_shared.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_common_la-krb5_init_shared.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_init_shared.Tpo -c -o src/providers/krb5/libsss_krb5_common_la-krb5_init_shared.lo `test -f 'src/providers/krb5/krb5_init_shared.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_init_shared.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_init_shared.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_init_shared.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_init_shared.c' object='src/providers/krb5/libsss_krb5_common_la-krb5_init_shared.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_common_la-krb5_init_shared.lo `test -f 'src/providers/krb5/krb5_init_shared.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_init_shared.c src/providers/krb5/libsss_krb5_common_la-krb5_ccache.lo: src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/providers/krb5/libsss_krb5_common_la-krb5_ccache.lo -MD -MP -MF src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_ccache.Tpo -c -o src/providers/krb5/libsss_krb5_common_la-krb5_ccache.lo `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_ccache.Tpo src/providers/krb5/$(DEPDIR)/libsss_krb5_common_la-krb5_ccache.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_ccache.c' object='src/providers/krb5/libsss_krb5_common_la-krb5_ccache.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/libsss_krb5_common_la-krb5_ccache.lo `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c src/util/libsss_krb5_common_la-sss_krb5.lo: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_krb5_common_la-sss_krb5.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_krb5_common_la-sss_krb5.Tpo -c -o src/util/libsss_krb5_common_la-sss_krb5.lo `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_krb5_common_la-sss_krb5.Tpo src/util/$(DEPDIR)/libsss_krb5_common_la-sss_krb5.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/libsss_krb5_common_la-sss_krb5.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_krb5_common_la-sss_krb5.lo `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c src/util/libsss_krb5_common_la-become_user.lo: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_krb5_common_la-become_user.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_krb5_common_la-become_user.Tpo -c -o src/util/libsss_krb5_common_la-become_user.lo `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_krb5_common_la-become_user.Tpo src/util/$(DEPDIR)/libsss_krb5_common_la-become_user.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/libsss_krb5_common_la-become_user.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_krb5_common_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_krb5_common_la-become_user.lo `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c src/providers/ldap/libsss_ldap_la-ldap_init.lo: src/providers/ldap/ldap_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_la-ldap_init.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_la-ldap_init.Tpo -c -o src/providers/ldap/libsss_ldap_la-ldap_init.lo `test -f 'src/providers/ldap/ldap_init.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_la-ldap_init.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_la-ldap_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_init.c' object='src/providers/ldap/libsss_ldap_la-ldap_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_la-ldap_init.lo `test -f 'src/providers/ldap/ldap_init.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_init.c src/providers/ldap/libsss_ldap_la-ldap_access.lo: src/providers/ldap/ldap_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_la-ldap_access.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_la-ldap_access.Tpo -c -o src/providers/ldap/libsss_ldap_la-ldap_access.lo `test -f 'src/providers/ldap/ldap_access.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_la-ldap_access.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_la-ldap_access.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_access.c' object='src/providers/ldap/libsss_ldap_la-ldap_access.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_la-ldap_access.lo `test -f 'src/providers/ldap/ldap_access.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_access.c src/providers/ldap/libsss_ldap_common_la-ldap_id.lo: src/providers/ldap/ldap_id.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-ldap_id.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-ldap_id.lo `test -f 'src/providers/ldap/ldap_id.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_id.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_id.c' object='src/providers/ldap/libsss_ldap_common_la-ldap_id.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-ldap_id.lo `test -f 'src/providers/ldap/ldap_id.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_id.c src/providers/ldap/libsss_ldap_common_la-ldap_id_enum.lo: src/providers/ldap/ldap_id_enum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-ldap_id_enum.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_enum.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-ldap_id_enum.lo `test -f 'src/providers/ldap/ldap_id_enum.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_id_enum.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_enum.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_enum.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_id_enum.c' object='src/providers/ldap/libsss_ldap_common_la-ldap_id_enum.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-ldap_id_enum.lo `test -f 'src/providers/ldap/ldap_id_enum.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_id_enum.c src/providers/ldap/libsss_ldap_common_la-sdap_async_enum.lo: src/providers/ldap/sdap_async_enum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_enum.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_enum.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_enum.lo `test -f 'src/providers/ldap/sdap_async_enum.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_enum.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_enum.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_enum.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_enum.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_enum.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_enum.lo `test -f 'src/providers/ldap/sdap_async_enum.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_enum.c src/providers/ldap/libsss_ldap_common_la-ldap_id_cleanup.lo: src/providers/ldap/ldap_id_cleanup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-ldap_id_cleanup.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_cleanup.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-ldap_id_cleanup.lo `test -f 'src/providers/ldap/ldap_id_cleanup.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_id_cleanup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_cleanup.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_cleanup.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_id_cleanup.c' object='src/providers/ldap/libsss_ldap_common_la-ldap_id_cleanup.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-ldap_id_cleanup.lo `test -f 'src/providers/ldap/ldap_id_cleanup.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_id_cleanup.c src/providers/ldap/libsss_ldap_common_la-ldap_id_netgroup.lo: src/providers/ldap/ldap_id_netgroup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-ldap_id_netgroup.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_netgroup.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-ldap_id_netgroup.lo `test -f 'src/providers/ldap/ldap_id_netgroup.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_id_netgroup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_netgroup.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_netgroup.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_id_netgroup.c' object='src/providers/ldap/libsss_ldap_common_la-ldap_id_netgroup.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-ldap_id_netgroup.lo `test -f 'src/providers/ldap/ldap_id_netgroup.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_id_netgroup.c src/providers/ldap/libsss_ldap_common_la-ldap_id_services.lo: src/providers/ldap/ldap_id_services.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-ldap_id_services.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_services.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-ldap_id_services.lo `test -f 'src/providers/ldap/ldap_id_services.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_id_services.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_services.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_id_services.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_id_services.c' object='src/providers/ldap/libsss_ldap_common_la-ldap_id_services.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-ldap_id_services.lo `test -f 'src/providers/ldap/ldap_id_services.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_id_services.c src/providers/ldap/libsss_ldap_common_la-ldap_auth.lo: src/providers/ldap/ldap_auth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-ldap_auth.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_auth.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-ldap_auth.lo `test -f 'src/providers/ldap/ldap_auth.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_auth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_auth.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_auth.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_auth.c' object='src/providers/ldap/libsss_ldap_common_la-ldap_auth.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-ldap_auth.lo `test -f 'src/providers/ldap/ldap_auth.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_auth.c src/providers/ldap/libsss_ldap_common_la-ldap_common.lo: src/providers/ldap/ldap_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-ldap_common.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_common.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-ldap_common.lo `test -f 'src/providers/ldap/ldap_common.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_common.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_common.c' object='src/providers/ldap/libsss_ldap_common_la-ldap_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-ldap_common.lo `test -f 'src/providers/ldap/ldap_common.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_common.c src/providers/ldap/libsss_ldap_common_la-ldap_options.lo: src/providers/ldap/ldap_options.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-ldap_options.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_options.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-ldap_options.lo `test -f 'src/providers/ldap/ldap_options.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_options.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_options.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_options.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_options.c' object='src/providers/ldap/libsss_ldap_common_la-ldap_options.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-ldap_options.lo `test -f 'src/providers/ldap/ldap_options.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_options.c src/providers/ldap/libsss_ldap_common_la-ldap_opts.lo: src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-ldap_opts.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_opts.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-ldap_opts.lo `test -f 'src/providers/ldap/ldap_opts.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_opts.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-ldap_opts.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_opts.c' object='src/providers/ldap/libsss_ldap_common_la-ldap_opts.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-ldap_opts.lo `test -f 'src/providers/ldap/ldap_opts.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_opts.c src/providers/ldap/libsss_ldap_common_la-sdap_access.lo: src/providers/ldap/sdap_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_access.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_access.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_access.lo `test -f 'src/providers/ldap/sdap_access.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_access.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_access.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_access.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_access.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_access.lo `test -f 'src/providers/ldap/sdap_access.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_access.c src/providers/ldap/libsss_ldap_common_la-sdap_async.lo: src/providers/ldap/sdap_async.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async.lo `test -f 'src/providers/ldap/sdap_async.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async.lo `test -f 'src/providers/ldap/sdap_async.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async.c src/providers/ldap/libsss_ldap_common_la-sdap_async_users.lo: src/providers/ldap/sdap_async_users.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_users.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_users.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_users.lo `test -f 'src/providers/ldap/sdap_async_users.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_users.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_users.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_users.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_users.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_users.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_users.lo `test -f 'src/providers/ldap/sdap_async_users.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_users.c src/providers/ldap/libsss_ldap_common_la-sdap_async_groups.lo: src/providers/ldap/sdap_async_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_groups.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_groups.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_groups.lo `test -f 'src/providers/ldap/sdap_async_groups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_groups.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_groups.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_groups.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_groups.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_groups.lo `test -f 'src/providers/ldap/sdap_async_groups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_groups.c src/providers/ldap/libsss_ldap_common_la-sdap_async_nested_groups.lo: src/providers/ldap/sdap_async_nested_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_nested_groups.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_nested_groups.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_nested_groups.lo `test -f 'src/providers/ldap/sdap_async_nested_groups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_nested_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_nested_groups.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_nested_groups.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_nested_groups.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_nested_groups.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_nested_groups.lo `test -f 'src/providers/ldap/sdap_async_nested_groups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_nested_groups.c src/providers/ldap/libsss_ldap_common_la-sdap_async_groups_ad.lo: src/providers/ldap/sdap_async_groups_ad.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_groups_ad.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_groups_ad.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_groups_ad.lo `test -f 'src/providers/ldap/sdap_async_groups_ad.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_groups_ad.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_groups_ad.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_groups_ad.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_groups_ad.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_groups_ad.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_groups_ad.lo `test -f 'src/providers/ldap/sdap_async_groups_ad.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_groups_ad.c src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups.lo: src/providers/ldap/sdap_async_initgroups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_initgroups.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups.lo `test -f 'src/providers/ldap/sdap_async_initgroups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_initgroups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_initgroups.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_initgroups.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_initgroups.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups.lo `test -f 'src/providers/ldap/sdap_async_initgroups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_initgroups.c src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups_ad.lo: src/providers/ldap/sdap_async_initgroups_ad.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups_ad.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_initgroups_ad.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups_ad.lo `test -f 'src/providers/ldap/sdap_async_initgroups_ad.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_initgroups_ad.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_initgroups_ad.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_initgroups_ad.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_initgroups_ad.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups_ad.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_initgroups_ad.lo `test -f 'src/providers/ldap/sdap_async_initgroups_ad.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_initgroups_ad.c src/providers/ldap/libsss_ldap_common_la-sdap_async_connection.lo: src/providers/ldap/sdap_async_connection.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_connection.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_connection.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_connection.lo `test -f 'src/providers/ldap/sdap_async_connection.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_connection.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_connection.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_connection.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_connection.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_connection.lo `test -f 'src/providers/ldap/sdap_async_connection.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_connection.c src/providers/ldap/libsss_ldap_common_la-sdap_async_netgroups.lo: src/providers/ldap/sdap_async_netgroups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_netgroups.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_netgroups.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_netgroups.lo `test -f 'src/providers/ldap/sdap_async_netgroups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_netgroups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_netgroups.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_netgroups.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_netgroups.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_netgroups.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_netgroups.lo `test -f 'src/providers/ldap/sdap_async_netgroups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_netgroups.c src/providers/ldap/libsss_ldap_common_la-sdap_async_services.lo: src/providers/ldap/sdap_async_services.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_services.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_services.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_services.lo `test -f 'src/providers/ldap/sdap_async_services.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_services.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_services.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_services.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_services.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_services.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_services.lo `test -f 'src/providers/ldap/sdap_async_services.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_services.c src/providers/ldap/libsss_ldap_common_la-sdap_ad_groups.lo: src/providers/ldap/sdap_ad_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_ad_groups.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_ad_groups.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_ad_groups.lo `test -f 'src/providers/ldap/sdap_ad_groups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_ad_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_ad_groups.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_ad_groups.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_ad_groups.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_ad_groups.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_ad_groups.lo `test -f 'src/providers/ldap/sdap_ad_groups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_ad_groups.c src/providers/ldap/libsss_ldap_common_la-sdap_child_helpers.lo: src/providers/ldap/sdap_child_helpers.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_child_helpers.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_child_helpers.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_child_helpers.lo `test -f 'src/providers/ldap/sdap_child_helpers.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_child_helpers.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_child_helpers.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_child_helpers.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_child_helpers.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_child_helpers.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_child_helpers.lo `test -f 'src/providers/ldap/sdap_child_helpers.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_child_helpers.c src/providers/ldap/libsss_ldap_common_la-sdap_fd_events.lo: src/providers/ldap/sdap_fd_events.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_fd_events.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_fd_events.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_fd_events.lo `test -f 'src/providers/ldap/sdap_fd_events.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_fd_events.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_fd_events.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_fd_events.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_fd_events.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_fd_events.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_fd_events.lo `test -f 'src/providers/ldap/sdap_fd_events.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_fd_events.c src/providers/ldap/libsss_ldap_common_la-sdap_id_op.lo: src/providers/ldap/sdap_id_op.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_id_op.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_id_op.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_id_op.lo `test -f 'src/providers/ldap/sdap_id_op.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_id_op.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_id_op.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_id_op.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_id_op.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_id_op.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_id_op.lo `test -f 'src/providers/ldap/sdap_id_op.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_id_op.c src/providers/ldap/libsss_ldap_common_la-sdap_idmap.lo: src/providers/ldap/sdap_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_idmap.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_idmap.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_idmap.lo `test -f 'src/providers/ldap/sdap_idmap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_idmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_idmap.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_idmap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_idmap.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_idmap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_idmap.lo `test -f 'src/providers/ldap/sdap_idmap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_idmap.c src/providers/ldap/libsss_ldap_common_la-sdap_range.lo: src/providers/ldap/sdap_range.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_range.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_range.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_range.lo `test -f 'src/providers/ldap/sdap_range.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_range.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_range.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_range.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_range.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_range.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_range.lo `test -f 'src/providers/ldap/sdap_range.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_range.c src/providers/ldap/libsss_ldap_common_la-sdap_reinit.lo: src/providers/ldap/sdap_reinit.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_reinit.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_reinit.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_reinit.lo `test -f 'src/providers/ldap/sdap_reinit.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_reinit.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_reinit.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_reinit.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_reinit.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_reinit.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_reinit.lo `test -f 'src/providers/ldap/sdap_reinit.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_reinit.c src/providers/ldap/libsss_ldap_common_la-sdap_dyndns.lo: src/providers/ldap/sdap_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_dyndns.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_dyndns.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_dyndns.lo `test -f 'src/providers/ldap/sdap_dyndns.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_dyndns.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_dyndns.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_dyndns.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_dyndns.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_dyndns.lo `test -f 'src/providers/ldap/sdap_dyndns.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_dyndns.c src/providers/ldap/libsss_ldap_common_la-sdap_refresh.lo: src/providers/ldap/sdap_refresh.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_refresh.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_refresh.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_refresh.lo `test -f 'src/providers/ldap/sdap_refresh.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_refresh.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_refresh.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_refresh.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_refresh.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_refresh.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_refresh.lo `test -f 'src/providers/ldap/sdap_refresh.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_refresh.c src/providers/ldap/libsss_ldap_common_la-sdap_utils.lo: src/providers/ldap/sdap_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_utils.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_utils.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_utils.lo `test -f 'src/providers/ldap/sdap_utils.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_utils.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_utils.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_utils.lo `test -f 'src/providers/ldap/sdap_utils.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_utils.c src/providers/ldap/libsss_ldap_common_la-sdap_domain.lo: src/providers/ldap/sdap_domain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_domain.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_domain.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_domain.lo `test -f 'src/providers/ldap/sdap_domain.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_domain.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_domain.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_domain.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_domain.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_domain.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_domain.lo `test -f 'src/providers/ldap/sdap_domain.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_domain.c src/providers/ldap/libsss_ldap_common_la-sdap_ops.lo: src/providers/ldap/sdap_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_ops.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_ops.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_ops.lo `test -f 'src/providers/ldap/sdap_ops.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_ops.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_ops.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_ops.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_ops.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_ops.lo `test -f 'src/providers/ldap/sdap_ops.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_ops.c src/providers/ldap/libsss_ldap_common_la-sdap.lo: src/providers/ldap/sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap.lo `test -f 'src/providers/ldap/sdap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap.c' object='src/providers/ldap/libsss_ldap_common_la-sdap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap.lo `test -f 'src/providers/ldap/sdap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap.c src/providers/ipa/libsss_ldap_common_la-ipa_dn.lo: src/providers/ipa/ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ipa/libsss_ldap_common_la-ipa_dn.lo -MD -MP -MF src/providers/ipa/$(DEPDIR)/libsss_ldap_common_la-ipa_dn.Tpo -c -o src/providers/ipa/libsss_ldap_common_la-ipa_dn.lo `test -f 'src/providers/ipa/ipa_dn.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/libsss_ldap_common_la-ipa_dn.Tpo src/providers/ipa/$(DEPDIR)/libsss_ldap_common_la-ipa_dn.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_dn.c' object='src/providers/ipa/libsss_ldap_common_la-ipa_dn.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/libsss_ldap_common_la-ipa_dn.lo `test -f 'src/providers/ipa/ipa_dn.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_dn.c src/util/libsss_ldap_common_la-user_info_msg.lo: src/util/user_info_msg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_ldap_common_la-user_info_msg.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_ldap_common_la-user_info_msg.Tpo -c -o src/util/libsss_ldap_common_la-user_info_msg.lo `test -f 'src/util/user_info_msg.c' || echo '$(srcdir)/'`src/util/user_info_msg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_ldap_common_la-user_info_msg.Tpo src/util/$(DEPDIR)/libsss_ldap_common_la-user_info_msg.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/user_info_msg.c' object='src/util/libsss_ldap_common_la-user_info_msg.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_ldap_common_la-user_info_msg.lo `test -f 'src/util/user_info_msg.c' || echo '$(srcdir)/'`src/util/user_info_msg.c src/util/libsss_ldap_common_la-sss_ldap.lo: src/util/sss_ldap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_ldap_common_la-sss_ldap.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_ldap_common_la-sss_ldap.Tpo -c -o src/util/libsss_ldap_common_la-sss_ldap.lo `test -f 'src/util/sss_ldap.c' || echo '$(srcdir)/'`src/util/sss_ldap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_ldap_common_la-sss_ldap.Tpo src/util/$(DEPDIR)/libsss_ldap_common_la-sss_ldap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_ldap.c' object='src/util/libsss_ldap_common_la-sss_ldap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_ldap_common_la-sss_ldap.lo `test -f 'src/util/sss_ldap.c' || echo '$(srcdir)/'`src/util/sss_ldap.c src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo.lo: src/providers/ldap/sdap_async_sudo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_sudo.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo.lo `test -f 'src/providers/ldap/sdap_async_sudo.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_sudo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_sudo.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_sudo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_sudo.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo.lo `test -f 'src/providers/ldap/sdap_async_sudo.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_sudo.c src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo_hostinfo.lo: src/providers/ldap/sdap_async_sudo_hostinfo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo_hostinfo.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_sudo_hostinfo.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo_hostinfo.lo `test -f 'src/providers/ldap/sdap_async_sudo_hostinfo.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_sudo_hostinfo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_sudo_hostinfo.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_sudo_hostinfo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_sudo_hostinfo.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo_hostinfo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_sudo_hostinfo.lo `test -f 'src/providers/ldap/sdap_async_sudo_hostinfo.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_sudo_hostinfo.c src/providers/ldap/libsss_ldap_common_la-sdap_sudo_refresh.lo: src/providers/ldap/sdap_sudo_refresh.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_sudo_refresh.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo_refresh.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_sudo_refresh.lo `test -f 'src/providers/ldap/sdap_sudo_refresh.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_sudo_refresh.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo_refresh.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo_refresh.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_sudo_refresh.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_sudo_refresh.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_sudo_refresh.lo `test -f 'src/providers/ldap/sdap_sudo_refresh.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_sudo_refresh.c src/providers/ldap/libsss_ldap_common_la-sdap_sudo_shared.lo: src/providers/ldap/sdap_sudo_shared.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_sudo_shared.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo_shared.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_sudo_shared.lo `test -f 'src/providers/ldap/sdap_sudo_shared.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_sudo_shared.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo_shared.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo_shared.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_sudo_shared.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_sudo_shared.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_sudo_shared.lo `test -f 'src/providers/ldap/sdap_sudo_shared.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_sudo_shared.c src/providers/ldap/libsss_ldap_common_la-sdap_sudo.lo: src/providers/ldap/sdap_sudo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_sudo.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_sudo.lo `test -f 'src/providers/ldap/sdap_sudo.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_sudo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_sudo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_sudo.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_sudo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_sudo.lo `test -f 'src/providers/ldap/sdap_sudo.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_sudo.c src/providers/ldap/libsss_ldap_common_la-sdap_autofs.lo: src/providers/ldap/sdap_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_autofs.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_autofs.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_autofs.lo `test -f 'src/providers/ldap/sdap_autofs.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_autofs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_autofs.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_autofs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_autofs.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_autofs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_autofs.lo `test -f 'src/providers/ldap/sdap_autofs.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_autofs.c src/providers/ldap/libsss_ldap_common_la-sdap_async_autofs.lo: src/providers/ldap/sdap_async_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -MT src/providers/ldap/libsss_ldap_common_la-sdap_async_autofs.lo -MD -MP -MF src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_autofs.Tpo -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_autofs.lo `test -f 'src/providers/ldap/sdap_async_autofs.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_autofs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_autofs.Tpo src/providers/ldap/$(DEPDIR)/libsss_ldap_common_la-sdap_async_autofs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_autofs.c' object='src/providers/ldap/libsss_ldap_common_la-sdap_async_autofs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_ldap_common_la_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/libsss_ldap_common_la-sdap_async_autofs.lo `test -f 'src/providers/ldap/sdap_async_autofs.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_autofs.c src/providers/proxy/libsss_proxy_la-proxy_init.lo: src/providers/proxy/proxy_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -MT src/providers/proxy/libsss_proxy_la-proxy_init.lo -MD -MP -MF src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_init.Tpo -c -o src/providers/proxy/libsss_proxy_la-proxy_init.lo `test -f 'src/providers/proxy/proxy_init.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_init.Tpo src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/proxy/proxy_init.c' object='src/providers/proxy/libsss_proxy_la-proxy_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -c -o src/providers/proxy/libsss_proxy_la-proxy_init.lo `test -f 'src/providers/proxy/proxy_init.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_init.c src/providers/proxy/libsss_proxy_la-proxy_id.lo: src/providers/proxy/proxy_id.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -MT src/providers/proxy/libsss_proxy_la-proxy_id.lo -MD -MP -MF src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_id.Tpo -c -o src/providers/proxy/libsss_proxy_la-proxy_id.lo `test -f 'src/providers/proxy/proxy_id.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_id.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_id.Tpo src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_id.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/proxy/proxy_id.c' object='src/providers/proxy/libsss_proxy_la-proxy_id.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -c -o src/providers/proxy/libsss_proxy_la-proxy_id.lo `test -f 'src/providers/proxy/proxy_id.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_id.c src/providers/proxy/libsss_proxy_la-proxy_netgroup.lo: src/providers/proxy/proxy_netgroup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -MT src/providers/proxy/libsss_proxy_la-proxy_netgroup.lo -MD -MP -MF src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_netgroup.Tpo -c -o src/providers/proxy/libsss_proxy_la-proxy_netgroup.lo `test -f 'src/providers/proxy/proxy_netgroup.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_netgroup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_netgroup.Tpo src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_netgroup.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/proxy/proxy_netgroup.c' object='src/providers/proxy/libsss_proxy_la-proxy_netgroup.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -c -o src/providers/proxy/libsss_proxy_la-proxy_netgroup.lo `test -f 'src/providers/proxy/proxy_netgroup.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_netgroup.c src/providers/proxy/libsss_proxy_la-proxy_services.lo: src/providers/proxy/proxy_services.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -MT src/providers/proxy/libsss_proxy_la-proxy_services.lo -MD -MP -MF src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_services.Tpo -c -o src/providers/proxy/libsss_proxy_la-proxy_services.lo `test -f 'src/providers/proxy/proxy_services.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_services.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_services.Tpo src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_services.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/proxy/proxy_services.c' object='src/providers/proxy/libsss_proxy_la-proxy_services.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -c -o src/providers/proxy/libsss_proxy_la-proxy_services.lo `test -f 'src/providers/proxy/proxy_services.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_services.c src/providers/proxy/libsss_proxy_la-proxy_auth.lo: src/providers/proxy/proxy_auth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -MT src/providers/proxy/libsss_proxy_la-proxy_auth.lo -MD -MP -MF src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_auth.Tpo -c -o src/providers/proxy/libsss_proxy_la-proxy_auth.lo `test -f 'src/providers/proxy/proxy_auth.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_auth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_auth.Tpo src/providers/proxy/$(DEPDIR)/libsss_proxy_la-proxy_auth.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/proxy/proxy_auth.c' object='src/providers/proxy/libsss_proxy_la-proxy_auth.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -c -o src/providers/proxy/libsss_proxy_la-proxy_auth.lo `test -f 'src/providers/proxy/proxy_auth.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_auth.c src/providers/libsss_proxy_la-data_provider_iface_generated.lo: src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -MT src/providers/libsss_proxy_la-data_provider_iface_generated.lo -MD -MP -MF src/providers/$(DEPDIR)/libsss_proxy_la-data_provider_iface_generated.Tpo -c -o src/providers/libsss_proxy_la-data_provider_iface_generated.lo `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libsss_proxy_la-data_provider_iface_generated.Tpo src/providers/$(DEPDIR)/libsss_proxy_la-data_provider_iface_generated.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_iface_generated.c' object='src/providers/libsss_proxy_la-data_provider_iface_generated.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_proxy_la_CFLAGS) $(CFLAGS) -c -o src/providers/libsss_proxy_la-data_provider_iface_generated.lo `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c src/util/libsss_semanage_la-sss_semanage.lo: src/util/sss_semanage.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_semanage_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_semanage_la-sss_semanage.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_semanage_la-sss_semanage.Tpo -c -o src/util/libsss_semanage_la-sss_semanage.lo `test -f 'src/util/sss_semanage.c' || echo '$(srcdir)/'`src/util/sss_semanage.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_semanage_la-sss_semanage.Tpo src/util/$(DEPDIR)/libsss_semanage_la-sss_semanage.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_semanage.c' object='src/util/libsss_semanage_la-sss_semanage.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_semanage_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_semanage_la-sss_semanage.lo `test -f 'src/util/sss_semanage.c' || echo '$(srcdir)/'`src/util/sss_semanage.c src/providers/simple/libsss_simple_la-simple_access_check.lo: src/providers/simple/simple_access_check.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simple_la_CFLAGS) $(CFLAGS) -MT src/providers/simple/libsss_simple_la-simple_access_check.lo -MD -MP -MF src/providers/simple/$(DEPDIR)/libsss_simple_la-simple_access_check.Tpo -c -o src/providers/simple/libsss_simple_la-simple_access_check.lo `test -f 'src/providers/simple/simple_access_check.c' || echo '$(srcdir)/'`src/providers/simple/simple_access_check.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/simple/$(DEPDIR)/libsss_simple_la-simple_access_check.Tpo src/providers/simple/$(DEPDIR)/libsss_simple_la-simple_access_check.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/simple/simple_access_check.c' object='src/providers/simple/libsss_simple_la-simple_access_check.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simple_la_CFLAGS) $(CFLAGS) -c -o src/providers/simple/libsss_simple_la-simple_access_check.lo `test -f 'src/providers/simple/simple_access_check.c' || echo '$(srcdir)/'`src/providers/simple/simple_access_check.c src/providers/simple/libsss_simple_la-simple_access.lo: src/providers/simple/simple_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simple_la_CFLAGS) $(CFLAGS) -MT src/providers/simple/libsss_simple_la-simple_access.lo -MD -MP -MF src/providers/simple/$(DEPDIR)/libsss_simple_la-simple_access.Tpo -c -o src/providers/simple/libsss_simple_la-simple_access.lo `test -f 'src/providers/simple/simple_access.c' || echo '$(srcdir)/'`src/providers/simple/simple_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/simple/$(DEPDIR)/libsss_simple_la-simple_access.Tpo src/providers/simple/$(DEPDIR)/libsss_simple_la-simple_access.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/simple/simple_access.c' object='src/providers/simple/libsss_simple_la-simple_access.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simple_la_CFLAGS) $(CFLAGS) -c -o src/providers/simple/libsss_simple_la-simple_access.lo `test -f 'src/providers/simple/simple_access.c' || echo '$(srcdir)/'`src/providers/simple/simple_access.c src/lib/sifp/libsss_simpleifp_la-sss_sifp.lo: src/lib/sifp/sss_sifp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -MT src/lib/sifp/libsss_simpleifp_la-sss_sifp.lo -MD -MP -MF src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp.Tpo -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp.lo `test -f 'src/lib/sifp/sss_sifp.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp.Tpo src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp.c' object='src/lib/sifp/libsss_simpleifp_la-sss_sifp.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp.lo `test -f 'src/lib/sifp/sss_sifp.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp.c src/lib/sifp/libsss_simpleifp_la-sss_sifp_dbus.lo: src/lib/sifp/sss_sifp_dbus.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -MT src/lib/sifp/libsss_simpleifp_la-sss_sifp_dbus.lo -MD -MP -MF src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_dbus.Tpo -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp_dbus.lo `test -f 'src/lib/sifp/sss_sifp_dbus.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_dbus.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_dbus.Tpo src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_dbus.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_dbus.c' object='src/lib/sifp/libsss_simpleifp_la-sss_sifp_dbus.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp_dbus.lo `test -f 'src/lib/sifp/sss_sifp_dbus.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_dbus.c src/lib/sifp/libsss_simpleifp_la-sss_sifp_attrs.lo: src/lib/sifp/sss_sifp_attrs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -MT src/lib/sifp/libsss_simpleifp_la-sss_sifp_attrs.lo -MD -MP -MF src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_attrs.Tpo -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp_attrs.lo `test -f 'src/lib/sifp/sss_sifp_attrs.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_attrs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_attrs.Tpo src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_attrs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_attrs.c' object='src/lib/sifp/libsss_simpleifp_la-sss_sifp_attrs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp_attrs.lo `test -f 'src/lib/sifp/sss_sifp_attrs.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_attrs.c src/lib/sifp/libsss_simpleifp_la-sss_sifp_common.lo: src/lib/sifp/sss_sifp_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -MT src/lib/sifp/libsss_simpleifp_la-sss_sifp_common.lo -MD -MP -MF src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_common.Tpo -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp_common.lo `test -f 'src/lib/sifp/sss_sifp_common.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_common.Tpo src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_common.c' object='src/lib/sifp/libsss_simpleifp_la-sss_sifp_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp_common.lo `test -f 'src/lib/sifp/sss_sifp_common.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_common.c src/lib/sifp/libsss_simpleifp_la-sss_sifp_parser.lo: src/lib/sifp/sss_sifp_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -MT src/lib/sifp/libsss_simpleifp_la-sss_sifp_parser.lo -MD -MP -MF src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_parser.Tpo -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp_parser.lo `test -f 'src/lib/sifp/sss_sifp_parser.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_parser.Tpo src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_parser.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_parser.c' object='src/lib/sifp/libsss_simpleifp_la-sss_sifp_parser.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp_parser.lo `test -f 'src/lib/sifp/sss_sifp_parser.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_parser.c src/lib/sifp/libsss_simpleifp_la-sss_sifp_utils.lo: src/lib/sifp/sss_sifp_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -MT src/lib/sifp/libsss_simpleifp_la-sss_sifp_utils.lo -MD -MP -MF src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_utils.Tpo -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp_utils.lo `test -f 'src/lib/sifp/sss_sifp_utils.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_utils.Tpo src/lib/sifp/$(DEPDIR)/libsss_simpleifp_la-sss_sifp_utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_utils.c' object='src/lib/sifp/libsss_simpleifp_la-sss_sifp_utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_simpleifp_la_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/libsss_simpleifp_la-sss_sifp_utils.lo `test -f 'src/lib/sifp/sss_sifp_utils.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_utils.c src/confdb/libsss_util_la-confdb.lo: src/confdb/confdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/confdb/libsss_util_la-confdb.lo -MD -MP -MF src/confdb/$(DEPDIR)/libsss_util_la-confdb.Tpo -c -o src/confdb/libsss_util_la-confdb.lo `test -f 'src/confdb/confdb.c' || echo '$(srcdir)/'`src/confdb/confdb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/confdb/$(DEPDIR)/libsss_util_la-confdb.Tpo src/confdb/$(DEPDIR)/libsss_util_la-confdb.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/confdb/confdb.c' object='src/confdb/libsss_util_la-confdb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/confdb/libsss_util_la-confdb.lo `test -f 'src/confdb/confdb.c' || echo '$(srcdir)/'`src/confdb/confdb.c src/db/libsss_util_la-sysdb.lo: src/db/sysdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb.Tpo -c -o src/db/libsss_util_la-sysdb.lo `test -f 'src/db/sysdb.c' || echo '$(srcdir)/'`src/db/sysdb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb.c' object='src/db/libsss_util_la-sysdb.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb.lo `test -f 'src/db/sysdb.c' || echo '$(srcdir)/'`src/db/sysdb.c src/db/libsss_util_la-sysdb_ops.lo: src/db/sysdb_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_ops.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_ops.Tpo -c -o src/db/libsss_util_la-sysdb_ops.lo `test -f 'src/db/sysdb_ops.c' || echo '$(srcdir)/'`src/db/sysdb_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_ops.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_ops.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_ops.c' object='src/db/libsss_util_la-sysdb_ops.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_ops.lo `test -f 'src/db/sysdb_ops.c' || echo '$(srcdir)/'`src/db/sysdb_ops.c src/db/libsss_util_la-sysdb_search.lo: src/db/sysdb_search.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_search.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_search.Tpo -c -o src/db/libsss_util_la-sysdb_search.lo `test -f 'src/db/sysdb_search.c' || echo '$(srcdir)/'`src/db/sysdb_search.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_search.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_search.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_search.c' object='src/db/libsss_util_la-sysdb_search.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_search.lo `test -f 'src/db/sysdb_search.c' || echo '$(srcdir)/'`src/db/sysdb_search.c src/db/libsss_util_la-sysdb_selinux.lo: src/db/sysdb_selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_selinux.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_selinux.Tpo -c -o src/db/libsss_util_la-sysdb_selinux.lo `test -f 'src/db/sysdb_selinux.c' || echo '$(srcdir)/'`src/db/sysdb_selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_selinux.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_selinux.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_selinux.c' object='src/db/libsss_util_la-sysdb_selinux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_selinux.lo `test -f 'src/db/sysdb_selinux.c' || echo '$(srcdir)/'`src/db/sysdb_selinux.c src/db/libsss_util_la-sysdb_upgrade.lo: src/db/sysdb_upgrade.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_upgrade.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_upgrade.Tpo -c -o src/db/libsss_util_la-sysdb_upgrade.lo `test -f 'src/db/sysdb_upgrade.c' || echo '$(srcdir)/'`src/db/sysdb_upgrade.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_upgrade.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_upgrade.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_upgrade.c' object='src/db/libsss_util_la-sysdb_upgrade.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_upgrade.lo `test -f 'src/db/sysdb_upgrade.c' || echo '$(srcdir)/'`src/db/sysdb_upgrade.c src/db/libsss_util_la-sysdb_services.lo: src/db/sysdb_services.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_services.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_services.Tpo -c -o src/db/libsss_util_la-sysdb_services.lo `test -f 'src/db/sysdb_services.c' || echo '$(srcdir)/'`src/db/sysdb_services.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_services.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_services.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_services.c' object='src/db/libsss_util_la-sysdb_services.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_services.lo `test -f 'src/db/sysdb_services.c' || echo '$(srcdir)/'`src/db/sysdb_services.c src/db/libsss_util_la-sysdb_autofs.lo: src/db/sysdb_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_autofs.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_autofs.Tpo -c -o src/db/libsss_util_la-sysdb_autofs.lo `test -f 'src/db/sysdb_autofs.c' || echo '$(srcdir)/'`src/db/sysdb_autofs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_autofs.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_autofs.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_autofs.c' object='src/db/libsss_util_la-sysdb_autofs.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_autofs.lo `test -f 'src/db/sysdb_autofs.c' || echo '$(srcdir)/'`src/db/sysdb_autofs.c src/db/libsss_util_la-sysdb_subdomains.lo: src/db/sysdb_subdomains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_subdomains.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_subdomains.Tpo -c -o src/db/libsss_util_la-sysdb_subdomains.lo `test -f 'src/db/sysdb_subdomains.c' || echo '$(srcdir)/'`src/db/sysdb_subdomains.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_subdomains.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_subdomains.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_subdomains.c' object='src/db/libsss_util_la-sysdb_subdomains.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_subdomains.lo `test -f 'src/db/sysdb_subdomains.c' || echo '$(srcdir)/'`src/db/sysdb_subdomains.c src/db/libsss_util_la-sysdb_views.lo: src/db/sysdb_views.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_views.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_views.Tpo -c -o src/db/libsss_util_la-sysdb_views.lo `test -f 'src/db/sysdb_views.c' || echo '$(srcdir)/'`src/db/sysdb_views.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_views.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_views.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_views.c' object='src/db/libsss_util_la-sysdb_views.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_views.lo `test -f 'src/db/sysdb_views.c' || echo '$(srcdir)/'`src/db/sysdb_views.c src/db/libsss_util_la-sysdb_ranges.lo: src/db/sysdb_ranges.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_ranges.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_ranges.Tpo -c -o src/db/libsss_util_la-sysdb_ranges.lo `test -f 'src/db/sysdb_ranges.c' || echo '$(srcdir)/'`src/db/sysdb_ranges.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_ranges.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_ranges.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_ranges.c' object='src/db/libsss_util_la-sysdb_ranges.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_ranges.lo `test -f 'src/db/sysdb_ranges.c' || echo '$(srcdir)/'`src/db/sysdb_ranges.c src/db/libsss_util_la-sysdb_idmap.lo: src/db/sysdb_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_idmap.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_idmap.Tpo -c -o src/db/libsss_util_la-sysdb_idmap.lo `test -f 'src/db/sysdb_idmap.c' || echo '$(srcdir)/'`src/db/sysdb_idmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_idmap.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_idmap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_idmap.c' object='src/db/libsss_util_la-sysdb_idmap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_idmap.lo `test -f 'src/db/sysdb_idmap.c' || echo '$(srcdir)/'`src/db/sysdb_idmap.c src/db/libsss_util_la-sysdb_gpo.lo: src/db/sysdb_gpo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_gpo.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_gpo.Tpo -c -o src/db/libsss_util_la-sysdb_gpo.lo `test -f 'src/db/sysdb_gpo.c' || echo '$(srcdir)/'`src/db/sysdb_gpo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_gpo.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_gpo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_gpo.c' object='src/db/libsss_util_la-sysdb_gpo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_gpo.lo `test -f 'src/db/sysdb_gpo.c' || echo '$(srcdir)/'`src/db/sysdb_gpo.c src/monitor/libsss_util_la-monitor_sbus.lo: src/monitor/monitor_sbus.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/monitor/libsss_util_la-monitor_sbus.lo -MD -MP -MF src/monitor/$(DEPDIR)/libsss_util_la-monitor_sbus.Tpo -c -o src/monitor/libsss_util_la-monitor_sbus.lo `test -f 'src/monitor/monitor_sbus.c' || echo '$(srcdir)/'`src/monitor/monitor_sbus.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/monitor/$(DEPDIR)/libsss_util_la-monitor_sbus.Tpo src/monitor/$(DEPDIR)/libsss_util_la-monitor_sbus.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/monitor/monitor_sbus.c' object='src/monitor/libsss_util_la-monitor_sbus.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/monitor/libsss_util_la-monitor_sbus.lo `test -f 'src/monitor/monitor_sbus.c' || echo '$(srcdir)/'`src/monitor/monitor_sbus.c src/providers/libsss_util_la-dp_auth_util.lo: src/providers/dp_auth_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/providers/libsss_util_la-dp_auth_util.lo -MD -MP -MF src/providers/$(DEPDIR)/libsss_util_la-dp_auth_util.Tpo -c -o src/providers/libsss_util_la-dp_auth_util.lo `test -f 'src/providers/dp_auth_util.c' || echo '$(srcdir)/'`src/providers/dp_auth_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libsss_util_la-dp_auth_util.Tpo src/providers/$(DEPDIR)/libsss_util_la-dp_auth_util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/dp_auth_util.c' object='src/providers/libsss_util_la-dp_auth_util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/providers/libsss_util_la-dp_auth_util.lo `test -f 'src/providers/dp_auth_util.c' || echo '$(srcdir)/'`src/providers/dp_auth_util.c src/providers/libsss_util_la-dp_pam_data_util.lo: src/providers/dp_pam_data_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/providers/libsss_util_la-dp_pam_data_util.lo -MD -MP -MF src/providers/$(DEPDIR)/libsss_util_la-dp_pam_data_util.Tpo -c -o src/providers/libsss_util_la-dp_pam_data_util.lo `test -f 'src/providers/dp_pam_data_util.c' || echo '$(srcdir)/'`src/providers/dp_pam_data_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libsss_util_la-dp_pam_data_util.Tpo src/providers/$(DEPDIR)/libsss_util_la-dp_pam_data_util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/dp_pam_data_util.c' object='src/providers/libsss_util_la-dp_pam_data_util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/providers/libsss_util_la-dp_pam_data_util.lo `test -f 'src/providers/dp_pam_data_util.c' || echo '$(srcdir)/'`src/providers/dp_pam_data_util.c src/providers/libsss_util_la-dp_sbus.lo: src/providers/dp_sbus.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/providers/libsss_util_la-dp_sbus.lo -MD -MP -MF src/providers/$(DEPDIR)/libsss_util_la-dp_sbus.Tpo -c -o src/providers/libsss_util_la-dp_sbus.lo `test -f 'src/providers/dp_sbus.c' || echo '$(srcdir)/'`src/providers/dp_sbus.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/libsss_util_la-dp_sbus.Tpo src/providers/$(DEPDIR)/libsss_util_la-dp_sbus.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/dp_sbus.c' object='src/providers/libsss_util_la-dp_sbus.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/providers/libsss_util_la-dp_sbus.lo `test -f 'src/providers/dp_sbus.c' || echo '$(srcdir)/'`src/providers/dp_sbus.c src/sbus/libsss_util_la-sbus_client.lo: src/sbus/sbus_client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sbus_client.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sbus_client.Tpo -c -o src/sbus/libsss_util_la-sbus_client.lo `test -f 'src/sbus/sbus_client.c' || echo '$(srcdir)/'`src/sbus/sbus_client.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sbus_client.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sbus_client.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sbus_client.c' object='src/sbus/libsss_util_la-sbus_client.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sbus_client.lo `test -f 'src/sbus/sbus_client.c' || echo '$(srcdir)/'`src/sbus/sbus_client.c src/sbus/libsss_util_la-sssd_dbus_common.lo: src/sbus/sssd_dbus_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sssd_dbus_common.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_common.Tpo -c -o src/sbus/libsss_util_la-sssd_dbus_common.lo `test -f 'src/sbus/sssd_dbus_common.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_common.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_common.c' object='src/sbus/libsss_util_la-sssd_dbus_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sssd_dbus_common.lo `test -f 'src/sbus/sssd_dbus_common.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_common.c src/sbus/libsss_util_la-sssd_dbus_connection.lo: src/sbus/sssd_dbus_connection.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sssd_dbus_connection.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_connection.Tpo -c -o src/sbus/libsss_util_la-sssd_dbus_connection.lo `test -f 'src/sbus/sssd_dbus_connection.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_connection.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_connection.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_connection.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_connection.c' object='src/sbus/libsss_util_la-sssd_dbus_connection.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sssd_dbus_connection.lo `test -f 'src/sbus/sssd_dbus_connection.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_connection.c src/sbus/libsss_util_la-sssd_dbus_meta.lo: src/sbus/sssd_dbus_meta.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sssd_dbus_meta.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_meta.Tpo -c -o src/sbus/libsss_util_la-sssd_dbus_meta.lo `test -f 'src/sbus/sssd_dbus_meta.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_meta.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_meta.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_meta.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_meta.c' object='src/sbus/libsss_util_la-sssd_dbus_meta.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sssd_dbus_meta.lo `test -f 'src/sbus/sssd_dbus_meta.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_meta.c src/sbus/libsss_util_la-sssd_dbus_interface.lo: src/sbus/sssd_dbus_interface.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sssd_dbus_interface.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_interface.Tpo -c -o src/sbus/libsss_util_la-sssd_dbus_interface.lo `test -f 'src/sbus/sssd_dbus_interface.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_interface.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_interface.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_interface.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_interface.c' object='src/sbus/libsss_util_la-sssd_dbus_interface.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sssd_dbus_interface.lo `test -f 'src/sbus/sssd_dbus_interface.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_interface.c src/sbus/libsss_util_la-sssd_dbus_introspect.lo: src/sbus/sssd_dbus_introspect.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sssd_dbus_introspect.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_introspect.Tpo -c -o src/sbus/libsss_util_la-sssd_dbus_introspect.lo `test -f 'src/sbus/sssd_dbus_introspect.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_introspect.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_introspect.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_introspect.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_introspect.c' object='src/sbus/libsss_util_la-sssd_dbus_introspect.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sssd_dbus_introspect.lo `test -f 'src/sbus/sssd_dbus_introspect.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_introspect.c src/sbus/libsss_util_la-sssd_dbus_invokers.lo: src/sbus/sssd_dbus_invokers.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sssd_dbus_invokers.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_invokers.Tpo -c -o src/sbus/libsss_util_la-sssd_dbus_invokers.lo `test -f 'src/sbus/sssd_dbus_invokers.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_invokers.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_invokers.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_invokers.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_invokers.c' object='src/sbus/libsss_util_la-sssd_dbus_invokers.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sssd_dbus_invokers.lo `test -f 'src/sbus/sssd_dbus_invokers.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_invokers.c src/sbus/libsss_util_la-sssd_dbus_properties.lo: src/sbus/sssd_dbus_properties.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sssd_dbus_properties.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_properties.Tpo -c -o src/sbus/libsss_util_la-sssd_dbus_properties.lo `test -f 'src/sbus/sssd_dbus_properties.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_properties.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_properties.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_properties.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_properties.c' object='src/sbus/libsss_util_la-sssd_dbus_properties.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sssd_dbus_properties.lo `test -f 'src/sbus/sssd_dbus_properties.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_properties.c src/sbus/libsss_util_la-sssd_dbus_request.lo: src/sbus/sssd_dbus_request.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sssd_dbus_request.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_request.Tpo -c -o src/sbus/libsss_util_la-sssd_dbus_request.lo `test -f 'src/sbus/sssd_dbus_request.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_request.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_request.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_request.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_request.c' object='src/sbus/libsss_util_la-sssd_dbus_request.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sssd_dbus_request.lo `test -f 'src/sbus/sssd_dbus_request.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_request.c src/sbus/libsss_util_la-sssd_dbus_server.lo: src/sbus/sssd_dbus_server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sssd_dbus_server.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_server.Tpo -c -o src/sbus/libsss_util_la-sssd_dbus_server.lo `test -f 'src/sbus/sssd_dbus_server.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_server.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_server.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_server.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_server.c' object='src/sbus/libsss_util_la-sssd_dbus_server.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sssd_dbus_server.lo `test -f 'src/sbus/sssd_dbus_server.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_server.c src/sbus/libsss_util_la-sssd_dbus_signals.lo: src/sbus/sssd_dbus_signals.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sssd_dbus_signals.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_signals.Tpo -c -o src/sbus/libsss_util_la-sssd_dbus_signals.lo `test -f 'src/sbus/sssd_dbus_signals.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_signals.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_signals.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_signals.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_signals.c' object='src/sbus/libsss_util_la-sssd_dbus_signals.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sssd_dbus_signals.lo `test -f 'src/sbus/sssd_dbus_signals.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_signals.c src/sbus/libsss_util_la-sssd_dbus_common_signals.lo: src/sbus/sssd_dbus_common_signals.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/sbus/libsss_util_la-sssd_dbus_common_signals.lo -MD -MP -MF src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_common_signals.Tpo -c -o src/sbus/libsss_util_la-sssd_dbus_common_signals.lo `test -f 'src/sbus/sssd_dbus_common_signals.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_common_signals.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_common_signals.Tpo src/sbus/$(DEPDIR)/libsss_util_la-sssd_dbus_common_signals.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_common_signals.c' object='src/sbus/libsss_util_la-sssd_dbus_common_signals.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/sbus/libsss_util_la-sssd_dbus_common_signals.lo `test -f 'src/sbus/sssd_dbus_common_signals.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_common_signals.c src/util/libsss_util_la-util.lo: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-util.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-util.Tpo -c -o src/util/libsss_util_la-util.lo `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-util.Tpo src/util/$(DEPDIR)/libsss_util_la-util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/libsss_util_la-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-util.lo `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c src/util/libsss_util_la-memory.lo: src/util/memory.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-memory.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-memory.Tpo -c -o src/util/libsss_util_la-memory.lo `test -f 'src/util/memory.c' || echo '$(srcdir)/'`src/util/memory.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-memory.Tpo src/util/$(DEPDIR)/libsss_util_la-memory.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/memory.c' object='src/util/libsss_util_la-memory.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-memory.lo `test -f 'src/util/memory.c' || echo '$(srcdir)/'`src/util/memory.c src/util/libsss_util_la-safe-format-string.lo: src/util/safe-format-string.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-safe-format-string.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-safe-format-string.Tpo -c -o src/util/libsss_util_la-safe-format-string.lo `test -f 'src/util/safe-format-string.c' || echo '$(srcdir)/'`src/util/safe-format-string.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-safe-format-string.Tpo src/util/$(DEPDIR)/libsss_util_la-safe-format-string.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/safe-format-string.c' object='src/util/libsss_util_la-safe-format-string.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-safe-format-string.lo `test -f 'src/util/safe-format-string.c' || echo '$(srcdir)/'`src/util/safe-format-string.c src/util/libsss_util_la-server.lo: src/util/server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-server.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-server.Tpo -c -o src/util/libsss_util_la-server.lo `test -f 'src/util/server.c' || echo '$(srcdir)/'`src/util/server.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-server.Tpo src/util/$(DEPDIR)/libsss_util_la-server.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/server.c' object='src/util/libsss_util_la-server.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-server.lo `test -f 'src/util/server.c' || echo '$(srcdir)/'`src/util/server.c src/util/libsss_util_la-signal.lo: src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-signal.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-signal.Tpo -c -o src/util/libsss_util_la-signal.lo `test -f 'src/util/signal.c' || echo '$(srcdir)/'`src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-signal.Tpo src/util/$(DEPDIR)/libsss_util_la-signal.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/signal.c' object='src/util/libsss_util_la-signal.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-signal.lo `test -f 'src/util/signal.c' || echo '$(srcdir)/'`src/util/signal.c src/util/libsss_util_la-usertools.lo: src/util/usertools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-usertools.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-usertools.Tpo -c -o src/util/libsss_util_la-usertools.lo `test -f 'src/util/usertools.c' || echo '$(srcdir)/'`src/util/usertools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-usertools.Tpo src/util/$(DEPDIR)/libsss_util_la-usertools.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/usertools.c' object='src/util/libsss_util_la-usertools.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-usertools.lo `test -f 'src/util/usertools.c' || echo '$(srcdir)/'`src/util/usertools.c src/util/libsss_util_la-backup_file.lo: src/util/backup_file.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-backup_file.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-backup_file.Tpo -c -o src/util/libsss_util_la-backup_file.lo `test -f 'src/util/backup_file.c' || echo '$(srcdir)/'`src/util/backup_file.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-backup_file.Tpo src/util/$(DEPDIR)/libsss_util_la-backup_file.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/backup_file.c' object='src/util/libsss_util_la-backup_file.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-backup_file.lo `test -f 'src/util/backup_file.c' || echo '$(srcdir)/'`src/util/backup_file.c src/util/libsss_util_la-strtonum.lo: src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-strtonum.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-strtonum.Tpo -c -o src/util/libsss_util_la-strtonum.lo `test -f 'src/util/strtonum.c' || echo '$(srcdir)/'`src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-strtonum.Tpo src/util/$(DEPDIR)/libsss_util_la-strtonum.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/strtonum.c' object='src/util/libsss_util_la-strtonum.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-strtonum.lo `test -f 'src/util/strtonum.c' || echo '$(srcdir)/'`src/util/strtonum.c src/util/libsss_util_la-check_and_open.lo: src/util/check_and_open.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-check_and_open.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-check_and_open.Tpo -c -o src/util/libsss_util_la-check_and_open.lo `test -f 'src/util/check_and_open.c' || echo '$(srcdir)/'`src/util/check_and_open.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-check_and_open.Tpo src/util/$(DEPDIR)/libsss_util_la-check_and_open.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/check_and_open.c' object='src/util/libsss_util_la-check_and_open.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-check_and_open.lo `test -f 'src/util/check_and_open.c' || echo '$(srcdir)/'`src/util/check_and_open.c src/util/libsss_util_la-refcount.lo: src/util/refcount.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-refcount.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-refcount.Tpo -c -o src/util/libsss_util_la-refcount.lo `test -f 'src/util/refcount.c' || echo '$(srcdir)/'`src/util/refcount.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-refcount.Tpo src/util/$(DEPDIR)/libsss_util_la-refcount.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/refcount.c' object='src/util/libsss_util_la-refcount.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-refcount.lo `test -f 'src/util/refcount.c' || echo '$(srcdir)/'`src/util/refcount.c src/util/libsss_util_la-sss_nss.lo: src/util/sss_nss.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-sss_nss.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-sss_nss.Tpo -c -o src/util/libsss_util_la-sss_nss.lo `test -f 'src/util/sss_nss.c' || echo '$(srcdir)/'`src/util/sss_nss.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-sss_nss.Tpo src/util/$(DEPDIR)/libsss_util_la-sss_nss.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_nss.c' object='src/util/libsss_util_la-sss_nss.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-sss_nss.lo `test -f 'src/util/sss_nss.c' || echo '$(srcdir)/'`src/util/sss_nss.c src/util/libsss_util_la-sss_utf8.lo: src/util/sss_utf8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-sss_utf8.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-sss_utf8.Tpo -c -o src/util/libsss_util_la-sss_utf8.lo `test -f 'src/util/sss_utf8.c' || echo '$(srcdir)/'`src/util/sss_utf8.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-sss_utf8.Tpo src/util/$(DEPDIR)/libsss_util_la-sss_utf8.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_utf8.c' object='src/util/libsss_util_la-sss_utf8.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-sss_utf8.lo `test -f 'src/util/sss_utf8.c' || echo '$(srcdir)/'`src/util/sss_utf8.c src/util/libsss_util_la-sss_tc_utf8.lo: src/util/sss_tc_utf8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-sss_tc_utf8.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-sss_tc_utf8.Tpo -c -o src/util/libsss_util_la-sss_tc_utf8.lo `test -f 'src/util/sss_tc_utf8.c' || echo '$(srcdir)/'`src/util/sss_tc_utf8.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-sss_tc_utf8.Tpo src/util/$(DEPDIR)/libsss_util_la-sss_tc_utf8.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_tc_utf8.c' object='src/util/libsss_util_la-sss_tc_utf8.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-sss_tc_utf8.lo `test -f 'src/util/sss_tc_utf8.c' || echo '$(srcdir)/'`src/util/sss_tc_utf8.c src/util/libsss_util_la-murmurhash3.lo: src/util/murmurhash3.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-murmurhash3.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-murmurhash3.Tpo -c -o src/util/libsss_util_la-murmurhash3.lo `test -f 'src/util/murmurhash3.c' || echo '$(srcdir)/'`src/util/murmurhash3.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-murmurhash3.Tpo src/util/$(DEPDIR)/libsss_util_la-murmurhash3.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/murmurhash3.c' object='src/util/libsss_util_la-murmurhash3.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-murmurhash3.lo `test -f 'src/util/murmurhash3.c' || echo '$(srcdir)/'`src/util/murmurhash3.c src/util/libsss_util_la-atomic_io.lo: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-atomic_io.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-atomic_io.Tpo -c -o src/util/libsss_util_la-atomic_io.lo `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-atomic_io.Tpo src/util/$(DEPDIR)/libsss_util_la-atomic_io.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/libsss_util_la-atomic_io.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-atomic_io.lo `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c src/util/libsss_util_la-authtok.lo: src/util/authtok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-authtok.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-authtok.Tpo -c -o src/util/libsss_util_la-authtok.lo `test -f 'src/util/authtok.c' || echo '$(srcdir)/'`src/util/authtok.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-authtok.Tpo src/util/$(DEPDIR)/libsss_util_la-authtok.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok.c' object='src/util/libsss_util_la-authtok.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-authtok.lo `test -f 'src/util/authtok.c' || echo '$(srcdir)/'`src/util/authtok.c src/util/libsss_util_la-authtok-utils.lo: src/util/authtok-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-authtok-utils.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-authtok-utils.Tpo -c -o src/util/libsss_util_la-authtok-utils.lo `test -f 'src/util/authtok-utils.c' || echo '$(srcdir)/'`src/util/authtok-utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-authtok-utils.Tpo src/util/$(DEPDIR)/libsss_util_la-authtok-utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok-utils.c' object='src/util/libsss_util_la-authtok-utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-authtok-utils.lo `test -f 'src/util/authtok-utils.c' || echo '$(srcdir)/'`src/util/authtok-utils.c src/util/libsss_util_la-sss_selinux.lo: src/util/sss_selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-sss_selinux.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-sss_selinux.Tpo -c -o src/util/libsss_util_la-sss_selinux.lo `test -f 'src/util/sss_selinux.c' || echo '$(srcdir)/'`src/util/sss_selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-sss_selinux.Tpo src/util/$(DEPDIR)/libsss_util_la-sss_selinux.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_selinux.c' object='src/util/libsss_util_la-sss_selinux.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-sss_selinux.lo `test -f 'src/util/sss_selinux.c' || echo '$(srcdir)/'`src/util/sss_selinux.c src/util/libsss_util_la-domain_info_utils.lo: src/util/domain_info_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-domain_info_utils.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-domain_info_utils.Tpo -c -o src/util/libsss_util_la-domain_info_utils.lo `test -f 'src/util/domain_info_utils.c' || echo '$(srcdir)/'`src/util/domain_info_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-domain_info_utils.Tpo src/util/$(DEPDIR)/libsss_util_la-domain_info_utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/domain_info_utils.c' object='src/util/libsss_util_la-domain_info_utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-domain_info_utils.lo `test -f 'src/util/domain_info_utils.c' || echo '$(srcdir)/'`src/util/domain_info_utils.c src/util/libsss_util_la-util_lock.lo: src/util/util_lock.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-util_lock.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-util_lock.Tpo -c -o src/util/libsss_util_la-util_lock.lo `test -f 'src/util/util_lock.c' || echo '$(srcdir)/'`src/util/util_lock.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-util_lock.Tpo src/util/$(DEPDIR)/libsss_util_la-util_lock.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util_lock.c' object='src/util/libsss_util_la-util_lock.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-util_lock.lo `test -f 'src/util/util_lock.c' || echo '$(srcdir)/'`src/util/util_lock.c src/util/libsss_util_la-util_errors.lo: src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-util_errors.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-util_errors.Tpo -c -o src/util/libsss_util_la-util_errors.lo `test -f 'src/util/util_errors.c' || echo '$(srcdir)/'`src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-util_errors.Tpo src/util/$(DEPDIR)/libsss_util_la-util_errors.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util_errors.c' object='src/util/libsss_util_la-util_errors.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-util_errors.lo `test -f 'src/util/util_errors.c' || echo '$(srcdir)/'`src/util/util_errors.c src/util/libsss_util_la-find_uid.lo: src/util/find_uid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-find_uid.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-find_uid.Tpo -c -o src/util/libsss_util_la-find_uid.lo `test -f 'src/util/find_uid.c' || echo '$(srcdir)/'`src/util/find_uid.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-find_uid.Tpo src/util/$(DEPDIR)/libsss_util_la-find_uid.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/find_uid.c' object='src/util/libsss_util_la-find_uid.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-find_uid.lo `test -f 'src/util/find_uid.c' || echo '$(srcdir)/'`src/util/find_uid.c src/util/libsss_util_la-sss_ini.lo: src/util/sss_ini.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-sss_ini.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-sss_ini.Tpo -c -o src/util/libsss_util_la-sss_ini.lo `test -f 'src/util/sss_ini.c' || echo '$(srcdir)/'`src/util/sss_ini.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-sss_ini.Tpo src/util/$(DEPDIR)/libsss_util_la-sss_ini.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_ini.c' object='src/util/libsss_util_la-sss_ini.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-sss_ini.lo `test -f 'src/util/sss_ini.c' || echo '$(srcdir)/'`src/util/sss_ini.c src/util/libsss_util_la-io.lo: src/util/io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-io.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-io.Tpo -c -o src/util/libsss_util_la-io.lo `test -f 'src/util/io.c' || echo '$(srcdir)/'`src/util/io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-io.Tpo src/util/$(DEPDIR)/libsss_util_la-io.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/io.c' object='src/util/libsss_util_la-io.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-io.lo `test -f 'src/util/io.c' || echo '$(srcdir)/'`src/util/io.c src/util/libsss_util_la-util_sss_idmap.lo: src/util/util_sss_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-util_sss_idmap.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-util_sss_idmap.Tpo -c -o src/util/libsss_util_la-util_sss_idmap.lo `test -f 'src/util/util_sss_idmap.c' || echo '$(srcdir)/'`src/util/util_sss_idmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-util_sss_idmap.Tpo src/util/$(DEPDIR)/libsss_util_la-util_sss_idmap.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util_sss_idmap.c' object='src/util/libsss_util_la-util_sss_idmap.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-util_sss_idmap.lo `test -f 'src/util/util_sss_idmap.c' || echo '$(srcdir)/'`src/util/util_sss_idmap.c src/util/libsss_util_la-well_known_sids.lo: src/util/well_known_sids.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-well_known_sids.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-well_known_sids.Tpo -c -o src/util/libsss_util_la-well_known_sids.lo `test -f 'src/util/well_known_sids.c' || echo '$(srcdir)/'`src/util/well_known_sids.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-well_known_sids.Tpo src/util/$(DEPDIR)/libsss_util_la-well_known_sids.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/well_known_sids.c' object='src/util/libsss_util_la-well_known_sids.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-well_known_sids.lo `test -f 'src/util/well_known_sids.c' || echo '$(srcdir)/'`src/util/well_known_sids.c src/util/libsss_util_la-string_utils.lo: src/util/string_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-string_utils.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-string_utils.Tpo -c -o src/util/libsss_util_la-string_utils.lo `test -f 'src/util/string_utils.c' || echo '$(srcdir)/'`src/util/string_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-string_utils.Tpo src/util/$(DEPDIR)/libsss_util_la-string_utils.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/string_utils.c' object='src/util/libsss_util_la-string_utils.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-string_utils.lo `test -f 'src/util/string_utils.c' || echo '$(srcdir)/'`src/util/string_utils.c src/util/libsss_util_la-become_user.lo: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-become_user.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-become_user.Tpo -c -o src/util/libsss_util_la-become_user.lo `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-become_user.Tpo src/util/$(DEPDIR)/libsss_util_la-become_user.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/libsss_util_la-become_user.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-become_user.lo `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c src/db/libsss_util_la-sysdb_sudo.lo: src/db/sysdb_sudo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_sudo.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_sudo.Tpo -c -o src/db/libsss_util_la-sysdb_sudo.lo `test -f 'src/db/sysdb_sudo.c' || echo '$(srcdir)/'`src/db/sysdb_sudo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_sudo.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_sudo.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_sudo.c' object='src/db/libsss_util_la-sysdb_sudo.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_sudo.lo `test -f 'src/db/sysdb_sudo.c' || echo '$(srcdir)/'`src/db/sysdb_sudo.c src/db/libsss_util_la-sysdb_ssh.lo: src/db/sysdb_ssh.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/db/libsss_util_la-sysdb_ssh.lo -MD -MP -MF src/db/$(DEPDIR)/libsss_util_la-sysdb_ssh.Tpo -c -o src/db/libsss_util_la-sysdb_ssh.lo `test -f 'src/db/sysdb_ssh.c' || echo '$(srcdir)/'`src/db/sysdb_ssh.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/db/$(DEPDIR)/libsss_util_la-sysdb_ssh.Tpo src/db/$(DEPDIR)/libsss_util_la-sysdb_ssh.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/db/sysdb_ssh.c' object='src/db/libsss_util_la-sysdb_ssh.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/db/libsss_util_la-sysdb_ssh.lo `test -f 'src/db/sysdb_ssh.c' || echo '$(srcdir)/'`src/db/sysdb_ssh.c src/util/libsss_util_la-sss_ssh.lo: src/util/sss_ssh.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -MT src/util/libsss_util_la-sss_ssh.lo -MD -MP -MF src/util/$(DEPDIR)/libsss_util_la-sss_ssh.Tpo -c -o src/util/libsss_util_la-sss_ssh.lo `test -f 'src/util/sss_ssh.c' || echo '$(srcdir)/'`src/util/sss_ssh.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/libsss_util_la-sss_ssh.Tpo src/util/$(DEPDIR)/libsss_util_la-sss_ssh.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_ssh.c' object='src/util/libsss_util_la-sss_ssh.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsss_util_la_CFLAGS) $(CFLAGS) -c -o src/util/libsss_util_la-sss_ssh.lo `test -f 'src/util/sss_ssh.c' || echo '$(srcdir)/'`src/util/sss_ssh.c src/ldb_modules/memberof_la-memberof.lo: src/ldb_modules/memberof.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memberof_la_CFLAGS) $(CFLAGS) -MT src/ldb_modules/memberof_la-memberof.lo -MD -MP -MF src/ldb_modules/$(DEPDIR)/memberof_la-memberof.Tpo -c -o src/ldb_modules/memberof_la-memberof.lo `test -f 'src/ldb_modules/memberof.c' || echo '$(srcdir)/'`src/ldb_modules/memberof.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/ldb_modules/$(DEPDIR)/memberof_la-memberof.Tpo src/ldb_modules/$(DEPDIR)/memberof_la-memberof.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/ldb_modules/memberof.c' object='src/ldb_modules/memberof_la-memberof.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memberof_la_CFLAGS) $(CFLAGS) -c -o src/ldb_modules/memberof_la-memberof.lo `test -f 'src/ldb_modules/memberof.c' || echo '$(srcdir)/'`src/ldb_modules/memberof.c src/util/memberof_la-util.lo: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memberof_la_CFLAGS) $(CFLAGS) -MT src/util/memberof_la-util.lo -MD -MP -MF src/util/$(DEPDIR)/memberof_la-util.Tpo -c -o src/util/memberof_la-util.lo `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/memberof_la-util.Tpo src/util/$(DEPDIR)/memberof_la-util.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/memberof_la-util.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memberof_la_CFLAGS) $(CFLAGS) -c -o src/util/memberof_la-util.lo `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c src/sss_client/sss_la-common.lo: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_la-common.lo -MD -MP -MF src/sss_client/$(DEPDIR)/sss_la-common.Tpo -c -o src/sss_client/sss_la-common.lo `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_la-common.Tpo src/sss_client/$(DEPDIR)/sss_la-common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_la-common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_la-common.lo `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/sss_la-nss_mc_common.lo: src/sss_client/nss_mc_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_la-nss_mc_common.lo -MD -MP -MF src/sss_client/$(DEPDIR)/sss_la-nss_mc_common.Tpo -c -o src/sss_client/sss_la-nss_mc_common.lo `test -f 'src/sss_client/nss_mc_common.c' || echo '$(srcdir)/'`src/sss_client/nss_mc_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_la-nss_mc_common.Tpo src/sss_client/$(DEPDIR)/sss_la-nss_mc_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/nss_mc_common.c' object='src/sss_client/sss_la-nss_mc_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_la-nss_mc_common.lo `test -f 'src/sss_client/nss_mc_common.c' || echo '$(srcdir)/'`src/sss_client/nss_mc_common.c src/util/sss_la-io.lo: src/util/io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -MT src/util/sss_la-io.lo -MD -MP -MF src/util/$(DEPDIR)/sss_la-io.Tpo -c -o src/util/sss_la-io.lo `test -f 'src/util/io.c' || echo '$(srcdir)/'`src/util/io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_la-io.Tpo src/util/$(DEPDIR)/sss_la-io.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/io.c' object='src/util/sss_la-io.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -c -o src/util/sss_la-io.lo `test -f 'src/util/io.c' || echo '$(srcdir)/'`src/util/io.c src/util/sss_la-murmurhash3.lo: src/util/murmurhash3.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -MT src/util/sss_la-murmurhash3.lo -MD -MP -MF src/util/$(DEPDIR)/sss_la-murmurhash3.Tpo -c -o src/util/sss_la-murmurhash3.lo `test -f 'src/util/murmurhash3.c' || echo '$(srcdir)/'`src/util/murmurhash3.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_la-murmurhash3.Tpo src/util/$(DEPDIR)/sss_la-murmurhash3.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/murmurhash3.c' object='src/util/sss_la-murmurhash3.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -c -o src/util/sss_la-murmurhash3.lo `test -f 'src/util/murmurhash3.c' || echo '$(srcdir)/'`src/util/murmurhash3.c src/sss_client/sss_la-nss_mc_passwd.lo: src/sss_client/nss_mc_passwd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_la-nss_mc_passwd.lo -MD -MP -MF src/sss_client/$(DEPDIR)/sss_la-nss_mc_passwd.Tpo -c -o src/sss_client/sss_la-nss_mc_passwd.lo `test -f 'src/sss_client/nss_mc_passwd.c' || echo '$(srcdir)/'`src/sss_client/nss_mc_passwd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_la-nss_mc_passwd.Tpo src/sss_client/$(DEPDIR)/sss_la-nss_mc_passwd.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/nss_mc_passwd.c' object='src/sss_client/sss_la-nss_mc_passwd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_la-nss_mc_passwd.lo `test -f 'src/sss_client/nss_mc_passwd.c' || echo '$(srcdir)/'`src/sss_client/nss_mc_passwd.c src/sss_client/sss_la-nss_mc_group.lo: src/sss_client/nss_mc_group.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_la-nss_mc_group.lo -MD -MP -MF src/sss_client/$(DEPDIR)/sss_la-nss_mc_group.Tpo -c -o src/sss_client/sss_la-nss_mc_group.lo `test -f 'src/sss_client/nss_mc_group.c' || echo '$(srcdir)/'`src/sss_client/nss_mc_group.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_la-nss_mc_group.Tpo src/sss_client/$(DEPDIR)/sss_la-nss_mc_group.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/nss_mc_group.c' object='src/sss_client/sss_la-nss_mc_group.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_la-nss_mc_group.lo `test -f 'src/sss_client/nss_mc_group.c' || echo '$(srcdir)/'`src/sss_client/nss_mc_group.c src/sss_client/nfs/sss_la-sss_nfs_client.lo: src/sss_client/nfs/sss_nfs_client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -MT src/sss_client/nfs/sss_la-sss_nfs_client.lo -MD -MP -MF src/sss_client/nfs/$(DEPDIR)/sss_la-sss_nfs_client.Tpo -c -o src/sss_client/nfs/sss_la-sss_nfs_client.lo `test -f 'src/sss_client/nfs/sss_nfs_client.c' || echo '$(srcdir)/'`src/sss_client/nfs/sss_nfs_client.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/nfs/$(DEPDIR)/sss_la-sss_nfs_client.Tpo src/sss_client/nfs/$(DEPDIR)/sss_la-sss_nfs_client.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/nfs/sss_nfs_client.c' object='src/sss_client/nfs/sss_la-sss_nfs_client.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_la_CFLAGS) $(CFLAGS) -c -o src/sss_client/nfs/sss_la-sss_nfs_client.lo `test -f 'src/sss_client/nfs/sss_nfs_client.c' || echo '$(srcdir)/'`src/sss_client/nfs/sss_nfs_client.c src/krb5_plugin/sssd_krb5_localauth_plugin_la-sssd_krb5_localauth_plugin.lo: src/krb5_plugin/sssd_krb5_localauth_plugin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -MT src/krb5_plugin/sssd_krb5_localauth_plugin_la-sssd_krb5_localauth_plugin.lo -MD -MP -MF src/krb5_plugin/$(DEPDIR)/sssd_krb5_localauth_plugin_la-sssd_krb5_localauth_plugin.Tpo -c -o src/krb5_plugin/sssd_krb5_localauth_plugin_la-sssd_krb5_localauth_plugin.lo `test -f 'src/krb5_plugin/sssd_krb5_localauth_plugin.c' || echo '$(srcdir)/'`src/krb5_plugin/sssd_krb5_localauth_plugin.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/krb5_plugin/$(DEPDIR)/sssd_krb5_localauth_plugin_la-sssd_krb5_localauth_plugin.Tpo src/krb5_plugin/$(DEPDIR)/sssd_krb5_localauth_plugin_la-sssd_krb5_localauth_plugin.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/krb5_plugin/sssd_krb5_localauth_plugin.c' object='src/krb5_plugin/sssd_krb5_localauth_plugin_la-sssd_krb5_localauth_plugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -c -o src/krb5_plugin/sssd_krb5_localauth_plugin_la-sssd_krb5_localauth_plugin.lo `test -f 'src/krb5_plugin/sssd_krb5_localauth_plugin.c' || echo '$(srcdir)/'`src/krb5_plugin/sssd_krb5_localauth_plugin.c src/util/sssd_krb5_localauth_plugin_la-murmurhash3.lo: src/util/murmurhash3.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -MT src/util/sssd_krb5_localauth_plugin_la-murmurhash3.lo -MD -MP -MF src/util/$(DEPDIR)/sssd_krb5_localauth_plugin_la-murmurhash3.Tpo -c -o src/util/sssd_krb5_localauth_plugin_la-murmurhash3.lo `test -f 'src/util/murmurhash3.c' || echo '$(srcdir)/'`src/util/murmurhash3.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sssd_krb5_localauth_plugin_la-murmurhash3.Tpo src/util/$(DEPDIR)/sssd_krb5_localauth_plugin_la-murmurhash3.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/murmurhash3.c' object='src/util/sssd_krb5_localauth_plugin_la-murmurhash3.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -c -o src/util/sssd_krb5_localauth_plugin_la-murmurhash3.lo `test -f 'src/util/murmurhash3.c' || echo '$(srcdir)/'`src/util/murmurhash3.c src/util/sssd_krb5_localauth_plugin_la-io.lo: src/util/io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -MT src/util/sssd_krb5_localauth_plugin_la-io.lo -MD -MP -MF src/util/$(DEPDIR)/sssd_krb5_localauth_plugin_la-io.Tpo -c -o src/util/sssd_krb5_localauth_plugin_la-io.lo `test -f 'src/util/io.c' || echo '$(srcdir)/'`src/util/io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sssd_krb5_localauth_plugin_la-io.Tpo src/util/$(DEPDIR)/sssd_krb5_localauth_plugin_la-io.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/io.c' object='src/util/sssd_krb5_localauth_plugin_la-io.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -c -o src/util/sssd_krb5_localauth_plugin_la-io.lo `test -f 'src/util/io.c' || echo '$(srcdir)/'`src/util/io.c src/sss_client/sssd_krb5_localauth_plugin_la-common.lo: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -MT src/sss_client/sssd_krb5_localauth_plugin_la-common.lo -MD -MP -MF src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-common.Tpo -c -o src/sss_client/sssd_krb5_localauth_plugin_la-common.lo `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-common.Tpo src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sssd_krb5_localauth_plugin_la-common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -c -o src/sss_client/sssd_krb5_localauth_plugin_la-common.lo `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_common.lo: src/sss_client/nss_mc_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -MT src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_common.lo -MD -MP -MF src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_mc_common.Tpo -c -o src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_common.lo `test -f 'src/sss_client/nss_mc_common.c' || echo '$(srcdir)/'`src/sss_client/nss_mc_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_mc_common.Tpo src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_mc_common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/nss_mc_common.c' object='src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -c -o src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_common.lo `test -f 'src/sss_client/nss_mc_common.c' || echo '$(srcdir)/'`src/sss_client/nss_mc_common.c src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_passwd.lo: src/sss_client/nss_mc_passwd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -MT src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_passwd.lo -MD -MP -MF src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_mc_passwd.Tpo -c -o src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_passwd.lo `test -f 'src/sss_client/nss_mc_passwd.c' || echo '$(srcdir)/'`src/sss_client/nss_mc_passwd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_mc_passwd.Tpo src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_mc_passwd.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/nss_mc_passwd.c' object='src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_passwd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -c -o src/sss_client/sssd_krb5_localauth_plugin_la-nss_mc_passwd.lo `test -f 'src/sss_client/nss_mc_passwd.c' || echo '$(srcdir)/'`src/sss_client/nss_mc_passwd.c src/sss_client/sssd_krb5_localauth_plugin_la-nss_passwd.lo: src/sss_client/nss_passwd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -MT src/sss_client/sssd_krb5_localauth_plugin_la-nss_passwd.lo -MD -MP -MF src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_passwd.Tpo -c -o src/sss_client/sssd_krb5_localauth_plugin_la-nss_passwd.lo `test -f 'src/sss_client/nss_passwd.c' || echo '$(srcdir)/'`src/sss_client/nss_passwd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_passwd.Tpo src/sss_client/$(DEPDIR)/sssd_krb5_localauth_plugin_la-nss_passwd.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/nss_passwd.c' object='src/sss_client/sssd_krb5_localauth_plugin_la-nss_passwd.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_localauth_plugin_la_CFLAGS) $(CFLAGS) -c -o src/sss_client/sssd_krb5_localauth_plugin_la-nss_passwd.lo `test -f 'src/sss_client/nss_passwd.c' || echo '$(srcdir)/'`src/sss_client/nss_passwd.c src/krb5_plugin/sssd_krb5_locator_plugin_la-sssd_krb5_locator_plugin.lo: src/krb5_plugin/sssd_krb5_locator_plugin.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_locator_plugin_la_CFLAGS) $(CFLAGS) -MT src/krb5_plugin/sssd_krb5_locator_plugin_la-sssd_krb5_locator_plugin.lo -MD -MP -MF src/krb5_plugin/$(DEPDIR)/sssd_krb5_locator_plugin_la-sssd_krb5_locator_plugin.Tpo -c -o src/krb5_plugin/sssd_krb5_locator_plugin_la-sssd_krb5_locator_plugin.lo `test -f 'src/krb5_plugin/sssd_krb5_locator_plugin.c' || echo '$(srcdir)/'`src/krb5_plugin/sssd_krb5_locator_plugin.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/krb5_plugin/$(DEPDIR)/sssd_krb5_locator_plugin_la-sssd_krb5_locator_plugin.Tpo src/krb5_plugin/$(DEPDIR)/sssd_krb5_locator_plugin_la-sssd_krb5_locator_plugin.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/krb5_plugin/sssd_krb5_locator_plugin.c' object='src/krb5_plugin/sssd_krb5_locator_plugin_la-sssd_krb5_locator_plugin.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_locator_plugin_la_CFLAGS) $(CFLAGS) -c -o src/krb5_plugin/sssd_krb5_locator_plugin_la-sssd_krb5_locator_plugin.lo `test -f 'src/krb5_plugin/sssd_krb5_locator_plugin.c' || echo '$(srcdir)/'`src/krb5_plugin/sssd_krb5_locator_plugin.c src/util/sssd_krb5_locator_plugin_la-atomic_io.lo: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_locator_plugin_la_CFLAGS) $(CFLAGS) -MT src/util/sssd_krb5_locator_plugin_la-atomic_io.lo -MD -MP -MF src/util/$(DEPDIR)/sssd_krb5_locator_plugin_la-atomic_io.Tpo -c -o src/util/sssd_krb5_locator_plugin_la-atomic_io.lo `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sssd_krb5_locator_plugin_la-atomic_io.Tpo src/util/$(DEPDIR)/sssd_krb5_locator_plugin_la-atomic_io.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/sssd_krb5_locator_plugin_la-atomic_io.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_krb5_locator_plugin_la_CFLAGS) $(CFLAGS) -c -o src/util/sssd_krb5_locator_plugin_la-atomic_io.lo `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c src/sss_client/sssd_pac_plugin_la-sssd_pac.lo: src/sss_client/sssd_pac.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_plugin_la_CFLAGS) $(CFLAGS) -MT src/sss_client/sssd_pac_plugin_la-sssd_pac.lo -MD -MP -MF src/sss_client/$(DEPDIR)/sssd_pac_plugin_la-sssd_pac.Tpo -c -o src/sss_client/sssd_pac_plugin_la-sssd_pac.lo `test -f 'src/sss_client/sssd_pac.c' || echo '$(srcdir)/'`src/sss_client/sssd_pac.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sssd_pac_plugin_la-sssd_pac.Tpo src/sss_client/$(DEPDIR)/sssd_pac_plugin_la-sssd_pac.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/sssd_pac.c' object='src/sss_client/sssd_pac_plugin_la-sssd_pac.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_plugin_la_CFLAGS) $(CFLAGS) -c -o src/sss_client/sssd_pac_plugin_la-sssd_pac.lo `test -f 'src/sss_client/sssd_pac.c' || echo '$(srcdir)/'`src/sss_client/sssd_pac.c src/sss_client/sssd_pac_plugin_la-common.lo: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_plugin_la_CFLAGS) $(CFLAGS) -MT src/sss_client/sssd_pac_plugin_la-common.lo -MD -MP -MF src/sss_client/$(DEPDIR)/sssd_pac_plugin_la-common.Tpo -c -o src/sss_client/sssd_pac_plugin_la-common.lo `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sssd_pac_plugin_la-common.Tpo src/sss_client/$(DEPDIR)/sssd_pac_plugin_la-common.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sssd_pac_plugin_la-common.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_plugin_la_CFLAGS) $(CFLAGS) -c -o src/sss_client/sssd_pac_plugin_la-common.lo `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/tests/cmocka/ad_gpo_tests-test_ad_gpo.o: src/tests/cmocka/test_ad_gpo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_gpo_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/ad_gpo_tests-test_ad_gpo.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/ad_gpo_tests-test_ad_gpo.Tpo -c -o src/tests/cmocka/ad_gpo_tests-test_ad_gpo.o `test -f 'src/tests/cmocka/test_ad_gpo.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ad_gpo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/ad_gpo_tests-test_ad_gpo.Tpo src/tests/cmocka/$(DEPDIR)/ad_gpo_tests-test_ad_gpo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ad_gpo.c' object='src/tests/cmocka/ad_gpo_tests-test_ad_gpo.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_gpo_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/ad_gpo_tests-test_ad_gpo.o `test -f 'src/tests/cmocka/test_ad_gpo.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ad_gpo.c src/tests/cmocka/ad_gpo_tests-test_ad_gpo.obj: src/tests/cmocka/test_ad_gpo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_gpo_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/ad_gpo_tests-test_ad_gpo.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/ad_gpo_tests-test_ad_gpo.Tpo -c -o src/tests/cmocka/ad_gpo_tests-test_ad_gpo.obj `if test -f 'src/tests/cmocka/test_ad_gpo.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ad_gpo.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ad_gpo.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/ad_gpo_tests-test_ad_gpo.Tpo src/tests/cmocka/$(DEPDIR)/ad_gpo_tests-test_ad_gpo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ad_gpo.c' object='src/tests/cmocka/ad_gpo_tests-test_ad_gpo.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_gpo_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/ad_gpo_tests-test_ad_gpo.obj `if test -f 'src/tests/cmocka/test_ad_gpo.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ad_gpo.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ad_gpo.c'; fi` src/providers/ldap/ad_ldap_opt_tests-ldap_opts.o: src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ad_ldap_opt_tests-ldap_opts.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/ad_ldap_opt_tests-ldap_opts.Tpo -c -o src/providers/ldap/ad_ldap_opt_tests-ldap_opts.o `test -f 'src/providers/ldap/ldap_opts.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ad_ldap_opt_tests-ldap_opts.Tpo src/providers/ldap/$(DEPDIR)/ad_ldap_opt_tests-ldap_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_opts.c' object='src/providers/ldap/ad_ldap_opt_tests-ldap_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ad_ldap_opt_tests-ldap_opts.o `test -f 'src/providers/ldap/ldap_opts.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_opts.c src/providers/ldap/ad_ldap_opt_tests-ldap_opts.obj: src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ad_ldap_opt_tests-ldap_opts.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/ad_ldap_opt_tests-ldap_opts.Tpo -c -o src/providers/ldap/ad_ldap_opt_tests-ldap_opts.obj `if test -f 'src/providers/ldap/ldap_opts.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ad_ldap_opt_tests-ldap_opts.Tpo src/providers/ldap/$(DEPDIR)/ad_ldap_opt_tests-ldap_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_opts.c' object='src/providers/ldap/ad_ldap_opt_tests-ldap_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ad_ldap_opt_tests-ldap_opts.obj `if test -f 'src/providers/ldap/ldap_opts.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_opts.c'; fi` src/providers/ad/ad_ldap_opt_tests-ad_opts.o: src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ad/ad_ldap_opt_tests-ad_opts.o -MD -MP -MF src/providers/ad/$(DEPDIR)/ad_ldap_opt_tests-ad_opts.Tpo -c -o src/providers/ad/ad_ldap_opt_tests-ad_opts.o `test -f 'src/providers/ad/ad_opts.c' || echo '$(srcdir)/'`src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/ad_ldap_opt_tests-ad_opts.Tpo src/providers/ad/$(DEPDIR)/ad_ldap_opt_tests-ad_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_opts.c' object='src/providers/ad/ad_ldap_opt_tests-ad_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ad/ad_ldap_opt_tests-ad_opts.o `test -f 'src/providers/ad/ad_opts.c' || echo '$(srcdir)/'`src/providers/ad/ad_opts.c src/providers/ad/ad_ldap_opt_tests-ad_opts.obj: src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ad/ad_ldap_opt_tests-ad_opts.obj -MD -MP -MF src/providers/ad/$(DEPDIR)/ad_ldap_opt_tests-ad_opts.Tpo -c -o src/providers/ad/ad_ldap_opt_tests-ad_opts.obj `if test -f 'src/providers/ad/ad_opts.c'; then $(CYGPATH_W) 'src/providers/ad/ad_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ad/ad_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/ad_ldap_opt_tests-ad_opts.Tpo src/providers/ad/$(DEPDIR)/ad_ldap_opt_tests-ad_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_opts.c' object='src/providers/ad/ad_ldap_opt_tests-ad_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ad/ad_ldap_opt_tests-ad_opts.obj `if test -f 'src/providers/ad/ad_opts.c'; then $(CYGPATH_W) 'src/providers/ad/ad_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ad/ad_opts.c'; fi` src/providers/krb5/ad_ldap_opt_tests-krb5_opts.o: src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/ad_ldap_opt_tests-krb5_opts.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/ad_ldap_opt_tests-krb5_opts.Tpo -c -o src/providers/krb5/ad_ldap_opt_tests-krb5_opts.o `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/ad_ldap_opt_tests-krb5_opts.Tpo src/providers/krb5/$(DEPDIR)/ad_ldap_opt_tests-krb5_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_opts.c' object='src/providers/krb5/ad_ldap_opt_tests-krb5_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/ad_ldap_opt_tests-krb5_opts.o `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c src/providers/krb5/ad_ldap_opt_tests-krb5_opts.obj: src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/ad_ldap_opt_tests-krb5_opts.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/ad_ldap_opt_tests-krb5_opts.Tpo -c -o src/providers/krb5/ad_ldap_opt_tests-krb5_opts.obj `if test -f 'src/providers/krb5/krb5_opts.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/ad_ldap_opt_tests-krb5_opts.Tpo src/providers/krb5/$(DEPDIR)/ad_ldap_opt_tests-krb5_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_opts.c' object='src/providers/krb5/ad_ldap_opt_tests-krb5_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/ad_ldap_opt_tests-krb5_opts.obj `if test -f 'src/providers/krb5/krb5_opts.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_opts.c'; fi` src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.o: src/tests/ad_ldap_opt-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.o -MD -MP -MF src/tests/$(DEPDIR)/ad_ldap_opt_tests-ad_ldap_opt-tests.Tpo -c -o src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.o `test -f 'src/tests/ad_ldap_opt-tests.c' || echo '$(srcdir)/'`src/tests/ad_ldap_opt-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/ad_ldap_opt_tests-ad_ldap_opt-tests.Tpo src/tests/$(DEPDIR)/ad_ldap_opt_tests-ad_ldap_opt-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/ad_ldap_opt-tests.c' object='src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.o `test -f 'src/tests/ad_ldap_opt-tests.c' || echo '$(srcdir)/'`src/tests/ad_ldap_opt-tests.c src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.obj: src/tests/ad_ldap_opt-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/ad_ldap_opt_tests-ad_ldap_opt-tests.Tpo -c -o src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.obj `if test -f 'src/tests/ad_ldap_opt-tests.c'; then $(CYGPATH_W) 'src/tests/ad_ldap_opt-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/ad_ldap_opt-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/ad_ldap_opt_tests-ad_ldap_opt-tests.Tpo src/tests/$(DEPDIR)/ad_ldap_opt_tests-ad_ldap_opt-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/ad_ldap_opt-tests.c' object='src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ad_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/tests/ad_ldap_opt_tests-ad_ldap_opt-tests.obj `if test -f 'src/tests/ad_ldap_opt-tests.c'; then $(CYGPATH_W) 'src/tests/ad_ldap_opt-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/ad_ldap_opt-tests.c'; fi` src/tests/auth_tests-auth-tests.o: src/tests/auth-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_tests_CFLAGS) $(CFLAGS) -MT src/tests/auth_tests-auth-tests.o -MD -MP -MF src/tests/$(DEPDIR)/auth_tests-auth-tests.Tpo -c -o src/tests/auth_tests-auth-tests.o `test -f 'src/tests/auth-tests.c' || echo '$(srcdir)/'`src/tests/auth-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/auth_tests-auth-tests.Tpo src/tests/$(DEPDIR)/auth_tests-auth-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/auth-tests.c' object='src/tests/auth_tests-auth-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_tests_CFLAGS) $(CFLAGS) -c -o src/tests/auth_tests-auth-tests.o `test -f 'src/tests/auth-tests.c' || echo '$(srcdir)/'`src/tests/auth-tests.c src/tests/auth_tests-auth-tests.obj: src/tests/auth-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_tests_CFLAGS) $(CFLAGS) -MT src/tests/auth_tests-auth-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/auth_tests-auth-tests.Tpo -c -o src/tests/auth_tests-auth-tests.obj `if test -f 'src/tests/auth-tests.c'; then $(CYGPATH_W) 'src/tests/auth-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/auth-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/auth_tests-auth-tests.Tpo src/tests/$(DEPDIR)/auth_tests-auth-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/auth-tests.c' object='src/tests/auth_tests-auth-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(auth_tests_CFLAGS) $(CFLAGS) -c -o src/tests/auth_tests-auth-tests.obj `if test -f 'src/tests/auth-tests.c'; then $(CYGPATH_W) 'src/tests/auth-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/auth-tests.c'; fi` src/sss_client/autofs/autofs_test_client-autofs_test_client.o: src/sss_client/autofs/autofs_test_client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -MT src/sss_client/autofs/autofs_test_client-autofs_test_client.o -MD -MP -MF src/sss_client/autofs/$(DEPDIR)/autofs_test_client-autofs_test_client.Tpo -c -o src/sss_client/autofs/autofs_test_client-autofs_test_client.o `test -f 'src/sss_client/autofs/autofs_test_client.c' || echo '$(srcdir)/'`src/sss_client/autofs/autofs_test_client.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/autofs/$(DEPDIR)/autofs_test_client-autofs_test_client.Tpo src/sss_client/autofs/$(DEPDIR)/autofs_test_client-autofs_test_client.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/autofs/autofs_test_client.c' object='src/sss_client/autofs/autofs_test_client-autofs_test_client.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -c -o src/sss_client/autofs/autofs_test_client-autofs_test_client.o `test -f 'src/sss_client/autofs/autofs_test_client.c' || echo '$(srcdir)/'`src/sss_client/autofs/autofs_test_client.c src/sss_client/autofs/autofs_test_client-autofs_test_client.obj: src/sss_client/autofs/autofs_test_client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -MT src/sss_client/autofs/autofs_test_client-autofs_test_client.obj -MD -MP -MF src/sss_client/autofs/$(DEPDIR)/autofs_test_client-autofs_test_client.Tpo -c -o src/sss_client/autofs/autofs_test_client-autofs_test_client.obj `if test -f 'src/sss_client/autofs/autofs_test_client.c'; then $(CYGPATH_W) 'src/sss_client/autofs/autofs_test_client.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/autofs/autofs_test_client.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/autofs/$(DEPDIR)/autofs_test_client-autofs_test_client.Tpo src/sss_client/autofs/$(DEPDIR)/autofs_test_client-autofs_test_client.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/autofs/autofs_test_client.c' object='src/sss_client/autofs/autofs_test_client-autofs_test_client.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -c -o src/sss_client/autofs/autofs_test_client-autofs_test_client.obj `if test -f 'src/sss_client/autofs/autofs_test_client.c'; then $(CYGPATH_W) 'src/sss_client/autofs/autofs_test_client.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/autofs/autofs_test_client.c'; fi` src/sss_client/autofs/autofs_test_client-sss_autofs.o: src/sss_client/autofs/sss_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -MT src/sss_client/autofs/autofs_test_client-sss_autofs.o -MD -MP -MF src/sss_client/autofs/$(DEPDIR)/autofs_test_client-sss_autofs.Tpo -c -o src/sss_client/autofs/autofs_test_client-sss_autofs.o `test -f 'src/sss_client/autofs/sss_autofs.c' || echo '$(srcdir)/'`src/sss_client/autofs/sss_autofs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/autofs/$(DEPDIR)/autofs_test_client-sss_autofs.Tpo src/sss_client/autofs/$(DEPDIR)/autofs_test_client-sss_autofs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/autofs/sss_autofs.c' object='src/sss_client/autofs/autofs_test_client-sss_autofs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -c -o src/sss_client/autofs/autofs_test_client-sss_autofs.o `test -f 'src/sss_client/autofs/sss_autofs.c' || echo '$(srcdir)/'`src/sss_client/autofs/sss_autofs.c src/sss_client/autofs/autofs_test_client-sss_autofs.obj: src/sss_client/autofs/sss_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -MT src/sss_client/autofs/autofs_test_client-sss_autofs.obj -MD -MP -MF src/sss_client/autofs/$(DEPDIR)/autofs_test_client-sss_autofs.Tpo -c -o src/sss_client/autofs/autofs_test_client-sss_autofs.obj `if test -f 'src/sss_client/autofs/sss_autofs.c'; then $(CYGPATH_W) 'src/sss_client/autofs/sss_autofs.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/autofs/sss_autofs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/autofs/$(DEPDIR)/autofs_test_client-sss_autofs.Tpo src/sss_client/autofs/$(DEPDIR)/autofs_test_client-sss_autofs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/autofs/sss_autofs.c' object='src/sss_client/autofs/autofs_test_client-sss_autofs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -c -o src/sss_client/autofs/autofs_test_client-sss_autofs.obj `if test -f 'src/sss_client/autofs/sss_autofs.c'; then $(CYGPATH_W) 'src/sss_client/autofs/sss_autofs.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/autofs/sss_autofs.c'; fi` src/sss_client/autofs_test_client-common.o: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -MT src/sss_client/autofs_test_client-common.o -MD -MP -MF src/sss_client/$(DEPDIR)/autofs_test_client-common.Tpo -c -o src/sss_client/autofs_test_client-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/autofs_test_client-common.Tpo src/sss_client/$(DEPDIR)/autofs_test_client-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/autofs_test_client-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -c -o src/sss_client/autofs_test_client-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/autofs_test_client-common.obj: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -MT src/sss_client/autofs_test_client-common.obj -MD -MP -MF src/sss_client/$(DEPDIR)/autofs_test_client-common.Tpo -c -o src/sss_client/autofs_test_client-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/autofs_test_client-common.Tpo src/sss_client/$(DEPDIR)/autofs_test_client-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/autofs_test_client-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autofs_test_client_CFLAGS) $(CFLAGS) -c -o src/sss_client/autofs_test_client-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` src/tests/check_and_open_tests-check_and_open-tests.o: src/tests/check_and_open-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_and_open_tests_CFLAGS) $(CFLAGS) -MT src/tests/check_and_open_tests-check_and_open-tests.o -MD -MP -MF src/tests/$(DEPDIR)/check_and_open_tests-check_and_open-tests.Tpo -c -o src/tests/check_and_open_tests-check_and_open-tests.o `test -f 'src/tests/check_and_open-tests.c' || echo '$(srcdir)/'`src/tests/check_and_open-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/check_and_open_tests-check_and_open-tests.Tpo src/tests/$(DEPDIR)/check_and_open_tests-check_and_open-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/check_and_open-tests.c' object='src/tests/check_and_open_tests-check_and_open-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_and_open_tests_CFLAGS) $(CFLAGS) -c -o src/tests/check_and_open_tests-check_and_open-tests.o `test -f 'src/tests/check_and_open-tests.c' || echo '$(srcdir)/'`src/tests/check_and_open-tests.c src/tests/check_and_open_tests-check_and_open-tests.obj: src/tests/check_and_open-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_and_open_tests_CFLAGS) $(CFLAGS) -MT src/tests/check_and_open_tests-check_and_open-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/check_and_open_tests-check_and_open-tests.Tpo -c -o src/tests/check_and_open_tests-check_and_open-tests.obj `if test -f 'src/tests/check_and_open-tests.c'; then $(CYGPATH_W) 'src/tests/check_and_open-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/check_and_open-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/check_and_open_tests-check_and_open-tests.Tpo src/tests/$(DEPDIR)/check_and_open_tests-check_and_open-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/check_and_open-tests.c' object='src/tests/check_and_open_tests-check_and_open-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_and_open_tests_CFLAGS) $(CFLAGS) -c -o src/tests/check_and_open_tests-check_and_open-tests.obj `if test -f 'src/tests/check_and_open-tests.c'; then $(CYGPATH_W) 'src/tests/check_and_open-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/check_and_open-tests.c'; fi` src/util/check_and_open_tests-check_and_open.o: src/util/check_and_open.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_and_open_tests_CFLAGS) $(CFLAGS) -MT src/util/check_and_open_tests-check_and_open.o -MD -MP -MF src/util/$(DEPDIR)/check_and_open_tests-check_and_open.Tpo -c -o src/util/check_and_open_tests-check_and_open.o `test -f 'src/util/check_and_open.c' || echo '$(srcdir)/'`src/util/check_and_open.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/check_and_open_tests-check_and_open.Tpo src/util/$(DEPDIR)/check_and_open_tests-check_and_open.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/check_and_open.c' object='src/util/check_and_open_tests-check_and_open.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_and_open_tests_CFLAGS) $(CFLAGS) -c -o src/util/check_and_open_tests-check_and_open.o `test -f 'src/util/check_and_open.c' || echo '$(srcdir)/'`src/util/check_and_open.c src/util/check_and_open_tests-check_and_open.obj: src/util/check_and_open.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_and_open_tests_CFLAGS) $(CFLAGS) -MT src/util/check_and_open_tests-check_and_open.obj -MD -MP -MF src/util/$(DEPDIR)/check_and_open_tests-check_and_open.Tpo -c -o src/util/check_and_open_tests-check_and_open.obj `if test -f 'src/util/check_and_open.c'; then $(CYGPATH_W) 'src/util/check_and_open.c'; else $(CYGPATH_W) '$(srcdir)/src/util/check_and_open.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/check_and_open_tests-check_and_open.Tpo src/util/$(DEPDIR)/check_and_open_tests-check_and_open.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/check_and_open.c' object='src/util/check_and_open_tests-check_and_open.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(check_and_open_tests_CFLAGS) $(CFLAGS) -c -o src/util/check_and_open_tests-check_and_open.obj `if test -f 'src/util/check_and_open.c'; then $(CYGPATH_W) 'src/util/check_and_open.c'; else $(CYGPATH_W) '$(srcdir)/src/util/check_and_open.c'; fi` src/tests/crypto_tests-crypto-tests.o: src/tests/crypto-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(crypto_tests_CFLAGS) $(CFLAGS) -MT src/tests/crypto_tests-crypto-tests.o -MD -MP -MF src/tests/$(DEPDIR)/crypto_tests-crypto-tests.Tpo -c -o src/tests/crypto_tests-crypto-tests.o `test -f 'src/tests/crypto-tests.c' || echo '$(srcdir)/'`src/tests/crypto-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/crypto_tests-crypto-tests.Tpo src/tests/$(DEPDIR)/crypto_tests-crypto-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/crypto-tests.c' object='src/tests/crypto_tests-crypto-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(crypto_tests_CFLAGS) $(CFLAGS) -c -o src/tests/crypto_tests-crypto-tests.o `test -f 'src/tests/crypto-tests.c' || echo '$(srcdir)/'`src/tests/crypto-tests.c src/tests/crypto_tests-crypto-tests.obj: src/tests/crypto-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(crypto_tests_CFLAGS) $(CFLAGS) -MT src/tests/crypto_tests-crypto-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/crypto_tests-crypto-tests.Tpo -c -o src/tests/crypto_tests-crypto-tests.obj `if test -f 'src/tests/crypto-tests.c'; then $(CYGPATH_W) 'src/tests/crypto-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/crypto-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/crypto_tests-crypto-tests.Tpo src/tests/$(DEPDIR)/crypto_tests-crypto-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/crypto-tests.c' object='src/tests/crypto_tests-crypto-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(crypto_tests_CFLAGS) $(CFLAGS) -c -o src/tests/crypto_tests-crypto-tests.obj `if test -f 'src/tests/crypto-tests.c'; then $(CYGPATH_W) 'src/tests/crypto-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/crypto-tests.c'; fi` src/tests/debug_tests-debug-tests.o: src/tests/debug-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debug_tests_CFLAGS) $(CFLAGS) -MT src/tests/debug_tests-debug-tests.o -MD -MP -MF src/tests/$(DEPDIR)/debug_tests-debug-tests.Tpo -c -o src/tests/debug_tests-debug-tests.o `test -f 'src/tests/debug-tests.c' || echo '$(srcdir)/'`src/tests/debug-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/debug_tests-debug-tests.Tpo src/tests/$(DEPDIR)/debug_tests-debug-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/debug-tests.c' object='src/tests/debug_tests-debug-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debug_tests_CFLAGS) $(CFLAGS) -c -o src/tests/debug_tests-debug-tests.o `test -f 'src/tests/debug-tests.c' || echo '$(srcdir)/'`src/tests/debug-tests.c src/tests/debug_tests-debug-tests.obj: src/tests/debug-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debug_tests_CFLAGS) $(CFLAGS) -MT src/tests/debug_tests-debug-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/debug_tests-debug-tests.Tpo -c -o src/tests/debug_tests-debug-tests.obj `if test -f 'src/tests/debug-tests.c'; then $(CYGPATH_W) 'src/tests/debug-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/debug-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/debug_tests-debug-tests.Tpo src/tests/$(DEPDIR)/debug_tests-debug-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/debug-tests.c' object='src/tests/debug_tests-debug-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debug_tests_CFLAGS) $(CFLAGS) -c -o src/tests/debug_tests-debug-tests.obj `if test -f 'src/tests/debug-tests.c'; then $(CYGPATH_W) 'src/tests/debug-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/debug-tests.c'; fi` src/tests/debug_tests-common.o: src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debug_tests_CFLAGS) $(CFLAGS) -MT src/tests/debug_tests-common.o -MD -MP -MF src/tests/$(DEPDIR)/debug_tests-common.Tpo -c -o src/tests/debug_tests-common.o `test -f 'src/tests/common.c' || echo '$(srcdir)/'`src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/debug_tests-common.Tpo src/tests/$(DEPDIR)/debug_tests-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common.c' object='src/tests/debug_tests-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debug_tests_CFLAGS) $(CFLAGS) -c -o src/tests/debug_tests-common.o `test -f 'src/tests/common.c' || echo '$(srcdir)/'`src/tests/common.c src/tests/debug_tests-common.obj: src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debug_tests_CFLAGS) $(CFLAGS) -MT src/tests/debug_tests-common.obj -MD -MP -MF src/tests/$(DEPDIR)/debug_tests-common.Tpo -c -o src/tests/debug_tests-common.obj `if test -f 'src/tests/common.c'; then $(CYGPATH_W) 'src/tests/common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/debug_tests-common.Tpo src/tests/$(DEPDIR)/debug_tests-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common.c' object='src/tests/debug_tests-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(debug_tests_CFLAGS) $(CFLAGS) -c -o src/tests/debug_tests-common.obj `if test -f 'src/tests/common.c'; then $(CYGPATH_W) 'src/tests/common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common.c'; fi` src/tests/dlopen_tests-dlopen-tests.o: src/tests/dlopen-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dlopen_tests_CFLAGS) $(CFLAGS) -MT src/tests/dlopen_tests-dlopen-tests.o -MD -MP -MF src/tests/$(DEPDIR)/dlopen_tests-dlopen-tests.Tpo -c -o src/tests/dlopen_tests-dlopen-tests.o `test -f 'src/tests/dlopen-tests.c' || echo '$(srcdir)/'`src/tests/dlopen-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/dlopen_tests-dlopen-tests.Tpo src/tests/$(DEPDIR)/dlopen_tests-dlopen-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/dlopen-tests.c' object='src/tests/dlopen_tests-dlopen-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dlopen_tests_CFLAGS) $(CFLAGS) -c -o src/tests/dlopen_tests-dlopen-tests.o `test -f 'src/tests/dlopen-tests.c' || echo '$(srcdir)/'`src/tests/dlopen-tests.c src/tests/dlopen_tests-dlopen-tests.obj: src/tests/dlopen-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dlopen_tests_CFLAGS) $(CFLAGS) -MT src/tests/dlopen_tests-dlopen-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/dlopen_tests-dlopen-tests.Tpo -c -o src/tests/dlopen_tests-dlopen-tests.obj `if test -f 'src/tests/dlopen-tests.c'; then $(CYGPATH_W) 'src/tests/dlopen-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/dlopen-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/dlopen_tests-dlopen-tests.Tpo src/tests/$(DEPDIR)/dlopen_tests-dlopen-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/dlopen-tests.c' object='src/tests/dlopen_tests-dlopen-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dlopen_tests_CFLAGS) $(CFLAGS) -c -o src/tests/dlopen_tests-dlopen-tests.obj `if test -f 'src/tests/dlopen-tests.c'; then $(CYGPATH_W) 'src/tests/dlopen-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/dlopen-tests.c'; fi` src/providers/dp_opt_tests-data_provider_opts.o: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dp_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/dp_opt_tests-data_provider_opts.o -MD -MP -MF src/providers/$(DEPDIR)/dp_opt_tests-data_provider_opts.Tpo -c -o src/providers/dp_opt_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/dp_opt_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/dp_opt_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/dp_opt_tests-data_provider_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dp_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/dp_opt_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c src/providers/dp_opt_tests-data_provider_opts.obj: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dp_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/dp_opt_tests-data_provider_opts.obj -MD -MP -MF src/providers/$(DEPDIR)/dp_opt_tests-data_provider_opts.Tpo -c -o src/providers/dp_opt_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/dp_opt_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/dp_opt_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/dp_opt_tests-data_provider_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dp_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/dp_opt_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` src/tests/cmocka/dp_opt_tests-test_dp_opts.o: src/tests/cmocka/test_dp_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dp_opt_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/dp_opt_tests-test_dp_opts.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/dp_opt_tests-test_dp_opts.Tpo -c -o src/tests/cmocka/dp_opt_tests-test_dp_opts.o `test -f 'src/tests/cmocka/test_dp_opts.c' || echo '$(srcdir)/'`src/tests/cmocka/test_dp_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/dp_opt_tests-test_dp_opts.Tpo src/tests/cmocka/$(DEPDIR)/dp_opt_tests-test_dp_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_dp_opts.c' object='src/tests/cmocka/dp_opt_tests-test_dp_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dp_opt_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/dp_opt_tests-test_dp_opts.o `test -f 'src/tests/cmocka/test_dp_opts.c' || echo '$(srcdir)/'`src/tests/cmocka/test_dp_opts.c src/tests/cmocka/dp_opt_tests-test_dp_opts.obj: src/tests/cmocka/test_dp_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dp_opt_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/dp_opt_tests-test_dp_opts.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/dp_opt_tests-test_dp_opts.Tpo -c -o src/tests/cmocka/dp_opt_tests-test_dp_opts.obj `if test -f 'src/tests/cmocka/test_dp_opts.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_dp_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_dp_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/dp_opt_tests-test_dp_opts.Tpo src/tests/cmocka/$(DEPDIR)/dp_opt_tests-test_dp_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_dp_opts.c' object='src/tests/cmocka/dp_opt_tests-test_dp_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dp_opt_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/dp_opt_tests-test_dp_opts.obj `if test -f 'src/tests/cmocka/test_dp_opts.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_dp_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_dp_opts.c'; fi` src/resolv/dyndns_tests-async_resolv.o: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -MT src/resolv/dyndns_tests-async_resolv.o -MD -MP -MF src/resolv/$(DEPDIR)/dyndns_tests-async_resolv.Tpo -c -o src/resolv/dyndns_tests-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/dyndns_tests-async_resolv.Tpo src/resolv/$(DEPDIR)/dyndns_tests-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/dyndns_tests-async_resolv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/dyndns_tests-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c src/resolv/dyndns_tests-async_resolv.obj: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -MT src/resolv/dyndns_tests-async_resolv.obj -MD -MP -MF src/resolv/$(DEPDIR)/dyndns_tests-async_resolv.Tpo -c -o src/resolv/dyndns_tests-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/dyndns_tests-async_resolv.Tpo src/resolv/$(DEPDIR)/dyndns_tests-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/dyndns_tests-async_resolv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/dyndns_tests-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` src/resolv/dyndns_tests-async_resolv_utils.o: src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -MT src/resolv/dyndns_tests-async_resolv_utils.o -MD -MP -MF src/resolv/$(DEPDIR)/dyndns_tests-async_resolv_utils.Tpo -c -o src/resolv/dyndns_tests-async_resolv_utils.o `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/dyndns_tests-async_resolv_utils.Tpo src/resolv/$(DEPDIR)/dyndns_tests-async_resolv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv_utils.c' object='src/resolv/dyndns_tests-async_resolv_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/dyndns_tests-async_resolv_utils.o `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c src/resolv/dyndns_tests-async_resolv_utils.obj: src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -MT src/resolv/dyndns_tests-async_resolv_utils.obj -MD -MP -MF src/resolv/$(DEPDIR)/dyndns_tests-async_resolv_utils.Tpo -c -o src/resolv/dyndns_tests-async_resolv_utils.obj `if test -f 'src/resolv/async_resolv_utils.c'; then $(CYGPATH_W) 'src/resolv/async_resolv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/dyndns_tests-async_resolv_utils.Tpo src/resolv/$(DEPDIR)/dyndns_tests-async_resolv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv_utils.c' object='src/resolv/dyndns_tests-async_resolv_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/dyndns_tests-async_resolv_utils.obj `if test -f 'src/resolv/async_resolv_utils.c'; then $(CYGPATH_W) 'src/resolv/async_resolv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv_utils.c'; fi` src/tests/cmocka/dyndns_tests-common_mock_be.o: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/dyndns_tests-common_mock_be.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/dyndns_tests-common_mock_be.Tpo -c -o src/tests/cmocka/dyndns_tests-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/dyndns_tests-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/dyndns_tests-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/dyndns_tests-common_mock_be.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/dyndns_tests-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c src/tests/cmocka/dyndns_tests-common_mock_be.obj: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/dyndns_tests-common_mock_be.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/dyndns_tests-common_mock_be.Tpo -c -o src/tests/cmocka/dyndns_tests-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/dyndns_tests-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/dyndns_tests-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/dyndns_tests-common_mock_be.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/dyndns_tests-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` src/tests/cmocka/dyndns_tests-test_dyndns.o: src/tests/cmocka/test_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/dyndns_tests-test_dyndns.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/dyndns_tests-test_dyndns.Tpo -c -o src/tests/cmocka/dyndns_tests-test_dyndns.o `test -f 'src/tests/cmocka/test_dyndns.c' || echo '$(srcdir)/'`src/tests/cmocka/test_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/dyndns_tests-test_dyndns.Tpo src/tests/cmocka/$(DEPDIR)/dyndns_tests-test_dyndns.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_dyndns.c' object='src/tests/cmocka/dyndns_tests-test_dyndns.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/dyndns_tests-test_dyndns.o `test -f 'src/tests/cmocka/test_dyndns.c' || echo '$(srcdir)/'`src/tests/cmocka/test_dyndns.c src/tests/cmocka/dyndns_tests-test_dyndns.obj: src/tests/cmocka/test_dyndns.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/dyndns_tests-test_dyndns.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/dyndns_tests-test_dyndns.Tpo -c -o src/tests/cmocka/dyndns_tests-test_dyndns.obj `if test -f 'src/tests/cmocka/test_dyndns.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_dyndns.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_dyndns.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/dyndns_tests-test_dyndns.Tpo src/tests/cmocka/$(DEPDIR)/dyndns_tests-test_dyndns.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_dyndns.c' object='src/tests/cmocka/dyndns_tests-test_dyndns.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/dyndns_tests-test_dyndns.obj `if test -f 'src/tests/cmocka/test_dyndns.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_dyndns.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_dyndns.c'; fi` src/providers/dyndns_tests-data_provider_opts.o: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -MT src/providers/dyndns_tests-data_provider_opts.o -MD -MP -MF src/providers/$(DEPDIR)/dyndns_tests-data_provider_opts.Tpo -c -o src/providers/dyndns_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/dyndns_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/dyndns_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/dyndns_tests-data_provider_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -c -o src/providers/dyndns_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c src/providers/dyndns_tests-data_provider_opts.obj: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -MT src/providers/dyndns_tests-data_provider_opts.obj -MD -MP -MF src/providers/$(DEPDIR)/dyndns_tests-data_provider_opts.Tpo -c -o src/providers/dyndns_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/dyndns_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/dyndns_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/dyndns_tests-data_provider_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dyndns_tests_CFLAGS) $(CFLAGS) -c -o src/providers/dyndns_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` src/tests/fail_over_tests-fail_over-tests.o: src/tests/fail_over-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -MT src/tests/fail_over_tests-fail_over-tests.o -MD -MP -MF src/tests/$(DEPDIR)/fail_over_tests-fail_over-tests.Tpo -c -o src/tests/fail_over_tests-fail_over-tests.o `test -f 'src/tests/fail_over-tests.c' || echo '$(srcdir)/'`src/tests/fail_over-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/fail_over_tests-fail_over-tests.Tpo src/tests/$(DEPDIR)/fail_over_tests-fail_over-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/fail_over-tests.c' object='src/tests/fail_over_tests-fail_over-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -c -o src/tests/fail_over_tests-fail_over-tests.o `test -f 'src/tests/fail_over-tests.c' || echo '$(srcdir)/'`src/tests/fail_over-tests.c src/tests/fail_over_tests-fail_over-tests.obj: src/tests/fail_over-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -MT src/tests/fail_over_tests-fail_over-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/fail_over_tests-fail_over-tests.Tpo -c -o src/tests/fail_over_tests-fail_over-tests.obj `if test -f 'src/tests/fail_over-tests.c'; then $(CYGPATH_W) 'src/tests/fail_over-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/fail_over-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/fail_over_tests-fail_over-tests.Tpo src/tests/$(DEPDIR)/fail_over_tests-fail_over-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/fail_over-tests.c' object='src/tests/fail_over_tests-fail_over-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -c -o src/tests/fail_over_tests-fail_over-tests.obj `if test -f 'src/tests/fail_over-tests.c'; then $(CYGPATH_W) 'src/tests/fail_over-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/fail_over-tests.c'; fi` src/providers/fail_over_tests-fail_over.o: src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -MT src/providers/fail_over_tests-fail_over.o -MD -MP -MF src/providers/$(DEPDIR)/fail_over_tests-fail_over.Tpo -c -o src/providers/fail_over_tests-fail_over.o `test -f 'src/providers/fail_over.c' || echo '$(srcdir)/'`src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/fail_over_tests-fail_over.Tpo src/providers/$(DEPDIR)/fail_over_tests-fail_over.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over.c' object='src/providers/fail_over_tests-fail_over.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -c -o src/providers/fail_over_tests-fail_over.o `test -f 'src/providers/fail_over.c' || echo '$(srcdir)/'`src/providers/fail_over.c src/providers/fail_over_tests-fail_over.obj: src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -MT src/providers/fail_over_tests-fail_over.obj -MD -MP -MF src/providers/$(DEPDIR)/fail_over_tests-fail_over.Tpo -c -o src/providers/fail_over_tests-fail_over.obj `if test -f 'src/providers/fail_over.c'; then $(CYGPATH_W) 'src/providers/fail_over.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/fail_over_tests-fail_over.Tpo src/providers/$(DEPDIR)/fail_over_tests-fail_over.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over.c' object='src/providers/fail_over_tests-fail_over.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -c -o src/providers/fail_over_tests-fail_over.obj `if test -f 'src/providers/fail_over.c'; then $(CYGPATH_W) 'src/providers/fail_over.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over.c'; fi` src/providers/fail_over_tests-fail_over_srv.o: src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -MT src/providers/fail_over_tests-fail_over_srv.o -MD -MP -MF src/providers/$(DEPDIR)/fail_over_tests-fail_over_srv.Tpo -c -o src/providers/fail_over_tests-fail_over_srv.o `test -f 'src/providers/fail_over_srv.c' || echo '$(srcdir)/'`src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/fail_over_tests-fail_over_srv.Tpo src/providers/$(DEPDIR)/fail_over_tests-fail_over_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over_srv.c' object='src/providers/fail_over_tests-fail_over_srv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -c -o src/providers/fail_over_tests-fail_over_srv.o `test -f 'src/providers/fail_over_srv.c' || echo '$(srcdir)/'`src/providers/fail_over_srv.c src/providers/fail_over_tests-fail_over_srv.obj: src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -MT src/providers/fail_over_tests-fail_over_srv.obj -MD -MP -MF src/providers/$(DEPDIR)/fail_over_tests-fail_over_srv.Tpo -c -o src/providers/fail_over_tests-fail_over_srv.obj `if test -f 'src/providers/fail_over_srv.c'; then $(CYGPATH_W) 'src/providers/fail_over_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over_srv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/fail_over_tests-fail_over_srv.Tpo src/providers/$(DEPDIR)/fail_over_tests-fail_over_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over_srv.c' object='src/providers/fail_over_tests-fail_over_srv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -c -o src/providers/fail_over_tests-fail_over_srv.obj `if test -f 'src/providers/fail_over_srv.c'; then $(CYGPATH_W) 'src/providers/fail_over_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over_srv.c'; fi` src/resolv/fail_over_tests-async_resolv.o: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -MT src/resolv/fail_over_tests-async_resolv.o -MD -MP -MF src/resolv/$(DEPDIR)/fail_over_tests-async_resolv.Tpo -c -o src/resolv/fail_over_tests-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/fail_over_tests-async_resolv.Tpo src/resolv/$(DEPDIR)/fail_over_tests-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/fail_over_tests-async_resolv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/fail_over_tests-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c src/resolv/fail_over_tests-async_resolv.obj: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -MT src/resolv/fail_over_tests-async_resolv.obj -MD -MP -MF src/resolv/$(DEPDIR)/fail_over_tests-async_resolv.Tpo -c -o src/resolv/fail_over_tests-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/fail_over_tests-async_resolv.Tpo src/resolv/$(DEPDIR)/fail_over_tests-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/fail_over_tests-async_resolv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/fail_over_tests-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` src/resolv/fail_over_tests-async_resolv_utils.o: src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -MT src/resolv/fail_over_tests-async_resolv_utils.o -MD -MP -MF src/resolv/$(DEPDIR)/fail_over_tests-async_resolv_utils.Tpo -c -o src/resolv/fail_over_tests-async_resolv_utils.o `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/fail_over_tests-async_resolv_utils.Tpo src/resolv/$(DEPDIR)/fail_over_tests-async_resolv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv_utils.c' object='src/resolv/fail_over_tests-async_resolv_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/fail_over_tests-async_resolv_utils.o `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c src/resolv/fail_over_tests-async_resolv_utils.obj: src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -MT src/resolv/fail_over_tests-async_resolv_utils.obj -MD -MP -MF src/resolv/$(DEPDIR)/fail_over_tests-async_resolv_utils.Tpo -c -o src/resolv/fail_over_tests-async_resolv_utils.obj `if test -f 'src/resolv/async_resolv_utils.c'; then $(CYGPATH_W) 'src/resolv/async_resolv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/fail_over_tests-async_resolv_utils.Tpo src/resolv/$(DEPDIR)/fail_over_tests-async_resolv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv_utils.c' object='src/resolv/fail_over_tests-async_resolv_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fail_over_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/fail_over_tests-async_resolv_utils.obj `if test -f 'src/resolv/async_resolv_utils.c'; then $(CYGPATH_W) 'src/resolv/async_resolv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv_utils.c'; fi` src/tests/files_tests-files-tests.o: src/tests/files-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -MT src/tests/files_tests-files-tests.o -MD -MP -MF src/tests/$(DEPDIR)/files_tests-files-tests.Tpo -c -o src/tests/files_tests-files-tests.o `test -f 'src/tests/files-tests.c' || echo '$(srcdir)/'`src/tests/files-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/files_tests-files-tests.Tpo src/tests/$(DEPDIR)/files_tests-files-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/files-tests.c' object='src/tests/files_tests-files-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -c -o src/tests/files_tests-files-tests.o `test -f 'src/tests/files-tests.c' || echo '$(srcdir)/'`src/tests/files-tests.c src/tests/files_tests-files-tests.obj: src/tests/files-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -MT src/tests/files_tests-files-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/files_tests-files-tests.Tpo -c -o src/tests/files_tests-files-tests.obj `if test -f 'src/tests/files-tests.c'; then $(CYGPATH_W) 'src/tests/files-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/files-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/files_tests-files-tests.Tpo src/tests/$(DEPDIR)/files_tests-files-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/files-tests.c' object='src/tests/files_tests-files-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -c -o src/tests/files_tests-files-tests.obj `if test -f 'src/tests/files-tests.c'; then $(CYGPATH_W) 'src/tests/files-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/files-tests.c'; fi` src/util/files_tests-check_and_open.o: src/util/check_and_open.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -MT src/util/files_tests-check_and_open.o -MD -MP -MF src/util/$(DEPDIR)/files_tests-check_and_open.Tpo -c -o src/util/files_tests-check_and_open.o `test -f 'src/util/check_and_open.c' || echo '$(srcdir)/'`src/util/check_and_open.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/files_tests-check_and_open.Tpo src/util/$(DEPDIR)/files_tests-check_and_open.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/check_and_open.c' object='src/util/files_tests-check_and_open.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -c -o src/util/files_tests-check_and_open.o `test -f 'src/util/check_and_open.c' || echo '$(srcdir)/'`src/util/check_and_open.c src/util/files_tests-check_and_open.obj: src/util/check_and_open.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -MT src/util/files_tests-check_and_open.obj -MD -MP -MF src/util/$(DEPDIR)/files_tests-check_and_open.Tpo -c -o src/util/files_tests-check_and_open.obj `if test -f 'src/util/check_and_open.c'; then $(CYGPATH_W) 'src/util/check_and_open.c'; else $(CYGPATH_W) '$(srcdir)/src/util/check_and_open.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/files_tests-check_and_open.Tpo src/util/$(DEPDIR)/files_tests-check_and_open.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/check_and_open.c' object='src/util/files_tests-check_and_open.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -c -o src/util/files_tests-check_and_open.obj `if test -f 'src/util/check_and_open.c'; then $(CYGPATH_W) 'src/util/check_and_open.c'; else $(CYGPATH_W) '$(srcdir)/src/util/check_and_open.c'; fi` src/util/files_tests-atomic_io.o: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -MT src/util/files_tests-atomic_io.o -MD -MP -MF src/util/$(DEPDIR)/files_tests-atomic_io.Tpo -c -o src/util/files_tests-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/files_tests-atomic_io.Tpo src/util/$(DEPDIR)/files_tests-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/files_tests-atomic_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -c -o src/util/files_tests-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c src/util/files_tests-atomic_io.obj: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -MT src/util/files_tests-atomic_io.obj -MD -MP -MF src/util/$(DEPDIR)/files_tests-atomic_io.Tpo -c -o src/util/files_tests-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/files_tests-atomic_io.Tpo src/util/$(DEPDIR)/files_tests-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/files_tests-atomic_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -c -o src/util/files_tests-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` src/tools/files_tests-selinux.o: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -MT src/tools/files_tests-selinux.o -MD -MP -MF src/tools/$(DEPDIR)/files_tests-selinux.Tpo -c -o src/tools/files_tests-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/files_tests-selinux.Tpo src/tools/$(DEPDIR)/files_tests-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/files_tests-selinux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -c -o src/tools/files_tests-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c src/tools/files_tests-selinux.obj: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -MT src/tools/files_tests-selinux.obj -MD -MP -MF src/tools/$(DEPDIR)/files_tests-selinux.Tpo -c -o src/tools/files_tests-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/files_tests-selinux.Tpo src/tools/$(DEPDIR)/files_tests-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/files_tests-selinux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -c -o src/tools/files_tests-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` src/tools/files_tests-files.o: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -MT src/tools/files_tests-files.o -MD -MP -MF src/tools/$(DEPDIR)/files_tests-files.Tpo -c -o src/tools/files_tests-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/files_tests-files.Tpo src/tools/$(DEPDIR)/files_tests-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/files_tests-files.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -c -o src/tools/files_tests-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c src/tools/files_tests-files.obj: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -MT src/tools/files_tests-files.obj -MD -MP -MF src/tools/$(DEPDIR)/files_tests-files.Tpo -c -o src/tools/files_tests-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/files_tests-files.Tpo src/tools/$(DEPDIR)/files_tests-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/files_tests-files.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(files_tests_CFLAGS) $(CFLAGS) -c -o src/tools/files_tests-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` src/tests/find_uid_tests-find_uid-tests.o: src/tests/find_uid-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -MT src/tests/find_uid_tests-find_uid-tests.o -MD -MP -MF src/tests/$(DEPDIR)/find_uid_tests-find_uid-tests.Tpo -c -o src/tests/find_uid_tests-find_uid-tests.o `test -f 'src/tests/find_uid-tests.c' || echo '$(srcdir)/'`src/tests/find_uid-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/find_uid_tests-find_uid-tests.Tpo src/tests/$(DEPDIR)/find_uid_tests-find_uid-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/find_uid-tests.c' object='src/tests/find_uid_tests-find_uid-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -c -o src/tests/find_uid_tests-find_uid-tests.o `test -f 'src/tests/find_uid-tests.c' || echo '$(srcdir)/'`src/tests/find_uid-tests.c src/tests/find_uid_tests-find_uid-tests.obj: src/tests/find_uid-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -MT src/tests/find_uid_tests-find_uid-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/find_uid_tests-find_uid-tests.Tpo -c -o src/tests/find_uid_tests-find_uid-tests.obj `if test -f 'src/tests/find_uid-tests.c'; then $(CYGPATH_W) 'src/tests/find_uid-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/find_uid-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/find_uid_tests-find_uid-tests.Tpo src/tests/$(DEPDIR)/find_uid_tests-find_uid-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/find_uid-tests.c' object='src/tests/find_uid_tests-find_uid-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -c -o src/tests/find_uid_tests-find_uid-tests.obj `if test -f 'src/tests/find_uid-tests.c'; then $(CYGPATH_W) 'src/tests/find_uid-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/find_uid-tests.c'; fi` src/util/find_uid_tests-find_uid.o: src/util/find_uid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -MT src/util/find_uid_tests-find_uid.o -MD -MP -MF src/util/$(DEPDIR)/find_uid_tests-find_uid.Tpo -c -o src/util/find_uid_tests-find_uid.o `test -f 'src/util/find_uid.c' || echo '$(srcdir)/'`src/util/find_uid.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/find_uid_tests-find_uid.Tpo src/util/$(DEPDIR)/find_uid_tests-find_uid.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/find_uid.c' object='src/util/find_uid_tests-find_uid.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -c -o src/util/find_uid_tests-find_uid.o `test -f 'src/util/find_uid.c' || echo '$(srcdir)/'`src/util/find_uid.c src/util/find_uid_tests-find_uid.obj: src/util/find_uid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -MT src/util/find_uid_tests-find_uid.obj -MD -MP -MF src/util/$(DEPDIR)/find_uid_tests-find_uid.Tpo -c -o src/util/find_uid_tests-find_uid.obj `if test -f 'src/util/find_uid.c'; then $(CYGPATH_W) 'src/util/find_uid.c'; else $(CYGPATH_W) '$(srcdir)/src/util/find_uid.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/find_uid_tests-find_uid.Tpo src/util/$(DEPDIR)/find_uid_tests-find_uid.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/find_uid.c' object='src/util/find_uid_tests-find_uid.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -c -o src/util/find_uid_tests-find_uid.obj `if test -f 'src/util/find_uid.c'; then $(CYGPATH_W) 'src/util/find_uid.c'; else $(CYGPATH_W) '$(srcdir)/src/util/find_uid.c'; fi` src/util/find_uid_tests-atomic_io.o: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -MT src/util/find_uid_tests-atomic_io.o -MD -MP -MF src/util/$(DEPDIR)/find_uid_tests-atomic_io.Tpo -c -o src/util/find_uid_tests-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/find_uid_tests-atomic_io.Tpo src/util/$(DEPDIR)/find_uid_tests-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/find_uid_tests-atomic_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -c -o src/util/find_uid_tests-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c src/util/find_uid_tests-atomic_io.obj: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -MT src/util/find_uid_tests-atomic_io.obj -MD -MP -MF src/util/$(DEPDIR)/find_uid_tests-atomic_io.Tpo -c -o src/util/find_uid_tests-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/find_uid_tests-atomic_io.Tpo src/util/$(DEPDIR)/find_uid_tests-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/find_uid_tests-atomic_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -c -o src/util/find_uid_tests-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` src/util/find_uid_tests-strtonum.o: src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -MT src/util/find_uid_tests-strtonum.o -MD -MP -MF src/util/$(DEPDIR)/find_uid_tests-strtonum.Tpo -c -o src/util/find_uid_tests-strtonum.o `test -f 'src/util/strtonum.c' || echo '$(srcdir)/'`src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/find_uid_tests-strtonum.Tpo src/util/$(DEPDIR)/find_uid_tests-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/strtonum.c' object='src/util/find_uid_tests-strtonum.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -c -o src/util/find_uid_tests-strtonum.o `test -f 'src/util/strtonum.c' || echo '$(srcdir)/'`src/util/strtonum.c src/util/find_uid_tests-strtonum.obj: src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -MT src/util/find_uid_tests-strtonum.obj -MD -MP -MF src/util/$(DEPDIR)/find_uid_tests-strtonum.Tpo -c -o src/util/find_uid_tests-strtonum.obj `if test -f 'src/util/strtonum.c'; then $(CYGPATH_W) 'src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/src/util/strtonum.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/find_uid_tests-strtonum.Tpo src/util/$(DEPDIR)/find_uid_tests-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/strtonum.c' object='src/util/find_uid_tests-strtonum.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(find_uid_tests_CFLAGS) $(CFLAGS) -c -o src/util/find_uid_tests-strtonum.obj `if test -f 'src/util/strtonum.c'; then $(CYGPATH_W) 'src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/src/util/strtonum.c'; fi` src/tests/cmocka/fqnames_tests-test_fqnames.o: src/tests/cmocka/test_fqnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fqnames_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/fqnames_tests-test_fqnames.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/fqnames_tests-test_fqnames.Tpo -c -o src/tests/cmocka/fqnames_tests-test_fqnames.o `test -f 'src/tests/cmocka/test_fqnames.c' || echo '$(srcdir)/'`src/tests/cmocka/test_fqnames.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/fqnames_tests-test_fqnames.Tpo src/tests/cmocka/$(DEPDIR)/fqnames_tests-test_fqnames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_fqnames.c' object='src/tests/cmocka/fqnames_tests-test_fqnames.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fqnames_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/fqnames_tests-test_fqnames.o `test -f 'src/tests/cmocka/test_fqnames.c' || echo '$(srcdir)/'`src/tests/cmocka/test_fqnames.c src/tests/cmocka/fqnames_tests-test_fqnames.obj: src/tests/cmocka/test_fqnames.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fqnames_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/fqnames_tests-test_fqnames.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/fqnames_tests-test_fqnames.Tpo -c -o src/tests/cmocka/fqnames_tests-test_fqnames.obj `if test -f 'src/tests/cmocka/test_fqnames.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_fqnames.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_fqnames.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/fqnames_tests-test_fqnames.Tpo src/tests/cmocka/$(DEPDIR)/fqnames_tests-test_fqnames.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_fqnames.c' object='src/tests/cmocka/fqnames_tests-test_fqnames.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fqnames_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/fqnames_tests-test_fqnames.obj `if test -f 'src/tests/cmocka/test_fqnames.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_fqnames.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_fqnames.c'; fi` src/providers/ad/gpo_child-ad_gpo_child.o: src/providers/ad/ad_gpo_child.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -MT src/providers/ad/gpo_child-ad_gpo_child.o -MD -MP -MF src/providers/ad/$(DEPDIR)/gpo_child-ad_gpo_child.Tpo -c -o src/providers/ad/gpo_child-ad_gpo_child.o `test -f 'src/providers/ad/ad_gpo_child.c' || echo '$(srcdir)/'`src/providers/ad/ad_gpo_child.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/gpo_child-ad_gpo_child.Tpo src/providers/ad/$(DEPDIR)/gpo_child-ad_gpo_child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_gpo_child.c' object='src/providers/ad/gpo_child-ad_gpo_child.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -c -o src/providers/ad/gpo_child-ad_gpo_child.o `test -f 'src/providers/ad/ad_gpo_child.c' || echo '$(srcdir)/'`src/providers/ad/ad_gpo_child.c src/providers/ad/gpo_child-ad_gpo_child.obj: src/providers/ad/ad_gpo_child.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -MT src/providers/ad/gpo_child-ad_gpo_child.obj -MD -MP -MF src/providers/ad/$(DEPDIR)/gpo_child-ad_gpo_child.Tpo -c -o src/providers/ad/gpo_child-ad_gpo_child.obj `if test -f 'src/providers/ad/ad_gpo_child.c'; then $(CYGPATH_W) 'src/providers/ad/ad_gpo_child.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ad/ad_gpo_child.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/gpo_child-ad_gpo_child.Tpo src/providers/ad/$(DEPDIR)/gpo_child-ad_gpo_child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_gpo_child.c' object='src/providers/ad/gpo_child-ad_gpo_child.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -c -o src/providers/ad/gpo_child-ad_gpo_child.obj `if test -f 'src/providers/ad/ad_gpo_child.c'; then $(CYGPATH_W) 'src/providers/ad/ad_gpo_child.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ad/ad_gpo_child.c'; fi` src/util/gpo_child-atomic_io.o: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -MT src/util/gpo_child-atomic_io.o -MD -MP -MF src/util/$(DEPDIR)/gpo_child-atomic_io.Tpo -c -o src/util/gpo_child-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/gpo_child-atomic_io.Tpo src/util/$(DEPDIR)/gpo_child-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/gpo_child-atomic_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -c -o src/util/gpo_child-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c src/util/gpo_child-atomic_io.obj: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -MT src/util/gpo_child-atomic_io.obj -MD -MP -MF src/util/$(DEPDIR)/gpo_child-atomic_io.Tpo -c -o src/util/gpo_child-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/gpo_child-atomic_io.Tpo src/util/$(DEPDIR)/gpo_child-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/gpo_child-atomic_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -c -o src/util/gpo_child-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` src/util/gpo_child-util.o: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -MT src/util/gpo_child-util.o -MD -MP -MF src/util/$(DEPDIR)/gpo_child-util.Tpo -c -o src/util/gpo_child-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/gpo_child-util.Tpo src/util/$(DEPDIR)/gpo_child-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/gpo_child-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -c -o src/util/gpo_child-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c src/util/gpo_child-util.obj: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -MT src/util/gpo_child-util.obj -MD -MP -MF src/util/$(DEPDIR)/gpo_child-util.Tpo -c -o src/util/gpo_child-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/gpo_child-util.Tpo src/util/$(DEPDIR)/gpo_child-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/gpo_child-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -c -o src/util/gpo_child-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` src/util/gpo_child-signal.o: src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -MT src/util/gpo_child-signal.o -MD -MP -MF src/util/$(DEPDIR)/gpo_child-signal.Tpo -c -o src/util/gpo_child-signal.o `test -f 'src/util/signal.c' || echo '$(srcdir)/'`src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/gpo_child-signal.Tpo src/util/$(DEPDIR)/gpo_child-signal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/signal.c' object='src/util/gpo_child-signal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -c -o src/util/gpo_child-signal.o `test -f 'src/util/signal.c' || echo '$(srcdir)/'`src/util/signal.c src/util/gpo_child-signal.obj: src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -MT src/util/gpo_child-signal.obj -MD -MP -MF src/util/$(DEPDIR)/gpo_child-signal.Tpo -c -o src/util/gpo_child-signal.obj `if test -f 'src/util/signal.c'; then $(CYGPATH_W) 'src/util/signal.c'; else $(CYGPATH_W) '$(srcdir)/src/util/signal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/gpo_child-signal.Tpo src/util/$(DEPDIR)/gpo_child-signal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/signal.c' object='src/util/gpo_child-signal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gpo_child_CFLAGS) $(CFLAGS) -c -o src/util/gpo_child-signal.obj `if test -f 'src/util/signal.c'; then $(CYGPATH_W) 'src/util/signal.c'; else $(CYGPATH_W) '$(srcdir)/src/util/signal.c'; fi` src/tests/cmocka/ifp_tests-common_mock_resp.o: src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/ifp_tests-common_mock_resp.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp.Tpo -c -o src/tests/cmocka/ifp_tests-common_mock_resp.o `test -f 'src/tests/cmocka/common_mock_resp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp.Tpo src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp.c' object='src/tests/cmocka/ifp_tests-common_mock_resp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/ifp_tests-common_mock_resp.o `test -f 'src/tests/cmocka/common_mock_resp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp.c src/tests/cmocka/ifp_tests-common_mock_resp.obj: src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/ifp_tests-common_mock_resp.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp.Tpo -c -o src/tests/cmocka/ifp_tests-common_mock_resp.obj `if test -f 'src/tests/cmocka/common_mock_resp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp.Tpo src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp.c' object='src/tests/cmocka/ifp_tests-common_mock_resp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/ifp_tests-common_mock_resp.obj `if test -f 'src/tests/cmocka/common_mock_resp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp.c'; fi` src/tests/cmocka/ifp_tests-common_mock_resp_dp.o: src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/ifp_tests-common_mock_resp_dp.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp_dp.Tpo -c -o src/tests/cmocka/ifp_tests-common_mock_resp_dp.o `test -f 'src/tests/cmocka/common_mock_resp_dp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp_dp.Tpo src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp_dp.c' object='src/tests/cmocka/ifp_tests-common_mock_resp_dp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/ifp_tests-common_mock_resp_dp.o `test -f 'src/tests/cmocka/common_mock_resp_dp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp_dp.c src/tests/cmocka/ifp_tests-common_mock_resp_dp.obj: src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/ifp_tests-common_mock_resp_dp.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp_dp.Tpo -c -o src/tests/cmocka/ifp_tests-common_mock_resp_dp.obj `if test -f 'src/tests/cmocka/common_mock_resp_dp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp_dp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp_dp.Tpo src/tests/cmocka/$(DEPDIR)/ifp_tests-common_mock_resp_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp_dp.c' object='src/tests/cmocka/ifp_tests-common_mock_resp_dp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/ifp_tests-common_mock_resp_dp.obj `if test -f 'src/tests/cmocka/common_mock_resp_dp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp_dp.c'; fi` src/responder/common/ifp_tests-responder_packet.o: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-responder_packet.o -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-responder_packet.Tpo -c -o src/responder/common/ifp_tests-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-responder_packet.Tpo src/responder/common/$(DEPDIR)/ifp_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/ifp_tests-responder_packet.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c src/responder/common/ifp_tests-responder_packet.obj: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-responder_packet.obj -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-responder_packet.Tpo -c -o src/responder/common/ifp_tests-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-responder_packet.Tpo src/responder/common/$(DEPDIR)/ifp_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/ifp_tests-responder_packet.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` src/responder/common/ifp_tests-responder_cmd.o: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-responder_cmd.o -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-responder_cmd.Tpo -c -o src/responder/common/ifp_tests-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-responder_cmd.Tpo src/responder/common/$(DEPDIR)/ifp_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/ifp_tests-responder_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c src/responder/common/ifp_tests-responder_cmd.obj: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-responder_cmd.obj -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-responder_cmd.Tpo -c -o src/responder/common/ifp_tests-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-responder_cmd.Tpo src/responder/common/$(DEPDIR)/ifp_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/ifp_tests-responder_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` src/responder/common/ifp_tests-negcache.o: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-negcache.o -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-negcache.Tpo -c -o src/responder/common/ifp_tests-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-negcache.Tpo src/responder/common/$(DEPDIR)/ifp_tests-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/ifp_tests-negcache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c src/responder/common/ifp_tests-negcache.obj: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-negcache.obj -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-negcache.Tpo -c -o src/responder/common/ifp_tests-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-negcache.Tpo src/responder/common/$(DEPDIR)/ifp_tests-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/ifp_tests-negcache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` src/responder/common/ifp_tests-responder_common.o: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-responder_common.o -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-responder_common.Tpo -c -o src/responder/common/ifp_tests-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-responder_common.Tpo src/responder/common/$(DEPDIR)/ifp_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/ifp_tests-responder_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c src/responder/common/ifp_tests-responder_common.obj: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-responder_common.obj -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-responder_common.Tpo -c -o src/responder/common/ifp_tests-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-responder_common.Tpo src/responder/common/$(DEPDIR)/ifp_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/ifp_tests-responder_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` src/responder/common/ifp_tests-responder_cache_req.o: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-responder_cache_req.o -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-responder_cache_req.Tpo -c -o src/responder/common/ifp_tests-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/ifp_tests-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/ifp_tests-responder_cache_req.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c src/responder/common/ifp_tests-responder_cache_req.obj: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-responder_cache_req.obj -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-responder_cache_req.Tpo -c -o src/responder/common/ifp_tests-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/ifp_tests-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/ifp_tests-responder_cache_req.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` src/tests/cmocka/ifp_tests-test_ifp.o: src/tests/cmocka/test_ifp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/ifp_tests-test_ifp.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/ifp_tests-test_ifp.Tpo -c -o src/tests/cmocka/ifp_tests-test_ifp.o `test -f 'src/tests/cmocka/test_ifp.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ifp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/ifp_tests-test_ifp.Tpo src/tests/cmocka/$(DEPDIR)/ifp_tests-test_ifp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ifp.c' object='src/tests/cmocka/ifp_tests-test_ifp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/ifp_tests-test_ifp.o `test -f 'src/tests/cmocka/test_ifp.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ifp.c src/tests/cmocka/ifp_tests-test_ifp.obj: src/tests/cmocka/test_ifp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/ifp_tests-test_ifp.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/ifp_tests-test_ifp.Tpo -c -o src/tests/cmocka/ifp_tests-test_ifp.obj `if test -f 'src/tests/cmocka/test_ifp.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ifp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ifp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/ifp_tests-test_ifp.Tpo src/tests/cmocka/$(DEPDIR)/ifp_tests-test_ifp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ifp.c' object='src/tests/cmocka/ifp_tests-test_ifp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/ifp_tests-test_ifp.obj `if test -f 'src/tests/cmocka/test_ifp.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ifp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ifp.c'; fi` src/responder/ifp/ifp_tests-ifpsrv_cmd.o: src/responder/ifp/ifpsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/ifp/ifp_tests-ifpsrv_cmd.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_cmd.Tpo -c -o src/responder/ifp/ifp_tests-ifpsrv_cmd.o `test -f 'src/responder/ifp/ifpsrv_cmd.c' || echo '$(srcdir)/'`src/responder/ifp/ifpsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_cmd.Tpo src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifpsrv_cmd.c' object='src/responder/ifp/ifp_tests-ifpsrv_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/ifp_tests-ifpsrv_cmd.o `test -f 'src/responder/ifp/ifpsrv_cmd.c' || echo '$(srcdir)/'`src/responder/ifp/ifpsrv_cmd.c src/responder/ifp/ifp_tests-ifpsrv_cmd.obj: src/responder/ifp/ifpsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/ifp/ifp_tests-ifpsrv_cmd.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_cmd.Tpo -c -o src/responder/ifp/ifp_tests-ifpsrv_cmd.obj `if test -f 'src/responder/ifp/ifpsrv_cmd.c'; then $(CYGPATH_W) 'src/responder/ifp/ifpsrv_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifpsrv_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_cmd.Tpo src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifpsrv_cmd.c' object='src/responder/ifp/ifp_tests-ifpsrv_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/ifp_tests-ifpsrv_cmd.obj `if test -f 'src/responder/ifp/ifpsrv_cmd.c'; then $(CYGPATH_W) 'src/responder/ifp/ifpsrv_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifpsrv_cmd.c'; fi` src/responder/ifp/ifp_tests-ifp_iface_generated.o: src/responder/ifp/ifp_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/ifp/ifp_tests-ifp_iface_generated.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/ifp_tests-ifp_iface_generated.Tpo -c -o src/responder/ifp/ifp_tests-ifp_iface_generated.o `test -f 'src/responder/ifp/ifp_iface_generated.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/ifp_tests-ifp_iface_generated.Tpo src/responder/ifp/$(DEPDIR)/ifp_tests-ifp_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_iface_generated.c' object='src/responder/ifp/ifp_tests-ifp_iface_generated.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/ifp_tests-ifp_iface_generated.o `test -f 'src/responder/ifp/ifp_iface_generated.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_iface_generated.c src/responder/ifp/ifp_tests-ifp_iface_generated.obj: src/responder/ifp/ifp_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/ifp/ifp_tests-ifp_iface_generated.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/ifp_tests-ifp_iface_generated.Tpo -c -o src/responder/ifp/ifp_tests-ifp_iface_generated.obj `if test -f 'src/responder/ifp/ifp_iface_generated.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_iface_generated.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/ifp_tests-ifp_iface_generated.Tpo src/responder/ifp/$(DEPDIR)/ifp_tests-ifp_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_iface_generated.c' object='src/responder/ifp/ifp_tests-ifp_iface_generated.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/ifp_tests-ifp_iface_generated.obj `if test -f 'src/responder/ifp/ifp_iface_generated.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_iface_generated.c'; fi` src/responder/ifp/ifp_tests-ifpsrv_util.o: src/responder/ifp/ifpsrv_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/ifp/ifp_tests-ifpsrv_util.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_util.Tpo -c -o src/responder/ifp/ifp_tests-ifpsrv_util.o `test -f 'src/responder/ifp/ifpsrv_util.c' || echo '$(srcdir)/'`src/responder/ifp/ifpsrv_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_util.Tpo src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifpsrv_util.c' object='src/responder/ifp/ifp_tests-ifpsrv_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/ifp_tests-ifpsrv_util.o `test -f 'src/responder/ifp/ifpsrv_util.c' || echo '$(srcdir)/'`src/responder/ifp/ifpsrv_util.c src/responder/ifp/ifp_tests-ifpsrv_util.obj: src/responder/ifp/ifpsrv_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/ifp/ifp_tests-ifpsrv_util.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_util.Tpo -c -o src/responder/ifp/ifp_tests-ifpsrv_util.obj `if test -f 'src/responder/ifp/ifpsrv_util.c'; then $(CYGPATH_W) 'src/responder/ifp/ifpsrv_util.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifpsrv_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_util.Tpo src/responder/ifp/$(DEPDIR)/ifp_tests-ifpsrv_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifpsrv_util.c' object='src/responder/ifp/ifp_tests-ifpsrv_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/ifp_tests-ifpsrv_util.obj `if test -f 'src/responder/ifp/ifpsrv_util.c'; then $(CYGPATH_W) 'src/responder/ifp/ifpsrv_util.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifpsrv_util.c'; fi` src/responder/common/ifp_tests-responder_utils.o: src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-responder_utils.o -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-responder_utils.Tpo -c -o src/responder/common/ifp_tests-responder_utils.o `test -f 'src/responder/common/responder_utils.c' || echo '$(srcdir)/'`src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-responder_utils.Tpo src/responder/common/$(DEPDIR)/ifp_tests-responder_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_utils.c' object='src/responder/common/ifp_tests-responder_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-responder_utils.o `test -f 'src/responder/common/responder_utils.c' || echo '$(srcdir)/'`src/responder/common/responder_utils.c src/responder/common/ifp_tests-responder_utils.obj: src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/ifp_tests-responder_utils.obj -MD -MP -MF src/responder/common/$(DEPDIR)/ifp_tests-responder_utils.Tpo -c -o src/responder/common/ifp_tests-responder_utils.obj `if test -f 'src/responder/common/responder_utils.c'; then $(CYGPATH_W) 'src/responder/common/responder_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/ifp_tests-responder_utils.Tpo src/responder/common/$(DEPDIR)/ifp_tests-responder_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_utils.c' object='src/responder/common/ifp_tests-responder_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ifp_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/ifp_tests-responder_utils.obj `if test -f 'src/responder/common/responder_utils.c'; then $(CYGPATH_W) 'src/responder/common/responder_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_utils.c'; fi` src/tests/ipa_hbac_tests-ipa_hbac-tests.o: src/tests/ipa_hbac-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_hbac_tests_CFLAGS) $(CFLAGS) -MT src/tests/ipa_hbac_tests-ipa_hbac-tests.o -MD -MP -MF src/tests/$(DEPDIR)/ipa_hbac_tests-ipa_hbac-tests.Tpo -c -o src/tests/ipa_hbac_tests-ipa_hbac-tests.o `test -f 'src/tests/ipa_hbac-tests.c' || echo '$(srcdir)/'`src/tests/ipa_hbac-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/ipa_hbac_tests-ipa_hbac-tests.Tpo src/tests/$(DEPDIR)/ipa_hbac_tests-ipa_hbac-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/ipa_hbac-tests.c' object='src/tests/ipa_hbac_tests-ipa_hbac-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_hbac_tests_CFLAGS) $(CFLAGS) -c -o src/tests/ipa_hbac_tests-ipa_hbac-tests.o `test -f 'src/tests/ipa_hbac-tests.c' || echo '$(srcdir)/'`src/tests/ipa_hbac-tests.c src/tests/ipa_hbac_tests-ipa_hbac-tests.obj: src/tests/ipa_hbac-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_hbac_tests_CFLAGS) $(CFLAGS) -MT src/tests/ipa_hbac_tests-ipa_hbac-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/ipa_hbac_tests-ipa_hbac-tests.Tpo -c -o src/tests/ipa_hbac_tests-ipa_hbac-tests.obj `if test -f 'src/tests/ipa_hbac-tests.c'; then $(CYGPATH_W) 'src/tests/ipa_hbac-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/ipa_hbac-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/ipa_hbac_tests-ipa_hbac-tests.Tpo src/tests/$(DEPDIR)/ipa_hbac_tests-ipa_hbac-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/ipa_hbac-tests.c' object='src/tests/ipa_hbac_tests-ipa_hbac-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_hbac_tests_CFLAGS) $(CFLAGS) -c -o src/tests/ipa_hbac_tests-ipa_hbac-tests.obj `if test -f 'src/tests/ipa_hbac-tests.c'; then $(CYGPATH_W) 'src/tests/ipa_hbac-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/ipa_hbac-tests.c'; fi` src/providers/ipa_ldap_opt_tests-data_provider_opts.o: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ipa_ldap_opt_tests-data_provider_opts.o -MD -MP -MF src/providers/$(DEPDIR)/ipa_ldap_opt_tests-data_provider_opts.Tpo -c -o src/providers/ipa_ldap_opt_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/ipa_ldap_opt_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/ipa_ldap_opt_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/ipa_ldap_opt_tests-data_provider_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ipa_ldap_opt_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c src/providers/ipa_ldap_opt_tests-data_provider_opts.obj: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ipa_ldap_opt_tests-data_provider_opts.obj -MD -MP -MF src/providers/$(DEPDIR)/ipa_ldap_opt_tests-data_provider_opts.Tpo -c -o src/providers/ipa_ldap_opt_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/ipa_ldap_opt_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/ipa_ldap_opt_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/ipa_ldap_opt_tests-data_provider_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ipa_ldap_opt_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` src/providers/ldap/ipa_ldap_opt_tests-sdap.o: src/providers/ldap/sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ipa_ldap_opt_tests-sdap.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap.Tpo -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap.o `test -f 'src/providers/ldap/sdap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap.Tpo src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap.c' object='src/providers/ldap/ipa_ldap_opt_tests-sdap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap.o `test -f 'src/providers/ldap/sdap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap.c src/providers/ldap/ipa_ldap_opt_tests-sdap.obj: src/providers/ldap/sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ipa_ldap_opt_tests-sdap.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap.Tpo -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap.obj `if test -f 'src/providers/ldap/sdap.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap.Tpo src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap.c' object='src/providers/ldap/ipa_ldap_opt_tests-sdap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap.obj `if test -f 'src/providers/ldap/sdap.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap.c'; fi` src/providers/ldap/ipa_ldap_opt_tests-sdap_range.o: src/providers/ldap/sdap_range.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ipa_ldap_opt_tests-sdap_range.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_range.Tpo -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap_range.o `test -f 'src/providers/ldap/sdap_range.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_range.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_range.Tpo src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_range.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_range.c' object='src/providers/ldap/ipa_ldap_opt_tests-sdap_range.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap_range.o `test -f 'src/providers/ldap/sdap_range.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_range.c src/providers/ldap/ipa_ldap_opt_tests-sdap_range.obj: src/providers/ldap/sdap_range.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ipa_ldap_opt_tests-sdap_range.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_range.Tpo -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap_range.obj `if test -f 'src/providers/ldap/sdap_range.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_range.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_range.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_range.Tpo src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_range.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_range.c' object='src/providers/ldap/ipa_ldap_opt_tests-sdap_range.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap_range.obj `if test -f 'src/providers/ldap/sdap_range.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_range.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_range.c'; fi` src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.o: src/providers/ldap/sdap_domain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_domain.Tpo -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.o `test -f 'src/providers/ldap/sdap_domain.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_domain.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_domain.Tpo src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_domain.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_domain.c' object='src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.o `test -f 'src/providers/ldap/sdap_domain.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_domain.c src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.obj: src/providers/ldap/sdap_domain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_domain.Tpo -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.obj `if test -f 'src/providers/ldap/sdap_domain.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_domain.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_domain.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_domain.Tpo src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-sdap_domain.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_domain.c' object='src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ipa_ldap_opt_tests-sdap_domain.obj `if test -f 'src/providers/ldap/sdap_domain.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_domain.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_domain.c'; fi` src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.o: src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-ldap_opts.Tpo -c -o src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.o `test -f 'src/providers/ldap/ldap_opts.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-ldap_opts.Tpo src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-ldap_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_opts.c' object='src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.o `test -f 'src/providers/ldap/ldap_opts.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_opts.c src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.obj: src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-ldap_opts.Tpo -c -o src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.obj `if test -f 'src/providers/ldap/ldap_opts.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-ldap_opts.Tpo src/providers/ldap/$(DEPDIR)/ipa_ldap_opt_tests-ldap_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_opts.c' object='src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ipa_ldap_opt_tests-ldap_opts.obj `if test -f 'src/providers/ldap/ldap_opts.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_opts.c'; fi` src/providers/ad/ipa_ldap_opt_tests-ad_opts.o: src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ad/ipa_ldap_opt_tests-ad_opts.o -MD -MP -MF src/providers/ad/$(DEPDIR)/ipa_ldap_opt_tests-ad_opts.Tpo -c -o src/providers/ad/ipa_ldap_opt_tests-ad_opts.o `test -f 'src/providers/ad/ad_opts.c' || echo '$(srcdir)/'`src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/ipa_ldap_opt_tests-ad_opts.Tpo src/providers/ad/$(DEPDIR)/ipa_ldap_opt_tests-ad_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_opts.c' object='src/providers/ad/ipa_ldap_opt_tests-ad_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ad/ipa_ldap_opt_tests-ad_opts.o `test -f 'src/providers/ad/ad_opts.c' || echo '$(srcdir)/'`src/providers/ad/ad_opts.c src/providers/ad/ipa_ldap_opt_tests-ad_opts.obj: src/providers/ad/ad_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ad/ipa_ldap_opt_tests-ad_opts.obj -MD -MP -MF src/providers/ad/$(DEPDIR)/ipa_ldap_opt_tests-ad_opts.Tpo -c -o src/providers/ad/ipa_ldap_opt_tests-ad_opts.obj `if test -f 'src/providers/ad/ad_opts.c'; then $(CYGPATH_W) 'src/providers/ad/ad_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ad/ad_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ad/$(DEPDIR)/ipa_ldap_opt_tests-ad_opts.Tpo src/providers/ad/$(DEPDIR)/ipa_ldap_opt_tests-ad_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ad/ad_opts.c' object='src/providers/ad/ipa_ldap_opt_tests-ad_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ad/ipa_ldap_opt_tests-ad_opts.obj `if test -f 'src/providers/ad/ad_opts.c'; then $(CYGPATH_W) 'src/providers/ad/ad_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ad/ad_opts.c'; fi` src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.o: src/providers/ipa/ipa_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.o -MD -MP -MF src/providers/ipa/$(DEPDIR)/ipa_ldap_opt_tests-ipa_opts.Tpo -c -o src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.o `test -f 'src/providers/ipa/ipa_opts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/ipa_ldap_opt_tests-ipa_opts.Tpo src/providers/ipa/$(DEPDIR)/ipa_ldap_opt_tests-ipa_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_opts.c' object='src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.o `test -f 'src/providers/ipa/ipa_opts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_opts.c src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.obj: src/providers/ipa/ipa_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.obj -MD -MP -MF src/providers/ipa/$(DEPDIR)/ipa_ldap_opt_tests-ipa_opts.Tpo -c -o src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.obj `if test -f 'src/providers/ipa/ipa_opts.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/ipa_ldap_opt_tests-ipa_opts.Tpo src/providers/ipa/$(DEPDIR)/ipa_ldap_opt_tests-ipa_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_opts.c' object='src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/ipa_ldap_opt_tests-ipa_opts.obj `if test -f 'src/providers/ipa/ipa_opts.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_opts.c'; fi` src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.o: src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/ipa_ldap_opt_tests-krb5_opts.Tpo -c -o src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.o `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/ipa_ldap_opt_tests-krb5_opts.Tpo src/providers/krb5/$(DEPDIR)/ipa_ldap_opt_tests-krb5_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_opts.c' object='src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.o `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.obj: src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/ipa_ldap_opt_tests-krb5_opts.Tpo -c -o src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.obj `if test -f 'src/providers/krb5/krb5_opts.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/ipa_ldap_opt_tests-krb5_opts.Tpo src/providers/krb5/$(DEPDIR)/ipa_ldap_opt_tests-krb5_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_opts.c' object='src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/ipa_ldap_opt_tests-krb5_opts.obj `if test -f 'src/providers/krb5/krb5_opts.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_opts.c'; fi` src/util/ipa_ldap_opt_tests-sss_ldap.o: src/util/sss_ldap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/util/ipa_ldap_opt_tests-sss_ldap.o -MD -MP -MF src/util/$(DEPDIR)/ipa_ldap_opt_tests-sss_ldap.Tpo -c -o src/util/ipa_ldap_opt_tests-sss_ldap.o `test -f 'src/util/sss_ldap.c' || echo '$(srcdir)/'`src/util/sss_ldap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ipa_ldap_opt_tests-sss_ldap.Tpo src/util/$(DEPDIR)/ipa_ldap_opt_tests-sss_ldap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_ldap.c' object='src/util/ipa_ldap_opt_tests-sss_ldap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/util/ipa_ldap_opt_tests-sss_ldap.o `test -f 'src/util/sss_ldap.c' || echo '$(srcdir)/'`src/util/sss_ldap.c src/util/ipa_ldap_opt_tests-sss_ldap.obj: src/util/sss_ldap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/util/ipa_ldap_opt_tests-sss_ldap.obj -MD -MP -MF src/util/$(DEPDIR)/ipa_ldap_opt_tests-sss_ldap.Tpo -c -o src/util/ipa_ldap_opt_tests-sss_ldap.obj `if test -f 'src/util/sss_ldap.c'; then $(CYGPATH_W) 'src/util/sss_ldap.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_ldap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ipa_ldap_opt_tests-sss_ldap.Tpo src/util/$(DEPDIR)/ipa_ldap_opt_tests-sss_ldap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_ldap.c' object='src/util/ipa_ldap_opt_tests-sss_ldap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/util/ipa_ldap_opt_tests-sss_ldap.obj `if test -f 'src/util/sss_ldap.c'; then $(CYGPATH_W) 'src/util/sss_ldap.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_ldap.c'; fi` src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.o: src/tests/ipa_ldap_opt-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.o -MD -MP -MF src/tests/$(DEPDIR)/ipa_ldap_opt_tests-ipa_ldap_opt-tests.Tpo -c -o src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.o `test -f 'src/tests/ipa_ldap_opt-tests.c' || echo '$(srcdir)/'`src/tests/ipa_ldap_opt-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/ipa_ldap_opt_tests-ipa_ldap_opt-tests.Tpo src/tests/$(DEPDIR)/ipa_ldap_opt_tests-ipa_ldap_opt-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/ipa_ldap_opt-tests.c' object='src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.o `test -f 'src/tests/ipa_ldap_opt-tests.c' || echo '$(srcdir)/'`src/tests/ipa_ldap_opt-tests.c src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.obj: src/tests/ipa_ldap_opt-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -MT src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/ipa_ldap_opt_tests-ipa_ldap_opt-tests.Tpo -c -o src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.obj `if test -f 'src/tests/ipa_ldap_opt-tests.c'; then $(CYGPATH_W) 'src/tests/ipa_ldap_opt-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/ipa_ldap_opt-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/ipa_ldap_opt_tests-ipa_ldap_opt-tests.Tpo src/tests/$(DEPDIR)/ipa_ldap_opt_tests-ipa_ldap_opt-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/ipa_ldap_opt-tests.c' object='src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ipa_ldap_opt_tests_CFLAGS) $(CFLAGS) -c -o src/tests/ipa_ldap_opt_tests-ipa_ldap_opt-tests.obj `if test -f 'src/tests/ipa_ldap_opt-tests.c'; then $(CYGPATH_W) 'src/tests/ipa_ldap_opt-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/ipa_ldap_opt-tests.c'; fi` src/tests/krb5_child_test-krb5_child-test.o: src/tests/krb5_child-test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/tests/krb5_child_test-krb5_child-test.o -MD -MP -MF src/tests/$(DEPDIR)/krb5_child_test-krb5_child-test.Tpo -c -o src/tests/krb5_child_test-krb5_child-test.o `test -f 'src/tests/krb5_child-test.c' || echo '$(srcdir)/'`src/tests/krb5_child-test.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/krb5_child_test-krb5_child-test.Tpo src/tests/$(DEPDIR)/krb5_child_test-krb5_child-test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/krb5_child-test.c' object='src/tests/krb5_child_test-krb5_child-test.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/tests/krb5_child_test-krb5_child-test.o `test -f 'src/tests/krb5_child-test.c' || echo '$(srcdir)/'`src/tests/krb5_child-test.c src/tests/krb5_child_test-krb5_child-test.obj: src/tests/krb5_child-test.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/tests/krb5_child_test-krb5_child-test.obj -MD -MP -MF src/tests/$(DEPDIR)/krb5_child_test-krb5_child-test.Tpo -c -o src/tests/krb5_child_test-krb5_child-test.obj `if test -f 'src/tests/krb5_child-test.c'; then $(CYGPATH_W) 'src/tests/krb5_child-test.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/krb5_child-test.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/krb5_child_test-krb5_child-test.Tpo src/tests/$(DEPDIR)/krb5_child_test-krb5_child-test.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/krb5_child-test.c' object='src/tests/krb5_child_test-krb5_child-test.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/tests/krb5_child_test-krb5_child-test.obj `if test -f 'src/tests/krb5_child-test.c'; then $(CYGPATH_W) 'src/tests/krb5_child-test.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/krb5_child-test.c'; fi` src/providers/krb5/krb5_child_test-krb5_utils.o: src/providers/krb5/krb5_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child_test-krb5_utils.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_utils.Tpo -c -o src/providers/krb5/krb5_child_test-krb5_utils.o `test -f 'src/providers/krb5/krb5_utils.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_utils.Tpo src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_utils.c' object='src/providers/krb5/krb5_child_test-krb5_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child_test-krb5_utils.o `test -f 'src/providers/krb5/krb5_utils.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_utils.c src/providers/krb5/krb5_child_test-krb5_utils.obj: src/providers/krb5/krb5_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child_test-krb5_utils.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_utils.Tpo -c -o src/providers/krb5/krb5_child_test-krb5_utils.obj `if test -f 'src/providers/krb5/krb5_utils.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_utils.Tpo src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_utils.c' object='src/providers/krb5/krb5_child_test-krb5_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child_test-krb5_utils.obj `if test -f 'src/providers/krb5/krb5_utils.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_utils.c'; fi` src/providers/krb5/krb5_child_test-krb5_ccache.o: src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child_test-krb5_ccache.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_ccache.Tpo -c -o src/providers/krb5/krb5_child_test-krb5_ccache.o `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_ccache.Tpo src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_ccache.c' object='src/providers/krb5/krb5_child_test-krb5_ccache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child_test-krb5_ccache.o `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c src/providers/krb5/krb5_child_test-krb5_ccache.obj: src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child_test-krb5_ccache.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_ccache.Tpo -c -o src/providers/krb5/krb5_child_test-krb5_ccache.obj `if test -f 'src/providers/krb5/krb5_ccache.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_ccache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_ccache.Tpo src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_ccache.c' object='src/providers/krb5/krb5_child_test-krb5_ccache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child_test-krb5_ccache.obj `if test -f 'src/providers/krb5/krb5_ccache.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_ccache.c'; fi` src/providers/krb5/krb5_child_test-krb5_child_handler.o: src/providers/krb5/krb5_child_handler.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child_test-krb5_child_handler.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_child_handler.Tpo -c -o src/providers/krb5/krb5_child_test-krb5_child_handler.o `test -f 'src/providers/krb5/krb5_child_handler.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_child_handler.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_child_handler.Tpo src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_child_handler.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_child_handler.c' object='src/providers/krb5/krb5_child_test-krb5_child_handler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child_test-krb5_child_handler.o `test -f 'src/providers/krb5/krb5_child_handler.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_child_handler.c src/providers/krb5/krb5_child_test-krb5_child_handler.obj: src/providers/krb5/krb5_child_handler.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child_test-krb5_child_handler.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_child_handler.Tpo -c -o src/providers/krb5/krb5_child_test-krb5_child_handler.obj `if test -f 'src/providers/krb5/krb5_child_handler.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_child_handler.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_child_handler.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_child_handler.Tpo src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_child_handler.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_child_handler.c' object='src/providers/krb5/krb5_child_test-krb5_child_handler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child_test-krb5_child_handler.obj `if test -f 'src/providers/krb5/krb5_child_handler.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_child_handler.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_child_handler.c'; fi` src/providers/krb5/krb5_child_test-krb5_common.o: src/providers/krb5/krb5_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child_test-krb5_common.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_common.Tpo -c -o src/providers/krb5/krb5_child_test-krb5_common.o `test -f 'src/providers/krb5/krb5_common.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_common.Tpo src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_common.c' object='src/providers/krb5/krb5_child_test-krb5_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child_test-krb5_common.o `test -f 'src/providers/krb5/krb5_common.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_common.c src/providers/krb5/krb5_child_test-krb5_common.obj: src/providers/krb5/krb5_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child_test-krb5_common.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_common.Tpo -c -o src/providers/krb5/krb5_child_test-krb5_common.obj `if test -f 'src/providers/krb5/krb5_common.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_common.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_common.Tpo src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_common.c' object='src/providers/krb5/krb5_child_test-krb5_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child_test-krb5_common.obj `if test -f 'src/providers/krb5/krb5_common.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_common.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_common.c'; fi` src/providers/krb5/krb5_child_test-krb5_opts.o: src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child_test-krb5_opts.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_opts.Tpo -c -o src/providers/krb5/krb5_child_test-krb5_opts.o `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_opts.Tpo src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_opts.c' object='src/providers/krb5/krb5_child_test-krb5_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child_test-krb5_opts.o `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c src/providers/krb5/krb5_child_test-krb5_opts.obj: src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child_test-krb5_opts.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_opts.Tpo -c -o src/providers/krb5/krb5_child_test-krb5_opts.obj `if test -f 'src/providers/krb5/krb5_opts.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_opts.Tpo src/providers/krb5/$(DEPDIR)/krb5_child_test-krb5_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_opts.c' object='src/providers/krb5/krb5_child_test-krb5_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child_test-krb5_opts.obj `if test -f 'src/providers/krb5/krb5_opts.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_opts.c'; fi` src/util/krb5_child_test-sss_krb5.o: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/util/krb5_child_test-sss_krb5.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child_test-sss_krb5.Tpo -c -o src/util/krb5_child_test-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child_test-sss_krb5.Tpo src/util/$(DEPDIR)/krb5_child_test-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/krb5_child_test-sss_krb5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child_test-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c src/util/krb5_child_test-sss_krb5.obj: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/util/krb5_child_test-sss_krb5.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child_test-sss_krb5.Tpo -c -o src/util/krb5_child_test-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child_test-sss_krb5.Tpo src/util/$(DEPDIR)/krb5_child_test-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/krb5_child_test-sss_krb5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child_test-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` src/providers/krb5_child_test-data_provider_fo.o: src/providers/data_provider_fo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child_test-data_provider_fo.o -MD -MP -MF src/providers/$(DEPDIR)/krb5_child_test-data_provider_fo.Tpo -c -o src/providers/krb5_child_test-data_provider_fo.o `test -f 'src/providers/data_provider_fo.c' || echo '$(srcdir)/'`src/providers/data_provider_fo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child_test-data_provider_fo.Tpo src/providers/$(DEPDIR)/krb5_child_test-data_provider_fo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_fo.c' object='src/providers/krb5_child_test-data_provider_fo.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child_test-data_provider_fo.o `test -f 'src/providers/data_provider_fo.c' || echo '$(srcdir)/'`src/providers/data_provider_fo.c src/providers/krb5_child_test-data_provider_fo.obj: src/providers/data_provider_fo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child_test-data_provider_fo.obj -MD -MP -MF src/providers/$(DEPDIR)/krb5_child_test-data_provider_fo.Tpo -c -o src/providers/krb5_child_test-data_provider_fo.obj `if test -f 'src/providers/data_provider_fo.c'; then $(CYGPATH_W) 'src/providers/data_provider_fo.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_fo.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child_test-data_provider_fo.Tpo src/providers/$(DEPDIR)/krb5_child_test-data_provider_fo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_fo.c' object='src/providers/krb5_child_test-data_provider_fo.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child_test-data_provider_fo.obj `if test -f 'src/providers/data_provider_fo.c'; then $(CYGPATH_W) 'src/providers/data_provider_fo.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_fo.c'; fi` src/providers/krb5_child_test-data_provider_opts.o: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child_test-data_provider_opts.o -MD -MP -MF src/providers/$(DEPDIR)/krb5_child_test-data_provider_opts.Tpo -c -o src/providers/krb5_child_test-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child_test-data_provider_opts.Tpo src/providers/$(DEPDIR)/krb5_child_test-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/krb5_child_test-data_provider_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child_test-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c src/providers/krb5_child_test-data_provider_opts.obj: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child_test-data_provider_opts.obj -MD -MP -MF src/providers/$(DEPDIR)/krb5_child_test-data_provider_opts.Tpo -c -o src/providers/krb5_child_test-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child_test-data_provider_opts.Tpo src/providers/$(DEPDIR)/krb5_child_test-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/krb5_child_test-data_provider_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child_test-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` src/providers/krb5_child_test-data_provider_callbacks.o: src/providers/data_provider_callbacks.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child_test-data_provider_callbacks.o -MD -MP -MF src/providers/$(DEPDIR)/krb5_child_test-data_provider_callbacks.Tpo -c -o src/providers/krb5_child_test-data_provider_callbacks.o `test -f 'src/providers/data_provider_callbacks.c' || echo '$(srcdir)/'`src/providers/data_provider_callbacks.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child_test-data_provider_callbacks.Tpo src/providers/$(DEPDIR)/krb5_child_test-data_provider_callbacks.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_callbacks.c' object='src/providers/krb5_child_test-data_provider_callbacks.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child_test-data_provider_callbacks.o `test -f 'src/providers/data_provider_callbacks.c' || echo '$(srcdir)/'`src/providers/data_provider_callbacks.c src/providers/krb5_child_test-data_provider_callbacks.obj: src/providers/data_provider_callbacks.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child_test-data_provider_callbacks.obj -MD -MP -MF src/providers/$(DEPDIR)/krb5_child_test-data_provider_callbacks.Tpo -c -o src/providers/krb5_child_test-data_provider_callbacks.obj `if test -f 'src/providers/data_provider_callbacks.c'; then $(CYGPATH_W) 'src/providers/data_provider_callbacks.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_callbacks.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child_test-data_provider_callbacks.Tpo src/providers/$(DEPDIR)/krb5_child_test-data_provider_callbacks.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_callbacks.c' object='src/providers/krb5_child_test-data_provider_callbacks.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child_test-data_provider_callbacks.obj `if test -f 'src/providers/data_provider_callbacks.c'; then $(CYGPATH_W) 'src/providers/data_provider_callbacks.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_callbacks.c'; fi` src/util/krb5_child_test-become_user.o: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/util/krb5_child_test-become_user.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child_test-become_user.Tpo -c -o src/util/krb5_child_test-become_user.o `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child_test-become_user.Tpo src/util/$(DEPDIR)/krb5_child_test-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/krb5_child_test-become_user.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child_test-become_user.o `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c src/util/krb5_child_test-become_user.obj: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/util/krb5_child_test-become_user.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child_test-become_user.Tpo -c -o src/util/krb5_child_test-become_user.obj `if test -f 'src/util/become_user.c'; then $(CYGPATH_W) 'src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/src/util/become_user.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child_test-become_user.Tpo src/util/$(DEPDIR)/krb5_child_test-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/krb5_child_test-become_user.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child_test-become_user.obj `if test -f 'src/util/become_user.c'; then $(CYGPATH_W) 'src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/src/util/become_user.c'; fi` src/providers/krb5_child_test-fail_over.o: src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child_test-fail_over.o -MD -MP -MF src/providers/$(DEPDIR)/krb5_child_test-fail_over.Tpo -c -o src/providers/krb5_child_test-fail_over.o `test -f 'src/providers/fail_over.c' || echo '$(srcdir)/'`src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child_test-fail_over.Tpo src/providers/$(DEPDIR)/krb5_child_test-fail_over.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over.c' object='src/providers/krb5_child_test-fail_over.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child_test-fail_over.o `test -f 'src/providers/fail_over.c' || echo '$(srcdir)/'`src/providers/fail_over.c src/providers/krb5_child_test-fail_over.obj: src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child_test-fail_over.obj -MD -MP -MF src/providers/$(DEPDIR)/krb5_child_test-fail_over.Tpo -c -o src/providers/krb5_child_test-fail_over.obj `if test -f 'src/providers/fail_over.c'; then $(CYGPATH_W) 'src/providers/fail_over.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child_test-fail_over.Tpo src/providers/$(DEPDIR)/krb5_child_test-fail_over.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over.c' object='src/providers/krb5_child_test-fail_over.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child_test-fail_over.obj `if test -f 'src/providers/fail_over.c'; then $(CYGPATH_W) 'src/providers/fail_over.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over.c'; fi` src/providers/krb5_child_test-fail_over_srv.o: src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child_test-fail_over_srv.o -MD -MP -MF src/providers/$(DEPDIR)/krb5_child_test-fail_over_srv.Tpo -c -o src/providers/krb5_child_test-fail_over_srv.o `test -f 'src/providers/fail_over_srv.c' || echo '$(srcdir)/'`src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child_test-fail_over_srv.Tpo src/providers/$(DEPDIR)/krb5_child_test-fail_over_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over_srv.c' object='src/providers/krb5_child_test-fail_over_srv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child_test-fail_over_srv.o `test -f 'src/providers/fail_over_srv.c' || echo '$(srcdir)/'`src/providers/fail_over_srv.c src/providers/krb5_child_test-fail_over_srv.obj: src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child_test-fail_over_srv.obj -MD -MP -MF src/providers/$(DEPDIR)/krb5_child_test-fail_over_srv.Tpo -c -o src/providers/krb5_child_test-fail_over_srv.obj `if test -f 'src/providers/fail_over_srv.c'; then $(CYGPATH_W) 'src/providers/fail_over_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over_srv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child_test-fail_over_srv.Tpo src/providers/$(DEPDIR)/krb5_child_test-fail_over_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over_srv.c' object='src/providers/krb5_child_test-fail_over_srv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child_test-fail_over_srv.obj `if test -f 'src/providers/fail_over_srv.c'; then $(CYGPATH_W) 'src/providers/fail_over_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over_srv.c'; fi` src/resolv/krb5_child_test-async_resolv.o: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/resolv/krb5_child_test-async_resolv.o -MD -MP -MF src/resolv/$(DEPDIR)/krb5_child_test-async_resolv.Tpo -c -o src/resolv/krb5_child_test-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/krb5_child_test-async_resolv.Tpo src/resolv/$(DEPDIR)/krb5_child_test-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/krb5_child_test-async_resolv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/resolv/krb5_child_test-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c src/resolv/krb5_child_test-async_resolv.obj: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/resolv/krb5_child_test-async_resolv.obj -MD -MP -MF src/resolv/$(DEPDIR)/krb5_child_test-async_resolv.Tpo -c -o src/resolv/krb5_child_test-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/krb5_child_test-async_resolv.Tpo src/resolv/$(DEPDIR)/krb5_child_test-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/krb5_child_test-async_resolv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/resolv/krb5_child_test-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` src/resolv/krb5_child_test-async_resolv_utils.o: src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/resolv/krb5_child_test-async_resolv_utils.o -MD -MP -MF src/resolv/$(DEPDIR)/krb5_child_test-async_resolv_utils.Tpo -c -o src/resolv/krb5_child_test-async_resolv_utils.o `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/krb5_child_test-async_resolv_utils.Tpo src/resolv/$(DEPDIR)/krb5_child_test-async_resolv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv_utils.c' object='src/resolv/krb5_child_test-async_resolv_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/resolv/krb5_child_test-async_resolv_utils.o `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c src/resolv/krb5_child_test-async_resolv_utils.obj: src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -MT src/resolv/krb5_child_test-async_resolv_utils.obj -MD -MP -MF src/resolv/$(DEPDIR)/krb5_child_test-async_resolv_utils.Tpo -c -o src/resolv/krb5_child_test-async_resolv_utils.obj `if test -f 'src/resolv/async_resolv_utils.c'; then $(CYGPATH_W) 'src/resolv/async_resolv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/krb5_child_test-async_resolv_utils.Tpo src/resolv/$(DEPDIR)/krb5_child_test-async_resolv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv_utils.c' object='src/resolv/krb5_child_test-async_resolv_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_test_CFLAGS) $(CFLAGS) -c -o src/resolv/krb5_child_test-async_resolv_utils.obj `if test -f 'src/resolv/async_resolv_utils.c'; then $(CYGPATH_W) 'src/resolv/async_resolv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv_utils.c'; fi` src/tests/krb5_utils_tests-krb5_utils-tests.o: src/tests/krb5_utils-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/tests/krb5_utils_tests-krb5_utils-tests.o -MD -MP -MF src/tests/$(DEPDIR)/krb5_utils_tests-krb5_utils-tests.Tpo -c -o src/tests/krb5_utils_tests-krb5_utils-tests.o `test -f 'src/tests/krb5_utils-tests.c' || echo '$(srcdir)/'`src/tests/krb5_utils-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/krb5_utils_tests-krb5_utils-tests.Tpo src/tests/$(DEPDIR)/krb5_utils_tests-krb5_utils-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/krb5_utils-tests.c' object='src/tests/krb5_utils_tests-krb5_utils-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/tests/krb5_utils_tests-krb5_utils-tests.o `test -f 'src/tests/krb5_utils-tests.c' || echo '$(srcdir)/'`src/tests/krb5_utils-tests.c src/tests/krb5_utils_tests-krb5_utils-tests.obj: src/tests/krb5_utils-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/tests/krb5_utils_tests-krb5_utils-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/krb5_utils_tests-krb5_utils-tests.Tpo -c -o src/tests/krb5_utils_tests-krb5_utils-tests.obj `if test -f 'src/tests/krb5_utils-tests.c'; then $(CYGPATH_W) 'src/tests/krb5_utils-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/krb5_utils-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/krb5_utils_tests-krb5_utils-tests.Tpo src/tests/$(DEPDIR)/krb5_utils_tests-krb5_utils-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/krb5_utils-tests.c' object='src/tests/krb5_utils_tests-krb5_utils-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/tests/krb5_utils_tests-krb5_utils-tests.obj `if test -f 'src/tests/krb5_utils-tests.c'; then $(CYGPATH_W) 'src/tests/krb5_utils-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/krb5_utils-tests.c'; fi` src/providers/krb5/krb5_utils_tests-krb5_utils.o: src/providers/krb5/krb5_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_utils_tests-krb5_utils.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_utils.Tpo -c -o src/providers/krb5/krb5_utils_tests-krb5_utils.o `test -f 'src/providers/krb5/krb5_utils.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_utils.Tpo src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_utils.c' object='src/providers/krb5/krb5_utils_tests-krb5_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_utils_tests-krb5_utils.o `test -f 'src/providers/krb5/krb5_utils.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_utils.c src/providers/krb5/krb5_utils_tests-krb5_utils.obj: src/providers/krb5/krb5_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_utils_tests-krb5_utils.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_utils.Tpo -c -o src/providers/krb5/krb5_utils_tests-krb5_utils.obj `if test -f 'src/providers/krb5/krb5_utils.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_utils.Tpo src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_utils.c' object='src/providers/krb5/krb5_utils_tests-krb5_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_utils_tests-krb5_utils.obj `if test -f 'src/providers/krb5/krb5_utils.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_utils.c'; fi` src/providers/krb5/krb5_utils_tests-krb5_ccache.o: src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_utils_tests-krb5_ccache.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_ccache.Tpo -c -o src/providers/krb5/krb5_utils_tests-krb5_ccache.o `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_ccache.Tpo src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_ccache.c' object='src/providers/krb5/krb5_utils_tests-krb5_ccache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_utils_tests-krb5_ccache.o `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c src/providers/krb5/krb5_utils_tests-krb5_ccache.obj: src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_utils_tests-krb5_ccache.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_ccache.Tpo -c -o src/providers/krb5/krb5_utils_tests-krb5_ccache.obj `if test -f 'src/providers/krb5/krb5_ccache.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_ccache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_ccache.Tpo src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_ccache.c' object='src/providers/krb5/krb5_utils_tests-krb5_ccache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_utils_tests-krb5_ccache.obj `if test -f 'src/providers/krb5/krb5_ccache.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_ccache.c'; fi` src/providers/krb5/krb5_utils_tests-krb5_common.o: src/providers/krb5/krb5_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_utils_tests-krb5_common.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_common.Tpo -c -o src/providers/krb5/krb5_utils_tests-krb5_common.o `test -f 'src/providers/krb5/krb5_common.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_common.Tpo src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_common.c' object='src/providers/krb5/krb5_utils_tests-krb5_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_utils_tests-krb5_common.o `test -f 'src/providers/krb5/krb5_common.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_common.c src/providers/krb5/krb5_utils_tests-krb5_common.obj: src/providers/krb5/krb5_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_utils_tests-krb5_common.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_common.Tpo -c -o src/providers/krb5/krb5_utils_tests-krb5_common.obj `if test -f 'src/providers/krb5/krb5_common.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_common.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_common.Tpo src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_common.c' object='src/providers/krb5/krb5_utils_tests-krb5_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_utils_tests-krb5_common.obj `if test -f 'src/providers/krb5/krb5_common.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_common.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_common.c'; fi` src/providers/krb5/krb5_utils_tests-krb5_opts.o: src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_utils_tests-krb5_opts.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_opts.Tpo -c -o src/providers/krb5/krb5_utils_tests-krb5_opts.o `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_opts.Tpo src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_opts.c' object='src/providers/krb5/krb5_utils_tests-krb5_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_utils_tests-krb5_opts.o `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c src/providers/krb5/krb5_utils_tests-krb5_opts.obj: src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_utils_tests-krb5_opts.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_opts.Tpo -c -o src/providers/krb5/krb5_utils_tests-krb5_opts.obj `if test -f 'src/providers/krb5/krb5_opts.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_opts.Tpo src/providers/krb5/$(DEPDIR)/krb5_utils_tests-krb5_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_opts.c' object='src/providers/krb5/krb5_utils_tests-krb5_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_utils_tests-krb5_opts.obj `if test -f 'src/providers/krb5/krb5_opts.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_opts.c'; fi` src/util/krb5_utils_tests-sss_krb5.o: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/util/krb5_utils_tests-sss_krb5.o -MD -MP -MF src/util/$(DEPDIR)/krb5_utils_tests-sss_krb5.Tpo -c -o src/util/krb5_utils_tests-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_utils_tests-sss_krb5.Tpo src/util/$(DEPDIR)/krb5_utils_tests-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/krb5_utils_tests-sss_krb5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/util/krb5_utils_tests-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c src/util/krb5_utils_tests-sss_krb5.obj: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/util/krb5_utils_tests-sss_krb5.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_utils_tests-sss_krb5.Tpo -c -o src/util/krb5_utils_tests-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_utils_tests-sss_krb5.Tpo src/util/$(DEPDIR)/krb5_utils_tests-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/krb5_utils_tests-sss_krb5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/util/krb5_utils_tests-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` src/providers/krb5_utils_tests-data_provider_fo.o: src/providers/data_provider_fo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5_utils_tests-data_provider_fo.o -MD -MP -MF src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_fo.Tpo -c -o src/providers/krb5_utils_tests-data_provider_fo.o `test -f 'src/providers/data_provider_fo.c' || echo '$(srcdir)/'`src/providers/data_provider_fo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_fo.Tpo src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_fo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_fo.c' object='src/providers/krb5_utils_tests-data_provider_fo.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_utils_tests-data_provider_fo.o `test -f 'src/providers/data_provider_fo.c' || echo '$(srcdir)/'`src/providers/data_provider_fo.c src/providers/krb5_utils_tests-data_provider_fo.obj: src/providers/data_provider_fo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5_utils_tests-data_provider_fo.obj -MD -MP -MF src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_fo.Tpo -c -o src/providers/krb5_utils_tests-data_provider_fo.obj `if test -f 'src/providers/data_provider_fo.c'; then $(CYGPATH_W) 'src/providers/data_provider_fo.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_fo.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_fo.Tpo src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_fo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_fo.c' object='src/providers/krb5_utils_tests-data_provider_fo.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_utils_tests-data_provider_fo.obj `if test -f 'src/providers/data_provider_fo.c'; then $(CYGPATH_W) 'src/providers/data_provider_fo.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_fo.c'; fi` src/providers/krb5_utils_tests-data_provider_opts.o: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5_utils_tests-data_provider_opts.o -MD -MP -MF src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_opts.Tpo -c -o src/providers/krb5_utils_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/krb5_utils_tests-data_provider_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_utils_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c src/providers/krb5_utils_tests-data_provider_opts.obj: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5_utils_tests-data_provider_opts.obj -MD -MP -MF src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_opts.Tpo -c -o src/providers/krb5_utils_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/krb5_utils_tests-data_provider_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_utils_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` src/providers/krb5_utils_tests-data_provider_callbacks.o: src/providers/data_provider_callbacks.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5_utils_tests-data_provider_callbacks.o -MD -MP -MF src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_callbacks.Tpo -c -o src/providers/krb5_utils_tests-data_provider_callbacks.o `test -f 'src/providers/data_provider_callbacks.c' || echo '$(srcdir)/'`src/providers/data_provider_callbacks.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_callbacks.Tpo src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_callbacks.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_callbacks.c' object='src/providers/krb5_utils_tests-data_provider_callbacks.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_utils_tests-data_provider_callbacks.o `test -f 'src/providers/data_provider_callbacks.c' || echo '$(srcdir)/'`src/providers/data_provider_callbacks.c src/providers/krb5_utils_tests-data_provider_callbacks.obj: src/providers/data_provider_callbacks.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5_utils_tests-data_provider_callbacks.obj -MD -MP -MF src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_callbacks.Tpo -c -o src/providers/krb5_utils_tests-data_provider_callbacks.obj `if test -f 'src/providers/data_provider_callbacks.c'; then $(CYGPATH_W) 'src/providers/data_provider_callbacks.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_callbacks.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_callbacks.Tpo src/providers/$(DEPDIR)/krb5_utils_tests-data_provider_callbacks.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_callbacks.c' object='src/providers/krb5_utils_tests-data_provider_callbacks.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_utils_tests-data_provider_callbacks.obj `if test -f 'src/providers/data_provider_callbacks.c'; then $(CYGPATH_W) 'src/providers/data_provider_callbacks.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_callbacks.c'; fi` src/util/krb5_utils_tests-become_user.o: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/util/krb5_utils_tests-become_user.o -MD -MP -MF src/util/$(DEPDIR)/krb5_utils_tests-become_user.Tpo -c -o src/util/krb5_utils_tests-become_user.o `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_utils_tests-become_user.Tpo src/util/$(DEPDIR)/krb5_utils_tests-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/krb5_utils_tests-become_user.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/util/krb5_utils_tests-become_user.o `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c src/util/krb5_utils_tests-become_user.obj: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/util/krb5_utils_tests-become_user.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_utils_tests-become_user.Tpo -c -o src/util/krb5_utils_tests-become_user.obj `if test -f 'src/util/become_user.c'; then $(CYGPATH_W) 'src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/src/util/become_user.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_utils_tests-become_user.Tpo src/util/$(DEPDIR)/krb5_utils_tests-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/krb5_utils_tests-become_user.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/util/krb5_utils_tests-become_user.obj `if test -f 'src/util/become_user.c'; then $(CYGPATH_W) 'src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/src/util/become_user.c'; fi` src/providers/krb5_utils_tests-fail_over.o: src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5_utils_tests-fail_over.o -MD -MP -MF src/providers/$(DEPDIR)/krb5_utils_tests-fail_over.Tpo -c -o src/providers/krb5_utils_tests-fail_over.o `test -f 'src/providers/fail_over.c' || echo '$(srcdir)/'`src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_utils_tests-fail_over.Tpo src/providers/$(DEPDIR)/krb5_utils_tests-fail_over.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over.c' object='src/providers/krb5_utils_tests-fail_over.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_utils_tests-fail_over.o `test -f 'src/providers/fail_over.c' || echo '$(srcdir)/'`src/providers/fail_over.c src/providers/krb5_utils_tests-fail_over.obj: src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5_utils_tests-fail_over.obj -MD -MP -MF src/providers/$(DEPDIR)/krb5_utils_tests-fail_over.Tpo -c -o src/providers/krb5_utils_tests-fail_over.obj `if test -f 'src/providers/fail_over.c'; then $(CYGPATH_W) 'src/providers/fail_over.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_utils_tests-fail_over.Tpo src/providers/$(DEPDIR)/krb5_utils_tests-fail_over.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over.c' object='src/providers/krb5_utils_tests-fail_over.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_utils_tests-fail_over.obj `if test -f 'src/providers/fail_over.c'; then $(CYGPATH_W) 'src/providers/fail_over.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over.c'; fi` src/providers/krb5_utils_tests-fail_over_srv.o: src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5_utils_tests-fail_over_srv.o -MD -MP -MF src/providers/$(DEPDIR)/krb5_utils_tests-fail_over_srv.Tpo -c -o src/providers/krb5_utils_tests-fail_over_srv.o `test -f 'src/providers/fail_over_srv.c' || echo '$(srcdir)/'`src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_utils_tests-fail_over_srv.Tpo src/providers/$(DEPDIR)/krb5_utils_tests-fail_over_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over_srv.c' object='src/providers/krb5_utils_tests-fail_over_srv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_utils_tests-fail_over_srv.o `test -f 'src/providers/fail_over_srv.c' || echo '$(srcdir)/'`src/providers/fail_over_srv.c src/providers/krb5_utils_tests-fail_over_srv.obj: src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/providers/krb5_utils_tests-fail_over_srv.obj -MD -MP -MF src/providers/$(DEPDIR)/krb5_utils_tests-fail_over_srv.Tpo -c -o src/providers/krb5_utils_tests-fail_over_srv.obj `if test -f 'src/providers/fail_over_srv.c'; then $(CYGPATH_W) 'src/providers/fail_over_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over_srv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_utils_tests-fail_over_srv.Tpo src/providers/$(DEPDIR)/krb5_utils_tests-fail_over_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over_srv.c' object='src/providers/krb5_utils_tests-fail_over_srv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_utils_tests-fail_over_srv.obj `if test -f 'src/providers/fail_over_srv.c'; then $(CYGPATH_W) 'src/providers/fail_over_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over_srv.c'; fi` src/resolv/krb5_utils_tests-async_resolv.o: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/resolv/krb5_utils_tests-async_resolv.o -MD -MP -MF src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv.Tpo -c -o src/resolv/krb5_utils_tests-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv.Tpo src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/krb5_utils_tests-async_resolv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/krb5_utils_tests-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c src/resolv/krb5_utils_tests-async_resolv.obj: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/resolv/krb5_utils_tests-async_resolv.obj -MD -MP -MF src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv.Tpo -c -o src/resolv/krb5_utils_tests-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv.Tpo src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/krb5_utils_tests-async_resolv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/krb5_utils_tests-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` src/resolv/krb5_utils_tests-async_resolv_utils.o: src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/resolv/krb5_utils_tests-async_resolv_utils.o -MD -MP -MF src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv_utils.Tpo -c -o src/resolv/krb5_utils_tests-async_resolv_utils.o `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv_utils.Tpo src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv_utils.c' object='src/resolv/krb5_utils_tests-async_resolv_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/krb5_utils_tests-async_resolv_utils.o `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c src/resolv/krb5_utils_tests-async_resolv_utils.obj: src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -MT src/resolv/krb5_utils_tests-async_resolv_utils.obj -MD -MP -MF src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv_utils.Tpo -c -o src/resolv/krb5_utils_tests-async_resolv_utils.obj `if test -f 'src/resolv/async_resolv_utils.c'; then $(CYGPATH_W) 'src/resolv/async_resolv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv_utils.Tpo src/resolv/$(DEPDIR)/krb5_utils_tests-async_resolv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv_utils.c' object='src/resolv/krb5_utils_tests-async_resolv_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_utils_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/krb5_utils_tests-async_resolv_utils.obj `if test -f 'src/resolv/async_resolv_utils.c'; then $(CYGPATH_W) 'src/resolv/async_resolv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv_utils.c'; fi` src/providers/krb5/krb5_child-krb5_child.o: src/providers/krb5/krb5_child.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child-krb5_child.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child-krb5_child.Tpo -c -o src/providers/krb5/krb5_child-krb5_child.o `test -f 'src/providers/krb5/krb5_child.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_child.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child-krb5_child.Tpo src/providers/krb5/$(DEPDIR)/krb5_child-krb5_child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_child.c' object='src/providers/krb5/krb5_child-krb5_child.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child-krb5_child.o `test -f 'src/providers/krb5/krb5_child.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_child.c src/providers/krb5/krb5_child-krb5_child.obj: src/providers/krb5/krb5_child.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child-krb5_child.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child-krb5_child.Tpo -c -o src/providers/krb5/krb5_child-krb5_child.obj `if test -f 'src/providers/krb5/krb5_child.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_child.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_child.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child-krb5_child.Tpo src/providers/krb5/$(DEPDIR)/krb5_child-krb5_child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_child.c' object='src/providers/krb5/krb5_child-krb5_child.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child-krb5_child.obj `if test -f 'src/providers/krb5/krb5_child.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_child.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_child.c'; fi` src/providers/krb5/krb5_child-krb5_ccache.o: src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child-krb5_ccache.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child-krb5_ccache.Tpo -c -o src/providers/krb5/krb5_child-krb5_ccache.o `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child-krb5_ccache.Tpo src/providers/krb5/$(DEPDIR)/krb5_child-krb5_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_ccache.c' object='src/providers/krb5/krb5_child-krb5_ccache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child-krb5_ccache.o `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c src/providers/krb5/krb5_child-krb5_ccache.obj: src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child-krb5_ccache.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child-krb5_ccache.Tpo -c -o src/providers/krb5/krb5_child-krb5_ccache.obj `if test -f 'src/providers/krb5/krb5_ccache.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_ccache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child-krb5_ccache.Tpo src/providers/krb5/$(DEPDIR)/krb5_child-krb5_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_ccache.c' object='src/providers/krb5/krb5_child-krb5_ccache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child-krb5_ccache.obj `if test -f 'src/providers/krb5/krb5_ccache.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_ccache.c'; fi` src/providers/krb5/krb5_child-krb5_keytab.o: src/providers/krb5/krb5_keytab.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child-krb5_keytab.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child-krb5_keytab.Tpo -c -o src/providers/krb5/krb5_child-krb5_keytab.o `test -f 'src/providers/krb5/krb5_keytab.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_keytab.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child-krb5_keytab.Tpo src/providers/krb5/$(DEPDIR)/krb5_child-krb5_keytab.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_keytab.c' object='src/providers/krb5/krb5_child-krb5_keytab.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child-krb5_keytab.o `test -f 'src/providers/krb5/krb5_keytab.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_keytab.c src/providers/krb5/krb5_child-krb5_keytab.obj: src/providers/krb5/krb5_keytab.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/providers/krb5/krb5_child-krb5_keytab.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/krb5_child-krb5_keytab.Tpo -c -o src/providers/krb5/krb5_child-krb5_keytab.obj `if test -f 'src/providers/krb5/krb5_keytab.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_keytab.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_keytab.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/krb5_child-krb5_keytab.Tpo src/providers/krb5/$(DEPDIR)/krb5_child-krb5_keytab.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_keytab.c' object='src/providers/krb5/krb5_child-krb5_keytab.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/krb5_child-krb5_keytab.obj `if test -f 'src/providers/krb5/krb5_keytab.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_keytab.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_keytab.c'; fi` src/providers/krb5_child-dp_pam_data_util.o: src/providers/dp_pam_data_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child-dp_pam_data_util.o -MD -MP -MF src/providers/$(DEPDIR)/krb5_child-dp_pam_data_util.Tpo -c -o src/providers/krb5_child-dp_pam_data_util.o `test -f 'src/providers/dp_pam_data_util.c' || echo '$(srcdir)/'`src/providers/dp_pam_data_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child-dp_pam_data_util.Tpo src/providers/$(DEPDIR)/krb5_child-dp_pam_data_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/dp_pam_data_util.c' object='src/providers/krb5_child-dp_pam_data_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child-dp_pam_data_util.o `test -f 'src/providers/dp_pam_data_util.c' || echo '$(srcdir)/'`src/providers/dp_pam_data_util.c src/providers/krb5_child-dp_pam_data_util.obj: src/providers/dp_pam_data_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/providers/krb5_child-dp_pam_data_util.obj -MD -MP -MF src/providers/$(DEPDIR)/krb5_child-dp_pam_data_util.Tpo -c -o src/providers/krb5_child-dp_pam_data_util.obj `if test -f 'src/providers/dp_pam_data_util.c'; then $(CYGPATH_W) 'src/providers/dp_pam_data_util.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/dp_pam_data_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/krb5_child-dp_pam_data_util.Tpo src/providers/$(DEPDIR)/krb5_child-dp_pam_data_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/dp_pam_data_util.c' object='src/providers/krb5_child-dp_pam_data_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/providers/krb5_child-dp_pam_data_util.obj `if test -f 'src/providers/dp_pam_data_util.c'; then $(CYGPATH_W) 'src/providers/dp_pam_data_util.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/dp_pam_data_util.c'; fi` src/util/krb5_child-user_info_msg.o: src/util/user_info_msg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-user_info_msg.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child-user_info_msg.Tpo -c -o src/util/krb5_child-user_info_msg.o `test -f 'src/util/user_info_msg.c' || echo '$(srcdir)/'`src/util/user_info_msg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-user_info_msg.Tpo src/util/$(DEPDIR)/krb5_child-user_info_msg.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/user_info_msg.c' object='src/util/krb5_child-user_info_msg.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-user_info_msg.o `test -f 'src/util/user_info_msg.c' || echo '$(srcdir)/'`src/util/user_info_msg.c src/util/krb5_child-user_info_msg.obj: src/util/user_info_msg.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-user_info_msg.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child-user_info_msg.Tpo -c -o src/util/krb5_child-user_info_msg.obj `if test -f 'src/util/user_info_msg.c'; then $(CYGPATH_W) 'src/util/user_info_msg.c'; else $(CYGPATH_W) '$(srcdir)/src/util/user_info_msg.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-user_info_msg.Tpo src/util/$(DEPDIR)/krb5_child-user_info_msg.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/user_info_msg.c' object='src/util/krb5_child-user_info_msg.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-user_info_msg.obj `if test -f 'src/util/user_info_msg.c'; then $(CYGPATH_W) 'src/util/user_info_msg.c'; else $(CYGPATH_W) '$(srcdir)/src/util/user_info_msg.c'; fi` src/util/krb5_child-sss_krb5.o: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-sss_krb5.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child-sss_krb5.Tpo -c -o src/util/krb5_child-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-sss_krb5.Tpo src/util/$(DEPDIR)/krb5_child-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/krb5_child-sss_krb5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c src/util/krb5_child-sss_krb5.obj: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-sss_krb5.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child-sss_krb5.Tpo -c -o src/util/krb5_child-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-sss_krb5.Tpo src/util/$(DEPDIR)/krb5_child-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/krb5_child-sss_krb5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` src/util/krb5_child-find_uid.o: src/util/find_uid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-find_uid.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child-find_uid.Tpo -c -o src/util/krb5_child-find_uid.o `test -f 'src/util/find_uid.c' || echo '$(srcdir)/'`src/util/find_uid.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-find_uid.Tpo src/util/$(DEPDIR)/krb5_child-find_uid.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/find_uid.c' object='src/util/krb5_child-find_uid.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-find_uid.o `test -f 'src/util/find_uid.c' || echo '$(srcdir)/'`src/util/find_uid.c src/util/krb5_child-find_uid.obj: src/util/find_uid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-find_uid.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child-find_uid.Tpo -c -o src/util/krb5_child-find_uid.obj `if test -f 'src/util/find_uid.c'; then $(CYGPATH_W) 'src/util/find_uid.c'; else $(CYGPATH_W) '$(srcdir)/src/util/find_uid.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-find_uid.Tpo src/util/$(DEPDIR)/krb5_child-find_uid.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/find_uid.c' object='src/util/krb5_child-find_uid.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-find_uid.obj `if test -f 'src/util/find_uid.c'; then $(CYGPATH_W) 'src/util/find_uid.c'; else $(CYGPATH_W) '$(srcdir)/src/util/find_uid.c'; fi` src/util/krb5_child-atomic_io.o: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-atomic_io.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child-atomic_io.Tpo -c -o src/util/krb5_child-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-atomic_io.Tpo src/util/$(DEPDIR)/krb5_child-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/krb5_child-atomic_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c src/util/krb5_child-atomic_io.obj: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-atomic_io.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child-atomic_io.Tpo -c -o src/util/krb5_child-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-atomic_io.Tpo src/util/$(DEPDIR)/krb5_child-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/krb5_child-atomic_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` src/util/krb5_child-authtok.o: src/util/authtok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-authtok.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child-authtok.Tpo -c -o src/util/krb5_child-authtok.o `test -f 'src/util/authtok.c' || echo '$(srcdir)/'`src/util/authtok.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-authtok.Tpo src/util/$(DEPDIR)/krb5_child-authtok.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok.c' object='src/util/krb5_child-authtok.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-authtok.o `test -f 'src/util/authtok.c' || echo '$(srcdir)/'`src/util/authtok.c src/util/krb5_child-authtok.obj: src/util/authtok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-authtok.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child-authtok.Tpo -c -o src/util/krb5_child-authtok.obj `if test -f 'src/util/authtok.c'; then $(CYGPATH_W) 'src/util/authtok.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-authtok.Tpo src/util/$(DEPDIR)/krb5_child-authtok.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok.c' object='src/util/krb5_child-authtok.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-authtok.obj `if test -f 'src/util/authtok.c'; then $(CYGPATH_W) 'src/util/authtok.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok.c'; fi` src/util/krb5_child-authtok-utils.o: src/util/authtok-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-authtok-utils.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child-authtok-utils.Tpo -c -o src/util/krb5_child-authtok-utils.o `test -f 'src/util/authtok-utils.c' || echo '$(srcdir)/'`src/util/authtok-utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-authtok-utils.Tpo src/util/$(DEPDIR)/krb5_child-authtok-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok-utils.c' object='src/util/krb5_child-authtok-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-authtok-utils.o `test -f 'src/util/authtok-utils.c' || echo '$(srcdir)/'`src/util/authtok-utils.c src/util/krb5_child-authtok-utils.obj: src/util/authtok-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-authtok-utils.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child-authtok-utils.Tpo -c -o src/util/krb5_child-authtok-utils.obj `if test -f 'src/util/authtok-utils.c'; then $(CYGPATH_W) 'src/util/authtok-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok-utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-authtok-utils.Tpo src/util/$(DEPDIR)/krb5_child-authtok-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok-utils.c' object='src/util/krb5_child-authtok-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-authtok-utils.obj `if test -f 'src/util/authtok-utils.c'; then $(CYGPATH_W) 'src/util/authtok-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok-utils.c'; fi` src/util/krb5_child-util.o: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-util.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child-util.Tpo -c -o src/util/krb5_child-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-util.Tpo src/util/$(DEPDIR)/krb5_child-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/krb5_child-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c src/util/krb5_child-util.obj: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-util.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child-util.Tpo -c -o src/util/krb5_child-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-util.Tpo src/util/$(DEPDIR)/krb5_child-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/krb5_child-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` src/util/krb5_child-signal.o: src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-signal.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child-signal.Tpo -c -o src/util/krb5_child-signal.o `test -f 'src/util/signal.c' || echo '$(srcdir)/'`src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-signal.Tpo src/util/$(DEPDIR)/krb5_child-signal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/signal.c' object='src/util/krb5_child-signal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-signal.o `test -f 'src/util/signal.c' || echo '$(srcdir)/'`src/util/signal.c src/util/krb5_child-signal.obj: src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-signal.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child-signal.Tpo -c -o src/util/krb5_child-signal.obj `if test -f 'src/util/signal.c'; then $(CYGPATH_W) 'src/util/signal.c'; else $(CYGPATH_W) '$(srcdir)/src/util/signal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-signal.Tpo src/util/$(DEPDIR)/krb5_child-signal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/signal.c' object='src/util/krb5_child-signal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-signal.obj `if test -f 'src/util/signal.c'; then $(CYGPATH_W) 'src/util/signal.c'; else $(CYGPATH_W) '$(srcdir)/src/util/signal.c'; fi` src/util/krb5_child-strtonum.o: src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-strtonum.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child-strtonum.Tpo -c -o src/util/krb5_child-strtonum.o `test -f 'src/util/strtonum.c' || echo '$(srcdir)/'`src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-strtonum.Tpo src/util/$(DEPDIR)/krb5_child-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/strtonum.c' object='src/util/krb5_child-strtonum.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-strtonum.o `test -f 'src/util/strtonum.c' || echo '$(srcdir)/'`src/util/strtonum.c src/util/krb5_child-strtonum.obj: src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-strtonum.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child-strtonum.Tpo -c -o src/util/krb5_child-strtonum.obj `if test -f 'src/util/strtonum.c'; then $(CYGPATH_W) 'src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/src/util/strtonum.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-strtonum.Tpo src/util/$(DEPDIR)/krb5_child-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/strtonum.c' object='src/util/krb5_child-strtonum.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-strtonum.obj `if test -f 'src/util/strtonum.c'; then $(CYGPATH_W) 'src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/src/util/strtonum.c'; fi` src/util/krb5_child-become_user.o: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-become_user.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child-become_user.Tpo -c -o src/util/krb5_child-become_user.o `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-become_user.Tpo src/util/$(DEPDIR)/krb5_child-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/krb5_child-become_user.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-become_user.o `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c src/util/krb5_child-become_user.obj: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-become_user.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child-become_user.Tpo -c -o src/util/krb5_child-become_user.obj `if test -f 'src/util/become_user.c'; then $(CYGPATH_W) 'src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/src/util/become_user.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-become_user.Tpo src/util/$(DEPDIR)/krb5_child-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/krb5_child-become_user.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-become_user.obj `if test -f 'src/util/become_user.c'; then $(CYGPATH_W) 'src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/src/util/become_user.c'; fi` src/util/krb5_child-util_errors.o: src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-util_errors.o -MD -MP -MF src/util/$(DEPDIR)/krb5_child-util_errors.Tpo -c -o src/util/krb5_child-util_errors.o `test -f 'src/util/util_errors.c' || echo '$(srcdir)/'`src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-util_errors.Tpo src/util/$(DEPDIR)/krb5_child-util_errors.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util_errors.c' object='src/util/krb5_child-util_errors.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-util_errors.o `test -f 'src/util/util_errors.c' || echo '$(srcdir)/'`src/util/util_errors.c src/util/krb5_child-util_errors.obj: src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/util/krb5_child-util_errors.obj -MD -MP -MF src/util/$(DEPDIR)/krb5_child-util_errors.Tpo -c -o src/util/krb5_child-util_errors.obj `if test -f 'src/util/util_errors.c'; then $(CYGPATH_W) 'src/util/util_errors.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util_errors.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/krb5_child-util_errors.Tpo src/util/$(DEPDIR)/krb5_child-util_errors.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util_errors.c' object='src/util/krb5_child-util_errors.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/util/krb5_child-util_errors.obj `if test -f 'src/util/util_errors.c'; then $(CYGPATH_W) 'src/util/util_errors.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util_errors.c'; fi` src/sss_client/krb5_child-common.o: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/sss_client/krb5_child-common.o -MD -MP -MF src/sss_client/$(DEPDIR)/krb5_child-common.Tpo -c -o src/sss_client/krb5_child-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/krb5_child-common.Tpo src/sss_client/$(DEPDIR)/krb5_child-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/krb5_child-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/sss_client/krb5_child-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/krb5_child-common.obj: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -MT src/sss_client/krb5_child-common.obj -MD -MP -MF src/sss_client/$(DEPDIR)/krb5_child-common.Tpo -c -o src/sss_client/krb5_child-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/krb5_child-common.Tpo src/sss_client/$(DEPDIR)/krb5_child-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/krb5_child-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(krb5_child_CFLAGS) $(CFLAGS) -c -o src/sss_client/krb5_child-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` src/providers/ldap/ldap_child-ldap_child.o: src/providers/ldap/ldap_child.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ldap_child-ldap_child.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/ldap_child-ldap_child.Tpo -c -o src/providers/ldap/ldap_child-ldap_child.o `test -f 'src/providers/ldap/ldap_child.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_child.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ldap_child-ldap_child.Tpo src/providers/ldap/$(DEPDIR)/ldap_child-ldap_child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_child.c' object='src/providers/ldap/ldap_child-ldap_child.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ldap_child-ldap_child.o `test -f 'src/providers/ldap/ldap_child.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_child.c src/providers/ldap/ldap_child-ldap_child.obj: src/providers/ldap/ldap_child.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/providers/ldap/ldap_child-ldap_child.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/ldap_child-ldap_child.Tpo -c -o src/providers/ldap/ldap_child-ldap_child.obj `if test -f 'src/providers/ldap/ldap_child.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_child.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_child.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/ldap_child-ldap_child.Tpo src/providers/ldap/$(DEPDIR)/ldap_child-ldap_child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_child.c' object='src/providers/ldap/ldap_child-ldap_child.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/ldap_child-ldap_child.obj `if test -f 'src/providers/ldap/ldap_child.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_child.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_child.c'; fi` src/providers/krb5/ldap_child-krb5_keytab.o: src/providers/krb5/krb5_keytab.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/providers/krb5/ldap_child-krb5_keytab.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/ldap_child-krb5_keytab.Tpo -c -o src/providers/krb5/ldap_child-krb5_keytab.o `test -f 'src/providers/krb5/krb5_keytab.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_keytab.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/ldap_child-krb5_keytab.Tpo src/providers/krb5/$(DEPDIR)/ldap_child-krb5_keytab.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_keytab.c' object='src/providers/krb5/ldap_child-krb5_keytab.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/ldap_child-krb5_keytab.o `test -f 'src/providers/krb5/krb5_keytab.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_keytab.c src/providers/krb5/ldap_child-krb5_keytab.obj: src/providers/krb5/krb5_keytab.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/providers/krb5/ldap_child-krb5_keytab.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/ldap_child-krb5_keytab.Tpo -c -o src/providers/krb5/ldap_child-krb5_keytab.obj `if test -f 'src/providers/krb5/krb5_keytab.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_keytab.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_keytab.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/ldap_child-krb5_keytab.Tpo src/providers/krb5/$(DEPDIR)/ldap_child-krb5_keytab.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_keytab.c' object='src/providers/krb5/ldap_child-krb5_keytab.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/ldap_child-krb5_keytab.obj `if test -f 'src/providers/krb5/krb5_keytab.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_keytab.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_keytab.c'; fi` src/util/ldap_child-sss_krb5.o: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-sss_krb5.o -MD -MP -MF src/util/$(DEPDIR)/ldap_child-sss_krb5.Tpo -c -o src/util/ldap_child-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-sss_krb5.Tpo src/util/$(DEPDIR)/ldap_child-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/ldap_child-sss_krb5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c src/util/ldap_child-sss_krb5.obj: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-sss_krb5.obj -MD -MP -MF src/util/$(DEPDIR)/ldap_child-sss_krb5.Tpo -c -o src/util/ldap_child-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-sss_krb5.Tpo src/util/$(DEPDIR)/ldap_child-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/ldap_child-sss_krb5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` src/util/ldap_child-atomic_io.o: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-atomic_io.o -MD -MP -MF src/util/$(DEPDIR)/ldap_child-atomic_io.Tpo -c -o src/util/ldap_child-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-atomic_io.Tpo src/util/$(DEPDIR)/ldap_child-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/ldap_child-atomic_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c src/util/ldap_child-atomic_io.obj: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-atomic_io.obj -MD -MP -MF src/util/$(DEPDIR)/ldap_child-atomic_io.Tpo -c -o src/util/ldap_child-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-atomic_io.Tpo src/util/$(DEPDIR)/ldap_child-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/ldap_child-atomic_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` src/util/ldap_child-authtok.o: src/util/authtok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-authtok.o -MD -MP -MF src/util/$(DEPDIR)/ldap_child-authtok.Tpo -c -o src/util/ldap_child-authtok.o `test -f 'src/util/authtok.c' || echo '$(srcdir)/'`src/util/authtok.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-authtok.Tpo src/util/$(DEPDIR)/ldap_child-authtok.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok.c' object='src/util/ldap_child-authtok.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-authtok.o `test -f 'src/util/authtok.c' || echo '$(srcdir)/'`src/util/authtok.c src/util/ldap_child-authtok.obj: src/util/authtok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-authtok.obj -MD -MP -MF src/util/$(DEPDIR)/ldap_child-authtok.Tpo -c -o src/util/ldap_child-authtok.obj `if test -f 'src/util/authtok.c'; then $(CYGPATH_W) 'src/util/authtok.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-authtok.Tpo src/util/$(DEPDIR)/ldap_child-authtok.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok.c' object='src/util/ldap_child-authtok.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-authtok.obj `if test -f 'src/util/authtok.c'; then $(CYGPATH_W) 'src/util/authtok.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok.c'; fi` src/util/ldap_child-authtok-utils.o: src/util/authtok-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-authtok-utils.o -MD -MP -MF src/util/$(DEPDIR)/ldap_child-authtok-utils.Tpo -c -o src/util/ldap_child-authtok-utils.o `test -f 'src/util/authtok-utils.c' || echo '$(srcdir)/'`src/util/authtok-utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-authtok-utils.Tpo src/util/$(DEPDIR)/ldap_child-authtok-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok-utils.c' object='src/util/ldap_child-authtok-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-authtok-utils.o `test -f 'src/util/authtok-utils.c' || echo '$(srcdir)/'`src/util/authtok-utils.c src/util/ldap_child-authtok-utils.obj: src/util/authtok-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-authtok-utils.obj -MD -MP -MF src/util/$(DEPDIR)/ldap_child-authtok-utils.Tpo -c -o src/util/ldap_child-authtok-utils.obj `if test -f 'src/util/authtok-utils.c'; then $(CYGPATH_W) 'src/util/authtok-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok-utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-authtok-utils.Tpo src/util/$(DEPDIR)/ldap_child-authtok-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok-utils.c' object='src/util/ldap_child-authtok-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-authtok-utils.obj `if test -f 'src/util/authtok-utils.c'; then $(CYGPATH_W) 'src/util/authtok-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok-utils.c'; fi` src/util/ldap_child-util.o: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-util.o -MD -MP -MF src/util/$(DEPDIR)/ldap_child-util.Tpo -c -o src/util/ldap_child-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-util.Tpo src/util/$(DEPDIR)/ldap_child-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/ldap_child-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c src/util/ldap_child-util.obj: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-util.obj -MD -MP -MF src/util/$(DEPDIR)/ldap_child-util.Tpo -c -o src/util/ldap_child-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-util.Tpo src/util/$(DEPDIR)/ldap_child-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/ldap_child-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` src/util/ldap_child-signal.o: src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-signal.o -MD -MP -MF src/util/$(DEPDIR)/ldap_child-signal.Tpo -c -o src/util/ldap_child-signal.o `test -f 'src/util/signal.c' || echo '$(srcdir)/'`src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-signal.Tpo src/util/$(DEPDIR)/ldap_child-signal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/signal.c' object='src/util/ldap_child-signal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-signal.o `test -f 'src/util/signal.c' || echo '$(srcdir)/'`src/util/signal.c src/util/ldap_child-signal.obj: src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-signal.obj -MD -MP -MF src/util/$(DEPDIR)/ldap_child-signal.Tpo -c -o src/util/ldap_child-signal.obj `if test -f 'src/util/signal.c'; then $(CYGPATH_W) 'src/util/signal.c'; else $(CYGPATH_W) '$(srcdir)/src/util/signal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-signal.Tpo src/util/$(DEPDIR)/ldap_child-signal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/signal.c' object='src/util/ldap_child-signal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-signal.obj `if test -f 'src/util/signal.c'; then $(CYGPATH_W) 'src/util/signal.c'; else $(CYGPATH_W) '$(srcdir)/src/util/signal.c'; fi` src/util/ldap_child-become_user.o: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-become_user.o -MD -MP -MF src/util/$(DEPDIR)/ldap_child-become_user.Tpo -c -o src/util/ldap_child-become_user.o `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-become_user.Tpo src/util/$(DEPDIR)/ldap_child-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/ldap_child-become_user.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-become_user.o `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c src/util/ldap_child-become_user.obj: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -MT src/util/ldap_child-become_user.obj -MD -MP -MF src/util/$(DEPDIR)/ldap_child-become_user.Tpo -c -o src/util/ldap_child-become_user.obj `if test -f 'src/util/become_user.c'; then $(CYGPATH_W) 'src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/src/util/become_user.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/ldap_child-become_user.Tpo src/util/$(DEPDIR)/ldap_child-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/ldap_child-become_user.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ldap_child_CFLAGS) $(CFLAGS) -c -o src/util/ldap_child-become_user.obj `if test -f 'src/util/become_user.c'; then $(CYGPATH_W) 'src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/src/util/become_user.c'; fi` src/util/nestedgroups_tests-sss_ldap.o: src/util/sss_ldap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/util/nestedgroups_tests-sss_ldap.o -MD -MP -MF src/util/$(DEPDIR)/nestedgroups_tests-sss_ldap.Tpo -c -o src/util/nestedgroups_tests-sss_ldap.o `test -f 'src/util/sss_ldap.c' || echo '$(srcdir)/'`src/util/sss_ldap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/nestedgroups_tests-sss_ldap.Tpo src/util/$(DEPDIR)/nestedgroups_tests-sss_ldap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_ldap.c' object='src/util/nestedgroups_tests-sss_ldap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/util/nestedgroups_tests-sss_ldap.o `test -f 'src/util/sss_ldap.c' || echo '$(srcdir)/'`src/util/sss_ldap.c src/util/nestedgroups_tests-sss_ldap.obj: src/util/sss_ldap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/util/nestedgroups_tests-sss_ldap.obj -MD -MP -MF src/util/$(DEPDIR)/nestedgroups_tests-sss_ldap.Tpo -c -o src/util/nestedgroups_tests-sss_ldap.obj `if test -f 'src/util/sss_ldap.c'; then $(CYGPATH_W) 'src/util/sss_ldap.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_ldap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/nestedgroups_tests-sss_ldap.Tpo src/util/$(DEPDIR)/nestedgroups_tests-sss_ldap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_ldap.c' object='src/util/nestedgroups_tests-sss_ldap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/util/nestedgroups_tests-sss_ldap.obj `if test -f 'src/util/sss_ldap.c'; then $(CYGPATH_W) 'src/util/sss_ldap.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_ldap.c'; fi` src/providers/nestedgroups_tests-data_provider_opts.o: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/nestedgroups_tests-data_provider_opts.o -MD -MP -MF src/providers/$(DEPDIR)/nestedgroups_tests-data_provider_opts.Tpo -c -o src/providers/nestedgroups_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/nestedgroups_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/nestedgroups_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/nestedgroups_tests-data_provider_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/nestedgroups_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c src/providers/nestedgroups_tests-data_provider_opts.obj: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/nestedgroups_tests-data_provider_opts.obj -MD -MP -MF src/providers/$(DEPDIR)/nestedgroups_tests-data_provider_opts.Tpo -c -o src/providers/nestedgroups_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/nestedgroups_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/nestedgroups_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/nestedgroups_tests-data_provider_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/nestedgroups_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` src/providers/ldap/nestedgroups_tests-ldap_opts.o: src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-ldap_opts.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_opts.Tpo -c -o src/providers/ldap/nestedgroups_tests-ldap_opts.o `test -f 'src/providers/ldap/ldap_opts.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_opts.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_opts.c' object='src/providers/ldap/nestedgroups_tests-ldap_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-ldap_opts.o `test -f 'src/providers/ldap/ldap_opts.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_opts.c src/providers/ldap/nestedgroups_tests-ldap_opts.obj: src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-ldap_opts.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_opts.Tpo -c -o src/providers/ldap/nestedgroups_tests-ldap_opts.obj `if test -f 'src/providers/ldap/ldap_opts.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_opts.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_opts.c' object='src/providers/ldap/nestedgroups_tests-ldap_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-ldap_opts.obj `if test -f 'src/providers/ldap/ldap_opts.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_opts.c'; fi` src/providers/ldap/nestedgroups_tests-ldap_options.o: src/providers/ldap/ldap_options.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-ldap_options.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_options.Tpo -c -o src/providers/ldap/nestedgroups_tests-ldap_options.o `test -f 'src/providers/ldap/ldap_options.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_options.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_options.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_options.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_options.c' object='src/providers/ldap/nestedgroups_tests-ldap_options.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-ldap_options.o `test -f 'src/providers/ldap/ldap_options.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_options.c src/providers/ldap/nestedgroups_tests-ldap_options.obj: src/providers/ldap/ldap_options.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-ldap_options.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_options.Tpo -c -o src/providers/ldap/nestedgroups_tests-ldap_options.obj `if test -f 'src/providers/ldap/ldap_options.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_options.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_options.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_options.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-ldap_options.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_options.c' object='src/providers/ldap/nestedgroups_tests-ldap_options.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-ldap_options.obj `if test -f 'src/providers/ldap/ldap_options.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_options.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_options.c'; fi` src/providers/ldap/nestedgroups_tests-sdap_domain.o: src/providers/ldap/sdap_domain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_domain.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_domain.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_domain.o `test -f 'src/providers/ldap/sdap_domain.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_domain.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_domain.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_domain.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_domain.c' object='src/providers/ldap/nestedgroups_tests-sdap_domain.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_domain.o `test -f 'src/providers/ldap/sdap_domain.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_domain.c src/providers/ldap/nestedgroups_tests-sdap_domain.obj: src/providers/ldap/sdap_domain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_domain.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_domain.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_domain.obj `if test -f 'src/providers/ldap/sdap_domain.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_domain.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_domain.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_domain.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_domain.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_domain.c' object='src/providers/ldap/nestedgroups_tests-sdap_domain.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_domain.obj `if test -f 'src/providers/ldap/sdap_domain.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_domain.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_domain.c'; fi` src/providers/ldap/nestedgroups_tests-sdap.o: src/providers/ldap/sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap.o `test -f 'src/providers/ldap/sdap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap.c' object='src/providers/ldap/nestedgroups_tests-sdap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap.o `test -f 'src/providers/ldap/sdap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap.c src/providers/ldap/nestedgroups_tests-sdap.obj: src/providers/ldap/sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap.obj `if test -f 'src/providers/ldap/sdap.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap.c' object='src/providers/ldap/nestedgroups_tests-sdap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap.obj `if test -f 'src/providers/ldap/sdap.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap.c'; fi` src/providers/ldap/nestedgroups_tests-sdap_utils.o: src/providers/ldap/sdap_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_utils.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_utils.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_utils.o `test -f 'src/providers/ldap/sdap_utils.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_utils.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_utils.c' object='src/providers/ldap/nestedgroups_tests-sdap_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_utils.o `test -f 'src/providers/ldap/sdap_utils.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_utils.c src/providers/ldap/nestedgroups_tests-sdap_utils.obj: src/providers/ldap/sdap_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_utils.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_utils.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_utils.obj `if test -f 'src/providers/ldap/sdap_utils.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_utils.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_utils.c' object='src/providers/ldap/nestedgroups_tests-sdap_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_utils.obj `if test -f 'src/providers/ldap/sdap_utils.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_utils.c'; fi` src/providers/ldap/nestedgroups_tests-sdap_range.o: src/providers/ldap/sdap_range.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_range.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_range.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_range.o `test -f 'src/providers/ldap/sdap_range.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_range.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_range.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_range.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_range.c' object='src/providers/ldap/nestedgroups_tests-sdap_range.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_range.o `test -f 'src/providers/ldap/sdap_range.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_range.c src/providers/ldap/nestedgroups_tests-sdap_range.obj: src/providers/ldap/sdap_range.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_range.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_range.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_range.obj `if test -f 'src/providers/ldap/sdap_range.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_range.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_range.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_range.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_range.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_range.c' object='src/providers/ldap/nestedgroups_tests-sdap_range.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_range.obj `if test -f 'src/providers/ldap/sdap_range.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_range.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_range.c'; fi` src/tests/cmocka/nestedgroups_tests-common_mock_sdap.o: src/tests/cmocka/common_mock_sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nestedgroups_tests-common_mock_sdap.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sdap.Tpo -c -o src/tests/cmocka/nestedgroups_tests-common_mock_sdap.o `test -f 'src/tests/cmocka/common_mock_sdap.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_sdap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sdap.Tpo src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_sdap.c' object='src/tests/cmocka/nestedgroups_tests-common_mock_sdap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nestedgroups_tests-common_mock_sdap.o `test -f 'src/tests/cmocka/common_mock_sdap.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_sdap.c src/tests/cmocka/nestedgroups_tests-common_mock_sdap.obj: src/tests/cmocka/common_mock_sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nestedgroups_tests-common_mock_sdap.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sdap.Tpo -c -o src/tests/cmocka/nestedgroups_tests-common_mock_sdap.obj `if test -f 'src/tests/cmocka/common_mock_sdap.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_sdap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sdap.Tpo src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_sdap.c' object='src/tests/cmocka/nestedgroups_tests-common_mock_sdap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nestedgroups_tests-common_mock_sdap.obj `if test -f 'src/tests/cmocka/common_mock_sdap.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_sdap.c'; fi` src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.o: src/tests/cmocka/common_mock_sysdb_objects.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sysdb_objects.Tpo -c -o src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.o `test -f 'src/tests/cmocka/common_mock_sysdb_objects.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_sysdb_objects.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sysdb_objects.Tpo src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sysdb_objects.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_sysdb_objects.c' object='src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.o `test -f 'src/tests/cmocka/common_mock_sysdb_objects.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_sysdb_objects.c src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.obj: src/tests/cmocka/common_mock_sysdb_objects.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sysdb_objects.Tpo -c -o src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.obj `if test -f 'src/tests/cmocka/common_mock_sysdb_objects.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_sysdb_objects.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_sysdb_objects.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sysdb_objects.Tpo src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_sysdb_objects.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_sysdb_objects.c' object='src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nestedgroups_tests-common_mock_sysdb_objects.obj `if test -f 'src/tests/cmocka/common_mock_sysdb_objects.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_sysdb_objects.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_sysdb_objects.c'; fi` src/providers/ldap/nestedgroups_tests-sdap_idmap.o: src/providers/ldap/sdap_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_idmap.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_idmap.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_idmap.o `test -f 'src/providers/ldap/sdap_idmap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_idmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_idmap.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_idmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_idmap.c' object='src/providers/ldap/nestedgroups_tests-sdap_idmap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_idmap.o `test -f 'src/providers/ldap/sdap_idmap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_idmap.c src/providers/ldap/nestedgroups_tests-sdap_idmap.obj: src/providers/ldap/sdap_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_idmap.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_idmap.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_idmap.obj `if test -f 'src/providers/ldap/sdap_idmap.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_idmap.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_idmap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_idmap.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_idmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_idmap.c' object='src/providers/ldap/nestedgroups_tests-sdap_idmap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_idmap.obj `if test -f 'src/providers/ldap/sdap_idmap.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_idmap.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_idmap.c'; fi` src/tests/cmocka/nestedgroups_tests-test_nested_groups.o: src/tests/cmocka/test_nested_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nestedgroups_tests-test_nested_groups.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-test_nested_groups.Tpo -c -o src/tests/cmocka/nestedgroups_tests-test_nested_groups.o `test -f 'src/tests/cmocka/test_nested_groups.c' || echo '$(srcdir)/'`src/tests/cmocka/test_nested_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-test_nested_groups.Tpo src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-test_nested_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_nested_groups.c' object='src/tests/cmocka/nestedgroups_tests-test_nested_groups.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nestedgroups_tests-test_nested_groups.o `test -f 'src/tests/cmocka/test_nested_groups.c' || echo '$(srcdir)/'`src/tests/cmocka/test_nested_groups.c src/tests/cmocka/nestedgroups_tests-test_nested_groups.obj: src/tests/cmocka/test_nested_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nestedgroups_tests-test_nested_groups.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-test_nested_groups.Tpo -c -o src/tests/cmocka/nestedgroups_tests-test_nested_groups.obj `if test -f 'src/tests/cmocka/test_nested_groups.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_nested_groups.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_nested_groups.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-test_nested_groups.Tpo src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-test_nested_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_nested_groups.c' object='src/tests/cmocka/nestedgroups_tests-test_nested_groups.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nestedgroups_tests-test_nested_groups.obj `if test -f 'src/tests/cmocka/test_nested_groups.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_nested_groups.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_nested_groups.c'; fi` src/tests/cmocka/nestedgroups_tests-common_mock_be.o: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nestedgroups_tests-common_mock_be.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_be.Tpo -c -o src/tests/cmocka/nestedgroups_tests-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/nestedgroups_tests-common_mock_be.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nestedgroups_tests-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c src/tests/cmocka/nestedgroups_tests-common_mock_be.obj: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nestedgroups_tests-common_mock_be.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_be.Tpo -c -o src/tests/cmocka/nestedgroups_tests-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/nestedgroups_tests-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/nestedgroups_tests-common_mock_be.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nestedgroups_tests-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.o: src/providers/ldap/sdap_async_nested_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_async_nested_groups.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.o `test -f 'src/providers/ldap/sdap_async_nested_groups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_nested_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_async_nested_groups.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_async_nested_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_nested_groups.c' object='src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.o `test -f 'src/providers/ldap/sdap_async_nested_groups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_async_nested_groups.c src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.obj: src/providers/ldap/sdap_async_nested_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_async_nested_groups.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.obj `if test -f 'src/providers/ldap/sdap_async_nested_groups.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_async_nested_groups.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_async_nested_groups.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_async_nested_groups.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_async_nested_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_async_nested_groups.c' object='src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_async_nested_groups.obj `if test -f 'src/providers/ldap/sdap_async_nested_groups.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_async_nested_groups.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_async_nested_groups.c'; fi` src/providers/ldap/nestedgroups_tests-sdap_ad_groups.o: src/providers/ldap/sdap_ad_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_ad_groups.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_ad_groups.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_ad_groups.o `test -f 'src/providers/ldap/sdap_ad_groups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_ad_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_ad_groups.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_ad_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_ad_groups.c' object='src/providers/ldap/nestedgroups_tests-sdap_ad_groups.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_ad_groups.o `test -f 'src/providers/ldap/sdap_ad_groups.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_ad_groups.c src/providers/ldap/nestedgroups_tests-sdap_ad_groups.obj: src/providers/ldap/sdap_ad_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/nestedgroups_tests-sdap_ad_groups.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_ad_groups.Tpo -c -o src/providers/ldap/nestedgroups_tests-sdap_ad_groups.obj `if test -f 'src/providers/ldap/sdap_ad_groups.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_ad_groups.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_ad_groups.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_ad_groups.Tpo src/providers/ldap/$(DEPDIR)/nestedgroups_tests-sdap_ad_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_ad_groups.c' object='src/providers/ldap/nestedgroups_tests-sdap_ad_groups.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/nestedgroups_tests-sdap_ad_groups.obj `if test -f 'src/providers/ldap/sdap_ad_groups.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_ad_groups.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_ad_groups.c'; fi` src/providers/ipa/nestedgroups_tests-ipa_dn.o: src/providers/ipa/ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ipa/nestedgroups_tests-ipa_dn.o -MD -MP -MF src/providers/ipa/$(DEPDIR)/nestedgroups_tests-ipa_dn.Tpo -c -o src/providers/ipa/nestedgroups_tests-ipa_dn.o `test -f 'src/providers/ipa/ipa_dn.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/nestedgroups_tests-ipa_dn.Tpo src/providers/ipa/$(DEPDIR)/nestedgroups_tests-ipa_dn.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_dn.c' object='src/providers/ipa/nestedgroups_tests-ipa_dn.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/nestedgroups_tests-ipa_dn.o `test -f 'src/providers/ipa/ipa_dn.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_dn.c src/providers/ipa/nestedgroups_tests-ipa_dn.obj: src/providers/ipa/ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -MT src/providers/ipa/nestedgroups_tests-ipa_dn.obj -MD -MP -MF src/providers/ipa/$(DEPDIR)/nestedgroups_tests-ipa_dn.Tpo -c -o src/providers/ipa/nestedgroups_tests-ipa_dn.obj `if test -f 'src/providers/ipa/ipa_dn.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_dn.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_dn.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/nestedgroups_tests-ipa_dn.Tpo src/providers/ipa/$(DEPDIR)/nestedgroups_tests-ipa_dn.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_dn.c' object='src/providers/ipa/nestedgroups_tests-ipa_dn.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nestedgroups_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/nestedgroups_tests-ipa_dn.obj `if test -f 'src/providers/ipa/ipa_dn.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_dn.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_dn.c'; fi` src/tests/cmocka/nss_srv_tests-common_mock_resp.o: src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nss_srv_tests-common_mock_resp.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp.Tpo -c -o src/tests/cmocka/nss_srv_tests-common_mock_resp.o `test -f 'src/tests/cmocka/common_mock_resp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp.Tpo src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp.c' object='src/tests/cmocka/nss_srv_tests-common_mock_resp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nss_srv_tests-common_mock_resp.o `test -f 'src/tests/cmocka/common_mock_resp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp.c src/tests/cmocka/nss_srv_tests-common_mock_resp.obj: src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nss_srv_tests-common_mock_resp.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp.Tpo -c -o src/tests/cmocka/nss_srv_tests-common_mock_resp.obj `if test -f 'src/tests/cmocka/common_mock_resp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp.Tpo src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp.c' object='src/tests/cmocka/nss_srv_tests-common_mock_resp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nss_srv_tests-common_mock_resp.obj `if test -f 'src/tests/cmocka/common_mock_resp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp.c'; fi` src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.o: src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp_dp.Tpo -c -o src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.o `test -f 'src/tests/cmocka/common_mock_resp_dp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp_dp.Tpo src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp_dp.c' object='src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.o `test -f 'src/tests/cmocka/common_mock_resp_dp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp_dp.c src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.obj: src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp_dp.Tpo -c -o src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.obj `if test -f 'src/tests/cmocka/common_mock_resp_dp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp_dp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp_dp.Tpo src/tests/cmocka/$(DEPDIR)/nss_srv_tests-common_mock_resp_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp_dp.c' object='src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nss_srv_tests-common_mock_resp_dp.obj `if test -f 'src/tests/cmocka/common_mock_resp_dp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp_dp.c'; fi` src/responder/common/nss_srv_tests-responder_packet.o: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/nss_srv_tests-responder_packet.o -MD -MP -MF src/responder/common/$(DEPDIR)/nss_srv_tests-responder_packet.Tpo -c -o src/responder/common/nss_srv_tests-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/nss_srv_tests-responder_packet.Tpo src/responder/common/$(DEPDIR)/nss_srv_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/nss_srv_tests-responder_packet.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/nss_srv_tests-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c src/responder/common/nss_srv_tests-responder_packet.obj: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/nss_srv_tests-responder_packet.obj -MD -MP -MF src/responder/common/$(DEPDIR)/nss_srv_tests-responder_packet.Tpo -c -o src/responder/common/nss_srv_tests-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/nss_srv_tests-responder_packet.Tpo src/responder/common/$(DEPDIR)/nss_srv_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/nss_srv_tests-responder_packet.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/nss_srv_tests-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` src/responder/common/nss_srv_tests-responder_cmd.o: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/nss_srv_tests-responder_cmd.o -MD -MP -MF src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cmd.Tpo -c -o src/responder/common/nss_srv_tests-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cmd.Tpo src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/nss_srv_tests-responder_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/nss_srv_tests-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c src/responder/common/nss_srv_tests-responder_cmd.obj: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/nss_srv_tests-responder_cmd.obj -MD -MP -MF src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cmd.Tpo -c -o src/responder/common/nss_srv_tests-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cmd.Tpo src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/nss_srv_tests-responder_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/nss_srv_tests-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` src/responder/common/nss_srv_tests-negcache.o: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/nss_srv_tests-negcache.o -MD -MP -MF src/responder/common/$(DEPDIR)/nss_srv_tests-negcache.Tpo -c -o src/responder/common/nss_srv_tests-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/nss_srv_tests-negcache.Tpo src/responder/common/$(DEPDIR)/nss_srv_tests-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/nss_srv_tests-negcache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/nss_srv_tests-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c src/responder/common/nss_srv_tests-negcache.obj: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/nss_srv_tests-negcache.obj -MD -MP -MF src/responder/common/$(DEPDIR)/nss_srv_tests-negcache.Tpo -c -o src/responder/common/nss_srv_tests-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/nss_srv_tests-negcache.Tpo src/responder/common/$(DEPDIR)/nss_srv_tests-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/nss_srv_tests-negcache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/nss_srv_tests-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` src/responder/common/nss_srv_tests-responder_common.o: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/nss_srv_tests-responder_common.o -MD -MP -MF src/responder/common/$(DEPDIR)/nss_srv_tests-responder_common.Tpo -c -o src/responder/common/nss_srv_tests-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/nss_srv_tests-responder_common.Tpo src/responder/common/$(DEPDIR)/nss_srv_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/nss_srv_tests-responder_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/nss_srv_tests-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c src/responder/common/nss_srv_tests-responder_common.obj: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/nss_srv_tests-responder_common.obj -MD -MP -MF src/responder/common/$(DEPDIR)/nss_srv_tests-responder_common.Tpo -c -o src/responder/common/nss_srv_tests-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/nss_srv_tests-responder_common.Tpo src/responder/common/$(DEPDIR)/nss_srv_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/nss_srv_tests-responder_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/nss_srv_tests-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` src/responder/common/nss_srv_tests-responder_cache_req.o: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/nss_srv_tests-responder_cache_req.o -MD -MP -MF src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cache_req.Tpo -c -o src/responder/common/nss_srv_tests-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/nss_srv_tests-responder_cache_req.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/nss_srv_tests-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c src/responder/common/nss_srv_tests-responder_cache_req.obj: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/nss_srv_tests-responder_cache_req.obj -MD -MP -MF src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cache_req.Tpo -c -o src/responder/common/nss_srv_tests-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/nss_srv_tests-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/nss_srv_tests-responder_cache_req.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/nss_srv_tests-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` src/tests/cmocka/nss_srv_tests-test_nss_srv.o: src/tests/cmocka/test_nss_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nss_srv_tests-test_nss_srv.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nss_srv_tests-test_nss_srv.Tpo -c -o src/tests/cmocka/nss_srv_tests-test_nss_srv.o `test -f 'src/tests/cmocka/test_nss_srv.c' || echo '$(srcdir)/'`src/tests/cmocka/test_nss_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nss_srv_tests-test_nss_srv.Tpo src/tests/cmocka/$(DEPDIR)/nss_srv_tests-test_nss_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_nss_srv.c' object='src/tests/cmocka/nss_srv_tests-test_nss_srv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nss_srv_tests-test_nss_srv.o `test -f 'src/tests/cmocka/test_nss_srv.c' || echo '$(srcdir)/'`src/tests/cmocka/test_nss_srv.c src/tests/cmocka/nss_srv_tests-test_nss_srv.obj: src/tests/cmocka/test_nss_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/nss_srv_tests-test_nss_srv.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/nss_srv_tests-test_nss_srv.Tpo -c -o src/tests/cmocka/nss_srv_tests-test_nss_srv.obj `if test -f 'src/tests/cmocka/test_nss_srv.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_nss_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_nss_srv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/nss_srv_tests-test_nss_srv.Tpo src/tests/cmocka/$(DEPDIR)/nss_srv_tests-test_nss_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_nss_srv.c' object='src/tests/cmocka/nss_srv_tests-test_nss_srv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/nss_srv_tests-test_nss_srv.obj `if test -f 'src/tests/cmocka/test_nss_srv.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_nss_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_nss_srv.c'; fi` src/responder/nss/nss_srv_tests-nsssrv_cmd.o: src/responder/nss/nsssrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/nss/nss_srv_tests-nsssrv_cmd.o -MD -MP -MF src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_cmd.Tpo -c -o src/responder/nss/nss_srv_tests-nsssrv_cmd.o `test -f 'src/responder/nss/nsssrv_cmd.c' || echo '$(srcdir)/'`src/responder/nss/nsssrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_cmd.Tpo src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/nss/nsssrv_cmd.c' object='src/responder/nss/nss_srv_tests-nsssrv_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/nss/nss_srv_tests-nsssrv_cmd.o `test -f 'src/responder/nss/nsssrv_cmd.c' || echo '$(srcdir)/'`src/responder/nss/nsssrv_cmd.c src/responder/nss/nss_srv_tests-nsssrv_cmd.obj: src/responder/nss/nsssrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/nss/nss_srv_tests-nsssrv_cmd.obj -MD -MP -MF src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_cmd.Tpo -c -o src/responder/nss/nss_srv_tests-nsssrv_cmd.obj `if test -f 'src/responder/nss/nsssrv_cmd.c'; then $(CYGPATH_W) 'src/responder/nss/nsssrv_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/nss/nsssrv_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_cmd.Tpo src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/nss/nsssrv_cmd.c' object='src/responder/nss/nss_srv_tests-nsssrv_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/nss/nss_srv_tests-nsssrv_cmd.obj `if test -f 'src/responder/nss/nsssrv_cmd.c'; then $(CYGPATH_W) 'src/responder/nss/nsssrv_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/nss/nsssrv_cmd.c'; fi` src/responder/nss/nss_srv_tests-nsssrv_netgroup.o: src/responder/nss/nsssrv_netgroup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/nss/nss_srv_tests-nsssrv_netgroup.o -MD -MP -MF src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_netgroup.Tpo -c -o src/responder/nss/nss_srv_tests-nsssrv_netgroup.o `test -f 'src/responder/nss/nsssrv_netgroup.c' || echo '$(srcdir)/'`src/responder/nss/nsssrv_netgroup.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_netgroup.Tpo src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_netgroup.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/nss/nsssrv_netgroup.c' object='src/responder/nss/nss_srv_tests-nsssrv_netgroup.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/nss/nss_srv_tests-nsssrv_netgroup.o `test -f 'src/responder/nss/nsssrv_netgroup.c' || echo '$(srcdir)/'`src/responder/nss/nsssrv_netgroup.c src/responder/nss/nss_srv_tests-nsssrv_netgroup.obj: src/responder/nss/nsssrv_netgroup.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/nss/nss_srv_tests-nsssrv_netgroup.obj -MD -MP -MF src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_netgroup.Tpo -c -o src/responder/nss/nss_srv_tests-nsssrv_netgroup.obj `if test -f 'src/responder/nss/nsssrv_netgroup.c'; then $(CYGPATH_W) 'src/responder/nss/nsssrv_netgroup.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/nss/nsssrv_netgroup.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_netgroup.Tpo src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_netgroup.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/nss/nsssrv_netgroup.c' object='src/responder/nss/nss_srv_tests-nsssrv_netgroup.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/nss/nss_srv_tests-nsssrv_netgroup.obj `if test -f 'src/responder/nss/nsssrv_netgroup.c'; then $(CYGPATH_W) 'src/responder/nss/nsssrv_netgroup.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/nss/nsssrv_netgroup.c'; fi` src/responder/nss/nss_srv_tests-nsssrv_services.o: src/responder/nss/nsssrv_services.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/nss/nss_srv_tests-nsssrv_services.o -MD -MP -MF src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_services.Tpo -c -o src/responder/nss/nss_srv_tests-nsssrv_services.o `test -f 'src/responder/nss/nsssrv_services.c' || echo '$(srcdir)/'`src/responder/nss/nsssrv_services.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_services.Tpo src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_services.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/nss/nsssrv_services.c' object='src/responder/nss/nss_srv_tests-nsssrv_services.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/nss/nss_srv_tests-nsssrv_services.o `test -f 'src/responder/nss/nsssrv_services.c' || echo '$(srcdir)/'`src/responder/nss/nsssrv_services.c src/responder/nss/nss_srv_tests-nsssrv_services.obj: src/responder/nss/nsssrv_services.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/nss/nss_srv_tests-nsssrv_services.obj -MD -MP -MF src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_services.Tpo -c -o src/responder/nss/nss_srv_tests-nsssrv_services.obj `if test -f 'src/responder/nss/nsssrv_services.c'; then $(CYGPATH_W) 'src/responder/nss/nsssrv_services.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/nss/nsssrv_services.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_services.Tpo src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_services.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/nss/nsssrv_services.c' object='src/responder/nss/nss_srv_tests-nsssrv_services.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/nss/nss_srv_tests-nsssrv_services.obj `if test -f 'src/responder/nss/nsssrv_services.c'; then $(CYGPATH_W) 'src/responder/nss/nsssrv_services.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/nss/nsssrv_services.c'; fi` src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.o: src/responder/nss/nsssrv_mmap_cache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.o -MD -MP -MF src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_mmap_cache.Tpo -c -o src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.o `test -f 'src/responder/nss/nsssrv_mmap_cache.c' || echo '$(srcdir)/'`src/responder/nss/nsssrv_mmap_cache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_mmap_cache.Tpo src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_mmap_cache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/nss/nsssrv_mmap_cache.c' object='src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.o `test -f 'src/responder/nss/nsssrv_mmap_cache.c' || echo '$(srcdir)/'`src/responder/nss/nsssrv_mmap_cache.c src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.obj: src/responder/nss/nsssrv_mmap_cache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.obj -MD -MP -MF src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_mmap_cache.Tpo -c -o src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.obj `if test -f 'src/responder/nss/nsssrv_mmap_cache.c'; then $(CYGPATH_W) 'src/responder/nss/nsssrv_mmap_cache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/nss/nsssrv_mmap_cache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_mmap_cache.Tpo src/responder/nss/$(DEPDIR)/nss_srv_tests-nsssrv_mmap_cache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/nss/nsssrv_mmap_cache.c' object='src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(nss_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/nss/nss_srv_tests-nsssrv_mmap_cache.obj `if test -f 'src/responder/nss/nsssrv_mmap_cache.c'; then $(CYGPATH_W) 'src/responder/nss/nsssrv_mmap_cache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/nss/nsssrv_mmap_cache.c'; fi` src/p11_child/p11_child-p11_child_nss.o: src/p11_child/p11_child_nss.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -MT src/p11_child/p11_child-p11_child_nss.o -MD -MP -MF src/p11_child/$(DEPDIR)/p11_child-p11_child_nss.Tpo -c -o src/p11_child/p11_child-p11_child_nss.o `test -f 'src/p11_child/p11_child_nss.c' || echo '$(srcdir)/'`src/p11_child/p11_child_nss.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/p11_child/$(DEPDIR)/p11_child-p11_child_nss.Tpo src/p11_child/$(DEPDIR)/p11_child-p11_child_nss.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/p11_child/p11_child_nss.c' object='src/p11_child/p11_child-p11_child_nss.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -c -o src/p11_child/p11_child-p11_child_nss.o `test -f 'src/p11_child/p11_child_nss.c' || echo '$(srcdir)/'`src/p11_child/p11_child_nss.c src/p11_child/p11_child-p11_child_nss.obj: src/p11_child/p11_child_nss.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -MT src/p11_child/p11_child-p11_child_nss.obj -MD -MP -MF src/p11_child/$(DEPDIR)/p11_child-p11_child_nss.Tpo -c -o src/p11_child/p11_child-p11_child_nss.obj `if test -f 'src/p11_child/p11_child_nss.c'; then $(CYGPATH_W) 'src/p11_child/p11_child_nss.c'; else $(CYGPATH_W) '$(srcdir)/src/p11_child/p11_child_nss.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/p11_child/$(DEPDIR)/p11_child-p11_child_nss.Tpo src/p11_child/$(DEPDIR)/p11_child-p11_child_nss.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/p11_child/p11_child_nss.c' object='src/p11_child/p11_child-p11_child_nss.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -c -o src/p11_child/p11_child-p11_child_nss.obj `if test -f 'src/p11_child/p11_child_nss.c'; then $(CYGPATH_W) 'src/p11_child/p11_child_nss.c'; else $(CYGPATH_W) '$(srcdir)/src/p11_child/p11_child_nss.c'; fi` src/util/p11_child-atomic_io.o: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -MT src/util/p11_child-atomic_io.o -MD -MP -MF src/util/$(DEPDIR)/p11_child-atomic_io.Tpo -c -o src/util/p11_child-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/p11_child-atomic_io.Tpo src/util/$(DEPDIR)/p11_child-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/p11_child-atomic_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -c -o src/util/p11_child-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c src/util/p11_child-atomic_io.obj: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -MT src/util/p11_child-atomic_io.obj -MD -MP -MF src/util/$(DEPDIR)/p11_child-atomic_io.Tpo -c -o src/util/p11_child-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/p11_child-atomic_io.Tpo src/util/$(DEPDIR)/p11_child-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/p11_child-atomic_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -c -o src/util/p11_child-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` src/util/p11_child-util.o: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -MT src/util/p11_child-util.o -MD -MP -MF src/util/$(DEPDIR)/p11_child-util.Tpo -c -o src/util/p11_child-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/p11_child-util.Tpo src/util/$(DEPDIR)/p11_child-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/p11_child-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -c -o src/util/p11_child-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c src/util/p11_child-util.obj: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -MT src/util/p11_child-util.obj -MD -MP -MF src/util/$(DEPDIR)/p11_child-util.Tpo -c -o src/util/p11_child-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/p11_child-util.Tpo src/util/$(DEPDIR)/p11_child-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/p11_child-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(p11_child_CFLAGS) $(CFLAGS) -c -o src/util/p11_child-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` src/tests/cmocka/pam_srv_tests-common_mock_resp.o: src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/pam_srv_tests-common_mock_resp.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp.Tpo -c -o src/tests/cmocka/pam_srv_tests-common_mock_resp.o `test -f 'src/tests/cmocka/common_mock_resp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp.Tpo src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp.c' object='src/tests/cmocka/pam_srv_tests-common_mock_resp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/pam_srv_tests-common_mock_resp.o `test -f 'src/tests/cmocka/common_mock_resp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp.c src/tests/cmocka/pam_srv_tests-common_mock_resp.obj: src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/pam_srv_tests-common_mock_resp.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp.Tpo -c -o src/tests/cmocka/pam_srv_tests-common_mock_resp.obj `if test -f 'src/tests/cmocka/common_mock_resp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp.Tpo src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp.c' object='src/tests/cmocka/pam_srv_tests-common_mock_resp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/pam_srv_tests-common_mock_resp.obj `if test -f 'src/tests/cmocka/common_mock_resp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp.c'; fi` src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.o: src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp_dp.Tpo -c -o src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.o `test -f 'src/tests/cmocka/common_mock_resp_dp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp_dp.Tpo src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp_dp.c' object='src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.o `test -f 'src/tests/cmocka/common_mock_resp_dp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp_dp.c src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.obj: src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp_dp.Tpo -c -o src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.obj `if test -f 'src/tests/cmocka/common_mock_resp_dp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp_dp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp_dp.Tpo src/tests/cmocka/$(DEPDIR)/pam_srv_tests-common_mock_resp_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp_dp.c' object='src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/pam_srv_tests-common_mock_resp_dp.obj `if test -f 'src/tests/cmocka/common_mock_resp_dp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp_dp.c'; fi` src/responder/common/pam_srv_tests-responder_packet.o: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/pam_srv_tests-responder_packet.o -MD -MP -MF src/responder/common/$(DEPDIR)/pam_srv_tests-responder_packet.Tpo -c -o src/responder/common/pam_srv_tests-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/pam_srv_tests-responder_packet.Tpo src/responder/common/$(DEPDIR)/pam_srv_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/pam_srv_tests-responder_packet.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/pam_srv_tests-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c src/responder/common/pam_srv_tests-responder_packet.obj: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/pam_srv_tests-responder_packet.obj -MD -MP -MF src/responder/common/$(DEPDIR)/pam_srv_tests-responder_packet.Tpo -c -o src/responder/common/pam_srv_tests-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/pam_srv_tests-responder_packet.Tpo src/responder/common/$(DEPDIR)/pam_srv_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/pam_srv_tests-responder_packet.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/pam_srv_tests-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` src/responder/common/pam_srv_tests-responder_cmd.o: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/pam_srv_tests-responder_cmd.o -MD -MP -MF src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cmd.Tpo -c -o src/responder/common/pam_srv_tests-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cmd.Tpo src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/pam_srv_tests-responder_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/pam_srv_tests-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c src/responder/common/pam_srv_tests-responder_cmd.obj: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/pam_srv_tests-responder_cmd.obj -MD -MP -MF src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cmd.Tpo -c -o src/responder/common/pam_srv_tests-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cmd.Tpo src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/pam_srv_tests-responder_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/pam_srv_tests-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` src/responder/common/pam_srv_tests-negcache.o: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/pam_srv_tests-negcache.o -MD -MP -MF src/responder/common/$(DEPDIR)/pam_srv_tests-negcache.Tpo -c -o src/responder/common/pam_srv_tests-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/pam_srv_tests-negcache.Tpo src/responder/common/$(DEPDIR)/pam_srv_tests-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/pam_srv_tests-negcache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/pam_srv_tests-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c src/responder/common/pam_srv_tests-negcache.obj: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/pam_srv_tests-negcache.obj -MD -MP -MF src/responder/common/$(DEPDIR)/pam_srv_tests-negcache.Tpo -c -o src/responder/common/pam_srv_tests-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/pam_srv_tests-negcache.Tpo src/responder/common/$(DEPDIR)/pam_srv_tests-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/pam_srv_tests-negcache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/pam_srv_tests-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` src/responder/common/pam_srv_tests-responder_common.o: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/pam_srv_tests-responder_common.o -MD -MP -MF src/responder/common/$(DEPDIR)/pam_srv_tests-responder_common.Tpo -c -o src/responder/common/pam_srv_tests-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/pam_srv_tests-responder_common.Tpo src/responder/common/$(DEPDIR)/pam_srv_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/pam_srv_tests-responder_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/pam_srv_tests-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c src/responder/common/pam_srv_tests-responder_common.obj: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/pam_srv_tests-responder_common.obj -MD -MP -MF src/responder/common/$(DEPDIR)/pam_srv_tests-responder_common.Tpo -c -o src/responder/common/pam_srv_tests-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/pam_srv_tests-responder_common.Tpo src/responder/common/$(DEPDIR)/pam_srv_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/pam_srv_tests-responder_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/pam_srv_tests-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` src/responder/common/pam_srv_tests-responder_cache_req.o: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/pam_srv_tests-responder_cache_req.o -MD -MP -MF src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cache_req.Tpo -c -o src/responder/common/pam_srv_tests-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/pam_srv_tests-responder_cache_req.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/pam_srv_tests-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c src/responder/common/pam_srv_tests-responder_cache_req.obj: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/pam_srv_tests-responder_cache_req.obj -MD -MP -MF src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cache_req.Tpo -c -o src/responder/common/pam_srv_tests-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/pam_srv_tests-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/pam_srv_tests-responder_cache_req.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/pam_srv_tests-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` src/tests/cmocka/pam_srv_tests-test_pam_srv.o: src/tests/cmocka/test_pam_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/pam_srv_tests-test_pam_srv.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/pam_srv_tests-test_pam_srv.Tpo -c -o src/tests/cmocka/pam_srv_tests-test_pam_srv.o `test -f 'src/tests/cmocka/test_pam_srv.c' || echo '$(srcdir)/'`src/tests/cmocka/test_pam_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/pam_srv_tests-test_pam_srv.Tpo src/tests/cmocka/$(DEPDIR)/pam_srv_tests-test_pam_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_pam_srv.c' object='src/tests/cmocka/pam_srv_tests-test_pam_srv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/pam_srv_tests-test_pam_srv.o `test -f 'src/tests/cmocka/test_pam_srv.c' || echo '$(srcdir)/'`src/tests/cmocka/test_pam_srv.c src/tests/cmocka/pam_srv_tests-test_pam_srv.obj: src/tests/cmocka/test_pam_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/pam_srv_tests-test_pam_srv.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/pam_srv_tests-test_pam_srv.Tpo -c -o src/tests/cmocka/pam_srv_tests-test_pam_srv.obj `if test -f 'src/tests/cmocka/test_pam_srv.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_pam_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_pam_srv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/pam_srv_tests-test_pam_srv.Tpo src/tests/cmocka/$(DEPDIR)/pam_srv_tests-test_pam_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_pam_srv.c' object='src/tests/cmocka/pam_srv_tests-test_pam_srv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/pam_srv_tests-test_pam_srv.obj `if test -f 'src/tests/cmocka/test_pam_srv.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_pam_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_pam_srv.c'; fi` src/sss_client/pam_srv_tests-pam_message.o: src/sss_client/pam_message.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/sss_client/pam_srv_tests-pam_message.o -MD -MP -MF src/sss_client/$(DEPDIR)/pam_srv_tests-pam_message.Tpo -c -o src/sss_client/pam_srv_tests-pam_message.o `test -f 'src/sss_client/pam_message.c' || echo '$(srcdir)/'`src/sss_client/pam_message.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/pam_srv_tests-pam_message.Tpo src/sss_client/$(DEPDIR)/pam_srv_tests-pam_message.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/pam_message.c' object='src/sss_client/pam_srv_tests-pam_message.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/sss_client/pam_srv_tests-pam_message.o `test -f 'src/sss_client/pam_message.c' || echo '$(srcdir)/'`src/sss_client/pam_message.c src/sss_client/pam_srv_tests-pam_message.obj: src/sss_client/pam_message.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/sss_client/pam_srv_tests-pam_message.obj -MD -MP -MF src/sss_client/$(DEPDIR)/pam_srv_tests-pam_message.Tpo -c -o src/sss_client/pam_srv_tests-pam_message.obj `if test -f 'src/sss_client/pam_message.c'; then $(CYGPATH_W) 'src/sss_client/pam_message.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/pam_message.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/pam_srv_tests-pam_message.Tpo src/sss_client/$(DEPDIR)/pam_srv_tests-pam_message.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/pam_message.c' object='src/sss_client/pam_srv_tests-pam_message.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/sss_client/pam_srv_tests-pam_message.obj `if test -f 'src/sss_client/pam_message.c'; then $(CYGPATH_W) 'src/sss_client/pam_message.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/pam_message.c'; fi` src/responder/pam/pam_srv_tests-pamsrv_cmd.o: src/responder/pam/pamsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/pam/pam_srv_tests-pamsrv_cmd.o -MD -MP -MF src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_cmd.Tpo -c -o src/responder/pam/pam_srv_tests-pamsrv_cmd.o `test -f 'src/responder/pam/pamsrv_cmd.c' || echo '$(srcdir)/'`src/responder/pam/pamsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_cmd.Tpo src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pam/pamsrv_cmd.c' object='src/responder/pam/pam_srv_tests-pamsrv_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/pam/pam_srv_tests-pamsrv_cmd.o `test -f 'src/responder/pam/pamsrv_cmd.c' || echo '$(srcdir)/'`src/responder/pam/pamsrv_cmd.c src/responder/pam/pam_srv_tests-pamsrv_cmd.obj: src/responder/pam/pamsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/pam/pam_srv_tests-pamsrv_cmd.obj -MD -MP -MF src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_cmd.Tpo -c -o src/responder/pam/pam_srv_tests-pamsrv_cmd.obj `if test -f 'src/responder/pam/pamsrv_cmd.c'; then $(CYGPATH_W) 'src/responder/pam/pamsrv_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pam/pamsrv_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_cmd.Tpo src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pam/pamsrv_cmd.c' object='src/responder/pam/pam_srv_tests-pamsrv_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/pam/pam_srv_tests-pamsrv_cmd.obj `if test -f 'src/responder/pam/pamsrv_cmd.c'; then $(CYGPATH_W) 'src/responder/pam/pamsrv_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pam/pamsrv_cmd.c'; fi` src/responder/pam/pam_srv_tests-pamsrv_p11.o: src/responder/pam/pamsrv_p11.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/pam/pam_srv_tests-pamsrv_p11.o -MD -MP -MF src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_p11.Tpo -c -o src/responder/pam/pam_srv_tests-pamsrv_p11.o `test -f 'src/responder/pam/pamsrv_p11.c' || echo '$(srcdir)/'`src/responder/pam/pamsrv_p11.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_p11.Tpo src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_p11.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pam/pamsrv_p11.c' object='src/responder/pam/pam_srv_tests-pamsrv_p11.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/pam/pam_srv_tests-pamsrv_p11.o `test -f 'src/responder/pam/pamsrv_p11.c' || echo '$(srcdir)/'`src/responder/pam/pamsrv_p11.c src/responder/pam/pam_srv_tests-pamsrv_p11.obj: src/responder/pam/pamsrv_p11.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/pam/pam_srv_tests-pamsrv_p11.obj -MD -MP -MF src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_p11.Tpo -c -o src/responder/pam/pam_srv_tests-pamsrv_p11.obj `if test -f 'src/responder/pam/pamsrv_p11.c'; then $(CYGPATH_W) 'src/responder/pam/pamsrv_p11.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pam/pamsrv_p11.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_p11.Tpo src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_p11.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pam/pamsrv_p11.c' object='src/responder/pam/pam_srv_tests-pamsrv_p11.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/pam/pam_srv_tests-pamsrv_p11.obj `if test -f 'src/responder/pam/pamsrv_p11.c'; then $(CYGPATH_W) 'src/responder/pam/pamsrv_p11.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pam/pamsrv_p11.c'; fi` src/responder/pam/pam_srv_tests-pam_helpers.o: src/responder/pam/pam_helpers.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/pam/pam_srv_tests-pam_helpers.o -MD -MP -MF src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_helpers.Tpo -c -o src/responder/pam/pam_srv_tests-pam_helpers.o `test -f 'src/responder/pam/pam_helpers.c' || echo '$(srcdir)/'`src/responder/pam/pam_helpers.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_helpers.Tpo src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_helpers.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pam/pam_helpers.c' object='src/responder/pam/pam_srv_tests-pam_helpers.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/pam/pam_srv_tests-pam_helpers.o `test -f 'src/responder/pam/pam_helpers.c' || echo '$(srcdir)/'`src/responder/pam/pam_helpers.c src/responder/pam/pam_srv_tests-pam_helpers.obj: src/responder/pam/pam_helpers.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/pam/pam_srv_tests-pam_helpers.obj -MD -MP -MF src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_helpers.Tpo -c -o src/responder/pam/pam_srv_tests-pam_helpers.obj `if test -f 'src/responder/pam/pam_helpers.c'; then $(CYGPATH_W) 'src/responder/pam/pam_helpers.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pam/pam_helpers.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_helpers.Tpo src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_helpers.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pam/pam_helpers.c' object='src/responder/pam/pam_srv_tests-pam_helpers.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/pam/pam_srv_tests-pam_helpers.obj `if test -f 'src/responder/pam/pam_helpers.c'; then $(CYGPATH_W) 'src/responder/pam/pam_helpers.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pam/pam_helpers.c'; fi` src/responder/pam/pam_srv_tests-pamsrv_dp.o: src/responder/pam/pamsrv_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/pam/pam_srv_tests-pamsrv_dp.o -MD -MP -MF src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_dp.Tpo -c -o src/responder/pam/pam_srv_tests-pamsrv_dp.o `test -f 'src/responder/pam/pamsrv_dp.c' || echo '$(srcdir)/'`src/responder/pam/pamsrv_dp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_dp.Tpo src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pam/pamsrv_dp.c' object='src/responder/pam/pam_srv_tests-pamsrv_dp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/pam/pam_srv_tests-pamsrv_dp.o `test -f 'src/responder/pam/pamsrv_dp.c' || echo '$(srcdir)/'`src/responder/pam/pamsrv_dp.c src/responder/pam/pam_srv_tests-pamsrv_dp.obj: src/responder/pam/pamsrv_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/pam/pam_srv_tests-pamsrv_dp.obj -MD -MP -MF src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_dp.Tpo -c -o src/responder/pam/pam_srv_tests-pamsrv_dp.obj `if test -f 'src/responder/pam/pamsrv_dp.c'; then $(CYGPATH_W) 'src/responder/pam/pamsrv_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pam/pamsrv_dp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_dp.Tpo src/responder/pam/$(DEPDIR)/pam_srv_tests-pamsrv_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pam/pamsrv_dp.c' object='src/responder/pam/pam_srv_tests-pamsrv_dp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/pam/pam_srv_tests-pamsrv_dp.obj `if test -f 'src/responder/pam/pamsrv_dp.c'; then $(CYGPATH_W) 'src/responder/pam/pamsrv_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pam/pamsrv_dp.c'; fi` src/responder/pam/pam_srv_tests-pam_LOCAL_domain.o: src/responder/pam/pam_LOCAL_domain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/pam/pam_srv_tests-pam_LOCAL_domain.o -MD -MP -MF src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_LOCAL_domain.Tpo -c -o src/responder/pam/pam_srv_tests-pam_LOCAL_domain.o `test -f 'src/responder/pam/pam_LOCAL_domain.c' || echo '$(srcdir)/'`src/responder/pam/pam_LOCAL_domain.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_LOCAL_domain.Tpo src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_LOCAL_domain.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pam/pam_LOCAL_domain.c' object='src/responder/pam/pam_srv_tests-pam_LOCAL_domain.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/pam/pam_srv_tests-pam_LOCAL_domain.o `test -f 'src/responder/pam/pam_LOCAL_domain.c' || echo '$(srcdir)/'`src/responder/pam/pam_LOCAL_domain.c src/responder/pam/pam_srv_tests-pam_LOCAL_domain.obj: src/responder/pam/pam_LOCAL_domain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -MT src/responder/pam/pam_srv_tests-pam_LOCAL_domain.obj -MD -MP -MF src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_LOCAL_domain.Tpo -c -o src/responder/pam/pam_srv_tests-pam_LOCAL_domain.obj `if test -f 'src/responder/pam/pam_LOCAL_domain.c'; then $(CYGPATH_W) 'src/responder/pam/pam_LOCAL_domain.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pam/pam_LOCAL_domain.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_LOCAL_domain.Tpo src/responder/pam/$(DEPDIR)/pam_srv_tests-pam_LOCAL_domain.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pam/pam_LOCAL_domain.c' object='src/responder/pam/pam_srv_tests-pam_LOCAL_domain.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_srv_tests_CFLAGS) $(CFLAGS) -c -o src/responder/pam/pam_srv_tests-pam_LOCAL_domain.obj `if test -f 'src/responder/pam/pam_LOCAL_domain.c'; then $(CYGPATH_W) 'src/responder/pam/pam_LOCAL_domain.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pam/pam_LOCAL_domain.c'; fi` src/providers/proxy/proxy_child-proxy_child.o: src/providers/proxy/proxy_child.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(proxy_child_CFLAGS) $(CFLAGS) -MT src/providers/proxy/proxy_child-proxy_child.o -MD -MP -MF src/providers/proxy/$(DEPDIR)/proxy_child-proxy_child.Tpo -c -o src/providers/proxy/proxy_child-proxy_child.o `test -f 'src/providers/proxy/proxy_child.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_child.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/proxy/$(DEPDIR)/proxy_child-proxy_child.Tpo src/providers/proxy/$(DEPDIR)/proxy_child-proxy_child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/proxy/proxy_child.c' object='src/providers/proxy/proxy_child-proxy_child.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(proxy_child_CFLAGS) $(CFLAGS) -c -o src/providers/proxy/proxy_child-proxy_child.o `test -f 'src/providers/proxy/proxy_child.c' || echo '$(srcdir)/'`src/providers/proxy/proxy_child.c src/providers/proxy/proxy_child-proxy_child.obj: src/providers/proxy/proxy_child.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(proxy_child_CFLAGS) $(CFLAGS) -MT src/providers/proxy/proxy_child-proxy_child.obj -MD -MP -MF src/providers/proxy/$(DEPDIR)/proxy_child-proxy_child.Tpo -c -o src/providers/proxy/proxy_child-proxy_child.obj `if test -f 'src/providers/proxy/proxy_child.c'; then $(CYGPATH_W) 'src/providers/proxy/proxy_child.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/proxy/proxy_child.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/proxy/$(DEPDIR)/proxy_child-proxy_child.Tpo src/providers/proxy/$(DEPDIR)/proxy_child-proxy_child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/proxy/proxy_child.c' object='src/providers/proxy/proxy_child-proxy_child.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(proxy_child_CFLAGS) $(CFLAGS) -c -o src/providers/proxy/proxy_child-proxy_child.obj `if test -f 'src/providers/proxy/proxy_child.c'; then $(CYGPATH_W) 'src/providers/proxy/proxy_child.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/proxy/proxy_child.c'; fi` src/providers/proxy_child-data_provider_iface_generated.o: src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(proxy_child_CFLAGS) $(CFLAGS) -MT src/providers/proxy_child-data_provider_iface_generated.o -MD -MP -MF src/providers/$(DEPDIR)/proxy_child-data_provider_iface_generated.Tpo -c -o src/providers/proxy_child-data_provider_iface_generated.o `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/proxy_child-data_provider_iface_generated.Tpo src/providers/$(DEPDIR)/proxy_child-data_provider_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_iface_generated.c' object='src/providers/proxy_child-data_provider_iface_generated.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(proxy_child_CFLAGS) $(CFLAGS) -c -o src/providers/proxy_child-data_provider_iface_generated.o `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c src/providers/proxy_child-data_provider_iface_generated.obj: src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(proxy_child_CFLAGS) $(CFLAGS) -MT src/providers/proxy_child-data_provider_iface_generated.obj -MD -MP -MF src/providers/$(DEPDIR)/proxy_child-data_provider_iface_generated.Tpo -c -o src/providers/proxy_child-data_provider_iface_generated.obj `if test -f 'src/providers/data_provider_iface_generated.c'; then $(CYGPATH_W) 'src/providers/data_provider_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_iface_generated.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/proxy_child-data_provider_iface_generated.Tpo src/providers/$(DEPDIR)/proxy_child-data_provider_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_iface_generated.c' object='src/providers/proxy_child-data_provider_iface_generated.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(proxy_child_CFLAGS) $(CFLAGS) -c -o src/providers/proxy_child-data_provider_iface_generated.obj `if test -f 'src/providers/data_provider_iface_generated.c'; then $(CYGPATH_W) 'src/providers/data_provider_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_iface_generated.c'; fi` src/tests/refcount_tests-refcount-tests.o: src/tests/refcount-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(refcount_tests_CFLAGS) $(CFLAGS) -MT src/tests/refcount_tests-refcount-tests.o -MD -MP -MF src/tests/$(DEPDIR)/refcount_tests-refcount-tests.Tpo -c -o src/tests/refcount_tests-refcount-tests.o `test -f 'src/tests/refcount-tests.c' || echo '$(srcdir)/'`src/tests/refcount-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/refcount_tests-refcount-tests.Tpo src/tests/$(DEPDIR)/refcount_tests-refcount-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/refcount-tests.c' object='src/tests/refcount_tests-refcount-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(refcount_tests_CFLAGS) $(CFLAGS) -c -o src/tests/refcount_tests-refcount-tests.o `test -f 'src/tests/refcount-tests.c' || echo '$(srcdir)/'`src/tests/refcount-tests.c src/tests/refcount_tests-refcount-tests.obj: src/tests/refcount-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(refcount_tests_CFLAGS) $(CFLAGS) -MT src/tests/refcount_tests-refcount-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/refcount_tests-refcount-tests.Tpo -c -o src/tests/refcount_tests-refcount-tests.obj `if test -f 'src/tests/refcount-tests.c'; then $(CYGPATH_W) 'src/tests/refcount-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/refcount-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/refcount_tests-refcount-tests.Tpo src/tests/$(DEPDIR)/refcount_tests-refcount-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/refcount-tests.c' object='src/tests/refcount_tests-refcount-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(refcount_tests_CFLAGS) $(CFLAGS) -c -o src/tests/refcount_tests-refcount-tests.obj `if test -f 'src/tests/refcount-tests.c'; then $(CYGPATH_W) 'src/tests/refcount-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/refcount-tests.c'; fi` src/tests/resolv_tests-resolv-tests.o: src/tests/resolv-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -MT src/tests/resolv_tests-resolv-tests.o -MD -MP -MF src/tests/$(DEPDIR)/resolv_tests-resolv-tests.Tpo -c -o src/tests/resolv_tests-resolv-tests.o `test -f 'src/tests/resolv-tests.c' || echo '$(srcdir)/'`src/tests/resolv-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/resolv_tests-resolv-tests.Tpo src/tests/$(DEPDIR)/resolv_tests-resolv-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/resolv-tests.c' object='src/tests/resolv_tests-resolv-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/resolv_tests-resolv-tests.o `test -f 'src/tests/resolv-tests.c' || echo '$(srcdir)/'`src/tests/resolv-tests.c src/tests/resolv_tests-resolv-tests.obj: src/tests/resolv-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -MT src/tests/resolv_tests-resolv-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/resolv_tests-resolv-tests.Tpo -c -o src/tests/resolv_tests-resolv-tests.obj `if test -f 'src/tests/resolv-tests.c'; then $(CYGPATH_W) 'src/tests/resolv-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/resolv-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/resolv_tests-resolv-tests.Tpo src/tests/$(DEPDIR)/resolv_tests-resolv-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/resolv-tests.c' object='src/tests/resolv_tests-resolv-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/resolv_tests-resolv-tests.obj `if test -f 'src/tests/resolv-tests.c'; then $(CYGPATH_W) 'src/tests/resolv-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/resolv-tests.c'; fi` src/tests/resolv_tests-common.o: src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -MT src/tests/resolv_tests-common.o -MD -MP -MF src/tests/$(DEPDIR)/resolv_tests-common.Tpo -c -o src/tests/resolv_tests-common.o `test -f 'src/tests/common.c' || echo '$(srcdir)/'`src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/resolv_tests-common.Tpo src/tests/$(DEPDIR)/resolv_tests-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common.c' object='src/tests/resolv_tests-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/resolv_tests-common.o `test -f 'src/tests/common.c' || echo '$(srcdir)/'`src/tests/common.c src/tests/resolv_tests-common.obj: src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -MT src/tests/resolv_tests-common.obj -MD -MP -MF src/tests/$(DEPDIR)/resolv_tests-common.Tpo -c -o src/tests/resolv_tests-common.obj `if test -f 'src/tests/common.c'; then $(CYGPATH_W) 'src/tests/common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/resolv_tests-common.Tpo src/tests/$(DEPDIR)/resolv_tests-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common.c' object='src/tests/resolv_tests-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -c -o src/tests/resolv_tests-common.obj `if test -f 'src/tests/common.c'; then $(CYGPATH_W) 'src/tests/common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common.c'; fi` src/resolv/resolv_tests-async_resolv.o: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -MT src/resolv/resolv_tests-async_resolv.o -MD -MP -MF src/resolv/$(DEPDIR)/resolv_tests-async_resolv.Tpo -c -o src/resolv/resolv_tests-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/resolv_tests-async_resolv.Tpo src/resolv/$(DEPDIR)/resolv_tests-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/resolv_tests-async_resolv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/resolv_tests-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c src/resolv/resolv_tests-async_resolv.obj: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -MT src/resolv/resolv_tests-async_resolv.obj -MD -MP -MF src/resolv/$(DEPDIR)/resolv_tests-async_resolv.Tpo -c -o src/resolv/resolv_tests-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/resolv_tests-async_resolv.Tpo src/resolv/$(DEPDIR)/resolv_tests-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/resolv_tests-async_resolv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/resolv_tests-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` src/resolv/resolv_tests-async_resolv_utils.o: src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -MT src/resolv/resolv_tests-async_resolv_utils.o -MD -MP -MF src/resolv/$(DEPDIR)/resolv_tests-async_resolv_utils.Tpo -c -o src/resolv/resolv_tests-async_resolv_utils.o `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/resolv_tests-async_resolv_utils.Tpo src/resolv/$(DEPDIR)/resolv_tests-async_resolv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv_utils.c' object='src/resolv/resolv_tests-async_resolv_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/resolv_tests-async_resolv_utils.o `test -f 'src/resolv/async_resolv_utils.c' || echo '$(srcdir)/'`src/resolv/async_resolv_utils.c src/resolv/resolv_tests-async_resolv_utils.obj: src/resolv/async_resolv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -MT src/resolv/resolv_tests-async_resolv_utils.obj -MD -MP -MF src/resolv/$(DEPDIR)/resolv_tests-async_resolv_utils.Tpo -c -o src/resolv/resolv_tests-async_resolv_utils.obj `if test -f 'src/resolv/async_resolv_utils.c'; then $(CYGPATH_W) 'src/resolv/async_resolv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/resolv_tests-async_resolv_utils.Tpo src/resolv/$(DEPDIR)/resolv_tests-async_resolv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv_utils.c' object='src/resolv/resolv_tests-async_resolv_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(resolv_tests_CFLAGS) $(CFLAGS) -c -o src/resolv/resolv_tests-async_resolv_utils.obj `if test -f 'src/resolv/async_resolv_utils.c'; then $(CYGPATH_W) 'src/resolv/async_resolv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv_utils.c'; fi` src/responder/common/responder_get_domains_tests-responder_get_domains.o: src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_get_domains_tests-responder_get_domains.o -MD -MP -MF src/responder/common/$(DEPDIR)/responder_get_domains_tests-responder_get_domains.Tpo -c -o src/responder/common/responder_get_domains_tests-responder_get_domains.o `test -f 'src/responder/common/responder_get_domains.c' || echo '$(srcdir)/'`src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_get_domains_tests-responder_get_domains.Tpo src/responder/common/$(DEPDIR)/responder_get_domains_tests-responder_get_domains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_get_domains.c' object='src/responder/common/responder_get_domains_tests-responder_get_domains.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_get_domains_tests-responder_get_domains.o `test -f 'src/responder/common/responder_get_domains.c' || echo '$(srcdir)/'`src/responder/common/responder_get_domains.c src/responder/common/responder_get_domains_tests-responder_get_domains.obj: src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_get_domains_tests-responder_get_domains.obj -MD -MP -MF src/responder/common/$(DEPDIR)/responder_get_domains_tests-responder_get_domains.Tpo -c -o src/responder/common/responder_get_domains_tests-responder_get_domains.obj `if test -f 'src/responder/common/responder_get_domains.c'; then $(CYGPATH_W) 'src/responder/common/responder_get_domains.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_get_domains.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_get_domains_tests-responder_get_domains.Tpo src/responder/common/$(DEPDIR)/responder_get_domains_tests-responder_get_domains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_get_domains.c' object='src/responder/common/responder_get_domains_tests-responder_get_domains.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_get_domains_tests-responder_get_domains.obj `if test -f 'src/responder/common/responder_get_domains.c'; then $(CYGPATH_W) 'src/responder/common/responder_get_domains.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_get_domains.c'; fi` src/tests/cmocka/responder_get_domains_tests-test_responder_common.o: src/tests/cmocka/test_responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/responder_get_domains_tests-test_responder_common.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-test_responder_common.Tpo -c -o src/tests/cmocka/responder_get_domains_tests-test_responder_common.o `test -f 'src/tests/cmocka/test_responder_common.c' || echo '$(srcdir)/'`src/tests/cmocka/test_responder_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-test_responder_common.Tpo src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-test_responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_responder_common.c' object='src/tests/cmocka/responder_get_domains_tests-test_responder_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/responder_get_domains_tests-test_responder_common.o `test -f 'src/tests/cmocka/test_responder_common.c' || echo '$(srcdir)/'`src/tests/cmocka/test_responder_common.c src/tests/cmocka/responder_get_domains_tests-test_responder_common.obj: src/tests/cmocka/test_responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/responder_get_domains_tests-test_responder_common.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-test_responder_common.Tpo -c -o src/tests/cmocka/responder_get_domains_tests-test_responder_common.obj `if test -f 'src/tests/cmocka/test_responder_common.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_responder_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-test_responder_common.Tpo src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-test_responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_responder_common.c' object='src/tests/cmocka/responder_get_domains_tests-test_responder_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/responder_get_domains_tests-test_responder_common.obj `if test -f 'src/tests/cmocka/test_responder_common.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_responder_common.c'; fi` src/tests/cmocka/responder_get_domains_tests-common_mock_resp.o: src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/responder_get_domains_tests-common_mock_resp.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-common_mock_resp.Tpo -c -o src/tests/cmocka/responder_get_domains_tests-common_mock_resp.o `test -f 'src/tests/cmocka/common_mock_resp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-common_mock_resp.Tpo src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-common_mock_resp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp.c' object='src/tests/cmocka/responder_get_domains_tests-common_mock_resp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/responder_get_domains_tests-common_mock_resp.o `test -f 'src/tests/cmocka/common_mock_resp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp.c src/tests/cmocka/responder_get_domains_tests-common_mock_resp.obj: src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/responder_get_domains_tests-common_mock_resp.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-common_mock_resp.Tpo -c -o src/tests/cmocka/responder_get_domains_tests-common_mock_resp.obj `if test -f 'src/tests/cmocka/common_mock_resp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-common_mock_resp.Tpo src/tests/cmocka/$(DEPDIR)/responder_get_domains_tests-common_mock_resp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp.c' object='src/tests/cmocka/responder_get_domains_tests-common_mock_resp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_get_domains_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/responder_get_domains_tests-common_mock_resp.obj `if test -f 'src/tests/cmocka/common_mock_resp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp.c'; fi` src/tests/cmocka/responder_cache_req_tests-common_mock_resp.o: src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/responder_cache_req_tests-common_mock_resp.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp.Tpo -c -o src/tests/cmocka/responder_cache_req_tests-common_mock_resp.o `test -f 'src/tests/cmocka/common_mock_resp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp.Tpo src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp.c' object='src/tests/cmocka/responder_cache_req_tests-common_mock_resp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/responder_cache_req_tests-common_mock_resp.o `test -f 'src/tests/cmocka/common_mock_resp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp.c src/tests/cmocka/responder_cache_req_tests-common_mock_resp.obj: src/tests/cmocka/common_mock_resp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/responder_cache_req_tests-common_mock_resp.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp.Tpo -c -o src/tests/cmocka/responder_cache_req_tests-common_mock_resp.obj `if test -f 'src/tests/cmocka/common_mock_resp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp.Tpo src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp.c' object='src/tests/cmocka/responder_cache_req_tests-common_mock_resp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/responder_cache_req_tests-common_mock_resp.obj `if test -f 'src/tests/cmocka/common_mock_resp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp.c'; fi` src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.o: src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp_dp.Tpo -c -o src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.o `test -f 'src/tests/cmocka/common_mock_resp_dp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp_dp.Tpo src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp_dp.c' object='src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.o `test -f 'src/tests/cmocka/common_mock_resp_dp.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_resp_dp.c src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.obj: src/tests/cmocka/common_mock_resp_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp_dp.Tpo -c -o src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.obj `if test -f 'src/tests/cmocka/common_mock_resp_dp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp_dp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp_dp.Tpo src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-common_mock_resp_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_resp_dp.c' object='src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/responder_cache_req_tests-common_mock_resp_dp.obj `if test -f 'src/tests/cmocka/common_mock_resp_dp.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_resp_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_resp_dp.c'; fi` src/responder/common/responder_cache_req_tests-responder_packet.o: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_cache_req_tests-responder_packet.o -MD -MP -MF src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_packet.Tpo -c -o src/responder/common/responder_cache_req_tests-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_packet.Tpo src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/responder_cache_req_tests-responder_packet.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_cache_req_tests-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c src/responder/common/responder_cache_req_tests-responder_packet.obj: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_cache_req_tests-responder_packet.obj -MD -MP -MF src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_packet.Tpo -c -o src/responder/common/responder_cache_req_tests-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_packet.Tpo src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/responder_cache_req_tests-responder_packet.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_cache_req_tests-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` src/responder/common/responder_cache_req_tests-responder_cmd.o: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_cache_req_tests-responder_cmd.o -MD -MP -MF src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cmd.Tpo -c -o src/responder/common/responder_cache_req_tests-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cmd.Tpo src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/responder_cache_req_tests-responder_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_cache_req_tests-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c src/responder/common/responder_cache_req_tests-responder_cmd.obj: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_cache_req_tests-responder_cmd.obj -MD -MP -MF src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cmd.Tpo -c -o src/responder/common/responder_cache_req_tests-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cmd.Tpo src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/responder_cache_req_tests-responder_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_cache_req_tests-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` src/responder/common/responder_cache_req_tests-negcache.o: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_cache_req_tests-negcache.o -MD -MP -MF src/responder/common/$(DEPDIR)/responder_cache_req_tests-negcache.Tpo -c -o src/responder/common/responder_cache_req_tests-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_cache_req_tests-negcache.Tpo src/responder/common/$(DEPDIR)/responder_cache_req_tests-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/responder_cache_req_tests-negcache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_cache_req_tests-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c src/responder/common/responder_cache_req_tests-negcache.obj: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_cache_req_tests-negcache.obj -MD -MP -MF src/responder/common/$(DEPDIR)/responder_cache_req_tests-negcache.Tpo -c -o src/responder/common/responder_cache_req_tests-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_cache_req_tests-negcache.Tpo src/responder/common/$(DEPDIR)/responder_cache_req_tests-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/responder_cache_req_tests-negcache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_cache_req_tests-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` src/responder/common/responder_cache_req_tests-responder_common.o: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_cache_req_tests-responder_common.o -MD -MP -MF src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_common.Tpo -c -o src/responder/common/responder_cache_req_tests-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_common.Tpo src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/responder_cache_req_tests-responder_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_cache_req_tests-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c src/responder/common/responder_cache_req_tests-responder_common.obj: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_cache_req_tests-responder_common.obj -MD -MP -MF src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_common.Tpo -c -o src/responder/common/responder_cache_req_tests-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_common.Tpo src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/responder_cache_req_tests-responder_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_cache_req_tests-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` src/responder/common/responder_cache_req_tests-responder_cache_req.o: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_cache_req_tests-responder_cache_req.o -MD -MP -MF src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cache_req.Tpo -c -o src/responder/common/responder_cache_req_tests-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/responder_cache_req_tests-responder_cache_req.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_cache_req_tests-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c src/responder/common/responder_cache_req_tests-responder_cache_req.obj: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_cache_req_tests-responder_cache_req.obj -MD -MP -MF src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cache_req.Tpo -c -o src/responder/common/responder_cache_req_tests-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/responder_cache_req_tests-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/responder_cache_req_tests-responder_cache_req.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_cache_req_tests-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.o: src/tests/cmocka/test_responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-test_responder_cache_req.Tpo -c -o src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.o `test -f 'src/tests/cmocka/test_responder_cache_req.c' || echo '$(srcdir)/'`src/tests/cmocka/test_responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-test_responder_cache_req.Tpo src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-test_responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_responder_cache_req.c' object='src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.o `test -f 'src/tests/cmocka/test_responder_cache_req.c' || echo '$(srcdir)/'`src/tests/cmocka/test_responder_cache_req.c src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.obj: src/tests/cmocka/test_responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-test_responder_cache_req.Tpo -c -o src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.obj `if test -f 'src/tests/cmocka/test_responder_cache_req.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_responder_cache_req.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-test_responder_cache_req.Tpo src/tests/cmocka/$(DEPDIR)/responder_cache_req_tests-test_responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_responder_cache_req.c' object='src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_cache_req_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/responder_cache_req_tests-test_responder_cache_req.obj `if test -f 'src/tests/cmocka/test_responder_cache_req.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_responder_cache_req.c'; fi` src/tests/responder_socket_access_tests-responder_socket_access-tests.o: src/tests/responder_socket_access-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -MT src/tests/responder_socket_access_tests-responder_socket_access-tests.o -MD -MP -MF src/tests/$(DEPDIR)/responder_socket_access_tests-responder_socket_access-tests.Tpo -c -o src/tests/responder_socket_access_tests-responder_socket_access-tests.o `test -f 'src/tests/responder_socket_access-tests.c' || echo '$(srcdir)/'`src/tests/responder_socket_access-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/responder_socket_access_tests-responder_socket_access-tests.Tpo src/tests/$(DEPDIR)/responder_socket_access_tests-responder_socket_access-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/responder_socket_access-tests.c' object='src/tests/responder_socket_access_tests-responder_socket_access-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -c -o src/tests/responder_socket_access_tests-responder_socket_access-tests.o `test -f 'src/tests/responder_socket_access-tests.c' || echo '$(srcdir)/'`src/tests/responder_socket_access-tests.c src/tests/responder_socket_access_tests-responder_socket_access-tests.obj: src/tests/responder_socket_access-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -MT src/tests/responder_socket_access_tests-responder_socket_access-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/responder_socket_access_tests-responder_socket_access-tests.Tpo -c -o src/tests/responder_socket_access_tests-responder_socket_access-tests.obj `if test -f 'src/tests/responder_socket_access-tests.c'; then $(CYGPATH_W) 'src/tests/responder_socket_access-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/responder_socket_access-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/responder_socket_access_tests-responder_socket_access-tests.Tpo src/tests/$(DEPDIR)/responder_socket_access_tests-responder_socket_access-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/responder_socket_access-tests.c' object='src/tests/responder_socket_access_tests-responder_socket_access-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -c -o src/tests/responder_socket_access_tests-responder_socket_access-tests.obj `if test -f 'src/tests/responder_socket_access-tests.c'; then $(CYGPATH_W) 'src/tests/responder_socket_access-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/responder_socket_access-tests.c'; fi` src/responder/common/responder_socket_access_tests-responder_common.o: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_socket_access_tests-responder_common.o -MD -MP -MF src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_common.Tpo -c -o src/responder/common/responder_socket_access_tests-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_common.Tpo src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/responder_socket_access_tests-responder_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_socket_access_tests-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c src/responder/common/responder_socket_access_tests-responder_common.obj: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_socket_access_tests-responder_common.obj -MD -MP -MF src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_common.Tpo -c -o src/responder/common/responder_socket_access_tests-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_common.Tpo src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/responder_socket_access_tests-responder_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_socket_access_tests-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` src/responder/common/responder_socket_access_tests-responder_packet.o: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_socket_access_tests-responder_packet.o -MD -MP -MF src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_packet.Tpo -c -o src/responder/common/responder_socket_access_tests-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_packet.Tpo src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/responder_socket_access_tests-responder_packet.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_socket_access_tests-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c src/responder/common/responder_socket_access_tests-responder_packet.obj: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_socket_access_tests-responder_packet.obj -MD -MP -MF src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_packet.Tpo -c -o src/responder/common/responder_socket_access_tests-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_packet.Tpo src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/responder_socket_access_tests-responder_packet.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_socket_access_tests-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` src/responder/common/responder_socket_access_tests-responder_cmd.o: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_socket_access_tests-responder_cmd.o -MD -MP -MF src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_cmd.Tpo -c -o src/responder/common/responder_socket_access_tests-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_cmd.Tpo src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/responder_socket_access_tests-responder_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_socket_access_tests-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c src/responder/common/responder_socket_access_tests-responder_cmd.obj: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -MT src/responder/common/responder_socket_access_tests-responder_cmd.obj -MD -MP -MF src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_cmd.Tpo -c -o src/responder/common/responder_socket_access_tests-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_cmd.Tpo src/responder/common/$(DEPDIR)/responder_socket_access_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/responder_socket_access_tests-responder_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_socket_access_tests_CFLAGS) $(CFLAGS) -c -o src/responder/common/responder_socket_access_tests-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` src/tests/safe_format_tests-safe-format-tests.o: src/tests/safe-format-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(safe_format_tests_CFLAGS) $(CFLAGS) -MT src/tests/safe_format_tests-safe-format-tests.o -MD -MP -MF src/tests/$(DEPDIR)/safe_format_tests-safe-format-tests.Tpo -c -o src/tests/safe_format_tests-safe-format-tests.o `test -f 'src/tests/safe-format-tests.c' || echo '$(srcdir)/'`src/tests/safe-format-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/safe_format_tests-safe-format-tests.Tpo src/tests/$(DEPDIR)/safe_format_tests-safe-format-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/safe-format-tests.c' object='src/tests/safe_format_tests-safe-format-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(safe_format_tests_CFLAGS) $(CFLAGS) -c -o src/tests/safe_format_tests-safe-format-tests.o `test -f 'src/tests/safe-format-tests.c' || echo '$(srcdir)/'`src/tests/safe-format-tests.c src/tests/safe_format_tests-safe-format-tests.obj: src/tests/safe-format-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(safe_format_tests_CFLAGS) $(CFLAGS) -MT src/tests/safe_format_tests-safe-format-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/safe_format_tests-safe-format-tests.Tpo -c -o src/tests/safe_format_tests-safe-format-tests.obj `if test -f 'src/tests/safe-format-tests.c'; then $(CYGPATH_W) 'src/tests/safe-format-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/safe-format-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/safe_format_tests-safe-format-tests.Tpo src/tests/$(DEPDIR)/safe_format_tests-safe-format-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/safe-format-tests.c' object='src/tests/safe_format_tests-safe-format-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(safe_format_tests_CFLAGS) $(CFLAGS) -c -o src/tests/safe_format_tests-safe-format-tests.obj `if test -f 'src/tests/safe-format-tests.c'; then $(CYGPATH_W) 'src/tests/safe-format-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/safe-format-tests.c'; fi` src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.o: src/tests/cmocka/sbus_internal_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_internal_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/sbus_internal_tests-sbus_internal_tests.Tpo -c -o src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.o `test -f 'src/tests/cmocka/sbus_internal_tests.c' || echo '$(srcdir)/'`src/tests/cmocka/sbus_internal_tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/sbus_internal_tests-sbus_internal_tests.Tpo src/tests/cmocka/$(DEPDIR)/sbus_internal_tests-sbus_internal_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/sbus_internal_tests.c' object='src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_internal_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.o `test -f 'src/tests/cmocka/sbus_internal_tests.c' || echo '$(srcdir)/'`src/tests/cmocka/sbus_internal_tests.c src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.obj: src/tests/cmocka/sbus_internal_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_internal_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/sbus_internal_tests-sbus_internal_tests.Tpo -c -o src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.obj `if test -f 'src/tests/cmocka/sbus_internal_tests.c'; then $(CYGPATH_W) 'src/tests/cmocka/sbus_internal_tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/sbus_internal_tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/sbus_internal_tests-sbus_internal_tests.Tpo src/tests/cmocka/$(DEPDIR)/sbus_internal_tests-sbus_internal_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/sbus_internal_tests.c' object='src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_internal_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/sbus_internal_tests-sbus_internal_tests.obj `if test -f 'src/tests/cmocka/sbus_internal_tests.c'; then $(CYGPATH_W) 'src/tests/cmocka/sbus_internal_tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/sbus_internal_tests.c'; fi` src/sbus/sbus_internal_tests-sssd_dbus_request.o: src/sbus/sssd_dbus_request.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_internal_tests_CFLAGS) $(CFLAGS) -MT src/sbus/sbus_internal_tests-sssd_dbus_request.o -MD -MP -MF src/sbus/$(DEPDIR)/sbus_internal_tests-sssd_dbus_request.Tpo -c -o src/sbus/sbus_internal_tests-sssd_dbus_request.o `test -f 'src/sbus/sssd_dbus_request.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_request.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/sbus_internal_tests-sssd_dbus_request.Tpo src/sbus/$(DEPDIR)/sbus_internal_tests-sssd_dbus_request.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_request.c' object='src/sbus/sbus_internal_tests-sssd_dbus_request.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_internal_tests_CFLAGS) $(CFLAGS) -c -o src/sbus/sbus_internal_tests-sssd_dbus_request.o `test -f 'src/sbus/sssd_dbus_request.c' || echo '$(srcdir)/'`src/sbus/sssd_dbus_request.c src/sbus/sbus_internal_tests-sssd_dbus_request.obj: src/sbus/sssd_dbus_request.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_internal_tests_CFLAGS) $(CFLAGS) -MT src/sbus/sbus_internal_tests-sssd_dbus_request.obj -MD -MP -MF src/sbus/$(DEPDIR)/sbus_internal_tests-sssd_dbus_request.Tpo -c -o src/sbus/sbus_internal_tests-sssd_dbus_request.obj `if test -f 'src/sbus/sssd_dbus_request.c'; then $(CYGPATH_W) 'src/sbus/sssd_dbus_request.c'; else $(CYGPATH_W) '$(srcdir)/src/sbus/sssd_dbus_request.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sbus/$(DEPDIR)/sbus_internal_tests-sssd_dbus_request.Tpo src/sbus/$(DEPDIR)/sbus_internal_tests-sssd_dbus_request.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sbus/sssd_dbus_request.c' object='src/sbus/sbus_internal_tests-sssd_dbus_request.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_internal_tests_CFLAGS) $(CFLAGS) -c -o src/sbus/sbus_internal_tests-sssd_dbus_request.obj `if test -f 'src/sbus/sssd_dbus_request.c'; then $(CYGPATH_W) 'src/sbus/sssd_dbus_request.c'; else $(CYGPATH_W) '$(srcdir)/src/sbus/sssd_dbus_request.c'; fi` src/tests/sbus_codegen_tests-common_dbus.o: src/tests/common_dbus.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -MT src/tests/sbus_codegen_tests-common_dbus.o -MD -MP -MF src/tests/$(DEPDIR)/sbus_codegen_tests-common_dbus.Tpo -c -o src/tests/sbus_codegen_tests-common_dbus.o `test -f 'src/tests/common_dbus.c' || echo '$(srcdir)/'`src/tests/common_dbus.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sbus_codegen_tests-common_dbus.Tpo src/tests/$(DEPDIR)/sbus_codegen_tests-common_dbus.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common_dbus.c' object='src/tests/sbus_codegen_tests-common_dbus.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sbus_codegen_tests-common_dbus.o `test -f 'src/tests/common_dbus.c' || echo '$(srcdir)/'`src/tests/common_dbus.c src/tests/sbus_codegen_tests-common_dbus.obj: src/tests/common_dbus.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -MT src/tests/sbus_codegen_tests-common_dbus.obj -MD -MP -MF src/tests/$(DEPDIR)/sbus_codegen_tests-common_dbus.Tpo -c -o src/tests/sbus_codegen_tests-common_dbus.obj `if test -f 'src/tests/common_dbus.c'; then $(CYGPATH_W) 'src/tests/common_dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common_dbus.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sbus_codegen_tests-common_dbus.Tpo src/tests/$(DEPDIR)/sbus_codegen_tests-common_dbus.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common_dbus.c' object='src/tests/sbus_codegen_tests-common_dbus.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sbus_codegen_tests-common_dbus.obj `if test -f 'src/tests/common_dbus.c'; then $(CYGPATH_W) 'src/tests/common_dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common_dbus.c'; fi` src/tests/sbus_codegen_tests-sbus_codegen_tests.o: src/tests/sbus_codegen_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -MT src/tests/sbus_codegen_tests-sbus_codegen_tests.o -MD -MP -MF src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests.Tpo -c -o src/tests/sbus_codegen_tests-sbus_codegen_tests.o `test -f 'src/tests/sbus_codegen_tests.c' || echo '$(srcdir)/'`src/tests/sbus_codegen_tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests.Tpo src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sbus_codegen_tests.c' object='src/tests/sbus_codegen_tests-sbus_codegen_tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sbus_codegen_tests-sbus_codegen_tests.o `test -f 'src/tests/sbus_codegen_tests.c' || echo '$(srcdir)/'`src/tests/sbus_codegen_tests.c src/tests/sbus_codegen_tests-sbus_codegen_tests.obj: src/tests/sbus_codegen_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -MT src/tests/sbus_codegen_tests-sbus_codegen_tests.obj -MD -MP -MF src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests.Tpo -c -o src/tests/sbus_codegen_tests-sbus_codegen_tests.obj `if test -f 'src/tests/sbus_codegen_tests.c'; then $(CYGPATH_W) 'src/tests/sbus_codegen_tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sbus_codegen_tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests.Tpo src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sbus_codegen_tests.c' object='src/tests/sbus_codegen_tests-sbus_codegen_tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sbus_codegen_tests-sbus_codegen_tests.obj `if test -f 'src/tests/sbus_codegen_tests.c'; then $(CYGPATH_W) 'src/tests/sbus_codegen_tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sbus_codegen_tests.c'; fi` src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.o: src/tests/sbus_codegen_tests_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -MT src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.o -MD -MP -MF src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests_generated.Tpo -c -o src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.o `test -f 'src/tests/sbus_codegen_tests_generated.c' || echo '$(srcdir)/'`src/tests/sbus_codegen_tests_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests_generated.Tpo src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sbus_codegen_tests_generated.c' object='src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.o `test -f 'src/tests/sbus_codegen_tests_generated.c' || echo '$(srcdir)/'`src/tests/sbus_codegen_tests_generated.c src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.obj: src/tests/sbus_codegen_tests_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -MT src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.obj -MD -MP -MF src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests_generated.Tpo -c -o src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.obj `if test -f 'src/tests/sbus_codegen_tests_generated.c'; then $(CYGPATH_W) 'src/tests/sbus_codegen_tests_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sbus_codegen_tests_generated.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests_generated.Tpo src/tests/$(DEPDIR)/sbus_codegen_tests-sbus_codegen_tests_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sbus_codegen_tests_generated.c' object='src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_codegen_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sbus_codegen_tests-sbus_codegen_tests_generated.obj `if test -f 'src/tests/sbus_codegen_tests_generated.c'; then $(CYGPATH_W) 'src/tests/sbus_codegen_tests_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sbus_codegen_tests_generated.c'; fi` src/tests/sbus_tests-common_dbus.o: src/tests/common_dbus.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_tests_CFLAGS) $(CFLAGS) -MT src/tests/sbus_tests-common_dbus.o -MD -MP -MF src/tests/$(DEPDIR)/sbus_tests-common_dbus.Tpo -c -o src/tests/sbus_tests-common_dbus.o `test -f 'src/tests/common_dbus.c' || echo '$(srcdir)/'`src/tests/common_dbus.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sbus_tests-common_dbus.Tpo src/tests/$(DEPDIR)/sbus_tests-common_dbus.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common_dbus.c' object='src/tests/sbus_tests-common_dbus.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sbus_tests-common_dbus.o `test -f 'src/tests/common_dbus.c' || echo '$(srcdir)/'`src/tests/common_dbus.c src/tests/sbus_tests-common_dbus.obj: src/tests/common_dbus.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_tests_CFLAGS) $(CFLAGS) -MT src/tests/sbus_tests-common_dbus.obj -MD -MP -MF src/tests/$(DEPDIR)/sbus_tests-common_dbus.Tpo -c -o src/tests/sbus_tests-common_dbus.obj `if test -f 'src/tests/common_dbus.c'; then $(CYGPATH_W) 'src/tests/common_dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common_dbus.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sbus_tests-common_dbus.Tpo src/tests/$(DEPDIR)/sbus_tests-common_dbus.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common_dbus.c' object='src/tests/sbus_tests-common_dbus.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sbus_tests-common_dbus.obj `if test -f 'src/tests/common_dbus.c'; then $(CYGPATH_W) 'src/tests/common_dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common_dbus.c'; fi` src/tests/sbus_tests-sbus_tests.o: src/tests/sbus_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_tests_CFLAGS) $(CFLAGS) -MT src/tests/sbus_tests-sbus_tests.o -MD -MP -MF src/tests/$(DEPDIR)/sbus_tests-sbus_tests.Tpo -c -o src/tests/sbus_tests-sbus_tests.o `test -f 'src/tests/sbus_tests.c' || echo '$(srcdir)/'`src/tests/sbus_tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sbus_tests-sbus_tests.Tpo src/tests/$(DEPDIR)/sbus_tests-sbus_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sbus_tests.c' object='src/tests/sbus_tests-sbus_tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sbus_tests-sbus_tests.o `test -f 'src/tests/sbus_tests.c' || echo '$(srcdir)/'`src/tests/sbus_tests.c src/tests/sbus_tests-sbus_tests.obj: src/tests/sbus_tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_tests_CFLAGS) $(CFLAGS) -MT src/tests/sbus_tests-sbus_tests.obj -MD -MP -MF src/tests/$(DEPDIR)/sbus_tests-sbus_tests.Tpo -c -o src/tests/sbus_tests-sbus_tests.obj `if test -f 'src/tests/sbus_tests.c'; then $(CYGPATH_W) 'src/tests/sbus_tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sbus_tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sbus_tests-sbus_tests.Tpo src/tests/$(DEPDIR)/sbus_tests-sbus_tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sbus_tests.c' object='src/tests/sbus_tests-sbus_tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sbus_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sbus_tests-sbus_tests.obj `if test -f 'src/tests/sbus_tests.c'; then $(CYGPATH_W) 'src/tests/sbus_tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sbus_tests.c'; fi` src/providers/sdap_tests-data_provider_opts.o: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/sdap_tests-data_provider_opts.o -MD -MP -MF src/providers/$(DEPDIR)/sdap_tests-data_provider_opts.Tpo -c -o src/providers/sdap_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/sdap_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/sdap_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/sdap_tests-data_provider_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/sdap_tests-data_provider_opts.o `test -f 'src/providers/data_provider_opts.c' || echo '$(srcdir)/'`src/providers/data_provider_opts.c src/providers/sdap_tests-data_provider_opts.obj: src/providers/data_provider_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/sdap_tests-data_provider_opts.obj -MD -MP -MF src/providers/$(DEPDIR)/sdap_tests-data_provider_opts.Tpo -c -o src/providers/sdap_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/sdap_tests-data_provider_opts.Tpo src/providers/$(DEPDIR)/sdap_tests-data_provider_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_opts.c' object='src/providers/sdap_tests-data_provider_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/sdap_tests-data_provider_opts.obj `if test -f 'src/providers/data_provider_opts.c'; then $(CYGPATH_W) 'src/providers/data_provider_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_opts.c'; fi` src/providers/ldap/sdap_tests-sdap_domain.o: src/providers/ldap/sdap_domain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/sdap_tests-sdap_domain.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_domain.Tpo -c -o src/providers/ldap/sdap_tests-sdap_domain.o `test -f 'src/providers/ldap/sdap_domain.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_domain.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_domain.Tpo src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_domain.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_domain.c' object='src/providers/ldap/sdap_tests-sdap_domain.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/sdap_tests-sdap_domain.o `test -f 'src/providers/ldap/sdap_domain.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_domain.c src/providers/ldap/sdap_tests-sdap_domain.obj: src/providers/ldap/sdap_domain.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/sdap_tests-sdap_domain.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_domain.Tpo -c -o src/providers/ldap/sdap_tests-sdap_domain.obj `if test -f 'src/providers/ldap/sdap_domain.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_domain.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_domain.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_domain.Tpo src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_domain.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_domain.c' object='src/providers/ldap/sdap_tests-sdap_domain.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/sdap_tests-sdap_domain.obj `if test -f 'src/providers/ldap/sdap_domain.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_domain.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_domain.c'; fi` src/providers/ldap/sdap_tests-sdap.o: src/providers/ldap/sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/sdap_tests-sdap.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/sdap_tests-sdap.Tpo -c -o src/providers/ldap/sdap_tests-sdap.o `test -f 'src/providers/ldap/sdap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/sdap_tests-sdap.Tpo src/providers/ldap/$(DEPDIR)/sdap_tests-sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap.c' object='src/providers/ldap/sdap_tests-sdap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/sdap_tests-sdap.o `test -f 'src/providers/ldap/sdap.c' || echo '$(srcdir)/'`src/providers/ldap/sdap.c src/providers/ldap/sdap_tests-sdap.obj: src/providers/ldap/sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/sdap_tests-sdap.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/sdap_tests-sdap.Tpo -c -o src/providers/ldap/sdap_tests-sdap.obj `if test -f 'src/providers/ldap/sdap.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/sdap_tests-sdap.Tpo src/providers/ldap/$(DEPDIR)/sdap_tests-sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap.c' object='src/providers/ldap/sdap_tests-sdap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/sdap_tests-sdap.obj `if test -f 'src/providers/ldap/sdap.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap.c'; fi` src/providers/ldap/sdap_tests-sdap_range.o: src/providers/ldap/sdap_range.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/sdap_tests-sdap_range.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_range.Tpo -c -o src/providers/ldap/sdap_tests-sdap_range.o `test -f 'src/providers/ldap/sdap_range.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_range.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_range.Tpo src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_range.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_range.c' object='src/providers/ldap/sdap_tests-sdap_range.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/sdap_tests-sdap_range.o `test -f 'src/providers/ldap/sdap_range.c' || echo '$(srcdir)/'`src/providers/ldap/sdap_range.c src/providers/ldap/sdap_tests-sdap_range.obj: src/providers/ldap/sdap_range.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/sdap_tests-sdap_range.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_range.Tpo -c -o src/providers/ldap/sdap_tests-sdap_range.obj `if test -f 'src/providers/ldap/sdap_range.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_range.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_range.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_range.Tpo src/providers/ldap/$(DEPDIR)/sdap_tests-sdap_range.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/sdap_range.c' object='src/providers/ldap/sdap_tests-sdap_range.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/sdap_tests-sdap_range.obj `if test -f 'src/providers/ldap/sdap_range.c'; then $(CYGPATH_W) 'src/providers/ldap/sdap_range.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/sdap_range.c'; fi` src/providers/ldap/sdap_tests-ldap_opts.o: src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/sdap_tests-ldap_opts.o -MD -MP -MF src/providers/ldap/$(DEPDIR)/sdap_tests-ldap_opts.Tpo -c -o src/providers/ldap/sdap_tests-ldap_opts.o `test -f 'src/providers/ldap/ldap_opts.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/sdap_tests-ldap_opts.Tpo src/providers/ldap/$(DEPDIR)/sdap_tests-ldap_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_opts.c' object='src/providers/ldap/sdap_tests-ldap_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/sdap_tests-ldap_opts.o `test -f 'src/providers/ldap/ldap_opts.c' || echo '$(srcdir)/'`src/providers/ldap/ldap_opts.c src/providers/ldap/sdap_tests-ldap_opts.obj: src/providers/ldap/ldap_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/ldap/sdap_tests-ldap_opts.obj -MD -MP -MF src/providers/ldap/$(DEPDIR)/sdap_tests-ldap_opts.Tpo -c -o src/providers/ldap/sdap_tests-ldap_opts.obj `if test -f 'src/providers/ldap/ldap_opts.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ldap/$(DEPDIR)/sdap_tests-ldap_opts.Tpo src/providers/ldap/$(DEPDIR)/sdap_tests-ldap_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ldap/ldap_opts.c' object='src/providers/ldap/sdap_tests-ldap_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ldap/sdap_tests-ldap_opts.obj `if test -f 'src/providers/ldap/ldap_opts.c'; then $(CYGPATH_W) 'src/providers/ldap/ldap_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ldap/ldap_opts.c'; fi` src/providers/ipa/sdap_tests-ipa_opts.o: src/providers/ipa/ipa_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/ipa/sdap_tests-ipa_opts.o -MD -MP -MF src/providers/ipa/$(DEPDIR)/sdap_tests-ipa_opts.Tpo -c -o src/providers/ipa/sdap_tests-ipa_opts.o `test -f 'src/providers/ipa/ipa_opts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/sdap_tests-ipa_opts.Tpo src/providers/ipa/$(DEPDIR)/sdap_tests-ipa_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_opts.c' object='src/providers/ipa/sdap_tests-ipa_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/sdap_tests-ipa_opts.o `test -f 'src/providers/ipa/ipa_opts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_opts.c src/providers/ipa/sdap_tests-ipa_opts.obj: src/providers/ipa/ipa_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/providers/ipa/sdap_tests-ipa_opts.obj -MD -MP -MF src/providers/ipa/$(DEPDIR)/sdap_tests-ipa_opts.Tpo -c -o src/providers/ipa/sdap_tests-ipa_opts.obj `if test -f 'src/providers/ipa/ipa_opts.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/sdap_tests-ipa_opts.Tpo src/providers/ipa/$(DEPDIR)/sdap_tests-ipa_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_opts.c' object='src/providers/ipa/sdap_tests-ipa_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/sdap_tests-ipa_opts.obj `if test -f 'src/providers/ipa/ipa_opts.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_opts.c'; fi` src/util/sdap_tests-sss_ldap.o: src/util/sss_ldap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/util/sdap_tests-sss_ldap.o -MD -MP -MF src/util/$(DEPDIR)/sdap_tests-sss_ldap.Tpo -c -o src/util/sdap_tests-sss_ldap.o `test -f 'src/util/sss_ldap.c' || echo '$(srcdir)/'`src/util/sss_ldap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sdap_tests-sss_ldap.Tpo src/util/$(DEPDIR)/sdap_tests-sss_ldap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_ldap.c' object='src/util/sdap_tests-sss_ldap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/util/sdap_tests-sss_ldap.o `test -f 'src/util/sss_ldap.c' || echo '$(srcdir)/'`src/util/sss_ldap.c src/util/sdap_tests-sss_ldap.obj: src/util/sss_ldap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/util/sdap_tests-sss_ldap.obj -MD -MP -MF src/util/$(DEPDIR)/sdap_tests-sss_ldap.Tpo -c -o src/util/sdap_tests-sss_ldap.obj `if test -f 'src/util/sss_ldap.c'; then $(CYGPATH_W) 'src/util/sss_ldap.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_ldap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sdap_tests-sss_ldap.Tpo src/util/$(DEPDIR)/sdap_tests-sss_ldap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_ldap.c' object='src/util/sdap_tests-sss_ldap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/util/sdap_tests-sss_ldap.obj `if test -f 'src/util/sss_ldap.c'; then $(CYGPATH_W) 'src/util/sss_ldap.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_ldap.c'; fi` src/tests/cmocka/sdap_tests-test_sdap.o: src/tests/cmocka/test_sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/sdap_tests-test_sdap.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/sdap_tests-test_sdap.Tpo -c -o src/tests/cmocka/sdap_tests-test_sdap.o `test -f 'src/tests/cmocka/test_sdap.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sdap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/sdap_tests-test_sdap.Tpo src/tests/cmocka/$(DEPDIR)/sdap_tests-test_sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sdap.c' object='src/tests/cmocka/sdap_tests-test_sdap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/sdap_tests-test_sdap.o `test -f 'src/tests/cmocka/test_sdap.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sdap.c src/tests/cmocka/sdap_tests-test_sdap.obj: src/tests/cmocka/test_sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/sdap_tests-test_sdap.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/sdap_tests-test_sdap.Tpo -c -o src/tests/cmocka/sdap_tests-test_sdap.obj `if test -f 'src/tests/cmocka/test_sdap.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sdap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/sdap_tests-test_sdap.Tpo src/tests/cmocka/$(DEPDIR)/sdap_tests-test_sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sdap.c' object='src/tests/cmocka/sdap_tests-test_sdap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sdap_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/sdap_tests-test_sdap.obj `if test -f 'src/tests/cmocka/test_sdap.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sdap.c'; fi` src/providers/ipa/selinux_child-selinux_child.o: src/providers/ipa/selinux_child.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -MT src/providers/ipa/selinux_child-selinux_child.o -MD -MP -MF src/providers/ipa/$(DEPDIR)/selinux_child-selinux_child.Tpo -c -o src/providers/ipa/selinux_child-selinux_child.o `test -f 'src/providers/ipa/selinux_child.c' || echo '$(srcdir)/'`src/providers/ipa/selinux_child.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/selinux_child-selinux_child.Tpo src/providers/ipa/$(DEPDIR)/selinux_child-selinux_child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/selinux_child.c' object='src/providers/ipa/selinux_child-selinux_child.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/selinux_child-selinux_child.o `test -f 'src/providers/ipa/selinux_child.c' || echo '$(srcdir)/'`src/providers/ipa/selinux_child.c src/providers/ipa/selinux_child-selinux_child.obj: src/providers/ipa/selinux_child.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -MT src/providers/ipa/selinux_child-selinux_child.obj -MD -MP -MF src/providers/ipa/$(DEPDIR)/selinux_child-selinux_child.Tpo -c -o src/providers/ipa/selinux_child-selinux_child.obj `if test -f 'src/providers/ipa/selinux_child.c'; then $(CYGPATH_W) 'src/providers/ipa/selinux_child.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/selinux_child.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/selinux_child-selinux_child.Tpo src/providers/ipa/$(DEPDIR)/selinux_child-selinux_child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/selinux_child.c' object='src/providers/ipa/selinux_child-selinux_child.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/selinux_child-selinux_child.obj `if test -f 'src/providers/ipa/selinux_child.c'; then $(CYGPATH_W) 'src/providers/ipa/selinux_child.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/selinux_child.c'; fi` src/util/selinux_child-sss_semanage.o: src/util/sss_semanage.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -MT src/util/selinux_child-sss_semanage.o -MD -MP -MF src/util/$(DEPDIR)/selinux_child-sss_semanage.Tpo -c -o src/util/selinux_child-sss_semanage.o `test -f 'src/util/sss_semanage.c' || echo '$(srcdir)/'`src/util/sss_semanage.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/selinux_child-sss_semanage.Tpo src/util/$(DEPDIR)/selinux_child-sss_semanage.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_semanage.c' object='src/util/selinux_child-sss_semanage.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -c -o src/util/selinux_child-sss_semanage.o `test -f 'src/util/sss_semanage.c' || echo '$(srcdir)/'`src/util/sss_semanage.c src/util/selinux_child-sss_semanage.obj: src/util/sss_semanage.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -MT src/util/selinux_child-sss_semanage.obj -MD -MP -MF src/util/$(DEPDIR)/selinux_child-sss_semanage.Tpo -c -o src/util/selinux_child-sss_semanage.obj `if test -f 'src/util/sss_semanage.c'; then $(CYGPATH_W) 'src/util/sss_semanage.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_semanage.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/selinux_child-sss_semanage.Tpo src/util/$(DEPDIR)/selinux_child-sss_semanage.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_semanage.c' object='src/util/selinux_child-sss_semanage.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -c -o src/util/selinux_child-sss_semanage.obj `if test -f 'src/util/sss_semanage.c'; then $(CYGPATH_W) 'src/util/sss_semanage.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_semanage.c'; fi` src/util/selinux_child-atomic_io.o: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -MT src/util/selinux_child-atomic_io.o -MD -MP -MF src/util/$(DEPDIR)/selinux_child-atomic_io.Tpo -c -o src/util/selinux_child-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/selinux_child-atomic_io.Tpo src/util/$(DEPDIR)/selinux_child-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/selinux_child-atomic_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -c -o src/util/selinux_child-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c src/util/selinux_child-atomic_io.obj: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -MT src/util/selinux_child-atomic_io.obj -MD -MP -MF src/util/$(DEPDIR)/selinux_child-atomic_io.Tpo -c -o src/util/selinux_child-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/selinux_child-atomic_io.Tpo src/util/$(DEPDIR)/selinux_child-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/selinux_child-atomic_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -c -o src/util/selinux_child-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` src/util/selinux_child-util.o: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -MT src/util/selinux_child-util.o -MD -MP -MF src/util/$(DEPDIR)/selinux_child-util.Tpo -c -o src/util/selinux_child-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/selinux_child-util.Tpo src/util/$(DEPDIR)/selinux_child-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/selinux_child-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -c -o src/util/selinux_child-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c src/util/selinux_child-util.obj: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -MT src/util/selinux_child-util.obj -MD -MP -MF src/util/$(DEPDIR)/selinux_child-util.Tpo -c -o src/util/selinux_child-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/selinux_child-util.Tpo src/util/$(DEPDIR)/selinux_child-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/selinux_child-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(selinux_child_CFLAGS) $(CFLAGS) -c -o src/util/selinux_child-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` src/tools/sss_cache-sss_cache.o: src/tools/sss_cache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-sss_cache.o -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-sss_cache.Tpo -c -o src/tools/sss_cache-sss_cache.o `test -f 'src/tools/sss_cache.c' || echo '$(srcdir)/'`src/tools/sss_cache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-sss_cache.Tpo src/tools/$(DEPDIR)/sss_cache-sss_cache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_cache.c' object='src/tools/sss_cache-sss_cache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-sss_cache.o `test -f 'src/tools/sss_cache.c' || echo '$(srcdir)/'`src/tools/sss_cache.c src/tools/sss_cache-sss_cache.obj: src/tools/sss_cache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-sss_cache.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-sss_cache.Tpo -c -o src/tools/sss_cache-sss_cache.obj `if test -f 'src/tools/sss_cache.c'; then $(CYGPATH_W) 'src/tools/sss_cache.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_cache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-sss_cache.Tpo src/tools/$(DEPDIR)/sss_cache-sss_cache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_cache.c' object='src/tools/sss_cache-sss_cache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-sss_cache.obj `if test -f 'src/tools/sss_cache.c'; then $(CYGPATH_W) 'src/tools/sss_cache.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_cache.c'; fi` src/sss_client/sss_cache-common.o: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_cache-common.o -MD -MP -MF src/sss_client/$(DEPDIR)/sss_cache-common.Tpo -c -o src/sss_client/sss_cache-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_cache-common.Tpo src/sss_client/$(DEPDIR)/sss_cache-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_cache-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_cache-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/sss_cache-common.obj: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_cache-common.obj -MD -MP -MF src/sss_client/$(DEPDIR)/sss_cache-common.Tpo -c -o src/sss_client/sss_cache-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_cache-common.Tpo src/sss_client/$(DEPDIR)/sss_cache-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_cache-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_cache-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` src/tools/sss_cache-tools_mc_util.o: src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-tools_mc_util.o -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-tools_mc_util.Tpo -c -o src/tools/sss_cache-tools_mc_util.o `test -f 'src/tools/tools_mc_util.c' || echo '$(srcdir)/'`src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-tools_mc_util.Tpo src/tools/$(DEPDIR)/sss_cache-tools_mc_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_mc_util.c' object='src/tools/sss_cache-tools_mc_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-tools_mc_util.o `test -f 'src/tools/tools_mc_util.c' || echo '$(srcdir)/'`src/tools/tools_mc_util.c src/tools/sss_cache-tools_mc_util.obj: src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-tools_mc_util.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-tools_mc_util.Tpo -c -o src/tools/sss_cache-tools_mc_util.obj `if test -f 'src/tools/tools_mc_util.c'; then $(CYGPATH_W) 'src/tools/tools_mc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_mc_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-tools_mc_util.Tpo src/tools/$(DEPDIR)/sss_cache-tools_mc_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_mc_util.c' object='src/tools/sss_cache-tools_mc_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-tools_mc_util.obj `if test -f 'src/tools/tools_mc_util.c'; then $(CYGPATH_W) 'src/tools/tools_mc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_mc_util.c'; fi` src/tools/sss_cache-sss_sync_ops.o: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-sss_sync_ops.o -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-sss_sync_ops.Tpo -c -o src/tools/sss_cache-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_cache-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_cache-sss_sync_ops.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c src/tools/sss_cache-sss_sync_ops.obj: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-sss_sync_ops.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-sss_sync_ops.Tpo -c -o src/tools/sss_cache-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_cache-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_cache-sss_sync_ops.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` src/tools/sss_cache-tools_util.o: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-tools_util.o -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-tools_util.Tpo -c -o src/tools/sss_cache-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-tools_util.Tpo src/tools/$(DEPDIR)/sss_cache-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_cache-tools_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c src/tools/sss_cache-tools_util.obj: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-tools_util.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-tools_util.Tpo -c -o src/tools/sss_cache-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-tools_util.Tpo src/tools/$(DEPDIR)/sss_cache-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_cache-tools_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` src/tools/sss_cache-files.o: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-files.o -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-files.Tpo -c -o src/tools/sss_cache-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-files.Tpo src/tools/$(DEPDIR)/sss_cache-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_cache-files.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c src/tools/sss_cache-files.obj: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-files.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-files.Tpo -c -o src/tools/sss_cache-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-files.Tpo src/tools/$(DEPDIR)/sss_cache-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_cache-files.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` src/tools/sss_cache-selinux.o: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-selinux.o -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-selinux.Tpo -c -o src/tools/sss_cache-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-selinux.Tpo src/tools/$(DEPDIR)/sss_cache-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_cache-selinux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c src/tools/sss_cache-selinux.obj: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/sss_cache-selinux.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_cache-selinux.Tpo -c -o src/tools/sss_cache-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_cache-selinux.Tpo src/tools/$(DEPDIR)/sss_cache-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_cache-selinux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/sss_cache-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` src/tools/common/sss_cache-sss_tools.o: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_cache-sss_tools.o -MD -MP -MF src/tools/common/$(DEPDIR)/sss_cache-sss_tools.Tpo -c -o src/tools/common/sss_cache-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_cache-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_cache-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_cache-sss_tools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_cache-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c src/tools/common/sss_cache-sss_tools.obj: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_cache-sss_tools.obj -MD -MP -MF src/tools/common/$(DEPDIR)/sss_cache-sss_tools.Tpo -c -o src/tools/common/sss_cache-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_cache-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_cache-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_cache-sss_tools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_cache-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` src/util/sss_cache-nscd.o: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/util/sss_cache-nscd.o -MD -MP -MF src/util/$(DEPDIR)/sss_cache-nscd.Tpo -c -o src/util/sss_cache-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_cache-nscd.Tpo src/util/$(DEPDIR)/sss_cache-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_cache-nscd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/util/sss_cache-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c src/util/sss_cache-nscd.obj: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -MT src/util/sss_cache-nscd.obj -MD -MP -MF src/util/$(DEPDIR)/sss_cache-nscd.Tpo -c -o src/util/sss_cache-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_cache-nscd.Tpo src/util/$(DEPDIR)/sss_cache-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_cache-nscd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_cache_CFLAGS) $(CFLAGS) -c -o src/util/sss_cache-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` src/tests/sss_config_tests-sss_config-tests.o: src/tests/sss_config-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_config_tests_CFLAGS) $(CFLAGS) -MT src/tests/sss_config_tests-sss_config-tests.o -MD -MP -MF src/tests/$(DEPDIR)/sss_config_tests-sss_config-tests.Tpo -c -o src/tests/sss_config_tests-sss_config-tests.o `test -f 'src/tests/sss_config-tests.c' || echo '$(srcdir)/'`src/tests/sss_config-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sss_config_tests-sss_config-tests.Tpo src/tests/$(DEPDIR)/sss_config_tests-sss_config-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sss_config-tests.c' object='src/tests/sss_config_tests-sss_config-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_config_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sss_config_tests-sss_config-tests.o `test -f 'src/tests/sss_config-tests.c' || echo '$(srcdir)/'`src/tests/sss_config-tests.c src/tests/sss_config_tests-sss_config-tests.obj: src/tests/sss_config-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_config_tests_CFLAGS) $(CFLAGS) -MT src/tests/sss_config_tests-sss_config-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/sss_config_tests-sss_config-tests.Tpo -c -o src/tests/sss_config_tests-sss_config-tests.obj `if test -f 'src/tests/sss_config-tests.c'; then $(CYGPATH_W) 'src/tests/sss_config-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sss_config-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sss_config_tests-sss_config-tests.Tpo src/tests/$(DEPDIR)/sss_config_tests-sss_config-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sss_config-tests.c' object='src/tests/sss_config_tests-sss_config-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_config_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sss_config_tests-sss_config-tests.obj `if test -f 'src/tests/sss_config-tests.c'; then $(CYGPATH_W) 'src/tests/sss_config-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sss_config-tests.c'; fi` src/tests/sss_config_tests-common.o: src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_config_tests_CFLAGS) $(CFLAGS) -MT src/tests/sss_config_tests-common.o -MD -MP -MF src/tests/$(DEPDIR)/sss_config_tests-common.Tpo -c -o src/tests/sss_config_tests-common.o `test -f 'src/tests/common.c' || echo '$(srcdir)/'`src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sss_config_tests-common.Tpo src/tests/$(DEPDIR)/sss_config_tests-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common.c' object='src/tests/sss_config_tests-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_config_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sss_config_tests-common.o `test -f 'src/tests/common.c' || echo '$(srcdir)/'`src/tests/common.c src/tests/sss_config_tests-common.obj: src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_config_tests_CFLAGS) $(CFLAGS) -MT src/tests/sss_config_tests-common.obj -MD -MP -MF src/tests/$(DEPDIR)/sss_config_tests-common.Tpo -c -o src/tests/sss_config_tests-common.obj `if test -f 'src/tests/common.c'; then $(CYGPATH_W) 'src/tests/common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sss_config_tests-common.Tpo src/tests/$(DEPDIR)/sss_config_tests-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common.c' object='src/tests/sss_config_tests-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_config_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sss_config_tests-common.obj `if test -f 'src/tests/common.c'; then $(CYGPATH_W) 'src/tests/common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common.c'; fi` src/tools/sss_groupdel-sss_groupdel.o: src/tools/sss_groupdel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-sss_groupdel.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-sss_groupdel.Tpo -c -o src/tools/sss_groupdel-sss_groupdel.o `test -f 'src/tools/sss_groupdel.c' || echo '$(srcdir)/'`src/tools/sss_groupdel.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-sss_groupdel.Tpo src/tools/$(DEPDIR)/sss_groupdel-sss_groupdel.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_groupdel.c' object='src/tools/sss_groupdel-sss_groupdel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-sss_groupdel.o `test -f 'src/tools/sss_groupdel.c' || echo '$(srcdir)/'`src/tools/sss_groupdel.c src/tools/sss_groupdel-sss_groupdel.obj: src/tools/sss_groupdel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-sss_groupdel.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-sss_groupdel.Tpo -c -o src/tools/sss_groupdel-sss_groupdel.obj `if test -f 'src/tools/sss_groupdel.c'; then $(CYGPATH_W) 'src/tools/sss_groupdel.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_groupdel.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-sss_groupdel.Tpo src/tools/$(DEPDIR)/sss_groupdel-sss_groupdel.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_groupdel.c' object='src/tools/sss_groupdel-sss_groupdel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-sss_groupdel.obj `if test -f 'src/tools/sss_groupdel.c'; then $(CYGPATH_W) 'src/tools/sss_groupdel.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_groupdel.c'; fi` src/sss_client/sss_groupdel-common.o: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_groupdel-common.o -MD -MP -MF src/sss_client/$(DEPDIR)/sss_groupdel-common.Tpo -c -o src/sss_client/sss_groupdel-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_groupdel-common.Tpo src/sss_client/$(DEPDIR)/sss_groupdel-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_groupdel-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_groupdel-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/sss_groupdel-common.obj: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_groupdel-common.obj -MD -MP -MF src/sss_client/$(DEPDIR)/sss_groupdel-common.Tpo -c -o src/sss_client/sss_groupdel-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_groupdel-common.Tpo src/sss_client/$(DEPDIR)/sss_groupdel-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_groupdel-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_groupdel-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` src/tools/sss_groupdel-tools_mc_util.o: src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-tools_mc_util.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-tools_mc_util.Tpo -c -o src/tools/sss_groupdel-tools_mc_util.o `test -f 'src/tools/tools_mc_util.c' || echo '$(srcdir)/'`src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-tools_mc_util.Tpo src/tools/$(DEPDIR)/sss_groupdel-tools_mc_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_mc_util.c' object='src/tools/sss_groupdel-tools_mc_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-tools_mc_util.o `test -f 'src/tools/tools_mc_util.c' || echo '$(srcdir)/'`src/tools/tools_mc_util.c src/tools/sss_groupdel-tools_mc_util.obj: src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-tools_mc_util.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-tools_mc_util.Tpo -c -o src/tools/sss_groupdel-tools_mc_util.obj `if test -f 'src/tools/tools_mc_util.c'; then $(CYGPATH_W) 'src/tools/tools_mc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_mc_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-tools_mc_util.Tpo src/tools/$(DEPDIR)/sss_groupdel-tools_mc_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_mc_util.c' object='src/tools/sss_groupdel-tools_mc_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-tools_mc_util.obj `if test -f 'src/tools/tools_mc_util.c'; then $(CYGPATH_W) 'src/tools/tools_mc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_mc_util.c'; fi` src/tools/sss_groupdel-sss_sync_ops.o: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-sss_sync_ops.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-sss_sync_ops.Tpo -c -o src/tools/sss_groupdel-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_groupdel-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_groupdel-sss_sync_ops.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c src/tools/sss_groupdel-sss_sync_ops.obj: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-sss_sync_ops.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-sss_sync_ops.Tpo -c -o src/tools/sss_groupdel-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_groupdel-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_groupdel-sss_sync_ops.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` src/tools/sss_groupdel-tools_util.o: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-tools_util.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-tools_util.Tpo -c -o src/tools/sss_groupdel-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-tools_util.Tpo src/tools/$(DEPDIR)/sss_groupdel-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_groupdel-tools_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c src/tools/sss_groupdel-tools_util.obj: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-tools_util.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-tools_util.Tpo -c -o src/tools/sss_groupdel-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-tools_util.Tpo src/tools/$(DEPDIR)/sss_groupdel-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_groupdel-tools_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` src/tools/sss_groupdel-files.o: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-files.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-files.Tpo -c -o src/tools/sss_groupdel-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-files.Tpo src/tools/$(DEPDIR)/sss_groupdel-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_groupdel-files.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c src/tools/sss_groupdel-files.obj: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-files.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-files.Tpo -c -o src/tools/sss_groupdel-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-files.Tpo src/tools/$(DEPDIR)/sss_groupdel-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_groupdel-files.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` src/tools/sss_groupdel-selinux.o: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-selinux.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-selinux.Tpo -c -o src/tools/sss_groupdel-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-selinux.Tpo src/tools/$(DEPDIR)/sss_groupdel-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_groupdel-selinux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c src/tools/sss_groupdel-selinux.obj: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupdel-selinux.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupdel-selinux.Tpo -c -o src/tools/sss_groupdel-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupdel-selinux.Tpo src/tools/$(DEPDIR)/sss_groupdel-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_groupdel-selinux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupdel-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` src/tools/common/sss_groupdel-sss_tools.o: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_groupdel-sss_tools.o -MD -MP -MF src/tools/common/$(DEPDIR)/sss_groupdel-sss_tools.Tpo -c -o src/tools/common/sss_groupdel-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_groupdel-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_groupdel-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_groupdel-sss_tools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_groupdel-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c src/tools/common/sss_groupdel-sss_tools.obj: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_groupdel-sss_tools.obj -MD -MP -MF src/tools/common/$(DEPDIR)/sss_groupdel-sss_tools.Tpo -c -o src/tools/common/sss_groupdel-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_groupdel-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_groupdel-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_groupdel-sss_tools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_groupdel-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` src/util/sss_groupdel-nscd.o: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/util/sss_groupdel-nscd.o -MD -MP -MF src/util/$(DEPDIR)/sss_groupdel-nscd.Tpo -c -o src/util/sss_groupdel-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_groupdel-nscd.Tpo src/util/$(DEPDIR)/sss_groupdel-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_groupdel-nscd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/util/sss_groupdel-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c src/util/sss_groupdel-nscd.obj: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -MT src/util/sss_groupdel-nscd.obj -MD -MP -MF src/util/$(DEPDIR)/sss_groupdel-nscd.Tpo -c -o src/util/sss_groupdel-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_groupdel-nscd.Tpo src/util/$(DEPDIR)/sss_groupdel-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_groupdel-nscd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupdel_CFLAGS) $(CFLAGS) -c -o src/util/sss_groupdel-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` src/tools/sss_groupmod-sss_groupmod.o: src/tools/sss_groupmod.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-sss_groupmod.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-sss_groupmod.Tpo -c -o src/tools/sss_groupmod-sss_groupmod.o `test -f 'src/tools/sss_groupmod.c' || echo '$(srcdir)/'`src/tools/sss_groupmod.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-sss_groupmod.Tpo src/tools/$(DEPDIR)/sss_groupmod-sss_groupmod.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_groupmod.c' object='src/tools/sss_groupmod-sss_groupmod.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-sss_groupmod.o `test -f 'src/tools/sss_groupmod.c' || echo '$(srcdir)/'`src/tools/sss_groupmod.c src/tools/sss_groupmod-sss_groupmod.obj: src/tools/sss_groupmod.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-sss_groupmod.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-sss_groupmod.Tpo -c -o src/tools/sss_groupmod-sss_groupmod.obj `if test -f 'src/tools/sss_groupmod.c'; then $(CYGPATH_W) 'src/tools/sss_groupmod.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_groupmod.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-sss_groupmod.Tpo src/tools/$(DEPDIR)/sss_groupmod-sss_groupmod.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_groupmod.c' object='src/tools/sss_groupmod-sss_groupmod.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-sss_groupmod.obj `if test -f 'src/tools/sss_groupmod.c'; then $(CYGPATH_W) 'src/tools/sss_groupmod.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_groupmod.c'; fi` src/sss_client/sss_groupmod-common.o: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_groupmod-common.o -MD -MP -MF src/sss_client/$(DEPDIR)/sss_groupmod-common.Tpo -c -o src/sss_client/sss_groupmod-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_groupmod-common.Tpo src/sss_client/$(DEPDIR)/sss_groupmod-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_groupmod-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_groupmod-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/sss_groupmod-common.obj: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_groupmod-common.obj -MD -MP -MF src/sss_client/$(DEPDIR)/sss_groupmod-common.Tpo -c -o src/sss_client/sss_groupmod-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_groupmod-common.Tpo src/sss_client/$(DEPDIR)/sss_groupmod-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_groupmod-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_groupmod-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` src/tools/sss_groupmod-tools_mc_util.o: src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-tools_mc_util.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-tools_mc_util.Tpo -c -o src/tools/sss_groupmod-tools_mc_util.o `test -f 'src/tools/tools_mc_util.c' || echo '$(srcdir)/'`src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-tools_mc_util.Tpo src/tools/$(DEPDIR)/sss_groupmod-tools_mc_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_mc_util.c' object='src/tools/sss_groupmod-tools_mc_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-tools_mc_util.o `test -f 'src/tools/tools_mc_util.c' || echo '$(srcdir)/'`src/tools/tools_mc_util.c src/tools/sss_groupmod-tools_mc_util.obj: src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-tools_mc_util.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-tools_mc_util.Tpo -c -o src/tools/sss_groupmod-tools_mc_util.obj `if test -f 'src/tools/tools_mc_util.c'; then $(CYGPATH_W) 'src/tools/tools_mc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_mc_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-tools_mc_util.Tpo src/tools/$(DEPDIR)/sss_groupmod-tools_mc_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_mc_util.c' object='src/tools/sss_groupmod-tools_mc_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-tools_mc_util.obj `if test -f 'src/tools/tools_mc_util.c'; then $(CYGPATH_W) 'src/tools/tools_mc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_mc_util.c'; fi` src/tools/sss_groupmod-sss_sync_ops.o: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-sss_sync_ops.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-sss_sync_ops.Tpo -c -o src/tools/sss_groupmod-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_groupmod-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_groupmod-sss_sync_ops.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c src/tools/sss_groupmod-sss_sync_ops.obj: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-sss_sync_ops.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-sss_sync_ops.Tpo -c -o src/tools/sss_groupmod-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_groupmod-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_groupmod-sss_sync_ops.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` src/tools/sss_groupmod-tools_util.o: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-tools_util.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-tools_util.Tpo -c -o src/tools/sss_groupmod-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-tools_util.Tpo src/tools/$(DEPDIR)/sss_groupmod-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_groupmod-tools_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c src/tools/sss_groupmod-tools_util.obj: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-tools_util.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-tools_util.Tpo -c -o src/tools/sss_groupmod-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-tools_util.Tpo src/tools/$(DEPDIR)/sss_groupmod-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_groupmod-tools_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` src/tools/sss_groupmod-files.o: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-files.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-files.Tpo -c -o src/tools/sss_groupmod-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-files.Tpo src/tools/$(DEPDIR)/sss_groupmod-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_groupmod-files.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c src/tools/sss_groupmod-files.obj: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-files.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-files.Tpo -c -o src/tools/sss_groupmod-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-files.Tpo src/tools/$(DEPDIR)/sss_groupmod-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_groupmod-files.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` src/tools/sss_groupmod-selinux.o: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-selinux.o -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-selinux.Tpo -c -o src/tools/sss_groupmod-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-selinux.Tpo src/tools/$(DEPDIR)/sss_groupmod-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_groupmod-selinux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c src/tools/sss_groupmod-selinux.obj: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/sss_groupmod-selinux.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_groupmod-selinux.Tpo -c -o src/tools/sss_groupmod-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_groupmod-selinux.Tpo src/tools/$(DEPDIR)/sss_groupmod-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_groupmod-selinux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_groupmod-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` src/tools/common/sss_groupmod-sss_tools.o: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_groupmod-sss_tools.o -MD -MP -MF src/tools/common/$(DEPDIR)/sss_groupmod-sss_tools.Tpo -c -o src/tools/common/sss_groupmod-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_groupmod-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_groupmod-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_groupmod-sss_tools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_groupmod-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c src/tools/common/sss_groupmod-sss_tools.obj: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_groupmod-sss_tools.obj -MD -MP -MF src/tools/common/$(DEPDIR)/sss_groupmod-sss_tools.Tpo -c -o src/tools/common/sss_groupmod-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_groupmod-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_groupmod-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_groupmod-sss_tools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_groupmod-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` src/util/sss_groupmod-nscd.o: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/util/sss_groupmod-nscd.o -MD -MP -MF src/util/$(DEPDIR)/sss_groupmod-nscd.Tpo -c -o src/util/sss_groupmod-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_groupmod-nscd.Tpo src/util/$(DEPDIR)/sss_groupmod-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_groupmod-nscd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/util/sss_groupmod-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c src/util/sss_groupmod-nscd.obj: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -MT src/util/sss_groupmod-nscd.obj -MD -MP -MF src/util/$(DEPDIR)/sss_groupmod-nscd.Tpo -c -o src/util/sss_groupmod-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_groupmod-nscd.Tpo src/util/$(DEPDIR)/sss_groupmod-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_groupmod-nscd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_groupmod_CFLAGS) $(CFLAGS) -c -o src/util/sss_groupmod-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` src/tests/sss_idmap_tests-sss_idmap-tests.o: src/tests/sss_idmap-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_idmap_tests_CFLAGS) $(CFLAGS) -MT src/tests/sss_idmap_tests-sss_idmap-tests.o -MD -MP -MF src/tests/$(DEPDIR)/sss_idmap_tests-sss_idmap-tests.Tpo -c -o src/tests/sss_idmap_tests-sss_idmap-tests.o `test -f 'src/tests/sss_idmap-tests.c' || echo '$(srcdir)/'`src/tests/sss_idmap-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sss_idmap_tests-sss_idmap-tests.Tpo src/tests/$(DEPDIR)/sss_idmap_tests-sss_idmap-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sss_idmap-tests.c' object='src/tests/sss_idmap_tests-sss_idmap-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_idmap_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sss_idmap_tests-sss_idmap-tests.o `test -f 'src/tests/sss_idmap-tests.c' || echo '$(srcdir)/'`src/tests/sss_idmap-tests.c src/tests/sss_idmap_tests-sss_idmap-tests.obj: src/tests/sss_idmap-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_idmap_tests_CFLAGS) $(CFLAGS) -MT src/tests/sss_idmap_tests-sss_idmap-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/sss_idmap_tests-sss_idmap-tests.Tpo -c -o src/tests/sss_idmap_tests-sss_idmap-tests.obj `if test -f 'src/tests/sss_idmap-tests.c'; then $(CYGPATH_W) 'src/tests/sss_idmap-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sss_idmap-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sss_idmap_tests-sss_idmap-tests.Tpo src/tests/$(DEPDIR)/sss_idmap_tests-sss_idmap-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sss_idmap-tests.c' object='src/tests/sss_idmap_tests-sss_idmap-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_idmap_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sss_idmap_tests-sss_idmap-tests.obj `if test -f 'src/tests/sss_idmap-tests.c'; then $(CYGPATH_W) 'src/tests/sss_idmap-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sss_idmap-tests.c'; fi` src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.o: src/tests/cmocka/sss_nss_idmap-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_nss_idmap_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/sss_nss_idmap_tests-sss_nss_idmap-tests.Tpo -c -o src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.o `test -f 'src/tests/cmocka/sss_nss_idmap-tests.c' || echo '$(srcdir)/'`src/tests/cmocka/sss_nss_idmap-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/sss_nss_idmap_tests-sss_nss_idmap-tests.Tpo src/tests/cmocka/$(DEPDIR)/sss_nss_idmap_tests-sss_nss_idmap-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/sss_nss_idmap-tests.c' object='src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_nss_idmap_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.o `test -f 'src/tests/cmocka/sss_nss_idmap-tests.c' || echo '$(srcdir)/'`src/tests/cmocka/sss_nss_idmap-tests.c src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.obj: src/tests/cmocka/sss_nss_idmap-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_nss_idmap_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/sss_nss_idmap_tests-sss_nss_idmap-tests.Tpo -c -o src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.obj `if test -f 'src/tests/cmocka/sss_nss_idmap-tests.c'; then $(CYGPATH_W) 'src/tests/cmocka/sss_nss_idmap-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/sss_nss_idmap-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/sss_nss_idmap_tests-sss_nss_idmap-tests.Tpo src/tests/cmocka/$(DEPDIR)/sss_nss_idmap_tests-sss_nss_idmap-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/sss_nss_idmap-tests.c' object='src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_nss_idmap_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/sss_nss_idmap_tests-sss_nss_idmap-tests.obj `if test -f 'src/tests/cmocka/sss_nss_idmap-tests.c'; then $(CYGPATH_W) 'src/tests/cmocka/sss_nss_idmap-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/sss_nss_idmap-tests.c'; fi` src/tools/sss_override-sss_override.o: src/tools/sss_override.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/sss_override-sss_override.o -MD -MP -MF src/tools/$(DEPDIR)/sss_override-sss_override.Tpo -c -o src/tools/sss_override-sss_override.o `test -f 'src/tools/sss_override.c' || echo '$(srcdir)/'`src/tools/sss_override.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_override-sss_override.Tpo src/tools/$(DEPDIR)/sss_override-sss_override.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_override.c' object='src/tools/sss_override-sss_override.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/sss_override-sss_override.o `test -f 'src/tools/sss_override.c' || echo '$(srcdir)/'`src/tools/sss_override.c src/tools/sss_override-sss_override.obj: src/tools/sss_override.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/sss_override-sss_override.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_override-sss_override.Tpo -c -o src/tools/sss_override-sss_override.obj `if test -f 'src/tools/sss_override.c'; then $(CYGPATH_W) 'src/tools/sss_override.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_override.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_override-sss_override.Tpo src/tools/$(DEPDIR)/sss_override-sss_override.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_override.c' object='src/tools/sss_override-sss_override.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/sss_override-sss_override.obj `if test -f 'src/tools/sss_override.c'; then $(CYGPATH_W) 'src/tools/sss_override.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_override.c'; fi` src/tools/common/sss_override-sss_colondb.o: src/tools/common/sss_colondb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_override-sss_colondb.o -MD -MP -MF src/tools/common/$(DEPDIR)/sss_override-sss_colondb.Tpo -c -o src/tools/common/sss_override-sss_colondb.o `test -f 'src/tools/common/sss_colondb.c' || echo '$(srcdir)/'`src/tools/common/sss_colondb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_override-sss_colondb.Tpo src/tools/common/$(DEPDIR)/sss_override-sss_colondb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_colondb.c' object='src/tools/common/sss_override-sss_colondb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_override-sss_colondb.o `test -f 'src/tools/common/sss_colondb.c' || echo '$(srcdir)/'`src/tools/common/sss_colondb.c src/tools/common/sss_override-sss_colondb.obj: src/tools/common/sss_colondb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_override-sss_colondb.obj -MD -MP -MF src/tools/common/$(DEPDIR)/sss_override-sss_colondb.Tpo -c -o src/tools/common/sss_override-sss_colondb.obj `if test -f 'src/tools/common/sss_colondb.c'; then $(CYGPATH_W) 'src/tools/common/sss_colondb.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_colondb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_override-sss_colondb.Tpo src/tools/common/$(DEPDIR)/sss_override-sss_colondb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_colondb.c' object='src/tools/common/sss_override-sss_colondb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_override-sss_colondb.obj `if test -f 'src/tools/common/sss_colondb.c'; then $(CYGPATH_W) 'src/tools/common/sss_colondb.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_colondb.c'; fi` src/tools/sss_override-sss_sync_ops.o: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/sss_override-sss_sync_ops.o -MD -MP -MF src/tools/$(DEPDIR)/sss_override-sss_sync_ops.Tpo -c -o src/tools/sss_override-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_override-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_override-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_override-sss_sync_ops.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/sss_override-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c src/tools/sss_override-sss_sync_ops.obj: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/sss_override-sss_sync_ops.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_override-sss_sync_ops.Tpo -c -o src/tools/sss_override-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_override-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_override-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_override-sss_sync_ops.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/sss_override-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` src/tools/sss_override-tools_util.o: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/sss_override-tools_util.o -MD -MP -MF src/tools/$(DEPDIR)/sss_override-tools_util.Tpo -c -o src/tools/sss_override-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_override-tools_util.Tpo src/tools/$(DEPDIR)/sss_override-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_override-tools_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/sss_override-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c src/tools/sss_override-tools_util.obj: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/sss_override-tools_util.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_override-tools_util.Tpo -c -o src/tools/sss_override-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_override-tools_util.Tpo src/tools/$(DEPDIR)/sss_override-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_override-tools_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/sss_override-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` src/tools/sss_override-files.o: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/sss_override-files.o -MD -MP -MF src/tools/$(DEPDIR)/sss_override-files.Tpo -c -o src/tools/sss_override-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_override-files.Tpo src/tools/$(DEPDIR)/sss_override-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_override-files.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/sss_override-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c src/tools/sss_override-files.obj: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/sss_override-files.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_override-files.Tpo -c -o src/tools/sss_override-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_override-files.Tpo src/tools/$(DEPDIR)/sss_override-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_override-files.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/sss_override-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` src/tools/sss_override-selinux.o: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/sss_override-selinux.o -MD -MP -MF src/tools/$(DEPDIR)/sss_override-selinux.Tpo -c -o src/tools/sss_override-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_override-selinux.Tpo src/tools/$(DEPDIR)/sss_override-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_override-selinux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/sss_override-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c src/tools/sss_override-selinux.obj: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/sss_override-selinux.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_override-selinux.Tpo -c -o src/tools/sss_override-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_override-selinux.Tpo src/tools/$(DEPDIR)/sss_override-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_override-selinux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/sss_override-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` src/tools/common/sss_override-sss_tools.o: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_override-sss_tools.o -MD -MP -MF src/tools/common/$(DEPDIR)/sss_override-sss_tools.Tpo -c -o src/tools/common/sss_override-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_override-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_override-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_override-sss_tools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_override-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c src/tools/common/sss_override-sss_tools.obj: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_override-sss_tools.obj -MD -MP -MF src/tools/common/$(DEPDIR)/sss_override-sss_tools.Tpo -c -o src/tools/common/sss_override-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_override-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_override-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_override-sss_tools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_override-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` src/util/sss_override-nscd.o: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/util/sss_override-nscd.o -MD -MP -MF src/util/$(DEPDIR)/sss_override-nscd.Tpo -c -o src/util/sss_override-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_override-nscd.Tpo src/util/$(DEPDIR)/sss_override-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_override-nscd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/util/sss_override-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c src/util/sss_override-nscd.obj: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -MT src/util/sss_override-nscd.obj -MD -MP -MF src/util/$(DEPDIR)/sss_override-nscd.Tpo -c -o src/util/sss_override-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_override-nscd.Tpo src/util/$(DEPDIR)/sss_override-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_override-nscd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_override_CFLAGS) $(CFLAGS) -c -o src/util/sss_override-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` src/tests/cmocka/sss_sifp_tests-test_sss_sifp.o: src/tests/cmocka/test_sss_sifp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/sss_sifp_tests-test_sss_sifp.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/sss_sifp_tests-test_sss_sifp.Tpo -c -o src/tests/cmocka/sss_sifp_tests-test_sss_sifp.o `test -f 'src/tests/cmocka/test_sss_sifp.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sss_sifp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/sss_sifp_tests-test_sss_sifp.Tpo src/tests/cmocka/$(DEPDIR)/sss_sifp_tests-test_sss_sifp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sss_sifp.c' object='src/tests/cmocka/sss_sifp_tests-test_sss_sifp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/sss_sifp_tests-test_sss_sifp.o `test -f 'src/tests/cmocka/test_sss_sifp.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sss_sifp.c src/tests/cmocka/sss_sifp_tests-test_sss_sifp.obj: src/tests/cmocka/test_sss_sifp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/sss_sifp_tests-test_sss_sifp.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/sss_sifp_tests-test_sss_sifp.Tpo -c -o src/tests/cmocka/sss_sifp_tests-test_sss_sifp.obj `if test -f 'src/tests/cmocka/test_sss_sifp.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sss_sifp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sss_sifp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/sss_sifp_tests-test_sss_sifp.Tpo src/tests/cmocka/$(DEPDIR)/sss_sifp_tests-test_sss_sifp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sss_sifp.c' object='src/tests/cmocka/sss_sifp_tests-test_sss_sifp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/sss_sifp_tests-test_sss_sifp.obj `if test -f 'src/tests/cmocka/test_sss_sifp.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sss_sifp.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sss_sifp.c'; fi` src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.o: src/lib/sifp/sss_sifp_attrs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.o -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_attrs.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.o `test -f 'src/lib/sifp/sss_sifp_attrs.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_attrs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_attrs.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_attrs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_attrs.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.o `test -f 'src/lib/sifp/sss_sifp_attrs.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_attrs.c src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.obj: src/lib/sifp/sss_sifp_attrs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.obj -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_attrs.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.obj `if test -f 'src/lib/sifp/sss_sifp_attrs.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp_attrs.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp_attrs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_attrs.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_attrs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_attrs.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_attrs.obj `if test -f 'src/lib/sifp/sss_sifp_attrs.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp_attrs.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp_attrs.c'; fi` src/lib/sifp/sss_sifp_tests-sss_sifp_common.o: src/lib/sifp/sss_sifp_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp_common.o -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_common.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_common.o `test -f 'src/lib/sifp/sss_sifp_common.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_common.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_common.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_common.o `test -f 'src/lib/sifp/sss_sifp_common.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_common.c src/lib/sifp/sss_sifp_tests-sss_sifp_common.obj: src/lib/sifp/sss_sifp_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp_common.obj -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_common.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_common.obj `if test -f 'src/lib/sifp/sss_sifp_common.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp_common.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_common.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_common.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_common.obj `if test -f 'src/lib/sifp/sss_sifp_common.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp_common.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp_common.c'; fi` src/lib/sifp/sss_sifp_tests-sss_sifp_parser.o: src/lib/sifp/sss_sifp_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp_parser.o -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_parser.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_parser.o `test -f 'src/lib/sifp/sss_sifp_parser.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_parser.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_parser.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_parser.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_parser.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp_parser.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_parser.o `test -f 'src/lib/sifp/sss_sifp_parser.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_parser.c src/lib/sifp/sss_sifp_tests-sss_sifp_parser.obj: src/lib/sifp/sss_sifp_parser.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp_parser.obj -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_parser.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_parser.obj `if test -f 'src/lib/sifp/sss_sifp_parser.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp_parser.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp_parser.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_parser.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_parser.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_parser.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp_parser.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_parser.obj `if test -f 'src/lib/sifp/sss_sifp_parser.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp_parser.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp_parser.c'; fi` src/lib/sifp/sss_sifp_tests-sss_sifp_utils.o: src/lib/sifp/sss_sifp_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp_utils.o -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_utils.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_utils.o `test -f 'src/lib/sifp/sss_sifp_utils.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_utils.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_utils.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_utils.o `test -f 'src/lib/sifp/sss_sifp_utils.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_utils.c src/lib/sifp/sss_sifp_tests-sss_sifp_utils.obj: src/lib/sifp/sss_sifp_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp_utils.obj -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_utils.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_utils.obj `if test -f 'src/lib/sifp/sss_sifp_utils.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_utils.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_utils.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_utils.obj `if test -f 'src/lib/sifp/sss_sifp_utils.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp_utils.c'; fi` src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.o: src/lib/sifp/sss_sifp_dbus.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.o -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_dbus.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.o `test -f 'src/lib/sifp/sss_sifp_dbus.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_dbus.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_dbus.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_dbus.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_dbus.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.o `test -f 'src/lib/sifp/sss_sifp_dbus.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp_dbus.c src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.obj: src/lib/sifp/sss_sifp_dbus.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.obj -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_dbus.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.obj `if test -f 'src/lib/sifp/sss_sifp_dbus.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp_dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp_dbus.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_dbus.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp_dbus.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp_dbus.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp_dbus.obj `if test -f 'src/lib/sifp/sss_sifp_dbus.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp_dbus.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp_dbus.c'; fi` src/lib/sifp/sss_sifp_tests-sss_sifp.o: src/lib/sifp/sss_sifp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp.o -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp.o `test -f 'src/lib/sifp/sss_sifp.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp.o `test -f 'src/lib/sifp/sss_sifp.c' || echo '$(srcdir)/'`src/lib/sifp/sss_sifp.c src/lib/sifp/sss_sifp_tests-sss_sifp.obj: src/lib/sifp/sss_sifp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -MT src/lib/sifp/sss_sifp_tests-sss_sifp.obj -MD -MP -MF src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp.Tpo -c -o src/lib/sifp/sss_sifp_tests-sss_sifp.obj `if test -f 'src/lib/sifp/sss_sifp.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp.Tpo src/lib/sifp/$(DEPDIR)/sss_sifp_tests-sss_sifp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/lib/sifp/sss_sifp.c' object='src/lib/sifp/sss_sifp_tests-sss_sifp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sifp_tests_CFLAGS) $(CFLAGS) -c -o src/lib/sifp/sss_sifp_tests-sss_sifp.obj `if test -f 'src/lib/sifp/sss_sifp.c'; then $(CYGPATH_W) 'src/lib/sifp/sss_sifp.c'; else $(CYGPATH_W) '$(srcdir)/src/lib/sifp/sss_sifp.c'; fi` src/sss_client/sss_ssh_authorizedkeys-common.o: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_ssh_authorizedkeys-common.o -MD -MP -MF src/sss_client/$(DEPDIR)/sss_ssh_authorizedkeys-common.Tpo -c -o src/sss_client/sss_ssh_authorizedkeys-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_ssh_authorizedkeys-common.Tpo src/sss_client/$(DEPDIR)/sss_ssh_authorizedkeys-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_ssh_authorizedkeys-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_ssh_authorizedkeys-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/sss_ssh_authorizedkeys-common.obj: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_ssh_authorizedkeys-common.obj -MD -MP -MF src/sss_client/$(DEPDIR)/sss_ssh_authorizedkeys-common.Tpo -c -o src/sss_client/sss_ssh_authorizedkeys-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_ssh_authorizedkeys-common.Tpo src/sss_client/$(DEPDIR)/sss_ssh_authorizedkeys-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_ssh_authorizedkeys-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_ssh_authorizedkeys-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.o: src/sss_client/ssh/sss_ssh_client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -MT src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.o -MD -MP -MF src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_client.Tpo -c -o src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.o `test -f 'src/sss_client/ssh/sss_ssh_client.c' || echo '$(srcdir)/'`src/sss_client/ssh/sss_ssh_client.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_client.Tpo src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_client.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/ssh/sss_ssh_client.c' object='src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -c -o src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.o `test -f 'src/sss_client/ssh/sss_ssh_client.c' || echo '$(srcdir)/'`src/sss_client/ssh/sss_ssh_client.c src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.obj: src/sss_client/ssh/sss_ssh_client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -MT src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.obj -MD -MP -MF src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_client.Tpo -c -o src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.obj `if test -f 'src/sss_client/ssh/sss_ssh_client.c'; then $(CYGPATH_W) 'src/sss_client/ssh/sss_ssh_client.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/ssh/sss_ssh_client.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_client.Tpo src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_client.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/ssh/sss_ssh_client.c' object='src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -c -o src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_client.obj `if test -f 'src/sss_client/ssh/sss_ssh_client.c'; then $(CYGPATH_W) 'src/sss_client/ssh/sss_ssh_client.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/ssh/sss_ssh_client.c'; fi` src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.o: src/sss_client/ssh/sss_ssh_authorizedkeys.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -MT src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.o -MD -MP -MF src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.Tpo -c -o src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.o `test -f 'src/sss_client/ssh/sss_ssh_authorizedkeys.c' || echo '$(srcdir)/'`src/sss_client/ssh/sss_ssh_authorizedkeys.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.Tpo src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/ssh/sss_ssh_authorizedkeys.c' object='src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -c -o src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.o `test -f 'src/sss_client/ssh/sss_ssh_authorizedkeys.c' || echo '$(srcdir)/'`src/sss_client/ssh/sss_ssh_authorizedkeys.c src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.obj: src/sss_client/ssh/sss_ssh_authorizedkeys.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -MT src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.obj -MD -MP -MF src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.Tpo -c -o src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.obj `if test -f 'src/sss_client/ssh/sss_ssh_authorizedkeys.c'; then $(CYGPATH_W) 'src/sss_client/ssh/sss_ssh_authorizedkeys.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/ssh/sss_ssh_authorizedkeys.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.Tpo src/sss_client/ssh/$(DEPDIR)/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/ssh/sss_ssh_authorizedkeys.c' object='src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_authorizedkeys_CFLAGS) $(CFLAGS) -c -o src/sss_client/ssh/sss_ssh_authorizedkeys-sss_ssh_authorizedkeys.obj `if test -f 'src/sss_client/ssh/sss_ssh_authorizedkeys.c'; then $(CYGPATH_W) 'src/sss_client/ssh/sss_ssh_authorizedkeys.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/ssh/sss_ssh_authorizedkeys.c'; fi` src/sss_client/sss_ssh_knownhostsproxy-common.o: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_ssh_knownhostsproxy-common.o -MD -MP -MF src/sss_client/$(DEPDIR)/sss_ssh_knownhostsproxy-common.Tpo -c -o src/sss_client/sss_ssh_knownhostsproxy-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_ssh_knownhostsproxy-common.Tpo src/sss_client/$(DEPDIR)/sss_ssh_knownhostsproxy-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_ssh_knownhostsproxy-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_ssh_knownhostsproxy-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/sss_ssh_knownhostsproxy-common.obj: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_ssh_knownhostsproxy-common.obj -MD -MP -MF src/sss_client/$(DEPDIR)/sss_ssh_knownhostsproxy-common.Tpo -c -o src/sss_client/sss_ssh_knownhostsproxy-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_ssh_knownhostsproxy-common.Tpo src/sss_client/$(DEPDIR)/sss_ssh_knownhostsproxy-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_ssh_knownhostsproxy-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_ssh_knownhostsproxy-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.o: src/sss_client/ssh/sss_ssh_client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -MT src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.o -MD -MP -MF src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_client.Tpo -c -o src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.o `test -f 'src/sss_client/ssh/sss_ssh_client.c' || echo '$(srcdir)/'`src/sss_client/ssh/sss_ssh_client.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_client.Tpo src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_client.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/ssh/sss_ssh_client.c' object='src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -c -o src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.o `test -f 'src/sss_client/ssh/sss_ssh_client.c' || echo '$(srcdir)/'`src/sss_client/ssh/sss_ssh_client.c src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.obj: src/sss_client/ssh/sss_ssh_client.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -MT src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.obj -MD -MP -MF src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_client.Tpo -c -o src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.obj `if test -f 'src/sss_client/ssh/sss_ssh_client.c'; then $(CYGPATH_W) 'src/sss_client/ssh/sss_ssh_client.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/ssh/sss_ssh_client.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_client.Tpo src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_client.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/ssh/sss_ssh_client.c' object='src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -c -o src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_client.obj `if test -f 'src/sss_client/ssh/sss_ssh_client.c'; then $(CYGPATH_W) 'src/sss_client/ssh/sss_ssh_client.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/ssh/sss_ssh_client.c'; fi` src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.o: src/sss_client/ssh/sss_ssh_knownhostsproxy.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -MT src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.o -MD -MP -MF src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.Tpo -c -o src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.o `test -f 'src/sss_client/ssh/sss_ssh_knownhostsproxy.c' || echo '$(srcdir)/'`src/sss_client/ssh/sss_ssh_knownhostsproxy.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.Tpo src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/ssh/sss_ssh_knownhostsproxy.c' object='src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -c -o src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.o `test -f 'src/sss_client/ssh/sss_ssh_knownhostsproxy.c' || echo '$(srcdir)/'`src/sss_client/ssh/sss_ssh_knownhostsproxy.c src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.obj: src/sss_client/ssh/sss_ssh_knownhostsproxy.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -MT src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.obj -MD -MP -MF src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.Tpo -c -o src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.obj `if test -f 'src/sss_client/ssh/sss_ssh_knownhostsproxy.c'; then $(CYGPATH_W) 'src/sss_client/ssh/sss_ssh_knownhostsproxy.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/ssh/sss_ssh_knownhostsproxy.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.Tpo src/sss_client/ssh/$(DEPDIR)/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/ssh/sss_ssh_knownhostsproxy.c' object='src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_ssh_knownhostsproxy_CFLAGS) $(CFLAGS) -c -o src/sss_client/ssh/sss_ssh_knownhostsproxy-sss_ssh_knownhostsproxy.obj `if test -f 'src/sss_client/ssh/sss_ssh_knownhostsproxy.c'; then $(CYGPATH_W) 'src/sss_client/ssh/sss_ssh_knownhostsproxy.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/ssh/sss_ssh_knownhostsproxy.c'; fi` src/sss_client/sss_sudo_cli-common.o: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_sudo_cli-common.o -MD -MP -MF src/sss_client/$(DEPDIR)/sss_sudo_cli-common.Tpo -c -o src/sss_client/sss_sudo_cli-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_sudo_cli-common.Tpo src/sss_client/$(DEPDIR)/sss_sudo_cli-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_sudo_cli-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_sudo_cli-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/sss_sudo_cli-common.obj: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_sudo_cli-common.obj -MD -MP -MF src/sss_client/$(DEPDIR)/sss_sudo_cli-common.Tpo -c -o src/sss_client/sss_sudo_cli-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_sudo_cli-common.Tpo src/sss_client/$(DEPDIR)/sss_sudo_cli-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_sudo_cli-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_sudo_cli-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` src/sss_client/sudo/sss_sudo_cli-sss_sudo.o: src/sss_client/sudo/sss_sudo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -MT src/sss_client/sudo/sss_sudo_cli-sss_sudo.o -MD -MP -MF src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo.Tpo -c -o src/sss_client/sudo/sss_sudo_cli-sss_sudo.o `test -f 'src/sss_client/sudo/sss_sudo.c' || echo '$(srcdir)/'`src/sss_client/sudo/sss_sudo.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo.Tpo src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/sudo/sss_sudo.c' object='src/sss_client/sudo/sss_sudo_cli-sss_sudo.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -c -o src/sss_client/sudo/sss_sudo_cli-sss_sudo.o `test -f 'src/sss_client/sudo/sss_sudo.c' || echo '$(srcdir)/'`src/sss_client/sudo/sss_sudo.c src/sss_client/sudo/sss_sudo_cli-sss_sudo.obj: src/sss_client/sudo/sss_sudo.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -MT src/sss_client/sudo/sss_sudo_cli-sss_sudo.obj -MD -MP -MF src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo.Tpo -c -o src/sss_client/sudo/sss_sudo_cli-sss_sudo.obj `if test -f 'src/sss_client/sudo/sss_sudo.c'; then $(CYGPATH_W) 'src/sss_client/sudo/sss_sudo.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/sudo/sss_sudo.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo.Tpo src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/sudo/sss_sudo.c' object='src/sss_client/sudo/sss_sudo_cli-sss_sudo.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -c -o src/sss_client/sudo/sss_sudo_cli-sss_sudo.obj `if test -f 'src/sss_client/sudo/sss_sudo.c'; then $(CYGPATH_W) 'src/sss_client/sudo/sss_sudo.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/sudo/sss_sudo.c'; fi` src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.o: src/sss_client/sudo/sss_sudo_response.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -MT src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.o -MD -MP -MF src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo_response.Tpo -c -o src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.o `test -f 'src/sss_client/sudo/sss_sudo_response.c' || echo '$(srcdir)/'`src/sss_client/sudo/sss_sudo_response.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo_response.Tpo src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo_response.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/sudo/sss_sudo_response.c' object='src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -c -o src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.o `test -f 'src/sss_client/sudo/sss_sudo_response.c' || echo '$(srcdir)/'`src/sss_client/sudo/sss_sudo_response.c src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.obj: src/sss_client/sudo/sss_sudo_response.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -MT src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.obj -MD -MP -MF src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo_response.Tpo -c -o src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.obj `if test -f 'src/sss_client/sudo/sss_sudo_response.c'; then $(CYGPATH_W) 'src/sss_client/sudo/sss_sudo_response.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/sudo/sss_sudo_response.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo_response.Tpo src/sss_client/sudo/$(DEPDIR)/sss_sudo_cli-sss_sudo_response.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/sudo/sss_sudo_response.c' object='src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -c -o src/sss_client/sudo/sss_sudo_cli-sss_sudo_response.obj `if test -f 'src/sss_client/sudo/sss_sudo_response.c'; then $(CYGPATH_W) 'src/sss_client/sudo/sss_sudo_response.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/sudo/sss_sudo_response.c'; fi` src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.o: src/sss_client/sudo_testcli/sudo_testcli.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -MT src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.o -MD -MP -MF src/sss_client/sudo_testcli/$(DEPDIR)/sss_sudo_cli-sudo_testcli.Tpo -c -o src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.o `test -f 'src/sss_client/sudo_testcli/sudo_testcli.c' || echo '$(srcdir)/'`src/sss_client/sudo_testcli/sudo_testcli.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/sudo_testcli/$(DEPDIR)/sss_sudo_cli-sudo_testcli.Tpo src/sss_client/sudo_testcli/$(DEPDIR)/sss_sudo_cli-sudo_testcli.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/sudo_testcli/sudo_testcli.c' object='src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -c -o src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.o `test -f 'src/sss_client/sudo_testcli/sudo_testcli.c' || echo '$(srcdir)/'`src/sss_client/sudo_testcli/sudo_testcli.c src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.obj: src/sss_client/sudo_testcli/sudo_testcli.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -MT src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.obj -MD -MP -MF src/sss_client/sudo_testcli/$(DEPDIR)/sss_sudo_cli-sudo_testcli.Tpo -c -o src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.obj `if test -f 'src/sss_client/sudo_testcli/sudo_testcli.c'; then $(CYGPATH_W) 'src/sss_client/sudo_testcli/sudo_testcli.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/sudo_testcli/sudo_testcli.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/sudo_testcli/$(DEPDIR)/sss_sudo_cli-sudo_testcli.Tpo src/sss_client/sudo_testcli/$(DEPDIR)/sss_sudo_cli-sudo_testcli.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/sudo_testcli/sudo_testcli.c' object='src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_sudo_cli_CFLAGS) $(CFLAGS) -c -o src/sss_client/sudo_testcli/sss_sudo_cli-sudo_testcli.obj `if test -f 'src/sss_client/sudo_testcli/sudo_testcli.c'; then $(CYGPATH_W) 'src/sss_client/sudo_testcli/sudo_testcli.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/sudo_testcli/sudo_testcli.c'; fi` src/tools/sss_userdel-sss_userdel.o: src/tools/sss_userdel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-sss_userdel.o -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-sss_userdel.Tpo -c -o src/tools/sss_userdel-sss_userdel.o `test -f 'src/tools/sss_userdel.c' || echo '$(srcdir)/'`src/tools/sss_userdel.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-sss_userdel.Tpo src/tools/$(DEPDIR)/sss_userdel-sss_userdel.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_userdel.c' object='src/tools/sss_userdel-sss_userdel.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-sss_userdel.o `test -f 'src/tools/sss_userdel.c' || echo '$(srcdir)/'`src/tools/sss_userdel.c src/tools/sss_userdel-sss_userdel.obj: src/tools/sss_userdel.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-sss_userdel.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-sss_userdel.Tpo -c -o src/tools/sss_userdel-sss_userdel.obj `if test -f 'src/tools/sss_userdel.c'; then $(CYGPATH_W) 'src/tools/sss_userdel.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_userdel.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-sss_userdel.Tpo src/tools/$(DEPDIR)/sss_userdel-sss_userdel.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_userdel.c' object='src/tools/sss_userdel-sss_userdel.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-sss_userdel.obj `if test -f 'src/tools/sss_userdel.c'; then $(CYGPATH_W) 'src/tools/sss_userdel.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_userdel.c'; fi` src/sss_client/sss_userdel-common.o: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_userdel-common.o -MD -MP -MF src/sss_client/$(DEPDIR)/sss_userdel-common.Tpo -c -o src/sss_client/sss_userdel-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_userdel-common.Tpo src/sss_client/$(DEPDIR)/sss_userdel-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_userdel-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_userdel-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/sss_userdel-common.obj: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_userdel-common.obj -MD -MP -MF src/sss_client/$(DEPDIR)/sss_userdel-common.Tpo -c -o src/sss_client/sss_userdel-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_userdel-common.Tpo src/sss_client/$(DEPDIR)/sss_userdel-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_userdel-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_userdel-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` src/tools/sss_userdel-tools_mc_util.o: src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-tools_mc_util.o -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-tools_mc_util.Tpo -c -o src/tools/sss_userdel-tools_mc_util.o `test -f 'src/tools/tools_mc_util.c' || echo '$(srcdir)/'`src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-tools_mc_util.Tpo src/tools/$(DEPDIR)/sss_userdel-tools_mc_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_mc_util.c' object='src/tools/sss_userdel-tools_mc_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-tools_mc_util.o `test -f 'src/tools/tools_mc_util.c' || echo '$(srcdir)/'`src/tools/tools_mc_util.c src/tools/sss_userdel-tools_mc_util.obj: src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-tools_mc_util.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-tools_mc_util.Tpo -c -o src/tools/sss_userdel-tools_mc_util.obj `if test -f 'src/tools/tools_mc_util.c'; then $(CYGPATH_W) 'src/tools/tools_mc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_mc_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-tools_mc_util.Tpo src/tools/$(DEPDIR)/sss_userdel-tools_mc_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_mc_util.c' object='src/tools/sss_userdel-tools_mc_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-tools_mc_util.obj `if test -f 'src/tools/tools_mc_util.c'; then $(CYGPATH_W) 'src/tools/tools_mc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_mc_util.c'; fi` src/tools/sss_userdel-sss_sync_ops.o: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-sss_sync_ops.o -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-sss_sync_ops.Tpo -c -o src/tools/sss_userdel-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_userdel-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_userdel-sss_sync_ops.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c src/tools/sss_userdel-sss_sync_ops.obj: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-sss_sync_ops.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-sss_sync_ops.Tpo -c -o src/tools/sss_userdel-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_userdel-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_userdel-sss_sync_ops.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` src/tools/sss_userdel-tools_util.o: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-tools_util.o -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-tools_util.Tpo -c -o src/tools/sss_userdel-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-tools_util.Tpo src/tools/$(DEPDIR)/sss_userdel-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_userdel-tools_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c src/tools/sss_userdel-tools_util.obj: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-tools_util.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-tools_util.Tpo -c -o src/tools/sss_userdel-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-tools_util.Tpo src/tools/$(DEPDIR)/sss_userdel-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_userdel-tools_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` src/tools/sss_userdel-files.o: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-files.o -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-files.Tpo -c -o src/tools/sss_userdel-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-files.Tpo src/tools/$(DEPDIR)/sss_userdel-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_userdel-files.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c src/tools/sss_userdel-files.obj: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-files.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-files.Tpo -c -o src/tools/sss_userdel-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-files.Tpo src/tools/$(DEPDIR)/sss_userdel-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_userdel-files.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` src/tools/sss_userdel-selinux.o: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-selinux.o -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-selinux.Tpo -c -o src/tools/sss_userdel-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-selinux.Tpo src/tools/$(DEPDIR)/sss_userdel-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_userdel-selinux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c src/tools/sss_userdel-selinux.obj: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/sss_userdel-selinux.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_userdel-selinux.Tpo -c -o src/tools/sss_userdel-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_userdel-selinux.Tpo src/tools/$(DEPDIR)/sss_userdel-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_userdel-selinux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/sss_userdel-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` src/tools/common/sss_userdel-sss_tools.o: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_userdel-sss_tools.o -MD -MP -MF src/tools/common/$(DEPDIR)/sss_userdel-sss_tools.Tpo -c -o src/tools/common/sss_userdel-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_userdel-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_userdel-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_userdel-sss_tools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_userdel-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c src/tools/common/sss_userdel-sss_tools.obj: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_userdel-sss_tools.obj -MD -MP -MF src/tools/common/$(DEPDIR)/sss_userdel-sss_tools.Tpo -c -o src/tools/common/sss_userdel-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_userdel-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_userdel-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_userdel-sss_tools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_userdel-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` src/util/sss_userdel-nscd.o: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/util/sss_userdel-nscd.o -MD -MP -MF src/util/$(DEPDIR)/sss_userdel-nscd.Tpo -c -o src/util/sss_userdel-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_userdel-nscd.Tpo src/util/$(DEPDIR)/sss_userdel-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_userdel-nscd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/util/sss_userdel-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c src/util/sss_userdel-nscd.obj: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -MT src/util/sss_userdel-nscd.obj -MD -MP -MF src/util/$(DEPDIR)/sss_userdel-nscd.Tpo -c -o src/util/sss_userdel-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_userdel-nscd.Tpo src/util/$(DEPDIR)/sss_userdel-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_userdel-nscd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_userdel_CFLAGS) $(CFLAGS) -c -o src/util/sss_userdel-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` src/tools/sss_usermod-sss_usermod.o: src/tools/sss_usermod.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-sss_usermod.o -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-sss_usermod.Tpo -c -o src/tools/sss_usermod-sss_usermod.o `test -f 'src/tools/sss_usermod.c' || echo '$(srcdir)/'`src/tools/sss_usermod.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-sss_usermod.Tpo src/tools/$(DEPDIR)/sss_usermod-sss_usermod.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_usermod.c' object='src/tools/sss_usermod-sss_usermod.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-sss_usermod.o `test -f 'src/tools/sss_usermod.c' || echo '$(srcdir)/'`src/tools/sss_usermod.c src/tools/sss_usermod-sss_usermod.obj: src/tools/sss_usermod.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-sss_usermod.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-sss_usermod.Tpo -c -o src/tools/sss_usermod-sss_usermod.obj `if test -f 'src/tools/sss_usermod.c'; then $(CYGPATH_W) 'src/tools/sss_usermod.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_usermod.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-sss_usermod.Tpo src/tools/$(DEPDIR)/sss_usermod-sss_usermod.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_usermod.c' object='src/tools/sss_usermod-sss_usermod.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-sss_usermod.obj `if test -f 'src/tools/sss_usermod.c'; then $(CYGPATH_W) 'src/tools/sss_usermod.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_usermod.c'; fi` src/sss_client/sss_usermod-common.o: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_usermod-common.o -MD -MP -MF src/sss_client/$(DEPDIR)/sss_usermod-common.Tpo -c -o src/sss_client/sss_usermod-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_usermod-common.Tpo src/sss_client/$(DEPDIR)/sss_usermod-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_usermod-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_usermod-common.o `test -f 'src/sss_client/common.c' || echo '$(srcdir)/'`src/sss_client/common.c src/sss_client/sss_usermod-common.obj: src/sss_client/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/sss_client/sss_usermod-common.obj -MD -MP -MF src/sss_client/$(DEPDIR)/sss_usermod-common.Tpo -c -o src/sss_client/sss_usermod-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/sss_client/$(DEPDIR)/sss_usermod-common.Tpo src/sss_client/$(DEPDIR)/sss_usermod-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/sss_client/common.c' object='src/sss_client/sss_usermod-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/sss_client/sss_usermod-common.obj `if test -f 'src/sss_client/common.c'; then $(CYGPATH_W) 'src/sss_client/common.c'; else $(CYGPATH_W) '$(srcdir)/src/sss_client/common.c'; fi` src/tools/sss_usermod-tools_mc_util.o: src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-tools_mc_util.o -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-tools_mc_util.Tpo -c -o src/tools/sss_usermod-tools_mc_util.o `test -f 'src/tools/tools_mc_util.c' || echo '$(srcdir)/'`src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-tools_mc_util.Tpo src/tools/$(DEPDIR)/sss_usermod-tools_mc_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_mc_util.c' object='src/tools/sss_usermod-tools_mc_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-tools_mc_util.o `test -f 'src/tools/tools_mc_util.c' || echo '$(srcdir)/'`src/tools/tools_mc_util.c src/tools/sss_usermod-tools_mc_util.obj: src/tools/tools_mc_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-tools_mc_util.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-tools_mc_util.Tpo -c -o src/tools/sss_usermod-tools_mc_util.obj `if test -f 'src/tools/tools_mc_util.c'; then $(CYGPATH_W) 'src/tools/tools_mc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_mc_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-tools_mc_util.Tpo src/tools/$(DEPDIR)/sss_usermod-tools_mc_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_mc_util.c' object='src/tools/sss_usermod-tools_mc_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-tools_mc_util.obj `if test -f 'src/tools/tools_mc_util.c'; then $(CYGPATH_W) 'src/tools/tools_mc_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_mc_util.c'; fi` src/tools/sss_usermod-sss_sync_ops.o: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-sss_sync_ops.o -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-sss_sync_ops.Tpo -c -o src/tools/sss_usermod-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_usermod-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_usermod-sss_sync_ops.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-sss_sync_ops.o `test -f 'src/tools/sss_sync_ops.c' || echo '$(srcdir)/'`src/tools/sss_sync_ops.c src/tools/sss_usermod-sss_sync_ops.obj: src/tools/sss_sync_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-sss_sync_ops.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-sss_sync_ops.Tpo -c -o src/tools/sss_usermod-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-sss_sync_ops.Tpo src/tools/$(DEPDIR)/sss_usermod-sss_sync_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/sss_sync_ops.c' object='src/tools/sss_usermod-sss_sync_ops.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-sss_sync_ops.obj `if test -f 'src/tools/sss_sync_ops.c'; then $(CYGPATH_W) 'src/tools/sss_sync_ops.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/sss_sync_ops.c'; fi` src/tools/sss_usermod-tools_util.o: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-tools_util.o -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-tools_util.Tpo -c -o src/tools/sss_usermod-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-tools_util.Tpo src/tools/$(DEPDIR)/sss_usermod-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_usermod-tools_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-tools_util.o `test -f 'src/tools/tools_util.c' || echo '$(srcdir)/'`src/tools/tools_util.c src/tools/sss_usermod-tools_util.obj: src/tools/tools_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-tools_util.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-tools_util.Tpo -c -o src/tools/sss_usermod-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-tools_util.Tpo src/tools/$(DEPDIR)/sss_usermod-tools_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/tools_util.c' object='src/tools/sss_usermod-tools_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-tools_util.obj `if test -f 'src/tools/tools_util.c'; then $(CYGPATH_W) 'src/tools/tools_util.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/tools_util.c'; fi` src/tools/sss_usermod-files.o: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-files.o -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-files.Tpo -c -o src/tools/sss_usermod-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-files.Tpo src/tools/$(DEPDIR)/sss_usermod-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_usermod-files.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-files.o `test -f 'src/tools/files.c' || echo '$(srcdir)/'`src/tools/files.c src/tools/sss_usermod-files.obj: src/tools/files.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-files.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-files.Tpo -c -o src/tools/sss_usermod-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-files.Tpo src/tools/$(DEPDIR)/sss_usermod-files.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/files.c' object='src/tools/sss_usermod-files.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-files.obj `if test -f 'src/tools/files.c'; then $(CYGPATH_W) 'src/tools/files.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/files.c'; fi` src/tools/sss_usermod-selinux.o: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-selinux.o -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-selinux.Tpo -c -o src/tools/sss_usermod-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-selinux.Tpo src/tools/$(DEPDIR)/sss_usermod-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_usermod-selinux.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-selinux.o `test -f 'src/tools/selinux.c' || echo '$(srcdir)/'`src/tools/selinux.c src/tools/sss_usermod-selinux.obj: src/tools/selinux.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/sss_usermod-selinux.obj -MD -MP -MF src/tools/$(DEPDIR)/sss_usermod-selinux.Tpo -c -o src/tools/sss_usermod-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/$(DEPDIR)/sss_usermod-selinux.Tpo src/tools/$(DEPDIR)/sss_usermod-selinux.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/selinux.c' object='src/tools/sss_usermod-selinux.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/sss_usermod-selinux.obj `if test -f 'src/tools/selinux.c'; then $(CYGPATH_W) 'src/tools/selinux.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/selinux.c'; fi` src/tools/common/sss_usermod-sss_tools.o: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_usermod-sss_tools.o -MD -MP -MF src/tools/common/$(DEPDIR)/sss_usermod-sss_tools.Tpo -c -o src/tools/common/sss_usermod-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_usermod-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_usermod-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_usermod-sss_tools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_usermod-sss_tools.o `test -f 'src/tools/common/sss_tools.c' || echo '$(srcdir)/'`src/tools/common/sss_tools.c src/tools/common/sss_usermod-sss_tools.obj: src/tools/common/sss_tools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/tools/common/sss_usermod-sss_tools.obj -MD -MP -MF src/tools/common/$(DEPDIR)/sss_usermod-sss_tools.Tpo -c -o src/tools/common/sss_usermod-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/sss_usermod-sss_tools.Tpo src/tools/common/$(DEPDIR)/sss_usermod-sss_tools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_tools.c' object='src/tools/common/sss_usermod-sss_tools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/tools/common/sss_usermod-sss_tools.obj `if test -f 'src/tools/common/sss_tools.c'; then $(CYGPATH_W) 'src/tools/common/sss_tools.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_tools.c'; fi` src/util/sss_usermod-nscd.o: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/util/sss_usermod-nscd.o -MD -MP -MF src/util/$(DEPDIR)/sss_usermod-nscd.Tpo -c -o src/util/sss_usermod-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_usermod-nscd.Tpo src/util/$(DEPDIR)/sss_usermod-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_usermod-nscd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/util/sss_usermod-nscd.o `test -f 'src/util/nscd.c' || echo '$(srcdir)/'`src/util/nscd.c src/util/sss_usermod-nscd.obj: src/util/nscd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -MT src/util/sss_usermod-nscd.obj -MD -MP -MF src/util/$(DEPDIR)/sss_usermod-nscd.Tpo -c -o src/util/sss_usermod-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/sss_usermod-nscd.Tpo src/util/$(DEPDIR)/sss_usermod-nscd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/nscd.c' object='src/util/sss_usermod-nscd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sss_usermod_CFLAGS) $(CFLAGS) -c -o src/util/sss_usermod-nscd.obj `if test -f 'src/util/nscd.c'; then $(CYGPATH_W) 'src/util/nscd.c'; else $(CYGPATH_W) '$(srcdir)/src/util/nscd.c'; fi` src/responder/ifp/sssd_ifp-ifpsrv.o: src/responder/ifp/ifpsrv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifpsrv.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv.Tpo -c -o src/responder/ifp/sssd_ifp-ifpsrv.o `test -f 'src/responder/ifp/ifpsrv.c' || echo '$(srcdir)/'`src/responder/ifp/ifpsrv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifpsrv.c' object='src/responder/ifp/sssd_ifp-ifpsrv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifpsrv.o `test -f 'src/responder/ifp/ifpsrv.c' || echo '$(srcdir)/'`src/responder/ifp/ifpsrv.c src/responder/ifp/sssd_ifp-ifpsrv.obj: src/responder/ifp/ifpsrv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifpsrv.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv.Tpo -c -o src/responder/ifp/sssd_ifp-ifpsrv.obj `if test -f 'src/responder/ifp/ifpsrv.c'; then $(CYGPATH_W) 'src/responder/ifp/ifpsrv.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifpsrv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifpsrv.c' object='src/responder/ifp/sssd_ifp-ifpsrv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifpsrv.obj `if test -f 'src/responder/ifp/ifpsrv.c'; then $(CYGPATH_W) 'src/responder/ifp/ifpsrv.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifpsrv.c'; fi` src/responder/ifp/sssd_ifp-ifpsrv_cmd.o: src/responder/ifp/ifpsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifpsrv_cmd.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_cmd.Tpo -c -o src/responder/ifp/sssd_ifp-ifpsrv_cmd.o `test -f 'src/responder/ifp/ifpsrv_cmd.c' || echo '$(srcdir)/'`src/responder/ifp/ifpsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_cmd.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifpsrv_cmd.c' object='src/responder/ifp/sssd_ifp-ifpsrv_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifpsrv_cmd.o `test -f 'src/responder/ifp/ifpsrv_cmd.c' || echo '$(srcdir)/'`src/responder/ifp/ifpsrv_cmd.c src/responder/ifp/sssd_ifp-ifpsrv_cmd.obj: src/responder/ifp/ifpsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifpsrv_cmd.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_cmd.Tpo -c -o src/responder/ifp/sssd_ifp-ifpsrv_cmd.obj `if test -f 'src/responder/ifp/ifpsrv_cmd.c'; then $(CYGPATH_W) 'src/responder/ifp/ifpsrv_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifpsrv_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_cmd.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifpsrv_cmd.c' object='src/responder/ifp/sssd_ifp-ifpsrv_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifpsrv_cmd.obj `if test -f 'src/responder/ifp/ifpsrv_cmd.c'; then $(CYGPATH_W) 'src/responder/ifp/ifpsrv_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifpsrv_cmd.c'; fi` src/responder/ifp/sssd_ifp-ifp_iface_generated.o: src/responder/ifp/ifp_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_iface_generated.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_generated.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_iface_generated.o `test -f 'src/responder/ifp/ifp_iface_generated.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_generated.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_iface_generated.c' object='src/responder/ifp/sssd_ifp-ifp_iface_generated.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_iface_generated.o `test -f 'src/responder/ifp/ifp_iface_generated.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_iface_generated.c src/responder/ifp/sssd_ifp-ifp_iface_generated.obj: src/responder/ifp/ifp_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_iface_generated.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_generated.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_iface_generated.obj `if test -f 'src/responder/ifp/ifp_iface_generated.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_iface_generated.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_generated.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_iface_generated.c' object='src/responder/ifp/sssd_ifp-ifp_iface_generated.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_iface_generated.obj `if test -f 'src/responder/ifp/ifp_iface_generated.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_iface_generated.c'; fi` src/responder/ifp/sssd_ifp-ifp_iface.o: src/responder/ifp/ifp_iface.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_iface.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_iface.o `test -f 'src/responder/ifp/ifp_iface.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_iface.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_iface.c' object='src/responder/ifp/sssd_ifp-ifp_iface.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_iface.o `test -f 'src/responder/ifp/ifp_iface.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_iface.c src/responder/ifp/sssd_ifp-ifp_iface.obj: src/responder/ifp/ifp_iface.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_iface.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_iface.obj `if test -f 'src/responder/ifp/ifp_iface.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_iface.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_iface.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_iface.c' object='src/responder/ifp/sssd_ifp-ifp_iface.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_iface.obj `if test -f 'src/responder/ifp/ifp_iface.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_iface.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_iface.c'; fi` src/responder/ifp/sssd_ifp-ifp_iface_nodes.o: src/responder/ifp/ifp_iface_nodes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_iface_nodes.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_nodes.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_iface_nodes.o `test -f 'src/responder/ifp/ifp_iface_nodes.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_iface_nodes.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_nodes.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_nodes.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_iface_nodes.c' object='src/responder/ifp/sssd_ifp-ifp_iface_nodes.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_iface_nodes.o `test -f 'src/responder/ifp/ifp_iface_nodes.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_iface_nodes.c src/responder/ifp/sssd_ifp-ifp_iface_nodes.obj: src/responder/ifp/ifp_iface_nodes.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_iface_nodes.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_nodes.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_iface_nodes.obj `if test -f 'src/responder/ifp/ifp_iface_nodes.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_iface_nodes.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_iface_nodes.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_nodes.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_iface_nodes.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_iface_nodes.c' object='src/responder/ifp/sssd_ifp-ifp_iface_nodes.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_iface_nodes.obj `if test -f 'src/responder/ifp/ifp_iface_nodes.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_iface_nodes.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_iface_nodes.c'; fi` src/responder/ifp/sssd_ifp-ifpsrv_util.o: src/responder/ifp/ifpsrv_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifpsrv_util.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_util.Tpo -c -o src/responder/ifp/sssd_ifp-ifpsrv_util.o `test -f 'src/responder/ifp/ifpsrv_util.c' || echo '$(srcdir)/'`src/responder/ifp/ifpsrv_util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_util.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifpsrv_util.c' object='src/responder/ifp/sssd_ifp-ifpsrv_util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifpsrv_util.o `test -f 'src/responder/ifp/ifpsrv_util.c' || echo '$(srcdir)/'`src/responder/ifp/ifpsrv_util.c src/responder/ifp/sssd_ifp-ifpsrv_util.obj: src/responder/ifp/ifpsrv_util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifpsrv_util.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_util.Tpo -c -o src/responder/ifp/sssd_ifp-ifpsrv_util.obj `if test -f 'src/responder/ifp/ifpsrv_util.c'; then $(CYGPATH_W) 'src/responder/ifp/ifpsrv_util.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifpsrv_util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_util.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifpsrv_util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifpsrv_util.c' object='src/responder/ifp/sssd_ifp-ifpsrv_util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifpsrv_util.obj `if test -f 'src/responder/ifp/ifpsrv_util.c'; then $(CYGPATH_W) 'src/responder/ifp/ifpsrv_util.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifpsrv_util.c'; fi` src/responder/ifp/sssd_ifp-ifp_domains.o: src/responder/ifp/ifp_domains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_domains.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_domains.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_domains.o `test -f 'src/responder/ifp/ifp_domains.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_domains.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_domains.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_domains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_domains.c' object='src/responder/ifp/sssd_ifp-ifp_domains.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_domains.o `test -f 'src/responder/ifp/ifp_domains.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_domains.c src/responder/ifp/sssd_ifp-ifp_domains.obj: src/responder/ifp/ifp_domains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_domains.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_domains.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_domains.obj `if test -f 'src/responder/ifp/ifp_domains.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_domains.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_domains.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_domains.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_domains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_domains.c' object='src/responder/ifp/sssd_ifp-ifp_domains.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_domains.obj `if test -f 'src/responder/ifp/ifp_domains.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_domains.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_domains.c'; fi` src/responder/ifp/sssd_ifp-ifp_components.o: src/responder/ifp/ifp_components.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_components.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_components.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_components.o `test -f 'src/responder/ifp/ifp_components.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_components.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_components.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_components.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_components.c' object='src/responder/ifp/sssd_ifp-ifp_components.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_components.o `test -f 'src/responder/ifp/ifp_components.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_components.c src/responder/ifp/sssd_ifp-ifp_components.obj: src/responder/ifp/ifp_components.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_components.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_components.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_components.obj `if test -f 'src/responder/ifp/ifp_components.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_components.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_components.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_components.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_components.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_components.c' object='src/responder/ifp/sssd_ifp-ifp_components.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_components.obj `if test -f 'src/responder/ifp/ifp_components.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_components.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_components.c'; fi` src/responder/ifp/sssd_ifp-ifp_users.o: src/responder/ifp/ifp_users.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_users.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_users.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_users.o `test -f 'src/responder/ifp/ifp_users.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_users.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_users.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_users.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_users.c' object='src/responder/ifp/sssd_ifp-ifp_users.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_users.o `test -f 'src/responder/ifp/ifp_users.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_users.c src/responder/ifp/sssd_ifp-ifp_users.obj: src/responder/ifp/ifp_users.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_users.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_users.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_users.obj `if test -f 'src/responder/ifp/ifp_users.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_users.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_users.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_users.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_users.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_users.c' object='src/responder/ifp/sssd_ifp-ifp_users.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_users.obj `if test -f 'src/responder/ifp/ifp_users.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_users.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_users.c'; fi` src/responder/ifp/sssd_ifp-ifp_groups.o: src/responder/ifp/ifp_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_groups.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_groups.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_groups.o `test -f 'src/responder/ifp/ifp_groups.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_groups.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_groups.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_groups.c' object='src/responder/ifp/sssd_ifp-ifp_groups.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_groups.o `test -f 'src/responder/ifp/ifp_groups.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_groups.c src/responder/ifp/sssd_ifp-ifp_groups.obj: src/responder/ifp/ifp_groups.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_groups.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_groups.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_groups.obj `if test -f 'src/responder/ifp/ifp_groups.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_groups.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_groups.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_groups.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_groups.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_groups.c' object='src/responder/ifp/sssd_ifp-ifp_groups.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_groups.obj `if test -f 'src/responder/ifp/ifp_groups.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_groups.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_groups.c'; fi` src/responder/ifp/sssd_ifp-ifp_cache.o: src/responder/ifp/ifp_cache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_cache.o -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_cache.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_cache.o `test -f 'src/responder/ifp/ifp_cache.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_cache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_cache.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_cache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_cache.c' object='src/responder/ifp/sssd_ifp-ifp_cache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_cache.o `test -f 'src/responder/ifp/ifp_cache.c' || echo '$(srcdir)/'`src/responder/ifp/ifp_cache.c src/responder/ifp/sssd_ifp-ifp_cache.obj: src/responder/ifp/ifp_cache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/ifp/sssd_ifp-ifp_cache.obj -MD -MP -MF src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_cache.Tpo -c -o src/responder/ifp/sssd_ifp-ifp_cache.obj `if test -f 'src/responder/ifp/ifp_cache.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_cache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_cache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_cache.Tpo src/responder/ifp/$(DEPDIR)/sssd_ifp-ifp_cache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/ifp/ifp_cache.c' object='src/responder/ifp/sssd_ifp-ifp_cache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/ifp/sssd_ifp-ifp_cache.obj `if test -f 'src/responder/ifp/ifp_cache.c'; then $(CYGPATH_W) 'src/responder/ifp/ifp_cache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/ifp/ifp_cache.c'; fi` src/responder/common/sssd_ifp-negcache.o: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-negcache.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-negcache.Tpo -c -o src/responder/common/sssd_ifp-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-negcache.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/sssd_ifp-negcache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c src/responder/common/sssd_ifp-negcache.obj: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-negcache.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-negcache.Tpo -c -o src/responder/common/sssd_ifp-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-negcache.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/sssd_ifp-negcache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` src/responder/common/sssd_ifp-responder_cmd.o: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_cmd.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_cmd.Tpo -c -o src/responder/common/sssd_ifp-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_cmd.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/sssd_ifp-responder_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c src/responder/common/sssd_ifp-responder_cmd.obj: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_cmd.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_cmd.Tpo -c -o src/responder/common/sssd_ifp-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_cmd.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/sssd_ifp-responder_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` src/responder/common/sssd_ifp-responder_common.o: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_common.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_common.Tpo -c -o src/responder/common/sssd_ifp-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_common.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/sssd_ifp-responder_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c src/responder/common/sssd_ifp-responder_common.obj: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_common.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_common.Tpo -c -o src/responder/common/sssd_ifp-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_common.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/sssd_ifp-responder_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` src/responder/common/sssd_ifp-responder_dp.o: src/responder/common/responder_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_dp.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_dp.Tpo -c -o src/responder/common/sssd_ifp-responder_dp.o `test -f 'src/responder/common/responder_dp.c' || echo '$(srcdir)/'`src/responder/common/responder_dp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_dp.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_dp.c' object='src/responder/common/sssd_ifp-responder_dp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_dp.o `test -f 'src/responder/common/responder_dp.c' || echo '$(srcdir)/'`src/responder/common/responder_dp.c src/responder/common/sssd_ifp-responder_dp.obj: src/responder/common/responder_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_dp.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_dp.Tpo -c -o src/responder/common/sssd_ifp-responder_dp.obj `if test -f 'src/responder/common/responder_dp.c'; then $(CYGPATH_W) 'src/responder/common/responder_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_dp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_dp.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_dp.c' object='src/responder/common/sssd_ifp-responder_dp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_dp.obj `if test -f 'src/responder/common/responder_dp.c'; then $(CYGPATH_W) 'src/responder/common/responder_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_dp.c'; fi` src/responder/common/sssd_ifp-responder_packet.o: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_packet.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_packet.Tpo -c -o src/responder/common/sssd_ifp-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_packet.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/sssd_ifp-responder_packet.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c src/responder/common/sssd_ifp-responder_packet.obj: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_packet.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_packet.Tpo -c -o src/responder/common/sssd_ifp-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_packet.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/sssd_ifp-responder_packet.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` src/responder/common/sssd_ifp-responder_get_domains.o: src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_get_domains.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_get_domains.Tpo -c -o src/responder/common/sssd_ifp-responder_get_domains.o `test -f 'src/responder/common/responder_get_domains.c' || echo '$(srcdir)/'`src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_get_domains.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_get_domains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_get_domains.c' object='src/responder/common/sssd_ifp-responder_get_domains.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_get_domains.o `test -f 'src/responder/common/responder_get_domains.c' || echo '$(srcdir)/'`src/responder/common/responder_get_domains.c src/responder/common/sssd_ifp-responder_get_domains.obj: src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_get_domains.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_get_domains.Tpo -c -o src/responder/common/sssd_ifp-responder_get_domains.obj `if test -f 'src/responder/common/responder_get_domains.c'; then $(CYGPATH_W) 'src/responder/common/responder_get_domains.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_get_domains.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_get_domains.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_get_domains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_get_domains.c' object='src/responder/common/sssd_ifp-responder_get_domains.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_get_domains.obj `if test -f 'src/responder/common/responder_get_domains.c'; then $(CYGPATH_W) 'src/responder/common/responder_get_domains.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_get_domains.c'; fi` src/responder/common/sssd_ifp-responder_utils.o: src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_utils.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_utils.Tpo -c -o src/responder/common/sssd_ifp-responder_utils.o `test -f 'src/responder/common/responder_utils.c' || echo '$(srcdir)/'`src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_utils.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_utils.c' object='src/responder/common/sssd_ifp-responder_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_utils.o `test -f 'src/responder/common/responder_utils.c' || echo '$(srcdir)/'`src/responder/common/responder_utils.c src/responder/common/sssd_ifp-responder_utils.obj: src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_utils.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_utils.Tpo -c -o src/responder/common/sssd_ifp-responder_utils.obj `if test -f 'src/responder/common/responder_utils.c'; then $(CYGPATH_W) 'src/responder/common/responder_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_utils.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_utils.c' object='src/responder/common/sssd_ifp-responder_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_utils.obj `if test -f 'src/responder/common/responder_utils.c'; then $(CYGPATH_W) 'src/responder/common/responder_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_utils.c'; fi` src/responder/common/sssd_ifp-responder_cache_req.o: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_cache_req.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_cache_req.Tpo -c -o src/responder/common/sssd_ifp-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/sssd_ifp-responder_cache_req.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c src/responder/common/sssd_ifp-responder_cache_req.obj: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_ifp-responder_cache_req.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_ifp-responder_cache_req.Tpo -c -o src/responder/common/sssd_ifp-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_ifp-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/sssd_ifp-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/sssd_ifp-responder_cache_req.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_ifp-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` src/monitor/sssd_ifp-monitor_iface_generated.o: src/monitor/monitor_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/monitor/sssd_ifp-monitor_iface_generated.o -MD -MP -MF src/monitor/$(DEPDIR)/sssd_ifp-monitor_iface_generated.Tpo -c -o src/monitor/sssd_ifp-monitor_iface_generated.o `test -f 'src/monitor/monitor_iface_generated.c' || echo '$(srcdir)/'`src/monitor/monitor_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/monitor/$(DEPDIR)/sssd_ifp-monitor_iface_generated.Tpo src/monitor/$(DEPDIR)/sssd_ifp-monitor_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/monitor/monitor_iface_generated.c' object='src/monitor/sssd_ifp-monitor_iface_generated.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/monitor/sssd_ifp-monitor_iface_generated.o `test -f 'src/monitor/monitor_iface_generated.c' || echo '$(srcdir)/'`src/monitor/monitor_iface_generated.c src/monitor/sssd_ifp-monitor_iface_generated.obj: src/monitor/monitor_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/monitor/sssd_ifp-monitor_iface_generated.obj -MD -MP -MF src/monitor/$(DEPDIR)/sssd_ifp-monitor_iface_generated.Tpo -c -o src/monitor/sssd_ifp-monitor_iface_generated.obj `if test -f 'src/monitor/monitor_iface_generated.c'; then $(CYGPATH_W) 'src/monitor/monitor_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/monitor/monitor_iface_generated.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/monitor/$(DEPDIR)/sssd_ifp-monitor_iface_generated.Tpo src/monitor/$(DEPDIR)/sssd_ifp-monitor_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/monitor/monitor_iface_generated.c' object='src/monitor/sssd_ifp-monitor_iface_generated.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/monitor/sssd_ifp-monitor_iface_generated.obj `if test -f 'src/monitor/monitor_iface_generated.c'; then $(CYGPATH_W) 'src/monitor/monitor_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/monitor/monitor_iface_generated.c'; fi` src/providers/sssd_ifp-data_provider_iface_generated.o: src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/providers/sssd_ifp-data_provider_iface_generated.o -MD -MP -MF src/providers/$(DEPDIR)/sssd_ifp-data_provider_iface_generated.Tpo -c -o src/providers/sssd_ifp-data_provider_iface_generated.o `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/sssd_ifp-data_provider_iface_generated.Tpo src/providers/$(DEPDIR)/sssd_ifp-data_provider_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_iface_generated.c' object='src/providers/sssd_ifp-data_provider_iface_generated.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/providers/sssd_ifp-data_provider_iface_generated.o `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c src/providers/sssd_ifp-data_provider_iface_generated.obj: src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/providers/sssd_ifp-data_provider_iface_generated.obj -MD -MP -MF src/providers/$(DEPDIR)/sssd_ifp-data_provider_iface_generated.Tpo -c -o src/providers/sssd_ifp-data_provider_iface_generated.obj `if test -f 'src/providers/data_provider_iface_generated.c'; then $(CYGPATH_W) 'src/providers/data_provider_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_iface_generated.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/sssd_ifp-data_provider_iface_generated.Tpo src/providers/$(DEPDIR)/sssd_ifp-data_provider_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_iface_generated.c' object='src/providers/sssd_ifp-data_provider_iface_generated.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/providers/sssd_ifp-data_provider_iface_generated.obj `if test -f 'src/providers/data_provider_iface_generated.c'; then $(CYGPATH_W) 'src/providers/data_provider_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_iface_generated.c'; fi` src/providers/sssd_ifp-data_provider_req.o: src/providers/data_provider_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/providers/sssd_ifp-data_provider_req.o -MD -MP -MF src/providers/$(DEPDIR)/sssd_ifp-data_provider_req.Tpo -c -o src/providers/sssd_ifp-data_provider_req.o `test -f 'src/providers/data_provider_req.c' || echo '$(srcdir)/'`src/providers/data_provider_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/sssd_ifp-data_provider_req.Tpo src/providers/$(DEPDIR)/sssd_ifp-data_provider_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_req.c' object='src/providers/sssd_ifp-data_provider_req.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/providers/sssd_ifp-data_provider_req.o `test -f 'src/providers/data_provider_req.c' || echo '$(srcdir)/'`src/providers/data_provider_req.c src/providers/sssd_ifp-data_provider_req.obj: src/providers/data_provider_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -MT src/providers/sssd_ifp-data_provider_req.obj -MD -MP -MF src/providers/$(DEPDIR)/sssd_ifp-data_provider_req.Tpo -c -o src/providers/sssd_ifp-data_provider_req.obj `if test -f 'src/providers/data_provider_req.c'; then $(CYGPATH_W) 'src/providers/data_provider_req.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_req.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/sssd_ifp-data_provider_req.Tpo src/providers/$(DEPDIR)/sssd_ifp-data_provider_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_req.c' object='src/providers/sssd_ifp-data_provider_req.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_ifp_CFLAGS) $(CFLAGS) -c -o src/providers/sssd_ifp-data_provider_req.obj `if test -f 'src/providers/data_provider_req.c'; then $(CYGPATH_W) 'src/providers/data_provider_req.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_req.c'; fi` src/responder/pac/sssd_pac-pacsrv.o: src/responder/pac/pacsrv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/pac/sssd_pac-pacsrv.o -MD -MP -MF src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv.Tpo -c -o src/responder/pac/sssd_pac-pacsrv.o `test -f 'src/responder/pac/pacsrv.c' || echo '$(srcdir)/'`src/responder/pac/pacsrv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv.Tpo src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pac/pacsrv.c' object='src/responder/pac/sssd_pac-pacsrv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/pac/sssd_pac-pacsrv.o `test -f 'src/responder/pac/pacsrv.c' || echo '$(srcdir)/'`src/responder/pac/pacsrv.c src/responder/pac/sssd_pac-pacsrv.obj: src/responder/pac/pacsrv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/pac/sssd_pac-pacsrv.obj -MD -MP -MF src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv.Tpo -c -o src/responder/pac/sssd_pac-pacsrv.obj `if test -f 'src/responder/pac/pacsrv.c'; then $(CYGPATH_W) 'src/responder/pac/pacsrv.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pac/pacsrv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv.Tpo src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pac/pacsrv.c' object='src/responder/pac/sssd_pac-pacsrv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/pac/sssd_pac-pacsrv.obj `if test -f 'src/responder/pac/pacsrv.c'; then $(CYGPATH_W) 'src/responder/pac/pacsrv.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pac/pacsrv.c'; fi` src/responder/pac/sssd_pac-pacsrv_cmd.o: src/responder/pac/pacsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/pac/sssd_pac-pacsrv_cmd.o -MD -MP -MF src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_cmd.Tpo -c -o src/responder/pac/sssd_pac-pacsrv_cmd.o `test -f 'src/responder/pac/pacsrv_cmd.c' || echo '$(srcdir)/'`src/responder/pac/pacsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_cmd.Tpo src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pac/pacsrv_cmd.c' object='src/responder/pac/sssd_pac-pacsrv_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/pac/sssd_pac-pacsrv_cmd.o `test -f 'src/responder/pac/pacsrv_cmd.c' || echo '$(srcdir)/'`src/responder/pac/pacsrv_cmd.c src/responder/pac/sssd_pac-pacsrv_cmd.obj: src/responder/pac/pacsrv_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/pac/sssd_pac-pacsrv_cmd.obj -MD -MP -MF src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_cmd.Tpo -c -o src/responder/pac/sssd_pac-pacsrv_cmd.obj `if test -f 'src/responder/pac/pacsrv_cmd.c'; then $(CYGPATH_W) 'src/responder/pac/pacsrv_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pac/pacsrv_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_cmd.Tpo src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pac/pacsrv_cmd.c' object='src/responder/pac/sssd_pac-pacsrv_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/pac/sssd_pac-pacsrv_cmd.obj `if test -f 'src/responder/pac/pacsrv_cmd.c'; then $(CYGPATH_W) 'src/responder/pac/pacsrv_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pac/pacsrv_cmd.c'; fi` src/responder/pac/sssd_pac-pacsrv_utils.o: src/responder/pac/pacsrv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/pac/sssd_pac-pacsrv_utils.o -MD -MP -MF src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_utils.Tpo -c -o src/responder/pac/sssd_pac-pacsrv_utils.o `test -f 'src/responder/pac/pacsrv_utils.c' || echo '$(srcdir)/'`src/responder/pac/pacsrv_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_utils.Tpo src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pac/pacsrv_utils.c' object='src/responder/pac/sssd_pac-pacsrv_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/pac/sssd_pac-pacsrv_utils.o `test -f 'src/responder/pac/pacsrv_utils.c' || echo '$(srcdir)/'`src/responder/pac/pacsrv_utils.c src/responder/pac/sssd_pac-pacsrv_utils.obj: src/responder/pac/pacsrv_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/pac/sssd_pac-pacsrv_utils.obj -MD -MP -MF src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_utils.Tpo -c -o src/responder/pac/sssd_pac-pacsrv_utils.obj `if test -f 'src/responder/pac/pacsrv_utils.c'; then $(CYGPATH_W) 'src/responder/pac/pacsrv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pac/pacsrv_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_utils.Tpo src/responder/pac/$(DEPDIR)/sssd_pac-pacsrv_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/pac/pacsrv_utils.c' object='src/responder/pac/sssd_pac-pacsrv_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/pac/sssd_pac-pacsrv_utils.obj `if test -f 'src/responder/pac/pacsrv_utils.c'; then $(CYGPATH_W) 'src/responder/pac/pacsrv_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/pac/pacsrv_utils.c'; fi` src/responder/common/sssd_pac-negcache.o: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-negcache.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-negcache.Tpo -c -o src/responder/common/sssd_pac-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-negcache.Tpo src/responder/common/$(DEPDIR)/sssd_pac-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/sssd_pac-negcache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c src/responder/common/sssd_pac-negcache.obj: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-negcache.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-negcache.Tpo -c -o src/responder/common/sssd_pac-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-negcache.Tpo src/responder/common/$(DEPDIR)/sssd_pac-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/sssd_pac-negcache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` src/responder/common/sssd_pac-responder_cmd.o: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_cmd.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_cmd.Tpo -c -o src/responder/common/sssd_pac-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_cmd.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/sssd_pac-responder_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c src/responder/common/sssd_pac-responder_cmd.obj: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_cmd.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_cmd.Tpo -c -o src/responder/common/sssd_pac-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_cmd.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/sssd_pac-responder_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` src/responder/common/sssd_pac-responder_common.o: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_common.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_common.Tpo -c -o src/responder/common/sssd_pac-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_common.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/sssd_pac-responder_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c src/responder/common/sssd_pac-responder_common.obj: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_common.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_common.Tpo -c -o src/responder/common/sssd_pac-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_common.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/sssd_pac-responder_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` src/responder/common/sssd_pac-responder_dp.o: src/responder/common/responder_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_dp.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_dp.Tpo -c -o src/responder/common/sssd_pac-responder_dp.o `test -f 'src/responder/common/responder_dp.c' || echo '$(srcdir)/'`src/responder/common/responder_dp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_dp.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_dp.c' object='src/responder/common/sssd_pac-responder_dp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_dp.o `test -f 'src/responder/common/responder_dp.c' || echo '$(srcdir)/'`src/responder/common/responder_dp.c src/responder/common/sssd_pac-responder_dp.obj: src/responder/common/responder_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_dp.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_dp.Tpo -c -o src/responder/common/sssd_pac-responder_dp.obj `if test -f 'src/responder/common/responder_dp.c'; then $(CYGPATH_W) 'src/responder/common/responder_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_dp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_dp.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_dp.c' object='src/responder/common/sssd_pac-responder_dp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_dp.obj `if test -f 'src/responder/common/responder_dp.c'; then $(CYGPATH_W) 'src/responder/common/responder_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_dp.c'; fi` src/responder/common/sssd_pac-responder_packet.o: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_packet.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_packet.Tpo -c -o src/responder/common/sssd_pac-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_packet.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/sssd_pac-responder_packet.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c src/responder/common/sssd_pac-responder_packet.obj: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_packet.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_packet.Tpo -c -o src/responder/common/sssd_pac-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_packet.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/sssd_pac-responder_packet.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` src/responder/common/sssd_pac-responder_get_domains.o: src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_get_domains.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_get_domains.Tpo -c -o src/responder/common/sssd_pac-responder_get_domains.o `test -f 'src/responder/common/responder_get_domains.c' || echo '$(srcdir)/'`src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_get_domains.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_get_domains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_get_domains.c' object='src/responder/common/sssd_pac-responder_get_domains.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_get_domains.o `test -f 'src/responder/common/responder_get_domains.c' || echo '$(srcdir)/'`src/responder/common/responder_get_domains.c src/responder/common/sssd_pac-responder_get_domains.obj: src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_get_domains.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_get_domains.Tpo -c -o src/responder/common/sssd_pac-responder_get_domains.obj `if test -f 'src/responder/common/responder_get_domains.c'; then $(CYGPATH_W) 'src/responder/common/responder_get_domains.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_get_domains.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_get_domains.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_get_domains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_get_domains.c' object='src/responder/common/sssd_pac-responder_get_domains.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_get_domains.obj `if test -f 'src/responder/common/responder_get_domains.c'; then $(CYGPATH_W) 'src/responder/common/responder_get_domains.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_get_domains.c'; fi` src/responder/common/sssd_pac-responder_utils.o: src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_utils.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_utils.Tpo -c -o src/responder/common/sssd_pac-responder_utils.o `test -f 'src/responder/common/responder_utils.c' || echo '$(srcdir)/'`src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_utils.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_utils.c' object='src/responder/common/sssd_pac-responder_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_utils.o `test -f 'src/responder/common/responder_utils.c' || echo '$(srcdir)/'`src/responder/common/responder_utils.c src/responder/common/sssd_pac-responder_utils.obj: src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_utils.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_utils.Tpo -c -o src/responder/common/sssd_pac-responder_utils.obj `if test -f 'src/responder/common/responder_utils.c'; then $(CYGPATH_W) 'src/responder/common/responder_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_utils.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_utils.c' object='src/responder/common/sssd_pac-responder_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_utils.obj `if test -f 'src/responder/common/responder_utils.c'; then $(CYGPATH_W) 'src/responder/common/responder_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_utils.c'; fi` src/responder/common/sssd_pac-responder_cache_req.o: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_cache_req.o -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_cache_req.Tpo -c -o src/responder/common/sssd_pac-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/sssd_pac-responder_cache_req.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c src/responder/common/sssd_pac-responder_cache_req.obj: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/responder/common/sssd_pac-responder_cache_req.obj -MD -MP -MF src/responder/common/$(DEPDIR)/sssd_pac-responder_cache_req.Tpo -c -o src/responder/common/sssd_pac-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/sssd_pac-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/sssd_pac-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/sssd_pac-responder_cache_req.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/responder/common/sssd_pac-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` src/monitor/sssd_pac-monitor_iface_generated.o: src/monitor/monitor_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/monitor/sssd_pac-monitor_iface_generated.o -MD -MP -MF src/monitor/$(DEPDIR)/sssd_pac-monitor_iface_generated.Tpo -c -o src/monitor/sssd_pac-monitor_iface_generated.o `test -f 'src/monitor/monitor_iface_generated.c' || echo '$(srcdir)/'`src/monitor/monitor_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/monitor/$(DEPDIR)/sssd_pac-monitor_iface_generated.Tpo src/monitor/$(DEPDIR)/sssd_pac-monitor_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/monitor/monitor_iface_generated.c' object='src/monitor/sssd_pac-monitor_iface_generated.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/monitor/sssd_pac-monitor_iface_generated.o `test -f 'src/monitor/monitor_iface_generated.c' || echo '$(srcdir)/'`src/monitor/monitor_iface_generated.c src/monitor/sssd_pac-monitor_iface_generated.obj: src/monitor/monitor_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/monitor/sssd_pac-monitor_iface_generated.obj -MD -MP -MF src/monitor/$(DEPDIR)/sssd_pac-monitor_iface_generated.Tpo -c -o src/monitor/sssd_pac-monitor_iface_generated.obj `if test -f 'src/monitor/monitor_iface_generated.c'; then $(CYGPATH_W) 'src/monitor/monitor_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/monitor/monitor_iface_generated.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/monitor/$(DEPDIR)/sssd_pac-monitor_iface_generated.Tpo src/monitor/$(DEPDIR)/sssd_pac-monitor_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/monitor/monitor_iface_generated.c' object='src/monitor/sssd_pac-monitor_iface_generated.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/monitor/sssd_pac-monitor_iface_generated.obj `if test -f 'src/monitor/monitor_iface_generated.c'; then $(CYGPATH_W) 'src/monitor/monitor_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/monitor/monitor_iface_generated.c'; fi` src/providers/sssd_pac-data_provider_iface_generated.o: src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/providers/sssd_pac-data_provider_iface_generated.o -MD -MP -MF src/providers/$(DEPDIR)/sssd_pac-data_provider_iface_generated.Tpo -c -o src/providers/sssd_pac-data_provider_iface_generated.o `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/sssd_pac-data_provider_iface_generated.Tpo src/providers/$(DEPDIR)/sssd_pac-data_provider_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_iface_generated.c' object='src/providers/sssd_pac-data_provider_iface_generated.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/providers/sssd_pac-data_provider_iface_generated.o `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c src/providers/sssd_pac-data_provider_iface_generated.obj: src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/providers/sssd_pac-data_provider_iface_generated.obj -MD -MP -MF src/providers/$(DEPDIR)/sssd_pac-data_provider_iface_generated.Tpo -c -o src/providers/sssd_pac-data_provider_iface_generated.obj `if test -f 'src/providers/data_provider_iface_generated.c'; then $(CYGPATH_W) 'src/providers/data_provider_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_iface_generated.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/sssd_pac-data_provider_iface_generated.Tpo src/providers/$(DEPDIR)/sssd_pac-data_provider_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_iface_generated.c' object='src/providers/sssd_pac-data_provider_iface_generated.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/providers/sssd_pac-data_provider_iface_generated.obj `if test -f 'src/providers/data_provider_iface_generated.c'; then $(CYGPATH_W) 'src/providers/data_provider_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_iface_generated.c'; fi` src/providers/sssd_pac-data_provider_req.o: src/providers/data_provider_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/providers/sssd_pac-data_provider_req.o -MD -MP -MF src/providers/$(DEPDIR)/sssd_pac-data_provider_req.Tpo -c -o src/providers/sssd_pac-data_provider_req.o `test -f 'src/providers/data_provider_req.c' || echo '$(srcdir)/'`src/providers/data_provider_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/sssd_pac-data_provider_req.Tpo src/providers/$(DEPDIR)/sssd_pac-data_provider_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_req.c' object='src/providers/sssd_pac-data_provider_req.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/providers/sssd_pac-data_provider_req.o `test -f 'src/providers/data_provider_req.c' || echo '$(srcdir)/'`src/providers/data_provider_req.c src/providers/sssd_pac-data_provider_req.obj: src/providers/data_provider_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -MT src/providers/sssd_pac-data_provider_req.obj -MD -MP -MF src/providers/$(DEPDIR)/sssd_pac-data_provider_req.Tpo -c -o src/providers/sssd_pac-data_provider_req.obj `if test -f 'src/providers/data_provider_req.c'; then $(CYGPATH_W) 'src/providers/data_provider_req.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_req.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/sssd_pac-data_provider_req.Tpo src/providers/$(DEPDIR)/sssd_pac-data_provider_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_req.c' object='src/providers/sssd_pac-data_provider_req.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sssd_pac_CFLAGS) $(CFLAGS) -c -o src/providers/sssd_pac-data_provider_req.obj `if test -f 'src/providers/data_provider_req.c'; then $(CYGPATH_W) 'src/providers/data_provider_req.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_req.c'; fi` src/tests/strtonum_tests-strtonum-tests.o: src/tests/strtonum-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(strtonum_tests_CFLAGS) $(CFLAGS) -MT src/tests/strtonum_tests-strtonum-tests.o -MD -MP -MF src/tests/$(DEPDIR)/strtonum_tests-strtonum-tests.Tpo -c -o src/tests/strtonum_tests-strtonum-tests.o `test -f 'src/tests/strtonum-tests.c' || echo '$(srcdir)/'`src/tests/strtonum-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/strtonum_tests-strtonum-tests.Tpo src/tests/$(DEPDIR)/strtonum_tests-strtonum-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/strtonum-tests.c' object='src/tests/strtonum_tests-strtonum-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(strtonum_tests_CFLAGS) $(CFLAGS) -c -o src/tests/strtonum_tests-strtonum-tests.o `test -f 'src/tests/strtonum-tests.c' || echo '$(srcdir)/'`src/tests/strtonum-tests.c src/tests/strtonum_tests-strtonum-tests.obj: src/tests/strtonum-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(strtonum_tests_CFLAGS) $(CFLAGS) -MT src/tests/strtonum_tests-strtonum-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/strtonum_tests-strtonum-tests.Tpo -c -o src/tests/strtonum_tests-strtonum-tests.obj `if test -f 'src/tests/strtonum-tests.c'; then $(CYGPATH_W) 'src/tests/strtonum-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/strtonum-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/strtonum_tests-strtonum-tests.Tpo src/tests/$(DEPDIR)/strtonum_tests-strtonum-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/strtonum-tests.c' object='src/tests/strtonum_tests-strtonum-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(strtonum_tests_CFLAGS) $(CFLAGS) -c -o src/tests/strtonum_tests-strtonum-tests.obj `if test -f 'src/tests/strtonum-tests.c'; then $(CYGPATH_W) 'src/tests/strtonum-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/strtonum-tests.c'; fi` src/util/strtonum_tests-strtonum.o: src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(strtonum_tests_CFLAGS) $(CFLAGS) -MT src/util/strtonum_tests-strtonum.o -MD -MP -MF src/util/$(DEPDIR)/strtonum_tests-strtonum.Tpo -c -o src/util/strtonum_tests-strtonum.o `test -f 'src/util/strtonum.c' || echo '$(srcdir)/'`src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/strtonum_tests-strtonum.Tpo src/util/$(DEPDIR)/strtonum_tests-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/strtonum.c' object='src/util/strtonum_tests-strtonum.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(strtonum_tests_CFLAGS) $(CFLAGS) -c -o src/util/strtonum_tests-strtonum.o `test -f 'src/util/strtonum.c' || echo '$(srcdir)/'`src/util/strtonum.c src/util/strtonum_tests-strtonum.obj: src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(strtonum_tests_CFLAGS) $(CFLAGS) -MT src/util/strtonum_tests-strtonum.obj -MD -MP -MF src/util/$(DEPDIR)/strtonum_tests-strtonum.Tpo -c -o src/util/strtonum_tests-strtonum.obj `if test -f 'src/util/strtonum.c'; then $(CYGPATH_W) 'src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/src/util/strtonum.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/strtonum_tests-strtonum.Tpo src/util/$(DEPDIR)/strtonum_tests-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/strtonum.c' object='src/util/strtonum_tests-strtonum.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(strtonum_tests_CFLAGS) $(CFLAGS) -c -o src/util/strtonum_tests-strtonum.obj `if test -f 'src/util/strtonum.c'; then $(CYGPATH_W) 'src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/src/util/strtonum.c'; fi` src/tests/sysdb_tests-sysdb-tests.o: src/tests/sysdb-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sysdb_tests_CFLAGS) $(CFLAGS) -MT src/tests/sysdb_tests-sysdb-tests.o -MD -MP -MF src/tests/$(DEPDIR)/sysdb_tests-sysdb-tests.Tpo -c -o src/tests/sysdb_tests-sysdb-tests.o `test -f 'src/tests/sysdb-tests.c' || echo '$(srcdir)/'`src/tests/sysdb-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sysdb_tests-sysdb-tests.Tpo src/tests/$(DEPDIR)/sysdb_tests-sysdb-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sysdb-tests.c' object='src/tests/sysdb_tests-sysdb-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sysdb_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sysdb_tests-sysdb-tests.o `test -f 'src/tests/sysdb-tests.c' || echo '$(srcdir)/'`src/tests/sysdb-tests.c src/tests/sysdb_tests-sysdb-tests.obj: src/tests/sysdb-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sysdb_tests_CFLAGS) $(CFLAGS) -MT src/tests/sysdb_tests-sysdb-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/sysdb_tests-sysdb-tests.Tpo -c -o src/tests/sysdb_tests-sysdb-tests.obj `if test -f 'src/tests/sysdb-tests.c'; then $(CYGPATH_W) 'src/tests/sysdb-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sysdb-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sysdb_tests-sysdb-tests.Tpo src/tests/$(DEPDIR)/sysdb_tests-sysdb-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sysdb-tests.c' object='src/tests/sysdb_tests-sysdb-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sysdb_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sysdb_tests-sysdb-tests.obj `if test -f 'src/tests/sysdb-tests.c'; then $(CYGPATH_W) 'src/tests/sysdb-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sysdb-tests.c'; fi` src/tests/sysdb_ssh_tests-sysdb_ssh-tests.o: src/tests/sysdb_ssh-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sysdb_ssh_tests_CFLAGS) $(CFLAGS) -MT src/tests/sysdb_ssh_tests-sysdb_ssh-tests.o -MD -MP -MF src/tests/$(DEPDIR)/sysdb_ssh_tests-sysdb_ssh-tests.Tpo -c -o src/tests/sysdb_ssh_tests-sysdb_ssh-tests.o `test -f 'src/tests/sysdb_ssh-tests.c' || echo '$(srcdir)/'`src/tests/sysdb_ssh-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sysdb_ssh_tests-sysdb_ssh-tests.Tpo src/tests/$(DEPDIR)/sysdb_ssh_tests-sysdb_ssh-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sysdb_ssh-tests.c' object='src/tests/sysdb_ssh_tests-sysdb_ssh-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sysdb_ssh_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sysdb_ssh_tests-sysdb_ssh-tests.o `test -f 'src/tests/sysdb_ssh-tests.c' || echo '$(srcdir)/'`src/tests/sysdb_ssh-tests.c src/tests/sysdb_ssh_tests-sysdb_ssh-tests.obj: src/tests/sysdb_ssh-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sysdb_ssh_tests_CFLAGS) $(CFLAGS) -MT src/tests/sysdb_ssh_tests-sysdb_ssh-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/sysdb_ssh_tests-sysdb_ssh-tests.Tpo -c -o src/tests/sysdb_ssh_tests-sysdb_ssh-tests.obj `if test -f 'src/tests/sysdb_ssh-tests.c'; then $(CYGPATH_W) 'src/tests/sysdb_ssh-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sysdb_ssh-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/sysdb_ssh_tests-sysdb_ssh-tests.Tpo src/tests/$(DEPDIR)/sysdb_ssh_tests-sysdb_ssh-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/sysdb_ssh-tests.c' object='src/tests/sysdb_ssh_tests-sysdb_ssh-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(sysdb_ssh_tests_CFLAGS) $(CFLAGS) -c -o src/tests/sysdb_ssh_tests-sysdb_ssh-tests.obj `if test -f 'src/tests/sysdb_ssh-tests.c'; then $(CYGPATH_W) 'src/tests/sysdb_ssh-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/sysdb_ssh-tests.c'; fi` src/tests/cmocka/test_authtok-test_authtok.o: src/tests/cmocka/test_authtok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_authtok-test_authtok.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_authtok-test_authtok.Tpo -c -o src/tests/cmocka/test_authtok-test_authtok.o `test -f 'src/tests/cmocka/test_authtok.c' || echo '$(srcdir)/'`src/tests/cmocka/test_authtok.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_authtok-test_authtok.Tpo src/tests/cmocka/$(DEPDIR)/test_authtok-test_authtok.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_authtok.c' object='src/tests/cmocka/test_authtok-test_authtok.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_authtok-test_authtok.o `test -f 'src/tests/cmocka/test_authtok.c' || echo '$(srcdir)/'`src/tests/cmocka/test_authtok.c src/tests/cmocka/test_authtok-test_authtok.obj: src/tests/cmocka/test_authtok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_authtok-test_authtok.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_authtok-test_authtok.Tpo -c -o src/tests/cmocka/test_authtok-test_authtok.obj `if test -f 'src/tests/cmocka/test_authtok.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_authtok.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_authtok.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_authtok-test_authtok.Tpo src/tests/cmocka/$(DEPDIR)/test_authtok-test_authtok.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_authtok.c' object='src/tests/cmocka/test_authtok-test_authtok.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_authtok-test_authtok.obj `if test -f 'src/tests/cmocka/test_authtok.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_authtok.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_authtok.c'; fi` src/util/test_authtok-authtok.o: src/util/authtok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -MT src/util/test_authtok-authtok.o -MD -MP -MF src/util/$(DEPDIR)/test_authtok-authtok.Tpo -c -o src/util/test_authtok-authtok.o `test -f 'src/util/authtok.c' || echo '$(srcdir)/'`src/util/authtok.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_authtok-authtok.Tpo src/util/$(DEPDIR)/test_authtok-authtok.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok.c' object='src/util/test_authtok-authtok.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -c -o src/util/test_authtok-authtok.o `test -f 'src/util/authtok.c' || echo '$(srcdir)/'`src/util/authtok.c src/util/test_authtok-authtok.obj: src/util/authtok.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -MT src/util/test_authtok-authtok.obj -MD -MP -MF src/util/$(DEPDIR)/test_authtok-authtok.Tpo -c -o src/util/test_authtok-authtok.obj `if test -f 'src/util/authtok.c'; then $(CYGPATH_W) 'src/util/authtok.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_authtok-authtok.Tpo src/util/$(DEPDIR)/test_authtok-authtok.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok.c' object='src/util/test_authtok-authtok.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -c -o src/util/test_authtok-authtok.obj `if test -f 'src/util/authtok.c'; then $(CYGPATH_W) 'src/util/authtok.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok.c'; fi` src/util/test_authtok-authtok-utils.o: src/util/authtok-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -MT src/util/test_authtok-authtok-utils.o -MD -MP -MF src/util/$(DEPDIR)/test_authtok-authtok-utils.Tpo -c -o src/util/test_authtok-authtok-utils.o `test -f 'src/util/authtok-utils.c' || echo '$(srcdir)/'`src/util/authtok-utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_authtok-authtok-utils.Tpo src/util/$(DEPDIR)/test_authtok-authtok-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok-utils.c' object='src/util/test_authtok-authtok-utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -c -o src/util/test_authtok-authtok-utils.o `test -f 'src/util/authtok-utils.c' || echo '$(srcdir)/'`src/util/authtok-utils.c src/util/test_authtok-authtok-utils.obj: src/util/authtok-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -MT src/util/test_authtok-authtok-utils.obj -MD -MP -MF src/util/$(DEPDIR)/test_authtok-authtok-utils.Tpo -c -o src/util/test_authtok-authtok-utils.obj `if test -f 'src/util/authtok-utils.c'; then $(CYGPATH_W) 'src/util/authtok-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok-utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_authtok-authtok-utils.Tpo src/util/$(DEPDIR)/test_authtok-authtok-utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/authtok-utils.c' object='src/util/test_authtok-authtok-utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -c -o src/util/test_authtok-authtok-utils.obj `if test -f 'src/util/authtok-utils.c'; then $(CYGPATH_W) 'src/util/authtok-utils.c'; else $(CYGPATH_W) '$(srcdir)/src/util/authtok-utils.c'; fi` src/util/test_authtok-util.o: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -MT src/util/test_authtok-util.o -MD -MP -MF src/util/$(DEPDIR)/test_authtok-util.Tpo -c -o src/util/test_authtok-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_authtok-util.Tpo src/util/$(DEPDIR)/test_authtok-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/test_authtok-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -c -o src/util/test_authtok-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c src/util/test_authtok-util.obj: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -MT src/util/test_authtok-util.obj -MD -MP -MF src/util/$(DEPDIR)/test_authtok-util.Tpo -c -o src/util/test_authtok-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_authtok-util.Tpo src/util/$(DEPDIR)/test_authtok-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/test_authtok-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_authtok_CFLAGS) $(CFLAGS) -c -o src/util/test_authtok-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` src/tests/cmocka/test_find_uid-test_find_uid.o: src/tests/cmocka/test_find_uid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_find_uid-test_find_uid.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_find_uid-test_find_uid.Tpo -c -o src/tests/cmocka/test_find_uid-test_find_uid.o `test -f 'src/tests/cmocka/test_find_uid.c' || echo '$(srcdir)/'`src/tests/cmocka/test_find_uid.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_find_uid-test_find_uid.Tpo src/tests/cmocka/$(DEPDIR)/test_find_uid-test_find_uid.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_find_uid.c' object='src/tests/cmocka/test_find_uid-test_find_uid.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_find_uid-test_find_uid.o `test -f 'src/tests/cmocka/test_find_uid.c' || echo '$(srcdir)/'`src/tests/cmocka/test_find_uid.c src/tests/cmocka/test_find_uid-test_find_uid.obj: src/tests/cmocka/test_find_uid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_find_uid-test_find_uid.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_find_uid-test_find_uid.Tpo -c -o src/tests/cmocka/test_find_uid-test_find_uid.obj `if test -f 'src/tests/cmocka/test_find_uid.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_find_uid.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_find_uid.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_find_uid-test_find_uid.Tpo src/tests/cmocka/$(DEPDIR)/test_find_uid-test_find_uid.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_find_uid.c' object='src/tests/cmocka/test_find_uid-test_find_uid.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_find_uid-test_find_uid.obj `if test -f 'src/tests/cmocka/test_find_uid.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_find_uid.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_find_uid.c'; fi` src/util/test_find_uid-find_uid.o: src/util/find_uid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -MT src/util/test_find_uid-find_uid.o -MD -MP -MF src/util/$(DEPDIR)/test_find_uid-find_uid.Tpo -c -o src/util/test_find_uid-find_uid.o `test -f 'src/util/find_uid.c' || echo '$(srcdir)/'`src/util/find_uid.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_find_uid-find_uid.Tpo src/util/$(DEPDIR)/test_find_uid-find_uid.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/find_uid.c' object='src/util/test_find_uid-find_uid.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -c -o src/util/test_find_uid-find_uid.o `test -f 'src/util/find_uid.c' || echo '$(srcdir)/'`src/util/find_uid.c src/util/test_find_uid-find_uid.obj: src/util/find_uid.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -MT src/util/test_find_uid-find_uid.obj -MD -MP -MF src/util/$(DEPDIR)/test_find_uid-find_uid.Tpo -c -o src/util/test_find_uid-find_uid.obj `if test -f 'src/util/find_uid.c'; then $(CYGPATH_W) 'src/util/find_uid.c'; else $(CYGPATH_W) '$(srcdir)/src/util/find_uid.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_find_uid-find_uid.Tpo src/util/$(DEPDIR)/test_find_uid-find_uid.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/find_uid.c' object='src/util/test_find_uid-find_uid.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -c -o src/util/test_find_uid-find_uid.obj `if test -f 'src/util/find_uid.c'; then $(CYGPATH_W) 'src/util/find_uid.c'; else $(CYGPATH_W) '$(srcdir)/src/util/find_uid.c'; fi` src/util/test_find_uid-atomic_io.o: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -MT src/util/test_find_uid-atomic_io.o -MD -MP -MF src/util/$(DEPDIR)/test_find_uid-atomic_io.Tpo -c -o src/util/test_find_uid-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_find_uid-atomic_io.Tpo src/util/$(DEPDIR)/test_find_uid-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/test_find_uid-atomic_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -c -o src/util/test_find_uid-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c src/util/test_find_uid-atomic_io.obj: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -MT src/util/test_find_uid-atomic_io.obj -MD -MP -MF src/util/$(DEPDIR)/test_find_uid-atomic_io.Tpo -c -o src/util/test_find_uid-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_find_uid-atomic_io.Tpo src/util/$(DEPDIR)/test_find_uid-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/test_find_uid-atomic_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -c -o src/util/test_find_uid-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` src/util/test_find_uid-strtonum.o: src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -MT src/util/test_find_uid-strtonum.o -MD -MP -MF src/util/$(DEPDIR)/test_find_uid-strtonum.Tpo -c -o src/util/test_find_uid-strtonum.o `test -f 'src/util/strtonum.c' || echo '$(srcdir)/'`src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_find_uid-strtonum.Tpo src/util/$(DEPDIR)/test_find_uid-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/strtonum.c' object='src/util/test_find_uid-strtonum.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -c -o src/util/test_find_uid-strtonum.o `test -f 'src/util/strtonum.c' || echo '$(srcdir)/'`src/util/strtonum.c src/util/test_find_uid-strtonum.obj: src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -MT src/util/test_find_uid-strtonum.obj -MD -MP -MF src/util/$(DEPDIR)/test_find_uid-strtonum.Tpo -c -o src/util/test_find_uid-strtonum.obj `if test -f 'src/util/strtonum.c'; then $(CYGPATH_W) 'src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/src/util/strtonum.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_find_uid-strtonum.Tpo src/util/$(DEPDIR)/test_find_uid-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/strtonum.c' object='src/util/test_find_uid-strtonum.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_find_uid_CFLAGS) $(CFLAGS) -c -o src/util/test_find_uid-strtonum.obj `if test -f 'src/util/strtonum.c'; then $(CYGPATH_W) 'src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/src/util/strtonum.c'; fi` src/tests/cmocka/test_io-test_io.o: src/tests/cmocka/test_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_io-test_io.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_io-test_io.Tpo -c -o src/tests/cmocka/test_io-test_io.o `test -f 'src/tests/cmocka/test_io.c' || echo '$(srcdir)/'`src/tests/cmocka/test_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_io-test_io.Tpo src/tests/cmocka/$(DEPDIR)/test_io-test_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_io.c' object='src/tests/cmocka/test_io-test_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_io-test_io.o `test -f 'src/tests/cmocka/test_io.c' || echo '$(srcdir)/'`src/tests/cmocka/test_io.c src/tests/cmocka/test_io-test_io.obj: src/tests/cmocka/test_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_io-test_io.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_io-test_io.Tpo -c -o src/tests/cmocka/test_io-test_io.obj `if test -f 'src/tests/cmocka/test_io.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_io.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_io-test_io.Tpo src/tests/cmocka/$(DEPDIR)/test_io-test_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_io.c' object='src/tests/cmocka/test_io-test_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_io-test_io.obj `if test -f 'src/tests/cmocka/test_io.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_io.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_io.c'; fi` src/util/test_io-io.o: src/util/io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -MT src/util/test_io-io.o -MD -MP -MF src/util/$(DEPDIR)/test_io-io.Tpo -c -o src/util/test_io-io.o `test -f 'src/util/io.c' || echo '$(srcdir)/'`src/util/io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_io-io.Tpo src/util/$(DEPDIR)/test_io-io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/io.c' object='src/util/test_io-io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -c -o src/util/test_io-io.o `test -f 'src/util/io.c' || echo '$(srcdir)/'`src/util/io.c src/util/test_io-io.obj: src/util/io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -MT src/util/test_io-io.obj -MD -MP -MF src/util/$(DEPDIR)/test_io-io.Tpo -c -o src/util/test_io-io.obj `if test -f 'src/util/io.c'; then $(CYGPATH_W) 'src/util/io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_io-io.Tpo src/util/$(DEPDIR)/test_io-io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/io.c' object='src/util/test_io-io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -c -o src/util/test_io-io.obj `if test -f 'src/util/io.c'; then $(CYGPATH_W) 'src/util/io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/io.c'; fi` src/tests/test_io-common.o: src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -MT src/tests/test_io-common.o -MD -MP -MF src/tests/$(DEPDIR)/test_io-common.Tpo -c -o src/tests/test_io-common.o `test -f 'src/tests/common.c' || echo '$(srcdir)/'`src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/test_io-common.Tpo src/tests/$(DEPDIR)/test_io-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common.c' object='src/tests/test_io-common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -c -o src/tests/test_io-common.o `test -f 'src/tests/common.c' || echo '$(srcdir)/'`src/tests/common.c src/tests/test_io-common.obj: src/tests/common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -MT src/tests/test_io-common.obj -MD -MP -MF src/tests/$(DEPDIR)/test_io-common.Tpo -c -o src/tests/test_io-common.obj `if test -f 'src/tests/common.c'; then $(CYGPATH_W) 'src/tests/common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/test_io-common.Tpo src/tests/$(DEPDIR)/test_io-common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/common.c' object='src/tests/test_io-common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_io_CFLAGS) $(CFLAGS) -c -o src/tests/test_io-common.obj `if test -f 'src/tests/common.c'; then $(CYGPATH_W) 'src/tests/common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/common.c'; fi` src/responder/common/test_negcache-negcache.o: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-negcache.o -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-negcache.Tpo -c -o src/responder/common/test_negcache-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-negcache.Tpo src/responder/common/$(DEPDIR)/test_negcache-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/test_negcache-negcache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-negcache.o `test -f 'src/responder/common/negcache.c' || echo '$(srcdir)/'`src/responder/common/negcache.c src/responder/common/test_negcache-negcache.obj: src/responder/common/negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-negcache.obj -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-negcache.Tpo -c -o src/responder/common/test_negcache-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-negcache.Tpo src/responder/common/$(DEPDIR)/test_negcache-negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/negcache.c' object='src/responder/common/test_negcache-negcache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-negcache.obj `if test -f 'src/responder/common/negcache.c'; then $(CYGPATH_W) 'src/responder/common/negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/negcache.c'; fi` src/responder/common/test_negcache-responder_cmd.o: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_cmd.o -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_cmd.Tpo -c -o src/responder/common/test_negcache-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_cmd.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/test_negcache-responder_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_cmd.o `test -f 'src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`src/responder/common/responder_cmd.c src/responder/common/test_negcache-responder_cmd.obj: src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_cmd.obj -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_cmd.Tpo -c -o src/responder/common/test_negcache-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_cmd.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cmd.c' object='src/responder/common/test_negcache-responder_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_cmd.obj `if test -f 'src/responder/common/responder_cmd.c'; then $(CYGPATH_W) 'src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cmd.c'; fi` src/responder/common/test_negcache-responder_common.o: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_common.o -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_common.Tpo -c -o src/responder/common/test_negcache-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_common.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/test_negcache-responder_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_common.o `test -f 'src/responder/common/responder_common.c' || echo '$(srcdir)/'`src/responder/common/responder_common.c src/responder/common/test_negcache-responder_common.obj: src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_common.obj -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_common.Tpo -c -o src/responder/common/test_negcache-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_common.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_common.c' object='src/responder/common/test_negcache-responder_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_common.obj `if test -f 'src/responder/common/responder_common.c'; then $(CYGPATH_W) 'src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_common.c'; fi` src/responder/common/test_negcache-responder_dp.o: src/responder/common/responder_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_dp.o -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_dp.Tpo -c -o src/responder/common/test_negcache-responder_dp.o `test -f 'src/responder/common/responder_dp.c' || echo '$(srcdir)/'`src/responder/common/responder_dp.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_dp.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_dp.c' object='src/responder/common/test_negcache-responder_dp.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_dp.o `test -f 'src/responder/common/responder_dp.c' || echo '$(srcdir)/'`src/responder/common/responder_dp.c src/responder/common/test_negcache-responder_dp.obj: src/responder/common/responder_dp.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_dp.obj -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_dp.Tpo -c -o src/responder/common/test_negcache-responder_dp.obj `if test -f 'src/responder/common/responder_dp.c'; then $(CYGPATH_W) 'src/responder/common/responder_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_dp.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_dp.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_dp.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_dp.c' object='src/responder/common/test_negcache-responder_dp.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_dp.obj `if test -f 'src/responder/common/responder_dp.c'; then $(CYGPATH_W) 'src/responder/common/responder_dp.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_dp.c'; fi` src/responder/common/test_negcache-responder_packet.o: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_packet.o -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_packet.Tpo -c -o src/responder/common/test_negcache-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_packet.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/test_negcache-responder_packet.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_packet.o `test -f 'src/responder/common/responder_packet.c' || echo '$(srcdir)/'`src/responder/common/responder_packet.c src/responder/common/test_negcache-responder_packet.obj: src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_packet.obj -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_packet.Tpo -c -o src/responder/common/test_negcache-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_packet.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_packet.c' object='src/responder/common/test_negcache-responder_packet.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_packet.obj `if test -f 'src/responder/common/responder_packet.c'; then $(CYGPATH_W) 'src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_packet.c'; fi` src/responder/common/test_negcache-responder_get_domains.o: src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_get_domains.o -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_get_domains.Tpo -c -o src/responder/common/test_negcache-responder_get_domains.o `test -f 'src/responder/common/responder_get_domains.c' || echo '$(srcdir)/'`src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_get_domains.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_get_domains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_get_domains.c' object='src/responder/common/test_negcache-responder_get_domains.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_get_domains.o `test -f 'src/responder/common/responder_get_domains.c' || echo '$(srcdir)/'`src/responder/common/responder_get_domains.c src/responder/common/test_negcache-responder_get_domains.obj: src/responder/common/responder_get_domains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_get_domains.obj -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_get_domains.Tpo -c -o src/responder/common/test_negcache-responder_get_domains.obj `if test -f 'src/responder/common/responder_get_domains.c'; then $(CYGPATH_W) 'src/responder/common/responder_get_domains.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_get_domains.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_get_domains.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_get_domains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_get_domains.c' object='src/responder/common/test_negcache-responder_get_domains.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_get_domains.obj `if test -f 'src/responder/common/responder_get_domains.c'; then $(CYGPATH_W) 'src/responder/common/responder_get_domains.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_get_domains.c'; fi` src/responder/common/test_negcache-responder_utils.o: src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_utils.o -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_utils.Tpo -c -o src/responder/common/test_negcache-responder_utils.o `test -f 'src/responder/common/responder_utils.c' || echo '$(srcdir)/'`src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_utils.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_utils.c' object='src/responder/common/test_negcache-responder_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_utils.o `test -f 'src/responder/common/responder_utils.c' || echo '$(srcdir)/'`src/responder/common/responder_utils.c src/responder/common/test_negcache-responder_utils.obj: src/responder/common/responder_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_utils.obj -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_utils.Tpo -c -o src/responder/common/test_negcache-responder_utils.obj `if test -f 'src/responder/common/responder_utils.c'; then $(CYGPATH_W) 'src/responder/common/responder_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_utils.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_utils.c' object='src/responder/common/test_negcache-responder_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_utils.obj `if test -f 'src/responder/common/responder_utils.c'; then $(CYGPATH_W) 'src/responder/common/responder_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_utils.c'; fi` src/responder/common/test_negcache-responder_cache_req.o: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_cache_req.o -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_cache_req.Tpo -c -o src/responder/common/test_negcache-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/test_negcache-responder_cache_req.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_cache_req.o `test -f 'src/responder/common/responder_cache_req.c' || echo '$(srcdir)/'`src/responder/common/responder_cache_req.c src/responder/common/test_negcache-responder_cache_req.obj: src/responder/common/responder_cache_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/responder/common/test_negcache-responder_cache_req.obj -MD -MP -MF src/responder/common/$(DEPDIR)/test_negcache-responder_cache_req.Tpo -c -o src/responder/common/test_negcache-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/responder/common/$(DEPDIR)/test_negcache-responder_cache_req.Tpo src/responder/common/$(DEPDIR)/test_negcache-responder_cache_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/responder/common/responder_cache_req.c' object='src/responder/common/test_negcache-responder_cache_req.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/responder/common/test_negcache-responder_cache_req.obj `if test -f 'src/responder/common/responder_cache_req.c'; then $(CYGPATH_W) 'src/responder/common/responder_cache_req.c'; else $(CYGPATH_W) '$(srcdir)/src/responder/common/responder_cache_req.c'; fi` src/monitor/test_negcache-monitor_iface_generated.o: src/monitor/monitor_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/monitor/test_negcache-monitor_iface_generated.o -MD -MP -MF src/monitor/$(DEPDIR)/test_negcache-monitor_iface_generated.Tpo -c -o src/monitor/test_negcache-monitor_iface_generated.o `test -f 'src/monitor/monitor_iface_generated.c' || echo '$(srcdir)/'`src/monitor/monitor_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/monitor/$(DEPDIR)/test_negcache-monitor_iface_generated.Tpo src/monitor/$(DEPDIR)/test_negcache-monitor_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/monitor/monitor_iface_generated.c' object='src/monitor/test_negcache-monitor_iface_generated.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/monitor/test_negcache-monitor_iface_generated.o `test -f 'src/monitor/monitor_iface_generated.c' || echo '$(srcdir)/'`src/monitor/monitor_iface_generated.c src/monitor/test_negcache-monitor_iface_generated.obj: src/monitor/monitor_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/monitor/test_negcache-monitor_iface_generated.obj -MD -MP -MF src/monitor/$(DEPDIR)/test_negcache-monitor_iface_generated.Tpo -c -o src/monitor/test_negcache-monitor_iface_generated.obj `if test -f 'src/monitor/monitor_iface_generated.c'; then $(CYGPATH_W) 'src/monitor/monitor_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/monitor/monitor_iface_generated.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/monitor/$(DEPDIR)/test_negcache-monitor_iface_generated.Tpo src/monitor/$(DEPDIR)/test_negcache-monitor_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/monitor/monitor_iface_generated.c' object='src/monitor/test_negcache-monitor_iface_generated.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/monitor/test_negcache-monitor_iface_generated.obj `if test -f 'src/monitor/monitor_iface_generated.c'; then $(CYGPATH_W) 'src/monitor/monitor_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/monitor/monitor_iface_generated.c'; fi` src/providers/test_negcache-data_provider_iface_generated.o: src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/providers/test_negcache-data_provider_iface_generated.o -MD -MP -MF src/providers/$(DEPDIR)/test_negcache-data_provider_iface_generated.Tpo -c -o src/providers/test_negcache-data_provider_iface_generated.o `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_negcache-data_provider_iface_generated.Tpo src/providers/$(DEPDIR)/test_negcache-data_provider_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_iface_generated.c' object='src/providers/test_negcache-data_provider_iface_generated.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/providers/test_negcache-data_provider_iface_generated.o `test -f 'src/providers/data_provider_iface_generated.c' || echo '$(srcdir)/'`src/providers/data_provider_iface_generated.c src/providers/test_negcache-data_provider_iface_generated.obj: src/providers/data_provider_iface_generated.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/providers/test_negcache-data_provider_iface_generated.obj -MD -MP -MF src/providers/$(DEPDIR)/test_negcache-data_provider_iface_generated.Tpo -c -o src/providers/test_negcache-data_provider_iface_generated.obj `if test -f 'src/providers/data_provider_iface_generated.c'; then $(CYGPATH_W) 'src/providers/data_provider_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_iface_generated.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_negcache-data_provider_iface_generated.Tpo src/providers/$(DEPDIR)/test_negcache-data_provider_iface_generated.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_iface_generated.c' object='src/providers/test_negcache-data_provider_iface_generated.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/providers/test_negcache-data_provider_iface_generated.obj `if test -f 'src/providers/data_provider_iface_generated.c'; then $(CYGPATH_W) 'src/providers/data_provider_iface_generated.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_iface_generated.c'; fi` src/providers/test_negcache-data_provider_req.o: src/providers/data_provider_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/providers/test_negcache-data_provider_req.o -MD -MP -MF src/providers/$(DEPDIR)/test_negcache-data_provider_req.Tpo -c -o src/providers/test_negcache-data_provider_req.o `test -f 'src/providers/data_provider_req.c' || echo '$(srcdir)/'`src/providers/data_provider_req.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_negcache-data_provider_req.Tpo src/providers/$(DEPDIR)/test_negcache-data_provider_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_req.c' object='src/providers/test_negcache-data_provider_req.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/providers/test_negcache-data_provider_req.o `test -f 'src/providers/data_provider_req.c' || echo '$(srcdir)/'`src/providers/data_provider_req.c src/providers/test_negcache-data_provider_req.obj: src/providers/data_provider_req.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/providers/test_negcache-data_provider_req.obj -MD -MP -MF src/providers/$(DEPDIR)/test_negcache-data_provider_req.Tpo -c -o src/providers/test_negcache-data_provider_req.obj `if test -f 'src/providers/data_provider_req.c'; then $(CYGPATH_W) 'src/providers/data_provider_req.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_req.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_negcache-data_provider_req.Tpo src/providers/$(DEPDIR)/test_negcache-data_provider_req.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_req.c' object='src/providers/test_negcache-data_provider_req.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/providers/test_negcache-data_provider_req.obj `if test -f 'src/providers/data_provider_req.c'; then $(CYGPATH_W) 'src/providers/data_provider_req.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_req.c'; fi` src/tests/cmocka/test_negcache-test_negcache.o: src/tests/cmocka/test_negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_negcache-test_negcache.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_negcache-test_negcache.Tpo -c -o src/tests/cmocka/test_negcache-test_negcache.o `test -f 'src/tests/cmocka/test_negcache.c' || echo '$(srcdir)/'`src/tests/cmocka/test_negcache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_negcache-test_negcache.Tpo src/tests/cmocka/$(DEPDIR)/test_negcache-test_negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_negcache.c' object='src/tests/cmocka/test_negcache-test_negcache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_negcache-test_negcache.o `test -f 'src/tests/cmocka/test_negcache.c' || echo '$(srcdir)/'`src/tests/cmocka/test_negcache.c src/tests/cmocka/test_negcache-test_negcache.obj: src/tests/cmocka/test_negcache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_negcache-test_negcache.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_negcache-test_negcache.Tpo -c -o src/tests/cmocka/test_negcache-test_negcache.obj `if test -f 'src/tests/cmocka/test_negcache.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_negcache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_negcache-test_negcache.Tpo src/tests/cmocka/$(DEPDIR)/test_negcache-test_negcache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_negcache.c' object='src/tests/cmocka/test_negcache-test_negcache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_negcache_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_negcache-test_negcache.obj `if test -f 'src/tests/cmocka/test_negcache.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_negcache.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_negcache.c'; fi` src/tests/cmocka/test_be_ptask-common_mock_be.o: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_be_ptask-common_mock_be.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_be_ptask-common_mock_be.Tpo -c -o src/tests/cmocka/test_be_ptask-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_be_ptask-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/test_be_ptask-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/test_be_ptask-common_mock_be.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_be_ptask-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c src/tests/cmocka/test_be_ptask-common_mock_be.obj: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_be_ptask-common_mock_be.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_be_ptask-common_mock_be.Tpo -c -o src/tests/cmocka/test_be_ptask-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_be_ptask-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/test_be_ptask-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/test_be_ptask-common_mock_be.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_be_ptask-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` src/tests/cmocka/test_be_ptask-test_be_ptask.o: src/tests/cmocka/test_be_ptask.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_be_ptask-test_be_ptask.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_be_ptask-test_be_ptask.Tpo -c -o src/tests/cmocka/test_be_ptask-test_be_ptask.o `test -f 'src/tests/cmocka/test_be_ptask.c' || echo '$(srcdir)/'`src/tests/cmocka/test_be_ptask.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_be_ptask-test_be_ptask.Tpo src/tests/cmocka/$(DEPDIR)/test_be_ptask-test_be_ptask.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_be_ptask.c' object='src/tests/cmocka/test_be_ptask-test_be_ptask.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_be_ptask-test_be_ptask.o `test -f 'src/tests/cmocka/test_be_ptask.c' || echo '$(srcdir)/'`src/tests/cmocka/test_be_ptask.c src/tests/cmocka/test_be_ptask-test_be_ptask.obj: src/tests/cmocka/test_be_ptask.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_be_ptask-test_be_ptask.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_be_ptask-test_be_ptask.Tpo -c -o src/tests/cmocka/test_be_ptask-test_be_ptask.obj `if test -f 'src/tests/cmocka/test_be_ptask.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_be_ptask.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_be_ptask.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_be_ptask-test_be_ptask.Tpo src/tests/cmocka/$(DEPDIR)/test_be_ptask-test_be_ptask.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_be_ptask.c' object='src/tests/cmocka/test_be_ptask-test_be_ptask.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_be_ptask-test_be_ptask.obj `if test -f 'src/tests/cmocka/test_be_ptask.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_be_ptask.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_be_ptask.c'; fi` src/providers/test_be_ptask-dp_ptask.o: src/providers/dp_ptask.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -MT src/providers/test_be_ptask-dp_ptask.o -MD -MP -MF src/providers/$(DEPDIR)/test_be_ptask-dp_ptask.Tpo -c -o src/providers/test_be_ptask-dp_ptask.o `test -f 'src/providers/dp_ptask.c' || echo '$(srcdir)/'`src/providers/dp_ptask.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_be_ptask-dp_ptask.Tpo src/providers/$(DEPDIR)/test_be_ptask-dp_ptask.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/dp_ptask.c' object='src/providers/test_be_ptask-dp_ptask.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -c -o src/providers/test_be_ptask-dp_ptask.o `test -f 'src/providers/dp_ptask.c' || echo '$(srcdir)/'`src/providers/dp_ptask.c src/providers/test_be_ptask-dp_ptask.obj: src/providers/dp_ptask.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -MT src/providers/test_be_ptask-dp_ptask.obj -MD -MP -MF src/providers/$(DEPDIR)/test_be_ptask-dp_ptask.Tpo -c -o src/providers/test_be_ptask-dp_ptask.obj `if test -f 'src/providers/dp_ptask.c'; then $(CYGPATH_W) 'src/providers/dp_ptask.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/dp_ptask.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_be_ptask-dp_ptask.Tpo src/providers/$(DEPDIR)/test_be_ptask-dp_ptask.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/dp_ptask.c' object='src/providers/test_be_ptask-dp_ptask.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_be_ptask_CFLAGS) $(CFLAGS) -c -o src/providers/test_be_ptask-dp_ptask.obj `if test -f 'src/providers/dp_ptask.c'; then $(CYGPATH_W) 'src/providers/dp_ptask.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/dp_ptask.c'; fi` src/tests/cmocka/test_cert_utils-test_cert_utils.o: src/tests/cmocka/test_cert_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cert_utils_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_cert_utils-test_cert_utils.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_cert_utils-test_cert_utils.Tpo -c -o src/tests/cmocka/test_cert_utils-test_cert_utils.o `test -f 'src/tests/cmocka/test_cert_utils.c' || echo '$(srcdir)/'`src/tests/cmocka/test_cert_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_cert_utils-test_cert_utils.Tpo src/tests/cmocka/$(DEPDIR)/test_cert_utils-test_cert_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_cert_utils.c' object='src/tests/cmocka/test_cert_utils-test_cert_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cert_utils_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_cert_utils-test_cert_utils.o `test -f 'src/tests/cmocka/test_cert_utils.c' || echo '$(srcdir)/'`src/tests/cmocka/test_cert_utils.c src/tests/cmocka/test_cert_utils-test_cert_utils.obj: src/tests/cmocka/test_cert_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cert_utils_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_cert_utils-test_cert_utils.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_cert_utils-test_cert_utils.Tpo -c -o src/tests/cmocka/test_cert_utils-test_cert_utils.obj `if test -f 'src/tests/cmocka/test_cert_utils.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_cert_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_cert_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_cert_utils-test_cert_utils.Tpo src/tests/cmocka/$(DEPDIR)/test_cert_utils-test_cert_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_cert_utils.c' object='src/tests/cmocka/test_cert_utils-test_cert_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_cert_utils_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_cert_utils-test_cert_utils.obj `if test -f 'src/tests/cmocka/test_cert_utils.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_cert_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_cert_utils.c'; fi` src/tests/cmocka/test_child_common-test_child_common.o: src/tests/cmocka/test_child_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_child_common-test_child_common.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_child_common-test_child_common.Tpo -c -o src/tests/cmocka/test_child_common-test_child_common.o `test -f 'src/tests/cmocka/test_child_common.c' || echo '$(srcdir)/'`src/tests/cmocka/test_child_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_child_common-test_child_common.Tpo src/tests/cmocka/$(DEPDIR)/test_child_common-test_child_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_child_common.c' object='src/tests/cmocka/test_child_common-test_child_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_child_common-test_child_common.o `test -f 'src/tests/cmocka/test_child_common.c' || echo '$(srcdir)/'`src/tests/cmocka/test_child_common.c src/tests/cmocka/test_child_common-test_child_common.obj: src/tests/cmocka/test_child_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_child_common-test_child_common.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_child_common-test_child_common.Tpo -c -o src/tests/cmocka/test_child_common-test_child_common.obj `if test -f 'src/tests/cmocka/test_child_common.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_child_common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_child_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_child_common-test_child_common.Tpo src/tests/cmocka/$(DEPDIR)/test_child_common-test_child_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_child_common.c' object='src/tests/cmocka/test_child_common-test_child_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_child_common-test_child_common.obj `if test -f 'src/tests/cmocka/test_child_common.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_child_common.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_child_common.c'; fi` src/util/test_child_common-child_common.o: src/util/child_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/util/test_child_common-child_common.o -MD -MP -MF src/util/$(DEPDIR)/test_child_common-child_common.Tpo -c -o src/util/test_child_common-child_common.o `test -f 'src/util/child_common.c' || echo '$(srcdir)/'`src/util/child_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_child_common-child_common.Tpo src/util/$(DEPDIR)/test_child_common-child_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/child_common.c' object='src/util/test_child_common-child_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/util/test_child_common-child_common.o `test -f 'src/util/child_common.c' || echo '$(srcdir)/'`src/util/child_common.c src/util/test_child_common-child_common.obj: src/util/child_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/util/test_child_common-child_common.obj -MD -MP -MF src/util/$(DEPDIR)/test_child_common-child_common.Tpo -c -o src/util/test_child_common-child_common.obj `if test -f 'src/util/child_common.c'; then $(CYGPATH_W) 'src/util/child_common.c'; else $(CYGPATH_W) '$(srcdir)/src/util/child_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_child_common-child_common.Tpo src/util/$(DEPDIR)/test_child_common-child_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/child_common.c' object='src/util/test_child_common-child_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/util/test_child_common-child_common.obj `if test -f 'src/util/child_common.c'; then $(CYGPATH_W) 'src/util/child_common.c'; else $(CYGPATH_W) '$(srcdir)/src/util/child_common.c'; fi` src/util/test_child_common-signal.o: src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/util/test_child_common-signal.o -MD -MP -MF src/util/$(DEPDIR)/test_child_common-signal.Tpo -c -o src/util/test_child_common-signal.o `test -f 'src/util/signal.c' || echo '$(srcdir)/'`src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_child_common-signal.Tpo src/util/$(DEPDIR)/test_child_common-signal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/signal.c' object='src/util/test_child_common-signal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/util/test_child_common-signal.o `test -f 'src/util/signal.c' || echo '$(srcdir)/'`src/util/signal.c src/util/test_child_common-signal.obj: src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/util/test_child_common-signal.obj -MD -MP -MF src/util/$(DEPDIR)/test_child_common-signal.Tpo -c -o src/util/test_child_common-signal.obj `if test -f 'src/util/signal.c'; then $(CYGPATH_W) 'src/util/signal.c'; else $(CYGPATH_W) '$(srcdir)/src/util/signal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_child_common-signal.Tpo src/util/$(DEPDIR)/test_child_common-signal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/signal.c' object='src/util/test_child_common-signal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/util/test_child_common-signal.obj `if test -f 'src/util/signal.c'; then $(CYGPATH_W) 'src/util/signal.c'; else $(CYGPATH_W) '$(srcdir)/src/util/signal.c'; fi` src/util/test_child_common-atomic_io.o: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/util/test_child_common-atomic_io.o -MD -MP -MF src/util/$(DEPDIR)/test_child_common-atomic_io.Tpo -c -o src/util/test_child_common-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_child_common-atomic_io.Tpo src/util/$(DEPDIR)/test_child_common-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/test_child_common-atomic_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/util/test_child_common-atomic_io.o `test -f 'src/util/atomic_io.c' || echo '$(srcdir)/'`src/util/atomic_io.c src/util/test_child_common-atomic_io.obj: src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/util/test_child_common-atomic_io.obj -MD -MP -MF src/util/$(DEPDIR)/test_child_common-atomic_io.Tpo -c -o src/util/test_child_common-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_child_common-atomic_io.Tpo src/util/$(DEPDIR)/test_child_common-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/atomic_io.c' object='src/util/test_child_common-atomic_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/util/test_child_common-atomic_io.obj `if test -f 'src/util/atomic_io.c'; then $(CYGPATH_W) 'src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/src/util/atomic_io.c'; fi` src/util/test_child_common-util_errors.o: src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/util/test_child_common-util_errors.o -MD -MP -MF src/util/$(DEPDIR)/test_child_common-util_errors.Tpo -c -o src/util/test_child_common-util_errors.o `test -f 'src/util/util_errors.c' || echo '$(srcdir)/'`src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_child_common-util_errors.Tpo src/util/$(DEPDIR)/test_child_common-util_errors.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util_errors.c' object='src/util/test_child_common-util_errors.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/util/test_child_common-util_errors.o `test -f 'src/util/util_errors.c' || echo '$(srcdir)/'`src/util/util_errors.c src/util/test_child_common-util_errors.obj: src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/util/test_child_common-util_errors.obj -MD -MP -MF src/util/$(DEPDIR)/test_child_common-util_errors.Tpo -c -o src/util/test_child_common-util_errors.obj `if test -f 'src/util/util_errors.c'; then $(CYGPATH_W) 'src/util/util_errors.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util_errors.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_child_common-util_errors.Tpo src/util/$(DEPDIR)/test_child_common-util_errors.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util_errors.c' object='src/util/test_child_common-util_errors.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/util/test_child_common-util_errors.obj `if test -f 'src/util/util_errors.c'; then $(CYGPATH_W) 'src/util/util_errors.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util_errors.c'; fi` src/util/test_child_common-util.o: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/util/test_child_common-util.o -MD -MP -MF src/util/$(DEPDIR)/test_child_common-util.Tpo -c -o src/util/test_child_common-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_child_common-util.Tpo src/util/$(DEPDIR)/test_child_common-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/test_child_common-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/util/test_child_common-util.o `test -f 'src/util/util.c' || echo '$(srcdir)/'`src/util/util.c src/util/test_child_common-util.obj: src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -MT src/util/test_child_common-util.obj -MD -MP -MF src/util/$(DEPDIR)/test_child_common-util.Tpo -c -o src/util/test_child_common-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_child_common-util.Tpo src/util/$(DEPDIR)/test_child_common-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/util.c' object='src/util/test_child_common-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_child_common_CFLAGS) $(CFLAGS) -c -o src/util/test_child_common-util.obj `if test -f 'src/util/util.c'; then $(CYGPATH_W) 'src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/src/util/util.c'; fi` src/tests/cmocka/test_copy_ccache-test_copy_ccache.o: src/tests/cmocka/test_copy_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_copy_ccache-test_copy_ccache.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_copy_ccache-test_copy_ccache.Tpo -c -o src/tests/cmocka/test_copy_ccache-test_copy_ccache.o `test -f 'src/tests/cmocka/test_copy_ccache.c' || echo '$(srcdir)/'`src/tests/cmocka/test_copy_ccache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_copy_ccache-test_copy_ccache.Tpo src/tests/cmocka/$(DEPDIR)/test_copy_ccache-test_copy_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_copy_ccache.c' object='src/tests/cmocka/test_copy_ccache-test_copy_ccache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_copy_ccache-test_copy_ccache.o `test -f 'src/tests/cmocka/test_copy_ccache.c' || echo '$(srcdir)/'`src/tests/cmocka/test_copy_ccache.c src/tests/cmocka/test_copy_ccache-test_copy_ccache.obj: src/tests/cmocka/test_copy_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_copy_ccache-test_copy_ccache.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_copy_ccache-test_copy_ccache.Tpo -c -o src/tests/cmocka/test_copy_ccache-test_copy_ccache.obj `if test -f 'src/tests/cmocka/test_copy_ccache.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_copy_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_copy_ccache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_copy_ccache-test_copy_ccache.Tpo src/tests/cmocka/$(DEPDIR)/test_copy_ccache-test_copy_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_copy_ccache.c' object='src/tests/cmocka/test_copy_ccache-test_copy_ccache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_copy_ccache-test_copy_ccache.obj `if test -f 'src/tests/cmocka/test_copy_ccache.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_copy_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_copy_ccache.c'; fi` src/providers/krb5/test_copy_ccache-krb5_ccache.o: src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_copy_ccache-krb5_ccache.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_copy_ccache-krb5_ccache.Tpo -c -o src/providers/krb5/test_copy_ccache-krb5_ccache.o `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_copy_ccache-krb5_ccache.Tpo src/providers/krb5/$(DEPDIR)/test_copy_ccache-krb5_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_ccache.c' object='src/providers/krb5/test_copy_ccache-krb5_ccache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_copy_ccache-krb5_ccache.o `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c src/providers/krb5/test_copy_ccache-krb5_ccache.obj: src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_copy_ccache-krb5_ccache.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_copy_ccache-krb5_ccache.Tpo -c -o src/providers/krb5/test_copy_ccache-krb5_ccache.obj `if test -f 'src/providers/krb5/krb5_ccache.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_ccache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_copy_ccache-krb5_ccache.Tpo src/providers/krb5/$(DEPDIR)/test_copy_ccache-krb5_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_ccache.c' object='src/providers/krb5/test_copy_ccache-krb5_ccache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_copy_ccache-krb5_ccache.obj `if test -f 'src/providers/krb5/krb5_ccache.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_ccache.c'; fi` src/util/test_copy_ccache-sss_krb5.o: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -MT src/util/test_copy_ccache-sss_krb5.o -MD -MP -MF src/util/$(DEPDIR)/test_copy_ccache-sss_krb5.Tpo -c -o src/util/test_copy_ccache-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_copy_ccache-sss_krb5.Tpo src/util/$(DEPDIR)/test_copy_ccache-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/test_copy_ccache-sss_krb5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -c -o src/util/test_copy_ccache-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c src/util/test_copy_ccache-sss_krb5.obj: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -MT src/util/test_copy_ccache-sss_krb5.obj -MD -MP -MF src/util/$(DEPDIR)/test_copy_ccache-sss_krb5.Tpo -c -o src/util/test_copy_ccache-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_copy_ccache-sss_krb5.Tpo src/util/$(DEPDIR)/test_copy_ccache-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/test_copy_ccache-sss_krb5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_ccache_CFLAGS) $(CFLAGS) -c -o src/util/test_copy_ccache-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` src/tests/cmocka/test_copy_keytab-common_mock_krb5.o: src/tests/cmocka/common_mock_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_copy_keytab-common_mock_krb5.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_copy_keytab-common_mock_krb5.Tpo -c -o src/tests/cmocka/test_copy_keytab-common_mock_krb5.o `test -f 'src/tests/cmocka/common_mock_krb5.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_krb5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_copy_keytab-common_mock_krb5.Tpo src/tests/cmocka/$(DEPDIR)/test_copy_keytab-common_mock_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_krb5.c' object='src/tests/cmocka/test_copy_keytab-common_mock_krb5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_copy_keytab-common_mock_krb5.o `test -f 'src/tests/cmocka/common_mock_krb5.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_krb5.c src/tests/cmocka/test_copy_keytab-common_mock_krb5.obj: src/tests/cmocka/common_mock_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_copy_keytab-common_mock_krb5.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_copy_keytab-common_mock_krb5.Tpo -c -o src/tests/cmocka/test_copy_keytab-common_mock_krb5.obj `if test -f 'src/tests/cmocka/common_mock_krb5.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_krb5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_copy_keytab-common_mock_krb5.Tpo src/tests/cmocka/$(DEPDIR)/test_copy_keytab-common_mock_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_krb5.c' object='src/tests/cmocka/test_copy_keytab-common_mock_krb5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_copy_keytab-common_mock_krb5.obj `if test -f 'src/tests/cmocka/common_mock_krb5.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_krb5.c'; fi` src/tests/cmocka/test_copy_keytab-test_copy_keytab.o: src/tests/cmocka/test_copy_keytab.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_copy_keytab-test_copy_keytab.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_copy_keytab-test_copy_keytab.Tpo -c -o src/tests/cmocka/test_copy_keytab-test_copy_keytab.o `test -f 'src/tests/cmocka/test_copy_keytab.c' || echo '$(srcdir)/'`src/tests/cmocka/test_copy_keytab.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_copy_keytab-test_copy_keytab.Tpo src/tests/cmocka/$(DEPDIR)/test_copy_keytab-test_copy_keytab.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_copy_keytab.c' object='src/tests/cmocka/test_copy_keytab-test_copy_keytab.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_copy_keytab-test_copy_keytab.o `test -f 'src/tests/cmocka/test_copy_keytab.c' || echo '$(srcdir)/'`src/tests/cmocka/test_copy_keytab.c src/tests/cmocka/test_copy_keytab-test_copy_keytab.obj: src/tests/cmocka/test_copy_keytab.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_copy_keytab-test_copy_keytab.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_copy_keytab-test_copy_keytab.Tpo -c -o src/tests/cmocka/test_copy_keytab-test_copy_keytab.obj `if test -f 'src/tests/cmocka/test_copy_keytab.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_copy_keytab.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_copy_keytab.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_copy_keytab-test_copy_keytab.Tpo src/tests/cmocka/$(DEPDIR)/test_copy_keytab-test_copy_keytab.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_copy_keytab.c' object='src/tests/cmocka/test_copy_keytab-test_copy_keytab.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_copy_keytab-test_copy_keytab.obj `if test -f 'src/tests/cmocka/test_copy_keytab.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_copy_keytab.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_copy_keytab.c'; fi` src/providers/krb5/test_copy_keytab-krb5_keytab.o: src/providers/krb5/krb5_keytab.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_copy_keytab-krb5_keytab.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_copy_keytab-krb5_keytab.Tpo -c -o src/providers/krb5/test_copy_keytab-krb5_keytab.o `test -f 'src/providers/krb5/krb5_keytab.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_keytab.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_copy_keytab-krb5_keytab.Tpo src/providers/krb5/$(DEPDIR)/test_copy_keytab-krb5_keytab.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_keytab.c' object='src/providers/krb5/test_copy_keytab-krb5_keytab.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_copy_keytab-krb5_keytab.o `test -f 'src/providers/krb5/krb5_keytab.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_keytab.c src/providers/krb5/test_copy_keytab-krb5_keytab.obj: src/providers/krb5/krb5_keytab.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_copy_keytab-krb5_keytab.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_copy_keytab-krb5_keytab.Tpo -c -o src/providers/krb5/test_copy_keytab-krb5_keytab.obj `if test -f 'src/providers/krb5/krb5_keytab.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_keytab.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_keytab.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_copy_keytab-krb5_keytab.Tpo src/providers/krb5/$(DEPDIR)/test_copy_keytab-krb5_keytab.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_keytab.c' object='src/providers/krb5/test_copy_keytab-krb5_keytab.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_copy_keytab-krb5_keytab.obj `if test -f 'src/providers/krb5/krb5_keytab.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_keytab.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_keytab.c'; fi` src/util/test_copy_keytab-sss_krb5.o: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -MT src/util/test_copy_keytab-sss_krb5.o -MD -MP -MF src/util/$(DEPDIR)/test_copy_keytab-sss_krb5.Tpo -c -o src/util/test_copy_keytab-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_copy_keytab-sss_krb5.Tpo src/util/$(DEPDIR)/test_copy_keytab-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/test_copy_keytab-sss_krb5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -c -o src/util/test_copy_keytab-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c src/util/test_copy_keytab-sss_krb5.obj: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -MT src/util/test_copy_keytab-sss_krb5.obj -MD -MP -MF src/util/$(DEPDIR)/test_copy_keytab-sss_krb5.Tpo -c -o src/util/test_copy_keytab-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_copy_keytab-sss_krb5.Tpo src/util/$(DEPDIR)/test_copy_keytab-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/test_copy_keytab-sss_krb5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_copy_keytab_CFLAGS) $(CFLAGS) -c -o src/util/test_copy_keytab-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` src/providers/test_data_provider_be-data_provider_be.o: src/providers/data_provider_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -MT src/providers/test_data_provider_be-data_provider_be.o -MD -MP -MF src/providers/$(DEPDIR)/test_data_provider_be-data_provider_be.Tpo -c -o src/providers/test_data_provider_be-data_provider_be.o `test -f 'src/providers/data_provider_be.c' || echo '$(srcdir)/'`src/providers/data_provider_be.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_data_provider_be-data_provider_be.Tpo src/providers/$(DEPDIR)/test_data_provider_be-data_provider_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_be.c' object='src/providers/test_data_provider_be-data_provider_be.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -c -o src/providers/test_data_provider_be-data_provider_be.o `test -f 'src/providers/data_provider_be.c' || echo '$(srcdir)/'`src/providers/data_provider_be.c src/providers/test_data_provider_be-data_provider_be.obj: src/providers/data_provider_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -MT src/providers/test_data_provider_be-data_provider_be.obj -MD -MP -MF src/providers/$(DEPDIR)/test_data_provider_be-data_provider_be.Tpo -c -o src/providers/test_data_provider_be-data_provider_be.obj `if test -f 'src/providers/data_provider_be.c'; then $(CYGPATH_W) 'src/providers/data_provider_be.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_be.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_data_provider_be-data_provider_be.Tpo src/providers/$(DEPDIR)/test_data_provider_be-data_provider_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/data_provider_be.c' object='src/providers/test_data_provider_be-data_provider_be.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -c -o src/providers/test_data_provider_be-data_provider_be.obj `if test -f 'src/providers/data_provider_be.c'; then $(CYGPATH_W) 'src/providers/data_provider_be.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/data_provider_be.c'; fi` src/tests/cmocka/test_data_provider_be-test_data_provider_be.o: src/tests/cmocka/test_data_provider_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_data_provider_be-test_data_provider_be.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_data_provider_be-test_data_provider_be.Tpo -c -o src/tests/cmocka/test_data_provider_be-test_data_provider_be.o `test -f 'src/tests/cmocka/test_data_provider_be.c' || echo '$(srcdir)/'`src/tests/cmocka/test_data_provider_be.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_data_provider_be-test_data_provider_be.Tpo src/tests/cmocka/$(DEPDIR)/test_data_provider_be-test_data_provider_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_data_provider_be.c' object='src/tests/cmocka/test_data_provider_be-test_data_provider_be.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_data_provider_be-test_data_provider_be.o `test -f 'src/tests/cmocka/test_data_provider_be.c' || echo '$(srcdir)/'`src/tests/cmocka/test_data_provider_be.c src/tests/cmocka/test_data_provider_be-test_data_provider_be.obj: src/tests/cmocka/test_data_provider_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_data_provider_be-test_data_provider_be.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_data_provider_be-test_data_provider_be.Tpo -c -o src/tests/cmocka/test_data_provider_be-test_data_provider_be.obj `if test -f 'src/tests/cmocka/test_data_provider_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_data_provider_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_data_provider_be.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_data_provider_be-test_data_provider_be.Tpo src/tests/cmocka/$(DEPDIR)/test_data_provider_be-test_data_provider_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_data_provider_be.c' object='src/tests/cmocka/test_data_provider_be-test_data_provider_be.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_data_provider_be-test_data_provider_be.obj `if test -f 'src/tests/cmocka/test_data_provider_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_data_provider_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_data_provider_be.c'; fi` src/tests/cmocka/test_data_provider_be-common_mock_be.o: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_data_provider_be-common_mock_be.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_data_provider_be-common_mock_be.Tpo -c -o src/tests/cmocka/test_data_provider_be-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_data_provider_be-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/test_data_provider_be-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/test_data_provider_be-common_mock_be.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_data_provider_be-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c src/tests/cmocka/test_data_provider_be-common_mock_be.obj: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_data_provider_be-common_mock_be.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_data_provider_be-common_mock_be.Tpo -c -o src/tests/cmocka/test_data_provider_be-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_data_provider_be-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/test_data_provider_be-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/test_data_provider_be-common_mock_be.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_data_provider_be_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_data_provider_be-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` src/tests/cmocka/test_fo_srv-test_fo_srv.o: src/tests/cmocka/test_fo_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_fo_srv-test_fo_srv.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_fo_srv-test_fo_srv.Tpo -c -o src/tests/cmocka/test_fo_srv-test_fo_srv.o `test -f 'src/tests/cmocka/test_fo_srv.c' || echo '$(srcdir)/'`src/tests/cmocka/test_fo_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_fo_srv-test_fo_srv.Tpo src/tests/cmocka/$(DEPDIR)/test_fo_srv-test_fo_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_fo_srv.c' object='src/tests/cmocka/test_fo_srv-test_fo_srv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_fo_srv-test_fo_srv.o `test -f 'src/tests/cmocka/test_fo_srv.c' || echo '$(srcdir)/'`src/tests/cmocka/test_fo_srv.c src/tests/cmocka/test_fo_srv-test_fo_srv.obj: src/tests/cmocka/test_fo_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_fo_srv-test_fo_srv.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_fo_srv-test_fo_srv.Tpo -c -o src/tests/cmocka/test_fo_srv-test_fo_srv.obj `if test -f 'src/tests/cmocka/test_fo_srv.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_fo_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_fo_srv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_fo_srv-test_fo_srv.Tpo src/tests/cmocka/$(DEPDIR)/test_fo_srv-test_fo_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_fo_srv.c' object='src/tests/cmocka/test_fo_srv-test_fo_srv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_fo_srv-test_fo_srv.obj `if test -f 'src/tests/cmocka/test_fo_srv.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_fo_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_fo_srv.c'; fi` src/providers/test_fo_srv-fail_over.o: src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -MT src/providers/test_fo_srv-fail_over.o -MD -MP -MF src/providers/$(DEPDIR)/test_fo_srv-fail_over.Tpo -c -o src/providers/test_fo_srv-fail_over.o `test -f 'src/providers/fail_over.c' || echo '$(srcdir)/'`src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_fo_srv-fail_over.Tpo src/providers/$(DEPDIR)/test_fo_srv-fail_over.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over.c' object='src/providers/test_fo_srv-fail_over.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -c -o src/providers/test_fo_srv-fail_over.o `test -f 'src/providers/fail_over.c' || echo '$(srcdir)/'`src/providers/fail_over.c src/providers/test_fo_srv-fail_over.obj: src/providers/fail_over.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -MT src/providers/test_fo_srv-fail_over.obj -MD -MP -MF src/providers/$(DEPDIR)/test_fo_srv-fail_over.Tpo -c -o src/providers/test_fo_srv-fail_over.obj `if test -f 'src/providers/fail_over.c'; then $(CYGPATH_W) 'src/providers/fail_over.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_fo_srv-fail_over.Tpo src/providers/$(DEPDIR)/test_fo_srv-fail_over.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over.c' object='src/providers/test_fo_srv-fail_over.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -c -o src/providers/test_fo_srv-fail_over.obj `if test -f 'src/providers/fail_over.c'; then $(CYGPATH_W) 'src/providers/fail_over.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over.c'; fi` src/providers/test_fo_srv-fail_over_srv.o: src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -MT src/providers/test_fo_srv-fail_over_srv.o -MD -MP -MF src/providers/$(DEPDIR)/test_fo_srv-fail_over_srv.Tpo -c -o src/providers/test_fo_srv-fail_over_srv.o `test -f 'src/providers/fail_over_srv.c' || echo '$(srcdir)/'`src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_fo_srv-fail_over_srv.Tpo src/providers/$(DEPDIR)/test_fo_srv-fail_over_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over_srv.c' object='src/providers/test_fo_srv-fail_over_srv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -c -o src/providers/test_fo_srv-fail_over_srv.o `test -f 'src/providers/fail_over_srv.c' || echo '$(srcdir)/'`src/providers/fail_over_srv.c src/providers/test_fo_srv-fail_over_srv.obj: src/providers/fail_over_srv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -MT src/providers/test_fo_srv-fail_over_srv.obj -MD -MP -MF src/providers/$(DEPDIR)/test_fo_srv-fail_over_srv.Tpo -c -o src/providers/test_fo_srv-fail_over_srv.obj `if test -f 'src/providers/fail_over_srv.c'; then $(CYGPATH_W) 'src/providers/fail_over_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over_srv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/$(DEPDIR)/test_fo_srv-fail_over_srv.Tpo src/providers/$(DEPDIR)/test_fo_srv-fail_over_srv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/fail_over_srv.c' object='src/providers/test_fo_srv-fail_over_srv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_fo_srv_CFLAGS) $(CFLAGS) -c -o src/providers/test_fo_srv-fail_over_srv.obj `if test -f 'src/providers/fail_over_srv.c'; then $(CYGPATH_W) 'src/providers/fail_over_srv.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/fail_over_srv.c'; fi` src/providers/ipa/test_ipa_dn-ipa_dn.o: src/providers/ipa/ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_dn_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_dn-ipa_dn.o -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_dn-ipa_dn.Tpo -c -o src/providers/ipa/test_ipa_dn-ipa_dn.o `test -f 'src/providers/ipa/ipa_dn.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_dn-ipa_dn.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_dn-ipa_dn.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_dn.c' object='src/providers/ipa/test_ipa_dn-ipa_dn.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_dn_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_dn-ipa_dn.o `test -f 'src/providers/ipa/ipa_dn.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_dn.c src/providers/ipa/test_ipa_dn-ipa_dn.obj: src/providers/ipa/ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_dn_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_dn-ipa_dn.obj -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_dn-ipa_dn.Tpo -c -o src/providers/ipa/test_ipa_dn-ipa_dn.obj `if test -f 'src/providers/ipa/ipa_dn.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_dn.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_dn.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_dn-ipa_dn.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_dn-ipa_dn.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_dn.c' object='src/providers/ipa/test_ipa_dn-ipa_dn.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_dn_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_dn-ipa_dn.obj `if test -f 'src/providers/ipa/ipa_dn.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_dn.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_dn.c'; fi` src/tests/cmocka/test_ipa_dn-test_ipa_dn.o: src/tests/cmocka/test_ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_dn_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_dn-test_ipa_dn.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_dn-test_ipa_dn.Tpo -c -o src/tests/cmocka/test_ipa_dn-test_ipa_dn.o `test -f 'src/tests/cmocka/test_ipa_dn.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_dn-test_ipa_dn.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_dn-test_ipa_dn.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ipa_dn.c' object='src/tests/cmocka/test_ipa_dn-test_ipa_dn.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_dn_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_dn-test_ipa_dn.o `test -f 'src/tests/cmocka/test_ipa_dn.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ipa_dn.c src/tests/cmocka/test_ipa_dn-test_ipa_dn.obj: src/tests/cmocka/test_ipa_dn.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_dn_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_dn-test_ipa_dn.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_dn-test_ipa_dn.Tpo -c -o src/tests/cmocka/test_ipa_dn-test_ipa_dn.obj `if test -f 'src/tests/cmocka/test_ipa_dn.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ipa_dn.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ipa_dn.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_dn-test_ipa_dn.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_dn-test_ipa_dn.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ipa_dn.c' object='src/tests/cmocka/test_ipa_dn-test_ipa_dn.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_dn_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_dn-test_ipa_dn.obj `if test -f 'src/tests/cmocka/test_ipa_dn.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ipa_dn.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ipa_dn.c'; fi` src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.o: src/tests/cmocka/test_ipa_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_idmap_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_idmap-test_ipa_idmap.Tpo -c -o src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.o `test -f 'src/tests/cmocka/test_ipa_idmap.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ipa_idmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_idmap-test_ipa_idmap.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_idmap-test_ipa_idmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ipa_idmap.c' object='src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_idmap_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.o `test -f 'src/tests/cmocka/test_ipa_idmap.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ipa_idmap.c src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.obj: src/tests/cmocka/test_ipa_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_idmap_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_idmap-test_ipa_idmap.Tpo -c -o src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.obj `if test -f 'src/tests/cmocka/test_ipa_idmap.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ipa_idmap.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ipa_idmap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_idmap-test_ipa_idmap.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_idmap-test_ipa_idmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ipa_idmap.c' object='src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_idmap_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_idmap-test_ipa_idmap.obj `if test -f 'src/tests/cmocka/test_ipa_idmap.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ipa_idmap.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ipa_idmap.c'; fi` src/providers/ipa/test_ipa_idmap-ipa_idmap.o: src/providers/ipa/ipa_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_idmap_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_idmap-ipa_idmap.o -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_idmap-ipa_idmap.Tpo -c -o src/providers/ipa/test_ipa_idmap-ipa_idmap.o `test -f 'src/providers/ipa/ipa_idmap.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_idmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_idmap-ipa_idmap.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_idmap-ipa_idmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_idmap.c' object='src/providers/ipa/test_ipa_idmap-ipa_idmap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_idmap_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_idmap-ipa_idmap.o `test -f 'src/providers/ipa/ipa_idmap.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_idmap.c src/providers/ipa/test_ipa_idmap-ipa_idmap.obj: src/providers/ipa/ipa_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_idmap_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_idmap-ipa_idmap.obj -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_idmap-ipa_idmap.Tpo -c -o src/providers/ipa/test_ipa_idmap-ipa_idmap.obj `if test -f 'src/providers/ipa/ipa_idmap.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_idmap.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_idmap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_idmap-ipa_idmap.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_idmap-ipa_idmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_idmap.c' object='src/providers/ipa/test_ipa_idmap-ipa_idmap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_idmap_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_idmap-ipa_idmap.obj `if test -f 'src/providers/ipa/ipa_idmap.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_idmap.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_idmap.c'; fi` src/providers/krb5/test_ipa_subdom_server-krb5_utils.o: src/providers/krb5/krb5_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_utils.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_utils.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_utils.o `test -f 'src/providers/krb5/krb5_utils.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_utils.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_utils.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_utils.o `test -f 'src/providers/krb5/krb5_utils.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_utils.c src/providers/krb5/test_ipa_subdom_server-krb5_utils.obj: src/providers/krb5/krb5_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_utils.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_utils.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_utils.obj `if test -f 'src/providers/krb5/krb5_utils.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_utils.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_utils.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_utils.obj `if test -f 'src/providers/krb5/krb5_utils.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_utils.c'; fi` src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.o: src/providers/krb5/krb5_delayed_online_authentication.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_delayed_online_authentication.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.o `test -f 'src/providers/krb5/krb5_delayed_online_authentication.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_delayed_online_authentication.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_delayed_online_authentication.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_delayed_online_authentication.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_delayed_online_authentication.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.o `test -f 'src/providers/krb5/krb5_delayed_online_authentication.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_delayed_online_authentication.c src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.obj: src/providers/krb5/krb5_delayed_online_authentication.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_delayed_online_authentication.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.obj `if test -f 'src/providers/krb5/krb5_delayed_online_authentication.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_delayed_online_authentication.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_delayed_online_authentication.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_delayed_online_authentication.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_delayed_online_authentication.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_delayed_online_authentication.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_delayed_online_authentication.obj `if test -f 'src/providers/krb5/krb5_delayed_online_authentication.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_delayed_online_authentication.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_delayed_online_authentication.c'; fi` src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.o: src/providers/krb5/krb5_renew_tgt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_renew_tgt.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.o `test -f 'src/providers/krb5/krb5_renew_tgt.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_renew_tgt.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_renew_tgt.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_renew_tgt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_renew_tgt.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.o `test -f 'src/providers/krb5/krb5_renew_tgt.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_renew_tgt.c src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.obj: src/providers/krb5/krb5_renew_tgt.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_renew_tgt.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.obj `if test -f 'src/providers/krb5/krb5_renew_tgt.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_renew_tgt.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_renew_tgt.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_renew_tgt.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_renew_tgt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_renew_tgt.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_renew_tgt.obj `if test -f 'src/providers/krb5/krb5_renew_tgt.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_renew_tgt.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_renew_tgt.c'; fi` src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.o: src/providers/krb5/krb5_wait_queue.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_wait_queue.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.o `test -f 'src/providers/krb5/krb5_wait_queue.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_wait_queue.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_wait_queue.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_wait_queue.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_wait_queue.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.o `test -f 'src/providers/krb5/krb5_wait_queue.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_wait_queue.c src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.obj: src/providers/krb5/krb5_wait_queue.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_wait_queue.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.obj `if test -f 'src/providers/krb5/krb5_wait_queue.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_wait_queue.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_wait_queue.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_wait_queue.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_wait_queue.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_wait_queue.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_wait_queue.obj `if test -f 'src/providers/krb5/krb5_wait_queue.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_wait_queue.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_wait_queue.c'; fi` src/providers/krb5/test_ipa_subdom_server-krb5_common.o: src/providers/krb5/krb5_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_common.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_common.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_common.o `test -f 'src/providers/krb5/krb5_common.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_common.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_common.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_common.o `test -f 'src/providers/krb5/krb5_common.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_common.c src/providers/krb5/test_ipa_subdom_server-krb5_common.obj: src/providers/krb5/krb5_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_common.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_common.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_common.obj `if test -f 'src/providers/krb5/krb5_common.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_common.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_common.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_common.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_common.obj `if test -f 'src/providers/krb5/krb5_common.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_common.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_common.c'; fi` src/providers/krb5/test_ipa_subdom_server-krb5_opts.o: src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_opts.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_opts.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_opts.o `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_opts.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_opts.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_opts.o `test -f 'src/providers/krb5/krb5_opts.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_opts.c src/providers/krb5/test_ipa_subdom_server-krb5_opts.obj: src/providers/krb5/krb5_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_opts.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_opts.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_opts.obj `if test -f 'src/providers/krb5/krb5_opts.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_opts.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_opts.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_opts.obj `if test -f 'src/providers/krb5/krb5_opts.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_opts.c'; fi` src/providers/krb5/test_ipa_subdom_server-krb5_auth.o: src/providers/krb5/krb5_auth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_auth.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_auth.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_auth.o `test -f 'src/providers/krb5/krb5_auth.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_auth.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_auth.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_auth.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_auth.o `test -f 'src/providers/krb5/krb5_auth.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_auth.c src/providers/krb5/test_ipa_subdom_server-krb5_auth.obj: src/providers/krb5/krb5_auth.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_auth.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_auth.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_auth.obj `if test -f 'src/providers/krb5/krb5_auth.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_auth.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_auth.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_auth.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_auth.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_auth.obj `if test -f 'src/providers/krb5/krb5_auth.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_auth.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_auth.c'; fi` src/providers/krb5/test_ipa_subdom_server-krb5_access.o: src/providers/krb5/krb5_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_access.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_access.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_access.o `test -f 'src/providers/krb5/krb5_access.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_access.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_access.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_access.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_access.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_access.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_access.o `test -f 'src/providers/krb5/krb5_access.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_access.c src/providers/krb5/test_ipa_subdom_server-krb5_access.obj: src/providers/krb5/krb5_access.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_access.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_access.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_access.obj `if test -f 'src/providers/krb5/krb5_access.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_access.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_access.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_access.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_access.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_access.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_access.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_access.obj `if test -f 'src/providers/krb5/krb5_access.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_access.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_access.c'; fi` src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.o: src/providers/krb5/krb5_child_handler.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_child_handler.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.o `test -f 'src/providers/krb5/krb5_child_handler.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_child_handler.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_child_handler.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_child_handler.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_child_handler.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.o `test -f 'src/providers/krb5/krb5_child_handler.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_child_handler.c src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.obj: src/providers/krb5/krb5_child_handler.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_child_handler.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.obj `if test -f 'src/providers/krb5/krb5_child_handler.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_child_handler.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_child_handler.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_child_handler.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_child_handler.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_child_handler.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_child_handler.obj `if test -f 'src/providers/krb5/krb5_child_handler.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_child_handler.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_child_handler.c'; fi` src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.o: src/providers/krb5/krb5_init_shared.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_init_shared.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.o `test -f 'src/providers/krb5/krb5_init_shared.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_init_shared.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_init_shared.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_init_shared.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_init_shared.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.o `test -f 'src/providers/krb5/krb5_init_shared.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_init_shared.c src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.obj: src/providers/krb5/krb5_init_shared.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_init_shared.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.obj `if test -f 'src/providers/krb5/krb5_init_shared.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_init_shared.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_init_shared.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_init_shared.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_init_shared.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_init_shared.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_init_shared.obj `if test -f 'src/providers/krb5/krb5_init_shared.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_init_shared.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_init_shared.c'; fi` src/providers/krb5/test_ipa_subdom_server-krb5_ccache.o: src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_ccache.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_ccache.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_ccache.o `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_ccache.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_ccache.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_ccache.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_ccache.o `test -f 'src/providers/krb5/krb5_ccache.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_ccache.c src/providers/krb5/test_ipa_subdom_server-krb5_ccache.obj: src/providers/krb5/krb5_ccache.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_ipa_subdom_server-krb5_ccache.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_ccache.Tpo -c -o src/providers/krb5/test_ipa_subdom_server-krb5_ccache.obj `if test -f 'src/providers/krb5/krb5_ccache.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_ccache.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_ccache.Tpo src/providers/krb5/$(DEPDIR)/test_ipa_subdom_server-krb5_ccache.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_ccache.c' object='src/providers/krb5/test_ipa_subdom_server-krb5_ccache.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_ipa_subdom_server-krb5_ccache.obj `if test -f 'src/providers/krb5/krb5_ccache.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_ccache.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_ccache.c'; fi` src/util/test_ipa_subdom_server-sss_krb5.o: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/util/test_ipa_subdom_server-sss_krb5.o -MD -MP -MF src/util/$(DEPDIR)/test_ipa_subdom_server-sss_krb5.Tpo -c -o src/util/test_ipa_subdom_server-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_ipa_subdom_server-sss_krb5.Tpo src/util/$(DEPDIR)/test_ipa_subdom_server-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/test_ipa_subdom_server-sss_krb5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/util/test_ipa_subdom_server-sss_krb5.o `test -f 'src/util/sss_krb5.c' || echo '$(srcdir)/'`src/util/sss_krb5.c src/util/test_ipa_subdom_server-sss_krb5.obj: src/util/sss_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/util/test_ipa_subdom_server-sss_krb5.obj -MD -MP -MF src/util/$(DEPDIR)/test_ipa_subdom_server-sss_krb5.Tpo -c -o src/util/test_ipa_subdom_server-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_ipa_subdom_server-sss_krb5.Tpo src/util/$(DEPDIR)/test_ipa_subdom_server-sss_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/sss_krb5.c' object='src/util/test_ipa_subdom_server-sss_krb5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/util/test_ipa_subdom_server-sss_krb5.obj `if test -f 'src/util/sss_krb5.c'; then $(CYGPATH_W) 'src/util/sss_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/util/sss_krb5.c'; fi` src/util/test_ipa_subdom_server-become_user.o: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/util/test_ipa_subdom_server-become_user.o -MD -MP -MF src/util/$(DEPDIR)/test_ipa_subdom_server-become_user.Tpo -c -o src/util/test_ipa_subdom_server-become_user.o `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_ipa_subdom_server-become_user.Tpo src/util/$(DEPDIR)/test_ipa_subdom_server-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/test_ipa_subdom_server-become_user.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/util/test_ipa_subdom_server-become_user.o `test -f 'src/util/become_user.c' || echo '$(srcdir)/'`src/util/become_user.c src/util/test_ipa_subdom_server-become_user.obj: src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/util/test_ipa_subdom_server-become_user.obj -MD -MP -MF src/util/$(DEPDIR)/test_ipa_subdom_server-become_user.Tpo -c -o src/util/test_ipa_subdom_server-become_user.obj `if test -f 'src/util/become_user.c'; then $(CYGPATH_W) 'src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/src/util/become_user.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/util/$(DEPDIR)/test_ipa_subdom_server-become_user.Tpo src/util/$(DEPDIR)/test_ipa_subdom_server-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/util/become_user.c' object='src/util/test_ipa_subdom_server-become_user.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/util/test_ipa_subdom_server-become_user.obj `if test -f 'src/util/become_user.c'; then $(CYGPATH_W) 'src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/src/util/become_user.c'; fi` src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.o: src/tests/cmocka/common_mock_sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_sdap.Tpo -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.o `test -f 'src/tests/cmocka/common_mock_sdap.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_sdap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_sdap.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_sdap.c' object='src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.o `test -f 'src/tests/cmocka/common_mock_sdap.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_sdap.c src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.obj: src/tests/cmocka/common_mock_sdap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_sdap.Tpo -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.obj `if test -f 'src/tests/cmocka/common_mock_sdap.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_sdap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_sdap.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_sdap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_sdap.c' object='src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_sdap.obj `if test -f 'src/tests/cmocka/common_mock_sdap.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_sdap.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_sdap.c'; fi` src/tests/cmocka/test_ipa_subdom_server-common_mock_be.o: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_subdom_server-common_mock_be.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_be.Tpo -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/test_ipa_subdom_server-common_mock_be.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c src/tests/cmocka/test_ipa_subdom_server-common_mock_be.obj: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_subdom_server-common_mock_be.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_be.Tpo -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/test_ipa_subdom_server-common_mock_be.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.o: src/tests/cmocka/common_mock_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_krb5.Tpo -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.o `test -f 'src/tests/cmocka/common_mock_krb5.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_krb5.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_krb5.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_krb5.c' object='src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.o `test -f 'src/tests/cmocka/common_mock_krb5.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_krb5.c src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.obj: src/tests/cmocka/common_mock_krb5.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_krb5.Tpo -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.obj `if test -f 'src/tests/cmocka/common_mock_krb5.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_krb5.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_krb5.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-common_mock_krb5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_krb5.c' object='src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_subdom_server-common_mock_krb5.obj `if test -f 'src/tests/cmocka/common_mock_krb5.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_krb5.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_krb5.c'; fi` src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.o: src/tests/cmocka/test_ipa_subdomains_server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-test_ipa_subdomains_server.Tpo -c -o src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.o `test -f 'src/tests/cmocka/test_ipa_subdomains_server.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ipa_subdomains_server.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-test_ipa_subdomains_server.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-test_ipa_subdomains_server.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ipa_subdomains_server.c' object='src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.o `test -f 'src/tests/cmocka/test_ipa_subdomains_server.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ipa_subdomains_server.c src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.obj: src/tests/cmocka/test_ipa_subdomains_server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-test_ipa_subdomains_server.Tpo -c -o src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.obj `if test -f 'src/tests/cmocka/test_ipa_subdomains_server.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ipa_subdomains_server.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ipa_subdomains_server.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-test_ipa_subdomains_server.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_server-test_ipa_subdomains_server.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ipa_subdomains_server.c' object='src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_subdom_server-test_ipa_subdomains_server.obj `if test -f 'src/tests/cmocka/test_ipa_subdomains_server.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ipa_subdomains_server.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ipa_subdomains_server.c'; fi` src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.o: src/providers/ipa/ipa_subdomains_server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.o -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_server.Tpo -c -o src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.o `test -f 'src/providers/ipa/ipa_subdomains_server.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_server.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_server.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_server.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_subdomains_server.c' object='src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.o `test -f 'src/providers/ipa/ipa_subdomains_server.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_server.c src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.obj: src/providers/ipa/ipa_subdomains_server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.obj -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_server.Tpo -c -o src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.obj `if test -f 'src/providers/ipa/ipa_subdomains_server.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_subdomains_server.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_subdomains_server.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_server.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_server.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_subdomains_server.c' object='src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_server.obj `if test -f 'src/providers/ipa/ipa_subdomains_server.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_subdomains_server.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_subdomains_server.c'; fi` src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.o: src/providers/ipa/ipa_subdomains_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.o -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_utils.Tpo -c -o src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.o `test -f 'src/providers/ipa/ipa_subdomains_utils.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_utils.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_subdomains_utils.c' object='src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.o `test -f 'src/providers/ipa/ipa_subdomains_utils.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_utils.c src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.obj: src/providers/ipa/ipa_subdomains_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.obj -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_utils.Tpo -c -o src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.obj `if test -f 'src/providers/ipa/ipa_subdomains_utils.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_subdomains_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_subdomains_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_utils.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_subdomains_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_subdomains_utils.c' object='src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_subdom_server-ipa_subdomains_utils.obj `if test -f 'src/providers/ipa/ipa_subdomains_utils.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_subdomains_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_subdomains_utils.c'; fi` src/providers/ipa/test_ipa_subdom_server-ipa_opts.o: src/providers/ipa/ipa_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_subdom_server-ipa_opts.o -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_opts.Tpo -c -o src/providers/ipa/test_ipa_subdom_server-ipa_opts.o `test -f 'src/providers/ipa/ipa_opts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_opts.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_opts.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_opts.c' object='src/providers/ipa/test_ipa_subdom_server-ipa_opts.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_subdom_server-ipa_opts.o `test -f 'src/providers/ipa/ipa_opts.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_opts.c src/providers/ipa/test_ipa_subdom_server-ipa_opts.obj: src/providers/ipa/ipa_opts.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_subdom_server-ipa_opts.obj -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_opts.Tpo -c -o src/providers/ipa/test_ipa_subdom_server-ipa_opts.obj `if test -f 'src/providers/ipa/ipa_opts.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_opts.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_opts.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_subdom_server-ipa_opts.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_opts.c' object='src/providers/ipa/test_ipa_subdom_server-ipa_opts.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_server_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_subdom_server-ipa_opts.obj `if test -f 'src/providers/ipa/ipa_opts.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_opts.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_opts.c'; fi` src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.o: src/tests/cmocka/test_ipa_subdomains_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_util_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_util-test_ipa_subdomains_utils.Tpo -c -o src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.o `test -f 'src/tests/cmocka/test_ipa_subdomains_utils.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ipa_subdomains_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_util-test_ipa_subdomains_utils.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_util-test_ipa_subdomains_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ipa_subdomains_utils.c' object='src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_util_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.o `test -f 'src/tests/cmocka/test_ipa_subdomains_utils.c' || echo '$(srcdir)/'`src/tests/cmocka/test_ipa_subdomains_utils.c src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.obj: src/tests/cmocka/test_ipa_subdomains_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_util_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_util-test_ipa_subdomains_utils.Tpo -c -o src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.obj `if test -f 'src/tests/cmocka/test_ipa_subdomains_utils.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ipa_subdomains_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ipa_subdomains_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_util-test_ipa_subdomains_utils.Tpo src/tests/cmocka/$(DEPDIR)/test_ipa_subdom_util-test_ipa_subdomains_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_ipa_subdomains_utils.c' object='src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_util_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_ipa_subdom_util-test_ipa_subdomains_utils.obj `if test -f 'src/tests/cmocka/test_ipa_subdomains_utils.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_ipa_subdomains_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_ipa_subdomains_utils.c'; fi` src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.o: src/providers/ipa/ipa_subdomains_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_util_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.o -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_subdom_util-ipa_subdomains_utils.Tpo -c -o src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.o `test -f 'src/providers/ipa/ipa_subdomains_utils.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_subdom_util-ipa_subdomains_utils.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_subdom_util-ipa_subdomains_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_subdomains_utils.c' object='src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_util_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.o `test -f 'src/providers/ipa/ipa_subdomains_utils.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_subdomains_utils.c src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.obj: src/providers/ipa/ipa_subdomains_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_util_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.obj -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_ipa_subdom_util-ipa_subdomains_utils.Tpo -c -o src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.obj `if test -f 'src/providers/ipa/ipa_subdomains_utils.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_subdomains_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_subdomains_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_ipa_subdom_util-ipa_subdomains_utils.Tpo src/providers/ipa/$(DEPDIR)/test_ipa_subdom_util-ipa_subdomains_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_subdomains_utils.c' object='src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_ipa_subdom_util_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_ipa_subdom_util-ipa_subdomains_utils.obj `if test -f 'src/providers/ipa/ipa_subdomains_utils.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_subdomains_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_subdomains_utils.c'; fi` src/tests/cmocka/test_krb5_wait_queue-common_mock_be.o: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_krb5_wait_queue-common_mock_be.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-common_mock_be.Tpo -c -o src/tests/cmocka/test_krb5_wait_queue-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/test_krb5_wait_queue-common_mock_be.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_krb5_wait_queue-common_mock_be.o `test -f 'src/tests/cmocka/common_mock_be.c' || echo '$(srcdir)/'`src/tests/cmocka/common_mock_be.c src/tests/cmocka/test_krb5_wait_queue-common_mock_be.obj: src/tests/cmocka/common_mock_be.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_krb5_wait_queue-common_mock_be.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-common_mock_be.Tpo -c -o src/tests/cmocka/test_krb5_wait_queue-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-common_mock_be.Tpo src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-common_mock_be.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/common_mock_be.c' object='src/tests/cmocka/test_krb5_wait_queue-common_mock_be.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_krb5_wait_queue-common_mock_be.obj `if test -f 'src/tests/cmocka/common_mock_be.c'; then $(CYGPATH_W) 'src/tests/cmocka/common_mock_be.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/common_mock_be.c'; fi` src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.o: src/tests/cmocka/test_krb5_wait_queue.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-test_krb5_wait_queue.Tpo -c -o src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.o `test -f 'src/tests/cmocka/test_krb5_wait_queue.c' || echo '$(srcdir)/'`src/tests/cmocka/test_krb5_wait_queue.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-test_krb5_wait_queue.Tpo src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-test_krb5_wait_queue.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_krb5_wait_queue.c' object='src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.o `test -f 'src/tests/cmocka/test_krb5_wait_queue.c' || echo '$(srcdir)/'`src/tests/cmocka/test_krb5_wait_queue.c src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.obj: src/tests/cmocka/test_krb5_wait_queue.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-test_krb5_wait_queue.Tpo -c -o src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.obj `if test -f 'src/tests/cmocka/test_krb5_wait_queue.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_krb5_wait_queue.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_krb5_wait_queue.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-test_krb5_wait_queue.Tpo src/tests/cmocka/$(DEPDIR)/test_krb5_wait_queue-test_krb5_wait_queue.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_krb5_wait_queue.c' object='src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_krb5_wait_queue-test_krb5_wait_queue.obj `if test -f 'src/tests/cmocka/test_krb5_wait_queue.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_krb5_wait_queue.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_krb5_wait_queue.c'; fi` src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.o: src/providers/krb5/krb5_wait_queue.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.o -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_krb5_wait_queue-krb5_wait_queue.Tpo -c -o src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.o `test -f 'src/providers/krb5/krb5_wait_queue.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_wait_queue.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_krb5_wait_queue-krb5_wait_queue.Tpo src/providers/krb5/$(DEPDIR)/test_krb5_wait_queue-krb5_wait_queue.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_wait_queue.c' object='src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.o `test -f 'src/providers/krb5/krb5_wait_queue.c' || echo '$(srcdir)/'`src/providers/krb5/krb5_wait_queue.c src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.obj: src/providers/krb5/krb5_wait_queue.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -MT src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.obj -MD -MP -MF src/providers/krb5/$(DEPDIR)/test_krb5_wait_queue-krb5_wait_queue.Tpo -c -o src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.obj `if test -f 'src/providers/krb5/krb5_wait_queue.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_wait_queue.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_wait_queue.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/krb5/$(DEPDIR)/test_krb5_wait_queue-krb5_wait_queue.Tpo src/providers/krb5/$(DEPDIR)/test_krb5_wait_queue-krb5_wait_queue.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/krb5/krb5_wait_queue.c' object='src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_krb5_wait_queue_CFLAGS) $(CFLAGS) -c -o src/providers/krb5/test_krb5_wait_queue-krb5_wait_queue.obj `if test -f 'src/providers/krb5/krb5_wait_queue.c'; then $(CYGPATH_W) 'src/providers/krb5/krb5_wait_queue.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/krb5/krb5_wait_queue.c'; fi` src/tests/cmocka/test_resolv_fake-test_resolv_fake.o: src/tests/cmocka/test_resolv_fake.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resolv_fake_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_resolv_fake-test_resolv_fake.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_resolv_fake-test_resolv_fake.Tpo -c -o src/tests/cmocka/test_resolv_fake-test_resolv_fake.o `test -f 'src/tests/cmocka/test_resolv_fake.c' || echo '$(srcdir)/'`src/tests/cmocka/test_resolv_fake.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_resolv_fake-test_resolv_fake.Tpo src/tests/cmocka/$(DEPDIR)/test_resolv_fake-test_resolv_fake.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_resolv_fake.c' object='src/tests/cmocka/test_resolv_fake-test_resolv_fake.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resolv_fake_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_resolv_fake-test_resolv_fake.o `test -f 'src/tests/cmocka/test_resolv_fake.c' || echo '$(srcdir)/'`src/tests/cmocka/test_resolv_fake.c src/tests/cmocka/test_resolv_fake-test_resolv_fake.obj: src/tests/cmocka/test_resolv_fake.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resolv_fake_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_resolv_fake-test_resolv_fake.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_resolv_fake-test_resolv_fake.Tpo -c -o src/tests/cmocka/test_resolv_fake-test_resolv_fake.obj `if test -f 'src/tests/cmocka/test_resolv_fake.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_resolv_fake.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_resolv_fake.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_resolv_fake-test_resolv_fake.Tpo src/tests/cmocka/$(DEPDIR)/test_resolv_fake-test_resolv_fake.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_resolv_fake.c' object='src/tests/cmocka/test_resolv_fake-test_resolv_fake.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resolv_fake_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_resolv_fake-test_resolv_fake.obj `if test -f 'src/tests/cmocka/test_resolv_fake.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_resolv_fake.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_resolv_fake.c'; fi` src/resolv/test_resolv_fake-async_resolv.o: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resolv_fake_CFLAGS) $(CFLAGS) -MT src/resolv/test_resolv_fake-async_resolv.o -MD -MP -MF src/resolv/$(DEPDIR)/test_resolv_fake-async_resolv.Tpo -c -o src/resolv/test_resolv_fake-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/test_resolv_fake-async_resolv.Tpo src/resolv/$(DEPDIR)/test_resolv_fake-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/test_resolv_fake-async_resolv.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resolv_fake_CFLAGS) $(CFLAGS) -c -o src/resolv/test_resolv_fake-async_resolv.o `test -f 'src/resolv/async_resolv.c' || echo '$(srcdir)/'`src/resolv/async_resolv.c src/resolv/test_resolv_fake-async_resolv.obj: src/resolv/async_resolv.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resolv_fake_CFLAGS) $(CFLAGS) -MT src/resolv/test_resolv_fake-async_resolv.obj -MD -MP -MF src/resolv/$(DEPDIR)/test_resolv_fake-async_resolv.Tpo -c -o src/resolv/test_resolv_fake-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/resolv/$(DEPDIR)/test_resolv_fake-async_resolv.Tpo src/resolv/$(DEPDIR)/test_resolv_fake-async_resolv.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/resolv/async_resolv.c' object='src/resolv/test_resolv_fake-async_resolv.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_resolv_fake_CFLAGS) $(CFLAGS) -c -o src/resolv/test_resolv_fake-async_resolv.obj `if test -f 'src/resolv/async_resolv.c'; then $(CYGPATH_W) 'src/resolv/async_resolv.c'; else $(CYGPATH_W) '$(srcdir)/src/resolv/async_resolv.c'; fi` src/tests/cmocka/test_sbus_opath-test_sbus_opath.o: src/tests/cmocka/test_sbus_opath.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sbus_opath_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_sbus_opath-test_sbus_opath.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_sbus_opath-test_sbus_opath.Tpo -c -o src/tests/cmocka/test_sbus_opath-test_sbus_opath.o `test -f 'src/tests/cmocka/test_sbus_opath.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sbus_opath.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_sbus_opath-test_sbus_opath.Tpo src/tests/cmocka/$(DEPDIR)/test_sbus_opath-test_sbus_opath.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sbus_opath.c' object='src/tests/cmocka/test_sbus_opath-test_sbus_opath.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sbus_opath_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_sbus_opath-test_sbus_opath.o `test -f 'src/tests/cmocka/test_sbus_opath.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sbus_opath.c src/tests/cmocka/test_sbus_opath-test_sbus_opath.obj: src/tests/cmocka/test_sbus_opath.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sbus_opath_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_sbus_opath-test_sbus_opath.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_sbus_opath-test_sbus_opath.Tpo -c -o src/tests/cmocka/test_sbus_opath-test_sbus_opath.obj `if test -f 'src/tests/cmocka/test_sbus_opath.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sbus_opath.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sbus_opath.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_sbus_opath-test_sbus_opath.Tpo src/tests/cmocka/$(DEPDIR)/test_sbus_opath-test_sbus_opath.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sbus_opath.c' object='src/tests/cmocka/test_sbus_opath-test_sbus_opath.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sbus_opath_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_sbus_opath-test_sbus_opath.obj `if test -f 'src/tests/cmocka/test_sbus_opath.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sbus_opath.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sbus_opath.c'; fi` src/tests/cmocka/test_sss_idmap-test_sss_idmap.o: src/tests/cmocka/test_sss_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sss_idmap_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_sss_idmap-test_sss_idmap.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_sss_idmap-test_sss_idmap.Tpo -c -o src/tests/cmocka/test_sss_idmap-test_sss_idmap.o `test -f 'src/tests/cmocka/test_sss_idmap.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sss_idmap.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_sss_idmap-test_sss_idmap.Tpo src/tests/cmocka/$(DEPDIR)/test_sss_idmap-test_sss_idmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sss_idmap.c' object='src/tests/cmocka/test_sss_idmap-test_sss_idmap.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sss_idmap_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_sss_idmap-test_sss_idmap.o `test -f 'src/tests/cmocka/test_sss_idmap.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sss_idmap.c src/tests/cmocka/test_sss_idmap-test_sss_idmap.obj: src/tests/cmocka/test_sss_idmap.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sss_idmap_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_sss_idmap-test_sss_idmap.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_sss_idmap-test_sss_idmap.Tpo -c -o src/tests/cmocka/test_sss_idmap-test_sss_idmap.obj `if test -f 'src/tests/cmocka/test_sss_idmap.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sss_idmap.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sss_idmap.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_sss_idmap-test_sss_idmap.Tpo src/tests/cmocka/$(DEPDIR)/test_sss_idmap-test_sss_idmap.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sss_idmap.c' object='src/tests/cmocka/test_sss_idmap-test_sss_idmap.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sss_idmap_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_sss_idmap-test_sss_idmap.obj `if test -f 'src/tests/cmocka/test_sss_idmap.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sss_idmap.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sss_idmap.c'; fi` src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.o: src/tests/cmocka/test_sysdb_subdomains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_subdomains_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_sysdb_subdomains-test_sysdb_subdomains.Tpo -c -o src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.o `test -f 'src/tests/cmocka/test_sysdb_subdomains.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sysdb_subdomains.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_sysdb_subdomains-test_sysdb_subdomains.Tpo src/tests/cmocka/$(DEPDIR)/test_sysdb_subdomains-test_sysdb_subdomains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sysdb_subdomains.c' object='src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_subdomains_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.o `test -f 'src/tests/cmocka/test_sysdb_subdomains.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sysdb_subdomains.c src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.obj: src/tests/cmocka/test_sysdb_subdomains.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_subdomains_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_sysdb_subdomains-test_sysdb_subdomains.Tpo -c -o src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.obj `if test -f 'src/tests/cmocka/test_sysdb_subdomains.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sysdb_subdomains.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sysdb_subdomains.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_sysdb_subdomains-test_sysdb_subdomains.Tpo src/tests/cmocka/$(DEPDIR)/test_sysdb_subdomains-test_sysdb_subdomains.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sysdb_subdomains.c' object='src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_subdomains_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_sysdb_subdomains-test_sysdb_subdomains.obj `if test -f 'src/tests/cmocka/test_sysdb_subdomains.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sysdb_subdomains.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sysdb_subdomains.c'; fi` src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.o: src/tests/cmocka/test_sysdb_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_utils_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_sysdb_utils-test_sysdb_utils.Tpo -c -o src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.o `test -f 'src/tests/cmocka/test_sysdb_utils.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sysdb_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_sysdb_utils-test_sysdb_utils.Tpo src/tests/cmocka/$(DEPDIR)/test_sysdb_utils-test_sysdb_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sysdb_utils.c' object='src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_utils_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.o `test -f 'src/tests/cmocka/test_sysdb_utils.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sysdb_utils.c src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.obj: src/tests/cmocka/test_sysdb_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_utils_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_sysdb_utils-test_sysdb_utils.Tpo -c -o src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.obj `if test -f 'src/tests/cmocka/test_sysdb_utils.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sysdb_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sysdb_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_sysdb_utils-test_sysdb_utils.Tpo src/tests/cmocka/$(DEPDIR)/test_sysdb_utils-test_sysdb_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sysdb_utils.c' object='src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_utils_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_sysdb_utils-test_sysdb_utils.obj `if test -f 'src/tests/cmocka/test_sysdb_utils.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sysdb_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sysdb_utils.c'; fi` src/tests/cmocka/test_sysdb_views-test_sysdb_views.o: src/tests/cmocka/test_sysdb_views.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_views_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_sysdb_views-test_sysdb_views.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_sysdb_views-test_sysdb_views.Tpo -c -o src/tests/cmocka/test_sysdb_views-test_sysdb_views.o `test -f 'src/tests/cmocka/test_sysdb_views.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sysdb_views.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_sysdb_views-test_sysdb_views.Tpo src/tests/cmocka/$(DEPDIR)/test_sysdb_views-test_sysdb_views.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sysdb_views.c' object='src/tests/cmocka/test_sysdb_views-test_sysdb_views.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_views_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_sysdb_views-test_sysdb_views.o `test -f 'src/tests/cmocka/test_sysdb_views.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sysdb_views.c src/tests/cmocka/test_sysdb_views-test_sysdb_views.obj: src/tests/cmocka/test_sysdb_views.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_views_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_sysdb_views-test_sysdb_views.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_sysdb_views-test_sysdb_views.Tpo -c -o src/tests/cmocka/test_sysdb_views-test_sysdb_views.obj `if test -f 'src/tests/cmocka/test_sysdb_views.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sysdb_views.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sysdb_views.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_sysdb_views-test_sysdb_views.Tpo src/tests/cmocka/$(DEPDIR)/test_sysdb_views-test_sysdb_views.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sysdb_views.c' object='src/tests/cmocka/test_sysdb_views-test_sysdb_views.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_views_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_sysdb_views-test_sysdb_views.obj `if test -f 'src/tests/cmocka/test_sysdb_views.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sysdb_views.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sysdb_views.c'; fi` src/providers/ipa/test_sysdb_views-ipa_utils.o: src/providers/ipa/ipa_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_views_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_sysdb_views-ipa_utils.o -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_sysdb_views-ipa_utils.Tpo -c -o src/providers/ipa/test_sysdb_views-ipa_utils.o `test -f 'src/providers/ipa/ipa_utils.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_sysdb_views-ipa_utils.Tpo src/providers/ipa/$(DEPDIR)/test_sysdb_views-ipa_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_utils.c' object='src/providers/ipa/test_sysdb_views-ipa_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_views_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_sysdb_views-ipa_utils.o `test -f 'src/providers/ipa/ipa_utils.c' || echo '$(srcdir)/'`src/providers/ipa/ipa_utils.c src/providers/ipa/test_sysdb_views-ipa_utils.obj: src/providers/ipa/ipa_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_views_CFLAGS) $(CFLAGS) -MT src/providers/ipa/test_sysdb_views-ipa_utils.obj -MD -MP -MF src/providers/ipa/$(DEPDIR)/test_sysdb_views-ipa_utils.Tpo -c -o src/providers/ipa/test_sysdb_views-ipa_utils.obj `if test -f 'src/providers/ipa/ipa_utils.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/providers/ipa/$(DEPDIR)/test_sysdb_views-ipa_utils.Tpo src/providers/ipa/$(DEPDIR)/test_sysdb_views-ipa_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/providers/ipa/ipa_utils.c' object='src/providers/ipa/test_sysdb_views-ipa_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_sysdb_views_CFLAGS) $(CFLAGS) -c -o src/providers/ipa/test_sysdb_views-ipa_utils.obj `if test -f 'src/providers/ipa/ipa_utils.c'; then $(CYGPATH_W) 'src/providers/ipa/ipa_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/providers/ipa/ipa_utils.c'; fi` src/tests/cmocka/test_tools_colondb-test_tools_colondb.o: src/tests/cmocka/test_tools_colondb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tools_colondb_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_tools_colondb-test_tools_colondb.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_tools_colondb-test_tools_colondb.Tpo -c -o src/tests/cmocka/test_tools_colondb-test_tools_colondb.o `test -f 'src/tests/cmocka/test_tools_colondb.c' || echo '$(srcdir)/'`src/tests/cmocka/test_tools_colondb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_tools_colondb-test_tools_colondb.Tpo src/tests/cmocka/$(DEPDIR)/test_tools_colondb-test_tools_colondb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_tools_colondb.c' object='src/tests/cmocka/test_tools_colondb-test_tools_colondb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tools_colondb_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_tools_colondb-test_tools_colondb.o `test -f 'src/tests/cmocka/test_tools_colondb.c' || echo '$(srcdir)/'`src/tests/cmocka/test_tools_colondb.c src/tests/cmocka/test_tools_colondb-test_tools_colondb.obj: src/tests/cmocka/test_tools_colondb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tools_colondb_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_tools_colondb-test_tools_colondb.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_tools_colondb-test_tools_colondb.Tpo -c -o src/tests/cmocka/test_tools_colondb-test_tools_colondb.obj `if test -f 'src/tests/cmocka/test_tools_colondb.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_tools_colondb.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_tools_colondb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_tools_colondb-test_tools_colondb.Tpo src/tests/cmocka/$(DEPDIR)/test_tools_colondb-test_tools_colondb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_tools_colondb.c' object='src/tests/cmocka/test_tools_colondb-test_tools_colondb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tools_colondb_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_tools_colondb-test_tools_colondb.obj `if test -f 'src/tests/cmocka/test_tools_colondb.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_tools_colondb.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_tools_colondb.c'; fi` src/tools/common/test_tools_colondb-sss_colondb.o: src/tools/common/sss_colondb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tools_colondb_CFLAGS) $(CFLAGS) -MT src/tools/common/test_tools_colondb-sss_colondb.o -MD -MP -MF src/tools/common/$(DEPDIR)/test_tools_colondb-sss_colondb.Tpo -c -o src/tools/common/test_tools_colondb-sss_colondb.o `test -f 'src/tools/common/sss_colondb.c' || echo '$(srcdir)/'`src/tools/common/sss_colondb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/test_tools_colondb-sss_colondb.Tpo src/tools/common/$(DEPDIR)/test_tools_colondb-sss_colondb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_colondb.c' object='src/tools/common/test_tools_colondb-sss_colondb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tools_colondb_CFLAGS) $(CFLAGS) -c -o src/tools/common/test_tools_colondb-sss_colondb.o `test -f 'src/tools/common/sss_colondb.c' || echo '$(srcdir)/'`src/tools/common/sss_colondb.c src/tools/common/test_tools_colondb-sss_colondb.obj: src/tools/common/sss_colondb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tools_colondb_CFLAGS) $(CFLAGS) -MT src/tools/common/test_tools_colondb-sss_colondb.obj -MD -MP -MF src/tools/common/$(DEPDIR)/test_tools_colondb-sss_colondb.Tpo -c -o src/tools/common/test_tools_colondb-sss_colondb.obj `if test -f 'src/tools/common/sss_colondb.c'; then $(CYGPATH_W) 'src/tools/common/sss_colondb.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_colondb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tools/common/$(DEPDIR)/test_tools_colondb-sss_colondb.Tpo src/tools/common/$(DEPDIR)/test_tools_colondb-sss_colondb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tools/common/sss_colondb.c' object='src/tools/common/test_tools_colondb-sss_colondb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_tools_colondb_CFLAGS) $(CFLAGS) -c -o src/tools/common/test_tools_colondb-sss_colondb.obj `if test -f 'src/tools/common/sss_colondb.c'; then $(CYGPATH_W) 'src/tools/common/sss_colondb.c'; else $(CYGPATH_W) '$(srcdir)/src/tools/common/sss_colondb.c'; fi` src/tests/cmocka/test_utils-test_utils.o: src/tests/cmocka/test_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_utils-test_utils.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_utils-test_utils.Tpo -c -o src/tests/cmocka/test_utils-test_utils.o `test -f 'src/tests/cmocka/test_utils.c' || echo '$(srcdir)/'`src/tests/cmocka/test_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_utils-test_utils.Tpo src/tests/cmocka/$(DEPDIR)/test_utils-test_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_utils.c' object='src/tests/cmocka/test_utils-test_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_utils-test_utils.o `test -f 'src/tests/cmocka/test_utils.c' || echo '$(srcdir)/'`src/tests/cmocka/test_utils.c src/tests/cmocka/test_utils-test_utils.obj: src/tests/cmocka/test_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_utils-test_utils.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_utils-test_utils.Tpo -c -o src/tests/cmocka/test_utils-test_utils.obj `if test -f 'src/tests/cmocka/test_utils.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_utils-test_utils.Tpo src/tests/cmocka/$(DEPDIR)/test_utils-test_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_utils.c' object='src/tests/cmocka/test_utils-test_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_utils-test_utils.obj `if test -f 'src/tests/cmocka/test_utils.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_utils.c'; fi` src/tests/cmocka/test_utils-test_sss_ssh.o: src/tests/cmocka/test_sss_ssh.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_utils-test_sss_ssh.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_utils-test_sss_ssh.Tpo -c -o src/tests/cmocka/test_utils-test_sss_ssh.o `test -f 'src/tests/cmocka/test_sss_ssh.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sss_ssh.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_utils-test_sss_ssh.Tpo src/tests/cmocka/$(DEPDIR)/test_utils-test_sss_ssh.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sss_ssh.c' object='src/tests/cmocka/test_utils-test_sss_ssh.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_utils-test_sss_ssh.o `test -f 'src/tests/cmocka/test_sss_ssh.c' || echo '$(srcdir)/'`src/tests/cmocka/test_sss_ssh.c src/tests/cmocka/test_utils-test_sss_ssh.obj: src/tests/cmocka/test_sss_ssh.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_utils-test_sss_ssh.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_utils-test_sss_ssh.Tpo -c -o src/tests/cmocka/test_utils-test_sss_ssh.obj `if test -f 'src/tests/cmocka/test_sss_ssh.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sss_ssh.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sss_ssh.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_utils-test_sss_ssh.Tpo src/tests/cmocka/$(DEPDIR)/test_utils-test_sss_ssh.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_sss_ssh.c' object='src/tests/cmocka/test_utils-test_sss_ssh.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_utils-test_sss_ssh.obj `if test -f 'src/tests/cmocka/test_sss_ssh.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_sss_ssh.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_sss_ssh.c'; fi` src/tests/cmocka/test_utils-test_string_utils.o: src/tests/cmocka/test_string_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_utils-test_string_utils.o -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_utils-test_string_utils.Tpo -c -o src/tests/cmocka/test_utils-test_string_utils.o `test -f 'src/tests/cmocka/test_string_utils.c' || echo '$(srcdir)/'`src/tests/cmocka/test_string_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_utils-test_string_utils.Tpo src/tests/cmocka/$(DEPDIR)/test_utils-test_string_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_string_utils.c' object='src/tests/cmocka/test_utils-test_string_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_utils-test_string_utils.o `test -f 'src/tests/cmocka/test_string_utils.c' || echo '$(srcdir)/'`src/tests/cmocka/test_string_utils.c src/tests/cmocka/test_utils-test_string_utils.obj: src/tests/cmocka/test_string_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -MT src/tests/cmocka/test_utils-test_string_utils.obj -MD -MP -MF src/tests/cmocka/$(DEPDIR)/test_utils-test_string_utils.Tpo -c -o src/tests/cmocka/test_utils-test_string_utils.obj `if test -f 'src/tests/cmocka/test_string_utils.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_string_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_string_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/cmocka/$(DEPDIR)/test_utils-test_string_utils.Tpo src/tests/cmocka/$(DEPDIR)/test_utils-test_string_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/cmocka/test_string_utils.c' object='src/tests/cmocka/test_utils-test_string_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_utils_CFLAGS) $(CFLAGS) -c -o src/tests/cmocka/test_utils-test_string_utils.obj `if test -f 'src/tests/cmocka/test_string_utils.c'; then $(CYGPATH_W) 'src/tests/cmocka/test_string_utils.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/cmocka/test_string_utils.c'; fi` src/tests/util_tests-util-tests.o: src/tests/util-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(util_tests_CFLAGS) $(CFLAGS) -MT src/tests/util_tests-util-tests.o -MD -MP -MF src/tests/$(DEPDIR)/util_tests-util-tests.Tpo -c -o src/tests/util_tests-util-tests.o `test -f 'src/tests/util-tests.c' || echo '$(srcdir)/'`src/tests/util-tests.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/util_tests-util-tests.Tpo src/tests/$(DEPDIR)/util_tests-util-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/util-tests.c' object='src/tests/util_tests-util-tests.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(util_tests_CFLAGS) $(CFLAGS) -c -o src/tests/util_tests-util-tests.o `test -f 'src/tests/util-tests.c' || echo '$(srcdir)/'`src/tests/util-tests.c src/tests/util_tests-util-tests.obj: src/tests/util-tests.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(util_tests_CFLAGS) $(CFLAGS) -MT src/tests/util_tests-util-tests.obj -MD -MP -MF src/tests/$(DEPDIR)/util_tests-util-tests.Tpo -c -o src/tests/util_tests-util-tests.obj `if test -f 'src/tests/util-tests.c'; then $(CYGPATH_W) 'src/tests/util-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/util-tests.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) src/tests/$(DEPDIR)/util_tests-util-tests.Tpo src/tests/$(DEPDIR)/util_tests-util-tests.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='src/tests/util-tests.c' object='src/tests/util_tests-util-tests.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(util_tests_CFLAGS) $(CFLAGS) -c -o src/tests/util_tests-util-tests.obj `if test -f 'src/tests/util-tests.c'; then $(CYGPATH_W) 'src/tests/util-tests.c'; else $(CYGPATH_W) '$(srcdir)/src/tests/util-tests.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf src/confdb/.libs src/confdb/_libs -rm -rf src/db/.libs src/db/_libs -rm -rf src/krb5_plugin/.libs src/krb5_plugin/_libs -rm -rf src/ldb_modules/.libs src/ldb_modules/_libs -rm -rf src/lib/cifs_idmap_sss/.libs src/lib/cifs_idmap_sss/_libs -rm -rf src/lib/idmap/.libs src/lib/idmap/_libs -rm -rf src/lib/sifp/.libs src/lib/sifp/_libs -rm -rf src/monitor/.libs src/monitor/_libs -rm -rf src/providers/.libs src/providers/_libs -rm -rf src/providers/ad/.libs src/providers/ad/_libs -rm -rf src/providers/ipa/.libs src/providers/ipa/_libs -rm -rf src/providers/krb5/.libs src/providers/krb5/_libs -rm -rf src/providers/ldap/.libs src/providers/ldap/_libs -rm -rf src/providers/proxy/.libs src/providers/proxy/_libs -rm -rf src/providers/simple/.libs src/providers/simple/_libs -rm -rf src/python/.libs src/python/_libs -rm -rf src/resolv/.libs src/resolv/_libs -rm -rf src/sbus/.libs src/sbus/_libs -rm -rf src/sss_client/.libs src/sss_client/_libs -rm -rf src/sss_client/autofs/.libs src/sss_client/autofs/_libs -rm -rf src/sss_client/idmap/.libs src/sss_client/idmap/_libs -rm -rf src/sss_client/libwbclient/.libs src/sss_client/libwbclient/_libs -rm -rf src/sss_client/nfs/.libs src/sss_client/nfs/_libs -rm -rf src/sss_client/sudo/.libs src/sss_client/sudo/_libs -rm -rf src/tests/.libs src/tests/_libs -rm -rf src/tools/.libs src/tools/_libs -rm -rf src/tools/common/.libs src/tools/common/_libs -rm -rf src/util/.libs src/util/_libs -rm -rf src/util/cert/.libs src/util/cert/_libs -rm -rf src/util/cert/libcrypto/.libs src/util/cert/libcrypto/_libs -rm -rf src/util/cert/nss/.libs src/util/cert/nss/_libs -rm -rf src/util/crypto/libcrypto/.libs src/util/crypto/libcrypto/_libs -rm -rf src/util/crypto/nss/.libs src/util/crypto/nss/_libs distclean-libtool: -rm -f libtool config.lt install-dist_dbuspolicyDATA: $(dist_dbuspolicy_DATA) @$(NORMAL_INSTALL) @list='$(dist_dbuspolicy_DATA)'; test -n "$(dbuspolicydir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(dbuspolicydir)'"; \ $(MKDIR_P) "$(DESTDIR)$(dbuspolicydir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbuspolicydir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(dbuspolicydir)" || exit $$?; \ done uninstall-dist_dbuspolicyDATA: @$(NORMAL_UNINSTALL) @list='$(dist_dbuspolicy_DATA)'; test -n "$(dbuspolicydir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(dbuspolicydir)'; $(am__uninstall_files_from_dir) install-dist_dbusserviceDATA: $(dist_dbusservice_DATA) @$(NORMAL_INSTALL) @list='$(dist_dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(dbusservicedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(dbusservicedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dbusservicedir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(dbusservicedir)" || exit $$?; \ done uninstall-dist_dbusserviceDATA: @$(NORMAL_UNINSTALL) @list='$(dist_dbusservice_DATA)'; test -n "$(dbusservicedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(dbusservicedir)'; $(am__uninstall_files_from_dir) install-dist_polkit_rulesDATA: $(dist_polkit_rules_DATA) @$(NORMAL_INSTALL) @list='$(dist_polkit_rules_DATA)'; test -n "$(polkit_rulesdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(polkit_rulesdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(polkit_rulesdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(polkit_rulesdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(polkit_rulesdir)" || exit $$?; \ done uninstall-dist_polkit_rulesDATA: @$(NORMAL_UNINSTALL) @list='$(dist_polkit_rules_DATA)'; test -n "$(polkit_rulesdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(polkit_rulesdir)'; $(am__uninstall_files_from_dir) install-dist_sssdapipluginDATA: $(dist_sssdapiplugin_DATA) @$(NORMAL_INSTALL) @list='$(dist_sssdapiplugin_DATA)'; test -n "$(sssdapiplugindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sssdapiplugindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sssdapiplugindir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sssdapiplugindir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(sssdapiplugindir)" || exit $$?; \ done uninstall-dist_sssdapipluginDATA: @$(NORMAL_UNINSTALL) @list='$(dist_sssdapiplugin_DATA)'; test -n "$(sssdapiplugindir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(sssdapiplugindir)'; $(am__uninstall_files_from_dir) install-dist_sssddataDATA: $(dist_sssddata_DATA) @$(NORMAL_INSTALL) @list='$(dist_sssddata_DATA)'; test -n "$(sssddatadir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(sssddatadir)'"; \ $(MKDIR_P) "$(DESTDIR)$(sssddatadir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sssddatadir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(sssddatadir)" || exit $$?; \ done uninstall-dist_sssddataDATA: @$(NORMAL_UNINSTALL) @list='$(dist_sssddata_DATA)'; test -n "$(sssddatadir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(sssddatadir)'; $(am__uninstall_files_from_dir) install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-systemdconfDATA: $(systemdconf_DATA) @$(NORMAL_INSTALL) @list='$(systemdconf_DATA)'; test -n "$(systemdconfdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(systemdconfdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(systemdconfdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(systemdconfdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(systemdconfdir)" || exit $$?; \ done uninstall-systemdconfDATA: @$(NORMAL_UNINSTALL) @list='$(systemdconf_DATA)'; test -n "$(systemdconfdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(systemdconfdir)'; $(am__uninstall_files_from_dir) install-systemdunitDATA: $(systemdunit_DATA) @$(NORMAL_INSTALL) @list='$(systemdunit_DATA)'; test -n "$(systemdunitdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(systemdunitdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(systemdunitdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(systemdunitdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(systemdunitdir)" || exit $$?; \ done uninstall-systemdunitDATA: @$(NORMAL_UNINSTALL) @list='$(systemdunit_DATA)'; test -n "$(systemdunitdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(systemdunitdir)'; $(am__uninstall_files_from_dir) install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_LTLIBRARIES) $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? nss-srv-tests.log: nss-srv-tests$(EXEEXT) @p='nss-srv-tests$(EXEEXT)'; \ b='nss-srv-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-find-uid.log: test-find-uid$(EXEEXT) @p='test-find-uid$(EXEEXT)'; \ b='test-find-uid'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-io.log: test-io$(EXEEXT) @p='test-io$(EXEEXT)'; \ b='test-io'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-negcache.log: test-negcache$(EXEEXT) @p='test-negcache$(EXEEXT)'; \ b='test-negcache'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test-authtok.log: test-authtok$(EXEEXT) @p='test-authtok$(EXEEXT)'; \ b='test-authtok'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) sss_nss_idmap-tests.log: sss_nss_idmap-tests$(EXEEXT) @p='sss_nss_idmap-tests$(EXEEXT)'; \ b='sss_nss_idmap-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) dyndns-tests.log: dyndns-tests$(EXEEXT) @p='dyndns-tests$(EXEEXT)'; \ b='dyndns-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) fqnames-tests.log: fqnames-tests$(EXEEXT) @p='fqnames-tests$(EXEEXT)'; \ b='fqnames-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) nestedgroups-tests.log: nestedgroups-tests$(EXEEXT) @p='nestedgroups-tests$(EXEEXT)'; \ b='nestedgroups-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_sss_idmap.log: test_sss_idmap$(EXEEXT) @p='test_sss_idmap$(EXEEXT)'; \ b='test_sss_idmap'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_ipa_idmap.log: test_ipa_idmap$(EXEEXT) @p='test_ipa_idmap$(EXEEXT)'; \ b='test_ipa_idmap'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_utils.log: test_utils$(EXEEXT) @p='test_utils$(EXEEXT)'; \ b='test_utils'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) ad_common_tests.log: ad_common_tests$(EXEEXT) @p='ad_common_tests$(EXEEXT)'; \ b='ad_common_tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) dp_opt_tests.log: dp_opt_tests$(EXEEXT) @p='dp_opt_tests$(EXEEXT)'; \ b='dp_opt_tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) responder-get-domains-tests.log: responder-get-domains-tests$(EXEEXT) @p='responder-get-domains-tests$(EXEEXT)'; \ b='responder-get-domains-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) sbus-internal-tests.log: sbus-internal-tests$(EXEEXT) @p='sbus-internal-tests$(EXEEXT)'; \ b='sbus-internal-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) sss_sifp-tests.log: sss_sifp-tests$(EXEEXT) @p='sss_sifp-tests$(EXEEXT)'; \ b='sss_sifp-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_search_bases.log: test_search_bases$(EXEEXT) @p='test_search_bases$(EXEEXT)'; \ b='test_search_bases'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_ldap_auth.log: test_ldap_auth$(EXEEXT) @p='test_ldap_auth$(EXEEXT)'; \ b='test_ldap_auth'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_sdap_access.log: test_sdap_access$(EXEEXT) @p='test_sdap_access$(EXEEXT)'; \ b='test_sdap_access'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) sdap-tests.log: sdap-tests$(EXEEXT) @p='sdap-tests$(EXEEXT)'; \ b='sdap-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_sysdb_views.log: test_sysdb_views$(EXEEXT) @p='test_sysdb_views$(EXEEXT)'; \ b='test_sysdb_views'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_sysdb_subdomains.log: test_sysdb_subdomains$(EXEEXT) @p='test_sysdb_subdomains$(EXEEXT)'; \ b='test_sysdb_subdomains'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_sysdb_utils.log: test_sysdb_utils$(EXEEXT) @p='test_sysdb_utils$(EXEEXT)'; \ b='test_sysdb_utils'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_be_ptask.log: test_be_ptask$(EXEEXT) @p='test_be_ptask$(EXEEXT)'; \ b='test_be_ptask'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_copy_ccache.log: test_copy_ccache$(EXEEXT) @p='test_copy_ccache$(EXEEXT)'; \ b='test_copy_ccache'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_copy_keytab.log: test_copy_keytab$(EXEEXT) @p='test_copy_keytab$(EXEEXT)'; \ b='test_copy_keytab'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_child_common.log: test_child_common$(EXEEXT) @p='test_child_common$(EXEEXT)'; \ b='test_child_common'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) responder_cache_req-tests.log: responder_cache_req-tests$(EXEEXT) @p='responder_cache_req-tests$(EXEEXT)'; \ b='responder_cache_req-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_sbus_opath.log: test_sbus_opath$(EXEEXT) @p='test_sbus_opath$(EXEEXT)'; \ b='test_sbus_opath'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_fo_srv.log: test_fo_srv$(EXEEXT) @p='test_fo_srv$(EXEEXT)'; \ b='test_fo_srv'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) pam-srv-tests.log: pam-srv-tests$(EXEEXT) @p='pam-srv-tests$(EXEEXT)'; \ b='pam-srv-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_ipa_subdom_util.log: test_ipa_subdom_util$(EXEEXT) @p='test_ipa_subdom_util$(EXEEXT)'; \ b='test_ipa_subdom_util'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_ipa_subdom_server.log: test_ipa_subdom_server$(EXEEXT) @p='test_ipa_subdom_server$(EXEEXT)'; \ b='test_ipa_subdom_server'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_tools_colondb.log: test_tools_colondb$(EXEEXT) @p='test_tools_colondb$(EXEEXT)'; \ b='test_tools_colondb'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_krb5_wait_queue.log: test_krb5_wait_queue$(EXEEXT) @p='test_krb5_wait_queue$(EXEEXT)'; \ b='test_krb5_wait_queue'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_cert_utils.log: test_cert_utils$(EXEEXT) @p='test_cert_utils$(EXEEXT)'; \ b='test_cert_utils'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_ldap_id_cleanup.log: test_ldap_id_cleanup$(EXEEXT) @p='test_ldap_id_cleanup$(EXEEXT)'; \ b='test_ldap_id_cleanup'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_data_provider_be.log: test_data_provider_be$(EXEEXT) @p='test_data_provider_be$(EXEEXT)'; \ b='test_data_provider_be'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_ipa_dn.log: test_ipa_dn$(EXEEXT) @p='test_ipa_dn$(EXEEXT)'; \ b='test_ipa_dn'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) test_resolv_fake.log: test_resolv_fake$(EXEEXT) @p='test_resolv_fake$(EXEEXT)'; \ b='test_resolv_fake'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) ifp_tests.log: ifp_tests$(EXEEXT) @p='ifp_tests$(EXEEXT)'; \ b='ifp_tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) ad_access_filter_tests.log: ad_access_filter_tests$(EXEEXT) @p='ad_access_filter_tests$(EXEEXT)'; \ b='ad_access_filter_tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) ad_gpo_tests.log: ad_gpo_tests$(EXEEXT) @p='ad_gpo_tests$(EXEEXT)'; \ b='ad_gpo_tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) dlopen-tests.log: dlopen-tests$(EXEEXT) @p='dlopen-tests$(EXEEXT)'; \ b='dlopen-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) sysdb-tests.log: sysdb-tests$(EXEEXT) @p='sysdb-tests$(EXEEXT)'; \ b='sysdb-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) strtonum-tests.log: strtonum-tests$(EXEEXT) @p='strtonum-tests$(EXEEXT)'; \ b='strtonum-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) resolv-tests.log: resolv-tests$(EXEEXT) @p='resolv-tests$(EXEEXT)'; \ b='resolv-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) krb5-utils-tests.log: krb5-utils-tests$(EXEEXT) @p='krb5-utils-tests$(EXEEXT)'; \ b='krb5-utils-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) check_and_open-tests.log: check_and_open-tests$(EXEEXT) @p='check_and_open-tests$(EXEEXT)'; \ b='check_and_open-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) files-tests.log: files-tests$(EXEEXT) @p='files-tests$(EXEEXT)'; \ b='files-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) refcount-tests.log: refcount-tests$(EXEEXT) @p='refcount-tests$(EXEEXT)'; \ b='refcount-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) fail_over-tests.log: fail_over-tests$(EXEEXT) @p='fail_over-tests$(EXEEXT)'; \ b='fail_over-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) find_uid-tests.log: find_uid-tests$(EXEEXT) @p='find_uid-tests$(EXEEXT)'; \ b='find_uid-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) auth-tests.log: auth-tests$(EXEEXT) @p='auth-tests$(EXEEXT)'; \ b='auth-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) ipa_ldap_opt-tests.log: ipa_ldap_opt-tests$(EXEEXT) @p='ipa_ldap_opt-tests$(EXEEXT)'; \ b='ipa_ldap_opt-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) ad_ldap_opt-tests.log: ad_ldap_opt-tests$(EXEEXT) @p='ad_ldap_opt-tests$(EXEEXT)'; \ b='ad_ldap_opt-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) simple_access-tests.log: simple_access-tests$(EXEEXT) @p='simple_access-tests$(EXEEXT)'; \ b='simple_access-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) crypto-tests.log: crypto-tests$(EXEEXT) @p='crypto-tests$(EXEEXT)'; \ b='crypto-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) util-tests.log: util-tests$(EXEEXT) @p='util-tests$(EXEEXT)'; \ b='util-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) debug-tests.log: debug-tests$(EXEEXT) @p='debug-tests$(EXEEXT)'; \ b='debug-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) ipa_hbac-tests.log: ipa_hbac-tests$(EXEEXT) @p='ipa_hbac-tests$(EXEEXT)'; \ b='ipa_hbac-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) sss_idmap-tests.log: sss_idmap-tests$(EXEEXT) @p='sss_idmap-tests$(EXEEXT)'; \ b='sss_idmap-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) responder_socket_access-tests.log: responder_socket_access-tests$(EXEEXT) @p='responder_socket_access-tests$(EXEEXT)'; \ b='responder_socket_access-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) safe-format-tests.log: safe-format-tests$(EXEEXT) @p='safe-format-tests$(EXEEXT)'; \ b='safe-format-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) sysdb_ssh-tests.log: sysdb_ssh-tests$(EXEEXT) @p='sysdb_ssh-tests$(EXEEXT)'; \ b='sysdb_ssh-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) sss_config-tests.log: sss_config-tests$(EXEEXT) @p='sss_config-tests$(EXEEXT)'; \ b='sss_config-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) sbus_tests.log: sbus_tests$(EXEEXT) @p='sbus_tests$(EXEEXT)'; \ b='sbus_tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) sbus_codegen_tests.log: sbus_codegen_tests$(EXEEXT) @p='sbus_codegen_tests$(EXEEXT)'; \ b='sbus_codegen_tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) src/tests/whitespace_test.log: src/tests/whitespace_test @p='src/tests/whitespace_test'; \ b='src/tests/whitespace_test'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .sh.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.sh$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(SH_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_SH_LOG_DRIVER_FLAGS) $(SH_LOG_DRIVER_FLAGS) -- $(SH_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \ $(HEADERS) config.h all-local install-binPROGRAMS: install-libLTLIBRARIES installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(autofslibdir)" "$(DESTDIR)$(cifsplugindir)" "$(DESTDIR)$(krb5authdata_plugindir)" "$(DESTDIR)$(krb5localauth_plugindir)" "$(DESTDIR)$(krb5plugindir)" "$(DESTDIR)$(ldblibdir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libwbclientdir)" "$(DESTDIR)$(nfslibdir)" "$(DESTDIR)$(nsslibdir)" "$(DESTDIR)$(pamlibdir)" "$(DESTDIR)$(pkglibdir)" "$(DESTDIR)$(py2execdir)" "$(DESTDIR)$(py3execdir)" "$(DESTDIR)$(sssdlibdir)" "$(DESTDIR)$(sudolibdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(sssdlibexecdir)" "$(DESTDIR)$(sss_obfuscate_pythondir)" "$(DESTDIR)$(initdir)" "$(DESTDIR)$(dbuspolicydir)" "$(DESTDIR)$(dbusservicedir)" "$(DESTDIR)$(polkit_rulesdir)" "$(DESTDIR)$(sssdapiplugindir)" "$(DESTDIR)$(sssddatadir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(systemdconfdir)" "$(DESTDIR)$(systemdunitdir)" "$(DESTDIR)$(includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f src/confdb/$(DEPDIR)/$(am__dirstamp) -rm -f src/confdb/$(am__dirstamp) -rm -f src/db/$(DEPDIR)/$(am__dirstamp) -rm -f src/db/$(am__dirstamp) -rm -f src/krb5_plugin/$(DEPDIR)/$(am__dirstamp) -rm -f src/krb5_plugin/$(am__dirstamp) -rm -f src/ldb_modules/$(DEPDIR)/$(am__dirstamp) -rm -f src/ldb_modules/$(am__dirstamp) -rm -f src/lib/cifs_idmap_sss/$(DEPDIR)/$(am__dirstamp) -rm -f src/lib/cifs_idmap_sss/$(am__dirstamp) -rm -f src/lib/idmap/$(DEPDIR)/$(am__dirstamp) -rm -f src/lib/idmap/$(am__dirstamp) -rm -f src/lib/sifp/$(DEPDIR)/$(am__dirstamp) -rm -f src/lib/sifp/$(am__dirstamp) -rm -f src/monitor/$(DEPDIR)/$(am__dirstamp) -rm -f src/monitor/$(am__dirstamp) -rm -f src/p11_child/$(DEPDIR)/$(am__dirstamp) -rm -f src/p11_child/$(am__dirstamp) -rm -f src/providers/$(DEPDIR)/$(am__dirstamp) -rm -f src/providers/$(am__dirstamp) -rm -f src/providers/ad/$(DEPDIR)/$(am__dirstamp) -rm -f src/providers/ad/$(am__dirstamp) -rm -f src/providers/ipa/$(DEPDIR)/$(am__dirstamp) -rm -f src/providers/ipa/$(am__dirstamp) -rm -f src/providers/krb5/$(DEPDIR)/$(am__dirstamp) -rm -f src/providers/krb5/$(am__dirstamp) -rm -f src/providers/ldap/$(DEPDIR)/$(am__dirstamp) -rm -f src/providers/ldap/$(am__dirstamp) -rm -f src/providers/proxy/$(DEPDIR)/$(am__dirstamp) -rm -f src/providers/proxy/$(am__dirstamp) -rm -f src/providers/simple/$(DEPDIR)/$(am__dirstamp) -rm -f src/providers/simple/$(am__dirstamp) -rm -f src/python/$(DEPDIR)/$(am__dirstamp) -rm -f src/python/$(am__dirstamp) -rm -f src/resolv/$(DEPDIR)/$(am__dirstamp) -rm -f src/resolv/$(am__dirstamp) -rm -f src/responder/autofs/$(DEPDIR)/$(am__dirstamp) -rm -f src/responder/autofs/$(am__dirstamp) -rm -f src/responder/common/$(DEPDIR)/$(am__dirstamp) -rm -f src/responder/common/$(am__dirstamp) -rm -f src/responder/ifp/$(DEPDIR)/$(am__dirstamp) -rm -f src/responder/ifp/$(am__dirstamp) -rm -f src/responder/nss/$(DEPDIR)/$(am__dirstamp) -rm -f src/responder/nss/$(am__dirstamp) -rm -f src/responder/pac/$(DEPDIR)/$(am__dirstamp) -rm -f src/responder/pac/$(am__dirstamp) -rm -f src/responder/pam/$(DEPDIR)/$(am__dirstamp) -rm -f src/responder/pam/$(am__dirstamp) -rm -f src/responder/ssh/$(DEPDIR)/$(am__dirstamp) -rm -f src/responder/ssh/$(am__dirstamp) -rm -f src/responder/sudo/$(DEPDIR)/$(am__dirstamp) -rm -f src/responder/sudo/$(am__dirstamp) -rm -f src/sbus/$(DEPDIR)/$(am__dirstamp) -rm -f src/sbus/$(am__dirstamp) -rm -f src/sss_client/$(DEPDIR)/$(am__dirstamp) -rm -f src/sss_client/$(am__dirstamp) -rm -f src/sss_client/autofs/$(DEPDIR)/$(am__dirstamp) -rm -f src/sss_client/autofs/$(am__dirstamp) -rm -f src/sss_client/idmap/$(DEPDIR)/$(am__dirstamp) -rm -f src/sss_client/idmap/$(am__dirstamp) -rm -f src/sss_client/libwbclient/$(DEPDIR)/$(am__dirstamp) -rm -f src/sss_client/libwbclient/$(am__dirstamp) -rm -f src/sss_client/nfs/$(DEPDIR)/$(am__dirstamp) -rm -f src/sss_client/nfs/$(am__dirstamp) -rm -f src/sss_client/ssh/$(DEPDIR)/$(am__dirstamp) -rm -f src/sss_client/ssh/$(am__dirstamp) -rm -f src/sss_client/sudo/$(DEPDIR)/$(am__dirstamp) -rm -f src/sss_client/sudo/$(am__dirstamp) -rm -f src/sss_client/sudo_testcli/$(DEPDIR)/$(am__dirstamp) -rm -f src/sss_client/sudo_testcli/$(am__dirstamp) -rm -f src/tests/$(DEPDIR)/$(am__dirstamp) -rm -f src/tests/$(am__dirstamp) -rm -f src/tests/cmocka/$(DEPDIR)/$(am__dirstamp) -rm -f src/tests/cmocka/$(am__dirstamp) -rm -f src/tools/$(DEPDIR)/$(am__dirstamp) -rm -f src/tools/$(am__dirstamp) -rm -f src/tools/common/$(DEPDIR)/$(am__dirstamp) -rm -f src/tools/common/$(am__dirstamp) -rm -f src/util/$(DEPDIR)/$(am__dirstamp) -rm -f src/util/$(am__dirstamp) -rm -f src/util/cert/$(DEPDIR)/$(am__dirstamp) -rm -f src/util/cert/$(am__dirstamp) -rm -f src/util/cert/libcrypto/$(DEPDIR)/$(am__dirstamp) -rm -f src/util/cert/libcrypto/$(am__dirstamp) -rm -f src/util/cert/nss/$(DEPDIR)/$(am__dirstamp) -rm -f src/util/cert/nss/$(am__dirstamp) -rm -f src/util/crypto/libcrypto/$(DEPDIR)/$(am__dirstamp) -rm -f src/util/crypto/libcrypto/$(am__dirstamp) -rm -f src/util/crypto/nss/$(DEPDIR)/$(am__dirstamp) -rm -f src/util/crypto/nss/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-autofslibLTLIBRARIES clean-binPROGRAMS \ clean-checkLTLIBRARIES clean-checkPROGRAMS \ clean-cifspluginLTLIBRARIES clean-generic \ clean-krb5authdata_pluginLTLIBRARIES \ clean-krb5localauth_pluginLTLIBRARIES \ clean-krb5pluginLTLIBRARIES clean-ldblibLTLIBRARIES \ clean-libLTLIBRARIES clean-libtool \ clean-libwbclientLTLIBRARIES clean-local \ clean-nfslibLTLIBRARIES clean-noinstLTLIBRARIES \ clean-noinstPROGRAMS clean-nsslibLTLIBRARIES \ clean-pamlibLTLIBRARIES clean-pkglibLTLIBRARIES \ clean-py2execLTLIBRARIES clean-py3execLTLIBRARIES \ clean-sbinPROGRAMS clean-sssdlibLTLIBRARIES \ clean-sssdlibexecPROGRAMS clean-sudolibLTLIBRARIES \ mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf src/confdb/$(DEPDIR) src/db/$(DEPDIR) src/krb5_plugin/$(DEPDIR) src/ldb_modules/$(DEPDIR) src/lib/cifs_idmap_sss/$(DEPDIR) src/lib/idmap/$(DEPDIR) src/lib/sifp/$(DEPDIR) src/monitor/$(DEPDIR) src/p11_child/$(DEPDIR) src/providers/$(DEPDIR) src/providers/ad/$(DEPDIR) src/providers/ipa/$(DEPDIR) src/providers/krb5/$(DEPDIR) src/providers/ldap/$(DEPDIR) src/providers/proxy/$(DEPDIR) src/providers/simple/$(DEPDIR) src/python/$(DEPDIR) src/resolv/$(DEPDIR) src/responder/autofs/$(DEPDIR) src/responder/common/$(DEPDIR) src/responder/ifp/$(DEPDIR) src/responder/nss/$(DEPDIR) src/responder/pac/$(DEPDIR) src/responder/pam/$(DEPDIR) src/responder/ssh/$(DEPDIR) src/responder/sudo/$(DEPDIR) src/sbus/$(DEPDIR) src/sss_client/$(DEPDIR) src/sss_client/autofs/$(DEPDIR) src/sss_client/idmap/$(DEPDIR) src/sss_client/libwbclient/$(DEPDIR) src/sss_client/nfs/$(DEPDIR) src/sss_client/ssh/$(DEPDIR) src/sss_client/sudo/$(DEPDIR) src/sss_client/sudo_testcli/$(DEPDIR) src/tests/$(DEPDIR) src/tests/cmocka/$(DEPDIR) src/tools/$(DEPDIR) src/tools/common/$(DEPDIR) src/util/$(DEPDIR) src/util/cert/$(DEPDIR) src/util/cert/libcrypto/$(DEPDIR) src/util/cert/nss/$(DEPDIR) src/util/crypto/libcrypto/$(DEPDIR) src/util/crypto/nss/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-autofslibLTLIBRARIES \ install-cifspluginLTLIBRARIES install-dist_dbuspolicyDATA \ install-dist_dbusserviceDATA install-dist_polkit_rulesDATA \ install-dist_sss_obfuscate_pythonSCRIPTS \ install-dist_sssdapipluginDATA install-dist_sssddataDATA \ install-includeHEADERS install-initSCRIPTS \ install-krb5authdata_pluginLTLIBRARIES \ install-krb5localauth_pluginLTLIBRARIES \ install-krb5pluginLTLIBRARIES install-ldblibLTLIBRARIES \ install-libwbclientLTLIBRARIES install-nfslibLTLIBRARIES \ install-nsslibLTLIBRARIES install-pamlibLTLIBRARIES \ install-pkgconfigDATA install-sssdlibLTLIBRARIES \ install-sudolibLTLIBRARIES install-systemdconfDATA \ install-systemdunitDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-binPROGRAMS install-libLTLIBRARIES \ install-pkglibLTLIBRARIES install-py2execLTLIBRARIES \ install-py3execLTLIBRARIES install-sbinPROGRAMS \ install-sssdlibexecPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -rf src/confdb/$(DEPDIR) src/db/$(DEPDIR) src/krb5_plugin/$(DEPDIR) src/ldb_modules/$(DEPDIR) src/lib/cifs_idmap_sss/$(DEPDIR) src/lib/idmap/$(DEPDIR) src/lib/sifp/$(DEPDIR) src/monitor/$(DEPDIR) src/p11_child/$(DEPDIR) src/providers/$(DEPDIR) src/providers/ad/$(DEPDIR) src/providers/ipa/$(DEPDIR) src/providers/krb5/$(DEPDIR) src/providers/ldap/$(DEPDIR) src/providers/proxy/$(DEPDIR) src/providers/simple/$(DEPDIR) src/python/$(DEPDIR) src/resolv/$(DEPDIR) src/responder/autofs/$(DEPDIR) src/responder/common/$(DEPDIR) src/responder/ifp/$(DEPDIR) src/responder/nss/$(DEPDIR) src/responder/pac/$(DEPDIR) src/responder/pam/$(DEPDIR) src/responder/ssh/$(DEPDIR) src/responder/sudo/$(DEPDIR) src/sbus/$(DEPDIR) src/sss_client/$(DEPDIR) src/sss_client/autofs/$(DEPDIR) src/sss_client/idmap/$(DEPDIR) src/sss_client/libwbclient/$(DEPDIR) src/sss_client/nfs/$(DEPDIR) src/sss_client/ssh/$(DEPDIR) src/sss_client/sudo/$(DEPDIR) src/sss_client/sudo_testcli/$(DEPDIR) src/tests/$(DEPDIR) src/tests/cmocka/$(DEPDIR) src/tools/$(DEPDIR) src/tools/common/$(DEPDIR) src/util/$(DEPDIR) src/util/cert/$(DEPDIR) src/util/cert/libcrypto/$(DEPDIR) src/util/cert/nss/$(DEPDIR) src/util/crypto/libcrypto/$(DEPDIR) src/util/crypto/nss/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-autofslibLTLIBRARIES uninstall-binPROGRAMS \ uninstall-cifspluginLTLIBRARIES uninstall-dist_dbuspolicyDATA \ uninstall-dist_dbusserviceDATA uninstall-dist_polkit_rulesDATA \ uninstall-dist_sss_obfuscate_pythonSCRIPTS \ uninstall-dist_sssdapipluginDATA uninstall-dist_sssddataDATA \ uninstall-includeHEADERS uninstall-initSCRIPTS \ uninstall-krb5authdata_pluginLTLIBRARIES \ uninstall-krb5localauth_pluginLTLIBRARIES \ uninstall-krb5pluginLTLIBRARIES uninstall-ldblibLTLIBRARIES \ uninstall-libLTLIBRARIES uninstall-libwbclientLTLIBRARIES \ uninstall-nfslibLTLIBRARIES uninstall-nsslibLTLIBRARIES \ uninstall-pamlibLTLIBRARIES uninstall-pkgconfigDATA \ uninstall-pkglibLTLIBRARIES uninstall-py2execLTLIBRARIES \ uninstall-py3execLTLIBRARIES uninstall-sbinPROGRAMS \ uninstall-sssdlibLTLIBRARIES uninstall-sssdlibexecPROGRAMS \ uninstall-sudolibLTLIBRARIES uninstall-systemdconfDATA \ uninstall-systemdunitDATA @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: $(am__recursive_targets) all check check-am install install-am \ install-data-am install-exec-am install-strip uninstall-am .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am all-local \ am--refresh check check-TESTS check-am clean \ clean-autofslibLTLIBRARIES clean-binPROGRAMS \ clean-checkLTLIBRARIES clean-checkPROGRAMS \ clean-cifspluginLTLIBRARIES clean-cscope clean-generic \ clean-krb5authdata_pluginLTLIBRARIES \ clean-krb5localauth_pluginLTLIBRARIES \ clean-krb5pluginLTLIBRARIES clean-ldblibLTLIBRARIES \ clean-libLTLIBRARIES clean-libtool \ clean-libwbclientLTLIBRARIES clean-local \ clean-nfslibLTLIBRARIES clean-noinstLTLIBRARIES \ clean-noinstPROGRAMS clean-nsslibLTLIBRARIES \ clean-pamlibLTLIBRARIES clean-pkglibLTLIBRARIES \ clean-py2execLTLIBRARIES clean-py3execLTLIBRARIES \ clean-sbinPROGRAMS clean-sssdlibLTLIBRARIES \ clean-sssdlibexecPROGRAMS clean-sudolibLTLIBRARIES cscope \ cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ distcheck distclean distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ info-am install install-am install-autofslibLTLIBRARIES \ install-binPROGRAMS install-cifspluginLTLIBRARIES install-data \ install-data-am install-data-hook install-dist_dbuspolicyDATA \ install-dist_dbusserviceDATA install-dist_polkit_rulesDATA \ install-dist_sss_obfuscate_pythonSCRIPTS \ install-dist_sssdapipluginDATA install-dist_sssddataDATA \ install-dvi install-dvi-am install-exec install-exec-am \ install-exec-hook install-html install-html-am \ install-includeHEADERS install-info install-info-am \ install-initSCRIPTS install-krb5authdata_pluginLTLIBRARIES \ install-krb5localauth_pluginLTLIBRARIES \ install-krb5pluginLTLIBRARIES install-ldblibLTLIBRARIES \ install-libLTLIBRARIES install-libwbclientLTLIBRARIES \ install-man install-nfslibLTLIBRARIES \ install-nsslibLTLIBRARIES install-pamlibLTLIBRARIES \ install-pdf install-pdf-am install-pkgconfigDATA \ install-pkglibLTLIBRARIES install-ps install-ps-am \ install-py2execLTLIBRARIES install-py3execLTLIBRARIES \ install-sbinPROGRAMS install-sssdlibLTLIBRARIES \ install-sssdlibexecPROGRAMS install-strip \ install-sudolibLTLIBRARIES install-systemdconfDATA \ install-systemdunitDATA installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am \ uninstall-autofslibLTLIBRARIES uninstall-binPROGRAMS \ uninstall-cifspluginLTLIBRARIES uninstall-dist_dbuspolicyDATA \ uninstall-dist_dbusserviceDATA uninstall-dist_polkit_rulesDATA \ uninstall-dist_sss_obfuscate_pythonSCRIPTS \ uninstall-dist_sssdapipluginDATA uninstall-dist_sssddataDATA \ uninstall-hook uninstall-includeHEADERS uninstall-initSCRIPTS \ uninstall-krb5authdata_pluginLTLIBRARIES \ uninstall-krb5localauth_pluginLTLIBRARIES \ uninstall-krb5pluginLTLIBRARIES uninstall-ldblibLTLIBRARIES \ uninstall-libLTLIBRARIES uninstall-libwbclientLTLIBRARIES \ uninstall-nfslibLTLIBRARIES uninstall-nsslibLTLIBRARIES \ uninstall-pamlibLTLIBRARIES uninstall-pkgconfigDATA \ uninstall-pkglibLTLIBRARIES uninstall-py2execLTLIBRARIES \ uninstall-py3execLTLIBRARIES uninstall-sbinPROGRAMS \ uninstall-sssdlibLTLIBRARIES uninstall-sssdlibexecPROGRAMS \ uninstall-sudolibLTLIBRARIES uninstall-systemdconfDATA \ uninstall-systemdunitDATA .PRECIOUS: Makefile # Some old versions of automake don't define builddir builddir ?= . .xml_generated.h: $(srcdir)/$(SBUS_CODEGEN) --mode=header --output=$@ $< .xml_generated.c: $(srcdir)/$(SBUS_CODEGEN) --mode=source --include=$(@:.c=.h) --output=$@ $< $(CODEGEN_CODE): $(SBUS_CODEGEN) ldb_mod_test_dir: memberof.la $(MKDIR_P) $(builddir)/ldb_mod_test_dir cp $(builddir)/.libs/memberof.so $(builddir)/ldb_mod_test_dir ##################### # Integration tests # ##################### intgcheck: set -e; \ rm -Rf intg; \ $(MKDIR_P) intg/bld; \ : Use /hopefully/ short prefix to keep D-Bus socket path short; \ prefix=`mktemp --tmpdir --directory sssd-intg.XXXXXXXX`; \ $(LN_S) "$$prefix" intg/pfx; \ cd intg/bld; \ $(abs_top_srcdir)/configure \ --prefix="$$prefix" \ --with-ldb-lib-dir="$$prefix"/lib/ldb \ --enable-intgcheck-reqs \ --without-semanage \ $(INTGCHECK_CONFIGURE_FLAGS); \ $(MAKE) $(AM_MAKEFLAGS); \ : Force single-thread install to workaround concurrency issues; \ $(MAKE) $(AM_MAKEFLAGS) -j1 install; \ : Remove .la files from LDB module directory to avoid loader warnings; \ rm "$$prefix"/lib/ldb/*.la; \ $(MAKE) $(AM_MAKEFLAGS) -C src/tests/intg intgcheck-installed; \ cd ../..; \ rm -Rf "$$prefix" intg ################ # TRANSLATIONS # ################ update-po: @HAVE_MANPAGES_TRUE@ $(MAKE) -C src/man update-po $(MAKE) -C po update-po src/sysv/systemd/sssd.service: src/sysv/systemd/sssd.service.in Makefile @$(MKDIR_P) src/sysv/systemd/ $(replace_script) src/sysv/systemd/journal.conf: src/sysv/systemd/journal.conf.in Makefile @$(MKDIR_P) src/sysv/systemd/ $(replace_script) installsssddirs:: $(MKDIR_P) \ $(DESTDIR)$(includedir) \ $(DESTDIR)$(libdir) \ $(DESTDIR)$(bindir) \ $(DESTDIR)$(sbindir) \ $(DESTDIR)$(mandir) \ $(DESTDIR)$(pidpath) \ $(DESTDIR)$(pluginpath) \ $(DESTDIR)$(libdir)/ldb \ $(DESTDIR)$(dbuspolicydir) \ $(DESTDIR)$(dbusservicedir) \ $(DESTDIR)$(sssdlibdir) \ $(DESTDIR)$(pkglibdir) \ $(DESTDIR)$(sssddatadir) \ $(DESTDIR)$(sudolibdir) \ $(DESTDIR)$(autofslibdir) \ $(SSSD_USER_DIRS) \ $(NULL); @SSSD_USER_TRUE@ -chown $(SSSD_USER):$(SSSD_USER) \ @SSSD_USER_TRUE@ $(SSSD_USER_DIRS) $(INSTALL) -d -m 0700 $(DESTDIR)$(dbpath) $(DESTDIR)$(logpath) \ $(DESTDIR)$(pipepath)/private \ $(DESTDIR)$(keytabdir) \ $(NULL) $(INSTALL) -d -m 0755 $(DESTDIR)$(mcpath) $(DESTDIR)$(pipepath) \ $(DESTDIR)$(pubconfpath) \ $(DESTDIR)$(pubconfpath)/krb5.include.d $(DESTDIR)$(gpocachepath) $(INSTALL) -d -m 0711 $(DESTDIR)$(sssdconfdir) @HAVE_DOXYGEN_TRUE@docs: @HAVE_DOXYGEN_TRUE@ $(DOXYGEN) src/doxy.config @HAVE_DOXYGEN_TRUE@ $(DOXYGEN) src/providers/ipa/ipa_hbac.doxy @HAVE_DOXYGEN_TRUE@ $(DOXYGEN) src/lib/idmap/sss_idmap.doxy @HAVE_DOXYGEN_TRUE@ $(DOXYGEN) src/sss_client/idmap/sss_nss_idmap.doxy @BUILD_IFP_TRUE@@HAVE_DOXYGEN_TRUE@ $(DOXYGEN) src/lib/sifp/sss_simpleifp.doxy @HAVE_DOXYGEN_FALSE@docs: @HAVE_DOXYGEN_FALSE@ @echo "Doxygen not installed, cannot generate documentation" @HAVE_DOXYGEN_FALSE@ @exit 1 @BUILD_PYTHON_BINDINGS_TRUE@$(abs_builddir)/src/config/SSSDConfig/ipachangeconf.py: @BUILD_PYTHON_BINDINGS_TRUE@ -cp $(srcdir)/src/config/SSSDConfig/ipachangeconf.py $(builddir)/src/config/SSSDConfig/ @BUILD_PYTHON_BINDINGS_TRUE@$(abs_builddir)/src/config/SSSDConfig/sssd_upgrade_config.py: @BUILD_PYTHON_BINDINGS_TRUE@ -cp $(srcdir)/src/config/SSSDConfig/sssd_upgrade_config.py $(builddir)/src/config/SSSDConfig/ all-local: ldb_mod_test_dir $(SSSDCONFIG_MODULES) @BUILD_PYTHON2_BINDINGS_TRUE@ cd $(builddir)/src/config; \ @BUILD_PYTHON2_BINDINGS_TRUE@ $(PYTHON2) setup.py build --build-base $(abs_builddir)/src/config @BUILD_PYTHON3_BINDINGS_TRUE@ cd $(builddir)/src/config; \ @BUILD_PYTHON3_BINDINGS_TRUE@ $(PYTHON3) setup.py build --build-base $(abs_builddir)/src/config install-exec-hook: installsssddirs @BUILD_PYTHON2_BINDINGS_TRUE@ if [ "$(DESTDIR)" = "" ]; then \ @BUILD_PYTHON2_BINDINGS_TRUE@ cd $(builddir)/src/config; \ @BUILD_PYTHON2_BINDINGS_TRUE@ $(PYTHON2) setup.py build --build-base $(abs_builddir)/src/config \ @BUILD_PYTHON2_BINDINGS_TRUE@ install $(DISTSETUPOPTS) --prefix=$(PYTHON2_PREFIX) \ @BUILD_PYTHON2_BINDINGS_TRUE@ --record=$(abs_builddir)/src/config/.files2; \ @BUILD_PYTHON2_BINDINGS_TRUE@ else \ @BUILD_PYTHON2_BINDINGS_TRUE@ cd $(builddir)/src/config; \ @BUILD_PYTHON2_BINDINGS_TRUE@ $(PYTHON2) setup.py build --build-base $(abs_builddir)/src/config \ @BUILD_PYTHON2_BINDINGS_TRUE@ install $(DISTSETUPOPTS) --prefix=$(PYTHON2_PREFIX) \ @BUILD_PYTHON2_BINDINGS_TRUE@ --record=$(abs_builddir)/src/config/.files2 --root=$(DESTDIR); \ @BUILD_PYTHON2_BINDINGS_TRUE@ fi @BUILD_PYTHON2_BINDINGS_TRUE@ cd $(DESTDIR)$(py2execdir) && \ @BUILD_PYTHON2_BINDINGS_TRUE@ mv -f _py2sss.so pysss.so ; \ @BUILD_PYTHON2_BINDINGS_TRUE@ mv -f _py2hbac.so pyhbac.so ; \ @BUILD_PYTHON2_BINDINGS_TRUE@ mv -f _py2sss_murmur.so pysss_murmur.so ; \ @BUILD_PYTHON2_BINDINGS_TRUE@ mv -f _py2sss_nss_idmap.so pysss_nss_idmap.so @BUILD_PYTHON3_BINDINGS_TRUE@ if [ "$(DESTDIR)" = "" ]; then \ @BUILD_PYTHON3_BINDINGS_TRUE@ cd $(builddir)/src/config; \ @BUILD_PYTHON3_BINDINGS_TRUE@ $(PYTHON3) setup.py build --build-base $(abs_builddir)/src/config \ @BUILD_PYTHON3_BINDINGS_TRUE@ install $(DISTSETUPOPTS) --prefix=$(PYTHON3_PREFIX) \ @BUILD_PYTHON3_BINDINGS_TRUE@ --record=$(abs_builddir)/src/config/.files3; \ @BUILD_PYTHON3_BINDINGS_TRUE@ else \ @BUILD_PYTHON3_BINDINGS_TRUE@ cd $(builddir)/src/config; \ @BUILD_PYTHON3_BINDINGS_TRUE@ $(PYTHON3) setup.py build --build-base $(abs_builddir)/src/config \ @BUILD_PYTHON3_BINDINGS_TRUE@ install $(DISTSETUPOPTS) --prefix=$(PYTHON3_PREFIX) \ @BUILD_PYTHON3_BINDINGS_TRUE@ --record=$(abs_builddir)/src/config/.files3 --root=$(DESTDIR); \ @BUILD_PYTHON3_BINDINGS_TRUE@ fi @BUILD_PYTHON3_BINDINGS_TRUE@ cd $(DESTDIR)$(py3execdir) && \ @BUILD_PYTHON3_BINDINGS_TRUE@ mv -f _py3sss.so pysss.so ; \ @BUILD_PYTHON3_BINDINGS_TRUE@ mv -f _py3hbac.so pyhbac.so ; \ @BUILD_PYTHON3_BINDINGS_TRUE@ mv -f _py3sss_murmur.so pysss_murmur.so ; \ @BUILD_PYTHON3_BINDINGS_TRUE@ mv -f _py3sss_nss_idmap.so pysss_nss_idmap.so for doc in $(SSSD_DOCS); do \ $(MKDIR_P) $$doc $(DESTDIR)/$(docdir); \ cp -a $$doc $(DESTDIR)/$(docdir)/; \ done; @HAVE_SYSTEMD_UNIT_TRUE@ $(MKDIR_P) $(DESTDIR)$(systemdunitdir) @HAVE_SYSTEMD_UNIT_TRUE@ $(MKDIR_P) $(DESTDIR)$(systemdconfdir) @HAVE_SYSTEMD_UNIT_FALSE@ $(MKDIR_P) $(DESTDIR)$(initdir) @SSSD_USER_TRUE@ -chgrp $(SSSD_USER) $(DESTDIR)$(sssdlibexecdir)/ldap_child @SSSD_USER_TRUE@ chmod 4750 $(DESTDIR)$(sssdlibexecdir)/ldap_child @SSSD_USER_TRUE@ -chgrp $(SSSD_USER) $(DESTDIR)$(sssdlibexecdir)/krb5_child @SSSD_USER_TRUE@ chmod 4750 $(DESTDIR)$(sssdlibexecdir)/krb5_child @SSSD_USER_TRUE@ -chgrp $(SSSD_USER) $(DESTDIR)$(sssdlibexecdir)/proxy_child @SSSD_USER_TRUE@ chmod 4750 $(DESTDIR)$(sssdlibexecdir)/proxy_child @BUILD_SEMANAGE_TRUE@@SSSD_USER_TRUE@ -chgrp $(SSSD_USER) $(DESTDIR)$(sssdlibexecdir)/selinux_child @BUILD_SEMANAGE_TRUE@@SSSD_USER_TRUE@ chmod 4750 $(DESTDIR)$(sssdlibexecdir)/selinux_child install-data-hook: rm $(DESTDIR)/$(nsslibdir)/libnss_sss.so.2 \ $(DESTDIR)/$(nsslibdir)/libnss_sss.so mv $(DESTDIR)/$(nsslibdir)/libnss_sss.so.2.0.0 $(DESTDIR)/$(nsslibdir)/libnss_sss.so.2 if [ ! $(krb5rcachedir) = "__LIBKRB5_DEFAULTS__" ]; then \ $(MKDIR_P) $(DESTDIR)/$(krb5rcachedir) ; \ fi uninstall-hook: if [ -f $(abs_builddir)/src/config/.files2 ]; then \ cat $(abs_builddir)/src/config/.files2 | xargs -iq rm -f $(DESTDIR)/q; \ rm $(abs_builddir)/src/config/.files2 ; \ fi if [ -f $(abs_builddir)/src/config/.files3 ]; then \ cat $(abs_builddir)/src/config/.files3 | xargs -iq rm -f $(DESTDIR)/q; \ rm $(abs_builddir)/src/config/.files3 ; \ fi for doc in $(SSSD_DOCS); do \ rm -Rf $(DESTDIR)/$(docdir)/$$doc; \ done; @BUILD_PYTHON2_BINDINGS_TRUE@ cd $(DESTDIR)$(py2execdir) && \ @BUILD_PYTHON2_BINDINGS_TRUE@ rm -f pysss.so pyhbac.so pysss_murmur.so pysss_nss_idmap.so @BUILD_PYTHON3_BINDINGS_TRUE@ cd $(DESTDIR)$(py3execdir) && \ @BUILD_PYTHON3_BINDINGS_TRUE@ rm -f pysss.so pyhbac.so pysss_murmur.so pysss_nss_idmap.so clean-local: @BUILD_PYTHON2_BINDINGS_TRUE@ if [ ! $(srcdir)/src/config/SSSDConfig/ipachangeconf.py -ef $(builddir)/src/config/SSSDConfig/ipachangeconf.py ]; then \ @BUILD_PYTHON2_BINDINGS_TRUE@ rm -f $(builddir)/src/config/SSSDConfig/ipachangeconf.py ; \ @BUILD_PYTHON2_BINDINGS_TRUE@ fi @BUILD_PYTHON2_BINDINGS_TRUE@ if [ ! $(srcdir)/src/config/SSSDConfig/ipachangeconf.py -ef $(builddir)/src/config/SSSDConfig/ipachangeconf.py ]; then \ @BUILD_PYTHON2_BINDINGS_TRUE@ rm -f $(builddir)/src/config/SSSDConfig/sssd_upgrade_config.py ; \ @BUILD_PYTHON2_BINDINGS_TRUE@ fi @BUILD_PYTHON2_BINDINGS_TRUE@ rm -f $(builddir)/src/config/SSSDConfig/*.pyc @BUILD_PYTHON2_BINDINGS_TRUE@ cd $(builddir)/src/config; $(PYTHON2) setup.py build --build-base $(abs_builddir)/src/config clean --all @BUILD_PYTHON3_BINDINGS_TRUE@ if [ ! $(srcdir)/src/config/SSSDConfig/ipachangeconf.py -ef $(builddir)/src/config/SSSDConfig/ipachangeconf.py ]; then \ @BUILD_PYTHON3_BINDINGS_TRUE@ rm -f $(builddir)/src/config/SSSDConfig/ipachangeconf.py ; \ @BUILD_PYTHON3_BINDINGS_TRUE@ fi @BUILD_PYTHON3_BINDINGS_TRUE@ if [ ! $(srcdir)/src/config/SSSDConfig/ipachangeconf.py -ef $(builddir)/src/config/SSSDConfig/ipachangeconf.py ]; then \ @BUILD_PYTHON3_BINDINGS_TRUE@ rm -f $(builddir)/src/config/SSSDConfig/sssd_upgrade_config.py ; \ @BUILD_PYTHON3_BINDINGS_TRUE@ fi @BUILD_PYTHON3_BINDINGS_TRUE@ rm -f $(builddir)/src/config/SSSDConfig/__pycache__/*.pyc @BUILD_PYTHON3_BINDINGS_TRUE@ cd $(builddir)/src/config; $(PYTHON3) setup.py build --build-base $(abs_builddir)/src/config clean --all for doc in $(SSSD_DOCS); do \ rm -Rf $$doc; \ done; rm -Rf ldb_mod_test_dir rm -f $(builddir)/src/sysv/systemd/sssd.service rm -f $(builddir)/src/sysv/systemd/journal.conf tests: all $(check_PROGRAMS) (cd src/tests/cwrap && $(MAKE) $(AM_MAKEFLAGS) $@) || exit 1; # RPM-related tasks RPMBUILD ?= $(PWD)/rpmbuild rpmroot: $(MKDIR_P) $(RPMBUILD)/BUILD $(MKDIR_P) $(RPMBUILD)/RPMS $(MKDIR_P) $(RPMBUILD)/SOURCES $(MKDIR_P) $(RPMBUILD)/SPECS $(MKDIR_P) $(RPMBUILD)/SRPMS rpmbrprep: dist-gzip rpmroot # When we're building RPMs from a git checkout, # we don't want to be bothered with translation # updates @GIT_CHECKOUT_TRUE@ git checkout $(srcdir)/po $(srcdir)/src/man/po cp $(builddir)/contrib/sssd.spec $(RPMBUILD)/SPECS cp $(distdir).tar.gz $(RPMBUILD)/SOURCES rpms: rpmbrprep cd $(RPMBUILD); \ rpmbuild --define "_topdir $(RPMBUILD)" -ba SPECS/sssd.spec @GIT_CHECKOUT_TRUE@prerelease-rpms: @GIT_CHECKOUT_TRUE@ cp $(srcdir)/version.m4 $(srcdir)/version.m4.orig @GIT_CHECKOUT_TRUE@ sed -e "s/m4_define(\[PRERELEASE_VERSION_NUMBER\], \[.*\])/m4_define(\[PRERELEASE_VERSION_NUMBER\], \[.`date +%Y%m%d.%H%M`.git`git log -1 --pretty=format:%h`\])/" < $(srcdir)/version.m4.orig > $(srcdir)/version.m4 @GIT_CHECKOUT_TRUE@ $(MAKE) rpms @GIT_CHECKOUT_TRUE@ mv $(srcdir)/version.m4.orig $(srcdir)/version.m4 # make srpms will use the old digest algorithm to be compatible # with RHEL5 srpm: rpmbrprep cd $(RPMBUILD); \ rpmbuild --define "_topdir $(RPMBUILD)" \ -bs SPECS/sssd.spec @GIT_CHECKOUT_TRUE@prerelease-srpm: @GIT_CHECKOUT_TRUE@ cp $(srcdir)/version.m4 $(srcdir)/version.m4.orig @GIT_CHECKOUT_TRUE@ sed -e "s/m4_define(\[PRERELEASE_VERSION_NUMBER\], \[.*\])/m4_define(\[PRERELEASE_VERSION_NUMBER\], \[.`date +%Y%m%d.%H%M`.git`git log -1 --pretty=format:%h`\])/" < $(srcdir)/version.m4.orig > $(srcdir)/version.m4 @GIT_CHECKOUT_TRUE@ $(MAKE) srpm @GIT_CHECKOUT_TRUE@ mv $(srcdir)/version.m4.orig $(srcdir)/version.m4 # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: sssd-1.13.4/PaxHeaders.16287/config.h.in0000644000000000000000000000007412703463541014355 xustar0030 atime=1460561772.871787583 30 ctime=1460561774.611793483 sssd-1.13.4/config.h.in0000644002412700241270000004531012703463541016027 0ustar00jhrozekjhrozek00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Absolute path to the build directory */ #undef ABS_BUILD_DIR /* Absolute path to the source directory */ #undef ABS_SRC_DIR /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* "The default enforcing level for AD GPO access-control" */ #undef AD_GPO_ACCESS_MODE_DEFAULT /* Path to the 3rd party modules */ #undef APP_MODULES_PATH /* whether to build with AUTOFS support */ #undef BUILD_AUTOFS /* whether to build with InfoPipe support */ #undef BUILD_IFP /* whether to build SSSD implementation of libwbclient */ #undef BUILD_LIBWBCLIENT /* whether to build with NFSv4 IDMAP support */ #undef BUILD_NFS_IDMAP /* whether to build with samba support */ #undef BUILD_SAMBA /* whether to build with SSH support */ #undef BUILD_SSH /* whether to build with SUDO support */ #undef BUILD_SUDO /* Path to the SSSD data provider plugins */ #undef DATA_PROVIDER_PLUGINS_PATH /* Path to the SSSD databases */ #undef DB_PATH /* The default value of krb5_ccachedir */ #undef DEFAULT_CCACHE_DIR /* The default value of krb5_ccname_template */ #undef DEFAULT_CCNAME_TEMPLATE /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS /* Where to store GPO policy files */ #undef GPO_CACHE_PATH /* Define to 1 if you have the header file. */ #undef HAVE_ARES_H /* whether platform is big endian */ #undef HAVE_BIG_ENDIAN /* Define to 1 if you have the header file. */ #undef HAVE_BYTESWAP_H /* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework. */ #undef HAVE_CFLOCALECOPYCURRENT /* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework. */ #undef HAVE_CFPREFERENCESCOPYAPPVALUE /* Define to 1 if you have the header file. */ #undef HAVE_CHECK_H /* Build with cifs idmap plugin */ #undef HAVE_CIFS_IDMAP_PLUGIN /* Build with internal config library */ #undef HAVE_CONFIG_LIB /* Define to 1 if the system has the type `DBusBasicValue'. */ #undef HAVE_DBUSBASICVALUE /* Define if dbus_watch_get_unix_fd exists */ #undef HAVE_DBUS_WATCH_GET_UNIX_FD /* Define if the GNU dcgettext() function is already present or preinstalled. */ #undef HAVE_DCGETTEXT /* Define to 1 if you have the declaration of `cygwin_conv_path', and to 0 if you don't. */ #undef HAVE_DECL_CYGWIN_CONV_PATH /* Define if you have the GNU dld library. */ #undef HAVE_DLD /* Define to 1 if you have the `dlerror' function. */ #undef HAVE_DLERROR /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define if you have the _dyld_func_lookup function. */ #undef HAVE_DYLD /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H /* Define to 1 if the system has the type `errno_t'. */ #undef HAVE_ERRNO_T /* whether compiler supports __attribute__((destructor)) */ #undef HAVE_FUNCTION_ATTRIBUTE_DESTRUCTOR /* whether compiler supports __attribute__((format)) */ #undef HAVE_FUNCTION_ATTRIBUTE_FORMAT /* whether compiler supports __attribute__((warn_unused_result)) */ #undef HAVE_FUNCTION_ATTRIBUTE_WARN_UNUSED_RESULT /* Define to 1 if you have the `futimens' function. */ #undef HAVE_FUTIMENS /* Define to 1 if you have the `getpgrp' function. */ #undef HAVE_GETPGRP /* Define if the GNU gettext() function is already present or preinstalled. */ #undef HAVE_GETTEXT /* Using glib2 for unicode */ #undef HAVE_GLIB2 /* Define if g_utf8_validate exists */ #undef HAVE_G_UTF8_VALIDATE /* Define if you have the iconv() function. */ #undef HAVE_ICONV /* Inotify works */ #undef HAVE_INOTIFY /* Define to 1 if the system has the type `intptr_t'. */ #undef HAVE_INTPTR_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_KEYUTILS_H /* Define to 1 if you have the `krb5_cc_cache_match' function. */ #undef HAVE_KRB5_CC_CACHE_MATCH /* Define to 1 if you have the `krb5_cc_get_full_name' function. */ #undef HAVE_KRB5_CC_GET_FULL_NAME /* Define to 1 if you have the `krb5_find_authdata' function. */ #undef HAVE_KRB5_FIND_AUTHDATA /* Define to 1 if you have the `krb5_free_keytab_entry_contents' function. */ #undef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS /* Define to 1 if you have the `krb5_free_unparsed_name' function. */ #undef HAVE_KRB5_FREE_UNPARSED_NAME /* Define to 1 if you have the `krb5_get_error_message' function. */ #undef HAVE_KRB5_GET_ERROR_MESSAGE /* Define to 1 if you have the `krb5_get_init_creds_opt_alloc' function. */ #undef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC /* Define to 1 if you have the `krb5_get_init_creds_opt_set_canonicalize' function. */ #undef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CANONICALIZE /* Define to 1 if you have the `krb5_get_init_creds_opt_set_change_password_prompt' function. */ #undef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT /* Define to 1 if you have the `krb5_get_init_creds_opt_set_expire_callback' function. */ #undef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_EXPIRE_CALLBACK /* Define to 1 if you have the `krb5_get_init_creds_opt_set_fast_ccache_name' function. */ #undef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_FAST_CCACHE_NAME /* Define to 1 if you have the `krb5_get_init_creds_opt_set_fast_flags' function. */ #undef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_FAST_FLAGS /* Define to 1 if you have the `krb5_get_init_creds_opt_set_responder' function. */ #undef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_RESPONDER /* Define to 1 if you have the `krb5_get_time_offsets' function. */ #undef HAVE_KRB5_GET_TIME_OFFSETS /* Define to 1 if you have the header file. */ #undef HAVE_KRB5_H /* Define to 1 if you have the header file. */ #undef HAVE_KRB5_KRB5_H /* Define to 1 if you have the `krb5_kt_free_entry' function. */ #undef HAVE_KRB5_KT_FREE_ENTRY /* Define to 1 if you have the `krb5_kt_have_content' function. */ #undef HAVE_KRB5_KT_HAVE_CONTENT /* Build with krb5 localauth plugin */ #undef HAVE_KRB5_LOCALAUTH_PLUGIN /* Build with krb5 locator plugin */ #undef HAVE_KRB5_LOCATOR_PLUGIN /* Define to 1 if you have the `krb5_parse_name_flags' function. */ #undef HAVE_KRB5_PARSE_NAME_FLAGS /* Define to 1 if you have the `krb5_principal_get_realm' function. */ #undef HAVE_KRB5_PRINCIPAL_GET_REALM /* Define to 1 if you have the `krb5_princ_realm' function. */ #undef HAVE_KRB5_PRINC_REALM /* Define to 1 if you have the `krb5_set_trace_callback' function. */ #undef HAVE_KRB5_SET_TRACE_CALLBACK /* Define to 1 if the system has the type `krb5_ticket_times'. */ #undef HAVE_KRB5_TICKET_TIMES /* Define to 1 if the system has the type `krb5_times'. */ #undef HAVE_KRB5_TIMES /* Define to 1 if you have the `krb5_timestamp_to_sfstring' function. */ #undef HAVE_KRB5_TIMESTAMP_TO_SFSTRING /* Define to 1 if the system has the type `krb5_trace_info'. */ #undef HAVE_KRB5_TRACE_INFO /* Define to 1 if you have the `krb5_unparse_name_flags' function. */ #undef HAVE_KRB5_UNPARSE_NAME_FLAGS /* Define if LDAP connection callbacks are available */ #undef HAVE_LDAP_CONNCB /* Define to 1 if you have the `ldap_control_create' function. */ #undef HAVE_LDAP_CONTROL_CREATE /* Define to 1 if you have the `ldap_create_deref_control_value' function. */ #undef HAVE_LDAP_CREATE_DEREF_CONTROL_VALUE /* Define to 1 if you have the `ldap_derefresponse_free' function. */ #undef HAVE_LDAP_DEREFRESPONSE_FREE /* Define to 1 if you have the `ldap_init_fd' function. */ #undef HAVE_LDAP_INIT_FD /* Define to 1 if you have the `ldap_parse_derefresponse_control' function. */ #undef HAVE_LDAP_PARSE_DEREFRESPONSE_CONTROL /* Define to 1 if you have the header file. */ #undef HAVE_LDB_H /* Define to 1 if you have the header file. */ #undef HAVE_LDB_MODULE_H /* Build with libcrypt crypto back end */ #undef HAVE_LIBCRYPTO /* Define if you have the libdl library or equivalent. */ #undef HAVE_LIBDL /* Define if libdlloader will be built on this platform */ #undef HAVE_LIBDLLOADER /* libini_config version 0.6.1 or greater */ #undef HAVE_LIBINI_CONFIG_V0 /* libini_config version 1.0.0 or greater */ #undef HAVE_LIBINI_CONFIG_V1 /* libini_config version 1.1.0 or greater */ #undef HAVE_LIBINI_CONFIG_V1_1 /* Build with libnetlink support */ #undef HAVE_LIBNL /* Libnetlink version = 1 */ #undef HAVE_LIBNL1 /* Libnetlink version = 3 */ #undef HAVE_LIBNL3 /* Define if libpcre version is less than 7 */ #undef HAVE_LIBPCRE_LESSER_THAN_7 /* Using libunistring for unicode */ #undef HAVE_LIBUNISTRING /* whether platform is little endian */ #undef HAVE_LITTLE_ENDIAN /* Define to 1 if the system has the type `long long'. */ #undef HAVE_LONG_LONG /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_NETLINK_H /* Does libnl have nl_set_passcred? */ #undef HAVE_NL_SET_PASSCRED /* Does libnl have nl_socket_add_membership? */ #undef HAVE_NL_SOCKET_ADD_MEMBERSHIP /* Does libnl have nl_socket_modify_cb? */ #undef HAVE_NL_SOCKET_MODIFY_CB /* Does libnl have nl_socket_set_passcred? */ #undef HAVE_NL_SOCKET_SET_PASSCRED /* flush nscd cache after local domain operations */ #undef HAVE_NSCD /* Build with NSS crypto back end */ #undef HAVE_NSS /* Whether to use the 'realm' directive with nsupdate */ #undef HAVE_NSUPDATE_REALM /* Build with the PAC responder */ #undef HAVE_PAC_RESPONDER /* Define to 1 if you have the `pam_modutil_getlogin' function. */ #undef HAVE_PAM_MODUTIL_GETLOGIN /* Define to 1 if you have the `pam_vsyslog' function. */ #undef HAVE_PAM_VSYSLOG /* Define to 1 if you have the header file. */ #undef HAVE_PCRE_H /* Define to 1 if you have the header file. */ #undef HAVE_POPT_H /* Define to 1 if you have the `prctl' function. */ #undef HAVE_PRCTL /* Pthread mutexes available. */ #undef HAVE_PTHREAD /* Define to 1 if you have the `pthread_mutexattr_setrobust' function. */ #undef HAVE_PTHREAD_MUTEXATTR_SETROBUST /* Define to 1 if you have the `pthread_mutexattr_setrobust_np' function. */ #undef HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP /* Define to 1 if you have the `pthread_mutex_consistent' function. */ #undef HAVE_PTHREAD_MUTEX_CONSISTENT /* Define to 1 if you have the `pthread_mutex_consistent_np' function. */ #undef HAVE_PTHREAD_MUTEX_CONSISTENT_NP /* Define to 1 if you have the `PyErr_NewExceptionWithDoc' function. */ #undef HAVE_PYERR_NEWEXCEPTIONWITHDOC /* Build with python2 bindings */ #undef HAVE_PYTHON2_BINDINGS /* Build with python3 bindings */ #undef HAVE_PYTHON3_BINDINGS /* Does libnl have rtnl_route_get_oif? */ #undef HAVE_RTNL_ROUTE_GET_OIF /* Define to 1 if you have the header file. */ #undef HAVE_SASL_SASL_H /* Define to 1 if you have the header file. */ #undef HAVE_SECURITY_OPENPAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SECURITY_PAM_APPL_H /* Define to 1 if you have the header file. */ #undef HAVE_SECURITY_PAM_EXT_H /* Define to 1 if you have the header file. */ #undef HAVE_SECURITY_PAM_MISC_H /* Define to 1 if you have the header file. */ #undef HAVE_SECURITY_PAM_MODULES_H /* Define to 1 if you have the header file. */ #undef HAVE_SECURITY_PAM_MODUTIL_H /* Define to 1 if you have the header file. */ #undef HAVE_SECURITY__PAM_MACROS_H /* Build with SELinux support */ #undef HAVE_SELINUX /* The directory to store SELinux user login is available */ #undef HAVE_SELINUX_LOGIN_DIR /* Define to 1 if you have the header file. */ #undef HAVE_SELINUX_SELINUX_H /* Build with SELinux support */ #undef HAVE_SEMANAGE /* Define to 1 if you have the header file. */ #undef HAVE_SEMANAGE_SEMANAGE_H /* Define to 1 if you have the header file. */ #undef HAVE_SETJMP_H /* Define if you have the shl_load function. */ #undef HAVE_SHL_LOAD /* Define to 1 if you have the `sigaction' function. */ #undef HAVE_SIGACTION /* Define to 1 if you have the `sigblock' function. */ #undef HAVE_SIGBLOCK /* Define to 1 if you have the `sigprocmask' function. */ #undef HAVE_SIGPROCMASK /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if `lc_arg' is a member of `struct ldap_conncb'. */ #undef HAVE_STRUCT_LDAP_CONNCB_LC_ARG /* Define to 1 if `gid' is a member of `struct ucred'. */ #undef HAVE_STRUCT_UCRED_GID /* Define to 1 if `pid' is a member of `struct ucred'. */ #undef HAVE_STRUCT_UCRED_PID /* Define to 1 if `uid' is a member of `struct ucred'. */ #undef HAVE_STRUCT_UCRED_UID /* Build with libsystemdlogin support */ #undef HAVE_SYSTEMD_LOGIN /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ENDIAN_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_INOTIFY_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_TDB_H /* Define if struct ucred is available */ #undef HAVE_UCRED /* Define to 1 if you have the header file. */ #undef HAVE_UNICASE_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTR_H /* Define to 1 if you have the `utimensat' function. */ #undef HAVE_UTIMENSAT /* The path to the ipa-getkeytab utility */ #undef IPA_GETKEYTAB_PATH /* KRB5 configuration file */ #undef KRB5_CONF_PATH /* Directory used for storing Kerberos replay caches */ #undef KRB5_RCACHE_DIR /* Where to store log files for the SSSD */ #undef LOG_PATH /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Where to store mmap cache files for the SSSD interconnects */ #undef MCACHE_PATH /* The shell used to deny access to users */ #undef NOLOGIN_SHELL /* whether to build sssd nss plugin with nonstandard glibc behaviour */ #undef NONSTANDARD_SSS_NSS_BEHAVIOUR /* NSCD configuration file */ #undef NSCD_CONF_PATH /* The path to nscd, if available */ #undef NSCD_PATH /* The path to nsupdate */ #undef NSUPDATE_PATH /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Where to store pid files for the SSSD */ #undef PID_PATH /* Where to store pipe files for the SSSD interconnects */ #undef PIPE_PATH /* Prerelease version number of package */ #undef PRERELEASE_VERSION /* Where to store pubconf files for the SSSD */ #undef PUBCONF_PATH /* The size of `char', as computed by sizeof. */ #undef SIZEOF_CHAR /* The size of `gid_t', as computed by sizeof. */ #undef SIZEOF_GID_T /* The size of `id_t', as computed by sizeof. */ #undef SIZEOF_ID_T /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG /* The size of `long long', as computed by sizeof. */ #undef SIZEOF_LONG_LONG /* The size of `off_t', as computed by sizeof. */ #undef SIZEOF_OFF_T /* The size of `short', as computed by sizeof. */ #undef SIZEOF_SHORT /* The size of `size_t', as computed by sizeof. */ #undef SIZEOF_SIZE_T /* The size of `ssize_t', as computed by sizeof. */ #undef SIZEOF_SSIZE_T /* The size of `uid_t', as computed by sizeof. */ #undef SIZEOF_UID_T /* "The default user to run SSSD as" */ #undef SSSD_USER /* Define to 1 if you want ldb version check. */ #undef SSS_LDB_VERSION_CHECK /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Directory used for 'make check' temporary files */ #undef TEST_DIR /* Define if the keyring should be used */ #undef USE_KEYRING /* Enable extensions on AIX 3, Interix. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif /* Enable threading extensions on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif /* Enable general extensions on Solaris. */ #ifndef __EXTENSIONS__ # undef __EXTENSIONS__ #endif /* Version number of package */ #undef VERSION /* journald is available */ #undef WITH_JOURNALD /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Define to 1 if on MINIX. */ #undef _MINIX /* Define to 2 if the system does not provide POSIX.1 features except with this defined. */ #undef _POSIX_1_SOURCE /* Define to 1 if you need to in order for `stat' and other things to work. */ #undef _POSIX_SOURCE /* Define to `short' if does not define. */ #undef int16_t /* Define to `long' if does not define. */ #undef int32_t /* Define to `long long' if does not define. */ #undef int64_t /* Define to `char' if does not define. */ #undef int8_t /* Define to `long long' if does not define. */ #undef intptr_t /* Define to `unsigned long long' if does not define. */ #undef ptrdiff_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to `int' if does not define. */ #undef ssize_t /* Define to `unsigned short' if does not define. */ #undef uint16_t /* Define to `unsigned long' if does not define. */ #undef uint32_t /* Define to `unsigned long long' if does not define. */ #undef uint64_t /* Define to `unsigned char' if does not define. */ #undef uint8_t /* Define to `unsigned int' if does not define. */ #undef uint_t /* Define to `unsigned long long' if does not define. */ #undef uintptr_t sssd-1.13.4/PaxHeaders.16287/aclocal.m40000644000000000000000000000013212703463540014164 xustar0030 mtime=1460561760.333745069 30 atime=1460561760.426745385 30 ctime=1460561774.332792537 sssd-1.13.4/aclocal.m40000644002412700241270000023511212703463540015644 0ustar00jhrozekjhrozek00000000000000# generated automatically by aclocal 1.15 -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*- # # Copyright (C) 1999-2006, 2007, 2008, 2011 Free Software Foundation, Inc. # Written by Thomas Tanner, 1999 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 18 LTDL_INIT # LT_CONFIG_LTDL_DIR(DIRECTORY, [LTDL-MODE]) # ------------------------------------------ # DIRECTORY contains the libltdl sources. It is okay to call this # function multiple times, as long as the same DIRECTORY is always given. AC_DEFUN([LT_CONFIG_LTDL_DIR], [AC_BEFORE([$0], [LTDL_INIT]) _$0($*) ])# LT_CONFIG_LTDL_DIR # We break this out into a separate macro, so that we can call it safely # internally without being caught accidentally by the sed scan in libtoolize. m4_defun([_LT_CONFIG_LTDL_DIR], [dnl remove trailing slashes m4_pushdef([_ARG_DIR], m4_bpatsubst([$1], [/*$])) m4_case(_LTDL_DIR, [], [dnl only set lt_ltdl_dir if _ARG_DIR is not simply `.' m4_if(_ARG_DIR, [.], [], [m4_define([_LTDL_DIR], _ARG_DIR) _LT_SHELL_INIT([lt_ltdl_dir=']_ARG_DIR['])])], [m4_if(_ARG_DIR, _LTDL_DIR, [], [m4_fatal([multiple libltdl directories: `]_LTDL_DIR[', `]_ARG_DIR['])])]) m4_popdef([_ARG_DIR]) ])# _LT_CONFIG_LTDL_DIR # Initialise: m4_define([_LTDL_DIR], []) # _LT_BUILD_PREFIX # ---------------- # If Autoconf is new enough, expand to `${top_build_prefix}', otherwise # to `${top_builddir}/'. m4_define([_LT_BUILD_PREFIX], [m4_ifdef([AC_AUTOCONF_VERSION], [m4_if(m4_version_compare(m4_defn([AC_AUTOCONF_VERSION]), [2.62]), [-1], [m4_ifdef([_AC_HAVE_TOP_BUILD_PREFIX], [${top_build_prefix}], [${top_builddir}/])], [${top_build_prefix}])], [${top_builddir}/])[]dnl ]) # LTDL_CONVENIENCE # ---------------- # sets LIBLTDL to the link flags for the libltdl convenience library and # LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-convenience to the configure arguments. Note that # AC_CONFIG_SUBDIRS is not called here. LIBLTDL will be prefixed with # '${top_build_prefix}' if available, otherwise with '${top_builddir}/', # and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single # quotes!). If your package is not flat and you're not using automake, # define top_build_prefix, top_builddir, and top_srcdir appropriately # in your Makefiles. AC_DEFUN([LTDL_CONVENIENCE], [AC_BEFORE([$0], [LTDL_INIT])dnl dnl Although the argument is deprecated and no longer documented, dnl LTDL_CONVENIENCE used to take a DIRECTORY orgument, if we have one dnl here make sure it is the same as any other declaration of libltdl's dnl location! This also ensures lt_ltdl_dir is set when configure.ac is dnl not yet using an explicit LT_CONFIG_LTDL_DIR. m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl _$0() ])# LTDL_CONVENIENCE # AC_LIBLTDL_CONVENIENCE accepted a directory argument in older libtools, # now we have LT_CONFIG_LTDL_DIR: AU_DEFUN([AC_LIBLTDL_CONVENIENCE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_CONVENIENCE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBLTDL_CONVENIENCE], []) # _LTDL_CONVENIENCE # ----------------- # Code shared by LTDL_CONVENIENCE and LTDL_INIT([convenience]). m4_defun([_LTDL_CONVENIENCE], [case $enable_ltdl_convenience in no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; "") enable_ltdl_convenience=yes ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; esac LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdlc.la" LTDLDEPS=$LIBLTDL LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}" AC_SUBST([LIBLTDL]) AC_SUBST([LTDLDEPS]) AC_SUBST([LTDLINCL]) # For backwards non-gettext consistent compatibility... INCLTDL="$LTDLINCL" AC_SUBST([INCLTDL]) ])# _LTDL_CONVENIENCE # LTDL_INSTALLABLE # ---------------- # sets LIBLTDL to the link flags for the libltdl installable library # and LTDLINCL to the include flags for the libltdl header and adds # --enable-ltdl-install to the configure arguments. Note that # AC_CONFIG_SUBDIRS is not called from here. If an installed libltdl # is not found, LIBLTDL will be prefixed with '${top_build_prefix}' if # available, otherwise with '${top_builddir}/', and LTDLINCL will be # prefixed with '${top_srcdir}/' (note the single quotes!). If your # package is not flat and you're not using automake, define top_build_prefix, # top_builddir, and top_srcdir appropriately in your Makefiles. # In the future, this macro may have to be called after LT_INIT. AC_DEFUN([LTDL_INSTALLABLE], [AC_BEFORE([$0], [LTDL_INIT])dnl dnl Although the argument is deprecated and no longer documented, dnl LTDL_INSTALLABLE used to take a DIRECTORY orgument, if we have one dnl here make sure it is the same as any other declaration of libltdl's dnl location! This also ensures lt_ltdl_dir is set when configure.ac is dnl not yet using an explicit LT_CONFIG_LTDL_DIR. m4_ifval([$1], [_LT_CONFIG_LTDL_DIR([$1])])dnl _$0() ])# LTDL_INSTALLABLE # AC_LIBLTDL_INSTALLABLE accepted a directory argument in older libtools, # now we have LT_CONFIG_LTDL_DIR: AU_DEFUN([AC_LIBLTDL_INSTALLABLE], [_LT_CONFIG_LTDL_DIR([m4_default([$1], [libltdl])]) _LTDL_INSTALLABLE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBLTDL_INSTALLABLE], []) # _LTDL_INSTALLABLE # ----------------- # Code shared by LTDL_INSTALLABLE and LTDL_INIT([installable]). m4_defun([_LTDL_INSTALLABLE], [if test -f $prefix/lib/libltdl.la; then lt_save_LDFLAGS="$LDFLAGS" LDFLAGS="-L$prefix/lib $LDFLAGS" AC_CHECK_LIB([ltdl], [lt_dlinit], [lt_lib_ltdl=yes]) LDFLAGS="$lt_save_LDFLAGS" if test x"${lt_lib_ltdl-no}" = xyes; then if test x"$enable_ltdl_install" != xyes; then # Don't overwrite $prefix/lib/libltdl.la without --enable-ltdl-install AC_MSG_WARN([not overwriting libltdl at $prefix, force with `--enable-ltdl-install']) enable_ltdl_install=no fi elif test x"$enable_ltdl_install" = xno; then AC_MSG_WARN([libltdl not installed, but installation disabled]) fi fi # If configure.ac declared an installable ltdl, and the user didn't override # with --disable-ltdl-install, we will install the shipped libltdl. case $enable_ltdl_install in no) ac_configure_args="$ac_configure_args --enable-ltdl-install=no" LIBLTDL="-lltdl" LTDLDEPS= LTDLINCL= ;; *) enable_ltdl_install=yes ac_configure_args="$ac_configure_args --enable-ltdl-install" LIBLTDL='_LT_BUILD_PREFIX'"${lt_ltdl_dir+$lt_ltdl_dir/}libltdl.la" LTDLDEPS=$LIBLTDL LTDLINCL='-I${top_srcdir}'"${lt_ltdl_dir+/$lt_ltdl_dir}" ;; esac AC_SUBST([LIBLTDL]) AC_SUBST([LTDLDEPS]) AC_SUBST([LTDLINCL]) # For backwards non-gettext consistent compatibility... INCLTDL="$LTDLINCL" AC_SUBST([INCLTDL]) ])# LTDL_INSTALLABLE # _LTDL_MODE_DISPATCH # ------------------- m4_define([_LTDL_MODE_DISPATCH], [dnl If _LTDL_DIR is `.', then we are configuring libltdl itself: m4_if(_LTDL_DIR, [], [], dnl if _LTDL_MODE was not set already, the default value is `subproject': [m4_case(m4_default(_LTDL_MODE, [subproject]), [subproject], [AC_CONFIG_SUBDIRS(_LTDL_DIR) _LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"])], [nonrecursive], [_LT_SHELL_INIT([lt_dlopen_dir="$lt_ltdl_dir"; lt_libobj_prefix="$lt_ltdl_dir/"])], [recursive], [], [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])])dnl dnl Be careful not to expand twice: m4_define([$0], []) ])# _LTDL_MODE_DISPATCH # _LT_LIBOBJ(MODULE_NAME) # ----------------------- # Like AC_LIBOBJ, except that MODULE_NAME goes into _LT_LIBOBJS instead # of into LIBOBJS. AC_DEFUN([_LT_LIBOBJ], [ m4_pattern_allow([^_LT_LIBOBJS$]) _LT_LIBOBJS="$_LT_LIBOBJS $1.$ac_objext" ])# _LT_LIBOBJS # LTDL_INIT([OPTIONS]) # -------------------- # Clients of libltdl can use this macro to allow the installer to # choose between a shipped copy of the ltdl sources or a preinstalled # version of the library. If the shipped ltdl sources are not in a # subdirectory named libltdl, the directory name must be given by # LT_CONFIG_LTDL_DIR. AC_DEFUN([LTDL_INIT], [dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) dnl We need to keep our own list of libobjs separate from our parent project, dnl and the easiest way to do that is redefine the AC_LIBOBJs macro while dnl we look for our own LIBOBJs. m4_pushdef([AC_LIBOBJ], m4_defn([_LT_LIBOBJ])) m4_pushdef([AC_LIBSOURCES]) dnl If not otherwise defined, default to the 1.5.x compatible subproject mode: m4_if(_LTDL_MODE, [], [m4_define([_LTDL_MODE], m4_default([$2], [subproject])) m4_if([-1], [m4_bregexp(_LTDL_MODE, [\(subproject\|\(non\)?recursive\)])], [m4_fatal([unknown libltdl mode: ]_LTDL_MODE)])]) AC_ARG_WITH([included_ltdl], [AS_HELP_STRING([--with-included-ltdl], [use the GNU ltdl sources included here])]) if test "x$with_included_ltdl" != xyes; then # We are not being forced to use the included libltdl sources, so # decide whether there is a useful installed version we can use. AC_CHECK_HEADER([ltdl.h], [AC_CHECK_DECL([lt_dlinterface_register], [AC_CHECK_LIB([ltdl], [lt_dladvise_preload], [with_included_ltdl=no], [with_included_ltdl=yes])], [with_included_ltdl=yes], [AC_INCLUDES_DEFAULT #include ])], [with_included_ltdl=yes], [AC_INCLUDES_DEFAULT] ) fi dnl If neither LT_CONFIG_LTDL_DIR, LTDL_CONVENIENCE nor LTDL_INSTALLABLE dnl was called yet, then for old times' sake, we assume libltdl is in an dnl eponymous directory: AC_PROVIDE_IFELSE([LT_CONFIG_LTDL_DIR], [], [_LT_CONFIG_LTDL_DIR([libltdl])]) AC_ARG_WITH([ltdl_include], [AS_HELP_STRING([--with-ltdl-include=DIR], [use the ltdl headers installed in DIR])]) if test -n "$with_ltdl_include"; then if test -f "$with_ltdl_include/ltdl.h"; then : else AC_MSG_ERROR([invalid ltdl include directory: `$with_ltdl_include']) fi else with_ltdl_include=no fi AC_ARG_WITH([ltdl_lib], [AS_HELP_STRING([--with-ltdl-lib=DIR], [use the libltdl.la installed in DIR])]) if test -n "$with_ltdl_lib"; then if test -f "$with_ltdl_lib/libltdl.la"; then : else AC_MSG_ERROR([invalid ltdl library directory: `$with_ltdl_lib']) fi else with_ltdl_lib=no fi case ,$with_included_ltdl,$with_ltdl_include,$with_ltdl_lib, in ,yes,no,no,) m4_case(m4_default(_LTDL_TYPE, [convenience]), [convenience], [_LTDL_CONVENIENCE], [installable], [_LTDL_INSTALLABLE], [m4_fatal([unknown libltdl build type: ]_LTDL_TYPE)]) ;; ,no,no,no,) # If the included ltdl is not to be used, then use the # preinstalled libltdl we found. AC_DEFINE([HAVE_LTDL], [1], [Define this if a modern libltdl is already installed]) LIBLTDL=-lltdl LTDLDEPS= LTDLINCL= ;; ,no*,no,*) AC_MSG_ERROR([`--with-ltdl-include' and `--with-ltdl-lib' options must be used together]) ;; *) with_included_ltdl=no LIBLTDL="-L$with_ltdl_lib -lltdl" LTDLDEPS= LTDLINCL="-I$with_ltdl_include" ;; esac INCLTDL="$LTDLINCL" # Report our decision... AC_MSG_CHECKING([where to find libltdl headers]) AC_MSG_RESULT([$LTDLINCL]) AC_MSG_CHECKING([where to find libltdl library]) AC_MSG_RESULT([$LIBLTDL]) _LTDL_SETUP dnl restore autoconf definition. m4_popdef([AC_LIBOBJ]) m4_popdef([AC_LIBSOURCES]) AC_CONFIG_COMMANDS_PRE([ _ltdl_libobjs= _ltdl_ltlibobjs= if test -n "$_LT_LIBOBJS"; then # Remove the extension. _lt_sed_drop_objext='s/\.o$//;s/\.obj$//' for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do _ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext" _ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo" done fi AC_SUBST([ltdl_LIBOBJS], [$_ltdl_libobjs]) AC_SUBST([ltdl_LTLIBOBJS], [$_ltdl_ltlibobjs]) ]) # Only expand once: m4_define([LTDL_INIT]) ])# LTDL_INIT # Old names: AU_DEFUN([AC_LIB_LTDL], [LTDL_INIT($@)]) AU_DEFUN([AC_WITH_LTDL], [LTDL_INIT($@)]) AU_DEFUN([LT_WITH_LTDL], [LTDL_INIT($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIB_LTDL], []) dnl AC_DEFUN([AC_WITH_LTDL], []) dnl AC_DEFUN([LT_WITH_LTDL], []) # _LTDL_SETUP # ----------- # Perform all the checks necessary for compilation of the ltdl objects # -- including compiler checks and header checks. This is a public # interface mainly for the benefit of libltdl's own configure.ac, most # other users should call LTDL_INIT instead. AC_DEFUN([_LTDL_SETUP], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_SYS_MODULE_EXT])dnl AC_REQUIRE([LT_SYS_MODULE_PATH])dnl AC_REQUIRE([LT_SYS_DLSEARCH_PATH])dnl AC_REQUIRE([LT_LIB_DLLOAD])dnl AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl AC_REQUIRE([LT_FUNC_DLSYM_USCORE])dnl AC_REQUIRE([LT_SYS_DLOPEN_DEPLIBS])dnl AC_REQUIRE([gl_FUNC_ARGZ])dnl m4_require([_LT_CHECK_OBJDIR])dnl m4_require([_LT_HEADER_DLFCN])dnl m4_require([_LT_CHECK_DLPREOPEN])dnl m4_require([_LT_DECL_SED])dnl dnl Don't require this, or it will be expanded earlier than the code dnl that sets the variables it relies on: _LT_ENABLE_INSTALL dnl _LTDL_MODE specific code must be called at least once: _LTDL_MODE_DISPATCH # In order that ltdl.c can compile, find out the first AC_CONFIG_HEADERS # the user used. This is so that ltdl.h can pick up the parent projects # config.h file, The first file in AC_CONFIG_HEADERS must contain the # definitions required by ltdl.c. # FIXME: Remove use of undocumented AC_LIST_HEADERS (2.59 compatibility). AC_CONFIG_COMMANDS_PRE([dnl m4_pattern_allow([^LT_CONFIG_H$])dnl m4_ifset([AH_HEADER], [LT_CONFIG_H=AH_HEADER], [m4_ifset([AC_LIST_HEADERS], [LT_CONFIG_H=`echo "AC_LIST_HEADERS" | $SED 's,^[[ ]]*,,;s,[[ :]].*$,,'`], [])])]) AC_SUBST([LT_CONFIG_H]) AC_CHECK_HEADERS([unistd.h dl.h sys/dl.h dld.h mach-o/dyld.h dirent.h], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_FUNCS([closedir opendir readdir], [], [AC_LIBOBJ([lt__dirent])]) AC_CHECK_FUNCS([strlcat strlcpy], [], [AC_LIBOBJ([lt__strl])]) m4_pattern_allow([LT_LIBEXT])dnl AC_DEFINE_UNQUOTED([LT_LIBEXT],["$libext"],[The archive extension]) name= eval "lt_libprefix=\"$libname_spec\"" m4_pattern_allow([LT_LIBPREFIX])dnl AC_DEFINE_UNQUOTED([LT_LIBPREFIX],["$lt_libprefix"],[The archive prefix]) name=ltdl eval "LTDLOPEN=\"$libname_spec\"" AC_SUBST([LTDLOPEN]) ])# _LTDL_SETUP # _LT_ENABLE_INSTALL # ------------------ m4_define([_LT_ENABLE_INSTALL], [AC_ARG_ENABLE([ltdl-install], [AS_HELP_STRING([--enable-ltdl-install], [install libltdl])]) case ,${enable_ltdl_install},${enable_ltdl_convenience} in *yes*) ;; *) enable_ltdl_convenience=yes ;; esac m4_ifdef([AM_CONDITIONAL], [AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno) AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno)]) ])# _LT_ENABLE_INSTALL # LT_SYS_DLOPEN_DEPLIBS # --------------------- AC_DEFUN([LT_SYS_DLOPEN_DEPLIBS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_CACHE_CHECK([whether deplibs are loaded by dlopen], [lt_cv_sys_dlopen_deplibs], [# PORTME does your system automatically load deplibs for dlopen? # or its logical equivalent (e.g. shl_load for HP-UX < 11) # For now, we just catch OSes we know something about -- in the # future, we'll try test this programmatically. lt_cv_sys_dlopen_deplibs=unknown case $host_os in aix3*|aix4.1.*|aix4.2.*) # Unknown whether this is true for these versions of AIX, but # we want this `case' here to explicitly catch those versions. lt_cv_sys_dlopen_deplibs=unknown ;; aix[[4-9]]*) lt_cv_sys_dlopen_deplibs=yes ;; amigaos*) case $host_cpu in powerpc) lt_cv_sys_dlopen_deplibs=no ;; esac ;; darwin*) # Assuming the user has installed a libdl from somewhere, this is true # If you are looking for one http://www.opendarwin.org/projects/dlcompat lt_cv_sys_dlopen_deplibs=yes ;; freebsd* | dragonfly*) lt_cv_sys_dlopen_deplibs=yes ;; gnu* | linux* | k*bsd*-gnu | kopensolaris*-gnu) # GNU and its variants, using gnu ld.so (Glibc) lt_cv_sys_dlopen_deplibs=yes ;; hpux10*|hpux11*) lt_cv_sys_dlopen_deplibs=yes ;; interix*) lt_cv_sys_dlopen_deplibs=yes ;; irix[[12345]]*|irix6.[[01]]*) # Catch all versions of IRIX before 6.2, and indicate that we don't # know how it worked for any of those versions. lt_cv_sys_dlopen_deplibs=unknown ;; irix*) # The case above catches anything before 6.2, and it's known that # at 6.2 and later dlopen does load deplibs. lt_cv_sys_dlopen_deplibs=yes ;; netbsd*) lt_cv_sys_dlopen_deplibs=yes ;; openbsd*) lt_cv_sys_dlopen_deplibs=yes ;; osf[[1234]]*) # dlopen did load deplibs (at least at 4.x), but until the 5.x series, # it did *not* use an RPATH in a shared library to find objects the # library depends on, so we explicitly say `no'. lt_cv_sys_dlopen_deplibs=no ;; osf5.0|osf5.0a|osf5.1) # dlopen *does* load deplibs and with the right loader patch applied # it even uses RPATH in a shared library to search for shared objects # that the library depends on, but there's no easy way to know if that # patch is installed. Since this is the case, all we can really # say is unknown -- it depends on the patch being installed. If # it is, this changes to `yes'. Without it, it would be `no'. lt_cv_sys_dlopen_deplibs=unknown ;; osf*) # the two cases above should catch all versions of osf <= 5.1. Read # the comments above for what we know about them. # At > 5.1, deplibs are loaded *and* any RPATH in a shared library # is used to find them so we can finally say `yes'. lt_cv_sys_dlopen_deplibs=yes ;; qnx*) lt_cv_sys_dlopen_deplibs=yes ;; solaris*) lt_cv_sys_dlopen_deplibs=yes ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) libltdl_cv_sys_dlopen_deplibs=yes ;; esac ]) if test "$lt_cv_sys_dlopen_deplibs" != yes; then AC_DEFINE([LTDL_DLOPEN_DEPLIBS], [1], [Define if the OS needs help to load dependent libraries for dlopen().]) fi ])# LT_SYS_DLOPEN_DEPLIBS # Old name: AU_ALIAS([AC_LTDL_SYS_DLOPEN_DEPLIBS], [LT_SYS_DLOPEN_DEPLIBS]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYS_DLOPEN_DEPLIBS], []) # LT_SYS_MODULE_EXT # ----------------- AC_DEFUN([LT_SYS_MODULE_EXT], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([which extension is used for runtime loadable modules], [libltdl_cv_shlibext], [ module=yes eval libltdl_cv_shlibext=$shrext_cmds module=no eval libltdl_cv_shrext=$shrext_cmds ]) if test -n "$libltdl_cv_shlibext"; then m4_pattern_allow([LT_MODULE_EXT])dnl AC_DEFINE_UNQUOTED([LT_MODULE_EXT], ["$libltdl_cv_shlibext"], [Define to the extension used for runtime loadable modules, say, ".so".]) fi if test "$libltdl_cv_shrext" != "$libltdl_cv_shlibext"; then m4_pattern_allow([LT_SHARED_EXT])dnl AC_DEFINE_UNQUOTED([LT_SHARED_EXT], ["$libltdl_cv_shrext"], [Define to the shared library suffix, say, ".dylib".]) fi ])# LT_SYS_MODULE_EXT # Old name: AU_ALIAS([AC_LTDL_SHLIBEXT], [LT_SYS_MODULE_EXT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SHLIBEXT], []) # LT_SYS_MODULE_PATH # ------------------ AC_DEFUN([LT_SYS_MODULE_PATH], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([which variable specifies run-time module search path], [lt_cv_module_path_var], [lt_cv_module_path_var="$shlibpath_var"]) if test -n "$lt_cv_module_path_var"; then m4_pattern_allow([LT_MODULE_PATH_VAR])dnl AC_DEFINE_UNQUOTED([LT_MODULE_PATH_VAR], ["$lt_cv_module_path_var"], [Define to the name of the environment variable that determines the run-time module search path.]) fi ])# LT_SYS_MODULE_PATH # Old name: AU_ALIAS([AC_LTDL_SHLIBPATH], [LT_SYS_MODULE_PATH]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SHLIBPATH], []) # LT_SYS_DLSEARCH_PATH # -------------------- AC_DEFUN([LT_SYS_DLSEARCH_PATH], [m4_require([_LT_SYS_DYNAMIC_LINKER])dnl AC_CACHE_CHECK([for the default library search path], [lt_cv_sys_dlsearch_path], [lt_cv_sys_dlsearch_path="$sys_lib_dlsearch_path_spec"]) if test -n "$lt_cv_sys_dlsearch_path"; then sys_dlsearch_path= for dir in $lt_cv_sys_dlsearch_path; do if test -z "$sys_dlsearch_path"; then sys_dlsearch_path="$dir" else sys_dlsearch_path="$sys_dlsearch_path$PATH_SEPARATOR$dir" fi done m4_pattern_allow([LT_DLSEARCH_PATH])dnl AC_DEFINE_UNQUOTED([LT_DLSEARCH_PATH], ["$sys_dlsearch_path"], [Define to the system default library search path.]) fi ])# LT_SYS_DLSEARCH_PATH # Old name: AU_ALIAS([AC_LTDL_SYSSEARCHPATH], [LT_SYS_DLSEARCH_PATH]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYSSEARCHPATH], []) # _LT_CHECK_DLPREOPEN # ------------------- m4_defun([_LT_CHECK_DLPREOPEN], [m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen], [libltdl_cv_preloaded_symbols], [if test -n "$lt_cv_sys_global_symbol_pipe"; then libltdl_cv_preloaded_symbols=yes else libltdl_cv_preloaded_symbols=no fi ]) if test x"$libltdl_cv_preloaded_symbols" = xyes; then AC_DEFINE([HAVE_PRELOADED_SYMBOLS], [1], [Define if libtool can extract symbol lists from object files.]) fi ])# _LT_CHECK_DLPREOPEN # LT_LIB_DLLOAD # ------------- AC_DEFUN([LT_LIB_DLLOAD], [m4_pattern_allow([^LT_DLLOADERS$]) LT_DLLOADERS= AC_SUBST([LT_DLLOADERS]) AC_LANG_PUSH([C]) LIBADD_DLOPEN= AC_SEARCH_LIBS([dlopen], [dl], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) if test "$ac_cv_search_dlopen" != "none required" ; then LIBADD_DLOPEN="-ldl" fi libltdl_cv_lib_dl_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if HAVE_DLFCN_H # include #endif ]], [[dlopen(0, 0);]])], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"], [AC_CHECK_LIB([svld], [dlopen], [AC_DEFINE([HAVE_LIBDL], [1], [Define if you have the libdl library or equivalent.]) LIBADD_DLOPEN="-lsvld" libltdl_cv_func_dlopen="yes" LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dlopen.la"])])]) if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes then lt_save_LIBS="$LIBS" LIBS="$LIBS $LIBADD_DLOPEN" AC_CHECK_FUNCS([dlerror]) LIBS="$lt_save_LIBS" fi AC_SUBST([LIBADD_DLOPEN]) LIBADD_SHL_LOAD= AC_CHECK_FUNC([shl_load], [AC_DEFINE([HAVE_SHL_LOAD], [1], [Define if you have the shl_load function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la"], [AC_CHECK_LIB([dld], [shl_load], [AC_DEFINE([HAVE_SHL_LOAD], [1], [Define if you have the shl_load function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}shl_load.la" LIBADD_SHL_LOAD="-ldld"])]) AC_SUBST([LIBADD_SHL_LOAD]) case $host_os in darwin[[1567]].*) # We only want this for pre-Mac OS X 10.4. AC_CHECK_FUNC([_dyld_func_lookup], [AC_DEFINE([HAVE_DYLD], [1], [Define if you have the _dyld_func_lookup function.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dyld.la"]) ;; beos*) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}load_add_on.la" ;; cygwin* | mingw* | os2* | pw32*) AC_CHECK_DECLS([cygwin_conv_path], [], [], [[#include ]]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}loadlibrary.la" ;; esac AC_CHECK_LIB([dld], [dld_link], [AC_DEFINE([HAVE_DLD], [1], [Define if you have the GNU dld library.]) LT_DLLOADERS="$LT_DLLOADERS ${lt_dlopen_dir+$lt_dlopen_dir/}dld_link.la"]) AC_SUBST([LIBADD_DLD_LINK]) m4_pattern_allow([^LT_DLPREOPEN$]) LT_DLPREOPEN= if test -n "$LT_DLLOADERS" then for lt_loader in $LT_DLLOADERS; do LT_DLPREOPEN="$LT_DLPREOPEN-dlpreopen $lt_loader " done AC_DEFINE([HAVE_LIBDLLOADER], [1], [Define if libdlloader will be built on this platform]) fi AC_SUBST([LT_DLPREOPEN]) dnl This isn't used anymore, but set it for backwards compatibility LIBADD_DL="$LIBADD_DLOPEN $LIBADD_SHL_LOAD" AC_SUBST([LIBADD_DL]) AC_LANG_POP ])# LT_LIB_DLLOAD # Old name: AU_ALIAS([AC_LTDL_DLLIB], [LT_LIB_DLLOAD]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_DLLIB], []) # LT_SYS_SYMBOL_USCORE # -------------------- # does the compiler prefix global symbols with an underscore? AC_DEFUN([LT_SYS_SYMBOL_USCORE], [m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl AC_CACHE_CHECK([for _ prefix in compiled symbols], [lt_cv_sys_symbol_underscore], [lt_cv_sys_symbol_underscore=no cat > conftest.$ac_ext <<_LT_EOF void nm_test_func(){} int main(){nm_test_func;return 0;} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. ac_nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then # See whether the symbols have a leading underscore. if grep '^. _nm_test_func' "$ac_nlist" >/dev/null; then lt_cv_sys_symbol_underscore=yes else if grep '^. nm_test_func ' "$ac_nlist" >/dev/null; then : else echo "configure: cannot find nm_test_func in $ac_nlist" >&AS_MESSAGE_LOG_FD fi fi else echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "configure: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.c >&AS_MESSAGE_LOG_FD fi rm -rf conftest* ]) sys_symbol_underscore=$lt_cv_sys_symbol_underscore AC_SUBST([sys_symbol_underscore]) ])# LT_SYS_SYMBOL_USCORE # Old name: AU_ALIAS([AC_LTDL_SYMBOL_USCORE], [LT_SYS_SYMBOL_USCORE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_SYMBOL_USCORE], []) # LT_FUNC_DLSYM_USCORE # -------------------- AC_DEFUN([LT_FUNC_DLSYM_USCORE], [AC_REQUIRE([LT_SYS_SYMBOL_USCORE])dnl if test x"$lt_cv_sys_symbol_underscore" = xyes; then if test x"$libltdl_cv_func_dlopen" = xyes || test x"$libltdl_cv_lib_dl_dlopen" = xyes ; then AC_CACHE_CHECK([whether we have to add an underscore for dlsym], [libltdl_cv_need_uscore], [libltdl_cv_need_uscore=unknown save_LIBS="$LIBS" LIBS="$LIBS $LIBADD_DLOPEN" _LT_TRY_DLOPEN_SELF( [libltdl_cv_need_uscore=no], [libltdl_cv_need_uscore=yes], [], [libltdl_cv_need_uscore=cross]) LIBS="$save_LIBS" ]) fi fi if test x"$libltdl_cv_need_uscore" = xyes; then AC_DEFINE([NEED_USCORE], [1], [Define if dlsym() requires a leading underscore in symbol names.]) fi ])# LT_FUNC_DLSYM_USCORE # Old name: AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], []) # Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PATH_PYTHON([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # --------------------------------------------------------------------------- # Adds support for distributing Python modules and packages. To # install modules, copy them to $(pythondir), using the python_PYTHON # automake variable. To install a package with the same name as the # automake package, install to $(pkgpythondir), or use the # pkgpython_PYTHON automake variable. # # The variables $(pyexecdir) and $(pkgpyexecdir) are provided as # locations to install python extension modules (shared libraries). # Another macro is required to find the appropriate flags to compile # extension modules. # # If your package is configured with a different prefix to python, # users will have to add the install directory to the PYTHONPATH # environment variable, or create a .pth file (see the python # documentation for details). # # If the MINIMUM-VERSION argument is passed, AM_PATH_PYTHON will # cause an error if the version of python installed on the system # doesn't meet the requirement. MINIMUM-VERSION should consist of # numbers and dots only. AC_DEFUN([AM_PATH_PYTHON], [ dnl Find a Python interpreter. Python versions prior to 2.0 are not dnl supported. (2.0 was released on October 16, 2000). m4_define_default([_AM_PYTHON_INTERPRETER_LIST], [python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 dnl python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0]) AC_ARG_VAR([PYTHON], [the Python interpreter]) m4_if([$1],[],[ dnl No version check is needed. # Find any Python interpreter. if test -z "$PYTHON"; then AC_PATH_PROGS([PYTHON], _AM_PYTHON_INTERPRETER_LIST, :) fi am_display_PYTHON=python ], [ dnl A version check is needed. if test -n "$PYTHON"; then # If the user set $PYTHON, use it and don't search something else. AC_MSG_CHECKING([whether $PYTHON version is >= $1]) AM_PYTHON_CHECK_VERSION([$PYTHON], [$1], [AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no]) AC_MSG_ERROR([Python interpreter is too old])]) am_display_PYTHON=$PYTHON else # Otherwise, try each interpreter until we find one that satisfies # VERSION. AC_CACHE_CHECK([for a Python interpreter with version >= $1], [am_cv_pathless_PYTHON],[ for am_cv_pathless_PYTHON in _AM_PYTHON_INTERPRETER_LIST none; do test "$am_cv_pathless_PYTHON" = none && break AM_PYTHON_CHECK_VERSION([$am_cv_pathless_PYTHON], [$1], [break]) done]) # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. if test "$am_cv_pathless_PYTHON" = none; then PYTHON=: else AC_PATH_PROG([PYTHON], [$am_cv_pathless_PYTHON]) fi am_display_PYTHON=$am_cv_pathless_PYTHON fi ]) if test "$PYTHON" = :; then dnl Run any user-specified action, or abort. m4_default([$3], [AC_MSG_ERROR([no suitable Python interpreter found])]) else dnl Query Python for its version number. Getting [:3] seems to be dnl the best way to do this; it's what "site.py" does in the standard dnl library. AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], [am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[[:3]])"`]) AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) dnl Use the values of $prefix and $exec_prefix for the corresponding dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made dnl distinct variables so they can be overridden if need be. However, dnl general consensus is that you shouldn't need this ability. AC_SUBST([PYTHON_PREFIX], ['${prefix}']) AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}']) dnl At times (like when building shared libraries) you may want dnl to know which OS platform Python thinks this is. AC_CACHE_CHECK([for $am_display_PYTHON platform], [am_cv_python_platform], [am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"`]) AC_SUBST([PYTHON_PLATFORM], [$am_cv_python_platform]) # Just factor out some code duplication. am_python_setup_sysconfig="\ import sys # Prefer sysconfig over distutils.sysconfig, for better compatibility # with python 3.x. See automake bug#10227. try: import sysconfig except ImportError: can_use_sysconfig = 0 else: can_use_sysconfig = 1 # Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: # try: from platform import python_implementation if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7': can_use_sysconfig = 0 except ImportError: pass" dnl Set up 4 directories: dnl pythondir -- where to install python scripts. This is the dnl site-packages directory, not the python standard library dnl directory like in previous automake betas. This behavior dnl is more consistent with lispdir.m4 for example. dnl Query distutils for this directory. AC_CACHE_CHECK([for $am_display_PYTHON script directory], [am_cv_python_pythondir], [if test "x$prefix" = xNONE then am_py_prefix=$ac_default_prefix else am_py_prefix=$prefix fi am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` case $am_cv_python_pythondir in $am_py_prefix*) am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` ;; *) case $am_py_prefix in /usr|/System*) ;; *) am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac ]) AC_SUBST([pythondir], [$am_cv_python_pythondir]) dnl pkgpythondir -- $PACKAGE directory under pythondir. Was dnl PYTHON_SITE_PACKAGE in previous betas, but this naming is dnl more consistent with the rest of automake. AC_SUBST([pkgpythondir], [\${pythondir}/$PACKAGE]) dnl pyexecdir -- directory for installing python extension modules dnl (shared libraries) dnl Query distutils for this directory. AC_CACHE_CHECK([for $am_display_PYTHON extension module directory], [am_cv_python_pyexecdir], [if test "x$exec_prefix" = xNONE then am_py_exec_prefix=$am_py_prefix else am_py_exec_prefix=$exec_prefix fi am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') sys.stdout.write(sitedir)"` case $am_cv_python_pyexecdir in $am_py_exec_prefix*) am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` ;; *) case $am_py_exec_prefix in /usr|/System*) ;; *) am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages ;; esac ;; esac ]) AC_SUBST([pyexecdir], [$am_cv_python_pyexecdir]) dnl pkgpyexecdir -- $(pyexecdir)/$(PACKAGE) AC_SUBST([pkgpyexecdir], [\${pyexecdir}/$PACKAGE]) dnl Run any user-specified action. $2 fi ]) # AM_PYTHON_CHECK_VERSION(PROG, VERSION, [ACTION-IF-TRUE], [ACTION-IF-FALSE]) # --------------------------------------------------------------------------- # Run ACTION-IF-TRUE if the Python interpreter PROG has version >= VERSION. # Run ACTION-IF-FALSE otherwise. # This test uses sys.hexversion instead of the string equivalent (first # word of sys.version), in order to cope with versions such as 2.2c1. # This supports Python 2.0 or higher. (2.0 was released on October 16, 2000). AC_DEFUN([AM_PYTHON_CHECK_VERSION], [prog="import sys # split strings by '.' and convert to numeric. Append some zeros # because we need at least 4 digits for the hex conversion. # map returns an iterator in Python 3.0 and a list in 2.x minver = list(map(int, '$2'.split('.'))) + [[0, 0, 0]] minverhex = 0 # xrange is not present in Python 3.0 and range returns an iterator for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]] sys.exit(sys.hexversion < minverhex)" AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/gettext.m4]) m4_include([m4/iconv.m4]) m4_include([m4/lib-ld.m4]) m4_include([m4/lib-link.m4]) m4_include([m4/lib-prefix.m4]) m4_include([m4/libtool.m4]) m4_include([m4/ltoptions.m4]) m4_include([m4/ltsugar.m4]) m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/nls.m4]) m4_include([m4/po.m4]) m4_include([m4/progtest.m4]) sssd-1.13.4/PaxHeaders.16287/configure.ac0000644000000000000000000000007412703456111014613 xustar0030 atime=1460561751.857716329 30 ctime=1460561774.332792537 sssd-1.13.4/configure.ac0000644002412700241270000003542712703456111016275 0ustar00jhrozekjhrozek00000000000000AC_PREREQ(2.59) m4_include([version.m4]) AC_INIT([sssd], VERSION_NUMBER, [sssd-devel@lists.fedorahosted.org]) AC_CONFIG_SRCDIR([BUILD.txt]) AC_CONFIG_AUX_DIR([build]) m4_ifdef([AC_USE_SYSTEM_EXTENSIONS], [AC_USE_SYSTEM_EXTENSIONS], [AC_GNU_SOURCE]) CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE" AM_INIT_AUTOMAKE([-Wall -Wno-portability foreign subdir-objects tar-pax parallel-tests]) AM_PROG_CC_C_O m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_DISABLE_STATIC AC_PROG_INSTALL LT_INIT m4_ifdef([AC_PROG_MKDIR_P], [AC_PROG_MKDIR_P], [AC_SUBST([MKDIR_P], "mkdir -p")]) LT_LIB_DLLOAD AC_CONFIG_MACRO_DIR([m4]) AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION([0.14.4]) AC_SUBST([PRERELEASE_VERSION], PRERELEASE_VERSION_NUMBER) AC_DEFINE([PRERELEASE_VERSION], "PRERELEASE_VERSION_NUMBER", [Prerelease version number of package]) AM_CONDITIONAL([GIT_CHECKOUT], [git log -1 >/dev/null 2>&1]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES]) AM_CONDITIONAL([HAVE_GCC], [test "$ac_cv_prog_gcc" = yes]) AC_CHECK_HEADERS(stdint.h dlfcn.h) AC_CONFIG_HEADER(config.h) AC_CHECK_TYPES([errno_t], [], [], [[#include ]]) m4_include([src/build_macros.m4]) BUILD_WITH_SHARED_BUILD_DIR AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([[#include ]], [[pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; (void) m; /* unused */ ]])], [AC_DEFINE([HAVE_PTHREAD], [1], [Pthread mutexes available.]) HAVE_PTHREAD=1 ], [AC_MSG_WARN([Pthread library not found! Clients will not be thread safe...])]) AM_CONDITIONAL([HAVE_PTHREAD], [test x"$HAVE_PTHREAD" != "x"]) SAVE_LIBS=$LIBS LIBS="$LIBS -lpthread" AC_CHECK_FUNCS([ pthread_mutexattr_setrobust \ pthread_mutex_consistent \ pthread_mutexattr_setrobust_np \ pthread_mutex_consistent_np ]) LIBS=$SAVE_LIBS # Check for presence of modern functions for setting file timestamps AC_CHECK_FUNCS([ utimensat \ futimens ]) #Check for endian headers AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h]) AC_C_BIGENDIAN([AC_DEFINE(HAVE_BIG_ENDIAN, [1], [whether platform is big endian])], [AC_DEFINE(HAVE_LITTLE_ENDIAN, [1], [whether platform is little endian])]) #Set the NSS library install path AC_ARG_ENABLE([nsslibdir], [AS_HELP_STRING([--enable-nsslibdir], [Where to install nss libraries ($libdir)])], [nsslibdir=$enableval], [nsslibdir=$libdir]) AC_SUBST(nsslibdir) #Set the PAM module install path AC_ARG_ENABLE([pammoddir], [AS_HELP_STRING([--enable-pammoddir], [Where to install pam modules ($libdir/security)])], [pammoddir=$enableval], [pammoddir=$libdir/security]) AC_SUBST(pammoddir) #Set the NFSv4 idmapd library install path AC_ARG_ENABLE([nfsidmaplibdir], [AS_HELP_STRING([--enable-nfsidmaplibdir], [Where to install libnfsidmap libraries ($libdir/libnfsidmap)])], [nfsidmaplibdir=$enableval], [nfsidmaplibdir=$libdir/libnfsidmap]) AC_SUBST(nfsidmaplibdir) #Include here cause WITH_INIT_DIR requires $osname set in platform.m4 m4_include([src/external/platform.m4]) m4_include(src/conf_macros.m4) WITH_DB_PATH WITH_PLUGIN_PATH WITH_PID_PATH WITH_LOG_PATH WITH_PUBCONF_PATH WITH_PIPE_PATH WITH_MCACHE_PATH WITH_DEFAULT_CCACHE_DIR WITH_DEFAULT_CCNAME_TEMPLATE WITH_ENVIRONMENT_FILE WITH_INIT_DIR WITH_TEST_DIR WITH_MANPAGES WITH_XML_CATALOG WITH_KRB5_PLUGIN_PATH WITH_KRB5_RCACHE_DIR WITH_KRB5AUTHDATA_PLUGIN_PATH WITH_KRB5_CONF WITH_PYTHON2_BINDINGS WITH_PYTHON3_BINDINGS WITH_CIFS_PLUGIN_PATH WITH_SELINUX WITH_NSCD WITH_IPA_GETKEYTAB WITH_SEMANAGE WITH_AD_GPO_DEFAULT WITH_GPO_CACHE_PATH WITH_NOLOGIN_SHELL WITH_APP_LIBS WITH_SUDO WITH_SUDO_LIB_PATH WITH_AUTOFS WITH_SSH WITH_IFP WITH_CRYPTO WITH_SYSLOG WITH_SAMBA WITH_NFS WITH_NFS_LIB_PATH WITH_LIBWBCLIENT WITH_SSSD_USER m4_include([src/external/pkg.m4]) m4_include([src/external/libpopt.m4]) m4_include([src/external/libtalloc.m4]) m4_include([src/external/libtdb.m4]) m4_include([src/external/libtevent.m4]) m4_include([src/external/libldb.m4]) m4_include([src/external/libdhash.m4]) m4_include([src/external/libcollection.m4]) m4_include([src/external/libini_config.m4]) m4_include([src/external/pam.m4]) m4_include([src/external/ldap.m4]) m4_include([src/external/libpcre.m4]) m4_include([src/external/krb5.m4]) m4_include([src/external/libcares.m4]) m4_include([src/external/libcmocka.m4]) m4_include([src/external/docbook.m4]) m4_include([src/external/sizes.m4]) m4_include([src/external/python.m4]) m4_include([src/external/selinux.m4]) m4_include([src/external/crypto.m4]) m4_include([src/external/nscd.m4]) m4_include([src/external/nsupdate.m4]) m4_include([src/external/libkeyutils.m4]) m4_include([src/external/libnl.m4]) m4_include([src/external/systemd.m4]) m4_include([src/external/pac_responder.m4]) m4_include([src/external/cifsidmap.m4]) m4_include([src/external/signal.m4]) m4_include([src/external/inotify.m4]) m4_include([src/external/samba.m4]) m4_include([src/external/sasl.m4]) m4_include([src/external/configlib.m4]) m4_include([src/external/libnfsidmap.m4]) m4_include([src/external/cwrap.m4]) m4_include([src/external/libresolv.m4]) m4_include([src/external/intgcheck.m4]) if test x$build_config_lib = xyes; then m4_include([src/external/libaugeas.m4]) fi WITH_UNICODE_LIB if test x$unicode_lib = xlibunistring; then m4_include([src/external/libunistring.m4]) AC_DEFINE_UNQUOTED(HAVE_LIBUNISTRING, 1, [Using libunistring for unicode]) UNICODE_LIBS=$UNISTRING_LIBS else m4_include([src/external/glib.m4]) AC_DEFINE_UNQUOTED(HAVE_GLIB2, 1, [Using glib2 for unicode]) UNICODE_LIBS=$GLIB2_LIBS fi AC_SUBST(UNICODE_LIBS) WITH_LIBNL if test x$HAVE_NSCD; then WITH_NSCD_CONF fi WITH_INITSCRIPT if test x$initscript = xsystemd; then WITH_SYSTEMD_UNIT_DIR WITH_SYSTEMD_CONF_DIR fi PKG_CHECK_MODULES([DBUS],[dbus-1]) dnl if test -n "`$PKG_CONFIG --modversion dbus-1 | grep '^0\.'`" ; then if ! $PKG_CONFIG --atleast-version 1.0.0 dbus-1; then DBUS_CFLAGS="$DBUS_CFLAGS -DDBUS_API_SUBJECT_TO_CHANGE" AC_MSG_RESULT([setting -DDBUS_API_SUBJECT_TO_CHANGE]) fi if test x$has_dbus != xno; then SAFE_LIBS="$LIBS" LIBS="$DBUS_LIBS" SAFE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS $DBUS_CFLAGS" AC_CHECK_FUNC([dbus_watch_get_unix_fd], AC_DEFINE([HAVE_DBUS_WATCH_GET_UNIX_FD], [1], [Define if dbus_watch_get_unix_fd exists])) AC_CHECK_TYPES([DBusBasicValue], [], [], [ #include ]) LIBS="$SAFE_LIBS" CFLAGS=$SAFE_CFLAGS fi # work around a bug in cov-build from Coverity test -n "$XML_CATALOG_FILES" || unset XML_CATALOG_FILES if test x$HAVE_MANPAGES != x; then CHECK_XML_TOOLS DOCBOOK_XSLT=http://docbook.sourceforge.net/release/xsl/current/manpages/profile-docbook.xsl CHECK_STYLESHEET([$SGML_CATALOG_FILES], [$DOCBOOK_XSLT], [Docbook XSL profiling templates], [HAVE_PROFILE_CATALOGS=1], [AC_MSG_WARN([Man pages might contain documentation for experimental features])]) if test x$HAVE_PROFILE_CATALOGS = x; then DOCBOOK_XSLT=http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl CHECK_STYLESHEET([$SGML_CATALOG_FILES], [$DOCBOOK_XSLT], [Docbook XSL templates], [], [AC_MSG_ERROR([could not find the docbook xsl catalog])]) fi AC_CHECK_PROG([PO4A],[po4a],[po4a],[no]) AC_SUBST(DOCBOOK_XSLT) fi AM_CONDITIONAL([HAVE_PROFILE_CATALOGS], [test "x$HAVE_PROFILE_CATALOGS" != "x"]) AM_CONDITIONAL([HAVE_MANPAGES], [test "x$HAVE_MANPAGES" != "x"]) AM_CONDITIONAL([HAVE_PO4A], [test "x$PO4A" != "xno"]) AC_CHECK_PROG(HAVE_PYTHON2, python2, yes, no) AS_IF([test x$HAVE_PYTHON2 = xyes], [AC_PATH_PROG(PYTHON2, python2)]) AC_CHECK_PROG(HAVE_PYTHON3, python3, yes, no) AS_IF([test x$HAVE_PYTHON3 = xyes], [AC_PATH_PROG(PYTHON3, python3)]) if test x$HAVE_PYTHON2_BINDINGS = x1; then AS_IF([test x$HAVE_PYTHON2 != xyes], [AC_MSG_ERROR([ The program python2 was not found in search path. Please ensure that it is installed and its directory is included in the search path. It is required for building python2 bindings. If you do not want to build them please use argument --without-python2-bindings when running configure.])]) PYTHON=$PYTHON2 AM_PATH_PYTHON([2.6]) AM_PYTHON_CONFIG([python2]) AM_CHECK_PYTHON_HEADERS([], AC_MSG_ERROR([Could not find python2 headers])) AM_CHECK_PYTHON_COMPAT AC_SUBST([py2execdir], [$pyexecdir]) AC_SUBST([python2dir], [$pythondir]) AC_SUBST([PYTHON2_CFLAGS], [$PYTHON_CFLAGS]) AC_SUBST([PYTHON2_LIBS], [$PYTHON_LIBS]) AC_SUBST([PYTHON2_INCLUDES], [$PYTHON_INCLUDES]) AC_SUBST([PYTHON2_VERSION], [$PYTHON_VERSION]) AC_SUBST([PYTHON2_PREFIX], [$PYTHON_PREFIX]) AC_SUBST([PYTHON2_EXEC_PREFIX], [$PYTHON_EXEC_PREFIX]) SSS_CLEAN_PYTHON_VARIABLES fi if test x$HAVE_PYTHON3_BINDINGS = x1; then AS_IF([test x$HAVE_PYTHON3 != xyes], [AC_MSG_ERROR([ The program python3 was not found in search path. Please ensure that it is installed and its directory is included in the search path. It is required for building python3 bindings. If you do not want to build them please use argument --without-python3-bindings when running configure.])]) PYTHON=$PYTHON3 AM_PATH_PYTHON([3.3]) AM_PYTHON_CONFIG([python3]) AM_CHECK_PYTHON_HEADERS([], AC_MSG_ERROR([Could not find python3 headers])) AM_CHECK_PYTHON_COMPAT AC_SUBST([py3execdir], [$pyexecdir]) AC_SUBST([python3dir], [$pythondir]) AC_SUBST([PYTHON3_CFLAGS], [$PYTHON_CFLAGS]) AC_SUBST([PYTHON3_LIBS], [$PYTHON_LIBS]) AC_SUBST([PYTHON3_INCLUDES], [$PYTHON_INCLUDES]) AC_SUBST([PYTHON3_VERSION], [$PYTHON_VERSION]) AC_SUBST([PYTHON3_PREFIX], [$PYTHON_PREFIX]) AC_SUBST([PYTHON3_EXEC_PREFIX], [$PYTHON_EXEC_PREFIX]) SSS_CLEAN_PYTHON_VARIABLES fi AM_CONDITIONAL([BUILD_PYTHON_BINDINGS], [test x"$with_python2_bindings" = xyes \ -o x"$with_python3_bindings" = xyes]) AM_PYTHON2_MODULE([ldap]) if test x$HAVE_SELINUX != x; then AM_CHECK_SELINUX AM_CHECK_SELINUX_LOGIN_DIR fi if test x$HAVE_SEMANAGE != x -a x$HAVE_SELINUX != x; then AM_CHECK_SEMANAGE fi if test x$HAVE_SYSTEMD_UNIT != x; then AM_CHECK_SYSTEMD fi dnl If journald was selected for logging, configure journald if test x$syslog = xjournald; then AM_CHECK_JOURNALD fi if test x$cryptolib = xnss; then AM_CHECK_NSS fi if test x$cryptolib = xlibcrypto; then AM_CHECK_LIBCRYPTO fi AM_CHECK_INOTIFY AC_CACHE_CHECK([whether compiler supports __attribute__((destructor))], sss_client_cv_attribute_destructor, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE([__attribute__((destructor)) static void cleanup(void) { }])], sss_client_cv_attribute_destructor=yes) ]) if test x"$sss_client_cv_attribute_destructor" = xyes ; then AC_DEFINE(HAVE_FUNCTION_ATTRIBUTE_DESTRUCTOR, 1, [whether compiler supports __attribute__((destructor))]) fi AC_CACHE_CHECK([whether compiler supports __attribute__((format))], sss_cv_attribute_format, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [void debug_fn(const char *format, ...) __attribute__ ((format (printf, 1, 2)));] )], [sss_cv_attribute_format=yes], [ AC_MSG_RESULT([no]) AC_MSG_WARN([compiler does NOT support __attribute__((format))]) ]) ]) if test x"$sss_cv_attribute_format" = xyes ; then AC_DEFINE(HAVE_FUNCTION_ATTRIBUTE_FORMAT, 1, [whether compiler supports __attribute__((format))]) fi AC_CACHE_CHECK([whether compiler supports __attribute__((warn_unused_result))], sss_cv_attribute_warn_unused_result, [AC_COMPILE_IFELSE( [AC_LANG_SOURCE( [ char _check_leaks(int bytes) __attribute__ ((warn_unused_result)); ] )], [sss_cv_attribute_warn_unused_result=yes], [ AC_MSG_RESULT([no]) AC_MSG_WARN([compiler does NOT support __attribute__((warn_unused_result))]) ]) ]) if test x"$sss_cv_attribute_warn_unused_result" = xyes ; then AC_DEFINE(HAVE_FUNCTION_ATTRIBUTE_WARN_UNUSED_RESULT, 1, [whether compiler supports __attribute__((warn_unused_result))]) fi PKG_CHECK_MODULES([CHECK], [check >= 0.9.5], [have_check=1], [have_check=]) if test x$have_check = x; then AC_MSG_WARN([Without the 'CHECK' libraries, you will be unable to run all tests in the 'make check' suite]) else AC_CHECK_HEADERS([check.h],,AC_MSG_ERROR([Could not find CHECK headers])) fi AC_PATH_PROG([DOXYGEN], [doxygen], [false]) AM_CONDITIONAL([HAVE_DOXYGEN], [test x$DOXYGEN != xfalse ]) AM_CONDITIONAL([HAVE_CHECK], [test x$have_check != x]) AM_CHECK_CMOCKA AM_CHECK_UID_WRAPPER AM_CHECK_NSS_WRAPPER SSS_ENABLE_INTGCHECK_REQS AM_CONDITIONAL([HAVE_DEVSHM], [test -d /dev/shm]) # Check if we should install polkit rules ENABLE_POLKIT_RULES_PATH AM_CONDITIONAL([HAVE_POLKIT_RULES_D], [test x$HAVE_POLKIT_RULES_D != x]) abs_build_dir=`pwd` AC_DEFINE_UNQUOTED([ABS_BUILD_DIR], ["$abs_build_dir"], [Absolute path to the build directory]) AC_SUBST([abs_builddir], $abs_build_dir) my_srcdir=`readlink -f $srcdir` AC_DEFINE_UNQUOTED([ABS_SRC_DIR], ["$my_srcdir"], [Absolute path to the source directory]) AC_CONFIG_FILES([Makefile contrib/sssd.spec src/examples/rwtab src/doxy.config contrib/sssd-pcsc.rules src/sysv/sssd src/sysv/gentoo/sssd src/sysv/SUSE/sssd po/Makefile.in src/man/Makefile src/tests/cwrap/Makefile src/tests/intg/Makefile src/providers/ipa/ipa_hbac.pc src/providers/ipa/ipa_hbac.doxy src/lib/idmap/sss_idmap.pc src/lib/idmap/sss_idmap.doxy src/sss_client/sudo/sss_sudo.doxy src/sss_client/idmap/sss_nss_idmap.pc src/sss_client/idmap/sss_nss_idmap.doxy src/sss_client/libwbclient/wbclient_sssd.pc src/lib/sifp/sss_simpleifp.pc src/lib/sifp/sss_simpleifp.doxy src/config/setup.py src/responder/ifp/org.freedesktop.sssd.infopipe.service src/config/SSSDConfig/__init__.py]) AC_OUTPUT sssd-1.13.4/PaxHeaders.16287/src0000644000000000000000000000013212703463557013046 xustar0030 mtime=1460561775.924797935 30 atime=1460561776.117798589 30 ctime=1460561775.924797935 sssd-1.13.4/src/0000755002412700241270000000000012703463557014577 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/PaxHeaders.16287/sss_client0000644000000000000000000000013212703463556015213 xustar0030 mtime=1460561774.955794649 30 atime=1460561776.117798589 30 ctime=1460561774.955794649 sssd-1.13.4/src/sss_client/0000755002412700241270000000000012703463556016744 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sss_client/PaxHeaders.16287/libwbclient0000644000000000000000000000013212703463556017511 xustar0030 mtime=1460561774.894794443 30 atime=1460561776.117798589 30 ctime=1460561774.894794443 sssd-1.13.4/src/sss_client/libwbclient/0000755002412700241270000000000012703463556021242 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbclient_common.c0000644000000000000000000000007412703456111023103 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.887794419 sssd-1.13.4/src/sss_client/libwbclient/wbclient_common.c0000644002412700241270000001061112703456111024551 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API Copyright (C) Gerald (Jerry) Carter 2007 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include "libwbclient.h" /** @brief Translate an error value into a string * * @param error * * @return a pointer to a static string **/ const char *wbcErrorString(wbcErr error) { switch (error) { case WBC_ERR_SUCCESS: return "WBC_ERR_SUCCESS"; case WBC_ERR_NOT_IMPLEMENTED: return "WBC_ERR_NOT_IMPLEMENTED"; case WBC_ERR_UNKNOWN_FAILURE: return "WBC_ERR_UNKNOWN_FAILURE"; case WBC_ERR_NO_MEMORY: return "WBC_ERR_NO_MEMORY"; case WBC_ERR_INVALID_SID: return "WBC_ERR_INVALID_SID"; case WBC_ERR_INVALID_PARAM: return "WBC_ERR_INVALID_PARAM"; case WBC_ERR_WINBIND_NOT_AVAILABLE: return "WBC_ERR_WINBIND_NOT_AVAILABLE"; case WBC_ERR_DOMAIN_NOT_FOUND: return "WBC_ERR_DOMAIN_NOT_FOUND"; case WBC_ERR_INVALID_RESPONSE: return "WBC_ERR_INVALID_RESPONSE"; case WBC_ERR_NSS_ERROR: return "WBC_ERR_NSS_ERROR"; case WBC_ERR_UNKNOWN_USER: return "WBC_ERR_UNKNOWN_USER"; case WBC_ERR_UNKNOWN_GROUP: return "WBC_ERR_UNKNOWN_GROUP"; case WBC_ERR_AUTH_ERROR: return "WBC_ERR_AUTH_ERROR"; case WBC_ERR_PWD_CHANGE_FAILED: return "WBC_ERR_PWD_CHANGE_FAILED"; } return "unknown wbcErr value"; } #define WBC_MAGIC (0x7a2b0e1e) #define WBC_MAGIC_FREE (0x875634fe) struct wbcMemPrefix { uint32_t magic; void (*destructor)(void *ptr); }; static size_t wbcPrefixLen(void) { size_t result = sizeof(struct wbcMemPrefix); return (result + 15) & ~15; } static struct wbcMemPrefix *wbcMemToPrefix(void *ptr) { return (struct wbcMemPrefix *)((void *)(((char *)ptr) - wbcPrefixLen())); } void *wbcAllocateMemory(size_t nelem, size_t elsize, void (*destructor)(void *ptr)) { struct wbcMemPrefix *result; if (nelem >= (2<<24)/elsize) { /* basic protection against integer wrap */ return NULL; } result = (struct wbcMemPrefix *)calloc( 1, nelem*elsize + wbcPrefixLen()); if (result == NULL) { return NULL; } result->magic = WBC_MAGIC; result->destructor = destructor; return ((char *)result) + wbcPrefixLen(); } /* Free library allocated memory */ void wbcFreeMemory(void *p) { struct wbcMemPrefix *wbcMem; if (p == NULL) { return; } wbcMem = wbcMemToPrefix(p); if (wbcMem->magic != WBC_MAGIC) { return; } /* paranoid check to ensure we don't double free */ wbcMem->magic = WBC_MAGIC_FREE; if (wbcMem->destructor != NULL) { wbcMem->destructor(p); } free(wbcMem); return; } char *wbcStrDup(const char *str) { char *result; size_t len; len = strlen(str); result = (char *)wbcAllocateMemory(len+1, sizeof(char), NULL); if (result == NULL) { return NULL; } memcpy(result, str, len+1); return result; } static void wbcStringArrayDestructor(void *ptr) { char **p = (char **)ptr; while (*p != NULL) { free(*p); p += 1; } } const char **wbcAllocateStringArray(int num_strings) { return (const char **)wbcAllocateMemory( num_strings + 1, sizeof(const char *), wbcStringArrayDestructor); } wbcErr wbcLibraryDetails(struct wbcLibraryDetails **_details) { struct wbcLibraryDetails *info; info = (struct wbcLibraryDetails *)wbcAllocateMemory( 1, sizeof(struct wbcLibraryDetails), NULL); if (info == NULL) { return WBC_ERR_NO_MEMORY; } info->major_version = WBCLIENT_MAJOR_VERSION; info->minor_version = WBCLIENT_MINOR_VERSION; info->vendor_version = WBCLIENT_VENDOR_VERSION; *_details = info; return WBC_ERR_SUCCESS; } sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_sid_common.c0000644000000000000000000000007412703456111022706 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.890794429 sssd-1.13.4/src/sss_client/libwbclient/wbc_sid_common.c0000644002412700241270000001313712703456111024362 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API Copyright (C) Gerald (Jerry) Carter 2007 Copyright (C) Volker Lendecke 2010 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include #include "libwbclient.h" #define MAX(a, b) (((a) > (b)) ? (a) : (b)) /* Convert a sid to a string into a buffer. Return the string * length. If buflen is too small, return the string length that would * result if it was long enough. */ int wbcSidToStringBuf(const struct wbcDomainSid *sid, char *buf, int buflen) { uint64_t id_auth; int i, ofs; if (!sid) { strncpy(buf, "(NULL SID)", buflen); buf[buflen < 10 ? buflen :10] = '\0'; return 10; /* strlen("(NULL SID)") */ } id_auth = (uint64_t)sid->id_auth[5] + ((uint64_t)sid->id_auth[4] << 8) + ((uint64_t)sid->id_auth[3] << 16) + ((uint64_t)sid->id_auth[2] << 24) + ((uint64_t)sid->id_auth[1] << 32) + ((uint64_t)sid->id_auth[0] << 40); ofs = snprintf(buf, buflen, "S-%hhu-", (unsigned char)sid->sid_rev_num); if (id_auth >= UINT32_MAX) { ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "0x%llx", (unsigned long long)id_auth); } else { ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "%llu", (unsigned long long)id_auth); } for (i = 0; i < sid->num_auths; i++) { ofs += snprintf(buf + ofs, MAX(buflen - ofs, 0), "-%u", (unsigned int)sid->sub_auths[i]); } return ofs; } /* Convert a binary SID to a character string */ wbcErr wbcSidToString(const struct wbcDomainSid *sid, char **sid_string) { char buf[WBC_SID_STRING_BUFLEN]; char *result; int len; if (!sid) { return WBC_ERR_INVALID_SID; } len = wbcSidToStringBuf(sid, buf, sizeof(buf)); if (len+1 > sizeof(buf)) { return WBC_ERR_INVALID_SID; } result = (char *)wbcAllocateMemory(len+1, 1, NULL); if (result == NULL) { return WBC_ERR_NO_MEMORY; } memcpy(result, buf, len+1); *sid_string = result; return WBC_ERR_SUCCESS; } #define AUTHORITY_MASK (~(0xffffffffffffULL)) /* Convert a character string to a binary SID */ wbcErr wbcStringToSid(const char *str, struct wbcDomainSid *sid) { const char *p; char *q; uint64_t x; wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; if (!sid) { wbc_status = WBC_ERR_INVALID_PARAM; BAIL_ON_WBC_ERROR(wbc_status); } /* Sanity check for either "S-" or "s-" */ if (!str || (str[0]!='S' && str[0]!='s') || (str[1]!='-')) { wbc_status = WBC_ERR_INVALID_PARAM; BAIL_ON_WBC_ERROR(wbc_status); } /* Get the SID revision number */ p = str+2; x = (uint64_t)strtoul(p, &q, 10); if (x==0 || x > UINT8_MAX || !q || *q!='-') { wbc_status = WBC_ERR_INVALID_SID; BAIL_ON_WBC_ERROR(wbc_status); } sid->sid_rev_num = (uint8_t)x; /* * Next the Identifier Authority. This is stored big-endian in a * 6 byte array. If the authority value is >= UINT_MAX, then it should * be expressed as a hex value, according to MS-DTYP. */ p = q+1; x = strtoull(p, &q, 0); if (!q || *q!='-' || (x & AUTHORITY_MASK)) { wbc_status = WBC_ERR_INVALID_SID; BAIL_ON_WBC_ERROR(wbc_status); } sid->id_auth[5] = (x & 0x0000000000ffULL); sid->id_auth[4] = (x & 0x00000000ff00ULL) >> 8; sid->id_auth[3] = (x & 0x000000ff0000ULL) >> 16; sid->id_auth[2] = (x & 0x0000ff000000ULL) >> 24; sid->id_auth[1] = (x & 0x00ff00000000ULL) >> 32; sid->id_auth[0] = (x & 0xff0000000000ULL) >> 40; /* now read the subauthorities */ p = q +1; sid->num_auths = 0; while (sid->num_auths < WBC_MAXSUBAUTHS) { x = strtoull(p, &q, 10); if (p == q) break; if (x > UINT32_MAX) { wbc_status = WBC_ERR_INVALID_SID; BAIL_ON_WBC_ERROR(wbc_status); } sid->sub_auths[sid->num_auths++] = x; if (*q != '-') { break; } p = q + 1; } /* IF we ended early, then the SID could not be converted */ if (q && *q!='\0') { wbc_status = WBC_ERR_INVALID_SID; BAIL_ON_WBC_ERROR(wbc_status); } wbc_status = WBC_ERR_SUCCESS; done: return wbc_status; } const char* wbcSidTypeString(enum wbcSidType type) { switch (type) { case WBC_SID_NAME_USE_NONE: return "SID_NONE"; case WBC_SID_NAME_USER: return "SID_USER"; case WBC_SID_NAME_DOM_GRP: return "SID_DOM_GROUP"; case WBC_SID_NAME_DOMAIN: return "SID_DOMAIN"; case WBC_SID_NAME_ALIAS: return "SID_ALIAS"; case WBC_SID_NAME_WKN_GRP: return "SID_WKN_GROUP"; case WBC_SID_NAME_DELETED: return "SID_DELETED"; case WBC_SID_NAME_INVALID: return "SID_INVALID"; case WBC_SID_NAME_UNKNOWN: return "SID_UNKNOWN"; case WBC_SID_NAME_COMPUTER: return "SID_COMPUTER"; default: return "Unknown type"; } } sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbclient_internal.h0000644000000000000000000000007412703456111023434 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.595793429 sssd-1.13.4/src/sss_client/libwbclient/wbclient_internal.h0000644002412700241270000000261112703456111025103 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API Copyright (C) Gerald (Jerry) Carter 2007 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef _WBCLIENT_INTERNAL_H #define _WBCLIENT_INTERNAL_H /* Private functions */ struct winbindd_request; struct winbindd_response; wbcErr wbcRequestResponse(int cmd, struct winbindd_request *request, struct winbindd_response *response); wbcErr wbcRequestResponsePriv(int cmd, struct winbindd_request *request, struct winbindd_response *response); void *wbcAllocateMemory(size_t nelem, size_t elsize, void (*destructor)(void *ptr)); char *wbcStrDup(const char *str); const char **wbcAllocateStringArray(int num_strings); #endif /* _WBCLIENT_INTERNAL_H */ sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbclient_sssd.pc.in0000644000000000000000000000007412703456111023354 xustar0030 atime=1460561772.796787329 30 ctime=1460561774.635793564 sssd-1.13.4/src/sss_client/libwbclient/wbclient_sssd.pc.in0000644002412700241270000000043212703456111025022 0ustar00jhrozekjhrozek00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@appmodpath@ includedir=@includedir@ Name: wbclient Description: SSSD implementation of Samba wbclient API Version: @libwbclient_version@ Libs: -L${libdir} -lwbclient Cflags: URL: http://fedorahosted.org/sssd/, http://www.samba.org sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbclient_sssd.h0000644000000000000000000000007412703456111022574 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.605793463 sssd-1.13.4/src/sss_client/libwbclient/wbclient_sssd.h0000644002412700241270000016541412703456111024256 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API Copyright (C) Gerald (Jerry) Carter 2007 Copyright (C) Volker Lendecke 2009 Copyright (C) Matthew Newton 2015 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef _WBCLIENT_H #define _WBCLIENT_H #include #include /* Define error types */ /** * @brief Status codes returned from wbc functions **/ enum _wbcErrType { WBC_ERR_SUCCESS = 0, /**< Successful completion **/ WBC_ERR_NOT_IMPLEMENTED, /**< Function not implemented **/ WBC_ERR_UNKNOWN_FAILURE, /**< General failure **/ WBC_ERR_NO_MEMORY, /**< Memory allocation error **/ WBC_ERR_INVALID_SID, /**< Invalid SID format **/ WBC_ERR_INVALID_PARAM, /**< An Invalid parameter was supplied **/ WBC_ERR_WINBIND_NOT_AVAILABLE, /**< Winbind daemon is not available **/ WBC_ERR_DOMAIN_NOT_FOUND, /**< Domain is not trusted or cannot be found **/ WBC_ERR_INVALID_RESPONSE, /**< Winbind returned an invalid response **/ WBC_ERR_NSS_ERROR, /**< NSS_STATUS error **/ WBC_ERR_AUTH_ERROR, /**< Authentication failed **/ WBC_ERR_UNKNOWN_USER, /**< User account cannot be found */ WBC_ERR_UNKNOWN_GROUP, /**< Group account cannot be found */ WBC_ERR_PWD_CHANGE_FAILED /**< Password Change has failed */ }; typedef enum _wbcErrType wbcErr; #define WBC_ERROR_IS_OK(x) ((x) == WBC_ERR_SUCCESS) const char *wbcErrorString(wbcErr error); /** * @brief Some useful details about the wbclient library * * 0.1: Initial version * 0.2: Added wbcRemoveUidMapping() * Added wbcRemoveGidMapping() * 0.3: Added wbcGetpwsid() * Added wbcGetSidAliases() * 0.4: Added wbcSidTypeString() * 0.5: Added wbcChangeTrustCredentials() * 0.6: Made struct wbcInterfaceDetails char* members non-const * 0.7: Added wbcSidToStringBuf() * 0.8: Added wbcSidsToUnixIds() and wbcLookupSids() * 0.9: Added support for WBC_ID_TYPE_BOTH * 0.10: Added wbcPingDc2() * 0.11: Extended wbcAuthenticateUserEx to provide PAC parsing * 0.12: Added wbcCtxCreate and friends **/ #define WBCLIENT_MAJOR_VERSION 0 #define WBCLIENT_MINOR_VERSION 12 #define WBCLIENT_VENDOR_VERSION "Samba libwbclient" struct wbcLibraryDetails { uint16_t major_version; uint16_t minor_version; const char *vendor_version; }; /** * @brief Some useful details about the running winbindd * **/ struct wbcInterfaceDetails { uint32_t interface_version; char *winbind_version; char winbind_separator; char *netbios_name; char *netbios_domain; char *dns_domain; }; /** * @brief Library context data * **/ struct wbcContext; /* * Data types used by the Winbind Client API */ #ifndef WBC_MAXSUBAUTHS #define WBC_MAXSUBAUTHS 15 /* max sub authorities in a SID */ #endif /** * @brief Windows Security Identifier * **/ struct wbcDomainSid { uint8_t sid_rev_num; uint8_t num_auths; uint8_t id_auth[6]; uint32_t sub_auths[WBC_MAXSUBAUTHS]; }; /** * @brief Security Identifier type **/ enum wbcSidType { WBC_SID_NAME_USE_NONE=0, WBC_SID_NAME_USER=1, WBC_SID_NAME_DOM_GRP=2, WBC_SID_NAME_DOMAIN=3, WBC_SID_NAME_ALIAS=4, WBC_SID_NAME_WKN_GRP=5, WBC_SID_NAME_DELETED=6, WBC_SID_NAME_INVALID=7, WBC_SID_NAME_UNKNOWN=8, WBC_SID_NAME_COMPUTER=9 }; /** * @brief Security Identifier with attributes **/ struct wbcSidWithAttr { struct wbcDomainSid sid; uint32_t attributes; }; /* wbcSidWithAttr->attributes */ #define WBC_SID_ATTR_GROUP_MANDATORY 0x00000001 #define WBC_SID_ATTR_GROUP_ENABLED_BY_DEFAULT 0x00000002 #define WBC_SID_ATTR_GROUP_ENABLED 0x00000004 #define WBC_SID_ATTR_GROUP_OWNER 0x00000008 #define WBC_SID_ATTR_GROUP_USEFOR_DENY_ONLY 0x00000010 #define WBC_SID_ATTR_GROUP_RESOURCE 0x20000000 #define WBC_SID_ATTR_GROUP_LOGON_ID 0xC0000000 /** * @brief Windows GUID * **/ struct wbcGuid { uint32_t time_low; uint16_t time_mid; uint16_t time_hi_and_version; uint8_t clock_seq[2]; uint8_t node[6]; }; /** * @brief Domain Information **/ struct wbcDomainInfo { char *short_name; char *dns_name; struct wbcDomainSid sid; uint32_t domain_flags; uint32_t trust_flags; uint32_t trust_type; }; /* wbcDomainInfo->domain_flags */ #define WBC_DOMINFO_DOMAIN_UNKNOWN 0x00000000 #define WBC_DOMINFO_DOMAIN_NATIVE 0x00000001 #define WBC_DOMINFO_DOMAIN_AD 0x00000002 #define WBC_DOMINFO_DOMAIN_PRIMARY 0x00000004 #define WBC_DOMINFO_DOMAIN_OFFLINE 0x00000008 /* wbcDomainInfo->trust_flags */ #define WBC_DOMINFO_TRUST_TRANSITIVE 0x00000001 #define WBC_DOMINFO_TRUST_INCOMING 0x00000002 #define WBC_DOMINFO_TRUST_OUTGOING 0x00000004 /* wbcDomainInfo->trust_type */ #define WBC_DOMINFO_TRUSTTYPE_NONE 0x00000000 #define WBC_DOMINFO_TRUSTTYPE_FOREST 0x00000001 #define WBC_DOMINFO_TRUSTTYPE_IN_FOREST 0x00000002 #define WBC_DOMINFO_TRUSTTYPE_EXTERNAL 0x00000003 /** * @brief Generic Blob **/ struct wbcBlob { uint8_t *data; size_t length; }; /** * @brief Named Blob **/ struct wbcNamedBlob { const char *name; uint32_t flags; struct wbcBlob blob; }; /** * @brief Auth User Parameters **/ struct wbcAuthUserParams { const char *account_name; const char *domain_name; const char *workstation_name; uint32_t flags; uint32_t parameter_control; enum wbcAuthUserLevel { WBC_AUTH_USER_LEVEL_PLAIN = 1, WBC_AUTH_USER_LEVEL_HASH = 2, WBC_AUTH_USER_LEVEL_RESPONSE = 3, WBC_AUTH_USER_LEVEL_PAC = 4 } level; union { const char *plaintext; struct { uint8_t nt_hash[16]; uint8_t lm_hash[16]; } hash; struct { uint8_t challenge[8]; uint32_t nt_length; uint8_t *nt_data; uint32_t lm_length; uint8_t *lm_data; } response; struct wbcBlob pac; } password; }; /** * @brief Logon User Parameters **/ struct wbcLogonUserParams { const char *username; const char *password; size_t num_blobs; struct wbcNamedBlob *blobs; }; /** * @brief ChangePassword Parameters **/ struct wbcChangePasswordParams { const char *account_name; const char *domain_name; uint32_t flags; enum wbcChangePasswordLevel { WBC_CHANGE_PASSWORD_LEVEL_PLAIN = 1, WBC_CHANGE_PASSWORD_LEVEL_RESPONSE = 2 } level; union { const char *plaintext; struct { uint32_t old_nt_hash_enc_length; uint8_t *old_nt_hash_enc_data; uint32_t old_lm_hash_enc_length; uint8_t *old_lm_hash_enc_data; } response; } old_password; union { const char *plaintext; struct { uint32_t nt_length; uint8_t *nt_data; uint32_t lm_length; uint8_t *lm_data; } response; } new_password; }; /* wbcAuthUserParams->parameter_control */ #define WBC_MSV1_0_CLEARTEXT_PASSWORD_ALLOWED 0x00000002 #define WBC_MSV1_0_UPDATE_LOGON_STATISTICS 0x00000004 #define WBC_MSV1_0_RETURN_USER_PARAMETERS 0x00000008 #define WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT 0x00000020 #define WBC_MSV1_0_RETURN_PROFILE_PATH 0x00000200 #define WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT 0x00000800 /* wbcAuthUserParams->flags */ #define WBC_AUTH_PARAM_FLAGS_INTERACTIVE_LOGON 0x00000001 /** * @brief Auth User Information * * Some of the strings are maybe NULL **/ struct wbcAuthUserInfo { uint32_t user_flags; char *account_name; char *user_principal; char *full_name; char *domain_name; char *dns_domain_name; uint32_t acct_flags; uint8_t user_session_key[16]; uint8_t lm_session_key[8]; uint16_t logon_count; uint16_t bad_password_count; uint64_t logon_time; uint64_t logoff_time; uint64_t kickoff_time; uint64_t pass_last_set_time; uint64_t pass_can_change_time; uint64_t pass_must_change_time; char *logon_server; char *logon_script; char *profile_path; char *home_directory; char *home_drive; /* * the 1st one is the account sid * the 2nd one is the primary_group sid * followed by the rest of the groups */ uint32_t num_sids; struct wbcSidWithAttr *sids; }; /** * @brief Logon User Information * * Some of the strings are maybe NULL **/ struct wbcLogonUserInfo { struct wbcAuthUserInfo *info; size_t num_blobs; struct wbcNamedBlob *blobs; }; /* wbcAuthUserInfo->user_flags */ #define WBC_AUTH_USER_INFO_GUEST 0x00000001 #define WBC_AUTH_USER_INFO_NOENCRYPTION 0x00000002 #define WBC_AUTH_USER_INFO_CACHED_ACCOUNT 0x00000004 #define WBC_AUTH_USER_INFO_USED_LM_PASSWORD 0x00000008 #define WBC_AUTH_USER_INFO_EXTRA_SIDS 0x00000020 #define WBC_AUTH_USER_INFO_SUBAUTH_SESSION_KEY 0x00000040 #define WBC_AUTH_USER_INFO_SERVER_TRUST_ACCOUNT 0x00000080 #define WBC_AUTH_USER_INFO_NTLMV2_ENABLED 0x00000100 #define WBC_AUTH_USER_INFO_RESOURCE_GROUPS 0x00000200 #define WBC_AUTH_USER_INFO_PROFILE_PATH_RETURNED 0x00000400 #define WBC_AUTH_USER_INFO_GRACE_LOGON 0x01000000 /* wbcAuthUserInfo->acct_flags */ #define WBC_ACB_DISABLED 0x00000001 /* 1 User account disabled */ #define WBC_ACB_HOMDIRREQ 0x00000002 /* 1 Home directory required */ #define WBC_ACB_PWNOTREQ 0x00000004 /* 1 User password not required */ #define WBC_ACB_TEMPDUP 0x00000008 /* 1 Temporary duplicate account */ #define WBC_ACB_NORMAL 0x00000010 /* 1 Normal user account */ #define WBC_ACB_MNS 0x00000020 /* 1 MNS logon user account */ #define WBC_ACB_DOMTRUST 0x00000040 /* 1 Interdomain trust account */ #define WBC_ACB_WSTRUST 0x00000080 /* 1 Workstation trust account */ #define WBC_ACB_SVRTRUST 0x00000100 /* 1 Server trust account */ #define WBC_ACB_PWNOEXP 0x00000200 /* 1 User password does not expire */ #define WBC_ACB_AUTOLOCK 0x00000400 /* 1 Account auto locked */ #define WBC_ACB_ENC_TXT_PWD_ALLOWED 0x00000800 /* 1 Encryped text password is allowed */ #define WBC_ACB_SMARTCARD_REQUIRED 0x00001000 /* 1 Smart Card required */ #define WBC_ACB_TRUSTED_FOR_DELEGATION 0x00002000 /* 1 Trusted for Delegation */ #define WBC_ACB_NOT_DELEGATED 0x00004000 /* 1 Not delegated */ #define WBC_ACB_USE_DES_KEY_ONLY 0x00008000 /* 1 Use DES key only */ #define WBC_ACB_DONT_REQUIRE_PREAUTH 0x00010000 /* 1 Preauth not required */ #define WBC_ACB_PW_EXPIRED 0x00020000 /* 1 Password Expired */ #define WBC_ACB_NO_AUTH_DATA_REQD 0x00080000 /* 1 = No authorization data required */ struct wbcAuthErrorInfo { uint32_t nt_status; char *nt_string; int32_t pam_error; char *display_string; }; /** * @brief User Password Policy Information **/ /* wbcUserPasswordPolicyInfo->password_properties */ #define WBC_DOMAIN_PASSWORD_COMPLEX 0x00000001 #define WBC_DOMAIN_PASSWORD_NO_ANON_CHANGE 0x00000002 #define WBC_DOMAIN_PASSWORD_NO_CLEAR_CHANGE 0x00000004 #define WBC_DOMAIN_PASSWORD_LOCKOUT_ADMINS 0x00000008 #define WBC_DOMAIN_PASSWORD_STORE_CLEARTEXT 0x00000010 #define WBC_DOMAIN_REFUSE_PASSWORD_CHANGE 0x00000020 struct wbcUserPasswordPolicyInfo { uint32_t min_length_password; uint32_t password_history; uint32_t password_properties; uint64_t expire; uint64_t min_passwordage; }; /** * @brief Change Password Reject Reason **/ enum wbcPasswordChangeRejectReason { WBC_PWD_CHANGE_NO_ERROR=0, WBC_PWD_CHANGE_PASSWORD_TOO_SHORT=1, WBC_PWD_CHANGE_PWD_IN_HISTORY=2, WBC_PWD_CHANGE_USERNAME_IN_PASSWORD=3, WBC_PWD_CHANGE_FULLNAME_IN_PASSWORD=4, WBC_PWD_CHANGE_NOT_COMPLEX=5, WBC_PWD_CHANGE_MACHINE_NOT_DEFAULT=6, WBC_PWD_CHANGE_FAILED_BY_FILTER=7, WBC_PWD_CHANGE_PASSWORD_TOO_LONG=8 }; /* Note: this defines exist for compatibility reasons with existing code */ #define WBC_PWD_CHANGE_REJECT_OTHER WBC_PWD_CHANGE_NO_ERROR #define WBC_PWD_CHANGE_REJECT_TOO_SHORT WBC_PWD_CHANGE_PASSWORD_TOO_SHORT #define WBC_PWD_CHANGE_REJECT_IN_HISTORY WBC_PWD_CHANGE_PWD_IN_HISTORY #define WBC_PWD_CHANGE_REJECT_COMPLEXITY WBC_PWD_CHANGE_NOT_COMPLEX /** * @brief Logoff User Parameters **/ struct wbcLogoffUserParams { const char *username; size_t num_blobs; struct wbcNamedBlob *blobs; }; /** @brief Credential cache log-on parameters * */ struct wbcCredentialCacheParams { const char *account_name; const char *domain_name; enum wbcCredentialCacheLevel { WBC_CREDENTIAL_CACHE_LEVEL_NTLMSSP = 1 } level; size_t num_blobs; struct wbcNamedBlob *blobs; }; /** @brief Info returned by credential cache auth * */ struct wbcCredentialCacheInfo { size_t num_blobs; struct wbcNamedBlob *blobs; }; /* * DomainControllerInfo struct */ struct wbcDomainControllerInfo { char *dc_name; }; /* * DomainControllerInfoEx struct */ struct wbcDomainControllerInfoEx { const char *dc_unc; const char *dc_address; uint16_t dc_address_type; struct wbcGuid *domain_guid; const char *domain_name; const char *forest_name; uint32_t dc_flags; const char *dc_site_name; const char *client_site_name; }; /********************************************************** * Memory Management **********************************************************/ /** * @brief Free library allocated memory * * @param * Pointer to free * * @return void **/ void wbcFreeMemory(void*); /********************************************************** * Context Management **********************************************************/ /** * @brief Create a new wbcContext context * * @return wbcContext **/ struct wbcContext *wbcCtxCreate(void); /** * @brief Free a library context * * @param ctx wbcContext to free * * @return void **/ void wbcCtxFree(struct wbcContext *ctx); /* * Utility functions for dealing with SIDs */ /** * @brief Get a string representation of the SID type * * @param type type of the SID * * @return string representation of the SID type */ const char* wbcSidTypeString(enum wbcSidType type); #define WBC_SID_STRING_BUFLEN (15*11+25) /* * @brief Print a sid into a buffer * * @param sid Binary Security Identifier * @param buf Target buffer * @param buflen Target buffer length * * @return Resulting string length. */ int wbcSidToStringBuf(const struct wbcDomainSid *sid, char *buf, int buflen); /** * @brief Convert a binary SID to a character string * * @param sid Binary Security Identifier * @param **sid_string Resulting character string * * @return #wbcErr **/ wbcErr wbcSidToString(const struct wbcDomainSid *sid, char **sid_string); /** * @brief Convert a character string to a binary SID * * @param *sid_string Character string in the form of S-... * @param sid Resulting binary SID * * @return #wbcErr **/ wbcErr wbcStringToSid(const char *sid_string, struct wbcDomainSid *sid); /* * Utility functions for dealing with GUIDs */ /** * @brief Convert a binary GUID to a character string * * @param guid Binary Guid * @param **guid_string Resulting character string * * @return #wbcErr **/ wbcErr wbcGuidToString(const struct wbcGuid *guid, char **guid_string); /** * @brief Convert a character string to a binary GUID * * @param *guid_string Character string * @param guid Resulting binary GUID * * @return #wbcErr **/ wbcErr wbcStringToGuid(const char *guid_string, struct wbcGuid *guid); /** * @brief Ping winbindd to see if the daemon is running * * @param *ctx wbclient Context * * @return #wbcErr **/ wbcErr wbcCtxPing(struct wbcContext *ctx); /** * @brief Ping winbindd to see if the daemon is running * * @return #wbcErr **/ wbcErr wbcPing(void); wbcErr wbcLibraryDetails(struct wbcLibraryDetails **details); wbcErr wbcCtxInterfaceDetails(struct wbcContext *ctx, struct wbcInterfaceDetails **details); wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **details); /********************************************************** * Name/SID conversion **********************************************************/ /** * @brief Convert a domain and name to SID * * @param *ctx wbclient Context * @param dom_name Domain name (possibly "") * @param name User or group name * @param *sid Pointer to the resolved domain SID * @param *name_type Pointer to the SID type * * @return #wbcErr **/ wbcErr wbcCtxLookupName(struct wbcContext *ctx, const char *dom_name, const char *name, struct wbcDomainSid *sid, enum wbcSidType *name_type); /** * @brief Convert a domain and name to SID * * @param dom_name Domain name (possibly "") * @param name User or group name * @param *sid Pointer to the resolved domain SID * @param *name_type Pointer to the SID type * * @return #wbcErr **/ wbcErr wbcLookupName(const char *dom_name, const char *name, struct wbcDomainSid *sid, enum wbcSidType *name_type); /** * @brief Convert a SID to a domain and name * * @param *ctx wbclient Context * @param *sid Pointer to the domain SID to be resolved * @param domain Resolved Domain name (possibly "") * @param name Resolved User or group name * @param *name_type Pointer to the resolved SID type * * @return #wbcErr **/ wbcErr wbcCtxLookupSid(struct wbcContext *ctx, const struct wbcDomainSid *sid, char **domain, char **name, enum wbcSidType *name_type); /** * @brief Convert a SID to a domain and name * * @param *sid Pointer to the domain SID to be resolved * @param domain Resolved Domain name (possibly "") * @param name Resolved User or group name * @param *name_type Pointer to the resolved SID type * * @return #wbcErr **/ wbcErr wbcLookupSid(const struct wbcDomainSid *sid, char **domain, char **name, enum wbcSidType *name_type); struct wbcTranslatedName { enum wbcSidType type; char *name; int domain_index; }; wbcErr wbcCtxLookupSids(struct wbcContext *ctx, const struct wbcDomainSid *sids, int num_sids, struct wbcDomainInfo **domains, int *num_domains, struct wbcTranslatedName **names); wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids, struct wbcDomainInfo **domains, int *num_domains, struct wbcTranslatedName **names); /** * @brief Translate a collection of RIDs within a domain to names */ wbcErr wbcCtxLookupRids(struct wbcContext *ctx, struct wbcDomainSid *dom_sid, int num_rids, uint32_t *rids, const char **domain_name, const char ***names, enum wbcSidType **types); /** * @brief Translate a collection of RIDs within a domain to names */ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, int num_rids, uint32_t *rids, const char **domain_name, const char ***names, enum wbcSidType **types); /* * @brief Get the groups a user belongs to **/ wbcErr wbcCtxLookupUserSids(struct wbcContext *ctx, const struct wbcDomainSid *user_sid, bool domain_groups_only, uint32_t *num_sids, struct wbcDomainSid **sids); /* * @brief Get the groups a user belongs to **/ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, bool domain_groups_only, uint32_t *num_sids, struct wbcDomainSid **sids); /* * @brief Get alias membership for sids **/ wbcErr wbcCtxGetSidAliases(struct wbcContext *ctx, const struct wbcDomainSid *dom_sid, struct wbcDomainSid *sids, uint32_t num_sids, uint32_t **alias_rids, uint32_t *num_alias_rids); /* * @brief Get alias membership for sids **/ wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, struct wbcDomainSid *sids, uint32_t num_sids, uint32_t **alias_rids, uint32_t *num_alias_rids); /** * @brief Lists Users **/ wbcErr wbcCtxListUsers(struct wbcContext *ctx, const char *domain_name, uint32_t *num_users, const char ***users); /** * @brief Lists Users **/ wbcErr wbcListUsers(const char *domain_name, uint32_t *num_users, const char ***users); /** * @brief Lists Groups **/ wbcErr wbcCtxListGroups(struct wbcContext *ctx, const char *domain_name, uint32_t *num_groups, const char ***groups); /** * @brief Lists Groups **/ wbcErr wbcListGroups(const char *domain_name, uint32_t *num_groups, const char ***groups); wbcErr wbcCtxGetDisplayName(struct wbcContext *ctx, const struct wbcDomainSid *sid, char **pdomain, char **pfullname, enum wbcSidType *pname_type); wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid, char **pdomain, char **pfullname, enum wbcSidType *pname_type); /********************************************************** * SID/uid/gid Mappings **********************************************************/ /** * @brief Convert a Windows SID to a Unix uid, allocating an uid if needed * * @param *ctx wbclient Context * @param *sid Pointer to the domain SID to be resolved * @param *puid Pointer to the resolved uid_t value * * @return #wbcErr * **/ wbcErr wbcCtxSidToUid(struct wbcContext *ctx, const struct wbcDomainSid *sid, uid_t *puid); /** * @brief Convert a Windows SID to a Unix uid, allocating an uid if needed * * @param *sid Pointer to the domain SID to be resolved * @param *puid Pointer to the resolved uid_t value * * @return #wbcErr * **/ wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid); /** * @brief Convert a Windows SID to a Unix uid if there already is a mapping * * @param *sid Pointer to the domain SID to be resolved * @param *puid Pointer to the resolved uid_t value * * @return #wbcErr * **/ wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid, uid_t *puid); /** * @brief Convert a Unix uid to a Windows SID, allocating a SID if needed * * @param *ctx wbclient Context * @param uid Unix uid to be resolved * @param *sid Pointer to the resolved domain SID * * @return #wbcErr * **/ wbcErr wbcCtxUidToSid(struct wbcContext *ctx, uid_t uid, struct wbcDomainSid *sid); /** * @brief Convert a Unix uid to a Windows SID, allocating a SID if needed * * @param uid Unix uid to be resolved * @param *sid Pointer to the resolved domain SID * * @return #wbcErr * **/ wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid); /** * @brief Convert a Unix uid to a Windows SID if there already is a mapping * * @param uid Unix uid to be resolved * @param *sid Pointer to the resolved domain SID * * @return #wbcErr * **/ wbcErr wbcQueryUidToSid(uid_t uid, struct wbcDomainSid *sid); /** * @brief Convert a Windows SID to a Unix gid, allocating a gid if needed * * @param *ctx wbclient Context * @param *sid Pointer to the domain SID to be resolved * @param *pgid Pointer to the resolved gid_t value * * @return #wbcErr * **/ wbcErr wbcCtxSidToGid(struct wbcContext *ctx, const struct wbcDomainSid *sid, gid_t *pgid); /** * @brief Convert a Windows SID to a Unix gid, allocating a gid if needed * * @param *sid Pointer to the domain SID to be resolved * @param *pgid Pointer to the resolved gid_t value * * @return #wbcErr * **/ wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid); /** * @brief Convert a Windows SID to a Unix gid if there already is a mapping * * @param *sid Pointer to the domain SID to be resolved * @param *pgid Pointer to the resolved gid_t value * * @return #wbcErr * **/ wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid, gid_t *pgid); /** * @brief Convert a Unix gid to a Windows SID, allocating a SID if needed * * @param *ctx wbclient Context * @param gid Unix gid to be resolved * @param *sid Pointer to the resolved domain SID * * @return #wbcErr * **/ wbcErr wbcCtxGidToSid(struct wbcContext *ctx, gid_t gid, struct wbcDomainSid *sid); /** * @brief Convert a Unix gid to a Windows SID, allocating a SID if needed * * @param gid Unix gid to be resolved * @param *sid Pointer to the resolved domain SID * * @return #wbcErr * **/ wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid); /** * @brief Convert a Unix gid to a Windows SID if there already is a mapping * * @param gid Unix gid to be resolved * @param *sid Pointer to the resolved domain SID * * @return #wbcErr * **/ wbcErr wbcQueryGidToSid(gid_t gid, struct wbcDomainSid *sid); enum wbcIdType { WBC_ID_TYPE_NOT_SPECIFIED, WBC_ID_TYPE_UID, WBC_ID_TYPE_GID, WBC_ID_TYPE_BOTH }; union wbcUnixIdContainer { uid_t uid; gid_t gid; }; struct wbcUnixId { enum wbcIdType type; union wbcUnixIdContainer id; }; /** * @brief Convert a list of sids to unix ids * * @param *ctx wbclient Context * @param sids Pointer to an array of SIDs to convert * @param num_sids Number of SIDs * @param ids Preallocated output array for translated IDs * * @return #wbcErr * **/ wbcErr wbcCtxSidsToUnixIds(struct wbcContext *ctx, const struct wbcDomainSid *sids, uint32_t num_sids, struct wbcUnixId *ids); /** * @brief Convert a list of sids to unix ids * * @param sids Pointer to an array of SIDs to convert * @param num_sids Number of SIDs * @param ids Preallocated output array for translated IDs * * @return #wbcErr * **/ wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids, struct wbcUnixId *ids); /** * @brief Obtain a new uid from Winbind * * @param *ctx wbclient Context * @param *puid Pointer to the allocated uid * * @return #wbcErr **/ wbcErr wbcCtxAllocateUid(struct wbcContext *ctx, uid_t *puid); /** * @brief Obtain a new uid from Winbind * * @param *puid Pointer to the allocated uid * * @return #wbcErr **/ wbcErr wbcAllocateUid(uid_t *puid); /** * @brief Obtain a new gid from Winbind * * @param *ctx wbclient Context * @param *pgid Pointer to the allocated gid * * @return #wbcErr **/ wbcErr wbcCtxAllocateGid(struct wbcContext *ctx, gid_t *pgid); /** * @brief Obtain a new gid from Winbind * * @param *pgid Pointer to the allocated gid * * @return #wbcErr **/ wbcErr wbcAllocateGid(gid_t *pgid); /** * @brief Set an user id mapping * * @param uid Uid of the desired mapping. * @param *sid Pointer to the sid of the desired mapping. * * @return #wbcErr * * @deprecated This method is not impemented any more and should * be removed in the next major version change. **/ wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid); /** * @brief Set a group id mapping * * @param gid Gid of the desired mapping. * @param *sid Pointer to the sid of the desired mapping. * * @return #wbcErr * * @deprecated This method is not impemented any more and should * be removed in the next major version change. **/ wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid); /** * @brief Remove a user id mapping * * @param uid Uid of the mapping to remove. * @param *sid Pointer to the sid of the mapping to remove. * * @return #wbcErr * * @deprecated This method is not impemented any more and should * be removed in the next major version change. **/ wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid); /** * @brief Remove a group id mapping * * @param gid Gid of the mapping to remove. * @param *sid Pointer to the sid of the mapping to remove. * * @return #wbcErr * * @deprecated This method is not impemented any more and should * be removed in the next major version change. **/ wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid); /** * @brief Set the highwater mark for allocated uids. * * @param uid_hwm The new uid highwater mark value * * @return #wbcErr * * @deprecated This method is not impemented any more and should * be removed in the next major version change. **/ wbcErr wbcSetUidHwm(uid_t uid_hwm); /** * @brief Set the highwater mark for allocated gids. * * @param gid_hwm The new gid highwater mark value * * @return #wbcErr * * @deprecated This method is not impemented any more and should * be removed in the next major version change. **/ wbcErr wbcSetGidHwm(gid_t gid_hwm); /********************************************************** * NSS Lookup User/Group details **********************************************************/ /** * @brief Fill in a struct passwd* for a domain user based * on username * * @param *ctx wbclient Context * @param *name Username to lookup * @param **pwd Pointer to resulting struct passwd* from the query. * * @return #wbcErr **/ wbcErr wbcCtxGetpwnam(struct wbcContext *ctx, const char *name, struct passwd **pwd); /** * @brief Fill in a struct passwd* for a domain user based * on username * * @param *name Username to lookup * @param **pwd Pointer to resulting struct passwd* from the query. * * @return #wbcErr **/ wbcErr wbcGetpwnam(const char *name, struct passwd **pwd); /** * @brief Fill in a struct passwd* for a domain user based * on uid * * @param *ctx wbclient Context * @param uid Uid to lookup * @param **pwd Pointer to resulting struct passwd* from the query. * * @return #wbcErr **/ wbcErr wbcCtxGetpwuid(struct wbcContext *ctx, uid_t uid, struct passwd **pwd); /** * @brief Fill in a struct passwd* for a domain user based * on uid * * @param uid Uid to lookup * @param **pwd Pointer to resulting struct passwd* from the query. * * @return #wbcErr **/ wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd); /** * @brief Fill in a struct passwd* for a domain user based * on sid * * @param *ctx wbclient Context * @param sid Sid to lookup * @param **pwd Pointer to resulting struct passwd* from the query. * * @return #wbcErr **/ wbcErr wbcCtxGetpwsid(struct wbcContext *ctx, struct wbcDomainSid * sid, struct passwd **pwd); /** * @brief Fill in a struct passwd* for a domain user based * on sid * * @param sid Sid to lookup * @param **pwd Pointer to resulting struct passwd* from the query. * * @return #wbcErr **/ wbcErr wbcGetpwsid(struct wbcDomainSid * sid, struct passwd **pwd); /** * @brief Fill in a struct passwd* for a domain user based * on username * * @param *ctx wbclient Context * @param *name Username to lookup * @param **grp Pointer to resulting struct group* from the query. * * @return #wbcErr **/ wbcErr wbcCtxGetgrnam(struct wbcContext *ctx, const char *name, struct group **grp); /** * @brief Fill in a struct passwd* for a domain user based * on username * * @param *name Username to lookup * @param **grp Pointer to resulting struct group* from the query. * * @return #wbcErr **/ wbcErr wbcGetgrnam(const char *name, struct group **grp); /** * @brief Fill in a struct passwd* for a domain user based * on uid * * @param *ctx wbclient Context * @param gid Uid to lookup * @param **grp Pointer to resulting struct group* from the query. * * @return #wbcErr **/ wbcErr wbcCtxGetgrgid(struct wbcContext *ctx, gid_t gid, struct group **grp); /** * @brief Fill in a struct passwd* for a domain user based * on uid * * @param gid Uid to lookup * @param **grp Pointer to resulting struct group* from the query. * * @return #wbcErr **/ wbcErr wbcGetgrgid(gid_t gid, struct group **grp); /** * @brief Reset the passwd iterator * * @param *ctx wbclient Context * * @return #wbcErr **/ wbcErr wbcCtxSetpwent(struct wbcContext *ctx); /** * @brief Reset the passwd iterator * * @return #wbcErr **/ wbcErr wbcSetpwent(void); /** * @brief Close the passwd iterator * * @param *ctx wbclient Context * * @return #wbcErr **/ wbcErr wbcCtxEndpwent(struct wbcContext *ctx); /** * @brief Close the passwd iterator * * @return #wbcErr **/ wbcErr wbcEndpwent(void); /** * @brief Return the next struct passwd* entry from the pwent iterator * * @param *ctx wbclient Context * @param **pwd Pointer to resulting struct passwd* from the query. * * @return #wbcErr **/ wbcErr wbcCtxGetpwent(struct wbcContext *ctx, struct passwd **pwd); /** * @brief Return the next struct passwd* entry from the pwent iterator * * @param **pwd Pointer to resulting struct passwd* from the query. * * @return #wbcErr **/ wbcErr wbcGetpwent(struct passwd **pwd); /** * @brief Reset the group iterator * * @param *ctx wbclient Context * * @return #wbcErr **/ wbcErr wbcCtxSetgrent(struct wbcContext *ctx); /** * @brief Reset the group iterator * * @return #wbcErr **/ wbcErr wbcSetgrent(void); /** * @brief Close the group iterator * * @param *ctx wbclient Context * * @return #wbcErr **/ wbcErr wbcCtxEndgrent(struct wbcContext *ctx); /** * @brief Close the group iterator * * @return #wbcErr **/ wbcErr wbcEndgrent(void); /** * @brief Return the next struct group* entry from the pwent iterator * * @param *ctx wbclient Context * @param **grp Pointer to resulting struct group* from the query. * * @return #wbcErr **/ wbcErr wbcCtxGetgrent(struct wbcContext *ctx, struct group **grp); /** * @brief Return the next struct group* entry from the pwent iterator * * @param **grp Pointer to resulting struct group* from the query. * * @return #wbcErr **/ wbcErr wbcGetgrent(struct group **grp); /** * @brief Return the next struct group* entry from the pwent iterator * * This is similar to #wbcGetgrent, just that the member list is empty * * @param *ctx wbclient Context * @param **grp Pointer to resulting struct group* from the query. * * @return #wbcErr **/ wbcErr wbcCtxGetgrlist(struct wbcContext *ctx, struct group **grp); /** * @brief Return the next struct group* entry from the pwent iterator * * This is similar to #wbcGetgrent, just that the member list is empty * * @param **grp Pointer to resulting struct group* from the query. * * @return #wbcErr **/ wbcErr wbcGetgrlist(struct group **grp); /** * @brief Return the unix group array belonging to the given user * * @param *ctx wbclient Context * @param *account The given user name * @param *num_groups Number of elements returned in the groups array * @param **_groups Pointer to resulting gid_t array. * * @return #wbcErr **/ wbcErr wbcCtxGetGroups(struct wbcContext *ctx, const char *account, uint32_t *num_groups, gid_t **_groups); /** * @brief Return the unix group array belonging to the given user * * @param *account The given user name * @param *num_groups Number of elements returned in the groups array * @param **_groups Pointer to resulting gid_t array. * * @return #wbcErr **/ wbcErr wbcGetGroups(const char *account, uint32_t *num_groups, gid_t **_groups); /********************************************************** * Lookup Domain information **********************************************************/ /** * @brief Lookup the current status of a trusted domain * * @param *ctx wbclient Context * @param domain The domain to query * * @param dinfo A pointer to store the returned domain_info struct. * * @return #wbcErr **/ wbcErr wbcCtxDomainInfo(struct wbcContext *ctx, const char *domain, struct wbcDomainInfo **dinfo); /** * @brief Lookup the current status of a trusted domain * * @param domain The domain to query * * @param dinfo A pointer to store the returned domain_info struct. * * @return #wbcErr **/ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo); /** * @brief Lookup the currently contacted DCs * * @param *ctx wbclient Context * @param domain The domain to query * * @param num_dcs Number of DCs currently known * @param dc_names Names of the currently known DCs * @param dc_ips IP addresses of the currently known DCs * * @return #wbcErr **/ wbcErr wbcCtxDcInfo(struct wbcContext *ctx, const char *domain, size_t *num_dcs, const char ***dc_names, const char ***dc_ips); /** * @brief Lookup the currently contacted DCs * * @param domain The domain to query * * @param num_dcs Number of DCs currently known * @param dc_names Names of the currently known DCs * @param dc_ips IP addresses of the currently known DCs * * @return #wbcErr **/ wbcErr wbcDcInfo(const char *domain, size_t *num_dcs, const char ***dc_names, const char ***dc_ips); /** * @brief Enumerate the domain trusts known by Winbind * * @param *ctx wbclient Context * @param **domains Pointer to the allocated domain list array * @param *num_domains Pointer to number of domains returned * * @return #wbcErr **/ wbcErr wbcCtxListTrusts(struct wbcContext *ctx, struct wbcDomainInfo **domains, size_t *num_domains); /** * @brief Enumerate the domain trusts known by Winbind * * @param **domains Pointer to the allocated domain list array * @param *num_domains Pointer to number of domains returned * * @return #wbcErr **/ wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains); /* Flags for wbcLookupDomainController */ #define WBC_LOOKUP_DC_FORCE_REDISCOVERY 0x00000001 #define WBC_LOOKUP_DC_DS_REQUIRED 0x00000010 #define WBC_LOOKUP_DC_DS_PREFERRED 0x00000020 #define WBC_LOOKUP_DC_GC_SERVER_REQUIRED 0x00000040 #define WBC_LOOKUP_DC_PDC_REQUIRED 0x00000080 #define WBC_LOOKUP_DC_BACKGROUND_ONLY 0x00000100 #define WBC_LOOKUP_DC_IP_REQUIRED 0x00000200 #define WBC_LOOKUP_DC_KDC_REQUIRED 0x00000400 #define WBC_LOOKUP_DC_TIMESERV_REQUIRED 0x00000800 #define WBC_LOOKUP_DC_WRITABLE_REQUIRED 0x00001000 #define WBC_LOOKUP_DC_GOOD_TIMESERV_PREFERRED 0x00002000 #define WBC_LOOKUP_DC_AVOID_SELF 0x00004000 #define WBC_LOOKUP_DC_ONLY_LDAP_NEEDED 0x00008000 #define WBC_LOOKUP_DC_IS_FLAT_NAME 0x00010000 #define WBC_LOOKUP_DC_IS_DNS_NAME 0x00020000 #define WBC_LOOKUP_DC_TRY_NEXTCLOSEST_SITE 0x00040000 #define WBC_LOOKUP_DC_DS_6_REQUIRED 0x00080000 #define WBC_LOOKUP_DC_RETURN_DNS_NAME 0x40000000 #define WBC_LOOKUP_DC_RETURN_FLAT_NAME 0x80000000 /** * @brief Enumerate the domain trusts known by Winbind * * @param *ctx wbclient Context * @param domain Name of the domain to query for a DC * @param flags Bit flags used to control the domain location query * @param *dc_info Pointer to the returned domain controller information * * @return #wbcErr **/ wbcErr wbcCtxLookupDomainController(struct wbcContext *ctx, const char *domain, uint32_t flags, struct wbcDomainControllerInfo **dc_info); /** * @brief Enumerate the domain trusts known by Winbind * * @param domain Name of the domain to query for a DC * @param flags Bit flags used to control the domain location query * @param *dc_info Pointer to the returned domain controller information * * @return #wbcErr **/ wbcErr wbcLookupDomainController(const char *domain, uint32_t flags, struct wbcDomainControllerInfo **dc_info); /** * @brief Get extended domain controller information * * @param *ctx wbclient Context * @param domain Name of the domain to query for a DC * @param guid Guid of the domain to query for a DC * @param site Site of the domain to query for a DC * @param flags Bit flags used to control the domain location query * @param *dc_info Pointer to the returned extended domain controller information * * @return #wbcErr **/ wbcErr wbcCtxLookupDomainControllerEx(struct wbcContext *ctx, const char *domain, struct wbcGuid *guid, const char *site, uint32_t flags, struct wbcDomainControllerInfoEx **dc_info); /** * @brief Get extended domain controller information * * @param domain Name of the domain to query for a DC * @param guid Guid of the domain to query for a DC * @param site Site of the domain to query for a DC * @param flags Bit flags used to control the domain location query * @param *dc_info Pointer to the returned extended domain controller information * * @return #wbcErr **/ wbcErr wbcLookupDomainControllerEx(const char *domain, struct wbcGuid *guid, const char *site, uint32_t flags, struct wbcDomainControllerInfoEx **dc_info); /********************************************************** * Athenticate functions **********************************************************/ /** * @brief Authenticate a username/password pair * * @param *ctx wbclient Context * @param username Name of user to authenticate * @param password Clear text password os user * * @return #wbcErr **/ wbcErr wbcCtxAuthenticateUser(struct wbcContext *ctx, const char *username, const char *password); /** * @brief Authenticate a username/password pair * * @param username Name of user to authenticate * @param password Clear text password os user * * @return #wbcErr **/ wbcErr wbcAuthenticateUser(const char *username, const char *password); /** * @brief Authenticate with more detailed information * * @param *ctx wbclient Context * @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH * is not supported yet * @param info Output details on WBC_ERR_SUCCESS * @param error Output details on WBC_ERR_AUTH_ERROR * * @return #wbcErr **/ wbcErr wbcCtxAuthenticateUserEx(struct wbcContext *ctx, const struct wbcAuthUserParams *params, struct wbcAuthUserInfo **info, struct wbcAuthErrorInfo **error); /** * @brief Authenticate with more detailed information * * @param params Input parameters, WBC_AUTH_USER_LEVEL_HASH * is not supported yet * @param info Output details on WBC_ERR_SUCCESS * @param error Output details on WBC_ERR_AUTH_ERROR * * @return #wbcErr **/ wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params, struct wbcAuthUserInfo **info, struct wbcAuthErrorInfo **error); /** * @brief Logon a User * * @param[in] *ctx wbclient Context * @param[in] params Pointer to a wbcLogonUserParams structure * @param[out] info Pointer to a pointer to a wbcLogonUserInfo structure * @param[out] error Pointer to a pointer to a wbcAuthErrorInfo structure * @param[out] policy Pointer to a pointer to a wbcUserPasswordPolicyInfo structure * * @return #wbcErr **/ wbcErr wbcCtxLogonUser(struct wbcContext *ctx, const struct wbcLogonUserParams *params, struct wbcLogonUserInfo **info, struct wbcAuthErrorInfo **error, struct wbcUserPasswordPolicyInfo **policy); /** * @brief Logon a User * * @param[in] params Pointer to a wbcLogonUserParams structure * @param[out] info Pointer to a pointer to a wbcLogonUserInfo structure * @param[out] error Pointer to a pointer to a wbcAuthErrorInfo structure * @param[out] policy Pointer to a pointer to a wbcUserPasswordPolicyInfo structure * * @return #wbcErr **/ wbcErr wbcLogonUser(const struct wbcLogonUserParams *params, struct wbcLogonUserInfo **info, struct wbcAuthErrorInfo **error, struct wbcUserPasswordPolicyInfo **policy); /** * @brief Trigger a logoff notification to Winbind for a specific user * * @param *ctx wbclient Context * @param username Name of user to remove from Winbind's list of * logged on users. * @param uid Uid assigned to the username * @param ccfilename Absolute path to the Krb5 credentials cache to * be removed * * @return #wbcErr **/ wbcErr wbcCtxLogoffUser(struct wbcContext *ctx, const char *username, uid_t uid, const char *ccfilename); /** * @brief Trigger a logoff notification to Winbind for a specific user * * @param username Name of user to remove from Winbind's list of * logged on users. * @param uid Uid assigned to the username * @param ccfilename Absolute path to the Krb5 credentials cache to * be removed * * @return #wbcErr **/ wbcErr wbcLogoffUser(const char *username, uid_t uid, const char *ccfilename); /** * @brief Trigger an extended logoff notification to Winbind for a specific user * * @param *ctx wbclient Context * @param params A wbcLogoffUserParams structure * @param error User output details on error * * @return #wbcErr **/ wbcErr wbcCtxLogoffUserEx(struct wbcContext *ctx, const struct wbcLogoffUserParams *params, struct wbcAuthErrorInfo **error); /** * @brief Trigger an extended logoff notification to Winbind for a specific user * * @param params A wbcLogoffUserParams structure * @param error User output details on error * * @return #wbcErr **/ wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params, struct wbcAuthErrorInfo **error); /** * @brief Change a password for a user * * @param *ctx wbclient Context * @param username Name of user to authenticate * @param old_password Old clear text password of user * @param new_password New clear text password of user * * @return #wbcErr **/ wbcErr wbcCtxChangeUserPassword(struct wbcContext *ctx, const char *username, const char *old_password, const char *new_password); /** * @brief Change a password for a user * * @param username Name of user to authenticate * @param old_password Old clear text password of user * @param new_password New clear text password of user * * @return #wbcErr **/ wbcErr wbcChangeUserPassword(const char *username, const char *old_password, const char *new_password); /** * @brief Change a password for a user with more detailed information upon * failure * * @param *ctx wbclient Context * @param params Input parameters * @param error User output details on WBC_ERR_PWD_CHANGE_FAILED * @param reject_reason New password reject reason on WBC_ERR_PWD_CHANGE_FAILED * @param policy Password policy output details on WBC_ERR_PWD_CHANGE_FAILED * * @return #wbcErr **/ wbcErr wbcCtxChangeUserPasswordEx(struct wbcContext *ctx, const struct wbcChangePasswordParams *params, struct wbcAuthErrorInfo **error, enum wbcPasswordChangeRejectReason *reject_reason, struct wbcUserPasswordPolicyInfo **policy); /** * @brief Change a password for a user with more detailed information upon * failure * * @param params Input parameters * @param error User output details on WBC_ERR_PWD_CHANGE_FAILED * @param reject_reason New password reject reason on WBC_ERR_PWD_CHANGE_FAILED * @param policy Password policy output details on WBC_ERR_PWD_CHANGE_FAILED * * @return #wbcErr **/ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params, struct wbcAuthErrorInfo **error, enum wbcPasswordChangeRejectReason *reject_reason, struct wbcUserPasswordPolicyInfo **policy); /** * @brief Authenticate a user with cached credentials * * @param *ctx wbclient Context * @param *params Pointer to a wbcCredentialCacheParams structure * @param **info Pointer to a pointer to a wbcCredentialCacheInfo structure * @param **error Pointer to a pointer to a wbcAuthErrorInfo structure * * @return #wbcErr **/ wbcErr wbcCtxCredentialCache(struct wbcContext *ctx, struct wbcCredentialCacheParams *params, struct wbcCredentialCacheInfo **info, struct wbcAuthErrorInfo **error); /** * @brief Authenticate a user with cached credentials * * @param *params Pointer to a wbcCredentialCacheParams structure * @param **info Pointer to a pointer to a wbcCredentialCacheInfo structure * @param **error Pointer to a pointer to a wbcAuthErrorInfo structure * * @return #wbcErr **/ wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, struct wbcCredentialCacheInfo **info, struct wbcAuthErrorInfo **error); /** * @brief Save a password with winbind for doing wbcCredentialCache() later * * @param *ctx wbclient Context * @param *user Username * @param *password Password * * @return #wbcErr **/ wbcErr wbcCtxCredentialSave(struct wbcContext *ctx, const char *user, const char *password); /** * @brief Save a password with winbind for doing wbcCredentialCache() later * * @param *user Username * @param *password Password * * @return #wbcErr **/ wbcErr wbcCredentialSave(const char *user, const char *password); /********************************************************** * Resolve functions **********************************************************/ /** * @brief Resolve a NetbiosName via WINS * * @param *ctx wbclient Context * @param name Name to resolve * @param *ip Pointer to the ip address string * * @return #wbcErr **/ wbcErr wbcCtxResolveWinsByName(struct wbcContext *ctx, const char *name, char **ip); /** * @brief Resolve a NetbiosName via WINS * * @param name Name to resolve * @param *ip Pointer to the ip address string * * @return #wbcErr **/ wbcErr wbcResolveWinsByName(const char *name, char **ip); /** * @brief Resolve an IP address via WINS into a NetbiosName * * @param *ctx wbclient Context * @param ip The ip address string * @param *name Pointer to the name * * @return #wbcErr * **/ wbcErr wbcCtxResolveWinsByIP(struct wbcContext *ctx, const char *ip, char **name); /** * @brief Resolve an IP address via WINS into a NetbiosName * * @param ip The ip address string * @param *name Pointer to the name * * @return #wbcErr * **/ wbcErr wbcResolveWinsByIP(const char *ip, char **name); /********************************************************** * Trusted domain functions **********************************************************/ /** * @brief Trigger a verification of the trust credentials of a specific domain * * @param *ctx wbclient Context * @param *domain The name of the domain. * @param error Output details on WBC_ERR_AUTH_ERROR * * @return #wbcErr **/ wbcErr wbcCtxCheckTrustCredentials(struct wbcContext *ctx, const char *domain, struct wbcAuthErrorInfo **error); /** * @brief Trigger a verification of the trust credentials of a specific domain * * @param *domain The name of the domain. * @param error Output details on WBC_ERR_AUTH_ERROR * * @return #wbcErr **/ wbcErr wbcCheckTrustCredentials(const char *domain, struct wbcAuthErrorInfo **error); /** * @brief Trigger a change of the trust credentials for a specific domain * * @param *ctx wbclient Context * @param *domain The name of the domain. * @param error Output details on WBC_ERR_AUTH_ERROR * * @return #wbcErr **/ wbcErr wbcCtxChangeTrustCredentials(struct wbcContext *ctx, const char *domain, struct wbcAuthErrorInfo **error); /** * @brief Trigger a change of the trust credentials for a specific domain * * @param *domain The name of the domain. * @param error Output details on WBC_ERR_AUTH_ERROR * * @return #wbcErr **/ wbcErr wbcChangeTrustCredentials(const char *domain, struct wbcAuthErrorInfo **error); /** * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost * version of wbcCheckTrustCredentials * * @param *ctx wbclient Context * @param *domain The name of the domain, only NULL for the default domain is * supported yet. Other values than NULL will result in * WBC_ERR_NOT_IMPLEMENTED. * @param error Output details on WBC_ERR_AUTH_ERROR * * @return #wbcErr **/ wbcErr wbcCtxPingDc(struct wbcContext *ctx, const char *domain, struct wbcAuthErrorInfo **error); /** * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost * version of wbcCheckTrustCredentials * * @param *domain The name of the domain, only NULL for the default domain is * supported yet. Other values than NULL will result in * WBC_ERR_NOT_IMPLEMENTED. * @param error Output details on WBC_ERR_AUTH_ERROR * * @return #wbcErr **/ wbcErr wbcPingDc(const char *domain, struct wbcAuthErrorInfo **error); /** * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost * version of wbcCheckTrustCredentials * * @param *ctx wbclient Context * @param *domain The name of the domain, only NULL for the default domain is * supported yet. Other values than NULL will result in * WBC_ERR_NOT_IMPLEMENTED. * @param error Output details on WBC_ERR_AUTH_ERROR * @param dcname DC that was attempted to ping * * @return #wbcErr **/ wbcErr wbcCtxPingDc2(struct wbcContext *ctx, const char *domain, struct wbcAuthErrorInfo **error, char **dcname); /** * @brief Trigger a no-op call through the NETLOGON pipe. Low-cost * version of wbcCheckTrustCredentials * * @param *domain The name of the domain, only NULL for the default domain is * supported yet. Other values than NULL will result in * WBC_ERR_NOT_IMPLEMENTED. * @param error Output details on WBC_ERR_AUTH_ERROR * @param dcname DC that was attempted to ping * * @return #wbcErr **/ wbcErr wbcPingDc2(const char *domain, struct wbcAuthErrorInfo **error, char **dcname); /********************************************************** * Helper functions **********************************************************/ /** * @brief Initialize a named blob and add to list of blobs * * @param[in,out] num_blobs Pointer to the number of blobs * @param[in,out] blobs Pointer to an array of blobs * @param[in] name Name of the new named blob * @param[in] flags Flags of the new named blob * @param[in] data Blob data of new blob * @param[in] length Blob data length of new blob * * @return #wbcErr **/ wbcErr wbcAddNamedBlob(size_t *num_blobs, struct wbcNamedBlob **blobs, const char *name, uint32_t flags, uint8_t *data, size_t length); #endif /* _WBCLIENT_H */ sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_util_common.c0000644000000000000000000000007412703456111023104 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.892794436 sssd-1.13.4/src/sss_client/libwbclient/wbc_util_common.c0000644002412700241270000000513212703456111024554 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client asynchronous API, utility functions Copyright (C) Gerald (Jerry) Carter 2007-2008 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include "libwbclient.h" #include "util/util.h" static void wbcNamedBlobDestructor(void *ptr) { struct wbcNamedBlob *b = (struct wbcNamedBlob *)ptr; while (b->name != NULL) { free(discard_const_p(char, b->name)); free(b->blob.data); b += 1; } } /* Initialize a named blob and add to list of blobs */ wbcErr wbcAddNamedBlob(size_t *num_blobs, struct wbcNamedBlob **pblobs, const char *name, uint32_t flags, uint8_t *data, size_t length) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcNamedBlob *blobs, *blob; if (name == NULL) { return WBC_ERR_INVALID_PARAM; } /* * Overallocate the b->name==NULL terminator for * wbcNamedBlobDestructor */ blobs = (struct wbcNamedBlob *)wbcAllocateMemory( *num_blobs + 2, sizeof(struct wbcNamedBlob), wbcNamedBlobDestructor); if (blobs == NULL) { return WBC_ERR_NO_MEMORY; } if (*pblobs != NULL) { struct wbcNamedBlob *old = *pblobs; memcpy(blobs, old, sizeof(struct wbcNamedBlob) * (*num_blobs)); if (*num_blobs != 0) { /* end indicator for wbcNamedBlobDestructor */ old[0].name = NULL; } wbcFreeMemory(old); } *pblobs = blobs; blob = &blobs[*num_blobs]; blob->name = strdup(name); BAIL_ON_PTR_ERROR(blob->name, wbc_status); blob->flags = flags; blob->blob.length = length; blob->blob.data = (uint8_t *)malloc(length); BAIL_ON_PTR_ERROR(blob->blob.data, wbc_status); memcpy(blob->blob.data, data, length); *num_blobs += 1; *pblobs = blobs; blobs = NULL; wbc_status = WBC_ERR_SUCCESS; done: wbcFreeMemory(blobs); return wbc_status; } sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_sid_sssd.c0000644000000000000000000000007412703456111022372 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.891794432 sssd-1.13.4/src/sss_client/libwbclient/wbc_sid_sssd.c0000644002412700241270000001554512703456111024053 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API - SSSD version Copyright (C) Sumit Bose 2014 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include "config.h" #include #include #include "sss_client/idmap/sss_nss_idmap.h" #include "libwbclient.h" #include "wbc_sssd_internal.h" #define MAX_NAME_LEN 1024 static int sss_id_type_to_wbcSidType(enum sss_id_type sss_type, enum wbcSidType *name_type) { switch (sss_type) { case SSS_ID_TYPE_NOT_SPECIFIED: *name_type = WBC_SID_NAME_USE_NONE; break; case SSS_ID_TYPE_UID: case SSS_ID_TYPE_BOTH: *name_type = WBC_SID_NAME_USER; break; case SSS_ID_TYPE_GID: *name_type = WBC_SID_NAME_DOM_GRP; break; default: return EINVAL; } return 0; }; /* Convert a domain and name to SID */ wbcErr wbcLookupName(const char *domain, const char *name, struct wbcDomainSid *sid, enum wbcSidType *name_type) { char *fq_name = NULL; char *str_sid; enum sss_id_type type; int ret; wbcErr wbc_status; if (domain == NULL || name == NULL || strnlen(domain, MAX_NAME_LEN) == MAX_NAME_LEN || strnlen(name, MAX_NAME_LEN) == MAX_NAME_LEN) { return WBC_ERR_INVALID_PARAM; } ret = asprintf(&fq_name, "%s@%s", name, domain); if (ret == -1) { return WBC_ERR_NO_MEMORY; } ret = sss_nss_getsidbyname(fq_name, &str_sid, &type); free(fq_name); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } ret = sss_id_type_to_wbcSidType(type, name_type); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } wbc_status = wbcStringToSid(str_sid, sid); free(str_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } return WBC_ERR_SUCCESS; } /* Convert a SID to a domain and name */ wbcErr wbcLookupSid(const struct wbcDomainSid *sid, char **pdomain, char **pname, enum wbcSidType *pname_type) { char *str_sid; char *fq_name = NULL; enum sss_id_type type; int ret; char *p; wbcErr wbc_status; wbc_status = wbcSidToString(sid, &str_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } ret = sss_nss_getnamebysid(str_sid, &fq_name, &type); wbcFreeMemory(str_sid); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } ret = sss_id_type_to_wbcSidType(type, pname_type); if (ret != 0) { wbc_status = WBC_ERR_UNKNOWN_FAILURE; goto done; } /* TODO: it would be nice to have a sss_nss_getnamebysid() call which * return name and domain separately. */ p = strchr(fq_name, '@'); if (p == NULL) { wbc_status = WBC_ERR_UNKNOWN_FAILURE; goto done; } *p = '\0'; *pname = wbcStrDup(fq_name); if (*pname == NULL) { wbc_status = WBC_ERR_NO_MEMORY; goto done; } *pdomain = wbcStrDup(p + 1); if (*pdomain == NULL) { wbcFreeMemory(*pname); wbc_status = WBC_ERR_NO_MEMORY; goto done; } wbc_status = WBC_ERR_SUCCESS; done: free(fq_name); return wbc_status; } wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids, struct wbcDomainInfo **pdomains, int *pnum_domains, struct wbcTranslatedName **pnames) { WBC_SSSD_NOT_IMPLEMENTED; } /* Translate a collection of RIDs within a domain to names */ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, int num_rids, uint32_t *rids, const char **pp_domain_name, const char ***pnames, enum wbcSidType **ptypes) { struct wbcDomainSid obj_sid = {0}; size_t c; wbcErr err; char *domain; char *name; enum wbcSidType type; const char **names = NULL; enum wbcSidType *types = NULL; obj_sid.sid_rev_num = dom_sid->sid_rev_num; obj_sid.num_auths = dom_sid->num_auths + 1; for (c = 0; c < 6; c++) { obj_sid.id_auth[c] = dom_sid->id_auth[c]; } for (c = 0; c < WBC_MAXSUBAUTHS; c++) { obj_sid.sub_auths[c] = dom_sid->sub_auths[c]; } names = wbcAllocateStringArray(num_rids + 1); if (names == NULL) { err = WBC_ERR_NO_MEMORY; goto done; } types = wbcAllocateMemory(num_rids + 1, sizeof(enum wbcSidType), NULL); if (types == NULL) { err = WBC_ERR_NO_MEMORY; goto done; } for (c = 0; c < num_rids; c++) { obj_sid.sub_auths[obj_sid.num_auths - 1] = rids[c]; err = wbcLookupSid(&obj_sid, &domain, &name, &type); if (err != WBC_ERR_SUCCESS) { goto done; } names[c] = strdup(name); wbcFreeMemory(name); if (names[c] == NULL) { err = WBC_ERR_NO_MEMORY; goto done; } types[c] = type; if (c == 0) { *pp_domain_name = domain; } else { wbcFreeMemory(domain); } } *pnames = names; *ptypes = types; err = WBC_ERR_SUCCESS; done: if (err != WBC_ERR_SUCCESS) { wbcFreeMemory(types); wbcFreeMemory(names); } return err; } /* Get the groups a user belongs to */ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, bool domain_groups_only, uint32_t *num_sids, struct wbcDomainSid **_sids) { WBC_SSSD_NOT_IMPLEMENTED; } /* Get alias membership for sids */ wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, struct wbcDomainSid *sids, uint32_t num_sids, uint32_t **alias_rids, uint32_t *num_alias_rids) { WBC_SSSD_NOT_IMPLEMENTED; } /* Lists Users */ wbcErr wbcListUsers(const char *domain_name, uint32_t *_num_users, const char ***_users) { WBC_SSSD_NOT_IMPLEMENTED; } /* Lists Groups */ wbcErr wbcListGroups(const char *domain_name, uint32_t *_num_groups, const char ***_groups) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcGetDisplayName(const struct wbcDomainSid *sid, char **pdomain, char **pfullname, enum wbcSidType *pname_type) { WBC_SSSD_NOT_IMPLEMENTED; } sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_err_internal.h0000644000000000000000000000007412703456111023250 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.594793425 sssd-1.13.4/src/sss_client/libwbclient/wbc_err_internal.h0000644002412700241270000000263712703456111024727 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API Copyright (C) Gerald (Jerry) Carter 2007 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef _WBC_ERR_INTERNAL_H #define _WBC_ERR_INTERNAL_H /* Private macros */ #define BAIL_ON_WBC_ERROR(x) \ do { \ if (!WBC_ERROR_IS_OK(x)) { \ goto done; \ } \ } while(0) #define BAIL_ON_PTR_ERROR(x, status) \ do { \ if ((x) == NULL) { \ status = WBC_ERR_NO_MEMORY; \ goto done; \ } else { \ status = WBC_ERR_SUCCESS; \ } \ } while (0) #endif /* _WBC_ERR_INTERNAL_H */ sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_pwd_sssd.c0000644000000000000000000000007412703456111022405 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.889794426 sssd-1.13.4/src/sss_client/libwbclient/wbc_pwd_sssd.c0000644002412700241270000003642212703456111024063 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API - SSSD version Copyright (C) Sumit Bose 2014 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include #include #include #include "libwbclient.h" #include "wbc_sssd_internal.h" #define DEFAULT_BUFSIZE_HALF 2048 #define DEFAULT_BUFSIZE (2 * DEFAULT_BUFSIZE_HALF) #define MAX_BUFSIZE (1024*1204) struct nss_ops_ctx { void *dl_handle; enum nss_status (*getpwnam_r)(const char *name, struct passwd *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*setpwent)(void); enum nss_status (*getpwent_r)(struct passwd *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*endpwent)(void); enum nss_status (*getgrnam_r)(const char *name, struct group *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*getgrgid_r)(gid_t gid, struct group *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*setgrent)(void); enum nss_status (*getgrent_r)(struct group *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*endgrent)(void); enum nss_status (*initgroups_dyn)(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop); }; struct nss_ops_ctx *ctx = NULL; static bool open_libnss_sss(void) { ctx = calloc(1, sizeof(struct nss_ops_ctx)); if (ctx == NULL) { return false; } ctx->dl_handle = dlopen("libnss_sss.so.2", RTLD_NOW); if (ctx->dl_handle == NULL) { goto fail; } ctx->getpwnam_r = dlsym(ctx->dl_handle, "_nss_sss_getpwnam_r"); if (ctx->getpwnam_r == NULL) { goto fail; } ctx->getpwuid_r = dlsym(ctx->dl_handle, "_nss_sss_getpwuid_r"); if (ctx->getpwuid_r == NULL) { goto fail; } ctx->setpwent = dlsym(ctx->dl_handle, "_nss_sss_setpwent"); if (ctx->setpwent == NULL) { goto fail; } ctx->getpwent_r = dlsym(ctx->dl_handle, "_nss_sss_getpwent_r"); if (ctx->getpwent_r == NULL) { goto fail; } ctx->endpwent = dlsym(ctx->dl_handle, "_nss_sss_endpwent"); if (ctx->endpwent == NULL) { goto fail; } ctx->getgrnam_r = dlsym(ctx->dl_handle, "_nss_sss_getgrnam_r"); if (ctx->getgrnam_r == NULL) { goto fail; } ctx->getgrgid_r = dlsym(ctx->dl_handle, "_nss_sss_getgrgid_r"); if (ctx->getgrgid_r == NULL) { goto fail; } ctx->setgrent = dlsym(ctx->dl_handle, "_nss_sss_setgrent"); if (ctx->setgrent == NULL) { goto fail; } ctx->getgrent_r = dlsym(ctx->dl_handle, "_nss_sss_getgrent_r"); if (ctx->getgrent_r == NULL) { goto fail; } ctx->endgrent = dlsym(ctx->dl_handle, "_nss_sss_endgrent"); if (ctx->endgrent == NULL) { goto fail; } ctx->initgroups_dyn = dlsym(ctx->dl_handle, "_nss_sss_initgroups_dyn"); if (ctx->initgroups_dyn == NULL) { goto fail; } return true; fail: if (ctx->dl_handle != NULL) { dlclose(ctx->dl_handle); } free(ctx); ctx = NULL; return false; } static void wbcPasswdDestructor(void *ptr) { struct passwd *pw = (struct passwd *)ptr; free(pw->pw_name); free(pw->pw_passwd); free(pw->pw_gecos); free(pw->pw_shell); free(pw->pw_dir); } static wbcErr copy_pwd(struct passwd *in, struct passwd **out) { struct passwd *pw; pw = (struct passwd *)wbcAllocateMemory(1, sizeof(struct passwd), wbcPasswdDestructor); if (pw == NULL) { return WBC_ERR_NO_MEMORY; } pw->pw_name = strdup(in->pw_name); if (pw->pw_name == NULL) { goto fail; } pw->pw_passwd = strdup(in->pw_passwd); if (pw->pw_passwd == NULL) { goto fail; } pw->pw_uid = in->pw_uid; pw->pw_gid = in->pw_gid; pw->pw_gecos = strdup(in->pw_gecos); if (pw->pw_gecos == NULL) { goto fail; } pw->pw_shell = strdup(in->pw_shell); if (pw->pw_shell == NULL) { goto fail; } pw->pw_dir = strdup(in->pw_dir); if (pw->pw_dir == NULL) { goto fail; } *out = pw; return WBC_ERR_SUCCESS; fail: wbcFreeMemory(pw); return WBC_ERR_NO_MEMORY; } static wbcErr nss_to_wbc(enum nss_status status) { wbcErr wbc_status; switch (status) { case NSS_STATUS_SUCCESS: wbc_status = WBC_ERR_SUCCESS; break; case NSS_STATUS_NOTFOUND: wbc_status = WBC_ERR_UNKNOWN_USER; break; case NSS_STATUS_UNAVAIL: wbc_status = WBC_ERR_WINBIND_NOT_AVAILABLE; break; default: wbc_status = WBC_ERR_UNKNOWN_FAILURE; } return wbc_status; } /* Fill in a struct passwd* for a domain user based on username */ wbcErr wbcGetpwnam(const char *name, struct passwd **pwd) { struct passwd lpwd = {0}; enum nss_status status; char *buffer = NULL; size_t buflen; wbcErr wbc_status; int nss_errno; if (ctx == NULL && !open_libnss_sss()) { return WBC_ERR_NSS_ERROR; } if (name == NULL || pwd == NULL) { return WBC_ERR_INVALID_PARAM; } buflen = DEFAULT_BUFSIZE; buffer = malloc(buflen); if (buffer == NULL) { return WBC_ERR_NO_MEMORY; } status = ctx->getpwnam_r(name, &lpwd, buffer, buflen, &nss_errno); wbc_status = nss_to_wbc(status); if (WBC_ERROR_IS_OK(wbc_status) == true) { wbc_status = copy_pwd(&lpwd, pwd); } free(buffer); return wbc_status; } /* Fill in a struct passwd* for a domain user based on uid */ wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd) { struct passwd lpwd = {0}; enum nss_status status; char *buffer = NULL; size_t buflen; wbcErr wbc_status; int nss_errno; if (ctx == NULL && !open_libnss_sss()) { return WBC_ERR_NSS_ERROR; } if (pwd == NULL) { return WBC_ERR_INVALID_PARAM; } buflen = DEFAULT_BUFSIZE; buffer = malloc(buflen); if (buffer == NULL) { return WBC_ERR_NO_MEMORY; } status = ctx->getpwuid_r(uid, &lpwd, buffer, buflen, &nss_errno); wbc_status = nss_to_wbc(status); if (WBC_ERROR_IS_OK(wbc_status) == true) { wbc_status = copy_pwd(&lpwd, pwd); } free(buffer); return wbc_status; } /* Fill in a struct passwd* for a domain user based on sid */ wbcErr wbcGetpwsid(struct wbcDomainSid *sid, struct passwd **pwd) { wbcErr wbc_status; uid_t uid; wbc_status = wbcSidToUid(sid, &uid); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } wbc_status = wbcGetpwuid(uid, pwd); return wbc_status; } static void wbcGroupDestructor(void *ptr) { struct group *gr = (struct group *)ptr; size_t c; free(gr->gr_name); free(gr->gr_passwd); /* if the array was partly created this can be NULL */ if (gr->gr_mem == NULL) { return; } for (c=0; gr->gr_mem[c] != NULL; c++) { free(gr->gr_mem[c]); } free(gr->gr_mem); } static wbcErr copy_grp(struct group *in, struct group **out) { struct group *gr; size_t members; size_t c; gr = (struct group *)wbcAllocateMemory(1, sizeof(struct group), wbcGroupDestructor); if (gr == NULL) { return WBC_ERR_NO_MEMORY; } gr->gr_name = strdup(in->gr_name); if (gr->gr_name == NULL) { goto fail; } gr->gr_passwd = strdup(in->gr_passwd); if (gr->gr_passwd == NULL) { goto fail; } gr->gr_gid = in->gr_gid; for (members = 0; in->gr_mem[members] != NULL; members++); gr->gr_mem = (char **)calloc(members+1, sizeof(char *)); if (gr->gr_mem == NULL) { goto fail; } for (c = 0; c < members; c++) { gr->gr_mem[c] = strdup(in->gr_mem[c]); if (gr->gr_mem[c] == NULL) { goto fail; } } *out = gr; return WBC_ERR_SUCCESS; fail: wbcFreeMemory(gr); return WBC_ERR_NO_MEMORY; } /* Fill in a struct passwd* for a domain user based on username */ wbcErr wbcGetgrnam(const char *name, struct group **grp) { struct group lgrp; enum nss_status status; char *newbuffer = NULL; char *buffer = NULL; size_t buflen = 0; wbcErr wbc_status; int nss_errno; if (ctx == NULL && !open_libnss_sss()) { return WBC_ERR_NSS_ERROR; } if (name == NULL || grp == NULL) { return WBC_ERR_INVALID_PARAM; } buflen = DEFAULT_BUFSIZE_HALF; do { buflen *= 2; newbuffer = realloc(buffer, buflen); if (newbuffer == NULL) { free(buffer); return WBC_ERR_NO_MEMORY; } buffer = newbuffer; memset(grp, 0, sizeof(struct group)); status = ctx->getgrnam_r(name, &lgrp, buffer, buflen, &nss_errno); wbc_status = nss_to_wbc(status); if (WBC_ERROR_IS_OK(wbc_status) == true) { wbc_status = copy_grp(&lgrp, grp); } } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \ && buflen < MAX_BUFSIZE); free(buffer); return wbc_status; } /* Fill in a struct passwd* for a domain user based on uid */ wbcErr wbcGetgrgid(gid_t gid, struct group **grp) { struct group lgrp; enum nss_status status; char *newbuffer = NULL; char *buffer = NULL; size_t buflen = 0; wbcErr wbc_status; int nss_errno; if (ctx == NULL && !open_libnss_sss()) { return WBC_ERR_NSS_ERROR; } if (grp == NULL) { return WBC_ERR_INVALID_PARAM; } buflen = DEFAULT_BUFSIZE_HALF; do { buflen *= 2; newbuffer = realloc(buffer, buflen); if (newbuffer == NULL) { free(buffer); return WBC_ERR_NO_MEMORY; } buffer = newbuffer; memset(grp, 0, sizeof(struct group)); status = ctx->getgrgid_r(gid, &lgrp, buffer, buflen, &nss_errno); wbc_status = nss_to_wbc(status); if (WBC_ERROR_IS_OK(wbc_status) == true) { wbc_status = copy_grp(&lgrp, grp); } } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \ && buflen < MAX_BUFSIZE); free(buffer); return wbc_status; } /* Reset the passwd iterator */ wbcErr wbcSetpwent(void) { enum nss_status status; wbcErr wbc_status; if (ctx == NULL && !open_libnss_sss()) { return WBC_ERR_NSS_ERROR; } status = ctx->setpwent(); wbc_status = nss_to_wbc(status); return wbc_status; } /* Close the passwd iterator */ wbcErr wbcEndpwent(void) { enum nss_status status; wbcErr wbc_status; if (ctx == NULL && !open_libnss_sss()) { return WBC_ERR_NSS_ERROR; } status = ctx->endpwent(); wbc_status = nss_to_wbc(status); return wbc_status; } /* Return the next struct passwd* entry from the pwent iterator */ wbcErr wbcGetpwent(struct passwd **pwd) { struct passwd lpwd = {0}; enum nss_status status; char *buffer = NULL; size_t buflen; wbcErr wbc_status; int nss_errno; if (ctx == NULL && !open_libnss_sss()) { return WBC_ERR_NSS_ERROR; } if (pwd == NULL) { return WBC_ERR_INVALID_PARAM; } buflen = DEFAULT_BUFSIZE; buffer = malloc(buflen); if (buffer == NULL) { return WBC_ERR_NO_MEMORY; } status = ctx->getpwent_r(&lpwd, buffer, buflen, &nss_errno); wbc_status = nss_to_wbc(status); if (WBC_ERROR_IS_OK(wbc_status) == true) { wbc_status = copy_pwd(&lpwd, pwd); } free(buffer); return wbc_status; } /* Reset the group iterator */ wbcErr wbcSetgrent(void) { enum nss_status status; wbcErr wbc_status; if (ctx == NULL && !open_libnss_sss()) { return WBC_ERR_NSS_ERROR; } status = ctx->setgrent(); wbc_status = nss_to_wbc(status); return wbc_status; } /* Close the group iterator */ wbcErr wbcEndgrent(void) { enum nss_status status; wbcErr wbc_status; if (ctx == NULL && !open_libnss_sss()) { return WBC_ERR_NSS_ERROR; } status = ctx->endgrent(); wbc_status = nss_to_wbc(status); return wbc_status; } /* Return the next struct group* entry from the pwent iterator */ wbcErr wbcGetgrent(struct group **grp) { struct group lgrp; enum nss_status status; char *newbuffer = NULL; char *buffer = NULL; size_t buflen = 0; wbcErr wbc_status; int nss_errno; if (ctx == NULL && !open_libnss_sss()) { return WBC_ERR_NSS_ERROR; } if (grp == NULL) { return WBC_ERR_INVALID_PARAM; } buflen = DEFAULT_BUFSIZE_HALF; do { buflen *= 2; newbuffer = realloc(buffer, buflen); if (newbuffer == NULL) { free(buffer); return WBC_ERR_NO_MEMORY; } buffer = newbuffer; memset(grp, 0, sizeof(struct group)); status = ctx->getgrent_r(&lgrp, buffer, buflen, &nss_errno); wbc_status = nss_to_wbc(status); if (WBC_ERROR_IS_OK(wbc_status) == true) { wbc_status = copy_grp(&lgrp, grp); } } while (status == NSS_STATUS_TRYAGAIN && nss_errno == ERANGE \ && buflen < MAX_BUFSIZE); free(buffer); return wbc_status; } /* Return the next struct group* entry from the pwent iterator */ wbcErr wbcGetgrlist(struct group **grp) { /* Not used anywhere */ WBC_SSSD_NOT_IMPLEMENTED; } /* Return the unix group array belonging to the given user */ wbcErr wbcGetGroups(const char *account, uint32_t *num_groups, gid_t **_groups) { wbcErr wbc_status; enum nss_status status; struct passwd *pwd; long int gr_size = 0; long int start = 0; gid_t *gids = NULL; int nss_errno; wbc_status = wbcGetpwnam(account, &pwd); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } gr_size = DEFAULT_BUFSIZE; gids = calloc(gr_size, sizeof(gid_t)); if (gids == NULL) { wbc_status = WBC_ERR_NO_MEMORY; goto done; } /* nss modules may skip the primary group when we pass it in so always * add it in advance */ gids[0] = pwd->pw_gid; start++; status = ctx->initgroups_dyn(pwd->pw_name, pwd->pw_gid, &start, &gr_size, &gids, -1, &nss_errno); wbc_status = nss_to_wbc(status); if (!WBC_ERROR_IS_OK(wbc_status)) { goto done; } *_groups = gids; *num_groups = start; wbc_status = WBC_ERR_SUCCESS; done: wbcFreeMemory(pwd); if (!WBC_ERROR_IS_OK(wbc_status)) { free(gids); } return wbc_status; } sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_ctx_sssd.c0000644000000000000000000000007412703456111022411 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.894794443 sssd-1.13.4/src/sss_client/libwbclient/wbc_ctx_sssd.c0000644002412700241270000002345612703456111024072 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API - SSSD version Copyright (C) Sumit Bose 2015 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include "config.h" #include "libwbclient.h" #include "wbc_sssd_internal.h" struct wbcContext *wbcCtxCreate(void) { WBC_SSSD_DEV_LOG; return NULL; } void wbcCtxFree(struct wbcContext *ctx) { WBC_SSSD_DEV_LOG; return; } wbcErr wbcCtxPing(struct wbcContext *ctx) { WBC_SSSD_NOT_IMPLEMENTED; } struct wbcContext *wbcGetGlobalCtx(void) { WBC_SSSD_DEV_LOG; return NULL; } wbcErr wbcCtxInterfaceDetails(struct wbcContext *ctx, struct wbcInterfaceDetails **details) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxLookupName(struct wbcContext *ctx, const char *dom_name, const char *name, struct wbcDomainSid *sid, enum wbcSidType *name_type) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxLookupSid(struct wbcContext *ctx, const struct wbcDomainSid *sid, char **domain, char **name, enum wbcSidType *name_type) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxLookupSids(struct wbcContext *ctx, const struct wbcDomainSid *sids, int num_sids, struct wbcDomainInfo **domains, int *num_domains, struct wbcTranslatedName **names) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxLookupRids(struct wbcContext *ctx, struct wbcDomainSid *dom_sid, int num_rids, uint32_t *rids, const char **domain_name, const char ***names, enum wbcSidType **types) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxLookupUserSids(struct wbcContext *ctx, const struct wbcDomainSid *user_sid, bool domain_groups_only, uint32_t *num_sids, struct wbcDomainSid **sids) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGetSidAliases(struct wbcContext *ctx, const struct wbcDomainSid *dom_sid, struct wbcDomainSid *sids, uint32_t num_sids, uint32_t **alias_rids, uint32_t *num_alias_rids) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxListUsers(struct wbcContext *ctx, const char *domain_name, uint32_t *num_users, const char ***users) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxListGroups(struct wbcContext *ctx, const char *domain_name, uint32_t *num_groups, const char ***groups) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGetDisplayName(struct wbcContext *ctx, const struct wbcDomainSid *sid, char **pdomain, char **pfullname, enum wbcSidType *pname_type) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxSidToUid(struct wbcContext *ctx, const struct wbcDomainSid *sid, uid_t *puid) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxUidToSid(struct wbcContext *ctx, uid_t uid, struct wbcDomainSid *sid) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxSidToGid(struct wbcContext *ctx, const struct wbcDomainSid *sid, gid_t *pgid) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGidToSid(struct wbcContext *ctx, gid_t gid, struct wbcDomainSid *sid) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxSidsToUnixIds(struct wbcContext *ctx, const struct wbcDomainSid *sids, uint32_t num_sids, struct wbcUnixId *ids) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxAllocateUid(struct wbcContext *ctx, uid_t *puid) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxAllocateGid(struct wbcContext *ctx, gid_t *pgid) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGetpwnam(struct wbcContext *ctx, const char *name, struct passwd **pwd) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGetpwuid(struct wbcContext *ctx, uid_t uid, struct passwd **pwd) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGetpwsid(struct wbcContext *ctx, struct wbcDomainSid * sid, struct passwd **pwd) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGetgrnam(struct wbcContext *ctx, const char *name, struct group **grp) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGetgrgid(struct wbcContext *ctx, gid_t gid, struct group **grp) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxSetpwent(struct wbcContext *ctx) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxEndpwent(struct wbcContext *ctx) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGetpwent(struct wbcContext *ctx, struct passwd **pwd) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxSetgrent(struct wbcContext *ctx) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxEndgrent(struct wbcContext *ctx) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGetgrent(struct wbcContext *ctx, struct group **grp) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGetgrlist(struct wbcContext *ctx, struct group **grp) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxGetGroups(struct wbcContext *ctx, const char *account, uint32_t *num_groups, gid_t **_groups) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxDomainInfo(struct wbcContext *ctx, const char *domain, struct wbcDomainInfo **dinfo) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxDcInfo(struct wbcContext *ctx, const char *domain, size_t *num_dcs, const char ***dc_names, const char ***dc_ips) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxListTrusts(struct wbcContext *ctx, struct wbcDomainInfo **domains, size_t *num_domains) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxLookupDomainController(struct wbcContext *ctx, const char *domain, uint32_t flags, struct wbcDomainControllerInfo **dc_info) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxLookupDomainControllerEx(struct wbcContext *ctx, const char *domain, struct wbcGuid *guid, const char *site, uint32_t flags, struct wbcDomainControllerInfoEx **dc_info) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxAuthenticateUser(struct wbcContext *ctx, const char *username, const char *password) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxAuthenticateUserEx(struct wbcContext *ctx, const struct wbcAuthUserParams *params, struct wbcAuthUserInfo **info, struct wbcAuthErrorInfo **error) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxLogonUser(struct wbcContext *ctx, const struct wbcLogonUserParams *params, struct wbcLogonUserInfo **info, struct wbcAuthErrorInfo **error, struct wbcUserPasswordPolicyInfo **policy) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxLogoffUser(struct wbcContext *ctx, const char *username, uid_t uid, const char *ccfilename) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxLogoffUserEx(struct wbcContext *ctx, const struct wbcLogoffUserParams *params, struct wbcAuthErrorInfo **error) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxChangeUserPassword(struct wbcContext *ctx, const char *username, const char *old_password, const char *new_password) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxChangeUserPasswordEx(struct wbcContext *ctx, const struct wbcChangePasswordParams *params, struct wbcAuthErrorInfo **error, enum wbcPasswordChangeRejectReason *reject_reason, struct wbcUserPasswordPolicyInfo **policy) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxCredentialCache(struct wbcContext *ctx, struct wbcCredentialCacheParams *params, struct wbcCredentialCacheInfo **info, struct wbcAuthErrorInfo **error) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxCredentialSave(struct wbcContext *ctx, const char *user, const char *password) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxResolveWinsByName(struct wbcContext *ctx, const char *name, char **ip) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxResolveWinsByIP(struct wbcContext *ctx, const char *ip, char **name) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxCheckTrustCredentials(struct wbcContext *ctx, const char *domain, struct wbcAuthErrorInfo **error) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxChangeTrustCredentials(struct wbcContext *ctx, const char *domain, struct wbcAuthErrorInfo **error) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxPingDc(struct wbcContext *ctx, const char *domain, struct wbcAuthErrorInfo **error) { WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcCtxPingDc2(struct wbcContext *ctx, const char *domain, struct wbcAuthErrorInfo **error, char **dcname) { WBC_SSSD_NOT_IMPLEMENTED; } sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_sssd_internal.h0000644000000000000000000000007412703456111023434 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.596793432 sssd-1.13.4/src/sss_client/libwbclient/wbc_sssd_internal.h0000644002412700241270000000227712703456111025113 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API - SSSD version Copyright (C) Sumit Bose 2014 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef _WBC_SSSD_INTERNAL_H #define _WBC_SSSD_INTERNAL_H #include #include "libwbclient.h" #if defined(DEVELOPER) #define WBC_SSSD_DEV_LOG syslog(LOG_DEBUG, "libwbclient_sssd: %s", __FUNCTION__); #else #define WBC_SSSD_DEV_LOG #endif #define WBC_SSSD_NOT_IMPLEMENTED \ do { \ WBC_SSSD_DEV_LOG; \ return WBC_ERR_NOT_IMPLEMENTED; \ } while(0) #endif /* _WBC_SSSD_INTERNAL_H */ sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/libwbclient.h0000644000000000000000000000007412703456111022227 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.593793422 sssd-1.13.4/src/sss_client/libwbclient/libwbclient.h0000644002412700241270000000237312703456111023703 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API Copyright (C) Gerald (Jerry) Carter 2007 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef _LIBWBCLIENT_H #define _LIBWBCLIENT_H #include #include #include #include #include /* Super header including necessary public and private header files for building the wbclient library. __DO NOT__ define anything in this file. Only include other headers. */ /* Public headers */ #include "wbclient_sssd.h" /* Private headers */ #include "wbc_err_internal.h" #include "wbclient_internal.h" #endif /* _LIBWBCLIENT_H */ sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_util_sssd.c0000644000000000000000000000007412703456111022570 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.893794439 sssd-1.13.4/src/sss_client/libwbclient/wbc_util_sssd.c0000644002412700241270000001040012703456111024232 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API - SSSD version Copyright (C) Sumit Bose 2014 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include "libwbclient.h" #include "wbc_sssd_internal.h" #define WINBIND_INTERFACE_VERSION 27 /** @brief Ping winbindd to see if the daemon is running * * @return #wbcErr **/ wbcErr wbcPing(void) { /* TODO: add real check */ return WBC_ERR_SUCCESS; } static void wbcInterfaceDetailsDestructor(void *ptr) { struct wbcInterfaceDetails *i = (struct wbcInterfaceDetails *)ptr; free(i->winbind_version); free(i->netbios_name); free(i->netbios_domain); free(i->dns_domain); } /** * @brief Query useful information about the winbind service * * @param *_details pointer to hold the struct wbcInterfaceDetails * * @return #wbcErr */ wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcInterfaceDetails *info; info = (struct wbcInterfaceDetails *)wbcAllocateMemory( 1, sizeof(struct wbcInterfaceDetails), wbcInterfaceDetailsDestructor); if (info == NULL) { return WBC_ERR_NO_MEMORY; } /* TODO: currently this call just returns a suitable winbind_separator * for wbinfo. */ info->interface_version = WINBIND_INTERFACE_VERSION; info->winbind_version = strdup("libwbclient for SSSD"); if (info->winbind_version == NULL) { wbc_status = WBC_ERR_NO_MEMORY; goto done; } info->winbind_separator = '\\'; info->netbios_name = strdup("-not available-"); if (info->netbios_name == NULL) { wbc_status = WBC_ERR_NO_MEMORY; goto done; } info->netbios_domain = strdup("-not available-"); if (info->netbios_domain == NULL) { wbc_status = WBC_ERR_NO_MEMORY; goto done; } info->dns_domain = strdup("-not available-"); if (info->dns_domain == NULL) { wbc_status = WBC_ERR_NO_MEMORY; goto done; } *_details = info; info = NULL; wbc_status = WBC_ERR_SUCCESS; done: wbcFreeMemory(info); return wbc_status; } /** @brief Lookup the current status of a trusted domain, sync wrapper * * @param domain Domain to query * @param *dinfo Pointer to returned struct wbcDomainInfo * * @return #wbcErr */ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo) { WBC_SSSD_NOT_IMPLEMENTED; } /* Get the list of current DCs */ wbcErr wbcDcInfo(const char *domain, size_t *num_dcs, const char ***dc_names, const char ***dc_ips) { WBC_SSSD_NOT_IMPLEMENTED; } /* Resolve a NetbiosName via WINS */ wbcErr wbcResolveWinsByName(const char *name, char **ip) { /* SSSD does not support WINS */ WBC_SSSD_NOT_IMPLEMENTED; } /* Resolve an IP address via WINS into a NetbiosName */ wbcErr wbcResolveWinsByIP(const char *ip, char **name) { /* SSSD does not support WINS */ WBC_SSSD_NOT_IMPLEMENTED; } /* Enumerate the domain trusts known by Winbind */ wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains) { WBC_SSSD_NOT_IMPLEMENTED; } /* Enumerate the domain trusts known by Winbind */ wbcErr wbcLookupDomainController(const char *domain, uint32_t flags, struct wbcDomainControllerInfo **dc_info) { WBC_SSSD_NOT_IMPLEMENTED; } /* Get extended domain controller information */ wbcErr wbcLookupDomainControllerEx(const char *domain, struct wbcGuid *guid, const char *site, uint32_t flags, struct wbcDomainControllerInfoEx **dc_info) { WBC_SSSD_NOT_IMPLEMENTED; } sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_pam_sssd.c0000644000000000000000000000007412703456111022370 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.889794426 sssd-1.13.4/src/sss_client/libwbclient/wbc_pam_sssd.c0000644002412700241270000001163712703456111024047 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API - SSSD version Copyright (C) Sumit Bose 2014 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include "libwbclient.h" #include "wbc_sssd_internal.h" /* Authenticate a username/password pair */ wbcErr wbcAuthenticateUser(const char *username, const char *password) { wbcErr wbc_status = WBC_ERR_SUCCESS; struct wbcAuthUserParams params = {0}; params.account_name = username; params.level = WBC_AUTH_USER_LEVEL_PLAIN; params.password.plaintext = password; wbc_status = wbcAuthenticateUserEx(¶ms, NULL, NULL); return wbc_status; } /* Authenticate with more detailed information */ wbcErr wbcAuthenticateUserEx(const struct wbcAuthUserParams *params, struct wbcAuthUserInfo **info, struct wbcAuthErrorInfo **error) { if (error != NULL) { *error = NULL; } WBC_SSSD_NOT_IMPLEMENTED; } /* Trigger a verification of the trust credentials of a specific domain */ wbcErr wbcCheckTrustCredentials(const char *domain, struct wbcAuthErrorInfo **error) { if (error != NULL) { *error = NULL; } WBC_SSSD_NOT_IMPLEMENTED; } /* Trigger a change of the trust credentials for a specific domain */ wbcErr wbcChangeTrustCredentials(const char *domain, struct wbcAuthErrorInfo **error) { if (error != NULL) { *error = NULL; } WBC_SSSD_NOT_IMPLEMENTED; } /* * Trigger a no-op NETLOGON call. Lightweight version of * wbcCheckTrustCredentials */ wbcErr wbcPingDc(const char *domain, struct wbcAuthErrorInfo **error) { return wbcPingDc2(domain, error, NULL); } /* * Trigger a no-op NETLOGON call. Lightweight version of * wbcCheckTrustCredentials, optionally return attempted DC */ wbcErr wbcPingDc2(const char *domain, struct wbcAuthErrorInfo **error, char **dcname) { WBC_SSSD_NOT_IMPLEMENTED; } /* Trigger an extended logoff notification to Winbind for a specific user */ wbcErr wbcLogoffUserEx(const struct wbcLogoffUserParams *params, struct wbcAuthErrorInfo **error) { WBC_SSSD_NOT_IMPLEMENTED; } /* Trigger a logoff notification to Winbind for a specific user */ wbcErr wbcLogoffUser(const char *username, uid_t uid, const char *ccfilename) { WBC_SSSD_NOT_IMPLEMENTED; } /* Change a password for a user with more detailed information upon failure */ wbcErr wbcChangeUserPasswordEx(const struct wbcChangePasswordParams *params, struct wbcAuthErrorInfo **error, enum wbcPasswordChangeRejectReason *reject_reason, struct wbcUserPasswordPolicyInfo **policy) { if (error != NULL) { *error = NULL; } if (policy != NULL) { *policy = NULL; } WBC_SSSD_NOT_IMPLEMENTED; } /* Change a password for a user */ wbcErr wbcChangeUserPassword(const char *username, const char *old_password, const char *new_password) { wbcErr wbc_status = WBC_ERR_SUCCESS; struct wbcChangePasswordParams params = {0}; params.account_name = username; params.level = WBC_CHANGE_PASSWORD_LEVEL_PLAIN; params.old_password.plaintext = old_password; params.new_password.plaintext = new_password; wbc_status = wbcChangeUserPasswordEx(¶ms, NULL, NULL, NULL); return wbc_status; } /* Logon a User */ wbcErr wbcLogonUser(const struct wbcLogonUserParams *params, struct wbcLogonUserInfo **info, struct wbcAuthErrorInfo **error, struct wbcUserPasswordPolicyInfo **policy) { if (info != NULL) { *info = NULL; } if (error != NULL) { *error = NULL; } if (policy != NULL) { *policy = NULL; } WBC_SSSD_NOT_IMPLEMENTED; } /* Authenticate a user with cached credentials */ wbcErr wbcCredentialCache(struct wbcCredentialCacheParams *params, struct wbcCredentialCacheInfo **info, struct wbcAuthErrorInfo **error) { if (error != NULL) { *error = NULL; } WBC_SSSD_NOT_IMPLEMENTED; } /* Authenticate a user with cached credentials */ wbcErr wbcCredentialSave(const char *user, const char *password) { WBC_SSSD_NOT_IMPLEMENTED; } sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbclient_sssd.c0000644000000000000000000000007412703456111022567 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.888794422 sssd-1.13.4/src/sss_client/libwbclient/wbclient_sssd.c0000644002412700241270000000243112703456111024236 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API - SSSD version Copyright (C) Sumit Bose 2014 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include "libwbclient.h" #include "wbc_sssd_internal.h" wbcErr wbcRequestResponse(int cmd, struct winbindd_request *request, struct winbindd_response *response) { /* Helper to make API check happy */ WBC_SSSD_NOT_IMPLEMENTED; } wbcErr wbcRequestResponsePriv(int cmd, struct winbindd_request *request, struct winbindd_response *response) { /* Helper to make API check happy */ WBC_SSSD_NOT_IMPLEMENTED; } sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbclient.exports0000644000000000000000000000007412703456111023015 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.372792673 sssd-1.13.4/src/sss_client/libwbclient/wbclient.exports0000644002412700241270000000672112703456111024472 0ustar00jhrozekjhrozek00000000000000WBCLIENT_0.9 { global: wbcGetpwuid; wbcLogoffUser; wbcSidToStringBuf; wbcLogonUser; wbcGetgrgid; wbcSetGidMapping; wbcQueryGidToSid; wbcListTrusts; wbcGetGroups; wbcDomainInfo; wbcSidToGid; wbcLookupRids; wbcCredentialCache; wbcDcInfo; wbcAuthenticateUserEx; wbcGetpwent; wbcGetSidAliases; wbcGetDisplayName; wbcAllocateUid; wbcSidToUid; wbcChangeTrustCredentials; wbcGetpwsid; wbcPingDc; wbcAllocateStringArray; wbcErrorString; wbcStringToGuid; wbcStrDup; wbcGetgrnam; wbcGetgrlist; wbcListUsers; wbcRemoveUidMapping; wbcLookupDomainController; wbcRemoveGidMapping; wbcSidTypeString; wbcAllocateMemory; wbcInterfaceDetails; wbcCheckTrustCredentials; wbcListGroups; wbcLookupUserSids; wbcResolveWinsByName; wbcSetpwent; wbcSetUidHwm; wbcSidsToUnixIds; wbcQuerySidToGid; wbcChangeUserPasswordEx; wbcPing; wbcQueryUidToSid; wbcEndpwent; wbcLibraryDetails; wbcSetgrent; wbcLookupName; wbcChangeUserPassword; wbcSetGidHwm; wbcAddNamedBlob; wbcGuidToString; wbcLookupSids; wbcRequestResponsePriv; wbcAllocateGid; wbcFreeMemory; wbcResolveWinsByIP; wbcRequestResponse; wbcStringToSid; wbcLookupSid; wbcCredentialSave; wbcGidToSid; wbcQuerySidToUid; wbcEndgrent; wbcGetgrent; wbcAuthenticateUser; wbcGetpwnam; wbcLookupDomainControllerEx; wbcLogoffUserEx; wbcSetUidMapping; wbcSidToString; wbcUidToSid; }; WBCLIENT_0.10 { global: wbcPingDc2; } WBCLIENT_0.9; WBCLIENT_0.11 { local: *; } WBCLIENT_0.10; WBCLIENT_0.12 { global: wbcCtxCreate; wbcCtxFree; wbcGetGlobalCtx; wbcCtxPing; wbcCtxInterfaceDetails; wbcCtxLookupName; wbcCtxLookupSid; wbcCtxLookupSids; wbcCtxLookupRids; wbcCtxLookupUserSids; wbcCtxGetSidAliases; wbcCtxListUsers; wbcCtxListGroups; wbcCtxGetDisplayName; wbcCtxSidToUid; wbcCtxUidToSid; wbcCtxSidToGid; wbcCtxGidToSid; wbcCtxSidsToUnixIds; wbcCtxAllocateUid; wbcCtxAllocateGid; wbcCtxGetpwnam; wbcCtxGetpwuid; wbcCtxGetpwsid; wbcCtxGetgrnam; wbcCtxGetgrgid; wbcCtxSetpwent; wbcCtxEndpwent; wbcCtxGetpwent; wbcCtxSetgrent; wbcCtxEndgrent; wbcCtxGetgrent; wbcCtxGetgrlist; wbcCtxGetGroups; wbcCtxDomainInfo; wbcCtxDcInfo; wbcCtxListTrusts; wbcCtxLookupDomainController; wbcCtxLookupDomainControllerEx; wbcCtxAuthenticateUser; wbcCtxAuthenticateUserEx; wbcCtxLogonUser; wbcCtxLogoffUser; wbcCtxLogoffUserEx; wbcCtxChangeUserPassword; wbcCtxChangeUserPasswordEx; wbcCtxCredentialCache; wbcCtxCredentialSave; wbcCtxResolveWinsByName; wbcCtxResolveWinsByIP; wbcCtxCheckTrustCredentials; wbcCtxChangeTrustCredentials; wbcCtxPingDc; wbcCtxPingDc2; } WBCLIENT_0.11; sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_guid.c0000644000000000000000000000007412703456111021507 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.884794409 sssd-1.13.4/src/sss_client/libwbclient/wbc_guid.c0000644002412700241270000000567112703456111023167 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API Copyright (C) Gerald (Jerry) Carter 2007 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include "libwbclient.h" /* Convert a binary GUID to a character string */ wbcErr wbcGuidToString(const struct wbcGuid *guid, char **guid_string) { char *result; result = (char *)wbcAllocateMemory(37, 1, NULL); if (result == NULL) { return WBC_ERR_NO_MEMORY; } snprintf(result, 37, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid->time_low, guid->time_mid, guid->time_hi_and_version, guid->clock_seq[0], guid->clock_seq[1], guid->node[0], guid->node[1], guid->node[2], guid->node[3], guid->node[4], guid->node[5]); *guid_string = result; return WBC_ERR_SUCCESS; } /* @brief Convert a character string to a binary GUID */ wbcErr wbcStringToGuid(const char *str, struct wbcGuid *guid) { uint32_t time_low; uint32_t time_mid, time_hi_and_version; uint32_t clock_seq[2]; uint32_t node[6]; int i; wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; if (!guid) { wbc_status = WBC_ERR_INVALID_PARAM; BAIL_ON_WBC_ERROR(wbc_status); } if (!str) { wbc_status = WBC_ERR_INVALID_PARAM; BAIL_ON_WBC_ERROR(wbc_status); } if (11 == sscanf(str, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", &time_low, &time_mid, &time_hi_and_version, &clock_seq[0], &clock_seq[1], &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) { wbc_status = WBC_ERR_SUCCESS; } else if (11 == sscanf(str, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}", &time_low, &time_mid, &time_hi_and_version, &clock_seq[0], &clock_seq[1], &node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) { wbc_status = WBC_ERR_SUCCESS; } BAIL_ON_WBC_ERROR(wbc_status); guid->time_low = time_low; guid->time_mid = time_mid; guid->time_hi_and_version = time_hi_and_version; guid->clock_seq[0] = clock_seq[0]; guid->clock_seq[1] = clock_seq[1]; for (i=0;i<6;i++) { guid->node[i] = node[i]; } wbc_status = WBC_ERR_SUCCESS; done: return wbc_status; } sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_idmap_sssd.c0000644000000000000000000000007412703456111022705 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.886794415 sssd-1.13.4/src/sss_client/libwbclient/wbc_idmap_sssd.c0000644002412700241270000001175212703456111024362 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API - SSSD version Copyright (C) Sumit Bose 2014 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include "sss_client/idmap/sss_nss_idmap.h" #include "libwbclient.h" #include "wbc_sssd_internal.h" /* Convert a Windows SID to a Unix uid, allocating an uid if needed */ wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid) { int ret; char *sid_str; uint32_t id; enum sss_id_type type; wbcErr wbc_status; wbc_status = wbcSidToString(sid, &sid_str); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } ret = sss_nss_getidbysid(sid_str, &id, &type); wbcFreeMemory(sid_str); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } if (type != SSS_ID_TYPE_UID && type != SSS_ID_TYPE_BOTH) { return WBC_ERR_UNKNOWN_GROUP; } *puid = (uid_t) id; return WBC_ERR_SUCCESS; } /* Convert a Unix uid to a Windows SID, allocating a SID if needed */ wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid) { int ret; char *str_sid; enum sss_id_type type; wbcErr wbc_status; ret = sss_nss_getsidbyid(uid, &str_sid, &type); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } if (type != SSS_ID_TYPE_UID && type != SSS_ID_TYPE_BOTH) { free(str_sid); return WBC_ERR_UNKNOWN_USER; } wbc_status = wbcStringToSid(str_sid, sid); free(str_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } return WBC_ERR_SUCCESS; } /** @brief Convert a Windows SID to a Unix gid, allocating a gid if needed * * @param *sid Pointer to the domain SID to be resolved * @param *pgid Pointer to the resolved gid_t value * * @return #wbcErr * **/ wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid) { int ret; char *sid_str; uint32_t id; enum sss_id_type type; wbcErr wbc_status; wbc_status = wbcSidToString(sid, &sid_str); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } ret = sss_nss_getidbysid(sid_str, &id, &type); wbcFreeMemory(sid_str); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } if (type != SSS_ID_TYPE_GID && type != SSS_ID_TYPE_BOTH) { return WBC_ERR_UNKNOWN_GROUP; } *pgid = (gid_t) id; return WBC_ERR_SUCCESS; } /* Convert a Unix gid to a Windows SID, allocating a SID if needed */ wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid) { int ret; char *str_sid; enum sss_id_type type; wbcErr wbc_status; ret = sss_nss_getsidbyid(gid, &str_sid, &type); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } if (type != SSS_ID_TYPE_GID && type != SSS_ID_TYPE_BOTH) { free(str_sid); return WBC_ERR_UNKNOWN_USER; } wbc_status = wbcStringToSid(str_sid, sid); free(str_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } return WBC_ERR_SUCCESS; } /* Obtain a new uid from Winbind */ wbcErr wbcAllocateUid(uid_t *puid) { /* Not supported by SSSD */ WBC_SSSD_NOT_IMPLEMENTED; } /* Obtain a new gid from Winbind */ wbcErr wbcAllocateGid(gid_t *pgid) { /* Not supported by SSSD */ WBC_SSSD_NOT_IMPLEMENTED; } /* Convert a list of SIDs */ wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids, struct wbcUnixId *ids) { int ret; char *sid_str; uint32_t id; enum sss_id_type type; size_t c; wbcErr wbc_status; for (c = 0; c < num_sids; c++) { wbc_status = wbcSidToString(&sids[c], &sid_str); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } ret = sss_nss_getidbysid(sid_str, &id, &type); wbcFreeMemory(sid_str); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } switch (type) { case SSS_ID_TYPE_UID: ids[c].type = WBC_ID_TYPE_UID; ids[c].id.uid = (uid_t) id; break; case SSS_ID_TYPE_GID: ids[c].type = WBC_ID_TYPE_GID; ids[c].id.gid = (gid_t) id; break; case SSS_ID_TYPE_BOTH: ids[c].type = WBC_ID_TYPE_BOTH; ids[c].id.uid = (uid_t) id; break; default: ids[c].type = WBC_ID_TYPE_NOT_SPECIFIED; } } return WBC_ERR_SUCCESS; } sssd-1.13.4/src/sss_client/libwbclient/PaxHeaders.16287/wbc_idmap_common.c0000644000000000000000000000007412703456111023221 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.885794412 sssd-1.13.4/src/sss_client/libwbclient/wbc_idmap_common.c0000644002412700241270000000477012703456111024700 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. Winbind client API Copyright (C) Gerald (Jerry) Carter 2007 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* Required Headers */ #include "libwbclient.h" /* Convert a Windows SID to a Unix uid if there already is a mapping */ wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid, uid_t *puid) { return WBC_ERR_NOT_IMPLEMENTED; } /* Convert a Unix uid to a Windows SID if there already is a mapping */ wbcErr wbcQueryUidToSid(uid_t uid, struct wbcDomainSid *sid) { return WBC_ERR_NOT_IMPLEMENTED; } /* Convert a Windows SID to a Unix gid if there already is a mapping */ wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid, gid_t *pgid) { return WBC_ERR_NOT_IMPLEMENTED; } /* Convert a Unix gid to a Windows SID if there already is a mapping */ wbcErr wbcQueryGidToSid(gid_t gid, struct wbcDomainSid *sid) { return WBC_ERR_NOT_IMPLEMENTED; } /* Set an user id mapping - not implemented any more */ wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid) { return WBC_ERR_NOT_IMPLEMENTED; } /* Set a group id mapping - not implemented any more */ wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid) { return WBC_ERR_NOT_IMPLEMENTED; } /* Remove a user id mapping - not implemented any more */ wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid) { return WBC_ERR_NOT_IMPLEMENTED; } /* Remove a group id mapping - not implemented any more */ wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid) { return WBC_ERR_NOT_IMPLEMENTED; } /* Set the highwater mark for allocated uids - not implemented any more */ wbcErr wbcSetUidHwm(uid_t uid_hwm) { return WBC_ERR_NOT_IMPLEMENTED; } /* Set the highwater mark for allocated gids - not implemented any more */ wbcErr wbcSetGidHwm(gid_t gid_hwm) { return WBC_ERR_NOT_IMPLEMENTED; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/nss_group.c0000644000000000000000000000007412703456111017445 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.674793697 sssd-1.13.4/src/sss_client/nss_group.c0000644002412700241270000004624212703456111021124 0ustar00jhrozekjhrozek00000000000000/* * System Security Services Daemon. NSS client interface * * Copyright (C) Simo Sorce 2007 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /* GROUP database NSS interface */ #include #include #include #include #include #include #include #include #include "sss_cli.h" #include "nss_mc.h" static struct sss_nss_getgrent_data { size_t len; size_t ptr; uint8_t *data; } sss_nss_getgrent_data; static void sss_nss_getgrent_data_clean(void) { if (sss_nss_getgrent_data.data != NULL) { free(sss_nss_getgrent_data.data); sss_nss_getgrent_data.data = NULL; } sss_nss_getgrent_data.len = 0; sss_nss_getgrent_data.ptr = 0; } enum sss_nss_gr_type { GETGR_NONE, GETGR_NAME, GETGR_GID }; static struct sss_nss_getgr_data { enum sss_nss_gr_type type; union { char *grname; gid_t gid; } id; uint8_t *repbuf; size_t replen; } sss_nss_getgr_data; static void sss_nss_getgr_data_clean(bool freebuf) { if (sss_nss_getgr_data.type == GETGR_NAME) { free(sss_nss_getgr_data.id.grname); } if (freebuf) { free(sss_nss_getgr_data.repbuf); } memset(&sss_nss_getgr_data, 0, sizeof(struct sss_nss_getgr_data)); } static enum nss_status sss_nss_get_getgr_cache(const char *name, gid_t gid, enum sss_nss_gr_type type, uint8_t **repbuf, size_t *replen, int *errnop) { bool freebuf = true; enum nss_status status; int ret = 0; if (sss_nss_getgr_data.type != type) { status = NSS_STATUS_NOTFOUND; goto done; } switch (type) { case GETGR_NAME: ret = strcmp(name, sss_nss_getgr_data.id.grname); if (ret != 0) { status = NSS_STATUS_NOTFOUND; goto done; } break; case GETGR_GID: if (sss_nss_getgr_data.id.gid != gid) { status = NSS_STATUS_NOTFOUND; goto done; } break; default: status = NSS_STATUS_TRYAGAIN; ret = EINVAL; goto done; } /* ok we have it, remove from cache and pass back to the caller */ *repbuf = sss_nss_getgr_data.repbuf; *replen = sss_nss_getgr_data.replen; /* prevent _clean() from freeing the buffer */ freebuf = false; status = NSS_STATUS_SUCCESS; done: sss_nss_getgr_data_clean(freebuf); *errnop = ret; return status; } /* this function always takes ownership of repbuf and NULLs it before * returning */ static void sss_nss_save_getgr_cache(const char *name, gid_t gid, enum sss_nss_gr_type type, uint8_t **repbuf, size_t replen) { int ret = 0; sss_nss_getgr_data.type = type; sss_nss_getgr_data.repbuf = *repbuf; sss_nss_getgr_data.replen = replen; switch (type) { case GETGR_NAME: if (name == NULL) { ret = EINVAL; goto done; } sss_nss_getgr_data.id.grname = strdup(name); if (!sss_nss_getgr_data.id.grname) { ret = ENOMEM; goto done; } break; case GETGR_GID: if (gid == 0) { ret = EINVAL; goto done; } sss_nss_getgr_data.id.gid = gid; break; default: ret = EINVAL; goto done; } done: if (ret) { sss_nss_getgr_data_clean(true); } *repbuf = NULL; } /* GETGRNAM Request: * * 0-X: string with name * * GERTGRGID Request: * * 0-7: 32bit number with gid * * INITGROUPS Request: * * 0-3: 32bit number with gid * 4-7: 32bit unsigned with max num of entries * * Replies: * * 0-3: 32bit unsigned number of results * 4-7: 32bit unsigned (reserved/padding) * For each result (64bit padded ?): * 0-3: 32bit number gid * 4-7: 32bit unsigned number of members * 8-X: sequence of 0 terminated strings (name, passwd, mem..) * * FIXME: do we need to pad so that each result is 32 bit aligned ? */ struct sss_nss_gr_rep { struct group *result; char *buffer; size_t buflen; }; static int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr, uint8_t *buf, size_t *len) { errno_t ret; size_t i, l, slen, ptmem, pad, dlen, glen; char *sbuf; uint32_t mem_num; uint32_t c; if (*len < 11) { /* not enough space for data, bad packet */ return EBADMSG; } SAFEALIGN_COPY_UINT32(&c, buf, NULL); pr->result->gr_gid = c; SAFEALIGN_COPY_UINT32(&mem_num, buf+sizeof(uint32_t), NULL); sbuf = (char *)&buf[8]; slen = *len - 8; dlen = pr->buflen; pr->result->gr_name = &(pr->buffer[0]); i = 0; ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &pr->result->gr_name, NULL); if (ret != EOK) return ret; pr->result->gr_passwd = &(pr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &pr->result->gr_passwd, NULL); if (ret != EOK) return ret; /* Make sure pr->buffer[i+pad] is aligned to sizeof(char *) */ pad = PADDING_SIZE(i, char *); /* now members */ pr->result->gr_mem = DISCARD_ALIGN(&(pr->buffer[i+pad]), char **); ptmem = (sizeof(char *) * (mem_num + 1)) + pad; if (ptmem > dlen) { return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */ } dlen -= ptmem; ptmem += i; pr->result->gr_mem[mem_num] = NULL; /* terminate array */ for (l = 0; l < mem_num; l++) { pr->result->gr_mem[l] = &(pr->buffer[ptmem]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &pr->result->gr_mem[l], &glen); if (ret != EOK) return ret; ptmem += glen + 1; } *len = slen -i; return 0; } /* INITGROUP Reply: * * 0-3: 32bit unsigned number of results * 4-7: 32bit unsigned (reserved/padding) * For each result: * 0-4: 32bit number with gid */ enum nss_status _nss_sss_initgroups_dyn(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop) { struct sss_cli_req_data rd; uint8_t *repbuf; size_t replen; enum nss_status nret; size_t buf_index = 0; size_t user_len; uint32_t num_ret; long int l, max_ret; int ret; ret = sss_strnlen(user, SSS_NAME_MAX, &user_len); if (ret != 0) { *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } ret = sss_nss_mc_initgroups_dyn(user, user_len, group, start, size, groups, limit); switch (ret) { case 0: *errnop = 0; return NSS_STATUS_SUCCESS; case ERANGE: *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; case ENOENT: /* fall through, we need to actively ask the parent * if no entry is found */ break; default: /* if using the mmaped cache failed, * fall back to socket based comms */ break; } rd.len = user_len + 1; rd.data = user; sss_nss_lock(); /* previous thread might already initialize entry in mmap cache */ ret = sss_nss_mc_initgroups_dyn(user, user_len, group, start, size, groups, limit); switch (ret) { case 0: *errnop = 0; nret = NSS_STATUS_SUCCESS; goto out; case ERANGE: *errnop = ERANGE; nret = NSS_STATUS_TRYAGAIN; goto out; case ENOENT: /* fall through, we need to actively ask the parent * if no entry is found */ break; default: /* if using the mmaped cache failed, * fall back to socket based comms */ break; } nret = sss_nss_make_request(SSS_NSS_INITGR, &rd, &repbuf, &replen, errnop); if (nret != NSS_STATUS_SUCCESS) { goto out; } /* no results if not found */ SAFEALIGN_COPY_UINT32(&num_ret, repbuf, NULL); if (num_ret == 0) { free(repbuf); nret = NSS_STATUS_NOTFOUND; goto out; } max_ret = num_ret; /* check we have enough space in the buffer */ if ((*size - *start) < num_ret) { long int newsize; gid_t *newgroups; newsize = *size + num_ret; if ((limit > 0) && (newsize > limit)) { newsize = limit; max_ret = newsize - *start; } newgroups = (gid_t *)realloc((*groups), newsize * sizeof(**groups)); if (!newgroups) { *errnop = ENOMEM; free(repbuf); nret = NSS_STATUS_TRYAGAIN; goto out; } *groups = newgroups; *size = newsize; } /* Skip first two 32 bit values (number of results and * reserved padding) */ buf_index = 2 * sizeof(uint32_t); for (l = 0; l < max_ret; l++) { SAFEALIGN_COPY_UINT32(&(*groups)[*start], repbuf + buf_index, &buf_index); *start += 1; } free(repbuf); nret = NSS_STATUS_SUCCESS; out: sss_nss_unlock(); return nret; } enum nss_status _nss_sss_getgrnam_r(const char *name, struct group *result, char *buffer, size_t buflen, int *errnop) { struct sss_cli_req_data rd; struct sss_nss_gr_rep grrep; uint8_t *repbuf; size_t replen, len, name_len; uint32_t num_results; enum nss_status nret; int ret; /* Caught once glibc passing in buffer == 0x0 */ if (!buffer || !buflen) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } ret = sss_strnlen(name, SSS_NAME_MAX, &name_len); if (ret != 0) { *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } ret = sss_nss_mc_getgrnam(name, name_len, result, buffer, buflen); switch (ret) { case 0: *errnop = 0; return NSS_STATUS_SUCCESS; case ERANGE: *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; case ENOENT: /* fall through, we need to actively ask the parent * if no entry is found */ break; default: /* if using the mmaped cache failed, * fall back to socket based comms */ break; } rd.len = name_len + 1; rd.data = name; sss_nss_lock(); /* previous thread might already initialize entry in mmap cache */ ret = sss_nss_mc_getgrnam(name, name_len, result, buffer, buflen); switch (ret) { case 0: *errnop = 0; nret = NSS_STATUS_SUCCESS; goto out; case ERANGE: *errnop = ERANGE; nret = NSS_STATUS_TRYAGAIN; goto out; case ENOENT: /* fall through, we need to actively ask the parent * if no entry is found */ break; default: /* if using the mmaped cache failed, * fall back to socket based comms */ break; } nret = sss_nss_get_getgr_cache(name, 0, GETGR_NAME, &repbuf, &replen, errnop); if (nret == NSS_STATUS_NOTFOUND) { nret = sss_nss_make_request(SSS_NSS_GETGRNAM, &rd, &repbuf, &replen, errnop); } if (nret != NSS_STATUS_SUCCESS) { goto out; } grrep.result = result; grrep.buffer = buffer; grrep.buflen = buflen; /* Get number of results from repbuf. */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if (num_results == 0) { free(repbuf); nret = NSS_STATUS_NOTFOUND; goto out; } /* only 1 result is accepted for this function */ if (num_results != 1) { *errnop = EBADMSG; free(repbuf); nret = NSS_STATUS_TRYAGAIN; goto out; } len = replen - 8; ret = sss_nss_getgr_readrep(&grrep, repbuf+8, &len); if (ret == ERANGE) { sss_nss_save_getgr_cache(name, 0, GETGR_NAME, &repbuf, replen); } else { free(repbuf); } if (ret) { *errnop = ret; nret = NSS_STATUS_TRYAGAIN; goto out; } nret = NSS_STATUS_SUCCESS; out: sss_nss_unlock(); return nret; } enum nss_status _nss_sss_getgrgid_r(gid_t gid, struct group *result, char *buffer, size_t buflen, int *errnop) { struct sss_cli_req_data rd; struct sss_nss_gr_rep grrep; uint8_t *repbuf; size_t replen, len; uint32_t num_results; enum nss_status nret; uint32_t group_gid; int ret; /* Caught once glibc passing in buffer == 0x0 */ if (!buffer || !buflen) return ERANGE; ret = sss_nss_mc_getgrgid(gid, result, buffer, buflen); switch (ret) { case 0: *errnop = 0; return NSS_STATUS_SUCCESS; case ERANGE: *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; case ENOENT: /* fall through, we need to actively ask the parent * if no entry is found */ break; default: /* if using the mmaped cache failed, * fall back to socket based comms */ break; } group_gid = gid; rd.len = sizeof(uint32_t); rd.data = &group_gid; sss_nss_lock(); /* previous thread might already initialize entry in mmap cache */ ret = sss_nss_mc_getgrgid(gid, result, buffer, buflen); switch (ret) { case 0: *errnop = 0; nret = NSS_STATUS_SUCCESS; goto out; case ERANGE: *errnop = ERANGE; nret = NSS_STATUS_TRYAGAIN; goto out; case ENOENT: /* fall through, we need to actively ask the parent * if no entry is found */ break; default: /* if using the mmaped cache failed, * fall back to socket based comms */ break; } nret = sss_nss_get_getgr_cache(NULL, gid, GETGR_GID, &repbuf, &replen, errnop); if (nret == NSS_STATUS_NOTFOUND) { nret = sss_nss_make_request(SSS_NSS_GETGRGID, &rd, &repbuf, &replen, errnop); } if (nret != NSS_STATUS_SUCCESS) { goto out; } grrep.result = result; grrep.buffer = buffer; grrep.buflen = buflen; /* Get number of results from repbuf. */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if (num_results == 0) { free(repbuf); nret = NSS_STATUS_NOTFOUND; goto out; } /* only 1 result is accepted for this function */ if (num_results != 1) { *errnop = EBADMSG; free(repbuf); nret = NSS_STATUS_TRYAGAIN; goto out; } len = replen - 8; ret = sss_nss_getgr_readrep(&grrep, repbuf+8, &len); if (ret == ERANGE) { sss_nss_save_getgr_cache(NULL, gid, GETGR_GID, &repbuf, replen); } else { free(repbuf); } if (ret) { *errnop = ret; nret = NSS_STATUS_TRYAGAIN; goto out; } nret = NSS_STATUS_SUCCESS; out: sss_nss_unlock(); return nret; } enum nss_status _nss_sss_setgrent(void) { enum nss_status nret; int errnop; sss_nss_lock(); /* make sure we do not have leftovers, and release memory */ sss_nss_getgrent_data_clean(); nret = sss_nss_make_request(SSS_NSS_SETGRENT, NULL, NULL, NULL, &errnop); if (nret != NSS_STATUS_SUCCESS) { errno = errnop; } sss_nss_unlock(); return nret; } static enum nss_status internal_getgrent_r(struct group *result, char *buffer, size_t buflen, int *errnop) { struct sss_cli_req_data rd; struct sss_nss_gr_rep grrep; uint8_t *repbuf; size_t replen; uint32_t num_results; enum nss_status nret; uint32_t num_entries; int ret; /* Caught once glibc passing in buffer == 0x0 */ if (!buffer || !buflen) return ERANGE; /* if there are leftovers return the next one */ if (sss_nss_getgrent_data.data != NULL && sss_nss_getgrent_data.ptr < sss_nss_getgrent_data.len) { repbuf = (uint8_t *)sss_nss_getgrent_data.data + sss_nss_getgrent_data.ptr; replen = sss_nss_getgrent_data.len - sss_nss_getgrent_data.ptr; grrep.result = result; grrep.buffer = buffer; grrep.buflen = buflen; ret = sss_nss_getgr_readrep(&grrep, repbuf, &replen); if (ret) { *errnop = ret; return NSS_STATUS_TRYAGAIN; } /* advance buffer pointer */ sss_nss_getgrent_data.ptr = sss_nss_getgrent_data.len - replen; return NSS_STATUS_SUCCESS; } /* release memory if any */ sss_nss_getgrent_data_clean(); /* retrieve no more than SSS_NSS_MAX_ENTRIES at a time */ num_entries = SSS_NSS_MAX_ENTRIES; rd.len = sizeof(uint32_t); rd.data = &num_entries; nret = sss_nss_make_request(SSS_NSS_GETGRENT, &rd, &repbuf, &replen, errnop); if (nret != NSS_STATUS_SUCCESS) { return nret; } /* Get number of results from repbuf. */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if ((num_results == 0) || (replen - 8 == 0)) { free(repbuf); return NSS_STATUS_NOTFOUND; } sss_nss_getgrent_data.data = repbuf; sss_nss_getgrent_data.len = replen; sss_nss_getgrent_data.ptr = 8; /* skip metadata fields */ /* call again ourselves, this will return the first result */ return internal_getgrent_r(result, buffer, buflen, errnop); } enum nss_status _nss_sss_getgrent_r(struct group *result, char *buffer, size_t buflen, int *errnop) { enum nss_status nret; sss_nss_lock(); nret = internal_getgrent_r(result, buffer, buflen, errnop); sss_nss_unlock(); return nret; } enum nss_status _nss_sss_endgrent(void) { enum nss_status nret; int errnop; sss_nss_lock(); /* make sure we do not have leftovers, and release memory */ sss_nss_getgrent_data_clean(); nret = sss_nss_make_request(SSS_NSS_ENDGRENT, NULL, NULL, NULL, &errnop); if (nret != NSS_STATUS_SUCCESS) { errno = errnop; } sss_nss_unlock(); return nret; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/sudo0000644000000000000000000000013212703463556016165 xustar0030 mtime=1460561774.822794198 30 atime=1460561776.117798589 30 ctime=1460561774.822794198 sssd-1.13.4/src/sss_client/sudo/0000755002412700241270000000000012703463556017716 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sss_client/sudo/PaxHeaders.16287/sss_sudo.c0000644000000000000000000000007412703456111020242 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.822794198 sssd-1.13.4/src/sss_client/sudo/sss_sudo.c0000644002412700241270000001442612703456111021720 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include #include "util/util.h" #include "sss_client/sss_cli.h" #include "sss_client/sudo/sss_sudo.h" #include "sss_client/sudo/sss_sudo_private.h" int sss_sudo_create_query(uid_t uid, const char *username, uint8_t **_query, size_t *_query_len); static void sss_sudo_free_rules(unsigned int num_rules, struct sss_sudo_rule *rules); static void sss_sudo_free_attrs(unsigned int num_attrs, struct sss_sudo_attr *attrs); static int sss_sudo_send_recv_generic(enum sss_cli_command command, uid_t uid, const char *username, uint32_t *_error, char **_domainname, struct sss_sudo_result **_result) { struct sss_cli_req_data request; uint8_t *query_buf = NULL; size_t query_len = 0; uint8_t *reply_buf = NULL; size_t reply_len = 0; int errnop = 0; int ret = 0; /* create query */ ret = sss_sudo_create_query(uid, username, &query_buf, &query_len); if (ret != EOK) { goto done; } request.len = query_len; request.data = (const void*)query_buf; /* send query and receive response */ errnop = 0; ret = sss_sudo_make_request(command, &request, &reply_buf, &reply_len, &errnop); if (ret != SSS_STATUS_SUCCESS) { ret = errnop; goto done; } /* parse structure */ ret = sss_sudo_parse_response((const char*)reply_buf, reply_len, _domainname, _result, _error); done: free(query_buf); free(reply_buf); return ret; } int sss_sudo_send_recv(uid_t uid, const char *username, const char *domainname, uint32_t *_error, struct sss_sudo_result **_result) { int ret; if (username == NULL || strlen(username) == 0) { return EINVAL; } /* send query and receive response */ ret = sss_sudo_send_recv_generic(SSS_SUDO_GET_SUDORULES, uid, username, _error, NULL, _result); return ret; } int sss_sudo_send_recv_defaults(uid_t uid, const char *username, uint32_t *_error, char **_domainname, struct sss_sudo_result **_result) { if (username == NULL || strlen(username) == 0) { return EINVAL; } return sss_sudo_send_recv_generic(SSS_SUDO_GET_DEFAULTS, uid, username, _error, _domainname, _result); } int sss_sudo_create_query(uid_t uid, const char *username, uint8_t **_query, size_t *_query_len) { uint8_t *data = NULL; size_t username_len = strlen(username) * sizeof(char) + 1; size_t data_len = sizeof(uid_t) + username_len; size_t offset = 0; data = (uint8_t*)malloc(data_len * sizeof(uint8_t)); if (data == NULL) { return ENOMEM; } SAFEALIGN_SET_VALUE(data, uid, uid_t, &offset); memcpy(data + offset, username, username_len); *_query = data; *_query_len = data_len; return EOK; } int sss_sudo_get_values(struct sss_sudo_rule *e, const char *attrname, char ***_values) { struct sss_sudo_attr *attr = NULL; char **values = NULL; int i, j; for (i = 0; i < e->num_attrs; i++) { attr = e->attrs + i; if (strcasecmp(attr->name, attrname) == 0) { values = calloc(attr->num_values + 1, sizeof(char*)); if (values == NULL) { return ENOMEM; } for (j = 0; j < attr->num_values; j++) { values[j] = strdup(attr->values[j]); if (values[j] == NULL) { sss_sudo_free_values(values); return ENOMEM; } } values[attr->num_values] = NULL; break; } } if (values == NULL) { return ENOENT; } *_values = values; return EOK; } void sss_sudo_free_values(char **values) { char **value = NULL; if (values == NULL) { return; } for (value = values; *value != NULL; value++) { free(*value); } free(values); } void sss_sudo_free_result(struct sss_sudo_result *result) { if (result == NULL) { return; } sss_sudo_free_rules(result->num_rules, result->rules); free(result); } void sss_sudo_free_rules(unsigned int num_rules, struct sss_sudo_rule *rules) { struct sss_sudo_rule *rule = NULL; int i; if (rules == NULL) { return; } for (i = 0; i < num_rules; i++) { rule = rules + i; sss_sudo_free_attrs(rule->num_attrs, rule->attrs); rule->attrs = NULL; } free(rules); } void sss_sudo_free_attrs(unsigned int num_attrs, struct sss_sudo_attr *attrs) { struct sss_sudo_attr *attr = NULL;; int i, j; if (attrs == NULL) { return; } for (i = 0; i < num_attrs; i++) { attr = attrs + i; free(attr->name); attr->name = NULL; for (j = 0; j < attr->num_values; j++) { free(attr->values[j]); attr->values[j] = NULL; } free(attr->values); } free(attrs); } sssd-1.13.4/src/sss_client/sudo/PaxHeaders.16287/sss_sudo_private.h0000644000000000000000000000007412703456111022001 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.823794202 sssd-1.13.4/src/sss_client/sudo/sss_sudo_private.h0000644002412700241270000000220212703456111023444 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_SUDO_PRIVATE_H_ #define SSS_SUDO_PRIVATE_H_ #include #include "sss_client/sudo/sss_sudo.h" int sss_sudo_parse_response(const char *message, size_t message_len, char **_domainname, struct sss_sudo_result **_result, uint32_t *_error); #endif /* SSS_SUDO_PRIVATE_H_ */ sssd-1.13.4/src/sss_client/sudo/PaxHeaders.16287/sss_sudo.doxy.in0000644000000000000000000000007312703456111021407 xustar0029 atime=1460561772.75578719 30 ctime=1460561774.636793568 sssd-1.13.4/src/sss_client/sudo/sss_sudo.doxy.in0000644002412700241270000023503412703456111023066 0ustar00jhrozekjhrozek00000000000000# Doxyfile 1.8.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = libsss_sudo # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = libsss_sudo_doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. Note that you specify absolute paths here, but also # relative paths, which will be relative from the directory where doxygen is # started. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, # and language is one of the parsers supported by doxygen: IDL, Java, # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, # C++. For instance to make doxygen treat .inc files as Fortran files (default # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented classes, # or namespaces to their corresponding documentation. Such a link can be # prevented in individual cases by by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES (the # default) will make doxygen replace the get and set methods by a property in # the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if section-label ... \endif # and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. Do not use # file names with spaces, bibtex cannot handle them. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @abs_top_srcdir@/src/sss_client/sudo/sss_sudo.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.cpp \ *.cc \ *.c \ *.h \ *.hh \ *.hpp \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.git/* \ */.svn/* \ */cmake/* \ */build/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = # If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page (index.html). # This can be useful if you have a project on for instance GitHub and want reuse # the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If left blank doxygen will # generate a default style sheet. Note that it is recommended to use # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET # since it does not replace the standard style sheet and is therefor more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user # can expand and collapse entries dynamically later on. Doxygen will expand # the tree to such a level that at most the specified number of entries are # visible (unless a fully collapsed tree already exceeds this amount). # So setting the number of entries 1 will produce a full collapsed tree by # default. 0 is a special value representing an infinite number of entries # and will result in a full expanded tree by default. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely # identify the documentation publisher. This should be a reverse domain-name # style string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NONE # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. # There are two flavours of web server based search depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. # See the manual for details. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain # the search results. Doxygen ships with an example indexer (doxyindexer) and # search engine (doxysearch.cgi) which are based on the open source search engine # library Xapian. See the manual for configuration details. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will returned the search results when EXTERNAL_SEARCH is enabled. # Doxygen ships with an example search engine (doxysearch) which is based on # the open source search engine library Xapian. See the manual for configuration # details. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. SEARCHDATA_FILE = searchdata.xml # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through other # doxygen projects that are not otherwise connected via tags files, but are # all added to the same search index. Each project needs to have a tag file set # via GENERATE_TAGFILE. The search mapping then maps the name of the tag file # to a relative location where the documentation can be found, # similar to the # TAGFILES option but without actually processing the tag file. # The format is: EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # managable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES sssd-1.13.4/src/sss_client/sudo/PaxHeaders.16287/sss_sudo.h0000644000000000000000000000007412703456111020247 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.592793419 sssd-1.13.4/src/sss_client/sudo/sss_sudo.h0000644002412700241270000001610712703456111021723 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_SUDO_H_ #define SSS_SUDO_H_ /** * @defgroup libsss_sudo A library for communication between SUDO and SSSD * libsss_sudo provides a mechanism to for a SUDO plugin * to communicate with the sudo responder of SSSD. * * @{ */ #include #include /** The value returned when the communication with SUDO is successful and * the user was found in one of the domains */ #define SSS_SUDO_ERROR_OK 0 /** * Component of a sss_rule structure. The component * has exactly one name and one or more values. * */ struct sss_sudo_attr { /** The attribute name */ char *name; /** A string array that contains all the attribute values */ char **values; /** The number of values the attribute contains. * * Attributes are multivalued in general. */ unsigned int num_values; }; /** * One sudo rule. The rule consists of one or more * attributes of sss_attr type */ struct sss_sudo_rule { /** The number of attributes in the rule */ unsigned int num_attrs; /** List of rule attributes */ struct sss_sudo_attr *attrs; }; /** * A result object returned from SSSD. * * The result consists of zero or more sss_rule elements. */ struct sss_sudo_result { /** * The number of rules for the user * * In case the user exists in one of SSSD domains * but no rules match for him, the num_rules element * is 0. */ unsigned int num_rules; /** List of rules found */ struct sss_sudo_rule *rules; }; /** * @brief Send a request to SSSD to retreive all SUDO rules for a given * user. * * @param[in] uid The uid of the user to retreive the rules for. * @param[in] username The username to retreive the rules for * @param[in] domainname The domain name the user is a member of. * @param[out] _error The result of the search in SSSD's domains. If the * user was present in the domain, the _error code is * SSS_SUDO_ERROR_OK and the _result structure is * returned even if it was empty (in other words * _result->num_rules == 0). Other problems are returned * as errno codes. Most prominently these are ENOENT * (the user was not found with SSSD), EIO (SSSD * encountered an internal problem) and EINVAL * (malformed query). * @param[out] _result Newly allocated structure sss_result that contains * the rules for the user. If no rules were found but * the user was valid, this structure is "empty", which * means that the num_rules member is 0. * * @return 0 on success and other errno values on failure. The return value * denotes whether communication with SSSD was successful. It does not * tell whether the result contains any rules or whether SSSD knew the * user at all. That information is transferred in the _error parameter. */ int sss_sudo_send_recv(uid_t uid, const char *username, const char *domainname, uint32_t *_error, struct sss_sudo_result **_result); /** * @brief Send a request to SSSD to retrieve the default options, commonly * stored in the "cn=defaults" record, * * @param[in] uid The uid of the user to retreive the rules for. * * @param[in] username The username to retreive the rules for. * * @param[out] _error The result of the search in SSSD's domains. If the * options were present in the domain, the _error code * is SSS_SUDO_ERROR_OK and the _result structure is * returned even if it was empty (in other words * _result->num_rules == 0). Other problems are returned * as errno codes. * * @param[out] _domainname The domain name the user is a member of. * * @param[out] _result Newly allocated structure sss_result that contains * the options. If no options were found this structure * is "empty", which means that the num_rules member * is 0. * * @return 0 on success and other errno values on failure. The return value * denotes whether communication with SSSD was successful. It does not * tell whether the result contains any rules or whether SSSD knew the * user at all. That information is transferred in the _error parameter. * * @note The _domainname should be freed using free(). */ int sss_sudo_send_recv_defaults(uid_t uid, const char *username, uint32_t *_error, char **_domainname, struct sss_sudo_result **_result); /** * @brief Free the sss_result structure returned by sss_sudo_send_recv * * @param[in] result The sss_result structure to free. The structure was * previously returned by sss_sudo_get_values(). */ void sss_sudo_free_result(struct sss_sudo_result *result); /** * @brief Get all values for a given attribute in a sss_rule * * @param[in] e The sss_rule to get values from * @param[in] attrname The name of the attribute to query from the rule * @param[out] values A newly allocated list of values the attribute has in * rule. On success, this parameter is an array of * NULL-terminated strings, the last element is a NULL * pointer. On failure (including when the attribute is * not found), the pointer address is not changed. * * @return 0 on success, ENOENT in case the attribute is not found and other * errno values on failure. * * @note the returned values should be freed using sss_sudo_free_values() */ int sss_sudo_get_values(struct sss_sudo_rule *e, const char *attrname, char ***values); /** * @brief Free the values returned by sss_sudo_get_values * * @param[in] values The list of values to free. The values were previously * returned by sss_sudo_get_values() */ void sss_sudo_free_values(char **values); /** * @} */ #endif /* SSS_SUDO_H_ */ sssd-1.13.4/src/sss_client/sudo/PaxHeaders.16287/sss_sudo_response.c0000644000000000000000000000007412703456111022160 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.821794195 sssd-1.13.4/src/sss_client/sudo/sss_sudo_response.c0000644002412700241270000001517712703456111023642 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include #include "sss_client/sss_cli.h" #include "sss_client/sudo/sss_sudo.h" #include "sss_client/sudo/sss_sudo_private.h" static int sss_sudo_parse_rule(const char *message, size_t message_len, size_t *_cursor, struct sss_sudo_rule *_rule); static int sss_sudo_parse_attr(const char *message, size_t message_len, size_t *_cursor, struct sss_sudo_attr *_attr); static int sss_sudo_parse_uint32(const char *message, size_t message_len, size_t *_cursor, uint32_t *_number); static int sss_sudo_parse_string(const char *message, size_t message_len, size_t *_cursor, char **_str); int sss_sudo_parse_response(const char *message, size_t message_len, char **_domainname, struct sss_sudo_result **_result, uint32_t *_error) { struct sss_sudo_result *result = NULL; char *domainname = NULL; size_t cursor = 0; int ret = EOK; int i = 0; /* error code */ ret = sss_sudo_parse_uint32(message, message_len, &cursor, _error); if (ret != EOK || *_error != SSS_SUDO_ERROR_OK) { return ret; } /* domain name - deprecated * it won't be used, but we will read it anyway to ease parsing * TODO: when possible change the protocol */ ret = sss_sudo_parse_string(message, message_len, &cursor, &domainname); if (ret != EOK) { return ret; } free(domainname); if (_domainname != NULL) { *_domainname = NULL; } /* result */ result = malloc(sizeof(struct sss_sudo_result)); if (result == NULL) { return ENOMEM; } memset(result, 0, sizeof(struct sss_sudo_result)); /* rules_num */ ret = sss_sudo_parse_uint32(message, message_len, &cursor, &result->num_rules); if (ret != EOK) { goto fail; } /* rules */ result->rules = calloc(result->num_rules, sizeof(struct sss_sudo_rule)); if (result->rules == NULL) { ret = ENOMEM; goto fail; } for (i = 0; i < result->num_rules; i++) { ret = sss_sudo_parse_rule(message, message_len, &cursor, &result->rules[i]); if (ret != EOK) { goto fail; } } *_result = result; return EOK; fail: sss_sudo_free_result(result); return ret; } int sss_sudo_parse_rule(const char *message, size_t message_len, size_t *_cursor, struct sss_sudo_rule *_rule) { int ret = EOK; int i = 0; /* attrs_num */ ret = sss_sudo_parse_uint32(message, message_len, _cursor, &_rule->num_attrs); if (ret != EOK) { return ret; } /* attrs */ _rule->attrs = calloc(_rule->num_attrs, sizeof(struct sss_sudo_attr)); if (_rule->attrs == NULL) { return ENOMEM; } for (i = 0; i < _rule->num_attrs; i++) { ret = sss_sudo_parse_attr(message, message_len, _cursor, &_rule->attrs[i]); if (ret != EOK) { return ret; } } return EOK; } int sss_sudo_parse_attr(const char *message, size_t message_len, size_t *_cursor, struct sss_sudo_attr *_attr) { char *str = NULL; int ret = EOK; int i = 0; /* name */ ret = sss_sudo_parse_string(message, message_len, _cursor, &str); if (ret != EOK) { return ret; } _attr->name = str; /* values_num */ ret = sss_sudo_parse_uint32(message, message_len, _cursor, &_attr->num_values); if (ret != EOK) { return ret; } /* values */ _attr->values = calloc(_attr->num_values, sizeof(const char*)); if (_attr->values == NULL) { return ENOMEM; } for (i = 0; i < _attr->num_values; i++) { ret = sss_sudo_parse_string(message, message_len, _cursor, &str); if (ret != EOK) { return ret; } _attr->values[i] = str; } return EOK; } int sss_sudo_parse_uint32(const char *message, size_t message_len, size_t *_cursor, uint32_t *_number) { size_t start_pos = 0; if (_cursor == NULL) { return EINVAL; } start_pos = *_cursor; if (start_pos + sizeof(uint32_t) > message_len) { return EINVAL; } /* expanded SAFEALIGN_COPY_UINT32 macro from util.h */ memcpy(_number, message + start_pos, sizeof(uint32_t)); *_cursor = start_pos + sizeof(uint32_t); return EOK; } int sss_sudo_parse_string(const char *message, size_t message_len, size_t *_cursor, char **_str) { const char *current = NULL; char *str = NULL; size_t start_pos = 0; size_t len = 0; size_t maxlen = 0; if (_cursor == NULL) { return EINVAL; } start_pos = *_cursor; maxlen = message_len - start_pos; if (start_pos >= message_len ) { return EINVAL; } current = message + start_pos; len = strnlen(current, maxlen); if (len == maxlen) { /* the string exceeds message length */ return EINVAL; } str = strndup(current, len); if (str == NULL) { return ENOMEM; } /* go after \0 */ *_cursor = start_pos + len + 1; *_str = str; return EOK; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/autofs0000644000000000000000000000013212703463556016514 xustar0030 mtime=1460561774.910794497 30 atime=1460561776.117798589 30 ctime=1460561774.910794497 sssd-1.13.4/src/sss_client/autofs/0000755002412700241270000000000012703463556020245 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sss_client/autofs/PaxHeaders.16287/autofs_test_client.c0000644000000000000000000000007412703456111022625 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.910794497 sssd-1.13.4/src/sss_client/autofs/autofs_test_client.c0000644002412700241270000000714012703456111024276 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "util/util.h" #include "sss_client/autofs/sss_autofs_private.h" struct automtent { const char *mapname; size_t cursor; }; int main(int argc, const char *argv[]) { void *ctx; errno_t ret; const char *mapname; char *key = NULL; char *value = NULL; char *pc_key = NULL; struct poptOption long_options[] = { POPT_AUTOHELP { "by-name", 'n', POPT_ARG_STRING, &pc_key, 0, "Request map by name", NULL }, POPT_TABLEEND }; poptContext pc = NULL; pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "MAPNAME"); while ((ret = poptGetNextOpt(pc)) > 0) ; mapname = poptGetArg(pc); if (mapname == NULL) { poptPrintUsage(pc, stderr, 0); fprintf(stderr, "Please specify the automounter map name\n"); poptFreeContext(pc); exit(EXIT_FAILURE); } poptFreeContext(pc); ret = _sss_setautomntent(mapname, &ctx); if (ret) { fprintf(stderr, "setautomntent failed [%d]: %s\n", ret, strerror(ret)); exit(EXIT_FAILURE); } printf("setautomntent done for %s\n", mapname); if (!pc_key) { do { ret = _sss_getautomntent_r(&key, &value, ctx); if (ret == 0) { if (!key || !value) { fprintf(stderr, "getautomntent returned success but no data?\n"); goto end; } printf("key: %s\t\tvalue: %s\n", key, value); free(key); key = NULL; free(value); value = NULL; } } while(ret == 0); if (ret != 0 && ret != ENOENT) { fprintf(stderr, "getautomntent_r failed [%d]: %s\n", ret, strerror(ret)); goto end; } } else { ret = _sss_getautomntbyname_r(pc_key, &value, ctx); if (ret == ENOENT) { fprintf(stderr, "no such entry in map\n"); } else if (ret != 0) { fprintf(stderr, "getautomntent_r failed [%d]: %s\n", ret, strerror(ret)); goto end; } else { if (!value) { fprintf(stderr, "_sss_getautomntbyname_r " "returned success but no data?\n"); goto end; } printf("key: %s\t\tvalue: %s\n", pc_key, value); free(value); } } end: ret = _sss_endautomntent(&ctx); if (ret) { fprintf(stderr, "endautomntent failed [%d]: %s\n", ret, strerror(ret)); exit(EXIT_FAILURE); } printf("endautomntent done for %s\n", mapname); return 0; } sssd-1.13.4/src/sss_client/autofs/PaxHeaders.16287/sss_autofs.exports0000644000000000000000000000007312703456111022401 xustar0030 atime=1460561751.653715637 29 ctime=1460561774.38679272 sssd-1.13.4/src/sss_client/autofs/sss_autofs.exports0000644002412700241270000000040012703456111024043 0ustar00jhrozekjhrozek00000000000000EXPORTED { # public functions global: _sss_setautomntent; _sss_getautomntent_r; _sss_getautomntbyname_r; _sss_endautomntent; # everything else is local local: *; }; sssd-1.13.4/src/sss_client/autofs/PaxHeaders.16287/sss_autofs.c0000644000000000000000000000007412703456111021120 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.702793792 sssd-1.13.4/src/sss_client/autofs/sss_autofs.c0000644002412700241270000002576112703456111022602 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "sss_client/autofs/sss_autofs_private.h" #include "sss_client/sss_cli.h" /* Historically, autofs map names were just file names. Direct key names * may be full directory paths */ #define MAX_AUTOMNTMAPNAME_LEN NAME_MAX #define MAX_AUTOMNTKEYNAME_LEN PATH_MAX /* How many entries shall _sss_getautomntent_r retreive at once */ #define GETAUTOMNTENT_MAX_ENTRIES 512 struct automtent { char *mapname; size_t cursor; }; static struct sss_getautomntent_data { char *mapname; size_t len; size_t ptr; uint8_t *data; } sss_getautomntent_data; static void sss_getautomntent_data_clean(void) { free(sss_getautomntent_data.data); free(sss_getautomntent_data.mapname); memset(&sss_getautomntent_data, 0, sizeof(struct sss_getautomntent_data)); } errno_t _sss_setautomntent(const char *mapname, void **context) { errno_t ret; int errnop; struct automtent *ctx; char *name; size_t name_len; struct sss_cli_req_data rd; uint8_t *repbuf = NULL; size_t replen; uint32_t num_results = 0; if (!mapname) return EINVAL; sss_nss_lock(); /* Make sure there are no leftovers from previous runs */ sss_getautomntent_data_clean(); ret = sss_strnlen(mapname, MAX_AUTOMNTMAPNAME_LEN, &name_len); if (ret != 0) { ret = EINVAL; goto out; } name = malloc(sizeof(char)*name_len + 1); if (name == NULL) { ret = ENOMEM; goto out; } strncpy(name, mapname, name_len + 1); rd.data = name; rd.len = name_len + 1; ret = sss_autofs_make_request(SSS_AUTOFS_SETAUTOMNTENT, &rd, &repbuf, &replen, &errnop); if (ret != SSS_STATUS_SUCCESS) { free(name); ret = errnop; goto out; } /* Get number of results from repbuf. */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if (num_results == 0) { free(name); free(repbuf); ret = ENOENT; goto out; } free(repbuf); ctx = malloc(sizeof(struct automtent)); if (!ctx) { free(name); ret = ENOMEM; goto out; } ctx->mapname = strdup(name); if (!ctx->mapname) { free(name); free(ctx); ret = ENOMEM; goto out; } ctx->cursor = 0; free(name); *context = ctx; ret = 0; out: sss_nss_unlock(); return ret; } static errno_t sss_getautomntent_data_return(const char *mapname, char **_key, char **_value) { size_t dp; uint32_t len = 0; char *key = NULL; uint32_t keylen; char *value = NULL; uint32_t vallen; errno_t ret; if (sss_getautomntent_data.mapname == NULL || sss_getautomntent_data.data == NULL || sss_getautomntent_data.ptr >= sss_getautomntent_data.len) { /* We're done with this buffer */ ret = ENOENT; goto done; } ret = strcmp(mapname, sss_getautomntent_data.mapname); if (ret != EOK) { /* The map we're looking for is not cached. Let responder * do an implicit setautomntent */ ret = ENOENT; goto done; } dp = sss_getautomntent_data.ptr; SAFEALIGN_COPY_UINT32(&len, sss_getautomntent_data.data+dp, &dp); if (len + sss_getautomntent_data.ptr > sss_getautomntent_data.len) { /* len is bigger than the buffer */ ret = EIO; goto done; } if (len == 0) { /* There are no more records. */ *_key = NULL; *_value = NULL; ret = ENOENT; goto done; } SAFEALIGN_COPY_UINT32(&keylen, sss_getautomntent_data.data+dp, &dp); if (keylen + dp > sss_getautomntent_data.len) { ret = EIO; goto done; } key = malloc(keylen); if (!key) { ret = ENOMEM; goto done; } safealign_memcpy(key, sss_getautomntent_data.data+dp, keylen, &dp); SAFEALIGN_COPY_UINT32(&vallen, sss_getautomntent_data.data+dp, &dp); if (vallen + dp > sss_getautomntent_data.len) { ret = EIO; goto done; } value = malloc(vallen); if (!value) { ret = ENOMEM; goto done; } safealign_memcpy(value, sss_getautomntent_data.data+dp, vallen, &dp); sss_getautomntent_data.ptr = dp; *_key = key; *_value = value; return EOK; done: free(key); free(value); sss_getautomntent_data_clean(); return ret; } /* The repbuf is owned by the sss_getautomntent_data once this * function is called */ static errno_t sss_getautomntent_data_save(const char *mapname, uint8_t **repbuf, size_t replen) { size_t rp; uint32_t num; rp = 0; SAFEALIGN_COPY_UINT32(&num, *repbuf+rp, &rp); if (num == 0) { free(*repbuf); return ENOENT; } sss_getautomntent_data.mapname = strdup(mapname); if (sss_getautomntent_data.mapname == NULL) { free(*repbuf); return ENOENT; } sss_getautomntent_data.data = *repbuf; sss_getautomntent_data.len = replen; sss_getautomntent_data.ptr = rp; *repbuf = NULL; return EOK; } errno_t _sss_getautomntent_r(char **key, char **value, void *context) { int errnop; errno_t ret; size_t name_len; struct sss_cli_req_data rd; uint8_t *repbuf = NULL; size_t replen; struct automtent *ctx; size_t ctr = 0; size_t data_len = 0; uint8_t *data; sss_nss_lock(); ctx = (struct automtent *) context; if (!ctx) { ret = EINVAL; goto out; } /* Be paranoid in case someone tries to smuggle in a huge map name */ ret = sss_strnlen(ctx->mapname, MAX_AUTOMNTMAPNAME_LEN, &name_len); if (ret != 0) { ret = EINVAL; goto out; } ret = sss_getautomntent_data_return(ctx->mapname, key, value); if (ret == EOK) { /* The results are available from cache. Just advance the * cursor and return. */ ctx->cursor++; ret = 0; goto out; } /* Don't try to handle any error codes, just go to the responder again */ data_len = sizeof(uint32_t) + /* mapname len */ name_len + 1 + /* mapname\0 */ sizeof(uint32_t) + /* index into the map */ sizeof(uint32_t); /* num entries to retreive */ data = malloc(data_len); if (!data) { ret = ENOMEM; goto out; } SAFEALIGN_SET_UINT32(data, name_len, &ctr); safealign_memcpy(data+ctr, ctx->mapname, name_len + 1, &ctr); SAFEALIGN_SET_UINT32(data+ctr, ctx->cursor, &ctr); SAFEALIGN_SET_UINT32(data+ctr, GETAUTOMNTENT_MAX_ENTRIES, &ctr); rd.data = data; rd.len = data_len; ret = sss_autofs_make_request(SSS_AUTOFS_GETAUTOMNTENT, &rd, &repbuf, &replen, &errnop); free(data); if (ret != SSS_STATUS_SUCCESS) { ret = errnop; goto out; } /* Got reply, let's save it and return from "cache" */ ret = sss_getautomntent_data_save(ctx->mapname, &repbuf, replen); if (ret == ENOENT) { /* No results */ *key = NULL; *value = NULL; goto out; } else if (ret != EOK) { /* Unexpected error */ goto out; } ret = sss_getautomntent_data_return(ctx->mapname, key, value); if (ret != EOK) { goto out; } /* Advance the cursor so that we'll fetch the next map * next time getautomntent is called */ ctx->cursor++; ret = 0; out: sss_nss_unlock(); return ret; } errno_t _sss_getautomntbyname_r(const char *key, char **value, void *context) { int errnop; errno_t ret; struct automtent *ctx; size_t key_len; size_t name_len; size_t data_len = 0; uint8_t *data; size_t ctr = 0; struct sss_cli_req_data rd; uint8_t *repbuf = NULL; size_t replen; char *buf; uint32_t len; uint32_t vallen; size_t rp; sss_nss_lock(); ctx = (struct automtent *) context; if (!ctx || !key) { ret = EINVAL; goto out; } /* Be paranoid in case someone tries to smuggle in a huge map name */ ret = sss_strnlen(ctx->mapname, MAX_AUTOMNTMAPNAME_LEN, &name_len); if (ret != 0) { ret = EINVAL; goto out; } ret = sss_strnlen(key, MAX_AUTOMNTKEYNAME_LEN, &key_len); if (ret != 0) { ret = EINVAL; goto out; } data_len = sizeof(uint32_t) + /* mapname len */ name_len + 1 + /* mapname\0 */ sizeof(uint32_t) + /* keyname len */ key_len + 1; /* keyname\0 */ data = malloc(data_len); if (!data) { ret = ENOMEM; goto out; } SAFEALIGN_SET_UINT32(data, name_len, &ctr); safealign_memcpy(data+ctr, ctx->mapname, name_len + 1, &ctr); SAFEALIGN_SET_UINT32(data+ctr, key_len, &ctr); safealign_memcpy(data+ctr, key, key_len + 1, &ctr); rd.data = data; rd.len = data_len; ret = sss_autofs_make_request(SSS_AUTOFS_GETAUTOMNTBYNAME, &rd, &repbuf, &replen, &errnop); free(data); if (ret != SSS_STATUS_SUCCESS) { ret = errnop; goto out; } /* Got reply, let's parse it */ rp = 0; SAFEALIGN_COPY_UINT32(&len, repbuf+rp, &rp); if (len == 0) { /* No data */ *value = NULL; ret = ENOENT; goto out; } SAFEALIGN_COPY_UINT32(&vallen, repbuf+rp, &rp); if (vallen > len-rp) { ret = EIO; goto out; } buf = malloc(vallen); if (!buf) { ret = ENOMEM; goto out; } safealign_memcpy(buf, repbuf+rp, vallen, &rp); *value = buf; ret = 0; out: free(repbuf); sss_nss_unlock(); return ret; } errno_t _sss_endautomntent(void **context) { struct automtent *fctx; errno_t ret; int errnop; if (!context) return 0; sss_nss_lock(); sss_getautomntent_data_clean(); fctx = (struct automtent *) *context; if (fctx != NULL) { free(fctx->mapname); free(fctx); } ret = sss_autofs_make_request(SSS_AUTOFS_ENDAUTOMNTENT, NULL, NULL, NULL, &errnop); if (ret != SSS_STATUS_SUCCESS) { ret = errnop; goto out; } ret = 0; out: sss_nss_unlock(); return ret; } sssd-1.13.4/src/sss_client/autofs/PaxHeaders.16287/sss_autofs_private.h0000644000000000000000000000007412703456111022657 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.703793795 sssd-1.13.4/src/sss_client/autofs/sss_autofs_private.h0000644002412700241270000000247012703456111024331 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" /** * Selects a map for processing. */ errno_t _sss_setautomntent(const char *mapname, void **context); /** * Iterates through key/value pairs in the selected map. The key is usually * the mount point, the value is mount information (server:/export) */ errno_t _sss_getautomntent_r(char **key, char **value, void *context); /** * Returns value for a specific key */ errno_t _sss_getautomntbyname_r(const char *key, char **value, void *context); /** * Deselect a map, end the processing */ errno_t _sss_endautomntent(void **context); sssd-1.13.4/src/sss_client/PaxHeaders.16287/sss_pam_macros.h0000644000000000000000000000007412703456111020444 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.898794456 sssd-1.13.4/src/sss_client/sss_pam_macros.h0000644002412700241270000000344612703456111022122 0ustar00jhrozekjhrozek00000000000000/* SSSD Client Interface for NSS and PAM. Authors: Stephen Gallagher Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef _SSS_PAM_MACROS_H #define _SSS_PAM_MACROS_H /* Older versions of the pam development headers do not include the * _pam_overwrite_n(n,x) macro. This implementation is copied from * the Fedora 11 _pam_macros.h. */ #ifdef HAVE_SECURITY__PAM_MACROS_H # include #endif /* HAVE_SECURITY__PAM_MACROS_H */ #ifndef _pam_overwrite #define _pam_overwrite(x) \ do { \ register char *__xx__; \ if ((__xx__=(x))) \ while (*__xx__) \ *__xx__++ = '\0'; \ } while (0) #endif /* _pam_overwrite */ #ifndef _pam_overwrite_n #define _pam_overwrite_n(x,n) \ do { \ register char *__xx__; \ register unsigned int __i__ = 0; \ if ((__xx__=(x))) \ for (;__i__. */ /* PASSWD database NSS interface */ #include #include #include #include #include #include #include #include "sss_cli.h" #include "nss_mc.h" static struct sss_nss_getpwent_data { size_t len; size_t ptr; uint8_t *data; } sss_nss_getpwent_data; static void sss_nss_getpwent_data_clean(void) { if (sss_nss_getpwent_data.data != NULL) { free(sss_nss_getpwent_data.data); sss_nss_getpwent_data.data = NULL; } sss_nss_getpwent_data.len = 0; sss_nss_getpwent_data.ptr = 0; } /* GETPWNAM Request: * * 0-X: string with name * * GERTPWUID Request: * * 0-3: 32bit number with uid * * Replies: * * 0-3: 32bit unsigned number of results * 4-7: 32bit unsigned (reserved/padding) * For each result: * 0-3: 32bit number uid * 4-7: 32bit number gid * 8-X: sequence of 5, 0 terminated, strings (name, passwd, gecos, dir, shell) */ struct sss_nss_pw_rep { struct passwd *result; char *buffer; size_t buflen; }; static int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr, uint8_t *buf, size_t *len) { errno_t ret; size_t i, slen, dlen; char *sbuf; uint32_t c; if (*len < 13) { /* not enough space for data, bad packet */ return EBADMSG; } SAFEALIGN_COPY_UINT32(&c, buf, NULL); pr->result->pw_uid = c; SAFEALIGN_COPY_UINT32(&c, buf+sizeof(uint32_t), NULL); pr->result->pw_gid = c; sbuf = (char *)&buf[8]; slen = *len - 8; dlen = pr->buflen; i = 0; pr->result->pw_name = &(pr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &pr->result->pw_name, NULL); if (ret != EOK) return ret; pr->result->pw_passwd = &(pr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &pr->result->pw_passwd, NULL); if (ret != EOK) return ret; pr->result->pw_gecos = &(pr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &pr->result->pw_gecos, NULL); if (ret != EOK) return ret; pr->result->pw_dir = &(pr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &pr->result->pw_dir, NULL); if (ret != EOK) return ret; pr->result->pw_shell = &(pr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &pr->result->pw_shell, NULL); if (ret != EOK) return ret; *len = slen - i; return 0; } enum nss_status _nss_sss_getpwnam_r(const char *name, struct passwd *result, char *buffer, size_t buflen, int *errnop) { struct sss_cli_req_data rd; struct sss_nss_pw_rep pwrep; uint8_t *repbuf; size_t replen, len, name_len; uint32_t num_results; enum nss_status nret; int ret; /* Caught once glibc passing in buffer == 0x0 */ if (!buffer || !buflen) { *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; } ret = sss_strnlen(name, SSS_NAME_MAX, &name_len); if (ret != 0) { *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } ret = sss_nss_mc_getpwnam(name, name_len, result, buffer, buflen); switch (ret) { case 0: *errnop = 0; return NSS_STATUS_SUCCESS; case ERANGE: *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; case ENOENT: /* fall through, we need to actively ask the parent * if no entry is found */ break; default: /* if using the mmaped cache failed, * fall back to socket based comms */ break; } rd.len = name_len + 1; rd.data = name; sss_nss_lock(); /* previous thread might already initialize entry in mmap cache */ ret = sss_nss_mc_getpwnam(name, name_len, result, buffer, buflen); switch (ret) { case 0: *errnop = 0; nret = NSS_STATUS_SUCCESS; goto out; case ERANGE: *errnop = ERANGE; nret = NSS_STATUS_TRYAGAIN; goto out; case ENOENT: /* fall through, we need to actively ask the parent * if no entry is found */ break; default: /* if using the mmaped cache failed, * fall back to socket based comms */ break; } nret = sss_nss_make_request(SSS_NSS_GETPWNAM, &rd, &repbuf, &replen, errnop); if (nret != NSS_STATUS_SUCCESS) { goto out; } pwrep.result = result; pwrep.buffer = buffer; pwrep.buflen = buflen; /* Get number of results from repbuf. */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if (num_results == 0) { free(repbuf); nret = NSS_STATUS_NOTFOUND; goto out; } /* only 1 result is accepted for this function */ if (num_results != 1) { *errnop = EBADMSG; free(repbuf); nret = NSS_STATUS_TRYAGAIN; goto out; } len = replen - 8; ret = sss_nss_getpw_readrep(&pwrep, repbuf+8, &len); free(repbuf); if (ret) { *errnop = ret; nret = NSS_STATUS_TRYAGAIN; goto out; } nret = NSS_STATUS_SUCCESS; out: sss_nss_unlock(); return nret; } enum nss_status _nss_sss_getpwuid_r(uid_t uid, struct passwd *result, char *buffer, size_t buflen, int *errnop) { struct sss_cli_req_data rd; struct sss_nss_pw_rep pwrep; uint8_t *repbuf; size_t replen, len; uint32_t num_results; enum nss_status nret; uint32_t user_uid; int ret; /* Caught once glibc passing in buffer == 0x0 */ if (!buffer || !buflen) return ERANGE; ret = sss_nss_mc_getpwuid(uid, result, buffer, buflen); switch (ret) { case 0: *errnop = 0; return NSS_STATUS_SUCCESS; case ERANGE: *errnop = ERANGE; return NSS_STATUS_TRYAGAIN; case ENOENT: /* fall through, we need to actively ask the parent * if no entry is found */ break; default: /* if using the mmaped cache failed, * fall back to socket based comms */ break; } user_uid = uid; rd.len = sizeof(uint32_t); rd.data = &user_uid; sss_nss_lock(); /* previous thread might already initialize entry in mmap cache */ ret = sss_nss_mc_getpwuid(uid, result, buffer, buflen); switch (ret) { case 0: *errnop = 0; nret = NSS_STATUS_SUCCESS; goto out; case ERANGE: *errnop = ERANGE; nret = NSS_STATUS_TRYAGAIN; goto out; case ENOENT: /* fall through, we need to actively ask the parent * if no entry is found */ break; default: /* if using the mmaped cache failed, * fall back to socket based comms */ break; } nret = sss_nss_make_request(SSS_NSS_GETPWUID, &rd, &repbuf, &replen, errnop); if (nret != NSS_STATUS_SUCCESS) { goto out; } pwrep.result = result; pwrep.buffer = buffer; pwrep.buflen = buflen; /* Get number of results from repbuf. */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if (num_results == 0) { free(repbuf); nret = NSS_STATUS_NOTFOUND; goto out; } /* only 1 result is accepted for this function */ if (num_results != 1) { *errnop = EBADMSG; free(repbuf); nret = NSS_STATUS_TRYAGAIN; goto out; } len = replen - 8; ret = sss_nss_getpw_readrep(&pwrep, repbuf+8, &len); free(repbuf); if (ret) { *errnop = ret; nret = NSS_STATUS_TRYAGAIN; goto out; } nret = NSS_STATUS_SUCCESS; out: sss_nss_unlock(); return nret; } enum nss_status _nss_sss_setpwent(void) { enum nss_status nret; int errnop; sss_nss_lock(); /* make sure we do not have leftovers, and release memory */ sss_nss_getpwent_data_clean(); nret = sss_nss_make_request(SSS_NSS_SETPWENT, NULL, NULL, NULL, &errnop); if (nret != NSS_STATUS_SUCCESS) { errno = errnop; } sss_nss_unlock(); return nret; } static enum nss_status internal_getpwent_r(struct passwd *result, char *buffer, size_t buflen, int *errnop) { struct sss_cli_req_data rd; struct sss_nss_pw_rep pwrep; uint8_t *repbuf; size_t replen; uint32_t num_results; enum nss_status nret; uint32_t num_entries; int ret; /* Caught once glibc passing in buffer == 0x0 */ if (!buffer || !buflen) return ERANGE; /* if there are leftovers return the next one */ if (sss_nss_getpwent_data.data != NULL && sss_nss_getpwent_data.ptr < sss_nss_getpwent_data.len) { repbuf = sss_nss_getpwent_data.data + sss_nss_getpwent_data.ptr; replen = sss_nss_getpwent_data.len - sss_nss_getpwent_data.ptr; pwrep.result = result; pwrep.buffer = buffer; pwrep.buflen = buflen; ret = sss_nss_getpw_readrep(&pwrep, repbuf, &replen); if (ret) { *errnop = ret; return NSS_STATUS_TRYAGAIN; } /* advance buffer pointer */ sss_nss_getpwent_data.ptr = sss_nss_getpwent_data.len - replen; return NSS_STATUS_SUCCESS; } /* release memory if any */ sss_nss_getpwent_data_clean(); /* retrieve no more than SSS_NSS_MAX_ENTRIES at a time */ num_entries = SSS_NSS_MAX_ENTRIES; rd.len = sizeof(uint32_t); rd.data = &num_entries; nret = sss_nss_make_request(SSS_NSS_GETPWENT, &rd, &repbuf, &replen, errnop); if (nret != NSS_STATUS_SUCCESS) { return nret; } /* Get number of results from repbuf. */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if ((num_results == 0) || (replen - 8 == 0)) { free(repbuf); return NSS_STATUS_NOTFOUND; } sss_nss_getpwent_data.data = repbuf; sss_nss_getpwent_data.len = replen; sss_nss_getpwent_data.ptr = 8; /* skip metadata fields */ /* call again ourselves, this will return the first result */ return internal_getpwent_r(result, buffer, buflen, errnop); } enum nss_status _nss_sss_getpwent_r(struct passwd *result, char *buffer, size_t buflen, int *errnop) { enum nss_status nret; sss_nss_lock(); nret = internal_getpwent_r(result, buffer, buflen, errnop); sss_nss_unlock(); return nret; } enum nss_status _nss_sss_endpwent(void) { enum nss_status nret; int errnop; sss_nss_lock(); /* make sure we do not have leftovers, and release memory */ sss_nss_getpwent_data_clean(); nret = sss_nss_make_request(SSS_NSS_ENDPWENT, NULL, NULL, NULL, &errnop); if (nret != NSS_STATUS_SUCCESS) { errno = errnop; } sss_nss_unlock(); return nret; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/nss_services.c0000644000000000000000000000007412703456111020134 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.676793703 sssd-1.13.4/src/sss_client/nss_services.c0000644002412700241270000003131312703456111021604 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include "sss_cli.h" static struct sss_nss_getservent_data { size_t len; size_t ptr; uint8_t *data; } sss_nss_getservent_data; static void sss_nss_getservent_data_clean(void) { if (sss_nss_getservent_data.data != NULL) { free(sss_nss_getservent_data.data); sss_nss_getservent_data.data = NULL; } sss_nss_getservent_data.len = 0; sss_nss_getservent_data.ptr = 0; } /* GETSERVBYNAME Request * * 0-X: Sequence of two, zero-terminated strings (name, protocol). * Protocol may be zero-length to imply "any" * * GETSERVBYPORT Request: * 0-3: 16-bit port number in network byte order * 4-15: Reserved/padding * 16-X: Zero-terminated string (protocol) * Protocol may be zero-length to imply "any" * * Replies: * 0-3: 32-bit unsigned number of results * 4-7: 32-bit unsigned (reserved/padding) * 7-X: Result data (blocks equal to number of results) * * Result data: * 0-3: 32-bit unsigned port number in network byte order * 4-7: 32-bit unsigned number of aliases * 8-X: sequence of zero-terminated strings * (name, protocol, zero or more aliases) */ struct sss_nss_svc_rep { struct servent *result; char *buffer; size_t buflen; }; #define SVC_METADATA_COUNT 8 static errno_t sss_nss_getsvc_readrep(struct sss_nss_svc_rep *sr, uint8_t *buf, size_t *len) { errno_t ret; uint32_t c; uint32_t num_aliases; size_t i, l, slen, dlen, pad, ptaliases, alen; char *sbuf; /* Buffer must contain two 32-bit integers, * at least one character and null-terminator * for the name, and at least a null- * terminator for the protocol. */ if (*len < 11) { /* not enough space for data, bad packet */ return EBADMSG; } /* Get the port */ SAFEALIGN_COPY_UINT32(&c, buf, NULL); sr->result->s_port = (uint16_t)c; /* Get the number of aliases */ SAFEALIGN_COPY_UINT32(&num_aliases, buf + sizeof(uint32_t), NULL); sbuf = (char *)&buf[2 * sizeof(uint32_t)]; slen = *len - (2 * sizeof(uint32_t)); dlen = sr->buflen; /* Copy in the name */ i = 0; sr->result->s_name = &(sr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &sr->result->s_name, NULL); if (ret != EOK) return ret; /* Copy in the protocol */ sr->result->s_proto = &(sr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &sr->result->s_proto, NULL); if (ret != EOK) return ret; /* Make sure sr->buffer[i+pad] is aligned to sizeof(char *) */ pad = PADDING_SIZE(i, char *); /* Copy in the aliases */ sr->result->s_aliases = DISCARD_ALIGN(&(sr->buffer[i+pad]), char **); ptaliases = (sizeof(char *) * (num_aliases + 1)) + pad; if (ptaliases > dlen) { return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */ } dlen -= ptaliases; ptaliases += i; sr->result->s_aliases[num_aliases] = NULL; /* terminate array */ for (l = 0; l < num_aliases; l++) { sr->result->s_aliases[l] = &(sr->buffer[ptaliases]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &sr->result->s_aliases[l], &alen); if (ret != EOK) return ret; ptaliases += alen + 1; } *len = slen - i; return EOK; } enum nss_status _nss_sss_getservbyname_r(const char *name, const char *protocol, struct servent *result, char *buffer, size_t buflen, int *errnop) { struct sss_cli_req_data rd; struct sss_nss_svc_rep svcrep; size_t name_len; size_t proto_len = 0; uint8_t *repbuf; uint8_t *data; size_t replen, len; uint32_t num_results; enum nss_status nret; int ret; /* Caught once glibc passing in buffer == 0x0 */ if (!buffer || !buflen) return ERANGE; ret = sss_strnlen(name, SSS_NAME_MAX, &name_len); if (ret != 0) { *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } if (protocol) { ret = sss_strnlen(protocol, SSS_NAME_MAX, &proto_len); if (ret != 0) { *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } } rd.len = name_len + proto_len + 2; data = malloc(sizeof(uint8_t)*rd.len); if (data == NULL) { nret = NSS_STATUS_TRYAGAIN; goto out; } memcpy(data, name, name_len + 1); if (protocol) { memcpy(data + name_len + 1, protocol, proto_len + 1); } else { /* No protocol specified, pass empty string */ data[name_len + 1] = '\0'; } rd.data = data; sss_nss_lock(); nret = sss_nss_make_request(SSS_NSS_GETSERVBYNAME, &rd, &repbuf, &replen, errnop); free(data); if (nret != NSS_STATUS_SUCCESS) { goto out; } svcrep.result = result; svcrep.buffer = buffer; svcrep.buflen = buflen; /* Get number of results from repbuf. */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if (num_results == 0) { free(repbuf); nret = NSS_STATUS_NOTFOUND; goto out; } /* only 1 result is accepted for this function */ if (num_results != 1) { *errnop = EBADMSG; free(repbuf); nret = NSS_STATUS_TRYAGAIN; goto out; } len = replen - SVC_METADATA_COUNT; ret = sss_nss_getsvc_readrep(&svcrep, repbuf + SVC_METADATA_COUNT, &len); free(repbuf); if (ret) { *errnop = ret; nret = NSS_STATUS_TRYAGAIN; goto out; } nret = NSS_STATUS_SUCCESS; out: sss_nss_unlock(); return nret; } enum nss_status _nss_sss_getservbyport_r(int port, const char *protocol, struct servent *result, char *buffer, size_t buflen, int *errnop) { struct sss_cli_req_data rd; struct sss_nss_svc_rep svcrep; size_t proto_len = 0; uint8_t *repbuf; uint8_t *data; size_t p = 0; size_t replen, len; uint32_t num_results; enum nss_status nret; int ret; /* Caught once glibc passing in buffer == 0x0 */ if (!buffer || !buflen) return ERANGE; if (protocol) { ret = sss_strnlen(protocol, SSS_NAME_MAX, &proto_len); if (ret != 0) { *errnop = EINVAL; return NSS_STATUS_NOTFOUND; } } rd.len = sizeof(uint32_t)*2 + proto_len + 1; data = malloc(sizeof(uint8_t)*rd.len); if (data == NULL) { nret = NSS_STATUS_TRYAGAIN; goto out; } SAFEALIGN_SET_UINT16(data, port, &p); /* Padding */ SAFEALIGN_SET_UINT16(data + p, 0, &p); SAFEALIGN_SET_UINT32(data + p, 0, &p); if (protocol) { memcpy(data + p, protocol, proto_len + 1); } else { /* No protocol specified, pass empty string */ data[p] = '\0'; } rd.data = data; sss_nss_lock(); nret = sss_nss_make_request(SSS_NSS_GETSERVBYPORT, &rd, &repbuf, &replen, errnop); free(data); if (nret != NSS_STATUS_SUCCESS) { goto out; } svcrep.result = result; svcrep.buffer = buffer; svcrep.buflen = buflen; /* Get number of results from repbuf. */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if (num_results == 0) { free(repbuf); nret = NSS_STATUS_NOTFOUND; goto out; } /* only 1 result is accepted for this function */ if (num_results != 1) { *errnop = EBADMSG; free(repbuf); nret = NSS_STATUS_TRYAGAIN; goto out; } len = replen - SVC_METADATA_COUNT; ret = sss_nss_getsvc_readrep(&svcrep, repbuf + SVC_METADATA_COUNT, &len); free(repbuf); if (ret) { *errnop = ret; nret = NSS_STATUS_TRYAGAIN; goto out; } nret = NSS_STATUS_SUCCESS; out: sss_nss_unlock(); return nret; } enum nss_status _nss_sss_setservent(void) { enum nss_status nret; int errnop; sss_nss_lock(); /* make sure we do not have leftovers, and release memory */ sss_nss_getservent_data_clean(); nret = sss_nss_make_request(SSS_NSS_SETSERVENT, NULL, NULL, NULL, &errnop); if (nret != NSS_STATUS_SUCCESS) { errno = errnop; } sss_nss_unlock(); return nret; } static enum nss_status internal_getservent_r(struct servent *result, char *buffer, size_t buflen, int *errnop); enum nss_status _nss_sss_getservent_r(struct servent *result, char *buffer, size_t buflen, int *errnop) { enum nss_status nret; sss_nss_lock(); nret = internal_getservent_r(result, buffer, buflen, errnop); sss_nss_unlock(); return nret; } static enum nss_status internal_getservent_r(struct servent *result, char *buffer, size_t buflen, int *errnop) { struct sss_cli_req_data rd; struct sss_nss_svc_rep pwrep; uint8_t *repbuf; size_t replen; uint32_t num_results; enum nss_status nret; uint32_t num_entries; int ret; /* Caught once glibc passing in buffer == 0x0 */ if (!buffer || !buflen) return ERANGE; /* if there are leftovers return the next one */ if (sss_nss_getservent_data.data != NULL && sss_nss_getservent_data.ptr < sss_nss_getservent_data.len) { repbuf = sss_nss_getservent_data.data + sss_nss_getservent_data.ptr; replen = sss_nss_getservent_data.len - sss_nss_getservent_data.ptr; pwrep.result = result; pwrep.buffer = buffer; pwrep.buflen = buflen; ret = sss_nss_getsvc_readrep(&pwrep, repbuf, &replen); if (ret) { *errnop = ret; return NSS_STATUS_TRYAGAIN; } /* advance buffer pointer */ sss_nss_getservent_data.ptr = sss_nss_getservent_data.len - replen; return NSS_STATUS_SUCCESS; } /* release memory if any */ sss_nss_getservent_data_clean(); /* retrieve no more than SSS_NSS_MAX_ENTRIES at a time */ num_entries = SSS_NSS_MAX_ENTRIES; rd.len = sizeof(uint32_t); rd.data = &num_entries; nret = sss_nss_make_request(SSS_NSS_GETSERVENT, &rd, &repbuf, &replen, errnop); if (nret != NSS_STATUS_SUCCESS) { return nret; } /* Get number of results from repbuf */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if ((num_results == 0) || (replen - SVC_METADATA_COUNT == 0)) { free(repbuf); return NSS_STATUS_NOTFOUND; } sss_nss_getservent_data.data = repbuf; sss_nss_getservent_data.len = replen; /* skip metadata fields */ sss_nss_getservent_data.ptr = SVC_METADATA_COUNT; /* call again ourselves, this will return the first result */ return internal_getservent_r(result, buffer, buflen, errnop); } enum nss_status _nss_sss_endservent(void) { enum nss_status nret; int errnop; sss_nss_lock(); /* make sure we do not have leftovers, and release memory */ sss_nss_getservent_data_clean(); nret = sss_nss_make_request(SSS_NSS_ENDSERVENT, NULL, NULL, NULL, &errnop); if (nret != NSS_STATUS_SUCCESS) { errno = errnop; } sss_nss_unlock(); return nret; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/pam_message.h0000644000000000000000000000007412703456111017714 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.591793415 sssd-1.13.4/src/sss_client/pam_message.h0000644002412700241270000000352012703456111021363 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2015 Red Hat PAM client - create message blob This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef _PAM_MESSAGE_H_ #define _PAM_MESSAGE_H_ #include #include #include "sss_client/sss_cli.h" struct pam_items { const char *pam_service; const char *pam_user; const char *pam_tty; const char *pam_ruser; const char *pam_rhost; char *pam_authtok; char *pam_newauthtok; const char *pamstack_authtok; const char *pamstack_oldauthtok; size_t pam_service_size; size_t pam_user_size; size_t pam_tty_size; size_t pam_ruser_size; size_t pam_rhost_size; enum sss_authtok_type pam_authtok_type; size_t pam_authtok_size; enum sss_authtok_type pam_newauthtok_type; size_t pam_newauthtok_size; pid_t cli_pid; const char *login_name; char *domain_name; const char *requested_domains; size_t requested_domains_size; char *otp_vendor; char *otp_token_id; char *otp_challenge; char *first_factor; char *cert_user; char *token_name; }; int pack_message_v3(struct pam_items *pi, size_t *size, uint8_t **buffer); #endif /* _PAM_MESSAGE_H_ */ sssd-1.13.4/src/sss_client/PaxHeaders.16287/ssh0000644000000000000000000000013212703463556016010 xustar0030 mtime=1460561774.987794758 30 atime=1460561776.117798589 30 ctime=1460561774.987794758 sssd-1.13.4/src/sss_client/ssh/0000755002412700241270000000000012703463556017541 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sss_client/ssh/PaxHeaders.16287/sss_ssh_client.h0000644000000000000000000000007412703456111021253 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.591793415 sssd-1.13.4/src/sss_client/ssh/sss_ssh_client.h0000644002412700241270000000253012703456111022722 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SSS_SSH_CLIENT_H_ #define _SSS_SSH_CLIENT_H_ void usage(poptContext pc, const char *error); int set_locale(void); #define BAD_POPT_PARAMS(pc, msg, val, label) do { \ usage(pc, msg); \ val = EXIT_FAILURE; \ goto label; \ } while(0) errno_t sss_ssh_get_ent(TALLOC_CTX *mem_ctx, enum sss_cli_command command, const char *name, const char *domain, const char *alias, struct sss_ssh_ent **result); #endif /* _SSS_SSH_CLIENT_H_ */ sssd-1.13.4/src/sss_client/ssh/PaxHeaders.16287/sss_ssh_knownhostsproxy.c0000644000000000000000000000007412703456111023307 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.987794758 sssd-1.13.4/src/sss_client/ssh/sss_ssh_knownhostsproxy.c0000644002412700241270000002112112703456111024753 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "util/crypto/sss_crypto.h" #include "util/sss_ssh.h" #include "sss_client/sss_cli.h" #include "sss_client/ssh/sss_ssh_client.h" #define BUFFER_SIZE 8192 /* connect to server using socket */ static int connect_socket(int family, struct sockaddr *addr, size_t addr_len) { int flags; int sock = -1; struct pollfd fds[2]; char buffer[BUFFER_SIZE]; int i; ssize_t res; int ret; /* set O_NONBLOCK on standard input */ flags = fcntl(0, F_GETFL); if (flags == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "fcntl() failed (%d): %s\n", ret, strerror(ret)); goto done; } ret = fcntl(0, F_SETFL, flags | O_NONBLOCK); if (ret == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "fcntl() failed (%d): %s\n", ret, strerror(ret)); goto done; } /* create socket */ sock = socket(family, SOCK_STREAM, IPPROTO_TCP); if (sock == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "socket() failed (%d): %s\n", ret, strerror(ret)); goto done; } /* connect to the server */ ret = connect(sock, addr, addr_len); if (ret == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "connect() failed (%d): %s\n", ret, strerror(ret)); goto done; } /* set O_NONBLOCK on the socket */ flags = fcntl(sock, F_GETFL); if (flags == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "fcntl() failed (%d): %s\n", ret, strerror(ret)); goto done; } ret = fcntl(sock, F_SETFL, flags | O_NONBLOCK); if (ret == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "fcntl() failed (%d): %s\n", ret, strerror(ret)); goto done; } fds[0].fd = 0; fds[0].events = POLLIN; fds[1].fd = sock; fds[1].events = POLLIN; while (1) { ret = poll(fds, 2, -1); if (ret == -1) { ret = errno; if (ret == EINTR || ret == EAGAIN) { continue; } DEBUG(SSSDBG_OP_FAILURE, "poll() failed (%d): %s\n", ret, strerror(ret)); goto done; } /* read from standard input & write to socket */ /* read from socket & write to standard output */ for (i = 0; i < 2; i++) { if (fds[i].revents & POLLIN) { res = read(fds[i].fd, buffer, BUFFER_SIZE); if (res == -1) { ret = errno; if (ret == EAGAIN || ret == EINTR || ret == EWOULDBLOCK) { continue; } DEBUG(SSSDBG_OP_FAILURE, "read() failed (%d): %s\n", ret, strerror(ret)); goto done; } else if (res == 0) { ret = EOK; goto done; } errno = 0; res = sss_atomic_write_s(i == 0 ? sock : 1, buffer, res); ret = errno; if (res == -1) { DEBUG(SSSDBG_OP_FAILURE, "sss_atomic_write_s() failed (%d): %s\n", ret, strerror(ret)); goto done; } else if (ret == EPIPE) { ret = EOK; goto done; } } if (fds[i].revents & POLLHUP) { ret = EOK; goto done; } } } done: if (sock >= 0) close(sock); return ret; } /* connect to server using proxy command */ static int connect_proxy_command(char **args) { int ret; execv(args[0], (char * const *)args); ret = errno; DEBUG(SSSDBG_OP_FAILURE, "execv() failed (%d): %s\n", ret, strerror(ret)); return ret; } int main(int argc, const char **argv) { TALLOC_CTX *mem_ctx = NULL; int pc_debug = SSSDBG_DEFAULT; int pc_port = 22; const char *pc_domain = NULL; const char *pc_host = NULL; const char **pc_args = NULL; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, { "port", 'p', POPT_ARG_INT, &pc_port, 0, _("The port to use to connect to the host"), NULL }, { "domain", 'd', POPT_ARG_STRING, &pc_domain, 0, _("The SSSD domain to use"), NULL }, POPT_TABLEEND }; poptContext pc = NULL; char strport[6]; struct addrinfo ai_hint; struct addrinfo *ai = NULL; char canonhost[NI_MAXHOST]; const char *host = NULL; struct sss_ssh_ent *ent; int ret; debug_prg_name = argv[0]; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale() failed (%d): %s\n", ret, strerror(ret)); ret = EXIT_FAILURE; goto fini; } mem_ctx = talloc_new(NULL); if (!mem_ctx) { DEBUG(SSSDBG_CRIT_FAILURE, "Not enough memory\n"); ret = EXIT_FAILURE; goto fini; } /* parse parameters */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "HOST [PROXY_COMMAND]"); while ((ret = poptGetNextOpt(pc)) > 0) ; DEBUG_INIT(pc_debug); if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } if (pc_port < 1 || pc_port > 65535) { BAD_POPT_PARAMS(pc, _("Invalid port\n"), ret, fini); } pc_host = poptGetArg(pc); if (pc_host == NULL) { BAD_POPT_PARAMS(pc, _("Host not specified\n"), ret, fini); } pc_args = poptGetArgs(pc); if (pc_args && pc_args[0] && pc_args[0][0] != '/') { BAD_POPT_PARAMS(pc, _("The path to the proxy command must be absolute\n"), ret, fini); } /* canonicalize hostname */ snprintf(strport, 6, "%d", pc_port); memset(&ai_hint, 0, sizeof(struct addrinfo)); ai_hint.ai_family = AF_UNSPEC; ai_hint.ai_socktype = SOCK_STREAM; ai_hint.ai_protocol = IPPROTO_TCP; ai_hint.ai_flags = AI_ADDRCONFIG | AI_NUMERICHOST | AI_NUMERICSERV; ret = getaddrinfo(pc_host, strport, &ai_hint, &ai); if (ret) { ai_hint.ai_flags = AI_ADDRCONFIG | AI_CANONNAME | AI_NUMERICSERV; ret = getaddrinfo(pc_host, strport, &ai_hint, &ai); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "getaddrinfo() failed (%d): %s\n", ret, gai_strerror(ret)); } else { host = ai[0].ai_canonname; } } else { ret = getnameinfo(ai[0].ai_addr, ai[0].ai_addrlen, canonhost, NI_MAXHOST, NULL, 0, NI_NAMEREQD); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "getnameinfo() failed (%d): %s\n", ret, gai_strerror(ret)); } else { host = canonhost; } } if (host) { /* look up public keys */ ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_HOST_PUBKEYS, host, pc_domain, pc_host, &ent); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_ssh_get_ent() failed (%d): %s\n", ret, strerror(ret)); } } /* connect to server */ if (pc_args) { ret = connect_proxy_command(discard_const(pc_args)); } else if (ai) { ret = connect_socket(ai[0].ai_family, ai[0].ai_addr, ai[0].ai_addrlen); } else { ret = EFAULT; } ret = (ret == EOK) ? EXIT_SUCCESS : EXIT_FAILURE; fini: poptFreeContext(pc); if (ai) freeaddrinfo(ai); talloc_free(mem_ctx); return ret; } sssd-1.13.4/src/sss_client/ssh/PaxHeaders.16287/sss_ssh_authorizedkeys.c0000644000000000000000000000007412703456111023042 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.986794755 sssd-1.13.4/src/sss_client/ssh/sss_ssh_authorizedkeys.c0000644002412700241270000000631712703456111024520 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "util/crypto/sss_crypto.h" #include "util/sss_ssh.h" #include "sss_client/sss_cli.h" #include "sss_client/ssh/sss_ssh_client.h" int main(int argc, const char **argv) { TALLOC_CTX *mem_ctx = NULL; int pc_debug = SSSDBG_DEFAULT; const char *pc_domain = NULL; const char *pc_user = NULL; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, { "domain", 'd', POPT_ARG_STRING, &pc_domain, 0, _("The SSSD domain to use"), NULL }, POPT_TABLEEND }; poptContext pc = NULL; struct sss_ssh_ent *ent; size_t i; char *repr; int ret; debug_prg_name = argv[0]; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale() failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); ret = EXIT_FAILURE; goto fini; } mem_ctx = talloc_new(NULL); if (!mem_ctx) { ERROR("Not enough memory\n"); ret = EXIT_FAILURE; goto fini; } /* parse parameters */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "USER"); while ((ret = poptGetNextOpt(pc)) > 0) ; DEBUG_INIT(pc_debug); if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } pc_user = poptGetArg(pc); if (pc_user == NULL) { BAD_POPT_PARAMS(pc, _("User not specified\n"), ret, fini); } /* look up public keys */ ret = sss_ssh_get_ent(mem_ctx, SSS_SSH_GET_USER_PUBKEYS, pc_user, pc_domain, NULL, &ent); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_ssh_get_ent() failed (%d): %s\n", ret, strerror(ret)); ERROR("Error looking up public keys\n"); ret = EXIT_FAILURE; goto fini; } /* print results */ for (i = 0; i < ent->num_pubkeys; i++) { ret = sss_ssh_format_pubkey(mem_ctx, &ent->pubkeys[i], &repr); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_ssh_format_pubkey() failed (%d): %s\n", ret, strerror(ret)); continue; } printf("%s\n", repr); } ret = EXIT_SUCCESS; fini: poptFreeContext(pc); talloc_free(mem_ctx); return ret; } sssd-1.13.4/src/sss_client/ssh/PaxHeaders.16287/sss_ssh_client.c0000644000000000000000000000007412703456111021246 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.986794755 sssd-1.13.4/src/sss_client/ssh/sss_ssh_client.c0000644002412700241270000001501712703456111022721 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include "util/util.h" #include "util/crypto/sss_crypto.h" #include "util/sss_ssh.h" #include "sss_client/sss_cli.h" #include "sss_client/ssh/sss_ssh_client.h" /* FIXME - split from tools_util to create a common function */ void usage(poptContext pc, const char *error) { poptPrintUsage(pc, stderr, 0); if (error) fprintf(stderr, "%s", error); } /* FIXME - split from tools_util to create a common function */ int set_locale(void) { char *c; c = setlocale(LC_ALL, ""); if (c == NULL) { /* If setlocale fails, continue with the default * locale. */ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to set locale\n"); } errno = 0; c = bindtextdomain(PACKAGE, LOCALEDIR); if (c == NULL) { return errno; } errno = 0; c = textdomain(PACKAGE); if (c == NULL) { return errno; } return EOK; } /* SSH public key request: * * header: * 0..3: flags (unsigned int, must be combination of SSS_SSH_REQ_* flags) * 4..7: name length (unsigned int) * 8..X: name (null-terminated UTF-8 string) * alias (only included if flags & SSS_SSH_REQ_ALIAS): * 0..3: alias length (unsigned int) * 4..X: alias (null-terminated UTF-8 string) * domain (ony included if flags & SSS_SSH_REQ_DOMAIN): * 0..3: domain length (unsigned int, 0 means default domain) * 4..X: domain (null-terminated UTF-8 string) * * SSH public key reply: * * header: * 0..3: number of results (unsigned int) * 4..7: reserved (unsigned int, must be 0) * results (repeated for each result): * 0..3: flags (unsigned int, must be 0) * 4..7: name length (unsigned int) * 8..(X-1): name (null-terminated UTF-8 string) * X..(X+3): key length (unsigned int) * (X+4)..Y: key (public key data) */ errno_t sss_ssh_get_ent(TALLOC_CTX *mem_ctx, enum sss_cli_command command, const char *name, const char *domain, const char *alias, struct sss_ssh_ent **result) { TALLOC_CTX *tmp_ctx; struct sss_ssh_ent *res = NULL; errno_t ret; uint32_t flags; uint32_t name_len; uint32_t alias_len = 0; uint32_t domain_len; size_t req_len; uint8_t *req = NULL; size_t c = 0; struct sss_cli_req_data rd; int req_ret, req_errno; uint8_t *rep = NULL; size_t rep_len; uint32_t count, reserved, len, i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } /* build request */ flags = 0; name_len = strlen(name)+1; req_len = 2*sizeof(uint32_t) + name_len; if (alias) { flags |= SSS_SSH_REQ_ALIAS; alias_len = strlen(alias)+1; req_len += sizeof(uint32_t) + alias_len; } flags |= SSS_SSH_REQ_DOMAIN; domain_len = domain ? (strlen(domain)+1) : 0; req_len += sizeof(uint32_t) + domain_len; req = talloc_array(tmp_ctx, uint8_t, req_len); if (!req) { ret = ENOMEM; goto done; } SAFEALIGN_SET_UINT32(req+c, flags, &c); SAFEALIGN_SET_UINT32(req+c, name_len, &c); safealign_memcpy(req+c, name, name_len, &c); if (alias) { SAFEALIGN_SET_UINT32(req+c, alias_len, &c); safealign_memcpy(req+c, alias, alias_len, &c); } SAFEALIGN_SET_UINT32(req+c, domain_len, &c); if (domain_len > 0) { safealign_memcpy(req+c, domain, domain_len, &c); } /* send request */ rd.data = req; rd.len = req_len; req_ret = sss_ssh_make_request(command, &rd, &rep, &rep_len, &req_errno); if (req_errno != EOK) { ret = req_errno; goto done; } if (req_ret != SSS_STATUS_SUCCESS) { ret = EFAULT; goto done; } /* parse reply */ c = 0; if (rep_len < c + 2*sizeof(uint32_t)) { ret = EINVAL; goto done; } SAFEALIGN_COPY_UINT32(&count, rep+c, &c); SAFEALIGN_COPY_UINT32(&reserved, rep+c, &c); if (reserved != 0) { ret = EINVAL; goto done; } res = talloc_zero(tmp_ctx, struct sss_ssh_ent); if (!res) { ret = ENOMEM; goto done; } if (count > 0) { res->pubkeys = talloc_zero_array(res, struct sss_ssh_pubkey, count); if (!res->pubkeys) { ret = ENOMEM; goto done; } res->num_pubkeys = count; } for (i = 0; i < count; i++) { if (rep_len-c < 2*sizeof(uint32_t)) { ret = EINVAL; goto done; } SAFEALIGN_COPY_UINT32(&flags, rep+c, &c); if (flags != 0) { ret = EINVAL; goto done; } SAFEALIGN_COPY_UINT32(&len, rep+c, &c); if (len > rep_len - c - sizeof(uint32_t)) { ret = EINVAL; goto done; } if (!res->name) { res->name = talloc_array(res, char, len); if (!res->name) { ret = ENOMEM; goto done; } safealign_memcpy(res->name, rep+c, len, &c); if (strnlen(res->name, len) != len-1) { ret = EINVAL; goto done; } } else { c += len; } SAFEALIGN_COPY_UINT32(&len, rep+c, &c); if (len > rep_len - c) { ret = EINVAL; goto done; } res->pubkeys[i].data = talloc_array(res, uint8_t, len); if (!res->pubkeys[i].data) { ret = ENOMEM; goto done; } safealign_memcpy(res->pubkeys[i].data, rep+c, len, &c); res->pubkeys[i].data_len = len; } *result = talloc_steal(mem_ctx, res); ret = EOK; done: talloc_free(tmp_ctx); free(rep); return ret; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/sss_pam_compat.h0000644000000000000000000000007412703456111020443 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.898794456 sssd-1.13.4/src/sss_client/sss_pam_compat.h0000644002412700241270000000247012703456111022115 0ustar00jhrozekjhrozek00000000000000/* SSSD Compat declarations for PAM. Authors: Lukas Slebodnik Copyright (C) Red Hat, Inc 2014 This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef _SSS_PAM_COMPAT_H #define _SSS_PAM_COMPAT_H #ifdef HAVE_SECURITY_PAM_MODUTIL_H # include #endif /* HAVE_SECURITY_PAM_MODUTIL_H */ #ifdef HAVE_SECURITY_PAM_EXT_H # include #endif /* HAVE_SECURITY_PAM_EXT_H */ #ifndef HAVE_PAM_VSYSLOG #define pam_vsyslog(pamh, priority, fmt, vargs) \ vsyslog((priority), (fmt), (vargs)) #endif /* HAVE_PAM_VSYSLOG */ #ifndef PAM_BAD_ITEM # define PAM_BAD_ITEM PAM_USER_UNKNOWN #endif /* PAM_BAD_ITEM */ #endif /* _SSS_PAM_COMPAT_H */ sssd-1.13.4/src/sss_client/PaxHeaders.16287/pam_sss.c0000644000000000000000000000007412703456111017073 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.896794449 sssd-1.13.4/src/sss_client/pam_sss.c0000644002412700241270000016467012703456111020560 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2009 Red Hat Copyright (C) 2010, rhafer@suse.de, Novell Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sss_pam_compat.h" #include "sss_pam_macros.h" #include "sss_cli.h" #include "pam_message.h" #include "util/atomic_io.h" #include "util/authtok-utils.h" #include #define _(STRING) dgettext (PACKAGE, STRING) #define FLAGS_USE_FIRST_PASS (1 << 0) #define FLAGS_FORWARD_PASS (1 << 1) #define FLAGS_USE_AUTHTOK (1 << 2) #define FLAGS_IGNORE_UNKNOWN_USER (1 << 3) #define FLAGS_IGNORE_AUTHINFO_UNAVAIL (1 << 4) #define FLAGS_USE_2FA (1 << 5) #define PWEXP_FLAG "pam_sss:password_expired_flag" #define FD_DESTRUCTOR "pam_sss:fd_destructor" #define PW_RESET_MSG_FILENAME_TEMPLATE SSSD_CONF_DIR"/customize/%s/pam_sss_pw_reset_message.%s" #define PW_RESET_MSG_MAX_SIZE 4096 #define OPT_RETRY_KEY "retry=" #define OPT_DOMAINS_KEY "domains=" #define EXP_ACC_MSG _("Permission denied. ") #define SRV_MSG _("Server message: ") #define DEBUG_MGS_LEN 1024 #define MAX_AUTHTOK_SIZE (1024*1024) #define CHECK_AND_RETURN_PI_STRING(s) ((s != NULL && *s != '\0')? s : "(not available)") static void logger(pam_handle_t *pamh, int level, const char *fmt, ...) { va_list ap; va_start(ap, fmt); #ifdef DEBUG va_list apd; char debug_msg[DEBUG_MGS_LEN]; int ret; va_copy(apd, ap); ret = vsnprintf(debug_msg, DEBUG_MGS_LEN, fmt, apd); if (ret >= DEBUG_MGS_LEN) { D(("the following message is truncated: %s", debug_msg)); } else if (ret < 0) { D(("vsnprintf failed to format debug message!")); } else { D((debug_msg)); } va_end(apd); #endif pam_vsyslog(pamh, LOG_AUTHPRIV|level, fmt, ap); va_end(ap); } static void free_exp_data(pam_handle_t *pamh, void *ptr, int err) { free(ptr); } static void close_fd(pam_handle_t *pamh, void *ptr, int err) { #ifdef PAM_DATA_REPLACE if (err & PAM_DATA_REPLACE) { /* Nothing to do */ return; } #endif /* PAM_DATA_REPLACE */ D(("Closing the fd")); sss_pam_close_fd(); } static void overwrite_and_free_authtoks(struct pam_items *pi) { if (pi->pam_authtok != NULL) { _pam_overwrite_n((void *)pi->pam_authtok, pi->pam_authtok_size); free((void *)pi->pam_authtok); pi->pam_authtok = NULL; } if (pi->pam_newauthtok != NULL) { _pam_overwrite_n((void *)pi->pam_newauthtok, pi->pam_newauthtok_size); free((void *)pi->pam_newauthtok); pi->pam_newauthtok = NULL; } if (pi->first_factor != NULL) { _pam_overwrite_n((void *)pi->first_factor, strlen(pi->first_factor)); free((void *)pi->first_factor); pi->first_factor = NULL; } pi->pamstack_authtok = NULL; pi->pamstack_oldauthtok = NULL; } static void overwrite_and_free_pam_items(struct pam_items *pi) { overwrite_and_free_authtoks(pi); free(pi->domain_name); pi->domain_name = NULL; free(pi->otp_vendor); pi->otp_vendor = NULL; free(pi->otp_token_id); pi->otp_token_id = NULL; free(pi->otp_challenge); pi->otp_challenge = NULL; free(pi->cert_user); pi->cert_user = NULL; free(pi->token_name); pi->token_name = NULL; } static int null_strcmp(const char *s1, const char *s2) { if (s1 == NULL && s2 == NULL) return 0; if (s1 == NULL && s2 != NULL) return -1; if (s1 != NULL && s2 == NULL) return 1; return strcmp(s1, s2); } enum { SSS_PAM_CONV_DONE = 0, SSS_PAM_CONV_STD, SSS_PAM_CONV_REENTER, }; static int do_pam_conversation(pam_handle_t *pamh, const int msg_style, const char *msg, const char *reenter_msg, char **_answer) { int ret; int state = SSS_PAM_CONV_STD; const struct pam_conv *conv; const struct pam_message *mesg[1]; struct pam_message *pam_msg; struct pam_response *resp=NULL; char *answer = NULL; if ((msg_style == PAM_TEXT_INFO || msg_style == PAM_ERROR_MSG) && msg == NULL) return PAM_SYSTEM_ERR; if ((msg_style == PAM_PROMPT_ECHO_OFF || msg_style == PAM_PROMPT_ECHO_ON) && (msg == NULL || _answer == NULL)) return PAM_SYSTEM_ERR; if (msg_style == PAM_TEXT_INFO || msg_style == PAM_ERROR_MSG) { logger(pamh, LOG_INFO, "User %s message: %s", msg_style == PAM_TEXT_INFO ? "info" : "error", msg); } ret=pam_get_item(pamh, PAM_CONV, (const void **) &conv); if (ret != PAM_SUCCESS) return ret; do { pam_msg = malloc(sizeof(struct pam_message)); if (pam_msg == NULL) { D(("Malloc failed.")); ret = PAM_SYSTEM_ERR; goto failed; } pam_msg->msg_style = msg_style; if (state == SSS_PAM_CONV_REENTER) { pam_msg->msg = reenter_msg; } else { pam_msg->msg = msg; } mesg[0] = (const struct pam_message *) pam_msg; ret=conv->conv(1, mesg, &resp, conv->appdata_ptr); free(pam_msg); if (ret != PAM_SUCCESS) { D(("Conversation failure: %s.", pam_strerror(pamh,ret))); goto failed; } if (msg_style == PAM_PROMPT_ECHO_OFF || msg_style == PAM_PROMPT_ECHO_ON) { if (resp == NULL) { D(("response expected, but resp==NULL")); ret = PAM_SYSTEM_ERR; goto failed; } if (state == SSS_PAM_CONV_REENTER) { if (null_strcmp(answer, resp[0].resp) != 0) { logger(pamh, LOG_NOTICE, "Passwords do not match."); _pam_overwrite((void *)resp[0].resp); free(resp[0].resp); if (answer != NULL) { _pam_overwrite((void *) answer); free(answer); answer = NULL; } ret = do_pam_conversation(pamh, PAM_ERROR_MSG, _("Passwords do not match"), NULL, NULL); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); ret = PAM_SYSTEM_ERR; goto failed; } ret = PAM_CRED_ERR; goto failed; } _pam_overwrite((void *)resp[0].resp); free(resp[0].resp); } else { if (resp[0].resp == NULL) { D(("Empty password")); answer = NULL; } else { answer = strndup(resp[0].resp, MAX_AUTHTOK_SIZE); _pam_overwrite((void *)resp[0].resp); free(resp[0].resp); if(answer == NULL) { D(("strndup failed")); ret = PAM_BUF_ERR; goto failed; } } } free(resp); resp = NULL; } if (reenter_msg != NULL && state == SSS_PAM_CONV_STD) { state = SSS_PAM_CONV_REENTER; } else { state = SSS_PAM_CONV_DONE; } } while (state != SSS_PAM_CONV_DONE); if (_answer) *_answer = answer; return PAM_SUCCESS; failed: free(answer); return ret; } static errno_t display_pw_reset_message(pam_handle_t *pamh, const char *domain_name, const char *suffix) { int ret; struct stat stat_buf; char *msg_buf = NULL; int fd = -1; size_t size; size_t total_len; char *filename = NULL; if (strchr(suffix, '/') != NULL || strchr(domain_name, '/') != NULL) { D(("Suffix [%s] or domain name [%s] contain illegal character.", suffix, domain_name)); return EINVAL; } size = sizeof(PW_RESET_MSG_FILENAME_TEMPLATE) + strlen(domain_name) + strlen(suffix); filename = malloc(size); if (filename == NULL) { D(("malloc failed.")); ret = ENOMEM; goto done; } ret = snprintf(filename, size, PW_RESET_MSG_FILENAME_TEMPLATE, domain_name, suffix); if (ret < 0 || ret >= size) { D(("snprintf failed.")); ret = EFAULT; goto done; } fd = open(filename, O_RDONLY); if (fd == -1) { ret = errno; D(("open failed [%d][%s].\n", ret, strerror(ret))); goto done; } ret = fstat(fd, &stat_buf); if (ret == -1) { ret = errno; D(("fstat failed [%d][%s].", ret, strerror(ret))); goto done; } if (!S_ISREG(stat_buf.st_mode)) { logger(pamh, LOG_ERR, "Password reset message file is not a regular file."); ret = EINVAL; goto done; } if (stat_buf.st_uid != 0 || stat_buf.st_gid != 0 || (stat_buf.st_mode & ~S_IFMT) != 0644) { logger(pamh, LOG_ERR,"Permission error, " "file [%s] must be owned by root with permissions 0644.", filename); ret = EPERM; goto done; } if (stat_buf.st_size > PW_RESET_MSG_MAX_SIZE) { logger(pamh, LOG_ERR, "Password reset message file is too large."); ret = EFBIG; goto done; } msg_buf = malloc(stat_buf.st_size + 1); if (msg_buf == NULL) { D(("malloc failed.")); ret = ENOMEM; goto done; } errno = 0; total_len = sss_atomic_read_s(fd, msg_buf, stat_buf.st_size); if (total_len == -1) { ret = errno; D(("read failed [%d][%s].", ret, strerror(ret))); goto done; } ret = close(fd); fd = -1; if (ret == -1) { ret = errno; D(("close failed [%d][%s].", ret, strerror(ret))); } if (total_len != stat_buf.st_size) { D(("read fewer bytes [%d] than expected [%d].", total_len, stat_buf.st_size)); ret = EIO; goto done; } msg_buf[stat_buf.st_size] = '\0'; ret = do_pam_conversation(pamh, PAM_TEXT_INFO, msg_buf, NULL, NULL); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); } done: if (fd != -1) { close(fd); } free(msg_buf); free(filename); return ret; } static errno_t select_pw_reset_message(pam_handle_t *pamh, struct pam_items *pi) { int ret; char *locale; const char *domain_name; domain_name = pi->domain_name; if (domain_name == NULL || *domain_name == '\0') { D(("Domain name is unknown.")); return EINVAL; } locale = setlocale(LC_MESSAGES, NULL); ret = -1; if (locale != NULL) { ret = display_pw_reset_message(pamh, domain_name, locale); } if (ret != 0) { ret = display_pw_reset_message(pamh, domain_name, "txt"); } if (ret != 0) { ret = do_pam_conversation(pamh, PAM_TEXT_INFO, _("Password reset by root is not supported."), NULL, NULL); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); } } return ret; } static int user_info_offline_auth(pam_handle_t *pamh, size_t buflen, uint8_t *buf) { int ret; int64_t expire_date; struct tm tm; char expire_str[128]; char user_msg[256]; expire_str[0] = '\0'; if (buflen != sizeof(uint32_t) + sizeof(int64_t)) { D(("User info response data has the wrong size")); return PAM_BUF_ERR; } memcpy(&expire_date, buf + sizeof(uint32_t), sizeof(int64_t)); if (expire_date > 0) { if (localtime_r((time_t *) &expire_date, &tm) != NULL) { ret = strftime(expire_str, sizeof(expire_str), "%c", &tm); if (ret == 0) { D(("strftime failed.")); expire_str[0] = '\0'; } } else { D(("localtime_r failed")); } } ret = snprintf(user_msg, sizeof(user_msg), "%s%s%s.", _("Authenticated with cached credentials"), expire_str[0] ? _(", your cached password will expire at: ") : "", expire_str[0] ? expire_str : ""); if (ret < 0 || ret >= sizeof(user_msg)) { D(("snprintf failed.")); return PAM_SYSTEM_ERR; } ret = do_pam_conversation(pamh, PAM_TEXT_INFO, user_msg, NULL, NULL); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); return PAM_SYSTEM_ERR; } return PAM_SUCCESS; } static int user_info_grace_login(pam_handle_t *pamh, size_t buflen, uint8_t *buf) { int ret; uint32_t grace; char user_msg[256]; if (buflen != 2* sizeof(uint32_t)) { D(("User info response data has the wrong size")); return PAM_BUF_ERR; } memcpy(&grace, buf + sizeof(uint32_t), sizeof(uint32_t)); ret = snprintf(user_msg, sizeof(user_msg), _("Your password has expired. " "You have %1$d grace login(s) remaining."), grace); if (ret < 0 || ret >= sizeof(user_msg)) { D(("snprintf failed.")); return PAM_SYSTEM_ERR; } ret = do_pam_conversation(pamh, PAM_TEXT_INFO, user_msg, NULL, NULL); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); return PAM_SYSTEM_ERR; } return PAM_SUCCESS; } #define MINSEC 60 #define HOURSEC (60*MINSEC) #define DAYSEC (24*HOURSEC) static int user_info_expire_warn(pam_handle_t *pamh, size_t buflen, uint8_t *buf) { int ret; uint32_t expire; char user_msg[256]; const char* unit="second(s)"; if (buflen != 2* sizeof(uint32_t)) { D(("User info response data has the wrong size")); return PAM_BUF_ERR; } memcpy(&expire, buf + sizeof(uint32_t), sizeof(uint32_t)); if (expire >= DAYSEC) { expire /= DAYSEC; unit = "day(s)"; } else if (expire >= HOURSEC) { expire /= HOURSEC; unit = "hour(s)"; } else if (expire >= MINSEC) { expire /= MINSEC; unit = "minute(s)"; } ret = snprintf(user_msg, sizeof(user_msg), _("Your password will expire in %1$d %2$s."), expire, unit); if (ret < 0 || ret >= sizeof(user_msg)) { D(("snprintf failed.")); return PAM_SYSTEM_ERR; } ret = do_pam_conversation(pamh, PAM_TEXT_INFO, user_msg, NULL, NULL); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); return PAM_SYSTEM_ERR; } return PAM_SUCCESS; } static int user_info_offline_auth_delayed(pam_handle_t *pamh, size_t buflen, uint8_t *buf) { int ret; int64_t delayed_until; struct tm tm; char delay_str[128]; char user_msg[256]; delay_str[0] = '\0'; if (buflen != sizeof(uint32_t) + sizeof(int64_t)) { D(("User info response data has the wrong size")); return PAM_BUF_ERR; } memcpy(&delayed_until, buf + sizeof(uint32_t), sizeof(int64_t)); if (delayed_until <= 0) { D(("User info response data has an invalid value")); return PAM_BUF_ERR; } if (localtime_r((time_t *) &delayed_until, &tm) != NULL) { ret = strftime(delay_str, sizeof(delay_str), "%c", &tm); if (ret == 0) { D(("strftime failed.")); delay_str[0] = '\0'; } } else { D(("localtime_r failed")); } ret = snprintf(user_msg, sizeof(user_msg), "%s%s.", _("Authentication is denied until: "), delay_str); if (ret < 0 || ret >= sizeof(user_msg)) { D(("snprintf failed.")); return PAM_SYSTEM_ERR; } ret = do_pam_conversation(pamh, PAM_TEXT_INFO, user_msg, NULL, NULL); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); return PAM_SYSTEM_ERR; } return PAM_SUCCESS; } static int user_info_offline_chpass(pam_handle_t *pamh) { int ret; ret = do_pam_conversation(pamh, PAM_TEXT_INFO, _("System is offline, password change not possible"), NULL, NULL); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); return PAM_SYSTEM_ERR; } return PAM_SUCCESS; } static int user_info_otp_chpass(pam_handle_t *pamh) { int ret; ret = do_pam_conversation(pamh, PAM_TEXT_INFO, _("After changing the OTP password, you need to " "log out and back in order to acquire a ticket"), NULL, NULL); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); return PAM_SYSTEM_ERR; } return PAM_SUCCESS; } static int user_info_account_expired(pam_handle_t *pamh, size_t buflen, uint8_t *buf) { int ret; uint32_t msg_len; char *user_msg; size_t bufsize = 0; /* resp_type and length of message are expected to be in buf */ if (buflen < 2* sizeof(uint32_t)) { D(("User info response data is too short")); return PAM_BUF_ERR; } /* msg_len = legth of message */ memcpy(&msg_len, buf + sizeof(uint32_t), sizeof(uint32_t)); if (buflen != 2* sizeof(uint32_t) + msg_len) { D(("User info response data has the wrong size")); return PAM_BUF_ERR; } bufsize = strlen(EXP_ACC_MSG) + 1; if (msg_len > 0) { bufsize += strlen(SRV_MSG) + msg_len; } user_msg = (char *)malloc(sizeof(char) * bufsize); if (!user_msg) { D(("Out of memory.")); return PAM_SYSTEM_ERR; } ret = snprintf(user_msg, bufsize, "%s%s%.*s", EXP_ACC_MSG, msg_len > 0 ? SRV_MSG : "", msg_len, msg_len > 0 ? (char *)(buf + 2 * sizeof(uint32_t)) : "" ); if (ret < 0 || ret > bufsize) { D(("snprintf failed.")); free(user_msg); return PAM_SYSTEM_ERR; } ret = do_pam_conversation(pamh, PAM_TEXT_INFO, user_msg, NULL, NULL); free(user_msg); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); return PAM_SYSTEM_ERR; } return PAM_SUCCESS; } static int user_info_chpass_error(pam_handle_t *pamh, size_t buflen, uint8_t *buf) { int ret; uint32_t msg_len; char *user_msg; size_t bufsize = 0; if (buflen < 2* sizeof(uint32_t)) { D(("User info response data is too short")); return PAM_BUF_ERR; } memcpy(&msg_len, buf + sizeof(uint32_t), sizeof(uint32_t)); if (buflen != 2* sizeof(uint32_t) + msg_len) { D(("User info response data has the wrong size")); return PAM_BUF_ERR; } bufsize = strlen(_("Password change failed. ")) + 1; if (msg_len > 0) { bufsize += strlen(_("Server message: ")) + msg_len; } user_msg = (char *)malloc(sizeof(char) * bufsize); if (!user_msg) { D(("Out of memory.")); return PAM_SYSTEM_ERR; } ret = snprintf(user_msg, bufsize, "%s%s%.*s", _("Password change failed. "), msg_len > 0 ? _("Server message: ") : "", msg_len, msg_len > 0 ? (char *)(buf + 2 * sizeof(uint32_t)) : "" ); if (ret < 0 || ret > bufsize) { D(("snprintf failed.")); free(user_msg); return PAM_SYSTEM_ERR; } ret = do_pam_conversation(pamh, PAM_TEXT_INFO, user_msg, NULL, NULL); free(user_msg); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); return PAM_SYSTEM_ERR; } return PAM_SUCCESS; } static int eval_user_info_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf) { int ret; uint32_t type; if (buflen < sizeof(uint32_t)) { D(("User info response data is too short")); return PAM_BUF_ERR; } memcpy(&type, buf, sizeof(uint32_t)); switch(type) { case SSS_PAM_USER_INFO_OFFLINE_AUTH: ret = user_info_offline_auth(pamh, buflen, buf); break; case SSS_PAM_USER_INFO_GRACE_LOGIN: ret = user_info_grace_login(pamh, buflen, buf); break; case SSS_PAM_USER_INFO_EXPIRE_WARN: ret = user_info_expire_warn(pamh, buflen, buf); break; case SSS_PAM_USER_INFO_OFFLINE_AUTH_DELAYED: ret = user_info_offline_auth_delayed(pamh, buflen, buf); break; case SSS_PAM_USER_INFO_OFFLINE_CHPASS: ret = user_info_offline_chpass(pamh); break; case SSS_PAM_USER_INFO_OTP_CHPASS: ret = user_info_otp_chpass(pamh); break; case SSS_PAM_USER_INFO_CHPASS_ERROR: ret = user_info_chpass_error(pamh, buflen, buf); break; case SSS_PAM_USER_INFO_ACCOUNT_EXPIRED: ret = user_info_account_expired(pamh, buflen, buf); break; default: D(("Unknown user info type [%d]", type)); ret = PAM_SYSTEM_ERR; } return ret; } static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf, struct pam_items *pi) { int ret; size_t p=0; char *env_item; int32_t c; int32_t type; int32_t len; int32_t pam_status; size_t offset; if (buflen < (2*sizeof(int32_t))) { D(("response buffer is too small")); return PAM_BUF_ERR; } memcpy(&pam_status, buf+p, sizeof(int32_t)); p += sizeof(int32_t); memcpy(&c, buf+p, sizeof(int32_t)); p += sizeof(int32_t); while(c>0) { if (buflen < (p+2*sizeof(int32_t))) { D(("response buffer is too small")); return PAM_BUF_ERR; } memcpy(&type, buf+p, sizeof(int32_t)); p += sizeof(int32_t); memcpy(&len, buf+p, sizeof(int32_t)); p += sizeof(int32_t); if (buflen < (p + len)) { D(("response buffer is too small")); return PAM_BUF_ERR; } switch(type) { case SSS_PAM_SYSTEM_INFO: if (buf[p + (len -1)] != '\0') { D(("system info does not end with \\0.")); break; } logger(pamh, LOG_INFO, "system info: [%s]", &buf[p]); break; case SSS_PAM_DOMAIN_NAME: if (buf[p + (len -1)] != '\0') { D(("domain name does not end with \\0.")); break; } D(("domain name: [%s]", &buf[p])); pi->domain_name = strdup((char *) &buf[p]); if (pi->domain_name == NULL) { D(("strdup failed")); } break; case SSS_ENV_ITEM: case SSS_PAM_ENV_ITEM: case SSS_ALL_ENV_ITEM: if (buf[p + (len -1)] != '\0') { D(("env item does not end with \\0.")); break; } D(("env item: [%s]", &buf[p])); if (type == SSS_PAM_ENV_ITEM || type == SSS_ALL_ENV_ITEM) { ret = pam_putenv(pamh, (char *)&buf[p]); if (ret != PAM_SUCCESS) { D(("pam_putenv failed.")); break; } } if (type == SSS_ENV_ITEM || type == SSS_ALL_ENV_ITEM) { env_item = strdup((char *)&buf[p]); if (env_item == NULL) { D(("strdup failed")); break; } ret = putenv(env_item); if (ret == -1) { D(("putenv failed.")); break; } } break; case SSS_PAM_USER_INFO: ret = eval_user_info_response(pamh, len, &buf[p]); if (ret != PAM_SUCCESS) { D(("eval_user_info_response failed")); } break; case SSS_PAM_TEXT_MSG: if (buf[p + (len -1)] != '\0') { D(("system info does not end with \\0.")); break; } ret = do_pam_conversation(pamh, PAM_TEXT_INFO, (char *) &buf[p], NULL, NULL); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); } break; case SSS_OTP: D(("OTP was used, removing authtokens.")); overwrite_and_free_authtoks(pi); ret = pam_set_item(pamh, PAM_AUTHTOK, NULL); if (ret != PAM_SUCCESS) { D(("Failed to remove PAM_AUTHTOK after using otp [%s]", pam_strerror(pamh,ret))); } break; case SSS_PAM_OTP_INFO: if (buf[p + (len - 1)] != '\0') { D(("otp info does not end with \\0.")); break; } pi->otp_vendor = strdup((char *) &buf[p]); if (pi->otp_vendor == NULL) { D(("strdup failed")); break; } offset = strlen(pi->otp_vendor) + 1; if (offset >= len) { D(("OTP message size mismatch")); free(pi->otp_vendor); pi->otp_vendor = NULL; break; } pi->otp_token_id = strdup((char *) &buf[p + offset]); if (pi->otp_token_id == NULL) { D(("strdup failed")); break; } offset += strlen(pi->otp_token_id) + 1; if (offset >= len) { D(("OTP message size mismatch")); free(pi->otp_token_id); pi->otp_token_id = NULL; break; } pi->otp_challenge = strdup((char *) &buf[p + offset]); if (pi->otp_challenge == NULL) { D(("strdup failed")); break; } break; case SSS_PAM_CERT_INFO: if (buf[p + (len - 1)] != '\0') { D(("cert info does not end with \\0.")); break; } pi->cert_user = strdup((char *) &buf[p]); if (pi->cert_user == NULL) { D(("strdup failed")); break; } offset = strlen(pi->cert_user) + 1; if (offset >= len) { D(("Cert message size mismatch")); free(pi->cert_user); pi->cert_user = NULL; break; } pi->token_name = strdup((char *) &buf[p + offset]); if (pi->token_name == NULL) { D(("strdup failed")); break; } D(("cert user: [%s] token name: [%s]", pi->cert_user, pi->token_name)); break; default: D(("Unknown response type [%d]", type)); } p += len; --c; } return PAM_SUCCESS; } static int get_pam_items(pam_handle_t *pamh, struct pam_items *pi) { int ret; pi->pam_authtok_type = SSS_AUTHTOK_TYPE_EMPTY; pi->pam_authtok = NULL; pi->pam_authtok_size = 0; pi->pam_newauthtok_type = SSS_AUTHTOK_TYPE_EMPTY; pi->pam_newauthtok = NULL; pi->pam_newauthtok_size = 0; pi->first_factor = NULL; ret = pam_get_item(pamh, PAM_SERVICE, (const void **) &(pi->pam_service)); if (ret != PAM_SUCCESS) return ret; if (pi->pam_service == NULL) pi->pam_service=""; pi->pam_service_size=strlen(pi->pam_service)+1; ret = pam_get_item(pamh, PAM_USER, (const void **) &(pi->pam_user)); if (ret != PAM_SUCCESS) return ret; if (pi->pam_user == NULL) { D(("No user found, aborting.")); return PAM_BAD_ITEM; } if (strcmp(pi->pam_user, "root") == 0) { D(("pam_sss will not handle root.")); return PAM_USER_UNKNOWN; } pi->pam_user_size=strlen(pi->pam_user)+1; ret = pam_get_item(pamh, PAM_TTY, (const void **) &(pi->pam_tty)); if (ret != PAM_SUCCESS) return ret; if (pi->pam_tty == NULL) pi->pam_tty=""; pi->pam_tty_size=strlen(pi->pam_tty)+1; ret = pam_get_item(pamh, PAM_RUSER, (const void **) &(pi->pam_ruser)); if (ret != PAM_SUCCESS) return ret; if (pi->pam_ruser == NULL) pi->pam_ruser=""; pi->pam_ruser_size=strlen(pi->pam_ruser)+1; ret = pam_get_item(pamh, PAM_RHOST, (const void **) &(pi->pam_rhost)); if (ret != PAM_SUCCESS) return ret; if (pi->pam_rhost == NULL) pi->pam_rhost=""; pi->pam_rhost_size=strlen(pi->pam_rhost)+1; ret = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &(pi->pamstack_authtok)); if (ret != PAM_SUCCESS) return ret; if (pi->pamstack_authtok == NULL) pi->pamstack_authtok=""; ret = pam_get_item(pamh, PAM_OLDAUTHTOK, (const void **) &(pi->pamstack_oldauthtok)); if (ret != PAM_SUCCESS) return ret; if (pi->pamstack_oldauthtok == NULL) pi->pamstack_oldauthtok=""; pi->cli_pid = getpid(); pi->login_name = pam_modutil_getlogin(pamh); if (pi->login_name == NULL) pi->login_name=""; pi->domain_name = NULL; if (pi->requested_domains == NULL) pi->requested_domains = ""; pi->requested_domains_size = strlen(pi->requested_domains) + 1; pi->otp_vendor = NULL; pi->otp_token_id = NULL; pi->otp_challenge = NULL; pi->cert_user = NULL; pi->token_name = NULL; return PAM_SUCCESS; } static void print_pam_items(struct pam_items *pi) { if (pi == NULL) return; D(("Service: %s", CHECK_AND_RETURN_PI_STRING(pi->pam_service))); D(("User: %s", CHECK_AND_RETURN_PI_STRING(pi->pam_user))); D(("Tty: %s", CHECK_AND_RETURN_PI_STRING(pi->pam_tty))); D(("Ruser: %s", CHECK_AND_RETURN_PI_STRING(pi->pam_ruser))); D(("Rhost: %s", CHECK_AND_RETURN_PI_STRING(pi->pam_rhost))); D(("Pamstack_Authtok: %s", CHECK_AND_RETURN_PI_STRING(pi->pamstack_authtok))); D(("Pamstack_Oldauthtok: %s", CHECK_AND_RETURN_PI_STRING(pi->pamstack_oldauthtok))); D(("Authtok: %s", CHECK_AND_RETURN_PI_STRING(pi->pam_authtok))); D(("Newauthtok: %s", CHECK_AND_RETURN_PI_STRING(pi->pam_newauthtok))); D(("Cli_PID: %d", pi->cli_pid)); D(("Requested domains: %s", pi->requested_domains)); } static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi, enum sss_cli_command task, bool quiet_mode) { int ret; int sret; int errnop; struct sss_cli_req_data rd; uint8_t *buf = NULL; uint8_t *repbuf = NULL; size_t replen; int pam_status = PAM_SYSTEM_ERR; print_pam_items(pi); ret = pack_message_v3(pi, &rd.len, &buf); if (ret != 0) { D(("pack_message failed.")); pam_status = PAM_SYSTEM_ERR; goto done; } rd.data = buf; errnop = 0; ret = sss_pam_make_request(task, &rd, &repbuf, &replen, &errnop); sret = pam_set_data(pamh, FD_DESTRUCTOR, NULL, close_fd); if (sret != PAM_SUCCESS) { D(("pam_set_data failed, client might leaks fds")); } if (ret != PAM_SUCCESS) { if (errnop != 0) { logger(pamh, LOG_ERR, "Request to sssd failed. %s", ssscli_err2string(errnop)); } pam_status = PAM_AUTHINFO_UNAVAIL; goto done; } /* FIXME: add an end signature */ if (replen < (2*sizeof(int32_t))) { D(("response not in expected format.")); pam_status = PAM_SYSTEM_ERR; goto done; } SAFEALIGN_COPY_UINT32(&pam_status, repbuf, NULL); ret = eval_response(pamh, replen, repbuf, pi); if (ret != PAM_SUCCESS) { D(("eval_response failed.")); pam_status = ret; goto done; } switch (task) { case SSS_PAM_AUTHENTICATE: logger(pamh, (pam_status == PAM_SUCCESS ? LOG_INFO : LOG_NOTICE), "authentication %s; logname=%s uid=%lu euid=%d tty=%s " "ruser=%s rhost=%s user=%s", pam_status == PAM_SUCCESS ? "success" : "failure", pi->login_name, getuid(), (unsigned long) geteuid(), pi->pam_tty, pi->pam_ruser, pi->pam_rhost, pi->pam_user); if (pam_status != PAM_SUCCESS) { /* don't log if quiet_mode is on and pam_status is * User not known to the underlying authentication module */ if (!quiet_mode || pam_status != 10) { logger(pamh, LOG_NOTICE, "received for user %s: %d (%s)", pi->pam_user, pam_status, pam_strerror(pamh,pam_status)); } } break; case SSS_PAM_CHAUTHTOK_PRELIM: if (pam_status != PAM_SUCCESS) { /* don't log if quiet_mode is on and pam_status is * User not known to the underlying authentication module */ if (!quiet_mode || pam_status != 10) { logger(pamh, LOG_NOTICE, "Authentication failed for user %s: %d (%s)", pi->pam_user, pam_status, pam_strerror(pamh,pam_status)); } } break; case SSS_PAM_CHAUTHTOK: if (pam_status != PAM_SUCCESS) { logger(pamh, LOG_NOTICE, "Password change failed for user %s: %d (%s)", pi->pam_user, pam_status, pam_strerror(pamh,pam_status)); } break; case SSS_PAM_ACCT_MGMT: if (pam_status != PAM_SUCCESS) { /* don't log if quiet_mode is on and pam_status is * User not known to the underlying authentication module */ if (!quiet_mode || pam_status != 10) { logger(pamh, LOG_NOTICE, "Access denied for user %s: %d (%s)", pi->pam_user, pam_status, pam_strerror(pamh,pam_status)); } } break; case SSS_PAM_OPEN_SESSION: case SSS_PAM_SETCRED: case SSS_PAM_CLOSE_SESSION: case SSS_PAM_PREAUTH: break; default: D(("Illegal task [%#x]", task)); return PAM_SYSTEM_ERR; } done: if (buf != NULL ) { _pam_overwrite_n((void *)buf, rd.len); free(buf); } free(repbuf); return pam_status; } static int prompt_password(pam_handle_t *pamh, struct pam_items *pi, const char *prompt) { int ret; char *answer = NULL; ret = do_pam_conversation(pamh, PAM_PROMPT_ECHO_OFF, prompt, NULL, &answer); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); return ret; } if (answer == NULL) { pi->pam_authtok = NULL; pi->pam_authtok_type = SSS_AUTHTOK_TYPE_EMPTY; pi->pam_authtok_size=0; } else { pi->pam_authtok = strdup(answer); _pam_overwrite((void *)answer); free(answer); answer=NULL; if (pi->pam_authtok == NULL) { return PAM_BUF_ERR; } pi->pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD; pi->pam_authtok_size=strlen(pi->pam_authtok); } return PAM_SUCCESS; } static int prompt_2fa(pam_handle_t *pamh, struct pam_items *pi, const char *prompt_fa1, const char *prompt_fa2) { int ret; const struct pam_conv *conv; const struct pam_message *mesg[2] = { NULL, NULL }; struct pam_message m[2] = { {0}, {0} }; struct pam_response *resp = NULL; size_t needed_size; ret = pam_get_item(pamh, PAM_CONV, (const void **) &conv); if (ret != PAM_SUCCESS) { return ret; } m[0].msg_style = PAM_PROMPT_ECHO_OFF; m[0].msg = prompt_fa1; m[1].msg_style = PAM_PROMPT_ECHO_OFF; m[1].msg = prompt_fa2; mesg[0] = (const struct pam_message *) m; /* The following assignment might look a bit odd but is recommended in the * pam_conv man page to make sure that the second argument of the PAM * conversation function can be interpreted in two different ways. * Basically it is important that both the actual struct pam_message and * the pointers to the struct pam_message are arrays. Since the assignment * makes clear that mesg[] and (*mesg)[] are arrays it should be kept this * way and not be replaced by other equivalent assignments. */ mesg[1] = & (( *mesg )[1]); ret = conv->conv(2, mesg, &resp, conv->appdata_ptr); if (ret != PAM_SUCCESS) { D(("Conversation failure: %s.", pam_strerror(pamh, ret))); return ret; } if (resp == NULL) { D(("response expected, but resp==NULL")); return PAM_SYSTEM_ERR; } if (resp[0].resp == NULL || *(resp[0].resp) == '\0') { D(("Missing factor.")); ret = PAM_CRED_INSUFFICIENT; goto done; } if (resp[1].resp == NULL || *(resp[1].resp) == '\0' || (pi->pam_service != NULL && strcmp(pi->pam_service, "sshd") == 0 && strcmp(resp[0].resp, resp[1].resp) == 0)) { /* Missing second factor, assume first factor contains combined 2FA * credentials. * Special handling for SSH with password authentication. Combined * 2FA credentials are used but SSH puts them in both responses. */ pi->pam_authtok = strndup(resp[0].resp, MAX_AUTHTOK_SIZE); if (pi->pam_authtok == NULL) { D(("strndup failed.")); ret = PAM_BUF_ERR; goto done; } pi->pam_authtok_size = strlen(pi->pam_authtok) + 1; pi->pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD; } else { ret = sss_auth_pack_2fa_blob(resp[0].resp, 0, resp[1].resp, 0, NULL, 0, &needed_size); if (ret != EAGAIN) { D(("sss_auth_pack_2fa_blob failed.")); ret = PAM_BUF_ERR; goto done; } pi->pam_authtok = malloc(needed_size); if (pi->pam_authtok == NULL) { D(("malloc failed.")); ret = PAM_BUF_ERR; goto done; } ret = sss_auth_pack_2fa_blob(resp[0].resp, 0, resp[1].resp, 0, (uint8_t *) pi->pam_authtok, needed_size, &needed_size); if (ret != EOK) { D(("sss_auth_pack_2fa_blob failed.")); ret = PAM_BUF_ERR; goto done; } pi->pam_authtok_size = needed_size; pi->pam_authtok_type = SSS_AUTHTOK_TYPE_2FA; pi->first_factor = strndup(resp[0].resp, MAX_AUTHTOK_SIZE); if (pi->first_factor == NULL) { D(("strndup failed.")); ret = PAM_BUF_ERR; goto done; } } ret = PAM_SUCCESS; done: if (resp != NULL) { if (resp[0].resp != NULL) { _pam_overwrite((void *)resp[0].resp); free(resp[0].resp); } if (resp[1].resp != NULL) { _pam_overwrite((void *)resp[1].resp); free(resp[1].resp); } free(resp); resp = NULL; } return ret; } #define SC_PROMPT_FMT "PIN for %s for user %s" static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi) { int ret; char *answer = NULL; char *prompt; size_t size; if (pi->token_name == NULL || *pi->token_name == '\0' || pi->cert_user == NULL || *pi->cert_user == '\0') { return EINVAL; } size = sizeof(SC_PROMPT_FMT) + strlen(pi->token_name) + strlen(pi->cert_user); prompt = malloc(size); if (prompt == NULL) { D(("malloc failed.")); return ENOMEM; } ret = snprintf(prompt, size, SC_PROMPT_FMT, pi->token_name, pi->cert_user); if (ret < 0 || ret >= size) { D(("snprintf failed.")); free(prompt); return EFAULT; } ret = do_pam_conversation(pamh, PAM_PROMPT_ECHO_OFF, prompt, NULL, &answer); free(prompt); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); return ret; } if (answer == NULL) { pi->pam_authtok = NULL; pi->pam_authtok_type = SSS_AUTHTOK_TYPE_EMPTY; pi->pam_authtok_size=0; } else { pi->pam_authtok = strdup(answer); _pam_overwrite((void *)answer); free(answer); answer=NULL; if (pi->pam_authtok == NULL) { return PAM_BUF_ERR; } pi->pam_authtok_type = SSS_AUTHTOK_TYPE_SC_PIN; pi->pam_authtok_size=strlen(pi->pam_authtok); } return PAM_SUCCESS; } static int prompt_new_password(pam_handle_t *pamh, struct pam_items *pi) { int ret; char *answer = NULL; ret = do_pam_conversation(pamh, PAM_PROMPT_ECHO_OFF, _("New Password: "), _("Reenter new Password: "), &answer); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); return ret; } if (answer == NULL) { pi->pam_newauthtok = NULL; pi->pam_newauthtok_type = SSS_AUTHTOK_TYPE_EMPTY; pi->pam_newauthtok_size=0; } else { pi->pam_newauthtok = strdup(answer); _pam_overwrite((void *)answer); free(answer); answer=NULL; if (pi->pam_newauthtok == NULL) { return PAM_BUF_ERR; } pi->pam_newauthtok_type = SSS_AUTHTOK_TYPE_PASSWORD; pi->pam_newauthtok_size=strlen(pi->pam_newauthtok); } return PAM_SUCCESS; } static void eval_argv(pam_handle_t *pamh, int argc, const char **argv, uint32_t *flags, int *retries, bool *quiet_mode, const char **domains) { char *ep; *quiet_mode = false; for (; argc-- > 0; ++argv) { if (strcmp(*argv, "forward_pass") == 0) { *flags |= FLAGS_FORWARD_PASS; } else if (strcmp(*argv, "use_first_pass") == 0) { *flags |= FLAGS_USE_FIRST_PASS; } else if (strcmp(*argv, "use_authtok") == 0) { *flags |= FLAGS_USE_AUTHTOK; } else if (strncmp(*argv, OPT_DOMAINS_KEY, strlen(OPT_DOMAINS_KEY)) == 0) { if (*(*argv+strlen(OPT_DOMAINS_KEY)) == '\0') { logger(pamh, LOG_ERR, "Missing argument to option domains."); *domains = ""; } else { *domains = *argv+strlen(OPT_DOMAINS_KEY); } } else if (strncmp(*argv, OPT_RETRY_KEY, strlen(OPT_RETRY_KEY)) == 0) { if (*(*argv+6) == '\0') { logger(pamh, LOG_ERR, "Missing argument to option retry."); *retries = 0; } else { errno = 0; *retries = strtol(*argv+6, &ep, 10); if (errno != 0) { D(("strtol failed [%d][%s]", errno, strerror(errno))); *retries = 0; } if (*ep != '\0') { logger(pamh, LOG_ERR, "Argument to option retry contains " "extra characters."); *retries = 0; } if (*retries < 0) { logger(pamh, LOG_ERR, "Argument to option retry must not " "be negative."); *retries = 0; } } } else if (strcmp(*argv, "quiet") == 0) { *quiet_mode = true; } else if (strcmp(*argv, "ignore_unknown_user") == 0) { *flags |= FLAGS_IGNORE_UNKNOWN_USER; } else if (strcmp(*argv, "ignore_authinfo_unavail") == 0) { *flags |= FLAGS_IGNORE_AUTHINFO_UNAVAIL; } else if (strcmp(*argv, "use_2fa") == 0) { *flags |= FLAGS_USE_2FA; } else { logger(pamh, LOG_WARNING, "unknown option: %s", *argv); } } return; } static int get_authtok_for_authentication(pam_handle_t *pamh, struct pam_items *pi, uint32_t flags) { int ret; if (flags & FLAGS_USE_FIRST_PASS) { pi->pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD; pi->pam_authtok = strdup(pi->pamstack_authtok); if (pi->pam_authtok == NULL) { D(("option use_first_pass set, but no password found")); return PAM_BUF_ERR; } pi->pam_authtok_size = strlen(pi->pam_authtok); } else { if (flags & FLAGS_USE_2FA || (pi->otp_vendor != NULL && pi->otp_token_id != NULL && pi->otp_challenge != NULL)) { ret = prompt_2fa(pamh, pi, _("First Factor: "), _("Second Factor: ")); } else if (pi->cert_user != NULL) { ret = prompt_sc_pin(pamh, pi); } else { ret = prompt_password(pamh, pi, _("Password: ")); } if (ret != PAM_SUCCESS) { D(("failed to get password from user")); return ret; } if (flags & FLAGS_FORWARD_PASS) { if (pi->pam_authtok_type == SSS_AUTHTOK_TYPE_PASSWORD) { ret = pam_set_item(pamh, PAM_AUTHTOK, pi->pam_authtok); } else if (pi->pam_authtok_type == SSS_AUTHTOK_TYPE_2FA && pi->first_factor != NULL) { ret = pam_set_item(pamh, PAM_AUTHTOK, pi->first_factor); } else { ret = EINVAL; } if (ret != PAM_SUCCESS) { D(("Failed to set PAM_AUTHTOK [%s], " "authtok may not be available for other modules", pam_strerror(pamh,ret))); } } } return PAM_SUCCESS; } static int get_authtok_for_password_change(pam_handle_t *pamh, struct pam_items *pi, uint32_t flags, int pam_flags) { int ret; const int *exp_data = NULL; pam_get_data(pamh, PWEXP_FLAG, (const void **) &exp_data); /* we query for the old password during PAM_PRELIM_CHECK to make * pam_sss work e.g. with pam_cracklib */ if (pam_flags & PAM_PRELIM_CHECK) { if ( (getuid() != 0 || exp_data ) && !(flags & FLAGS_USE_FIRST_PASS)) { ret = prompt_password(pamh, pi, _("Current Password: ")); if (ret != PAM_SUCCESS) { D(("failed to get password from user")); return ret; } ret = pam_set_item(pamh, PAM_OLDAUTHTOK, pi->pam_authtok); if (ret != PAM_SUCCESS) { D(("Failed to set PAM_OLDAUTHTOK [%s], " "oldauthtok may not be available", pam_strerror(pamh,ret))); return ret; } } return PAM_SUCCESS; } if (pi->pamstack_oldauthtok == NULL) { if (getuid() != 0) { D(("no password found for chauthtok")); return PAM_BUF_ERR; } else { pi->pam_authtok_type = SSS_AUTHTOK_TYPE_EMPTY; pi->pam_authtok = NULL; pi->pam_authtok_size = 0; } } else { pi->pam_authtok = strdup(pi->pamstack_oldauthtok); if (pi->pam_authtok == NULL) { D(("strdup failed")); return PAM_BUF_ERR; } pi->pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD; pi->pam_authtok_size = strlen(pi->pam_authtok); } if (flags & FLAGS_USE_AUTHTOK) { pi->pam_newauthtok_type = SSS_AUTHTOK_TYPE_PASSWORD; pi->pam_newauthtok = strdup(pi->pamstack_authtok); if (pi->pam_newauthtok == NULL) { D(("option use_authtok set, but no new password found")); return PAM_BUF_ERR; } pi->pam_newauthtok_size = strlen(pi->pam_newauthtok); } else { ret = prompt_new_password(pamh, pi); if (ret != PAM_SUCCESS) { D(("failed to get new password from user")); return ret; } if (flags & FLAGS_FORWARD_PASS) { ret = pam_set_item(pamh, PAM_AUTHTOK, pi->pam_newauthtok); if (ret != PAM_SUCCESS) { D(("Failed to set PAM_AUTHTOK [%s], " "oldauthtok may not be available", pam_strerror(pamh,ret))); } } } return PAM_SUCCESS; } static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, int pam_flags, int argc, const char **argv) { int ret; int pam_status; struct pam_items pi; uint32_t flags = 0; const int *exp_data; int *pw_exp_data; bool retry = false; bool quiet_mode = false; int retries = 0; const char *domains = NULL; bindtextdomain(PACKAGE, LOCALEDIR); D(("Hello pam_sssd: %#x", task)); eval_argv(pamh, argc, argv, &flags, &retries, &quiet_mode, &domains); /* Fail all authentication on misconfigured domains= parameter. The admin * probably wanted to restrict authentication, so it's safer to fail */ if (domains && strcmp(domains, "") == 0) { return PAM_SYSTEM_ERR; } pi.requested_domains = domains; ret = get_pam_items(pamh, &pi); if (ret != PAM_SUCCESS) { D(("get items returned error: %s", pam_strerror(pamh,ret))); if (flags & FLAGS_IGNORE_UNKNOWN_USER && ret == PAM_USER_UNKNOWN) { ret = PAM_IGNORE; } if (flags & FLAGS_IGNORE_AUTHINFO_UNAVAIL && ret == PAM_AUTHINFO_UNAVAIL) { ret = PAM_IGNORE; } return ret; } do { retry = false; switch(task) { case SSS_PAM_AUTHENTICATE: /* * Only do preauth if * - FLAGS_USE_FIRST_PASS is not set * - no password is on the stack * - preauth indicator file exists. */ if ( !(flags & FLAGS_USE_FIRST_PASS) && pi.pam_authtok == NULL && access(PAM_PREAUTH_INDICATOR, F_OK) == 0) { pam_status = send_and_receive(pamh, &pi, SSS_PAM_PREAUTH, quiet_mode); if (pam_status != PAM_SUCCESS) { D(("send_and_receive returned [%d] during pre-auth", pam_status)); /* * Since we are only interested in the result message * and will always use password authentication * as a fallback, errors can be ignored here. */ } } ret = get_authtok_for_authentication(pamh, &pi, flags); if (ret != PAM_SUCCESS) { D(("failed to get authentication token: %s", pam_strerror(pamh, ret))); return ret; } break; case SSS_PAM_CHAUTHTOK: ret = get_authtok_for_password_change(pamh, &pi, flags, pam_flags); if (ret != PAM_SUCCESS) { D(("failed to get tokens for password change: %s", pam_strerror(pamh, ret))); overwrite_and_free_pam_items(&pi); return ret; } if (pam_flags & PAM_PRELIM_CHECK) { task = SSS_PAM_CHAUTHTOK_PRELIM; } break; case SSS_PAM_ACCT_MGMT: case SSS_PAM_SETCRED: case SSS_PAM_OPEN_SESSION: case SSS_PAM_CLOSE_SESSION: break; default: D(("Illegal task [%#x]", task)); return PAM_SYSTEM_ERR; } pam_status = send_and_receive(pamh, &pi, task, quiet_mode); if (flags & FLAGS_IGNORE_UNKNOWN_USER && pam_status == PAM_USER_UNKNOWN) { pam_status = PAM_IGNORE; } if (flags & FLAGS_IGNORE_AUTHINFO_UNAVAIL && pam_status == PAM_AUTHINFO_UNAVAIL) { pam_status = PAM_IGNORE; } switch (task) { case SSS_PAM_AUTHENTICATE: /* We allow sssd to send the return code PAM_NEW_AUTHTOK_REQD during * authentication, see sss_cli.h for details */ if (pam_status == PAM_NEW_AUTHTOK_REQD) { D(("Authtoken expired, trying to change it")); pw_exp_data = malloc(sizeof(int)); if (pw_exp_data == NULL) { D(("malloc failed.")); pam_status = PAM_BUF_ERR; break; } *pw_exp_data = 1; pam_status = pam_set_data(pamh, PWEXP_FLAG, pw_exp_data, free_exp_data); if (pam_status != PAM_SUCCESS) { D(("pam_set_data failed.")); } } break; case SSS_PAM_ACCT_MGMT: if (pam_status == PAM_SUCCESS && pam_get_data(pamh, PWEXP_FLAG, (const void **) &exp_data) == PAM_SUCCESS) { ret = do_pam_conversation(pamh, PAM_TEXT_INFO, _("Password expired. Change your password now."), NULL, NULL); if (ret != PAM_SUCCESS) { D(("do_pam_conversation failed.")); } pam_status = PAM_NEW_AUTHTOK_REQD; } break; case SSS_PAM_CHAUTHTOK: if (pam_status != PAM_SUCCESS && pam_status != PAM_USER_UNKNOWN) { ret = pam_set_item(pamh, PAM_AUTHTOK, NULL); if (ret != PAM_SUCCESS) { D(("Failed to unset PAM_AUTHTOK [%s]", pam_strerror(pamh,ret))); } ret = pam_set_item(pamh, PAM_OLDAUTHTOK, NULL); if (ret != PAM_SUCCESS) { D(("Failed to unset PAM_OLDAUTHTOK [%s]", pam_strerror(pamh,ret))); } } break; case SSS_PAM_CHAUTHTOK_PRELIM: if (pam_status == PAM_PERM_DENIED && pi.pam_authtok_size == 0 && getuid() == 0 && pam_get_data(pamh, PWEXP_FLAG, (const void **) &exp_data) != PAM_SUCCESS) { ret = select_pw_reset_message(pamh, &pi); if (ret != 0) { D(("select_pw_reset_message failed.\n")); } } default: /* nothing to do */ break; } overwrite_and_free_pam_items(&pi); D(("retries [%d].", retries)); if (pam_status != PAM_SUCCESS && (task == SSS_PAM_AUTHENTICATE || task == SSS_PAM_CHAUTHTOK_PRELIM) && retries > 0) { retry = true; retries--; flags &= ~FLAGS_USE_FIRST_PASS; ret = pam_set_item(pamh, PAM_AUTHTOK, NULL); if (ret != PAM_SUCCESS) { D(("Failed to unset PAM_AUTHTOK [%s]", pam_strerror(pamh,ret))); } ret = pam_set_item(pamh, PAM_OLDAUTHTOK, NULL); if (ret != PAM_SUCCESS) { D(("Failed to unset PAM_OLDAUTHTOK [%s]", pam_strerror(pamh,ret))); } } } while(retry); return pam_status; } PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv ) { return pam_sss(SSS_PAM_AUTHENTICATE, pamh, flags, argc, argv); } PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv ) { return pam_sss(SSS_PAM_SETCRED, pamh, flags, argc, argv); } PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv ) { return pam_sss(SSS_PAM_ACCT_MGMT, pamh, flags, argc, argv); } PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv ) { return pam_sss(SSS_PAM_CHAUTHTOK, pamh, flags, argc, argv); } PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv ) { return pam_sss(SSS_PAM_OPEN_SESSION, pamh, flags, argc, argv); } PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv ) { return pam_sss(SSS_PAM_CLOSE_SESSION, pamh, flags, argc, argv); } #ifdef PAM_STATIC /* static module data */ struct pam_module _pam_sssd_modstruct ={ "pam_sssd", pam_sm_authenticate, pam_sm_setcred, pam_sm_acct_mgmt, pam_sm_open_session, pam_sm_close_session, pam_sm_chauthtok }; #endif sssd-1.13.4/src/sss_client/PaxHeaders.16287/common.c0000644000000000000000000000007312703456111016715 xustar0030 atime=1460561751.653715637 29 ctime=1460561774.67279369 sssd-1.13.4/src/sss_client/common.c0000644002412700241270000007752512703456111020405 0ustar00jhrozekjhrozek00000000000000/* * System Security Services Daemon. NSS client interface * * Copyright (C) Simo Sorce 2007 * * Winbind derived code: * Copyright (C) Tim Potter 2000 * Copyright (C) Andrew Tridgell 2000 * Copyright (C) Andrew Bartlett 2002 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define _(STRING) dgettext (PACKAGE, STRING) #include "sss_cli.h" #if HAVE_PTHREAD #include #endif /* * Note we set MSG_NOSIGNAL to avoid * having to fiddle with signal masks * but also do not want to die in case * SIGPIPE gets raised and the application * does not handle it. */ #ifdef MSG_NOSIGNAL #define SSS_DEFAULT_WRITE_FLAGS MSG_NOSIGNAL #else #define SSS_DEFAULT_WRITE_FLAGS 0 #endif /* common functions */ int sss_cli_sd = -1; /* the sss client socket descriptor */ struct stat sss_cli_sb; /* the sss client stat buffer */ #if HAVE_FUNCTION_ATTRIBUTE_DESTRUCTOR __attribute__((destructor)) #endif static void sss_cli_close_socket(void) { if (sss_cli_sd != -1) { close(sss_cli_sd); sss_cli_sd = -1; } } /* Requests: * * byte 0-3: 32bit unsigned with length (the complete packet length: 0 to X) * byte 4-7: 32bit unsigned with command code * byte 8-11: 32bit unsigned (reserved) * byte 12-15: 32bit unsigned (reserved) * byte 16-X: (optional) request structure associated to the command code used */ static enum sss_status sss_cli_send_req(enum sss_cli_command cmd, struct sss_cli_req_data *rd, int *errnop) { uint32_t header[4]; size_t datasent; header[0] = SSS_NSS_HEADER_SIZE + (rd?rd->len:0); header[1] = cmd; header[2] = 0; header[3] = 0; datasent = 0; while (datasent < header[0]) { struct pollfd pfd; int rdsent; int res, error; *errnop = 0; pfd.fd = sss_cli_sd; pfd.events = POLLOUT; do { errno = 0; res = poll(&pfd, 1, SSS_CLI_SOCKET_TIMEOUT); error = errno; /* If error is EINTR here, we'll try again * If it's any other error, we'll catch it * below. */ } while (error == EINTR); switch (res) { case -1: *errnop = error; break; case 0: *errnop = ETIME; break; case 1: if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) { *errnop = EPIPE; } if (!(pfd.revents & POLLOUT)) { *errnop = EBUSY; } break; default: /* more than one avail ?? */ *errnop = EBADF; break; } if (*errnop) { sss_cli_close_socket(); return SSS_STATUS_UNAVAIL; } errno = 0; if (datasent < SSS_NSS_HEADER_SIZE) { res = send(sss_cli_sd, (char *)header + datasent, SSS_NSS_HEADER_SIZE - datasent, SSS_DEFAULT_WRITE_FLAGS); } else { rdsent = datasent - SSS_NSS_HEADER_SIZE; res = send(sss_cli_sd, (const char *)rd->data + rdsent, rd->len - rdsent, SSS_DEFAULT_WRITE_FLAGS); } error = errno; if ((res == -1) || (res == 0)) { if ((error == EINTR) || error == EAGAIN) { /* If the write was interrupted, go back through * the loop and try again */ continue; } /* Write failed */ sss_cli_close_socket(); *errnop = error; return SSS_STATUS_UNAVAIL; } datasent += res; } return SSS_STATUS_SUCCESS; } /* Replies: * * byte 0-3: 32bit unsigned with length (the complete packet length: 0 to X) * byte 4-7: 32bit unsigned with command code * byte 8-11: 32bit unsigned with the request status (server errno) * byte 12-15: 32bit unsigned (reserved) * byte 16-X: (optional) reply structure associated to the command code used */ static enum sss_status sss_cli_recv_rep(enum sss_cli_command cmd, uint8_t **_buf, int *_len, int *errnop) { uint32_t header[4]; size_t datarecv; uint8_t *buf = NULL; bool pollhup = false; int len; int ret; header[0] = SSS_NSS_HEADER_SIZE; /* unitl we know the real length */ header[1] = 0; header[2] = 0; header[3] = 0; datarecv = 0; buf = NULL; len = 0; *errnop = 0; while (datarecv < header[0]) { struct pollfd pfd; int bufrecv; int res, error; pfd.fd = sss_cli_sd; pfd.events = POLLIN; do { errno = 0; res = poll(&pfd, 1, SSS_CLI_SOCKET_TIMEOUT); error = errno; /* If error is EINTR here, we'll try again * If it's any other error, we'll catch it * below. */ } while (error == EINTR); switch (res) { case -1: *errnop = error; break; case 0: *errnop = ETIME; break; case 1: if (pfd.revents & (POLLHUP)) { pollhup = true; } if (pfd.revents & (POLLERR | POLLNVAL)) { *errnop = EPIPE; } if (!(pfd.revents & POLLIN)) { *errnop = EBUSY; } break; default: /* more than one avail ?? */ *errnop = EBADF; break; } if (*errnop) { sss_cli_close_socket(); ret = SSS_STATUS_UNAVAIL; goto failed; } errno = 0; if (datarecv < SSS_NSS_HEADER_SIZE) { res = read(sss_cli_sd, (char *)header + datarecv, SSS_NSS_HEADER_SIZE - datarecv); } else { bufrecv = datarecv - SSS_NSS_HEADER_SIZE; res = read(sss_cli_sd, (char *) buf + bufrecv, header[0] - datarecv); } error = errno; if ((res == -1) || (res == 0)) { if ((error == EINTR) || error == EAGAIN) { /* If the read was interrupted, go back through * the loop and try again */ continue; } /* Read failed. I think the only useful thing * we can do here is just return -1 and fail * since the transaction has failed half way * through. */ sss_cli_close_socket(); *errnop = error; ret = SSS_STATUS_UNAVAIL; goto failed; } datarecv += res; if (datarecv == SSS_NSS_HEADER_SIZE && len == 0) { /* at this point recv buf is not yet * allocated and the header has just * been read, do checks and proceed */ if (header[2] != 0) { /* server side error */ sss_cli_close_socket(); *errnop = header[2]; if (*errnop == EAGAIN) { ret = SSS_STATUS_TRYAGAIN; goto failed; } else { ret = SSS_STATUS_UNAVAIL; goto failed; } } if (header[1] != cmd) { /* wrong command id */ sss_cli_close_socket(); *errnop = EBADMSG; ret = SSS_STATUS_UNAVAIL; goto failed; } if (header[0] > SSS_NSS_HEADER_SIZE) { len = header[0] - SSS_NSS_HEADER_SIZE; buf = malloc(len); if (!buf) { sss_cli_close_socket(); *errnop = ENOMEM; ret = SSS_STATUS_UNAVAIL; goto failed; } } } } if (pollhup) { sss_cli_close_socket(); } *_len = len; *_buf = buf; return SSS_STATUS_SUCCESS; failed: free(buf); return ret; } /* this function will check command codes match and returned length is ok */ /* repbuf and replen report only the data section not the header */ static enum sss_status sss_cli_make_request_nochecks( enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop) { enum sss_status ret; uint8_t *buf = NULL; int len = 0; /* send data */ ret = sss_cli_send_req(cmd, rd, errnop); if (ret != SSS_STATUS_SUCCESS) { return ret; } /* data sent, now get reply */ ret = sss_cli_recv_rep(cmd, &buf, &len, errnop); if (ret != SSS_STATUS_SUCCESS) { return ret; } /* we got through, now we have the custom data in buf if any, * return it if requested */ if (repbuf && buf) { *repbuf = buf; if (replen) { *replen = len; } } else { free(buf); if (replen) { *replen = 0; } } return SSS_STATUS_SUCCESS; } /* GET_VERSION Reply: * 0-3: 32bit unsigned version number */ static bool sss_cli_check_version(const char *socket_name) { uint8_t *repbuf = NULL; size_t replen; enum sss_status nret; int errnop; uint32_t expected_version; uint32_t obtained_version; struct sss_cli_req_data req; if (strcmp(socket_name, SSS_NSS_SOCKET_NAME) == 0) { expected_version = SSS_NSS_PROTOCOL_VERSION; } else if (strcmp(socket_name, SSS_PAM_SOCKET_NAME) == 0 || strcmp(socket_name, SSS_PAM_PRIV_SOCKET_NAME) == 0) { expected_version = SSS_PAM_PROTOCOL_VERSION; } else if (strcmp(socket_name, SSS_SUDO_SOCKET_NAME) == 0) { expected_version = SSS_SUDO_PROTOCOL_VERSION; } else if (strcmp(socket_name, SSS_AUTOFS_SOCKET_NAME) == 0) { expected_version = SSS_AUTOFS_PROTOCOL_VERSION; } else if (strcmp(socket_name, SSS_SSH_SOCKET_NAME) == 0) { expected_version = SSS_SSH_PROTOCOL_VERSION; } else if (strcmp(socket_name, SSS_PAC_SOCKET_NAME) == 0) { expected_version = SSS_PAC_PROTOCOL_VERSION; } else { return false; } req.len = sizeof(expected_version); req.data = &expected_version; nret = sss_cli_make_request_nochecks(SSS_GET_VERSION, &req, &repbuf, &replen, &errnop); if (nret != SSS_STATUS_SUCCESS) { return false; } if (!repbuf) { return false; } SAFEALIGN_COPY_UINT32(&obtained_version, repbuf, NULL); free(repbuf); return (obtained_version == expected_version); } /* this 2 functions are adapted from samba3 winbinbd's wb_common.c */ /* Make sure socket handle isn't stdin (0), stdout(1) or stderr(2) by setting * the limit to 3 */ #define RECURSION_LIMIT 3 static int make_nonstd_fd_internals(int fd, int limit) { int new_fd; if (fd >= 0 && fd <= 2) { #ifdef F_DUPFD if ((new_fd = fcntl(fd, F_DUPFD, 3)) == -1) { return -1; } /* Paranoia */ if (new_fd < 3) { close(new_fd); return -1; } close(fd); return new_fd; #else if (limit <= 0) return -1; new_fd = dup(fd); if (new_fd == -1) return -1; /* use the program stack to hold our list of FDs to close */ new_fd = make_nonstd_fd_internals(new_fd, limit - 1); close(fd); return new_fd; #endif } return fd; } /**************************************************************************** Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available, else if SYSV use O_NDELAY if BSD use FNDELAY Set close on exec also. ****************************************************************************/ static int make_safe_fd(int fd) { int result, flags; int new_fd = make_nonstd_fd_internals(fd, RECURSION_LIMIT); if (new_fd == -1) { close(fd); return -1; } /* Socket should be nonblocking. */ #ifdef O_NONBLOCK #define FLAG_TO_SET O_NONBLOCK #else #ifdef SYSV #define FLAG_TO_SET O_NDELAY #else /* BSD */ #define FLAG_TO_SET FNDELAY #endif #endif if ((flags = fcntl(new_fd, F_GETFL)) == -1) { close(new_fd); return -1; } flags |= FLAG_TO_SET; if (fcntl(new_fd, F_SETFL, flags) == -1) { close(new_fd); return -1; } #undef FLAG_TO_SET /* Socket should be closed on exec() */ #ifdef FD_CLOEXEC result = flags = fcntl(new_fd, F_GETFD, 0); if (flags >= 0) { flags |= FD_CLOEXEC; result = fcntl( new_fd, F_SETFD, flags ); } if (result < 0) { close(new_fd); return -1; } #endif return new_fd; } static int sss_cli_open_socket(int *errnop, const char *socket_name) { struct sockaddr_un nssaddr; bool inprogress = true; bool connected = false; unsigned int wait_time; unsigned int sleep_time; time_t start_time = time(NULL); int ret; int sd; memset(&nssaddr, 0, sizeof(struct sockaddr_un)); nssaddr.sun_family = AF_UNIX; strncpy(nssaddr.sun_path, socket_name, strlen(socket_name) + 1); sd = socket(AF_UNIX, SOCK_STREAM, 0); if (sd == -1) { *errnop = errno; return -1; } /* set as non-blocking, close on exec, and make sure standard * descriptors are not used */ sd = make_safe_fd(sd); if (sd == -1) { *errnop = errno; return -1; } /* this piece is adapted from winbind client code */ wait_time = 0; sleep_time = 0; while (inprogress) { int connect_errno = 0; socklen_t errnosize; struct pollfd pfd; wait_time += sleep_time; ret = connect(sd, (struct sockaddr *)&nssaddr, sizeof(nssaddr)); if (ret == 0) { connected = true; break; } switch(errno) { case EINPROGRESS: pfd.fd = sd; pfd.events = POLLOUT; ret = poll(&pfd, 1, SSS_CLI_SOCKET_TIMEOUT - wait_time); if (ret > 0) { errnosize = sizeof(connect_errno); ret = getsockopt(sd, SOL_SOCKET, SO_ERROR, &connect_errno, &errnosize); if (ret >= 0 && connect_errno == 0) { connected = true; break; } } wait_time = time(NULL) - start_time; break; case EAGAIN: if (wait_time < SSS_CLI_SOCKET_TIMEOUT) { sleep_time = rand() % 2 + 1; sleep(sleep_time); } break; default: *errnop = errno; inprogress = false; break; } if (wait_time >= SSS_CLI_SOCKET_TIMEOUT) { inprogress = false; } if (connected) { inprogress = false; } } if (!connected) { close(sd); return -1; } ret = fstat(sd, &sss_cli_sb); if (ret != 0) { close(sd); return -1; } return sd; } static enum sss_status sss_cli_check_socket(int *errnop, const char *socket_name) { static pid_t mypid; struct stat mysb; int mysd; int ret; if (getpid() != mypid) { ret = fstat(sss_cli_sd, &mysb); if (ret == 0) { if (S_ISSOCK(mysb.st_mode) && mysb.st_dev == sss_cli_sb.st_dev && mysb.st_ino == sss_cli_sb.st_ino) { sss_cli_close_socket(); } } sss_cli_sd = -1; mypid = getpid(); } /* check if the socket has been closed on the other side */ if (sss_cli_sd != -1) { struct pollfd pfd; int res, error; *errnop = 0; pfd.fd = sss_cli_sd; pfd.events = POLLIN | POLLOUT; do { errno = 0; res = poll(&pfd, 1, SSS_CLI_SOCKET_TIMEOUT); error = errno; /* If error is EINTR here, we'll try again * If it's any other error, we'll catch it * below. */ } while (error == EINTR); switch (res) { case -1: *errnop = error; break; case 0: *errnop = ETIME; break; case 1: if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) { *errnop = EPIPE; } if (!(pfd.revents & (POLLIN | POLLOUT))) { *errnop = EBUSY; } break; default: /* more than one avail ?? */ *errnop = EBADF; break; } if (*errnop == 0) { return SSS_STATUS_SUCCESS; } sss_cli_close_socket(); } mysd = sss_cli_open_socket(errnop, socket_name); if (mysd == -1) { return SSS_STATUS_UNAVAIL; } sss_cli_sd = mysd; if (sss_cli_check_version(socket_name)) { return SSS_STATUS_SUCCESS; } sss_cli_close_socket(); *errnop = EFAULT; return SSS_STATUS_UNAVAIL; } /* this function will check command codes match and returned length is ok */ /* repbuf and replen report only the data section not the header */ enum nss_status sss_nss_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop) { enum sss_status ret; char *envval; /* avoid looping in the nss daemon */ envval = getenv("_SSS_LOOPS"); if (envval && strcmp(envval, "NO") == 0) { return NSS_STATUS_NOTFOUND; } ret = sss_cli_check_socket(errnop, SSS_NSS_SOCKET_NAME); if (ret != SSS_STATUS_SUCCESS) { #ifdef NONSTANDARD_SSS_NSS_BEHAVIOUR *errnop = 0; errno = 0; return NSS_STATUS_NOTFOUND; #else return NSS_STATUS_UNAVAIL; #endif } ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop); if (ret == SSS_STATUS_UNAVAIL && *errnop == EPIPE) { /* try reopen socket */ ret = sss_cli_check_socket(errnop, SSS_NSS_SOCKET_NAME); if (ret != SSS_STATUS_SUCCESS) { #ifdef NONSTANDARD_SSS_NSS_BEHAVIOUR *errnop = 0; errno = 0; return NSS_STATUS_NOTFOUND; #else return NSS_STATUS_UNAVAIL; #endif } /* and make request one more time */ ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop); } switch (ret) { case SSS_STATUS_TRYAGAIN: return NSS_STATUS_TRYAGAIN; case SSS_STATUS_SUCCESS: return NSS_STATUS_SUCCESS; case SSS_STATUS_UNAVAIL: default: #ifdef NONSTANDARD_SSS_NSS_BEHAVIOUR *errnop = 0; errno = 0; return NSS_STATUS_NOTFOUND; #else return NSS_STATUS_UNAVAIL; #endif } } int sss_pac_check_and_open(void) { enum sss_status ret; int errnop; ret = sss_cli_check_socket(&errnop, SSS_PAC_SOCKET_NAME); if (ret != SSS_STATUS_SUCCESS) { return EIO; } return EOK; } int sss_pac_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop) { enum sss_status ret; char *envval; /* avoid looping in the nss daemon */ envval = getenv("_SSS_LOOPS"); if (envval && strcmp(envval, "NO") == 0) { return NSS_STATUS_NOTFOUND; } ret = sss_cli_check_socket(errnop, SSS_PAC_SOCKET_NAME); if (ret != SSS_STATUS_SUCCESS) { return NSS_STATUS_UNAVAIL; } ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop); if (ret == SSS_STATUS_UNAVAIL && *errnop == EPIPE) { /* try reopen socket */ ret = sss_cli_check_socket(errnop, SSS_PAC_SOCKET_NAME); if (ret != SSS_STATUS_SUCCESS) { return NSS_STATUS_UNAVAIL; } /* and make request one more time */ ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop); } switch (ret) { case SSS_STATUS_TRYAGAIN: return NSS_STATUS_TRYAGAIN; case SSS_STATUS_SUCCESS: return NSS_STATUS_SUCCESS; case SSS_STATUS_UNAVAIL: default: return NSS_STATUS_UNAVAIL; } } errno_t check_server_cred(int sockfd) { #ifdef HAVE_UCRED int ret; struct ucred server_cred; socklen_t server_cred_len = sizeof(server_cred); ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &server_cred, &server_cred_len); if (ret != 0) { return errno; } if (server_cred_len != sizeof(struct ucred)) { return ESSS_BAD_CRED_MSG; } if (server_cred.uid != 0 || server_cred.gid != 0) { return ESSS_SERVER_NOT_TRUSTED; } #endif return 0; } int sss_pam_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop) { int ret, statret; errno_t error; enum sss_status status; char *envval; struct stat stat_buf; const char *socket_name; sss_pam_lock(); /* avoid looping in the pam daemon */ envval = getenv("_SSS_LOOPS"); if (envval && strcmp(envval, "NO") == 0) { ret = PAM_SERVICE_ERR; goto out; } /* only root shall use the privileged pipe */ if (getuid() == 0 && getgid() == 0) { socket_name = SSS_PAM_PRIV_SOCKET_NAME; statret = stat(socket_name, &stat_buf); if (statret != 0) { ret = PAM_SERVICE_ERR; goto out; } if ( ! (stat_buf.st_uid == 0 && stat_buf.st_gid == 0 && S_ISSOCK(stat_buf.st_mode) && (stat_buf.st_mode & ~S_IFMT) == 0600 )) { *errnop = ESSS_BAD_PRIV_SOCKET; ret = PAM_SERVICE_ERR; goto out; } } else { socket_name = SSS_PAM_SOCKET_NAME; statret = stat(socket_name, &stat_buf); if (statret != 0) { ret = PAM_SERVICE_ERR; goto out; } if ( ! (stat_buf.st_uid == 0 && stat_buf.st_gid == 0 && S_ISSOCK(stat_buf.st_mode) && (stat_buf.st_mode & ~S_IFMT) == 0666 )) { *errnop = ESSS_BAD_PUB_SOCKET; ret = PAM_SERVICE_ERR; goto out; } } status = sss_cli_check_socket(errnop, socket_name); if (status != SSS_STATUS_SUCCESS) { ret = PAM_SERVICE_ERR; goto out; } error = check_server_cred(sss_cli_sd); if (error != 0) { sss_cli_close_socket(); *errnop = error; ret = PAM_SERVICE_ERR; goto out; } status = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop); if (status == SSS_STATUS_UNAVAIL && *errnop == EPIPE) { /* try reopen socket */ status = sss_cli_check_socket(errnop, socket_name); if (status != SSS_STATUS_SUCCESS) { ret = PAM_SERVICE_ERR; goto out; } /* and make request one more time */ status = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop); } if (status == SSS_STATUS_SUCCESS) { ret = PAM_SUCCESS; } else { ret = PAM_SERVICE_ERR; } out: sss_pam_unlock(); return ret; } void sss_pam_close_fd(void) { sss_pam_lock(); if (sss_cli_sd != -1) { close(sss_cli_sd); sss_cli_sd = -1; } sss_pam_unlock(); } static enum sss_status sss_cli_make_request_with_checks(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop, const char *socket_name) { enum sss_status ret = SSS_STATUS_UNAVAIL; ret = sss_cli_check_socket(errnop, socket_name); if (ret != SSS_STATUS_SUCCESS) { return SSS_STATUS_UNAVAIL; } ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop); if (ret == SSS_STATUS_UNAVAIL && *errnop == EPIPE) { /* try reopen socket */ ret = sss_cli_check_socket(errnop, socket_name); if (ret != SSS_STATUS_SUCCESS) { return SSS_STATUS_UNAVAIL; } /* and make request one more time */ ret = sss_cli_make_request_nochecks(cmd, rd, repbuf, replen, errnop); } return ret; } int sss_sudo_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop) { return sss_cli_make_request_with_checks(cmd, rd, repbuf, replen, errnop, SSS_SUDO_SOCKET_NAME); } int sss_autofs_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop) { return sss_cli_make_request_with_checks(cmd, rd, repbuf, replen, errnop, SSS_AUTOFS_SOCKET_NAME); } int sss_ssh_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop) { return sss_cli_make_request_with_checks(cmd, rd, repbuf, replen, errnop, SSS_SSH_SOCKET_NAME); } const char *ssscli_err2string(int err) { const char *m; switch(err) { case ESSS_BAD_PRIV_SOCKET: return _("Privileged socket has wrong ownership or permissions."); break; case ESSS_BAD_PUB_SOCKET: return _("Public socket has wrong ownership or permissions."); break; case ESSS_BAD_CRED_MSG: return _("Unexpected format of the server credential message."); break; case ESSS_SERVER_NOT_TRUSTED: return _("SSSD is not run by root."); break; default: m = strerror(err); if (m == NULL) { return _("An error occurred, but no description can be found."); } return m; break; } return _("Unexpected error while looking for an error description"); } /* Return strlen(str) or maxlen, whichever is shorter * Returns EINVAL if str is NULL, EFBIG if str is longer than maxlen * _len will return the result * * This function is useful for preventing buffer overflow attacks. */ errno_t sss_strnlen(const char *str, size_t maxlen, size_t *len) { if (!str) { return EINVAL; } #if defined __USE_GNU *len = strnlen(str, maxlen); #else *len = 0; while (*len < maxlen) { if (str[*len] == '\0') break; (*len)++; } #endif if (*len == maxlen && str[*len] != '\0') { return EFBIG; } return 0; } #if HAVE_PTHREAD typedef void (*sss_mutex_init)(void); struct sss_mutex { pthread_mutex_t mtx; pthread_once_t once; sss_mutex_init init; }; static void sss_nss_mt_init(void); static void sss_pam_mt_init(void); static void sss_nss_mc_mt_init(void); static struct sss_mutex sss_nss_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER, .once = PTHREAD_ONCE_INIT, .init = sss_nss_mt_init }; static struct sss_mutex sss_pam_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER, .once = PTHREAD_ONCE_INIT, .init = sss_pam_mt_init }; static struct sss_mutex sss_nss_mc_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER, .once = PTHREAD_ONCE_INIT, .init = sss_nss_mc_mt_init }; /* Wrappers for robust mutex support */ static int sss_mutexattr_setrobust (pthread_mutexattr_t *attr) { #ifdef HAVE_PTHREAD_MUTEXATTR_SETROBUST return pthread_mutexattr_setrobust(attr, PTHREAD_MUTEX_ROBUST); #elif defined(HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP) return pthread_mutexattr_setrobust_np(attr, PTHREAD_MUTEX_ROBUST_NP); #else #warning Robust mutexes are not supported on this platform. return 0; #endif } static int sss_mutex_consistent(pthread_mutex_t *mtx) { #ifdef HAVE_PTHREAD_MUTEX_CONSISTENT return pthread_mutex_consistent(mtx); #elif defined(HAVE_PTHREAD_MUTEX_CONSISTENT_NP) return pthread_mutex_consistent_np(mtx); #else #warning Robust mutexes are not supported on this platform. return 0; #endif } /* Generic mutex init, lock, unlock functions */ static void sss_mt_init(struct sss_mutex *m) { pthread_mutexattr_t attr; if (pthread_mutexattr_init(&attr) != 0) { return; } if (sss_mutexattr_setrobust(&attr) != 0) { return; } pthread_mutex_init(&m->mtx, &attr); pthread_mutexattr_destroy(&attr); } static void sss_mt_lock(struct sss_mutex *m) { pthread_once(&m->once, m->init); if (pthread_mutex_lock(&m->mtx) == EOWNERDEAD) { sss_cli_close_socket(); sss_mutex_consistent(&m->mtx); } } static void sss_mt_unlock(struct sss_mutex *m) { pthread_mutex_unlock(&m->mtx); } /* NSS mutex wrappers */ static void sss_nss_mt_init(void) { sss_mt_init(&sss_nss_mtx); } void sss_nss_lock(void) { sss_mt_lock(&sss_nss_mtx); } void sss_nss_unlock(void) { sss_mt_unlock(&sss_nss_mtx); } /* NSS mutex wrappers */ static void sss_pam_mt_init(void) { sss_mt_init(&sss_pam_mtx); } void sss_pam_lock(void) { sss_mt_lock(&sss_pam_mtx); } void sss_pam_unlock(void) { sss_mt_unlock(&sss_pam_mtx); } /* NSS mutex wrappers */ static void sss_nss_mc_mt_init(void) { sss_mt_init(&sss_nss_mc_mtx); } void sss_nss_mc_lock(void) { sss_mt_lock(&sss_nss_mc_mtx); } void sss_nss_mc_unlock(void) { sss_mt_unlock(&sss_nss_mc_mtx); } #else /* sorry no mutexes available */ void sss_nss_lock(void) { return; } void sss_nss_unlock(void) { return; } void sss_pam_lock(void) { return; } void sss_pam_unlock(void) { return; } void sss_nss_mc_lock(void) { return; } void sss_nss_mc_unlock(void) { return; } #endif errno_t sss_readrep_copy_string(const char *in, size_t *offset, size_t *slen, size_t *dlen, char **out, size_t *size) { size_t i = 0; while (*slen > *offset && *dlen > 0) { (*out)[i] = in[*offset]; if ((*out)[i] == '\0') break; i++; (*offset)++; (*dlen)--; } if (*slen <= *offset) { /* premature end of buf */ return EBADMSG; } if (*dlen == 0) { /* not enough memory */ return ERANGE; /* not ENOMEM, ERANGE is what glibc looks for */ } (*offset)++; (*dlen)--; if (size) { *size = i; } return EOK; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/nss_mc_group.c0000644000000000000000000000007412703456111020124 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.682793724 sssd-1.13.4/src/sss_client/nss_mc_group.c0000644002412700241270000001602312703456111021575 0ustar00jhrozekjhrozek00000000000000/* * System Security Services Daemon. NSS client interface * * Copyright (C) Simo Sorce 2011 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /* GROUP database NSS interface using mmap cache */ #include #include #include #include #include #include #include #include "nss_mc.h" #include "util/util_safealign.h" struct sss_cli_mc_ctx gr_mc_ctx = { UNINITIALIZED, -1, 0, NULL, 0, NULL, 0, NULL, 0, 0 }; static errno_t sss_nss_mc_parse_result(struct sss_mc_rec *rec, struct group *result, char *buffer, size_t buflen) { struct sss_mc_grp_data *data; time_t expire; void *cookie; char *membuf; size_t memsize; int ret; int i; /* additional checks before filling result*/ expire = rec->expire; if (expire < time(NULL)) { /* entry is now invalid */ return EINVAL; } data = (struct sss_mc_grp_data *)rec->data; memsize = (data->members + 1) * sizeof(char *); if (data->strs_len + memsize > buflen) { return ERANGE; } /* fill in glibc provided structs */ /* copy in buffer */ membuf = buffer + memsize; memcpy(membuf, data->strs, data->strs_len); /* fill in group */ result->gr_gid = data->gid; /* The address &buffer[0] must be aligned to sizeof(char *) */ if (!IS_ALIGNED(buffer, char *)) { /* The buffer is not properly aligned. */ return EFAULT; } result->gr_mem = DISCARD_ALIGN(buffer, char **); result->gr_mem[data->members] = NULL; cookie = NULL; ret = sss_nss_str_ptr_from_buffer(&result->gr_name, &cookie, membuf, data->strs_len); if (ret) { return ret; } ret = sss_nss_str_ptr_from_buffer(&result->gr_passwd, &cookie, membuf, data->strs_len); if (ret) { return ret; } for (i = 0; i < data->members; i++) { ret = sss_nss_str_ptr_from_buffer(&result->gr_mem[i], &cookie, membuf, data->strs_len); if (ret) { return ret; } } if (cookie != NULL) { return EINVAL; } return 0; } errno_t sss_nss_mc_getgrnam(const char *name, size_t name_len, struct group *result, char *buffer, size_t buflen) { struct sss_mc_rec *rec = NULL; struct sss_mc_grp_data *data; char *rec_name; uint32_t hash; uint32_t slot; int ret; const size_t strs_offset = offsetof(struct sss_mc_grp_data, strs); size_t data_size; ret = sss_nss_mc_get_ctx("group", &gr_mc_ctx); if (ret) { return ret; } /* Get max size of data table. */ data_size = gr_mc_ctx.dt_size; /* hashes are calculated including the NULL terminator */ hash = sss_nss_mc_hash(&gr_mc_ctx, name, name_len + 1); slot = gr_mc_ctx.hash_table[hash]; /* If slot is not within the bounds of mmaped region and * it's value is not MC_INVALID_VAL, then the cache is * probbably corrupted. */ while (MC_SLOT_WITHIN_BOUNDS(slot, data_size)) { /* free record from previous iteration */ free(rec); rec = NULL; ret = sss_nss_mc_get_record(&gr_mc_ctx, slot, &rec); if (ret) { goto done; } /* check record matches what we are searching for */ if (hash != rec->hash1) { /* if name hash does not match we can skip this immediately */ slot = sss_nss_mc_next_slot_with_hash(rec, hash); continue; } data = (struct sss_mc_grp_data *)rec->data; /* Integrity check * - name_len cannot be longer than all strings * - data->name cannot point outside strings * - all strings must be within copy of record * - size of record must be lower that data table size */ if (name_len > data->strs_len || (data->name + name_len) > (strs_offset + data->strs_len) || data->strs_len > rec->len || rec->len > data_size) { ret = ENOENT; goto done; } rec_name = (char *)data + data->name; if (strcmp(name, rec_name) == 0) { break; } slot = sss_nss_mc_next_slot_with_hash(rec, hash); } if (!MC_SLOT_WITHIN_BOUNDS(slot, data_size)) { ret = ENOENT; goto done; } ret = sss_nss_mc_parse_result(rec, result, buffer, buflen); done: free(rec); __sync_sub_and_fetch(&gr_mc_ctx.active_threads, 1); return ret; } errno_t sss_nss_mc_getgrgid(gid_t gid, struct group *result, char *buffer, size_t buflen) { struct sss_mc_rec *rec = NULL; struct sss_mc_grp_data *data; char gidstr[11]; uint32_t hash; uint32_t slot; int len; int ret; ret = sss_nss_mc_get_ctx("group", &gr_mc_ctx); if (ret) { return ret; } len = snprintf(gidstr, 11, "%ld", (long)gid); if (len > 10) { ret = EINVAL; goto done; } /* hashes are calculated including the NULL terminator */ hash = sss_nss_mc_hash(&gr_mc_ctx, gidstr, len+1); slot = gr_mc_ctx.hash_table[hash]; /* If slot is not within the bounds of mmaped region and * it's value is not MC_INVALID_VAL, then the cache is * probbably corrupted. */ while (MC_SLOT_WITHIN_BOUNDS(slot, gr_mc_ctx.dt_size)) { /* free record from previous iteration */ free(rec); rec = NULL; ret = sss_nss_mc_get_record(&gr_mc_ctx, slot, &rec); if (ret) { goto done; } /* check record matches what we are searching for */ if (hash != rec->hash2) { /* if uid hash does not match we can skip this immediately */ slot = sss_nss_mc_next_slot_with_hash(rec, hash); continue; } data = (struct sss_mc_grp_data *)rec->data; if (gid == data->gid) { break; } slot = sss_nss_mc_next_slot_with_hash(rec, hash); } if (!MC_SLOT_WITHIN_BOUNDS(slot, gr_mc_ctx.dt_size)) { ret = ENOENT; goto done; } ret = sss_nss_mc_parse_result(rec, result, buffer, buflen); done: free(rec); __sync_sub_and_fetch(&gr_mc_ctx.active_threads, 1); return ret; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/nss_netgroup.c0000644000000000000000000000007212703456111020152 xustar0030 atime=1460561751.654715641 28 ctime=1460561774.6757937 sssd-1.13.4/src/sss_client/nss_netgroup.c0000644002412700241270000002111212703456111021620 0ustar00jhrozekjhrozek00000000000000/* SSSD nss_netgroup.c Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "sss_cli.h" #include "nss_compat.h" #define CLEAR_NETGRENT_DATA(netgrent) do { \ free(netgrent->data); \ netgrent->data = NULL; \ netgrent->idx.position = 0; \ netgrent->data_size = 0; \ } while (0); /* * Replies: * * 0-3: 32bit unsigned number of results N * 4-7: 32bit unsigned (reserved/padding) * For each result: * 8-11: 32bit unsigned type of result * 12-X: \0 terminated string representing a tuple * (host, user, domain) * or a netgroup, depending on the type indicator * ... repeated N times */ #define NETGR_METADATA_COUNT 2 * sizeof(uint32_t) struct sss_nss_netgr_rep { struct __netgrent *result; char *buffer; size_t buflen; }; static int sss_nss_getnetgr_readrep(struct sss_nss_netgr_rep *pr, uint8_t *buf, size_t *len) { errno_t ret; char *sbuf; char *temp; size_t i, slen, dlen, size; uint32_t type; if (*len < 6) { /* Not enough space for data, bad packet */ return EBADMSG; } sbuf = (char *)(buf + sizeof(uint32_t)); slen = *len - sizeof(uint32_t); dlen = pr->buflen; i = 0; SAFEALIGN_COPY_UINT32(&type, buf, NULL); switch (type) { case SSS_NETGR_REP_TRIPLE: pr->result->type = triple_val; /* Host value */ temp = &(pr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &temp, &size); if (ret != EOK) return ret; /* libc expects NULL instead of empty string */ if (size == 0) { pr->result->val.triple.host = NULL; } else { pr->result->val.triple.host = temp; } /* User value */ temp = &(pr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &temp, &size); if (ret != EOK) return ret; /* libc expects NULL instead of empty string */ if (size == 0) { pr->result->val.triple.user = NULL; } else { pr->result->val.triple.user = temp; } /* Domain value */ temp = &(pr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &temp, &size); if (ret != EOK) return ret; /* libc expects NULL instead of empty string */ if (size == 0) { pr->result->val.triple.domain = NULL; } else { pr->result->val.triple.domain = temp; } break; case SSS_NETGR_REP_GROUP: pr->result->type = group_val; temp = &(pr->buffer[i]); ret = sss_readrep_copy_string(sbuf, &i, &slen, &dlen, &temp, NULL); if (ret != EOK) return ret; pr->result->val.group = temp; break; default: return EBADMSG; } *len = slen -i; return 0; } enum nss_status _nss_sss_setnetgrent(const char *netgroup, struct __netgrent *result) { uint8_t *repbuf = NULL; size_t replen; uint32_t num_results; enum nss_status nret; struct sss_cli_req_data rd; int errnop; char *name; size_t name_len; errno_t ret; if (!netgroup) return NSS_STATUS_NOTFOUND; sss_nss_lock(); /* make sure we do not have leftovers, and release memory */ CLEAR_NETGRENT_DATA(result); ret = sss_strnlen(netgroup, SSS_NAME_MAX, &name_len); if (ret != 0) { nret = NSS_STATUS_NOTFOUND; goto out; } name = malloc(sizeof(char)*name_len + 1); if (name == NULL) { nret = NSS_STATUS_TRYAGAIN; goto out; } strncpy(name, netgroup, name_len + 1); rd.data = name; rd.len = name_len + 1; nret = sss_nss_make_request(SSS_NSS_SETNETGRENT, &rd, &repbuf, &replen, &errnop); free(name); if (nret != NSS_STATUS_SUCCESS) { errno = errnop; goto out; } /* Get number of results from repbuf */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if ((num_results == 0) || (replen < NETGR_METADATA_COUNT)) { free(repbuf); nret = NSS_STATUS_NOTFOUND; goto out; } free(repbuf); nret = NSS_STATUS_SUCCESS; out: sss_nss_unlock(); return nret; } static enum nss_status internal_getnetgrent_r(struct __netgrent *result, char *buffer, size_t buflen, int *errnop) { struct sss_cli_req_data rd; struct sss_nss_netgr_rep netgrrep; uint8_t *repbuf; size_t replen; uint32_t num_results; enum nss_status nret; uint32_t num_entries; int ret; /* Caught once glibc passing in buffer == 0x0 */ if (!buffer || !buflen) return ERANGE; /* If we're already processing result data, continue to * return it. */ if (result->data != NULL && result->idx.position < result->data_size) { repbuf = (uint8_t *) result->data + result->idx.position; replen = result->data_size - result->idx.position; netgrrep.result = result; netgrrep.buffer = buffer; netgrrep.buflen = buflen; ret = sss_nss_getnetgr_readrep(&netgrrep, repbuf, &replen); if (ret != 0) { *errnop = ret; return NSS_STATUS_TRYAGAIN; } result->idx.position = result->data_size - replen; return NSS_STATUS_SUCCESS; } /* Release memory, if any */ CLEAR_NETGRENT_DATA(result); /* retrieve no more than SSS_NSS_MAX_ENTRIES at a time */ num_entries = SSS_NSS_MAX_ENTRIES; rd.len = sizeof(uint32_t); rd.data = &num_entries; nret = sss_nss_make_request(SSS_NSS_GETNETGRENT, &rd, &repbuf, &replen, errnop); if (nret != NSS_STATUS_SUCCESS) { return nret; } /* Get number of results from repbuf. */ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); /* no results if not found */ if ((num_results == 0) || (replen <= NETGR_METADATA_COUNT)) { free(repbuf); return NSS_STATUS_RETURN; } result->data = (char *) repbuf; result->data_size = replen; /* skip metadata fields */ result->idx.position = NETGR_METADATA_COUNT; /* call again ourselves, this will return the first result */ return internal_getnetgrent_r(result, buffer, buflen, errnop); } enum nss_status _nss_sss_getnetgrent_r(struct __netgrent *result, char *buffer, size_t buflen, int *errnop) { enum nss_status nret; sss_nss_lock(); nret = internal_getnetgrent_r(result, buffer, buflen, errnop); sss_nss_unlock(); return nret; } enum nss_status _nss_sss_endnetgrent(struct __netgrent *result) { enum nss_status nret; int errnop; sss_nss_lock(); /* make sure we do not have leftovers, and release memory */ CLEAR_NETGRENT_DATA(result); nret = sss_nss_make_request(SSS_NSS_ENDNETGRENT, NULL, NULL, NULL, &errnop); if (nret != NSS_STATUS_SUCCESS) { errno = errnop; } sss_nss_unlock(); return nret; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/pam_message.c0000644000000000000000000000007412703456111017707 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.896794449 sssd-1.13.4/src/sss_client/pam_message.c0000644002412700241270000001207412703456111021362 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose PAM client - create message blob Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include #include #include "sss_pam_compat.h" #include "sss_pam_macros.h" #include "pam_message.h" #include "sss_cli.h" static size_t add_authtok_item(enum pam_item_type type, enum sss_authtok_type authtok_type, const char *tok, const size_t size, uint8_t *buf) { size_t rp = 0; uint32_t c; if (tok == NULL) return 0; c = type; memcpy(&buf[rp], &c, sizeof(uint32_t)); rp += sizeof(uint32_t); c = size + sizeof(uint32_t); memcpy(&buf[rp], &c, sizeof(uint32_t)); rp += sizeof(uint32_t); c = authtok_type; memcpy(&buf[rp], &c, sizeof(uint32_t)); rp += sizeof(uint32_t); memcpy(&buf[rp], tok, size); rp += size; return rp; } static size_t add_uint32_t_item(enum pam_item_type type, const uint32_t val, uint8_t *buf) { size_t rp = 0; uint32_t c; c = type; memcpy(&buf[rp], &c, sizeof(uint32_t)); rp += sizeof(uint32_t); c = sizeof(uint32_t); memcpy(&buf[rp], &c, sizeof(uint32_t)); rp += sizeof(uint32_t); c = val; memcpy(&buf[rp], &c, sizeof(uint32_t)); rp += sizeof(uint32_t); return rp; } static size_t add_string_item(enum pam_item_type type, const char *str, const size_t size, uint8_t *buf) { size_t rp = 0; uint32_t c; if (str == NULL || *str == '\0') return 0; c = type; memcpy(&buf[rp], &c, sizeof(uint32_t)); rp += sizeof(uint32_t); c = size; memcpy(&buf[rp], &c, sizeof(uint32_t)); rp += sizeof(uint32_t); memcpy(&buf[rp], str, size); rp += size; return rp; } int pack_message_v3(struct pam_items *pi, size_t *size, uint8_t **buffer) { int len; uint8_t *buf; size_t rp; len = sizeof(uint32_t) + sizeof(uint32_t); len += *pi->pam_user != '\0' ? 2*sizeof(uint32_t) + pi->pam_user_size : 0; len += *pi->pam_service != '\0' ? 2*sizeof(uint32_t) + pi->pam_service_size : 0; len += *pi->pam_tty != '\0' ? 2*sizeof(uint32_t) + pi->pam_tty_size : 0; len += *pi->pam_ruser != '\0' ? 2*sizeof(uint32_t) + pi->pam_ruser_size : 0; len += *pi->pam_rhost != '\0' ? 2*sizeof(uint32_t) + pi->pam_rhost_size : 0; len += pi->pam_authtok != NULL ? 3*sizeof(uint32_t) + pi->pam_authtok_size : 0; len += pi->pam_newauthtok != NULL ? 3*sizeof(uint32_t) + pi->pam_newauthtok_size : 0; len += 3*sizeof(uint32_t); /* cli_pid */ len += *pi->requested_domains != '\0' ? 2*sizeof(uint32_t) + pi->requested_domains_size : 0; buf = malloc(len); if (buf == NULL) { D(("malloc failed.")); return PAM_BUF_ERR; } rp = 0; SAFEALIGN_SETMEM_UINT32(buf, SSS_START_OF_PAM_REQUEST, &rp); rp += add_string_item(SSS_PAM_ITEM_USER, pi->pam_user, pi->pam_user_size, &buf[rp]); rp += add_string_item(SSS_PAM_ITEM_SERVICE, pi->pam_service, pi->pam_service_size, &buf[rp]); rp += add_string_item(SSS_PAM_ITEM_TTY, pi->pam_tty, pi->pam_tty_size, &buf[rp]); rp += add_string_item(SSS_PAM_ITEM_RUSER, pi->pam_ruser, pi->pam_ruser_size, &buf[rp]); rp += add_string_item(SSS_PAM_ITEM_RHOST, pi->pam_rhost, pi->pam_rhost_size, &buf[rp]); rp += add_string_item(SSS_PAM_ITEM_REQUESTED_DOMAINS, pi->requested_domains, pi->requested_domains_size, &buf[rp]); rp += add_uint32_t_item(SSS_PAM_ITEM_CLI_PID, (uint32_t) pi->cli_pid, &buf[rp]); rp += add_authtok_item(SSS_PAM_ITEM_AUTHTOK, pi->pam_authtok_type, pi->pam_authtok, pi->pam_authtok_size, &buf[rp]); rp += add_authtok_item(SSS_PAM_ITEM_NEWAUTHTOK, pi->pam_newauthtok_type, pi->pam_newauthtok, pi->pam_newauthtok_size, &buf[rp]); SAFEALIGN_SETMEM_UINT32(buf + rp, SSS_END_OF_PAM_REQUEST, &rp); if (rp != len) { D(("error during packet creation.")); free(buf); return PAM_BUF_ERR; } *size = len; *buffer = buf; return 0; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/krb5_authdata_int.h0000644000000000000000000000007412703456111021023 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.903794473 sssd-1.13.4/src/sss_client/krb5_authdata_int.h0000644002412700241270000002036612703456111022501 0ustar00jhrozekjhrozek00000000000000/* SSSD - MIT Kerberos authdata plugin This file contains definitions and declarations to build authdata plugins for MIT Kerberos outside of the MIT Kerberos source tree. */ #ifndef _KRB5_AUTHDATA_INT_H #define _KRB5_AUTHDATA_INT_H krb5_error_code KRB5_CALLCONV krb5_ser_pack_int32(krb5_int32, krb5_octet **, size_t *); krb5_error_code KRB5_CALLCONV krb5_ser_unpack_int32(krb5_int32 *, krb5_octet **, size_t *); krb5_error_code KRB5_CALLCONV krb5_ser_pack_bytes(krb5_octet *, size_t, krb5_octet **, size_t *); #define AD_USAGE_AS_REQ 0x01 #define AD_USAGE_TGS_REQ 0x02 #define AD_USAGE_AP_REQ 0x04 #define AD_USAGE_KDC_ISSUED 0x08 #define AD_USAGE_MASK 0x0F #define AD_INFORMATIONAL 0x10 struct _krb5_authdata_context; typedef struct _krb5_authdata_context *krb5_authdata_context; typedef void (*authdata_client_plugin_flags_proc)(krb5_context kcontext, void *plugin_context, krb5_authdatatype ad_type, krb5_flags *flags); typedef krb5_error_code (*authdata_client_plugin_init_proc)(krb5_context context, void **plugin_context); typedef void (*authdata_client_plugin_fini_proc)(krb5_context kcontext, void *plugin_context); typedef krb5_error_code (*authdata_client_request_init_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void **request_context); typedef void (*authdata_client_request_fini_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context); typedef krb5_error_code (*authdata_client_import_authdata_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, krb5_authdata **authdata, krb5_boolean kdc_issued_flag, krb5_const_principal issuer); typedef krb5_error_code (*authdata_client_export_authdata_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, krb5_flags usage, krb5_authdata ***authdata); typedef krb5_error_code (*authdata_client_get_attribute_types_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, krb5_data **attrs); typedef krb5_error_code (*authdata_client_get_attribute_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, const krb5_data *attribute, krb5_boolean *authenticated, krb5_boolean *complete, krb5_data *value, krb5_data *display_value, int *more); typedef krb5_error_code (*authdata_client_set_attribute_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, krb5_boolean complete, const krb5_data *attribute, const krb5_data *value); typedef krb5_error_code (*authdata_client_delete_attribute_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, const krb5_data *attribute); typedef krb5_error_code (*authdata_client_export_internal_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, krb5_boolean restrict_authenticated, void **ptr); typedef void (*authdata_client_free_internal_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, void *ptr); typedef krb5_error_code (*authdata_client_verify_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, const krb5_auth_context *auth_context, const krb5_keyblock *key, const krb5_ap_req *req); typedef krb5_error_code (*authdata_client_size_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, size_t *sizep); typedef krb5_error_code (*authdata_client_externalize_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, krb5_octet **buffer, size_t *lenremain); typedef krb5_error_code (*authdata_client_internalize_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, krb5_octet **buffer, size_t *lenremain); typedef krb5_error_code (*authdata_client_copy_proc)(krb5_context kcontext, struct _krb5_authdata_context *context, void *plugin_context, void *request_context, void *dst_plugin_context, void *dst_request_context); typedef struct krb5plugin_authdata_client_ftable_v0 { char *name; krb5_authdatatype *ad_type_list; authdata_client_plugin_init_proc init; authdata_client_plugin_fini_proc fini; authdata_client_plugin_flags_proc flags; authdata_client_request_init_proc request_init; authdata_client_request_fini_proc request_fini; authdata_client_get_attribute_types_proc get_attribute_types; authdata_client_get_attribute_proc get_attribute; authdata_client_set_attribute_proc set_attribute; authdata_client_delete_attribute_proc delete_attribute; authdata_client_export_authdata_proc export_authdata; authdata_client_import_authdata_proc import_authdata; authdata_client_export_internal_proc export_internal; authdata_client_free_internal_proc free_internal; authdata_client_verify_proc verify; authdata_client_size_proc size; authdata_client_externalize_proc externalize; authdata_client_internalize_proc internalize; authdata_client_copy_proc copy; /* optional */ } krb5plugin_authdata_client_ftable_v0; #endif /* _KRB5_AUTHDATA_INT_H */ sssd-1.13.4/src/sss_client/PaxHeaders.16287/idmap0000644000000000000000000000013212703463556016305 xustar0030 mtime=1460561774.807794147 30 atime=1460561776.117798589 30 ctime=1460561774.807794147 sssd-1.13.4/src/sss_client/idmap/0000755002412700241270000000000012703463556020036 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sss_client/idmap/PaxHeaders.16287/sss_nss_idmap.c0000644000000000000000000000007412703456111021365 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.807794147 sssd-1.13.4/src/sss_client/idmap/sss_nss_idmap.c0000644002412700241270000001717412703456111023046 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Responder Interface for ID-SID mappings Authors: Sumit Bose Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "sss_client/sss_cli.h" #include "sss_client/idmap/sss_nss_idmap.h" #include "util/strtonum.h" #define DATA_START (3 * sizeof(uint32_t)) union input { const char *str; uint32_t id; }; struct output { enum sss_id_type type; union { char *str; uint32_t id; struct sss_nss_kv *kv_list; } d; }; int nss_status_to_errno(enum nss_status nret) { switch (nret) { case NSS_STATUS_TRYAGAIN: return EAGAIN; case NSS_STATUS_SUCCESS: return EOK; case NSS_STATUS_UNAVAIL: default: return ENOENT; } return EINVAL; } void sss_nss_free_kv(struct sss_nss_kv *kv_list) { size_t c; if (kv_list != NULL) { for (c = 0; kv_list[c].key != NULL; c++) { free(kv_list[c].key); free(kv_list[c].value); } free(kv_list); } } static int buf_to_kv_list(uint8_t *buf, size_t buf_len, struct sss_nss_kv **kv_list) { size_t c; size_t count = 0; struct sss_nss_kv *list; uint8_t *p; int ret; for (c = 0; c < buf_len; c++) { if (buf[c] == '\0') { count++; } } if ((count % 2) != 0) { return EINVAL; } count /= 2; list = calloc((count + 1), sizeof(struct sss_nss_kv)); if (list == NULL) { return ENOMEM; } p = buf; for (c = 0; c < count; c++) { list[c].key = strdup((char *) p); if (list[c].key == NULL) { ret = ENOMEM; goto done; } p = memchr(p, '\0', buf_len - (p - buf)); if (p == NULL) { ret = EINVAL; goto done; } p++; list[c].value = strdup((char *) p); if (list[c].value == NULL) { ret = ENOMEM; goto done; } p = memchr(p, '\0', buf_len - (p - buf)); if (p == NULL) { ret = EINVAL; goto done; } p++; } *kv_list = list; ret = EOK; done: if (ret != EOK) { sss_nss_free_kv(list); } return ret; } static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , struct output *out) { int ret; size_t inp_len; struct sss_cli_req_data rd; uint8_t *repbuf = NULL; size_t replen; int errnop; enum nss_status nret; uint32_t num_results; char *str = NULL; size_t data_len; uint32_t c; struct sss_nss_kv *kv_list; switch (cmd) { case SSS_NSS_GETSIDBYNAME: case SSS_NSS_GETNAMEBYSID: case SSS_NSS_GETIDBYSID: case SSS_NSS_GETORIGBYNAME: ret = sss_strnlen(inp.str, SSS_NAME_MAX, &inp_len); if (ret != EOK) { return EINVAL; } rd.len = inp_len + 1; rd.data = inp.str; break; case SSS_NSS_GETSIDBYID: rd.len = sizeof(uint32_t); rd.data = &inp.id; break; default: return EINVAL; } sss_nss_lock(); nret = sss_nss_make_request(cmd, &rd, &repbuf, &replen, &errnop); if (nret != NSS_STATUS_SUCCESS) { ret = nss_status_to_errno(nret); goto done; } if (replen < 8) { ret = EBADMSG; goto done; } SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); if (num_results == 0) { ret = ENOENT; goto done; } else if (num_results > 1) { ret = EBADMSG; goto done; } /* Skip first two 32 bit values (number of results and * reserved padding) */ SAFEALIGN_COPY_UINT32(&out->type, repbuf + 2 * sizeof(uint32_t), NULL); data_len = replen - DATA_START; switch(cmd) { case SSS_NSS_GETSIDBYID: case SSS_NSS_GETSIDBYNAME: case SSS_NSS_GETNAMEBYSID: if (data_len <= 1 || repbuf[replen - 1] != '\0') { ret = EBADMSG; goto done; } str = malloc(sizeof(char) * data_len); if (str == NULL) { ret = ENOMEM; goto done; } strncpy(str, (char *) repbuf + DATA_START, data_len); out->d.str = str; break; case SSS_NSS_GETIDBYSID: if (data_len != sizeof(uint32_t)) { ret = EBADMSG; goto done; } SAFEALIGN_COPY_UINT32(&c, repbuf + DATA_START, NULL); out->d.id = c; break; case SSS_NSS_GETORIGBYNAME: ret = buf_to_kv_list(repbuf + DATA_START, data_len, &kv_list); if (ret != EOK) { goto done; } out->d.kv_list = kv_list; break; default: ret = EINVAL; goto done; } ret = EOK; done: sss_nss_unlock(); free(repbuf); if (ret != EOK) { free(str); } return ret; } int sss_nss_getsidbyname(const char *fq_name, char **sid, enum sss_id_type *type) { int ret; union input inp; struct output out; if (sid == NULL || fq_name == NULL || *fq_name == '\0') { return EINVAL; } inp.str = fq_name; ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYNAME, &out); if (ret == EOK) { *sid = out.d.str; *type = out.type; } return ret; } int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type) { int ret; union input inp; struct output out; if (sid == NULL) { return EINVAL; } inp.id = id; ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYID, &out); if (ret == EOK) { *sid = out.d.str; *type = out.type; } return ret; } int sss_nss_getnamebysid(const char *sid, char **fq_name, enum sss_id_type *type) { int ret; union input inp; struct output out; if (fq_name == NULL || sid == NULL || *sid == '\0') { return EINVAL; } inp.str = sid; ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYSID, &out); if (ret == EOK) { *fq_name = out.d.str; *type = out.type; } return ret; } int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type) { int ret; union input inp; struct output out; if (id == NULL || id_type == NULL || sid == NULL || *sid == '\0') { return EINVAL; } inp.str = sid; ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETIDBYSID, &out); if (ret == EOK) { *id = out.d.id; *id_type = out.type; } return ret; } int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, enum sss_id_type *type) { int ret; union input inp; struct output out; if (kv_list == NULL || fq_name == NULL || *fq_name == '\0') { return EINVAL; } inp.str = fq_name; ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETORIGBYNAME, &out); if (ret == EOK) { *kv_list = out.d.kv_list; *type = out.type; } return ret; } sssd-1.13.4/src/sss_client/idmap/PaxHeaders.16287/sss_nss_idmap.exports0000644000000000000000000000007412703456111022647 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.371792669 sssd-1.13.4/src/sss_client/idmap/sss_nss_idmap.exports0000644002412700241270000000056112703456111024320 0ustar00jhrozekjhrozek00000000000000SSS_NSS_IDMAP_0.0.1 { # public functions global: sss_nss_getsidbyname; sss_nss_getsidbyid; sss_nss_getnamebysid; sss_nss_getidbysid; # everything else is local local: *; }; SSS_NSS_IDMAP_0.1.0 { # public functions global: sss_nss_getorigbyname; sss_nss_free_kv; } SSS_NSS_IDMAP_0.0.1; sssd-1.13.4/src/sss_client/idmap/PaxHeaders.16287/sss_nss_idmap.doxy.in0000644000000000000000000000007412703456111022533 xustar0030 atime=1460561772.782787281 30 ctime=1460561774.633793558 sssd-1.13.4/src/sss_client/idmap/sss_nss_idmap.doxy.in0000644002412700241270000017552012703456111024214 0ustar00jhrozekjhrozek00000000000000# Doxyfile 1.6.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = sss_nss_idmap # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = nss_idmap_doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @abs_top_srcdir@/src/sss_client/idmap/sss_nss_idmap.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.cpp \ *.cc \ *.c \ *.h \ *.hh \ *.hpp \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.git/* \ */.svn/* \ */cmake/* \ */build/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated # HTML page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NONE # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) # there is already a search function so this one should typically # be disabled. SEARCHENGINE = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES sssd-1.13.4/src/sss_client/idmap/PaxHeaders.16287/sss_nss_idmap.unit_tests0000644000000000000000000000007412703456111023344 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.382792706 sssd-1.13.4/src/sss_client/idmap/sss_nss_idmap.unit_tests0000644002412700241270000000026312703456111025014 0ustar00jhrozekjhrozek00000000000000# version script files can be combined. They needn't be in single file UNIT_TEST_ONLY { # should not be part of installed library global: sss_nss_make_request; }; sssd-1.13.4/src/sss_client/idmap/PaxHeaders.16287/sss_nss_idmap.pc.in0000644000000000000000000000007412703456111022152 xustar0030 atime=1460561772.769787237 30 ctime=1460561774.634793561 sssd-1.13.4/src/sss_client/idmap/sss_nss_idmap.pc.in0000644002412700241270000000037312703456111023624 0ustar00jhrozekjhrozek00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: sss_nss_idmap Description: NSS Responder ID-SID mapping interface Version: @VERSION@ Libs: -L${libdir} -lsss_nss_idmap Cflags: URL: http://fedorahosted.org/sssd/ sssd-1.13.4/src/sss_client/idmap/PaxHeaders.16287/sss_nss_idmap.h0000644000000000000000000000007412703456111021372 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.605793463 sssd-1.13.4/src/sss_client/idmap/sss_nss_idmap.h0000644002412700241270000001052512703456111023044 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Responder ID-mapping interface Authors: Sumit Bose Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_NSS_IDMAP_H_ #define SSS_NSS_IDMAP_H_ #include /** * Object types */ enum sss_id_type { SSS_ID_TYPE_NOT_SPECIFIED = 0, SSS_ID_TYPE_UID, SSS_ID_TYPE_GID, SSS_ID_TYPE_BOTH /* used for user or magic private groups */ }; struct sss_nss_kv { char *key; char *value; }; /** * @brief Find SID by fully qualified name * * @param[in] fq_name Fully qualified name of a user or a group * @param[out] sid String representation of the SID of the requested user * or group, must be freed by the caller * @param[out] type Type of the object related to the given name * * @return * - 0 (EOK): success, sid contains the requested SID * - ENOENT: requested object was not found in the domain extracted from the given name * - ENETUNREACH: SSSD does not know how to handle the domain extracted from the given name * - ENOSYS: this call is not supported by the configured provider * - EINVAL: input cannot be parsed * - EIO: remote servers cannot be reached * - EFAULT: any other error */ int sss_nss_getsidbyname(const char *fq_name, char **sid, enum sss_id_type *type); /** * @brief Find SID by a POSIX UID or GID * * @param[in] id POSIX UID or GID * @param[out] sid String representation of the SID of the requested user * or group, must be freed by the caller * @param[out] type Type of the object related to the given ID * * @return * - see #sss_nss_getsidbyname */ int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type); /** * @brief Return the fully qualified name for the given SID * * @param[in] sid String representation of the SID * @param[out] fq_name Fully qualified name of a user or a group, * must be freed by the caller * @param[out] type Type of the object related to the SID * * @return * - see #sss_nss_getsidbyname */ int sss_nss_getnamebysid(const char *sid, char **fq_name, enum sss_id_type *type); /** * @brief Return the POSIX ID for the given SID * * @param[in] sid String representation of the SID * @param[out] id POSIX ID related to the SID * @param[out] id_type Type of the object related to the SID * * @return * - see #sss_nss_getsidbyname */ int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type); /** * @brief Find original data by fully qualified name * * @param[in] fq_name Fully qualified name of a user or a group * @param[out] kv_list A NULL terminate list of key-value pairs where the key * is the attribute name in the cache of SSSD, * must be freed by the caller with sss_nss_free_kv() * @param[out] type Type of the object related to the given name * * @return * - 0 (EOK): success, sid contains the requested SID * - ENOENT: requested object was not found in the domain extracted from the given name * - ENETUNREACH: SSSD does not know how to handle the domain extracted from the given name * - ENOSYS: this call is not supported by the configured provider * - EINVAL: input cannot be parsed * - EIO: remote servers cannot be reached * - EFAULT: any other error */ int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, enum sss_id_type *type); /** * @brief Free key-value list returned by sss_nss_getorigbyname() * * @param[in] kv_list Key-value list returned by sss_nss_getorigbyname(). */ void sss_nss_free_kv(struct sss_nss_kv *kv_list); #endif /* SSS_NSS_IDMAP_H_ */ sssd-1.13.4/src/sss_client/PaxHeaders.16287/nss_mc.h0000644000000000000000000000007312703456111016714 xustar0030 atime=1460561751.654715641 29 ctime=1460561774.68479373 sssd-1.13.4/src/sss_client/nss_mc.h0000644002412700241270000000623012703456111020365 0ustar00jhrozekjhrozek00000000000000/* * System Security Services Daemon. NSS client interface * * Copyright (C) Simo Sorce 2011 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /* NSS interfaces to mmap cache */ #ifndef _NSS_MC_H_ #define _NSS_MC_H_ #include #include #include #include #include "util/mmap_cache.h" #ifndef HAVE_ERRNO_T #define HAVE_ERRNO_T typedef int errno_t; #endif enum sss_mc_state { UNINITIALIZED = 0, INITIALIZED, RECYCLED, }; /* common stuff */ struct sss_cli_mc_ctx { enum sss_mc_state initialized; int fd; uint32_t seed; /* seed from the tables header */ void *mmap_base; /* base address of mmap */ size_t mmap_size; /* total size of mmap */ uint8_t *data_table; /* data table address (in mmap) */ uint32_t dt_size; /* size of data table */ uint32_t *hash_table; /* hash table address (in mmap) */ uint32_t ht_size; /* size of hash table */ uint32_t active_threads; /* count of threads which use memory cache */ }; errno_t sss_nss_mc_get_ctx(const char *name, struct sss_cli_mc_ctx *ctx); errno_t sss_nss_check_header(struct sss_cli_mc_ctx *ctx); uint32_t sss_nss_mc_hash(struct sss_cli_mc_ctx *ctx, const char *key, size_t len); errno_t sss_nss_mc_get_record(struct sss_cli_mc_ctx *ctx, uint32_t slot, struct sss_mc_rec **_rec); errno_t sss_nss_str_ptr_from_buffer(char **str, void **cookie, char *buf, size_t len); uint32_t sss_nss_mc_next_slot_with_hash(struct sss_mc_rec *rec, uint32_t hash); /* passwd db */ errno_t sss_nss_mc_getpwnam(const char *name, size_t name_len, struct passwd *result, char *buffer, size_t buflen); errno_t sss_nss_mc_getpwuid(uid_t uid, struct passwd *result, char *buffer, size_t buflen); /* group db */ errno_t sss_nss_mc_getgrnam(const char *name, size_t name_len, struct group *result, char *buffer, size_t buflen); errno_t sss_nss_mc_getgrgid(gid_t gid, struct group *result, char *buffer, size_t buflen); /* initgroups db */ errno_t sss_nss_mc_initgroups_dyn(const char *name, size_t name_len, gid_t group, long int *start, long int *size, gid_t **groups, long int limit); #endif /* _NSS_MC_H_ */ sssd-1.13.4/src/sss_client/PaxHeaders.16287/nss_mc_initgr.c0000644000000000000000000000007412703456111020264 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.683793727 sssd-1.13.4/src/sss_client/nss_mc_initgr.c0000644002412700241270000001166212703456111021741 0ustar00jhrozekjhrozek00000000000000/* * System Security Services Daemon. NSS client interface * * Authors: * Lukas Slebodnik * * Copyright (C) 2015 Red Hat * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /* INITGROUPs database NSS interface using mmap cache */ #include #include #include #include #include #include #include #include "nss_mc.h" #include "util/util_safealign.h" struct sss_cli_mc_ctx initgr_mc_ctx = { UNINITIALIZED, -1, 0, NULL, 0, NULL, 0, NULL, 0, 0 }; static errno_t sss_nss_mc_parse_result(struct sss_mc_rec *rec, long int *start, long int *size, gid_t **groups, long int limit) { struct sss_mc_initgr_data *data; time_t expire; long int i; uint32_t num_groups; long int max_ret; /* additional checks before filling result*/ expire = rec->expire; if (expire < time(NULL)) { /* entry is now invalid */ return EINVAL; } data = (struct sss_mc_initgr_data *)rec->data; num_groups = data->num_groups; max_ret = num_groups; /* check we have enough space in the buffer */ if ((*size - *start) < num_groups) { long int newsize; gid_t *newgroups; newsize = *size + num_groups; if ((limit > 0) && (newsize > limit)) { newsize = limit; max_ret = newsize - *start; } newgroups = (gid_t *)realloc((*groups), newsize * sizeof(**groups)); if (!newgroups) { return ENOMEM; } *groups = newgroups; *size = newsize; } for (i = 0; i < max_ret; i++) { SAFEALIGN_COPY_UINT32(&(*groups)[*start], data->gids + i, NULL); *start += 1; } return 0; } errno_t sss_nss_mc_initgroups_dyn(const char *name, size_t name_len, gid_t group, long int *start, long int *size, gid_t **groups, long int limit) { struct sss_mc_rec *rec = NULL; struct sss_mc_initgr_data *data; char *rec_name; uint32_t hash; uint32_t slot; int ret; const size_t data_offset = offsetof(struct sss_mc_initgr_data, gids); size_t data_size; ret = sss_nss_mc_get_ctx("initgroups", &initgr_mc_ctx); if (ret) { return ret; } /* Get max size of data table. */ data_size = initgr_mc_ctx.dt_size; /* hashes are calculated including the NULL terminator */ hash = sss_nss_mc_hash(&initgr_mc_ctx, name, name_len + 1); slot = initgr_mc_ctx.hash_table[hash]; /* If slot is not within the bounds of mmaped region and * it's value is not MC_INVALID_VAL, then the cache is * probbably corrupted. */ while (MC_SLOT_WITHIN_BOUNDS(slot, data_size)) { /* free record from previous iteration */ free(rec); rec = NULL; ret = sss_nss_mc_get_record(&initgr_mc_ctx, slot, &rec); if (ret) { goto done; } /* check record matches what we are searching for */ if (hash != rec->hash1) { /* if name hash does not match we can skip this immediately */ slot = sss_nss_mc_next_slot_with_hash(rec, hash); continue; } data = (struct sss_mc_initgr_data *)rec->data; rec_name = (char *)data + data->name; /* Integrity check * - name_len cannot be longer than all strings or data * - all data must be within copy of record * - size of record must be lower that data table size * - data->strs cannot point outside strings */ if (name_len > data->strs_len || data->strs_len > data->data_len || data->data_len > rec->len || rec->len > data_size || (data->strs + name_len) > (data_offset + data->data_len)) { ret = ENOENT; goto done; } if (strcmp(name, rec_name) == 0) { break; } slot = sss_nss_mc_next_slot_with_hash(rec, hash); } if (!MC_SLOT_WITHIN_BOUNDS(slot, data_size)) { ret = ENOENT; goto done; } ret = sss_nss_mc_parse_result(rec, start, size, groups, limit); done: free(rec); __sync_sub_and_fetch(&initgr_mc_ctx.active_threads, 1); return ret; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/nss_mc_passwd.c0000644000000000000000000000007312703456111020270 xustar0030 atime=1460561751.654715641 29 ctime=1460561774.68179372 sssd-1.13.4/src/sss_client/nss_mc_passwd.c0000644002412700241270000001557512703456111021755 0ustar00jhrozekjhrozek00000000000000/* * System Security Services Daemon. NSS client interface * * Copyright (C) Simo Sorce 2011 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /* PASSWD database NSS interface using mmap cache */ #include #include #include #include #include #include #include #include "nss_mc.h" struct sss_cli_mc_ctx pw_mc_ctx = { UNINITIALIZED, -1, 0, NULL, 0, NULL, 0, NULL, 0, 0 }; static errno_t sss_nss_mc_parse_result(struct sss_mc_rec *rec, struct passwd *result, char *buffer, size_t buflen) { struct sss_mc_pwd_data *data; time_t expire; void *cookie; int ret; /* additional checks before filling result*/ expire = rec->expire; if (expire < time(NULL)) { /* entry is now invalid */ return EINVAL; } data = (struct sss_mc_pwd_data *)rec->data; if (data->strs_len > buflen) { return ERANGE; } /* fill in glibc provided structs */ /* copy in buffer */ memcpy(buffer, data->strs, data->strs_len); /* fill in passwd */ result->pw_uid = data->uid; result->pw_gid = data->gid; cookie = NULL; ret = sss_nss_str_ptr_from_buffer(&result->pw_name, &cookie, buffer, data->strs_len); if (ret) { return ret; } ret = sss_nss_str_ptr_from_buffer(&result->pw_passwd, &cookie, buffer, data->strs_len); if (ret) { return ret; } ret = sss_nss_str_ptr_from_buffer(&result->pw_gecos, &cookie, buffer, data->strs_len); if (ret) { return ret; } ret = sss_nss_str_ptr_from_buffer(&result->pw_dir, &cookie, buffer, data->strs_len); if (ret) { return ret; } ret = sss_nss_str_ptr_from_buffer(&result->pw_shell, &cookie, buffer, data->strs_len); if (ret) { return ret; } if (cookie != NULL) { return EINVAL; } return 0; } errno_t sss_nss_mc_getpwnam(const char *name, size_t name_len, struct passwd *result, char *buffer, size_t buflen) { struct sss_mc_rec *rec = NULL; struct sss_mc_pwd_data *data; char *rec_name; uint32_t hash; uint32_t slot; int ret; const size_t strs_offset = offsetof(struct sss_mc_pwd_data, strs); size_t data_size; ret = sss_nss_mc_get_ctx("passwd", &pw_mc_ctx); if (ret) { return ret; } /* Get max size of data table. */ data_size = pw_mc_ctx.dt_size; /* hashes are calculated including the NULL terminator */ hash = sss_nss_mc_hash(&pw_mc_ctx, name, name_len + 1); slot = pw_mc_ctx.hash_table[hash]; /* If slot is not within the bounds of mmaped region and * it's value is not MC_INVALID_VAL, then the cache is * probbably corrupted. */ while (MC_SLOT_WITHIN_BOUNDS(slot, data_size)) { /* free record from previous iteration */ free(rec); rec = NULL; ret = sss_nss_mc_get_record(&pw_mc_ctx, slot, &rec); if (ret) { goto done; } /* check record matches what we are searching for */ if (hash != rec->hash1) { /* if name hash does not match we can skip this immediately */ slot = sss_nss_mc_next_slot_with_hash(rec, hash); continue; } data = (struct sss_mc_pwd_data *)rec->data; /* Integrity check * - name_len cannot be longer than all strings * - data->name cannot point outside strings * - all strings must be within copy of record * - size of record must be lower that data table size */ if (name_len > data->strs_len || (data->name + name_len) > (strs_offset + data->strs_len) || data->strs_len > rec->len || rec->len > data_size) { ret = ENOENT; goto done; } rec_name = (char *)data + data->name; if (strcmp(name, rec_name) == 0) { break; } slot = sss_nss_mc_next_slot_with_hash(rec, hash); } if (!MC_SLOT_WITHIN_BOUNDS(slot, data_size)) { ret = ENOENT; goto done; } ret = sss_nss_mc_parse_result(rec, result, buffer, buflen); done: free(rec); __sync_sub_and_fetch(&pw_mc_ctx.active_threads, 1); return ret; } errno_t sss_nss_mc_getpwuid(uid_t uid, struct passwd *result, char *buffer, size_t buflen) { struct sss_mc_rec *rec = NULL; struct sss_mc_pwd_data *data; char uidstr[11]; uint32_t hash; uint32_t slot; int len; int ret; ret = sss_nss_mc_get_ctx("passwd", &pw_mc_ctx); if (ret) { return ret; } len = snprintf(uidstr, 11, "%ld", (long)uid); if (len > 10) { ret = EINVAL; goto done; } /* hashes are calculated including the NULL terminator */ hash = sss_nss_mc_hash(&pw_mc_ctx, uidstr, len+1); slot = pw_mc_ctx.hash_table[hash]; /* If slot is not within the bounds of mmaped region and * it's value is not MC_INVALID_VAL, then the cache is * probbably corrupted. */ while (MC_SLOT_WITHIN_BOUNDS(slot, pw_mc_ctx.dt_size)) { /* free record from previous iteration */ free(rec); rec = NULL; ret = sss_nss_mc_get_record(&pw_mc_ctx, slot, &rec); if (ret) { goto done; } /* check record matches what we are searching for */ if (hash != rec->hash2) { /* if uid hash does not match we can skip this immediately */ slot = sss_nss_mc_next_slot_with_hash(rec, hash); continue; } data = (struct sss_mc_pwd_data *)rec->data; if (uid == data->uid) { break; } slot = sss_nss_mc_next_slot_with_hash(rec, hash); } if (!MC_SLOT_WITHIN_BOUNDS(slot, pw_mc_ctx.dt_size)) { ret = ENOENT; goto done; } ret = sss_nss_mc_parse_result(rec, result, buffer, buflen); done: free(rec); __sync_sub_and_fetch(&pw_mc_ctx.active_threads, 1); return ret; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/COPYING0000644000000000000000000000007412703456111016315 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.378792693 sssd-1.13.4/src/sss_client/COPYING0000644002412700241270000010451312703456111017770 0ustar00jhrozekjhrozek00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . sssd-1.13.4/src/sss_client/PaxHeaders.16287/sss_pam.exports0000644000000000000000000000007412703456111020355 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.384792713 sssd-1.13.4/src/sss_client/sss_pam.exports0000644002412700241270000000003012703456111022015 0ustar00jhrozekjhrozek00000000000000{ global: *; }; sssd-1.13.4/src/sss_client/PaxHeaders.16287/nfs0000644000000000000000000000013212703463556016001 xustar0030 mtime=1460561774.899794459 30 atime=1460561776.118798593 30 ctime=1460561774.899794459 sssd-1.13.4/src/sss_client/nfs/0000755002412700241270000000000012703463556017532 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sss_client/nfs/PaxHeaders.16287/sss_nfs_client.c0000644000000000000000000000007412703456111021230 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.899794459 sssd-1.13.4/src/sss_client/nfs/sss_nfs_client.c0000644002412700241270000003321612703456111022704 0ustar00jhrozekjhrozek00000000000000/* SSSD NFS Client Copyright (C) Noam Meltzer 2013-2014 Copyright (C) Noam Meltzer 2014- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #define _GNU_SOURCE #include #include #include #include #include #include #include "nfsidmap_internal.h" #include "sss_client/sss_cli.h" #include "sss_client/nss_mc.h" /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ #define PLUGIN_NAME "sss_nfs" #define CONF_SECTION "sss_nfs" #define CONF_USE_MC "memcache" #define REPLY_ID_OFFSET (8) #define REPLY_NAME_OFFSET (REPLY_ID_OFFSET + 8) #define BUF_LEN (4096) #define USE_MC_DEFAULT true /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ static char sss_nfs_plugin_name[] = PLUGIN_NAME; static char nfs_conf_sect[] = CONF_SECTION; static char nfs_conf_use_mc[] = CONF_USE_MC; static bool nfs_use_mc = USE_MC_DEFAULT; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /* Forward declarations */ static int send_recv(uint8_t **repp, size_t *rep_lenp, enum sss_cli_command cmd, const void *req, size_t req_len); static int reply_to_id(id_t *idp, uint8_t *rep, size_t rep_len); static int reply_to_name(char *name, size_t len, uint8_t *rep, size_t rep_len); /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /* get from memcache functions */ static int get_uid_from_mc(id_t *uid, const char *name) { int rc = 0; struct passwd pwd; char *buf = NULL; char *p = NULL; size_t buflen = 0; size_t len = 0; if (!nfs_use_mc) { return -1; } sss_strnlen(name, SSS_NAME_MAX, &len); do { buflen += BUF_LEN; if ((p = realloc(buf, buflen)) == NULL) { rc = ENOMEM; goto done; } buf = p; rc = sss_nss_mc_getpwnam(name, len, &pwd, buf, buflen); } while (rc == ERANGE); if (rc == 0) { IDMAP_LOG(1, ("found user %s in memcache", name)); *uid = pwd.pw_uid; } else { IDMAP_LOG(1, ("user %s not in memcache", name)); } done: free(buf); return rc; } static int get_gid_from_mc(id_t *gid, const char *name) { int rc = 0; struct group grp; char *buf = NULL; char *p = NULL; size_t buflen = 0; size_t len; if (!nfs_use_mc) { return -1; } sss_strnlen(name, SSS_NAME_MAX, &len); do { buflen += BUF_LEN; if ((p = realloc(buf, buflen)) == NULL) { rc = ENOMEM; goto done; } buf = p; rc = sss_nss_mc_getgrnam(name, len, &grp, buf, buflen); } while (rc == ERANGE); if (rc == 0) { IDMAP_LOG(1, ("found group %s in memcache", name)); *gid = grp.gr_gid; } else { IDMAP_LOG(1, ("group %s not in memcache", name)); } done: free(buf); return rc; } static int get_user_from_mc(char *name, size_t len, uid_t uid) { int rc; struct passwd pwd; char *buf = NULL; char *p = NULL; size_t buflen = 0; size_t pw_name_len; if (!nfs_use_mc) { return -1; } do { buflen += BUF_LEN; if ((p = realloc(buf, buflen)) == NULL) { rc = ENOMEM; goto done; } buf = p; rc = sss_nss_mc_getpwuid(uid, &pwd, buf, buflen); } while (rc == ERANGE); if (rc == 0) { pw_name_len = strlen(pwd.pw_name) + 1; if (pw_name_len > len) { IDMAP_LOG(0, ("%s: reply too long; pw_name_len=%lu, len=%lu", __func__, pw_name_len, len)); rc = ENOBUFS; } IDMAP_LOG(1, ("found uid %i in memcache", uid)); memcpy(name, pwd.pw_name, pw_name_len); } else { IDMAP_LOG(1, ("uid %i not in memcache", uid)); } done: free(buf); return rc; } static int get_group_from_mc(char *name, size_t len, id_t gid) { int rc; struct group grp; char *buf = NULL; char *p = NULL; size_t buflen = 0; size_t gr_name_len; if (!nfs_use_mc) { return -1; } do { buflen += BUF_LEN; if ((p = realloc(buf, buflen)) == NULL) { rc = ENOMEM; goto done; } buf = p; rc = sss_nss_mc_getgrgid(gid, &grp, buf, buflen); } while (rc == ERANGE); if (rc == 0) { gr_name_len = strlen(grp.gr_name) + 1; if (gr_name_len > len) { IDMAP_LOG(0, ("%s: reply too long; gr_name_len=%lu, len=%lu", __func__, gr_name_len, len)); rc = ENOBUFS; } IDMAP_LOG(1, ("found gid %i in memcache", gid)); memcpy(name, grp.gr_name, gr_name_len); } else { IDMAP_LOG(1, ("gid %i not in memcache", gid)); } done: free(buf); return rc; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ static int name_to_id(const char *name, id_t *id, enum sss_cli_command cmd) { int rc; uint8_t *rep = NULL; size_t rep_len = 0; size_t name_len; sss_strnlen(name, SSS_NAME_MAX, &name_len); rc = send_recv(&rep, &rep_len, cmd, name, name_len + 1); if (rc == 0) { rc = reply_to_id(id, rep, rep_len); } free(rep); return rc; } static int id_to_name(char *name, size_t len, id_t id, enum sss_cli_command cmd) { int rc; size_t rep_len = 0; size_t req_len = sizeof(id_t); uint8_t *rep = NULL; uint8_t req[req_len]; memcpy(req, &id, req_len); rc = send_recv(&rep, &rep_len, cmd, &req, req_len); if (rc == 0) { rc = reply_to_name(name, len, rep, rep_len); } free(rep); return rc; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ static int send_recv(uint8_t **rep, size_t *rep_len, enum sss_cli_command cmd, const void *req, size_t req_len) { int err = 0; enum nss_status req_rc; struct sss_cli_req_data rd; rd.data = req; rd.len = req_len; sss_nss_lock(); req_rc = sss_nss_make_request(cmd, &rd, rep, rep_len, &err); sss_nss_unlock(); if (req_rc == NSS_STATUS_NOTFOUND) { return ENOENT; } if (req_rc != NSS_STATUS_SUCCESS) { IDMAP_LOG(0, ("no-make-request; err=%i", err)); return EPIPE; } return 0; } static int reply_to_id(id_t *idp, uint8_t *rep, size_t rep_len) { int rc = 0; id_t id; uint32_t num_results = 0; if (rep_len < sizeof(uint32_t)) { IDMAP_LOG(0, ("%s: reply too small; rep_len=%lu", __func__, rep_len)); rc = EBADMSG; goto done; } SAFEALIGN_COPY_UINT32(&num_results, rep, NULL); if (num_results > 1) { IDMAP_LOG(0, ("%s: too many results (%lu)", __func__, num_results)); rc = EBADMSG; goto done; } if (num_results == 0) { rc = ENOENT; goto done; } if (rep_len < sizeof(uint32_t) + REPLY_ID_OFFSET) { IDMAP_LOG(0, ("%s: reply too small(2); rep_len=%lu", __func__, rep_len)); rc = EBADMSG; goto done; } SAFEALIGN_COPY_UINT32(&id, rep + REPLY_ID_OFFSET, NULL); *idp = id; done: return rc; } static int reply_to_name(char *name, size_t len, uint8_t *rep, size_t rep_len) { int rc = 0; uint32_t num_results = 0; const char *buf; size_t buf_len; size_t offset; if (rep_len < sizeof(uint32_t)) { IDMAP_LOG(0, ("%s: reply too small; rep_len=%lu", __func__, rep_len)); rc = EBADMSG; goto done; } SAFEALIGN_COPY_UINT32(&num_results, rep, NULL); if (num_results > 1) { IDMAP_LOG(0, ("%s: too many results (%lu)", __func__, num_results)); rc = EBADMSG; goto done; } if (num_results == 0) { rc = ENOENT; goto done; } if (rep_len < sizeof(uint32_t) + REPLY_NAME_OFFSET) { IDMAP_LOG(0, ("%s: reply too small(2); rep_len=%lu", __func__, rep_len)); rc = EBADMSG; goto done; } buf = (const char *)(rep + REPLY_NAME_OFFSET); buf_len = rep_len - REPLY_NAME_OFFSET; offset = 0; rc = sss_readrep_copy_string(buf, &offset, &buf_len, &len, &name, NULL); if (rc != 0) { rc = -rc; } done: return rc; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /* configuration parsing aids */ static bool str_equal(const char *s1, const char *s2) { bool res = false; size_t len1; size_t len2; len1 = strlen(s1); len2 = strlen(s2); if (len1 == len2) { res = (strncasecmp(s1, s2, len1) == 0); } return res; } static int nfs_conf_get_bool(char *sect, char *attr, int def) { int res; char *val; res = def; val = conf_get_str(sect, attr); if (val) { res = (str_equal("1", val) || str_equal("yes", val) || str_equal("true", val) || str_equal("on", val)); } return res; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /* libnfsidmap return-code aids */ /* * we only want to return 0 or ENOENT; otherwise libnfsidmap will stop * translation instead of proceeding to the next translation plugin */ int normalise_rc(int rc) { int res; res = rc; if (res != 0 && res != ENOENT) { res = ENOENT; } return res; } /* log the actual rc from our code (to be used before normalising the rc) */ void log_actual_rc(const char *trans_name, int rc) { char tmp[80]; IDMAP_LOG(1, ("%s: rc=%i msg=%s", trans_name, rc, strerror_r(rc, tmp, sizeof(tmp)))); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /* The external interface */ static int sss_nfs_init(void) { nfs_use_mc = nfs_conf_get_bool(nfs_conf_sect, nfs_conf_use_mc, USE_MC_DEFAULT); IDMAP_LOG(1, ("%s: use memcache: %i", __func__, nfs_use_mc)); return 0; } static int sss_nfs_princ_to_ids(char *secname, char *princ, uid_t *uid, gid_t *gid, extra_mapping_params **ex) { IDMAP_LOG(0, ("%s: not implemented", __func__)); return -ENOENT; } static int sss_nfs_name_to_uid(char *name, uid_t *uid) { int rc; size_t name_len = 0; if (name == NULL) { IDMAP_LOG(0, ("%s: name is null", __func__)); return -EINVAL; } if (uid == NULL) { IDMAP_LOG(0, ("%s: uid is null", __func__)); return -EINVAL; } rc = sss_strnlen(name, SSS_NAME_MAX, &name_len); if (rc != 0) { IDMAP_LOG(0, ("%s: no-strnlen; rc=%i", __func__, rc)); return -rc; } rc = get_uid_from_mc(uid, name); if (rc != 0) { rc = name_to_id(name, uid, SSS_NSS_GETPWNAM); } log_actual_rc(__func__, rc); rc = normalise_rc(rc); return -rc; } static int sss_nfs_name_to_gid(char *name, gid_t *gid) { int rc; size_t name_len = 0; if (name == NULL) { IDMAP_LOG(0, ("%s: name is null", __func__)); return -EINVAL; } if (gid == NULL) { IDMAP_LOG(0, ("%s: gid is null", __func__)); return -EINVAL; } rc = sss_strnlen(name, SSS_NAME_MAX, &name_len); if (rc != 0) { IDMAP_LOG(0, ("%s: no-strnlen; rc=%i", __func__, rc)); return -rc; } rc = get_gid_from_mc(gid, name); if (rc != 0) { rc = name_to_id(name, gid, SSS_NSS_GETGRNAM); } log_actual_rc(__func__, rc); rc = normalise_rc(rc); return -rc; } static int sss_nfs_uid_to_name(uid_t uid, char *domain, char *name, size_t len) { int rc; if (name == NULL) { IDMAP_LOG(0, ("%s: name is null", __func__)); return -EINVAL; } rc = get_user_from_mc(name, len, uid); if (rc != 0) { rc = id_to_name(name, len, uid, SSS_NSS_GETPWUID); } log_actual_rc(__func__, rc); rc = normalise_rc(rc); return -rc; } static int sss_nfs_gid_to_name(gid_t gid, char *domain, char *name, size_t len) { int rc; if (name == NULL) { IDMAP_LOG(0, ("%s: name is null", __func__)); return -EINVAL; } rc = get_group_from_mc(name, len, gid); if (rc != 0) { rc = id_to_name(name, len, gid, SSS_NSS_GETGRGID); } log_actual_rc(__func__, rc); rc = normalise_rc(rc); return -rc; } static int sss_nfs_gss_princ_to_grouplist( char *secname, char *princ, gid_t *groups, int *ngroups, extra_mapping_params **ex) { IDMAP_LOG(0, ("%s: not implemented", __func__)); return -ENOENT; } static struct trans_func s_sss_nfs_trans = { .name = sss_nfs_plugin_name, .init = sss_nfs_init, .princ_to_ids = sss_nfs_princ_to_ids, .name_to_uid = sss_nfs_name_to_uid, .name_to_gid = sss_nfs_name_to_gid, .uid_to_name = sss_nfs_uid_to_name, .gid_to_name = sss_nfs_gid_to_name, .gss_princ_to_grouplist = sss_nfs_gss_princ_to_grouplist, }; struct trans_func *libnfsidmap_plugin_init(void) { return (&s_sss_nfs_trans); } sssd-1.13.4/src/sss_client/nfs/PaxHeaders.16287/nfsidmap_internal.h0000644000000000000000000000007412703456111021716 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.597793435 sssd-1.13.4/src/sss_client/nfs/nfsidmap_internal.h0000644002412700241270000000576412703456111023401 0ustar00jhrozekjhrozek00000000000000/* * nfsidmap_internal.h * * nfs idmapping library, primarily for nfs4 client/server kernel idmapping * and for userland nfs4 idmapping by acl libraries. * * Copyright (c) 2004 The Regents of the University of Michigan. * All rights reserved. * * Andy Adamson * * 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 ``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. */ char *get_default_domain(void); struct conf_list *get_local_realms(void); typedef struct trans_func * (*libnfsidmap_plugin_init_t)(void); struct trans_func { char *name; int (*init)(void); int (*princ_to_ids)(char *secname, char *princ, uid_t *uid, gid_t *gid, extra_mapping_params **ex); int (*name_to_uid)(char *name, uid_t *uid); int (*name_to_gid)(char *name, gid_t *gid); int (*uid_to_name)(uid_t uid, char *domain, char *name, size_t len); int (*gid_to_name)(gid_t gid, char *domain, char *name, size_t len); int (*gss_princ_to_grouplist)(char *secname, char *princ, gid_t *groups, int *ngroups, extra_mapping_params **ex); }; struct mapping_plugin { void *dl_handle; struct trans_func *trans; }; typedef enum { IDTYPE_USER = 1, IDTYPE_GROUP = 2 } idtypes; extern int idmap_verbosity; extern nfs4_idmap_log_function_t idmap_log_func; /* Level zero always prints, others print depending on verbosity level */ #define IDMAP_LOG(LVL, MSG) \ do { if (LVL <= idmap_verbosity) (*idmap_log_func)MSG; } while (0) /* * from libnfsidmap's cfg.h (same license as above) * Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved. * Copyright (c) 2000, 2003 H�kan Olsson. All rights reserved. */ extern char *conf_get_str(char *, char *); sssd-1.13.4/src/sss_client/PaxHeaders.16287/nss_compat.h0000644000000000000000000000007312703456111017600 xustar0030 atime=1460561751.654715641 29 ctime=1460561774.67879371 sssd-1.13.4/src/sss_client/nss_compat.h0000644002412700241270000000365412703456111021260 0ustar00jhrozekjhrozek00000000000000/* SSSD nss_compat.h Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Portions of this source file were copied from nss-pam-ldapd version 0.7.8, licensed under LGPLv2.1+ */ #ifndef NSS_COMPAT_H_ #define NSS_COMPAT_H_ /* We also define struct __netgrent because it's definition is not publically available. This is taken from inet/netgroup.h of the glibc (2.3.6) source tarball. The first part of the struct is the only part that is modified by our getnetgrent() function, all the other fields are not touched at all. */ struct __netgrent { enum { triple_val, group_val } type; union { struct { const char *host; const char *user; const char *domain; } triple; const char *group; } val; /* the following stuff is used by some NSS services but not by ours (it's not completely clear how these are shared between different services) or is used by our caller */ char *data; size_t data_size; union { char *cursor; unsigned long int position; } idx; /* added name to union to avoid warning */ int first; struct name_list *known_groups; struct name_list *needed_groups; void *nip; /* changed from `service_user *nip' */ }; #endif /* NSS_COMPAT_H_ */ sssd-1.13.4/src/sss_client/PaxHeaders.16287/nss_mc_common.c0000644000000000000000000000007412703456111020260 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.679793714 sssd-1.13.4/src/sss_client/nss_mc_common.c0000644002412700241270000002314312703456111021732 0ustar00jhrozekjhrozek00000000000000/* * System Security Services Daemon. NSS client interface * * Copyright (C) Simo Sorce 2011 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ /* NSS interfaces to mmap cache */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "nss_mc.h" #include "sss_cli.h" #include "util/io.h" /* FIXME: hook up to library destructor to avoid leaks */ /* FIXME: temporarily open passwd file on our own, later we will probably * use socket passing from the main process */ /* FIXME: handle name upper/lower casing ? Maybe a flag passed down by * sssd or a flag in sss_mc_header ? per domain ? */ #define MEMCPY_WITH_BARRIERS(res, dest, src, len) \ do { \ uint32_t _b1; \ res = false; \ _b1 = (src)->b1; \ if (MC_VALID_BARRIER(_b1)) { \ __sync_synchronize(); \ memcpy(dest, src, len); \ __sync_synchronize(); \ if ((src)->b2 == _b1) { \ res = true; \ } \ } \ } while(0) errno_t sss_nss_check_header(struct sss_cli_mc_ctx *ctx) { struct sss_mc_header h; bool copy_ok; int count; int ret; struct stat fdstat; /* retry barrier protected reading max 5 times then give up */ for (count = 5; count > 0; count--) { MEMCPY_WITH_BARRIERS(copy_ok, &h, (struct sss_mc_header *)ctx->mmap_base, sizeof(struct sss_mc_header)); if (copy_ok) { /* record is consistent so we can proceed */ break; } } if (count == 0) { /* couldn't successfully read header we have to give up */ return EIO; } if (h.major_vno != SSS_MC_MAJOR_VNO || h.minor_vno != SSS_MC_MINOR_VNO || h.status == SSS_MC_HEADER_RECYCLED) { return EINVAL; } /* first time we check the header, let's fill our own struct */ if (ctx->data_table == NULL) { ctx->seed = h.seed; ctx->data_table = MC_PTR_ADD(ctx->mmap_base, h.data_table); ctx->hash_table = MC_PTR_ADD(ctx->mmap_base, h.hash_table); ctx->dt_size = h.dt_size; ctx->ht_size = h.ht_size; } else { if (ctx->seed != h.seed || ctx->data_table != MC_PTR_ADD(ctx->mmap_base, h.data_table) || ctx->hash_table != MC_PTR_ADD(ctx->mmap_base, h.hash_table) || ctx->dt_size != h.dt_size || ctx->ht_size != h.ht_size) { return EINVAL; } } ret = fstat(ctx->fd, &fdstat); if (ret == -1) { return EIO; } if (fdstat.st_nlink == 0) { /* memory cache was removed; we need to reinitialize it. */ return EINVAL; } return 0; } static void sss_nss_mc_destroy_ctx(struct sss_cli_mc_ctx *ctx) { uint32_t active_threads = ctx->active_threads; if ((ctx->mmap_base != NULL) && (ctx->mmap_size != 0)) { munmap(ctx->mmap_base, ctx->mmap_size); } if (ctx->fd != -1) { close(ctx->fd); } memset(ctx, 0, sizeof(struct sss_cli_mc_ctx)); ctx->fd = -1; /* restore count of active threads */ ctx->active_threads = active_threads; } static errno_t sss_nss_mc_init_ctx(const char *name, struct sss_cli_mc_ctx *ctx) { struct stat fdstat; char *file = NULL; int ret; sss_nss_mc_lock(); /* check if ctx is initialised by previous thread. */ if (ctx->initialized != UNINITIALIZED) { ret = sss_nss_check_header(ctx); goto done; } ret = asprintf(&file, "%s/%s", SSS_NSS_MCACHE_DIR, name); if (ret == -1) { ret = ENOMEM; goto done; } ctx->fd = sss_open_cloexec(file, O_RDONLY, &ret); if (ctx->fd == -1) { goto done; } ret = fstat(ctx->fd, &fdstat); if (ret == -1) { ret = EIO; goto done; } if (fdstat.st_size < MC_HEADER_SIZE) { ret = ENOMEM; goto done; } ctx->mmap_size = fdstat.st_size; ctx->mmap_base = mmap(NULL, ctx->mmap_size, PROT_READ, MAP_SHARED, ctx->fd, 0); if (ctx->mmap_base == MAP_FAILED) { ret = ENOMEM; goto done; } ret = sss_nss_check_header(ctx); if (ret != 0) { goto done; } ctx->initialized = INITIALIZED; ret = 0; done: if (ret) { sss_nss_mc_destroy_ctx(ctx); } free(file); sss_nss_mc_unlock(); return ret; } errno_t sss_nss_mc_get_ctx(const char *name, struct sss_cli_mc_ctx *ctx) { char *envval; int ret; bool need_decrement = false; envval = getenv("SSS_NSS_USE_MEMCACHE"); if (envval && strcasecmp(envval, "NO") == 0) { return EPERM; } switch (ctx->initialized) { case UNINITIALIZED: __sync_add_and_fetch(&ctx->active_threads, 1); ret = sss_nss_mc_init_ctx(name, ctx); if (ret) { need_decrement = true; } break; case INITIALIZED: __sync_add_and_fetch(&ctx->active_threads, 1); ret = sss_nss_check_header(ctx); if (ret) { need_decrement = true; } break; case RECYCLED: /* we need to safely destroy memory cache */ ret = EAGAIN; break; default: ret = EFAULT; } if (ret) { if (ctx->initialized == INITIALIZED) { ctx->initialized = RECYCLED; } if (ctx->initialized == RECYCLED && ctx->active_threads == 0) { /* just one thread should call munmap */ sss_nss_mc_lock(); if (ctx->initialized == RECYCLED) { sss_nss_mc_destroy_ctx(ctx); } sss_nss_mc_unlock(); } if (need_decrement) { /* In case of error, we will not touch mmapped area => decrement */ __sync_sub_and_fetch(&ctx->active_threads, 1); } } return ret; } uint32_t sss_nss_mc_hash(struct sss_cli_mc_ctx *ctx, const char *key, size_t len) { return murmurhash3(key, len, ctx->seed) % MC_HT_ELEMS(ctx->ht_size); } errno_t sss_nss_mc_get_record(struct sss_cli_mc_ctx *ctx, uint32_t slot, struct sss_mc_rec **_rec) { struct sss_mc_rec *rec; struct sss_mc_rec *copy_rec = NULL; size_t buf_size = 0; size_t rec_len; uint32_t b1; uint32_t b2; bool copy_ok; int count; int ret; /* try max 5 times */ for (count = 5; count > 0; count--) { rec = MC_SLOT_TO_PTR(ctx->data_table, slot, struct sss_mc_rec); /* fetch record length */ b1 = rec->b1; __sync_synchronize(); rec_len = rec->len; __sync_synchronize(); b2 = rec->b2; if (!MC_VALID_BARRIER(b1) || b1 != b2) { /* record is inconsistent, retry */ continue; } if (!MC_CHECK_RECORD_LENGTH(ctx, rec)) { /* record has invalid length */ free(copy_rec); return EINVAL; } if (rec_len > buf_size) { free(copy_rec); copy_rec = malloc(rec_len); if (!copy_rec) { ret = ENOMEM; goto done; } buf_size = rec_len; } /* we cannot access data directly, we must copy data and then * access the copy */ MEMCPY_WITH_BARRIERS(copy_ok, copy_rec, rec, rec_len); /* we must check data is consistent again after the copy */ if (copy_ok && b1 == copy_rec->b2) { /* record is consistent, use it */ break; } } if (count == 0) { /* couldn't successfully read header we have to give up */ ret = EIO; goto done; } *_rec = copy_rec; ret = 0; done: if (ret) { free(copy_rec); *_rec = NULL; } return ret; } /* * returns strings froma a buffer. * * Call first time with *cookie set to null, then call again * with the returned cookie. * On the last string the cookie will be reset to null and * all strings will have been returned. * In case the last string is not zero terminated EINVAL is returned. */ errno_t sss_nss_str_ptr_from_buffer(char **str, void **cookie, char *buf, size_t len) { char *max = buf + len; char *ret; char *p; if (*cookie == NULL) { p = buf; } else { p = *((char **)cookie); } ret = p; while (p < max) { if (*p == '\0') { break; } p++; } if (p >= max) { return EINVAL; } p++; if (p == max) { *cookie = NULL; } else { *cookie = p; } *str = ret; return 0; } uint32_t sss_nss_mc_next_slot_with_hash(struct sss_mc_rec *rec, uint32_t hash) { if (rec->hash1 == hash) { return rec->next1; } else if (rec->hash2 == hash) { return rec->next2; } else { /* it should never happen. */ return MC_INVALID_VAL; } } sssd-1.13.4/src/sss_client/PaxHeaders.16287/sssd_pac.c0000644000000000000000000000007312703456111017224 xustar0030 atime=1460561751.654715641 29 ctime=1460561774.90279447 sssd-1.13.4/src/sss_client/sssd_pac.c0000644002412700241270000002124312703456111020676 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2011, 2012, 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* A short documentation about authdata plugins can be found in * http://http://k5wiki.kerberos.org/wiki/Projects/VerifyAuthData */ #include #include #include "krb5_authdata_int.h" #include "sss_cli.h" struct sssd_context { krb5_data data; }; static krb5_error_code sssdpac_init(krb5_context kcontext, void **plugin_context) { *plugin_context = NULL; return 0; } static void sssdpac_flags(krb5_context kcontext, void *plugin_context, krb5_authdatatype ad_type, krb5_flags *flags) { *flags = AD_USAGE_KDC_ISSUED | AD_USAGE_TGS_REQ; } static void sssdpac_fini(krb5_context kcontext, void *plugin_context) { return; } static krb5_error_code sssdpac_request_init(krb5_context kcontext, krb5_authdata_context context, void *plugin_context, void **request_context) { struct sssd_context *sssdctx; sssdctx = (struct sssd_context *)calloc(1, sizeof(*sssdctx)); if (sssdctx == NULL) { return ENOMEM; } *request_context = sssdctx; return 0; } static krb5_error_code sssdpac_import_authdata(krb5_context kcontext, krb5_authdata_context context, void *plugin_context, void *request_context, krb5_authdata **authdata, krb5_boolean kdc_issued, krb5_const_principal kdc_issuer) { char *data = NULL; struct sssd_context *sssdctx = (struct sssd_context *)request_context; if (authdata[0] == NULL) { return EINVAL; } if (authdata[0]->length > 0) { data = malloc(sizeof(char) * authdata[0]->length); if (data == NULL) { return ENOMEM; } memcpy(data, authdata[0]->contents, authdata[0]->length); } if (sssdctx->data.data != NULL) { krb5_free_data_contents(kcontext, &sssdctx->data); } sssdctx->data.length = authdata[0]->length; sssdctx->data.data = data; return 0; } static void sssdpac_request_fini(krb5_context kcontext, krb5_authdata_context context, void *plugin_context, void *request_context) { struct sssd_context *sssdctx = (struct sssd_context *)request_context; if (sssdctx != NULL) { if (sssdctx->data.data != NULL) { krb5_free_data_contents(kcontext, &sssdctx->data); } free(sssdctx); } } static krb5_error_code sssdpac_verify(krb5_context kcontext, krb5_authdata_context context, void *plugin_context, void *request_context, const krb5_auth_context *auth_context, const krb5_keyblock *key, const krb5_ap_req *req) { krb5_error_code kerr; int ret; krb5_pac pac; struct sssd_context *sssdctx = (struct sssd_context *)request_context; struct sss_cli_req_data sss_data; int errnop; if (sssdctx == NULL || sssdctx->data.data == NULL) { return EINVAL; } kerr = krb5_pac_parse(kcontext, sssdctx->data.data, sssdctx->data.length, &pac); if (kerr != 0) { return EINVAL; } kerr = krb5_pac_verify(kcontext, pac, req->ticket->enc_part2->times.authtime, req->ticket->enc_part2->client, key, NULL); /* deallocate pac */ krb5_pac_free(kcontext, pac); pac = NULL; if (kerr != 0) { /* The krb5 documentation says: * A checksum mismatch can occur if the PAC was copied from a * cross-realm TGT by an ignorant KDC; also Apple Mac OS X Server * Open Directory (as of 10.6) generates PACs with no server checksum * at all. One should consider not failing the whole authentication * because of this reason, but, instead, treating the ticket as * if it did not contain a PAC or marking the PAC information as * non-verified. */ return 0; } sss_data.len = sssdctx->data.length; sss_data.data = sssdctx->data.data; ret = sss_pac_make_request(SSS_PAC_ADD_PAC_USER, &sss_data, NULL, NULL, &errnop); if (ret != 0) { /* Ignore the error */ } return 0; } static krb5_error_code sssdpac_size(krb5_context kcontext, krb5_authdata_context context, void *plugin_context, void *request_context, size_t *sizep) { struct sssd_context *sssdctx = (struct sssd_context *)request_context; *sizep += sizeof(krb5_int32); *sizep += sssdctx->data.length; *sizep += sizeof(krb5_int32); return 0; } static krb5_error_code sssdpac_externalize(krb5_context kcontext, krb5_authdata_context context, void *plugin_context, void *request_context, krb5_octet **buffer, size_t *lenremain) { krb5_error_code code = 0; struct sssd_context *sssdctx = (struct sssd_context *)request_context; size_t required = 0; krb5_octet *bp; size_t remain; bp = *buffer; remain = *lenremain; if (sssdctx->data.data != NULL) { sssdpac_size(kcontext, context, plugin_context, request_context, &required); if (required <= remain) { krb5_ser_pack_int32((krb5_int32)sssdctx->data.length, &bp, &remain); krb5_ser_pack_bytes((krb5_octet *)sssdctx->data.data, (size_t)sssdctx->data.length, &bp, &remain); krb5_ser_pack_int32(0, &bp, &remain); } else { code = ENOMEM; } } else { krb5_ser_pack_int32(0, &bp, &remain); /* length */ krb5_ser_pack_int32(0, &bp, &remain); /* verified */ } *buffer = bp; *lenremain = remain; return code; } static krb5_error_code sssdpac_internalize(krb5_context kcontext, krb5_authdata_context context, void *plugin_context, void *request_context, krb5_octet **buffer, size_t *lenremain) { struct sssd_context *sssdctx = (struct sssd_context *)request_context; krb5_error_code code; krb5_int32 ibuf; krb5_octet *bp; size_t remain; krb5_data data; bp = *buffer; remain = *lenremain; /* length */ code = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (code != 0) { return code; } if (ibuf != 0) { data.length = ibuf; data.data = malloc(sizeof(char) * ibuf); if (data.data == NULL) { return ENOMEM; } memcpy(data.data, bp, ibuf); bp += ibuf; remain -= ibuf; } else { data.length = 0; data.data = NULL; } /* verified */ code = krb5_ser_unpack_int32(&ibuf, &bp, &remain); if (code != 0) { free(data.data); return code; } if (sssdctx->data.data != NULL) { krb5_free_data_contents(kcontext, &sssdctx->data); } sssdctx->data.length = data.length; sssdctx->data.data = data.data; *buffer = bp; *lenremain = remain; return 0; } static krb5_authdatatype sssdpac_ad_types[] = { KRB5_AUTHDATA_WIN2K_PAC, 0 }; krb5plugin_authdata_client_ftable_v0 authdata_client_0 = { ((void *)((uintptr_t)("sssd_sssdpac"))), sssdpac_ad_types, sssdpac_init, sssdpac_fini, sssdpac_flags, sssdpac_request_init, sssdpac_request_fini, NULL, NULL, NULL, NULL, NULL, sssdpac_import_authdata, NULL, NULL, sssdpac_verify, sssdpac_size, sssdpac_externalize, sssdpac_internalize, NULL }; sssd-1.13.4/src/sss_client/PaxHeaders.16287/sss_cli.h0000644000000000000000000000007412703456111017072 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.677793707 sssd-1.13.4/src/sss_client/sss_cli.h0000644002412700241270000005676112703456111020560 0ustar00jhrozekjhrozek00000000000000/* SSSD Client Interface for NSS and PAM. Authors: Simo Sorce Copyright (C) Red Hat, Inc 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef _SSSCLI_H #define _SSSCLI_H #include #include #include #include #include #include #include "util/util_safealign.h" #ifndef HAVE_ERRNO_T #define HAVE_ERRNO_T typedef int errno_t; #endif #ifndef EOK #define EOK 0 #endif #define SSS_NSS_PROTOCOL_VERSION 1 #define SSS_PAM_PROTOCOL_VERSION 3 #define SSS_SUDO_PROTOCOL_VERSION 1 #define SSS_AUTOFS_PROTOCOL_VERSION 1 #define SSS_SSH_PROTOCOL_VERSION 0 #define SSS_PAC_PROTOCOL_VERSION 1 #ifdef LOGIN_NAME_MAX #define SSS_NAME_MAX LOGIN_NAME_MAX #else #define SSS_NAME_MAX 256 #endif /** * @defgroup sss_cli_command SSS client commands * @{ */ /** The allowed commands a SSS client can send to the SSSD */ enum sss_cli_command { /* null */ SSS_CLI_NULL = 0x0000, /* version */ SSS_GET_VERSION = 0x0001, /* passwd */ SSS_NSS_GETPWNAM = 0x0011, SSS_NSS_GETPWUID = 0x0012, SSS_NSS_SETPWENT = 0x0013, SSS_NSS_GETPWENT = 0x0014, SSS_NSS_ENDPWENT = 0x0015, /* group */ SSS_NSS_GETGRNAM = 0x0021, SSS_NSS_GETGRGID = 0x0022, SSS_NSS_SETGRENT = 0x0023, SSS_NSS_GETGRENT = 0x0024, SSS_NSS_ENDGRENT = 0x0025, SSS_NSS_INITGR = 0x0026, #if 0 /* aliases */ SSS_NSS_GETALIASBYNAME = 0x0031, SSS_NSS_GETALIASBYPORT = 0x0032, SSS_NSS_SETALIASENT = 0x0033, SSS_NSS_GETALIASENT = 0x0034, SSS_NSS_ENDALIASENT = 0x0035, /* ethers */ SSS_NSS_GETHOSTTON = 0x0041, SSS_NSS_GETNTOHOST = 0x0042, SSS_NSS_SETETHERENT = 0x0043, SSS_NSS_GETETHERENT = 0x0044, SSS_NSS_ENDETHERENT = 0x0045, /* hosts */ SSS_NSS_GETHOSTBYNAME = 0x0051, SSS_NSS_GETHOSTBYNAME2 = 0x0052, SSS_NSS_GETHOSTBYADDR = 0x0053, SSS_NSS_SETHOSTENT = 0x0054, SSS_NSS_GETHOSTENT = 0x0055, SSS_NSS_ENDHOSTENT = 0x0056, #endif /* netgroup */ SSS_NSS_SETNETGRENT = 0x0061, SSS_NSS_GETNETGRENT = 0x0062, SSS_NSS_ENDNETGRENT = 0x0063, /* SSS_NSS_INNETGR = 0x0064, */ #if 0 /* networks */ SSS_NSS_GETNETBYNAME = 0x0071, SSS_NSS_GETNETBYADDR = 0x0072, SSS_NSS_SETNETENT = 0x0073, SSS_NSS_GETNETENT = 0x0074, SSS_NSS_ENDNETENT = 0x0075, /* protocols */ SSS_NSS_GETPROTOBYNAME = 0x0081, SSS_NSS_GETPROTOBYNUM = 0x0082, SSS_NSS_SETPROTOENT = 0x0083, SSS_NSS_GETPROTOENT = 0x0084, SSS_NSS_ENDPROTOENT = 0x0085, /* rpc */ SSS_NSS_GETRPCBYNAME = 0x0091, SSS_NSS_GETRPCBYNUM = 0x0092, SSS_NSS_SETRPCENT = 0x0093, SSS_NSS_GETRPCENT = 0x0094, SSS_NSS_ENDRPCENT = 0x0095, #endif /* services */ SSS_NSS_GETSERVBYNAME = 0x00A1, SSS_NSS_GETSERVBYPORT = 0x00A2, SSS_NSS_SETSERVENT = 0x00A3, SSS_NSS_GETSERVENT = 0x00A4, SSS_NSS_ENDSERVENT = 0x00A5, #if 0 /* shadow */ SSS_NSS_GETSPNAM = 0x00B1, SSS_NSS_GETSPUID = 0x00B2, SSS_NSS_SETSPENT = 0x00B3, SSS_NSS_GETSPENT = 0x00B4, SSS_NSS_ENDSPENT = 0x00B5, #endif /* SUDO */ SSS_SUDO_GET_SUDORULES = 0x00C1, SSS_SUDO_GET_DEFAULTS = 0x00C2, /* autofs */ SSS_AUTOFS_SETAUTOMNTENT = 0x00D1, SSS_AUTOFS_GETAUTOMNTENT = 0x00D2, SSS_AUTOFS_GETAUTOMNTBYNAME = 0x00D3, SSS_AUTOFS_ENDAUTOMNTENT = 0x00D4, /* SSH */ SSS_SSH_GET_USER_PUBKEYS = 0x00E1, SSS_SSH_GET_HOST_PUBKEYS = 0x00E2, /* PAM related calls */ SSS_PAM_AUTHENTICATE = 0x00F1, /**< see pam_sm_authenticate(3) for * details. * * Additionally we allow sssd to send * the return code PAM_NEW_AUTHTOK_REQD * during authentication if the * authentication was successful but * the authentication token is expired. * To meet the standards of libpam we * return PAM_SUCCESS for * authentication and set a flag so * that the account management module * can return PAM_NEW_AUTHTOK_REQD if * sssd return success for account * management. We do this to reduce the * communication with external servers, * because there are cases, e.g. * Kerberos authentication, where the * information that the password is * expired is already available during * authentication. */ SSS_PAM_SETCRED = 0x00F2, /**< see pam_sm_setcred(3) for * details */ SSS_PAM_ACCT_MGMT = 0x00F3, /**< see pam_sm_acct_mgmt(3) for * details */ SSS_PAM_OPEN_SESSION = 0x00F4, /**< see pam_sm_open_session(3) for * details */ SSS_PAM_CLOSE_SESSION = 0x00F5, /**< see pam_sm_close_session(3) for *details */ SSS_PAM_CHAUTHTOK = 0x00F6, /**< second run of the password change * operation where the PAM_UPDATE_AUTHTOK * flag is set and the real change may * happen, see pam_sm_chauthtok(3) for * details */ SSS_PAM_CHAUTHTOK_PRELIM = 0x00F7, /**< first run of the password change * operation where the PAM_PRELIM_CHECK * flag is set, see pam_sm_chauthtok(3) * for details */ SSS_CMD_RENEW = 0x00F8, /**< Renew a credential with a limited * lifetime, e.g. a Kerberos Ticket * Granting Ticket (TGT) */ SSS_PAM_PREAUTH = 0x00F9, /**< Request which can be run before * an authentication request to find * out which authentication methods * are available for the given user. */ /* PAC responder calls */ SSS_PAC_ADD_PAC_USER = 0x0101, /* ID-SID mapping calls */ SSS_NSS_GETSIDBYNAME = 0x0111, /**< Takes a zero terminated fully qualified name and returns the zero terminated string representation of the SID of the object with the given name. */ SSS_NSS_GETSIDBYID = 0x0112, /**< Takes an unsigned 32bit integer (POSIX ID) and returns the zero terminated string representation of the SID of the object with the given ID. */ SSS_NSS_GETNAMEBYSID = 0x0113, /**< Takes the zero terminated string representation of a SID and returns the zero terminated fully qualified name of the related object. */ SSS_NSS_GETIDBYSID = 0x0114, /**< Takes the zero terminated string representation of a SID and returns and returns the POSIX ID of the related object as unsigned 32bit integer value and another unsigned 32bit integer value indicating the type (unknown, user, group, both) of the object. */ SSS_NSS_GETORIGBYNAME = 0x0115, /**< Takes a zero terminated fully qualified name and returns a list of zero terminated strings with key-value pairs where the first string is the key and second the value. Hence the list should have an even number of strings, if not the whole list is invalid. */ }; /** * @} */ /* end of group sss_cli_command */ /** * @defgroup sss_pam SSSD and PAM * * SSSD offers authentication and authorization via PAM * * The SSSD provides a PAM client modules pam_sss which can be called from the * PAM stack of the operation system. pam_sss will collect all the data about * the user from the PAM stack and sends them via a socket to the PAM * responder of the SSSD. The PAM responder selects the appropriate backend * and forwards the data via DBUS to the backend. The backend preforms the * requested operation and sends the result expressed by a PAM return value * and optional additional information back to the PAM responder. Finally the * PAM responder forwards the response back to the client. * * @{ */ /** * @} */ /* end of group sss_pam */ /** * @defgroup sss_authtok_type Authentication Tokens * @ingroup sss_pam * * To indicate to the components of the SSSD how to handle the authentication * token the client sends the type of the authentication token to the SSSD. * * @{ */ /** The different types of authentication tokens */ enum sss_authtok_type { SSS_AUTHTOK_TYPE_EMPTY = 0x0000, /**< No authentication token * available */ SSS_AUTHTOK_TYPE_PASSWORD = 0x0001, /**< Authentication token is a * password, it may or may no contain * a trailing \\0 */ SSS_AUTHTOK_TYPE_CCFILE = 0x0002, /**< Authentication token is a path to * a Kerberos credential cache file, * it may or may no contain * a trailing \\0 */ SSS_AUTHTOK_TYPE_2FA = 0x0003, /**< Authentication token has two * factors, they may or may no contain * a trailing \\0 */ SSS_AUTHTOK_TYPE_SC_PIN = 0x0004, /**< Authentication token is a Smart * Card pin, it may or may no contain * a trailing \\0 */ SSS_AUTHTOK_TYPE_SC_KEYPAD = 0x0005, /**< Authentication token indicates * Smart Card authentication is used * and that the pin will be entered * at the card reader. */ }; /** * @} */ /* end of group sss_authtok_type */ #define SSS_START_OF_PAM_REQUEST 0x4d415049 #define SSS_END_OF_PAM_REQUEST 0x4950414d #define PAM_PREAUTH_INDICATOR PUBCONF_PATH"/pam_preauth_available" enum pam_item_type { SSS_PAM_ITEM_EMPTY = 0x0000, SSS_PAM_ITEM_USER, SSS_PAM_ITEM_SERVICE, SSS_PAM_ITEM_TTY, SSS_PAM_ITEM_RUSER, SSS_PAM_ITEM_RHOST, SSS_PAM_ITEM_AUTHTOK, SSS_PAM_ITEM_NEWAUTHTOK, SSS_PAM_ITEM_CLI_LOCALE, SSS_PAM_ITEM_CLI_PID, SSS_PAM_ITEM_REQUESTED_DOMAINS, }; #define SSS_NSS_MAX_ENTRIES 256 #define SSS_NSS_HEADER_SIZE (sizeof(uint32_t) * 4) struct sss_cli_req_data { size_t len; const void *data; }; /* this is in milliseconds, wait up to 300 seconds */ #define SSS_CLI_SOCKET_TIMEOUT 300000 enum sss_status { SSS_STATUS_TRYAGAIN, SSS_STATUS_UNAVAIL, SSS_STATUS_SUCCESS }; /** * @defgroup sss_pam_cli Responses to the PAM client * @ingroup sss_pam * @{ */ /** * @defgroup response_type Messages from the server * @ingroup sss_pam_cli * * SSSD can send different kind of information back to the client. * A response from the SSSD can contain 0 or more messages. Each message * contains a type tag and the size of the message data, both are unsigned * 32-bit integer values, followed be the message specific data. * * If the message is generated by a backend it is send back to the PAM * responder via a D-BUS message in an array of D-BUS structs. The struct * consists of a DBUS_TYPE_UINT32 for the tag and a DBUS_TYPE_ARRAY to hold * the message. * * Examples: * - #SSS_PAM_ENV_ITEM, uint32_t | uint32_t | uint8_t[4] ----------|----------|------------ 0x03 | 0x04 | a=b\\0 * @{ */ /** Types of different messages */ enum response_type { SSS_PAM_SYSTEM_INFO = 0x01, /**< Message for the system log. * @param String, zero terminated. */ SSS_PAM_DOMAIN_NAME, /**< Name of the domain the user belongs too. * This messages is generated by the PAM responder. * @param String, zero terminated, with the domain * name. */ SSS_PAM_ENV_ITEM, /**< Set and environment variable with pam_putenv(3). * @param String, zero terminated, of the form * name=value. See pam_putenv(3) for details. */ SSS_ENV_ITEM, /**< Set and environment variable with putenv(3). * @param String, zero terminated, of the form * name=value. See putenv(3) for details. */ SSS_ALL_ENV_ITEM, /**< Set and environment variable with putenv(3) and * pam_putenv(3). * @param String, zero terminated, of the form * name=value. See putenv(3) and pam_putenv(3) for * details. */ SSS_PAM_USER_INFO, /**< A message which should be displayed to the user. * @param User info message, see #user_info_type * for details. */ SSS_PAM_TEXT_MSG, /**< A plain text message which should be displayed to * the user.This should only be used in the case where * it is not possile to use SSS_PAM_USER_INFO. * @param A zero terminated string. */ SSS_PAM_OTP_INFO, /**< A message which optionally may contain the name * of the vendor, the ID of an OTP token and a * challenge. * @param Three zero terminated strings, if one of the * strings is missing the message will contain only * an empty string (\0) for that component. */ SSS_PAM_CERT_INFO, SSS_OTP, /**< Indicates that the autotok was a OTP, so don't * cache it. There is no message. * @param None. */ }; /** * @defgroup user_info_type User info messages * @ingroup response_type * * To achieve a consistent user experience and to facilitate * internationalization all messages show to the user are generate by the PAM * client and not by the SSSD server components. To indicate what message the * client should display to the user SSSD can send a #SSS_PAM_USER_INFO message * where the data part contains one of the following tags as an unsigned * 32-bit integer value and optional data. * * Examples: * - #SSS_PAM_USER_INFO_OFFLINE_CHPASS * uint32_t | uint32_t | uint32_t * ----------|----------|---------- * 0x06 | 0x04 | 0x03 * * - #SSS_PAM_USER_INFO_CHPASS_ERROR * uint32_t | uint32_t | uint32_t | uint32_t | uint8_t[3] * ----------|----------|----------|----------|------------ * 0x06 | 0x0B | 0x04 | 0x03 | abc * @{ */ /** Different types of user messages */ enum user_info_type { SSS_PAM_USER_INFO_OFFLINE_AUTH = 0x01, /**< Inform the user that the * authentication happened offline. * This message is generated by the * PAM responder. * @param Time when the cached * password will expire in seconds * since the UNIX Epoch as returned * by time(2) as int64_t. A value * of zero indicates that the * cached password will never * expire. */ SSS_PAM_USER_INFO_OFFLINE_AUTH_DELAYED, /**< Tell the user how low a new * authentication is delayed. This * message is generated by the PAM * responder. * @param Time when an * authentication is allowed again * in seconds since the UNIX Epoch * as returned by time(2) as * int64_t. */ SSS_PAM_USER_INFO_OFFLINE_CHPASS, /**< * Tell the user that it is not * possible to change the password while * the system is offline. This message * is generated by the PAM responder. */ SSS_PAM_USER_INFO_OTP_CHPASS, /**< Tell the user that he needs to kinit * or login and logout to get a TGT after * an OTP password change */ SSS_PAM_USER_INFO_CHPASS_ERROR, /**< Tell the user that a password change * failed and optionally give a reason. * @param Size of the message as unsigned * 32-bit integer value. A value of 0 * indicates that no message is following. * @param String with the specified * length. */ SSS_PAM_USER_INFO_GRACE_LOGIN, /**< Warn the user that the password is * expired and inform about the remaining * number of grace logins. * @param The number of remaining grace * logins as uint32_t */ SSS_PAM_USER_INFO_EXPIRE_WARN, /**< Warn the user that the password will * expire soon. * @param Number of seconds before the * user's password will expire. */ SSS_PAM_USER_INFO_ACCOUNT_EXPIRED, /**< Tell the user that the account * has expired and optionally give * a reason. * @param Size of the message as * unsigned 32-bit integer value. A * value of 0 indicates that no message * is following. @param String with the * specified length. */ }; /** * @} */ /* end of group user_info_type */ /** * @} */ /* end of group response_type */ /** * @} */ /* end of group sss_pam_cli */ enum sss_netgr_rep_type { SSS_NETGR_REP_TRIPLE = 1, SSS_NETGR_REP_GROUP }; enum sss_cli_error_codes { ESSS_SSS_CLI_ERROR_START = 0x1000, ESSS_BAD_PRIV_SOCKET, ESSS_BAD_PUB_SOCKET, ESSS_BAD_CRED_MSG, ESSS_SERVER_NOT_TRUSTED, ESS_SSS_CLI_ERROR_MAX }; const char *ssscli_err2string(int err); enum nss_status sss_nss_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop); int sss_pam_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop); void sss_pam_close_fd(void); /* Checks access to the PAC responder and opens the socket, if available. * Required for processes like krb5_child that need to open the socket * before dropping privs. */ int sss_pac_check_and_open(void); int sss_pac_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop); int sss_sudo_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop); int sss_autofs_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop); int sss_ssh_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop); #if 0 /* GETSPNAM Request: * * 0-X: string with name * * Replies: * * 0-3: 32bit unsigned number of results * 4-7: 32bit unsigned (reserved/padding) * For each result: * 0-7: 64bit unsigned with Date of last change * 8-15: 64bit unsigned with Min #days between changes * 16-23: 64bit unsigned with Max #days between changes * 24-31: 64bit unsigned with #days before pwd expires * 32-39: 64bit unsigned with #days after pwd expires until account is disabled * 40-47: 64bit unsigned with expiration date in days since 1970-01-01 * 48-55: 64bit unsigned (flags/reserved) * 56-X: sequence of 2, 0 terminated, strings (name, pwd) 64bit padded */ #endif /* Return strlen(str) or maxlen, whichever is shorter * Returns EINVAL if str is NULL, EFBIG if str is longer than maxlen * _len will return the result */ errno_t sss_strnlen(const char *str, size_t maxlen, size_t *len); void sss_nss_lock(void); void sss_nss_unlock(void); void sss_pam_lock(void); void sss_pam_unlock(void); void sss_nss_mc_lock(void); void sss_nss_mc_unlock(void); errno_t sss_readrep_copy_string(const char *in, size_t *offset, size_t *slen, size_t *dlen, char **out, size_t *size); #endif /* _SSSCLI_H */ sssd-1.13.4/src/sss_client/PaxHeaders.16287/sudo_testcli0000644000000000000000000000013212703463556017714 xustar0030 mtime=1460561774.988794761 30 atime=1460561776.118798593 30 ctime=1460561774.988794761 sssd-1.13.4/src/sss_client/sudo_testcli/0000755002412700241270000000000012703463556021445 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sss_client/sudo_testcli/PaxHeaders.16287/sudo_testcli.c0000644000000000000000000000007412703456111022630 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.988794761 sssd-1.13.4/src/sss_client/sudo_testcli/sudo_testcli.c0000644002412700241270000000727712703456111024314 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "sss_client/sss_cli.h" #include "sss_client/sudo/sss_sudo.h" #include "sss_client/sudo/sss_sudo_private.h" #ifndef EOK #define EOK 0 #endif void print_sss_result(struct sss_sudo_result *result); int main(int argc, char **argv) { int ret = 0; struct sss_sudo_result *result = NULL; struct passwd *passwd = NULL; const char *username = NULL; char *domainname = NULL; uid_t uid = 0; uint32_t error = 0; if (argc != 2 && argc != 3) { fprintf(stderr, "Usage: sss_sudo_cli username [uid]\n"); goto fail; } username = argv[1]; if (argc == 3) { uid = atoi(argv[2]); } else { passwd = getpwnam(username); if (passwd == NULL) { fprintf(stderr, "Unknown user\n"); goto fail; } uid = passwd->pw_uid; } /* get sss_result - it will send new query to responder */ /* get default options */ ret = sss_sudo_send_recv_defaults(uid, username, &error, &domainname, &result); if (ret != EOK) { fprintf(stderr, "sss_sudo_send_recv_defaults() failed: %s\n", strerror(ret)); goto fail; } printf("User [%s:%llu] found in domain: %s\n\n", username, (unsigned long long)uid, domainname != NULL ? domainname : ""); printf("=== Printing response data [default options] ===\n"); printf("Response code: %d\n\n", error); if (error == SSS_SUDO_ERROR_OK) { print_sss_result(result); } sss_sudo_free_result(result); result = NULL; /* get rules */ ret = sss_sudo_send_recv(uid, username, domainname, &error, &result); if (ret != EOK) { fprintf(stderr, "sss_sudo_send_recv() failed: %s\n", strerror(ret)); goto fail; } printf("\n=== Printing response data [rules] ===\n"); printf("Response code: %d\n\n", error); if (error == SSS_SUDO_ERROR_OK) { print_sss_result(result); } free(domainname); sss_sudo_free_result(result); return 0; fail: free(domainname); sss_sudo_free_result(result); return 1; } void print_sss_result(struct sss_sudo_result *result) { struct sss_sudo_rule *rule = NULL; struct sss_sudo_attr *attr = NULL; int i = 0; int j = 0; int k = 0; printf("Number of rules: %d\n", result->num_rules); for (i = 0; i < result->num_rules; i++) { rule = &result->rules[i]; printf("=== Rule %d has %d attributes\n", i, rule->num_attrs); for (j = 0; j < rule->num_attrs; j++) { attr = &rule->attrs[j]; printf(" === Attribute named %s has %d values:\n", attr->name, attr->num_values); for (k = 0; k < attr->num_values; k++) { printf(" %s\n", attr->values[k]); } } } } sssd-1.13.4/src/sss_client/PaxHeaders.16287/pam_test_client.c0000644000000000000000000000007412703456111020600 xustar0030 atime=1460561751.654715641 30 ctime=1460561774.955794649 sssd-1.13.4/src/sss_client/pam_test_client.c0000644002412700241270000000703712703456111022256 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #ifdef HAVE_SECURITY_PAM_MISC_H # include #elif defined(HAVE_SECURITY_OPENPAM_H) # include #endif #ifdef HAVE_SECURITY_PAM_MISC_H static struct pam_conv conv = { misc_conv, NULL }; #elif defined(HAVE_SECURITY_OPENPAM_H) static struct pam_conv conv = { openpam_ttyconv, NULL }; #else # error "Missing text based pam conversation function" #endif int main(int argc, char *argv[]) { pam_handle_t *pamh; char *user; char *action; int ret; if (argc == 1) { fprintf(stderr, "missing action and user name, using default\n"); action = strdup("auth"); user = strdup("dummy"); } else if (argc == 2) { fprintf(stdout, "using first argument as action and default user name\n"); action = strdup(argv[1]); user = strdup("dummy"); } else { action = strdup(argv[1]); user = strdup(argv[2]); } if (action == NULL || user == NULL) { fprintf(stderr, "Out of memory!\n"); return 1; } fprintf(stdout, "action: %s\nuser: %s\n", action,user); ret = pam_start("sss_test", user, &conv, &pamh); if (ret != PAM_SUCCESS) { fprintf(stderr, "pam_start failed: %s\n", pam_strerror(pamh, ret)); return 1; } if ( strncmp(action, "auth", 4)== 0 ) { fprintf(stdout, "testing pam_authenticate\n"); ret = pam_authenticate(pamh, 0); fprintf(stderr, "pam_authenticate: %s\n", pam_strerror(pamh, ret)); } else if ( strncmp(action, "chau", 4)== 0 ) { fprintf(stdout, "testing pam_chauthtok\n"); ret = pam_chauthtok(pamh, 0); fprintf(stderr, "pam_chauthtok: %s\n", pam_strerror(pamh, ret)); } else if ( strncmp(action, "acct", 4)== 0 ) { fprintf(stdout, "testing pam_acct_mgmt\n"); ret = pam_acct_mgmt(pamh, 0); fprintf(stderr, "pam_acct_mgmt: %s\n", pam_strerror(pamh, ret)); } else if ( strncmp(action, "setc", 4)== 0 ) { fprintf(stdout, "testing pam_setcred\n"); ret = pam_setcred(pamh, 0); fprintf(stderr, "pam_setcred: %d[%s]\n", ret, pam_strerror(pamh, ret)); } else if ( strncmp(action, "open", 4)== 0 ) { fprintf(stdout, "testing pam_open_session\n"); ret = pam_open_session(pamh, 0); fprintf(stderr, "pam_open_session: %s\n", pam_strerror(pamh, ret)); } else if ( strncmp(action, "clos", 4)== 0 ) { fprintf(stdout, "testing pam_close_session\n"); ret = pam_close_session(pamh, 0); fprintf(stderr, "pam_close_session: %s\n", pam_strerror(pamh, ret)); } else { fprintf(stderr, "unknown action\n"); } pam_end(pamh, ret); return 0; } sssd-1.13.4/src/sss_client/PaxHeaders.16287/COPYING.LESSER0000644000000000000000000000007412703456111017311 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.379792696 sssd-1.13.4/src/sss_client/COPYING.LESSER0000644002412700241270000001673312703456111020772 0ustar00jhrozekjhrozek00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. sssd-1.13.4/src/PaxHeaders.16287/python0000644000000000000000000000013212703463556014366 xustar0030 mtime=1460561774.651793619 30 atime=1460561776.118798593 30 ctime=1460561774.651793619 sssd-1.13.4/src/python/0000755002412700241270000000000012703463556016117 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/python/PaxHeaders.16287/pysss_murmur.c0000644000000000000000000000007412703456111017371 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.650793615 sssd-1.13.4/src/python/pysss_murmur.c0000644002412700241270000000456012703456111021045 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/sss_python.h" #include "util/murmurhash3.h" PyDoc_STRVAR(murmurhash3_doc, "murmurhash3(key, key_len, seed) -> 32bit integer hash\n\ \n\ Calculate the murmur hash version 3 of the first key_len bytes from key\n\ using the given seed." ); static PyObject * py_murmurhash3(PyObject *module, PyObject *args) { const char *key; long key_len; long long seed; uint32_t hash; if (!PyArg_ParseTuple(args, sss_py_const_p(char, "slL"), &key, &key_len, &seed)) { PyErr_Format(PyExc_ValueError, "Invalid argument\n"); return NULL; } if (seed > UINT32_MAX || key_len > INT_MAX || key_len < 0 || key_len > strlen(key)) { PyErr_Format(PyExc_ValueError, "Invalid value\n"); return NULL; } hash = murmurhash3(key, key_len, seed); return PyLong_FromUnsignedLong((unsigned long) hash); } static PyMethodDef methods[] = { { sss_py_const_p(char, "murmurhash3"), (PyCFunction) py_murmurhash3, METH_VARARGS, murmurhash3_doc }, { NULL,NULL, 0, NULL } }; #ifdef IS_PY3K static struct PyModuleDef pysss_murmurdef = { PyModuleDef_HEAD_INIT, "pysss_murmur", NULL, -1, methods, NULL, NULL, NULL, NULL }; PyMODINIT_FUNC PyInit_pysss_murmur(void) #else PyMODINIT_FUNC initpysss_murmur(void) #endif { PyObject *m; #ifdef IS_PY3K m = PyModule_Create(&pysss_murmurdef); #else m = Py_InitModule3(sss_py_const_p(char, "pysss_murmur"), methods, sss_py_const_p(char, "murmur hash functions")); #endif if (m == NULL) MODINITERROR; #ifdef IS_PY3K return m; #endif } sssd-1.13.4/src/python/PaxHeaders.16287/pysss_nss_idmap.c0000644000000000000000000000007412703456111020017 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.651793619 sssd-1.13.4/src/python/pysss_nss_idmap.c0000644002412700241270000002534712703456111021501 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Alexander Bokovoy Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/sss_python.h" #include "sss_client/idmap/sss_nss_idmap.h" #define SSS_NAME_KEY "name" #define SSS_SID_KEY "sid" #define SSS_ID_KEY "id" #define SSS_TYPE_KEY "type" enum lookup_type { SIDBYNAME, SIDBYID, NAMEBYSID, IDBYSID }; static int add_dict(PyObject *py_result, PyObject *key, PyObject *res_type, PyObject *res, PyObject *id_type) { int ret; PyObject *py_dict; py_dict = PyDict_New(); if (py_dict == NULL) { return ENOMEM; } ret = PyDict_SetItem(py_dict, res_type, res); if (ret != 0) { Py_XDECREF(py_dict); return ret; } ret = PyDict_SetItem(py_dict, PyBytes_FromString(SSS_TYPE_KEY), id_type); if (ret != 0) { Py_XDECREF(py_dict); return ret; } ret = PyDict_SetItem(py_result, key, py_dict); return ret; } static char *py_string_or_unicode_as_string(PyObject *inp) { PyObject *py_str = NULL; if (PyUnicode_Check(inp)) { py_str = PyUnicode_AsUTF8String(inp); } else if (PyBytes_Check(inp)) { py_str = inp; } else { PyErr_Format(PyExc_TypeError, "input must be unicode or a string"); return NULL; } return PyBytes_AS_STRING(py_str); } static int do_getsidbyname(PyObject *py_result, PyObject *py_name) { int ret; const char *name; char *sid = NULL; enum sss_id_type id_type; name = py_string_or_unicode_as_string(py_name); if (name == NULL) { return EINVAL; } ret = sss_nss_getsidbyname(name, &sid, &id_type); if (ret == 0) { ret = add_dict(py_result, py_name, PyBytes_FromString(SSS_SID_KEY), PyUnicode_FromString(sid), PYNUMBER_FROMLONG(id_type)); } free(sid); return ret; } static int do_getnamebysid(PyObject *py_result, PyObject *py_sid) { int ret; const char *sid; char *name = NULL; enum sss_id_type id_type; sid = py_string_or_unicode_as_string(py_sid); if (sid == NULL) { return EINVAL; } ret = sss_nss_getnamebysid(sid, &name, &id_type); if (ret == 0) { ret = add_dict(py_result, py_sid, PyBytes_FromString(SSS_NAME_KEY), PyUnicode_FromString(name), PYNUMBER_FROMLONG(id_type)); } free(name); return ret; } static int do_getsidbyid(PyObject *py_result, PyObject *py_id) { long id; const char *id_str; char *endptr; char *sid = NULL; int ret; enum sss_id_type id_type; #ifndef IS_PY3K if (PyInt_Check(py_id)) { id = PyInt_AS_LONG(py_id); } else #endif if (PyLong_Check(py_id)) { id = PyLong_AsLong(py_id); } else { id_str = py_string_or_unicode_as_string(py_id); if (id_str == NULL) { return EINVAL; } errno = 0; id = strtol(id_str, &endptr, 10); if (errno != 0 || *endptr != '\0') { return EINVAL; } } if (id < 0 || id > UINT32_MAX) { return EINVAL; } ret = sss_nss_getsidbyid((uint32_t) id, &sid, &id_type); if (ret == 0) { ret = add_dict(py_result, py_id, PyBytes_FromString(SSS_SID_KEY), PyUnicode_FromString(sid), PYNUMBER_FROMLONG(id_type)); } free(sid); return ret; } static int do_getidbysid(PyObject *py_result, PyObject *py_sid) { const char *sid; uint32_t id; enum sss_id_type id_type; int ret; sid = py_string_or_unicode_as_string(py_sid); if (sid == NULL) { return EINVAL; } ret = sss_nss_getidbysid(sid, &id, &id_type); if (ret == 0) { ret = add_dict(py_result, py_sid, PyBytes_FromString(SSS_ID_KEY), PYNUMBER_FROMLONG(id), PYNUMBER_FROMLONG(id_type)); } return ret; } static int do_lookup(enum lookup_type type, PyObject *py_result, PyObject *py_inp) { switch(type) { case SIDBYNAME: return do_getsidbyname(py_result, py_inp); break; case NAMEBYSID: return do_getnamebysid(py_result, py_inp); break; case SIDBYID: return do_getsidbyid(py_result, py_inp); break; case IDBYSID: return do_getidbysid(py_result, py_inp); break; default: return ENOSYS; } return ENOSYS; } static PyObject *check_args(enum lookup_type type, PyObject *args) { PyObject *obj, *py_value; int ret; Py_ssize_t len, i; PyObject *py_result; if (!PyArg_ParseTuple(args, sss_py_const_p(char, "O"), &obj)) { PyErr_Format(PyExc_ValueError, "Unable to retrieve argument\n"); return NULL; } if (!(PyList_Check(obj) || PyTuple_Check(obj) || PyBytes_Check(obj) || PyUnicode_Check(obj) || (type == SIDBYID && (PYNUMBER_CHECK(obj))))) { PyErr_Format(PyExc_ValueError, "Only string, long or list or tuples of them " \ "are accepted\n"); return NULL; } py_result = PyDict_New(); Py_XINCREF(py_result); if (py_result == NULL) { PyErr_Format(PyExc_MemoryError, "Unable to allocate resulting dictionary\n"); return NULL; } if (PyList_Check(obj) || PyTuple_Check(obj)) { len = PySequence_Size(obj); for(i=0; i < len; i++) { py_value = PySequence_GetItem(obj, i); if ((py_value != NULL) && (PyBytes_Check(py_value) || PyUnicode_Check(py_value) || (type == SIDBYID && PYNUMBER_CHECK(py_value)))) { ret = do_lookup(type, py_result, py_value); if (ret != 0) { /* Skip this name */ continue; } } } } else { ret = do_lookup(type, py_result, obj); switch (ret) { case 0: case ENOENT: /* nothing found, return empty dict */ break; case EINVAL: PyErr_Format(PyExc_ValueError, "Unable to retrieve argument\n"); Py_XDECREF(py_result); return NULL; break; default: PyErr_Format(PyExc_IOError, "Operation not supported\n"); Py_XDECREF(py_result); return NULL; } } Py_XDECREF(py_result); return py_result; } PyDoc_STRVAR(getsidbyname_doc, "getsidbyname(name or list/tuple of names) -> dict(name => dict(results))\n\ \n\ Returns a dictionary with a dictonary of results for each given name.\n\ The result dictonary contain the SID and the type of the object which can be\n\ accessed with the key constants SID_KEY and TYPE_KEY, respectively.\n\ \n\ The return type can be one of the following constants:\n\ - ID_NOT_SPECIFIED\n\ - ID_USER\n\ - ID_GROUP\n\ - ID_BOTH" ); static PyObject * py_getsidbyname(PyObject *module, PyObject *args) { return check_args(SIDBYNAME, args); } PyDoc_STRVAR(getsidbyid_doc, "getsidbyid(id or list/tuple of id) -> dict(id => dict(results))\n\ \n\ Returns a dictionary with a dictonary of results for each given POSIX ID.\n\ The result dictonary contain the SID and the type of the object which can be\n\ accessed with the key constants SID_KEY and TYPE_KEY, respectively." ); static PyObject * py_getsidbyid(PyObject *module, PyObject *args) { return check_args(SIDBYID, args); } PyDoc_STRVAR(getnamebysid_doc, "getnamebysid(sid or list/tuple of sid) -> dict(sid => dict(results))\n\ \n\ Returns a dictionary with a dictonary of results for each given SID.\n\ The result dictonary contain the name and the type of the object which can be\n\ accessed with the key constants NAME_KEY and TYPE_KEY, respectively.\n\ \n\ NOTE: getnamebysid currently works only with id_provider set as \"ad\" or \"ipa\"" ); static PyObject * py_getnamebysid(PyObject *module, PyObject *args) { return check_args(NAMEBYSID, args); } PyDoc_STRVAR(getidbysid_doc, "getidbysid(sid) -> POSIX ID\n\ \n\ Returns the POSIX ID of the object with the given SID." "getidbysid(sid or list/tuple of sid) -> dict(sid => dict(results))\n\ \n\ Returns a dictionary with a dictonary of results for each given SID.\n\ The result dictonary contain the POSIX ID and the type of the object which\n\ can be accessed with the key constants ID_KEY and TYPE_KEY, respectively." ); static PyObject * py_getidbysid(PyObject *module, PyObject *args) { return check_args(IDBYSID, args); } static PyMethodDef methods[] = { { sss_py_const_p(char, "getsidbyname"), (PyCFunction) py_getsidbyname, METH_VARARGS, getsidbyname_doc }, { sss_py_const_p(char, "getsidbyid"), (PyCFunction) py_getsidbyid, METH_VARARGS, getsidbyid_doc }, { sss_py_const_p(char, "getnamebysid"), (PyCFunction) py_getnamebysid, METH_VARARGS, getnamebysid_doc }, { sss_py_const_p(char, "getidbysid"), (PyCFunction) py_getidbysid, METH_VARARGS, getidbysid_doc }, { NULL,NULL, 0, NULL } }; #ifdef IS_PY3K static struct PyModuleDef pysss_nss_idmap_def = { PyModuleDef_HEAD_INIT, "pysss_nss_idmap", NULL, -1, methods, NULL, NULL, NULL, NULL }; PyMODINIT_FUNC PyInit_pysss_nss_idmap(void) #else PyMODINIT_FUNC initpysss_nss_idmap(void) #endif { PyObject *module; #ifdef IS_PY3K module = PyModule_Create(&pysss_nss_idmap_def); #else module = Py_InitModule3(sss_py_const_p(char, "pysss_nss_idmap"), methods, sss_py_const_p(char, "SSSD ID-mapping functions")); #endif if (module == NULL) MODINITERROR; PyModule_AddIntConstant(module, "ID_NOT_SPECIFIED", SSS_ID_TYPE_NOT_SPECIFIED); PyModule_AddIntConstant(module, "ID_USER", SSS_ID_TYPE_UID); PyModule_AddIntConstant(module, "ID_GROUP", SSS_ID_TYPE_GID); PyModule_AddIntConstant(module, "ID_BOTH", SSS_ID_TYPE_BOTH); PyModule_AddStringConstant(module, "SID_KEY", SSS_SID_KEY); PyModule_AddStringConstant(module, "NAME_KEY", SSS_NAME_KEY); PyModule_AddStringConstant(module, "ID_KEY", SSS_ID_KEY); PyModule_AddStringConstant(module, "TYPE_KEY", SSS_TYPE_KEY); #ifdef IS_PY3K return module; #endif } sssd-1.13.4/src/python/PaxHeaders.16287/pyhbac.c0000644000000000000000000000007412703456111016047 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.642793588 sssd-1.13.4/src/python/pyhbac.c0000644002412700241270000015327512703456111017533 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/util.h" #include "util/sss_python.h" #include "providers/ipa/ipa_hbac.h" #define PYTHON_MODULE_NAME "pyhbac" #ifndef PYHBAC_ENCODING #define PYHBAC_ENCODING "UTF-8" #endif #define PYHBAC_ENCODING_ERRORS "strict" #define CHECK_ATTRIBUTE_DELETE(attr, attrname) do { \ if (attr == NULL) { \ PyErr_Format(PyExc_TypeError, \ "Cannot delete the %s attribute", \ attrname); \ return -1; \ } \ } while(0) static PyObject *PyExc_HbacError; /* ==================== Utility functions ========================*/ static char * py_strdup(const char *string) { char *copy; copy = PyMem_New(char, strlen(string)+1); if (copy == NULL) { PyErr_NoMemory(); return NULL; } return strcpy(copy, string); } static char * py_strcat_realloc(char *first, const char *second) { char *new_first; new_first = PyMem_Realloc(first, strlen(first) + strlen(second) + 1); if (new_first == NULL) { PyErr_NoMemory(); return NULL; } return strcat(new_first, second); } static PyObject * get_utf8_string(PyObject *obj, const char *attrname) { const char *a = attrname ? attrname : "attribute"; PyObject *obj_utf8 = NULL; if (PyBytes_Check(obj)) { obj_utf8 = obj; Py_INCREF(obj_utf8); /* Make sure we can DECREF later */ } else if (PyUnicode_Check(obj)) { if ((obj_utf8 = PyUnicode_AsUTF8String(obj)) == NULL) { return NULL; } } else { PyErr_Format(PyExc_TypeError, "%s must be a string", a); return NULL; } return obj_utf8; } static void free_string_list(const char **list) { int i; if (!list) return; for (i=0; list[i]; i++) { PyMem_Free(discard_const_p(char, list[i])); } PyMem_Free(list); } static const char ** sequence_as_string_list(PyObject *seq, const char *paramname) { const char *p = paramname ? paramname : "attribute values"; const char **ret; PyObject *utf_item; int i; Py_ssize_t len; PyObject *item; if (!PySequence_Check(seq)) { PyErr_Format(PyExc_TypeError, "The object must be a sequence\n"); return NULL; } len = PySequence_Size(seq); if (len == -1) return NULL; ret = PyMem_New(const char *, (len+1)); if (!ret) { PyErr_NoMemory(); return NULL; } for (i = 0; i < len; i++) { item = PySequence_GetItem(seq, i); if (item == NULL) { break; } utf_item = get_utf8_string(item, p); if (utf_item == NULL) { Py_DECREF(item); return NULL; } ret[i] = py_strdup(PyBytes_AsString(utf_item)); Py_DECREF(utf_item); if (!ret[i]) { Py_DECREF(item); return NULL; } Py_DECREF(item); } ret[i] = NULL; return ret; } static bool verify_sequence(PyObject *seq, const char *attrname) { const char *a = attrname ? attrname : "attribute"; if (!PySequence_Check(seq)) { PyErr_Format(PyExc_TypeError, "%s must be a sequence", a); return false; } return true; } static int pyobject_to_category(PyObject *o) { long c; c = PYNUMBER_ASLONG(o); if (c == -1 && PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "Invalid type for category element - must be an int\n"); return -1; } switch (c) { case HBAC_CATEGORY_NULL: case HBAC_CATEGORY_ALL: return c; } PyErr_Format(PyExc_ValueError, "Invalid value %ld for category\n", c); return -1; } static uint32_t native_category(PyObject *pycat) { PyObject *iterator; PyObject *item; uint32_t cat; int ret; iterator = PyObject_GetIter(pycat); if (iterator == NULL) { PyErr_Format(PyExc_RuntimeError, "Cannot iterate category\n"); return -1; } cat = 0; while ((item = PyIter_Next(iterator))) { ret = pyobject_to_category(item); Py_DECREF(item); if (ret == -1) { Py_DECREF(iterator); return -1; } cat |= ret; } Py_DECREF(iterator); return cat; } static char * str_concat_sequence(PyObject *seq, const char *delim) { Py_ssize_t size; Py_ssize_t i; PyObject *item; char *s = NULL; char *part; size = PySequence_Size(seq); if (size == 0) { s = py_strdup(""); if (s == NULL) { return NULL; } return s; } for (i=0; i < size; i++) { item = PySequence_GetItem(seq, i); if (item == NULL) goto fail; #ifdef IS_PY3K part = PyUnicode_AsUTF8(item); #else part = PyString_AsString(item); #endif if (s) { s = py_strcat_realloc(s, delim); if (s == NULL) goto fail; s = py_strcat_realloc(s, part); if (s == NULL) goto fail; } else { s = py_strdup(part); if (s == NULL) goto fail; } Py_DECREF(item); } return s; fail: Py_XDECREF(item); PyMem_Free(s); return NULL; } /* ================= HBAC Exception handling =====================*/ static void set_hbac_exception(PyObject *exc, struct hbac_info *error) { PyObject *obj; obj = Py_BuildValue(sss_py_const_p(char, "(i,s)"), error->code, error->rule_name ? error->rule_name : "no rule"); PyErr_SetObject(exc, obj); Py_XDECREF(obj); } /* ==================== HBAC Rule Element ========================*/ typedef struct { PyObject_HEAD PyObject *category; PyObject *names; PyObject *groups; } HbacRuleElement; static PyObject * HbacRuleElement_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { HbacRuleElement *self; self = (HbacRuleElement *) type->tp_alloc(type, 0); if (self == NULL) { PyErr_NoMemory(); return NULL; } self->category = PySet_New(NULL); self->names = PyList_New(0); self->groups = PyList_New(0); if (!self->names || !self->groups || !self->category) { Py_DECREF(self); PyErr_NoMemory(); return NULL; } return (PyObject *) self; } static int HbacRuleElement_clear(HbacRuleElement *self) { Py_CLEAR(self->names); Py_CLEAR(self->groups); Py_CLEAR(self->category); return 0; } static void HbacRuleElement_dealloc(HbacRuleElement *self) { HbacRuleElement_clear(self); Py_TYPE(self)->tp_free((PyObject*) self); } static int HbacRuleElement_traverse(HbacRuleElement *self, visitproc visit, void *arg) { Py_VISIT(self->groups); Py_VISIT(self->names); Py_VISIT(self->category); return 0; } static int hbac_rule_element_set_names(HbacRuleElement *self, PyObject *names, void *closure); static int hbac_rule_element_set_groups(HbacRuleElement *self, PyObject *groups, void *closure); static int hbac_rule_element_set_category(HbacRuleElement *self, PyObject *category, void *closure); static int HbacRuleElement_init(HbacRuleElement *self, PyObject *args, PyObject *kwargs) { const char * const kwlist[] = { "names", "groups", "category", NULL }; PyObject *names = NULL; PyObject *groups = NULL; PyObject *category = NULL; PyObject *tmp = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, sss_py_const_p(char, "|OOO"), discard_const_p(char *, kwlist), &names, &groups, &category)) { return -1; } if (names) { if (hbac_rule_element_set_names(self, names, NULL) != 0) { return -1; } } if (groups) { if (hbac_rule_element_set_groups(self, groups, NULL) != 0) { return -1; } } if (category) { if (hbac_rule_element_set_category(self, category, NULL) != 0) { return -1; } } else { tmp = PYNUMBER_FROMLONG(HBAC_CATEGORY_NULL); if (!tmp) { return -1; } if (PySet_Add(self->category, tmp) != 0) { Py_DECREF(tmp); return -1; } } return 0; } static int hbac_rule_element_set_names(HbacRuleElement *self, PyObject *names, void *closure) { CHECK_ATTRIBUTE_DELETE(names, "names"); if (!verify_sequence(names, "names")) { return -1; } SAFE_SET(self->names, names); return 0; } static PyObject * hbac_rule_element_get_names(HbacRuleElement *self, void *closure) { Py_INCREF(self->names); return self->names; } static int hbac_rule_element_set_groups(HbacRuleElement *self, PyObject *groups, void *closure) { CHECK_ATTRIBUTE_DELETE(groups, "groups"); if (!verify_sequence(groups, "groups")) { return -1; } SAFE_SET(self->groups, groups); return 0; } static PyObject * hbac_rule_element_get_groups(HbacRuleElement *self, void *closure) { Py_INCREF(self->groups); return self->groups; } static int hbac_rule_element_set_category(HbacRuleElement *self, PyObject *category, void *closure) { PyObject *iterator; PyObject *item; int ret; CHECK_ATTRIBUTE_DELETE(category, "category"); if (!PySet_Check(category)) { PyErr_Format(PyExc_TypeError, "The category must be a set type\n"); return -1; } /* Check the values, too */ iterator = PyObject_GetIter(category); if (iterator == NULL) { PyErr_Format(PyExc_RuntimeError, "Cannot iterate a set?\n"); return -1; } while ((item = PyIter_Next(iterator))) { ret = pyobject_to_category(item); Py_DECREF(item); if (ret == -1) { Py_DECREF(iterator); return -1; } } SAFE_SET(self->category, category); Py_DECREF(iterator); return 0; } static PyObject * hbac_rule_element_get_category(HbacRuleElement *self, void *closure) { Py_INCREF(self->category); return self->category; } static PyObject * HbacRuleElement_repr(HbacRuleElement *self) { char *strnames = NULL; char *strgroups = NULL; uint32_t category; PyObject *o, *format, *args; format = PyUnicode_FromString(""); if (format == NULL) { return NULL; } strnames = str_concat_sequence(self->names, discard_const_p(char, ",")); strgroups = str_concat_sequence(self->groups, discard_const_p(char, ",")); category = native_category(self->category); if (strnames == NULL || strgroups == NULL || category == -1) { PyMem_Free(strnames); PyMem_Free(strgroups); Py_DECREF(format); return NULL; } args = Py_BuildValue(sss_py_const_p(char, "Kss"), (unsigned long long ) category, strnames, strgroups); if (args == NULL) { PyMem_Free(strnames); PyMem_Free(strgroups); Py_DECREF(format); return NULL; } o = PyUnicode_Format(format, args); PyMem_Free(strnames); PyMem_Free(strgroups); Py_DECREF(format); Py_DECREF(args); return o; } PyDoc_STRVAR(HbacRuleElement_names__doc__, "(sequence of strings) A list of object names this element applies to"); PyDoc_STRVAR(HbacRuleElement_groups__doc__, "(sequence of strings) A list of group names this element applies to"); PyDoc_STRVAR(HbacRuleElement_category__doc__, "(set) A set of categories this rule falls into"); static PyGetSetDef py_hbac_rule_element_getset[] = { { discard_const_p(char, "names"), (getter) hbac_rule_element_get_names, (setter) hbac_rule_element_set_names, HbacRuleElement_names__doc__, NULL }, { discard_const_p(char, "groups"), (getter) hbac_rule_element_get_groups, (setter) hbac_rule_element_set_groups, HbacRuleElement_groups__doc__, NULL }, { discard_const_p(char, "category"), (getter) hbac_rule_element_get_category, (setter) hbac_rule_element_set_category, HbacRuleElement_category__doc__, NULL }, { NULL, 0, 0, 0, NULL } /* Sentinel */ }; PyDoc_STRVAR(HbacRuleElement__doc__, "IPA HBAC Rule Element\n\n" "HbacRuleElement() -> new empty rule element\n" "HbacRuleElement([names], [groups], [category]) -> optionally, provide\n" "names and/or groups and/or category\n"); static PyTypeObject pyhbac_hbacrule_element_type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = sss_py_const_p(char, "pyhbac.HbacRuleElement"), .tp_basicsize = sizeof(HbacRuleElement), .tp_new = HbacRuleElement_new, .tp_dealloc = (destructor) HbacRuleElement_dealloc, .tp_traverse = (traverseproc) HbacRuleElement_traverse, .tp_clear = (inquiry) HbacRuleElement_clear, .tp_init = (initproc) HbacRuleElement_init, .tp_repr = (reprfunc) HbacRuleElement_repr, .tp_getset = py_hbac_rule_element_getset, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, .tp_doc = HbacRuleElement__doc__ }; static void free_hbac_rule_element(struct hbac_rule_element *el) { if (!el) return; free_string_list(el->names); free_string_list(el->groups); PyMem_Free(el); } struct hbac_rule_element * HbacRuleElement_to_native(HbacRuleElement *pyel) { struct hbac_rule_element *el = NULL; /* check the type, None would wreak havoc here because for some reason * it would pass the sequence check */ if (!PyObject_IsInstance((PyObject *) pyel, (PyObject *) &pyhbac_hbacrule_element_type)) { PyErr_Format(PyExc_TypeError, "The element must be of type HbacRuleElement\n"); goto fail; } el = PyMem_Malloc(sizeof(struct hbac_rule_element)); if (!el) { PyErr_NoMemory(); goto fail; } el->category = native_category(pyel->category); el->names = sequence_as_string_list(pyel->names, "names"); el->groups = sequence_as_string_list(pyel->groups, "groups"); if (!el->names || !el->groups || el->category == -1) { goto fail; } return el; fail: free_hbac_rule_element(el); return NULL; } /* ==================== HBAC Rule ========================*/ typedef struct { PyObject_HEAD PyObject *name; bool enabled; HbacRuleElement *users; HbacRuleElement *services; HbacRuleElement *targethosts; HbacRuleElement *srchosts; } HbacRuleObject; static void free_hbac_rule(struct hbac_rule *rule); static struct hbac_rule * HbacRule_to_native(HbacRuleObject *pyrule); static PyObject * HbacRule_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { HbacRuleObject *self; self = (HbacRuleObject *) type->tp_alloc(type, 0); if (self == NULL) { PyErr_NoMemory(); return NULL; } self->name = PyUnicode_FromString(""); if (self->name == NULL) { Py_DECREF(self); PyErr_NoMemory(); return NULL; } self->enabled = false; self->services = (HbacRuleElement *) HbacRuleElement_new( &pyhbac_hbacrule_element_type, NULL, NULL); self->users = (HbacRuleElement *) HbacRuleElement_new( &pyhbac_hbacrule_element_type, NULL, NULL); self->targethosts = (HbacRuleElement *) HbacRuleElement_new( &pyhbac_hbacrule_element_type, NULL, NULL); self->srchosts = (HbacRuleElement *) HbacRuleElement_new( &pyhbac_hbacrule_element_type, NULL, NULL); if (self->services == NULL || self->users == NULL || self->targethosts == NULL || self->srchosts == NULL) { Py_XDECREF(self->services); Py_XDECREF(self->users); Py_XDECREF(self->targethosts); Py_XDECREF(self->srchosts); Py_DECREF(self->name); Py_DECREF(self); PyErr_NoMemory(); return NULL; } return (PyObject *) self; } static int HbacRule_clear(HbacRuleObject *self) { Py_CLEAR(self->name); Py_CLEAR(self->services); Py_CLEAR(self->users); Py_CLEAR(self->targethosts); Py_CLEAR(self->srchosts); return 0; } static void HbacRule_dealloc(HbacRuleObject *self) { HbacRule_clear(self); Py_TYPE(self)->tp_free((PyObject*) self); } static int HbacRule_traverse(HbacRuleObject *self, visitproc visit, void *arg) { Py_VISIT((PyObject *) self->name); Py_VISIT((PyObject *) self->services); Py_VISIT((PyObject *) self->users); Py_VISIT((PyObject *) self->targethosts); Py_VISIT((PyObject *) self->srchosts); return 0; } static int hbac_rule_set_enabled(HbacRuleObject *self, PyObject *enabled, void *closure); static int hbac_rule_set_name(HbacRuleObject *self, PyObject *name, void *closure); static int HbacRule_init(HbacRuleObject *self, PyObject *args, PyObject *kwargs) { const char * const kwlist[] = { "name", "enabled", NULL }; PyObject *name = NULL; PyObject *empty_tuple = NULL; PyObject *enabled=NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, sss_py_const_p(char, "O|O"), discard_const_p(char *, kwlist), &name, &enabled)) { return -1; } if (enabled) { if (hbac_rule_set_enabled(self, enabled, NULL) == -1) { return -1; } } if (hbac_rule_set_name(self, name, NULL) == -1) { return -1; } empty_tuple = PyTuple_New(0); if (!empty_tuple) { return -1; } if (HbacRuleElement_init(self->users, empty_tuple, NULL) == -1 || HbacRuleElement_init(self->services, empty_tuple, NULL) == -1 || HbacRuleElement_init(self->targethosts, empty_tuple, NULL) == -1 || HbacRuleElement_init(self->srchosts, empty_tuple, NULL) == -1) { Py_DECREF(empty_tuple); return -1; } Py_DECREF(empty_tuple); return 0; } static int hbac_rule_set_enabled(HbacRuleObject *self, PyObject *enabled, void *closure) { CHECK_ATTRIBUTE_DELETE(enabled, "enabled"); if (PyBytes_Check(enabled) || PyUnicode_Check(enabled)) { PyObject *utf8_str; char *str; utf8_str = get_utf8_string(enabled, "enabled"); if (!utf8_str) return -1; str = PyBytes_AsString(utf8_str); if (!str) { Py_DECREF(utf8_str); return -1; } if (strcasecmp(str, "true") == 0) { self->enabled = true; } else if (strcasecmp(str, "false") == 0) { self->enabled = false; } else { PyErr_Format(PyExc_ValueError, "enabled only accepts 'true' of 'false' " "string literals"); Py_DECREF(utf8_str); return -1; } Py_DECREF(utf8_str); return 0; } else if (PyBool_Check(enabled) == true) { self->enabled = (enabled == Py_True); return 0; } else if (PYNUMBER_CHECK(enabled)) { switch(PYNUMBER_ASLONG(enabled)) { case 0: self->enabled = false; break; case 1: self->enabled = true; break; default: PyErr_Format(PyExc_ValueError, "enabled only accepts '0' of '1' " "integer constants"); return -1; } return 0; } PyErr_Format(PyExc_TypeError, "enabled must be a boolean, an integer " "1 or 0 or a string constant true/false"); return -1; } static PyObject * hbac_rule_get_enabled(HbacRuleObject *self, void *closure) { if (self->enabled) { Py_RETURN_TRUE; } Py_RETURN_FALSE; } static int hbac_rule_set_name(HbacRuleObject *self, PyObject *name, void *closure) { CHECK_ATTRIBUTE_DELETE(name, "name"); if (!PyBytes_Check(name) && !PyUnicode_Check(name)) { PyErr_Format(PyExc_TypeError, "name must be a string or Unicode"); return -1; } SAFE_SET(self->name, name); return 0; } static PyObject * hbac_rule_get_name(HbacRuleObject *self, void *closure) { if (PyUnicode_Check(self->name)) { Py_INCREF(self->name); return self->name; } else if (PyBytes_Check(self->name)) { return PyUnicode_FromEncodedObject(self->name, PYHBAC_ENCODING, PYHBAC_ENCODING_ERRORS); } /* setter does typechecking but let us be paranoid */ PyErr_Format(PyExc_TypeError, "name must be a string or Unicode"); return NULL; } static PyObject * HbacRule_repr(HbacRuleObject *self) { PyObject *users_repr; PyObject *services_repr; PyObject *targethosts_repr; PyObject *srchosts_repr; PyObject *o, *format, *args; format = PyUnicode_FromString(""); if (format == NULL) { return NULL; } users_repr = HbacRuleElement_repr(self->users); services_repr = HbacRuleElement_repr(self->services); targethosts_repr = HbacRuleElement_repr(self->targethosts); srchosts_repr = HbacRuleElement_repr(self->srchosts); if (users_repr == NULL || services_repr == NULL || targethosts_repr == NULL || srchosts_repr == NULL) { Py_XDECREF(users_repr); Py_XDECREF(services_repr); Py_XDECREF(targethosts_repr); Py_XDECREF(srchosts_repr); Py_DECREF(format); return NULL; } args = Py_BuildValue(sss_py_const_p(char, "OiOOOO"), self->name, self->enabled, users_repr, services_repr, targethosts_repr, srchosts_repr); if (args == NULL) { Py_DECREF(users_repr); Py_DECREF(services_repr); Py_DECREF(targethosts_repr); Py_DECREF(srchosts_repr); Py_DECREF(format); return NULL; } o = PyUnicode_Format(format, args); Py_DECREF(users_repr); Py_DECREF(services_repr); Py_DECREF(targethosts_repr); Py_DECREF(srchosts_repr); Py_DECREF(format); Py_DECREF(args); return o; } static PyObject * py_hbac_rule_validate(HbacRuleObject *self, PyObject *args) { struct hbac_rule *rule; bool is_valid; uint32_t missing; uint32_t attr; PyObject *ret = NULL; PyObject *py_is_valid = NULL; PyObject *py_missing = NULL; PyObject *py_attr = NULL; rule = HbacRule_to_native(self); if (!rule) { /* Make sure there is at least a generic exception */ if (!PyErr_Occurred()) { PyErr_Format(PyExc_IOError, "Could not convert HbacRule to native type\n"); } goto fail; } is_valid = hbac_rule_is_complete(rule, &missing); free_hbac_rule(rule); ret = PyTuple_New(2); if (!ret) { PyErr_NoMemory(); goto fail; } py_is_valid = PyBool_FromLong(is_valid); py_missing = PySet_New(NULL); if (!py_missing || !py_is_valid) { PyErr_NoMemory(); goto fail; } for (attr = HBAC_RULE_ELEMENT_USERS; attr <= HBAC_RULE_ELEMENT_SOURCEHOSTS; attr <<= 1) { if (!(missing & attr)) continue; py_attr = PYNUMBER_FROMLONG(attr); if (!py_attr) { PyErr_NoMemory(); goto fail; } if (PySet_Add(py_missing, py_attr) != 0) { /* If the set-add succeeded, it would steal the reference */ Py_DECREF(py_attr); goto fail; } } PyTuple_SET_ITEM(ret, 0, py_is_valid); PyTuple_SET_ITEM(ret, 1, py_missing); return ret; fail: Py_XDECREF(ret); Py_XDECREF(py_missing); Py_XDECREF(py_is_valid); return NULL; } PyDoc_STRVAR(py_hbac_rule_validate__doc__, "validate() -> (valid, missing)\n\n" "Validate an HBAC rule\n" "Returns a tuple of (bool, set). The boolean value describes whether\n" "the rule is valid. If it is False, then the set lists all the missing " "rule elements as HBAC_RULE_ELEMENT_* constants\n"); static PyMethodDef py_hbac_rule_methods[] = { { sss_py_const_p(char, "validate"), (PyCFunction) py_hbac_rule_validate, METH_VARARGS, py_hbac_rule_validate__doc__, }, { NULL, NULL, 0, NULL } /* Sentinel */ }; PyDoc_STRVAR(HbacRuleObject_users__doc__, "(HbacRuleElement) Users and user groups for which this rule applies"); PyDoc_STRVAR(HbacRuleObject_services__doc__, "(HbacRuleElement) Services and service groups for which this rule applies"); PyDoc_STRVAR(HbacRuleObject_targethosts__doc__, "(HbacRuleElement) Target hosts for which this rule applies"); PyDoc_STRVAR(HbacRuleObject_srchosts__doc__, "(HbacRuleElement) Source hosts for which this rule applies"); static PyMemberDef py_hbac_rule_members[] = { { discard_const_p(char, "users"), T_OBJECT_EX, offsetof(HbacRuleObject, users), 0, HbacRuleObject_users__doc__ }, { discard_const_p(char, "services"), T_OBJECT_EX, offsetof(HbacRuleObject, services), 0, HbacRuleObject_services__doc__ }, { discard_const_p(char, "targethosts"), T_OBJECT_EX, offsetof(HbacRuleObject, targethosts), 0, HbacRuleObject_targethosts__doc__}, { discard_const_p(char, "srchosts"), T_OBJECT_EX, offsetof(HbacRuleObject, srchosts), 0, HbacRuleObject_srchosts__doc__}, { NULL, 0, 0, 0, NULL } /* Sentinel */ }; PyDoc_STRVAR(HbacRuleObject_enabled__doc__, "(bool) Is the rule enabled"); PyDoc_STRVAR(HbacRuleObject_name__doc__, "(string) The name of the rule"); static PyGetSetDef py_hbac_rule_getset[] = { { discard_const_p(char, "enabled"), (getter) hbac_rule_get_enabled, (setter) hbac_rule_set_enabled, HbacRuleObject_enabled__doc__, NULL }, { discard_const_p(char, "name"), (getter) hbac_rule_get_name, (setter) hbac_rule_set_name, HbacRuleObject_name__doc__, NULL }, {NULL, 0, 0, 0, NULL} /* Sentinel */ }; PyDoc_STRVAR(HbacRuleObject__doc__, "IPA HBAC Rule\n\n" "HbacRule(name, [enabled]) -> instantiate an empty rule, optionally\n" "specify whether it is enabled. Rules are created disabled by default and\n" "contain empty HbacRuleElement instances in services, users, targethosts\n" "and srchosts attributes.\n"); static PyTypeObject pyhbac_hbacrule_type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = sss_py_const_p(char, "pyhbac.HbacRule"), .tp_basicsize = sizeof(HbacRuleObject), .tp_new = HbacRule_new, .tp_dealloc = (destructor) HbacRule_dealloc, .tp_traverse = (traverseproc) HbacRule_traverse, .tp_clear = (inquiry) HbacRule_clear, .tp_init = (initproc) HbacRule_init, .tp_repr = (reprfunc) HbacRule_repr, .tp_members = py_hbac_rule_members, .tp_methods = py_hbac_rule_methods, .tp_getset = py_hbac_rule_getset, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, .tp_doc = HbacRuleObject__doc__ }; static void free_hbac_rule(struct hbac_rule *rule) { if (!rule) return; free_hbac_rule_element(rule->services); free_hbac_rule_element(rule->users); free_hbac_rule_element(rule->targethosts); free_hbac_rule_element(rule->srchosts); PyMem_Free(discard_const_p(char, rule->name)); PyMem_Free(rule); } static struct hbac_rule * HbacRule_to_native(HbacRuleObject *pyrule) { struct hbac_rule *rule = NULL; PyObject *utf_name; rule = PyMem_Malloc(sizeof(struct hbac_rule)); if (!rule) { PyErr_NoMemory(); goto fail; } if (!PyObject_IsInstance((PyObject *) pyrule, (PyObject *) &pyhbac_hbacrule_type)) { PyErr_Format(PyExc_TypeError, "The rule must be of type HbacRule\n"); goto fail; } utf_name = get_utf8_string(pyrule->name, "name"); if (utf_name == NULL) { return NULL; } rule->name = py_strdup(PyBytes_AsString(utf_name)); Py_DECREF(utf_name); if (rule->name == NULL) { goto fail; } rule->services = HbacRuleElement_to_native(pyrule->services); rule->users = HbacRuleElement_to_native(pyrule->users); rule->targethosts = HbacRuleElement_to_native(pyrule->targethosts); rule->srchosts = HbacRuleElement_to_native(pyrule->srchosts); if (!rule->services || !rule->users || !rule->targethosts || !rule->srchosts) { goto fail; } rule->enabled = pyrule->enabled; return rule; fail: free_hbac_rule(rule); return NULL; } /* ==================== HBAC Request Element ========================*/ typedef struct { PyObject_HEAD PyObject *name; PyObject *groups; } HbacRequestElement; static PyObject * HbacRequestElement_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { HbacRequestElement *self; self = (HbacRequestElement *) type->tp_alloc(type, 0); if (self == NULL) { PyErr_NoMemory(); return NULL; } self->name = PyUnicode_FromString(""); if (self->name == NULL) { PyErr_NoMemory(); Py_DECREF(self); return NULL; } self->groups = PyList_New(0); if (self->groups == NULL) { Py_DECREF(self->name); Py_DECREF(self); PyErr_NoMemory(); return NULL; } return (PyObject *) self; } static int HbacRequestElement_clear(HbacRequestElement *self) { Py_CLEAR(self->name); Py_CLEAR(self->groups); return 0; } static void HbacRequestElement_dealloc(HbacRequestElement *self) { HbacRequestElement_clear(self); Py_TYPE(self)->tp_free((PyObject*) self); } static int HbacRequestElement_traverse(HbacRequestElement *self, visitproc visit, void *arg) { Py_VISIT(self->name); Py_VISIT(self->groups); return 0; } static int hbac_request_element_set_groups(HbacRequestElement *self, PyObject *groups, void *closure); static int hbac_request_element_set_name(HbacRequestElement *self, PyObject *name, void *closure); static int HbacRequestElement_init(HbacRequestElement *self, PyObject *args, PyObject *kwargs) { const char * const kwlist[] = { "name", "groups", NULL }; PyObject *name = NULL; PyObject *groups = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, sss_py_const_p(char, "|OO"), discard_const_p(char *, kwlist), &name, &groups)) { return -1; } if (name) { if (hbac_request_element_set_name(self, name, NULL) != 0) { return -1; } } if (groups) { if (hbac_request_element_set_groups(self, groups, NULL) != 0) { return -1; } } return 0; } static int hbac_request_element_set_name(HbacRequestElement *self, PyObject *name, void *closure) { CHECK_ATTRIBUTE_DELETE(name, "name"); if (!PyBytes_Check(name) && !PyUnicode_Check(name)) { PyErr_Format(PyExc_TypeError, "name must be a string or Unicode"); return -1; } SAFE_SET(self->name, name); return 0; } static PyObject * hbac_request_element_get_name(HbacRequestElement *self, void *closure) { if (PyUnicode_Check(self->name)) { Py_INCREF(self->name); return self->name; } else if (PyBytes_Check(self->name)) { return PyUnicode_FromEncodedObject(self->name, PYHBAC_ENCODING, PYHBAC_ENCODING_ERRORS); } /* setter does typechecking but let us be paranoid */ PyErr_Format(PyExc_TypeError, "name must be a string or Unicode"); return NULL; } static int hbac_request_element_set_groups(HbacRequestElement *self, PyObject *groups, void *closure) { CHECK_ATTRIBUTE_DELETE(groups, "groups"); if (!verify_sequence(groups, "groups")) { return -1; } SAFE_SET(self->groups, groups); return 0; } static PyObject * hbac_request_element_get_groups(HbacRequestElement *self, void *closure) { Py_INCREF(self->groups); return self->groups; } static PyObject * HbacRequestElement_repr(HbacRequestElement *self) { char *strgroups; PyObject *o, *format, *args; format = PyUnicode_FromString(""); if (format == NULL) { return NULL; } strgroups = str_concat_sequence(self->groups, discard_const_p(char, ",")); if (strgroups == NULL) { Py_DECREF(format); return NULL; } args = Py_BuildValue(sss_py_const_p(char, "Os"), self->name, strgroups); if (args == NULL) { PyMem_Free(strgroups); Py_DECREF(format); return NULL; } o = PyUnicode_Format(format, args); PyMem_Free(strgroups); Py_DECREF(format); Py_DECREF(args); return o; } PyDoc_STRVAR(HbacRequestElement_name__doc__, "(string) An object name this element applies to"); PyDoc_STRVAR(HbacRequestElement_groups__doc__, "(list of strings) A list of group names this element applies to"); static PyGetSetDef py_hbac_request_element_getset[] = { { discard_const_p(char, "name"), (getter) hbac_request_element_get_name, (setter) hbac_request_element_set_name, HbacRequestElement_name__doc__, NULL }, { discard_const_p(char, "groups"), (getter) hbac_request_element_get_groups, (setter) hbac_request_element_set_groups, HbacRequestElement_groups__doc__, NULL }, { NULL, 0, 0, 0, NULL } /* Sentinel */ }; PyDoc_STRVAR(HbacRequestElement__doc__, "IPA HBAC Request Element\n\n" "HbacRequestElement() -> new empty request element\n" "HbacRequestElement([name], [groups]) -> optionally, provide name and/or " "groups\n"); static PyTypeObject pyhbac_hbacrequest_element_type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = sss_py_const_p(char, "pyhbac.HbacRequestElement"), .tp_basicsize = sizeof(HbacRequestElement), .tp_new = HbacRequestElement_new, .tp_dealloc = (destructor) HbacRequestElement_dealloc, .tp_traverse = (traverseproc) HbacRequestElement_traverse, .tp_clear = (inquiry) HbacRequestElement_clear, .tp_init = (initproc) HbacRequestElement_init, .tp_repr = (reprfunc) HbacRequestElement_repr, .tp_getset = py_hbac_request_element_getset, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, .tp_doc = HbacRequestElement__doc__ }; static void free_hbac_request_element(struct hbac_request_element *el) { if (!el) return; PyMem_Free(discard_const_p(char, el->name)); free_string_list(el->groups); PyMem_Free(el); } static struct hbac_request_element * HbacRequestElement_to_native(HbacRequestElement *pyel) { struct hbac_request_element *el = NULL; PyObject *utf_name; if (!PyObject_IsInstance((PyObject *) pyel, (PyObject *) &pyhbac_hbacrequest_element_type)) { PyErr_Format(PyExc_TypeError, "The element must be of type HbacRequestElement\n"); goto fail; } el = PyMem_Malloc(sizeof(struct hbac_request_element)); if (!el) { PyErr_NoMemory(); goto fail; } utf_name = get_utf8_string(pyel->name, "name"); if (utf_name == NULL) { return NULL; } el->name = py_strdup(PyBytes_AsString(utf_name)); Py_DECREF(utf_name); if (!el->name) { goto fail; } el->groups = sequence_as_string_list(pyel->groups, "groups"); if (!el->groups) { goto fail; } return el; fail: free_hbac_request_element(el); return NULL; } /* ==================== HBAC Request ========================*/ typedef struct { PyObject_HEAD HbacRequestElement *service; HbacRequestElement *user; HbacRequestElement *targethost; HbacRequestElement *srchost; PyObject *rule_name; } HbacRequest; static PyObject * HbacRequest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { HbacRequest *self; self = (HbacRequest *) type->tp_alloc(type, 0); if (self == NULL) { PyErr_NoMemory(); return NULL; } self->service = (HbacRequestElement *) HbacRequestElement_new( &pyhbac_hbacrequest_element_type, NULL, NULL); self->user = (HbacRequestElement *) HbacRequestElement_new( &pyhbac_hbacrequest_element_type, NULL, NULL); self->targethost = (HbacRequestElement *) HbacRequestElement_new( &pyhbac_hbacrequest_element_type, NULL, NULL); self->srchost = (HbacRequestElement *) HbacRequestElement_new( &pyhbac_hbacrequest_element_type, NULL, NULL); if (self->service == NULL || self->user == NULL || self->targethost == NULL || self->srchost == NULL) { Py_XDECREF(self->service); Py_XDECREF(self->user); Py_XDECREF(self->targethost); Py_XDECREF(self->srchost); Py_DECREF(self); PyErr_NoMemory(); return NULL; } return (PyObject *) self; } static int HbacRequest_clear(HbacRequest *self) { Py_CLEAR(self->service); Py_CLEAR(self->user); Py_CLEAR(self->targethost); Py_CLEAR(self->srchost); Py_CLEAR(self->rule_name); return 0; } static void HbacRequest_dealloc(HbacRequest *self) { HbacRequest_clear(self); Py_TYPE(self)->tp_free((PyObject*) self); } static int HbacRequest_traverse(HbacRequest *self, visitproc visit, void *arg) { Py_VISIT((PyObject *) self->service); Py_VISIT((PyObject *) self->user); Py_VISIT((PyObject *) self->targethost); Py_VISIT((PyObject *) self->srchost); return 0; } static int HbacRequest_init(HbacRequest *self, PyObject *args, PyObject *kwargs) { PyObject *empty_tuple = NULL; empty_tuple = PyTuple_New(0); if (!empty_tuple) { PyErr_NoMemory(); return -1; } self->rule_name = NULL; if (HbacRequestElement_init(self->user, empty_tuple, NULL) == -1 || HbacRequestElement_init(self->service, empty_tuple, NULL) == -1 || HbacRequestElement_init(self->targethost, empty_tuple, NULL) == -1 || HbacRequestElement_init(self->srchost, empty_tuple, NULL) == -1) { Py_DECREF(empty_tuple); return -1; } Py_DECREF(empty_tuple); return 0; } PyDoc_STRVAR(py_hbac_evaluate__doc__, "evaluate(rules) -> int\n\n" "Evaluate a set of HBAC rules.\n" "rules is a sequence of HbacRule objects. The returned value describes\n" "the result of evaluation and will have one of HBAC_EVAL_* values.\n" "Use hbac_result_string() to get textual representation of the result\n" "On error, HbacError exception is raised.\n" "If HBAC_EVAL_ALLOW is returned, the class attribute rule_name would\n" "contain the name of the rule that matched. Otherwise, the attribute\n" "contains None\n"); static struct hbac_eval_req * HbacRequest_to_native(HbacRequest *pyreq); static void free_hbac_rule_list(struct hbac_rule **rules) { int i; if (!rules) return; for(i=0; rules[i]; i++) { free_hbac_rule(rules[i]); } PyMem_Free(rules); } static void free_hbac_eval_req(struct hbac_eval_req *req); static PyObject * py_hbac_evaluate(HbacRequest *self, PyObject *args) { PyObject *py_rules_list = NULL; PyObject *py_rule = NULL; Py_ssize_t num_rules; struct hbac_rule **rules = NULL; struct hbac_eval_req *hbac_req = NULL; enum hbac_eval_result eres; struct hbac_info *info = NULL; PyObject *ret = NULL; long i; if (!PyArg_ParseTuple(args, sss_py_const_p(char, "O"), &py_rules_list)) { goto fail; } if (!PySequence_Check(py_rules_list)) { PyErr_Format(PyExc_TypeError, "The parameter rules must be a sequence\n"); goto fail; } num_rules = PySequence_Size(py_rules_list); rules = PyMem_New(struct hbac_rule *, num_rules+1); if (!rules) { PyErr_NoMemory(); goto fail; } for (i=0; i < num_rules; i++) { py_rule = PySequence_GetItem(py_rules_list, i); if (!PyObject_IsInstance(py_rule, (PyObject *) &pyhbac_hbacrule_type)) { PyErr_Format(PyExc_TypeError, "A rule must be of type HbacRule\n"); goto fail; } rules[i] = HbacRule_to_native((HbacRuleObject *) py_rule); if (!rules[i]) { /* Make sure there is at least a generic exception */ if (!PyErr_Occurred()) { PyErr_Format(PyExc_IOError, "Could not convert HbacRule to native type\n"); } goto fail; } } rules[num_rules] = NULL; hbac_req = HbacRequest_to_native(self); if (!hbac_req) { if (!PyErr_Occurred()) { PyErr_Format(PyExc_IOError, "Could not convert HbacRequest to native type\n"); } goto fail; } Py_XDECREF(self->rule_name); self->rule_name = NULL; eres = hbac_evaluate(rules, hbac_req, &info); switch (eres) { case HBAC_EVAL_ALLOW: self->rule_name = PyUnicode_FromString(info->rule_name); if (!self->rule_name) { PyErr_NoMemory(); goto fail; } /* FALLTHROUGH */ case HBAC_EVAL_DENY: ret = PYNUMBER_FROMLONG(eres); break; case HBAC_EVAL_ERROR: set_hbac_exception(PyExc_HbacError, info); goto fail; case HBAC_EVAL_OOM: PyErr_NoMemory(); goto fail; } free_hbac_eval_req(hbac_req); free_hbac_rule_list(rules); hbac_free_info(info); return ret; fail: hbac_free_info(info); free_hbac_eval_req(hbac_req); free_hbac_rule_list(rules); return NULL; } static PyObject * hbac_request_element_get_rule_name(HbacRequest *self, void *closure) { if (self->rule_name == NULL) { Py_INCREF(Py_None); return Py_None; } else if (PyUnicode_Check(self->rule_name)) { Py_INCREF(self->rule_name); return self->rule_name; } PyErr_Format(PyExc_TypeError, "rule_name is not Unicode"); return NULL; } static PyObject * HbacRequest_repr(HbacRequest *self) { PyObject *user_repr; PyObject *service_repr; PyObject *targethost_repr; PyObject *srchost_repr; PyObject *o, *format, *args; format = PyUnicode_FromString(""); if (format == NULL) { return NULL; } user_repr = HbacRequestElement_repr(self->user); service_repr = HbacRequestElement_repr(self->service); targethost_repr = HbacRequestElement_repr(self->targethost); srchost_repr = HbacRequestElement_repr(self->srchost); if (user_repr == NULL || service_repr == NULL || targethost_repr == NULL || srchost_repr == NULL) { Py_XDECREF(user_repr); Py_XDECREF(service_repr); Py_XDECREF(targethost_repr); Py_XDECREF(srchost_repr); Py_DECREF(format); return NULL; } args = Py_BuildValue(sss_py_const_p(char, "OOOO"), user_repr, service_repr, targethost_repr, srchost_repr); if (args == NULL) { Py_DECREF(user_repr); Py_DECREF(service_repr); Py_DECREF(targethost_repr); Py_DECREF(srchost_repr); Py_DECREF(format); return NULL; } o = PyUnicode_Format(format, args); Py_DECREF(user_repr); Py_DECREF(service_repr); Py_DECREF(targethost_repr); Py_DECREF(srchost_repr); Py_DECREF(format); Py_DECREF(args); return o; } static PyMethodDef py_hbac_request_methods[] = { { sss_py_const_p(char, "evaluate"), (PyCFunction) py_hbac_evaluate, METH_VARARGS, py_hbac_evaluate__doc__ }, { NULL, NULL, 0, NULL } /* Sentinel */ }; PyDoc_STRVAR(HbacRequest_service__doc__, "(HbacRequestElement) This is a list of service DNs to check, it must\n" "consist of the actual service requested, as well as all parent groups\n" "containing that service"); PyDoc_STRVAR(HbacRequest_user__doc__, "(HbacRequestElement) This is a list of user DNs to check, it must consist\n" "of the actual user requested, as well as all parent groups containing\n" "that user."); PyDoc_STRVAR(HbacRequest_targethost__doc__, "(HbacRequestElement) This is a list of target hosts to check, it must\n" "consist of the actual target host requested, as well as all parent groups\n" "containing that target host."); PyDoc_STRVAR(HbacRequest_srchost__doc__, "(HbacRequestElement) This is a list of source hosts to check, it must\n" "consist of the actual source host requested, as well as all parent groups\n" "containing that source host."); static PyMemberDef py_hbac_request_members[] = { { discard_const_p(char, "service"), T_OBJECT_EX, offsetof(HbacRequest, service), 0, HbacRequest_service__doc__ }, { discard_const_p(char, "user"), T_OBJECT_EX, offsetof(HbacRequest, user), 0, HbacRequest_user__doc__ }, { discard_const_p(char, "targethost"), T_OBJECT_EX, offsetof(HbacRequest, targethost), 0, HbacRequest_targethost__doc__ }, { discard_const_p(char, "srchost"), T_OBJECT_EX, offsetof(HbacRequest, srchost), 0, HbacRequest_srchost__doc__ }, { NULL, 0, 0, 0, NULL } /* Sentinel */ }; PyDoc_STRVAR(HbacRequest_rule_name__doc__, "(string) If result of evaluation was to allow access, this member contains\n" "the name of the rule that allowed it. Otherwise, this attribute contains \n" "None. This attribute is read-only.\n"); static PyGetSetDef py_hbac_request_getset[] = { { discard_const_p(char, "rule_name"), (getter) hbac_request_element_get_rule_name, NULL, /* read only */ HbacRequest_rule_name__doc__, NULL }, { NULL, 0, 0, 0, NULL } /* Sentinel */ }; PyDoc_STRVAR(HbacRequest__doc__, "IPA HBAC Request\n\n" "HbacRequest() -> new empty HBAC request"); static PyTypeObject pyhbac_hbacrequest_type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = sss_py_const_p(char, "pyhbac.HbacRequest"), .tp_basicsize = sizeof(HbacRequest), .tp_new = HbacRequest_new, .tp_dealloc = (destructor) HbacRequest_dealloc, .tp_traverse = (traverseproc) HbacRequest_traverse, .tp_clear = (inquiry) HbacRequest_clear, .tp_init = (initproc) HbacRequest_init, .tp_repr = (reprfunc) HbacRequest_repr, .tp_methods = py_hbac_request_methods, .tp_members = py_hbac_request_members, .tp_getset = py_hbac_request_getset, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_doc = HbacRequest__doc__ }; static void free_hbac_eval_req(struct hbac_eval_req *req) { if (!req) return; free_hbac_request_element(req->service); free_hbac_request_element(req->user); free_hbac_request_element(req->targethost); free_hbac_request_element(req->srchost); PyMem_Free(req); } static struct hbac_eval_req * HbacRequest_to_native(HbacRequest *pyreq) { struct hbac_eval_req *req = NULL; req = PyMem_Malloc(sizeof(struct hbac_eval_req)); if (!req) { PyErr_NoMemory(); goto fail; } if (!PyObject_IsInstance((PyObject *) pyreq, (PyObject *) &pyhbac_hbacrequest_type)) { PyErr_Format(PyExc_TypeError, "The request must be of type HbacRequest\n"); goto fail; } req->service = HbacRequestElement_to_native(pyreq->service); req->user = HbacRequestElement_to_native(pyreq->user); req->targethost = HbacRequestElement_to_native(pyreq->targethost); req->srchost = HbacRequestElement_to_native(pyreq->srchost); if (!req->service || !req->user || !req->targethost || !req->srchost) { goto fail; } return req; fail: free_hbac_eval_req(req); return NULL; } /* =================== the pyhbac module initialization =====================*/ PyDoc_STRVAR(py_hbac_result_string__doc__, "hbac_result_string(code) -> string\n" "Returns a string representation of the HBAC result code"); static PyObject * py_hbac_result_string(PyObject *module, PyObject *args) { enum hbac_eval_result result; const char *str; if (!PyArg_ParseTuple(args, sss_py_const_p(char, "i"), &result)) { return NULL; } str = hbac_result_string(result); if (str == NULL) { /* None needs to be referenced, too */ Py_INCREF(Py_None); return Py_None; } return PyUnicode_FromString(str); } PyDoc_STRVAR(py_hbac_error_string__doc__, "hbac_error_string(code) -> string\n" "Returns a string representation of the HBAC error code"); static PyObject * py_hbac_error_string(PyObject *module, PyObject *args) { enum hbac_error_code code; const char *str; if (!PyArg_ParseTuple(args, sss_py_const_p(char, "i"), &code)) { return NULL; } str = hbac_error_string(code); if (str == NULL) { /* None needs to be referenced, too */ Py_INCREF(Py_None); return Py_None; } return PyUnicode_FromString(str); } static PyMethodDef pyhbac_module_methods[] = { { sss_py_const_p(char, "hbac_result_string"), (PyCFunction) py_hbac_result_string, METH_VARARGS, py_hbac_result_string__doc__, }, { sss_py_const_p(char, "hbac_error_string"), (PyCFunction) py_hbac_error_string, METH_VARARGS, py_hbac_error_string__doc__, }, {NULL, NULL, 0, NULL} /* Sentinel */ }; PyDoc_STRVAR(HbacError__doc__, "An HBAC processing exception\n\n" "This exception is raised when there is an internal error during the\n" "HBAC processing, such as an Out-Of-Memory situation or unparseable\n" "rule. HbacError.args argument is a tuple that contains error code and\n" "the name of the rule that was being processed. Use hbac_error_string()\n" "to get the text representation of the HBAC error"); #ifdef IS_PY3K static struct PyModuleDef pyhbacdef = { PyModuleDef_HEAD_INIT, PYTHON_MODULE_NAME, NULL, -1, pyhbac_module_methods, NULL, NULL, NULL, NULL }; PyMODINIT_FUNC PyInit_pyhbac(void) #else PyMODINIT_FUNC initpyhbac(void) #endif { PyObject *m; int ret; #ifdef IS_PY3K m = PyModule_Create(&pyhbacdef); #else m = Py_InitModule(sss_py_const_p(char, PYTHON_MODULE_NAME), pyhbac_module_methods); #endif if (m == NULL) MODINITERROR; /* The HBAC module exception */ PyExc_HbacError = sss_exception_with_doc( discard_const_p(char, "hbac.HbacError"), HbacError__doc__, PyExc_EnvironmentError, NULL); Py_INCREF(PyExc_HbacError); ret = PyModule_AddObject(m, sss_py_const_p(char, "HbacError"), PyExc_HbacError); if (ret == -1) MODINITERROR; /* HBAC rule categories */ ret = PyModule_AddIntMacro(m, HBAC_CATEGORY_NULL); if (ret == -1) MODINITERROR; ret = PyModule_AddIntMacro(m, HBAC_CATEGORY_ALL); if (ret == -1) MODINITERROR; /* HBAC rule elements */ ret = PyModule_AddIntMacro(m, HBAC_RULE_ELEMENT_USERS); if (ret == -1) MODINITERROR; ret = PyModule_AddIntMacro(m, HBAC_RULE_ELEMENT_SERVICES); if (ret == -1) MODINITERROR; ret = PyModule_AddIntMacro(m, HBAC_RULE_ELEMENT_TARGETHOSTS); if (ret == -1) MODINITERROR; ret = PyModule_AddIntMacro(m, HBAC_RULE_ELEMENT_SOURCEHOSTS); if (ret == -1) MODINITERROR; /* enum hbac_eval_result */ ret = PyModule_AddIntMacro(m, HBAC_EVAL_ALLOW); if (ret == -1) MODINITERROR; ret = PyModule_AddIntMacro(m, HBAC_EVAL_DENY); if (ret == -1) MODINITERROR; ret = PyModule_AddIntMacro(m, HBAC_EVAL_ERROR); if (ret == -1) MODINITERROR; /* enum hbac_error_code */ ret = PyModule_AddIntMacro(m, HBAC_ERROR_UNKNOWN); if (ret == -1) MODINITERROR; ret = PyModule_AddIntMacro(m, HBAC_SUCCESS); if (ret == -1) MODINITERROR; ret = PyModule_AddIntMacro(m, HBAC_ERROR_NOT_IMPLEMENTED); if (ret == -1) MODINITERROR; ret = PyModule_AddIntMacro(m, HBAC_ERROR_OUT_OF_MEMORY); if (ret == -1) MODINITERROR; ret = PyModule_AddIntMacro(m, HBAC_ERROR_UNPARSEABLE_RULE); if (ret == -1) MODINITERROR; TYPE_READY(m, pyhbac_hbacrule_type, "HbacRule"); TYPE_READY(m, pyhbac_hbacrule_element_type, "HbacRuleElement"); TYPE_READY(m, pyhbac_hbacrequest_element_type, "HbacRequestElement"); TYPE_READY(m, pyhbac_hbacrequest_type, "HbacRequest"); #ifdef IS_PY3K return m; #endif } sssd-1.13.4/src/python/PaxHeaders.16287/pysss.c0000644000000000000000000000007412703456111015762 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.649793612 sssd-1.13.4/src/python/pysss.c0000644002412700241270000007672512703456111017452 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "util/sss_python.h" #include "db/sysdb.h" #include "tools/tools_util.h" #include "tools/sss_sync_ops.h" #include "util/crypto/sss_crypto.h" /* * function taken from samba sources tree as of Aug 20 2009, * file source4/lib/ldb/pyldb.c */ static char **PyList_AsStringList(TALLOC_CTX *mem_ctx, PyObject *list, const char *paramname) { char **ret; int i; ret = talloc_array(mem_ctx, char *, PyList_Size(list)+1); for (i = 0; i < PyList_Size(list); i++) { char *itemstr; Py_ssize_t itemlen; PyObject *item = PyList_GetItem(list, i); #ifdef IS_PY3K if (!PyUnicode_Check(item)) { #else if (!PyString_Check(item)) { #endif PyErr_Format(PyExc_TypeError, "%s should be strings", paramname); return NULL; } #ifdef IS_PY3K itemstr = PyUnicode_AsUTF8AndSize(item, &itemlen); #else itemstr = PyString_AsString(item); itemlen = strlen(itemstr); #endif ret[i] = talloc_strndup(ret, itemstr, itemlen); } ret[i] = NULL; return ret; } /* ======================= sysdb python wrappers ==========================*/ /* * The sss.password object */ typedef struct { PyObject_HEAD TALLOC_CTX *mem_ctx; struct tevent_context *ev; struct sysdb_ctx *sysdb; struct confdb_ctx *confdb; struct sss_domain_info *local; int lock; int unlock; } PySssLocalObject; /* * Error reporting */ static void PyErr_SetSssErrorWithMessage(int ret, const char *message) { PyObject *exc = Py_BuildValue(discard_const_p(char, "(is)"), ret, message); PyErr_SetObject(PyExc_IOError, exc); Py_XDECREF(exc); } static void PyErr_SetSssError(int ret) { PyErr_SetSssErrorWithMessage(ret, strerror(ret)); } /* * Common init of all methods */ static struct tools_ctx *init_ctx(PySssLocalObject *self) { struct ops_ctx *octx = NULL; struct tools_ctx *tctx = NULL; tctx = talloc_zero(self->mem_ctx, struct tools_ctx); if (tctx == NULL) { return NULL; } tctx->confdb = self->confdb; tctx->sysdb = self->sysdb; tctx->local = self->local; /* tctx->nctx is NULL here, which is OK since we don't parse domains * in the python bindings (yet?) */ octx = talloc_zero(tctx, struct ops_ctx); if (octx == NULL) { PyErr_NoMemory(); return NULL; } octx->domain = self->local; tctx->octx = octx; return tctx; } /* * Add a user */ PyDoc_STRVAR(py_sss_useradd__doc__, "Add a user named ``username``.\n\n" ":param username: name of the user\n\n" ":param kwargs: Keyword arguments that customize the operation\n\n" "* useradd can be customized further with keyword arguments:\n" " * ``uid``: The UID of the user\n" " * ``gid``: The GID of the user\n" " * ``gecos``: The comment string\n" " * ``homedir``: Home directory\n" " * ``shell``: Login shell\n" " * ``skel``: Specify an alternative skeleton directory\n" " * ``create_home``: (bool) Force creation of home directory on or off\n" " * ``groups``: List of groups the user is member of\n"); static PyObject *py_sss_useradd(PySssLocalObject *self, PyObject *args, PyObject *kwds) { struct tools_ctx *tctx = NULL; unsigned long uid = 0; unsigned long gid = 0; const char *gecos = NULL; const char *home = NULL; const char *shell = NULL; const char *skel = NULL; char *username = NULL; int ret; const char * const kwlist[] = { "username", "uid", "gid", "gecos", "homedir", "shell", "skel", "create_home", "groups", NULL }; PyObject *py_groups = Py_None; PyObject *py_create_home = Py_None; int create_home = 0; bool in_transaction = false; /* parse arguments */ if (!PyArg_ParseTupleAndKeywords(args, kwds, discard_const_p(char, "s|kkssssO!O!"), discard_const_p(char *, kwlist), &username, &uid, &gid, &gecos, &home, &shell, &skel, &PyBool_Type, &py_create_home, &PyList_Type, &py_groups)) { goto fail; } tctx = init_ctx(self); if (!tctx) { PyErr_NoMemory(); return NULL; } if (py_groups != Py_None) { tctx->octx->addgroups = PyList_AsStringList(tctx, py_groups, "groups"); if (!tctx->octx->addgroups) { PyErr_NoMemory(); return NULL; } } /* user-wise the parameter is only bool - do or don't, * however we must have a third state - undecided, pick default */ if (py_create_home == Py_True) { create_home = DO_CREATE_HOME; } else if (py_create_home == Py_False) { create_home = DO_NOT_CREATE_HOME; } tctx->octx->name = username; tctx->octx->uid = uid; /* fill in defaults */ ret = useradd_defaults(tctx, self->confdb, tctx->octx, gecos, home, shell, create_home, skel); if (ret != EOK) { PyErr_SetSssError(ret); goto fail; } /* Add the user within a transaction */ tctx->error = sysdb_transaction_start(tctx->sysdb); if (tctx->error != EOK) { PyErr_SetSssError(tctx->error); goto fail; } in_transaction = true; /* useradd */ tctx->error = useradd(tctx, tctx->octx); if (tctx->error) { PyErr_SetSssError(tctx->error); goto fail; } tctx->error = sysdb_transaction_commit(tctx->sysdb); if (tctx->error) { PyErr_SetSssError(tctx->error); goto fail; } in_transaction = false; /* Create user's home directory and/or mail spool */ if (tctx->octx->create_homedir) { /* We need to know the UID and GID of the user, if * sysdb did assign it automatically, do a lookup */ if (tctx->octx->uid == 0 || tctx->octx->gid == 0) { ret = sysdb_getpwnam_sync(tctx, tctx->octx->name, tctx->octx); if (ret != EOK) { PyErr_SetSssError(ret); goto fail; } } ret = create_homedir(tctx->octx->skeldir, tctx->octx->home, tctx->octx->uid, tctx->octx->gid, tctx->octx->umask); if (ret != EOK) { PyErr_SetSssError(ret); goto fail; } /* failure here should not be fatal */ create_mail_spool(tctx, tctx->octx->name, tctx->octx->maildir, tctx->octx->uid, tctx->octx->gid); } talloc_zfree(tctx); Py_RETURN_NONE; fail: if (in_transaction) { /* We do not handle return value of sysdb_transaction_cancel() * because we don't want to overwrite previous error code. */ sysdb_transaction_cancel(tctx->sysdb); } talloc_zfree(tctx); return NULL; } /* * Delete a user */ PyDoc_STRVAR(py_sss_userdel__doc__, "Remove the user named ``username``.\n\n" ":param username: Name of user being removed\n" ":param kwargs: Keyword arguments that customize the operation\n\n" "* userdel can be customized further with keyword arguments:\n" " * ``force``: (bool) Force removal of files not owned by the user\n" " * ``remove``: (bool) Toggle removing home directory and mail spool\n"); static PyObject *py_sss_userdel(PySssLocalObject *self, PyObject *args, PyObject *kwds) { struct tools_ctx *tctx = NULL; char *username = NULL; int ret; PyObject *py_remove = Py_None; int remove_home = 0; PyObject *py_force = Py_None; const char * const kwlist[] = { "username", "remove", "force", NULL }; if(!PyArg_ParseTupleAndKeywords(args, kwds, discard_const_p(char, "s|O!O!"), discard_const_p(char *, kwlist), &username, &PyBool_Type, &py_remove, &PyBool_Type, &py_force)) { goto fail; } tctx = init_ctx(self); if (!tctx) { PyErr_NoMemory(); return NULL; } tctx->octx->name = username; if (py_remove == Py_True) { remove_home = DO_REMOVE_HOME; } else if (py_remove == Py_False) { remove_home = DO_NOT_REMOVE_HOME; } /* * Fills in defaults for ops_ctx user did not specify. */ ret = userdel_defaults(tctx, tctx->confdb, tctx->octx, remove_home); if (ret != EOK) { PyErr_SetSssError(ret); goto fail; } ret = run_userdel_cmd(tctx); if (ret != EOK) { PyErr_SetSssError(ret); goto fail; } if (tctx->octx->remove_homedir) { ret = sysdb_getpwnam_sync(tctx, tctx->octx->name, tctx->octx); if (ret != EOK) { PyErr_SetSssError(ret); goto fail; } } /* Delete the user */ ret = userdel(tctx, self->sysdb, tctx->octx); if (ret != EOK) { PyErr_SetSssError(ret); goto fail; } if (tctx->octx->remove_homedir) { ret = remove_homedir(tctx, tctx->octx->home, tctx->octx->maildir, tctx->octx->name, tctx->octx->uid, (py_force == Py_True)); if (ret != EOK) { PyErr_SetSssError(ret); goto fail; } } talloc_zfree(tctx); Py_RETURN_NONE; fail: talloc_zfree(tctx); return NULL; } /* * Modify a user */ PyDoc_STRVAR(py_sss_usermod__doc__, "Modify a user.\n\n" ":param username: Name of user being modified\n\n" ":param kwargs: Keyword arguments that customize the operation\n\n" "* usermod can be customized further with keyword arguments:\n" " * ``uid``: The UID of the user\n" " * ``gid``: The GID of the user\n" " * ``gecos``: The comment string\n" " * ``homedir``: Home directory\n" " * ``shell``: Login shell\n" " * ``addgroups``: List of groups to add the user to\n" " * ``rmgroups``: List of groups to remove the user from\n" " * ``lock``: Lock or unlock the account\n"); static PyObject *py_sss_usermod(PySssLocalObject *self, PyObject *args, PyObject *kwds) { struct tools_ctx *tctx = NULL; PyObject *py_addgroups = Py_None; PyObject *py_rmgroups = Py_None; unsigned long uid = 0; unsigned long gid = 0; char *gecos = NULL; char *home = NULL; char *shell = NULL; char *username = NULL; unsigned long lock = 0; const char * const kwlist[] = { "username", "uid", "gid", "lock", "gecos", "homedir", "shell", "addgroups", "rmgroups", NULL }; bool in_transaction = false; /* parse arguments */ if (!PyArg_ParseTupleAndKeywords(args, kwds, discard_const_p(char, "s|kkksssO!O!"), discard_const_p(char *, kwlist), &username, &uid, &gid, &lock, &gecos, &home, &shell, &PyList_Type, &py_addgroups, &PyList_Type, &py_rmgroups)) { goto fail; } tctx = init_ctx(self); if (!tctx) { PyErr_NoMemory(); return NULL; } if (lock && lock != DO_LOCK && lock != DO_UNLOCK) { PyErr_SetString(PyExc_ValueError, "Unknown value for lock parameter"); goto fail; } if (py_addgroups != Py_None) { tctx->octx->addgroups = PyList_AsStringList(tctx, py_addgroups, "addgroups"); if (!tctx->octx->addgroups) { return NULL; } } if (py_rmgroups != Py_None) { tctx->octx->rmgroups = PyList_AsStringList(tctx, py_rmgroups, "rmgroups"); if (!tctx->octx->rmgroups) { return NULL; } } tctx->octx->name = username; tctx->octx->uid = uid; tctx->octx->gid = gid; tctx->octx->gecos = gecos; tctx->octx->home = home; tctx->octx->shell = shell; tctx->octx->lock = lock; /* Modify the user within a transaction */ tctx->error = sysdb_transaction_start(tctx->sysdb); if (tctx->error != EOK) { PyErr_SetSssError(tctx->error); goto fail; } in_transaction = true; /* usermod */ tctx->error = usermod(tctx, tctx->octx); if (tctx->error) { PyErr_SetSssError(tctx->error); goto fail; } tctx->error = sysdb_transaction_commit(tctx->sysdb); if (tctx->error) { PyErr_SetSssError(tctx->error); goto fail; } in_transaction = false; talloc_zfree(tctx); Py_RETURN_NONE; fail: if (in_transaction) { /* We do not handle return value of sysdb_transaction_cancel() * because we don't want to overwrite previous error code. */ sysdb_transaction_cancel(tctx->sysdb); } talloc_zfree(tctx); return NULL; } /* * Add a group */ PyDoc_STRVAR(py_sss_groupadd__doc__, "Add a group.\n\n" ":param groupname: Name of group being added\n\n" ":param kwargs: Keyword arguments ro customize the operation\n\n" "* groupmod can be customized further with keyword arguments:\n" " * ``gid``: The GID of the group\n"); static PyObject *py_sss_groupadd(PySssLocalObject *self, PyObject *args, PyObject *kwds) { struct tools_ctx *tctx = NULL; char *groupname; unsigned long gid = 0; const char * const kwlist[] = { "groupname", "gid", NULL }; bool in_transaction = false; /* parse arguments */ if (!PyArg_ParseTupleAndKeywords(args, kwds, discard_const_p(char, "s|k"), discard_const_p(char *, kwlist), &groupname, &gid)) { goto fail; } tctx = init_ctx(self); if (!tctx) { PyErr_NoMemory(); return NULL; } tctx->octx->name = groupname; tctx->octx->gid = gid; /* Add the group within a transaction */ tctx->error = sysdb_transaction_start(tctx->sysdb); if (tctx->error != EOK) { PyErr_SetSssError(tctx->error); goto fail; } in_transaction = true; /* groupadd */ tctx->error = groupadd(tctx->octx); if (tctx->error) { PyErr_SetSssError(tctx->error); goto fail; } tctx->error = sysdb_transaction_commit(tctx->sysdb); if (tctx->error) { PyErr_SetSssError(tctx->error); goto fail; } in_transaction = false; talloc_zfree(tctx); Py_RETURN_NONE; fail: if (in_transaction) { /* We do not handle return value of sysdb_transaction_cancel() * because we don't want to overwrite previous error code. */ sysdb_transaction_cancel(tctx->sysdb); } talloc_zfree(tctx); return NULL; } /* * Delete a group */ PyDoc_STRVAR(py_sss_groupdel__doc__, "Remove a group.\n\n" ":param groupname: Name of group being removed\n"); static PyObject *py_sss_groupdel(PySssLocalObject *self, PyObject *args, PyObject *kwds) { struct tools_ctx *tctx = NULL; char *groupname = NULL; int ret; if(!PyArg_ParseTuple(args, discard_const_p(char, "s"), &groupname)) { goto fail; } tctx = init_ctx(self); if (!tctx) { PyErr_NoMemory(); return NULL; } tctx->octx->name = groupname; /* Remove the group */ ret = groupdel(tctx, self->sysdb, tctx->octx); if (ret != EOK) { PyErr_SetSssError(ret); goto fail; } talloc_zfree(tctx); Py_RETURN_NONE; fail: talloc_zfree(tctx); return NULL; } /* * Modify a group */ PyDoc_STRVAR(py_sss_groupmod__doc__, "Modify a group.\n\n" ":param groupname: Name of group being modified\n\n" ":param kwargs: Keyword arguments ro customize the operation\n\n" "* groupmod can be customized further with keyword arguments:\n" " * ``gid``: The GID of the group\n\n" " * ``addgroups``: Groups to add the group to\n\n" " * ``rmgroups``: Groups to remove the group from\n\n"); static PyObject *py_sss_groupmod(PySssLocalObject *self, PyObject *args, PyObject *kwds) { struct tools_ctx *tctx = NULL; PyObject *py_addgroups = Py_None; PyObject *py_rmgroups = Py_None; unsigned long gid = 0; char *groupname = NULL; const char * const kwlist[] = { "groupname", "gid", "addgroups", "rmgroups", NULL }; bool in_transaction = false; /* parse arguments */ if (!PyArg_ParseTupleAndKeywords(args, kwds, discard_const_p(char, "s|kO!O!"), discard_const_p(char *, kwlist), &groupname, &gid, &PyList_Type, &py_addgroups, &PyList_Type, &py_rmgroups)) { goto fail; } tctx = init_ctx(self); if (!tctx) { PyErr_NoMemory(); return NULL; } if (py_addgroups != Py_None) { tctx->octx->addgroups = PyList_AsStringList(tctx, py_addgroups, "addgroups"); if (!tctx->octx->addgroups) { return NULL; } } if (py_rmgroups != Py_None) { tctx->octx->rmgroups = PyList_AsStringList(tctx, py_rmgroups, "rmgroups"); if (!tctx->octx->rmgroups) { return NULL; } } tctx->octx->name = groupname; tctx->octx->gid = gid; /* Modify the group within a transaction */ tctx->error = sysdb_transaction_start(tctx->sysdb); if (tctx->error != EOK) { PyErr_SetSssError(tctx->error); goto fail; } in_transaction = true; /* groupmod */ tctx->error = groupmod(tctx, tctx->octx); if (tctx->error) { PyErr_SetSssError(tctx->error); goto fail; } tctx->error = sysdb_transaction_commit(tctx->sysdb); if (tctx->error) { PyErr_SetSssError(tctx->error); goto fail; } in_transaction = false; talloc_zfree(tctx); Py_RETURN_NONE; fail: if (in_transaction) { /* We do not handle return value of sysdb_transaction_cancel() * because we don't want to overwrite previous error code. */ sysdb_transaction_cancel(tctx->sysdb); } talloc_zfree(tctx); return NULL; } /* * Get list of groups user belongs to */ PyDoc_STRVAR(py_sss_getgrouplist__doc__, "Get list of groups user belongs to.\n\n" "NOTE: The interface uses the system NSS calls and is not limited to " "users served by the SSSD!\n" ":param username: name of user to get list for\n"); static PyObject *py_sss_getgrouplist(PyObject *self, PyObject *args) { char *username = NULL; gid_t *groups = NULL; struct passwd *pw; struct group *gr; int ngroups; int ret; Py_ssize_t i, idx; PyObject *groups_tuple; if(!PyArg_ParseTuple(args, discard_const_p(char, "s"), &username)) { goto fail; } pw = getpwnam(username); if (pw == NULL) { goto fail; } ngroups = 32; groups = malloc(sizeof(gid_t) * ngroups); if (groups == NULL) { goto fail; } do { ret = getgrouplist(username, pw->pw_gid, groups, &ngroups); if (ret < ngroups) { gid_t *tmp_groups = realloc(groups, ngroups * sizeof(gid_t)); if (tmp_groups == NULL) { goto fail; } groups = tmp_groups; } } while (ret != ngroups); groups_tuple = PyTuple_New((Py_ssize_t) ngroups); if (groups_tuple == NULL) { goto fail; } /* Populate a tuple with names of groups * In unlikely case of group not being able to resolve, skip it * We also need to resize resulting tuple to avoid empty elements there */ idx = 0; for (i = 0; i < ngroups; i++) { gr = getgrgid(groups[i]); if (gr) { PyTuple_SetItem(groups_tuple, idx, #ifdef IS_PY3K PyUnicode_FromString(gr->gr_name) #else PyString_FromString(gr->gr_name) #endif ); idx++; } } free(groups); groups = NULL; if (i != idx) { _PyTuple_Resize(&groups_tuple, idx); } return groups_tuple; fail: free(groups); return NULL; } /*** python plumbing begins here ***/ /* * The sss.local destructor */ static void PySssLocalObject_dealloc(PySssLocalObject *self) { talloc_free(self->mem_ctx); Py_TYPE(self)->tp_free((PyObject *)self); } /* * The sss.local constructor */ static PyObject *PySssLocalObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { TALLOC_CTX *mem_ctx; PySssLocalObject *self; char *confdb_path; int ret; mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { PyErr_NoMemory(); return NULL; } self = (PySssLocalObject *) type->tp_alloc(type, 0); if (self == NULL) { talloc_free(mem_ctx); PyErr_NoMemory(); return NULL; } self->mem_ctx = mem_ctx; confdb_path = talloc_asprintf(self->mem_ctx, "%s/%s", DB_PATH, CONFDB_FILE); if (confdb_path == NULL) { PyErr_NoMemory(); goto fail; } /* Connect to the conf db */ ret = confdb_init(self->mem_ctx, &self->confdb, confdb_path); if (ret != EOK) { PyErr_SetSssErrorWithMessage(ret, "Could not initialize connection to the confdb\n"); goto fail; } ret = sssd_domain_init(self->mem_ctx, self->confdb, "local", DB_PATH, &self->local); if (ret != EOK) { PyErr_SetSssErrorWithMessage(ret, "Could not initialize connection to the sysdb\n"); goto fail; } self->sysdb = self->local->sysdb; self->lock = DO_LOCK; self->unlock = DO_UNLOCK; return (PyObject *) self; fail: Py_DECREF(self); return NULL; } /* * sss.local object methods */ static PyMethodDef sss_local_methods[] = { { sss_py_const_p(char, "useradd"), (PyCFunction) py_sss_useradd, METH_KEYWORDS, py_sss_useradd__doc__ }, { sss_py_const_p(char, "userdel"), (PyCFunction) py_sss_userdel, METH_KEYWORDS, py_sss_userdel__doc__ }, { sss_py_const_p(char, "usermod"), (PyCFunction) py_sss_usermod, METH_KEYWORDS, py_sss_usermod__doc__ }, { sss_py_const_p(char, "groupadd"), (PyCFunction) py_sss_groupadd, METH_KEYWORDS, py_sss_groupadd__doc__ }, { sss_py_const_p(char, "groupdel"), (PyCFunction) py_sss_groupdel, METH_KEYWORDS, py_sss_groupdel__doc__ }, { sss_py_const_p(char, "groupmod"), (PyCFunction) py_sss_groupmod, METH_KEYWORDS, py_sss_groupmod__doc__ }, {NULL, NULL, 0, NULL} /* Sentinel */ }; static PyMemberDef sss_local_members[] = { { discard_const_p(char, "lock"), T_INT, offsetof(PySssLocalObject, lock), READONLY, NULL}, { discard_const_p(char, "unlock"), T_INT, offsetof(PySssLocalObject, unlock), READONLY, NULL}, {NULL, 0, 0, 0, NULL} /* Sentinel */ }; /* * sss.local object properties */ static PyTypeObject pysss_local_type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = sss_py_const_p(char, "sss.local"), .tp_basicsize = sizeof(PySssLocalObject), .tp_new = PySssLocalObject_new, .tp_dealloc = (destructor) PySssLocalObject_dealloc, .tp_methods = sss_local_methods, .tp_members = sss_local_members, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_doc = sss_py_const_p(char, "SSS DB manipulation"), }; /* ==================== obfuscation python wrappers ========================*/ /* * The sss.local object */ typedef struct { PyObject_HEAD int aes_256; } PySssPasswordObject; PyDoc_STRVAR(py_sss_encrypt__doc__, "Obfuscate a password\n\n" ":param password: The password to obfuscate\n\n" ":param method: The obfuscation method\n\n"); static PyObject *py_sss_encrypt(PySssPasswordObject *self, PyObject *args, PyObject *kwds) { char *password = NULL; int plen; /* may contain NULL bytes */ char *obfpwd = NULL; TALLOC_CTX *tctx = NULL; int ret; int mode; PyObject *retval = NULL; /* parse arguments */ if (!PyArg_ParseTuple(args, discard_const_p(char, "s#i"), &password, &plen, &mode)) { return NULL; } tctx = talloc_new(NULL); if (!tctx) { PyErr_NoMemory(); return NULL; } ret = sss_password_encrypt(tctx, password, plen+1, mode, &obfpwd); if (ret != EOK) { PyErr_SetSssError(ret); goto fail; } retval = Py_BuildValue(sss_py_const_p(char, "s"), obfpwd); if (retval == NULL) { goto fail; } fail: talloc_zfree(tctx); return retval; } #if 0 PyDoc_STRVAR(py_sss_decrypt__doc__, "Deobfuscate a password\n\n" ":param obfpwd: The password to convert back to clear text\n\n"); static PyObject *py_sss_decrypt(PySssPasswordObject *self, PyObject *args, PyObject *kwds) { char *password = NULL; char *obfpwd = NULL; TALLOC_CTX *tctx = NULL; int ret; PyObject *retval = NULL; /* parse arguments */ if (!PyArg_ParseTuple(args, discard_const_p(char, "s"), &obfpwd)) { return NULL; } tctx = talloc_new(NULL); if (!tctx) { PyErr_NoMemory(); return NULL; } ret = sss_password_decrypt(tctx, obfpwd, &password); if (ret != EOK) { PyErr_SetSssError(ret); goto fail; } retval = Py_BuildValue("s", password); if (retval == NULL) { goto fail; } fail: talloc_zfree(tctx); return retval; } #endif /* * The sss.password destructor */ static void PySssPasswordObject_dealloc(PySssPasswordObject *self) { Py_TYPE(self)->tp_free((PyObject*) self); } /* * The sss.password constructor */ static PyObject *PySssPasswordObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PySssPasswordObject *self; self = (PySssPasswordObject *) type->tp_alloc(type, 0); if (self == NULL) { PyErr_NoMemory(); return NULL; } self->aes_256 = AES_256; return (PyObject *) self; } /* * sss.password object methods */ static PyMethodDef sss_password_methods[] = { { sss_py_const_p(char, "encrypt"), (PyCFunction) py_sss_encrypt, METH_VARARGS | METH_STATIC, py_sss_encrypt__doc__ }, #if 0 { "decrypt", (PyCFunction) py_sss_decrypt, METH_VARARGS | METH_STATIC, py_sss_decrypt__doc__ }, #endif {NULL, NULL, 0, NULL} /* Sentinel */ }; /* * sss.password object members */ static PyMemberDef sss_password_members[] = { { discard_const_p(char, "AES_256"), T_INT, offsetof(PySssPasswordObject, aes_256), READONLY, NULL}, {NULL, 0, 0, 0, NULL} /* Sentinel */ }; /* * sss.password object properties */ static PyTypeObject pysss_password_type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = sss_py_const_p(char, "sss.password"), .tp_basicsize = sizeof(PySssPasswordObject), .tp_new = PySssPasswordObject_new, .tp_dealloc = (destructor) PySssPasswordObject_dealloc, .tp_methods = sss_password_methods, .tp_members = sss_password_members, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, .tp_doc = sss_py_const_p(char, "SSS password obfuscation"), }; /* ==================== the sss module initialization =======================*/ /* * Module methods */ static PyMethodDef module_methods[] = { {"getgrouplist", py_sss_getgrouplist, METH_VARARGS, py_sss_getgrouplist__doc__}, {NULL, NULL, 0, NULL} /* Sentinel */ }; /* * Module initialization */ #ifdef IS_PY3K static struct PyModuleDef pysssdef = { PyModuleDef_HEAD_INIT, "pysss", NULL, -1, module_methods, NULL, NULL, NULL, NULL }; PyMODINIT_FUNC PyInit_pysss(void) #else PyMODINIT_FUNC initpysss(void) #endif { PyObject *m; if (PyType_Ready(&pysss_local_type) < 0) MODINITERROR; if (PyType_Ready(&pysss_password_type) < 0) MODINITERROR; #ifdef IS_PY3K m = PyModule_Create(&pysssdef); #else m = Py_InitModule(discard_const_p(char, "pysss"), module_methods); #endif if (m == NULL) MODINITERROR; Py_INCREF(&pysss_local_type); PyModule_AddObject(m, discard_const_p(char, "local"), (PyObject *)&pysss_local_type); Py_INCREF(&pysss_password_type); PyModule_AddObject(m, discard_const_p(char, "password"), (PyObject *)&pysss_password_type); #ifdef IS_PY3K return m; #endif } sssd-1.13.4/src/PaxHeaders.16287/man0000644000000000000000000000013212703463557013621 xustar0030 mtime=1460561775.982798132 30 atime=1460561776.118798593 30 ctime=1460561775.982798132 sssd-1.13.4/src/man/0000755002412700241270000000000012703463557015352 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/man/PaxHeaders.16287/sss_groupshow.8.xml0000644000000000000000000000007212703456111017502 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.981798128 sssd-1.13.4/src/man/sss_groupshow.8.xml0000644002412700241270000000426012703456111021155 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_groupshow 8 sss_groupshow print properties of a group sss_groupshow options GROUP DESCRIPTION sss_groupshow displays information about a group identified by its name GROUP. The information includes the group ID number, members of the group and the parent group. OPTIONS , Also print indirect group members in a tree-like hierarchy. Note that this also affects printing parent groups - without , only the direct parent will be printed. sssd-1.13.4/src/man/PaxHeaders.16287/sss_useradd.8.xml0000644000000000000000000000007212703456111017074 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.971798094 sssd-1.13.4/src/man/sss_useradd.8.xml0000644002412700241270000001552412703456111020554 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_useradd 8 sss_useradd create a new user sss_useradd options LOGIN DESCRIPTION sss_useradd creates a new user account using the values specified on the command line plus the default values from the system. OPTIONS , UID Set the UID of the user to the value of UID. If not given, it is chosen automatically. , COMMENT Any text string describing the user. Often used as the field for the user's full name. , HOME_DIR The home directory of the user account. The default is to append the LOGIN name to /home and use that as the home directory. The base that is prepended before LOGIN is tunable with user_defaults/baseDirectory setting in sssd.conf. , SHELL The user's login shell. The default is currently /bin/bash. The default can be changed with user_defaults/defaultShell setting in sssd.conf. , GROUPS A list of existing groups this user is also a member of. , Create the user's home directory if it does not exist. The files and directories contained in the skeleton directory (which can be defined with the -k option or in the config file) will be copied to the home directory. , Do not create the user's home directory. Overrides configuration settings. , SKELDIR The skeleton directory, which contains files and directories to be copied in the user's home directory, when the home directory is created by sss_useradd. Special files (block devices, character devices, named pipes and unix sockets) will not be copied. This option is only valid if the (or ) option is specified, or creation of home directories is set to TRUE in the configuration. , SELINUX_USER The SELinux user for the user's login. If not specified, the system default will be used. sssd-1.13.4/src/man/PaxHeaders.16287/Makefile.in0000644000000000000000000000013212703463544015737 xustar0030 mtime=1460561764.413758904 30 atime=1460561772.661786871 30 ctime=1460561775.959798054 sssd-1.13.4/src/man/Makefile.in0000644002412700241270000007765112703463544017433 0ustar00jhrozekjhrozek00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_PROFILE_CATALOGS_TRUE@am__append_1 = --stringparam profile.condition "$(CONDS)" @BUILD_SAMBA_TRUE@am__append_2 = sssd-ipa.5 sssd-ad.5 @BUILD_SSH_TRUE@am__append_3 = sss_ssh_authorizedkeys.1 sss_ssh_knownhostsproxy.1 @BUILD_SUDO_TRUE@am__append_4 = sssd-sudo.5 @BUILD_IFP_TRUE@am__append_5 = sssd-ifp.5 @BUILD_NFS_IDMAP_TRUE@am__append_6 = sss_rpcidmapd.5 subdir = src/man ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ $(top_srcdir)/version.m4 $(top_srcdir)/src/build_macros.m4 \ $(top_srcdir)/src/external/platform.m4 \ $(top_srcdir)/src/conf_macros.m4 \ $(top_srcdir)/src/external/pkg.m4 \ $(top_srcdir)/src/external/libpopt.m4 \ $(top_srcdir)/src/external/libtalloc.m4 \ $(top_srcdir)/src/external/libtdb.m4 \ $(top_srcdir)/src/external/libtevent.m4 \ $(top_srcdir)/src/external/libldb.m4 \ $(top_srcdir)/src/external/libdhash.m4 \ $(top_srcdir)/src/external/libcollection.m4 \ $(top_srcdir)/src/external/libini_config.m4 \ $(top_srcdir)/src/external/pam.m4 \ $(top_srcdir)/src/external/ldap.m4 \ $(top_srcdir)/src/external/libpcre.m4 \ $(top_srcdir)/src/external/krb5.m4 \ $(top_srcdir)/src/external/libcares.m4 \ $(top_srcdir)/src/external/libcmocka.m4 \ $(top_srcdir)/src/external/docbook.m4 \ $(top_srcdir)/src/external/sizes.m4 \ $(top_srcdir)/src/external/python.m4 \ $(top_srcdir)/src/external/selinux.m4 \ $(top_srcdir)/src/external/crypto.m4 \ $(top_srcdir)/src/external/nscd.m4 \ $(top_srcdir)/src/external/nsupdate.m4 \ $(top_srcdir)/src/external/libkeyutils.m4 \ $(top_srcdir)/src/external/libnl.m4 \ $(top_srcdir)/src/external/systemd.m4 \ $(top_srcdir)/src/external/pac_responder.m4 \ $(top_srcdir)/src/external/cifsidmap.m4 \ $(top_srcdir)/src/external/signal.m4 \ $(top_srcdir)/src/external/inotify.m4 \ $(top_srcdir)/src/external/samba.m4 \ $(top_srcdir)/src/external/sasl.m4 \ $(top_srcdir)/src/external/configlib.m4 \ $(top_srcdir)/src/external/libnfsidmap.m4 \ $(top_srcdir)/src/external/cwrap.m4 \ $(top_srcdir)/src/external/libresolv.m4 \ $(top_srcdir)/src/external/intgcheck.m4 \ $(top_srcdir)/src/external/libaugeas.m4 \ $(top_srcdir)/src/external/libunistring.m4 \ $(top_srcdir)/src/external/glib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \ "$(DESTDIR)$(man8dir)" man5dir = $(mandir)/man5 man8dir = $(mandir)/man8 NROFF = nroff MANS = $(man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUGEAS_CFLAGS = @AUGEAS_CFLAGS@ AUGEAS_LIBS = @AUGEAS_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CARES_CFLAGS = @CARES_CFLAGS@ CARES_LIBS = @CARES_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CMOCKA_CFLAGS = @CMOCKA_CFLAGS@ CMOCKA_LIBS = @CMOCKA_LIBS@ COLLECTION_CFLAGS = @COLLECTION_CFLAGS@ COLLECTION_LIBS = @COLLECTION_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPTO_CFLAGS = @CRYPTO_CFLAGS@ CRYPTO_LIBS = @CRYPTO_LIBS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHASH_CFLAGS = @DHASH_CFLAGS@ DHASH_LIBS = @DHASH_LIBS@ DLLTOOL = @DLLTOOL@ DOCBOOK_XSLT = @DOCBOOK_XSLT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB2_CFLAGS = @GLIB2_CFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMSGFMT = @GMSGFMT@ GPO_DEFAULT = @GPO_DEFAULT@ GREP = @GREP@ HAVE_FAKEROOT = @HAVE_FAKEROOT@ HAVE_LDAPMODIFY = @HAVE_LDAPMODIFY@ HAVE_MANPAGES = @HAVE_MANPAGES@ HAVE_NSS_WRAPPER = @HAVE_NSS_WRAPPER@ HAVE_PYTHON2 = @HAVE_PYTHON2@ HAVE_PYTHON2_BINDINGS = @HAVE_PYTHON2_BINDINGS@ HAVE_PYTHON3 = @HAVE_PYTHON3@ HAVE_PYTHON3_BINDINGS = @HAVE_PYTHON3_BINDINGS@ HAVE_SELINUX = @HAVE_SELINUX@ HAVE_SEMANAGE = @HAVE_SEMANAGE@ HAVE_SYSTEMD = @HAVE_SYSTEMD@ HAVE_UID_WRAPPER = @HAVE_UID_WRAPPER@ INI_CONFIG_CFLAGS = @INI_CONFIG_CFLAGS@ INI_CONFIG_LIBS = @INI_CONFIG_LIBS@ INI_CONFIG_V0_CFLAGS = @INI_CONFIG_V0_CFLAGS@ INI_CONFIG_V0_LIBS = @INI_CONFIG_V0_LIBS@ INI_CONFIG_V1_1_CFLAGS = @INI_CONFIG_V1_1_CFLAGS@ INI_CONFIG_V1_1_LIBS = @INI_CONFIG_V1_1_LIBS@ INI_CONFIG_V1_CFLAGS = @INI_CONFIG_V1_CFLAGS@ INI_CONFIG_V1_LIBS = @INI_CONFIG_V1_LIBS@ INOTIFY_LIBS = @INOTIFY_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ JOURNALD_CFLAGS = @JOURNALD_CFLAGS@ JOURNALD_LIBS = @JOURNALD_LIBS@ KEYUTILS_LIBS = @KEYUTILS_LIBS@ KRB5_CFLAGS = @KRB5_CFLAGS@ KRB5_CONFIG = @KRB5_CONFIG@ KRB5_LIBS = @KRB5_LIBS@ LD = @LD@ LDB_CFLAGS = @LDB_CFLAGS@ LDB_LIBS = @LDB_LIBS@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ LIBADD_DLOPEN = @LIBADD_DLOPEN@ LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ LIBNL1_LIBS = @LIBNL1_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ NDR_KRB5PAC_CFLAGS = @NDR_KRB5PAC_CFLAGS@ NDR_KRB5PAC_LIBS = @NDR_KRB5PAC_LIBS@ NDR_NBT_CFLAGS = @NDR_NBT_CFLAGS@ NDR_NBT_LIBS = @NDR_NBT_LIBS@ NFSIDMAP_CFLAGS = @NFSIDMAP_CFLAGS@ NFSIDMAP_LIBS = @NFSIDMAP_LIBS@ NFSIDMAP_OBJ = @NFSIDMAP_OBJ@ NM = @NM@ NMEDIT = @NMEDIT@ NSCD = @NSCD@ NSCD_PATH = @NSCD_PATH@ NSS_CFLAGS = @NSS_CFLAGS@ NSS_LIBS = @NSS_LIBS@ NSUPDATE = @NSUPDATE@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENLDAP_CFLAGS = @OPENLDAP_CFLAGS@ OPENLDAP_LIBS = @OPENLDAP_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_LIBS = @PAM_LIBS@ PAM_MISC_LIBS = @PAM_MISC_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PKG_CONFIG = @PKG_CONFIG@ ######################## # MANPAGE TRANSLATIONS # ######################## PO4A = @PO4A@ POPT_CFLAGS = @POPT_CFLAGS@ POPT_LIBS = @POPT_LIBS@ POSUB = @POSUB@ PRERELEASE_VERSION = @PRERELEASE_VERSION@ PYTEST = @PYTEST@ PYTHON = @PYTHON@ PYTHON2 = @PYTHON2@ PYTHON2_CFLAGS = @PYTHON2_CFLAGS@ PYTHON2_EXEC_PREFIX = @PYTHON2_EXEC_PREFIX@ PYTHON2_INCLUDES = @PYTHON2_INCLUDES@ PYTHON2_LIBS = @PYTHON2_LIBS@ PYTHON2_PREFIX = @PYTHON2_PREFIX@ PYTHON2_VERSION = @PYTHON2_VERSION@ PYTHON3 = @PYTHON3@ PYTHON3_CFLAGS = @PYTHON3_CFLAGS@ PYTHON3_EXEC_PREFIX = @PYTHON3_EXEC_PREFIX@ PYTHON3_INCLUDES = @PYTHON3_INCLUDES@ PYTHON3_LIBS = @PYTHON3_LIBS@ PYTHON3_PREFIX = @PYTHON3_PREFIX@ PYTHON3_VERSION = @PYTHON3_VERSION@ PYTHON_CONFIG = @PYTHON_CONFIG@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RESOLV_CFLAGS = @RESOLV_CFLAGS@ RESOLV_LIBS = @RESOLV_LIBS@ SASL_CFLAGS = @SASL_CFLAGS@ SASL_LIBS = @SASL_LIBS@ SED = @SED@ SELINUX_LIBS = @SELINUX_LIBS@ SEMANAGE_LIBS = @SEMANAGE_LIBS@ SET_MAKE = @SET_MAKE@ SGML_CATALOG_FILES = @SGML_CATALOG_FILES@ SHELL = @SHELL@ SLAPD = @SLAPD@ SMBCLIENT_CFLAGS = @SMBCLIENT_CFLAGS@ SMBCLIENT_LIBS = @SMBCLIENT_LIBS@ SSSD_USER = @SSSD_USER@ STRIP = @STRIP@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ TALLOC_CFLAGS = @TALLOC_CFLAGS@ TALLOC_LIBS = @TALLOC_LIBS@ TDB_CFLAGS = @TDB_CFLAGS@ TDB_LIBS = @TDB_LIBS@ TEST_DIR = @TEST_DIR@ TEVENT_CFLAGS = @TEVENT_CFLAGS@ TEVENT_LIBS = @TEVENT_LIBS@ UNICODE_LIBS = @UNICODE_LIBS@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ XMLLINT = @XMLLINT@ XSLTPROC = @XSLTPROC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appmodpath = @appmodpath@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cifspluginpath = @cifspluginpath@ config_def_ccache_dir = @config_def_ccache_dir@ config_def_ccname_template = @config_def_ccname_template@ datadir = @datadir@ datarootdir = @datarootdir@ dbpath = @dbpath@ docdir = @docdir@ dvidir = @dvidir@ environment_file = @environment_file@ exec_prefix = @exec_prefix@ gpocachepath = @gpocachepath@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ krb5authdatapluginpath = @krb5authdatapluginpath@ krb5pluginpath = @krb5pluginpath@ krb5rcachedir = @krb5rcachedir@ ldblibdir = @ldblibdir@ libdir = @libdir@ libexecdir = @libexecdir@ libwbclient_version = @libwbclient_version@ libwbclient_version_info = @libwbclient_version_info@ localedir = @localedir@ localstatedir = @localstatedir@ logpath = @logpath@ mandir = @mandir@ mcpath = @mcpath@ mkdir_p = @mkdir_p@ nfsidmaplibdir = @nfsidmaplibdir@ nfslibpath = @nfslibpath@ nsslibdir = @nsslibdir@ oldincludedir = @oldincludedir@ pammoddir = @pammoddir@ pdfdir = @pdfdir@ pidpath = @pidpath@ pipepath = @pipepath@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ pluginpath = @pluginpath@ polkitdir = @polkitdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pubconfpath = @pubconfpath@ py2execdir = @py2execdir@ py3execdir = @py3execdir@ pyexecdir = @pyexecdir@ python2dir = @python2dir@ python3dir = @python3dir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedbuilddir = @sharedbuilddir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sudolibpath = @sudolibpath@ sysconfdir = @sysconfdir@ systemdconfdir = @systemdconfdir@ systemdunitdir = @systemdunitdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ # The following variable is dependent on placement of this file top_builddir = ../.. top_srcdir = @top_srcdir@ ############ # MANPAGES # ############ # If no conditions are given, *all* conditionals are expanded. We don't want # to include any conditions by default, so we need to pass a phony conditional # conditionals are delimeted with a semicolon @BUILD_SUDO_TRUE@SUDO_CONDS = ;with_sudo @BUILD_AUTOFS_TRUE@AUTOFS_CONDS = ;with_autofs @BUILD_SSH_TRUE@SSH_CONDS = ;with_ssh @BUILD_PAC_RESPONDER_TRUE@PAC_RESPONDER_CONDS = ;with_pac_responder @BUILD_IFP_TRUE@IFP_CONDS = ;with_ifp @GPO_DEFAULT_ENFORCING_FALSE@GPO_CONDS = ;gpo_default_permissive @GPO_DEFAULT_ENFORCING_TRUE@GPO_CONDS = ;gpo_default_enforcing CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(PAC_RESPONDER_CONDS)$(IFP_CONDS)$(GPO_CONDS) XMLLINT_FLAGS = --catalogs --postvalid --nonet --noent --xinclude --noout XSLTPROC_FLAGS = --catalogs --xinclude --nonet $(am__append_1) EXTRA_DIST = $(wildcard $(srcdir)/*.xml) $(wildcard \ $(srcdir)/include/*.xml) $(POTFILE) $(PO4A_CONFIG) man_MANS = sss_useradd.8 sss_userdel.8 sss_usermod.8 sss_groupadd.8 \ sss_groupdel.8 sss_groupmod.8 sssd.8 sssd.conf.5 sssd-ldap.5 \ sssd-krb5.5 sssd-simple.5 sssd_krb5_locator_plugin.8 \ sss_groupshow.8 pam_sss.8 sss_obfuscate.8 sss_cache.8 \ sss_debuglevel.8 sss_seed.8 sss_override.8 $(am__append_2) \ $(am__append_3) $(am__append_4) $(am__append_5) \ $(am__append_6) SUFFIXES = .1.xml .1 .3.xml .3 .5.xml .5 .8.xml .8 PACKAGE_DOC = sssd-docs POTFILE = po/$(PACKAGE_DOC).pot PO4A_CONFIG = po/po4a.cfg # Extract the list of languages from the po4a config file. LINGUAS_DIST = `$(SED) -ne 's/^.*\[po4a_langs\] \(.*\)$$/\1/p' $(srcdir)/$(PO4A_CONFIG)` PO4A_COMMON_OPTS = --option doctype=docbook \ --package-name $(PACKAGE_DOC) \ --variable builddir=$(CURDIR) \ --package-version $(PACKAGE_VERSION) \ --msgid-bugs-address sssd-devel@redhat.com \ --copyright-holder "Red Hat" PO4A_BUILD_OPTS = $(PO4A_COMMON_OPTS) --no-backups XML_DOC = $(wildcard $(srcdir)/*.xml) $(wildcard $(srcdir)/include/*.xml) @HAVE_PO4A_TRUE@CFG_PAGES = $(addprefix $(srcdir)/, $(shell grep '\[type:docbook\]' $(PO4A_CONFIG) | awk '{print $$2}' | tr '\n' ' ')) @HAVE_PO4A_TRUE@NONTRANSLATED_PAGES = $(filter-out $(CFG_PAGES), $(XML_DOC)) all: all-am .SUFFIXES: .SUFFIXES: .1.xml .1 .3.xml .3 .5.xml .5 .8.xml .8 $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/man/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/man/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-man5: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man5dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.5[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ done; } uninstall-man5: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man5dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.5[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) install-man8: $(man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(man_MANS)'; \ test -n "$(man8dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.8[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ done; } uninstall-man8: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man8dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.8[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: @HAVE_PO4A_FALSE@dist-hook: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile $(MANS) all-local installdirs: for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic distclean-local dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-data-local install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-man5 install-man8 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic \ maintainer-clean-local mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool \ mostlyclean-local pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local uninstall-man uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 .MAKE: install-am install-strip .PHONY: all all-am all-local check check-am clean clean-generic \ clean-libtool clean-local cscopelist-am ctags-am dist-hook \ distclean distclean-generic distclean-libtool distclean-local \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-data-local \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-man1 install-man5 install-man8 install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic maintainer-clean-local mostlyclean \ mostlyclean-generic mostlyclean-libtool mostlyclean-local pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am uninstall-local \ uninstall-man uninstall-man1 uninstall-man5 uninstall-man8 .PRECIOUS: Makefile #Special Rules: export SGML_CATALOG_FILES DOCBOOK_XSLT ?= http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $(NULL) .1.xml.1: $(XMLLINT) $(XMLLINT_FLAGS) $< $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(DOCBOOK_XSLT) $< .3.xml.3: $(XMLLINT) $(XMLLINT_FLAGS) $< $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(DOCBOOK_XSLT) $< .5.xml.5: $(XMLLINT) $(XMLLINT_FLAGS) $< $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(DOCBOOK_XSLT) $< .8.xml.8: $(XMLLINT) $(XMLLINT_FLAGS) $< $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(DOCBOOK_XSLT) $< # If the user has not defined it let's use the default. LINGUAS ?= $(LINGUAS_DIST) # FIXME: Use a stamp file until po4a supports them internally. @HAVE_PO4A_TRUE@man.stamp: $(XML_DOC) $(POTFILE) $(PO4A_CONFIG) @HAVE_PO4A_TRUE@ cd $(srcdir) && \ @HAVE_PO4A_TRUE@ $(PO4A) $(PO4A_BUILD_OPTS) $(PO4A_CONFIG) @HAVE_PO4A_TRUE@ touch $@ @HAVE_PO4A_TRUE@update-po: @HAVE_PO4A_TRUE@ @if test x"$(NONTRANSLATED_PAGES)" != "x"; then \ @HAVE_PO4A_TRUE@ echo "The following pages are not translated" $(NONTRANSLATED_PAGES); \ @HAVE_PO4A_TRUE@ exit 1; \ @HAVE_PO4A_TRUE@ fi @HAVE_PO4A_TRUE@ cd $(srcdir) && \ @HAVE_PO4A_TRUE@ $(PO4A) $(PO4A_BUILD_OPTS) --force $(PO4A_CONFIG) @HAVE_PO4A_TRUE@dist-hook: man.stamp @HAVE_PO4A_TRUE@ if [ -f man.stamp ]; then \ @HAVE_PO4A_TRUE@ cp man.stamp $(distdir); \ @HAVE_PO4A_TRUE@ for lang in $(LINGUAS_DIST); do \ @HAVE_PO4A_TRUE@ cp $(srcdir)/po/$$lang.po $(distdir)/po; \ @HAVE_PO4A_TRUE@ $(mkdir_p) $(distdir)/$$lang; \ @HAVE_PO4A_TRUE@ cp -r $(builddir)/$$lang $(distdir)/; \ @HAVE_PO4A_TRUE@ done; \ @HAVE_PO4A_TRUE@ else \ @HAVE_PO4A_TRUE@ cp $(srcdir)/man.stamp $(distdir); \ @HAVE_PO4A_TRUE@ for lang in $(LINGUAS_DIST); do \ @HAVE_PO4A_TRUE@ cp $(srcdir)/po/$$lang.po $(distdir)/po; \ @HAVE_PO4A_TRUE@ $(mkdir_p) $(distdir)/$$lang; \ @HAVE_PO4A_TRUE@ cp -r $(srcdir)/$$lang $(distdir)/; \ @HAVE_PO4A_TRUE@ done; \ @HAVE_PO4A_TRUE@ fi @HAVE_PO4A_TRUE@clean-local-no: @HAVE_PO4A_TRUE@clean-local-yes: @HAVE_PO4A_TRUE@ for lang in $(LINGUAS); do \ @HAVE_PO4A_TRUE@ if [ -d $$lang ]; then \ @HAVE_PO4A_TRUE@ rm -rf $$lang; \ @HAVE_PO4A_TRUE@ fi \ @HAVE_PO4A_TRUE@ done @HAVE_PO4A_TRUE@ rm -f $(man_MANS) @HAVE_PO4A_TRUE@ rm -f man.stamp @HAVE_PO4A_FALSE@man.stamp: $(XML_DOC) @HAVE_PO4A_FALSE@ touch $@ @HAVE_PO4A_FALSE@clean-local-no: @HAVE_PO4A_FALSE@clean-local-yes: @HAVE_PO4A_FALSE@ rm -f $(man_MANS) @HAVE_PO4A_FALSE@ rm -f man.stamp clean-local: clean-local-@USE_NLS@ distclean-local: clean-local-@USE_NLS@ mostlyclean-local: clean-local-@USE_NLS@ maintainer-clean-local: clean-local-@USE_NLS@ # Generate translated manual pages all-local: all-local-@USE_NLS@ all-local-no: all-local-yes: man.stamp if [ -z $$recursion ]; then \ for lang in $(LINGUAS); do \ if [ -d $$lang ]; then \ sources=$$(ls -1 $$lang/*.xml); \ manpages=$$(echo $$sources | $(SED) 's/\.xml//g'); \ $(MAKE) recursion=1 man_MANS="$$manpages"; \ fi \ done \ fi install-data-local: install-data-local-@USE_NLS@ install-data-local-no: install-data-local-yes: for lang in $(LINGUAS); do \ if [ -d $$lang ]; then \ sources=$$(ls -1 $$lang/*.xml); \ manpages=$$(echo $$sources | $(SED) 's/\.xml//g'); \ $(MAKE) install-man \ mandir="$(mandir)/$$lang" \ man_MANS="$$manpages"; \ fi \ done uninstall-local: uninstall-local-@USE_NLS@ uninstall-local-no: uninstall-local-yes: for lang in $(LINGUAS); do \ if [ -d $$lang ]; then \ sources=$$(ls -1 $$lang/*.xml); \ manpages=$$(echo $$sources | $(SED) 's/\.xml//g'); \ $(MAKE) uninstall-man \ mandir="$(mandir)/$$lang" \ man_MANS="$$manpages"; \ fi \ done # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: sssd-1.13.4/src/man/PaxHeaders.16287/sss_ssh_authorizedkeys.1.xml0000644000000000000000000000007212703456111021365 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.978798118 sssd-1.13.4/src/man/sss_ssh_authorizedkeys.1.xml0000644002412700241270000000765412703456111023052 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_ssh_authorizedkeys 1 sss_ssh_authorizedkeys get OpenSSH authorized keys sss_ssh_authorizedkeys options USER DESCRIPTION sss_ssh_authorizedkeys acquires SSH public keys for user USER and outputs them in OpenSSH authorized_keys format (see the AUTHORIZED_KEYS FILE FORMAT section of sshd 8 for more information). sshd 8 can be configured to use sss_ssh_authorizedkeys for public key user authentication if it is compiled with support for either AuthorizedKeysCommand or PubkeyAgent sshd_config 5 options. If AuthorizedKeysCommand is supported, sshd 8 can be configured to use it by putting the following directives in sshd_config 5: AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys AuthorizedKeysCommandUser nobody If PubkeyAgent is supported, sshd 8 can be configured to use it by using the following directive for sshd 8 configuration: PubKeyAgent /usr/bin/sss_ssh_authorizedkeys %u OPTIONS , DOMAIN Search for user public keys in SSSD domain DOMAIN. EXIT STATUS In case of success, an exit value of 0 is returned. Otherwise, 1 is returned. sssd-1.13.4/src/man/PaxHeaders.16287/sssd_krb5_locator_plugin.8.xml0000644000000000000000000000007212703456111021555 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.966798077 sssd-1.13.4/src/man/sssd_krb5_locator_plugin.8.xml0000644002412700241270000000552612703456111023236 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sssd_krb5_locator_plugin 8 sssd_krb5_locator_plugin Kerberos locator plugin DESCRIPTION The Kerberos locator plugin sssd_krb5_locator_plugin is used by the Kerberos provider of sssd 8 to tell the Kerberos libraries what Realm and which KDC to use. Typically this is done in krb5.conf 5 which is always read by the Kerberos libraries. To simplify the configuration the Realm and the KDC can be defined in sssd.conf 5 as described in sssd-krb5 5 sssd 8 puts the Realm and the name or IP address of the KDC into the environment variables SSSD_KRB5_REALM and SSSD_KRB5_KDC respectively. When sssd_krb5_locator_plugin is called by the kerberos libraries it reads and evaluates these variables and returns them to the libraries. NOTES Not all Kerberos implementations support the use of plugins. If sssd_krb5_locator_plugin is not available on your system you have to edit /etc/krb5.conf to reflect your Kerberos setup. If the environment variable SSSD_KRB5_LOCATOR_DEBUG is set to any value debug messages will be sent to stderr. sssd-1.13.4/src/man/PaxHeaders.16287/sss_groupadd.8.xml0000644000000000000000000000007212703456111017252 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.975798108 sssd-1.13.4/src/man/sss_groupadd.8.xml0000644002412700241270000000412012703456111020720 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_groupadd 8 sss_groupadd create a new group sss_groupadd options GROUP DESCRIPTION sss_groupadd creates a new group. These groups are compatible with POSIX groups, with the additional feature that they can contain other groups as members. OPTIONS , GID Set the GID of the group to the value of GID. If not given, it is chosen automatically. sssd-1.13.4/src/man/PaxHeaders.16287/sss_rpcidmapd.5.xml0000644000000000000000000000007212703456111017405 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.981798128 sssd-1.13.4/src/man/sss_rpcidmapd.5.xml0000644002412700241270000001037312703456111021062 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss rpc.idmapd plugin Noam Meltzer Primary Data Inc. Developer (2013-2014) Noam Meltzer Developer (2014-) tsnoam@gmail.com sss_rpcidmapd 5 File Formats and Conventions sss_rpcidmapd sss plugin configuration directives for rpc.idmapd CONFIGURATION FILE rpc.idmapd configuration file is usually found at /etc/idmapd.conf. See idmapd.conf 5 for more information. SSS CONFIGURATION EXTENSION Enable SSS plugin In section [Translation], modify/set Method attribute to contain sss. [sss] config section In order to change the default of one of the configuration attributes of the sss plugin listed below you will need to create a config section for it, named [sss]. Configuration attributes memcache (bool) Indicates whether or not to use memcache optimisation technique. Default: True SSSD INTEGRATION The sss plugin requires the NSS Responder to be enabled in sssd. The attribute use_fully_qualified_names must be enabled on all domains (NFSv4 clients expect a fully qualified name to be sent on the wire). EXAMPLE The following example shows a minimal idmapd.conf which makes use of the sss plugin. [General] Verbosity = 2 # domain must be synced between NFSv4 server and clients # Solaris/Illumos/AIX use "localdomain" as default! Domain = default [Mapping] Nobody-User = nfsnobody Nobody-Group = nfsnobody [Translation] Method = sss SEE ALSO sssd8 , idmapd.conf 5 sssd-1.13.4/src/man/PaxHeaders.16287/pam_sss.8.xml0000644000000000000000000000007312703456111016223 xustar0029 atime=1460561751.63671558 30 ctime=1460561775.964798071 sssd-1.13.4/src/man/pam_sss.8.xml0000644002412700241270000001730012703456111017674 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages SSSD The SSSD upstream - http://fedorahosted.org/sssd pam_sss 8 pam_sss PAM module for SSSD pam_sss.so quiet forward_pass use_first_pass use_authtok retry=N ignore_unknown_user ignore_authinfo_unavail domains=X DESCRIPTION pam_sss.so is the PAM interface to the System Security Services daemon (SSSD). Errors and results are logged through syslog(3) with the LOG_AUTHPRIV facility. OPTIONS Suppress log messages for unknown users. If is set the entered password is put on the stack for other PAM modules to use. The argument use_first_pass forces the module to use a previous stacked modules password and will never prompt the user - if no password is available or the password is not appropriate, the user will be denied access. When password changing enforce the module to set the new password to the one provided by a previously stacked password module. If specified the user is asked another N times for a password if authentication fails. Default is 0. Please note that this option might not work as expected if the application calling PAM handles the user dialog on its own. A typical example is sshd with . If this option is specified and the user does not exist, the PAM module will return PAM_IGNORE. This causes the PAM framework to ignore this module. Specifies that the PAM module should return PAM_IGNORE if it cannot contact the SSSD daemon. This causes the PAM framework to ignore this module. Allows the administrator to restrict the domains a particular PAM service is allowed to authenticate against. The format is a comma-separated list of SSSD domain names, as specified in the sssd.conf file. NOTE: Must be used in conjunction with the pam_trusted_users and pam_public_domains options. Please see the sssd.conf 5 manual page for more information on these two PAM responder options. MODULE TYPES PROVIDED All module types (, , and ) are provided. FILES If a password reset by root fails, because the corresponding SSSD provider does not support password resets, an individual message can be displayed. This message can e.g. contain instructions about how to reset a password. The message is read from the file pam_sss_pw_reset_message.LOC where LOC stands for a locale string returned by setlocale3 . If there is no matching file the content of pam_sss_pw_reset_message.txt is displayed. Root must be the owner of the files and only root may have read and write permissions while all other users must have only read permissions. These files are searched in the directory /etc/sssd/customize/DOMAIN_NAME/. If no matching file is present a generic message is displayed. sssd-1.13.4/src/man/PaxHeaders.16287/sssd-ifp.5.xml0000644000000000000000000000007212703456111016302 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.977798115 sssd-1.13.4/src/man/sssd-ifp.5.xml0000644002412700241270000001560712703456111017764 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sssd-ifp 5 File Formats and Conventions sssd-ifp SSSD InfoPipe responder DESCRIPTION This manual page describes the configuration of the InfoPipe responder for sssd 8 . For a detailed syntax reference, refer to the FILE FORMAT section of the sssd.conf 5 manual page. The InfoPipe responder provides a public D-Bus interface accessible over the system bus. The interface allows the user to query information about remote users and groups over the system bus. CONFIGURATION OPTIONS These options can be used to configure the InfoPipe responder. allowed_uids (string) Specifies the comma-separated list of UID values or user names that are allowed to access the InfoPipe responder. User names are resolved to UIDs at startup. Default: 0 (only the root user is allowed to access the InfoPipe responder) Please note that although the UID 0 is used as the default it will be overwritten with this option. If you still want to allow the root user to access the InfoPipe responder, which would be the typical case, you have to add 0 to the list of allowed UIDs as well. user_attributes (string) Specifies the comma-separated list of white or blacklisted attributes. By default, the InfoPipe responder only allows the default set of POSIX attributes to be requested. This set is the same as returned by getpwnam 3 and includes: name user's login name uidNumber user ID gidNumber primary group ID gecos user information, typically full name homeDirectory home directory loginShell user shell It is possible to add another attribute to this set by using +attr_name or explicitly remove an attribute using -attr_name. For example, to allow telephoneNumber but deny loginShell, you would use the following configuration: user_attributes = +telephoneNumber, -loginShell Default: not set. Only the default set of POSIX attributes is allowed. wildcart_limit (integer) Specifies an upper limit on the number of entries that are downloaded during a wildcard lookup that overrides caller-supplied limit. Default: 0 (let the caller set an upper limit) sssd-1.13.4/src/man/PaxHeaders.16287/sssd-ipa.5.xml0000644000000000000000000000007212703456111016275 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.971798094 sssd-1.13.4/src/man/sssd-ipa.5.xml0000644002412700241270000010037412703456111017753 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sssd-ipa 5 File Formats and Conventions sssd-ipa SSSD IPA provider DESCRIPTION This manual page describes the configuration of the IPA provider for sssd 8 . For a detailed syntax reference, refer to the FILE FORMAT section of the sssd.conf 5 manual page. The IPA provider is a back end used to connect to an IPA server. (Refer to the freeipa.org web site for information about IPA servers.) This provider requires that the machine be joined to the IPA domain; configuration is almost entirely self-discovered and obtained directly from the server. The IPA provider accepts the same options used by the sssd-ldap 5 identity provider and the sssd-krb5 5 authentication provider with some exceptions described below. However, it is neither necessary nor recommended to set these options. IPA provider can also be used as an access and chpass provider. As an access provider it uses HBAC (host-based access control) rules. Please refer to freeipa.org for more information about HBAC. No configuration of access provider is required on the client side. The IPA provider will use the PAC responder if the Kerberos tickets of users from trusted realms contain a PAC. To make configuration easier the PAC responder is started automatically if the IPA ID provider is configured. CONFIGURATION OPTIONS Refer to the section DOMAIN SECTIONS of the sssd.conf 5 manual page for details on the configuration of an SSSD domain. ipa_domain (string) Specifies the name of the IPA domain. This is optional. If not provided, the configuration domain name is used. ipa_server, ipa_backup_server (string) The comma-separated list of IP addresses or hostnames of the IPA servers to which SSSD should connect in the order of preference. For more information on failover and server redundancy, see the FAILOVER section. This is optional if autodiscovery is enabled. For more information on service discovery, refer to the SERVICE DISCOVERY section. ipa_hostname (string) Optional. May be set on machines where the hostname(5) does not reflect the fully qualified name used in the IPA domain to identify this host. dyndns_update (boolean) Optional. This option tells SSSD to automatically update the DNS server built into FreeIPA v2 with the IP address of this client. The update is secured using GSS-TSIG. The IP address of the IPA LDAP connection is used for the updates, if it is not otherwise specified by using the dyndns_iface option. NOTE: On older systems (such as RHEL 5), for this behavior to work reliably, the default Kerberos realm must be set properly in /etc/krb5.conf NOTE: While it is still possible to use the old ipa_dyndns_update option, users should migrate to using dyndns_update in their config file. Default: false dyndns_ttl (integer) The TTL to apply to the client DNS record when updating it. If dyndns_update is false this has no effect. This will override the TTL serverside if set by an administrator. NOTE: While it is still possible to use the old ipa_dyndns_ttl option, users should migrate to using dyndns_ttl in their config file. Default: 1200 (seconds) dyndns_iface (string) Optional. Applicable only when dyndns_update is true. Choose the interface or a list of interfaces whose IP addresses should be used for dynamic DNS updates. Special value * implies that IPs from all interfaces should be used. NOTE: While it is still possible to use the old ipa_dyndns_iface option, users should migrate to using dyndns_iface in their config file. Default: Use the IP addresses of the interface which is used for IPA LDAP connection Example: dyndns_iface = em1, vnet1, vnet2 ipa_enable_dns_sites (boolean) Enables DNS sites - location based service discovery. If true and service discovery (see Service Discovery paragraph at the bottom of the man page) is enabled, then the SSSD will first attempt location based discovery using a query that contains "_location.hostname.example.com" and then fall back to traditional SRV discovery. If the location based discovery succeeds, the IPA servers located with the location based discovery are treated as primary servers and the IPA servers located using the traditional SRV discovery are used as back up servers Default: false dyndns_refresh_interval (integer) How often should the back end perform periodic DNS update in addition to the automatic update performed when the back end goes online. This option is optional and applicable only when dyndns_update is true. Default: 0 (disabled) dyndns_update_ptr (bool) Whether the PTR record should also be explicitly updated when updating the client's DNS records. Applicable only when dyndns_update is true. This option should be False in most IPA deployments as the IPA server generates the PTR records automatically when forward records are changed. Default: False (disabled) dyndns_force_tcp (bool) Whether the nsupdate utility should default to using TCP for communicating with the DNS server. Default: False (let nsupdate choose the protocol) dyndns_server (string) The DNS server to use when performing a DNS update. In most setups, it's recommended to leave this option unset. Setting this option makes sense for environments where the DNS server is different from the identity server. Please note that this option will be only used in fallback attempt when previous attempt using autodetected settings failed. Default: None (let nsupdate choose the server) ipa_hbac_search_base (string) Optional. Use the given string as search base for HBAC related objects. Default: Use base DN ipa_host_search_base (string) Optional. Use the given string as search base for host objects. See ldap_search_base for information about configuring multiple search bases. Default: the value of ldap_search_base ipa_selinux_search_base (string) Optional. Use the given string as search base for SELinux user maps. See ldap_search_base for information about configuring multiple search bases. Default: the value of ldap_search_base ipa_subdomains_search_base (string) Optional. Use the given string as search base for trusted domains. See ldap_search_base for information about configuring multiple search bases. Default: the value of cn=trusts,%basedn ipa_master_domain_search_base (string) Optional. Use the given string as search base for master domain object. See ldap_search_base for information about configuring multiple search bases. Default: the value of cn=ad,cn=etc,%basedn ipa_views_search_base (string) Optional. Use the given string as search base for views containers. See ldap_search_base for information about configuring multiple search bases. Default: the value of cn=views,cn=accounts,%basedn krb5_validate (boolean) Verify with the help of krb5_keytab that the TGT obtained has not been spoofed. Default: true Note that this default differs from the traditional Kerberos provider back end. krb5_realm (string) The name of the Kerberos realm. This is optional and defaults to the value of ipa_domain. The name of the Kerberos realm has a special meaning in IPA - it is converted into the base DN to use for performing LDAP operations. krb5_canonicalize (boolean) Specifies if the host and user principal should be canonicalized when connecting to IPA LDAP and also for AS requests. This feature is available with MIT Kerberos >= 1.7 Default: true krb5_use_fast (string) Enables flexible authentication secure tunneling (FAST) for Kerberos pre-authentication. The following options are supported: never use FAST. try to use FAST. If the server does not support FAST, continue the authentication without it. This is equivalent to not setting this option at all. demand to use FAST. The authentication fails if the server does not require fast. Default: try NOTE: SSSD supports FAST only with MIT Kerberos version 1.8 and later. If SSSD is used with an older version of MIT Kerberos, using this option is a configuration error. krb5_confd_path (string) Absolute path of a directory where SSSD should place Kerberos configuration snippets. To disable the creation of the configuration snippets set the parameter to 'none'. Default: not set (krb5.include.d subdirectory of SSSD's pubconf directory) ipa_hbac_refresh (integer) The amount of time between lookups of the HBAC rules against the IPA server. This will reduce the latency and load on the IPA server if there are many access-control requests made in a short period. Default: 5 (seconds) ipa_hbac_selinux (integer) The amount of time between lookups of the SELinux maps against the IPA server. This will reduce the latency and load on the IPA server if there are many user login requests made in a short period. Default: 5 (seconds) ipa_server_mode (boolean) This option should only be set by the IPA installer. The option denotes that the SSSD is running on IPA server and should perform lookups of users and groups from trusted domains differently. Default: false ipa_automount_location (string) The automounter location this IPA client will be using Default: The location named "default" VIEWS AND OVERRIDES SSSD can handle views and overrides which are offered by FreeIPA 4.1 and later version. Since all paths and objectclasses are fixed on the server side there is basically no need to configure anything. For completeness the related options are listed here with their default values. ipa_view_class (string) Objectclass of the view container. Default: nsContainer ipa_view_name (string) Name of the attribute holding the name of the view. Default: cn ipa_overide_object_class (string) Objectclass of the override objects. Default: ipaOverrideAnchor ipa_anchor_uuid (string) Name of the attribute containing the reference to the original object in a remote domain. Default: ipaAnchorUUID ipa_user_override_object_class (string) Name of the objectclass for user overrides. It is used to determine if the found override object is related to a user or a group. User overrides can contain attributes given by ldap_user_name ldap_user_uid_number ldap_user_gid_number ldap_user_gecos ldap_user_home_directory ldap_user_shell ldap_user_ssh_public_key Default: ipaUserOverride ipa_group_override_object_class (string) Name of the objectclass for group overrides. It is used to determine if the found override object is related to a user or a group. Group overrides can contain attributes given by ldap_group_name ldap_group_gid_number Default: ipaGroupOverride SUBDOMAINS PROVIDER The IPA subdomains provider behaves slightly differently if it is configured explicitly or implicitly. If the option 'subdomains_provider = ipa' is found in the domain section of sssd.conf, the IPA subdomains provider is configured explicitly, and all subdomain requests are sent to the IPA server if necessary. If the option 'subdomains_provider' is not set in the domain section of sssd.conf but there is the option 'id_provider = ipa', the IPA subdomains provider is configured implicitly. In this case, if a subdomain request fails and indicates that the server does not support subdomains, i.e. is not configured for trusts, the IPA subdomains provider is disabled. After an hour or after the IPA provider goes online, the subdomains provider is enabled again. EXAMPLE The following example assumes that SSSD is correctly configured and example.com is one of the domains in the [sssd] section. This examples shows only the ipa provider-specific options. [domain/example.com] id_provider = ipa ipa_server = ipaserver.example.com ipa_hostname = myhost.example.com sssd-1.13.4/src/man/PaxHeaders.16287/sss_cache.8.xml0000644000000000000000000000007212703456111016510 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.968798084 sssd-1.13.4/src/man/sss_cache.8.xml0000644002412700241270000001625012703456111020165 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_cache 8 sss_cache perform cache cleanup sss_cache options DESCRIPTION sss_cache invalidates records in SSSD cache. Invalidated records are forced to be reloaded from server as soon as related SSSD backend is online. OPTIONS , Invalidate all cached entries except for sudo rules. , login Invalidate specific user. , Invalidate all user records. This option overrides invalidation of specific user if it was also set. , group Invalidate specific group. , Invalidate all group records. This option overrides invalidation of specific group if it was also set. , netgroup Invalidate specific netgroup. , Invalidate all netgroup records. This option overrides invalidation of specific netgroup if it was also set. , service Invalidate specific service. , Invalidate all service records. This option overrides invalidation of specific service if it was also set. , autofs-map Invalidate specific autofs maps. , Invalidate all autofs maps. This option overrides invalidation of specific map if it was also set. , hostname Invalidate SSH public keys of a specific host. , Invalidate SSH public keys of all hosts. This option overrides invalidation of SSH public keys of specific host if it was also set. , domain Restrict invalidation process only to a particular domain. sssd-1.13.4/src/man/PaxHeaders.16287/Makefile.am0000644000000000000000000000007312703456111015722 xustar0030 atime=1460561764.378758785 29 ctime=1460561775.95879805 sssd-1.13.4/src/man/Makefile.am0000644002412700241270000001310512703456111017372 0ustar00jhrozekjhrozek00000000000000# The following variable is dependent on placement of this file top_builddir = ../.. ############ # MANPAGES # ############ # If no conditions are given, *all* conditionals are expanded. We don't want # to include any conditions by default, so we need to pass a phony conditional if BUILD_SUDO # conditionals are delimeted with a semicolon SUDO_CONDS = ;with_sudo endif if BUILD_AUTOFS AUTOFS_CONDS = ;with_autofs endif if BUILD_SSH SSH_CONDS = ;with_ssh endif if BUILD_PAC_RESPONDER PAC_RESPONDER_CONDS = ;with_pac_responder endif if BUILD_IFP IFP_CONDS = ;with_ifp endif if GPO_DEFAULT_ENFORCING GPO_CONDS = ;gpo_default_enforcing else GPO_CONDS = ;gpo_default_permissive endif CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(PAC_RESPONDER_CONDS)$(IFP_CONDS)$(GPO_CONDS) #Special Rules: export SGML_CATALOG_FILES DOCBOOK_XSLT = @DOCBOOK_XSLT@ DOCBOOK_XSLT ?= http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl XMLLINT_FLAGS = --catalogs --postvalid --nonet --noent --xinclude --noout XSLTPROC_FLAGS = --catalogs --xinclude --nonet if HAVE_PROFILE_CATALOGS XSLTPROC_FLAGS += --stringparam profile.condition "$(CONDS)" endif EXTRA_DIST = $(wildcard $(srcdir)/*.xml) $(wildcard $(srcdir)/include/*.xml) man_MANS = \ sss_useradd.8 sss_userdel.8 sss_usermod.8 \ sss_groupadd.8 sss_groupdel.8 sss_groupmod.8 \ sssd.8 sssd.conf.5 sssd-ldap.5 \ sssd-krb5.5 sssd-simple.5 \ sssd_krb5_locator_plugin.8 sss_groupshow.8 \ pam_sss.8 sss_obfuscate.8 sss_cache.8 sss_debuglevel.8 sss_seed.8 \ sss_override.8 $(NULL) if BUILD_SAMBA man_MANS += sssd-ipa.5 sssd-ad.5 endif if BUILD_SSH man_MANS += sss_ssh_authorizedkeys.1 sss_ssh_knownhostsproxy.1 endif if BUILD_SUDO man_MANS += sssd-sudo.5 endif if BUILD_IFP man_MANS += sssd-ifp.5 endif if BUILD_NFS_IDMAP man_MANS += sss_rpcidmapd.5 endif SUFFIXES = .1.xml .1 .3.xml .3 .5.xml .5 .8.xml .8 .1.xml.1: $(XMLLINT) $(XMLLINT_FLAGS) $< $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(DOCBOOK_XSLT) $< .3.xml.3: $(XMLLINT) $(XMLLINT_FLAGS) $< $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(DOCBOOK_XSLT) $< .5.xml.5: $(XMLLINT) $(XMLLINT_FLAGS) $< $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(DOCBOOK_XSLT) $< .8.xml.8: $(XMLLINT) $(XMLLINT_FLAGS) $< $(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) $(DOCBOOK_XSLT) $< ######################## # MANPAGE TRANSLATIONS # ######################## PO4A=@PO4A@ SED=@SED@ PACKAGE_DOC=sssd-docs POTFILE = po/$(PACKAGE_DOC).pot PO4A_CONFIG = po/po4a.cfg # Extract the list of languages from the po4a config file. LINGUAS_DIST = `$(SED) -ne 's/^.*\[po4a_langs\] \(.*\)$$/\1/p' $(srcdir)/$(PO4A_CONFIG)` # If the user has not defined it let's use the default. LINGUAS ?= $(LINGUAS_DIST) PO4A_COMMON_OPTS = --option doctype=docbook \ --package-name $(PACKAGE_DOC) \ --variable builddir=$(CURDIR) \ --package-version $(PACKAGE_VERSION) \ --msgid-bugs-address sssd-devel@redhat.com \ --copyright-holder "Red Hat" PO4A_BUILD_OPTS = $(PO4A_COMMON_OPTS) --no-backups EXTRA_DIST += \ $(POTFILE)\ $(PO4A_CONFIG) XML_DOC = $(wildcard $(srcdir)/*.xml) $(wildcard $(srcdir)/include/*.xml) if HAVE_PO4A CFG_PAGES = $(addprefix $(srcdir)/, $(shell grep '\[type:docbook\]' $(PO4A_CONFIG) | awk '{print $$2}' | tr '\n' ' ')) NONTRANSLATED_PAGES = $(filter-out $(CFG_PAGES), $(XML_DOC)) # FIXME: Use a stamp file until po4a supports them internally. man.stamp: $(XML_DOC) $(POTFILE) $(PO4A_CONFIG) cd $(srcdir) && \ $(PO4A) $(PO4A_BUILD_OPTS) $(PO4A_CONFIG) touch $@ update-po: @if test x"$(NONTRANSLATED_PAGES)" != "x"; then \ echo "The following pages are not translated" $(NONTRANSLATED_PAGES); \ exit 1; \ fi cd $(srcdir) && \ $(PO4A) $(PO4A_BUILD_OPTS) --force $(PO4A_CONFIG) dist-hook: man.stamp if [ -f man.stamp ]; then \ cp man.stamp $(distdir); \ for lang in $(LINGUAS_DIST); do \ cp $(srcdir)/po/$$lang.po $(distdir)/po; \ $(mkdir_p) $(distdir)/$$lang; \ cp -r $(builddir)/$$lang $(distdir)/; \ done; \ else \ cp $(srcdir)/man.stamp $(distdir); \ for lang in $(LINGUAS_DIST); do \ cp $(srcdir)/po/$$lang.po $(distdir)/po; \ $(mkdir_p) $(distdir)/$$lang; \ cp -r $(srcdir)/$$lang $(distdir)/; \ done; \ fi clean-local-no: clean-local-yes: for lang in $(LINGUAS); do \ if [ -d $$lang ]; then \ rm -rf $$lang; \ fi \ done rm -f $(man_MANS) rm -f man.stamp else man.stamp: $(XML_DOC) touch $@ clean-local-no: clean-local-yes: rm -f $(man_MANS) rm -f man.stamp endif clean-local: clean-local-@USE_NLS@ distclean-local: clean-local-@USE_NLS@ mostlyclean-local: clean-local-@USE_NLS@ maintainer-clean-local: clean-local-@USE_NLS@ # Generate translated manual pages all-local: all-local-@USE_NLS@ all-local-no: all-local-yes: man.stamp if [ -z $$recursion ]; then \ for lang in $(LINGUAS); do \ if [ -d $$lang ]; then \ sources=$$(ls -1 $$lang/*.xml); \ manpages=$$(echo $$sources | $(SED) 's/\.xml//g'); \ $(MAKE) recursion=1 man_MANS="$$manpages"; \ fi \ done \ fi install-data-local: install-data-local-@USE_NLS@ install-data-local-no: install-data-local-yes: for lang in $(LINGUAS); do \ if [ -d $$lang ]; then \ sources=$$(ls -1 $$lang/*.xml); \ manpages=$$(echo $$sources | $(SED) 's/\.xml//g'); \ $(MAKE) install-man \ mandir="$(mandir)/$$lang" \ man_MANS="$$manpages"; \ fi \ done uninstall-local: uninstall-local-@USE_NLS@ uninstall-local-no: uninstall-local-yes: for lang in $(LINGUAS); do \ if [ -d $$lang ]; then \ sources=$$(ls -1 $$lang/*.xml); \ manpages=$$(echo $$sources | $(SED) 's/\.xml//g'); \ $(MAKE) uninstall-man \ mandir="$(mandir)/$$lang" \ man_MANS="$$manpages"; \ fi \ done sssd-1.13.4/src/man/PaxHeaders.16287/sss_userdel.8.xml0000644000000000000000000000007212703456111017110 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.976798111 sssd-1.13.4/src/man/sss_userdel.8.xml0000644002412700241270000000661512703456111020571 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_userdel 8 sss_userdel delete a user account sss_userdel options LOGIN DESCRIPTION sss_userdel deletes a user identified by login name LOGIN from the system. OPTIONS , Files in the user's home directory will be removed along with the home directory itself and the user's mail spool. Overrides the configuration. , Files in the user's home directory will NOT be removed along with the home directory itself and the user's mail spool. Overrides the configuration. , This option forces sss_userdel to remove the user's home directory and mail spool, even if they are not owned by the specified user. , Before actually deleting the user, terminate all his processes. sssd-1.13.4/src/man/PaxHeaders.16287/sss_override.8.xml0000644000000000000000000000007212703456111017264 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.982798132 sssd-1.13.4/src/man/sss_override.8.xml0000644002412700241270000002531712703456111020745 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_override 8 sss_override create local overrides of user and group attributes sss_override COMMAND options DESCRIPTION sss_override enables to create a client-side view and allows to change selected values of specific user and groups. This change takes effect only on local machine. Overrides data are stored in the SSSD cache. If the cache is deleted, all local overrides are lost. Please note that after the first override is created using any of the following user-add, group-add, user-import or group-import command. SSSD needs to be restarted to take effect. sss_override prints message when a restart is required. AVAILABLE COMMANDS Argument NAME is the name of original object in all commands. It is not possible to override uid or gid to 0. NAME NAME UID GID HOME SHELL GECOS Override attributes of an user. Please be aware that calling this command will replace any previous override for the (NAMEd) user. NAME Remove user overrides. However be aware that overridden attributes might be returned from memory cache. Please see SSSD option memcache_timeout for more details. DOMAIN List all users with set overrides. If DOMAIN parameter is set, only users from the domain are listed. NAME Show user overrides. FILE Import user overrides from FILE. Data format is similar to standard passwd file. The format is: original_name:name:uid:gid:gecos:home:shell where original_name is original name of the user whose attributes should be overridden. The rest of fields correspond to new values. You can omit a value simply by leaving corresponding field empty. Examples: ckent:superman:::::: ckent@krypton.com::501:501:Superman:/home/earth:/bin/bash FILE Export all overridden attributes and store them in FILE. See user-import for data format. NAME NAME GID Override attributes of a group. Please be aware that calling this command will replace any previous override for the (NAMEd) group. NAME Remove group overrides. However be aware that overridden attributes might be returned from memory cache. Please see SSSD option memcache_timeout for more details. DOMAIN List all groups with set overrides. If DOMAIN parameter is set, only groups from the domain are listed. NAME Show group overrides. FILE Import group overrides from FILE. Data format is similar to standard group file. The format is: original_name:name:gid where original_name is original name of the group whose attributes should be overridden. The rest of fields correspond to new values. You can omit a value simply by leaving corresponding field empty. Examples: admins:administrators: Domain Users:Users:501 FILE Export all overridden attributes and store them in FILE. See group-import for data format. COMMON OPTIONS Those options are available with all commands. LEVEL sssd-1.13.4/src/man/PaxHeaders.16287/sss_ssh_knownhostsproxy.1.xml0000644000000000000000000000007212703456111021632 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.975798108 sssd-1.13.4/src/man/sss_ssh_knownhostsproxy.1.xml0000644002412700241270000000744712703456111023317 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_ssh_knownhostsproxy 1 sss_ssh_knownhostsproxy get OpenSSH host keys sss_ssh_knownhostsproxy options HOST PROXY_COMMAND DESCRIPTION sss_ssh_knownhostsproxy acquires SSH host public keys for host HOST, stores them in a custom OpenSSH known_hosts file (see the SSH_KNOWN_HOSTS FILE FORMAT section of sshd 8 for more information) /var/lib/sss/pubconf/known_hosts and estabilishes connection to the host. If PROXY_COMMAND is specified, it is used to create the connection to the host instead of opening a socket. ssh 1 can be configured to use sss_ssh_knownhostsproxy for host key authentication by using the following directives for ssh 1 configuration: ProxyCommand /usr/bin/sss_ssh_knownhostsproxy -p %p %h GlobalKnownHostsFile /var/lib/sss/pubconf/known_hosts OPTIONS , PORT Use port PORT to connect to the host. By default, port 22 is used. , DOMAIN Search for host public keys in SSSD domain DOMAIN. EXIT STATUS In case of success, an exit value of 0 is returned. Otherwise, 1 is returned. sssd-1.13.4/src/man/PaxHeaders.16287/sss_groupdel.8.xml0000644000000000000000000000007212703456111017266 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.980798125 sssd-1.13.4/src/man/sss_groupdel.8.xml0000644002412700241270000000305512703456111020742 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_groupdel 8 sss_groupdel delete a group sss_groupdel options GROUP DESCRIPTION sss_groupdel deletes a group identified by its name GROUP from the system. OPTIONS sssd-1.13.4/src/man/PaxHeaders.16287/sssd-krb5.5.xml0000644000000000000000000000007212703456111016367 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.974798104 sssd-1.13.4/src/man/sssd-krb5.5.xml0000644002412700241270000006514212703456111020050 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sssd-krb5 5 File Formats and Conventions sssd-krb5 SSSD Kerberos provider DESCRIPTION This manual page describes the configuration of the Kerberos 5 authentication backend for sssd 8 . For a detailed syntax reference, please refer to the FILE FORMAT section of the sssd.conf 5 manual page. The Kerberos 5 authentication backend contains auth and chpass providers. It must be paired with an identity provider in order to function properly (for example, id_provider = ldap). Some information required by the Kerberos 5 authentication backend must be provided by the identity provider, such as the user's Kerberos Principal Name (UPN). The configuration of the identity provider should have an entry to specify the UPN. Please refer to the man page for the applicable identity provider for details on how to configure this. This backend also provides access control based on the .k5login file in the home directory of the user. See .k5login5 for more details. Please note that an empty .k5login file will deny all access to this user. To activate this feature, use 'access_provider = krb5' in your SSSD configuration. In the case where the UPN is not available in the identity backend, sssd will construct a UPN using the format username@krb5_realm. CONFIGURATION OPTIONS If the auth-module krb5 is used in an SSSD domain, the following options must be used. See the sssd.conf 5 manual page, section DOMAIN SECTIONS, for details on the configuration of an SSSD domain. krb5_server, krb5_backup_server (string) Specifies the comma-separated list of IP addresses or hostnames of the Kerberos servers to which SSSD should connect, in the order of preference. For more information on failover and server redundancy, see the FAILOVER section. An optional port number (preceded by a colon) may be appended to the addresses or hostnames. If empty, service discovery is enabled; for more information, refer to the SERVICE DISCOVERY section. When using service discovery for KDC or kpasswd servers, SSSD first searches for DNS entries that specify _udp as the protocol and falls back to _tcp if none are found. This option was named krb5_kdcip in earlier releases of SSSD. While the legacy name is recognized for the time being, users are advised to migrate their config files to use krb5_server instead. krb5_realm (string) The name of the Kerberos realm. This option is required and must be specified. krb5_kpasswd, krb5_backup_kpasswd (string) If the change password service is not running on the KDC, alternative servers can be defined here. An optional port number (preceded by a colon) may be appended to the addresses or hostnames. For more information on failover and server redundancy, see the FAILOVER section. NOTE: Even if there are no more kpasswd servers to try, the backend is not switched to operate offline if authentication against the KDC is still possible. Default: Use the KDC krb5_ccachedir (string) Directory to store credential caches. All the substitution sequences of krb5_ccname_template can be used here, too, except %d and %P. The directory is created as private and owned by the user, with permissions set to 0700. Default: /tmp krb5_ccname_template (string) Location of the user's credential cache. Three credential cache types are currently supported: FILE, DIR and KEYRING:persistent. The cache can be specified either as TYPE:RESIDUAL, or as an absolute path, which implies the FILE type. In the template, the following sequences are substituted: %u login name %U login UID %p principal name %r realm name %h home directory %d value of krb5_ccachedir %P the process ID of the SSSD client %% a literal '%' If the template ends with 'XXXXXX' mkstemp(3) is used to create a unique filename in a safe way. When using KEYRING types, the only supported mechanism is KEYRING:persistent:%U, which uses the Linux kernel keyring to store credentials on a per-UID basis. This is also the recommended choice, as it is the most secure and predictable method. The default value for the credential cache name is sourced from the profile stored in the system wide krb5.conf configuration file in the [libdefaults] section. The option name is default_ccache_name. See krb5.conf(5)'s PARAMETER EXPANSION paragraph for additional information on the expansion format defined by krb5.conf. NOTE: Please be aware that libkrb5 ccache expansion template from krb5.conf 5 uses different expansion sequences than SSSD. Default: (from libkrb5) krb5_auth_timeout (integer) Timeout in seconds after an online authentication request or change password request is aborted. If possible, the authentication request is continued offline. Default: 6 krb5_validate (boolean) Verify with the help of krb5_keytab that the TGT obtained has not been spoofed. The keytab is checked for entries sequentially, and the first entry with a matching realm is used for validation. If no entry matches the realm, the last entry in the keytab is used. This process can be used to validate environments using cross-realm trust by placing the appropriate keytab entry as the last entry or the only entry in the keytab file. Default: false krb5_keytab (string) The location of the keytab to use when validating credentials obtained from KDCs. Default: /etc/krb5.keytab krb5_store_password_if_offline (boolean) Store the password of the user if the provider is offline and use it to request a TGT when the provider comes online again. NOTE: this feature is only available on Linux. Passwords stored in this way are kept in plaintext in the kernel keyring and are potentially accessible by the root user (with difficulty). Default: false krb5_renewable_lifetime (string) Request a renewable ticket with a total lifetime, given as an integer immediately followed by a time unit: s for seconds m for minutes h for hours d for days. If there is no unit given, s is assumed. NOTE: It is not possible to mix units. To set the renewable lifetime to one and a half hours, use '90m' instead of '1h30m'. Default: not set, i.e. the TGT is not renewable krb5_lifetime (string) Request ticket with a lifetime, given as an integer immediately followed by a time unit: s for seconds m for minutes h for hours d for days. If there is no unit given s is assumed. NOTE: It is not possible to mix units. To set the lifetime to one and a half hours please use '90m' instead of '1h30m'. Default: not set, i.e. the default ticket lifetime configured on the KDC. krb5_renew_interval (string) The time in seconds between two checks if the TGT should be renewed. TGTs are renewed if about half of their lifetime is exceeded, given as an integer immediately followed by a time unit: s for seconds m for minutes h for hours d for days. If there is no unit given, s is assumed. NOTE: It is not possible to mix units. To set the renewable lifetime to one and a half hours, use '90m' instead of '1h30m'. If this option is not set or is 0 the automatic renewal is disabled. Default: not set krb5_use_fast (string) Enables flexible authentication secure tunneling (FAST) for Kerberos pre-authentication. The following options are supported: never use FAST. This is equivalent to not setting this option at all. try to use FAST. If the server does not support FAST, continue the authentication without it. demand to use FAST. The authentication fails if the server does not require fast. Default: not set, i.e. FAST is not used. NOTE: a keytab is required to use FAST. NOTE: SSSD supports FAST only with MIT Kerberos version 1.8 and later. If SSSD is used with an older version of MIT Kerberos, using this option is a configuration error. krb5_fast_principal (string) Specifies the server principal to use for FAST. krb5_canonicalize (boolean) Specifies if the host and user principal should be canonicalized. This feature is available with MIT Kerberos 1.7 and later versions. Default: false krb5_use_kdcinfo (boolean) Specifies if the SSSD should instruct the Kerberos libraries what realm and which KDCs to use. This option is on by default, if you disable it, you need to configure the Kerberos library using the krb5.conf 5 configuration file. See the sssd_krb5_locator_plugin 8 manual page for more information on the locator plugin. Default: true krb5_use_enterprise_principal (boolean) Specifies if the user principal should be treated as enterprise principal. See section 5 of RFC 6806 for more details about enterprise principals. Default: false (AD provider: true) krb5_map_user (string) The list of mappings is given as a comma-separated list of pairs username:primary where username is a UNIX user name and primary is a user part of a kerberos principal. This mapping is used when user is authenticating using auth_provider = krb5. example: krb5_realm = REALM krb5_map_user = joe:juser,dick:richard joe and dick are UNIX user names and juser and richard are primaries of kerberos principals. For user joe resp. dick SSSD will try to kinit as juser@REALM resp. richard@REALM. Default: not set EXAMPLE The following example assumes that SSSD is correctly configured and FOO is one of the domains in the [sssd] section. This example shows only configuration of Kerberos authentication; it does not include any identity provider. [domain/FOO] auth_provider = krb5 krb5_server = 192.168.1.1 krb5_realm = EXAMPLE.COM sssd-1.13.4/src/man/PaxHeaders.16287/sss_seed.8.xml0000644000000000000000000000007212703456111016365 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.967798081 sssd-1.13.4/src/man/sss_seed.8.xml0000644002412700241270000001472312703456111020045 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_seed 8 sss_seed seed the SSSD cache with a user sss_seed options -D DOMAIN -n USER DESCRIPTION sss_seed seeds the SSSD cache with a user entry and temporary password. If a user entry is already present in the SSSD cache then the entry is updated with the temporary password. OPTIONS , DOMAIN Provide the name of the domain in which the user is a member of. The domain is also used to retrieve user information. The domain must be configured in sssd.conf. The DOMAIN option must be provided. Information retrieved from the domain overrides what is provided in the options. , USER The username of the entry to be created or modified in the cache. The USER option must be provided. , UID Set the UID of the user to UID. , GID Set the GID of the user to GID. , COMMENT Any text string describing the user. Often used as the field for the user's full name. , HOME_DIR Set the home directory of the user to HOME_DIR. , SHELL Set the login shell of the user to SHELL. , Interactive mode for entering user information. This option will only prompt for information not provided in the options or retrieved from the domain. , PASS_FILE Specify file to read user's password from. (if not specified password is prompted for) NOTES The length of the password (or the size of file specified with -p or --password-file option) must be less than or equal to PASS_MAX bytes (64 bytes on systems with no globally-defined PASS_MAX value). sssd-1.13.4/src/man/PaxHeaders.16287/sssd-ad.5.xml0000644000000000000000000000007212703456111016110 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.962798064 sssd-1.13.4/src/man/sssd-ad.5.xml0000644002412700241270000013626612703456111017577 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sssd-ad 5 File Formats and Conventions sssd-ad SSSD Active Directory provider DESCRIPTION This manual page describes the configuration of the AD provider for sssd 8 . For a detailed syntax reference, refer to the FILE FORMAT section of the sssd.conf 5 manual page. The AD provider is a back end used to connect to an Active Directory server. This provider requires that the machine be joined to the AD domain and a keytab is available. The AD provider supports connecting to Active Directory 2008 R2 or later. Earlier versions may work, but are unsupported. The AD provider can be used to get user information and authenticate users from trusted domains. Currently only trusted domains in the same forest are recognized. In addition servers from trusted domains are always auto-discovered. The AD provider accepts the same options used by the sssd-ldap 5 identity provider and the sssd-krb5 5 authentication provider with some exceptions described below. However, it is neither necessary nor recommended to set these options. The AD provider can also be used as an access, chpass, sudo and autofs provider. No configuration of the access provider is required on the client side. By default, the AD provider will map UID and GID values from the objectSID parameter in Active Directory. For details on this, see the ID MAPPING section below. If you want to disable ID mapping and instead rely on POSIX attributes defined in Active Directory, you should set ldap_id_mapping = False In order to retrieve users and groups using POSIX attributes from trusted domains, the AD administrator must make sure that the POSIX attributes are replicated to the Global Catalog. Users, groups and other entities served by SSSD are always treated as case-insensitive in the AD provider for compatibility with Active Directory's LDAP implementation. CONFIGURATION OPTIONS Refer to the section DOMAIN SECTIONS of the sssd.conf 5 manual page for details on the configuration of an SSSD domain. ad_domain (string) Specifies the name of the Active Directory domain. This is optional. If not provided, the configuration domain name is used. For proper operation, this option should be specified as the lower-case version of the long version of the Active Directory domain. The short domain name (also known as the NetBIOS or the flat name) is autodetected by the SSSD. ad_server, ad_backup_server (string) The comma-separated list of hostnames of the AD servers to which SSSD should connect in order of preference. For more information on failover and server redundancy, see the FAILOVER section. This is optional if autodiscovery is enabled. For more information on service discovery, refer to the SERVICE DISCOVERY section. Note: Trusted domains will always auto-discover servers even if the primary server is explicitly defined in the ad_server option. ad_hostname (string) Optional. May be set on machines where the hostname(5) does not reflect the fully qualified name used in the Active Directory domain to identify this host. This field is used to determine the host principal in use in the keytab. It must match the hostname for which the keytab was issued. ad_enable_dns_sites (boolean) Enables DNS sites - location based service discovery. If true and service discovery (see Service Discovery paragraph at the bottom of the man page) is enabled, the SSSD will first attempt to discover the Active Directory server to connect to using the Active Directory Site Discovery and fall back to the DNS SRV records if no AD site is found. The DNS SRV configuration, including the discovery domain, is used during site discovery as well. Default: true ad_access_filter (string) This option specifies LDAP access control filter that the user must match in order to be allowed access. Please note that the access_provider option must be explicitly set to ad in order for this option to have an effect. The option also supports specifying different filters per domain or forest. This extended filter would consist of: KEYWORD:NAME:FILTER. The keyword can be either DOM, FOREST or missing. If the keyword equals to DOM or is missing, then NAME specifies the domain or subdomain the filter applies to. If the keyword equals to FOREST, then the filter equals to all domains from the forest specified by NAME. Multiple filters can be separated with the ? character, similarly to how search bases work. The most specific match is always used. For example, if the option specified filter for a domain the user is a member of and a global filter, the per-domain filter would be applied. If there are more matches with the same specification, the first one is used. Examples: # apply filter on domain called dom1 only: dom1:(memberOf=cn=admins,ou=groups,dc=dom1,dc=com) # apply filter on domain called dom2 only: DOM:dom2:(memberOf=cn=admins,ou=groups,dc=dom2,dc=com) # apply filter on forest called EXAMPLE.COM only: FOREST:EXAMPLE.COM:(memberOf=cn=admins,ou=groups,dc=example,dc=com) Default: Not set ad_site (string) Specify AD site to which client should try to connect. If this option is not provided, the AD site will be auto-discovered. Default: Not set ad_enable_gc (boolean) By default, the SSSD connects to the Global Catalog first to retrieve users from trusted domains and uses the LDAP port to retrieve group memberships or as a fallback. Disabling this option makes the SSSD only connect to the LDAP port of the current AD server. Please note that disabling Global Catalog support does not disable retrieving users from trusted domains. The SSSD would connect to the LDAP port of trusted domains instead. However, Global Catalog must be used in order to resolve cross-domain group memberships. Default: true ad_gpo_access_control (string) This option specifies the operation mode for GPO-based access control functionality: whether it operates in disabled mode, enforcing mode, or permissive mode. Please note that the access_provider option must be explicitly set to ad in order for this option to have an effect. GPO-based access control functionality uses GPO policy settings to determine whether or not a particular user is allowed to logon to a particular host. NOTE: If the operation mode is set to enforcing, it is possible that users that were previously allowed logon access will now be denied logon access (as dictated by the GPO policy settings). In order to facilitate a smooth transition for administrators, a permissive mode is available that will not enforce the access control rules, but will evaluate them and will output a syslog message if access would have been denied. By examining the logs, administrators can then make the necessary changes before setting the mode to enforcing. There are three supported values for this option: disabled: GPO-based access control rules are neither evaluated nor enforced. enforcing: GPO-based access control rules are evaluated and enforced. permissive: GPO-based access control rules are evaluated, but not enforced. Instead, a syslog message will be emitted indicating that the user would have been denied access if this option's value were set to enforcing. Default: permissive Default: enforcing ad_gpo_cache_timeout (integer) The amount of time between lookups of GPO policy files against the AD server. This will reduce the latency and load on the AD server if there are many access-control requests made in a short period. Default: 5 (seconds) ad_gpo_map_interactive (string) A comma-separated list of PAM service names for which GPO-based access control is evaluated based on the InteractiveLogonRight and DenyInteractiveLogonRight policy settings. Note: Using the Group Policy Management Editor this value is called "Allow log on locally" and "Deny log on locally". It is possible to add another PAM service name to the default set by using +service_name or to explicitly remove a PAM service name from the default set by using -service_name. For example, in order to replace a default PAM service name for this logon right (e.g. login) with a custom pam service name (e.g. my_pam_service), you would use the following configuration: ad_gpo_map_interactive = +my_pam_service, -login Default: the default set of PAM service names includes: login su su-l gdm-fingerprint gdm-password gdm-smartcard kdm lightdm lxdm sddm xdm ad_gpo_map_remote_interactive (string) A comma-separated list of PAM service names for which GPO-based access control is evaluated based on the RemoteInteractiveLogonRight and DenyRemoteInteractiveLogonRight policy settings. Note: Using the Group Policy Management Editor this value is called "Allow log on through Remote Desktop Services" and "Deny log on through Remote Desktop Services". It is possible to add another PAM service name to the default set by using +service_name or to explicitly remove a PAM service name from the default set by using -service_name. For example, in order to replace a default PAM service name for this logon right (e.g. sshd) with a custom pam service name (e.g. my_pam_service), you would use the following configuration: ad_gpo_map_remote_interactive = +my_pam_service, -sshd Default: the default set of PAM service names includes: sshd cockpit ad_gpo_map_network (string) A comma-separated list of PAM service names for which GPO-based access control is evaluated based on the NetworkLogonRight and DenyNetworkLogonRight policy settings. Note: Using the Group Policy Management Editor this value is called "Access this computer from the network" and "Deny access to this computer from the network". It is possible to add another PAM service name to the default set by using +service_name or to explicitly remove a PAM service name from the default set by using -service_name. For example, in order to replace a default PAM service name for this logon right (e.g. ftp) with a custom pam service name (e.g. my_pam_service), you would use the following configuration: ad_gpo_map_network = +my_pam_service, -ftp Default: the default set of PAM service names includes: ftp samba ad_gpo_map_batch (string) A comma-separated list of PAM service names for which GPO-based access control is evaluated based on the BatchLogonRight and DenyBatchLogonRight policy settings. Note: Using the Group Policy Management Editor this value is called "Allow log on as a batch job" and "Deny log on as a batch job". It is possible to add another PAM service name to the default set by using +service_name or to explicitly remove a PAM service name from the default set by using -service_name. For example, in order to replace a default PAM service name for this logon right (e.g. crond) with a custom pam service name (e.g. my_pam_service), you would use the following configuration: ad_gpo_map_batch = +my_pam_service, -crond Default: the default set of PAM service names includes: crond ad_gpo_map_service (string) A comma-separated list of PAM service names for which GPO-based access control is evaluated based on the ServiceLogonRight and DenyServiceLogonRight policy settings. Note: Using the Group Policy Management Editor this value is called "Allow log on as a service" and "Deny log on as a service". It is possible to add a PAM service name to the default set by using +service_name. Since the default set is empty, it is not possible to remove a PAM service name from the default set. For example, in order to add a custom pam service name (e.g. my_pam_service), you would use the following configuration: ad_gpo_map_service = +my_pam_service Default: not set ad_gpo_map_permit (string) A comma-separated list of PAM service names for which GPO-based access is always granted, regardless of any GPO Logon Rights. It is possible to add another PAM service name to the default set by using +service_name or to explicitly remove a PAM service name from the default set by using -service_name. For example, in order to replace a default PAM service name for unconditionally permitted access (e.g. sudo) with a custom pam service name (e.g. my_pam_service), you would use the following configuration: ad_gpo_map_permit = +my_pam_service, -sudo Default: the default set of PAM service names includes: sudo sudo-i systemd-user ad_gpo_map_deny (string) A comma-separated list of PAM service names for which GPO-based access is always denied, regardless of any GPO Logon Rights. It is possible to add a PAM service name to the default set by using +service_name. Since the default set is empty, it is not possible to remove a PAM service name from the default set. For example, in order to add a custom pam service name (e.g. my_pam_service), you would use the following configuration: ad_gpo_map_deny = +my_pam_service Default: not set ad_gpo_default_right (string) This option defines how access control is evaluated for PAM service names that are not explicitly listed in one of the ad_gpo_map_* options. This option can be set in two different manners. First, this option can be set to use a default logon right. For example, if this option is set to 'interactive', it means that unmapped PAM service names will be processed based on the InteractiveLogonRight and DenyInteractiveLogonRight policy settings. Alternatively, this option can be set to either always permit or always deny access for unmapped PAM service names. Supported values for this option include: interactive remote_interactive network batch service permit deny Default: deny ad_maximum_machine_account_password_age (integer) SSSD will check once a day if the machine account password is older than the given age in days and try to renew it. A value of 0 will disable the renewal attempt. Default: 30 days ad_machine_account_password_renewal_opts (string) This option should only be used to test the machine account renewal task. The option expect 2 integers seperated by a colon (':'). The first integer defines the interval in seconds how often the task is run. The second specifies the inital timeout in seconds before the task is run for the first time after startup. Default: 86400:750 (24h and 15m) dyndns_update (boolean) Optional. This option tells SSSD to automatically update the Active Directory DNS server with the IP address of this client. The update is secured using GSS-TSIG. As a consequence, the Active Directory administrator only needs to allow secure updates for the DNS zone. The IP address of the AD LDAP connection is used for the updates, if it is not otherwise specified by using the dyndns_iface option. NOTE: On older systems (such as RHEL 5), for this behavior to work reliably, the default Kerberos realm must be set properly in /etc/krb5.conf Default: true dyndns_ttl (integer) The TTL to apply to the client DNS record when updating it. If dyndns_update is false this has no effect. This will override the TTL serverside if set by an administrator. Default: 3600 (seconds) dyndns_iface (string) Optional. Applicable only when dyndns_update is true. Choose the interface or a list of interfaces whose IP addresses should be used for dynamic DNS updates. Special value * implies that IPs from all interfaces should be used. Default: Use the IP addresses of the interface which is used for AD LDAP connection Example: dyndns_iface = em1, vnet1, vnet2 dyndns_refresh_interval (integer) How often should the back end perform periodic DNS update in addition to the automatic update performed when the back end goes online. This option is optional and applicable only when dyndns_update is true. Default: 86400 (24 hours) dyndns_update_ptr (bool) Whether the PTR record should also be explicitly updated when updating the client's DNS records. Applicable only when dyndns_update is true. Default: True dyndns_force_tcp (bool) Whether the nsupdate utility should default to using TCP for communicating with the DNS server. Default: False (let nsupdate choose the protocol) dyndns_server (string) The DNS server to use when performing a DNS update. In most setups, it's recommended to leave this option unset. Setting this option makes sense for environments where the DNS server is different from the identity server. Please note that this option will be only used in fallback attempt when previous attempt using autodetected settings failed. Default: None (let nsupdate choose the server) krb5_use_enterprise_principal (boolean) Specifies if the user principal should be treated as enterprise principal. See section 5 of RFC 6806 for more details about enterprise principals. Default: true Note that this default differs from the traditional Kerberos provider back end. krb5_confd_path (string) Absolute path of a directory where SSSD should place Kerberos configuration snippets. To disable the creation of the configuration snippets set the parameter to 'none'. Default: not set (krb5.include.d subdirectory of SSSD's pubconf directory) EXAMPLE The following example assumes that SSSD is correctly configured and example.com is one of the domains in the [sssd] section. This example shows only the AD provider-specific options. [domain/EXAMPLE] id_provider = ad auth_provider = ad access_provider = ad chpass_provider = ad ad_server = dc1.example.com ad_hostname = client.example.com ad_domain = example.com NOTES The AD access control provider checks if the account is expired. It has the same effect as the following configuration of the LDAP provider: access_provider = ldap ldap_access_order = expire ldap_account_expire_policy = ad However, unless the ad access control provider is explicitly configured, the default access provider is permit. Please note that if you configure an access provider other than ad, you need to set all the connection parameters (such as LDAP URIs and encryption details) manually. When the autofs provider is set to ad, the RFC2307 schema attribute mapping (nisMap, nisObject, ...) is used, because these attributes are included the default Active Directory schema. sssd-1.13.4/src/man/PaxHeaders.16287/sss_groupmod.8.xml0000644000000000000000000000007212703456111017301 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.960798057 sssd-1.13.4/src/man/sss_groupmod.8.xml0000644002412700241270000000515212703456111020755 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_groupmod 8 sss_groupmod modify a group sss_groupmod options GROUP DESCRIPTION sss_groupmod modifies the group to reflect the changes that are specified on the command line. OPTIONS , GROUPS Append this group to groups specified by the GROUPS parameter. The GROUPS parameter is a comma separated list of group names. , GROUPS Remove this group from groups specified by the GROUPS parameter. sssd-1.13.4/src/man/PaxHeaders.16287/sssd.8.xml0000644000000000000000000000007212703456111015531 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.973798101 sssd-1.13.4/src/man/sssd.8.xml0000644002412700241270000001725112703456111017210 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sssd 8 sssd System Security Services Daemon sssd options DESCRIPTION SSSD provides a set of daemons to manage access to remote directories and authentication mechanisms. It provides an NSS and PAM interface toward the system and a pluggable backend system to connect to multiple different account sources as well as D-Bus interface. It is also the basis to provide client auditing and policy services for projects like FreeIPA. It provides a more robust database to store local users as well as extended user data. OPTIONS , LEVEL mode 1: Add a timestamp to the debug messages 0: Disable timestamp in the debug messages Default: 1 mode 1: Add microseconds to the timestamp in debug messages 0: Disable microseconds in timestamp Default: 0 , Send the debug output to files instead of stderr. By default, the log files are stored in /var/log/sssd and there are separate log files for every SSSD service and domain. , Become a daemon after starting up. , Run in the foreground, don't become a daemon. , Specify a non-default config file. The default is /etc/sssd/sssd.conf. For reference on the config file syntax and options, consult the sssd.conf 5 manual page. Print version number and exit. Signals SIGTERM/SIGINT Informs the SSSD to gracefully terminate all of its child processes and then shut down the monitor. SIGHUP Tells the SSSD to stop writing to its current debug file descriptors and to close and reopen them. This is meant to facilitate log rolling with programs like logrotate. SIGUSR1 Tells the SSSD to simulate offline operation for the duration of the offline_timeout parameter. This is useful for testing. The signal can be sent to either the sssd process or any sssd_be process directly. SIGUSR2 Tells the SSSD to go online immediately. This is useful for testing. The signal can be sent to either the sssd process or any sssd_be process directly. NOTES If the environment variable SSS_NSS_USE_MEMCACHE is set to "NO", client applications will not use the fast in memory cache. sssd-1.13.4/src/man/PaxHeaders.16287/sss_debuglevel.8.xml0000644000000000000000000000007212703456111017563 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.970798091 sssd-1.13.4/src/man/sss_debuglevel.8.xml0000644002412700241270000000464712703456111021247 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_debuglevel 8 sss_debuglevel change debug level while SSSD is running sss_debuglevel options NEW_DEBUG_LEVEL DESCRIPTION sss_debuglevel changes debug level of SSSD monitor and providers to NEW_DEBUG_LEVEL while SSSD is running. OPTIONS , Specify a non-default config file. The default is /etc/sssd/sssd.conf. For reference on the config file syntax and options, consult the sssd.conf 5 manual page. NEW_DEBUG_LEVEL sssd-1.13.4/src/man/PaxHeaders.16287/sssd-sudo.5.xml0000644000000000000000000000007212703456111016476 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.979798122 sssd-1.13.4/src/man/sssd-sudo.5.xml0000644002412700241270000001757312703456111020164 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sssd-sudo 5 File Formats and Conventions sssd-sudo Configuring sudo with the SSSD back end DESCRIPTION This manual page describes how to configure sudo 8 to work with sssd 8 and how SSSD caches sudo rules. Configuring sudo to cooperate with SSSD To enable SSSD as a source for sudo rules, add sss to the sudoers entry in nsswitch.conf 5 . For example, to configure sudo to first lookup rules in the standard sudoers 5 file (which should contain rules that apply to local users) and then in SSSD, the nsswitch.conf file should contain the following line: sudoers: files sss More information about configuring the sudoers search order from the nsswitch.conf file as well as information about the LDAP schema that is used to store sudo rules in the directory can be found in sudoers.ldap 5 . Note: in order to use netgroups or IPA hostgroups in sudo rules, you also need to correctly set nisdomainname 1 to your NIS domain name (which equals to IPA domain name when using hostgroups). Configuring SSSD to fetch sudo rules All configuration that is needed on SSSD side is to extend the list of services with "sudo" in [sssd] section of sssd.conf 5 . To speed up the LDAP lookups, you can also set search base for sudo rules using ldap_sudo_search_base option. The following example shows how to configure SSSD to download sudo rules from an LDAP server. [sssd] config_file_version = 2 services = nss, pam, sudo domains = EXAMPLE [domain/EXAMPLE] id_provider = ldap sudo_provider = ldap ldap_uri = ldap://example.com ldap_sudo_search_base = ou=sudoers,dc=example,dc=com When the SSSD is configured to use IPA as the ID provider, the sudo provider is automatically enabled. The sudo search base is configured to use the compat tree (ou=sudoers,$DC). The SUDO rule caching mechanism The biggest challenge, when developing sudo support in SSSD, was to ensure that running sudo with SSSD as the data source provides the same user experience and is as fast as sudo but keeps providing the most current set of rules as possible. To satisfy these requirements, SSSD uses three kinds of updates. They are referred to as full refresh, smart refresh and rules refresh. The smart refresh periodically downloads rules that are new or were modified after the last update. Its primary goal is to keep the database growing by fetching only small increments that do not generate large amounts of network traffic. The full refresh simply deletes all sudo rules stored in the cache and replaces them with all rules that are stored on the server. This is used to keep the cache consistent by removing every rule which was deleted from the server. However, full refresh may produce a lot of traffic and thus it should be run only occasionally depending on the size and stability of the sudo rules. The rules refresh ensures that we do not grant the user more permission than defined. It is triggered each time the user runs sudo. Rules refresh will find all rules that apply to this user, check their expiration time and redownload them if expired. In the case that any of these rules are missing on the server, the SSSD will do an out of band full refresh because more rules (that apply to other users) may have been deleted. If enabled, SSSD will store only rules that can be applied to this machine. This means rules that contain one of the following values in sudoHost attribute: keyword ALL wildcard netgroup (in the form "+netgroup") hostname or fully qualified domain name of this machine one of the IP addresses of this machine one of the IP addresses of the network (in the form "address/mask") There are many configuration options that can be used to adjust the behavior. Please refer to "ldap_sudo_*" in sssd-ldap 5 and "sudo_*" in sssd.conf 5 . sssd-1.13.4/src/man/PaxHeaders.16287/sssd.conf.5.xml0000644000000000000000000000007112703456111016451 xustar0028 atime=1460561751.6427156 29 ctime=1460561775.96179806 sssd-1.13.4/src/man/sssd.conf.5.xml0000644002412700241270000034525512703456111020141 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sssd.conf 5 File Formats and Conventions sssd.conf the configuration file for SSSD FILE FORMAT The file has an ini-style syntax and consists of sections and parameters. A section begins with the name of the section in square brackets and continues until the next section begins. An example of section with single and multi-valued parameters: [section] key = value key2 = value2,value3 The data types used are string (no quotes needed), integer and bool (with values of TRUE/FALSE). A line comment starts with a hash sign (#) or a semicolon (;). Inline comments are not supported. All sections can have an optional description parameter. Its function is only as a label for the section. sssd.conf must be a regular file, owned by root and only root may read from or write to the file. GENERAL OPTIONS Following options are usable in more than one configuration sections. Options usable in all sections debug_level (integer) debug_timestamps (bool) Add a timestamp to the debug messages. If journald is enabled for SSSD debug logging this option is ignored. Default: true debug_microseconds (bool) Add microseconds to the timestamp in debug messages. If journald is enabled for SSSD debug logging this option is ignored. Default: false Options usable in SERVICE and DOMAIN sections timeout (integer) Timeout in seconds between heartbeats for this service. This is used to ensure that the process is alive and capable of answering requests. Default: 10 SPECIAL SECTIONS The [sssd] section Individual pieces of SSSD functionality are provided by special SSSD services that are started and stopped together with SSSD. The services are managed by a special service frequently called monitor. The [sssd] section is used to configure the monitor as well as some other important options like the identity domains. Section parameters config_file_version (integer) Indicates what is the syntax of the config file. SSSD 0.6.0 and later use version 2. services Comma separated list of services that are started when sssd itself starts. Supported services: nss, pam , sudo , autofs , ssh , pac , ifp reconnection_retries (integer) Number of times services should attempt to reconnect in the event of a Data Provider crash or restart before they give up Default: 3 domains A domain is a database containing user information. SSSD can use more domains at the same time, but at least one must be configured or SSSD won't start. This parameter described the list of domains in the order you want them to be queried. A domain name should only consist of alphanumeric ASCII characters, dashes, dots and underscores. re_expression (string) Default regular expression that describes how to parse the string containing user name and domain into these components. Each domain can have an individual regular expression configured. For some ID providers there are also default regular expressions. See DOMAIN SECTIONS for more info on these regular expressions. full_name_format (string) A printf 3 -compatible format that describes how to compose a fully qualified name from user name and domain name components. The following expansions are supported: %1$s user name %2$s domain name as specified in the SSSD config file. %3$s domain flat name. Mostly usable for Active Directory domains, both directly configured or discovered via IPA trusts. Each domain can have an individual format string configured. see DOMAIN SECTIONS for more info on this option. try_inotify (boolean) SSSD monitors the state of resolv.conf to identify when it needs to update its internal DNS resolver. By default, we will attempt to use inotify for this, and will fall back to polling resolv.conf every five seconds if inotify cannot be used. There are some limited situations where it is preferred that we should skip even trying to use inotify. In these rare cases, this option should be set to 'false' Default: true on platforms where inotify is supported. False on other platforms. Note: this option will have no effect on platforms where inotify is unavailable. On these platforms, polling will always be used. krb5_rcache_dir (string) Directory on the filesystem where SSSD should store Kerberos replay cache files. This option accepts a special value __LIBKRB5_DEFAULTS__ that will instruct SSSD to let libkrb5 decide the appropriate location for the replay cache. Default: Distribution-specific and specified at build-time. (__LIBKRB5_DEFAULTS__ if not configured) user (string) The user to drop the privileges to where appropriate to avoid running as the root user. Default: not set, process will run as root default_domain_suffix (string) This string will be used as a default domain name for all names without a domain name component. The main use case is environments where the primary domain is intended for managing host policies and all users are located in a trusted domain. The option allows those users to log in just with their user name without giving a domain name as well. Please note that if this option is set all users from the primary domain have to use their fully qualified name, e.g. user@domain.name, to log in. Setting this option changes default of use_fully_qualified_names to True. It is not allowed to use this option together with use_fully_qualified_names set to False. Default: not set override_space (string) This parameter will replace spaces (space bar) with the given character for user and group names. e.g. (_). User name "john doe" will be "john_doe" This feature was added to help compatibility with shell scripts that have difficulty handling spaces, due to the default field separator in the shell. Please note it is a configuration error to use a replacement character that might be used in user or group names. If a name contains the replacement character SSSD tries to return the unmodified name but in general the result of a lookup is undefined. Default: not set (spaces will not be replaced) certificate_verification (string) With this parameter the certificate verification can be tuned with a comma separated list of options. Supported options are: no_ocsp Disables Online Certificate Status Protocol (OCSP) checks. This might be needed if the OCSP servers defined in the certificate are not reachable from the client. Unknown options are reported but ignored. Default: not set, i.e. do not restrict certificate vertification SERVICES SECTIONS Settings that can be used to configure different services are described in this section. They should reside in the [$NAME] section, for example, for NSS service, the section would be [nss] General service configuration options These options can be used to configure any service. reconnection_retries (integer) Number of times services should attempt to reconnect in the event of a Data Provider crash or restart before they give up Default: 3 fd_limit This option specifies the maximum number of file descriptors that may be opened at one time by this SSSD process. On systems where SSSD is granted the CAP_SYS_RESOURCE capability, this will be an absolute setting. On systems without this capability, the resulting value will be the lower value of this or the limits.conf "hard" limit. Default: 8192 (or limits.conf "hard" limit) client_idle_timeout This option specifies the number of seconds that a client of an SSSD process can hold onto a file descriptor without communicating on it. This value is limited in order to avoid resource exhaustion on the system. Default: 60 force_timeout (integer) If a service is not responding to ping checks (see the timeout option), it is first sent the SIGTERM signal that instructs it to quit gracefully. If the service does not terminate after force_timeout seconds, the monitor will forcibly shut it down by sending a SIGKILL signal. Default: 60 offline_timeout (integer) When SSSD switches to offline mode the amount of time before it tries to go back online will increase based upon the time spent disconnected. This value is in seconds and calculated by the following: offline_timeout + random_offset The random offset can increment up to 30 seconds. After each unsuccessful attempt to go online, the new interval is recalculated by the following: new_interval = old_interval*2 + random_offset Note that the maximum length of each interval is currently limited to one hour. If the calculated length of new_interval is greater than an hour, it will be forced to one hour. Default: 60 subdomain_inherit (string) Specifies a list of configuration parameters that should be inherited by a subdomain. Please note that only selected parameters can be inherited. Currently the following options can be inherited: ignore_group_members ldap_purge_cache_timeout ldap_use_tokengroups ldap_user_principal Example: subdomain_inherit = ldap_purge_cache_timeout Default: none NSS configuration options These options can be used to configure the Name Service Switch (NSS) service. enum_cache_timeout (integer) How many seconds should nss_sss cache enumerations (requests for info about all users) Default: 120 entry_cache_nowait_percentage (integer) The entry cache can be set to automatically update entries in the background if they are requested beyond a percentage of the entry_cache_timeout value for the domain. For example, if the domain's entry_cache_timeout is set to 30s and entry_cache_nowait_percentage is set to 50 (percent), entries that come in after 15 seconds past the last cache update will be returned immediately, but the SSSD will go and update the cache on its own, so that future requests will not need to block waiting for a cache update. Valid values for this option are 0-99 and represent a percentage of the entry_cache_timeout for each domain. For performance reasons, this percentage will never reduce the nowait timeout to less than 10 seconds. (0 disables this feature) Default: 50 entry_negative_timeout (integer) Specifies for how many seconds nss_sss should cache negative cache hits (that is, queries for invalid database entries, like nonexistent ones) before asking the back end again. Default: 15 filter_users, filter_groups (string) Exclude certain users from being fetched from the sss NSS database. This is particularly useful for system accounts. This option can also be set per-domain or include fully-qualified names to filter only users from the particular domain. Default: root filter_users_in_groups (bool) If you want filtered user still be group members set this option to false. Default: true fallback_homedir (string) Set a default template for a user's home directory if one is not specified explicitly by the domain's data provider. The available values for this option are the same as for override_homedir. example: fallback_homedir = /home/%u Default: not set (no substitution for unset home directories) override_shell (string) Override the login shell for all users. This option supersedes any other shell options if it takes effect and can be set either in the [nss] section or per-domain. Default: not set (SSSD will use the value retrieved from LDAP) allowed_shells (string) Restrict user shell to one of the listed values. The order of evaluation is: 1. If the shell is present in /etc/shells, it is used. 2. If the shell is in the allowed_shells list but not in /etc/shells, use the value of the shell_fallback parameter. 3. If the shell is not in the allowed_shells list and not in /etc/shells, a nologin shell is used. The wildcard (*) can be used to allow any shell. The (*) is useful if you want to use shell_fallback in case that user's shell is not in /etc/shells and maintaining list of all allowed shells in allowed_shells would be to much overhead. An empty string for shell is passed as-is to libc. The /etc/shells is only read on SSSD start up, which means that a restart of the SSSD is required in case a new shell is installed. Default: Not set. The user shell is automatically used. vetoed_shells (string) Replace any instance of these shells with the shell_fallback shell_fallback (string) The default shell to use if an allowed shell is not installed on the machine. Default: /bin/sh default_shell The default shell to use if the provider does not return one during lookup. This option can be specified globally in the [nss] section or per-domain. Default: not set (Return NULL if no shell is specified and rely on libc to substitute something sensible when necessary, usually /bin/sh) get_domains_timeout (int) Specifies time in seconds for which the list of subdomains will be considered valid. Default: 60 memcache_timeout (int) Specifies time in seconds for which records in the in-memory cache will be valid. Default: 300 NOTE: If the environment variable SSS_NSS_USE_MEMCACHE is set to "NO", client applications will not use the fast in-memory cache. user_attributes (string) Some of the additional NSS responder requests can return more attributes than just the POSIX ones defined by the NSS interface. The list of attributes is controlled by this option. It is handled the same way as the user_attributes option of the InfoPipe responder (see sssd-ifp 5 for details) but with no default values. To make configuration more easy the NSS responder will check the InfoPipe option if it is not set for the NSS responder. Default: not set, fallback to InfoPipe option PAM configuration options These options can be used to configure the Pluggable Authentication Module (PAM) service. offline_credentials_expiration (integer) If the authentication provider is offline, how long should we allow cached logins (in days since the last successful online login). Default: 0 (No limit) offline_failed_login_attempts (integer) If the authentication provider is offline, how many failed login attempts are allowed. Default: 0 (No limit) offline_failed_login_delay (integer) The time in minutes which has to pass after offline_failed_login_attempts has been reached before a new login attempt is possible. If set to 0 the user cannot authenticate offline if offline_failed_login_attempts has been reached. Only a successful online authentication can enable offline authentication again. Default: 5 pam_verbosity (integer) Controls what kind of messages are shown to the user during authentication. The higher the number to more messages are displayed. Currently sssd supports the following values: 0: do not show any message 1: show only important messages 2: show informational messages 3: show all messages and debug information Default: 1 pam_id_timeout (integer) For any PAM request while SSSD is online, the SSSD will attempt to immediately update the cached identity information for the user in order to ensure that authentication takes place with the latest information. A complete PAM conversation may perform multiple PAM requests, such as account management and session opening. This option controls (on a per-client-application basis) how long (in seconds) we can cache the identity information to avoid excessive round-trips to the identity provider. Default: 5 pam_pwd_expiration_warning (integer) Display a warning N days before the password expires. Please note that the backend server has to provide information about the expiration time of the password. If this information is missing, sssd cannot display a warning. If zero is set, then this filter is not applied, i.e. if the expiration warning was received from backend server, it will automatically be displayed. This setting can be overridden by setting pwd_expiration_warning for a particular domain. Default: 0 get_domains_timeout (int) Specifies time in seconds for which the list of subdomains will be considered valid. Default: 60 pam_trusted_users (string) Specifies the comma-separated list of UID values or user names that are allowed to access the PAM responder. User names are resolved to UIDs at startup. Default: all (All users are allowed to access the PAM responder) Please note that UID 0 is always allowed to access the PAM responder even in case it is not in the pam_trusted_users list. pam_public_domains (string) Specifies the comma-separated list of domain names that are accessible even to untrusted users. Two special values for pam_public_domains option are defined: all (Untrusted users are allowed to access all domains in PAM responder.) none (Untrusted users are not allowed to access any domains PAM in responder.) Default: none pam_account_expired_message (string) Allows a custom expiration message to be set, replacing the default 'Permission denied' message. Note: Please be aware that message is only printed for the SSH service unless pam_verbostiy is set to 3 (show all messages and debug information). example: pam_account_expired_message = Account expired, please contact help desk. Default: none pam_account_locked_message (string) Allows a custom lockout message to be set, replacing the default 'Permission denied' message. example: pam_account_locked_message = Account locked, please contact help desk. Default: none p11_child_timeout (integer) How many seconds will pam_sss wait for p11_child to finish. Default: 10 SUDO configuration options These options can be used to configure the sudo service. The detailed instructions for configuration of sudo 8 to work with sssd 8 are in the manual page sssd-sudo 5 . sudo_timed (bool) Whether or not to evaluate the sudoNotBefore and sudoNotAfter attributes that implement time-dependent sudoers entries. Default: false AUTOFS configuration options These options can be used to configure the autofs service. autofs_negative_timeout (integer) Specifies for how many seconds should the autofs responder negative cache hits (that is, queries for invalid map entries, like nonexistent ones) before asking the back end again. Default: 15 SSH configuration options These options can be used to configure the SSH service. ssh_hash_known_hosts (bool) Whether or not to hash host names and addresses in the managed known_hosts file. Default: true ssh_known_hosts_timeout (integer) How many seconds to keep a host in the managed known_hosts file after its host keys were requested. Default: 180 ca_db (string) Path to a storage of trusted CA certificates. The option is used to validate user certificates before deriving public ssh keys from them. Default: /etc/pki/nssdb PAC responder configuration options The PAC responder works together with the authorization data plugin for MIT Kerberos sssd_pac_plugin.so and a sub-domain provider. The plugin sends the PAC data during a GSSAPI authentication to the PAC responder. The sub-domain provider collects domain SID and ID ranges of the domain the client is joined to and of remote trusted domains from the local domain controller. If the PAC is decoded and evaluated some of the following operations are done: If the remote user does not exist in the cache, it is created. The uid is determined with the help of the SID, trusted domains will have UPGs and the gid will have the same value as the uid. The home directory is set based on the subdomain_homedir parameter. The shell will be empty by default, i.e. the system defaults are used, but can be overwritten with the default_shell parameter. If there are SIDs of groups from domains sssd knows about, the user will be added to those groups. These options can be used to configure the PAC responder. allowed_uids (string) Specifies the comma-separated list of UID values or user names that are allowed to access the PAC responder. User names are resolved to UIDs at startup. Default: 0 (only the root user is allowed to access the PAC responder) Please note that although the UID 0 is used as the default it will be overwritten with this option. If you still want to allow the root user to access the PAC responder, which would be the typical case, you have to add 0 to the list of allowed UIDs as well. DOMAIN SECTIONS These configuration options can be present in a domain configuration section, that is, in a section called [domain/NAME] min_id,max_id (integer) UID and GID limits for the domain. If a domain contains an entry that is outside these limits, it is ignored. For users, this affects the primary GID limit. The user will not be returned to NSS if either the UID or the primary GID is outside the range. For non-primary group memberships, those that are in range will be reported as expected. These ID limits affect even saving entries to cache, not only returning them by name or ID. Default: 1 for min_id, 0 (no limit) for max_id enumerate (bool) Determines if a domain can be enumerated. This parameter can have one of the following values: TRUE = Users and groups are enumerated FALSE = No enumerations for this domain Default: FALSE Note: Enabling enumeration has a moderate performance impact on SSSD while enumeration is running. It may take up to several minutes after SSSD startup to fully complete enumerations. During this time, individual requests for information will go directly to LDAP, though it may be slow, due to the heavy enumeration processing. Saving a large number of entries to cache after the enumeration completes might also be CPU intensive as the memberships have to be recomputed. While the first enumeration is running, requests for the complete user or group lists may return no results until it completes. Further, enabling enumeration may increase the time necessary to detect network disconnection, as longer timeouts are required to ensure that enumeration lookups are completed successfully. For more information, refer to the man pages for the specific id_provider in use. For the reasons cited above, enabling enumeration is not recommended, especially in large environments. subdomain_enumerate (string) Whether any of autodetected trusted domains should be enumerated. The supported values are: all All discovered trusted domains will be enumerated none No discovered trusted domains will be enumerated Optionally, a list of one or more domain names can enable enumeration just for these trusted domains. Default: none force_timeout (integer) If a service is not responding to ping checks (see the timeout option), it is first sent the SIGTERM signal that instructs it to quit gracefully. If the service does not terminate after force_timeout seconds, the monitor will forcibly shut it down by sending a SIGKILL signal. Default: 60 entry_cache_timeout (integer) How many seconds should nss_sss consider entries valid before asking the backend again The cache expiration timestamps are stored as attributes of individual objects in the cache. Therefore, changing the cache timeout only has effect for newly added or expired entries. You should run the sss_cache 8 tool in order to force refresh of entries that have already been cached. Default: 5400 entry_cache_user_timeout (integer) How many seconds should nss_sss consider user entries valid before asking the backend again Default: entry_cache_timeout entry_cache_group_timeout (integer) How many seconds should nss_sss consider group entries valid before asking the backend again Default: entry_cache_timeout entry_cache_netgroup_timeout (integer) How many seconds should nss_sss consider netgroup entries valid before asking the backend again Default: entry_cache_timeout entry_cache_service_timeout (integer) How many seconds should nss_sss consider service entries valid before asking the backend again Default: entry_cache_timeout entry_cache_sudo_timeout (integer) How many seconds should sudo consider rules valid before asking the backend again Default: entry_cache_timeout entry_cache_autofs_timeout (integer) How many seconds should the autofs service consider automounter maps valid before asking the backend again Default: entry_cache_timeout entry_cache_ssh_host_timeout (integer) How many seconds to keep a host ssh key after refresh. IE how long to cache the host key for. Default: entry_cache_timeout refresh_expired_interval (integer) Specifies how many seconds SSSD has to wait before triggering a background refresh task which will refresh all expired or nearly expired records. The background refresh will process users, groups and netgroups in the cache. You can consider setting this value to 3/4 * entry_cache_timeout. Default: 0 (disabled) cache_credentials (bool) Determines if user credentials are also cached in the local LDB cache User credentials are stored in a SHA512 hash, not in plaintext Default: FALSE cache_credentials_minimal_first_factor_length (int) If 2-Factor-Authentication (2FA) is used and credentials should be saved this value determines the minimal length the first authentication factor (long term password) must have to be saved as SHA512 hash into the cache. This should avoid that the short PINs of a PIN based 2FA scheme are saved in the cache which would make them easy targets for brute-force attacks. Default: 8 account_cache_expiration (integer) Number of days entries are left in cache after last successful login before being removed during a cleanup of the cache. 0 means keep forever. The value of this parameter must be greater than or equal to offline_credentials_expiration. Default: 0 (unlimited) pwd_expiration_warning (integer) Display a warning N days before the password expires. If zero is set, then this filter is not applied, i.e. if the expiration warning was received from backend server, it will automatically be displayed. Please note that the backend server has to provide information about the expiration time of the password. If this information is missing, sssd cannot display a warning. Also an auth provider has to be configured for the backend. Default: 7 (Kerberos), 0 (LDAP) id_provider (string) The identification provider used for the domain. Supported ID providers are: proxy: Support a legacy NSS provider local: SSSD internal provider for local users ldap: LDAP provider. See sssd-ldap 5 for more information on configuring LDAP. ipa: FreeIPA and Red Hat Enterprise Identity Management provider. See sssd-ipa 5 for more information on configuring FreeIPA. ad: Active Directory provider. See sssd-ad 5 for more information on configuring Active Directory. use_fully_qualified_names (bool) Use the full name and domain (as formatted by the domain's full_name_format) as the user's login name reported to NSS. If set to TRUE, all requests to this domain must use fully qualified names. For example, if used in LOCAL domain that contains a "test" user, getent passwd test wouldn't find the user while getent passwd test@LOCAL would. NOTE: This option has no effect on netgroup lookups due to their tendency to include nested netgroups without qualified names. For netgroups, all domains will be searched when an unqualified name is requested. Default: FALSE (TRUE if default_domain_suffix is used) ignore_group_members (bool) Do not return group members for group lookups. If set to TRUE, the group membership attribute is not requested from the ldap server, and group members are not returned when processing group lookup calls, such as getgrnam 3 or getgrgid 3 . As an effect, getent group $groupname would return the requested group as if it was empty. Enabling this option can also make access provider checks for group membership significantly faster, especially for groups containing many members. Default: FALSE auth_provider (string) The authentication provider used for the domain. Supported auth providers are: ldap for native LDAP authentication. See sssd-ldap 5 for more information on configuring LDAP. krb5 for Kerberos authentication. See sssd-krb5 5 for more information on configuring Kerberos. ipa: FreeIPA and Red Hat Enterprise Identity Management provider. See sssd-ipa 5 for more information on configuring FreeIPA. ad: Active Directory provider. See sssd-ad 5 for more information on configuring Active Directory. proxy for relaying authentication to some other PAM target. local: SSSD internal provider for local users none disables authentication explicitly. Default: id_provider is used if it is set and can handle authentication requests. access_provider (string) The access control provider used for the domain. There are two built-in access providers (in addition to any included in installed backends) Internal special providers are: permit always allow access. It's the only permitted access provider for a local domain. deny always deny access. ldap for native LDAP authentication. See sssd-ldap 5 for more information on configuring LDAP. ipa: FreeIPA and Red Hat Enterprise Identity Management provider. See sssd-ipa 5 for more information on configuring FreeIPA. ad: Active Directory provider. See sssd-ad 5 for more information on configuring Active Directory. simple access control based on access or deny lists. See sssd-simple 5 for more information on configuring the simple access module. Default: permit chpass_provider (string) The provider which should handle change password operations for the domain. Supported change password providers are: ldap to change a password stored in a LDAP server. See sssd-ldap 5 for more information on configuring LDAP. krb5 to change the Kerberos password. See sssd-krb5 5 for more information on configuring Kerberos. ipa: FreeIPA and Red Hat Enterprise Identity Management provider. See sssd-ipa 5 for more information on configuring FreeIPA. ad: Active Directory provider. See sssd-ad 5 for more information on configuring Active Directory. proxy for relaying password changes to some other PAM target. none disallows password changes explicitly. Default: auth_provider is used if it is set and can handle change password requests. sudo_provider (string) The SUDO provider used for the domain. Supported SUDO providers are: ldap for rules stored in LDAP. See sssd-ldap 5 for more information on configuring LDAP. ipa the same as ldap but with IPA default settings. ad the same as ldap but with AD default settings. none disables SUDO explicitly. Default: The value of id_provider is used if it is set. The detailed instructions for configuration of sudo_provider are in the manual page sssd-sudo 5 . There are many configuration options that can be used to adjust the behavior. Please refer to "ldap_sudo_*" in sssd-ldap 5 . selinux_provider (string) The provider which should handle loading of selinux settings. Note that this provider will be called right after access provider ends. Supported selinux providers are: ipa to load selinux settings from an IPA server. See sssd-ipa 5 for more information on configuring IPA. none disallows fetching selinux settings explicitly. Default: id_provider is used if it is set and can handle selinux loading requests. subdomains_provider (string) The provider which should handle fetching of subdomains. This value should be always the same as id_provider. Supported subdomain providers are: ipa to load a list of subdomains from an IPA server. See sssd-ipa 5 for more information on configuring IPA. ad to load a list of subdomains from an Active Directory server. See sssd-ad 5 for more information on configuring the AD provider. none disallows fetching subdomains explicitly. Default: The value of id_provider is used if it is set. autofs_provider (string) The autofs provider used for the domain. Supported autofs providers are: ldap to load maps stored in LDAP. See sssd-ldap 5 for more information on configuring LDAP. ipa to load maps stored in an IPA server. See sssd-ipa 5 for more information on configuring IPA. ad to load maps stored in an AD server. See sssd-ad 5 for more information on configuring the AD provider. none disables autofs explicitly. Default: The value of id_provider is used if it is set. hostid_provider (string) The provider used for retrieving host identity information. Supported hostid providers are: ipa to load host identity stored in an IPA server. See sssd-ipa 5 for more information on configuring IPA. none disables hostid explicitly. Default: The value of id_provider is used if it is set. re_expression (string) Regular expression for this domain that describes how to parse the string containing user name and domain into these components. The "domain" can match either the SSSD configuration domain name, or, in the case of IPA trust subdomains and Active Directory domains, the flat (NetBIOS) name of the domain. Default for the AD and IPA provider: (((?P<domain>[^\\]+)\\(?P<name>.+$))|((?P<name>[^@]+)@(?P<domain>.+$))|(^(?P<name>[^@\\]+)$)) which allows three different styles for user names: username username@domain.name domain\username While the first two correspond to the general default the third one is introduced to allow easy integration of users from Windows domains. Default: (?P<name>[^@]+)@?(?P<domain>[^@]*$) which translates to "the name is everything up to the @ sign, the domain everything after that" PLEASE NOTE: the support for non-unique named subpatterns is not available on all platforms (e.g. RHEL5 and SLES10). Only platforms with libpcre version 7 or higher can support non-unique named subpatterns. PLEASE NOTE ALSO: older version of libpcre only support the Python syntax (?P<name>) to label subpatterns. full_name_format (string) A printf 3 -compatible format that describes how to compose a fully qualified name from user name and domain name components. The following expansions are supported: %1$s user name %2$s domain name as specified in the SSSD config file. %3$s domain flat name. Mostly usable for Active Directory domains, both directly configured or discovered via IPA trusts. Default: %1$s@%2$s. lookup_family_order (string) Provides the ability to select preferred address family to use when performing DNS lookups. Supported values: ipv4_first: Try looking up IPv4 address, if that fails, try IPv6 ipv4_only: Only attempt to resolve hostnames to IPv4 addresses. ipv6_first: Try looking up IPv6 address, if that fails, try IPv4 ipv6_only: Only attempt to resolve hostnames to IPv6 addresses. Default: ipv4_first dns_resolver_timeout (integer) Defines the amount of time (in seconds) to wait for a reply from the DNS resolver before assuming that it is unreachable. If this timeout is reached, the domain will continue to operate in offline mode. Default: 6 dns_discovery_domain (string) If service discovery is used in the back end, specifies the domain part of the service discovery DNS query. Default: Use the domain part of machine's hostname override_gid (integer) Override the primary GID value with the one specified. case_sensitive (string) Treat user and group names as case sensitive. At the moment, this option is not supported in the local provider. Possible option values are: True Case sensitive. This value is invalid for AD provider. False Case insensitive. Preserving Same as False (case insensitive), but does not lowercase names in the result of NSS operations. Note that name aliases (and in case of services also protocol names) are still lowercased in the output. Default: True (False for AD provider) proxy_fast_alias (boolean) When a user or group is looked up by name in the proxy provider, a second lookup by ID is performed to "canonicalize" the name in case the requested name was an alias. Setting this option to true would cause the SSSD to perform the ID lookup from cache for performance reasons. Default: false subdomain_homedir (string) Use this homedir as default value for all subdomains within this domain in IPA AD trust. See override_homedir for info about possible values. In addition to those, the expansion below can only be used with subdomain_homedir. %F flat (NetBIOS) name of a subdomain. The value can be overridden by override_homedir option. Default: /home/%d/%u realmd_tags (string) Various tags stored by the realmd configuration service for this domain. cached_auth_timeout (int) Specifies time in seconds since last successful online authentication for which user will be authenticated using cached credentials while SSSD is in the online mode. Special value 0 implies that this feature is disabled. Please note that if cached_auth_timeout is longer than pam_id_timeout then the back end could be called to handle initgroups. Default: 0 Options valid for proxy domains. proxy_pam_target (string) The proxy target PAM proxies to. Default: not set by default, you have to take an existing pam configuration or create a new one and add the service name here. proxy_lib_name (string) The name of the NSS library to use in proxy domains. The NSS functions searched for in the library are in the form of _nss_$(libName)_$(function), for example _nss_files_getpwent. The local domain section This section contains settings for domain that stores users and groups in SSSD native database, that is, a domain that uses id_provider=local. Section parameters default_shell (string) The default shell for users created with SSSD userspace tools. Default: /bin/bash base_directory (string) The tools append the login name to base_directory and use that as the home directory. Default: /home create_homedir (bool) Indicate if a home directory should be created by default for new users. Can be overridden on command line. Default: TRUE remove_homedir (bool) Indicate if a home directory should be removed by default for deleted users. Can be overridden on command line. Default: TRUE homedir_umask (integer) Used by sss_useradd 8 to specify the default permissions on a newly created home directory. Default: 077 skel_dir (string) The skeleton directory, which contains files and directories to be copied in the user's home directory, when the home directory is created by sss_useradd 8 Default: /etc/skel mail_dir (string) The mail spool directory. This is needed to manipulate the mailbox when its corresponding user account is modified or deleted. If not specified, a default value is used. Default: /var/mail userdel_cmd (string) The command that is run after a user is removed. The command us passed the username of the user being removed as the first and only parameter. The return code of the command is not taken into account. Default: None, no command is run EXAMPLE The following example shows a typical SSSD config. It does not describe configuration of the domains themselves - refer to documentation on configuring domains for more details. [sssd] domains = LDAP services = nss, pam config_file_version = 2 [nss] filter_groups = root filter_users = root [pam] [domain/LDAP] id_provider = ldap ldap_uri = ldap://ldap.example.com ldap_search_base = dc=example,dc=com auth_provider = krb5 krb5_server = kerberos.example.com krb5_realm = EXAMPLE.COM cache_credentials = true min_id = 10000 max_id = 20000 enumerate = False sssd-1.13.4/src/man/PaxHeaders.16287/include0000644000000000000000000000013212703463557015244 xustar0030 mtime=1460561775.995798176 30 atime=1460561776.118798593 30 ctime=1460561775.995798176 sssd-1.13.4/src/man/include/0000755002412700241270000000000012703463557016775 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/man/include/PaxHeaders.16287/seealso.xml0000644000000000000000000000007312703456111017466 xustar0029 atime=1460561751.63671558 30 ctime=1460561775.994798172 sssd-1.13.4/src/man/include/seealso.xml0000644002412700241270000000754212703456111021146 0ustar00jhrozekjhrozek00000000000000 SEE ALSO sssd8 , sssd.conf5 , sssd-ldap5 , sssd-krb55 , sssd-simple5 , sssd-ipa5 , sssd-ad5 , sssd-sudo 5 , sss_cache8 , sss_debuglevel8 , sss_groupadd8 , sss_groupdel8 , sss_groupshow8 , sss_groupmod8 , sss_useradd8 , sss_userdel8 , sss_usermod8 , sss_obfuscate8 , sss_seed8 , sssd_krb5_locator_plugin8 , sss_ssh_authorizedkeys 8 , sss_ssh_knownhostsproxy 8 , sssd-ifp 5 , pam_sss8 . sss_rpcidmapd 5 sssd-1.13.4/src/man/include/PaxHeaders.16287/upstream.xml0000644000000000000000000000007312703456111017673 xustar0029 atime=1460561751.63671558 30 ctime=1460561775.985798142 sssd-1.13.4/src/man/include/upstream.xml0000644002412700241270000000021312703456111021337 0ustar00jhrozekjhrozek00000000000000 SSSD The SSSD upstream - http://fedorahosted.org/sssd sssd-1.13.4/src/man/include/PaxHeaders.16287/debug_levels.xml0000644000000000000000000000007412703456111020474 xustar0030 atime=1460561751.635715576 30 ctime=1460561775.993798169 sssd-1.13.4/src/man/include/debug_levels.xml0000644002412700241270000000722612703456111022152 0ustar00jhrozekjhrozek00000000000000 SSSD supports two representations for specifying the debug level. The simplest is to specify a decimal value from 0-9, which represents enabling that level and all lower-level debug messages. The more comprehensive option is to specify a hexadecimal bitmask to enable or disable specific levels (such as if you wish to suppress a level). Please note that each SSSD service logs into its own log file. Also please note that enabling debug_level in the [sssd] section only enables debugging just for the sssd process itself, not for the responder or provider processes. The debug_level parameter should be added to all sections that you wish to produce debug logs from. In addition to changing the log level in the config file using the debug_level parameter, which is persistent, but requires SSSD restart, it is also possible to change the debug level on the fly using the sss_debuglevel 8 tool. Currently supported debug levels: 0, 0x0010: Fatal failures. Anything that would prevent SSSD from starting up or causes it to cease running. 1, 0x0020: Critical failures. An error that doesn't kill the SSSD, but one that indicates that at least one major feature is not going to work properly. 2, 0x0040: Serious failures. An error announcing that a particular request or operation has failed. 3, 0x0080: Minor failures. These are the errors that would percolate down to cause the operation failure of 2. 4, 0x0100: Configuration settings. 5, 0x0200: Function data. 6, 0x0400: Trace messages for operation functions. 7, 0x1000: Trace messages for internal control functions. 8, 0x2000: Contents of function-internal variables that may be interesting. 9, 0x4000: Extremely low-level tracing information. To log required bitmask debug levels, simply add their numbers together as shown in following examples: Example: To log fatal failures, critical failures, serious failures and function data use 0x0270. Example: To log fatal failures, configuration settings, function data, trace messages for internal control functions use 0x1310. Note: The bitmask format of debug levels was introduced in 1.7.0. Default: 0 sssd-1.13.4/src/man/include/PaxHeaders.16287/service_discovery.xml0000644000000000000000000000007312703456111021562 xustar0029 atime=1460561751.63671558 30 ctime=1460561775.984798139 sssd-1.13.4/src/man/include/service_discovery.xml0000644002412700241270000000355712703456111023244 0ustar00jhrozekjhrozek00000000000000 SERVICE DISCOVERY The service discovery feature allows back ends to automatically find the appropriate servers to connect to using a special DNS query. This feature is not supported for backup servers. Configuration If no servers are specified, the back end automatically uses service discovery to try to find a server. Optionally, the user may choose to use both fixed server addresses and service discovery by inserting a special keyword, _srv_, in the list of servers. The order of preference is maintained. This feature is useful if, for example, the user prefers to use service discovery whenever possible, and fall back to a specific server when no servers can be discovered using DNS. The domain name Please refer to the dns_discovery_domain parameter in the sssd.conf 5 manual page for more details. The protocol The queries usually specify _tcp as the protocol. Exceptions are documented in respective option description. See Also For more information on the service discovery mechanism, refer to RFC 2782. sssd-1.13.4/src/man/include/PaxHeaders.16287/autofs_restart.xml0000644000000000000000000000007412703456111021101 xustar0030 atime=1460561751.635715576 30 ctime=1460561775.988798152 sssd-1.13.4/src/man/include/autofs_restart.xml0000644002412700241270000000036712703456111022556 0ustar00jhrozekjhrozek00000000000000 Please note that the automounter only reads the master map on startup, so if any autofs-related changes are made to the sssd.conf, you typically also need to restart the automounter daemon after restarting the SSSD. sssd-1.13.4/src/man/include/PaxHeaders.16287/param_help_py.xml0000644000000000000000000000007312703456111020653 xustar0029 atime=1460561751.63671558 30 ctime=1460561775.983798135 sssd-1.13.4/src/man/include/param_help_py.xml0000644002412700241270000000032312703456111022321 0ustar00jhrozekjhrozek00000000000000 , Display help message and exit. sssd-1.13.4/src/man/include/PaxHeaders.16287/ldap_id_mapping.xml0000644000000000000000000000007412703456111021143 xustar0030 atime=1460561751.635715576 30 ctime=1460561775.994798172 sssd-1.13.4/src/man/include/ldap_id_mapping.xml0000644002412700241270000003513512703456111022621 0ustar00jhrozekjhrozek00000000000000 ID MAPPING The ID-mapping feature allows SSSD to act as a client of Active Directory without requiring administrators to extend user attributes to support POSIX attributes for user and group identifiers. NOTE: When ID-mapping is enabled, the uidNumber and gidNumber attributes are ignored. This is to avoid the possibility of conflicts between automatically-assigned and manually-assigned values. If you need to use manually-assigned values, ALL values must be manually-assigned. Please note that changing the ID mapping related configuration options will cause user and group IDs to change. At the moment, SSSD does not support changing IDs, so the SSSD database must be removed. Because cached passwords are also stored in the database, removing the database should only be performed while the authentication servers are reachable, otherwise users might get locked out. In order to cache the password, an authentication must be performed. It is not sufficient to use sss_cache 8 to remove the database, rather the process consists of: Making sure the remote servers are reachable Stopping the SSSD service Removing the database Starting the SSSD service Moreover, as the change of IDs might necessitate the adjustment of other system properties such as file and directory ownership, it's advisable to plan ahead and test the ID mapping configuration thoroughly. Mapping Algorithm Active Directory provides an objectSID for every user and group object in the directory. This objectSID can be broken up into components that represent the Active Directory domain identity and the relative identifier (RID) of the user or group object. The SSSD ID-mapping algorithm takes a range of available UIDs and divides it into equally-sized component sections - called "slices"-. Each slice represents the space available to an Active Directory domain. When a user or group entry for a particular domain is encountered for the first time, the SSSD allocates one of the available slices for that domain. In order to make this slice-assignment repeatable on different client machines, we select the slice based on the following algorithm: The SID string is passed through the murmurhash3 algorithm to convert it to a 32-bit hashed value. We then take the modulus of this value with the total number of available slices to pick the slice. NOTE: It is possible to encounter collisions in the hash and subsequent modulus. In these situations, we will select the next available slice, but it may not be possible to reproduce the same exact set of slices on other machines (since the order that they are encountered will determine their slice). In this situation, it is recommended to either switch to using explicit POSIX attributes in Active Directory (disabling ID-mapping) or configure a default domain to guarantee that at least one is always consistent. See Configuration for details. Configuration Minimum configuration (in the [domain/DOMAINNAME] section): ldap_id_mapping = True ldap_schema = ad The default configuration results in configuring 10,000 slices, each capable of holding up to 200,000 IDs, starting from 10,001 and going up to 2,000,100,000. This should be sufficient for most deployments. Advanced Configuration ldap_idmap_range_min (integer) Specifies the lower bound of the range of POSIX IDs to use for mapping Active Directory user and group SIDs. NOTE: This option is different from min_id in that min_id acts to filter the output of requests to this domain, whereas this option controls the range of ID assignment. This is a subtle distinction, but the good general advice would be to have min_id be less-than or equal to ldap_idmap_range_min Default: 200000 ldap_idmap_range_max (integer) Specifies the upper bound of the range of POSIX IDs to use for mapping Active Directory user and group SIDs. NOTE: This option is different from max_id in that max_id acts to filter the output of requests to this domain, whereas this option controls the range of ID assignment. This is a subtle distinction, but the good general advice would be to have max_id be greater-than or equal to ldap_idmap_range_max Default: 2000200000 ldap_idmap_range_size (integer) Specifies the number of IDs available for each slice. If the range size does not divide evenly into the min and max values, it will create as many complete slices as it can. NOTE: The value of this option must be at least as large as the highest user RID planned for use on the Active Directory server. User lookups and login will fail for any user whose RID is greater than this value. For example, if your most recently-added Active Directory user has objectSid=S-1-5-21-2153326666-2176343378-3404031434-1107, ldap_idmap_range_size must be at least 1108 as range size is equal to maximal SID minus minimal SID plus one (e.g. 1108 = 1107 - 0 + 1). It is important to plan ahead for future expansion, as changing this value will result in changing all of the ID mappings on the system, leading to users with different local IDs than they previously had. Default: 200000 ldap_idmap_default_domain_sid (string) Specify the domain SID of the default domain. This will guarantee that this domain will always be assigned to slice zero in the ID map, bypassing the murmurhash algorithm described above. Default: not set ldap_idmap_default_domain (string) Specify the name of the default domain. Default: not set ldap_idmap_autorid_compat (boolean) Changes the behavior of the ID-mapping algorithm to behave more similarly to winbind's idmap_autorid algorithm. When this option is configured, domains will be allocated starting with slice zero and increasing monatomically with each additional domain. NOTE: This algorithm is non-deterministic (it depends on the order that users and groups are requested). If this mode is required for compatibility with machines running winbind, it is recommended to also use the ldap_idmap_default_domain_sid option to guarantee that at least one domain is consistently allocated to slice zero. Default: False ldap_idmap_helper_table_size (integer) Maximal number of secondary slices that is tried when performing mapping from UNIX id to SID. Note: Additional secondary slices might be generated when SID is being mapped to UNIX id and RID part of SID is out of range for secondary slices generated so far. If value of ldap_idmap_helper_table_size is equal to 0 then no additional secondary slices are generated. Default: 10 Well-Known SIDs SSSD supports to look up the names of Well-Known SIDs, i.e. SIDs with a special hardcoded meaning. Since the generic users and groups related to those Well-Known SIDs have no equivalent in a Linux/UNIX environment no POSIX IDs are available for those objects. The SID name space is organized in authorities which can be seen as different domains. The authorities for the Well-Known SIDs are Null Authority World Authority Local Authority Creator Authority NT Authority Built-in The capitalized version of these names are used as domain names when returning the fully qualified name of a Well-Known SID. Since some utilities allow to modify SID based access control information with the help of a name instead of using the SID directly SSSD supports to look up the SID by the name as well. To avoid collisions only the fully qualified names can be used to look up Well-Known SIDs. As a result the domain names NULL AUTHORITY, WORLD AUTHORITY, LOCAL AUTHORITY, CREATOR AUTHORITY, NT AUTHORITY and BUILTIN should not be used as domain names in sssd.conf. sssd-1.13.4/src/man/include/PaxHeaders.16287/homedir_substring.xml0000644000000000000000000000007412703456111021563 xustar0030 atime=1460561751.635715576 30 ctime=1460561775.990798159 sssd-1.13.4/src/man/include/homedir_substring.xml0000644002412700241270000000141312703456111023231 0ustar00jhrozekjhrozek00000000000000 homedir_substring (string) The value of this option will be used in the expansion of the override_homedir option if the template contains the format string %H. An LDAP directory entry can directly contain this template so that this option can be used to expand the home directory path for each client machine (or operating system). It can be set per-domain or globally in the [nss] section. A value specified in a domain section will override one set in the [nss] section. Default: /home sssd-1.13.4/src/man/include/PaxHeaders.16287/param_help.xml0000644000000000000000000000007312703456111020143 xustar0029 atime=1460561751.63671558 30 ctime=1460561775.995798176 sssd-1.13.4/src/man/include/param_help.xml0000644002412700241270000000032312703456111021611 0ustar00jhrozekjhrozek00000000000000 , Display help message and exit. sssd-1.13.4/src/man/include/PaxHeaders.16287/local.xml0000644000000000000000000000007412703456111017126 xustar0030 atime=1460561751.635715576 30 ctime=1460561775.991798162 sssd-1.13.4/src/man/include/local.xml0000644002412700241270000000150512703456111020576 0ustar00jhrozekjhrozek00000000000000 THE LOCAL DOMAIN In order to function correctly, a domain with id_provider=local must be created and the SSSD must be running. The administrator might want to use the SSSD local users instead of traditional UNIX users in cases where the group nesting (see sss_groupadd 8 ) is needed. The local users are also useful for testing and development of the SSSD without having to deploy a full remote server. The sss_user* and sss_group* tools use a local LDB storage to store users and groups. sssd-1.13.4/src/man/include/PaxHeaders.16287/failover.xml0000644000000000000000000000007412703456111017643 xustar0030 atime=1460561751.635715576 30 ctime=1460561775.988798152 sssd-1.13.4/src/man/include/failover.xml0000644002412700241270000000472112703456111021316 0ustar00jhrozekjhrozek00000000000000 FAILOVER The failover feature allows back ends to automatically switch to a different server if the current server fails. Failover Syntax The list of servers is given as a comma-separated list; any number of spaces is allowed around the comma. The servers are listed in order of preference. The list can contain any number of servers. For each failover-enabled config option, two variants exist: primary and backup. The idea is that servers in the primary list are preferred and backup servers are only searched if no primary servers can be reached. If a backup server is selected, a timeout of 31 seconds is set. After this timeout SSSD will periodically try to reconnect to one of the primary servers. If it succeeds, it will replace the current active (backup) server. The Failover Mechanism The failover mechanism distinguishes between a machine and a service. The back end first tries to resolve the hostname of a given machine; if this resolution attempt fails, the machine is considered offline. No further attempts are made to connect to this machine for any other service. If the resolution attempt succeeds, the back end tries to connect to a service on this machine. If the service connection attempt fails, then only this particular service is considered offline and the back end automatically switches over to the next service. The machine is still considered online and might still be tried for another service. Further connection attempts are made to machines or services marked as offline after a specified period of time; this is currently hard coded to 30 seconds. If there are no more machines to try, the back end as a whole switches to offline mode, and then attempts to reconnect every 30 seconds. sssd-1.13.4/src/man/include/PaxHeaders.16287/ldap_search_bases.xml0000644000000000000000000000007412703456111021456 xustar0030 atime=1460561751.635715576 30 ctime=1460561775.987798148 sssd-1.13.4/src/man/include/ldap_search_bases.xml0000644002412700241270000000216212703456111023126 0ustar00jhrozekjhrozek00000000000000 An optional base DN, search scope and LDAP filter to restrict LDAP searches for this attribute type. syntax: search_base[?scope?[filter][?search_base?scope?[filter]]*] The scope can be one of "base", "onelevel" or "subtree". The scope functions as specified in section 4.5.1.2 of http://tools.ietf.org/html/rfc4511 The filter must be a valid LDAP search filter as specified by http://www.ietf.org/rfc/rfc2254.txt For examples of this syntax, please refer to the ldap_search_base examples section. Default: the value of ldap_search_base Please note that specifying scope or filter is not supported for searches against an Active Directory Server that might yield a large number of results and trigger the Range Retrieval extension in the response. sssd-1.13.4/src/man/include/PaxHeaders.16287/experimental.xml0000644000000000000000000000007412703456111020531 xustar0030 atime=1460561751.635715576 30 ctime=1460561775.986798145 sssd-1.13.4/src/man/include/experimental.xml0000644002412700241270000000016612703456111022203 0ustar00jhrozekjhrozek00000000000000 This is an experimental feature, please use http://fedorahosted.org/sssd to report any issues. sssd-1.13.4/src/man/include/PaxHeaders.16287/override_homedir.xml0000644000000000000000000000007412703456111021362 xustar0030 atime=1460561751.635715576 30 ctime=1460561775.989798155 sssd-1.13.4/src/man/include/override_homedir.xml0000644002412700241270000000413112703456111023030 0ustar00jhrozekjhrozek00000000000000 override_homedir (string) Override the user's home directory. You can either provide an absolute value or a template. In the template, the following sequences are substituted: %u login name %U UID number %d domain name %f fully qualified user name (user@domain) %P UPN - User Principal Name (name@REALM) %o The original home directory retrieved from the identity provider. %H The value of configure option homedir_substring. %% a literal '%' This option can also be set per-domain. example: override_homedir = /home/%u Default: Not set (SSSD will use the value retrieved from LDAP) sssd-1.13.4/src/man/PaxHeaders.16287/sss_obfuscate.8.xml0000644000000000000000000000007212703456111017420 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.972798098 sssd-1.13.4/src/man/sss_obfuscate.8.xml0000644002412700241270000000756212703456111021103 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sss_obfuscate 8 sss_obfuscate obfuscate a clear text password sss_obfuscate options [PASSWORD] DESCRIPTION sss_obfuscate converts a given password into human-unreadable format and places it into appropriate domain section of the SSSD config file. The cleartext password is read from standard input or entered interactively. The obfuscated password is put into ldap_default_authtok parameter of a given SSSD domain and the ldap_default_authtok_type parameter is set to obfuscated_password. Refer to sssd-ldap 5 for more details on these parameters. Please note that obfuscating the password provides no real security benefit as it is still possible for an attacker to reverse-engineer the password back. Using better authentication mechanisms such as client side certificates or GSSAPI is strongly advised. OPTIONS , The password to obfuscate will be read from standard input. , DOMAIN The SSSD domain to use the password in. The default name is default. , FILE Read the config file specified by the positional parameter. Default: /etc/sssd/sssd.conf sssd-1.13.4/src/man/PaxHeaders.16287/po0000644000000000000000000000013212703463557014237 xustar0030 mtime=1460561775.997798183 30 atime=1460561776.118798593 30 ctime=1460561775.997798183 sssd-1.13.4/src/man/po/0000755002412700241270000000000012703463557015770 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/man/po/PaxHeaders.16287/sssd-docs.pot0000644000000000000000000000007412703456111016733 xustar0030 atime=1460561751.640715593 30 ctime=1460561775.997798183 sssd-1.13.4/src/man/po/sssd-docs.pot0000644002412700241270000151677112703456111020424 0ustar00jhrozekjhrozek00000000000000# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR Red Hat # This file is distributed under the same license as the sssd-docs package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: sssd-docs 1.13.4\n" "Report-Msgid-Bugs-To: sssd-devel@redhat.com\n" "POT-Creation-Date: 2016-04-13 16:34+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Content of: #: sss_groupmod.8.xml:5 sssd.conf.5.xml:5 sssd-ldap.5.xml:5 pam_sss.8.xml:5 sssd_krb5_locator_plugin.8.xml:5 sssd-simple.5.xml:5 sssd-ipa.5.xml:5 sssd-ad.5.xml:5 sssd-sudo.5.xml:5 sssd.8.xml:5 sss_obfuscate.8.xml:5 sss_override.8.xml:5 sss_useradd.8.xml:5 sssd-krb5.5.xml:5 sss_groupadd.8.xml:5 sss_userdel.8.xml:5 sss_groupdel.8.xml:5 sss_groupshow.8.xml:5 sss_usermod.8.xml:5 sss_cache.8.xml:5 sss_debuglevel.8.xml:5 sss_seed.8.xml:5 sssd-ifp.5.xml:5 sss_rpcidmapd.5.xml:5 sss_ssh_authorizedkeys.1.xml:5 sss_ssh_knownhostsproxy.1.xml:5 msgid "SSSD Manual pages" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_groupmod.8.xml:10 sss_groupmod.8.xml:15 msgid "sss_groupmod" msgstr "" #. type: Content of: <reference><refentry><refmeta><manvolnum> #: sss_groupmod.8.xml:11 pam_sss.8.xml:14 sssd_krb5_locator_plugin.8.xml:11 sssd.8.xml:11 sss_obfuscate.8.xml:11 sss_override.8.xml:11 sss_useradd.8.xml:11 sss_groupadd.8.xml:11 sss_userdel.8.xml:11 sss_groupdel.8.xml:11 sss_groupshow.8.xml:11 sss_usermod.8.xml:11 sss_cache.8.xml:11 sss_debuglevel.8.xml:11 sss_seed.8.xml:11 msgid "8" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_groupmod.8.xml:16 msgid "modify a group" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_groupmod.8.xml:21 msgid "" "<command>sss_groupmod</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg " "choice='plain'><replaceable>GROUP</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sss_groupmod.8.xml:30 sssd-ldap.5.xml:21 pam_sss.8.xml:53 sssd_krb5_locator_plugin.8.xml:20 sssd-simple.5.xml:22 sssd-ipa.5.xml:21 sssd-ad.5.xml:21 sssd-sudo.5.xml:21 sssd.8.xml:29 sss_obfuscate.8.xml:30 sss_override.8.xml:30 sss_useradd.8.xml:30 sssd-krb5.5.xml:21 sss_groupadd.8.xml:30 sss_userdel.8.xml:30 sss_groupdel.8.xml:30 sss_groupshow.8.xml:30 sss_usermod.8.xml:30 sss_cache.8.xml:29 sss_debuglevel.8.xml:30 sss_seed.8.xml:31 sssd-ifp.5.xml:21 sss_ssh_authorizedkeys.1.xml:30 sss_ssh_knownhostsproxy.1.xml:31 msgid "DESCRIPTION" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_groupmod.8.xml:32 msgid "" "<command>sss_groupmod</command> modifies the group to reflect the changes " "that are specified on the command line." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sss_groupmod.8.xml:39 pam_sss.8.xml:60 sssd.8.xml:42 sss_obfuscate.8.xml:58 sss_useradd.8.xml:39 sss_groupadd.8.xml:39 sss_userdel.8.xml:39 sss_groupdel.8.xml:39 sss_groupshow.8.xml:39 sss_usermod.8.xml:39 sss_cache.8.xml:38 sss_debuglevel.8.xml:38 sss_seed.8.xml:42 sss_ssh_authorizedkeys.1.xml:76 sss_ssh_knownhostsproxy.1.xml:62 msgid "OPTIONS" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_groupmod.8.xml:43 sss_usermod.8.xml:77 msgid "" "<option>-a</option>,<option>--append-group</option> " "<replaceable>GROUPS</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_groupmod.8.xml:48 msgid "" "Append this group to groups specified by the " "<replaceable>GROUPS</replaceable> parameter. The " "<replaceable>GROUPS</replaceable> parameter is a comma separated list of " "group names." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_groupmod.8.xml:57 sss_usermod.8.xml:91 msgid "" "<option>-r</option>,<option>--remove-group</option> " "<replaceable>GROUPS</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_groupmod.8.xml:62 msgid "" "Remove this group from groups specified by the " "<replaceable>GROUPS</replaceable> parameter." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sssd.conf.5.xml:10 sssd.conf.5.xml:16 msgid "sssd.conf" msgstr "" #. type: Content of: <reference><refentry><refmeta><manvolnum> #: sssd.conf.5.xml:11 sssd-ldap.5.xml:11 sssd-simple.5.xml:11 sssd-ipa.5.xml:11 sssd-ad.5.xml:11 sssd-sudo.5.xml:11 sssd-krb5.5.xml:11 sssd-ifp.5.xml:11 sss_rpcidmapd.5.xml:27 msgid "5" msgstr "" #. type: Content of: <reference><refentry><refmeta><refmiscinfo> #: sssd.conf.5.xml:12 sssd-ldap.5.xml:12 sssd-simple.5.xml:12 sssd-ipa.5.xml:12 sssd-ad.5.xml:12 sssd-sudo.5.xml:12 sssd-krb5.5.xml:12 sssd-ifp.5.xml:12 sss_rpcidmapd.5.xml:28 msgid "File Formats and Conventions" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sssd.conf.5.xml:17 msgid "the configuration file for SSSD" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd.conf.5.xml:21 msgid "FILE FORMAT" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd.conf.5.xml:29 #, no-wrap msgid "" "<replaceable>[section]</replaceable>\n" "<replaceable>key</replaceable> = <replaceable>value</replaceable>\n" "<replaceable>key2</replaceable> = <replaceable>value2,value3</replaceable>\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.conf.5.xml:24 msgid "" "The file has an ini-style syntax and consists of sections and parameters. A " "section begins with the name of the section in square brackets and continues " "until the next section begins. An example of section with single and " "multi-valued parameters: <placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.conf.5.xml:36 msgid "" "The data types used are string (no quotes needed), integer and bool (with " "values of <quote>TRUE/FALSE</quote>)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.conf.5.xml:41 msgid "" "A line comment starts with a hash sign (<quote>#</quote>) or a semicolon " "(<quote>;</quote>). Inline comments are not supported." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.conf.5.xml:47 msgid "" "All sections can have an optional <replaceable>description</replaceable> " "parameter. Its function is only as a label for the section." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.conf.5.xml:53 msgid "" "<filename>sssd.conf</filename> must be a regular file, owned by root and " "only root may read from or write to the file." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd.conf.5.xml:59 msgid "GENERAL OPTIONS" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.conf.5.xml:61 msgid "Following options are usable in more than one configuration sections." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd.conf.5.xml:65 msgid "Options usable in all sections" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:69 msgid "debug_level (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:73 msgid "debug_timestamps (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:76 msgid "" "Add a timestamp to the debug messages. If journald is enabled for SSSD " "debug logging this option is ignored." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:81 sssd.conf.5.xml:634 sssd.conf.5.xml:1139 sssd-ldap.5.xml:1665 sssd-ldap.5.xml:1762 sssd-ldap.5.xml:1824 sssd-ldap.5.xml:2381 sssd-ldap.5.xml:2446 sssd-ldap.5.xml:2464 sssd-ipa.5.xml:405 sssd-ipa.5.xml:440 sssd-ad.5.xml:174 sssd-ad.5.xml:272 sssd-ad.5.xml:799 sssd-ad.5.xml:918 sssd-krb5.5.xml:499 msgid "Default: true" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:86 msgid "debug_microseconds (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:89 msgid "" "Add microseconds to the timestamp in debug messages. If journald is enabled " "for SSSD debug logging this option is ignored." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:94 sssd.conf.5.xml:1093 sssd.conf.5.xml:2231 sssd-ldap.5.xml:692 sssd-ldap.5.xml:1539 sssd-ldap.5.xml:1558 sssd-ldap.5.xml:1734 sssd-ldap.5.xml:2151 sssd-ipa.5.xml:139 sssd-ipa.5.xml:211 sssd-ipa.5.xml:542 sssd-krb5.5.xml:266 sssd-krb5.5.xml:300 sssd-krb5.5.xml:471 msgid "Default: false" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.conf.5.xml:67 sssd.conf.5.xml:105 sssd-ldap.5.xml:2189 msgid "<placeholder type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd.conf.5.xml:103 msgid "Options usable in SERVICE and DOMAIN sections" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:107 msgid "timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:110 msgid "" "Timeout in seconds between heartbeats for this service. This is used to " "ensure that the process is alive and capable of answering requests." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:115 sssd.conf.5.xml:1057 sssd-ldap.5.xml:1410 include/ldap_id_mapping.xml:264 msgid "Default: 10" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd.conf.5.xml:125 msgid "SPECIAL SECTIONS" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd.conf.5.xml:128 msgid "The [sssd] section" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><title> #: sssd.conf.5.xml:137 sssd.conf.5.xml:2339 msgid "Section parameters" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:139 msgid "config_file_version (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:142 msgid "" "Indicates what is the syntax of the config file. SSSD 0.6.0 and later use " "version 2." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:148 msgid "services" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:151 msgid "Comma separated list of services that are started when sssd itself starts." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:155 msgid "" "Supported services: nss, pam <phrase condition=\"with_sudo\">, sudo</phrase> " "<phrase condition=\"with_autofs\">, autofs</phrase> <phrase " "condition=\"with_ssh\">, ssh</phrase> <phrase " "condition=\"with_pac_responder\">, pac</phrase> <phrase " "condition=\"with_ifp\">, ifp</phrase>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:165 sssd.conf.5.xml:419 msgid "reconnection_retries (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:168 sssd.conf.5.xml:422 msgid "" "Number of times services should attempt to reconnect in the event of a Data " "Provider crash or restart before they give up" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:173 sssd.conf.5.xml:427 msgid "Default: 3" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:178 msgid "domains" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:181 msgid "" "A domain is a database containing user information. SSSD can use more " "domains at the same time, but at least one must be configured or SSSD won't " "start. This parameter described the list of domains in the order you want " "them to be queried. A domain name should only consist of alphanumeric ASCII " "characters, dashes, dots and underscores." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:193 sssd.conf.5.xml:2014 msgid "re_expression (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:196 msgid "" "Default regular expression that describes how to parse the string containing " "user name and domain into these components." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:201 msgid "" "Each domain can have an individual regular expression configured. For some " "ID providers there are also default regular expressions. See DOMAIN " "SECTIONS for more info on these regular expressions." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:210 sssd.conf.5.xml:2065 msgid "full_name_format (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:213 sssd.conf.5.xml:2068 msgid "" "A <citerefentry> <refentrytitle>printf</refentrytitle> " "<manvolnum>3</manvolnum> </citerefentry>-compatible format that describes " "how to compose a fully qualified name from user name and domain name " "components." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:224 sssd.conf.5.xml:2079 msgid "%1$s" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:225 sssd.conf.5.xml:2080 msgid "user name" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:228 sssd.conf.5.xml:2083 msgid "%2$s" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:231 sssd.conf.5.xml:2086 msgid "domain name as specified in the SSSD config file." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:237 sssd.conf.5.xml:2092 msgid "%3$s" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:240 sssd.conf.5.xml:2095 msgid "" "domain flat name. Mostly usable for Active Directory domains, both directly " "configured or discovered via IPA trusts." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:221 sssd.conf.5.xml:2076 msgid "" "The following expansions are supported: <placeholder type=\"variablelist\" " "id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:250 msgid "" "Each domain can have an individual format string configured. see DOMAIN " "SECTIONS for more info on this option." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:256 msgid "try_inotify (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:259 msgid "" "SSSD monitors the state of resolv.conf to identify when it needs to update " "its internal DNS resolver. By default, we will attempt to use inotify for " "this, and will fall back to polling resolv.conf every five seconds if " "inotify cannot be used." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:267 msgid "" "There are some limited situations where it is preferred that we should skip " "even trying to use inotify. In these rare cases, this option should be set " "to 'false'" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:273 msgid "" "Default: true on platforms where inotify is supported. False on other " "platforms." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:277 msgid "" "Note: this option will have no effect on platforms where inotify is " "unavailable. On these platforms, polling will always be used." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:284 msgid "krb5_rcache_dir (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:287 msgid "" "Directory on the filesystem where SSSD should store Kerberos replay cache " "files." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:291 msgid "" "This option accepts a special value __LIBKRB5_DEFAULTS__ that will instruct " "SSSD to let libkrb5 decide the appropriate location for the replay cache." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:297 msgid "" "Default: Distribution-specific and specified at " "build-time. (__LIBKRB5_DEFAULTS__ if not configured)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:304 msgid "user (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:307 msgid "" "The user to drop the privileges to where appropriate to avoid running as the " "root user." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:312 msgid "Default: not set, process will run as root" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:317 msgid "default_domain_suffix (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:320 msgid "" "This string will be used as a default domain name for all names without a " "domain name component. The main use case is environments where the primary " "domain is intended for managing host policies and all users are located in a " "trusted domain. The option allows those users to log in just with their " "user name without giving a domain name as well." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:330 msgid "" "Please note that if this option is set all users from the primary domain " "have to use their fully qualified name, e.g. user@domain.name, to log " "in. Setting this option changes default of use_fully_qualified_names to " "True. It is not allowed to use this option together with " "use_fully_qualified_names set to False." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:339 sssd-ldap.5.xml:663 sssd-ldap.5.xml:1498 sssd-ldap.5.xml:1510 sssd-ldap.5.xml:1592 sssd-ad.5.xml:609 sssd-ad.5.xml:679 sssd-krb5.5.xml:410 sssd-krb5.5.xml:550 include/ldap_id_mapping.xml:205 include/ldap_id_mapping.xml:216 msgid "Default: not set" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:344 msgid "override_space (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:347 msgid "" "This parameter will replace spaces (space bar) with the given character for " "user and group names. e.g. (_). User name "john doe" will be " ""john_doe" This feature was added to help compatibility with shell " "scripts that have difficulty handling spaces, due to the default field " "separator in the shell." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:356 msgid "" "Please note it is a configuration error to use a replacement character that " "might be used in user or group names. If a name contains the replacement " "character SSSD tries to return the unmodified name but in general the result " "of a lookup is undefined." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:364 msgid "Default: not set (spaces will not be replaced)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:369 msgid "certificate_verification (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:377 msgid "no_ocsp" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:379 msgid "" "Disables Online Certificate Status Protocol (OCSP) checks. This might be " "needed if the OCSP servers defined in the certificate are not reachable from " "the client." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:372 msgid "" "With this parameter the certificate verification can be tuned with a comma " "separated list of options. Supported options are: <placeholder " "type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:389 msgid "Unknown options are reported but ignored." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:392 msgid "Default: not set, i.e. do not restrict certificate vertification" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sssd.conf.5.xml:130 msgid "" "Individual pieces of SSSD functionality are provided by special SSSD " "services that are started and stopped together with SSSD. The services are " "managed by a special service frequently called <quote>monitor</quote>. The " "<quote>[sssd]</quote> section is used to configure the monitor as well as " "some other important options like the identity domains. <placeholder " "type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd.conf.5.xml:404 msgid "SERVICES SECTIONS" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.conf.5.xml:406 msgid "" "Settings that can be used to configure different services are described in " "this section. They should reside in the [<replaceable>$NAME</replaceable>] " "section, for example, for NSS service, the section would be " "<quote>[nss]</quote>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd.conf.5.xml:413 msgid "General service configuration options" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sssd.conf.5.xml:415 msgid "These options can be used to configure any service." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:432 msgid "fd_limit" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:435 msgid "" "This option specifies the maximum number of file descriptors that may be " "opened at one time by this SSSD process. On systems where SSSD is granted " "the CAP_SYS_RESOURCE capability, this will be an absolute setting. On " "systems without this capability, the resulting value will be the lower value " "of this or the limits.conf \"hard\" limit." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:444 msgid "Default: 8192 (or limits.conf \"hard\" limit)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:449 msgid "client_idle_timeout" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:452 msgid "" "This option specifies the number of seconds that a client of an SSSD process " "can hold onto a file descriptor without communicating on it. This value is " "limited in order to avoid resource exhaustion on the system." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:459 sssd.conf.5.xml:475 sssd.conf.5.xml:507 sssd.conf.5.xml:765 sssd.conf.5.xml:957 sssd.conf.5.xml:1347 sssd-ldap.5.xml:1237 msgid "Default: 60" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:464 sssd.conf.5.xml:1336 msgid "force_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:467 sssd.conf.5.xml:1339 msgid "" "If a service is not responding to ping checks (see the " "<quote>timeout</quote> option), it is first sent the SIGTERM signal that " "instructs it to quit gracefully. If the service does not terminate after " "<quote>force_timeout</quote> seconds, the monitor will forcibly shut it down " "by sending a SIGKILL signal." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:480 msgid "offline_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:483 msgid "" "When SSSD switches to offline mode the amount of time before it tries to go " "back online will increase based upon the time spent disconnected. This " "value is in seconds and calculated by the following:" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:490 msgid "offline_timeout + random_offset" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:493 msgid "" "The random offset can increment up to 30 seconds. After each unsuccessful " "attempt to go online, the new interval is recalculated by the following:" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:498 msgid "new_interval = old_interval*2 + random_offset" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:501 msgid "" "Note that the maximum length of each interval is currently limited to one " "hour. If the calculated length of new_interval is greater than an hour, it " "will be forced to one hour." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:512 msgid "subdomain_inherit (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:515 msgid "" "Specifies a list of configuration parameters that should be inherited by a " "subdomain. Please note that only selected parameters can be inherited. " "Currently the following options can be inherited:" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:521 msgid "ignore_group_members" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:524 msgid "ldap_purge_cache_timeout" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:527 sssd-ldap.5.xml:1054 msgid "ldap_use_tokengroups" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:530 msgid "ldap_user_principal" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><programlisting> #: sssd.conf.5.xml:535 #, no-wrap msgid "" "subdomain_inherit = ldap_purge_cache_timeout\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:533 msgid "Example: <placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:539 sssd.conf.5.xml:1001 sssd.conf.5.xml:1026 sssd.conf.5.xml:1045 sssd.conf.5.xml:1330 sssd-ldap.5.xml:1793 msgid "Default: none" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd.conf.5.xml:547 msgid "NSS configuration options" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sssd.conf.5.xml:549 msgid "" "These options can be used to configure the Name Service Switch (NSS) " "service." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:554 msgid "enum_cache_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:557 msgid "" "How many seconds should nss_sss cache enumerations (requests for info about " "all users)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:561 msgid "Default: 120" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:566 msgid "entry_cache_nowait_percentage (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:569 msgid "" "The entry cache can be set to automatically update entries in the background " "if they are requested beyond a percentage of the entry_cache_timeout value " "for the domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:575 msgid "" "For example, if the domain's entry_cache_timeout is set to 30s and " "entry_cache_nowait_percentage is set to 50 (percent), entries that come in " "after 15 seconds past the last cache update will be returned immediately, " "but the SSSD will go and update the cache on its own, so that future " "requests will not need to block waiting for a cache update." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:585 msgid "" "Valid values for this option are 0-99 and represent a percentage of the " "entry_cache_timeout for each domain. For performance reasons, this " "percentage will never reduce the nowait timeout to less than 10 seconds. (0 " "disables this feature)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:593 msgid "Default: 50" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:598 msgid "entry_negative_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:601 msgid "" "Specifies for how many seconds nss_sss should cache negative cache hits " "(that is, queries for invalid database entries, like nonexistent ones) " "before asking the back end again." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:607 sssd.conf.5.xml:1117 msgid "Default: 15" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:612 msgid "filter_users, filter_groups (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:615 msgid "" "Exclude certain users from being fetched from the sss NSS database. This is " "particularly useful for system accounts. This option can also be set " "per-domain or include fully-qualified names to filter only users from the " "particular domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:622 msgid "Default: root" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:627 msgid "filter_users_in_groups (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:630 msgid "If you want filtered user still be group members set this option to false." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:641 msgid "fallback_homedir (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:644 msgid "" "Set a default template for a user's home directory if one is not specified " "explicitly by the domain's data provider." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:649 msgid "The available values for this option are the same as for override_homedir." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><programlisting> #: sssd.conf.5.xml:655 #, no-wrap msgid "" "fallback_homedir = /home/%u\n" " " msgstr "" #. type: Content of: <varlistentry><listitem><para> #: sssd.conf.5.xml:653 sssd.conf.5.xml:1020 sssd.conf.5.xml:1039 sssd-krb5.5.xml:533 include/override_homedir.xml:55 msgid "example: <placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:659 msgid "Default: not set (no substitution for unset home directories)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:665 msgid "override_shell (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:668 msgid "" "Override the login shell for all users. This option supersedes any other " "shell options if it takes effect and can be set either in the [nss] section " "or per-domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:674 msgid "Default: not set (SSSD will use the value retrieved from LDAP)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:680 msgid "allowed_shells (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:683 msgid "Restrict user shell to one of the listed values. The order of evaluation is:" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:686 msgid "1. If the shell is present in <quote>/etc/shells</quote>, it is used." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:690 msgid "" "2. If the shell is in the allowed_shells list but not in " "<quote>/etc/shells</quote>, use the value of the shell_fallback parameter." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:695 msgid "" "3. If the shell is not in the allowed_shells list and not in " "<quote>/etc/shells</quote>, a nologin shell is used." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:700 msgid "The wildcard (*) can be used to allow any shell." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:703 msgid "" "The (*) is useful if you want to use shell_fallback in case that user's " "shell is not in <quote>/etc/shells</quote> and maintaining list of all " "allowed shells in allowed_shells would be to much overhead." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:710 msgid "An empty string for shell is passed as-is to libc." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:713 msgid "" "The <quote>/etc/shells</quote> is only read on SSSD start up, which means " "that a restart of the SSSD is required in case a new shell is installed." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:717 msgid "Default: Not set. The user shell is automatically used." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:722 msgid "vetoed_shells (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:725 msgid "Replace any instance of these shells with the shell_fallback" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:730 msgid "shell_fallback (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:733 msgid "" "The default shell to use if an allowed shell is not installed on the " "machine." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:737 msgid "Default: /bin/sh" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:742 msgid "default_shell" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:745 msgid "" "The default shell to use if the provider does not return one during " "lookup. This option can be specified globally in the [nss] section or " "per-domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:751 msgid "" "Default: not set (Return NULL if no shell is specified and rely on libc to " "substitute something sensible when necessary, usually /bin/sh)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:758 sssd.conf.5.xml:950 msgid "get_domains_timeout (int)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:761 sssd.conf.5.xml:953 msgid "" "Specifies time in seconds for which the list of subdomains will be " "considered valid." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:770 msgid "memcache_timeout (int)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:773 msgid "" "Specifies time in seconds for which records in the in-memory cache will be " "valid." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:777 sssd-ldap.5.xml:706 msgid "Default: 300" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:780 msgid "" "NOTE: If the environment variable SSS_NSS_USE_MEMCACHE is set to \"NO\", " "client applications will not use the fast in-memory cache." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.conf.5.xml:788 sssd-ifp.5.xml:74 msgid "user_attributes (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:791 msgid "" "Some of the additional NSS responder requests can return more attributes " "than just the POSIX ones defined by the NSS interface. The list of " "attributes is controlled by this option. It is handled the same way as the " "<quote>user_attributes</quote> option of the InfoPipe responder (see " "<citerefentry> <refentrytitle>sssd-ifp</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> for details) but with no default " "values." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:804 msgid "" "To make configuration more easy the NSS responder will check the InfoPipe " "option if it is not set for the NSS responder." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:809 msgid "Default: not set, fallback to InfoPipe option" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd.conf.5.xml:816 msgid "PAM configuration options" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sssd.conf.5.xml:818 msgid "" "These options can be used to configure the Pluggable Authentication Module " "(PAM) service." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:823 msgid "offline_credentials_expiration (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:826 msgid "" "If the authentication provider is offline, how long should we allow cached " "logins (in days since the last successful online login)." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:831 sssd.conf.5.xml:844 msgid "Default: 0 (No limit)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:837 msgid "offline_failed_login_attempts (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:840 msgid "" "If the authentication provider is offline, how many failed login attempts " "are allowed." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:850 msgid "offline_failed_login_delay (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:853 msgid "" "The time in minutes which has to pass after offline_failed_login_attempts " "has been reached before a new login attempt is possible." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:858 msgid "" "If set to 0 the user cannot authenticate offline if " "offline_failed_login_attempts has been reached. Only a successful online " "authentication can enable offline authentication again." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:864 sssd.conf.5.xml:917 msgid "Default: 5" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:870 msgid "pam_verbosity (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:873 msgid "" "Controls what kind of messages are shown to the user during " "authentication. The higher the number to more messages are displayed." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:878 msgid "Currently sssd supports the following values:" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:881 msgid "<emphasis>0</emphasis>: do not show any message" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:884 msgid "<emphasis>1</emphasis>: show only important messages" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:888 msgid "<emphasis>2</emphasis>: show informational messages" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:891 msgid "<emphasis>3</emphasis>: show all messages and debug information" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:895 sssd.8.xml:63 msgid "Default: 1" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:900 msgid "pam_id_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:903 msgid "" "For any PAM request while SSSD is online, the SSSD will attempt to " "immediately update the cached identity information for the user in order to " "ensure that authentication takes place with the latest information." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:909 msgid "" "A complete PAM conversation may perform multiple PAM requests, such as " "account management and session opening. This option controls (on a " "per-client-application basis) how long (in seconds) we can cache the " "identity information to avoid excessive round-trips to the identity " "provider." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:923 msgid "pam_pwd_expiration_warning (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:926 sssd.conf.5.xml:1550 msgid "Display a warning N days before the password expires." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:929 msgid "" "Please note that the backend server has to provide information about the " "expiration time of the password. If this information is missing, sssd " "cannot display a warning." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:935 sssd.conf.5.xml:1553 msgid "" "If zero is set, then this filter is not applied, i.e. if the expiration " "warning was received from backend server, it will automatically be " "displayed." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:940 msgid "" "This setting can be overridden by setting " "<emphasis>pwd_expiration_warning</emphasis> for a particular domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:945 sssd.conf.5.xml:2291 sssd.8.xml:79 msgid "Default: 0" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:962 msgid "pam_trusted_users (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:965 msgid "" "Specifies the comma-separated list of UID values or user names that are " "allowed to access the PAM responder. User names are resolved to UIDs at " "startup." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:971 msgid "Default: all (All users are allowed to access the PAM responder)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:975 msgid "" "Please note that UID 0 is always allowed to access the PAM responder even in " "case it is not in the pam_trusted_users list." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:982 msgid "pam_public_domains (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:985 msgid "" "Specifies the comma-separated list of domain names that are accessible even " "to untrusted users." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:989 msgid "Two special values for pam_public_domains option are defined:" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:993 msgid "all (Untrusted users are allowed to access all domains in PAM responder.)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:997 msgid "" "none (Untrusted users are not allowed to access any domains PAM in " "responder.)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:1006 msgid "pam_account_expired_message (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1009 msgid "" "Allows a custom expiration message to be set, replacing the default " "'Permission denied' message." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1014 msgid "" "Note: Please be aware that message is only printed for the SSH service " "unless pam_verbostiy is set to 3 (show all messages and debug information)." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><programlisting> #: sssd.conf.5.xml:1022 #, no-wrap msgid "" "pam_account_expired_message = Account expired, please contact help desk.\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:1031 msgid "pam_account_locked_message (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1034 msgid "" "Allows a custom lockout message to be set, replacing the default 'Permission " "denied' message." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para><programlisting> #: sssd.conf.5.xml:1041 #, no-wrap msgid "" "pam_account_locked_message = Account locked, please contact help desk.\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:1050 msgid "p11_child_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1053 msgid "How many seconds will pam_sss wait for p11_child to finish." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd.conf.5.xml:1066 msgid "SUDO configuration options" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sssd.conf.5.xml:1068 msgid "" "These options can be used to configure the sudo service. The detailed " "instructions for configuration of <citerefentry> " "<refentrytitle>sudo</refentrytitle> <manvolnum>8</manvolnum> </citerefentry> " "to work with <citerefentry> <refentrytitle>sssd</refentrytitle> " "<manvolnum>8</manvolnum> </citerefentry> are in the manual page " "<citerefentry> <refentrytitle>sssd-sudo</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry>." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:1085 msgid "sudo_timed (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1088 msgid "" "Whether or not to evaluate the sudoNotBefore and sudoNotAfter attributes " "that implement time-dependent sudoers entries." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd.conf.5.xml:1101 msgid "AUTOFS configuration options" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sssd.conf.5.xml:1103 msgid "These options can be used to configure the autofs service." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:1107 msgid "autofs_negative_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1110 msgid "" "Specifies for how many seconds should the autofs responder negative cache " "hits (that is, queries for invalid map entries, like nonexistent ones) " "before asking the back end again." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd.conf.5.xml:1126 msgid "SSH configuration options" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sssd.conf.5.xml:1128 msgid "These options can be used to configure the SSH service." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:1132 msgid "ssh_hash_known_hosts (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1135 msgid "" "Whether or not to hash host names and addresses in the managed known_hosts " "file." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:1144 msgid "ssh_known_hosts_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1147 msgid "" "How many seconds to keep a host in the managed known_hosts file after its " "host keys were requested." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1151 msgid "Default: 180" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:1156 msgid "ca_db (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1159 msgid "" "Path to a storage of trusted CA certificates. The option is used to validate " "user certificates before deriving public ssh keys from them." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1164 msgid "Default: /etc/pki/nssdb" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd.conf.5.xml:1172 msgid "PAC responder configuration options" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sssd.conf.5.xml:1174 msgid "" "The PAC responder works together with the authorization data plugin for MIT " "Kerberos sssd_pac_plugin.so and a sub-domain provider. The plugin sends the " "PAC data during a GSSAPI authentication to the PAC responder. The sub-domain " "provider collects domain SID and ID ranges of the domain the client is " "joined to and of remote trusted domains from the local domain controller. " "If the PAC is decoded and evaluated some of the following operations are " "done:" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><itemizedlist><listitem><para> #: sssd.conf.5.xml:1183 msgid "" "If the remote user does not exist in the cache, it is created. The uid is " "determined with the help of the SID, trusted domains will have UPGs and the " "gid will have the same value as the uid. The home directory is set based on " "the subdomain_homedir parameter. The shell will be empty by default, " "i.e. the system defaults are used, but can be overwritten with the " "default_shell parameter." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><itemizedlist><listitem><para> #: sssd.conf.5.xml:1191 msgid "" "If there are SIDs of groups from domains sssd knows about, the user will be " "added to those groups." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sssd.conf.5.xml:1197 msgid "These options can be used to configure the PAC responder." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.conf.5.xml:1201 sssd-ifp.5.xml:50 msgid "allowed_uids (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1204 msgid "" "Specifies the comma-separated list of UID values or user names that are " "allowed to access the PAC responder. User names are resolved to UIDs at " "startup." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1210 msgid "Default: 0 (only the root user is allowed to access the PAC responder)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1214 msgid "" "Please note that although the UID 0 is used as the default it will be " "overwritten with this option. If you still want to allow the root user to " "access the PAC responder, which would be the typical case, you have to add 0 " "to the list of allowed UIDs as well." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd.conf.5.xml:1228 msgid "DOMAIN SECTIONS" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1235 msgid "min_id,max_id (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1238 msgid "" "UID and GID limits for the domain. If a domain contains an entry that is " "outside these limits, it is ignored." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1243 msgid "" "For users, this affects the primary GID limit. The user will not be returned " "to NSS if either the UID or the primary GID is outside the range. For " "non-primary group memberships, those that are in range will be reported as " "expected." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1250 msgid "" "These ID limits affect even saving entries to cache, not only returning them " "by name or ID." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1254 msgid "Default: 1 for min_id, 0 (no limit) for max_id" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1260 msgid "enumerate (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1263 msgid "" "Determines if a domain can be enumerated. This parameter can have one of the " "following values:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1267 msgid "TRUE = Users and groups are enumerated" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1270 msgid "FALSE = No enumerations for this domain" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1273 sssd.conf.5.xml:1505 sssd.conf.5.xml:1672 msgid "Default: FALSE" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1276 msgid "" "Note: Enabling enumeration has a moderate performance impact on SSSD while " "enumeration is running. It may take up to several minutes after SSSD startup " "to fully complete enumerations. During this time, individual requests for " "information will go directly to LDAP, though it may be slow, due to the " "heavy enumeration processing. Saving a large number of entries to cache " "after the enumeration completes might also be CPU intensive as the " "memberships have to be recomputed." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1289 msgid "" "While the first enumeration is running, requests for the complete user or " "group lists may return no results until it completes." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1294 msgid "" "Further, enabling enumeration may increase the time necessary to detect " "network disconnection, as longer timeouts are required to ensure that " "enumeration lookups are completed successfully. For more information, refer " "to the man pages for the specific id_provider in use." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1302 msgid "" "For the reasons cited above, enabling enumeration is not recommended, " "especially in large environments." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1310 msgid "subdomain_enumerate (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1317 msgid "all" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1318 msgid "All discovered trusted domains will be enumerated" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1321 msgid "none" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1322 msgid "No discovered trusted domains will be enumerated" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1313 msgid "" "Whether any of autodetected trusted domains should be enumerated. The " "supported values are: <placeholder type=\"variablelist\" id=\"0\"/> " "Optionally, a list of one or more domain names can enable enumeration just " "for these trusted domains." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1353 msgid "entry_cache_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1356 msgid "" "How many seconds should nss_sss consider entries valid before asking the " "backend again" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1360 msgid "" "The cache expiration timestamps are stored as attributes of individual " "objects in the cache. Therefore, changing the cache timeout only has effect " "for newly added or expired entries. You should run the <citerefentry> " "<refentrytitle>sss_cache</refentrytitle> <manvolnum>8</manvolnum> " "</citerefentry> tool in order to force refresh of entries that have already " "been cached." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1373 msgid "Default: 5400" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1379 msgid "entry_cache_user_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1382 msgid "" "How many seconds should nss_sss consider user entries valid before asking " "the backend again" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1386 sssd.conf.5.xml:1399 sssd.conf.5.xml:1412 sssd.conf.5.xml:1425 sssd.conf.5.xml:1438 sssd.conf.5.xml:1452 sssd.conf.5.xml:1466 msgid "Default: entry_cache_timeout" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1392 msgid "entry_cache_group_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1395 msgid "" "How many seconds should nss_sss consider group entries valid before asking " "the backend again" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1405 msgid "entry_cache_netgroup_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1408 msgid "" "How many seconds should nss_sss consider netgroup entries valid before " "asking the backend again" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1418 msgid "entry_cache_service_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1421 msgid "" "How many seconds should nss_sss consider service entries valid before asking " "the backend again" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1431 msgid "entry_cache_sudo_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1434 msgid "" "How many seconds should sudo consider rules valid before asking the backend " "again" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1444 msgid "entry_cache_autofs_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1447 msgid "" "How many seconds should the autofs service consider automounter maps valid " "before asking the backend again" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1458 msgid "entry_cache_ssh_host_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1461 msgid "" "How many seconds to keep a host ssh key after refresh. IE how long to cache " "the host key for." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1472 msgid "refresh_expired_interval (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1475 msgid "" "Specifies how many seconds SSSD has to wait before triggering a background " "refresh task which will refresh all expired or nearly expired records." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1480 msgid "" "The background refresh will process users, groups and netgroups in the " "cache." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1484 msgid "You can consider setting this value to 3/4 * entry_cache_timeout." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1488 sssd-ldap.5.xml:730 sssd-ipa.5.xml:227 msgid "Default: 0 (disabled)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1494 msgid "cache_credentials (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1497 msgid "Determines if user credentials are also cached in the local LDB cache" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1501 msgid "User credentials are stored in a SHA512 hash, not in plaintext" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1511 msgid "cache_credentials_minimal_first_factor_length (int)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1514 msgid "" "If 2-Factor-Authentication (2FA) is used and credentials should be saved " "this value determines the minimal length the first authentication factor " "(long term password) must have to be saved as SHA512 hash into the cache." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1521 msgid "" "This should avoid that the short PINs of a PIN based 2FA scheme are saved in " "the cache which would make them easy targets for brute-force attacks." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1526 msgid "Default: 8" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1532 msgid "account_cache_expiration (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1535 msgid "" "Number of days entries are left in cache after last successful login before " "being removed during a cleanup of the cache. 0 means keep forever. The " "value of this parameter must be greater than or equal to " "offline_credentials_expiration." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1542 msgid "Default: 0 (unlimited)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1547 msgid "pwd_expiration_warning (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1558 msgid "" "Please note that the backend server has to provide information about the " "expiration time of the password. If this information is missing, sssd " "cannot display a warning. Also an auth provider has to be configured for the " "backend." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1565 msgid "Default: 7 (Kerberos), 0 (LDAP)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1571 msgid "id_provider (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1574 msgid "" "The identification provider used for the domain. Supported ID providers " "are:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1578 msgid "<quote>proxy</quote>: Support a legacy NSS provider" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1581 sssd.conf.5.xml:1718 msgid "<quote>local</quote>: SSSD internal provider for local users" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1585 msgid "" "<quote>ldap</quote>: LDAP provider. See <citerefentry> " "<refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> for more information on configuring LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1593 sssd.conf.5.xml:1698 sssd.conf.5.xml:1753 sssd.conf.5.xml:1806 msgid "" "<quote>ipa</quote>: FreeIPA and Red Hat Enterprise Identity Management " "provider. See <citerefentry> <refentrytitle>sssd-ipa</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> for more information on configuring " "FreeIPA." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1602 sssd.conf.5.xml:1707 sssd.conf.5.xml:1762 sssd.conf.5.xml:1815 msgid "" "<quote>ad</quote>: Active Directory provider. See <citerefentry> " "<refentrytitle>sssd-ad</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> for more information on configuring Active Directory." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1613 msgid "use_fully_qualified_names (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1616 msgid "" "Use the full name and domain (as formatted by the domain's full_name_format) " "as the user's login name reported to NSS." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1621 msgid "" "If set to TRUE, all requests to this domain must use fully qualified " "names. For example, if used in LOCAL domain that contains a \"test\" user, " "<command>getent passwd test</command> wouldn't find the user while " "<command>getent passwd test@LOCAL</command> would." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1629 msgid "" "NOTE: This option has no effect on netgroup lookups due to their tendency to " "include nested netgroups without qualified names. For netgroups, all domains " "will be searched when an unqualified name is requested." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1636 msgid "Default: FALSE (TRUE if default_domain_suffix is used)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1642 msgid "ignore_group_members (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1645 msgid "Do not return group members for group lookups." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1648 msgid "" "If set to TRUE, the group membership attribute is not requested from the " "ldap server, and group members are not returned when processing group lookup " "calls, such as <citerefentry> <refentrytitle>getgrnam</refentrytitle> " "<manvolnum>3</manvolnum> </citerefentry> or <citerefentry> " "<refentrytitle>getgrgid</refentrytitle> <manvolnum>3</manvolnum> " "</citerefentry>. As an effect, <quote>getent group $groupname</quote> would " "return the requested group as if it was empty." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1666 msgid "" "Enabling this option can also make access provider checks for group " "membership significantly faster, especially for groups containing many " "members." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1677 msgid "auth_provider (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1680 msgid "" "The authentication provider used for the domain. Supported auth providers " "are:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1684 sssd.conf.5.xml:1746 msgid "" "<quote>ldap</quote> for native LDAP authentication. See <citerefentry> " "<refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> for more information on configuring LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1691 msgid "" "<quote>krb5</quote> for Kerberos authentication. See <citerefentry> " "<refentrytitle>sssd-krb5</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> for more information on configuring Kerberos." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1715 msgid "<quote>proxy</quote> for relaying authentication to some other PAM target." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1722 msgid "<quote>none</quote> disables authentication explicitly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1725 msgid "" "Default: <quote>id_provider</quote> is used if it is set and can handle " "authentication requests." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1731 msgid "access_provider (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1734 msgid "" "The access control provider used for the domain. There are two built-in " "access providers (in addition to any included in installed backends) " "Internal special providers are:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1740 msgid "" "<quote>permit</quote> always allow access. It's the only permitted access " "provider for a local domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1743 msgid "<quote>deny</quote> always deny access." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1770 msgid "" "<quote>simple</quote> access control based on access or deny lists. See " "<citerefentry> <refentrytitle>sssd-simple</refentrytitle> " "<manvolnum>5</manvolnum></citerefentry> for more information on configuring " "the simple access module." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1777 msgid "Default: <quote>permit</quote>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1782 msgid "chpass_provider (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1785 msgid "" "The provider which should handle change password operations for the domain. " "Supported change password providers are:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1790 msgid "" "<quote>ldap</quote> to change a password stored in a LDAP server. See " "<citerefentry> <refentrytitle>sssd-ldap</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> for more information on configuring " "LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1798 msgid "" "<quote>krb5</quote> to change the Kerberos password. See <citerefentry> " "<refentrytitle>sssd-krb5</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> for more information on configuring Kerberos." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1823 msgid "<quote>proxy</quote> for relaying password changes to some other PAM target." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1827 msgid "<quote>none</quote> disallows password changes explicitly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1830 msgid "" "Default: <quote>auth_provider</quote> is used if it is set and can handle " "change password requests." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1837 msgid "sudo_provider (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1840 msgid "The SUDO provider used for the domain. Supported SUDO providers are:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1844 msgid "" "<quote>ldap</quote> for rules stored in LDAP. See <citerefentry> " "<refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> for more information on configuring LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1852 msgid "" "<quote>ipa</quote> the same as <quote>ldap</quote> but with IPA default " "settings." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1856 msgid "" "<quote>ad</quote> the same as <quote>ldap</quote> but with AD default " "settings." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1860 msgid "<quote>none</quote> disables SUDO explicitly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1863 sssd.conf.5.xml:1941 sssd.conf.5.xml:1982 sssd.conf.5.xml:2007 msgid "Default: The value of <quote>id_provider</quote> is used if it is set." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1867 msgid "" "The detailed instructions for configuration of sudo_provider are in the " "manual page <citerefentry> <refentrytitle>sssd-sudo</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry>. There are many configuration " "options that can be used to adjust the behavior. Please refer to " "\"ldap_sudo_*\" in <citerefentry> <refentrytitle>sssd-ldap</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry>." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1884 msgid "selinux_provider (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1887 msgid "" "The provider which should handle loading of selinux settings. Note that this " "provider will be called right after access provider ends. Supported selinux " "providers are:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1893 msgid "" "<quote>ipa</quote> to load selinux settings from an IPA server. See " "<citerefentry> <refentrytitle>sssd-ipa</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> for more information on configuring " "IPA." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1901 msgid "<quote>none</quote> disallows fetching selinux settings explicitly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1904 msgid "" "Default: <quote>id_provider</quote> is used if it is set and can handle " "selinux loading requests." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1910 msgid "subdomains_provider (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1913 msgid "" "The provider which should handle fetching of subdomains. This value should " "be always the same as id_provider. Supported subdomain providers are:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1919 msgid "" "<quote>ipa</quote> to load a list of subdomains from an IPA server. See " "<citerefentry> <refentrytitle>sssd-ipa</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> for more information on configuring " "IPA." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1928 msgid "" "<quote>ad</quote> to load a list of subdomains from an Active Directory " "server. See <citerefentry> <refentrytitle>sssd-ad</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> for more information on configuring " "the AD provider." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1937 msgid "<quote>none</quote> disallows fetching subdomains explicitly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1948 msgid "autofs_provider (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1951 msgid "The autofs provider used for the domain. Supported autofs providers are:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1955 msgid "" "<quote>ldap</quote> to load maps stored in LDAP. See <citerefentry> " "<refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> for more information on configuring LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1962 msgid "" "<quote>ipa</quote> to load maps stored in an IPA server. See <citerefentry> " "<refentrytitle>sssd-ipa</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> for more information on configuring IPA." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1970 msgid "" "<quote>ad</quote> to load maps stored in an AD server. See <citerefentry> " "<refentrytitle>sssd-ad</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> for more information on configuring the AD provider." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1979 msgid "<quote>none</quote> disables autofs explicitly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:1989 msgid "hostid_provider (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1992 msgid "" "The provider used for retrieving host identity information. Supported " "hostid providers are:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:1996 msgid "" "<quote>ipa</quote> to load host identity stored in an IPA server. See " "<citerefentry> <refentrytitle>sssd-ipa</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> for more information on configuring " "IPA." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2004 msgid "<quote>none</quote> disables hostid explicitly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2017 msgid "" "Regular expression for this domain that describes how to parse the string " "containing user name and domain into these components. The \"domain\" can " "match either the SSSD configuration domain name, or, in the case of IPA " "trust subdomains and Active Directory domains, the flat (NetBIOS) name of " "the domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2026 msgid "" "Default for the AD and IPA provider: " "<quote>(((?P<domain>[^\\\\]+)\\\\(?P<name>.+$))|((?P<name>[^@]+)@(?P<domain>.+$))|(^(?P<name>[^@\\\\]+)$))</quote> " "which allows three different styles for user names:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd.conf.5.xml:2031 msgid "username" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd.conf.5.xml:2034 msgid "username@domain.name" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd.conf.5.xml:2037 msgid "domain\\username" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2040 msgid "" "While the first two correspond to the general default the third one is " "introduced to allow easy integration of users from Windows domains." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2045 msgid "" "Default: <quote>(?P<name>[^@]+)@?(?P<domain>[^@]*$)</quote> " "which translates to \"the name is everything up to the <quote>@</quote> " "sign, the domain everything after that\"" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2051 msgid "" "PLEASE NOTE: the support for non-unique named subpatterns is not available " "on all platforms (e.g. RHEL5 and SLES10). Only platforms with libpcre " "version 7 or higher can support non-unique named subpatterns." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2058 msgid "" "PLEASE NOTE ALSO: older version of libpcre only support the Python syntax " "(?P<name>) to label subpatterns." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2105 msgid "Default: <quote>%1$s@%2$s</quote>." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2111 msgid "lookup_family_order (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2114 msgid "" "Provides the ability to select preferred address family to use when " "performing DNS lookups." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2118 msgid "Supported values:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2121 msgid "ipv4_first: Try looking up IPv4 address, if that fails, try IPv6" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2124 msgid "ipv4_only: Only attempt to resolve hostnames to IPv4 addresses." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2127 msgid "ipv6_first: Try looking up IPv6 address, if that fails, try IPv4" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2130 msgid "ipv6_only: Only attempt to resolve hostnames to IPv6 addresses." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2133 msgid "Default: ipv4_first" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2139 msgid "dns_resolver_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2142 msgid "" "Defines the amount of time (in seconds) to wait for a reply from the DNS " "resolver before assuming that it is unreachable. If this timeout is reached, " "the domain will continue to operate in offline mode." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2148 sssd-ldap.5.xml:1221 sssd-ldap.5.xml:1263 sssd-ldap.5.xml:1281 sssd-krb5.5.xml:248 msgid "Default: 6" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2154 msgid "dns_discovery_domain (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2157 msgid "" "If service discovery is used in the back end, specifies the domain part of " "the service discovery DNS query." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2161 msgid "Default: Use the domain part of machine's hostname" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2167 msgid "override_gid (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2170 msgid "Override the primary GID value with the one specified." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2176 msgid "case_sensitive (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2184 msgid "True" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2187 msgid "Case sensitive. This value is invalid for AD provider." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2193 msgid "False" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2195 msgid "Case insensitive." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2199 msgid "Preserving" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2202 msgid "" "Same as False (case insensitive), but does not lowercase names in the result " "of NSS operations. Note that name aliases (and in case of services also " "protocol names) are still lowercased in the output." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2179 msgid "" "Treat user and group names as case sensitive. At the moment, this option is " "not supported in the local provider. Possible option values are: " "<placeholder type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2214 msgid "Default: True (False for AD provider)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2220 msgid "proxy_fast_alias (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2223 msgid "" "When a user or group is looked up by name in the proxy provider, a second " "lookup by ID is performed to \"canonicalize\" the name in case the requested " "name was an alias. Setting this option to true would cause the SSSD to " "perform the ID lookup from cache for performance reasons." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2237 msgid "subdomain_homedir (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2248 msgid "%F" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2249 msgid "flat (NetBIOS) name of a subdomain." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2240 msgid "" "Use this homedir as default value for all subdomains within this domain in " "IPA AD trust. See <emphasis>override_homedir</emphasis> for info about " "possible values. In addition to those, the expansion below can only be used " "with <emphasis>subdomain_homedir</emphasis>. <placeholder " "type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2254 msgid "The value can be overridden by <emphasis>override_homedir</emphasis> option." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2258 msgid "Default: <filename>/home/%d/%u</filename>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2263 msgid "realmd_tags (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2266 msgid "Various tags stored by the realmd configuration service for this domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2272 msgid "cached_auth_timeout (int)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2275 msgid "" "Specifies time in seconds since last successful online authentication for " "which user will be authenticated using cached credentials while SSSD is in " "the online mode." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2281 msgid "Special value 0 implies that this feature is disabled." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2285 msgid "" "Please note that if <quote>cached_auth_timeout</quote> is longer than " "<quote>pam_id_timeout</quote> then the back end could be called to handle " "<quote>initgroups.</quote>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.conf.5.xml:1230 msgid "" "These configuration options can be present in a domain configuration " "section, that is, in a section called " "<quote>[domain/<replaceable>NAME</replaceable>]</quote> <placeholder " "type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2303 msgid "proxy_pam_target (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2306 msgid "The proxy target PAM proxies to." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2309 msgid "" "Default: not set by default, you have to take an existing pam configuration " "or create a new one and add the service name here." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd.conf.5.xml:2317 msgid "proxy_lib_name (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2320 msgid "" "The name of the NSS library to use in proxy domains. The NSS functions " "searched for in the library are in the form of _nss_$(libName)_$(function), " "for example _nss_files_getpwent." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.conf.5.xml:2299 msgid "" "Options valid for proxy domains. <placeholder type=\"variablelist\" " "id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd.conf.5.xml:2332 msgid "The local domain section" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sssd.conf.5.xml:2334 msgid "" "This section contains settings for domain that stores users and groups in " "SSSD native database, that is, a domain that uses " "<replaceable>id_provider=local</replaceable>." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:2341 msgid "default_shell (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2344 msgid "The default shell for users created with SSSD userspace tools." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2348 msgid "Default: <filename>/bin/bash</filename>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:2353 msgid "base_directory (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2356 msgid "" "The tools append the login name to <replaceable>base_directory</replaceable> " "and use that as the home directory." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2361 msgid "Default: <filename>/home</filename>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:2366 msgid "create_homedir (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2369 msgid "" "Indicate if a home directory should be created by default for new users. " "Can be overridden on command line." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2373 sssd.conf.5.xml:2385 msgid "Default: TRUE" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:2378 msgid "remove_homedir (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2381 msgid "" "Indicate if a home directory should be removed by default for deleted " "users. Can be overridden on command line." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:2390 msgid "homedir_umask (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2393 msgid "" "Used by <citerefentry> <refentrytitle>sss_useradd</refentrytitle> " "<manvolnum>8</manvolnum> </citerefentry> to specify the default permissions " "on a newly created home directory." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2401 msgid "Default: 077" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:2406 msgid "skel_dir (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2409 msgid "" "The skeleton directory, which contains files and directories to be copied in " "the user's home directory, when the home directory is created by " "<citerefentry> <refentrytitle>sss_useradd</refentrytitle> " "<manvolnum>8</manvolnum> </citerefentry>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2419 msgid "Default: <filename>/etc/skel</filename>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:2424 msgid "mail_dir (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2427 msgid "" "The mail spool directory. This is needed to manipulate the mailbox when its " "corresponding user account is modified or deleted. If not specified, a " "default value is used." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2434 msgid "Default: <filename>/var/mail</filename>" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sssd.conf.5.xml:2439 msgid "userdel_cmd (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2442 msgid "" "The command that is run after a user is removed. The command us passed the " "username of the user being removed as the first and only parameter. The " "return code of the command is not taken into account." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd.conf.5.xml:2448 msgid "Default: None, no command is run" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd.conf.5.xml:2458 sssd-ldap.5.xml:2629 sssd-simple.5.xml:131 sssd-ipa.5.xml:717 sssd-ad.5.xml:955 sssd-krb5.5.xml:564 sss_rpcidmapd.5.xml:98 msgid "EXAMPLE" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd.conf.5.xml:2464 #, no-wrap msgid "" "[sssd]\n" "domains = LDAP\n" "services = nss, pam\n" "config_file_version = 2\n" "\n" "[nss]\n" "filter_groups = root\n" "filter_users = root\n" "\n" "[pam]\n" "\n" "[domain/LDAP]\n" "id_provider = ldap\n" "ldap_uri = ldap://ldap.example.com\n" "ldap_search_base = dc=example,dc=com\n" "\n" "auth_provider = krb5\n" "krb5_server = kerberos.example.com\n" "krb5_realm = EXAMPLE.COM\n" "cache_credentials = true\n" "\n" "min_id = 10000\n" "max_id = 20000\n" "enumerate = False\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.conf.5.xml:2460 msgid "" "The following example shows a typical SSSD config. It does not describe " "configuration of the domains themselves - refer to documentation on " "configuring domains for more details. <placeholder type=\"programlisting\" " "id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sssd-ldap.5.xml:10 sssd-ldap.5.xml:16 msgid "sssd-ldap" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sssd-ldap.5.xml:17 msgid "SSSD LDAP provider" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:23 msgid "" "This manual page describes the configuration of LDAP domains for " "<citerefentry> <refentrytitle>sssd</refentrytitle> <manvolnum>8</manvolnum> " "</citerefentry>. Refer to the <quote>FILE FORMAT</quote> section of the " "<citerefentry> <refentrytitle>sssd.conf</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> manual page for detailed syntax " "information." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:35 msgid "You can configure SSSD to use more than one LDAP domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:38 msgid "" "LDAP back end supports id, auth, access and chpass providers. If you want to " "authenticate against an LDAP server either TLS/SSL or LDAPS is " "required. <command>sssd</command> <emphasis>does not</emphasis> support " "authentication over an unencrypted channel. If the LDAP server is used only " "as an identity provider, an encrypted channel is not needed. Please refer to " "<quote>ldap_access_filter</quote> config option for more information about " "using LDAP as an access provider." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd-ldap.5.xml:49 sssd-simple.5.xml:69 sssd-ipa.5.xml:70 sssd-ad.5.xml:89 sssd-krb5.5.xml:63 sssd-ifp.5.xml:44 msgid "CONFIGURATION OPTIONS" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:60 msgid "ldap_uri, ldap_backup_uri (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:63 msgid "" "Specifies the comma-separated list of URIs of the LDAP servers to which SSSD " "should connect in the order of preference. Refer to the " "<quote>FAILOVER</quote> section for more information on failover and server " "redundancy. If neither option is specified, service discovery is " "enabled. For more information, refer to the <quote>SERVICE DISCOVERY</quote> " "section." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:70 msgid "The format of the URI must match the format defined in RFC 2732:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:73 msgid "ldap[s]://<host>[:port]" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:76 msgid "For explicit IPv6 addresses, <host> must be enclosed in brackets []" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:79 msgid "example: ldap://[fc00::126:25]:389" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:85 msgid "ldap_chpass_uri, ldap_chpass_backup_uri (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:88 msgid "" "Specifies the comma-separated list of URIs of the LDAP servers to which SSSD " "should connect in the order of preference to change the password of a " "user. Refer to the <quote>FAILOVER</quote> section for more information on " "failover and server redundancy." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:95 msgid "To enable service discovery ldap_chpass_dns_service_name must be set." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:99 msgid "Default: empty, i.e. ldap_uri is used." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:105 msgid "ldap_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:108 msgid "The default base DN to use for performing LDAP user operations." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:112 msgid "" "Starting with SSSD 1.7.0, SSSD supports multiple search bases using the " "syntax:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:116 msgid "search_base[?scope?[filter][?search_base?scope?[filter]]*]" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:119 msgid "The scope can be one of \"base\", \"onelevel\" or \"subtree\"." msgstr "" #. type: Content of: <listitem><para> #: sssd-ldap.5.xml:122 include/ldap_search_bases.xml:18 msgid "" "The filter must be a valid LDAP search filter as specified by " "http://www.ietf.org/rfc/rfc2254.txt" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:126 sssd-ldap.5.xml:646 sssd-ad.5.xml:220 sss_override.8.xml:135 sss_override.8.xml:232 msgid "Examples:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:129 msgid "" "ldap_search_base = dc=example,dc=com (which is equivalent to) " "ldap_search_base = dc=example,dc=com?subtree?" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:134 msgid "" "ldap_search_base = " "cn=host_specific,dc=example,dc=com?subtree?(host=thishost)?dc=example.com?subtree?" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:137 msgid "" "Note: It is unsupported to have multiple search bases which reference " "identically-named objects (for example, groups with the same name in two " "different search bases). This will lead to unpredictable behavior on client " "machines." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:144 msgid "" "Default: If not set, the value of the defaultNamingContext or namingContexts " "attribute from the RootDSE of the LDAP server is used. If " "defaultNamingContext does not exist or has an empty value namingContexts is " "used. The namingContexts attribute must have a single value with the DN of " "the search base of the LDAP server to make this work. Multiple values are " "are not supported." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:158 msgid "ldap_schema (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:161 msgid "" "Specifies the Schema Type in use on the target LDAP server. Depending on " "the selected schema, the default attribute names retrieved from the servers " "may vary. The way that some attributes are handled may also differ." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:168 msgid "Four schema types are currently supported:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ldap.5.xml:172 msgid "rfc2307" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ldap.5.xml:177 msgid "rfc2307bis" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ldap.5.xml:182 msgid "IPA" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ldap.5.xml:187 msgid "AD" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:193 msgid "" "The main difference between these schema types is how group memberships are " "recorded in the server. With rfc2307, group members are listed by name in " "the <emphasis>memberUid</emphasis> attribute. With rfc2307bis and IPA, " "group members are listed by DN and stored in the <emphasis>member</emphasis> " "attribute. The AD schema type sets the attributes to correspond with Active " "Directory 2008r2 values." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:203 msgid "Default: rfc2307" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:209 msgid "ldap_default_bind_dn (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:212 msgid "The default bind DN to use for performing LDAP operations." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:219 msgid "ldap_default_authtok_type (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:222 msgid "The type of the authentication token of the default bind DN." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:226 msgid "The two mechanisms currently supported are:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:229 msgid "password" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:232 msgid "obfuscated_password" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:235 msgid "Default: password" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:241 msgid "ldap_default_authtok (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:244 msgid "" "The authentication token of the default bind DN. Only clear text passwords " "are currently supported." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:251 msgid "ldap_user_object_class (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:254 msgid "The object class of a user entry in LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:257 msgid "Default: posixAccount" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:263 msgid "ldap_user_name (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:266 msgid "The LDAP attribute that corresponds to the user's login name." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:270 msgid "Default: uid" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:276 msgid "ldap_user_uid_number (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:279 msgid "The LDAP attribute that corresponds to the user's id." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:283 msgid "Default: uidNumber" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:289 msgid "ldap_user_gid_number (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:292 msgid "The LDAP attribute that corresponds to the user's primary group id." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:296 sssd-ldap.5.xml:863 msgid "Default: gidNumber" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:302 msgid "ldap_user_gecos (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:305 msgid "The LDAP attribute that corresponds to the user's gecos field." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:309 msgid "Default: gecos" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:315 msgid "ldap_user_home_directory (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:318 msgid "The LDAP attribute that contains the name of the user's home directory." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:322 msgid "Default: homeDirectory" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:328 msgid "ldap_user_shell (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:331 msgid "The LDAP attribute that contains the path to the user's default shell." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:335 msgid "Default: loginShell" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:341 msgid "ldap_user_uuid (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:344 msgid "The LDAP attribute that contains the UUID/GUID of an LDAP user object." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:348 sssd-ldap.5.xml:889 msgid "" "Default: not set in the general case, objectGUID for AD and ipaUniqueID for " "IPA" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:355 msgid "ldap_user_objectsid (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:358 msgid "" "The LDAP attribute that contains the objectSID of an LDAP user object. This " "is usually only necessary for ActiveDirectory servers." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:363 sssd-ldap.5.xml:904 msgid "Default: objectSid for ActiveDirectory, not set for other servers." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:370 msgid "ldap_user_modify_timestamp (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:373 sssd-ldap.5.xml:914 sssd-ldap.5.xml:1137 msgid "" "The LDAP attribute that contains timestamp of the last modification of the " "parent object." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:377 sssd-ldap.5.xml:918 sssd-ldap.5.xml:1144 msgid "Default: modifyTimestamp" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:383 msgid "ldap_user_shadow_last_change (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:386 msgid "" "When using ldap_pwd_policy=shadow, this parameter contains the name of an " "LDAP attribute corresponding to its <citerefentry> " "<refentrytitle>shadow</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> counterpart (date of the last password change)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:396 msgid "Default: shadowLastChange" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:402 msgid "ldap_user_shadow_min (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:405 msgid "" "When using ldap_pwd_policy=shadow, this parameter contains the name of an " "LDAP attribute corresponding to its <citerefentry> " "<refentrytitle>shadow</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> counterpart (minimum password age)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:414 msgid "Default: shadowMin" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:420 msgid "ldap_user_shadow_max (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:423 msgid "" "When using ldap_pwd_policy=shadow, this parameter contains the name of an " "LDAP attribute corresponding to its <citerefentry> " "<refentrytitle>shadow</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> counterpart (maximum password age)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:432 msgid "Default: shadowMax" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:438 msgid "ldap_user_shadow_warning (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:441 msgid "" "When using ldap_pwd_policy=shadow, this parameter contains the name of an " "LDAP attribute corresponding to its <citerefentry> " "<refentrytitle>shadow</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> counterpart (password warning period)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:451 msgid "Default: shadowWarning" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:457 msgid "ldap_user_shadow_inactive (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:460 msgid "" "When using ldap_pwd_policy=shadow, this parameter contains the name of an " "LDAP attribute corresponding to its <citerefentry> " "<refentrytitle>shadow</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> counterpart (password inactivity period)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:470 msgid "Default: shadowInactive" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:476 msgid "ldap_user_shadow_expire (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:479 msgid "" "When using ldap_pwd_policy=shadow or ldap_account_expire_policy=shadow, this " "parameter contains the name of an LDAP attribute corresponding to its " "<citerefentry> <refentrytitle>shadow</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> counterpart (account expiration " "date)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:489 msgid "Default: shadowExpire" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:495 msgid "ldap_user_krb_last_pwd_change (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:498 msgid "" "When using ldap_pwd_policy=mit_kerberos, this parameter contains the name of " "an LDAP attribute storing the date and time of last password change in " "kerberos." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:504 msgid "Default: krbLastPwdChange" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:510 msgid "ldap_user_krb_password_expiration (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:513 msgid "" "When using ldap_pwd_policy=mit_kerberos, this parameter contains the name of " "an LDAP attribute storing the date and time when current password expires." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:519 msgid "Default: krbPasswordExpiration" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:525 msgid "ldap_user_ad_account_expires (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:528 msgid "" "When using ldap_account_expire_policy=ad, this parameter contains the name " "of an LDAP attribute storing the expiration time of the account." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:533 msgid "Default: accountExpires" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:539 msgid "ldap_user_ad_user_account_control (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:542 msgid "" "When using ldap_account_expire_policy=ad, this parameter contains the name " "of an LDAP attribute storing the user account control bit field." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:547 msgid "Default: userAccountControl" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:553 msgid "ldap_ns_account_lock (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:556 msgid "" "When using ldap_account_expire_policy=rhds or equivalent, this parameter " "determines if access is allowed or not." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:561 msgid "Default: nsAccountLock" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:567 msgid "ldap_user_nds_login_disabled (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:570 msgid "" "When using ldap_account_expire_policy=nds, this attribute determines if " "access is allowed or not." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:574 sssd-ldap.5.xml:588 msgid "Default: loginDisabled" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:580 msgid "ldap_user_nds_login_expiration_time (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:583 msgid "" "When using ldap_account_expire_policy=nds, this attribute determines until " "which date access is granted." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:594 msgid "ldap_user_nds_login_allowed_time_map (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:597 msgid "" "When using ldap_account_expire_policy=nds, this attribute determines the " "hours of a day in a week when access is granted." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:602 msgid "Default: loginAllowedTimeMap" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:608 msgid "ldap_user_principal (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:611 msgid "" "The LDAP attribute that contains the user's Kerberos User Principal Name " "(UPN)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:615 msgid "Default: krbPrincipalName" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:621 msgid "ldap_user_extra_attrs (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:624 msgid "" "Comma-separated list of LDAP attributes that SSSD would fetch along with the " "usual set of user attributes." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:629 msgid "" "The list can either contain LDAP attribute names only, or colon-separated " "tuples of SSSD cache attribute name and LDAP attribute name. In case only " "LDAP attribute name is specified, the attribute is saved to the cache " "verbatim. Using a custom SSSD attribute name might be required by " "environments that configure several SSSD domains with different LDAP " "schemas." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:639 msgid "" "Please note that several attribute names are reserved by SSSD, notably the " "<quote>name</quote> attribute. SSSD would report an error if any of the " "reserved attribute names is used as an extra attribute name." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:649 msgid "ldap_user_extra_attrs = telephoneNumber" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:652 msgid "" "Save the <quote>telephoneNumber</quote> attribute from LDAP as " "<quote>telephoneNumber</quote> to the cache." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:656 msgid "ldap_user_extra_attrs = phone:telephoneNumber" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:659 msgid "" "Save the <quote>telephoneNumber</quote> attribute from LDAP as " "<quote>phone</quote> to the cache." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:669 msgid "ldap_user_ssh_public_key (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:672 msgid "The LDAP attribute that contains the user's SSH public keys." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:676 msgid "Default: sshPublicKey" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:682 msgid "ldap_force_upper_case_realm (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:685 msgid "" "Some directory servers, for example Active Directory, might deliver the " "realm part of the UPN in lower case, which might cause the authentication to " "fail. Set this option to a non-zero value if you want to use an upper-case " "realm." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:698 msgid "ldap_enumeration_refresh_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:701 msgid "" "Specifies how many seconds SSSD has to wait before refreshing its cache of " "enumerated records." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:712 msgid "ldap_purge_cache_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:715 msgid "" "Determine how often to check the cache for inactive entries (such as groups " "with no members and users who have never logged in) and remove them to save " "space." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:721 msgid "" "Setting this option to zero will disable the cache cleanup operation. Please " "note that if enumeration is enabled, the cleanup task is required in order " "to detect entries removed from the server and can't be disabled. By default, " "the cleanup task will run every 3 hours with enumeration enabled." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:736 msgid "ldap_user_fullname (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:739 msgid "The LDAP attribute that corresponds to the user's full name." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:743 sssd-ldap.5.xml:850 sssd-ldap.5.xml:1095 sssd-ldap.5.xml:1169 sssd-ldap.5.xml:2210 sssd-ipa.5.xml:590 msgid "Default: cn" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:749 msgid "ldap_user_member_of (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:752 msgid "The LDAP attribute that lists the user's group memberships." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:756 msgid "Default: memberOf" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:762 msgid "ldap_user_authorized_service (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:765 msgid "" "If access_provider=ldap and ldap_access_order=authorized_service, SSSD will " "use the presence of the authorizedService attribute in the user's LDAP entry " "to determine access privilege." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:772 msgid "" "An explicit deny (!svc) is resolved first. Second, SSSD searches for " "explicit allow (svc) and finally for allow_all (*)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:777 msgid "" "Please note that the ldap_access_order configuration option " "<emphasis>must</emphasis> include <quote>authorized_service</quote> in order " "for the ldap_user_authorized_service option to work." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:784 msgid "Default: authorizedService" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:790 msgid "ldap_user_authorized_host (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:793 msgid "" "If access_provider=ldap and ldap_access_order=host, SSSD will use the " "presence of the host attribute in the user's LDAP entry to determine access " "privilege." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:799 msgid "" "An explicit deny (!host) is resolved first. Second, SSSD searches for " "explicit allow (host) and finally for allow_all (*)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:804 msgid "" "Please note that the ldap_access_order configuration option " "<emphasis>must</emphasis> include <quote>host</quote> in order for the " "ldap_user_authorized_host option to work." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:811 msgid "Default: host" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:817 msgid "ldap_user_certificate (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:820 msgid "Name of the LDAP attribute containing the X509 certificate of the user." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:824 msgid "Default: no set in the general case, userCertificate;binary for IPA" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:831 msgid "ldap_group_object_class (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:834 msgid "The object class of a group entry in LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:837 msgid "Default: posixGroup" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:843 msgid "ldap_group_name (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:846 msgid "The LDAP attribute that corresponds to the group name." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:856 msgid "ldap_group_gid_number (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:859 msgid "The LDAP attribute that corresponds to the group's id." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:869 msgid "ldap_group_member (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:872 msgid "The LDAP attribute that contains the names of the group's members." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:876 msgid "Default: memberuid (rfc2307) / member (rfc2307bis)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:882 msgid "ldap_group_uuid (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:885 msgid "The LDAP attribute that contains the UUID/GUID of an LDAP group object." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:896 msgid "ldap_group_objectsid (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:899 msgid "" "The LDAP attribute that contains the objectSID of an LDAP group object. This " "is usually only necessary for ActiveDirectory servers." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:911 msgid "ldap_group_modify_timestamp (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:924 msgid "ldap_group_type (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:927 msgid "" "The LDAP attribute that contains an integer value indicating the type of the " "group and maybe other flags." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:932 msgid "" "This attribute is currently only used by the AD provider to determine if a " "group is a domain local groups and has to be filtered out for trusted " "domains." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:938 msgid "Default: groupType in the AD provider, othewise not set" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:945 msgid "ldap_group_external_member (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:948 msgid "" "The LDAP attribute that references group members that are defined in an " "external domain. At the moment, only IPA's external members are supported." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:954 msgid "Default: ipaExternalMember in the IPA provider, otherwise unset." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:961 msgid "ldap_group_nesting_level (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:964 msgid "" "If ldap_schema is set to a schema format that supports nested groups " "(e.g. RFC2307bis), then this option controls how many levels of nesting SSSD " "will follow. This option has no effect on the RFC2307 schema." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:971 msgid "" "Note: This option specifies the guaranteed level of nested groups to be " "processed for any lookup. However, nested groups beyond this limit " "<emphasis>may be</emphasis> returned if previous lookups already resolved " "the deeper nesting levels. Also, subsequent lookups for other groups may " "enlarge the result set for original lookup if re-queried." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:980 msgid "" "If ldap_group_nesting_level is set to 0 then no nested groups are processed " "at all. However, when connected to Active-Directory Server 2008 and later " "using <quote>id_provider=ad</quote> it is furthermore required to disable " "usage of Token-Groups by setting ldap_use_tokengroups to false in order to " "restrict group nesting." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:989 msgid "Default: 2" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:995 msgid "ldap_groups_use_matching_rule_in_chain" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:998 msgid "" "This option tells SSSD to take advantage of an Active Directory-specific " "feature which may speed up group lookup operations on deployments with " "complex or deep nested groups." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1004 msgid "" "In most common cases, it is best to leave this option disabled. It generally " "only provides a performance increase on very complex nestings." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1009 sssd-ldap.5.xml:1036 msgid "" "If this option is enabled, SSSD will use it if it detects that the server " "supports it during initial connection. So \"True\" here essentially means " "\"auto-detect\"." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1015 sssd-ldap.5.xml:1042 msgid "" "Note: This feature is currently known to work only with Active Directory " "2008 R1 and later. See <ulink " "url=\"http://msdn.microsoft.com/en-us/library/windows/desktop/aa746475%28v=vs.85%29.aspx\"> " "MSDN(TM) documentation</ulink> for more details." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1021 sssd-ldap.5.xml:1048 sssd-ldap.5.xml:1339 sssd-ldap.5.xml:1360 sssd-ldap.5.xml:1866 include/ldap_id_mapping.xml:244 msgid "Default: False" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1027 msgid "ldap_initgroups_use_matching_rule_in_chain" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1030 msgid "" "This option tells SSSD to take advantage of an Active Directory-specific " "feature which might speed up initgroups operations (most notably when " "dealing with complex or deep nested groups)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1057 msgid "" "This options enables or disables use of Token-Groups attribute when " "performing initgroup for users from Active Directory Server 2008 and later." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1062 msgid "Default: True for AD and IPA otherwise False." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1068 msgid "ldap_netgroup_object_class (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1071 msgid "The object class of a netgroup entry in LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1074 msgid "In IPA provider, ipa_netgroup_object_class should be used instead." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1078 msgid "Default: nisNetgroup" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1084 msgid "ldap_netgroup_name (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1087 msgid "The LDAP attribute that corresponds to the netgroup name." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1091 msgid "In IPA provider, ipa_netgroup_name should be used instead." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1101 msgid "ldap_netgroup_member (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1104 msgid "The LDAP attribute that contains the names of the netgroup's members." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1108 msgid "In IPA provider, ipa_netgroup_member should be used instead." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1112 msgid "Default: memberNisNetgroup" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1118 msgid "ldap_netgroup_triple (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1121 msgid "The LDAP attribute that contains the (host, user, domain) netgroup triples." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1125 sssd-ldap.5.xml:1141 msgid "This option is not available in IPA provider." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1128 msgid "Default: nisNetgroupTriple" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1134 msgid "ldap_netgroup_modify_timestamp (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1150 msgid "ldap_service_object_class (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1153 msgid "The object class of a service entry in LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1156 msgid "Default: ipService" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1162 msgid "ldap_service_name (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1165 msgid "" "The LDAP attribute that contains the name of service attributes and their " "aliases." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1175 msgid "ldap_service_port (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1178 msgid "The LDAP attribute that contains the port managed by this service." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1182 msgid "Default: ipServicePort" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1188 msgid "ldap_service_proto (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1191 msgid "The LDAP attribute that contains the protocols understood by this service." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1195 msgid "Default: ipServiceProtocol" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1201 msgid "ldap_service_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1206 msgid "ldap_search_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1209 msgid "" "Specifies the timeout (in seconds) that ldap searches are allowed to run " "before they are cancelled and cached results are returned (and offline mode " "is entered)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1215 msgid "" "Note: this option is subject to change in future versions of the SSSD. It " "will likely be replaced at some point by a series of timeouts for specific " "lookup types." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1227 msgid "ldap_enumeration_search_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1230 msgid "" "Specifies the timeout (in seconds) that ldap searches for user and group " "enumerations are allowed to run before they are cancelled and cached results " "are returned (and offline mode is entered)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1243 msgid "ldap_network_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1246 msgid "" "Specifies the timeout (in seconds) after which the <citerefentry> " "<refentrytitle>poll</refentrytitle> <manvolnum>2</manvolnum> " "</citerefentry>/<citerefentry> <refentrytitle>select</refentrytitle> " "<manvolnum>2</manvolnum> </citerefentry> following a <citerefentry> " "<refentrytitle>connect</refentrytitle> <manvolnum>2</manvolnum> " "</citerefentry> returns in case of no activity." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1269 msgid "ldap_opt_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1272 msgid "" "Specifies a timeout (in seconds) after which calls to synchronous LDAP APIs " "will abort if no response is received. Also controls the timeout when " "communicating with the KDC in case of SASL bind, the timeout of an LDAP bind " "operation, password change extended operation and the StartTLS operation." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1287 msgid "ldap_connection_expire_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1290 msgid "" "Specifies a timeout (in seconds) that a connection to an LDAP server will be " "maintained. After this time, the connection will be re-established. If used " "in parallel with SASL/GSSAPI, the sooner of the two values (this value " "vs. the TGT lifetime) will be used." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1298 sssd-ldap.5.xml:2367 msgid "Default: 900 (15 minutes)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1304 msgid "ldap_page_size (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1307 msgid "" "Specify the number of records to retrieve from LDAP in a single " "request. Some LDAP servers enforce a maximum limit per-request." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1312 msgid "Default: 1000" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1318 msgid "ldap_disable_paging (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1321 msgid "" "Disable the LDAP paging control. This option should be used if the LDAP " "server reports that it supports the LDAP paging control in its RootDSE but " "it is not enabled or does not behave properly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1327 msgid "" "Example: OpenLDAP servers with the paging control module installed on the " "server but not enabled will report it in the RootDSE but be unable to use " "it." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1333 msgid "" "Example: 389 DS has a bug where it can only support a one paging control at " "a time on a single connection. On busy clients, this can result in some " "requests being denied." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1345 msgid "ldap_disable_range_retrieval (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1348 msgid "Disable Active Directory range retrieval." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1351 msgid "" "Active Directory limits the number of members to be retrieved in a single " "lookup using the MaxValRange policy (which defaults to 1500 members). If a " "group contains more members, the reply would include an AD-specific range " "extension. This option disables parsing of the range extension, therefore " "large groups will appear as having no members." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1366 msgid "ldap_sasl_minssf (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1369 msgid "" "When communicating with an LDAP server using SASL, specify the minimum " "security level necessary to establish the connection. The values of this " "option are defined by OpenLDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1375 msgid "Default: Use the system default (usually specified by ldap.conf)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1382 msgid "ldap_deref_threshold (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1385 msgid "" "Specify the number of group members that must be missing from the internal " "cache in order to trigger a dereference lookup. If less members are missing, " "they are looked up individually." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1391 msgid "You can turn off dereference lookups completely by setting the value to 0." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1395 msgid "" "A dereference lookup is a means of fetching all group members in a single " "LDAP call. Different LDAP servers may implement different dereference " "methods. The currently supported servers are 389/RHDS, OpenLDAP and Active " "Directory." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1403 msgid "" "<emphasis>Note:</emphasis> If any of the search bases specifies a search " "filter, then the dereference lookup performance enhancement will be disabled " "regardless of this setting." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1416 msgid "ldap_tls_reqcert (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1419 msgid "" "Specifies what checks to perform on server certificates in a TLS session, if " "any. It can be specified as one of the following values:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1425 msgid "" "<emphasis>never</emphasis> = The client will not request or check any server " "certificate." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1429 msgid "" "<emphasis>allow</emphasis> = The server certificate is requested. If no " "certificate is provided, the session proceeds normally. If a bad certificate " "is provided, it will be ignored and the session proceeds normally." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1436 msgid "" "<emphasis>try</emphasis> = The server certificate is requested. If no " "certificate is provided, the session proceeds normally. If a bad certificate " "is provided, the session is immediately terminated." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1442 msgid "" "<emphasis>demand</emphasis> = The server certificate is requested. If no " "certificate is provided, or a bad certificate is provided, the session is " "immediately terminated." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1448 msgid "<emphasis>hard</emphasis> = Same as <quote>demand</quote>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1452 msgid "Default: hard" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1458 msgid "ldap_tls_cacert (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1461 msgid "" "Specifies the file that contains certificates for all of the Certificate " "Authorities that <command>sssd</command> will recognize." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1466 sssd-ldap.5.xml:1484 sssd-ldap.5.xml:1525 msgid "" "Default: use OpenLDAP defaults, typically in " "<filename>/etc/openldap/ldap.conf</filename>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1473 msgid "ldap_tls_cacertdir (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1476 msgid "" "Specifies the path of a directory that contains Certificate Authority " "certificates in separate individual files. Typically the file names need to " "be the hash of the certificate followed by '.0'. If available, " "<command>cacertdir_rehash</command> can be used to create the correct names." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1491 msgid "ldap_tls_cert (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1494 msgid "Specifies the file that contains the certificate for the client's key." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1504 msgid "ldap_tls_key (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1507 msgid "Specifies the file that contains the client's key." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1516 msgid "ldap_tls_cipher_suite (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1519 msgid "" "Specifies acceptable cipher suites. Typically this is a colon separated " "list. See <citerefentry><refentrytitle>ldap.conf</refentrytitle> " "<manvolnum>5</manvolnum></citerefentry> for format." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1532 msgid "ldap_id_use_start_tls (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1535 msgid "" "Specifies that the id_provider connection must also use <systemitem " "class=\"protocol\">tls</systemitem> to protect the channel." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1545 msgid "ldap_id_mapping (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1548 msgid "" "Specifies that SSSD should attempt to map user and group IDs from the " "ldap_user_objectsid and ldap_group_objectsid attributes instead of relying " "on ldap_user_uid_number and ldap_group_gid_number." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1554 msgid "Currently this feature supports only ActiveDirectory objectSID mapping." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1564 msgid "ldap_min_id, ldap_max_id (interger)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1567 msgid "" "In contrast to the SID based ID mapping which is used if ldap_id_mapping is " "set to true the allowed ID range for ldap_user_uid_number and " "ldap_group_gid_number is unbound. In a setup with sub/trusted-domains this " "might lead to ID collisions. To avoid collisions ldap_min_id and ldap_max_id " "can be set to restrict the allowed range for the IDs which are read directly " "from the server. Sub-domains can then pick other ranges to map IDs." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1579 msgid "Default: not set (both options are set to 0)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1585 msgid "ldap_sasl_mech (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1588 msgid "" "Specify the SASL mechanism to use. Currently only GSSAPI is tested and " "supported." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1598 msgid "ldap_sasl_authid (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1601 msgid "" "Specify the SASL authorization id to use. When GSSAPI is used, this " "represents the Kerberos principal used for authentication to the directory. " "This option can either contain the full principal (for example " "host/myhost@EXAMPLE.COM) or just the principal name (for example " "host/myhost)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1609 msgid "Default: host/hostname@REALM" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1615 msgid "ldap_sasl_realm (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1618 msgid "" "Specify the SASL realm to use. When not specified, this option defaults to " "the value of krb5_realm. If the ldap_sasl_authid contains the realm as " "well, this option is ignored." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1624 msgid "Default: the value of krb5_realm." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1630 msgid "ldap_sasl_canonicalize (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1633 msgid "" "If set to true, the LDAP library would perform a reverse lookup to " "canonicalize the host name during a SASL bind." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1638 msgid "Default: false;" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1644 msgid "ldap_krb5_keytab (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1647 msgid "Specify the keytab to use when using SASL/GSSAPI." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1650 msgid "Default: System keytab, normally <filename>/etc/krb5.keytab</filename>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1656 msgid "ldap_krb5_init_creds (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1659 msgid "" "Specifies that the id_provider should init Kerberos credentials (TGT). This " "action is performed only if SASL is used and the mechanism selected is " "GSSAPI." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1671 msgid "ldap_krb5_ticket_lifetime (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1674 msgid "Specifies the lifetime in seconds of the TGT if GSSAPI is used." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1678 sssd-ad.5.xml:849 msgid "Default: 86400 (24 hours)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1684 sssd-krb5.5.xml:74 msgid "krb5_server, krb5_backup_server (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1687 msgid "" "Specifies the comma-separated list of IP addresses or hostnames of the " "Kerberos servers to which SSSD should connect in the order of " "preference. For more information on failover and server redundancy, see the " "<quote>FAILOVER</quote> section. An optional port number (preceded by a " "colon) may be appended to the addresses or hostnames. If empty, service " "discovery is enabled - for more information, refer to the <quote>SERVICE " "DISCOVERY</quote> section." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1699 sssd-krb5.5.xml:89 msgid "" "When using service discovery for KDC or kpasswd servers, SSSD first searches " "for DNS entries that specify _udp as the protocol and falls back to _tcp if " "none are found." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1704 sssd-krb5.5.xml:94 msgid "" "This option was named <quote>krb5_kdcip</quote> in earlier releases of " "SSSD. While the legacy name is recognized for the time being, users are " "advised to migrate their config files to use <quote>krb5_server</quote> " "instead." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1713 sssd-ipa.5.xml:415 sssd-krb5.5.xml:103 msgid "krb5_realm (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1716 msgid "Specify the Kerberos REALM (for SASL/GSSAPI auth)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1719 msgid "Default: System defaults, see <filename>/etc/krb5.conf</filename>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1725 sssd-ipa.5.xml:430 sssd-krb5.5.xml:462 msgid "krb5_canonicalize (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1728 msgid "" "Specifies if the host principal should be canonicalized when connecting to " "LDAP server. This feature is available with MIT Kerberos >= 1.7" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1740 sssd-krb5.5.xml:477 msgid "krb5_use_kdcinfo (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1743 sssd-krb5.5.xml:480 msgid "" "Specifies if the SSSD should instruct the Kerberos libraries what realm and " "which KDCs to use. This option is on by default, if you disable it, you need " "to configure the Kerberos library using the <citerefentry> " "<refentrytitle>krb5.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> configuration file." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1754 sssd-krb5.5.xml:491 msgid "" "See the <citerefentry> " "<refentrytitle>sssd_krb5_locator_plugin</refentrytitle> " "<manvolnum>8</manvolnum> </citerefentry> manual page for more information on " "the locator plugin." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1768 msgid "ldap_pwd_policy (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1771 msgid "" "Select the policy to evaluate the password expiration on the client " "side. The following values are allowed:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1776 msgid "" "<emphasis>none</emphasis> - No evaluation on the client side. This option " "cannot disable server-side password policies." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1781 msgid "" "<emphasis>shadow</emphasis> - Use " "<citerefentry><refentrytitle>shadow</refentrytitle> " "<manvolnum>5</manvolnum></citerefentry> style attributes to evaluate if the " "password has expired." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1787 msgid "" "<emphasis>mit_kerberos</emphasis> - Use the attributes used by MIT Kerberos " "to determine if the password has expired. Use chpass_provider=krb5 to update " "these attributes when the password is changed." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1796 msgid "" "<emphasis>Note</emphasis>: if a password policy is configured on server " "side, it always takes precedence over policy set with this option." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1804 msgid "ldap_referrals (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1807 msgid "Specifies whether automatic referral chasing should be enabled." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1811 msgid "" "Please note that sssd only supports referral chasing when it is compiled " "with OpenLDAP version 2.4.13 or higher." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1816 msgid "" "Chasing referrals may incur a performance penalty in environments that use " "them heavily, a notable example is Microsoft Active Directory. If your setup " "does not in fact require the use of referrals, setting this option to false " "might bring a noticeable performance improvement." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1830 msgid "ldap_dns_service_name (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1833 msgid "Specifies the service name to use when service discovery is enabled." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1837 msgid "Default: ldap" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1843 msgid "ldap_chpass_dns_service_name (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1846 msgid "" "Specifies the service name to use to find an LDAP server which allows " "password changes when service discovery is enabled." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1851 msgid "Default: not set, i.e. service discovery is disabled" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1857 msgid "ldap_chpass_update_last_change (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1860 msgid "" "Specifies whether to update the ldap_user_shadow_last_change attribute with " "days since the Epoch after a password change operation." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1872 msgid "ldap_access_filter (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1875 msgid "" "If using access_provider = ldap and ldap_access_order = filter (default), " "this option is mandatory. It specifies an LDAP search filter criteria that " "must be met for the user to be granted access on this host. If " "access_provider = ldap, ldap_access_order = filter and this option is not " "set, it will result in all users being denied access. Use access_provider = " "permit to change this default behavior. Please note that this filter is " "applied on the LDAP user entry only and thus filtering based on nested " "groups may not work (e.g. memberOf attribute on AD entries points only to " "direct parents). If filtering based on nested groups is required, please see " "<citerefentry> " "<refentrytitle>sssd-simple</refentrytitle><manvolnum>5</manvolnum> " "</citerefentry>." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1895 msgid "Example:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><programlisting> #: sssd-ldap.5.xml:1898 #, no-wrap msgid "" "access_provider = ldap\n" "ldap_access_filter = (employeeType=admin)\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1902 msgid "" "This example means that access to this host is restricted to users whose " "employeeType attribute is set to \"admin\"." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1907 msgid "" "Offline caching for this feature is limited to determining whether the " "user's last online login was granted access permission. If they were granted " "access during their last login, they will continue to be granted access " "while offline and vice-versa." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1915 sssd-ldap.5.xml:1972 msgid "Default: Empty" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1921 msgid "ldap_account_expire_policy (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1924 msgid "" "With this option a client side evaluation of access control attributes can " "be enabled." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1928 msgid "" "Please note that it is always recommended to use server side access control, " "i.e. the LDAP server should deny the bind request with a suitable error code " "even if the password is correct." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1935 msgid "The following values are allowed:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1938 msgid "" "<emphasis>shadow</emphasis>: use the value of ldap_user_shadow_expire to " "determine if the account is expired." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1943 msgid "" "<emphasis>ad</emphasis>: use the value of the 32bit field " "ldap_user_ad_user_account_control and allow access if the second bit is not " "set. If the attribute is missing access is granted. Also the expiration time " "of the account is checked." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1950 msgid "" "<emphasis>rhds</emphasis>, <emphasis>ipa</emphasis>, " "<emphasis>389ds</emphasis>: use the value of ldap_ns_account_lock to check " "if access is allowed or not." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1956 msgid "" "<emphasis>nds</emphasis>: the values of " "ldap_user_nds_login_allowed_time_map, ldap_user_nds_login_disabled and " "ldap_user_nds_login_expiration_time are used to check if access is " "allowed. If both attributes are missing access is granted." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1965 msgid "" "Please note that the ldap_access_order configuration option " "<emphasis>must</emphasis> include <quote>expire</quote> in order for the " "ldap_account_expire_policy option to work." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:1978 msgid "ldap_access_order (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1981 msgid "Comma separated list of access control options. Allowed values are:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1985 msgid "<emphasis>filter</emphasis>: use ldap_access_filter" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1988 msgid "" "<emphasis>lockout</emphasis>: use account locking. If set, this option " "denies access in case that ldap attribute 'pwdAccountLockedTime' is present " "and has value of '000001010000Z'. Please see the option ldap_pwdlockout_dn. " "Please note that 'access_provider = ldap' must be set for this feature to " "work." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:1998 msgid "" "<emphasis> Please note that this option is superseded by the " "<quote>ppolicy</quote> option and might be removed in a future release. " "</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2005 msgid "" "<emphasis>ppolicy</emphasis>: use account locking. If set, this option " "denies access in case that ldap attribute 'pwdAccountLockedTime' is present " "and has value of '000001010000Z' or represents any time in the past. The " "value of the 'pwdAccountLockedTime' attribute must end with 'Z', which " "denotes the UTC time zone. Other time zones are not currently supported and " "will result in \"access-denied\" when users attempt to log in. Please see " "the option ldap_pwdlockout_dn. Please note that 'access_provider = ldap' " "must be set for this feature to work." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2022 msgid "<emphasis>expire</emphasis>: use ldap_account_expire_policy" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2026 msgid "" "<emphasis>pwd_expire_policy_reject, pwd_expire_policy_warn, " "pwd_expire_policy_renew: </emphasis> These options are useful if users are " "interested in being warned that password is about to expire and " "authentication is based on using a different method than passwords - for " "example SSH keys." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2036 msgid "" "The difference between these options is the action taken if user password is " "expired: pwd_expire_policy_reject - user is denied to log in, " "pwd_expire_policy_warn - user is still able to log in, " "pwd_expire_policy_renew - user is prompted to change his password " "immediately." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2044 msgid "Note If user password is expired no explicit message is prompted by SSSD." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2048 msgid "" "Please note that 'access_provider = ldap' must be set for this feature to " "work. Also 'ldap_pwd_policy' must be set to an appropriate password policy." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2053 msgid "" "<emphasis>authorized_service</emphasis>: use the authorizedService attribute " "to determine access" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2058 msgid "<emphasis>host</emphasis>: use the host attribute to determine access" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2062 msgid "Default: filter" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2065 msgid "" "Please note that it is a configuration error if a value is used more than " "once." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2072 msgid "ldap_pwdlockout_dn (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2075 msgid "" "This option specifies the DN of password policy entry on LDAP server. Please " "note that absence of this option in sssd.conf in case of enabled account " "lockout checking will yield access denied as ppolicy attributes on LDAP " "server cannot be checked properly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2083 msgid "Example: cn=ppolicy,ou=policies,dc=example,dc=com" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2086 msgid "Default: cn=ppolicy,ou=policies,$ldap_search_base" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2092 msgid "ldap_deref (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2095 msgid "" "Specifies how alias dereferencing is done when performing a search. The " "following options are allowed:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2100 msgid "<emphasis>never</emphasis>: Aliases are never dereferenced." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2104 msgid "" "<emphasis>searching</emphasis>: Aliases are dereferenced in subordinates of " "the base object, but not in locating the base object of the search." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2109 msgid "" "<emphasis>finding</emphasis>: Aliases are only dereferenced when locating " "the base object of the search." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2114 msgid "" "<emphasis>always</emphasis>: Aliases are dereferenced both in searching and " "in locating the base object of the search." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2119 msgid "" "Default: Empty (this is handled as <emphasis>never</emphasis> by the LDAP " "client libraries)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2127 msgid "ldap_rfc2307_fallback_to_local_users (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2130 msgid "" "Allows to retain local users as members of an LDAP group for servers that " "use the RFC2307 schema." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2134 msgid "" "In some environments where the RFC2307 schema is used, local users are made " "members of LDAP groups by adding their names to the memberUid attribute. " "The self-consistency of the domain is compromised when this is done, so SSSD " "would normally remove the \"missing\" users from the cached group " "memberships as soon as nsswitch tries to fetch information about the user " "via getpw*() or initgroups() calls." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2145 msgid "" "This option falls back to checking if local users are referenced, and caches " "them so that later initgroups() calls will augment the local users with the " "additional LDAP groups." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2157 sssd-ifp.5.xml:136 msgid "wildcart_limit (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2160 msgid "" "Specifies an upper limit on the number of entries that are downloaded during " "a wildcard lookup." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2164 msgid "At the moment, only the InfoPipe responder supports wildcard lookups." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2168 msgid "Default: 1000 (often the size of one page)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:51 msgid "" "All of the common configuration options that apply to SSSD domains also " "apply to LDAP domains. Refer to the <quote>DOMAIN SECTIONS</quote> section " "of the <citerefentry> <refentrytitle>sssd.conf</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> manual page for full details. " "<placeholder type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd-ldap.5.xml:2178 msgid "SUDO OPTIONS" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:2180 msgid "" "The detailed instructions for configuration of sudo_provider are in the " "manual page <citerefentry> <refentrytitle>sssd-sudo</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry>." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2191 msgid "ldap_sudorule_object_class (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2194 msgid "The object class of a sudo rule entry in LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2197 msgid "Default: sudoRole" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2203 msgid "ldap_sudorule_name (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2206 msgid "The LDAP attribute that corresponds to the sudo rule name." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2216 msgid "ldap_sudorule_command (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2219 msgid "The LDAP attribute that corresponds to the command name." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2223 msgid "Default: sudoCommand" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2229 msgid "ldap_sudorule_host (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2232 msgid "" "The LDAP attribute that corresponds to the host name (or host IP address, " "host IP network, or host netgroup)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2237 msgid "Default: sudoHost" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2243 msgid "ldap_sudorule_user (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2246 msgid "" "The LDAP attribute that corresponds to the user name (or UID, group name or " "user's netgroup)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2250 msgid "Default: sudoUser" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2256 msgid "ldap_sudorule_option (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2259 msgid "The LDAP attribute that corresponds to the sudo options." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2263 msgid "Default: sudoOption" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2269 msgid "ldap_sudorule_runasuser (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2272 msgid "" "The LDAP attribute that corresponds to the user name that commands may be " "run as." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2276 msgid "Default: sudoRunAsUser" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2282 msgid "ldap_sudorule_runasgroup (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2285 msgid "" "The LDAP attribute that corresponds to the group name or group GID that " "commands may be run as." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2289 msgid "Default: sudoRunAsGroup" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2295 msgid "ldap_sudorule_notbefore (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2298 msgid "" "The LDAP attribute that corresponds to the start date/time for when the sudo " "rule is valid." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2302 msgid "Default: sudoNotBefore" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2308 msgid "ldap_sudorule_notafter (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2311 msgid "" "The LDAP attribute that corresponds to the expiration date/time, after which " "the sudo rule will no longer be valid." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2316 msgid "Default: sudoNotAfter" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2322 msgid "ldap_sudorule_order (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2325 msgid "The LDAP attribute that corresponds to the ordering index of the rule." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2329 msgid "Default: sudoOrder" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2335 msgid "ldap_sudo_full_refresh_interval (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2338 msgid "" "How many seconds SSSD will wait between executing a full refresh of sudo " "rules (which downloads all rules that are stored on the server)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2343 msgid "" "The value must be greater than <emphasis>ldap_sudo_smart_refresh_interval " "</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2348 msgid "Default: 21600 (6 hours)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2354 msgid "ldap_sudo_smart_refresh_interval (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2357 msgid "" "How many seconds SSSD has to wait before executing a smart refresh of sudo " "rules (which downloads all rules that have USN higher than the highest USN " "of cached rules)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2363 msgid "" "If USN attributes are not supported by the server, the modifyTimestamp " "attribute is used instead." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2373 msgid "ldap_sudo_use_host_filter (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2376 msgid "" "If true, SSSD will download only rules that are applicable to this machine " "(using the IPv4 or IPv6 host/network addresses and hostnames)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2387 msgid "ldap_sudo_hostnames (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2390 msgid "" "Space separated list of hostnames or fully qualified domain names that " "should be used to filter the rules." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2395 msgid "" "If this option is empty, SSSD will try to discover the hostname and the " "fully qualified domain name automatically." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2400 sssd-ldap.5.xml:2423 sssd-ldap.5.xml:2441 sssd-ldap.5.xml:2459 msgid "" "If <emphasis>ldap_sudo_use_host_filter</emphasis> is " "<emphasis>false</emphasis> then this option has no effect." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2405 sssd-ldap.5.xml:2428 msgid "Default: not specified" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2411 msgid "ldap_sudo_ip (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2414 msgid "" "Space separated list of IPv4 or IPv6 host/network addresses that should be " "used to filter the rules." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2419 msgid "" "If this option is empty, SSSD will try to discover the addresses " "automatically." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2434 msgid "ldap_sudo_include_netgroups (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2437 msgid "" "If true then SSSD will download every rule that contains a netgroup in " "sudoHost attribute." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2452 msgid "ldap_sudo_include_regexp (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2455 msgid "" "If true then SSSD will download every rule that contains a wildcard in " "sudoHost attribute." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:2471 msgid "" "This manual page only describes attribute name mapping. For detailed " "explanation of sudo related attribute semantics, see <citerefentry> " "<refentrytitle>sudoers.ldap</refentrytitle><manvolnum>5</manvolnum> " "</citerefentry>" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd-ldap.5.xml:2481 msgid "AUTOFS OPTIONS" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:2483 msgid "" "Some of the defaults for the parameters below are dependent on the LDAP " "schema." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2489 msgid "ldap_autofs_map_master_name (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2492 msgid "The name of the automount master map in LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2495 msgid "Default: auto.master" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2502 msgid "ldap_autofs_map_object_class (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2505 msgid "The object class of an automount map entry in LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2508 msgid "Default: automountMap" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2515 msgid "ldap_autofs_map_name (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2518 msgid "The name of an automount map entry in LDAP." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2521 msgid "Default: ou (rfc2307), automountMapName (rfc2307bis, ipa, ad)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2529 msgid "ldap_autofs_entry_object_class (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2532 msgid "" "The object class of an automount entry in LDAP. The entry usually " "corresponds to a mount point." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2537 msgid "Default: automount" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2544 msgid "ldap_autofs_entry_key (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2547 sssd-ldap.5.xml:2562 msgid "" "The key of an automount entry in LDAP. The entry usually corresponds to a " "mount point." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2551 msgid "Default: cn (rfc2307), automountKey (rfc2307bis, ipa, ad)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2559 msgid "ldap_autofs_entry_value (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ldap.5.xml:2566 msgid "Default: automountInformation" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:2487 msgid "" "<placeholder type=\"variablelist\" id=\"0\"/> <placeholder " "type=\"variablelist\" id=\"1\"/> <placeholder type=\"variablelist\" " "id=\"2\"/> <placeholder type=\"variablelist\" id=\"3\"/> <placeholder " "type=\"variablelist\" id=\"4\"/> <placeholder type=\"variablelist\" " "id=\"5\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd-ldap.5.xml:2576 msgid "ADVANCED OPTIONS" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2583 msgid "ldap_netgroup_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2588 msgid "ldap_user_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2593 msgid "ldap_group_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><note> #: sssd-ldap.5.xml:2598 msgid "<note>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><note><para> #: sssd-ldap.5.xml:2600 msgid "" "If the option <quote>ldap_use_tokengroups</quote> is enabled. The searches " "against Active Directory will not be restricted and return all groups " "memberships, even with no gid mapping. It is recommended to disable this " "feature, if group names are not being displayed correctly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist> #: sssd-ldap.5.xml:2607 msgid "</note>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2609 msgid "ldap_sudo_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ldap.5.xml:2614 msgid "ldap_autofs_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:2578 msgid "" "These options are supported by LDAP domains, but they should be used with " "caution. Please include them in your configuration only if you know what you " "are doing. <placeholder type=\"variablelist\" id=\"0\"/> <placeholder " "type=\"variablelist\" id=\"1\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:2631 msgid "" "The following example assumes that SSSD is correctly configured and LDAP is " "set to one of the domains in the <replaceable>[domains]</replaceable> " "section." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd-ldap.5.xml:2637 #, no-wrap msgid "" "[domain/LDAP]\n" "id_provider = ldap\n" "auth_provider = ldap\n" "ldap_uri = ldap://ldap.mydomain.org\n" "ldap_search_base = dc=mydomain,dc=org\n" "ldap_tls_reqcert = demand\n" "cache_credentials = true\n" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: sssd-ldap.5.xml:2636 sssd-ldap.5.xml:2654 sssd-simple.5.xml:139 sssd-ipa.5.xml:725 sssd-ad.5.xml:963 sssd-sudo.5.xml:56 sssd-sudo.5.xml:98 sssd-krb5.5.xml:573 include/ldap_id_mapping.xml:105 msgid "<placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd-ldap.5.xml:2648 msgid "LDAP ACCESS FILTER EXAMPLE" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:2650 msgid "" "The following example assumes that SSSD is correctly configured and to use " "the ldap_access_order=lockout." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd-ldap.5.xml:2655 #, no-wrap msgid "" "[domain/LDAP]\n" "id_provider = ldap\n" "auth_provider = ldap\n" "access_provider = ldap\n" "ldap_access_order = lockout\n" "ldap_pwdlockout_dn = cn=ppolicy,ou=policies,dc=mydomain,dc=org\n" "ldap_uri = ldap://ldap.mydomain.org\n" "ldap_search_base = dc=mydomain,dc=org\n" "ldap_tls_reqcert = demand\n" "cache_credentials = true\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd-ldap.5.xml:2670 sssd_krb5_locator_plugin.8.xml:61 sssd-simple.5.xml:148 sssd-ad.5.xml:978 sssd.8.xml:195 sss_seed.8.xml:163 msgid "NOTES" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ldap.5.xml:2672 msgid "" "The descriptions of some of the configuration options in this manual page " "are based on the <citerefentry> <refentrytitle>ldap.conf</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> manual page from the OpenLDAP 2.4 " "distribution." msgstr "" #. type: Content of: <refentryinfo> #: pam_sss.8.xml:8 include/upstream.xml:2 msgid "" "<productname>SSSD</productname> <orgname>The SSSD upstream - " "http://fedorahosted.org/sssd</orgname>" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: pam_sss.8.xml:13 pam_sss.8.xml:18 msgid "pam_sss" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: pam_sss.8.xml:19 msgid "PAM module for SSSD" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: pam_sss.8.xml:24 msgid "" "<command>pam_sss.so</command> <arg choice='opt'> " "<replaceable>quiet</replaceable> </arg> <arg choice='opt'> " "<replaceable>forward_pass</replaceable> </arg> <arg choice='opt'> " "<replaceable>use_first_pass</replaceable> </arg> <arg choice='opt'> " "<replaceable>use_authtok</replaceable> </arg> <arg choice='opt'> " "<replaceable>retry=N</replaceable> </arg> <arg choice='opt'> " "<replaceable>ignore_unknown_user</replaceable> </arg> <arg choice='opt'> " "<replaceable>ignore_authinfo_unavail</replaceable> </arg> <arg choice='opt'> " "<replaceable>domains=X</replaceable> </arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: pam_sss.8.xml:54 msgid "" "<command>pam_sss.so</command> is the PAM interface to the System Security " "Services daemon (SSSD). Errors and results are logged through " "<command>syslog(3)</command> with the LOG_AUTHPRIV facility." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: pam_sss.8.xml:64 msgid "<option>quiet</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: pam_sss.8.xml:67 msgid "Suppress log messages for unknown users." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: pam_sss.8.xml:72 msgid "<option>forward_pass</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: pam_sss.8.xml:75 msgid "" "If <option>forward_pass</option> is set the entered password is put on the " "stack for other PAM modules to use." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: pam_sss.8.xml:82 msgid "<option>use_first_pass</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: pam_sss.8.xml:85 msgid "" "The argument use_first_pass forces the module to use a previous stacked " "modules password and will never prompt the user - if no password is " "available or the password is not appropriate, the user will be denied " "access." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: pam_sss.8.xml:93 msgid "<option>use_authtok</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: pam_sss.8.xml:96 msgid "" "When password changing enforce the module to set the new password to the one " "provided by a previously stacked password module." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: pam_sss.8.xml:103 msgid "<option>retry=N</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: pam_sss.8.xml:106 msgid "" "If specified the user is asked another N times for a password if " "authentication fails. Default is 0." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: pam_sss.8.xml:108 msgid "" "Please note that this option might not work as expected if the application " "calling PAM handles the user dialog on its own. A typical example is " "<command>sshd</command> with <option>PasswordAuthentication</option>." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: pam_sss.8.xml:117 msgid "<option>ignore_unknown_user</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: pam_sss.8.xml:120 msgid "" "If this option is specified and the user does not exist, the PAM module will " "return PAM_IGNORE. This causes the PAM framework to ignore this module." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: pam_sss.8.xml:127 msgid "<option>ignore_authinfo_unavail</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: pam_sss.8.xml:131 msgid "" "Specifies that the PAM module should return PAM_IGNORE if it cannot contact " "the SSSD daemon. This causes the PAM framework to ignore this module." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: pam_sss.8.xml:138 msgid "<option>domains</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: pam_sss.8.xml:142 msgid "" "Allows the administrator to restrict the domains a particular PAM service is " "allowed to authenticate against. The format is a comma-separated list of " "SSSD domain names, as specified in the sssd.conf file." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: pam_sss.8.xml:148 msgid "" "NOTE: Must be used in conjunction with the <quote>pam_trusted_users</quote> " "and <quote>pam_public_domains</quote> options. Please see the " "<citerefentry> <refentrytitle>sssd.conf</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> manual page for more information on " "these two PAM responder options." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: pam_sss.8.xml:164 msgid "MODULE TYPES PROVIDED" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: pam_sss.8.xml:165 msgid "" "All module types (<option>account</option>, <option>auth</option>, " "<option>password</option> and <option>session</option>) are provided." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: pam_sss.8.xml:171 msgid "FILES" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: pam_sss.8.xml:172 msgid "" "If a password reset by root fails, because the corresponding SSSD provider " "does not support password resets, an individual message can be " "displayed. This message can e.g. contain instructions about how to reset a " "password." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: pam_sss.8.xml:177 msgid "" "The message is read from the file " "<filename>pam_sss_pw_reset_message.LOC</filename> where LOC stands for a " "locale string returned by <citerefentry> " "<refentrytitle>setlocale</refentrytitle><manvolnum>3</manvolnum> " "</citerefentry>. If there is no matching file the content of " "<filename>pam_sss_pw_reset_message.txt</filename> is displayed. Root must be " "the owner of the files and only root may have read and write permissions " "while all other users must have only read permissions." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: pam_sss.8.xml:187 msgid "" "These files are searched in the directory " "<filename>/etc/sssd/customize/DOMAIN_NAME/</filename>. If no matching file " "is present a generic message is displayed." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sssd_krb5_locator_plugin.8.xml:10 sssd_krb5_locator_plugin.8.xml:15 msgid "sssd_krb5_locator_plugin" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sssd_krb5_locator_plugin.8.xml:16 msgid "Kerberos locator plugin" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd_krb5_locator_plugin.8.xml:22 msgid "" "The Kerberos locator plugin <command>sssd_krb5_locator_plugin</command> is " "used by the Kerberos provider of <citerefentry> " "<refentrytitle>sssd</refentrytitle> <manvolnum>8</manvolnum> </citerefentry> " "to tell the Kerberos libraries what Realm and which KDC to use. Typically " "this is done in <citerefentry> <refentrytitle>krb5.conf</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> which is always read by the " "Kerberos libraries. To simplify the configuration the Realm and the KDC can " "be defined in <citerefentry> <refentrytitle>sssd.conf</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> as described in <citerefentry> " "<refentrytitle>sssd-krb5</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd_krb5_locator_plugin.8.xml:48 msgid "" "<citerefentry> <refentrytitle>sssd</refentrytitle> <manvolnum>8</manvolnum> " "</citerefentry> puts the Realm and the name or IP address of the KDC into " "the environment variables SSSD_KRB5_REALM and SSSD_KRB5_KDC respectively. " "When <command>sssd_krb5_locator_plugin</command> is called by the kerberos " "libraries it reads and evaluates these variables and returns them to the " "libraries." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd_krb5_locator_plugin.8.xml:63 msgid "" "Not all Kerberos implementations support the use of plugins. If " "<command>sssd_krb5_locator_plugin</command> is not available on your system " "you have to edit /etc/krb5.conf to reflect your Kerberos setup." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd_krb5_locator_plugin.8.xml:69 msgid "" "If the environment variable SSSD_KRB5_LOCATOR_DEBUG is set to any value " "debug messages will be sent to stderr." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sssd-simple.5.xml:10 sssd-simple.5.xml:16 msgid "sssd-simple" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sssd-simple.5.xml:17 msgid "the configuration file for SSSD's 'simple' access-control provider" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-simple.5.xml:24 msgid "" "This manual page describes the configuration of the simple access-control " "provider for <citerefentry> <refentrytitle>sssd</refentrytitle> " "<manvolnum>8</manvolnum> </citerefentry>. For a detailed syntax reference, " "refer to the <quote>FILE FORMAT</quote> section of the <citerefentry> " "<refentrytitle>sssd.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> manual page." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-simple.5.xml:38 msgid "" "The simple access provider grants or denies access based on an access or " "deny list of user or group names. The following rules apply:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><itemizedlist><listitem><para> #: sssd-simple.5.xml:43 msgid "If all lists are empty, access is granted" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><itemizedlist><listitem><para> #: sssd-simple.5.xml:47 msgid "" "If any list is provided, the order of evaluation is allow,deny. This means " "that any matching deny rule will supersede any matched allow rule." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><itemizedlist><listitem><para> #: sssd-simple.5.xml:54 msgid "" "If either or both \"allow\" lists are provided, all users are denied unless " "they appear in the list." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><itemizedlist><listitem><para> #: sssd-simple.5.xml:60 msgid "" "If only \"deny\" lists are provided, all users are granted access unless " "they appear in the list." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-simple.5.xml:78 msgid "simple_allow_users (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-simple.5.xml:81 msgid "Comma separated list of users who are allowed to log in." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-simple.5.xml:88 msgid "simple_deny_users (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-simple.5.xml:91 msgid "Comma separated list of users who are explicitly denied access." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-simple.5.xml:97 msgid "simple_allow_groups (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-simple.5.xml:100 msgid "" "Comma separated list of groups that are allowed to log in. This applies only " "to groups within this SSSD domain. Local groups are not evaluated." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-simple.5.xml:108 msgid "simple_deny_groups (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-simple.5.xml:111 msgid "" "Comma separated list of groups that are explicitly denied access. This " "applies only to groups within this SSSD domain. Local groups are not " "evaluated." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-simple.5.xml:70 sssd-ipa.5.xml:71 sssd-ad.5.xml:90 msgid "" "Refer to the section <quote>DOMAIN SECTIONS</quote> of the <citerefentry> " "<refentrytitle>sssd.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> manual page for details on the configuration of an SSSD " "domain. <placeholder type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-simple.5.xml:120 msgid "" "Specifying no values for any of the lists is equivalent to skipping it " "entirely. Beware of this while generating parameters for the simple provider " "using automated scripts." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-simple.5.xml:125 msgid "" "Please note that it is an configuration error if both, simple_allow_users " "and simple_deny_users, are defined." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-simple.5.xml:133 msgid "" "The following example assumes that SSSD is correctly configured and " "example.com is one of the domains in the <replaceable>[sssd]</replaceable> " "section. This examples shows only the simple access provider-specific " "options." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd-simple.5.xml:140 #, no-wrap msgid "" "[domain/example.com]\n" "access_provider = simple\n" "simple_allow_users = user1, user2\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-simple.5.xml:150 msgid "" "The complete group membership hierarchy is resolved before the access check, " "thus even nested groups can be included in the access lists. Please be " "aware that the <quote>ldap_group_nesting_level</quote> option may impact the " "results and should be set to a sufficient value. (<citerefentry> " "<refentrytitle>sssd-ldap</refentrytitle><manvolnum>5</manvolnum> " "</citerefentry>) option." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sssd-ipa.5.xml:10 sssd-ipa.5.xml:16 msgid "sssd-ipa" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sssd-ipa.5.xml:17 msgid "SSSD IPA provider" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ipa.5.xml:23 msgid "" "This manual page describes the configuration of the IPA provider for " "<citerefentry> <refentrytitle>sssd</refentrytitle> <manvolnum>8</manvolnum> " "</citerefentry>. For a detailed syntax reference, refer to the <quote>FILE " "FORMAT</quote> section of the <citerefentry> " "<refentrytitle>sssd.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> manual page." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ipa.5.xml:36 msgid "" "The IPA provider is a back end used to connect to an IPA server. (Refer to " "the freeipa.org web site for information about IPA servers.) This provider " "requires that the machine be joined to the IPA domain; configuration is " "almost entirely self-discovered and obtained directly from the server." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ipa.5.xml:43 msgid "" "The IPA provider accepts the same options used by the <citerefentry> " "<refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> identity provider and the <citerefentry> " "<refentrytitle>sssd-krb5</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> authentication provider with some exceptions described " "below." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ipa.5.xml:55 msgid "" "However, it is neither necessary nor recommended to set these options. IPA " "provider can also be used as an access and chpass provider. As an access " "provider it uses HBAC (host-based access control) rules. Please refer to " "freeipa.org for more information about HBAC. No configuration of access " "provider is required on the client side." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ipa.5.xml:62 msgid "" "The IPA provider will use the PAC responder if the Kerberos tickets of users " "from trusted realms contain a PAC. To make configuration easier the PAC " "responder is started automatically if the IPA ID provider is configured." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:78 msgid "ipa_domain (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:81 msgid "" "Specifies the name of the IPA domain. This is optional. If not provided, " "the configuration domain name is used." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:89 msgid "ipa_server, ipa_backup_server (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:92 msgid "" "The comma-separated list of IP addresses or hostnames of the IPA servers to " "which SSSD should connect in the order of preference. For more information " "on failover and server redundancy, see the <quote>FAILOVER</quote> section. " "This is optional if autodiscovery is enabled. For more information on " "service discovery, refer to the <quote>SERVICE DISCOVERY</quote> section." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:105 msgid "ipa_hostname (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:108 msgid "" "Optional. May be set on machines where the hostname(5) does not reflect the " "fully qualified name used in the IPA domain to identify this host." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:116 sssd-ad.5.xml:780 msgid "dyndns_update (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:119 msgid "" "Optional. This option tells SSSD to automatically update the DNS server " "built into FreeIPA v2 with the IP address of this client. The update is " "secured using GSS-TSIG. The IP address of the IPA LDAP connection is used " "for the updates, if it is not otherwise specified by using the " "<quote>dyndns_iface</quote> option." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:128 sssd-ad.5.xml:794 msgid "" "NOTE: On older systems (such as RHEL 5), for this behavior to work reliably, " "the default Kerberos realm must be set properly in /etc/krb5.conf" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:133 msgid "" "NOTE: While it is still possible to use the old " "<emphasis>ipa_dyndns_update</emphasis> option, users should migrate to using " "<emphasis>dyndns_update</emphasis> in their config file." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:145 sssd-ad.5.xml:805 msgid "dyndns_ttl (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:148 sssd-ad.5.xml:808 msgid "" "The TTL to apply to the client DNS record when updating it. If " "dyndns_update is false this has no effect. This will override the TTL " "serverside if set by an administrator." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:153 msgid "" "NOTE: While it is still possible to use the old " "<emphasis>ipa_dyndns_ttl</emphasis> option, users should migrate to using " "<emphasis>dyndns_ttl</emphasis> in their config file." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:159 msgid "Default: 1200 (seconds)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:165 sssd-ad.5.xml:819 msgid "dyndns_iface (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:168 sssd-ad.5.xml:822 msgid "" "Optional. Applicable only when dyndns_update is true. Choose the interface " "or a list of interfaces whose IP addresses should be used for dynamic DNS " "updates. Special value <quote>*</quote> implies that IPs from all interfaces " "should be used." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:175 msgid "" "NOTE: While it is still possible to use the old " "<emphasis>ipa_dyndns_iface</emphasis> option, users should migrate to using " "<emphasis>dyndns_iface</emphasis> in their config file." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:181 msgid "" "Default: Use the IP addresses of the interface which is used for IPA LDAP " "connection" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:185 sssd-ad.5.xml:833 msgid "Example: dyndns_iface = em1, vnet1, vnet2" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:191 msgid "ipa_enable_dns_sites (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:194 sssd-ad.5.xml:160 msgid "Enables DNS sites - location based service discovery." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:198 msgid "" "If true and service discovery (see Service Discovery paragraph at the bottom " "of the man page) is enabled, then the SSSD will first attempt location " "based discovery using a query that contains " "\"_location.hostname.example.com\" and then fall back to traditional SRV " "discovery. If the location based discovery succeeds, the IPA servers located " "with the location based discovery are treated as primary servers and the IPA " "servers located using the traditional SRV discovery are used as back up " "servers" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:217 sssd-ad.5.xml:839 msgid "dyndns_refresh_interval (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:220 sssd-ad.5.xml:842 msgid "" "How often should the back end perform periodic DNS update in addition to the " "automatic update performed when the back end goes online. This option is " "optional and applicable only when dyndns_update is true." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:233 sssd-ad.5.xml:855 msgid "dyndns_update_ptr (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:236 sssd-ad.5.xml:858 msgid "" "Whether the PTR record should also be explicitly updated when updating the " "client's DNS records. Applicable only when dyndns_update is true." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:241 msgid "" "This option should be False in most IPA deployments as the IPA server " "generates the PTR records automatically when forward records are changed." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:247 msgid "Default: False (disabled)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:253 sssd-ad.5.xml:869 msgid "dyndns_force_tcp (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:256 sssd-ad.5.xml:872 msgid "" "Whether the nsupdate utility should default to using TCP for communicating " "with the DNS server." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:260 sssd-ad.5.xml:876 msgid "Default: False (let nsupdate choose the protocol)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:266 sssd-ad.5.xml:882 msgid "dyndns_server (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:269 sssd-ad.5.xml:885 msgid "" "The DNS server to use when performing a DNS update. In most setups, it's " "recommended to leave this option unset." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:274 sssd-ad.5.xml:890 msgid "" "Setting this option makes sense for environments where the DNS server is " "different from the identity server." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:279 sssd-ad.5.xml:895 msgid "" "Please note that this option will be only used in fallback attempt when " "previous attempt using autodetected settings failed." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:284 sssd-ad.5.xml:900 msgid "Default: None (let nsupdate choose the server)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:290 msgid "ipa_hbac_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:293 msgid "Optional. Use the given string as search base for HBAC related objects." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:297 msgid "Default: Use base DN" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:303 msgid "ipa_host_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:306 msgid "Optional. Use the given string as search base for host objects." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:310 sssd-ipa.5.xml:329 sssd-ipa.5.xml:348 sssd-ipa.5.xml:367 sssd-ipa.5.xml:386 msgid "" "See <quote>ldap_search_base</quote> for information about configuring " "multiple search bases." msgstr "" #. type: Content of: <listitem><para> #: sssd-ipa.5.xml:315 sssd-ipa.5.xml:334 include/ldap_search_bases.xml:27 msgid "Default: the value of <emphasis>ldap_search_base</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:322 msgid "ipa_selinux_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:325 msgid "Optional. Use the given string as search base for SELinux user maps." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:341 msgid "ipa_subdomains_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:344 msgid "Optional. Use the given string as search base for trusted domains." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:353 msgid "Default: the value of <emphasis>cn=trusts,%basedn</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:360 msgid "ipa_master_domain_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:363 msgid "Optional. Use the given string as search base for master domain object." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:372 msgid "Default: the value of <emphasis>cn=ad,cn=etc,%basedn</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:379 msgid "ipa_views_search_base (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:382 msgid "Optional. Use the given string as search base for views containers." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:391 msgid "Default: the value of <emphasis>cn=views,cn=accounts,%basedn</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:398 sssd-krb5.5.xml:254 msgid "krb5_validate (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:401 msgid "" "Verify with the help of krb5_keytab that the TGT obtained has not been " "spoofed." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:408 sssd-ad.5.xml:921 msgid "" "Note that this default differs from the traditional Kerberos provider back " "end." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:418 msgid "" "The name of the Kerberos realm. This is optional and defaults to the value " "of <quote>ipa_domain</quote>." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:422 msgid "" "The name of the Kerberos realm has a special meaning in IPA - it is " "converted into the base DN to use for performing LDAP operations." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:433 msgid "" "Specifies if the host and user principal should be canonicalized when " "connecting to IPA LDAP and also for AS requests. This feature is available " "with MIT Kerberos >= 1.7" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:446 sssd-krb5.5.xml:416 msgid "krb5_use_fast (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:449 sssd-krb5.5.xml:419 msgid "" "Enables flexible authentication secure tunneling (FAST) for Kerberos " "pre-authentication. The following options are supported:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:454 msgid "<emphasis>never</emphasis> use FAST." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:457 msgid "" "<emphasis>try</emphasis> to use FAST. If the server does not support FAST, " "continue the authentication without it. This is equivalent to not setting " "this option at all." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:463 sssd-krb5.5.xml:433 msgid "" "<emphasis>demand</emphasis> to use FAST. The authentication fails if the " "server does not require fast." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:468 msgid "Default: try" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:471 sssd-krb5.5.xml:444 msgid "" "NOTE: SSSD supports FAST only with MIT Kerberos version 1.8 and later. If " "SSSD is used with an older version of MIT Kerberos, using this option is a " "configuration error." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:480 sssd-ad.5.xml:928 msgid "krb5_confd_path (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:483 sssd-ad.5.xml:931 msgid "" "Absolute path of a directory where SSSD should place Kerberos configuration " "snippets." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:487 sssd-ad.5.xml:935 msgid "" "To disable the creation of the configuration snippets set the parameter to " "'none'." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:491 sssd-ad.5.xml:939 msgid "Default: not set (krb5.include.d subdirectory of SSSD's pubconf directory)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:498 msgid "ipa_hbac_refresh (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:501 msgid "" "The amount of time between lookups of the HBAC rules against the IPA " "server. This will reduce the latency and load on the IPA server if there are " "many access-control requests made in a short period." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:508 sssd-ipa.5.xml:524 sssd-ad.5.xml:355 msgid "Default: 5 (seconds)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:514 msgid "ipa_hbac_selinux (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:517 msgid "" "The amount of time between lookups of the SELinux maps against the IPA " "server. This will reduce the latency and load on the IPA server if there are " "many user login requests made in a short period." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:530 msgid "ipa_server_mode (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:533 msgid "This option should only be set by the IPA installer." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:537 msgid "" "The option denotes that the SSSD is running on IPA server and should perform " "lookups of users and groups from trusted domains differently." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:548 msgid "ipa_automount_location (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:551 msgid "The automounter location this IPA client will be using" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:554 msgid "Default: The location named \"default\"" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sssd-ipa.5.xml:562 msgid "VIEWS AND OVERRIDES" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:571 msgid "ipa_view_class (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:574 msgid "Objectclass of the view container." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:577 msgid "Default: nsContainer" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:583 msgid "ipa_view_name (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:586 msgid "Name of the attribute holding the name of the view." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:596 msgid "ipa_overide_object_class (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:599 msgid "Objectclass of the override objects." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:602 msgid "Default: ipaOverrideAnchor" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:608 msgid "ipa_anchor_uuid (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:611 msgid "" "Name of the attribute containing the reference to the original object in a " "remote domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:615 msgid "Default: ipaAnchorUUID" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:621 msgid "ipa_user_override_object_class (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:624 msgid "" "Name of the objectclass for user overrides. It is used to determine if the " "found override object is related to a user or a group." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:629 msgid "User overrides can contain attributes given by" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ipa.5.xml:632 msgid "ldap_user_name" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ipa.5.xml:635 msgid "ldap_user_uid_number" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ipa.5.xml:638 msgid "ldap_user_gid_number" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ipa.5.xml:641 msgid "ldap_user_gecos" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ipa.5.xml:644 msgid "ldap_user_home_directory" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ipa.5.xml:647 msgid "ldap_user_shell" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ipa.5.xml:650 msgid "ldap_user_ssh_public_key" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:655 msgid "Default: ipaUserOverride" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><term> #: sssd-ipa.5.xml:661 msgid "ipa_group_override_object_class (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:664 msgid "" "Name of the objectclass for group overrides. It is used to determine if the " "found override object is related to a user or a group." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:669 msgid "Group overrides can contain attributes given by" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ipa.5.xml:672 msgid "ldap_group_name" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ipa.5.xml:675 msgid "ldap_group_gid_number" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para><variablelist><varlistentry><listitem><para> #: sssd-ipa.5.xml:680 msgid "Default: ipaGroupOverride" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sssd-ipa.5.xml:564 msgid "" "SSSD can handle views and overrides which are offered by FreeIPA 4.1 and " "later version. Since all paths and objectclasses are fixed on the server " "side there is basically no need to configure anything. For completeness the " "related options are listed here with their default values. <placeholder " "type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd-ipa.5.xml:690 msgid "SUBDOMAINS PROVIDER" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ipa.5.xml:692 msgid "" "The IPA subdomains provider behaves slightly differently if it is configured " "explicitly or implicitly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ipa.5.xml:696 msgid "" "If the option 'subdomains_provider = ipa' is found in the domain section of " "sssd.conf, the IPA subdomains provider is configured explicitly, and all " "subdomain requests are sent to the IPA server if necessary." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ipa.5.xml:702 msgid "" "If the option 'subdomains_provider' is not set in the domain section of " "sssd.conf but there is the option 'id_provider = ipa', the IPA subdomains " "provider is configured implicitly. In this case, if a subdomain request " "fails and indicates that the server does not support subdomains, i.e. is not " "configured for trusts, the IPA subdomains provider is disabled. After an " "hour or after the IPA provider goes online, the subdomains provider is " "enabled again." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ipa.5.xml:719 msgid "" "The following example assumes that SSSD is correctly configured and " "example.com is one of the domains in the <replaceable>[sssd]</replaceable> " "section. This examples shows only the ipa provider-specific options." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd-ipa.5.xml:726 #, no-wrap msgid "" "[domain/example.com]\n" "id_provider = ipa\n" "ipa_server = ipaserver.example.com\n" "ipa_hostname = myhost.example.com\n" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sssd-ad.5.xml:10 sssd-ad.5.xml:16 msgid "sssd-ad" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sssd-ad.5.xml:17 msgid "SSSD Active Directory provider" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:23 msgid "" "This manual page describes the configuration of the AD provider for " "<citerefentry> <refentrytitle>sssd</refentrytitle> <manvolnum>8</manvolnum> " "</citerefentry>. For a detailed syntax reference, refer to the <quote>FILE " "FORMAT</quote> section of the <citerefentry> " "<refentrytitle>sssd.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> manual page." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:36 msgid "" "The AD provider is a back end used to connect to an Active Directory " "server. This provider requires that the machine be joined to the AD domain " "and a keytab is available." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:41 msgid "" "The AD provider supports connecting to Active Directory 2008 R2 or " "later. Earlier versions may work, but are unsupported." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:45 msgid "" "The AD provider can be used to get user information and authenticate users " "from trusted domains. Currently only trusted domains in the same forest are " "recognized. In addition servers from trusted domains are always " "auto-discovered." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:51 msgid "" "The AD provider accepts the same options used by the <citerefentry> " "<refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> identity provider and the <citerefentry> " "<refentrytitle>sssd-krb5</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> authentication provider with some exceptions described " "below." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:63 msgid "" "However, it is neither necessary nor recommended to set these options. The " "AD provider can also be used as an access, chpass, sudo and autofs " "provider. No configuration of the access provider is required on the client " "side." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd-ad.5.xml:75 #, no-wrap msgid "" "ldap_id_mapping = False\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:69 msgid "" "By default, the AD provider will map UID and GID values from the objectSID " "parameter in Active Directory. For details on this, see the <quote>ID " "MAPPING</quote> section below. If you want to disable ID mapping and instead " "rely on POSIX attributes defined in Active Directory, you should set " "<placeholder type=\"programlisting\" id=\"0\"/> In order to retrieve users " "and groups using POSIX attributes from trusted domains, the AD administrator " "must make sure that the POSIX attributes are replicated to the Global " "Catalog." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:82 msgid "" "Users, groups and other entities served by SSSD are always treated as " "case-insensitive in the AD provider for compatibility with Active " "Directory's LDAP implementation." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:97 msgid "ad_domain (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:100 msgid "" "Specifies the name of the Active Directory domain. This is optional. If not " "provided, the configuration domain name is used." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:105 msgid "" "For proper operation, this option should be specified as the lower-case " "version of the long version of the Active Directory domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:110 msgid "" "The short domain name (also known as the NetBIOS or the flat name) is " "autodetected by the SSSD." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:117 msgid "ad_server, ad_backup_server (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:120 msgid "" "The comma-separated list of hostnames of the AD servers to which SSSD should " "connect in order of preference. For more information on failover and server " "redundancy, see the <quote>FAILOVER</quote> section." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:127 msgid "" "This is optional if autodiscovery is enabled. For more information on " "service discovery, refer to the <quote>SERVICE DISCOVERY</quote> section." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:132 msgid "" "Note: Trusted domains will always auto-discover servers even if the primary " "server is explicitly defined in the ad_server option." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:140 msgid "ad_hostname (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:143 msgid "" "Optional. May be set on machines where the hostname(5) does not reflect the " "fully qualified name used in the Active Directory domain to identify this " "host." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:149 msgid "" "This field is used to determine the host principal in use in the keytab. It " "must match the hostname for which the keytab was issued." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:157 msgid "ad_enable_dns_sites (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:164 msgid "" "If true and service discovery (see Service Discovery paragraph at the bottom " "of the man page) is enabled, the SSSD will first attempt to discover the " "Active Directory server to connect to using the Active Directory Site " "Discovery and fall back to the DNS SRV records if no AD site is found. The " "DNS SRV configuration, including the discovery domain, is used during site " "discovery as well." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:180 msgid "ad_access_filter (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:183 msgid "" "This option specifies LDAP access control filter that the user must match in " "order to be allowed access. Please note that the " "<quote>access_provider</quote> option must be explicitly set to " "<quote>ad</quote> in order for this option to have an effect." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:191 msgid "" "The option also supports specifying different filters per domain or " "forest. This extended filter would consist of: " "<quote>KEYWORD:NAME:FILTER</quote>. The keyword can be either " "<quote>DOM</quote>, <quote>FOREST</quote> or missing." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:199 msgid "" "If the keyword equals to <quote>DOM</quote> or is missing, then " "<quote>NAME</quote> specifies the domain or subdomain the filter applies " "to. If the keyword equals to <quote>FOREST</quote>, then the filter equals " "to all domains from the forest specified by <quote>NAME</quote>." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:207 msgid "" "Multiple filters can be separated with the <quote>?</quote> character, " "similarly to how search bases work." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:212 msgid "" "The most specific match is always used. For example, if the option specified " "filter for a domain the user is a member of and a global filter, the " "per-domain filter would be applied. If there are more matches with the same " "specification, the first one is used." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><programlisting> #: sssd-ad.5.xml:223 #, no-wrap msgid "" "# apply filter on domain called dom1 only:\n" "dom1:(memberOf=cn=admins,ou=groups,dc=dom1,dc=com)\n" "\n" "# apply filter on domain called dom2 only:\n" "DOM:dom2:(memberOf=cn=admins,ou=groups,dc=dom2,dc=com)\n" "\n" "# apply filter on forest called EXAMPLE.COM only:\n" "FOREST:EXAMPLE.COM:(memberOf=cn=admins,ou=groups,dc=example,dc=com)\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:233 sssd-ad.5.xml:247 msgid "Default: Not set" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:239 msgid "ad_site (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:242 msgid "" "Specify AD site to which client should try to connect. If this option is " "not provided, the AD site will be auto-discovered." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:253 msgid "ad_enable_gc (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:256 msgid "" "By default, the SSSD connects to the Global Catalog first to retrieve users " "from trusted domains and uses the LDAP port to retrieve group memberships or " "as a fallback. Disabling this option makes the SSSD only connect to the LDAP " "port of the current AD server." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:264 msgid "" "Please note that disabling Global Catalog support does not disable " "retrieving users from trusted domains. The SSSD would connect to the LDAP " "port of trusted domains instead. However, Global Catalog must be used in " "order to resolve cross-domain group memberships." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:278 msgid "ad_gpo_access_control (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:281 msgid "" "This option specifies the operation mode for GPO-based access control " "functionality: whether it operates in disabled mode, enforcing mode, or " "permissive mode. Please note that the <quote>access_provider</quote> option " "must be explicitly set to <quote>ad</quote> in order for this option to have " "an effect." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:290 msgid "" "GPO-based access control functionality uses GPO policy settings to determine " "whether or not a particular user is allowed to logon to a particular host." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:296 msgid "" "NOTE: If the operation mode is set to enforcing, it is possible that users " "that were previously allowed logon access will now be denied logon access " "(as dictated by the GPO policy settings). In order to facilitate a smooth " "transition for administrators, a permissive mode is available that will not " "enforce the access control rules, but will evaluate them and will output a " "syslog message if access would have been denied. By examining the logs, " "administrators can then make the necessary changes before setting the mode " "to enforcing." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:309 msgid "There are three supported values for this option:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:313 msgid "disabled: GPO-based access control rules are neither evaluated nor enforced." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:319 msgid "enforcing: GPO-based access control rules are evaluated and enforced." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:325 msgid "" "permissive: GPO-based access control rules are evaluated, but not enforced. " "Instead, a syslog message will be emitted indicating that the user would " "have been denied access if this option's value were set to enforcing." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:336 msgid "Default: permissive" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:339 msgid "Default: enforcing" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:345 msgid "ad_gpo_cache_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:348 msgid "" "The amount of time between lookups of GPO policy files against the AD " "server. This will reduce the latency and load on the AD server if there are " "many access-control requests made in a short period." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:361 msgid "ad_gpo_map_interactive (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:364 msgid "" "A comma-separated list of PAM service names for which GPO-based access " "control is evaluated based on the InteractiveLogonRight and " "DenyInteractiveLogonRight policy settings." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:370 msgid "" "Note: Using the Group Policy Management Editor this value is called \"Allow " "log on locally\" and \"Deny log on locally\"." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><programlisting> #: sssd-ad.5.xml:384 #, no-wrap msgid "" "ad_gpo_map_interactive = +my_pam_service, -login\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:375 msgid "" "It is possible to add another PAM service name to the default set by using " "<quote>+service_name</quote> or to explicitly remove a PAM service name from " "the default set by using <quote>-service_name</quote>. For example, in " "order to replace a default PAM service name for this logon right " "(e.g. <quote>login</quote>) with a custom pam service name " "(e.g. <quote>my_pam_service</quote>), you would use the following " "configuration: <placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:388 sssd-ad.5.xml:479 sssd-ad.5.xml:525 sssd-ad.5.xml:570 sssd-ad.5.xml:636 msgid "Default: the default set of PAM service names includes:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:392 msgid "login" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:397 msgid "su" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:402 msgid "su-l" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:407 msgid "gdm-fingerprint" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:412 msgid "gdm-password" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:417 msgid "gdm-smartcard" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:422 msgid "kdm" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:427 msgid "lightdm" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:432 msgid "lxdm" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:437 msgid "sddm" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:442 msgid "xdm" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:451 msgid "ad_gpo_map_remote_interactive (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:454 msgid "" "A comma-separated list of PAM service names for which GPO-based access " "control is evaluated based on the RemoteInteractiveLogonRight and " "DenyRemoteInteractiveLogonRight policy settings." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:460 msgid "" "Note: Using the Group Policy Management Editor this value is called \"Allow " "log on through Remote Desktop Services\" and \"Deny log on through Remote " "Desktop Services\"." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><programlisting> #: sssd-ad.5.xml:475 #, no-wrap msgid "" "ad_gpo_map_remote_interactive = +my_pam_service, -sshd\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:466 msgid "" "It is possible to add another PAM service name to the default set by using " "<quote>+service_name</quote> or to explicitly remove a PAM service name from " "the default set by using <quote>-service_name</quote>. For example, in " "order to replace a default PAM service name for this logon right " "(e.g. <quote>sshd</quote>) with a custom pam service name " "(e.g. <quote>my_pam_service</quote>), you would use the following " "configuration: <placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:483 msgid "sshd" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:488 msgid "cockpit" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:497 msgid "ad_gpo_map_network (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:500 msgid "" "A comma-separated list of PAM service names for which GPO-based access " "control is evaluated based on the NetworkLogonRight and " "DenyNetworkLogonRight policy settings." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:506 msgid "" "Note: Using the Group Policy Management Editor this value is called \"Access " "this computer from the network\" and \"Deny access to this computer from the " "network\"." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><programlisting> #: sssd-ad.5.xml:521 #, no-wrap msgid "" "ad_gpo_map_network = +my_pam_service, -ftp\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:512 msgid "" "It is possible to add another PAM service name to the default set by using " "<quote>+service_name</quote> or to explicitly remove a PAM service name from " "the default set by using <quote>-service_name</quote>. For example, in " "order to replace a default PAM service name for this logon right " "(e.g. <quote>ftp</quote>) with a custom pam service name " "(e.g. <quote>my_pam_service</quote>), you would use the following " "configuration: <placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:529 msgid "ftp" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:534 msgid "samba" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:543 msgid "ad_gpo_map_batch (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:546 msgid "" "A comma-separated list of PAM service names for which GPO-based access " "control is evaluated based on the BatchLogonRight and DenyBatchLogonRight " "policy settings." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:552 msgid "" "Note: Using the Group Policy Management Editor this value is called \"Allow " "log on as a batch job\" and \"Deny log on as a batch job\"." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><programlisting> #: sssd-ad.5.xml:566 #, no-wrap msgid "" "ad_gpo_map_batch = +my_pam_service, -crond\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:557 msgid "" "It is possible to add another PAM service name to the default set by using " "<quote>+service_name</quote> or to explicitly remove a PAM service name from " "the default set by using <quote>-service_name</quote>. For example, in " "order to replace a default PAM service name for this logon right " "(e.g. <quote>crond</quote>) with a custom pam service name " "(e.g. <quote>my_pam_service</quote>), you would use the following " "configuration: <placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:574 msgid "crond" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:583 msgid "ad_gpo_map_service (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:586 msgid "" "A comma-separated list of PAM service names for which GPO-based access " "control is evaluated based on the ServiceLogonRight and " "DenyServiceLogonRight policy settings." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:592 msgid "" "Note: Using the Group Policy Management Editor this value is called \"Allow " "log on as a service\" and \"Deny log on as a service\"." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><programlisting> #: sssd-ad.5.xml:605 #, no-wrap msgid "" "ad_gpo_map_service = +my_pam_service\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:597 sssd-ad.5.xml:667 msgid "" "It is possible to add a PAM service name to the default set by using " "<quote>+service_name</quote>. Since the default set is empty, it is not " "possible to remove a PAM service name from the default set. For example, in " "order to add a custom pam service name (e.g. <quote>my_pam_service</quote>), " "you would use the following configuration: <placeholder " "type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:615 msgid "ad_gpo_map_permit (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:618 msgid "" "A comma-separated list of PAM service names for which GPO-based access is " "always granted, regardless of any GPO Logon Rights." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><programlisting> #: sssd-ad.5.xml:632 #, no-wrap msgid "" "ad_gpo_map_permit = +my_pam_service, -sudo\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:623 msgid "" "It is possible to add another PAM service name to the default set by using " "<quote>+service_name</quote> or to explicitly remove a PAM service name from " "the default set by using <quote>-service_name</quote>. For example, in " "order to replace a default PAM service name for unconditionally permitted " "access (e.g. <quote>sudo</quote>) with a custom pam service name " "(e.g. <quote>my_pam_service</quote>), you would use the following " "configuration: <placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:640 msgid "sudo" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:645 msgid "sudo-i" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:650 msgid "systemd-user" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:659 msgid "ad_gpo_map_deny (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:662 msgid "" "A comma-separated list of PAM service names for which GPO-based access is " "always denied, regardless of any GPO Logon Rights." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><programlisting> #: sssd-ad.5.xml:675 #, no-wrap msgid "" "ad_gpo_map_deny = +my_pam_service\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:685 msgid "ad_gpo_default_right (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:688 msgid "" "This option defines how access control is evaluated for PAM service names " "that are not explicitly listed in one of the ad_gpo_map_* options. This " "option can be set in two different manners. First, this option can be set to " "use a default logon right. For example, if this option is set to " "'interactive', it means that unmapped PAM service names will be processed " "based on the InteractiveLogonRight and DenyInteractiveLogonRight policy " "settings. Alternatively, this option can be set to either always permit or " "always deny access for unmapped PAM service names." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:701 msgid "Supported values for this option include:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:705 msgid "interactive" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:710 msgid "remote_interactive" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:715 msgid "network" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:720 msgid "batch" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:725 msgid "service" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:730 msgid "permit" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><itemizedlist><listitem><para> #: sssd-ad.5.xml:735 msgid "deny" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:741 msgid "Default: deny" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:747 msgid "ad_maximum_machine_account_password_age (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:750 msgid "" "SSSD will check once a day if the machine account password is older than the " "given age in days and try to renew it. A value of 0 will disable the renewal " "attempt." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:756 msgid "Default: 30 days" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:762 msgid "ad_machine_account_password_renewal_opts (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:765 msgid "" "This option should only be used to test the machine account renewal " "task. The option expect 2 integers seperated by a colon (':'). The first " "integer defines the interval in seconds how often the task is run. The " "second specifies the inital timeout in seconds before the task is run for " "the first time after startup." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:774 msgid "Default: 86400:750 (24h and 15m)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:783 msgid "" "Optional. This option tells SSSD to automatically update the Active " "Directory DNS server with the IP address of this client. The update is " "secured using GSS-TSIG. As a consequence, the Active Directory administrator " "only needs to allow secure updates for the DNS zone. The IP address of the " "AD LDAP connection is used for the updates, if it is not otherwise specified " "by using the <quote>dyndns_iface</quote> option." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:813 msgid "Default: 3600 (seconds)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:829 msgid "" "Default: Use the IP addresses of the interface which is used for AD LDAP " "connection" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:863 sss_rpcidmapd.5.xml:76 msgid "Default: True" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-ad.5.xml:909 sssd-krb5.5.xml:505 msgid "krb5_use_enterprise_principal (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-ad.5.xml:912 sssd-krb5.5.xml:508 msgid "" "Specifies if the user principal should be treated as enterprise " "principal. See section 5 of RFC 6806 for more details about enterprise " "principals." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:957 msgid "" "The following example assumes that SSSD is correctly configured and " "example.com is one of the domains in the <replaceable>[sssd]</replaceable> " "section. This example shows only the AD provider-specific options." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd-ad.5.xml:964 #, no-wrap msgid "" "[domain/EXAMPLE]\n" "id_provider = ad\n" "auth_provider = ad\n" "access_provider = ad\n" "chpass_provider = ad\n" "\n" "ad_server = dc1.example.com\n" "ad_hostname = client.example.com\n" "ad_domain = example.com\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd-ad.5.xml:984 #, no-wrap msgid "" "access_provider = ldap\n" "ldap_access_order = expire\n" "ldap_account_expire_policy = ad\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:980 msgid "" "The AD access control provider checks if the account is expired. It has the " "same effect as the following configuration of the LDAP provider: " "<placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:990 msgid "" "However, unless the <quote>ad</quote> access control provider is explicitly " "configured, the default access provider is <quote>permit</quote>. Please " "note that if you configure an access provider other than <quote>ad</quote>, " "you need to set all the connection parameters (such as LDAP URIs and " "encryption details) manually." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ad.5.xml:998 msgid "" "When the autofs provider is set to <quote>ad</quote>, the RFC2307 schema " "attribute mapping (nisMap, nisObject, ...) is used, because these attributes " "are included the default Active Directory schema." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sssd-sudo.5.xml:10 sssd-sudo.5.xml:16 msgid "sssd-sudo" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sssd-sudo.5.xml:17 msgid "Configuring sudo with the SSSD back end" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:23 msgid "" "This manual page describes how to configure <citerefentry> " "<refentrytitle>sudo</refentrytitle> <manvolnum>8</manvolnum> </citerefentry> " "to work with <citerefentry> <refentrytitle>sssd</refentrytitle> " "<manvolnum>8</manvolnum> </citerefentry> and how SSSD caches sudo rules." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd-sudo.5.xml:36 msgid "Configuring sudo to cooperate with SSSD" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:38 msgid "" "To enable SSSD as a source for sudo rules, add <emphasis>sss</emphasis> to " "the <emphasis>sudoers</emphasis> entry in <citerefentry> " "<refentrytitle>nsswitch.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry>." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:47 msgid "" "For example, to configure sudo to first lookup rules in the standard " "<citerefentry> <refentrytitle>sudoers</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> file (which should contain rules " "that apply to local users) and then in SSSD, the nsswitch.conf file should " "contain the following line:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd-sudo.5.xml:57 #, no-wrap msgid "sudoers: files sss\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:61 msgid "" "More information about configuring the sudoers search order from the " "nsswitch.conf file as well as information about the LDAP schema that is used " "to store sudo rules in the directory can be found in <citerefentry> " "<refentrytitle>sudoers.ldap</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry>." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:70 msgid "" "<emphasis>Note</emphasis>: in order to use netgroups or IPA hostgroups in " "sudo rules, you also need to correctly set <citerefentry> " "<refentrytitle>nisdomainname</refentrytitle> <manvolnum>1</manvolnum> " "</citerefentry> to your NIS domain name (which equals to IPA domain name " "when using hostgroups)." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd-sudo.5.xml:82 msgid "Configuring SSSD to fetch sudo rules" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:84 msgid "" "All configuration that is needed on SSSD side is to extend the list of " "<emphasis>services</emphasis> with \"sudo\" in [sssd] section of " "<citerefentry> <refentrytitle>sssd.conf</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry>. To speed up the LDAP lookups, you " "can also set search base for sudo rules using " "<emphasis>ldap_sudo_search_base</emphasis> option." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:94 msgid "" "The following example shows how to configure SSSD to download sudo rules " "from an LDAP server." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd-sudo.5.xml:99 #, no-wrap msgid "" "[sssd]\n" "config_file_version = 2\n" "services = nss, pam, sudo\n" "domains = EXAMPLE\n" "\n" "[domain/EXAMPLE]\n" "id_provider = ldap\n" "sudo_provider = ldap\n" "ldap_uri = ldap://example.com\n" "ldap_sudo_search_base = ou=sudoers,dc=example,dc=com\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:112 msgid "" "When the SSSD is configured to use IPA as the ID provider, the sudo provider " "is automatically enabled. The sudo search base is configured to use the " "compat tree (ou=sudoers,$DC)." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd-sudo.5.xml:119 msgid "The SUDO rule caching mechanism" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:121 msgid "" "The biggest challenge, when developing sudo support in SSSD, was to ensure " "that running sudo with SSSD as the data source provides the same user " "experience and is as fast as sudo but keeps providing the most current set " "of rules as possible. To satisfy these requirements, SSSD uses three kinds " "of updates. They are referred to as full refresh, smart refresh and rules " "refresh." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:129 msgid "" "The <emphasis>smart refresh</emphasis> periodically downloads rules that are " "new or were modified after the last update. Its primary goal is to keep the " "database growing by fetching only small increments that do not generate " "large amounts of network traffic." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:135 msgid "" "The <emphasis>full refresh</emphasis> simply deletes all sudo rules stored " "in the cache and replaces them with all rules that are stored on the " "server. This is used to keep the cache consistent by removing every rule " "which was deleted from the server. However, full refresh may produce a lot " "of traffic and thus it should be run only occasionally depending on the size " "and stability of the sudo rules." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:143 msgid "" "The <emphasis>rules refresh</emphasis> ensures that we do not grant the user " "more permission than defined. It is triggered each time the user runs " "sudo. Rules refresh will find all rules that apply to this user, check their " "expiration time and redownload them if expired. In the case that any of " "these rules are missing on the server, the SSSD will do an out of band full " "refresh because more rules (that apply to other users) may have been " "deleted." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:152 msgid "" "If enabled, SSSD will store only rules that can be applied to this " "machine. This means rules that contain one of the following values in " "<emphasis>sudoHost</emphasis> attribute:" msgstr "" #. type: Content of: <reference><refentry><refsect1><itemizedlist><listitem><para> #: sssd-sudo.5.xml:159 msgid "keyword ALL" msgstr "" #. type: Content of: <reference><refentry><refsect1><itemizedlist><listitem><para> #: sssd-sudo.5.xml:164 msgid "wildcard" msgstr "" #. type: Content of: <reference><refentry><refsect1><itemizedlist><listitem><para> #: sssd-sudo.5.xml:169 msgid "netgroup (in the form \"+netgroup\")" msgstr "" #. type: Content of: <reference><refentry><refsect1><itemizedlist><listitem><para> #: sssd-sudo.5.xml:174 msgid "hostname or fully qualified domain name of this machine" msgstr "" #. type: Content of: <reference><refentry><refsect1><itemizedlist><listitem><para> #: sssd-sudo.5.xml:179 msgid "one of the IP addresses of this machine" msgstr "" #. type: Content of: <reference><refentry><refsect1><itemizedlist><listitem><para> #: sssd-sudo.5.xml:184 msgid "one of the IP addresses of the network (in the form \"address/mask\")" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-sudo.5.xml:190 msgid "" "There are many configuration options that can be used to adjust the " "behavior. Please refer to \"ldap_sudo_*\" in <citerefentry> " "<refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> and \"sudo_*\" in <citerefentry> " "<refentrytitle>sssd.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry>." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sssd.8.xml:10 sssd.8.xml:15 msgid "sssd" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sssd.8.xml:16 msgid "System Security Services Daemon" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sssd.8.xml:21 msgid "" "<command>sssd</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.8.xml:31 msgid "" "<command>SSSD</command> provides a set of daemons to manage access to remote " "directories and authentication mechanisms. It provides an NSS and PAM " "interface toward the system and a pluggable backend system to connect to " "multiple different account sources as well as D-Bus interface. It is also " "the basis to provide client auditing and policy services for projects like " "FreeIPA. It provides a more robust database to store local users as well as " "extended user data." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:46 msgid "" "<option>-d</option>,<option>--debug-level</option> " "<replaceable>LEVEL</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:53 msgid "<option>--debug-timestamps=</option><replaceable>mode</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:57 msgid "<emphasis>1</emphasis>: Add a timestamp to the debug messages" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:60 msgid "<emphasis>0</emphasis>: Disable timestamp in the debug messages" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:69 msgid "<option>--debug-microseconds=</option><replaceable>mode</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:73 msgid "<emphasis>1</emphasis>: Add microseconds to the timestamp in debug messages" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:76 msgid "<emphasis>0</emphasis>: Disable microseconds in timestamp" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:85 msgid "<option>-f</option>,<option>--debug-to-files</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:89 msgid "" "Send the debug output to files instead of stderr. By default, the log files " "are stored in <filename>/var/log/sssd</filename> and there are separate log " "files for every SSSD service and domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:97 msgid "<option>-D</option>,<option>--daemon</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:101 msgid "Become a daemon after starting up." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:107 sss_seed.8.xml:136 msgid "<option>-i</option>,<option>--interactive</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:111 msgid "Run in the foreground, don't become a daemon." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:117 sss_debuglevel.8.xml:42 msgid "<option>-c</option>,<option>--config</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:121 sss_debuglevel.8.xml:46 msgid "" "Specify a non-default config file. The default is " "<filename>/etc/sssd/sssd.conf</filename>. For reference on the config file " "syntax and options, consult the <citerefentry> " "<refentrytitle>sssd.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> manual page." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:135 msgid "<option>--version</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:139 msgid "Print version number and exit." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sssd.8.xml:147 msgid "Signals" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:150 msgid "SIGTERM/SIGINT" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:153 msgid "" "Informs the SSSD to gracefully terminate all of its child processes and then " "shut down the monitor." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:159 msgid "SIGHUP" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:162 msgid "" "Tells the SSSD to stop writing to its current debug file descriptors and to " "close and reopen them. This is meant to facilitate log rolling with programs " "like logrotate." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:170 msgid "SIGUSR1" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:173 msgid "" "Tells the SSSD to simulate offline operation for the duration of the " "<quote>offline_timeout</quote> parameter. This is useful for testing. The " "signal can be sent to either the sssd process or any sssd_be process " "directly." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sssd.8.xml:182 msgid "SIGUSR2" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd.8.xml:185 msgid "" "Tells the SSSD to go online immediately. This is useful for testing. The " "signal can be sent to either the sssd process or any sssd_be process " "directly." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd.8.xml:197 msgid "" "If the environment variable SSS_NSS_USE_MEMCACHE is set to \"NO\", client " "applications will not use the fast in memory cache." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_obfuscate.8.xml:10 sss_obfuscate.8.xml:15 msgid "sss_obfuscate" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_obfuscate.8.xml:16 msgid "obfuscate a clear text password" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_obfuscate.8.xml:21 msgid "" "<command>sss_obfuscate</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg " "choice='plain'><replaceable>[PASSWORD]</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_obfuscate.8.xml:32 msgid "" "<command>sss_obfuscate</command> converts a given password into " "human-unreadable format and places it into appropriate domain section of the " "SSSD config file." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_obfuscate.8.xml:37 msgid "" "The cleartext password is read from standard input or entered " "interactively. The obfuscated password is put into " "<quote>ldap_default_authtok</quote> parameter of a given SSSD domain and the " "<quote>ldap_default_authtok_type</quote> parameter is set to " "<quote>obfuscated_password</quote>. Refer to <citerefentry> " "<refentrytitle>sssd-ldap</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> for more details on these parameters." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_obfuscate.8.xml:49 msgid "" "Please note that obfuscating the password provides <emphasis>no real " "security benefit</emphasis> as it is still possible for an attacker to " "reverse-engineer the password back. Using better authentication mechanisms " "such as client side certificates or GSSAPI is <emphasis>strongly</emphasis> " "advised." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_obfuscate.8.xml:63 msgid "<option>-s</option>,<option>--stdin</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_obfuscate.8.xml:67 msgid "The password to obfuscate will be read from standard input." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_obfuscate.8.xml:74 sss_ssh_authorizedkeys.1.xml:80 sss_ssh_knownhostsproxy.1.xml:78 msgid "" "<option>-d</option>,<option>--domain</option> " "<replaceable>DOMAIN</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_obfuscate.8.xml:79 msgid "" "The SSSD domain to use the password in. The default name is " "<quote>default</quote>." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_obfuscate.8.xml:86 msgid "<option>-f</option>,<option>--file</option> <replaceable>FILE</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_obfuscate.8.xml:91 msgid "Read the config file specified by the positional parameter." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_obfuscate.8.xml:95 msgid "Default: <filename>/etc/sssd/sssd.conf</filename>" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_override.8.xml:10 sss_override.8.xml:15 msgid "sss_override" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_override.8.xml:16 msgid "create local overrides of user and group attributes" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_override.8.xml:21 msgid "" "<command>sss_override</command> <arg " "choice='plain'><replaceable>COMMAND</replaceable></arg> <arg choice='opt'> " "<replaceable>options</replaceable> </arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_override.8.xml:32 msgid "" "<command>sss_override</command> enables to create a client-side view and " "allows to change selected values of specific user and groups. This change " "takes effect only on local machine." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_override.8.xml:37 msgid "" "Overrides data are stored in the SSSD cache. If the cache is deleted, all " "local overrides are lost. Please note that after the first override is " "created using any of the following <emphasis>user-add</emphasis>, " "<emphasis>group-add</emphasis>, <emphasis>user-import</emphasis> or " "<emphasis>group-import</emphasis> command. SSSD needs to be restarted to " "take effect. <emphasis>sss_override</emphasis> prints message when a " "restart is required." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sss_override.8.xml:50 msgid "AVAILABLE COMMANDS" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_override.8.xml:52 msgid "" "Argument <emphasis>NAME</emphasis> is the name of original object in all " "commands. It is not possible to override <emphasis>uid</emphasis> or " "<emphasis>gid</emphasis> to 0." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:59 msgid "" "<option>user-add</option> <emphasis>NAME</emphasis> " "<optional><option>-n,--name</option> NAME</optional> " "<optional><option>-u,--uid</option> UID</optional> " "<optional><option>-g,--gid</option> GID</optional> " "<optional><option>-h,--home</option> HOME</optional> " "<optional><option>-s,--shell</option> SHELL</optional> " "<optional><option>-c,--gecos</option> GECOS</optional>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:70 msgid "" "Override attributes of an user. Please be aware that calling this command " "will replace any previous override for the (NAMEd) user." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:78 msgid "<option>user-del</option> <emphasis>NAME</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:83 msgid "" "Remove user overrides. However be aware that overridden attributes might be " "returned from memory cache. Please see SSSD option " "<emphasis>memcache_timeout</emphasis> for more details." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:92 msgid "" "<option>user-find</option> <optional><option>-d,--domain</option> " "DOMAIN</optional>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:97 msgid "" "List all users with set overrides. If <emphasis>DOMAIN</emphasis> parameter " "is set, only users from the domain are listed." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:105 msgid "<option>user-show</option> <emphasis>NAME</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:110 msgid "Show user overrides." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:116 msgid "<option>user-import</option> <emphasis>FILE</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:121 msgid "" "Import user overrides from <emphasis>FILE</emphasis>. Data format is " "similar to standard passwd file. The format is:" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:126 msgid "original_name:name:uid:gid:gecos:home:shell" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:129 msgid "" "where original_name is original name of the user whose attributes should be " "overridden. The rest of fields correspond to new values. You can omit a " "value simply by leaving corresponding field empty." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:138 msgid "ckent:superman::::::" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:141 msgid "ckent@krypton.com::501:501:Superman:/home/earth:/bin/bash" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:147 msgid "<option>user-export</option> <emphasis>FILE</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:152 msgid "" "Export all overridden attributes and store them in " "<emphasis>FILE</emphasis>. See <emphasis>user-import</emphasis> for data " "format." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:160 msgid "" "<option>group-add</option> <emphasis>NAME</emphasis> " "<optional><option>-n,--name</option> NAME</optional> " "<optional><option>-g,--gid</option> GID</optional>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:167 msgid "" "Override attributes of a group. Please be aware that calling this command " "will replace any previous override for the (NAMEd) group." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:175 msgid "<option>group-del</option> <emphasis>NAME</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:180 msgid "" "Remove group overrides. However be aware that overridden attributes might be " "returned from memory cache. Please see SSSD option " "<emphasis>memcache_timeout</emphasis> for more details." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:189 msgid "" "<option>group-find</option> <optional><option>-d,--domain</option> " "DOMAIN</optional>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:194 msgid "" "List all groups with set overrides. If <emphasis>DOMAIN</emphasis> " "parameter is set, only groups from the domain are listed." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:202 msgid "<option>group-show</option> <emphasis>NAME</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:207 msgid "Show group overrides." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:213 msgid "<option>group-import</option> <emphasis>FILE</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:218 msgid "" "Import group overrides from <emphasis>FILE</emphasis>. Data format is " "similar to standard group file. The format is:" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:223 msgid "original_name:name:gid" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:226 msgid "" "where original_name is original name of the group whose attributes should be " "overridden. The rest of fields correspond to new values. You can omit a " "value simply by leaving corresponding field empty." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:235 msgid "admins:administrators:" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:238 msgid "Domain Users:Users:501" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:244 msgid "<option>group-export</option> <emphasis>FILE</emphasis>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_override.8.xml:249 msgid "" "Export all overridden attributes and store them in " "<emphasis>FILE</emphasis>. See <emphasis>group-import</emphasis> for data " "format." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sss_override.8.xml:259 msgid "COMMON OPTIONS" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_override.8.xml:261 msgid "Those options are available with all commands." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_override.8.xml:266 msgid "<option>--debug</option> <replaceable>LEVEL</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_useradd.8.xml:10 sss_useradd.8.xml:15 msgid "sss_useradd" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_useradd.8.xml:16 msgid "create a new user" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_useradd.8.xml:21 msgid "" "<command>sss_useradd</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg " "choice='plain'><replaceable>LOGIN</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_useradd.8.xml:32 msgid "" "<command>sss_useradd</command> creates a new user account using the values " "specified on the command line plus the default values from the system." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_useradd.8.xml:43 sss_seed.8.xml:76 msgid "<option>-u</option>,<option>--uid</option> <replaceable>UID</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_useradd.8.xml:48 msgid "" "Set the UID of the user to the value of <replaceable>UID</replaceable>. If " "not given, it is chosen automatically." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_useradd.8.xml:55 sss_usermod.8.xml:43 sss_seed.8.xml:100 msgid "" "<option>-c</option>,<option>--gecos</option> " "<replaceable>COMMENT</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_useradd.8.xml:60 sss_usermod.8.xml:48 sss_seed.8.xml:105 msgid "" "Any text string describing the user. Often used as the field for the user's " "full name." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_useradd.8.xml:67 sss_usermod.8.xml:55 sss_seed.8.xml:112 msgid "" "<option>-h</option>,<option>--home</option> " "<replaceable>HOME_DIR</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_useradd.8.xml:72 msgid "" "The home directory of the user account. The default is to append the " "<replaceable>LOGIN</replaceable> name to <filename>/home</filename> and use " "that as the home directory. The base that is prepended before " "<replaceable>LOGIN</replaceable> is tunable with " "<quote>user_defaults/baseDirectory</quote> setting in sssd.conf." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_useradd.8.xml:82 sss_usermod.8.xml:66 sss_seed.8.xml:124 msgid "" "<option>-s</option>,<option>--shell</option> " "<replaceable>SHELL</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_useradd.8.xml:87 msgid "" "The user's login shell. The default is currently " "<filename>/bin/bash</filename>. The default can be changed with " "<quote>user_defaults/defaultShell</quote> setting in sssd.conf." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_useradd.8.xml:96 msgid "" "<option>-G</option>,<option>--groups</option> " "<replaceable>GROUPS</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_useradd.8.xml:101 msgid "A list of existing groups this user is also a member of." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_useradd.8.xml:107 msgid "<option>-m</option>,<option>--create-home</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_useradd.8.xml:111 msgid "" "Create the user's home directory if it does not exist. The files and " "directories contained in the skeleton directory (which can be defined with " "the -k option or in the config file) will be copied to the home directory." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_useradd.8.xml:121 msgid "<option>-M</option>,<option>--no-create-home</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_useradd.8.xml:125 msgid "Do not create the user's home directory. Overrides configuration settings." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_useradd.8.xml:132 msgid "" "<option>-k</option>,<option>--skel</option> " "<replaceable>SKELDIR</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_useradd.8.xml:137 msgid "" "The skeleton directory, which contains files and directories to be copied in " "the user's home directory, when the home directory is created by " "<command>sss_useradd</command>." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_useradd.8.xml:143 msgid "" "Special files (block devices, character devices, named pipes and unix " "sockets) will not be copied." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_useradd.8.xml:147 msgid "" "This option is only valid if the <option>-m</option> (or " "<option>--create-home</option>) option is specified, or creation of home " "directories is set to TRUE in the configuration." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_useradd.8.xml:156 sss_usermod.8.xml:124 msgid "" "<option>-Z</option>,<option>--selinux-user</option> " "<replaceable>SELINUX_USER</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_useradd.8.xml:161 msgid "" "The SELinux user for the user's login. If not specified, the system default " "will be used." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sssd-krb5.5.xml:10 sssd-krb5.5.xml:16 msgid "sssd-krb5" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sssd-krb5.5.xml:17 msgid "SSSD Kerberos provider" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-krb5.5.xml:23 msgid "" "This manual page describes the configuration of the Kerberos 5 " "authentication backend for <citerefentry> " "<refentrytitle>sssd</refentrytitle> <manvolnum>8</manvolnum> " "</citerefentry>. For a detailed syntax reference, please refer to the " "<quote>FILE FORMAT</quote> section of the <citerefentry> " "<refentrytitle>sssd.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> manual page." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-krb5.5.xml:36 msgid "" "The Kerberos 5 authentication backend contains auth and chpass providers. It " "must be paired with an identity provider in order to function properly (for " "example, id_provider = ldap). Some information required by the Kerberos 5 " "authentication backend must be provided by the identity provider, such as " "the user's Kerberos Principal Name (UPN). The configuration of the identity " "provider should have an entry to specify the UPN. Please refer to the man " "page for the applicable identity provider for details on how to configure " "this." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-krb5.5.xml:47 msgid "" "This backend also provides access control based on the .k5login file in the " "home directory of the user. See <citerefentry> " "<refentrytitle>.k5login</refentrytitle><manvolnum>5</manvolnum> " "</citerefentry> for more details. Please note that an empty .k5login file " "will deny all access to this user. To activate this feature, use " "'access_provider = krb5' in your SSSD configuration." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-krb5.5.xml:55 msgid "" "In the case where the UPN is not available in the identity backend, " "<command>sssd</command> will construct a UPN using the format " "<replaceable>username</replaceable>@<replaceable>krb5_realm</replaceable>." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:77 msgid "" "Specifies the comma-separated list of IP addresses or hostnames of the " "Kerberos servers to which SSSD should connect, in the order of " "preference. For more information on failover and server redundancy, see the " "<quote>FAILOVER</quote> section. An optional port number (preceded by a " "colon) may be appended to the addresses or hostnames. If empty, service " "discovery is enabled; for more information, refer to the <quote>SERVICE " "DISCOVERY</quote> section." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:106 msgid "" "The name of the Kerberos realm. This option is required and must be " "specified." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:113 msgid "krb5_kpasswd, krb5_backup_kpasswd (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:116 msgid "" "If the change password service is not running on the KDC, alternative " "servers can be defined here. An optional port number (preceded by a colon) " "may be appended to the addresses or hostnames." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:122 msgid "" "For more information on failover and server redundancy, see the " "<quote>FAILOVER</quote> section. NOTE: Even if there are no more kpasswd " "servers to try, the backend is not switched to operate offline if " "authentication against the KDC is still possible." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:129 msgid "Default: Use the KDC" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:135 msgid "krb5_ccachedir (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:138 msgid "" "Directory to store credential caches. All the substitution sequences of " "krb5_ccname_template can be used here, too, except %d and %P. The directory " "is created as private and owned by the user, with permissions set to 0700." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:145 msgid "Default: /tmp" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:151 msgid "krb5_ccname_template (string)" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:165 include/override_homedir.xml:11 msgid "%u" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:166 include/override_homedir.xml:12 msgid "login name" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:169 include/override_homedir.xml:15 msgid "%U" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:170 msgid "login UID" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:173 msgid "%p" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:174 msgid "principal name" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:178 msgid "%r" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:179 msgid "realm name" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:182 msgid "%h" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:183 sssd-ifp.5.xml:108 msgid "home directory" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:187 include/override_homedir.xml:19 msgid "%d" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:188 msgid "value of krb5_ccachedir" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:193 include/override_homedir.xml:27 msgid "%P" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:194 msgid "the process ID of the SSSD client" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:199 include/override_homedir.xml:45 msgid "%%" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:200 include/override_homedir.xml:46 msgid "a literal '%'" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:154 msgid "" "Location of the user's credential cache. Three credential cache types are " "currently supported: <quote>FILE</quote>, <quote>DIR</quote> and " "<quote>KEYRING:persistent</quote>. The cache can be specified either as " "<replaceable>TYPE:RESIDUAL</replaceable>, or as an absolute path, which " "implies the <quote>FILE</quote> type. In the template, the following " "sequences are substituted: <placeholder type=\"variablelist\" id=\"0\"/> If " "the template ends with 'XXXXXX' mkstemp(3) is used to create a unique " "filename in a safe way." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:208 msgid "" "When using KEYRING types, the only supported mechanism is " "<quote>KEYRING:persistent:%U</quote>, which uses the Linux kernel keyring to " "store credentials on a per-UID basis. This is also the recommended choice, " "as it is the most secure and predictable method." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:216 msgid "" "The default value for the credential cache name is sourced from the profile " "stored in the system wide krb5.conf configuration file in the [libdefaults] " "section. The option name is default_ccache_name. See krb5.conf(5)'s " "PARAMETER EXPANSION paragraph for additional information on the expansion " "format defined by krb5.conf." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:225 msgid "" "NOTE: Please be aware that libkrb5 ccache expansion template from " "<citerefentry> <refentrytitle>krb5.conf</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> uses different expansion sequences " "than SSSD." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:234 msgid "Default: (from libkrb5)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:240 msgid "krb5_auth_timeout (integer)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:243 msgid "" "Timeout in seconds after an online authentication request or change password " "request is aborted. If possible, the authentication request is continued " "offline." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:257 msgid "" "Verify with the help of krb5_keytab that the TGT obtained has not been " "spoofed. The keytab is checked for entries sequentially, and the first entry " "with a matching realm is used for validation. If no entry matches the realm, " "the last entry in the keytab is used. This process can be used to validate " "environments using cross-realm trust by placing the appropriate keytab entry " "as the last entry or the only entry in the keytab file." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:272 msgid "krb5_keytab (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:275 msgid "" "The location of the keytab to use when validating credentials obtained from " "KDCs." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:279 msgid "Default: /etc/krb5.keytab" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:285 msgid "krb5_store_password_if_offline (boolean)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:288 msgid "" "Store the password of the user if the provider is offline and use it to " "request a TGT when the provider comes online again." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:293 msgid "" "NOTE: this feature is only available on Linux. Passwords stored in this way " "are kept in plaintext in the kernel keyring and are potentially accessible " "by the root user (with difficulty)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:306 msgid "krb5_renewable_lifetime (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:309 msgid "" "Request a renewable ticket with a total lifetime, given as an integer " "immediately followed by a time unit:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:314 sssd-krb5.5.xml:348 sssd-krb5.5.xml:385 msgid "<emphasis>s</emphasis> for seconds" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:317 sssd-krb5.5.xml:351 sssd-krb5.5.xml:388 msgid "<emphasis>m</emphasis> for minutes" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:320 sssd-krb5.5.xml:354 sssd-krb5.5.xml:391 msgid "<emphasis>h</emphasis> for hours" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:323 sssd-krb5.5.xml:357 sssd-krb5.5.xml:394 msgid "<emphasis>d</emphasis> for days." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:326 sssd-krb5.5.xml:397 msgid "If there is no unit given, <emphasis>s</emphasis> is assumed." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:330 sssd-krb5.5.xml:401 msgid "" "NOTE: It is not possible to mix units. To set the renewable lifetime to one " "and a half hours, use '90m' instead of '1h30m'." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:335 msgid "Default: not set, i.e. the TGT is not renewable" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:341 msgid "krb5_lifetime (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:344 msgid "" "Request ticket with a lifetime, given as an integer immediately followed by " "a time unit:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:360 msgid "If there is no unit given <emphasis>s</emphasis> is assumed." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:364 msgid "" "NOTE: It is not possible to mix units. To set the lifetime to one and a " "half hours please use '90m' instead of '1h30m'." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:369 msgid "Default: not set, i.e. the default ticket lifetime configured on the KDC." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:376 msgid "krb5_renew_interval (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:379 msgid "" "The time in seconds between two checks if the TGT should be renewed. TGTs " "are renewed if about half of their lifetime is exceeded, given as an integer " "immediately followed by a time unit:" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:406 msgid "If this option is not set or is 0 the automatic renewal is disabled." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:424 msgid "" "<emphasis>never</emphasis> use FAST. This is equivalent to not setting this " "option at all." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:428 msgid "" "<emphasis>try</emphasis> to use FAST. If the server does not support FAST, " "continue the authentication without it." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:438 msgid "Default: not set, i.e. FAST is not used." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:441 msgid "NOTE: a keytab is required to use FAST." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:453 msgid "krb5_fast_principal (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:456 msgid "Specifies the server principal to use for FAST." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:465 msgid "" "Specifies if the host and user principal should be canonicalized. This " "feature is available with MIT Kerberos 1.7 and later versions." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:514 msgid "Default: false (AD provider: true)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><term> #: sssd-krb5.5.xml:520 msgid "krb5_map_user (string)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:523 msgid "" "The list of mappings is given as a comma-separated list of pairs " "<quote>username:primary</quote> where <quote>username</quote> is a UNIX user " "name and <quote>primary</quote> is a user part of a kerberos principal. This " "mapping is used when user is authenticating using <quote>auth_provider = " "krb5</quote>." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para><programlisting> #: sssd-krb5.5.xml:535 #, no-wrap msgid "" "krb5_realm = REALM\n" "krb5_map_user = joe:juser,dick:richard\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><variablelist><varlistentry><listitem><para> #: sssd-krb5.5.xml:540 msgid "" "<quote>joe</quote> and <quote>dick</quote> are UNIX user names and " "<quote>juser</quote> and <quote>richard</quote> are primaries of kerberos " "principals. For user <quote>joe</quote> resp. <quote>dick</quote> SSSD will " "try to kinit as <quote>juser@REALM</quote> resp. " "<quote>richard@REALM</quote>." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-krb5.5.xml:65 msgid "" "If the auth-module krb5 is used in an SSSD domain, the following options " "must be used. See the <citerefentry> " "<refentrytitle>sssd.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> manual page, section <quote>DOMAIN SECTIONS</quote>, for " "details on the configuration of an SSSD domain. <placeholder " "type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-krb5.5.xml:566 msgid "" "The following example assumes that SSSD is correctly configured and FOO is " "one of the domains in the <replaceable>[sssd]</replaceable> section. This " "example shows only configuration of Kerberos authentication; it does not " "include any identity provider." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sssd-krb5.5.xml:574 #, no-wrap msgid "" "[domain/FOO]\n" "auth_provider = krb5\n" "krb5_server = 192.168.1.1\n" "krb5_realm = EXAMPLE.COM\n" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_groupadd.8.xml:10 sss_groupadd.8.xml:15 msgid "sss_groupadd" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_groupadd.8.xml:16 msgid "create a new group" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_groupadd.8.xml:21 msgid "" "<command>sss_groupadd</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg " "choice='plain'><replaceable>GROUP</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_groupadd.8.xml:32 msgid "" "<command>sss_groupadd</command> creates a new group. These groups are " "compatible with POSIX groups, with the additional feature that they can " "contain other groups as members." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_groupadd.8.xml:43 sss_seed.8.xml:88 msgid "<option>-g</option>,<option>--gid</option> <replaceable>GID</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_groupadd.8.xml:48 msgid "" "Set the GID of the group to the value of <replaceable>GID</replaceable>. If " "not given, it is chosen automatically." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_userdel.8.xml:10 sss_userdel.8.xml:15 msgid "sss_userdel" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_userdel.8.xml:16 msgid "delete a user account" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_userdel.8.xml:21 msgid "" "<command>sss_userdel</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg " "choice='plain'><replaceable>LOGIN</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_userdel.8.xml:32 msgid "" "<command>sss_userdel</command> deletes a user identified by login name " "<replaceable>LOGIN</replaceable> from the system." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_userdel.8.xml:44 msgid "<option>-r</option>,<option>--remove</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_userdel.8.xml:48 msgid "" "Files in the user's home directory will be removed along with the home " "directory itself and the user's mail spool. Overrides the configuration." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_userdel.8.xml:56 msgid "<option>-R</option>,<option>--no-remove</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_userdel.8.xml:60 msgid "" "Files in the user's home directory will NOT be removed along with the home " "directory itself and the user's mail spool. Overrides the configuration." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_userdel.8.xml:68 msgid "<option>-f</option>,<option>--force</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_userdel.8.xml:72 msgid "" "This option forces <command>sss_userdel</command> to remove the user's home " "directory and mail spool, even if they are not owned by the specified user." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_userdel.8.xml:80 msgid "<option>-k</option>,<option>--kick</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_userdel.8.xml:84 msgid "Before actually deleting the user, terminate all his processes." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_groupdel.8.xml:10 sss_groupdel.8.xml:15 msgid "sss_groupdel" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_groupdel.8.xml:16 msgid "delete a group" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_groupdel.8.xml:21 msgid "" "<command>sss_groupdel</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg " "choice='plain'><replaceable>GROUP</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_groupdel.8.xml:32 msgid "" "<command>sss_groupdel</command> deletes a group identified by its name " "<replaceable>GROUP</replaceable> from the system." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_groupshow.8.xml:10 sss_groupshow.8.xml:15 msgid "sss_groupshow" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_groupshow.8.xml:16 msgid "print properties of a group" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_groupshow.8.xml:21 msgid "" "<command>sss_groupshow</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg " "choice='plain'><replaceable>GROUP</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_groupshow.8.xml:32 msgid "" "<command>sss_groupshow</command> displays information about a group " "identified by its name <replaceable>GROUP</replaceable>. The information " "includes the group ID number, members of the group and the parent group." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_groupshow.8.xml:43 msgid "<option>-R</option>,<option>--recursive</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_groupshow.8.xml:47 msgid "" "Also print indirect group members in a tree-like hierarchy. Note that this " "also affects printing parent groups - without <option>R</option>, only the " "direct parent will be printed." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_usermod.8.xml:10 sss_usermod.8.xml:15 msgid "sss_usermod" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_usermod.8.xml:16 msgid "modify a user account" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_usermod.8.xml:21 msgid "" "<command>sss_usermod</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg " "choice='plain'><replaceable>LOGIN</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_usermod.8.xml:32 msgid "" "<command>sss_usermod</command> modifies the account specified by " "<replaceable>LOGIN</replaceable> to reflect the changes that are specified " "on the command line." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_usermod.8.xml:60 msgid "The home directory of the user account." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_usermod.8.xml:71 msgid "The user's login shell." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_usermod.8.xml:82 msgid "" "Append this user to groups specified by the " "<replaceable>GROUPS</replaceable> parameter. The " "<replaceable>GROUPS</replaceable> parameter is a comma separated list of " "group names." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_usermod.8.xml:96 msgid "" "Remove this user from groups specified by the " "<replaceable>GROUPS</replaceable> parameter." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_usermod.8.xml:103 msgid "<option>-l</option>,<option>--lock</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_usermod.8.xml:107 msgid "Lock the user account. The user won't be able to log in." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_usermod.8.xml:114 msgid "<option>-u</option>,<option>--unlock</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_usermod.8.xml:118 msgid "Unlock the user account." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_usermod.8.xml:129 msgid "The SELinux user for the user's login." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_usermod.8.xml:135 msgid "<option>--addattr</option> <replaceable>ATTR_NAME_VAL</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_usermod.8.xml:140 msgid "Add an attribute/value pair. The format is attrname=value." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_usermod.8.xml:147 msgid "<option>--setattr</option> <replaceable>ATTR_NAME_VAL</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_usermod.8.xml:152 msgid "" "Set an attribute to a name/value pair. The format is attrname=value. For " "multi-valued attributes, the command replaces the values already present" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_usermod.8.xml:160 msgid "<option>--delattr</option> <replaceable>ATTR_NAME_VAL</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_usermod.8.xml:165 msgid "Delete an attribute/value pair. The format is attrname=value." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_cache.8.xml:10 sss_cache.8.xml:15 msgid "sss_cache" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_cache.8.xml:16 msgid "perform cache cleanup" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_cache.8.xml:21 msgid "" "<command>sss_cache</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_cache.8.xml:31 msgid "" "<command>sss_cache</command> invalidates records in SSSD cache. Invalidated " "records are forced to be reloaded from server as soon as related SSSD " "backend is online." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:42 msgid "<option>-E</option>,<option>--everything</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:46 msgid "Invalidate all cached entries except for sudo rules." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:52 msgid "<option>-u</option>,<option>--user</option> <replaceable>login</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:57 msgid "Invalidate specific user." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:63 msgid "<option>-U</option>,<option>--users</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:67 msgid "" "Invalidate all user records. This option overrides invalidation of specific " "user if it was also set." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:74 msgid "" "<option>-g</option>,<option>--group</option> " "<replaceable>group</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:79 msgid "Invalidate specific group." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:85 msgid "<option>-G</option>,<option>--groups</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:89 msgid "" "Invalidate all group records. This option overrides invalidation of specific " "group if it was also set." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:96 msgid "" "<option>-n</option>,<option>--netgroup</option> " "<replaceable>netgroup</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:101 msgid "Invalidate specific netgroup." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:107 msgid "<option>-N</option>,<option>--netgroups</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:111 msgid "" "Invalidate all netgroup records. This option overrides invalidation of " "specific netgroup if it was also set." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:118 msgid "" "<option>-s</option>,<option>--service</option> " "<replaceable>service</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:123 msgid "Invalidate specific service." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:129 msgid "<option>-S</option>,<option>--services</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:133 msgid "" "Invalidate all service records. This option overrides invalidation of " "specific service if it was also set." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:140 msgid "" "<option>-a</option>,<option>--autofs-map</option> " "<replaceable>autofs-map</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:145 msgid "Invalidate specific autofs maps." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:151 msgid "<option>-A</option>,<option>--autofs-maps</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:155 msgid "" "Invalidate all autofs maps. This option overrides invalidation of specific " "map if it was also set." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:162 msgid "" "<option>-h</option>,<option>--ssh-host</option> " "<replaceable>hostname</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:167 msgid "Invalidate SSH public keys of a specific host." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:173 msgid "<option>-H</option>,<option>--ssh-hosts</option>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:177 msgid "" "Invalidate SSH public keys of all hosts. This option overrides invalidation " "of SSH public keys of specific host if it was also set." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_cache.8.xml:185 msgid "" "<option>-d</option>,<option>--domain</option> " "<replaceable>domain</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_cache.8.xml:190 msgid "Restrict invalidation process only to a particular domain." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_debuglevel.8.xml:10 sss_debuglevel.8.xml:15 msgid "sss_debuglevel" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_debuglevel.8.xml:16 msgid "change debug level while SSSD is running" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_debuglevel.8.xml:21 msgid "" "<command>sss_debuglevel</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg " "choice='plain'><replaceable>NEW_DEBUG_LEVEL</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_debuglevel.8.xml:32 msgid "" "<command>sss_debuglevel</command> changes debug level of SSSD monitor and " "providers to <replaceable>NEW_DEBUG_LEVEL</replaceable> while SSSD is " "running." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_debuglevel.8.xml:59 msgid "<replaceable>NEW_DEBUG_LEVEL</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_seed.8.xml:10 sss_seed.8.xml:15 msgid "sss_seed" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_seed.8.xml:16 msgid "seed the SSSD cache with a user" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_seed.8.xml:21 msgid "" "<command>sss_seed</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg choice='plain'>-D " "<replaceable>DOMAIN</replaceable></arg> <arg choice='plain'>-n " "<replaceable>USER</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_seed.8.xml:33 msgid "" "<command>sss_seed</command> seeds the SSSD cache with a user entry and " "temporary password. If a user entry is already present in the SSSD cache " "then the entry is updated with the temporary password." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_seed.8.xml:46 msgid "" "<option>-D</option>,<option>--domain</option> " "<replaceable>DOMAIN</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_seed.8.xml:51 msgid "" "Provide the name of the domain in which the user is a member of. The domain " "is also used to retrieve user information. The domain must be configured in " "sssd.conf. The <replaceable>DOMAIN</replaceable> option must be provided. " "Information retrieved from the domain overrides what is provided in the " "options." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_seed.8.xml:63 msgid "" "<option>-n</option>,<option>--username</option> " "<replaceable>USER</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_seed.8.xml:68 msgid "" "The username of the entry to be created or modified in the cache. The " "<replaceable>USER</replaceable> option must be provided." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_seed.8.xml:81 msgid "Set the UID of the user to <replaceable>UID</replaceable>." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_seed.8.xml:93 msgid "Set the GID of the user to <replaceable>GID</replaceable>." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_seed.8.xml:117 msgid "Set the home directory of the user to <replaceable>HOME_DIR</replaceable>." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_seed.8.xml:129 msgid "Set the login shell of the user to <replaceable>SHELL</replaceable>." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_seed.8.xml:140 msgid "" "Interactive mode for entering user information. This option will only prompt " "for information not provided in the options or retrieved from the domain." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_seed.8.xml:148 msgid "" "<option>-p</option>,<option>--password-file</option> " "<replaceable>PASS_FILE</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_seed.8.xml:153 msgid "" "Specify file to read user's password from. (if not specified password is " "prompted for)" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_seed.8.xml:165 msgid "" "The length of the password (or the size of file specified with -p or " "--password-file option) must be less than or equal to PASS_MAX bytes (64 " "bytes on systems with no globally-defined PASS_MAX value)." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sssd-ifp.5.xml:10 sssd-ifp.5.xml:16 msgid "sssd-ifp" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sssd-ifp.5.xml:17 msgid "SSSD InfoPipe responder" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ifp.5.xml:23 msgid "" "This manual page describes the configuration of the InfoPipe responder for " "<citerefentry> <refentrytitle>sssd</refentrytitle> <manvolnum>8</manvolnum> " "</citerefentry>. For a detailed syntax reference, refer to the <quote>FILE " "FORMAT</quote> section of the <citerefentry> " "<refentrytitle>sssd.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> manual page." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ifp.5.xml:36 msgid "" "The InfoPipe responder provides a public D-Bus interface accessible over the " "system bus. The interface allows the user to query information about remote " "users and groups over the system bus." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sssd-ifp.5.xml:46 msgid "These options can be used to configure the InfoPipe responder." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:53 msgid "" "Specifies the comma-separated list of UID values or user names that are " "allowed to access the InfoPipe responder. User names are resolved to UIDs at " "startup." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:59 msgid "Default: 0 (only the root user is allowed to access the InfoPipe responder)" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:63 msgid "" "Please note that although the UID 0 is used as the default it will be " "overwritten with this option. If you still want to allow the root user to " "access the InfoPipe responder, which would be the typical case, you have to " "add 0 to the list of allowed UIDs as well." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:77 msgid "Specifies the comma-separated list of white or blacklisted attributes." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-ifp.5.xml:91 msgid "name" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:92 msgid "user's login name" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-ifp.5.xml:95 msgid "uidNumber" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:96 msgid "user ID" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-ifp.5.xml:99 msgid "gidNumber" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:100 msgid "primary group ID" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-ifp.5.xml:103 msgid "gecos" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:104 msgid "user information, typically full name" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-ifp.5.xml:107 msgid "homeDirectory" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><term> #: sssd-ifp.5.xml:111 msgid "loginShell" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:112 msgid "user shell" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:81 msgid "" "By default, the InfoPipe responder only allows the default set of POSIX " "attributes to be requested. This set is the same as returned by " "<citerefentry> <refentrytitle>getpwnam</refentrytitle> " "<manvolnum>3</manvolnum> </citerefentry> and includes: <placeholder " "type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para><programlisting> #: sssd-ifp.5.xml:125 #, no-wrap msgid "" "user_attributes = +telephoneNumber, -loginShell\n" " " msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:117 msgid "" "It is possible to add another attribute to this set by using " "<quote>+attr_name</quote> or explicitly remove an attribute using " "<quote>-attr_name</quote>. For example, to allow " "<quote>telephoneNumber</quote> but deny <quote>loginShell</quote>, you would " "use the following configuration: <placeholder type=\"programlisting\" " "id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:129 msgid "Default: not set. Only the default set of POSIX attributes is allowed." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:139 msgid "" "Specifies an upper limit on the number of entries that are downloaded during " "a wildcard lookup that overrides caller-supplied limit." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sssd-ifp.5.xml:144 msgid "Default: 0 (let the caller set an upper limit)" msgstr "" #. type: Content of: <reference><refentry><refentryinfo> #: sss_rpcidmapd.5.xml:8 msgid "" "<productname>sss rpc.idmapd plugin</productname> <author> " "<firstname>Noam</firstname> <surname>Meltzer</surname> <affiliation> " "<orgname>Primary Data Inc.</orgname> </affiliation> <contrib>Developer " "(2013-2014)</contrib> </author> <author> <firstname>Noam</firstname> " "<surname>Meltzer</surname> <contrib>Developer (2014-)</contrib> " "<email>tsnoam@gmail.com</email> </author>" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_rpcidmapd.5.xml:26 sss_rpcidmapd.5.xml:32 msgid "sss_rpcidmapd" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_rpcidmapd.5.xml:33 msgid "sss plugin configuration directives for rpc.idmapd" msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sss_rpcidmapd.5.xml:37 msgid "CONFIGURATION FILE" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_rpcidmapd.5.xml:39 msgid "" "rpc.idmapd configuration file is usually found at " "<emphasis>/etc/idmapd.conf</emphasis>. See <citerefentry> " "<refentrytitle>idmapd.conf</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry> for more information." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sss_rpcidmapd.5.xml:49 msgid "SSS CONFIGURATION EXTENSION" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sss_rpcidmapd.5.xml:51 msgid "Enable SSS plugin" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sss_rpcidmapd.5.xml:53 msgid "" "In section <quote>[Translation]</quote>, modify/set <quote>Method</quote> " "attribute to contain <emphasis>sss</emphasis>." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><title> #: sss_rpcidmapd.5.xml:59 msgid "[sss] config section" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><para> #: sss_rpcidmapd.5.xml:61 msgid "" "In order to change the default of one of the configuration attributes of the " "<emphasis>sss</emphasis> plugin listed below you will need to create a " "config section for it, named <quote>[sss]</quote>." msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><title> #: sss_rpcidmapd.5.xml:67 msgid "Configuration attributes" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><term> #: sss_rpcidmapd.5.xml:69 msgid "memcache (bool)" msgstr "" #. type: Content of: <reference><refentry><refsect1><refsect2><variablelist><varlistentry><listitem><para> #: sss_rpcidmapd.5.xml:72 msgid "Indicates whether or not to use memcache optimisation technique." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sss_rpcidmapd.5.xml:85 msgid "SSSD INTEGRATION" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_rpcidmapd.5.xml:87 msgid "" "The sss plugin requires the <emphasis>NSS Responder</emphasis> to be enabled " "in sssd." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_rpcidmapd.5.xml:91 msgid "" "The attribute <quote>use_fully_qualified_names</quote> must be enabled on " "all domains (NFSv4 clients expect a fully qualified name to be sent on the " "wire)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sss_rpcidmapd.5.xml:103 #, no-wrap msgid "" "[General]\n" "Verbosity = 2\n" "# domain must be synced between NFSv4 server and clients\n" "# Solaris/Illumos/AIX use \"localdomain\" as default!\n" "Domain = default\n" "\n" "[Mapping]\n" "Nobody-User = nfsnobody\n" "Nobody-Group = nfsnobody\n" "\n" "[Translation]\n" "Method = sss\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_rpcidmapd.5.xml:100 msgid "" "The following example shows a minimal idmapd.conf which makes use of the sss " "plugin. <placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <refsect1><title> #: sss_rpcidmapd.5.xml:120 include/seealso.xml:2 msgid "SEE ALSO" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_rpcidmapd.5.xml:122 msgid "" "<citerefentry> <refentrytitle>sssd</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> <refentrytitle>idmapd.conf</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry>" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_ssh_authorizedkeys.1.xml:10 sss_ssh_authorizedkeys.1.xml:15 msgid "sss_ssh_authorizedkeys" msgstr "" #. type: Content of: <reference><refentry><refmeta><manvolnum> #: sss_ssh_authorizedkeys.1.xml:11 sss_ssh_knownhostsproxy.1.xml:11 msgid "1" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_ssh_authorizedkeys.1.xml:16 msgid "get OpenSSH authorized keys" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_ssh_authorizedkeys.1.xml:21 msgid "" "<command>sss_ssh_authorizedkeys</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg " "choice='plain'><replaceable>USER</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_ssh_authorizedkeys.1.xml:32 msgid "" "<command>sss_ssh_authorizedkeys</command> acquires SSH public keys for user " "<replaceable>USER</replaceable> and outputs them in OpenSSH authorized_keys " "format (see the <quote>AUTHORIZED_KEYS FILE FORMAT</quote> section of " "<citerefentry><refentrytitle>sshd</refentrytitle> " "<manvolnum>8</manvolnum></citerefentry> for more information)." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_ssh_authorizedkeys.1.xml:41 msgid "" "<citerefentry><refentrytitle>sshd</refentrytitle> " "<manvolnum>8</manvolnum></citerefentry> can be configured to use " "<command>sss_ssh_authorizedkeys</command> for public key user authentication " "if it is compiled with support for either " "<quote>AuthorizedKeysCommand</quote> or <quote>PubkeyAgent</quote> " "<citerefentry> <refentrytitle>sshd_config</refentrytitle> " "<manvolnum>5</manvolnum></citerefentry> options." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sss_ssh_authorizedkeys.1.xml:58 #, no-wrap msgid "" " AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys\n" " AuthorizedKeysCommandUser nobody\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_ssh_authorizedkeys.1.xml:51 msgid "" "If <quote>AuthorizedKeysCommand</quote> is supported, " "<citerefentry><refentrytitle>sshd</refentrytitle> " "<manvolnum>8</manvolnum></citerefentry> can be configured to use it by " "putting the following directives in <citerefentry> " "<refentrytitle>sshd_config</refentrytitle> " "<manvolnum>5</manvolnum></citerefentry>: <placeholder " "type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sss_ssh_authorizedkeys.1.xml:70 #, no-wrap msgid "PubKeyAgent /usr/bin/sss_ssh_authorizedkeys %u\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_ssh_authorizedkeys.1.xml:63 msgid "" "If <quote>PubkeyAgent</quote> is supported, " "<citerefentry><refentrytitle>sshd</refentrytitle> " "<manvolnum>8</manvolnum></citerefentry> can be configured to use it by using " "the following directive for <citerefentry> " "<refentrytitle>sshd</refentrytitle> <manvolnum>8</manvolnum></citerefentry> " "configuration: <placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_ssh_authorizedkeys.1.xml:85 msgid "" "Search for user public keys in SSSD domain " "<replaceable>DOMAIN</replaceable>." msgstr "" #. type: Content of: <reference><refentry><refsect1><title> #: sss_ssh_authorizedkeys.1.xml:94 sss_ssh_knownhostsproxy.1.xml:92 msgid "EXIT STATUS" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_ssh_authorizedkeys.1.xml:96 sss_ssh_knownhostsproxy.1.xml:94 msgid "" "In case of success, an exit value of 0 is returned. Otherwise, 1 is " "returned." msgstr "" #. type: Content of: <reference><refentry><refnamediv><refname> #: sss_ssh_knownhostsproxy.1.xml:10 sss_ssh_knownhostsproxy.1.xml:15 msgid "sss_ssh_knownhostsproxy" msgstr "" #. type: Content of: <reference><refentry><refnamediv><refpurpose> #: sss_ssh_knownhostsproxy.1.xml:16 msgid "get OpenSSH host keys" msgstr "" #. type: Content of: <reference><refentry><refsynopsisdiv><cmdsynopsis> #: sss_ssh_knownhostsproxy.1.xml:21 msgid "" "<command>sss_ssh_knownhostsproxy</command> <arg choice='opt'> " "<replaceable>options</replaceable> </arg> <arg " "choice='plain'><replaceable>HOST</replaceable></arg> <arg " "choice='opt'><replaceable>PROXY_COMMAND</replaceable></arg>" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_ssh_knownhostsproxy.1.xml:33 msgid "" "<command>sss_ssh_knownhostsproxy</command> acquires SSH host public keys for " "host <replaceable>HOST</replaceable>, stores them in a custom OpenSSH " "known_hosts file (see the <quote>SSH_KNOWN_HOSTS FILE FORMAT</quote> section " "of <citerefentry><refentrytitle>sshd</refentrytitle> " "<manvolnum>8</manvolnum></citerefentry> for more information) " "<filename>/var/lib/sss/pubconf/known_hosts</filename> and estabilishes " "connection to the host." msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_ssh_knownhostsproxy.1.xml:43 msgid "" "If <replaceable>PROXY_COMMAND</replaceable> is specified, it is used to " "create the connection to the host instead of opening a socket." msgstr "" #. type: Content of: <reference><refentry><refsect1><para><programlisting> #: sss_ssh_knownhostsproxy.1.xml:55 #, no-wrap msgid "" "ProxyCommand /usr/bin/sss_ssh_knownhostsproxy -p %p %h\n" "GlobalKnownHostsFile /var/lib/sss/pubconf/known_hosts\n" msgstr "" #. type: Content of: <reference><refentry><refsect1><para> #: sss_ssh_knownhostsproxy.1.xml:48 msgid "" "<citerefentry><refentrytitle>ssh</refentrytitle> " "<manvolnum>1</manvolnum></citerefentry> can be configured to use " "<command>sss_ssh_knownhostsproxy</command> for host key authentication by " "using the following directives for " "<citerefentry><refentrytitle>ssh</refentrytitle> " "<manvolnum>1</manvolnum></citerefentry> configuration: <placeholder " "type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><term> #: sss_ssh_knownhostsproxy.1.xml:66 msgid "<option>-p</option>,<option>--port</option> <replaceable>PORT</replaceable>" msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_ssh_knownhostsproxy.1.xml:71 msgid "" "Use port <replaceable>PORT</replaceable> to connect to the host. By " "default, port 22 is used." msgstr "" #. type: Content of: <reference><refentry><refsect1><variablelist><varlistentry><listitem><para> #: sss_ssh_knownhostsproxy.1.xml:83 msgid "" "Search for host public keys in SSSD domain " "<replaceable>DOMAIN</replaceable>." msgstr "" #. type: Content of: <refsect1><title> #: include/service_discovery.xml:2 msgid "SERVICE DISCOVERY" msgstr "" #. type: Content of: <refsect1><para> #: include/service_discovery.xml:4 msgid "" "The service discovery feature allows back ends to automatically find the " "appropriate servers to connect to using a special DNS query. This feature is " "not supported for backup servers." msgstr "" #. type: Content of: <refsect1><refsect2><title> #: include/service_discovery.xml:9 include/ldap_id_mapping.xml:99 msgid "Configuration" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/service_discovery.xml:11 msgid "" "If no servers are specified, the back end automatically uses service " "discovery to try to find a server. Optionally, the user may choose to use " "both fixed server addresses and service discovery by inserting a special " "keyword, <quote>_srv_</quote>, in the list of servers. The order of " "preference is maintained. This feature is useful if, for example, the user " "prefers to use service discovery whenever possible, and fall back to a " "specific server when no servers can be discovered using DNS." msgstr "" #. type: Content of: <refsect1><refsect2><title> #: include/service_discovery.xml:23 msgid "The domain name" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/service_discovery.xml:25 msgid "" "Please refer to the <quote>dns_discovery_domain</quote> parameter in the " "<citerefentry> <refentrytitle>sssd.conf</refentrytitle> " "<manvolnum>5</manvolnum> </citerefentry> manual page for more details." msgstr "" #. type: Content of: <refsect1><refsect2><title> #: include/service_discovery.xml:35 msgid "The protocol" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/service_discovery.xml:37 msgid "" "The queries usually specify _tcp as the protocol. Exceptions are documented " "in respective option description." msgstr "" #. type: Content of: <refsect1><refsect2><title> #: include/service_discovery.xml:42 msgid "See Also" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/service_discovery.xml:44 msgid "For more information on the service discovery mechanism, refer to RFC 2782." msgstr "" #. type: Content of: outside any tag (error?) #: include/upstream.xml:1 msgid "<placeholder type=\"refentryinfo\" id=\"0\"/>" msgstr "" #. type: Content of: <refsect1><title> #: include/failover.xml:2 msgid "FAILOVER" msgstr "" #. type: Content of: <refsect1><para> #: include/failover.xml:4 msgid "" "The failover feature allows back ends to automatically switch to a different " "server if the current server fails." msgstr "" #. type: Content of: <refsect1><refsect2><title> #: include/failover.xml:8 msgid "Failover Syntax" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/failover.xml:10 msgid "" "The list of servers is given as a comma-separated list; any number of spaces " "is allowed around the comma. The servers are listed in order of " "preference. The list can contain any number of servers." msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/failover.xml:16 msgid "" "For each failover-enabled config option, two variants exist: " "<emphasis>primary</emphasis> and <emphasis>backup</emphasis>. The idea is " "that servers in the primary list are preferred and backup servers are only " "searched if no primary servers can be reached. If a backup server is " "selected, a timeout of 31 seconds is set. After this timeout SSSD will " "periodically try to reconnect to one of the primary servers. If it succeeds, " "it will replace the current active (backup) server." msgstr "" #. type: Content of: <refsect1><refsect2><title> #: include/failover.xml:27 msgid "The Failover Mechanism" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/failover.xml:29 msgid "" "The failover mechanism distinguishes between a machine and a service. The " "back end first tries to resolve the hostname of a given machine; if this " "resolution attempt fails, the machine is considered offline. No further " "attempts are made to connect to this machine for any other service. If the " "resolution attempt succeeds, the back end tries to connect to a service on " "this machine. If the service connection attempt fails, then only this " "particular service is considered offline and the back end automatically " "switches over to the next service. The machine is still considered online " "and might still be tried for another service." msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/failover.xml:42 msgid "" "Further connection attempts are made to machines or services marked as " "offline after a specified period of time; this is currently hard coded to 30 " "seconds." msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/failover.xml:47 msgid "" "If there are no more machines to try, the back end as a whole switches to " "offline mode, and then attempts to reconnect every 30 seconds." msgstr "" #. type: Content of: <refsect1><title> #: include/ldap_id_mapping.xml:2 msgid "ID MAPPING" msgstr "" #. type: Content of: <refsect1><para> #: include/ldap_id_mapping.xml:4 msgid "" "The ID-mapping feature allows SSSD to act as a client of Active Directory " "without requiring administrators to extend user attributes to support POSIX " "attributes for user and group identifiers." msgstr "" #. type: Content of: <refsect1><para> #: include/ldap_id_mapping.xml:9 msgid "" "NOTE: When ID-mapping is enabled, the uidNumber and gidNumber attributes are " "ignored. This is to avoid the possibility of conflicts between " "automatically-assigned and manually-assigned values. If you need to use " "manually-assigned values, ALL values must be manually-assigned." msgstr "" #. type: Content of: <refsect1><para> #: include/ldap_id_mapping.xml:16 msgid "" "Please note that changing the ID mapping related configuration options will " "cause user and group IDs to change. At the moment, SSSD does not support " "changing IDs, so the SSSD database must be removed. Because cached passwords " "are also stored in the database, removing the database should only be " "performed while the authentication servers are reachable, otherwise users " "might get locked out. In order to cache the password, an authentication must " "be performed. It is not sufficient to use <citerefentry> " "<refentrytitle>sss_cache</refentrytitle> <manvolnum>8</manvolnum> " "</citerefentry> to remove the database, rather the process consists of:" msgstr "" #. type: Content of: <refsect1><para><itemizedlist><listitem><para> #: include/ldap_id_mapping.xml:33 msgid "Making sure the remote servers are reachable" msgstr "" #. type: Content of: <refsect1><para><itemizedlist><listitem><para> #: include/ldap_id_mapping.xml:38 msgid "Stopping the SSSD service" msgstr "" #. type: Content of: <refsect1><para><itemizedlist><listitem><para> #: include/ldap_id_mapping.xml:43 msgid "Removing the database" msgstr "" #. type: Content of: <refsect1><para><itemizedlist><listitem><para> #: include/ldap_id_mapping.xml:48 msgid "Starting the SSSD service" msgstr "" #. type: Content of: <refsect1><para> #: include/ldap_id_mapping.xml:52 msgid "" "Moreover, as the change of IDs might necessitate the adjustment of other " "system properties such as file and directory ownership, it's advisable to " "plan ahead and test the ID mapping configuration thoroughly." msgstr "" #. type: Content of: <refsect1><refsect2><title> #: include/ldap_id_mapping.xml:59 msgid "Mapping Algorithm" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/ldap_id_mapping.xml:61 msgid "" "Active Directory provides an objectSID for every user and group object in " "the directory. This objectSID can be broken up into components that " "represent the Active Directory domain identity and the relative identifier " "(RID) of the user or group object." msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/ldap_id_mapping.xml:67 msgid "" "The SSSD ID-mapping algorithm takes a range of available UIDs and divides it " "into equally-sized component sections - called \"slices\"-. Each slice " "represents the space available to an Active Directory domain." msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/ldap_id_mapping.xml:73 msgid "" "When a user or group entry for a particular domain is encountered for the " "first time, the SSSD allocates one of the available slices for that " "domain. In order to make this slice-assignment repeatable on different " "client machines, we select the slice based on the following algorithm:" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/ldap_id_mapping.xml:80 msgid "" "The SID string is passed through the murmurhash3 algorithm to convert it to " "a 32-bit hashed value. We then take the modulus of this value with the total " "number of available slices to pick the slice." msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/ldap_id_mapping.xml:86 msgid "" "NOTE: It is possible to encounter collisions in the hash and subsequent " "modulus. In these situations, we will select the next available slice, but " "it may not be possible to reproduce the same exact set of slices on other " "machines (since the order that they are encountered will determine their " "slice). In this situation, it is recommended to either switch to using " "explicit POSIX attributes in Active Directory (disabling ID-mapping) or " "configure a default domain to guarantee that at least one is always " "consistent. See <quote>Configuration</quote> for details." msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/ldap_id_mapping.xml:101 msgid "Minimum configuration (in the <quote>[domain/DOMAINNAME]</quote> section):" msgstr "" #. type: Content of: <refsect1><refsect2><para><programlisting> #: include/ldap_id_mapping.xml:106 #, no-wrap msgid "" "ldap_id_mapping = True\n" "ldap_schema = ad\n" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/ldap_id_mapping.xml:111 msgid "" "The default configuration results in configuring 10,000 slices, each capable " "of holding up to 200,000 IDs, starting from 10,001 and going up to " "2,000,100,000. This should be sufficient for most deployments." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><title> #: include/ldap_id_mapping.xml:117 msgid "Advanced Configuration" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><term> #: include/ldap_id_mapping.xml:120 msgid "ldap_idmap_range_min (integer)" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:123 msgid "" "Specifies the lower bound of the range of POSIX IDs to use for mapping " "Active Directory user and group SIDs." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:127 msgid "" "NOTE: This option is different from <quote>min_id</quote> in that " "<quote>min_id</quote> acts to filter the output of requests to this domain, " "whereas this option controls the range of ID assignment. This is a subtle " "distinction, but the good general advice would be to have " "<quote>min_id</quote> be less-than or equal to " "<quote>ldap_idmap_range_min</quote>" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:137 include/ldap_id_mapping.xml:191 msgid "Default: 200000" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><term> #: include/ldap_id_mapping.xml:142 msgid "ldap_idmap_range_max (integer)" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:145 msgid "" "Specifies the upper bound of the range of POSIX IDs to use for mapping " "Active Directory user and group SIDs." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:149 msgid "" "NOTE: This option is different from <quote>max_id</quote> in that " "<quote>max_id</quote> acts to filter the output of requests to this domain, " "whereas this option controls the range of ID assignment. This is a subtle " "distinction, but the good general advice would be to have " "<quote>max_id</quote> be greater-than or equal to " "<quote>ldap_idmap_range_max</quote>" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:159 msgid "Default: 2000200000" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><term> #: include/ldap_id_mapping.xml:164 msgid "ldap_idmap_range_size (integer)" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:167 msgid "" "Specifies the number of IDs available for each slice. If the range size " "does not divide evenly into the min and max values, it will create as many " "complete slices as it can." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:173 msgid "" "NOTE: The value of this option must be at least as large as the highest user " "RID planned for use on the Active Directory server. User lookups and login " "will fail for any user whose RID is greater than this value." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:179 msgid "" "For example, if your most recently-added Active Directory user has " "objectSid=S-1-5-21-2153326666-2176343378-3404031434-1107, " "<quote>ldap_idmap_range_size</quote> must be at least 1108 as range size is " "equal to maximal SID minus minimal SID plus one (e.g. 1108 = 1107 - 0 + 1)." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:186 msgid "" "It is important to plan ahead for future expansion, as changing this value " "will result in changing all of the ID mappings on the system, leading to " "users with different local IDs than they previously had." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><term> #: include/ldap_id_mapping.xml:196 msgid "ldap_idmap_default_domain_sid (string)" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:199 msgid "" "Specify the domain SID of the default domain. This will guarantee that this " "domain will always be assigned to slice zero in the ID map, bypassing the " "murmurhash algorithm described above." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><term> #: include/ldap_id_mapping.xml:210 msgid "ldap_idmap_default_domain (string)" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:213 msgid "Specify the name of the default domain." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><term> #: include/ldap_id_mapping.xml:221 msgid "ldap_idmap_autorid_compat (boolean)" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:224 msgid "" "Changes the behavior of the ID-mapping algorithm to behave more similarly to " "winbind's <quote>idmap_autorid</quote> algorithm." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:229 msgid "" "When this option is configured, domains will be allocated starting with " "slice zero and increasing monatomically with each additional domain." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:234 msgid "" "NOTE: This algorithm is non-deterministic (it depends on the order that " "users and groups are requested). If this mode is required for compatibility " "with machines running winbind, it is recommended to also use the " "<quote>ldap_idmap_default_domain_sid</quote> option to guarantee that at " "least one domain is consistently allocated to slice zero." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><term> #: include/ldap_id_mapping.xml:249 msgid "ldap_idmap_helper_table_size (integer)" msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:252 msgid "" "Maximal number of secondary slices that is tried when performing mapping " "from UNIX id to SID." msgstr "" #. type: Content of: <refsect1><refsect2><refsect3><variablelist><varlistentry><listitem><para> #: include/ldap_id_mapping.xml:256 msgid "" "Note: Additional secondary slices might be generated when SID is being " "mapped to UNIX id and RID part of SID is out of range for secondary slices " "generated so far. If value of ldap_idmap_helper_table_size is equal to 0 " "then no additional secondary slices are generated." msgstr "" #. type: Content of: <refsect1><refsect2><title> #: include/ldap_id_mapping.xml:273 msgid "Well-Known SIDs" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/ldap_id_mapping.xml:275 msgid "" "SSSD supports to look up the names of Well-Known SIDs, i.e. SIDs with a " "special hardcoded meaning. Since the generic users and groups related to " "those Well-Known SIDs have no equivalent in a Linux/UNIX environment no " "POSIX IDs are available for those objects." msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/ldap_id_mapping.xml:281 msgid "" "The SID name space is organized in authorities which can be seen as " "different domains. The authorities for the Well-Known SIDs are" msgstr "" #. type: Content of: <refsect1><refsect2><para><itemizedlist><listitem><para> #: include/ldap_id_mapping.xml:284 msgid "Null Authority" msgstr "" #. type: Content of: <refsect1><refsect2><para><itemizedlist><listitem><para> #: include/ldap_id_mapping.xml:285 msgid "World Authority" msgstr "" #. type: Content of: <refsect1><refsect2><para><itemizedlist><listitem><para> #: include/ldap_id_mapping.xml:286 msgid "Local Authority" msgstr "" #. type: Content of: <refsect1><refsect2><para><itemizedlist><listitem><para> #: include/ldap_id_mapping.xml:287 msgid "Creator Authority" msgstr "" #. type: Content of: <refsect1><refsect2><para><itemizedlist><listitem><para> #: include/ldap_id_mapping.xml:288 msgid "NT Authority" msgstr "" #. type: Content of: <refsect1><refsect2><para><itemizedlist><listitem><para> #: include/ldap_id_mapping.xml:289 msgid "Built-in" msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/ldap_id_mapping.xml:291 msgid "" "The capitalized version of these names are used as domain names when " "returning the fully qualified name of a Well-Known SID." msgstr "" #. type: Content of: <refsect1><refsect2><para> #: include/ldap_id_mapping.xml:295 msgid "" "Since some utilities allow to modify SID based access control information " "with the help of a name instead of using the SID directly SSSD supports to " "look up the SID by the name as well. To avoid collisions only the fully " "qualified names can be used to look up Well-Known SIDs. As a result the " "domain names <quote>NULL AUTHORITY</quote>, <quote>WORLD AUTHORITY</quote>, " "<quote> LOCAL AUTHORITY</quote>, <quote>CREATOR AUTHORITY</quote>, <quote>NT " "AUTHORITY</quote> and <quote>BUILTIN</quote> should not be used as domain " "names in <filename>sssd.conf</filename>." msgstr "" #. type: Content of: <varlistentry><term> #: include/param_help.xml:3 msgid "<option>-?</option>,<option>--help</option>" msgstr "" #. type: Content of: <varlistentry><listitem><para> #: include/param_help.xml:7 include/param_help_py.xml:7 msgid "Display help message and exit." msgstr "" #. type: Content of: <varlistentry><term> #: include/param_help_py.xml:3 msgid "<option>-h</option>,<option>--help</option>" msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:3 msgid "" "SSSD supports two representations for specifying the debug level. The " "simplest is to specify a decimal value from 0-9, which represents enabling " "that level and all lower-level debug messages. The more comprehensive option " "is to specify a hexadecimal bitmask to enable or disable specific levels " "(such as if you wish to suppress a level)." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:10 msgid "" "Please note that each SSSD service logs into its own log file. Also please " "note that enabling <quote>debug_level</quote> in the <quote>[sssd]</quote> " "section only enables debugging just for the sssd process itself, not for the " "responder or provider processes. The <quote>debug_level</quote> parameter " "should be added to all sections that you wish to produce debug logs from." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:18 msgid "" "In addition to changing the log level in the config file using the " "<quote>debug_level</quote> parameter, which is persistent, but requires SSSD " "restart, it is also possible to change the debug level on the fly using the " "<citerefentry> <refentrytitle>sss_debuglevel</refentrytitle> " "<manvolnum>8</manvolnum> </citerefentry> tool." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:29 msgid "Currently supported debug levels:" msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:32 msgid "" "<emphasis>0</emphasis>, <emphasis>0x0010</emphasis>: Fatal " "failures. Anything that would prevent SSSD from starting up or causes it to " "cease running." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:38 msgid "" "<emphasis>1</emphasis>, <emphasis>0x0020</emphasis>: Critical failures. An " "error that doesn't kill the SSSD, but one that indicates that at least one " "major feature is not going to work properly." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:45 msgid "" "<emphasis>2</emphasis>, <emphasis>0x0040</emphasis>: Serious failures. An " "error announcing that a particular request or operation has failed." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:50 msgid "" "<emphasis>3</emphasis>, <emphasis>0x0080</emphasis>: Minor failures. These " "are the errors that would percolate down to cause the operation failure of " "2." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:55 msgid "<emphasis>4</emphasis>, <emphasis>0x0100</emphasis>: Configuration settings." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:59 msgid "<emphasis>5</emphasis>, <emphasis>0x0200</emphasis>: Function data." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:63 msgid "" "<emphasis>6</emphasis>, <emphasis>0x0400</emphasis>: Trace messages for " "operation functions." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:67 msgid "" "<emphasis>7</emphasis>, <emphasis>0x1000</emphasis>: Trace messages for " "internal control functions." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:72 msgid "" "<emphasis>8</emphasis>, <emphasis>0x2000</emphasis>: Contents of " "function-internal variables that may be interesting." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:77 msgid "" "<emphasis>9</emphasis>, <emphasis>0x4000</emphasis>: Extremely low-level " "tracing information." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:81 msgid "" "To log required bitmask debug levels, simply add their numbers together as " "shown in following examples:" msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:85 msgid "" "<emphasis>Example</emphasis>: To log fatal failures, critical failures, " "serious failures and function data use 0x0270." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:89 msgid "" "<emphasis>Example</emphasis>: To log fatal failures, configuration settings, " "function data, trace messages for internal control functions use 0x1310." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:94 msgid "" "<emphasis>Note</emphasis>: The bitmask format of debug levels was introduced " "in 1.7.0." msgstr "" #. type: Content of: <listitem><para> #: include/debug_levels.xml:98 msgid "<emphasis>Default</emphasis>: 0" msgstr "" #. type: Content of: outside any tag (error?) #: include/experimental.xml:1 msgid "" "<emphasis> This is an experimental feature, please use " "http://fedorahosted.org/sssd to report any issues. </emphasis>" msgstr "" #. type: Content of: <refsect1><title> #: include/local.xml:2 msgid "THE LOCAL DOMAIN" msgstr "" #. type: Content of: <refsect1><para> #: include/local.xml:4 msgid "" "In order to function correctly, a domain with " "<quote>id_provider=local</quote> must be created and the SSSD must be " "running." msgstr "" #. type: Content of: <refsect1><para> #: include/local.xml:9 msgid "" "The administrator might want to use the SSSD local users instead of " "traditional UNIX users in cases where the group nesting (see <citerefentry> " "<refentrytitle>sss_groupadd</refentrytitle> <manvolnum>8</manvolnum> " "</citerefentry>) is needed. The local users are also useful for testing and " "development of the SSSD without having to deploy a full remote server. The " "<command>sss_user*</command> and <command>sss_group*</command> tools use a " "local LDB storage to store users and groups." msgstr "" #. type: Content of: <refsect1><para> #: include/seealso.xml:4 msgid "" "<citerefentry> <refentrytitle>sssd</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sssd.conf</refentrytitle><manvolnum>5</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sssd-ldap</refentrytitle><manvolnum>5</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sssd-krb5</refentrytitle><manvolnum>5</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sssd-simple</refentrytitle><manvolnum>5</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sssd-ipa</refentrytitle><manvolnum>5</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sssd-ad</refentrytitle><manvolnum>5</manvolnum> " "</citerefentry>, <phrase condition=\"with_sudo\"> <citerefentry> " "<refentrytitle>sssd-sudo</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry>, </phrase> <citerefentry> " "<refentrytitle>sss_cache</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sss_debuglevel</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sss_groupadd</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sss_groupdel</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sss_groupshow</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sss_groupmod</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sss_useradd</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sss_userdel</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sss_usermod</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sss_obfuscate</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sss_seed</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <citerefentry> " "<refentrytitle>sssd_krb5_locator_plugin</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>, <phrase condition=\"with_ssh\"> <citerefentry> " "<refentrytitle>sss_ssh_authorizedkeys</refentrytitle> " "<manvolnum>8</manvolnum> </citerefentry>, <citerefentry> " "<refentrytitle>sss_ssh_knownhostsproxy</refentrytitle> " "<manvolnum>8</manvolnum> </citerefentry>, </phrase> <phrase " "condition=\"with_ifp\"> <citerefentry> " "<refentrytitle>sssd-ifp</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry>, </phrase> <citerefentry> " "<refentrytitle>pam_sss</refentrytitle><manvolnum>8</manvolnum> " "</citerefentry>. <citerefentry> " "<refentrytitle>sss_rpcidmapd</refentrytitle> <manvolnum>5</manvolnum> " "</citerefentry>" msgstr "" #. type: Content of: <listitem><para> #: include/ldap_search_bases.xml:3 msgid "" "An optional base DN, search scope and LDAP filter to restrict LDAP searches " "for this attribute type." msgstr "" #. type: Content of: <listitem><para><programlisting> #: include/ldap_search_bases.xml:9 #, no-wrap msgid "search_base[?scope?[filter][?search_base?scope?[filter]]*]\n" msgstr "" #. type: Content of: <listitem><para> #: include/ldap_search_bases.xml:7 msgid "syntax: <placeholder type=\"programlisting\" id=\"0\"/>" msgstr "" #. type: Content of: <listitem><para> #: include/ldap_search_bases.xml:13 msgid "" "The scope can be one of \"base\", \"onelevel\" or \"subtree\". The scope " "functions as specified in section 4.5.1.2 of " "http://tools.ietf.org/html/rfc4511" msgstr "" #. type: Content of: <listitem><para> #: include/ldap_search_bases.xml:23 msgid "" "For examples of this syntax, please refer to the " "<quote>ldap_search_base</quote> examples section." msgstr "" #. type: Content of: <listitem><para> #: include/ldap_search_bases.xml:31 msgid "" "Please note that specifying scope or filter is not supported for searches " "against an Active Directory Server that might yield a large number of " "results and trigger the Range Retrieval extension in the response." msgstr "" #. type: Content of: <para> #: include/autofs_restart.xml:2 msgid "" "Please note that the automounter only reads the master map on startup, so if " "any autofs-related changes are made to the sssd.conf, you typically also " "need to restart the automounter daemon after restarting the SSSD." msgstr "" #. type: Content of: <varlistentry><term> #: include/override_homedir.xml:2 msgid "override_homedir (string)" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: include/override_homedir.xml:16 msgid "UID number" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: include/override_homedir.xml:20 msgid "domain name" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><term> #: include/override_homedir.xml:23 msgid "%f" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: include/override_homedir.xml:24 msgid "fully qualified user name (user@domain)" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: include/override_homedir.xml:28 msgid "UPN - User Principal Name (name@REALM)" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><term> #: include/override_homedir.xml:31 msgid "%o" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: include/override_homedir.xml:33 msgid "The original home directory retrieved from the identity provider." msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><term> #: include/override_homedir.xml:38 msgid "%H" msgstr "" #. type: Content of: <varlistentry><listitem><para><variablelist><varlistentry><listitem><para> #: include/override_homedir.xml:40 msgid "The value of configure option <emphasis>homedir_substring</emphasis>." msgstr "" #. type: Content of: <varlistentry><listitem><para> #: include/override_homedir.xml:5 msgid "" "Override the user's home directory. You can either provide an absolute value " "or a template. In the template, the following sequences are substituted: " "<placeholder type=\"variablelist\" id=\"0\"/>" msgstr "" #. type: Content of: <varlistentry><listitem><para> #: include/override_homedir.xml:52 msgid "This option can also be set per-domain." msgstr "" #. type: Content of: <varlistentry><listitem><para><programlisting> #: include/override_homedir.xml:57 #, no-wrap msgid "" "override_homedir = /home/%u\n" " " msgstr "" #. type: Content of: <varlistentry><listitem><para> #: include/override_homedir.xml:61 msgid "Default: Not set (SSSD will use the value retrieved from LDAP)" msgstr "" #. type: Content of: <varlistentry><term> #: include/homedir_substring.xml:2 msgid "homedir_substring (string)" msgstr "" #. type: Content of: <varlistentry><listitem><para> #: include/homedir_substring.xml:5 msgid "" "The value of this option will be used in the expansion of the " "<emphasis>override_homedir</emphasis> option if the template contains the " "format string <emphasis>%H</emphasis>. An LDAP directory entry can directly " "contain this template so that this option can be used to expand the home " "directory path for each client machine (or operating system). It can be set " "per-domain or globally in the [nss] section. A value specified in a domain " "section will override one set in the [nss] section." msgstr "" #. type: Content of: <varlistentry><listitem><para> #: include/homedir_substring.xml:15 msgid "Default: /home" msgstr "" �������sssd-1.13.4/src/man/po/PaxHeaders.16287/po4a.cfg����������������������������������������������������0000644�0000000�0000000�00000000073�12703456111�015630� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������29 atime=1460561751.63971559 30 ctime=1460561775.997798183 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������sssd-1.13.4/src/man/po/po4a.cfg���������������������������������������������������������������������0000644�0024127�0024127�00000006655�12703456111�017314� 0����������������������������������������������������������������������������������������������������ustar�00jhrozek�������������������������jhrozek�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������[po4a_langs] br ca cs de eu es fr ja lv nl pt pt_BR ru tg uk zh_CN [po4a_paths] po/sssd-docs.pot $lang:po/$lang.po [type:docbook] sss_groupmod.8.xml $lang:$(builddir)/$lang/sss_groupmod.8.xml [type:docbook] sssd.conf.5.xml $lang:$(builddir)/$lang/sssd.conf.5.xml [type:docbook] sssd-ldap.5.xml $lang:$(builddir)/$lang/sssd-ldap.5.xml [type:docbook] pam_sss.8.xml $lang:$(builddir)/$lang/pam_sss.8.xml [type:docbook] sssd_krb5_locator_plugin.8.xml $lang:$(builddir)/$lang/sssd_krb5_locator_plugin.8.xml [type:docbook] sssd-simple.5.xml $lang:$(builddir)/$lang/sssd-simple.5.xml [type:docbook] sssd-ipa.5.xml $lang:$(builddir)/$lang/sssd-ipa.5.xml [type:docbook] sssd-ad.5.xml $lang:$(builddir)/$lang/sssd-ad.5.xml [type:docbook] sssd-sudo.5.xml $lang:$(builddir)/$lang/sssd-sudo.5.xml [type:docbook] sssd.8.xml $lang:$(builddir)/$lang/sssd.8.xml [type:docbook] sss_obfuscate.8.xml $lang:$(builddir)/$lang/sss_obfuscate.8.xml [type:docbook] sss_override.8.xml $lang:$(builddir)/$lang/sss_override.8.xml [type:docbook] sss_useradd.8.xml $lang:$(builddir)/$lang/sss_useradd.8.xml [type:docbook] sssd-krb5.5.xml $lang:$(builddir)/$lang/sssd-krb5.5.xml [type:docbook] sss_groupadd.8.xml $lang:$(builddir)/$lang/sss_groupadd.8.xml [type:docbook] sss_userdel.8.xml $lang:$(builddir)/$lang/sss_userdel.8.xml [type:docbook] sss_groupdel.8.xml $lang:$(builddir)/$lang/sss_groupdel.8.xml [type:docbook] sss_groupshow.8.xml $lang:$(builddir)/$lang/sss_groupshow.8.xml [type:docbook] sss_usermod.8.xml $lang:$(builddir)/$lang/sss_usermod.8.xml [type:docbook] sss_cache.8.xml $lang:$(builddir)/$lang/sss_cache.8.xml [type:docbook] sss_debuglevel.8.xml $lang:$(builddir)/$lang/sss_debuglevel.8.xml [type:docbook] sss_seed.8.xml $lang:$(builddir)/$lang/sss_seed.8.xml [type:docbook] sssd-ifp.5.xml $lang:$(builddir)/$lang/sssd-ifp.5.xml [type:docbook] sss_rpcidmapd.5.xml $lang:$(builddir)/$lang/sss_rpcidmapd.5.xml [type:docbook] sss_ssh_authorizedkeys.1.xml $lang:$(builddir)/$lang/sss_ssh_authorizedkeys.1.xml [type:docbook] sss_ssh_knownhostsproxy.1.xml $lang:$(builddir)/$lang/sss_ssh_knownhostsproxy.1.xml [type:docbook] include/service_discovery.xml $lang:$(builddir)/$lang/include/service_discovery.xml opt:"-k 0" [type:docbook] include/upstream.xml $lang:$(builddir)/$lang/include/upstream.xml opt:"-k 0" [type:docbook] include/failover.xml $lang:$(builddir)/$lang/include/failover.xml opt:"-k 0" [type:docbook] include/ldap_id_mapping.xml $lang:$(builddir)/$lang/include/ldap_id_mapping.xml opt:"-k 0" [type:docbook] include/param_help.xml $lang:$(builddir)/$lang/include/param_help.xml opt:"-k 0" [type:docbook] include/param_help_py.xml $lang:$(builddir)/$lang/include/param_help_py.xml opt:"-k 0" [type:docbook] include/debug_levels.xml $lang:$(builddir)/$lang/include/debug_levels.xml opt:"-k 0" [type:docbook] include/experimental.xml $lang:$(builddir)/$lang/include/experimental.xml opt:"-k 0" [type:docbook] include/local.xml $lang:$(builddir)/$lang/include/local.xml opt:"-k 0" [type:docbook] include/seealso.xml $lang:$(builddir)/$lang/include/seealso.xml opt:"-k 0" [type:docbook] include/ldap_search_bases.xml $lang:$(builddir)/$lang/include/ldap_search_bases.xml opt:"-k 0" [type:docbook] include/autofs_restart.xml $lang:$(builddir)/$lang/include/autofs_restart.xml opt:"-k 0" [type:docbook] include/override_homedir.xml $lang:$(builddir)/$lang/include/override_homedir.xml opt:"-k 0" [type:docbook] include/homedir_substring.xml $lang:$(builddir)/$lang/include/homedir_substring.xml opt:"-k 0" �����������������������������������������������������������������������������������sssd-1.13.4/src/man/PaxHeaders.16287/sss_usermod.8.xml����������������������������������������������0000644�0000000�0000000�00000000072�12703456111�017123� x����������������������������������������������������������������������������������������������������ustar�00�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������28 atime=1460561751.6427156 30 ctime=1460561775.965798074 ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������sssd-1.13.4/src/man/sss_usermod.8.xml���������������������������������������������������������������0000644�0024127�0024127�00000014452�12703456111�020602� 0����������������������������������������������������������������������������������������������������ustar�00jhrozek�������������������������jhrozek�������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"> <reference> <title>SSSD Manual pages sss_usermod 8 sss_usermod modify a user account sss_usermod options LOGIN DESCRIPTION sss_usermod modifies the account specified by LOGIN to reflect the changes that are specified on the command line. OPTIONS , COMMENT Any text string describing the user. Often used as the field for the user's full name. , HOME_DIR The home directory of the user account. , SHELL The user's login shell. , GROUPS Append this user to groups specified by the GROUPS parameter. The GROUPS parameter is a comma separated list of group names. , GROUPS Remove this user from groups specified by the GROUPS parameter. , Lock the user account. The user won't be able to log in. , Unlock the user account. , SELINUX_USER The SELinux user for the user's login. ATTR_NAME_VAL Add an attribute/value pair. The format is attrname=value. ATTR_NAME_VAL Set an attribute to a name/value pair. The format is attrname=value. For multi-valued attributes, the command replaces the values already present ATTR_NAME_VAL Delete an attribute/value pair. The format is attrname=value. sssd-1.13.4/src/man/PaxHeaders.16287/sssd-simple.5.xml0000644000000000000000000000007212703456111017015 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.969798088 sssd-1.13.4/src/man/sssd-simple.5.xml0000644002412700241270000001432312703456111020471 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sssd-simple 5 File Formats and Conventions sssd-simple the configuration file for SSSD's 'simple' access-control provider DESCRIPTION This manual page describes the configuration of the simple access-control provider for sssd 8 . For a detailed syntax reference, refer to the FILE FORMAT section of the sssd.conf 5 manual page. The simple access provider grants or denies access based on an access or deny list of user or group names. The following rules apply: If all lists are empty, access is granted If any list is provided, the order of evaluation is allow,deny. This means that any matching deny rule will supersede any matched allow rule. If either or both "allow" lists are provided, all users are denied unless they appear in the list. If only "deny" lists are provided, all users are granted access unless they appear in the list. CONFIGURATION OPTIONS Refer to the section DOMAIN SECTIONS of the sssd.conf 5 manual page for details on the configuration of an SSSD domain. simple_allow_users (string) Comma separated list of users who are allowed to log in. simple_deny_users (string) Comma separated list of users who are explicitly denied access. simple_allow_groups (string) Comma separated list of groups that are allowed to log in. This applies only to groups within this SSSD domain. Local groups are not evaluated. simple_deny_groups (string) Comma separated list of groups that are explicitly denied access. This applies only to groups within this SSSD domain. Local groups are not evaluated. Specifying no values for any of the lists is equivalent to skipping it entirely. Beware of this while generating parameters for the simple provider using automated scripts. Please note that it is an configuration error if both, simple_allow_users and simple_deny_users, are defined. EXAMPLE The following example assumes that SSSD is correctly configured and example.com is one of the domains in the [sssd] section. This examples shows only the simple access provider-specific options. [domain/example.com] access_provider = simple simple_allow_users = user1, user2 NOTES The complete group membership hierarchy is resolved before the access check, thus even nested groups can be included in the access lists. Please be aware that the ldap_group_nesting_level option may impact the results and should be set to a sufficient value. ( sssd-ldap5 ) option. sssd-1.13.4/src/man/PaxHeaders.16287/sssd-ldap.5.xml0000644000000000000000000000007212703456111016444 xustar0028 atime=1460561751.6427156 30 ctime=1460561775.963798067 sssd-1.13.4/src/man/sssd-ldap.5.xml0000644002412700241270000035115612703456111020130 0ustar00jhrozekjhrozek00000000000000 SSSD Manual pages sssd-ldap 5 File Formats and Conventions sssd-ldap SSSD LDAP provider DESCRIPTION This manual page describes the configuration of LDAP domains for sssd 8 . Refer to the FILE FORMAT section of the sssd.conf 5 manual page for detailed syntax information. You can configure SSSD to use more than one LDAP domain. LDAP back end supports id, auth, access and chpass providers. If you want to authenticate against an LDAP server either TLS/SSL or LDAPS is required. sssd does not support authentication over an unencrypted channel. If the LDAP server is used only as an identity provider, an encrypted channel is not needed. Please refer to ldap_access_filter config option for more information about using LDAP as an access provider. CONFIGURATION OPTIONS All of the common configuration options that apply to SSSD domains also apply to LDAP domains. Refer to the DOMAIN SECTIONS section of the sssd.conf 5 manual page for full details. ldap_uri, ldap_backup_uri (string) Specifies the comma-separated list of URIs of the LDAP servers to which SSSD should connect in the order of preference. Refer to the FAILOVER section for more information on failover and server redundancy. If neither option is specified, service discovery is enabled. For more information, refer to the SERVICE DISCOVERY section. The format of the URI must match the format defined in RFC 2732: ldap[s]://<host>[:port] For explicit IPv6 addresses, <host> must be enclosed in brackets [] example: ldap://[fc00::126:25]:389 ldap_chpass_uri, ldap_chpass_backup_uri (string) Specifies the comma-separated list of URIs of the LDAP servers to which SSSD should connect in the order of preference to change the password of a user. Refer to the FAILOVER section for more information on failover and server redundancy. To enable service discovery ldap_chpass_dns_service_name must be set. Default: empty, i.e. ldap_uri is used. ldap_search_base (string) The default base DN to use for performing LDAP user operations. Starting with SSSD 1.7.0, SSSD supports multiple search bases using the syntax: search_base[?scope?[filter][?search_base?scope?[filter]]*] The scope can be one of "base", "onelevel" or "subtree". The filter must be a valid LDAP search filter as specified by http://www.ietf.org/rfc/rfc2254.txt Examples: ldap_search_base = dc=example,dc=com (which is equivalent to) ldap_search_base = dc=example,dc=com?subtree? ldap_search_base = cn=host_specific,dc=example,dc=com?subtree?(host=thishost)?dc=example.com?subtree? Note: It is unsupported to have multiple search bases which reference identically-named objects (for example, groups with the same name in two different search bases). This will lead to unpredictable behavior on client machines. Default: If not set, the value of the defaultNamingContext or namingContexts attribute from the RootDSE of the LDAP server is used. If defaultNamingContext does not exist or has an empty value namingContexts is used. The namingContexts attribute must have a single value with the DN of the search base of the LDAP server to make this work. Multiple values are are not supported. ldap_schema (string) Specifies the Schema Type in use on the target LDAP server. Depending on the selected schema, the default attribute names retrieved from the servers may vary. The way that some attributes are handled may also differ. Four schema types are currently supported: rfc2307 rfc2307bis IPA AD The main difference between these schema types is how group memberships are recorded in the server. With rfc2307, group members are listed by name in the memberUid attribute. With rfc2307bis and IPA, group members are listed by DN and stored in the member attribute. The AD schema type sets the attributes to correspond with Active Directory 2008r2 values. Default: rfc2307 ldap_default_bind_dn (string) The default bind DN to use for performing LDAP operations. ldap_default_authtok_type (string) The type of the authentication token of the default bind DN. The two mechanisms currently supported are: password obfuscated_password Default: password ldap_default_authtok (string) The authentication token of the default bind DN. Only clear text passwords are currently supported. ldap_user_object_class (string) The object class of a user entry in LDAP. Default: posixAccount ldap_user_name (string) The LDAP attribute that corresponds to the user's login name. Default: uid ldap_user_uid_number (string) The LDAP attribute that corresponds to the user's id. Default: uidNumber ldap_user_gid_number (string) The LDAP attribute that corresponds to the user's primary group id. Default: gidNumber ldap_user_gecos (string) The LDAP attribute that corresponds to the user's gecos field. Default: gecos ldap_user_home_directory (string) The LDAP attribute that contains the name of the user's home directory. Default: homeDirectory ldap_user_shell (string) The LDAP attribute that contains the path to the user's default shell. Default: loginShell ldap_user_uuid (string) The LDAP attribute that contains the UUID/GUID of an LDAP user object. Default: not set in the general case, objectGUID for AD and ipaUniqueID for IPA ldap_user_objectsid (string) The LDAP attribute that contains the objectSID of an LDAP user object. This is usually only necessary for ActiveDirectory servers. Default: objectSid for ActiveDirectory, not set for other servers. ldap_user_modify_timestamp (string) The LDAP attribute that contains timestamp of the last modification of the parent object. Default: modifyTimestamp ldap_user_shadow_last_change (string) When using ldap_pwd_policy=shadow, this parameter contains the name of an LDAP attribute corresponding to its shadow 5 counterpart (date of the last password change). Default: shadowLastChange ldap_user_shadow_min (string) When using ldap_pwd_policy=shadow, this parameter contains the name of an LDAP attribute corresponding to its shadow 5 counterpart (minimum password age). Default: shadowMin ldap_user_shadow_max (string) When using ldap_pwd_policy=shadow, this parameter contains the name of an LDAP attribute corresponding to its shadow 5 counterpart (maximum password age). Default: shadowMax ldap_user_shadow_warning (string) When using ldap_pwd_policy=shadow, this parameter contains the name of an LDAP attribute corresponding to its shadow 5 counterpart (password warning period). Default: shadowWarning ldap_user_shadow_inactive (string) When using ldap_pwd_policy=shadow, this parameter contains the name of an LDAP attribute corresponding to its shadow 5 counterpart (password inactivity period). Default: shadowInactive ldap_user_shadow_expire (string) When using ldap_pwd_policy=shadow or ldap_account_expire_policy=shadow, this parameter contains the name of an LDAP attribute corresponding to its shadow 5 counterpart (account expiration date). Default: shadowExpire ldap_user_krb_last_pwd_change (string) When using ldap_pwd_policy=mit_kerberos, this parameter contains the name of an LDAP attribute storing the date and time of last password change in kerberos. Default: krbLastPwdChange ldap_user_krb_password_expiration (string) When using ldap_pwd_policy=mit_kerberos, this parameter contains the name of an LDAP attribute storing the date and time when current password expires. Default: krbPasswordExpiration ldap_user_ad_account_expires (string) When using ldap_account_expire_policy=ad, this parameter contains the name of an LDAP attribute storing the expiration time of the account. Default: accountExpires ldap_user_ad_user_account_control (string) When using ldap_account_expire_policy=ad, this parameter contains the name of an LDAP attribute storing the user account control bit field. Default: userAccountControl ldap_ns_account_lock (string) When using ldap_account_expire_policy=rhds or equivalent, this parameter determines if access is allowed or not. Default: nsAccountLock ldap_user_nds_login_disabled (string) When using ldap_account_expire_policy=nds, this attribute determines if access is allowed or not. Default: loginDisabled ldap_user_nds_login_expiration_time (string) When using ldap_account_expire_policy=nds, this attribute determines until which date access is granted. Default: loginDisabled ldap_user_nds_login_allowed_time_map (string) When using ldap_account_expire_policy=nds, this attribute determines the hours of a day in a week when access is granted. Default: loginAllowedTimeMap ldap_user_principal (string) The LDAP attribute that contains the user's Kerberos User Principal Name (UPN). Default: krbPrincipalName ldap_user_extra_attrs (string) Comma-separated list of LDAP attributes that SSSD would fetch along with the usual set of user attributes. The list can either contain LDAP attribute names only, or colon-separated tuples of SSSD cache attribute name and LDAP attribute name. In case only LDAP attribute name is specified, the attribute is saved to the cache verbatim. Using a custom SSSD attribute name might be required by environments that configure several SSSD domains with different LDAP schemas. Please note that several attribute names are reserved by SSSD, notably the name attribute. SSSD would report an error if any of the reserved attribute names is used as an extra attribute name. Examples: ldap_user_extra_attrs = telephoneNumber Save the telephoneNumber attribute from LDAP as telephoneNumber to the cache. ldap_user_extra_attrs = phone:telephoneNumber Save the telephoneNumber attribute from LDAP as phone to the cache. Default: not set ldap_user_ssh_public_key (string) The LDAP attribute that contains the user's SSH public keys. Default: sshPublicKey ldap_force_upper_case_realm (boolean) Some directory servers, for example Active Directory, might deliver the realm part of the UPN in lower case, which might cause the authentication to fail. Set this option to a non-zero value if you want to use an upper-case realm. Default: false ldap_enumeration_refresh_timeout (integer) Specifies how many seconds SSSD has to wait before refreshing its cache of enumerated records. Default: 300 ldap_purge_cache_timeout (integer) Determine how often to check the cache for inactive entries (such as groups with no members and users who have never logged in) and remove them to save space. Setting this option to zero will disable the cache cleanup operation. Please note that if enumeration is enabled, the cleanup task is required in order to detect entries removed from the server and can't be disabled. By default, the cleanup task will run every 3 hours with enumeration enabled. Default: 0 (disabled) ldap_user_fullname (string) The LDAP attribute that corresponds to the user's full name. Default: cn ldap_user_member_of (string) The LDAP attribute that lists the user's group memberships. Default: memberOf ldap_user_authorized_service (string) If access_provider=ldap and ldap_access_order=authorized_service, SSSD will use the presence of the authorizedService attribute in the user's LDAP entry to determine access privilege. An explicit deny (!svc) is resolved first. Second, SSSD searches for explicit allow (svc) and finally for allow_all (*). Please note that the ldap_access_order configuration option must include authorized_service in order for the ldap_user_authorized_service option to work. Default: authorizedService ldap_user_authorized_host (string) If access_provider=ldap and ldap_access_order=host, SSSD will use the presence of the host attribute in the user's LDAP entry to determine access privilege. An explicit deny (!host) is resolved first. Second, SSSD searches for explicit allow (host) and finally for allow_all (*). Please note that the ldap_access_order configuration option must include host in order for the ldap_user_authorized_host option to work. Default: host ldap_user_certificate (string) Name of the LDAP attribute containing the X509 certificate of the user. Default: no set in the general case, userCertificate;binary for IPA ldap_group_object_class (string) The object class of a group entry in LDAP. Default: posixGroup ldap_group_name (string) The LDAP attribute that corresponds to the group name. Default: cn ldap_group_gid_number (string) The LDAP attribute that corresponds to the group's id. Default: gidNumber ldap_group_member (string) The LDAP attribute that contains the names of the group's members. Default: memberuid (rfc2307) / member (rfc2307bis) ldap_group_uuid (string) The LDAP attribute that contains the UUID/GUID of an LDAP group object. Default: not set in the general case, objectGUID for AD and ipaUniqueID for IPA ldap_group_objectsid (string) The LDAP attribute that contains the objectSID of an LDAP group object. This is usually only necessary for ActiveDirectory servers. Default: objectSid for ActiveDirectory, not set for other servers. ldap_group_modify_timestamp (string) The LDAP attribute that contains timestamp of the last modification of the parent object. Default: modifyTimestamp ldap_group_type (integer) The LDAP attribute that contains an integer value indicating the type of the group and maybe other flags. This attribute is currently only used by the AD provider to determine if a group is a domain local groups and has to be filtered out for trusted domains. Default: groupType in the AD provider, othewise not set ldap_group_external_member (string) The LDAP attribute that references group members that are defined in an external domain. At the moment, only IPA's external members are supported. Default: ipaExternalMember in the IPA provider, otherwise unset. ldap_group_nesting_level (integer) If ldap_schema is set to a schema format that supports nested groups (e.g. RFC2307bis), then this option controls how many levels of nesting SSSD will follow. This option has no effect on the RFC2307 schema. Note: This option specifies the guaranteed level of nested groups to be processed for any lookup. However, nested groups beyond this limit may be returned if previous lookups already resolved the deeper nesting levels. Also, subsequent lookups for other groups may enlarge the result set for original lookup if re-queried. If ldap_group_nesting_level is set to 0 then no nested groups are processed at all. However, when connected to Active-Directory Server 2008 and later using id_provider=ad it is furthermore required to disable usage of Token-Groups by setting ldap_use_tokengroups to false in order to restrict group nesting. Default: 2 ldap_groups_use_matching_rule_in_chain This option tells SSSD to take advantage of an Active Directory-specific feature which may speed up group lookup operations on deployments with complex or deep nested groups. In most common cases, it is best to leave this option disabled. It generally only provides a performance increase on very complex nestings. If this option is enabled, SSSD will use it if it detects that the server supports it during initial connection. So "True" here essentially means "auto-detect". Note: This feature is currently known to work only with Active Directory 2008 R1 and later. See MSDN(TM) documentation for more details. Default: False ldap_initgroups_use_matching_rule_in_chain This option tells SSSD to take advantage of an Active Directory-specific feature which might speed up initgroups operations (most notably when dealing with complex or deep nested groups). If this option is enabled, SSSD will use it if it detects that the server supports it during initial connection. So "True" here essentially means "auto-detect". Note: This feature is currently known to work only with Active Directory 2008 R1 and later. See MSDN(TM) documentation for more details. Default: False ldap_use_tokengroups This options enables or disables use of Token-Groups attribute when performing initgroup for users from Active Directory Server 2008 and later. Default: True for AD and IPA otherwise False. ldap_netgroup_object_class (string) The object class of a netgroup entry in LDAP. In IPA provider, ipa_netgroup_object_class should be used instead. Default: nisNetgroup ldap_netgroup_name (string) The LDAP attribute that corresponds to the netgroup name. In IPA provider, ipa_netgroup_name should be used instead. Default: cn ldap_netgroup_member (string) The LDAP attribute that contains the names of the netgroup's members. In IPA provider, ipa_netgroup_member should be used instead. Default: memberNisNetgroup ldap_netgroup_triple (string) The LDAP attribute that contains the (host, user, domain) netgroup triples. This option is not available in IPA provider. Default: nisNetgroupTriple ldap_netgroup_modify_timestamp (string) The LDAP attribute that contains timestamp of the last modification of the parent object. This option is not available in IPA provider. Default: modifyTimestamp ldap_service_object_class (string) The object class of a service entry in LDAP. Default: ipService ldap_service_name (string) The LDAP attribute that contains the name of service attributes and their aliases. Default: cn ldap_service_port (string) The LDAP attribute that contains the port managed by this service. Default: ipServicePort ldap_service_proto (string) The LDAP attribute that contains the protocols understood by this service. Default: ipServiceProtocol ldap_service_search_base (string) ldap_search_timeout (integer) Specifies the timeout (in seconds) that ldap searches are allowed to run before they are cancelled and cached results are returned (and offline mode is entered) Note: this option is subject to change in future versions of the SSSD. It will likely be replaced at some point by a series of timeouts for specific lookup types. Default: 6 ldap_enumeration_search_timeout (integer) Specifies the timeout (in seconds) that ldap searches for user and group enumerations are allowed to run before they are cancelled and cached results are returned (and offline mode is entered) Default: 60 ldap_network_timeout (integer) Specifies the timeout (in seconds) after which the poll 2 / select 2 following a connect 2 returns in case of no activity. Default: 6 ldap_opt_timeout (integer) Specifies a timeout (in seconds) after which calls to synchronous LDAP APIs will abort if no response is received. Also controls the timeout when communicating with the KDC in case of SASL bind, the timeout of an LDAP bind operation, password change extended operation and the StartTLS operation. Default: 6 ldap_connection_expire_timeout (integer) Specifies a timeout (in seconds) that a connection to an LDAP server will be maintained. After this time, the connection will be re-established. If used in parallel with SASL/GSSAPI, the sooner of the two values (this value vs. the TGT lifetime) will be used. Default: 900 (15 minutes) ldap_page_size (integer) Specify the number of records to retrieve from LDAP in a single request. Some LDAP servers enforce a maximum limit per-request. Default: 1000 ldap_disable_paging (boolean) Disable the LDAP paging control. This option should be used if the LDAP server reports that it supports the LDAP paging control in its RootDSE but it is not enabled or does not behave properly. Example: OpenLDAP servers with the paging control module installed on the server but not enabled will report it in the RootDSE but be unable to use it. Example: 389 DS has a bug where it can only support a one paging control at a time on a single connection. On busy clients, this can result in some requests being denied. Default: False ldap_disable_range_retrieval (boolean) Disable Active Directory range retrieval. Active Directory limits the number of members to be retrieved in a single lookup using the MaxValRange policy (which defaults to 1500 members). If a group contains more members, the reply would include an AD-specific range extension. This option disables parsing of the range extension, therefore large groups will appear as having no members. Default: False ldap_sasl_minssf (integer) When communicating with an LDAP server using SASL, specify the minimum security level necessary to establish the connection. The values of this option are defined by OpenLDAP. Default: Use the system default (usually specified by ldap.conf) ldap_deref_threshold (integer) Specify the number of group members that must be missing from the internal cache in order to trigger a dereference lookup. If less members are missing, they are looked up individually. You can turn off dereference lookups completely by setting the value to 0. A dereference lookup is a means of fetching all group members in a single LDAP call. Different LDAP servers may implement different dereference methods. The currently supported servers are 389/RHDS, OpenLDAP and Active Directory. Note: If any of the search bases specifies a search filter, then the dereference lookup performance enhancement will be disabled regardless of this setting. Default: 10 ldap_tls_reqcert (string) Specifies what checks to perform on server certificates in a TLS session, if any. It can be specified as one of the following values: never = The client will not request or check any server certificate. allow = The server certificate is requested. If no certificate is provided, the session proceeds normally. If a bad certificate is provided, it will be ignored and the session proceeds normally. try = The server certificate is requested. If no certificate is provided, the session proceeds normally. If a bad certificate is provided, the session is immediately terminated. demand = The server certificate is requested. If no certificate is provided, or a bad certificate is provided, the session is immediately terminated. hard = Same as demand Default: hard ldap_tls_cacert (string) Specifies the file that contains certificates for all of the Certificate Authorities that sssd will recognize. Default: use OpenLDAP defaults, typically in /etc/openldap/ldap.conf ldap_tls_cacertdir (string) Specifies the path of a directory that contains Certificate Authority certificates in separate individual files. Typically the file names need to be the hash of the certificate followed by '.0'. If available, cacertdir_rehash can be used to create the correct names. Default: use OpenLDAP defaults, typically in /etc/openldap/ldap.conf ldap_tls_cert (string) Specifies the file that contains the certificate for the client's key. Default: not set ldap_tls_key (string) Specifies the file that contains the client's key. Default: not set ldap_tls_cipher_suite (string) Specifies acceptable cipher suites. Typically this is a colon separated list. See ldap.conf 5 for format. Default: use OpenLDAP defaults, typically in /etc/openldap/ldap.conf ldap_id_use_start_tls (boolean) Specifies that the id_provider connection must also use tls to protect the channel. Default: false ldap_id_mapping (boolean) Specifies that SSSD should attempt to map user and group IDs from the ldap_user_objectsid and ldap_group_objectsid attributes instead of relying on ldap_user_uid_number and ldap_group_gid_number. Currently this feature supports only ActiveDirectory objectSID mapping. Default: false ldap_min_id, ldap_max_id (interger) In contrast to the SID based ID mapping which is used if ldap_id_mapping is set to true the allowed ID range for ldap_user_uid_number and ldap_group_gid_number is unbound. In a setup with sub/trusted-domains this might lead to ID collisions. To avoid collisions ldap_min_id and ldap_max_id can be set to restrict the allowed range for the IDs which are read directly from the server. Sub-domains can then pick other ranges to map IDs. Default: not set (both options are set to 0) ldap_sasl_mech (string) Specify the SASL mechanism to use. Currently only GSSAPI is tested and supported. Default: not set ldap_sasl_authid (string) Specify the SASL authorization id to use. When GSSAPI is used, this represents the Kerberos principal used for authentication to the directory. This option can either contain the full principal (for example host/myhost@EXAMPLE.COM) or just the principal name (for example host/myhost). Default: host/hostname@REALM ldap_sasl_realm (string) Specify the SASL realm to use. When not specified, this option defaults to the value of krb5_realm. If the ldap_sasl_authid contains the realm as well, this option is ignored. Default: the value of krb5_realm. ldap_sasl_canonicalize (boolean) If set to true, the LDAP library would perform a reverse lookup to canonicalize the host name during a SASL bind. Default: false; ldap_krb5_keytab (string) Specify the keytab to use when using SASL/GSSAPI. Default: System keytab, normally /etc/krb5.keytab ldap_krb5_init_creds (boolean) Specifies that the id_provider should init Kerberos credentials (TGT). This action is performed only if SASL is used and the mechanism selected is GSSAPI. Default: true ldap_krb5_ticket_lifetime (integer) Specifies the lifetime in seconds of the TGT if GSSAPI is used. Default: 86400 (24 hours) krb5_server, krb5_backup_server (string) Specifies the comma-separated list of IP addresses or hostnames of the Kerberos servers to which SSSD should connect in the order of preference. For more information on failover and server redundancy, see the FAILOVER section. An optional port number (preceded by a colon) may be appended to the addresses or hostnames. If empty, service discovery is enabled - for more information, refer to the SERVICE DISCOVERY section. When using service discovery for KDC or kpasswd servers, SSSD first searches for DNS entries that specify _udp as the protocol and falls back to _tcp if none are found. This option was named krb5_kdcip in earlier releases of SSSD. While the legacy name is recognized for the time being, users are advised to migrate their config files to use krb5_server instead. krb5_realm (string) Specify the Kerberos REALM (for SASL/GSSAPI auth). Default: System defaults, see /etc/krb5.conf krb5_canonicalize (boolean) Specifies if the host principal should be canonicalized when connecting to LDAP server. This feature is available with MIT Kerberos >= 1.7 Default: false krb5_use_kdcinfo (boolean) Specifies if the SSSD should instruct the Kerberos libraries what realm and which KDCs to use. This option is on by default, if you disable it, you need to configure the Kerberos library using the krb5.conf 5 configuration file. See the sssd_krb5_locator_plugin 8 manual page for more information on the locator plugin. Default: true ldap_pwd_policy (string) Select the policy to evaluate the password expiration on the client side. The following values are allowed: none - No evaluation on the client side. This option cannot disable server-side password policies. shadow - Use shadow 5 style attributes to evaluate if the password has expired. mit_kerberos - Use the attributes used by MIT Kerberos to determine if the password has expired. Use chpass_provider=krb5 to update these attributes when the password is changed. Default: none Note: if a password policy is configured on server side, it always takes precedence over policy set with this option. ldap_referrals (boolean) Specifies whether automatic referral chasing should be enabled. Please note that sssd only supports referral chasing when it is compiled with OpenLDAP version 2.4.13 or higher. Chasing referrals may incur a performance penalty in environments that use them heavily, a notable example is Microsoft Active Directory. If your setup does not in fact require the use of referrals, setting this option to false might bring a noticeable performance improvement. Default: true ldap_dns_service_name (string) Specifies the service name to use when service discovery is enabled. Default: ldap ldap_chpass_dns_service_name (string) Specifies the service name to use to find an LDAP server which allows password changes when service discovery is enabled. Default: not set, i.e. service discovery is disabled ldap_chpass_update_last_change (bool) Specifies whether to update the ldap_user_shadow_last_change attribute with days since the Epoch after a password change operation. Default: False ldap_access_filter (string) If using access_provider = ldap and ldap_access_order = filter (default), this option is mandatory. It specifies an LDAP search filter criteria that must be met for the user to be granted access on this host. If access_provider = ldap, ldap_access_order = filter and this option is not set, it will result in all users being denied access. Use access_provider = permit to change this default behavior. Please note that this filter is applied on the LDAP user entry only and thus filtering based on nested groups may not work (e.g. memberOf attribute on AD entries points only to direct parents). If filtering based on nested groups is required, please see sssd-simple5 . Example: access_provider = ldap ldap_access_filter = (employeeType=admin) This example means that access to this host is restricted to users whose employeeType attribute is set to "admin". Offline caching for this feature is limited to determining whether the user's last online login was granted access permission. If they were granted access during their last login, they will continue to be granted access while offline and vice-versa. Default: Empty ldap_account_expire_policy (string) With this option a client side evaluation of access control attributes can be enabled. Please note that it is always recommended to use server side access control, i.e. the LDAP server should deny the bind request with a suitable error code even if the password is correct. The following values are allowed: shadow: use the value of ldap_user_shadow_expire to determine if the account is expired. ad: use the value of the 32bit field ldap_user_ad_user_account_control and allow access if the second bit is not set. If the attribute is missing access is granted. Also the expiration time of the account is checked. rhds, ipa, 389ds: use the value of ldap_ns_account_lock to check if access is allowed or not. nds: the values of ldap_user_nds_login_allowed_time_map, ldap_user_nds_login_disabled and ldap_user_nds_login_expiration_time are used to check if access is allowed. If both attributes are missing access is granted. Please note that the ldap_access_order configuration option must include expire in order for the ldap_account_expire_policy option to work. Default: Empty ldap_access_order (string) Comma separated list of access control options. Allowed values are: filter: use ldap_access_filter lockout: use account locking. If set, this option denies access in case that ldap attribute 'pwdAccountLockedTime' is present and has value of '000001010000Z'. Please see the option ldap_pwdlockout_dn. Please note that 'access_provider = ldap' must be set for this feature to work. Please note that this option is superseded by the ppolicy option and might be removed in a future release. ppolicy: use account locking. If set, this option denies access in case that ldap attribute 'pwdAccountLockedTime' is present and has value of '000001010000Z' or represents any time in the past. The value of the 'pwdAccountLockedTime' attribute must end with 'Z', which denotes the UTC time zone. Other time zones are not currently supported and will result in "access-denied" when users attempt to log in. Please see the option ldap_pwdlockout_dn. Please note that 'access_provider = ldap' must be set for this feature to work. expire: use ldap_account_expire_policy pwd_expire_policy_reject, pwd_expire_policy_warn, pwd_expire_policy_renew: These options are useful if users are interested in being warned that password is about to expire and authentication is based on using a different method than passwords - for example SSH keys. The difference between these options is the action taken if user password is expired: pwd_expire_policy_reject - user is denied to log in, pwd_expire_policy_warn - user is still able to log in, pwd_expire_policy_renew - user is prompted to change his password immediately. Note If user password is expired no explicit message is prompted by SSSD. Please note that 'access_provider = ldap' must be set for this feature to work. Also 'ldap_pwd_policy' must be set to an appropriate password policy. authorized_service: use the authorizedService attribute to determine access host: use the host attribute to determine access Default: filter Please note that it is a configuration error if a value is used more than once. ldap_pwdlockout_dn (string) This option specifies the DN of password policy entry on LDAP server. Please note that absence of this option in sssd.conf in case of enabled account lockout checking will yield access denied as ppolicy attributes on LDAP server cannot be checked properly. Example: cn=ppolicy,ou=policies,dc=example,dc=com Default: cn=ppolicy,ou=policies,$ldap_search_base ldap_deref (string) Specifies how alias dereferencing is done when performing a search. The following options are allowed: never: Aliases are never dereferenced. searching: Aliases are dereferenced in subordinates of the base object, but not in locating the base object of the search. finding: Aliases are only dereferenced when locating the base object of the search. always: Aliases are dereferenced both in searching and in locating the base object of the search. Default: Empty (this is handled as never by the LDAP client libraries) ldap_rfc2307_fallback_to_local_users (boolean) Allows to retain local users as members of an LDAP group for servers that use the RFC2307 schema. In some environments where the RFC2307 schema is used, local users are made members of LDAP groups by adding their names to the memberUid attribute. The self-consistency of the domain is compromised when this is done, so SSSD would normally remove the "missing" users from the cached group memberships as soon as nsswitch tries to fetch information about the user via getpw*() or initgroups() calls. This option falls back to checking if local users are referenced, and caches them so that later initgroups() calls will augment the local users with the additional LDAP groups. Default: false wildcart_limit (integer) Specifies an upper limit on the number of entries that are downloaded during a wildcard lookup. At the moment, only the InfoPipe responder supports wildcard lookups. Default: 1000 (often the size of one page) SUDO OPTIONS The detailed instructions for configuration of sudo_provider are in the manual page sssd-sudo 5 . ldap_sudorule_object_class (string) The object class of a sudo rule entry in LDAP. Default: sudoRole ldap_sudorule_name (string) The LDAP attribute that corresponds to the sudo rule name. Default: cn ldap_sudorule_command (string) The LDAP attribute that corresponds to the command name. Default: sudoCommand ldap_sudorule_host (string) The LDAP attribute that corresponds to the host name (or host IP address, host IP network, or host netgroup) Default: sudoHost ldap_sudorule_user (string) The LDAP attribute that corresponds to the user name (or UID, group name or user's netgroup) Default: sudoUser ldap_sudorule_option (string) The LDAP attribute that corresponds to the sudo options. Default: sudoOption ldap_sudorule_runasuser (string) The LDAP attribute that corresponds to the user name that commands may be run as. Default: sudoRunAsUser ldap_sudorule_runasgroup (string) The LDAP attribute that corresponds to the group name or group GID that commands may be run as. Default: sudoRunAsGroup ldap_sudorule_notbefore (string) The LDAP attribute that corresponds to the start date/time for when the sudo rule is valid. Default: sudoNotBefore ldap_sudorule_notafter (string) The LDAP attribute that corresponds to the expiration date/time, after which the sudo rule will no longer be valid. Default: sudoNotAfter ldap_sudorule_order (string) The LDAP attribute that corresponds to the ordering index of the rule. Default: sudoOrder ldap_sudo_full_refresh_interval (integer) How many seconds SSSD will wait between executing a full refresh of sudo rules (which downloads all rules that are stored on the server). The value must be greater than ldap_sudo_smart_refresh_interval Default: 21600 (6 hours) ldap_sudo_smart_refresh_interval (integer) How many seconds SSSD has to wait before executing a smart refresh of sudo rules (which downloads all rules that have USN higher than the highest USN of cached rules). If USN attributes are not supported by the server, the modifyTimestamp attribute is used instead. Default: 900 (15 minutes) ldap_sudo_use_host_filter (boolean) If true, SSSD will download only rules that are applicable to this machine (using the IPv4 or IPv6 host/network addresses and hostnames). Default: true ldap_sudo_hostnames (string) Space separated list of hostnames or fully qualified domain names that should be used to filter the rules. If this option is empty, SSSD will try to discover the hostname and the fully qualified domain name automatically. If ldap_sudo_use_host_filter is false then this option has no effect. Default: not specified ldap_sudo_ip (string) Space separated list of IPv4 or IPv6 host/network addresses that should be used to filter the rules. If this option is empty, SSSD will try to discover the addresses automatically. If ldap_sudo_use_host_filter is false then this option has no effect. Default: not specified ldap_sudo_include_netgroups (boolean) If true then SSSD will download every rule that contains a netgroup in sudoHost attribute. If ldap_sudo_use_host_filter is false then this option has no effect. Default: true ldap_sudo_include_regexp (boolean) If true then SSSD will download every rule that contains a wildcard in sudoHost attribute. If ldap_sudo_use_host_filter is false then this option has no effect. Default: true This manual page only describes attribute name mapping. For detailed explanation of sudo related attribute semantics, see sudoers.ldap5 AUTOFS OPTIONS Some of the defaults for the parameters below are dependent on the LDAP schema. ldap_autofs_map_master_name (string) The name of the automount master map in LDAP. Default: auto.master ldap_autofs_map_object_class (string) The object class of an automount map entry in LDAP. Default: automountMap ldap_autofs_map_name (string) The name of an automount map entry in LDAP. Default: ou (rfc2307), automountMapName (rfc2307bis, ipa, ad) ldap_autofs_entry_object_class (string) The object class of an automount entry in LDAP. The entry usually corresponds to a mount point. Default: automount ldap_autofs_entry_key (string) The key of an automount entry in LDAP. The entry usually corresponds to a mount point. Default: cn (rfc2307), automountKey (rfc2307bis, ipa, ad) ldap_autofs_entry_value (string) The key of an automount entry in LDAP. The entry usually corresponds to a mount point. Default: automountInformation ADVANCED OPTIONS These options are supported by LDAP domains, but they should be used with caution. Please include them in your configuration only if you know what you are doing. ldap_netgroup_search_base (string) ldap_user_search_base (string) ldap_group_search_base (string) If the option ldap_use_tokengroups is enabled. The searches against Active Directory will not be restricted and return all groups memberships, even with no gid mapping. It is recommended to disable this feature, if group names are not being displayed correctly. ldap_sudo_search_base (string) ldap_autofs_search_base (string) EXAMPLE The following example assumes that SSSD is correctly configured and LDAP is set to one of the domains in the [domains] section. [domain/LDAP] id_provider = ldap auth_provider = ldap ldap_uri = ldap://ldap.mydomain.org ldap_search_base = dc=mydomain,dc=org ldap_tls_reqcert = demand cache_credentials = true LDAP ACCESS FILTER EXAMPLE The following example assumes that SSSD is correctly configured and to use the ldap_access_order=lockout. [domain/LDAP] id_provider = ldap auth_provider = ldap access_provider = ldap ldap_access_order = lockout ldap_pwdlockout_dn = cn=ppolicy,ou=policies,dc=mydomain,dc=org ldap_uri = ldap://ldap.mydomain.org ldap_search_base = dc=mydomain,dc=org ldap_tls_reqcert = demand cache_credentials = true NOTES The descriptions of some of the configuration options in this manual page are based on the ldap.conf 5 manual page from the OpenLDAP 2.4 distribution. sssd-1.13.4/src/PaxHeaders.16287/build_macros.m40000644000000000000000000000007412703456111016021 xustar0030 atime=1460561754.180724206 30 ctime=1460561774.294792408 sssd-1.13.4/src/build_macros.m40000644002412700241270000000346012703456111017473 0ustar00jhrozekjhrozek00000000000000AC_DEFUN([BUILD_WITH_SHARED_BUILD_DIR], [ AC_ARG_WITH([shared-build-dir], [AC_HELP_STRING([--with-shared-build-dir=DIR], [temporary build directory where libraries are installed [$srcdir/sharedbuild]])]) sharedbuilddir="$srcdir/sharedbuild" if test x"$with_shared_build_dir" != x; then sharedbuilddir=$with_shared_build_dir CFLAGS="$CFLAGS -I$with_shared_build_dir/include" CPPFLAGS="$CPPFLAGS -I$with_shared_build_dir/include" LDFLAGS="$LDFLAGS -L$with_shared_build_dir/lib" fi AC_SUBST(sharedbuilddir) ]) AC_DEFUN([BUILD_WITH_AUX_INFO], [ AC_ARG_WITH([aux-info], [AC_HELP_STRING([--with-aux-info], [Build with -aux-info output])]) ]) AM_CONDITIONAL([WANT_AUX_INFO], [test x$with_aux_info = xyes]) dnl AC_CONFIG_FILES conditionalization requires using AM_COND_IF, however dnl dnl AM_COND_IF is new to Automake 1.11. To use it on new Automake without dnl dnl requiring same, a fallback implementation for older Autoconf is provided. dnl dnl Note that disabling of AC_CONFIG_FILES requires Automake 1.11, this code dnl dnl is correct only in terms of m4sh generated script. m4_ifndef([AM_COND_IF], [AC_DEFUN([AM_COND_IF], [ if test -z "$$1_TRUE"; then : m4_n([$2])[]dnl m4_ifval([$3], [else $3 ])dnl fi[]dnl ])]) dnl SSS_AC_EXPAND_LIB_DIR() prepare variable sss_extra_libdir, dnl variable will contain expanded version of string "$libdir" dnl therefore this variable can be safely added to LDFLAGS as dnl "-L$sss_extra_libdir ". AC_DEFUN([SSS_AC_EXPAND_LIB_DIR], [ AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) dnl By default, look in $includedir and $libdir. AC_LIB_WITH_FINAL_PREFIX([ eval additional_libdir=\"$libdir\" ]) sss_extra_libdir="$additional_libdir" ]) sssd-1.13.4/src/PaxHeaders.16287/providers0000644000000000000000000000013212703463557015063 xustar0030 mtime=1460561775.059795002 30 atime=1460561776.118798593 30 ctime=1460561775.059795002 sssd-1.13.4/src/providers/0000755002412700241270000000000012703463557016614 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/providers/PaxHeaders.16287/dp_dyndns.h0000644000000000000000000000007412703456111017264 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.525793191 sssd-1.13.4/src/providers/dp_dyndns.h0000644002412700241270000001117012703456111020733 0ustar00jhrozekjhrozek00000000000000/* SSSD dp_dyndns.h Authors: Jakub Hrozek Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DP_DYNDNS_H_ #define DP_DYNDNS_H_ /* dynamic dns helpers */ struct sss_iface_addr; typedef void (*nsupdate_timer_fn_t)(void *pvt); enum be_nsupdate_auth { BE_NSUPDATE_AUTH_NONE, BE_NSUPDATE_AUTH_GSS_TSIG, }; struct be_nsupdate_ctx { struct dp_option *opts; enum be_nsupdate_auth auth_type; time_t last_refresh; bool timer_in_progress; struct tevent_timer *refresh_timer; nsupdate_timer_fn_t timer_callback; void *timer_pvt; }; enum dp_dyndns_opts { DP_OPT_DYNDNS_UPDATE, DP_OPT_DYNDNS_REFRESH_INTERVAL, DP_OPT_DYNDNS_IFACE, DP_OPT_DYNDNS_TTL, DP_OPT_DYNDNS_UPDATE_PTR, DP_OPT_DYNDNS_FORCE_TCP, DP_OPT_DYNDNS_AUTH, DP_OPT_DYNDNS_SERVER, DP_OPT_DYNDNS /* attrs counter */ }; #define DYNDNS_REMOVE_A 0x1 #define DYNDNS_REMOVE_AAAA 0x2 errno_t be_nsupdate_check(void); errno_t be_nsupdate_init(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct dp_option *defopts, struct be_nsupdate_ctx **_ctx); errno_t be_nsupdate_init_timer(struct be_nsupdate_ctx *ctx, struct tevent_context *ev, nsupdate_timer_fn_t timer_callback, void *timer_pvt); void be_nsupdate_timer_schedule(struct tevent_context *ev, struct be_nsupdate_ctx *ctx); errno_t sss_iface_addr_list_get(TALLOC_CTX *mem_ctx, const char *ifname, struct sss_iface_addr **_addrlist); errno_t sss_iface_addr_list_as_str_list(TALLOC_CTX *mem_ctx, struct sss_iface_addr *ifaddr_list, char ***_straddrs); errno_t be_nsupdate_create_fwd_msg(TALLOC_CTX *mem_ctx, const char *realm, const char *servername, const char *hostname, const unsigned int ttl, uint8_t remove_af, struct sss_iface_addr *addresses, char **_update_msg); errno_t be_nsupdate_create_ptr_msg(TALLOC_CTX *mem_ctx, const char *realm, const char *servername, const char *hostname, const unsigned int ttl, struct sockaddr_storage *address, bool delete, char **_update_msg); /* Returns: * * ERR_OK - on success * * ERR_DYNDNS_FAILED - if nsupdate fails for any reason * * ERR_DYNDNS_TIMEOUT - if the update times out. child_status * is ETIMEDOUT in this case */ struct tevent_req *be_nsupdate_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, enum be_nsupdate_auth auth_type, char *nsupdate_msg, bool force_tcp); errno_t be_nsupdate_recv(struct tevent_req *req, int *child_status); struct tevent_req * nsupdate_get_addrs_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_resolv_ctx *be_res, const char *hostname); errno_t nsupdate_get_addrs_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sss_iface_addr **_addrlist, size_t *_count); void sss_iface_addr_concatenate(struct sss_iface_addr **list, struct sss_iface_addr *list2); errno_t sss_get_dualstack_addresses(TALLOC_CTX *mem_ctx, struct sockaddr *ss, struct sss_iface_addr **_iface_addrs); struct sss_iface_addr * sss_iface_addr_get_next(struct sss_iface_addr *address); struct sockaddr_storage* sss_iface_addr_get_address(struct sss_iface_addr *address); #endif /* DP_DYNDNS_H_ */ sssd-1.13.4/src/providers/PaxHeaders.16287/data_provider_req.h0000644000000000000000000000007412703456111020774 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.522793181 sssd-1.13.4/src/providers/data_provider_req.h0000644002412700241270000000321212703456111022441 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider -- backend request Copyright (C) Petr Cech 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __DATA_PROVIDER_REQ__ #define __DATA_PROVIDER_REQ__ #include #define BE_REQ_USER 0x0001 #define BE_REQ_GROUP 0x0002 #define BE_REQ_INITGROUPS 0x0003 #define BE_REQ_NETGROUP 0x0004 #define BE_REQ_SERVICES 0x0005 #define BE_REQ_SUDO_FULL 0x0006 #define BE_REQ_SUDO_RULES 0x0007 #define BE_REQ_AUTOFS 0x0009 #define BE_REQ_HOST 0x0010 #define BE_REQ_BY_SECID 0x0011 #define BE_REQ_USER_AND_GROUP 0x0012 #define BE_REQ_BY_UUID 0x0013 #define BE_REQ_BY_CERT 0x0014 #define BE_REQ_TYPE_MASK 0x00FF #define BE_REQ_FAST 0x1000 /** * @brief Convert request type to string for logging purpose. * * @param[in] req_type Type of request. * @return Pointer to string with request type. There could be 'fast' flag. */ const char *be_req2str(dbus_uint32_t req_type); #endif /* __DATA_PROVIDER_REQ__ */ sssd-1.13.4/src/providers/PaxHeaders.16287/fail_over_srv.h0000644000000000000000000000007412703456111020142 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.534793222 sssd-1.13.4/src/providers/fail_over_srv.h0000644002412700241270000001252612703456111021617 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __FAIL_OVER_SRV_H__ #define __FAIL_OVER_SRV_H__ #include #include #include "resolv/async_resolv.h" /* SRV lookup plugin interface */ struct fo_server_info { char *host; int port; unsigned short priority; }; /* * If discovery_domain is NULL, it should be detected automatically. */ typedef struct tevent_req * (*fo_srv_lookup_plugin_send_t)(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *service, const char *protocol, const char *discovery_domain, void *pvt); /* * Returns: * EOK - at least one primary or backup server was found * ERR_SRV_NOT_FOUND - no primary nor backup server found * ERR_SRV_LOOKUP_ERROR - error communicating with SRV database * other code - depends on plugin * * If EOK is returned: * - and no primary server is found: * *_primary_servers = NULL * *_num_primary_servers = 0 * - and no backup server is found: * *_backup_servers = NULL * *_num_backup_servers = 0 * - *_dns_domain = DNS domain name where the servers were found */ typedef errno_t (*fo_srv_lookup_plugin_recv_t)(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain, uint32_t *_ttl, struct fo_server_info **_primary_servers, size_t *_num_primary_servers, struct fo_server_info **_backup_servers, size_t *_num_backup_servers); struct tevent_req *fo_discover_srv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv_ctx, const char *service, const char *protocol, const char **discovery_domains); errno_t fo_discover_srv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain, uint32_t *_ttl, struct fo_server_info **_servers, size_t *_num_servers); struct tevent_req *fo_discover_servers_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv_ctx, const char *service, const char *protocol, const char *primary_domain, const char *backup_domain); errno_t fo_discover_servers_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain, uint32_t *_ttl, struct fo_server_info **_primary_servers, size_t *_num_primary_servers, struct fo_server_info **_backup_servers, size_t *_num_backup_servers); /* Simple SRV lookup plugin */ struct fo_resolve_srv_dns_ctx; struct fo_resolve_srv_dns_ctx * fo_resolve_srv_dns_ctx_init(TALLOC_CTX *mem_ctx, struct resolv_ctx *resolv_ctx, enum restrict_family family_order, enum host_database *host_dbs, const char *hostname, const char *sssd_domain); struct tevent_req *fo_resolve_srv_dns_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *service, const char *protocol, const char *discovery_domain, void *pvt); errno_t fo_resolve_srv_dns_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain, uint32_t *_ttl, struct fo_server_info **_primary_servers, size_t *_num_primary_servers, struct fo_server_info **_backup_servers, size_t *_num_backup_servers); #endif /* __FAIL_OVER_SRV_H__ */ sssd-1.13.4/src/providers/PaxHeaders.16287/dp_ptask.c0000644000000000000000000000007412703456111017102 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.659793646 sssd-1.13.4/src/providers/dp_ptask.c0000644002412700241270000003330412703456111020554 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "providers/dp_backend.h" #include "providers/dp_ptask_private.h" #include "providers/dp_ptask.h" #define backoff_allowed(ptask) (ptask->max_backoff != 0) enum be_ptask_schedule { BE_PTASK_SCHEDULE_FROM_NOW, BE_PTASK_SCHEDULE_FROM_LAST }; enum be_ptask_delay { BE_PTASK_FIRST_DELAY, BE_PTASK_ENABLED_DELAY, BE_PTASK_PERIOD }; static void be_ptask_schedule(struct be_ptask *task, enum be_ptask_delay delay_type, enum be_ptask_schedule from); static int be_ptask_destructor(void *pvt) { struct be_ptask *task; task = talloc_get_type(pvt, struct be_ptask); if (task == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "BUG: task is NULL\n"); return 0; } DEBUG(SSSDBG_TRACE_FUNC, "Terminating periodic task [%s]\n", task->name); return 0; } static void be_ptask_online_cb(void *pvt) { struct be_ptask *task = NULL; task = talloc_get_type(pvt, struct be_ptask); if (task == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "BUG: task is NULL\n"); return; } DEBUG(SSSDBG_TRACE_FUNC, "Back end is online\n"); be_ptask_enable(task); } static void be_ptask_offline_cb(void *pvt) { struct be_ptask *task = NULL; task = talloc_get_type(pvt, struct be_ptask); DEBUG(SSSDBG_TRACE_FUNC, "Back end is offline\n"); be_ptask_disable(task); } static void be_ptask_timeout(struct tevent_context *ev, struct tevent_timer *tt, struct timeval tv, void *pvt) { struct be_ptask *task = NULL; task = talloc_get_type(pvt, struct be_ptask); DEBUG(SSSDBG_OP_FAILURE, "Task [%s]: timed out\n", task->name); talloc_zfree(task->req); be_ptask_schedule(task, BE_PTASK_PERIOD, BE_PTASK_SCHEDULE_FROM_NOW); } static void be_ptask_done(struct tevent_req *req); static void be_ptask_execute(struct tevent_context *ev, struct tevent_timer *tt, struct timeval tv, void *pvt) { struct be_ptask *task = NULL; struct tevent_timer *timeout = NULL; task = talloc_get_type(pvt, struct be_ptask); task->timer = NULL; /* timer is freed by tevent */ if (be_is_offline(task->be_ctx)) { DEBUG(SSSDBG_TRACE_FUNC, "Back end is offline\n"); switch (task->offline) { case BE_PTASK_OFFLINE_SKIP: be_ptask_schedule(task, BE_PTASK_PERIOD, BE_PTASK_SCHEDULE_FROM_NOW); return; case BE_PTASK_OFFLINE_DISABLE: /* This case is normally handled by offline callback but we * should handle it here as well since we can get here in some * special cases for example unit tests or tevent events order. */ be_ptask_disable(task); return; case BE_PTASK_OFFLINE_EXECUTE: /* continue */ break; } } DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: executing task, timeout %lu " "seconds\n", task->name, task->timeout); task->last_execution = tv.tv_sec; task->req = task->send_fn(task, task->ev, task->be_ctx, task, task->pvt); if (task->req == NULL) { /* skip this iteration and try again later */ DEBUG(SSSDBG_OP_FAILURE, "Task [%s]: failed to execute task, " "will try again later\n", task->name); be_ptask_schedule(task, BE_PTASK_PERIOD, BE_PTASK_SCHEDULE_FROM_NOW); return; } tevent_req_set_callback(task->req, be_ptask_done, task); /* schedule timeout */ if (task->timeout > 0) { tv = tevent_timeval_current_ofs(task->timeout, 0); timeout = tevent_add_timer(task->ev, task->req, tv, be_ptask_timeout, task); if (timeout == NULL) { /* If we can't guarantee a timeout, * we need to cancel the request. */ talloc_zfree(task->req); DEBUG(SSSDBG_OP_FAILURE, "Task [%s]: failed to set timeout, " "the task will be rescheduled\n", task->name); be_ptask_schedule(task, BE_PTASK_PERIOD, BE_PTASK_SCHEDULE_FROM_NOW); } } return; } static void be_ptask_done(struct tevent_req *req) { struct be_ptask *task = NULL; errno_t ret; task = tevent_req_callback_data(req, struct be_ptask); ret = task->recv_fn(req); talloc_zfree(req); task->req = NULL; switch (ret) { case EOK: DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: finished successfully\n", task->name); be_ptask_schedule(task, BE_PTASK_PERIOD, BE_PTASK_SCHEDULE_FROM_LAST); break; default: DEBUG(SSSDBG_OP_FAILURE, "Task [%s]: failed with [%d]: %s\n", task->name, ret, sss_strerror(ret)); be_ptask_schedule(task, BE_PTASK_PERIOD, BE_PTASK_SCHEDULE_FROM_NOW); break; } } static void be_ptask_schedule(struct be_ptask *task, enum be_ptask_delay delay_type, enum be_ptask_schedule from) { struct timeval tv = { 0, }; time_t delay = 0; if (!task->enabled) { DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: disabled\n", task->name); return; } switch (delay_type) { case BE_PTASK_FIRST_DELAY: delay = task->first_delay; break; case BE_PTASK_ENABLED_DELAY: delay = task->enabled_delay; break; case BE_PTASK_PERIOD: delay = task->period; if (backoff_allowed(task) && task->period * 2 <= task->max_backoff) { /* double the period for the next execution */ task->period *= 2; } break; } /* add random offset */ if (task->random_offset != 0) { delay = delay + (rand_r(&task->ro_seed) % task->random_offset); } switch (from) { case BE_PTASK_SCHEDULE_FROM_NOW: tv = tevent_timeval_current_ofs(delay, 0); DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: scheduling task %lu seconds " "from now [%lu]\n", task->name, delay, tv.tv_sec); break; case BE_PTASK_SCHEDULE_FROM_LAST: tv = tevent_timeval_set(task->last_execution + delay, 0); DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: scheduling task %lu seconds " "from last execution time [%lu]\n", task->name, delay, tv.tv_sec); break; } if (task->timer != NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Task [%s]: another timer is already " "active?\n", task->name); talloc_zfree(task->timer); } task->timer = tevent_add_timer(task->ev, task, tv, be_ptask_execute, task); if (task->timer == NULL) { /* nothing we can do about it */ DEBUG(SSSDBG_CRIT_FAILURE, "FATAL: Unable to schedule task [%s]\n", task->name); be_ptask_disable(task); } task->next_execution = tv.tv_sec; } errno_t be_ptask_create(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, time_t period, time_t first_delay, time_t enabled_delay, time_t random_offset, time_t timeout, enum be_ptask_offline offline, time_t max_backoff, be_ptask_send_t send_fn, be_ptask_recv_t recv_fn, void *pvt, const char *name, struct be_ptask **_task) { struct be_ptask *task = NULL; errno_t ret; if (be_ctx == NULL || period == 0 || send_fn == NULL || recv_fn == NULL || name == NULL) { return EINVAL; } task = talloc_zero(mem_ctx, struct be_ptask); if (task == NULL) { ret = ENOMEM; goto done; } task->ev = be_ctx->ev; task->be_ctx = be_ctx; task->period = period; task->orig_period = period; task->first_delay = first_delay; task->enabled_delay = enabled_delay; task->random_offset = random_offset; task->ro_seed = time(NULL) * getpid(); task->max_backoff = max_backoff; task->timeout = timeout; task->offline = offline; task->send_fn = send_fn; task->recv_fn = recv_fn; task->pvt = pvt; task->name = talloc_strdup(task, name); if (task->name == NULL) { ret = ENOMEM; goto done; } task->enabled = true; talloc_set_destructor((TALLOC_CTX*)task, be_ptask_destructor); if (offline == BE_PTASK_OFFLINE_DISABLE) { /* install offline and online callbacks */ ret = be_add_online_cb(task, be_ctx, be_ptask_online_cb, task, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to install online callback [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = be_add_offline_cb(task, be_ctx, be_ptask_offline_cb, task, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to install offline callback [%d]: %s\n", ret, sss_strerror(ret)); goto done; } } DEBUG(SSSDBG_TRACE_FUNC, "Periodic task [%s] was created\n", task->name); be_ptask_schedule(task, BE_PTASK_FIRST_DELAY, BE_PTASK_SCHEDULE_FROM_NOW); if (_task != NULL) { *_task = task; } ret = EOK; done: if (ret != EOK) { talloc_free(task); } return ret; } void be_ptask_enable(struct be_ptask *task) { if (task->enabled) { DEBUG(SSSDBG_MINOR_FAILURE, "Task [%s]: already enabled\n", task->name); return; } DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: enabling task\n", task->name); task->enabled = true; be_ptask_schedule(task, BE_PTASK_ENABLED_DELAY, BE_PTASK_SCHEDULE_FROM_NOW); } /* Disable the task, but if a request already in progress, let it finish. */ void be_ptask_disable(struct be_ptask *task) { DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: disabling task\n", task->name); talloc_zfree(task->timer); task->enabled = false; task->period = task->orig_period; } void be_ptask_destroy(struct be_ptask **task) { talloc_zfree(*task); } time_t be_ptask_get_period(struct be_ptask *task) { return task->period; } time_t be_ptask_get_timeout(struct be_ptask *task) { return task->timeout; } struct be_ptask_sync_ctx { be_ptask_sync_t fn; void *pvt; }; struct be_ptask_sync_state { int dummy; }; /* This is not an asynchronous request so there is not any _done function. */ static struct tevent_req * be_ptask_sync_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct be_ptask_sync_ctx *ctx = NULL; struct be_ptask_sync_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct be_ptask_sync_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } ctx = talloc_get_type(pvt, struct be_ptask_sync_ctx); ret = ctx->fn(mem_ctx, ev, be_ctx, be_ptask, ctx->pvt); if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t be_ptask_sync_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } errno_t be_ptask_create_sync(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, time_t period, time_t first_delay, time_t enabled_delay, time_t random_offset, time_t timeout, enum be_ptask_offline offline, time_t max_backoff, be_ptask_sync_t fn, void *pvt, const char *name, struct be_ptask **_task) { errno_t ret; struct be_ptask_sync_ctx *ctx = NULL; ctx = talloc_zero(mem_ctx, struct be_ptask_sync_ctx); if (ctx == NULL) { ret = ENOMEM; goto done; } ctx->fn = fn; ctx->pvt = pvt; ret = be_ptask_create(mem_ctx, be_ctx, period, first_delay, enabled_delay, random_offset, timeout, offline, max_backoff, be_ptask_sync_send, be_ptask_sync_recv, ctx, name, _task); if (ret != EOK) { goto done; } talloc_steal(*_task, ctx); ret = EOK; done: if (ret != EOK) { talloc_free(ctx); } return ret; } sssd-1.13.4/src/providers/PaxHeaders.16287/data_provider_iface_generated.c0000644000000000000000000000007412703456111023265 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.662793656 sssd-1.13.4/src/providers/data_provider_iface_generated.c0000644002412700241270000000565512703456111024747 0ustar00jhrozekjhrozek00000000000000/* The following definitions are auto-generated from data_provider_iface.xml */ #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_meta.h" #include "sbus/sssd_dbus_invokers.h" #include "data_provider_iface_generated.h" /* methods for org.freedesktop.sssd.dataprovider */ const struct sbus_method_meta data_provider_iface__methods[] = { { "RegisterService", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct data_provider_iface, RegisterService), NULL, /* no invoker */ }, { "pamHandler", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct data_provider_iface, pamHandler), NULL, /* no invoker */ }, { "sudoHandler", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct data_provider_iface, sudoHandler), NULL, /* no invoker */ }, { "autofsHandler", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct data_provider_iface, autofsHandler), NULL, /* no invoker */ }, { "hostHandler", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct data_provider_iface, hostHandler), NULL, /* no invoker */ }, { "getDomains", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct data_provider_iface, getDomains), NULL, /* no invoker */ }, { "getAccountInfo", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct data_provider_iface, getAccountInfo), NULL, /* no invoker */ }, { NULL, } }; /* interface info for org.freedesktop.sssd.dataprovider */ const struct sbus_interface_meta data_provider_iface_meta = { "org.freedesktop.sssd.dataprovider", /* name */ data_provider_iface__methods, NULL, /* no signals */ NULL, /* no properties */ sbus_invoke_get_all, /* GetAll invoker */ }; /* methods for org.freedesktop.sssd.dataprovider_rev */ const struct sbus_method_meta data_provider_rev_iface__methods[] = { { "updateCache", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct data_provider_rev_iface, updateCache), NULL, /* no invoker */ }, { "initgrCheck", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct data_provider_rev_iface, initgrCheck), NULL, /* no invoker */ }, { NULL, } }; /* interface info for org.freedesktop.sssd.dataprovider_rev */ const struct sbus_interface_meta data_provider_rev_iface_meta = { "org.freedesktop.sssd.dataprovider_rev", /* name */ data_provider_rev_iface__methods, NULL, /* no signals */ NULL, /* no properties */ sbus_invoke_get_all, /* GetAll invoker */ }; sssd-1.13.4/src/providers/PaxHeaders.16287/fail_over_srv.c0000644000000000000000000000007412703456111020135 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.665793666 sssd-1.13.4/src/providers/fail_over_srv.c0000644002412700241270000005055412703456111021615 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "resolv/async_resolv.h" #include "providers/fail_over_srv.h" struct fo_discover_srv_state { char *dns_domain; struct fo_server_info *servers; size_t num_servers; uint32_t ttl; }; static void fo_discover_srv_done(struct tevent_req *subreq); struct tevent_req *fo_discover_srv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv_ctx, const char *service, const char *protocol, const char **discovery_domains) { struct fo_discover_srv_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct fo_discover_srv_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } subreq = resolv_discover_srv_send(state, ev, resolv_ctx, service, protocol, discovery_domains); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, fo_discover_srv_done, req); return req; immediately: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void fo_discover_srv_done(struct tevent_req *subreq) { struct fo_discover_srv_state *state = NULL; struct tevent_req *req = NULL; struct ares_srv_reply *reply_list = NULL; struct ares_srv_reply *record = NULL; int i; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct fo_discover_srv_state); ret = resolv_discover_srv_recv(state, subreq, &reply_list, &state->ttl, &state->dns_domain); talloc_zfree(subreq); if (ret == ENOENT) { ret = ERR_SRV_NOT_FOUND; goto done; } else if (ret == EIO) { ret = ERR_SRV_LOOKUP_ERROR; goto done; } else if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Got answer. Processing...\n"); /* sort and store the answer */ ret = resolv_sort_srv_reply(&reply_list); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not sort the answers from DNS " "[%d]: %s\n", ret, strerror(ret)); goto done; } state->num_servers = 0; for (record = reply_list; record != NULL; record = record->next) { state->num_servers++; } DEBUG(SSSDBG_TRACE_FUNC, "Got %zu servers\n", state->num_servers); state->servers = talloc_array(state, struct fo_server_info, state->num_servers); if (state->servers == NULL) { ret = ENOMEM; goto done; } for (record = reply_list, i = 0; record != NULL; record = record->next, i++) { state->servers[i].host = talloc_steal(state->servers, record->host); state->servers[i].port = record->port; state->servers[i].priority = record->priority; } talloc_zfree(reply_list); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } errno_t fo_discover_srv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain, uint32_t *_ttl, struct fo_server_info **_servers, size_t *_num_servers) { struct fo_discover_srv_state *state = NULL; state = tevent_req_data(req, struct fo_discover_srv_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_dns_domain != NULL) { *_dns_domain = talloc_steal(mem_ctx, state->dns_domain); } if (_servers != NULL) { *_servers = talloc_steal(mem_ctx, state->servers); } if (_ttl != NULL) { *_ttl = state->ttl; } if (_num_servers != NULL) { *_num_servers = state->num_servers; } return EOK; } struct fo_discover_servers_state { struct tevent_context *ev; struct resolv_ctx *resolv_ctx; const char *service; const char *protocol; const char *primary_domain; const char *backup_domain; char *dns_domain; uint32_t ttl; struct fo_server_info *primary_servers; size_t num_primary_servers; struct fo_server_info *backup_servers; size_t num_backup_servers; }; static void fo_discover_servers_primary_done(struct tevent_req *subreq); static void fo_discover_servers_backup_done(struct tevent_req *subreq); struct tevent_req *fo_discover_servers_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv_ctx, const char *service, const char *protocol, const char *primary_domain, const char *backup_domain) { struct fo_discover_servers_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; const char **domains = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct fo_discover_servers_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } if (primary_domain == NULL) { if (backup_domain == NULL) { state->primary_servers = NULL; state->num_primary_servers = 0; state->backup_servers = NULL; state->num_backup_servers = 0; state->dns_domain = NULL; state->ttl = 0; ret = EOK; goto immediately; } else { primary_domain = backup_domain; backup_domain = NULL; } } state->ev = ev; state->resolv_ctx = resolv_ctx; state->service = talloc_strdup(state, service); if (state->service == NULL) { ret = ENOMEM; goto immediately; } state->protocol = talloc_strdup(state, protocol); if (state->protocol == NULL) { ret = ENOMEM; goto immediately; } state->primary_domain = talloc_strdup(state, primary_domain); if (state->primary_domain == NULL) { ret = ENOMEM; goto immediately; } state->backup_domain = talloc_strdup(state, backup_domain); if (state->backup_domain == NULL && backup_domain != NULL) { ret = ENOMEM; goto immediately; } DEBUG(SSSDBG_TRACE_FUNC, "Looking up primary servers\n"); domains = talloc_zero_array(state, const char *, 3); if (domains == NULL) { ret = ENOMEM; goto immediately; } domains[0] = state->primary_domain; domains[1] = state->backup_domain; subreq = fo_discover_srv_send(state, ev, resolv_ctx, state->service, state->protocol, domains); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, fo_discover_servers_primary_done, req); return req; immediately: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void fo_discover_servers_primary_done(struct tevent_req *subreq) { struct fo_discover_servers_state *state = NULL; struct tevent_req *req = NULL; const char **domains = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct fo_discover_servers_state); ret = fo_discover_srv_recv(state, subreq, &state->dns_domain, &state->ttl, &state->primary_servers, &state->num_primary_servers); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve primary servers " "[%d]: %s\n", ret, sss_strerror(ret)); if (ret != ERR_SRV_NOT_FOUND && ret != ERR_SRV_LOOKUP_ERROR) { /* abort on system error */ goto done; } } if (state->backup_domain == NULL) { /* if there is no backup domain, we are done */ DEBUG(SSSDBG_TRACE_FUNC, "No backup domain specified\n"); goto done; } if (state->dns_domain != NULL && strcasecmp(state->dns_domain, state->backup_domain) == 0) { /* If there was no error and dns_domain is the same as backup domain, * it means that we were unable to resolve SRV in primary domain, but * SRV from backup domain was resolved and those servers are considered * to be primary. We are done. */ state->backup_servers = NULL; state->num_backup_servers = 0; ret = EOK; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Looking up backup servers\n"); domains = talloc_zero_array(state, const char *, 2); if (domains == NULL) { ret = ENOMEM; goto done; } domains[0] = state->backup_domain; subreq = fo_discover_srv_send(state, state->ev, state->resolv_ctx, state->service, state->protocol, domains); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, fo_discover_servers_backup_done, req); ret = EAGAIN; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static void fo_discover_servers_backup_done(struct tevent_req *subreq) { struct fo_discover_servers_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct fo_discover_servers_state); ret = fo_discover_srv_recv(state, subreq, NULL, NULL, &state->backup_servers, &state->num_backup_servers); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to retrieve backup servers " "[%d]: %s\n", ret, sss_strerror(ret)); if (ret == ERR_SRV_NOT_FOUND || ret == ERR_SRV_LOOKUP_ERROR) { /* we have successfully fetched primary servers, so we will * finish the request normally on non system error */ ret = EOK; } } if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } errno_t fo_discover_servers_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain, uint32_t *_ttl, struct fo_server_info **_primary_servers, size_t *_num_primary_servers, struct fo_server_info **_backup_servers, size_t *_num_backup_servers) { struct fo_discover_servers_state *state = NULL; state = tevent_req_data(req, struct fo_discover_servers_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_primary_servers) { *_primary_servers = talloc_steal(mem_ctx, state->primary_servers); } if (_num_primary_servers) { *_num_primary_servers = state->num_primary_servers; } if (_backup_servers) { *_backup_servers = talloc_steal(mem_ctx, state->backup_servers); } if (_num_backup_servers) { *_num_backup_servers = state->num_backup_servers; } if (_dns_domain) { *_dns_domain = talloc_steal(mem_ctx, state->dns_domain); } if (_ttl) { *_ttl = state->ttl; } return EOK; } struct fo_resolve_srv_dns_ctx { struct resolv_ctx *resolv_ctx; enum restrict_family family_order; enum host_database *host_dbs; char *hostname; char *sssd_domain; char *detected_domain; }; struct fo_resolve_srv_dns_state { struct tevent_context *ev; struct fo_resolve_srv_dns_ctx *ctx; const char *service; const char *protocol; const char *discovery_domain; char *dns_domain; uint32_t ttl; struct fo_server_info *servers; size_t num_servers; }; static void fo_resolve_srv_dns_domain_done(struct tevent_req *subreq); static errno_t fo_resolve_srv_dns_discover(struct tevent_req *req); static void fo_resolve_srv_dns_done(struct tevent_req *subreq); struct fo_resolve_srv_dns_ctx * fo_resolve_srv_dns_ctx_init(TALLOC_CTX *mem_ctx, struct resolv_ctx *resolv_ctx, enum restrict_family family_order, enum host_database *host_dbs, const char *hostname, const char *sssd_domain) { struct fo_resolve_srv_dns_ctx *ctx = NULL; ctx = talloc_zero(mem_ctx, struct fo_resolve_srv_dns_ctx); if (ctx == NULL) { return NULL; } ctx->resolv_ctx = resolv_ctx; ctx->family_order = family_order; ctx->host_dbs = host_dbs; ctx->hostname = talloc_strdup(ctx, hostname); if (ctx->hostname == NULL) { goto fail; } ctx->sssd_domain = talloc_strdup(ctx, sssd_domain); if (ctx->sssd_domain == NULL) { goto fail; } return ctx; fail: talloc_free(ctx); return NULL; } struct tevent_req *fo_resolve_srv_dns_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *service, const char *protocol, const char *discovery_domain, void *pvt) { struct fo_resolve_srv_dns_state *state = NULL; struct fo_resolve_srv_dns_ctx *ctx = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct fo_resolve_srv_dns_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } ctx = talloc_get_type(pvt, struct fo_resolve_srv_dns_ctx); if (ctx == NULL) { ret = EINVAL; goto immediately; } state->ev = ev; state->ctx = ctx; state->service = service; state->protocol = protocol; if (discovery_domain == NULL) { state->discovery_domain = NULL; } else { state->discovery_domain = discovery_domain; } if (discovery_domain == NULL && ctx->detected_domain == NULL) { /* we will try to detect proper discovery domain */ subreq = resolv_get_domain_send(state, state->ev, ctx->resolv_ctx, ctx->hostname, ctx->host_dbs, ctx->family_order); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, fo_resolve_srv_dns_domain_done, req); } else { /* we will use either provided or previously detected * discovery domain */ ret = fo_resolve_srv_dns_discover(req); if (ret != EAGAIN) { goto immediately; } } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void fo_resolve_srv_dns_domain_done(struct tevent_req *subreq) { struct fo_resolve_srv_dns_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct fo_resolve_srv_dns_state); ret = resolv_get_domain_recv(state->ctx, subreq, &state->ctx->detected_domain); talloc_zfree(subreq); if (ret != EOK) { goto done; } ret = fo_resolve_srv_dns_discover(req); done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static errno_t fo_resolve_srv_dns_discover(struct tevent_req *req) { struct fo_resolve_srv_dns_state *state = NULL; struct fo_resolve_srv_dns_ctx *ctx = NULL; struct tevent_req *subreq = NULL; const char **domains = NULL; errno_t ret; state = tevent_req_data(req, struct fo_resolve_srv_dns_state); ctx = state->ctx; domains = talloc_zero_array(state, const char *, 3); if (domains == NULL) { ret = ENOMEM; goto done; } if (state->discovery_domain == NULL) { /* we will use detected domain with SSSD domain as fallback */ domains[0] = talloc_strdup(domains, ctx->detected_domain); if (domains[0] == NULL) { ret = ENOMEM; goto done; } if (strcasecmp(ctx->detected_domain, ctx->sssd_domain) != 0) { domains[1] = talloc_strdup(domains, ctx->sssd_domain); if (domains[1] == NULL) { ret = ENOMEM; goto done; } } } else { /* We will use only discovery domain that was provided via plugin * interface. We don't have to dup here because it is already on * state. */ domains[0] = state->discovery_domain; } subreq = fo_discover_srv_send(state, state->ev, ctx->resolv_ctx, state->service, state->protocol, domains); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, fo_resolve_srv_dns_done, req); ret = EAGAIN; done: if (ret != EAGAIN) { talloc_free(domains); } return ret; } static void fo_resolve_srv_dns_done(struct tevent_req *subreq) { struct fo_resolve_srv_dns_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct fo_resolve_srv_dns_state); ret = fo_discover_srv_recv(state, subreq, &state->dns_domain, &state->ttl, &state->servers, &state->num_servers); talloc_zfree(subreq); if (ret != EOK) { goto done; } done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } errno_t fo_resolve_srv_dns_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain, uint32_t *_ttl, struct fo_server_info **_primary_servers, size_t *_num_primary_servers, struct fo_server_info **_backup_servers, size_t *_num_backup_servers) { struct fo_resolve_srv_dns_state *state = NULL; state = tevent_req_data(req, struct fo_resolve_srv_dns_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_primary_servers) { *_primary_servers = talloc_steal(mem_ctx, state->servers); } if (_num_primary_servers) { *_num_primary_servers = state->num_servers; } /* backup servers are not supported by simple srv lookup */ if (_backup_servers) { *_backup_servers = NULL; } if (_num_backup_servers) { *_num_backup_servers = 0; } if (_dns_domain) { *_dns_domain = talloc_steal(mem_ctx, state->dns_domain); } if (_ttl) { *_ttl = state->ttl; } return EOK; } sssd-1.13.4/src/providers/PaxHeaders.16287/simple0000644000000000000000000000013212703463556016353 xustar0030 mtime=1460561774.815794175 30 atime=1460561776.118798593 30 ctime=1460561774.815794175 sssd-1.13.4/src/providers/simple/0000755002412700241270000000000012703463556020104 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/providers/simple/PaxHeaders.16287/simple_access_check.c0000644000000000000000000000007412703456111022535 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.814794171 sssd-1.13.4/src/providers/simple/simple_access_check.c0000644002412700241270000006413112703456111024211 0ustar00jhrozekjhrozek00000000000000/* SSSD Simple access control Copyright (C) Sumit Bose 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/dp_backend.h" #include "providers/simple/simple_access.h" #include "util/sss_utf8.h" #include "db/sysdb.h" #define NON_EXIST_USR_ALLOW "The user %s does not exist. Possible typo in simple_allow_users.\n" #define NON_EXIST_USR_DENY "The user %s does not exist. Possible typo in simple_deny_users.\n" #define NON_EXIST_GRP_ALLOW "The group %s does not exist. Possible typo in simple_allow_groups.\n" #define NON_EXIST_GRP_DENY "The group %s does not exist. Possible typo in simple_deny_groups.\n" static bool is_posix(const struct ldb_message *group) { const char *val; val = ldb_msg_find_attr_as_string(group, SYSDB_POSIX, NULL); if (!val || /* Groups are posix by default */ strcasecmp(val, "TRUE") == 0) { return true; } return false; } /* Returns EOK if the result is definitive, EAGAIN if only partial result */ static errno_t simple_check_users(struct simple_ctx *ctx, const char *username, bool *access_granted) { struct sss_domain_info *domain = NULL; int i; /* First, check whether the user is in the allowed users list */ if (ctx->allow_users != NULL) { for(i = 0; ctx->allow_users[i] != NULL; i++) { domain = find_domain_by_object_name(ctx->domain, ctx->allow_users[i]); if (domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, NON_EXIST_USR_ALLOW, ctx->allow_users[i]); sss_log(SSS_LOG_CRIT, NON_EXIST_USR_ALLOW, ctx->allow_users[i]); continue; } if (sss_string_equal(domain->case_sensitive, username, ctx->allow_users[i])) { DEBUG(SSSDBG_TRACE_LIBS, "User [%s] found in allow list, access granted.\n", username); /* Do not return immediately on explicit allow * We need to make sure none of the user's groups * are denied. But there's no need to check username * matches any more. */ *access_granted = true; break; } } } else if (!ctx->allow_groups) { /* If neither allow rule is in place, we'll assume allowed * unless a deny rule disables us below. */ DEBUG(SSSDBG_TRACE_LIBS, "No allow rule, assumuing allow unless explicitly denied\n"); *access_granted = true; } /* Next check whether this user has been specifically denied */ if (ctx->deny_users != NULL) { for(i = 0; ctx->deny_users[i] != NULL; i++) { domain = find_domain_by_object_name(ctx->domain, ctx->deny_users[i]); if (domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, NON_EXIST_USR_DENY, ctx->deny_users[i]); sss_log(SSS_LOG_CRIT, NON_EXIST_USR_DENY, ctx->deny_users[i]); return EINVAL; } if (sss_string_equal(domain->case_sensitive, username, ctx->deny_users[i])) { DEBUG(SSSDBG_TRACE_LIBS, "User [%s] found in deny list, access denied.\n", ctx->deny_users[i]); /* Return immediately on explicit denial */ *access_granted = false; return EOK; } } } return EAGAIN; } static errno_t simple_check_groups(struct simple_ctx *ctx, const char **group_names, bool *access_granted) { struct sss_domain_info *domain = NULL; bool matched; int i, j; /* Now process allow and deny group rules * If access was already granted above, we'll skip * this redundant rule check */ if (ctx->allow_groups && !*access_granted) { matched = false; for (i = 0; ctx->allow_groups[i]; i++) { domain = find_domain_by_object_name(ctx->domain, ctx->allow_groups[i]); if (domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, NON_EXIST_GRP_ALLOW, ctx->allow_groups[i]); sss_log(SSS_LOG_CRIT, NON_EXIST_GRP_ALLOW, ctx->allow_groups[i]); continue; } for(j = 0; group_names[j]; j++) { if (sss_string_equal(domain->case_sensitive, group_names[j], ctx->allow_groups[i])) { matched = true; break; } } /* If any group has matched, we can skip out on the * processing early */ if (matched) { DEBUG(SSSDBG_TRACE_LIBS, "Group [%s] found in allow list, access granted.\n", group_names[j]); *access_granted = true; break; } } } /* Finally, process the deny group rules */ if (ctx->deny_groups) { matched = false; for (i = 0; ctx->deny_groups[i]; i++) { domain = find_domain_by_object_name(ctx->domain, ctx->deny_groups[i]); if (domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, NON_EXIST_GRP_DENY, ctx->deny_groups[i]); sss_log(SSS_LOG_CRIT, NON_EXIST_GRP_DENY, ctx->deny_groups[i]); return EINVAL; } for(j = 0; group_names[j]; j++) { if (sss_string_equal(domain->case_sensitive, group_names[j], ctx->deny_groups[i])) { matched = true; break; } } /* If any group has matched, we can skip out on the * processing early */ if (matched) { DEBUG(SSSDBG_TRACE_LIBS, "Group [%s] found in deny list, access denied.\n", group_names[j]); *access_granted = false; break; } } } return EOK; } struct simple_resolve_group_state { struct sss_domain_info *domain; gid_t gid; struct simple_ctx *ctx; const char *name; }; static errno_t simple_resolve_group_check(struct simple_resolve_group_state *state); static void simple_resolve_group_done(struct tevent_req *subreq); static struct tevent_req * simple_resolve_group_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct simple_ctx *ctx, struct sss_domain_info *domain, gid_t gid) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct simple_resolve_group_state *state; struct be_acct_req *ar; req = tevent_req_create(mem_ctx, &state, struct simple_resolve_group_state); if (!req) return NULL; state->domain = domain; state->gid = gid; state->ctx = ctx; /* First check if the group was updated already. If it was (maybe its * parent was updated first), then just shortcut */ ret = simple_resolve_group_check(state); if (ret == EOK) { DEBUG(SSSDBG_TRACE_LIBS, "Group already updated\n"); ret = EOK; goto done; } else if (ret != EAGAIN) { DEBUG(SSSDBG_OP_FAILURE, "Cannot check if group was already updated [%d]: %s\n", ret, sss_strerror(ret)); goto done; } /* EAGAIN - still needs update */ ar = talloc(state, struct be_acct_req); if (!ar) { ret = ENOMEM; goto done; } ar->entry_type = BE_REQ_GROUP; ar->attr_type = BE_ATTR_CORE; ar->filter_type = BE_FILTER_IDNUM; ar->filter_value = talloc_asprintf(ar, "%llu", (unsigned long long) gid); ar->domain = talloc_strdup(ar, state->domain->name); if (!ar->domain || !ar->filter_value) { ret = ENOMEM; goto done; } subreq = be_get_account_info_send(state, ev, NULL, ctx->be_ctx, ar); if (!subreq) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, simple_resolve_group_done, req); return req; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t simple_resolve_group_check(struct simple_resolve_group_state *state) { errno_t ret; struct ldb_message *group; const char *group_attrs[] = { SYSDB_NAME, SYSDB_POSIX, SYSDB_GIDNUM, NULL }; /* Check the cache by GID again and fetch the name */ ret = sysdb_search_group_by_gid(state, state->domain, state->gid, group_attrs, &group); if (ret == ENOENT) { /* The group is missing, we will try to update it. */ return EAGAIN; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not look up group by gid [%"SPRIgid"]: [%d][%s]\n", state->gid, ret, sss_strerror(ret)); return ret; } state->name = ldb_msg_find_attr_as_string(group, SYSDB_NAME, NULL); if (!state->name) { DEBUG(SSSDBG_OP_FAILURE, "No group name\n"); return ERR_ACCOUNT_UNKNOWN; } if (is_posix(group) == false) { DEBUG(SSSDBG_TRACE_LIBS, "The group is still non-POSIX\n"); return EAGAIN; } DEBUG(SSSDBG_TRACE_LIBS, "Got POSIX group\n"); return EOK; } static void simple_resolve_group_done(struct tevent_req *subreq) { struct tevent_req *req; struct simple_resolve_group_state *state; int err_maj; int err_min; errno_t ret; const char *err_msg; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct simple_resolve_group_state); ret = be_get_account_info_recv(subreq, state, &err_maj, &err_min, &err_msg); talloc_zfree(subreq); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "be_get_account_info_recv failed\n"); tevent_req_error(req, ret); return; } if (err_maj) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot refresh data from DP: %u,%u: %s\n", err_maj, err_min, err_msg); tevent_req_error(req, EIO); return; } /* Check the cache by GID again and fetch the name */ ret = simple_resolve_group_check(state); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Refresh failed\n"); tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t simple_resolve_group_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, const char **name) { struct simple_resolve_group_state *state; state = tevent_req_data(req, struct simple_resolve_group_state); TEVENT_REQ_RETURN_ON_ERROR(req); *name = talloc_strdup(mem_ctx, state->name); return EOK; } struct simple_group { struct sss_domain_info *domain; gid_t gid; }; struct simple_check_groups_state { struct tevent_context *ev; struct simple_ctx *ctx; struct sss_domain_info *domain; struct simple_group *lookup_groups; size_t num_groups; size_t giter; const char **group_names; size_t num_names; bool failed_to_resolve_groups; }; static void simple_check_get_groups_next(struct tevent_req *subreq); static errno_t simple_check_get_groups_primary(struct simple_check_groups_state *state, gid_t gid); static errno_t simple_check_process_group(struct simple_check_groups_state *state, struct ldb_message *group); static struct tevent_req * simple_check_get_groups_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct simple_ctx *ctx, const char *username) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct simple_check_groups_state *state; const char *attrs[] = { SYSDB_NAME, SYSDB_POSIX, SYSDB_GIDNUM, SYSDB_SID_STR, NULL }; size_t group_count; struct ldb_message *user; struct ldb_message **groups; int i; gid_t gid; req = tevent_req_create(mem_ctx, &state, struct simple_check_groups_state); if (!req) return NULL; state->ev = ev; state->ctx = ctx; state->failed_to_resolve_groups = false; DEBUG(SSSDBG_TRACE_LIBS, "Looking up groups for user %s\n", username); /* get domain from username */ state->domain = find_domain_by_object_name(ctx->domain, username); if (state->domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid user %s!\n", username); ret = EINVAL; goto done; } ret = sysdb_search_user_by_name(state, state->domain, username, attrs, &user); if (ret == ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "No such user %s\n", username); ret = ERR_ACCOUNT_UNKNOWN; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not look up username [%s]: [%d][%s]\n", username, ret, sss_strerror(ret)); goto done; } ret = sysdb_asq_search(state, state->domain, user->dn, NULL, SYSDB_MEMBEROF, attrs, &group_count, &groups); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "User %s is a member of %zu supplemental groups\n", username, group_count); /* One extra space for terminator, one extra space for private group */ state->group_names = talloc_zero_array(state, const char *, group_count + 2); state->lookup_groups = talloc_zero_array(state, struct simple_group, group_count + 2); if (!state->group_names || !state->lookup_groups) { ret = ENOMEM; goto done; } for (i=0; i < group_count; i++) { /* Some providers (like the AD provider) might perform initgroups * without resolving the group names. In order for the simple access * provider to work correctly, we need to resolve the groups before * performing the access check. In AD provider, the situation is * even more tricky b/c the groups HAVE name, but their name * attribute is set to SID and they are set as non-POSIX */ ret = simple_check_process_group(state, groups[i]); if (ret != EOK) { goto done; } } gid = ldb_msg_find_attr_as_uint64(user, SYSDB_GIDNUM, 0); if (!gid) { DEBUG(SSSDBG_MINOR_FAILURE, "User %s has no gid?\n", username); ret = EINVAL; goto done; } ret = simple_check_get_groups_primary(state, gid); if (ret != EOK) { goto done; } if (state->num_groups == 0) { /* If all groups could have been resolved by name, we are * done */ DEBUG(SSSDBG_TRACE_FUNC, "All groups had name attribute\n"); ret = EOK; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Need to resolve %zu groups\n", state->num_groups); state->giter = 0; subreq = simple_resolve_group_send(req, state->ev, state->ctx, state->lookup_groups[state->giter].domain, state->lookup_groups[state->giter].gid); if (!subreq) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, simple_check_get_groups_next, req); return req; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void simple_check_get_groups_next(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct simple_check_groups_state *state = tevent_req_data(req, struct simple_check_groups_state); errno_t ret; ret = simple_resolve_group_recv(subreq, state->group_names, &state->group_names[state->num_names]); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not resolve name of group with GID %"SPRIgid"\n", state->lookup_groups[state->giter].gid); state->failed_to_resolve_groups = true; } else { state->num_names++; } state->giter++; if (state->giter < state->num_groups) { subreq = simple_resolve_group_send(req, state->ev, state->ctx, state->lookup_groups[state->giter].domain, state->lookup_groups[state->giter].gid); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, simple_check_get_groups_next, req); return; } DEBUG(SSSDBG_TRACE_INTERNAL, "All groups resolved. Done.\n"); tevent_req_done(req); } static errno_t simple_check_process_group(struct simple_check_groups_state *state, struct ldb_message *group) { const char *name; const char *group_sid; struct sss_domain_info *domain; gid_t gid; bool posix; posix = is_posix(group); name = ldb_msg_find_attr_as_string(group, SYSDB_NAME, NULL); gid = ldb_msg_find_attr_as_uint64(group, SYSDB_GIDNUM, 0); /* With the current sysdb layout, every group has a name */ if (name == NULL) { return EINVAL; } if (gid == 0) { if (posix == true) { DEBUG(SSSDBG_CRIT_FAILURE, "POSIX group without GID\n"); return EINVAL; } /* Non-posix group with a name. Still can be used for access * control as the name should point to the real name, no SID */ state->group_names[state->num_names] = talloc_strdup(state->group_names, name); if (!state->group_names[state->num_names]) { return ENOMEM; } DEBUG(SSSDBG_TRACE_INTERNAL, "Adding group %s\n", name); state->num_names++; return EOK; } /* Here are only groups with a name and gid. POSIX group can already * be used, non-POSIX groups can be resolved */ if (posix) { state->group_names[state->num_names] = talloc_strdup(state->group_names, name); if (!state->group_names[state->num_names]) { return ENOMEM; } DEBUG(SSSDBG_TRACE_INTERNAL, "Adding group %s\n", name); state->num_names++; return EOK; } /* Try to get group SID and assign it a domain */ group_sid = ldb_msg_find_attr_as_string(group, SYSDB_SID_STR, NULL); if (group_sid == NULL) { /* We will look it up in main domain. */ domain = state->ctx->domain; } else { domain = find_domain_by_sid(state->ctx->domain, group_sid); if (domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "There is no domain information for " "SID %s\n", group_sid); return ENOENT; } } /* It is a non-posix group with a GID. Needs resolving */ state->lookup_groups[state->num_groups].domain = domain; state->lookup_groups[state->num_groups].gid = gid; DEBUG(SSSDBG_TRACE_INTERNAL, "Adding GID %"SPRIgid"\n", gid); state->num_groups++; return EOK; } static errno_t simple_check_get_groups_primary(struct simple_check_groups_state *state, gid_t gid) { errno_t ret; const char *group_attrs[] = { SYSDB_NAME, SYSDB_POSIX, SYSDB_GIDNUM, SYSDB_SID_STR, NULL }; struct ldb_message *msg; ret = sysdb_search_group_by_gid(state, state->domain, gid, group_attrs, &msg); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not look up primary group [%"SPRIgid"]: [%d][%s]\n", gid, ret, sss_strerror(ret)); /* We have to treat this as non-fatal, because the primary * group may be local to the machine and not available in * our ID provider. */ } else { ret = simple_check_process_group(state, msg); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot process primary group\n"); return ret; } } return EOK; } static errno_t simple_check_get_groups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, const char ***_group_names) { struct simple_check_groups_state *state; state = tevent_req_data(req, struct simple_check_groups_state); TEVENT_REQ_RETURN_ON_ERROR(req); *_group_names = talloc_steal(mem_ctx, state->group_names); if (state->failed_to_resolve_groups) { return ERR_SIMPLE_GROUPS_MISSING; } return EOK; } struct simple_access_check_state { bool access_granted; struct simple_ctx *ctx; const char *username; const char **group_names; }; static void simple_access_check_done(struct tevent_req *subreq); struct tevent_req *simple_access_check_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct simple_ctx *ctx, const char *username) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct simple_access_check_state *state; req = tevent_req_create(mem_ctx, &state, struct simple_access_check_state); if (!req) return NULL; state->access_granted = false; state->ctx = ctx; state->username = talloc_strdup(state, username); if (!state->username) { ret = ENOMEM; goto immediate; } DEBUG(SSSDBG_FUNC_DATA, "Simple access check for %s\n", username); ret = simple_check_users(ctx, username, &state->access_granted); if (ret == EOK) { goto immediate; } else if (ret != EAGAIN) { ret = ERR_INTERNAL; goto immediate; } /* EAGAIN -- check groups */ if (!ctx->allow_groups && !ctx->deny_groups) { /* There are no group restrictions, so just return * here with whatever we've decided. */ DEBUG(SSSDBG_TRACE_LIBS, "No group restrictions, end request\n"); ret = EOK; goto immediate; } /* The group names might not be available. Fire a request to * gather them. In most cases, the request will just shortcut */ subreq = simple_check_get_groups_send(state, ev, ctx, username); if (!subreq) { ret = ENOMEM; goto immediate; } tevent_req_set_callback(subreq, simple_access_check_done, req); return req; immediate: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void simple_access_check_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct simple_access_check_state *state = tevent_req_data(req, struct simple_access_check_state); errno_t ret; /* We know the names now. Run the check. */ ret = simple_check_get_groups_recv(subreq, state, &state->group_names); talloc_zfree(subreq); if (ret == ENOENT) { /* If the user wasn't found, just shortcut */ state->access_granted = false; tevent_req_done(req); return; } else if (ret == ERR_SIMPLE_GROUPS_MISSING) { DEBUG(SSSDBG_OP_FAILURE, "Could not collect groups of user %s\n", state->username); if (state->ctx->deny_groups == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "But no deny groups were defined so we can continue.\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "Some deny groups were defined, we can't continue\n"); tevent_req_error(req, ret); return; } } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not collect groups of user %s\n", state->username); tevent_req_error(req, ret); return; } ret = simple_check_groups(state->ctx, state->group_names, &state->access_granted); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not check group access [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ERR_INTERNAL); return; } /* Now just return whatever we decided */ DEBUG(SSSDBG_TRACE_INTERNAL, "Group check done\n"); tevent_req_done(req); } errno_t simple_access_check_recv(struct tevent_req *req, bool *access_granted) { struct simple_access_check_state *state = tevent_req_data(req, struct simple_access_check_state); TEVENT_REQ_RETURN_ON_ERROR(req); DEBUG(SSSDBG_TRACE_LIBS, "Access %sgranted\n", state->access_granted ? "" : "not "); if (access_granted) { *access_granted = state->access_granted; } return EOK; } sssd-1.13.4/src/providers/simple/PaxHeaders.16287/simple_access.c0000644000000000000000000000007412703456111021400 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.815794175 sssd-1.13.4/src/providers/simple/simple_access.c0000644002412700241270000002071712703456111023056 0ustar00jhrozekjhrozek00000000000000/* SSSD Simple access control Copyright (C) Sumit Bose 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "providers/simple/simple_access.h" #include "util/sss_utf8.h" #include "providers/dp_backend.h" #include "db/sysdb.h" #define CONFDB_SIMPLE_ALLOW_USERS "simple_allow_users" #define CONFDB_SIMPLE_DENY_USERS "simple_deny_users" #define CONFDB_SIMPLE_ALLOW_GROUPS "simple_allow_groups" #define CONFDB_SIMPLE_DENY_GROUPS "simple_deny_groups" #define TIMEOUT_OF_REFRESH_FILTER_LISTS 5 static void simple_access_check(struct tevent_req *req); static errno_t simple_access_parse_names(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, char **list, char ***_out); static int simple_access_obtain_filter_lists(struct simple_ctx *ctx) { struct be_ctx *bectx = ctx->be_ctx; int ret; int i; struct { const char *name; const char *option; char **orig_list; char ***ctx_list; } lists[] = {{"Allow users", CONFDB_SIMPLE_ALLOW_USERS, NULL, NULL}, {"Deny users", CONFDB_SIMPLE_DENY_USERS, NULL, NULL}, {"Allow groups", CONFDB_SIMPLE_ALLOW_GROUPS, NULL, NULL}, {"Deny groups", CONFDB_SIMPLE_DENY_GROUPS, NULL, NULL}, {NULL, NULL, NULL, NULL}}; lists[0].ctx_list = &ctx->allow_users; lists[1].ctx_list = &ctx->deny_users; lists[2].ctx_list = &ctx->allow_groups; lists[3].ctx_list = &ctx->deny_groups; ret = sysdb_master_domain_update(bectx->domain); if (ret != EOK) { DEBUG(SSSDBG_FUNC_DATA, "Update of master domain failed [%d]: %s.\n", ret, sss_strerror(ret)); goto failed; } for (i = 0; lists[i].name != NULL; i++) { ret = confdb_get_string_as_list(bectx->cdb, ctx, bectx->conf_path, lists[i].option, &lists[i].orig_list); if (ret == ENOENT) { DEBUG(SSSDBG_FUNC_DATA, "%s list is empty.\n", lists[i].name); *lists[i].ctx_list = NULL; continue; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "confdb_get_string_as_list failed.\n"); goto failed; } ret = simple_access_parse_names(ctx, bectx, lists[i].orig_list, lists[i].ctx_list); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse %s list [%d]: %s\n", lists[i].name, ret, sss_strerror(ret)); goto failed; } } if (!ctx->allow_users && !ctx->allow_groups && !ctx->deny_users && !ctx->deny_groups) { DEBUG(SSSDBG_OP_FAILURE, "No rules supplied for simple access provider. " "Access will be granted for all users.\n"); } return EOK; failed: return ret; } void simple_access_handler(struct be_req *be_req) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct pam_data *pd; struct tevent_req *req; struct simple_ctx *ctx; int ret; time_t now; pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); pd->pam_status = PAM_SYSTEM_ERR; if (pd->cmd != SSS_PAM_ACCT_MGMT) { DEBUG(SSSDBG_CONF_SETTINGS, "simple access does not handle pam task %d.\n", pd->cmd); pd->pam_status = PAM_MODULE_UNKNOWN; goto done; } ctx = talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data, struct simple_ctx); now = time(NULL); if ((now - ctx->last_refresh_of_filter_lists) > TIMEOUT_OF_REFRESH_FILTER_LISTS) { ret = simple_access_obtain_filter_lists(ctx); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to refresh filter lists\n"); } ctx->last_refresh_of_filter_lists = now; } req = simple_access_check_send(be_req, be_ctx->ev, ctx, pd->user); if (!req) { pd->pam_status = PAM_SYSTEM_ERR; goto done; } tevent_req_set_callback(req, simple_access_check, be_req); return; done: be_req_terminate(be_req, DP_ERR_OK, pd->pam_status, NULL); } static void simple_access_check(struct tevent_req *req) { bool access_granted = false; errno_t ret; struct pam_data *pd; struct be_req *be_req; be_req = tevent_req_callback_data(req, struct be_req); pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); ret = simple_access_check_recv(req, &access_granted); talloc_free(req); if (ret != EOK) { pd->pam_status = PAM_SYSTEM_ERR; goto done; } if (access_granted) { pd->pam_status = PAM_SUCCESS; } else { pd->pam_status = PAM_PERM_DENIED; } done: be_req_terminate(be_req, DP_ERR_OK, pd->pam_status, NULL); } static errno_t simple_access_parse_names(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, char **list, char ***_out) { TALLOC_CTX *tmp_ctx = NULL; char **out = NULL; char *domain = NULL; char *name = NULL; size_t size; size_t i; errno_t ret; if (list == NULL) { *_out = NULL; return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); ret = ENOMEM; goto done; } for (size = 0; list[size] != NULL; size++) { /* count size */ } out = talloc_zero_array(tmp_ctx, char*, size + 1); if (out == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); ret = ENOMEM; goto done; } /* Since this is access provider, we should fail on any error so we don't * allow unauthorized access. */ for (i = 0; i < size; i++) { ret = sss_parse_name(tmp_ctx, be_ctx->domain->names, list[i], &domain, &name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name '%s' [%d]: %s\n", list[i], ret, sss_strerror(ret)); goto done; } if (domain == NULL || strcasecmp(domain, be_ctx->domain->name) == 0 || (be_ctx->domain->flat_name != NULL && strcasecmp(domain, be_ctx->domain->flat_name) == 0)) { /* This object belongs to main SSSD domain. Those users and groups * are stored without domain part, so we will strip it off. * */ out[i] = talloc_move(out, &name); } else { /* Subdomain users and groups are stored as fully qualified names, * thus we will remember the domain part. * * Since subdomains may come and go, we will look for their * existence later, during each access check. */ out[i] = talloc_move(out, &list[i]); } } *_out = talloc_steal(mem_ctx, out); ret = EOK; done: talloc_free(tmp_ctx); return ret; } struct bet_ops simple_access_ops = { .handler = simple_access_handler, .finalize = NULL }; int sssm_simple_access_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret = EINVAL; struct simple_ctx *ctx; ctx = talloc_zero(bectx, struct simple_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ctx->domain = bectx->domain; ctx->be_ctx = bectx; ctx->last_refresh_of_filter_lists = 0; ret = simple_access_obtain_filter_lists(ctx); if (ret != EOK) { goto failed; } *ops = &simple_access_ops; *pvt_data = ctx; return EOK; failed: talloc_free(ctx); return ret; } sssd-1.13.4/src/providers/simple/PaxHeaders.16287/simple_access.h0000644000000000000000000000007412703456111021405 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.537793232 sssd-1.13.4/src/providers/simple/simple_access.h0000644002412700241270000000266712703456111023067 0ustar00jhrozekjhrozek00000000000000/* SSSD Simple access control Copyright (C) Sumit Bose 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SIMPLE_ACCESS_H__ #define __SIMPLE_ACCESS_H__ #include "util/util.h" struct simple_ctx { struct sss_domain_info *domain; struct be_ctx *be_ctx; char **allow_users; char **deny_users; char **allow_groups; char **deny_groups; time_t last_refresh_of_filter_lists; }; struct tevent_req *simple_access_check_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct simple_ctx *ctx, const char *username); errno_t simple_access_check_recv(struct tevent_req *req, bool *access_granted); #endif /* __SIMPLE_ACCESS_H__ */ sssd-1.13.4/src/providers/PaxHeaders.16287/dp_refresh.c0000644000000000000000000000007412703456111017416 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.660793649 sssd-1.13.4/src/providers/dp_refresh.c0000644002412700241270000002246712703456111021100 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "providers/dp_backend.h" #include "providers/dp_ptask.h" #include "providers/dp_refresh.h" #include "util/util_errors.h" #include "db/sysdb.h" static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, time_t period, const char *objectclass, struct ldb_dn *base_dn, const char *attr, char ***_values) { TALLOC_CTX *tmp_ctx = NULL; const char *attrs[] = {attr, NULL}; const char *filter = NULL; char **values = NULL; struct ldb_message **msgs = NULL; struct sysdb_attrs **records = NULL; size_t count; time_t now = time(NULL); errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } filter = talloc_asprintf(tmp_ctx, "(&(%s<=%lld))", SYSDB_CACHE_EXPIRE, (long long) now + period); if (filter == NULL) { ret = ENOMEM; goto done; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, base_dn, LDB_SCOPE_SUBTREE, filter, attrs, &count, &msgs); if (ret == ENOENT) { count = 0; } else if (ret != EOK) { goto done; } ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &records); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not convert ldb message to sysdb_attrs\n"); goto done; } ret = sysdb_attrs_to_list(tmp_ctx, records, count, attr, &values); if (ret != EOK) { goto done; } *_values = talloc_steal(mem_ctx, values); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx, enum be_refresh_type type, struct sss_domain_info *domain, time_t period, char ***_values) { struct ldb_dn *base_dn = NULL; const char *class = NULL; errno_t ret; switch (type) { case BE_REFRESH_TYPE_USERS: base_dn = sysdb_user_base_dn(mem_ctx, domain); class = SYSDB_USER_CLASS; break; case BE_REFRESH_TYPE_GROUPS: base_dn = sysdb_group_base_dn(mem_ctx, domain); class = SYSDB_GROUP_CLASS; break; case BE_REFRESH_TYPE_NETGROUPS: base_dn = sysdb_netgroup_base_dn(mem_ctx, domain); class = SYSDB_NETGROUP_CLASS; break; case BE_REFRESH_TYPE_SENTINEL: return ERR_INTERNAL; break; } if (base_dn == NULL) { return ENOMEM; } ret = be_refresh_get_values_ex(mem_ctx, domain, period, class, base_dn, SYSDB_NAME, _values); talloc_free(base_dn); return ret; } struct be_refresh_cb { const char *name; bool enabled; be_refresh_send_t send_fn; be_refresh_recv_t recv_fn; void *pvt; }; struct be_refresh_ctx { struct be_refresh_cb callbacks[BE_REFRESH_TYPE_SENTINEL]; }; struct be_refresh_ctx *be_refresh_ctx_init(TALLOC_CTX *mem_ctx) { struct be_refresh_ctx *ctx = NULL; ctx = talloc_zero(mem_ctx, struct be_refresh_ctx); if (ctx == NULL) { return NULL; } ctx->callbacks[BE_REFRESH_TYPE_USERS].name = "users"; ctx->callbacks[BE_REFRESH_TYPE_GROUPS].name = "groups"; ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].name = "netgroups"; return ctx; } errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, enum be_refresh_type type, be_refresh_send_t send_fn, be_refresh_recv_t recv_fn, void *pvt) { if (ctx == NULL || send_fn == NULL || recv_fn == NULL || type >= BE_REFRESH_TYPE_SENTINEL) { return EINVAL; } if (ctx->callbacks[type].enabled) { return EEXIST; } ctx->callbacks[type].enabled = true; ctx->callbacks[type].send_fn = send_fn; ctx->callbacks[type].recv_fn = recv_fn; ctx->callbacks[type].pvt = pvt; return EOK; } struct be_refresh_state { struct tevent_context *ev; struct be_ctx *be_ctx; struct be_refresh_ctx *ctx; struct be_refresh_cb *cb; struct sss_domain_info *domain; enum be_refresh_type index; time_t period; }; static errno_t be_refresh_step(struct tevent_req *req); static void be_refresh_done(struct tevent_req *subreq); struct tevent_req *be_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct be_refresh_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct be_refresh_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->be_ctx = be_ctx; state->domain = be_ctx->domain; state->period = be_ptask_get_period(be_ptask); state->ctx = talloc_get_type(pvt, struct be_refresh_ctx); if (state->ctx == NULL) { ret = EINVAL; goto immediately; } ret = be_refresh_step(req); if (ret == EOK) { goto immediately; } else if (ret != EAGAIN) { DEBUG(SSSDBG_CRIT_FAILURE, "be_refresh_step() failed [%d]: %s\n", ret, sss_strerror(ret)); goto immediately; } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t be_refresh_step(struct tevent_req *req) { struct be_refresh_state *state = NULL; struct tevent_req *subreq = NULL; char **values = NULL; errno_t ret; state = tevent_req_data(req, struct be_refresh_state); while (state->domain != NULL) { /* find first enabled callback */ state->cb = &state->ctx->callbacks[state->index]; while (state->index != BE_REFRESH_TYPE_SENTINEL && !state->cb->enabled) { state->index++; state->cb = &state->ctx->callbacks[state->index]; } /* if not found than continue with next domain */ if (state->index == BE_REFRESH_TYPE_SENTINEL) { state->domain = get_next_domain(state->domain, 0); continue; } if (state->cb->send_fn == NULL || state->cb->recv_fn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid parameters!\n"); ret = ERR_INTERNAL; goto done; } ret = be_refresh_get_values(state, state->index, state->domain, state->period, &values); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain DN list [%d]: %s\n", ret, sss_strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Refreshing %s in domain %s\n", state->cb->name, state->domain->name); subreq = state->cb->send_fn(state, state->ev, state->be_ctx, state->domain, values, state->cb->pvt); if (subreq == NULL) { ret = ENOMEM; goto done; } /* make the list disappear with subreq */ talloc_steal(subreq, values); tevent_req_set_callback(subreq, be_refresh_done, req); state->index++; ret = EAGAIN; goto done; } ret = EOK; done: if (ret != EOK && ret != EAGAIN) { talloc_free(values); } return ret; } static void be_refresh_done(struct tevent_req *subreq) { struct be_refresh_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct be_refresh_state); ret = state->cb->recv_fn(subreq); talloc_zfree(subreq); if (ret != EOK) { goto done; } ret = be_refresh_step(req); if (ret == EAGAIN) { return; } done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } errno_t be_refresh_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/PaxHeaders.16287/fail_over.c0000644000000000000000000000007412703456111017243 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.664793663 sssd-1.13.4/src/providers/fail_over.c0000644002412700241270000013713712703456111020726 0ustar00jhrozekjhrozek00000000000000/* SSSD Fail over helper functions. Authors: Martin Nagy Jakub Hrozek Copyright (C) Red Hat, Inc 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/dlinklist.h" #include "util/refcount.h" #include "util/util.h" #include "providers/fail_over.h" #include "resolv/async_resolv.h" #define STATUS_DIFF(p, now) ((now).tv_sec - (p)->last_status_change.tv_sec) #define SERVER_NAME(s) ((s)->common ? (s)->common->name : "(no name)") #define DEFAULT_PORT_STATUS PORT_NEUTRAL #define DEFAULT_SERVER_STATUS SERVER_NAME_NOT_RESOLVED #define DEFAULT_SRV_STATUS SRV_NEUTRAL enum srv_lookup_status { SRV_NEUTRAL, /* We didn't try this SRV lookup yet */ SRV_RESOLVED, /* This SRV lookup is resolved */ SRV_RESOLVE_ERROR, /* Could not resolve this SRV lookup */ SRV_EXPIRED /* Need to refresh the SRV query */ }; struct fo_ctx { struct fo_service *service_list; struct server_common *server_common_list; struct fo_options *opts; fo_srv_lookup_plugin_send_t srv_send_fn; fo_srv_lookup_plugin_recv_t srv_recv_fn; void *srv_pvt; }; struct fo_service { struct fo_service *prev; struct fo_service *next; struct fo_ctx *ctx; char *name; struct fo_server *active_server; struct fo_server *last_tried_server; struct fo_server *server_list; /* Function pointed by user_data_cmp returns 0 if user_data is equal * or nonzero value if not. Set to NULL if no user data comparison * is needed in fail over duplicate servers detection. */ datacmp_fn user_data_cmp; }; struct fo_server { REFCOUNT_COMMON; struct fo_server *prev; struct fo_server *next; bool primary; void *user_data; int port; enum port_status port_status; struct srv_data *srv_data; struct fo_service *service; struct timeval last_status_change; struct server_common *common; TALLOC_CTX *fo_internal_owner; }; struct server_common { REFCOUNT_COMMON; struct fo_ctx *ctx; struct server_common *prev; struct server_common *next; char *name; struct resolv_hostent *rhostent; struct resolve_service_request *request_list; enum server_status server_status; struct timeval last_status_change; }; struct srv_data { char *dns_domain; char *discovery_domain; char *sssd_domain; char *proto; char *srv; struct fo_server *meta; int srv_lookup_status; int ttl; struct timeval last_status_change; }; struct resolve_service_request { struct resolve_service_request *prev; struct resolve_service_request *next; struct server_common *server_common; struct tevent_req *req; struct tevent_context *ev; }; struct status { int value; struct timeval last_change; }; struct fo_ctx * fo_context_init(TALLOC_CTX *mem_ctx, struct fo_options *opts) { struct fo_ctx *ctx; ctx = talloc_zero(mem_ctx, struct fo_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No memory\n"); return NULL; } ctx->opts = talloc_zero(ctx, struct fo_options); if (ctx->opts == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No memory\n"); return NULL; } ctx->opts->srv_retry_neg_timeout = opts->srv_retry_neg_timeout; ctx->opts->retry_timeout = opts->retry_timeout; ctx->opts->family_order = opts->family_order; ctx->opts->service_resolv_timeout = opts->service_resolv_timeout; DEBUG(SSSDBG_TRACE_FUNC, "Created new fail over context, retry timeout is %ld\n", ctx->opts->retry_timeout); return ctx; } static const char * str_port_status(enum port_status status) { switch (status) { case PORT_NEUTRAL: return "neutral"; case PORT_WORKING: return "working"; case PORT_NOT_WORKING: return "not working"; } return "unknown port status"; } static const char * str_srv_data_status(enum srv_lookup_status status) { switch (status) { case SRV_NEUTRAL: return "neutral"; case SRV_RESOLVED: return "resolved"; case SRV_RESOLVE_ERROR: return "not resolved"; case SRV_EXPIRED: return "expired"; } return "unknown SRV lookup status"; } static const char * str_server_status(enum server_status status) { switch (status) { case SERVER_NAME_NOT_RESOLVED: return "name not resolved"; case SERVER_RESOLVING_NAME: return "resolving name"; case SERVER_NAME_RESOLVED: return "name resolved"; case SERVER_WORKING: return "working"; case SERVER_NOT_WORKING: return "not working"; } return "unknown server status"; } int fo_is_srv_lookup(struct fo_server *s) { return s && s->srv_data; } static void fo_server_free(struct fo_server *server) { if (server == NULL) { return; } talloc_free(server->fo_internal_owner); } static struct fo_server * collapse_srv_lookup(struct fo_server **_server) { struct fo_server *tmp, *meta, *server; server = *_server; meta = server->srv_data->meta; DEBUG(SSSDBG_CONF_SETTINGS, "Need to refresh SRV lookup for domain %s\n", meta->srv_data->dns_domain); if (server != meta) { while (server->prev && server->prev->srv_data == meta->srv_data) { tmp = server->prev; DLIST_REMOVE(server->service->server_list, tmp); fo_server_free(tmp); } while (server->next && server->next->srv_data == meta->srv_data) { tmp = server->next; DLIST_REMOVE(server->service->server_list, tmp); fo_server_free(tmp); } if (server == server->service->active_server) { server->service->active_server = NULL; } if (server == server->service->last_tried_server) { server->service->last_tried_server = meta; } /* add back the meta server to denote SRV lookup */ DLIST_ADD_AFTER(server->service->server_list, meta, server); DLIST_REMOVE(server->service->server_list, server); fo_server_free(server); } meta->srv_data->srv_lookup_status = SRV_NEUTRAL; meta->srv_data->last_status_change.tv_sec = 0; *_server = NULL; return meta; } static enum srv_lookup_status get_srv_data_status(struct srv_data *data) { struct timeval tv; time_t timeout; gettimeofday(&tv, NULL); /* Determine timeout value based on state of previous lookup. */ if (data->srv_lookup_status == SRV_RESOLVE_ERROR) { timeout = data->meta->service->ctx->opts->srv_retry_neg_timeout; } else { timeout = data->ttl; } if (STATUS_DIFF(data, tv) > timeout) { switch(data->srv_lookup_status) { case SRV_EXPIRED: case SRV_NEUTRAL: break; case SRV_RESOLVED: data->srv_lookup_status = SRV_EXPIRED; data->last_status_change.tv_sec = 0; break; case SRV_RESOLVE_ERROR: data->srv_lookup_status = SRV_NEUTRAL; data->last_status_change.tv_sec = 0; DEBUG(SSSDBG_TRACE_FUNC, "Changing state of SRV lookup from 'SRV_RESOLVE_ERROR' to " "'SRV_NEUTRAL'.\n"); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown state for SRV server!\n"); } } return data->srv_lookup_status; } static void set_srv_data_status(struct srv_data *data, enum srv_lookup_status status) { DEBUG(SSSDBG_CONF_SETTINGS, "Marking SRV lookup of service '%s' as '%s'\n", data->meta->service->name, str_srv_data_status(status)); gettimeofday(&data->last_status_change, NULL); data->srv_lookup_status = status; } /* * This function will return the status of the server. If the status was * last updated a long time ago, we will first reset the status. */ static enum server_status get_server_status(struct fo_server *server) { struct timeval tv; time_t timeout; if (server->common == NULL) return SERVER_NAME_RESOLVED; DEBUG(SSSDBG_TRACE_LIBS, "Status of server '%s' is '%s'\n", SERVER_NAME(server), str_server_status(server->common->server_status)); timeout = server->service->ctx->opts->retry_timeout; gettimeofday(&tv, NULL); if (timeout != 0 && server->common->server_status == SERVER_NOT_WORKING) { if (STATUS_DIFF(server->common, tv) > timeout) { DEBUG(SSSDBG_CONF_SETTINGS, "Reseting the server status of '%s'\n", SERVER_NAME(server)); server->common->server_status = SERVER_NAME_NOT_RESOLVED; server->common->last_status_change.tv_sec = tv.tv_sec; } } if (server->common->rhostent && STATUS_DIFF(server->common, tv) > server->common->rhostent->addr_list[0]->ttl) { DEBUG(SSSDBG_CONF_SETTINGS, "Hostname resolution expired, resetting the server " "status of '%s'\n", SERVER_NAME(server)); fo_set_server_status(server, SERVER_NAME_NOT_RESOLVED); } return server->common->server_status; } /* * This function will return the status of the service. If the status was * last updated a long time ago, we will first reset the status. */ static enum port_status get_port_status(struct fo_server *server) { struct timeval tv; time_t timeout; DEBUG(SSSDBG_TRACE_LIBS, "Port status of port %d for server '%s' is '%s'\n", server->port, SERVER_NAME(server), str_port_status(server->port_status)); timeout = server->service->ctx->opts->retry_timeout; if (timeout != 0 && server->port_status == PORT_NOT_WORKING) { gettimeofday(&tv, NULL); if (STATUS_DIFF(server, tv) > timeout) { DEBUG(SSSDBG_CONF_SETTINGS, "Reseting the status of port %d for server '%s'\n", server->port, SERVER_NAME(server)); server->port_status = PORT_NEUTRAL; server->last_status_change.tv_sec = tv.tv_sec; } } return server->port_status; } static int server_works(struct fo_server *server) { if (get_server_status(server) == SERVER_NOT_WORKING) return 0; return 1; } static int service_works(struct fo_server *server) { if (!server_works(server)) return 0; if (get_port_status(server) == PORT_NOT_WORKING) return 0; return 1; } static int service_destructor(struct fo_service *service) { DLIST_REMOVE(service->ctx->service_list, service); return 0; } int fo_new_service(struct fo_ctx *ctx, const char *name, datacmp_fn user_data_cmp, struct fo_service **_service) { struct fo_service *service; int ret; DEBUG(SSSDBG_TRACE_FUNC, "Creating new service '%s'\n", name); ret = fo_get_service(ctx, name, &service); if (ret == EOK) { DEBUG(SSSDBG_FUNC_DATA, "Service '%s' already exists\n", name); if (_service) { *_service = service; } return EEXIST; } else if (ret != ENOENT) { return ret; } service = talloc_zero(ctx, struct fo_service); if (service == NULL) return ENOMEM; service->name = talloc_strdup(service, name); if (service->name == NULL) { talloc_free(service); return ENOMEM; } service->user_data_cmp = user_data_cmp; service->ctx = ctx; DLIST_ADD(ctx->service_list, service); talloc_set_destructor(service, service_destructor); if (_service) { *_service = service; } return EOK; } int fo_get_service(struct fo_ctx *ctx, const char *name, struct fo_service **_service) { struct fo_service *service; DLIST_FOR_EACH(service, ctx->service_list) { if (!strcmp(name, service->name)) { *_service = service; return EOK; } } return ENOENT; } static int get_server_common(TALLOC_CTX *mem_ctx, struct fo_ctx *ctx, const char *name, struct server_common **_common) { struct server_common *common; DLIST_FOR_EACH(common, ctx->server_common_list) { if (!strcasecmp(name, common->name)) { *_common = rc_reference(mem_ctx, struct server_common, common); if (*_common == NULL) return ENOMEM; return EOK; } } return ENOENT; } static int server_common_destructor(void *memptr) { struct server_common *common; common = talloc_get_type(memptr, struct server_common); if (common->request_list) { DEBUG(SSSDBG_CRIT_FAILURE, "BUG: pending requests still associated with this server\n"); return -1; } DLIST_REMOVE(common->ctx->server_common_list, common); return 0; } static struct server_common * create_server_common(TALLOC_CTX *mem_ctx, struct fo_ctx *ctx, const char *name) { struct server_common *common; common = rc_alloc(mem_ctx, struct server_common); if (common == NULL) { return NULL; } common->name = talloc_strdup(common, name); if (common->name == NULL) { return NULL; } common->ctx = ctx; common->prev = NULL; common->next = NULL; common->rhostent = NULL; common->request_list = NULL; common->server_status = DEFAULT_SERVER_STATUS; common->last_status_change.tv_sec = 0; common->last_status_change.tv_usec = 0; talloc_set_destructor((TALLOC_CTX *) common, server_common_destructor); DLIST_ADD_END(ctx->server_common_list, common, struct server_common *); return common; } static struct fo_server * fo_server_alloc(struct fo_service *service, int port, void *user_data, bool primary) { static struct fo_server *server; TALLOC_CTX *server_owner; server_owner = talloc_new(service); if (server_owner == NULL) { return NULL; } server = rc_alloc(server_owner, struct fo_server); if (server == NULL) { return NULL; } server->fo_internal_owner = server_owner; server->common = NULL; server->next = NULL; server->prev = NULL; server->srv_data = NULL; server->last_status_change.tv_sec = 0; server->last_status_change.tv_usec = 0; server->port = port; server->user_data = user_data; server->service = service; server->port_status = DEFAULT_PORT_STATUS; server->primary = primary; return server; } int fo_add_srv_server(struct fo_service *service, const char *srv, const char *discovery_domain, const char *sssd_domain, const char *proto, void *user_data) { struct fo_server *server; DEBUG(SSSDBG_TRACE_FUNC, "Adding new SRV server to service '%s' using '%s'.\n", service->name, proto); DLIST_FOR_EACH(server, service->server_list) { /* Compare user data only if user_data_cmp and both arguments * are not NULL. */ if (server->service->user_data_cmp && user_data && server->user_data) { if (server->service->user_data_cmp(server->user_data, user_data)) { continue; } } if (fo_is_srv_lookup(server)) { if (((discovery_domain == NULL && server->srv_data->dns_domain == NULL) || (discovery_domain != NULL && server->srv_data->dns_domain != NULL && strcasecmp(server->srv_data->dns_domain, discovery_domain) == 0)) && strcasecmp(server->srv_data->proto, proto) == 0) { return EEXIST; } } } /* SRV servers are always primary */ server = fo_server_alloc(service, 0, user_data, true); if (server == NULL) { return ENOMEM; } /* add the SRV-specific data */ server->srv_data = talloc_zero(service, struct srv_data); if (server->srv_data == NULL) return ENOMEM; server->srv_data->proto = talloc_strdup(server->srv_data, proto); server->srv_data->srv = talloc_strdup(server->srv_data, srv); if (server->srv_data->proto == NULL || server->srv_data->srv == NULL) return ENOMEM; if (discovery_domain) { server->srv_data->discovery_domain = talloc_strdup(server->srv_data, discovery_domain); if (server->srv_data->discovery_domain == NULL) return ENOMEM; server->srv_data->dns_domain = talloc_strdup(server->srv_data, discovery_domain); if (server->srv_data->dns_domain == NULL) return ENOMEM; } server->srv_data->sssd_domain = talloc_strdup(server->srv_data, sssd_domain); if (server->srv_data->sssd_domain == NULL) return ENOMEM; server->srv_data->meta = server; server->srv_data->srv_lookup_status = DEFAULT_SRV_STATUS; server->srv_data->last_status_change.tv_sec = 0; DLIST_ADD_END(service->server_list, server, struct fo_server *); return EOK; } static struct fo_server * create_fo_server(struct fo_service *service, const char *name, int port, void *user_data, bool primary) { struct fo_server *server; int ret; server = fo_server_alloc(service, port, user_data, primary); if (server == NULL) return NULL; server->port = port; server->user_data = user_data; server->service = service; server->port_status = DEFAULT_PORT_STATUS; server->primary = primary; if (name != NULL) { ret = get_server_common(server, service->ctx, name, &server->common); if (ret == ENOENT) { server->common = create_server_common(server, service->ctx, name); if (server->common == NULL) { fo_server_free(server); return NULL; } } else if (ret != EOK) { fo_server_free(server); return NULL; } } return server; } int fo_get_server_count(struct fo_service *service) { struct fo_server *server; int count = 0; DLIST_FOR_EACH(server, service->server_list) { count++; } return count; } static bool fo_server_match(struct fo_server *server, const char *name, int port, void *user_data) { if (server->port != port) { return false; } /* Compare user data only if user_data_cmp and both arguments * are not NULL. */ if (server->service->user_data_cmp && server->user_data && user_data) { if (server->service->user_data_cmp(server->user_data, user_data)) { return false; } } if (name == NULL && server->common == NULL) { return true; } if (name != NULL && server->common != NULL && server->common->name != NULL) { if (!strcasecmp(name, server->common->name)) return true; } return false; } static bool fo_server_cmp(struct fo_server *s1, struct fo_server *s2) { char *name = NULL; if (s2->common != NULL) { name = s2->common->name; } return fo_server_match(s1, name, s2->port, s2->user_data); } static bool fo_server_exists(struct fo_server *list, const char *name, int port, void *user_data) { struct fo_server *server = NULL; DLIST_FOR_EACH(server, list) { if (fo_server_match(server, name, port, user_data)) { return true; } } return false; } static errno_t fo_add_server_to_list(struct fo_server **to_list, struct fo_server *check_list, struct fo_server *server, const char *service_name) { const char *debug_name = NULL; const char *name = NULL; bool exists; if (server->common == NULL || server->common->name == NULL) { debug_name = "(no name)"; name = NULL; } else { debug_name = server->common->name; name = server->common->name; } exists = fo_server_exists(check_list, name, server->port, server->user_data); if (exists) { DEBUG(SSSDBG_TRACE_FUNC, "Server '%s:%d' for service '%s' " "is already present\n", debug_name, server->port, service_name); return EEXIST; } DLIST_ADD_END(*to_list, server, struct fo_server *); DEBUG(SSSDBG_TRACE_FUNC, "Inserted %s server '%s:%d' to service " "'%s'\n", (server->primary ? "primary" : "backup"), debug_name, server->port, service_name); return EOK; } static errno_t fo_add_server_list(struct fo_service *service, struct fo_server *after_server, struct fo_server_info *servers, size_t num_servers, struct srv_data *srv_data, void *user_data, bool primary, struct fo_server **_last_server) { struct fo_server *server = NULL; struct fo_server *last_server = NULL; struct fo_server *srv_list = NULL; size_t i; errno_t ret; for (i = 0; i < num_servers; i++) { server = create_fo_server(service, servers[i].host, servers[i].port, user_data, primary); if (server == NULL) { return ENOMEM; } server->srv_data = srv_data; ret = fo_add_server_to_list(&srv_list, service->server_list, server, service->name); if (ret != EOK) { fo_server_free(server); continue; } last_server = server; } if (srv_list != NULL) { DLIST_ADD_LIST_AFTER(service->server_list, after_server, srv_list, struct fo_server *); } if (_last_server != NULL) { *_last_server = last_server == NULL ? after_server : last_server; } return EOK; } int fo_add_server(struct fo_service *service, const char *name, int port, void *user_data, bool primary) { struct fo_server *server; errno_t ret; server = create_fo_server(service, name, port, user_data, primary); if (!server) { return ENOMEM; } ret = fo_add_server_to_list(&service->server_list, service->server_list, server, service->name); if (ret != EOK) { fo_server_free(server); } return ret; } void fo_ref_server(TALLOC_CTX *ref_ctx, struct fo_server *server) { if (server) { server = rc_reference(ref_ctx, struct fo_server, server); } } static int get_first_server_entity(struct fo_service *service, struct fo_server **_server) { struct fo_server *server; /* If we already have a working server, use that one. */ server = service->active_server; if (server != NULL) { if (service_works(server) && fo_is_server_primary(server)) { goto done; } service->active_server = NULL; } /* * Otherwise iterate through the server list. */ /* First, try primary servers after the last one we tried. * (only if the last one was primary as well) */ if (service->last_tried_server != NULL && service->last_tried_server->primary) { if (service->last_tried_server->port_status == PORT_NEUTRAL && server_works(service->last_tried_server)) { server = service->last_tried_server; goto done; } DLIST_FOR_EACH(server, service->last_tried_server->next) { /* Go only through primary servers */ if (!server->primary) continue; if (service_works(server)) { goto done; } } } /* If none were found, try at the start, primary first */ DLIST_FOR_EACH(server, service->server_list) { /* First iterate only over primary servers */ if (!server->primary) continue; if (service_works(server)) { goto done; } if (server == service->last_tried_server) { break; } } DLIST_FOR_EACH(server, service->server_list) { /* Now iterate only over backup servers */ if (server->primary) continue; if (service_works(server)) { goto done; } } service->last_tried_server = NULL; return ENOENT; done: service->last_tried_server = server; *_server = server; return EOK; } static int resolve_service_request_destructor(struct resolve_service_request *request) { DLIST_REMOVE(request->server_common->request_list, request); return 0; } static int set_lookup_hook(struct tevent_context *ev, struct fo_server *server, struct tevent_req *req) { struct resolve_service_request *request; request = talloc(req, struct resolve_service_request); if (request == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No memory\n"); talloc_free(request); return ENOMEM; } request->server_common = rc_reference(request, struct server_common, server->common); if (request->server_common == NULL) { talloc_free(request); return ENOMEM; } request->ev = ev; request->req = req; DLIST_ADD(server->common->request_list, request); talloc_set_destructor(request, resolve_service_request_destructor); return EOK; } /******************************************************************* * Get server to connect to. * *******************************************************************/ struct resolve_service_state { struct fo_server *server; struct resolv_ctx *resolv; struct tevent_context *ev; struct tevent_timer *timeout_handler; struct fo_ctx *fo_ctx; }; static errno_t fo_resolve_service_activate_timeout(struct tevent_req *req, struct tevent_context *ev, const unsigned long timeout_seconds); static void fo_resolve_service_cont(struct tevent_req *subreq); static void fo_resolve_service_done(struct tevent_req *subreq); static bool fo_resolve_service_server(struct tevent_req *req); /* Forward declarations for SRV resolving */ static struct tevent_req * resolve_srv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv, struct fo_ctx *ctx, struct fo_server *server); static int resolve_srv_recv(struct tevent_req *req, struct fo_server **server); struct tevent_req * fo_resolve_service_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv, struct fo_ctx *ctx, struct fo_service *service) { int ret; struct fo_server *server; struct tevent_req *req; struct tevent_req *subreq; struct resolve_service_state *state; DEBUG(SSSDBG_CONF_SETTINGS, "Trying to resolve service '%s'\n", service->name); req = tevent_req_create(mem_ctx, &state, struct resolve_service_state); if (req == NULL) return NULL; state->resolv = resolv; state->ev = ev; state->fo_ctx = ctx; ret = get_first_server_entity(service, &server); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "No available servers for service '%s'\n", service->name); goto done; } /* Activate per-service timeout handler */ ret = fo_resolve_service_activate_timeout(req, ev, ctx->opts->service_resolv_timeout); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set service timeout\n"); goto done; } if (fo_is_srv_lookup(server)) { /* Don't know the server yet, must do a SRV lookup */ subreq = resolve_srv_send(state, ev, resolv, ctx, server); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, fo_resolve_service_cont, req); return req; } /* This is a regular server, just do hostname lookup */ state->server = server; if (fo_resolve_service_server(req)) { tevent_req_post(req, ev); } ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void set_server_common_status(struct server_common *common, enum server_status status); static void fo_resolve_service_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); DEBUG(SSSDBG_MINOR_FAILURE, "Service resolving timeout reached\n"); tevent_req_error(req, ETIMEDOUT); } static errno_t fo_resolve_service_activate_timeout(struct tevent_req *req, struct tevent_context *ev, const unsigned long timeout_seconds) { struct timeval tv; struct resolve_service_state *state = tevent_req_data(req, struct resolve_service_state); tv = tevent_timeval_current(); tv = tevent_timeval_add(&tv, timeout_seconds, 0); state->timeout_handler = tevent_add_timer(ev, state, tv, fo_resolve_service_timeout, req); if (state->timeout_handler == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n"); return ENOMEM; } DEBUG(SSSDBG_TRACE_INTERNAL, "Resolve timeout set to %lu seconds\n", timeout_seconds); return EOK; } /* SRV resolving finished, see if we got server to work with */ static void fo_resolve_service_cont(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct resolve_service_state *state = tevent_req_data(req, struct resolve_service_state); int ret; ret = resolve_srv_recv(subreq, &state->server); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } fo_resolve_service_server(req); } static bool fo_resolve_service_server(struct tevent_req *req) { struct resolve_service_state *state = tevent_req_data(req, struct resolve_service_state); struct tevent_req *subreq; int ret; switch (get_server_status(state->server)) { case SERVER_NAME_NOT_RESOLVED: /* Request name resolution. */ subreq = resolv_gethostbyname_send(state->server->common, state->ev, state->resolv, state->server->common->name, state->fo_ctx->opts->family_order, default_host_dbs); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return true; } tevent_req_set_callback(subreq, fo_resolve_service_done, state->server->common); fo_set_server_status(state->server, SERVER_RESOLVING_NAME); /* FALLTHROUGH */ case SERVER_RESOLVING_NAME: /* Name resolution is already under way. Just add ourselves into the * waiting queue so we get notified after the operation is finished. */ ret = set_lookup_hook(state->ev, state->server, req); if (ret != EOK) { tevent_req_error(req, ret); return true; } break; default: /* The name is already resolved. Return immediately. */ tevent_req_done(req); return true; } return false; } static void fo_resolve_service_done(struct tevent_req *subreq) { struct server_common *common = tevent_req_callback_data(subreq, struct server_common); int resolv_status; struct resolve_service_request *request; int ret; if (common->rhostent != NULL) { talloc_zfree(common->rhostent); } ret = resolv_gethostbyname_recv(subreq, common, &resolv_status, NULL, &common->rhostent); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to resolve server '%s': %s\n", common->name, resolv_strerror(resolv_status)); /* If the resolver failed to resolve a hostname but did not * encounter an error, tell the caller to retry another server. * * If there are no more servers to try, the next request would * just shortcut with ENOENT. */ if (ret == ENOENT) { ret = EAGAIN; } set_server_common_status(common, SERVER_NOT_WORKING); } else { set_server_common_status(common, SERVER_NAME_RESOLVED); } /* Take care of all requests for this server. */ while ((request = common->request_list) != NULL) { DLIST_REMOVE(common->request_list, request); /* If the request callback decresed refcount on the returned * server, we would have crashed as common would not be valid * anymore. Rather schedule the notify for next tev iteration */ tevent_req_defer_callback(request->req, request->ev); if (ret) { tevent_req_error(request->req, ret); } else { tevent_req_done(request->req); } } } int fo_resolve_service_recv(struct tevent_req *req, TALLOC_CTX *ref_ctx, struct fo_server **server) { struct resolve_service_state *state; state = tevent_req_data(req, struct resolve_service_state); /* always return the server if asked for, otherwise the caller * cannot mark it as faulty in case we return an error */ if (server != NULL) { fo_ref_server(ref_ctx, state->server); *server = state->server; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /******************************************************************* * Resolve the server to connect to using a SRV query. * *******************************************************************/ static void resolve_srv_done(struct tevent_req *subreq); struct resolve_srv_state { struct fo_server *meta; struct fo_service *service; struct fo_server *out; struct resolv_ctx *resolv; struct tevent_context *ev; struct fo_ctx *fo_ctx; }; static struct tevent_req * resolve_srv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv, struct fo_ctx *ctx, struct fo_server *server) { int ret; struct tevent_req *req; struct tevent_req *subreq; struct resolve_srv_state *state; int status; req = tevent_req_create(mem_ctx, &state, struct resolve_srv_state); if (req == NULL) return NULL; state->service = server->service; state->ev = ev; state->resolv = resolv; state->fo_ctx = ctx; state->meta = server->srv_data->meta; status = get_srv_data_status(server->srv_data); DEBUG(SSSDBG_FUNC_DATA, "The status of SRV lookup is %s\n", str_srv_data_status(status)); switch(status) { case SRV_EXPIRED: /* Need a refresh */ state->meta = collapse_srv_lookup(&server); /* FALLTHROUGH. * "server" might be invalid now if the SRV * query collapsed * */ case SRV_NEUTRAL: /* Request SRV lookup */ if (server != NULL && server != state->meta) { /* A server created by expansion of meta server was marked as * neutral. We have to collapse the servers and issue new * SRV resolution. */ state->meta = collapse_srv_lookup(&server); } if (ctx->srv_send_fn == NULL || ctx->srv_recv_fn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "No SRV lookup plugin is set\n"); ret = ENOTSUP; goto done; } subreq = ctx->srv_send_fn(state, ev, state->meta->srv_data->srv, state->meta->srv_data->proto, state->meta->srv_data->discovery_domain, ctx->srv_pvt); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, resolve_srv_done, req); break; case SRV_RESOLVE_ERROR: /* query could not be resolved but don't retry yet */ ret = EIO; state->out = server; /* The port status was reseted to neutral but we still haven't reached * timeout to try to resolve SRV record again. We will set the port * status back to not working. */ fo_set_port_status(state->meta, PORT_NOT_WORKING); goto done; case SRV_RESOLVED: /* The query is resolved and valid. Return. */ state->out = server; tevent_req_done(req); tevent_req_post(req, state->ev); return req; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected status %d for a SRV server\n", status); ret = EIO; goto done; } ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void resolve_srv_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct resolve_srv_state *state = tevent_req_data(req, struct resolve_srv_state); struct fo_server *last_server = NULL; struct fo_server_info *primary_servers = NULL; struct fo_server_info *backup_servers = NULL; size_t num_primary_servers = 0; size_t num_backup_servers = 0; char *dns_domain = NULL; int ret; uint32_t ttl; ret = state->fo_ctx->srv_recv_fn(state, subreq, &dns_domain, &ttl, &primary_servers, &num_primary_servers, &backup_servers, &num_backup_servers); talloc_free(subreq); switch (ret) { case EOK: if ((num_primary_servers == 0 || primary_servers == NULL) && (num_backup_servers == 0 || backup_servers == NULL)) { DEBUG(SSSDBG_CRIT_FAILURE, "SRV lookup plugin returned EOK but " "no servers\n"); ret = EFAULT; goto done; } state->meta->srv_data->ttl = ttl; talloc_zfree(state->meta->srv_data->dns_domain); state->meta->srv_data->dns_domain = talloc_steal(state->meta->srv_data, dns_domain); last_server = state->meta; if (primary_servers != NULL) { ret = fo_add_server_list(state->service, last_server, primary_servers, num_primary_servers, state->meta->srv_data, state->meta->user_data, true, &last_server); if (ret != EOK) { goto done; } } if (backup_servers != NULL) { ret = fo_add_server_list(state->service, last_server, backup_servers, num_backup_servers, state->meta->srv_data, state->meta->user_data, false, &last_server); if (ret != EOK) { goto done; } } if (last_server == state->meta) { /* SRV lookup returned only those servers * that are already present. */ DEBUG(SSSDBG_TRACE_FUNC, "SRV lookup did not return " "any new server.\n"); ret = ERR_SRV_DUPLICATES; goto done; } /* At least one new server was inserted. * We will return the first new server. */ if (state->meta->next == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "BUG: state->meta->next is NULL\n"); ret = ERR_INTERNAL; goto done; } state->out = state->meta->next; /* And remove meta server from the server list. It will be * inserted again during srv collapse. */ DLIST_REMOVE(state->service->server_list, state->meta); if (state->service->last_tried_server == state->meta) { state->service->last_tried_server = state->out; } set_srv_data_status(state->meta->srv_data, SRV_RESOLVED); ret = EOK; break; case ERR_SRV_NOT_FOUND: /* fall through */ case ERR_SRV_LOOKUP_ERROR: fo_set_port_status(state->meta, PORT_NOT_WORKING); /* fall through */ default: DEBUG(SSSDBG_OP_FAILURE, "Unable to resolve SRV [%d]: %s\n", ret, sss_strerror(ret)); } done: if (ret != EOK) { state->out = state->meta; set_srv_data_status(state->meta->srv_data, SRV_RESOLVE_ERROR); tevent_req_error(req, ret); return; } tevent_req_done(req); } static int resolve_srv_recv(struct tevent_req *req, struct fo_server **server) { struct resolve_srv_state *state = tevent_req_data(req, struct resolve_srv_state); /* always return the server if asked for, otherwise the caller * cannot mark it as faulty in case we return an error */ if (server) { *server = state->out; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /******************************************************************* * Get Fully Qualified Domain Name of the host machine * *******************************************************************/ static void set_server_common_status(struct server_common *common, enum server_status status) { DEBUG(SSSDBG_CONF_SETTINGS, "Marking server '%s' as '%s'\n", common->name, str_server_status(status)); common->server_status = status; gettimeofday(&common->last_status_change, NULL); } void fo_set_server_status(struct fo_server *server, enum server_status status) { if (server->common == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: Trying to set server status of a name-less server\n"); return; } set_server_common_status(server->common, status); } void fo_set_port_status(struct fo_server *server, enum port_status status) { struct fo_server *siter; DEBUG(SSSDBG_CONF_SETTINGS, "Marking port %d of server '%s' as '%s'\n", server->port, SERVER_NAME(server), str_port_status(status)); server->port_status = status; gettimeofday(&server->last_status_change, NULL); if (status == PORT_WORKING) { fo_set_server_status(server, SERVER_WORKING); server->service->active_server = server; } if (!server->common || !server->common->name) return; /* It is possible to introduce duplicates when expanding SRV results * into fo_server structures. Find the duplicates and set the same * status */ DLIST_FOR_EACH(siter, server->service->server_list) { if (fo_server_cmp(siter, server)) { DEBUG(SSSDBG_TRACE_FUNC, "Marking port %d of duplicate server '%s' as '%s'\n", siter->port, SERVER_NAME(siter), str_port_status(status)); siter->port_status = status; gettimeofday(&siter->last_status_change, NULL); } } } struct fo_server *fo_get_active_server(struct fo_service *service) { return service->active_server; } void fo_try_next_server(struct fo_service *service) { struct fo_server *server; if (!service) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: No service supplied\n"); return; } server = service->active_server; if (!server) { return; } service->active_server = 0; if (server->port_status == PORT_WORKING) { server->port_status = PORT_NEUTRAL; } } void * fo_get_server_user_data(struct fo_server *server) { return server->user_data; } int fo_get_server_port(struct fo_server *server) { return server->port; } const char * fo_get_server_name(struct fo_server *server) { if (!server->common) { return NULL; } return server->common->name; } const char *fo_get_server_str_name(struct fo_server *server) { if (!server->common) { if (fo_is_srv_lookup(server)) { return "SRV lookup meta-server"; } return "unknown name"; } return server->common->name; } struct resolv_hostent * fo_get_server_hostent(struct fo_server *server) { if (server->common == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: Trying to get hostent from a name-less server\n"); return NULL; } return server->common->rhostent; } bool fo_is_server_primary(struct fo_server *server) { return server->primary; } time_t fo_get_server_hostname_last_change(struct fo_server *server) { if (server->common == NULL) { return 0; } return server->common->last_status_change.tv_sec; } time_t fo_get_service_retry_timeout(struct fo_service *svc) { if (svc == NULL || svc->ctx == NULL || svc->ctx->opts == NULL) { return 0; } return svc->ctx->opts->retry_timeout; } void fo_reset_servers(struct fo_service *service) { struct fo_server *server; DLIST_FOR_EACH(server, service->server_list) { if (server->srv_data != NULL) { set_srv_data_status(server->srv_data, SRV_NEUTRAL); } if (server->common) { fo_set_server_status(server, SERVER_NAME_NOT_RESOLVED); } fo_set_port_status(server, PORT_NEUTRAL); } } void fo_reset_services(struct fo_ctx *fo_ctx) { struct fo_service *service; DEBUG(SSSDBG_TRACE_LIBS, "Resetting all servers in all services\n"); DLIST_FOR_EACH(service, fo_ctx->service_list) { fo_reset_servers(service); } } bool fo_svc_has_server(struct fo_service *service, struct fo_server *server) { struct fo_server *srv; DLIST_FOR_EACH(srv, service->server_list) { if (srv == server) return true; } return false; } bool fo_set_srv_lookup_plugin(struct fo_ctx *ctx, fo_srv_lookup_plugin_send_t send_fn, fo_srv_lookup_plugin_recv_t recv_fn, void *pvt) { if (ctx == NULL || send_fn == NULL || recv_fn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid parameters\n"); return false; } if (ctx->srv_send_fn != NULL || ctx->srv_recv_fn != NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "SRV lookup plugin is already set\n"); return false; } ctx->srv_send_fn = send_fn; ctx->srv_recv_fn = recv_fn; ctx->srv_pvt = talloc_steal(ctx, pvt); return true; } sssd-1.13.4/src/providers/PaxHeaders.16287/data_provider_be.c0000644000000000000000000000007412703456111020566 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.653793625 sssd-1.13.4/src/providers/data_provider_be.c0000644002412700241270000026553112703456111022251 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider Process Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "util/sss_utf8.h" #include "confdb/confdb.h" #include "db/sysdb.h" #include "sbus/sssd_dbus.h" #include "providers/dp_backend.h" #include "providers/fail_over.h" #include "providers/dp_refresh.h" #include "providers/dp_ptask.h" #include "util/child_common.h" #include "resolv/async_resolv.h" #include "monitor/monitor_interfaces.h" #define MSG_TARGET_NO_CONFIGURED "sssd_be: The requested target is not configured" #define ACCESS_PERMIT "permit" #define ACCESS_DENY "deny" #define NO_PROVIDER "none" static int data_provider_res_init(struct sbus_request *dbus_req, void *data); static int data_provider_go_offline(struct sbus_request *dbus_req, void *data); static int data_provider_reset_offline(struct sbus_request *dbus_req, void *data); static int data_provider_logrotate(struct sbus_request *dbus_req, void *data); struct mon_cli_iface monitor_be_methods = { { &mon_cli_iface_meta, 0 }, .ping = monitor_common_pong, .resInit = data_provider_res_init, .shutDown = NULL, .goOffline = data_provider_go_offline, .resetOffline = data_provider_reset_offline, .rotateLogs = data_provider_logrotate, .clearMemcache = NULL, .clearEnumCache = NULL, .sysbusReconnect = NULL, }; static int client_registration(struct sbus_request *dbus_req, void *data); static int be_get_account_info(struct sbus_request *dbus_req, void *user_data); static int be_pam_handler(struct sbus_request *dbus_req, void *user_data); static int be_sudo_handler(struct sbus_request *dbus_req, void *user_data); static int be_autofs_handler(struct sbus_request *dbus_req, void *user_data); static int be_host_handler(struct sbus_request *dbus_req, void *user_data); static int be_get_subdomains(struct sbus_request *dbus_req, void *user_data); struct data_provider_iface be_methods = { { &data_provider_iface_meta, 0 }, .RegisterService = client_registration, .pamHandler = be_pam_handler, .sudoHandler = be_sudo_handler, .autofsHandler = be_autofs_handler, .hostHandler = be_host_handler, .getDomains = be_get_subdomains, .getAccountInfo = be_get_account_info, }; static struct bet_data bet_data[] = { {BET_NULL, NULL, NULL}, {BET_ID, CONFDB_DOMAIN_ID_PROVIDER, "sssm_%s_id_init"}, {BET_AUTH, CONFDB_DOMAIN_AUTH_PROVIDER, "sssm_%s_auth_init"}, {BET_ACCESS, CONFDB_DOMAIN_ACCESS_PROVIDER, "sssm_%s_access_init"}, {BET_CHPASS, CONFDB_DOMAIN_CHPASS_PROVIDER, "sssm_%s_chpass_init"}, {BET_SUDO, CONFDB_DOMAIN_SUDO_PROVIDER, "sssm_%s_sudo_init"}, {BET_AUTOFS, CONFDB_DOMAIN_AUTOFS_PROVIDER, "sssm_%s_autofs_init"}, {BET_SELINUX, CONFDB_DOMAIN_SELINUX_PROVIDER, "sssm_%s_selinux_init"}, {BET_HOSTID, CONFDB_DOMAIN_HOSTID_PROVIDER, "sssm_%s_hostid_init"}, {BET_SUBDOMAINS, CONFDB_DOMAIN_SUBDOMAINS_PROVIDER, "sssm_%s_subdomains_init"}, {BET_MAX, NULL, NULL} }; struct bet_queue_item { struct bet_queue_item *prev; struct bet_queue_item *next; TALLOC_CTX *mem_ctx; struct be_req *be_req; be_req_fn_t fn; }; static const char *dp_err_to_string(int dp_err_type) { switch (dp_err_type) { case DP_ERR_OK: return "Success"; case DP_ERR_OFFLINE: return "Provider is Offline"; case DP_ERR_TIMEOUT: return "Request timed out"; case DP_ERR_FATAL: return "Internal Error"; default: break; } return "Unknown Error"; } static const char *safe_be_req_err_msg(const char *msg_in, int dp_err_type) { bool ok; if (msg_in == NULL) { /* No custom error, just use default */ return dp_err_to_string(dp_err_type); } ok = sss_utf8_check((const uint8_t *) msg_in, strlen(msg_in)); if (!ok) { DEBUG(SSSDBG_MINOR_FAILURE, "Back end message [%s] contains invalid non-UTF8 character, " \ "using default\n", msg_in); return dp_err_to_string(dp_err_type); } return msg_in; } #define REQ_PHASE_ACCESS 0 #define REQ_PHASE_SELINUX 1 struct be_req { struct be_client *becli; struct be_ctx *be_ctx; struct sss_domain_info *domain; void *req_data; be_async_callback_t fn; void *pvt; /* This is utilized in access provider * request handling to indicate if access or * selinux provider is calling the callback. */ int phase; struct be_req *prev; struct be_req *next; }; static int be_req_destructor(struct be_req *be_req) { DLIST_REMOVE(be_req->be_ctx->active_requests, be_req); return 0; } struct be_req *be_req_create(TALLOC_CTX *mem_ctx, struct be_client *becli, struct be_ctx *be_ctx, be_async_callback_t fn, void *pvt_fn_data) { struct be_req *be_req; be_req = talloc_zero(mem_ctx, struct be_req); if (be_req == NULL) return NULL; be_req->becli = becli; be_req->be_ctx = be_ctx; be_req->domain = be_ctx->domain; be_req->fn = fn; be_req->pvt = pvt_fn_data; /* Add this request to active request list and make sure it is * removed on termination. */ DLIST_ADD(be_ctx->active_requests, be_req); talloc_set_destructor(be_req, be_req_destructor); return be_req; } static errno_t be_req_set_domain(struct be_req *be_req, const char *domain) { struct sss_domain_info *dom = NULL; dom = find_domain_by_name(be_req->be_ctx->domain, domain, true); if (dom == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown domain [%s]!\n", domain); return ERR_DOMAIN_NOT_FOUND; } DEBUG(SSSDBG_TRACE_FUNC, "Changing request domain from [%s] to [%s]\n", be_req->domain->name, dom->name); be_req->domain = dom; return EOK; } struct be_ctx *be_req_get_be_ctx(struct be_req *be_req) { return be_req->be_ctx; } void *be_req_get_data(struct be_req *be_req) { return be_req->req_data; } void be_req_terminate(struct be_req *be_req, int dp_err_type, int errnum, const char *errstr) { if (be_req->fn == NULL) return; be_req->fn(be_req, dp_err_type, errnum, errstr); } void be_terminate_domain_requests(struct be_ctx *be_ctx, const char *domain) { struct be_req *be_req; struct be_req *next_be_req; DEBUG(SSSDBG_TRACE_FUNC, "Terminating requests for domain [%s]\n", domain); if (domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "BUG: domain is NULL\n"); return; } be_req = be_ctx->active_requests; while (be_req) { /* save pointer to next request in case be_req will be freed */ next_be_req = be_req->next; if (strcmp(domain, be_req->domain->name) == 0) { be_req_terminate(be_req, DP_ERR_FATAL, ERR_DOMAIN_NOT_FOUND, sss_strerror(ERR_DOMAIN_NOT_FOUND)); } be_req = next_be_req; } } struct be_async_req { be_req_fn_t fn; struct be_req *req; }; static void be_async_req_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct be_async_req *async_req; async_req = talloc_get_type(pvt, struct be_async_req); async_req->fn(async_req->req); } struct be_spy { TALLOC_CTX *freectx; struct be_spy *double_agent; }; static int be_spy_destructor(struct be_spy *spy) { /* If there's a double_agent, set its * freectx to NULL so that we don't * try to loop. When that spy fires, * it will just be a no-op. */ spy->double_agent->freectx = NULL; talloc_zfree(spy->freectx); return 0; } static errno_t be_spy_create(TALLOC_CTX *mem_ctx, struct be_req *be_req) { errno_t ret; struct be_spy *cli_spy = NULL; struct be_spy *req_spy = NULL; /* Attach a spy for the be_client so that if it dies, * we can free the be_req automatically. */ cli_spy = talloc_zero(be_req->becli, struct be_spy); if (!cli_spy) { ret = ENOMEM; goto done; } cli_spy->freectx = be_req; /* Also create a spy on the be_req so that we * can free the other spy when the be_req * completes successfully. */ req_spy = talloc_zero(be_req, struct be_spy); if (!req_spy) { ret = ENOMEM; goto done; } req_spy->freectx = cli_spy; /* Create paired spy links to prevent loops */ cli_spy->double_agent = req_spy; req_spy->double_agent = cli_spy; /* Now create the destructors that will actually free * the opposing spies. */ talloc_set_destructor(cli_spy, be_spy_destructor); talloc_set_destructor(req_spy, be_spy_destructor); /* Now steal the be_req onto the mem_ctx so that it * will be guaranteed that this data will be * available for the full duration of execution. */ talloc_steal(mem_ctx, be_req); ret = EOK; done: if (ret != EOK) { talloc_free(cli_spy); talloc_free(req_spy); } return ret; } /* This function alters the memory hierarchy of the be_req * to ensure memory safety during shutdown. It creates a * spy on the be_cli object so that it will free the be_req * if the client is freed. * * It is generally allocated atop the private data context * for the appropriate back-end against which it is being * filed. */ static errno_t be_file_request(TALLOC_CTX *mem_ctx, struct be_req *be_req, be_req_fn_t fn) { errno_t ret; struct be_async_req *areq; struct tevent_timer *te; struct timeval tv; if (!fn || !be_req) return EINVAL; ret = be_spy_create(mem_ctx, be_req); if (ret != EOK) return ret; areq = talloc(be_req, struct be_async_req); if (!areq) { return ENOMEM; } areq->fn = fn; areq->req = be_req; /* fire immediately */ tv.tv_sec = 0; tv.tv_usec = 0; te = tevent_add_timer(be_req->be_ctx->ev, be_req, tv, be_async_req_handler, areq); if (te == NULL) { return EIO; } return EOK; } static errno_t be_queue_request(TALLOC_CTX *queue_mem_ctx, struct bet_queue_item **req_queue, TALLOC_CTX *req_mem_ctx, struct be_req *be_req, be_req_fn_t fn) { struct bet_queue_item *item; int ret; if (*req_queue == NULL) { DEBUG(SSSDBG_TRACE_ALL, "Queue is empty, " \ "running request immediately.\n"); ret = be_file_request(req_mem_ctx, be_req, fn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "be_file_request failed.\n"); return ret; } } item = talloc_zero(queue_mem_ctx, struct bet_queue_item); if (item == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed, cannot add item to " \ "request queue.\n"); } else { DEBUG(SSSDBG_TRACE_ALL, "Adding request to queue.\n"); item->mem_ctx = req_mem_ctx; item->be_req = be_req; item->fn = fn; DLIST_ADD_END(*req_queue, item, struct bet_queue_item *); } return EOK; } static void be_queue_next_request(struct be_req *be_req, enum bet_type type) { struct bet_queue_item *item; struct bet_queue_item *current = NULL; struct bet_queue_item **req_queue; struct sbus_request *dbus_req; int ret; uint16_t err_maj; uint32_t err_min; const char *err_msg = "Cannot file back end request"; struct be_req *next_be_req = NULL; req_queue = &be_req->becli->bectx->bet_info[type].req_queue; if (*req_queue == NULL) { DEBUG(SSSDBG_TRACE_ALL, "Queue is empty, nothing to do.\n"); return; } DLIST_FOR_EACH(item, *req_queue) { if (item->be_req == be_req) { current = item; break; } } if (current != NULL) { DLIST_REMOVE(*req_queue, current); } if (*req_queue == NULL) { DEBUG(SSSDBG_TRACE_ALL, "Request queue is empty.\n"); return; } next_be_req = (*req_queue)->be_req; ret = be_file_request((*req_queue)->mem_ctx, next_be_req, (*req_queue)->fn); if (ret == EOK) { DEBUG(SSSDBG_TRACE_ALL, "Queued request filed successfully.\n"); return; } DEBUG(SSSDBG_OP_FAILURE, "be_file_request failed.\n"); be_queue_next_request(next_be_req, type); dbus_req = (struct sbus_request *) next_be_req->pvt; if (dbus_req) { /* Return a reply if one was requested * There may not be one if this request began * while we were offline */ err_maj = DP_ERR_FATAL; err_min = ret; sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &err_maj, DBUS_TYPE_UINT32, &err_min, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); } talloc_free(next_be_req); } bool be_is_offline(struct be_ctx *ctx) { return ctx->offstat.offline; } static void check_if_online(struct be_ctx *ctx); static errno_t try_to_go_online(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *be_ctx_void) { struct be_ctx *ctx = (struct be_ctx*) be_ctx_void; check_if_online(ctx); return EOK; } static int get_offline_timeout(struct be_ctx *ctx) { errno_t ret; int offline_timeout; ret = confdb_get_int(ctx->cdb, ctx->conf_path, CONFDB_DOMAIN_OFFLINE_TIMEOUT, 60, &offline_timeout); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get offline_timeout from confdb. " "Will use 60 seconds.\n"); offline_timeout = 60; } return offline_timeout; } void be_mark_offline(struct be_ctx *ctx) { int offline_timeout; errno_t ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Going offline!\n"); ctx->offstat.went_offline = time(NULL); ctx->offstat.offline = true; ctx->run_online_cb = true; if (ctx->check_if_online_ptask == NULL) { /* This is the first time we go offline - create a periodic task * to check if we can switch to online. */ DEBUG(SSSDBG_TRACE_INTERNAL, "Initialize check_if_online_ptask.\n"); offline_timeout = get_offline_timeout(ctx); ret = be_ptask_create_sync(ctx, ctx, offline_timeout, offline_timeout, offline_timeout, 30, offline_timeout, BE_PTASK_OFFLINE_EXECUTE, 3600 /* max_backoff */, try_to_go_online, ctx, "Check if online (periodic)", &ctx->check_if_online_ptask); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "be_ptask_create_sync failed [%d]: %s\n", ret, sss_strerror(ret)); } } else { /* Periodic task was already created. Just enable it. */ DEBUG(SSSDBG_TRACE_INTERNAL, "Enable check_if_online_ptask.\n"); be_ptask_enable(ctx->check_if_online_ptask); } be_run_offline_cb(ctx); } static void be_subdom_reset_status(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { struct sss_domain_info *subdom = talloc_get_type(pvt, struct sss_domain_info); DEBUG(SSSDBG_TRACE_LIBS, "Resetting subdomain %s\n", subdom->name); subdom->state = DOM_ACTIVE; } static void be_mark_subdom_offline(struct sss_domain_info *subdom, struct be_ctx *be_ctx) { struct timeval tv; struct tevent_timer *timeout = NULL; int reset_status_timeout; reset_status_timeout = get_offline_timeout(be_ctx); tv = tevent_timeval_current_ofs(reset_status_timeout, 0); switch (subdom->state) { case DOM_DISABLED: DEBUG(SSSDBG_MINOR_FAILURE, "Won't touch disabled subdomain\n"); return; case DOM_INACTIVE: DEBUG(SSSDBG_TRACE_ALL, "Subdomain already inactive\n"); return; case DOM_ACTIVE: DEBUG(SSSDBG_TRACE_LIBS, "Marking subdomain %s as inactive\n", subdom->name); break; } timeout = tevent_add_timer(be_ctx->ev, be_ctx, tv, be_subdom_reset_status, subdom); if (timeout == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot create timer\n"); return; } subdom->state = DOM_INACTIVE; } void be_mark_dom_offline(struct sss_domain_info *dom, struct be_ctx *ctx) { if (IS_SUBDOMAIN(dom) == false) { DEBUG(SSSDBG_TRACE_LIBS, "Marking back end offline\n"); be_mark_offline(ctx); } else { DEBUG(SSSDBG_TRACE_LIBS, "Marking subdomain %s offline\n", dom->name); be_mark_subdom_offline(dom, ctx); } } static void reactivate_subdoms(struct sss_domain_info *head) { struct sss_domain_info *dom; DEBUG(SSSDBG_TRACE_LIBS, "Resetting all subdomains\n"); for (dom = head; dom; dom = get_next_domain(dom, true)) { if (sss_domain_get_state(dom) == DOM_INACTIVE) { sss_domain_set_state(dom, DOM_ACTIVE); } } } static void be_reset_offline(struct be_ctx *ctx) { ctx->offstat.went_offline = 0; ctx->offstat.offline = false; reactivate_subdoms(ctx->domain); be_ptask_disable(ctx->check_if_online_ptask); be_run_online_cb(ctx); } static void get_subdomains_callback(struct be_req *req, int dp_err_type, int errnum, const char *errstr) { struct sbus_request *dbus_req; dbus_uint16_t err_maj = 0; dbus_uint32_t err_min = 0; const char *err_msg = NULL; DEBUG(SSSDBG_TRACE_FUNC, "Backend returned: (%d, %d, %s) [%s]\n", dp_err_type, errnum, errstr?errstr:"", dp_err_to_string(dp_err_type)); be_queue_next_request(req, BET_SUBDOMAINS); dbus_req = (struct sbus_request *)req->pvt; if (dbus_req) { /* Return a reply if one was requested * There may not be one if this request began * while we were offline */ err_maj = dp_err_type; err_min = errnum; err_msg = safe_be_req_err_msg(errstr, dp_err_type); sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &err_maj, DBUS_TYPE_UINT32, &err_min, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); } talloc_free(req); } static int be_get_subdomains(struct sbus_request *dbus_req, void *user_data) { struct be_subdom_req *req; struct be_req *be_req = NULL; struct be_client *becli; char *domain_hint; dbus_uint16_t err_maj; dbus_uint32_t err_min; const char *err_msg; int ret; becli = talloc_get_type(user_data, struct be_client); if (!becli) return EINVAL; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_STRING, &domain_hint, DBUS_TYPE_INVALID)) return EOK; /* handled */ /* return an error if corresponding backend target is not configured */ if (becli->bectx->bet_info[BET_SUBDOMAINS].bet_ops == NULL) { DEBUG(SSSDBG_TRACE_INTERNAL, "Undefined backend target.\n"); err_maj = DP_ERR_FATAL; err_min = ENODEV; err_msg = "Subdomains back end target is not configured"; goto immediate; } DEBUG(SSSDBG_TRACE_FUNC, "Got get subdomains [%s]\n", domain_hint == NULL ? "no hint": domain_hint ); /* If we are offline return immediately */ if (becli->bectx->offstat.offline) { DEBUG(SSSDBG_TRACE_FUNC, "Cannot proceed, provider is offline.\n"); err_maj = DP_ERR_OFFLINE; err_min = EAGAIN; err_msg = "Provider is offline"; goto immediate; } /* process request */ be_req = be_req_create(becli, becli, becli->bectx, get_subdomains_callback, dbus_req); if (!be_req) { err_maj = DP_ERR_FATAL; err_min = ENOMEM; err_msg = "Out of memory"; goto immediate; } req = talloc(be_req, struct be_subdom_req); if (!req) { err_maj = DP_ERR_FATAL; err_min = ENOMEM; err_msg = "Out of memory"; goto immediate; } req->domain_hint = talloc_strdup(req, domain_hint); if (!req->domain_hint) { err_maj = DP_ERR_FATAL; err_min = ENOMEM; err_msg = "Out of memory"; goto immediate; } be_req->req_data = req; ret = be_queue_request(becli->bectx, &becli->bectx->bet_info[BET_SUBDOMAINS].req_queue, becli->bectx, be_req, becli->bectx->bet_info[BET_SUBDOMAINS].bet_ops->handler); if (ret != EOK) { err_maj = DP_ERR_FATAL; err_min = ret; err_msg = "Cannot file back end request"; goto immediate; } return EOK; immediate: if (be_req) { talloc_free(be_req); } /* send reply back */ sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &err_maj, DBUS_TYPE_UINT32, &err_min, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); if (!(err_maj == DP_ERR_FATAL && err_min == ENODEV)) { DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); } return EOK; } static void acctinfo_callback(struct be_req *req, int dp_err_type, int errnum, const char *errstr) { struct sbus_request *dbus_req; dbus_uint16_t err_maj = 0; dbus_uint32_t err_min = 0; const char *err_msg = NULL; dbus_req = (struct sbus_request *)req->pvt; if (dbus_req) { /* Return a reply if one was requested * There may not be one if this request began * while we were offline */ err_maj = dp_err_type; err_min = errnum; err_msg = safe_be_req_err_msg(errstr, dp_err_type); sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &err_maj, DBUS_TYPE_UINT32, &err_min, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); DEBUG(SSSDBG_CONF_SETTINGS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); } /* finally free the request */ talloc_free(req); } struct be_initgr_prereq { char *user; char *domain; uint32_t gnum; uint32_t *groups; void *orig_pvt_data; int orig_dp_err_type; int orig_errnum; const char *orig_errstr; }; static void acctinfo_callback_initgr_wrap(struct be_req *be_req) { struct be_initgr_prereq *pr = talloc_get_type(be_req->pvt, struct be_initgr_prereq); be_req->pvt = pr->orig_pvt_data; acctinfo_callback(be_req, pr->orig_dp_err_type, pr->orig_errnum, pr->orig_errstr); } static void acctinfo_callback_initgr_sbus(DBusPendingCall *pending, void *ptr) { struct be_req *be_req = talloc_get_type(ptr, struct be_req); dbus_pending_call_unref(pending); acctinfo_callback_initgr_wrap(be_req); } static void acctinfo_initgroups_callback(struct be_req *be_req, int dp_err_type, int errnum, const char *errstr) { struct be_initgr_prereq *pr = talloc_get_type(be_req->pvt, struct be_initgr_prereq); DBusMessage *msg = NULL; dbus_bool_t dbret; int num; int ret; pr->orig_dp_err_type = dp_err_type; pr->orig_errnum = errnum; pr->orig_errstr = errstr; if (!be_req->be_ctx->nss_cli || !be_req->be_ctx->nss_cli->conn) { DEBUG(SSSDBG_MINOR_FAILURE, "NSS Service not conected\n"); ret = EACCES; goto done; } /* Set up null request */ msg = dbus_message_new_method_call(NULL, DP_PATH, DATA_PROVIDER_REV_IFACE, DATA_PROVIDER_REV_IFACE_INITGRCHECK); if (!msg) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); ret = ENOMEM; goto done; } num = pr->gnum; dbret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &pr->user, DBUS_TYPE_STRING, &pr->domain, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &pr->groups, num, DBUS_TYPE_INVALID); if (!dbret) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); ret = ENOMEM; goto done; } /* ping the NSS service, no reply expected */ ret = sbus_conn_send(be_req->be_ctx->nss_cli->conn, msg, -1, acctinfo_callback_initgr_sbus, be_req, NULL); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Error contacting NSS responder: %d [%s]\n", ret, strerror(ret)); } done: if (msg) { dbus_message_unref(msg); } if (ret != EOK) { /* return immediately if we cannot contact nss provider */ acctinfo_callback_initgr_wrap(be_req); } } static errno_t be_initgroups_prereq(struct be_req *be_req) { struct be_acct_req *ar = talloc_get_type(be_req_get_data(be_req), struct be_acct_req); struct be_initgr_prereq *pr; struct ldb_result *res; errno_t ret; const char *tmpstr; int i; ret = sysdb_initgroups(be_req, be_req->be_ctx->domain, ar->filter_value, &res); if (ret && ret != ENOENT) { return ret; } /* if the user is completely missing there is no need to contact NSS, * it would be a noop */ if (ret == ENOENT || res->count == 0) { /* yet unknown, ignore */ return EOK; } pr = talloc(be_req, struct be_initgr_prereq); if (!pr) { return ENOMEM; } pr->groups = talloc_array(pr, gid_t, res->count); if (!pr->groups) { return ENOMEM; } tmpstr = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); if (!tmpstr) { return EINVAL; } pr->user = talloc_strdup(pr, tmpstr); if (!pr->user) { return ENOMEM; } pr->domain = talloc_strdup(pr, be_req->be_ctx->domain->name); if (!pr->domain) { return ENOMEM; } /* The first GID is the primary so it might be duplicated * later in the list */ for (pr->gnum = 0, i = 0; i < res->count; i++) { pr->groups[pr->gnum] = ldb_msg_find_attr_as_uint(res->msgs[i], SYSDB_GIDNUM, 0); /* if 0 it may be a non-posix group, so we skip it */ if (pr->groups[pr->gnum] != 0) { pr->gnum++; } } talloc_zfree(res); pr->orig_pvt_data = be_req->pvt; be_req->pvt = pr; be_req->fn = acctinfo_initgroups_callback; return EOK; } static errno_t be_file_account_request(struct be_req *be_req, struct be_acct_req *ar) { errno_t ret; struct be_ctx *be_ctx = be_req->be_ctx; be_req->req_data = ar; /* see if we need a pre request call, only done for initgroups for now */ if ((ar->entry_type & 0xFF) == BE_REQ_INITGROUPS) { ret = be_initgroups_prereq(be_req); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Prerequest failed\n"); return ret; } } /* process request */ ret = be_file_request(be_ctx, be_req, be_ctx->bet_info[BET_ID].bet_ops->handler); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to file request\n"); return ret; } return EOK; } static errno_t split_name_extended(TALLOC_CTX *mem_ctx, const char *filter, char **name, char **extended) { char *p; *name = talloc_strdup(mem_ctx, filter); if (!*name) { return ENOENT; } p = strchr(*name, ':'); if (p) { /* Extended info included */ *p = '\0'; *extended = p + 1; } else { *extended = NULL; } return EOK; } static void be_get_account_info_done(struct be_req *be_req, int dp_err, int dp_ret, const char *errstr); struct be_get_account_info_state { int err_maj; int err_min; const char *err_msg; }; struct tevent_req * be_get_account_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_client *becli, struct be_ctx *be_ctx, struct be_acct_req *ar) { struct tevent_req *req; struct be_get_account_info_state *state; struct be_req *be_req; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct be_get_account_info_state); if (!req) return NULL; be_req = be_req_create(state, becli, be_ctx, be_get_account_info_done, req); if (!be_req) { ret = ENOMEM; goto done; } ret = be_req_set_domain(be_req, ar->domain); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set request domain [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = be_file_account_request(be_req, ar); if (ret != EOK) { goto done; } return req; done: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void be_get_account_info_done(struct be_req *be_req, int dp_err, int dp_ret, const char *errstr) { struct tevent_req *req; struct be_get_account_info_state *state; req = talloc_get_type(be_req->pvt, struct tevent_req); state = tevent_req_data(req, struct be_get_account_info_state); state->err_maj = dp_err; state->err_min = dp_ret; if (errstr) { state->err_msg = talloc_strdup(state, errstr); if (state->err_msg == NULL) { talloc_free(be_req); tevent_req_error(req, ENOMEM); return; } } talloc_free(be_req); tevent_req_done(req); } errno_t be_get_account_info_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, int *_err_maj, int *_err_min, const char **_err_msg) { struct be_get_account_info_state *state; state = tevent_req_data(req, struct be_get_account_info_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_err_maj) { *_err_maj = state->err_maj; } if (_err_min) { *_err_min = state->err_min; } if (_err_msg) { *_err_msg = talloc_steal(mem_ctx, state->err_msg); } return EOK; } static int be_get_account_info(struct sbus_request *dbus_req, void *user_data) { struct be_acct_req *req; struct be_req *be_req; struct be_client *becli; uint32_t type; char *filter; char *domain; uint32_t attr_type; int ret; dbus_uint16_t err_maj; dbus_uint32_t err_min; const char *err_msg; be_req = NULL; becli = talloc_get_type(user_data, struct be_client); if (!becli) return EINVAL; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_UINT32, &type, DBUS_TYPE_UINT32, &attr_type, DBUS_TYPE_STRING, &filter, DBUS_TYPE_STRING, &domain, DBUS_TYPE_INVALID)) return EOK; /* handled */ DEBUG(SSSDBG_FUNC_DATA, "Got request for [%#x][%s][%d][%s]\n", type, be_req2str(type), attr_type, filter); /* If we are offline and fast reply was requested * return offline immediately */ if ((type & BE_REQ_FAST) && becli->bectx->offstat.offline) { /* Send back an immediate reply */ err_maj = DP_ERR_OFFLINE; err_min = EAGAIN; err_msg = "Fast reply - offline"; ret = sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &err_maj, DBUS_TYPE_UINT32, &err_min, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); if (ret != EOK) { return ret; } DEBUG(SSSDBG_CONF_SETTINGS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); dbus_req = NULL; /* This reply will be queued and sent * when we reenter the mainloop. * * Continue processing in case we are * going back online. */ } be_req = be_req_create(becli, becli, becli->bectx, acctinfo_callback, dbus_req); if (!be_req) { err_maj = DP_ERR_FATAL; err_min = ENOMEM; err_msg = "Out of memory"; goto done; } ret = be_req_set_domain(be_req, domain); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set request domain [%d]: %s\n", ret, sss_strerror(ret)); err_maj = DP_ERR_FATAL; err_min = ret; err_msg = sss_strerror(ret); goto done; } req = talloc_zero(be_req, struct be_acct_req); if (!req) { err_maj = DP_ERR_FATAL; err_min = ENOMEM; err_msg = "Out of memory"; goto done; } req->entry_type = type; req->attr_type = (int)attr_type; req->domain = talloc_strdup(req, domain); if (!req->domain) { err_maj = DP_ERR_FATAL; err_min = ENOMEM; err_msg = "Out of memory"; goto done; } if ((attr_type != BE_ATTR_CORE) && (attr_type != BE_ATTR_MEM) && (attr_type != BE_ATTR_ALL)) { /* Unrecognized attr type */ err_maj = DP_ERR_FATAL; err_min = EINVAL; err_msg = "Invalid Attrs Parameter"; goto done; } if (filter) { ret = EOK; if (strncmp(filter, "name=", 5) == 0) { req->filter_type = BE_FILTER_NAME; ret = split_name_extended(req, &filter[5], &req->filter_value, &req->extra_value); } else if (strncmp(filter, "idnumber=", 9) == 0) { req->filter_type = BE_FILTER_IDNUM; ret = split_name_extended(req, &filter[9], &req->filter_value, &req->extra_value); } else if (strncmp(filter, DP_SEC_ID"=", DP_SEC_ID_LEN + 1) == 0) { req->filter_type = BE_FILTER_SECID; ret = split_name_extended(req, &filter[DP_SEC_ID_LEN + 1], &req->filter_value, &req->extra_value); } else if (strncmp(filter, DP_CERT"=", DP_CERT_LEN + 1) == 0) { req->filter_type = BE_FILTER_CERT; ret = split_name_extended(req, &filter[DP_CERT_LEN + 1], &req->filter_value, &req->extra_value); } else if (strncmp(filter, DP_WILDCARD"=", DP_WILDCARD_LEN + 1) == 0) { req->filter_type = BE_FILTER_WILDCARD; ret = split_name_extended(req, &filter[DP_WILDCARD_LEN + 1], &req->filter_value, &req->extra_value); } else if (strcmp(filter, ENUM_INDICATOR) == 0) { req->filter_type = BE_FILTER_ENUM; req->filter_value = NULL; req->extra_value = NULL; } else { err_maj = DP_ERR_FATAL; err_min = EINVAL; err_msg = "Invalid Filter"; goto done; } if (ret != EOK) { err_maj = DP_ERR_FATAL; err_min = EINVAL; err_msg = "Invalid Filter"; goto done; } } else { err_maj = DP_ERR_FATAL; err_min = EINVAL; err_msg = "Missing Filter Parameter"; goto done; } ret = be_file_account_request(be_req, req); if (ret != EOK) { err_maj = DP_ERR_FATAL; err_min = ret; err_msg = "Cannot file account request"; goto done; } return EOK; done: if (be_req) { talloc_free(be_req); } if (dbus_req) { ret = sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &err_maj, DBUS_TYPE_UINT32, &err_min, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); if (ret != EOK) { return ret; } DEBUG(SSSDBG_CONF_SETTINGS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); } return EOK; } static void be_pam_handler_callback(struct be_req *req, int dp_err_type, int errnum, const char *errstr) { struct be_client *becli = req->becli; struct sbus_request *dbus_req; struct pam_data *pd; DBusMessage *reply; dbus_bool_t dbret; errno_t ret; DEBUG(SSSDBG_CONF_SETTINGS, "Backend returned: (%d, %d, %s) [%s]\n", dp_err_type, errnum, errstr?errstr:"", dp_err_to_string(dp_err_type)); pd = talloc_get_type(be_req_get_data(req), struct pam_data); if (pd->cmd == SSS_PAM_ACCT_MGMT && pd->pam_status == PAM_SUCCESS && req->phase == REQ_PHASE_ACCESS && dp_err_type == DP_ERR_OK) { if (!becli->bectx->bet_info[BET_SELINUX].bet_ops) { DEBUG(SSSDBG_TRACE_FUNC, "SELinux provider doesn't exist, " "not sending the request to it.\n"); } else { req->phase = REQ_PHASE_SELINUX; /* Now is the time to call SELinux provider */ ret = be_file_request(becli->bectx->bet_info[BET_SELINUX].pvt_bet_data, req, becli->bectx->bet_info[BET_SELINUX].bet_ops->handler); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "be_file_request failed.\n"); goto done; } return; } } DEBUG(SSSDBG_CONF_SETTINGS, "Sending result [%d][%s]\n", pd->pam_status, pd->domain); dbus_req = (struct sbus_request *)req->pvt; reply = dbus_message_new_method_return(dbus_req->message); if (reply == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "dbus_message_new_method_return failed, cannot send reply.\n"); goto done; } dbret = dp_pack_pam_response(reply, pd); if (!dbret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n"); dbus_message_unref(reply); goto done; } sbus_request_finish(dbus_req, reply); dbus_message_unref(reply); DEBUG(SSSDBG_CONF_SETTINGS, "Sent result [%d][%s]\n", pd->pam_status, pd->domain); done: talloc_free(req); } static int be_pam_handler(struct sbus_request *dbus_req, void *user_data) { DBusError dbus_error; DBusMessage *reply; struct be_client *becli; dbus_bool_t ret; struct pam_data *pd = NULL; struct be_req *be_req = NULL; enum bet_type target = BET_NULL; becli = talloc_get_type(user_data, struct be_client); if (!becli) return EINVAL; be_req = be_req_create(becli, becli, becli->bectx, be_pam_handler_callback, dbus_req); if (!be_req) { DEBUG(SSSDBG_TRACE_LIBS, "talloc_zero failed.\n"); return ENOMEM; } dbus_error_init(&dbus_error); ret = dp_unpack_pam_request(dbus_req->message, be_req, &pd, &dbus_error); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse message!\n"); talloc_free(be_req); return EIO; } pd->pam_status = PAM_SYSTEM_ERR; if (pd->domain == NULL) { pd->domain = talloc_strdup(pd, becli->bectx->domain->name); if (pd->domain == NULL) { talloc_free(be_req); return ENOMEM; } } ret = be_req_set_domain(be_req, pd->domain); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set request domain [%d]: %s\n", ret, sss_strerror(ret)); pd->pam_status = PAM_SYSTEM_ERR; goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Got request with the following data\n"); DEBUG_PAM_DATA(SSSDBG_CONF_SETTINGS, pd); switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: case SSS_PAM_PREAUTH: target = BET_AUTH; break; case SSS_PAM_ACCT_MGMT: target = BET_ACCESS; be_req->phase = REQ_PHASE_ACCESS; break; case SSS_PAM_CHAUTHTOK: case SSS_PAM_CHAUTHTOK_PRELIM: target = BET_CHPASS; break; case SSS_PAM_OPEN_SESSION: case SSS_PAM_SETCRED: case SSS_PAM_CLOSE_SESSION: pd->pam_status = PAM_SUCCESS; goto done; break; default: DEBUG(SSSDBG_TRACE_LIBS, "Unsupported PAM command [%d].\n", pd->cmd); pd->pam_status = PAM_MODULE_UNKNOWN; goto done; } /* return PAM_MODULE_UNKNOWN if corresponding backend target is not * configured */ if (!becli->bectx->bet_info[target].bet_ops) { DEBUG(SSSDBG_TRACE_LIBS, "Undefined backend target.\n"); pd->pam_status = PAM_MODULE_UNKNOWN; goto done; } be_req->req_data = pd; ret = be_file_request(becli->bectx->bet_info[target].pvt_bet_data, be_req, becli->bectx->bet_info[target].bet_ops->handler); if (ret != EOK) { DEBUG(SSSDBG_TRACE_LIBS, "be_file_request failed.\n"); goto done; } return EOK; done: DEBUG(SSSDBG_CONF_SETTINGS, "Sending result [%d][%s]\n", pd->pam_status, pd->domain); reply = dbus_message_new_method_return(dbus_req->message); if (reply == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "dbus_message_new_method_return failed, cannot send reply.\n"); return ENOMEM; } ret = dp_pack_pam_response(reply, pd); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n"); talloc_free(be_req); dbus_message_unref(reply); return EIO; } /* send reply back immediately */ sbus_request_finish(dbus_req, reply); dbus_message_unref(reply); talloc_free(be_req); return EOK; } static void be_sudo_handler_reply(struct sbus_request *dbus_req, dbus_uint16_t dp_err, dbus_uint32_t dp_ret, const char *errstr) { const char *err_msg = NULL; if (dbus_req == NULL) { return; } err_msg = errstr ? errstr : "No errmsg set\n"; sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &dp_err, DBUS_TYPE_UINT32, &dp_ret, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); DEBUG(SSSDBG_FUNC_DATA, "SUDO Backend returned: (%d, %d, %s)\n", dp_err, dp_ret, errstr ? errstr : ""); } static void be_sudo_handler_callback(struct be_req *req, int dp_err, int dp_ret, const char *errstr) { const char *err_msg = NULL; struct sbus_request *dbus_req; dbus_req = (struct sbus_request *)(req->pvt); err_msg = safe_be_req_err_msg(errstr, dp_err); be_sudo_handler_reply(dbus_req, dp_err, dp_ret, err_msg); talloc_free(req); } static int be_sudo_handler(struct sbus_request *dbus_req, void *user_data) { DBusError dbus_error; DBusMessageIter iter; DBusMessageIter array_iter; struct be_client *be_cli = NULL; struct be_req *be_req = NULL; struct be_sudo_req *sudo_req = NULL; int ret = 0; uint32_t type; uint32_t rules_num = 0; const char *rule = NULL; const char *err_msg = NULL; int i; DEBUG(SSSDBG_TRACE_FUNC, "Entering be_sudo_handler()\n"); be_cli = talloc_get_type(user_data, struct be_client); if (be_cli == NULL) { return EINVAL; } /* create be request */ be_req = be_req_create(be_cli, be_cli, be_cli->bectx, be_sudo_handler_callback, dbus_req); if (be_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } dbus_error_init(&dbus_error); dbus_message_iter_init(dbus_req->message, &iter); /* get type of the request */ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n"); ret = EIO; err_msg = "Invalid D-Bus message format"; goto fail; } dbus_message_iter_get_basic(&iter, &type); dbus_message_iter_next(&iter); /* step behind the request type */ /* If we are offline and fast reply was requested * return offline immediately */ if ((type & BE_REQ_FAST) && be_cli->bectx->offstat.offline) { be_sudo_handler_reply(dbus_req, DP_ERR_OFFLINE, EAGAIN, "Fast reply - offline"); be_req->pvt = dbus_req = NULL; /* This reply will be queued and sent * when we reenter the mainloop. * * Continue processing in case we are * going back online. */ } /* get and set sudo request data */ sudo_req = talloc_zero(be_req, struct be_sudo_req); if (sudo_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); goto fail; } sudo_req->type = (~BE_REQ_FAST) & type; /* get additional arguments according to the request type */ switch (sudo_req->type) { case BE_REQ_SUDO_FULL: /* no arguments required */ break; case BE_REQ_SUDO_RULES: /* additional arguments: * rules_num * rules[rules_num] */ /* read rules_num */ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n"); ret = EIO; err_msg = "Invalid D-Bus message format"; goto fail; } dbus_message_iter_get_basic(&iter, &rules_num); sudo_req->rules = talloc_array(sudo_req, char*, rules_num + 1); if (sudo_req->rules == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto fail; } dbus_message_iter_next(&iter); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n"); ret = EIO; err_msg = "Invalid D-Bus message format"; goto fail; } dbus_message_iter_recurse(&iter, &array_iter); /* read the rules */ for (i = 0; i < rules_num; i++) { if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_STRING) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed, to parse the message!\n"); ret = EIO; err_msg = "Invalid D-Bus message format"; goto fail; } dbus_message_iter_get_basic(&array_iter, &rule); sudo_req->rules[i] = talloc_strdup(sudo_req->rules, rule); if (sudo_req->rules[i] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto fail; } dbus_message_iter_next(&array_iter); } sudo_req->rules[rules_num] = NULL; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type %d\n", sudo_req->type); ret = EINVAL; err_msg = "Invalid DP request type"; goto fail; } be_req->req_data = sudo_req; /* return an error if corresponding backend target is not configured */ if (!be_cli->bectx->bet_info[BET_SUDO].bet_ops) { DEBUG(SSSDBG_CRIT_FAILURE, "Undefined backend target.\n"); ret = ENODEV; goto fail; } ret = be_file_request(be_cli->bectx->bet_info[BET_SUDO].pvt_bet_data, be_req, be_cli->bectx->bet_info[BET_SUDO].bet_ops->handler); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_file_request failed.\n"); err_msg = "Cannot file back end request"; goto fail; } return EOK; fail: /* send reply back immediately */ be_sudo_handler_callback(be_req, DP_ERR_FATAL, ret, err_msg ? err_msg : strerror(ret)); return EOK; } static void be_autofs_handler_callback(struct be_req *req, int dp_err_type, int errnum, const char *errstr); static int be_autofs_handler(struct sbus_request *dbus_req, void *user_data) { struct be_client *be_cli = NULL; struct be_req *be_req = NULL; struct be_autofs_req *be_autofs_req = NULL; int ret = 0; uint32_t type; char *filter; char *filter_val; dbus_uint16_t err_maj; dbus_uint32_t err_min; const char *err_msg; DEBUG(SSSDBG_TRACE_FUNC, "Entering be_autofs_handler()\n"); be_cli = talloc_get_type(user_data, struct be_client); if (be_cli == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get back end client context\n"); return EINVAL; } if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_UINT32, &type, DBUS_TYPE_STRING, &filter, DBUS_TYPE_INVALID)) return EOK; /* handled */ /* If we are offline and fast reply was requested * return offline immediately */ if ((type & BE_REQ_FAST) && be_cli->bectx->offstat.offline) { /* Send back an immediate reply */ err_maj = DP_ERR_OFFLINE; err_min = EAGAIN; err_msg = "Fast reply - offline"; ret = sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &err_maj, DBUS_TYPE_UINT32, &err_min, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); if (ret != EOK) { return ret; } DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); dbus_req = NULL; /* This reply will be queued and sent * when we reenter the mainloop. * * Continue processing in case we are * going back online. */ } if (filter) { if (strncmp(filter, "mapname=", 8) == 0) { filter_val = &filter[8]; } else { err_maj = DP_ERR_FATAL; err_min = EINVAL; err_msg = "Invalid Filter"; goto done; } } else { err_maj = DP_ERR_FATAL; err_min = EINVAL; err_msg = "Missing Filter Parameter"; goto done; } /* create be request */ be_req = be_req_create(be_cli, be_cli, be_cli->bectx, be_autofs_handler_callback, dbus_req); if (be_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); err_maj = DP_ERR_FATAL; err_min = ENOMEM; err_msg = "Out of memory"; goto done; } /* set autofs request data */ be_autofs_req = talloc_zero(be_req, struct be_autofs_req); if (be_autofs_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); err_maj = DP_ERR_FATAL; err_min = ENOMEM; err_msg = "Out of memory"; goto done; } be_autofs_req->mapname = talloc_strdup(be_autofs_req, filter_val); if (be_autofs_req->mapname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); err_maj = DP_ERR_FATAL; err_min = ENOMEM; err_msg = "Out of memory"; goto done; } be_req->req_data = be_autofs_req; if (!be_cli->bectx->bet_info[BET_AUTOFS].bet_ops) { DEBUG(SSSDBG_CRIT_FAILURE, "Undefined backend target.\n"); err_maj = DP_ERR_FATAL; err_min = ENODEV; err_msg = "Autofs back end target is not configured"; goto done; } ret = be_file_request(be_cli->bectx->bet_info[BET_AUTOFS].pvt_bet_data, be_req, be_cli->bectx->bet_info[BET_AUTOFS].bet_ops->handler); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_file_request failed.\n"); err_maj = DP_ERR_FATAL; err_min = ENODEV; err_msg = "Cannot file back end request"; goto done; } return EOK; done: if (be_req) { talloc_free(be_req); } if (dbus_req) { ret = sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &err_maj, DBUS_TYPE_UINT32, &err_min, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); if (ret != EOK) { return ret; } DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); } return EOK; } static void be_autofs_handler_callback(struct be_req *req, int dp_err_type, int errnum, const char *errstr) { struct sbus_request *dbus_req; dbus_uint16_t err_maj = 0; dbus_uint32_t err_min = 0; const char *err_msg = NULL; dbus_req = (struct sbus_request *)req->pvt; if (dbus_req) { /* Return a reply if one was requested * There may not be one if this request began * while we were offline */ err_maj = dp_err_type; err_min = errnum; err_msg = safe_be_req_err_msg(errstr, dp_err_type); sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &err_maj, DBUS_TYPE_UINT32, &err_min, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); } /* finally free the request */ talloc_free(req); } static int be_host_handler(struct sbus_request *dbus_req, void *user_data) { struct be_host_req *req; struct be_req *be_req; struct be_client *becli; uint32_t flags; char *filter; int ret; dbus_uint16_t err_maj; dbus_uint32_t err_min; const char *err_msg; be_req = NULL; becli = talloc_get_type(user_data, struct be_client); if (!becli) return EINVAL; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_UINT32, &flags, DBUS_TYPE_STRING, &filter, DBUS_TYPE_INVALID)) return EOK; /* request finished */ DEBUG(SSSDBG_TRACE_LIBS, "Got request for [%u][%s]\n", flags, filter); /* If we are offline and fast reply was requested * return offline immediately */ if ((flags & BE_REQ_FAST) && becli->bectx->offstat.offline) { /* Send back an immediate reply */ err_maj = DP_ERR_OFFLINE; err_min = EAGAIN; err_msg = "Fast reply - offline"; ret = sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &err_maj, DBUS_TYPE_UINT32, &err_min, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); if (ret != EOK) { return ret; } DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); dbus_req = NULL; /* This reply will be queued and sent * when we reenter the mainloop. * * Continue processing in case we are * going back online. */ } be_req = be_req_create(becli, becli, becli->bectx, acctinfo_callback, dbus_req); if (!be_req) { err_maj = DP_ERR_FATAL; err_min = ENOMEM; err_msg = "Out of memory"; goto done; } req = talloc(be_req, struct be_host_req); if (!req) { err_maj = DP_ERR_FATAL; err_min = ENOMEM; err_msg = "Out of memory"; goto done; } req->type = BE_REQ_HOST | (flags & BE_REQ_FAST); be_req->req_data = req; if (filter) { ret = strncmp(filter, "name=", 5); if (ret == 0) { req->filter_type = BE_FILTER_NAME; ret = split_name_extended(req, &filter[5], &req->name, &req->alias); } if (ret) { err_maj = DP_ERR_FATAL; err_min = EINVAL; err_msg = "Invalid Filter"; goto done; } } else { err_maj = DP_ERR_FATAL; err_min = EINVAL; err_msg = "Missing Filter Parameter"; goto done; } /* process request */ if (!becli->bectx->bet_info[BET_HOSTID].bet_ops) { DEBUG(SSSDBG_CRIT_FAILURE, "Undefined backend target.\n"); err_maj = DP_ERR_FATAL; err_min = ENODEV; err_msg = "HostID back end target is not configured"; goto done; } ret = be_file_request(becli->bectx->bet_info[BET_HOSTID].pvt_bet_data, be_req, becli->bectx->bet_info[BET_HOSTID].bet_ops->handler); if (ret != EOK) { err_maj = DP_ERR_FATAL; err_min = ret; err_msg = "Failed to file request"; goto done; } return EOK; done: if (be_req) { talloc_free(be_req); } if (dbus_req) { ret = sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &err_maj, DBUS_TYPE_UINT32, &err_min, DBUS_TYPE_STRING, &err_msg, DBUS_TYPE_INVALID); if (ret != EOK) { return ret; } DEBUG(SSSDBG_TRACE_LIBS, "Request processed. Returned %d,%d,%s\n", err_maj, err_min, err_msg); } return EOK; } static int be_client_destructor(void *ctx) { struct be_client *becli = talloc_get_type(ctx, struct be_client); if (becli->bectx) { if (becli->bectx->nss_cli == becli) { DEBUG(SSSDBG_TRACE_FUNC, "Removed NSS client\n"); becli->bectx->nss_cli = NULL; } else if (becli->bectx->pam_cli == becli) { DEBUG(SSSDBG_TRACE_FUNC, "Removed PAM client\n"); becli->bectx->pam_cli = NULL; } else if (becli->bectx->sudo_cli == becli) { DEBUG(SSSDBG_TRACE_FUNC, "Removed SUDO client\n"); becli->bectx->sudo_cli = NULL; } else if (becli->bectx->autofs_cli == becli) { DEBUG(SSSDBG_TRACE_FUNC, "Removed autofs client\n"); becli->bectx->autofs_cli = NULL; } else if (becli->bectx->ssh_cli == becli) { DEBUG(SSSDBG_TRACE_FUNC, "Removed SSH client\n"); becli->bectx->ssh_cli = NULL; } else if (becli->bectx->pac_cli == becli) { DEBUG(SSSDBG_TRACE_FUNC, "Removed PAC client\n"); becli->bectx->pac_cli = NULL; } else if (becli->bectx->ifp_cli == becli) { DEBUG(SSSDBG_TRACE_FUNC, "Removed IFP client\n"); becli->bectx->ifp_cli = NULL; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown client removed ...\n"); } } return 0; } static int client_registration(struct sbus_request *dbus_req, void *data) { dbus_uint16_t version = DATA_PROVIDER_VERSION; struct sbus_connection *conn; struct be_client *becli; DBusError dbus_error; dbus_uint16_t cli_ver; char *cli_name; dbus_bool_t dbret; int ret; conn = dbus_req->conn; becli = talloc_get_type(data, struct be_client); if (!becli) { DEBUG(SSSDBG_FATAL_FAILURE, "Connection holds no valid init data\n"); return EINVAL; } /* First thing, cancel the timeout */ DEBUG(SSSDBG_CONF_SETTINGS, "Cancel DP ID timeout [%p]\n", becli->timeout); talloc_zfree(becli->timeout); dbus_error_init(&dbus_error); dbret = dbus_message_get_args(dbus_req->message, &dbus_error, DBUS_TYPE_UINT16, &cli_ver, DBUS_TYPE_STRING, &cli_name, DBUS_TYPE_INVALID); if (!dbret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse message, killing connection\n"); if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); sbus_disconnect(conn); /* FIXME: should we just talloc_zfree(conn) ? */ return EIO; } if (strcasecmp(cli_name, "NSS") == 0) { becli->bectx->nss_cli = becli; } else if (strcasecmp(cli_name, "PAM") == 0) { becli->bectx->pam_cli = becli; } else if (strcasecmp(cli_name, "SUDO") == 0) { becli->bectx->sudo_cli = becli; } else if (strcasecmp(cli_name, "autofs") == 0) { becli->bectx->autofs_cli = becli; } else if (strcasecmp(cli_name, "SSH") == 0) { becli->bectx->ssh_cli = becli; } else if (strcasecmp(cli_name, "PAC") == 0) { becli->bectx->pac_cli = becli; } else if (strcasecmp(cli_name, "InfoPipe") == 0) { becli->bectx->ifp_cli = becli; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown client! [%s]\n", cli_name); } talloc_set_destructor((TALLOC_CTX *)becli, be_client_destructor); DEBUG(SSSDBG_CONF_SETTINGS, "Added Frontend client [%s]\n", cli_name); /* reply that all is ok */ ret = sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &version, DBUS_TYPE_INVALID); if (ret != EOK) { sbus_disconnect(conn); return ret; } becli->initialized = true; return EOK; } static errno_t be_file_check_online_request(struct be_req *req) { int ret; req->be_ctx->offstat.went_offline = time(NULL); reset_fo(req->be_ctx); ret = be_file_request(req->be_ctx, req, req->be_ctx->bet_info[BET_ID].bet_ops->check_online); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_file_request failed.\n"); } return ret; } static void check_online_callback(struct be_req *req, int dp_err_type, int errnum, const char *errstr) { int ret; DEBUG(SSSDBG_CONF_SETTINGS, "Backend returned: (%d, %d, %s) [%s]\n", dp_err_type, errnum, errstr?errstr:"", dp_err_to_string(dp_err_type)); req->be_ctx->check_online_ref_count--; if (dp_err_type != DP_ERR_OK && req->be_ctx->check_online_ref_count > 0) { ret = be_file_check_online_request(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_file_check_online_request failed.\n"); goto done; } return; } done: req->be_ctx->check_online_ref_count = 0; if (dp_err_type != DP_ERR_OFFLINE) { if (dp_err_type != DP_ERR_OK) { reset_fo(req->be_ctx); } be_reset_offline(req->be_ctx); } talloc_free(req); return; } static void check_if_online(struct be_ctx *ctx) { int ret; struct be_req *be_req = NULL; be_run_unconditional_online_cb(ctx); if (ctx->offstat.offline == false) { DEBUG(SSSDBG_TRACE_INTERNAL, "Backend is already online, nothing to do.\n"); return; } /* Make sure nobody tries to go online while we are checking */ ctx->offstat.went_offline = time(NULL); DEBUG(SSSDBG_TRACE_INTERNAL, "Trying to go back online!\n"); ctx->check_online_ref_count++; if (ctx->check_online_ref_count != 1) { DEBUG(SSSDBG_TRACE_INTERNAL, "There is an online check already running.\n"); return; } if (ctx->bet_info[BET_ID].bet_ops->check_online == NULL) { DEBUG(SSSDBG_TRACE_INTERNAL, "ID providers does not provide a check_online method.\n"); goto failed; } be_req = be_req_create(ctx, NULL, ctx, check_online_callback, NULL); if (be_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); goto failed; } ret = be_file_check_online_request(be_req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_file_check_online_request failed.\n"); goto failed; } return; failed: ctx->check_online_ref_count--; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to run a check_online test.\n"); talloc_free(be_req); if (ctx->check_online_ref_count == 0) { reset_fo(ctx); be_reset_offline(ctx); } return; } static void init_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { struct be_client *becli; DEBUG(SSSDBG_OP_FAILURE, "Client timed out before Identification [%p]!\n", te); becli = talloc_get_type(ptr, struct be_client); sbus_disconnect(becli->conn); talloc_zfree(becli); } static int be_client_init(struct sbus_connection *conn, void *data) { struct be_ctx *bectx; struct be_client *becli; struct timeval tv; bectx = talloc_get_type(data, struct be_ctx); /* hang off this memory to the connection so that when the connection * is freed we can potentially call a destructor */ becli = talloc(conn, struct be_client); if (!becli) { DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n"); talloc_zfree(conn); return ENOMEM; } becli->bectx = bectx; becli->conn = conn; becli->initialized = false; /* Allow access from the SSSD user */ sbus_allow_uid(conn, &bectx->uid); /* 5 seconds should be plenty */ tv = tevent_timeval_current_ofs(5, 0); becli->timeout = tevent_add_timer(bectx->ev, becli, tv, init_timeout, becli); if (!becli->timeout) { DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n"); talloc_zfree(conn); return ENOMEM; } DEBUG(SSSDBG_CONF_SETTINGS, "Set-up Backend ID timeout [%p]\n", becli->timeout); return sbus_conn_register_iface(conn, &be_methods.vtable, DP_PATH, becli); } /* be_srv_init * set up per-domain sbus channel */ static int be_srv_init(struct be_ctx *ctx, uid_t uid, gid_t gid) { char *sbus_address; int ret; /* Set up SBUS connection to the monitor */ ret = dp_get_sbus_address(ctx, &sbus_address, ctx->domain->name); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not get sbus backend address.\n"); return ret; } ctx->uid = uid; ctx->gid = gid; ret = sbus_new_server(ctx, ctx->ev, sbus_address, uid, gid, true, &ctx->sbus_srv, be_client_init, ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up sbus server.\n"); return ret; } return EOK; } static void be_target_access_permit(struct be_req *be_req) { struct pam_data *pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); DEBUG(SSSDBG_TRACE_ALL, "be_target_access_permit called, returning PAM_SUCCESS.\n"); pd->pam_status = PAM_SUCCESS; be_req_terminate(be_req, DP_ERR_OK, PAM_SUCCESS, NULL); } static struct bet_ops be_target_access_permit_ops = { .check_online = NULL, .handler = be_target_access_permit, .finalize = NULL }; static void be_target_access_deny(struct be_req *be_req) { struct pam_data *pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); DEBUG(SSSDBG_TRACE_ALL, "be_target_access_deny called, returning PAM_PERM_DENIED.\n"); pd->pam_status = PAM_PERM_DENIED; be_req_terminate(be_req, DP_ERR_OK, PAM_PERM_DENIED, NULL); } static struct bet_ops be_target_access_deny_ops = { .check_online = NULL, .handler = be_target_access_deny, .finalize = NULL }; static int load_backend_module(struct be_ctx *ctx, enum bet_type bet_type, struct bet_info *bet_info, const char *default_mod_name) { TALLOC_CTX *tmp_ctx; int ret = EINVAL; bool already_loaded = false; int lb=0; char *mod_name = NULL; char *path = NULL; void *handle; char *mod_init_fn_name = NULL; bet_init_fn_t mod_init_fn = NULL; (*bet_info).bet_type = bet_type; (*bet_info).mod_name = NULL; (*bet_info).bet_ops = NULL; (*bet_info).pvt_bet_data = NULL; if (bet_type <= BET_NULL || bet_type >= BET_MAX || bet_type != bet_data[bet_type].bet_type) { DEBUG(SSSDBG_OP_FAILURE, "invalid bet_type or bet_data corrupted.\n"); return EINVAL; } tmp_ctx = talloc_new(ctx); if (!tmp_ctx) { DEBUG(SSSDBG_TRACE_LIBS, "talloc_new failed.\n"); return ENOMEM; } ret = confdb_get_string(ctx->cdb, tmp_ctx, ctx->conf_path, bet_data[bet_type].option_name, NULL, &mod_name); if (ret != EOK) { ret = EFAULT; goto done; } if (!mod_name) { if (default_mod_name != NULL) { DEBUG(SSSDBG_FUNC_DATA, "no module name found in confdb, using [%s].\n", default_mod_name); mod_name = talloc_strdup(ctx, default_mod_name); } else { ret = ENOENT; goto done; } } if (strcasecmp(mod_name, NO_PROVIDER) == 0) { ret = ENOENT; goto done; } if (bet_type == BET_ACCESS) { if (strcmp(mod_name, ACCESS_PERMIT) == 0) { (*bet_info).bet_ops = &be_target_access_permit_ops; (*bet_info).pvt_bet_data = NULL; (*bet_info).mod_name = talloc_strdup(ctx, ACCESS_PERMIT); ret = EOK; goto done; } if (strcmp(mod_name, ACCESS_DENY) == 0) { (*bet_info).bet_ops = &be_target_access_deny_ops; (*bet_info).pvt_bet_data = NULL; (*bet_info).mod_name = talloc_strdup(ctx, ACCESS_DENY); ret = EOK; goto done; } } mod_init_fn_name = talloc_asprintf(tmp_ctx, bet_data[bet_type].mod_init_fn_name_fmt, mod_name); if (mod_init_fn_name == NULL) { DEBUG(SSSDBG_TRACE_LIBS, "talloc_asprintf failed\n"); ret = ENOMEM; goto done; } lb = 0; while(ctx->loaded_be[lb].be_name != NULL) { if (strncmp(ctx->loaded_be[lb].be_name, mod_name, strlen(mod_name)) == 0) { DEBUG(SSSDBG_TRACE_LIBS, "Backend [%s] already loaded.\n", mod_name); already_loaded = true; break; } ++lb; if (lb >= BET_MAX) { DEBUG(SSSDBG_OP_FAILURE, "Backend context corrupted.\n"); ret = EINVAL; goto done; } } if (!already_loaded) { path = talloc_asprintf(tmp_ctx, "%s/libsss_%s.so", DATA_PROVIDER_PLUGINS_PATH, mod_name); if (!path) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Loading backend [%s] with path [%s].\n", mod_name, path); handle = dlopen(path, RTLD_NOW); if (!handle) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load %s module with path (%s), error: %s\n", mod_name, path, dlerror()); ret = ELIBACC; goto done; } ctx->loaded_be[lb].be_name = talloc_strdup(ctx, mod_name); ctx->loaded_be[lb].handle = handle; } mod_init_fn = (bet_init_fn_t)dlsym(ctx->loaded_be[lb].handle, mod_init_fn_name); if (mod_init_fn == NULL) { if (default_mod_name != NULL && strcmp(default_mod_name, mod_name) == 0 ) { /* If the default is used and fails we indicate this to the caller * by returning ENOENT. Ths way the caller can decide how to * handle the different types of error conditions. */ ret = ENOENT; } else { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load init fn %s from module %s, error: %s\n", mod_init_fn_name, mod_name, dlerror()); ret = ELIBBAD; } goto done; } ret = mod_init_fn(ctx, &(*bet_info).bet_ops, &(*bet_info).pvt_bet_data); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error (%d) in module (%s) initialization (%s)!\n", ret, mod_name, mod_init_fn_name); goto done; } (*bet_info).mod_name = talloc_strdup(ctx, mod_name); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static void signal_be_offline(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { struct be_ctx *ctx = talloc_get_type(private_data, struct be_ctx); be_mark_offline(ctx); } static void signal_be_reset_offline(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { struct be_ctx *ctx = talloc_get_type(private_data, struct be_ctx); check_if_online(ctx); } int be_process_init_sudo(struct be_ctx *be_ctx) { TALLOC_CTX *tmp_ctx = NULL; char **services = NULL; char *provider = NULL; bool responder_enabled = false; int i; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } ret = confdb_get_string_as_list(be_ctx->cdb, tmp_ctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_ACTIVE_SERVICES, &services); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to read from confdb [%d]: %s\n", ret, strerror(ret)); goto done; } for (i = 0; services[i] != NULL; i++) { if (strcmp(services[i], "sudo") == 0) { responder_enabled = true; break; } } ret = confdb_get_string(be_ctx->cdb, tmp_ctx, be_ctx->conf_path, CONFDB_DOMAIN_SUDO_PROVIDER, NULL, &provider); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to read from confdb [%d]: %s\n", ret, strerror(ret)); goto done; } if (!responder_enabled && provider == NULL) { /* provider is not set explicitly */ DEBUG(SSSDBG_TRACE_FUNC, "SUDO is not listed in services, disabling SUDO module.\n"); ret = ENOENT; goto done; } if (!responder_enabled && provider != NULL && strcmp(provider, NO_PROVIDER) != 0) { /* provider is set but responder is disabled */ DEBUG(SSSDBG_MINOR_FAILURE, "SUDO provider is set, but it is not " "listed in active services. SUDO support will not work!\n"); } ret = load_backend_module(be_ctx, BET_SUDO, &be_ctx->bet_info[BET_SUDO], be_ctx->bet_info[BET_ID].mod_name); done: talloc_free(tmp_ctx); return ret; } int be_process_init(TALLOC_CTX *mem_ctx, const char *be_domain, uid_t uid, gid_t gid, struct tevent_context *ev, struct confdb_ctx *cdb) { struct be_ctx *ctx; struct tevent_signal *tes; int ret; ctx = talloc_zero(mem_ctx, struct be_ctx); if (!ctx) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing be_ctx\n"); return ENOMEM; } ctx->ev = ev; ctx->cdb = cdb; ctx->identity = talloc_asprintf(ctx, "%%BE_%s", be_domain); ctx->conf_path = talloc_asprintf(ctx, CONFDB_DOMAIN_PATH_TMPL, be_domain); if (!ctx->identity || !ctx->conf_path) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!?\n"); ret = ENOMEM; goto fail; } ret = be_init_failover(ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing failover context\n"); goto fail; } ret = sssd_domain_init(ctx, cdb, be_domain, DB_PATH, &ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error opening cache database\n"); goto fail; } ret = sss_monitor_init(ctx, ctx->ev, &monitor_be_methods, ctx->identity, DATA_PROVIDER_VERSION, ctx, &ctx->mon_conn); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error setting up monitor bus\n"); goto fail; } /* We need this for subdomains support, as they have to store fully * qualified user and group names for now */ ret = sss_names_init(ctx->domain, cdb, ctx->domain->name, &ctx->domain->names); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error setting fully qualified name format for %s\n", ctx->domain->name); goto fail; } ret = be_srv_init(ctx, uid, gid); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error setting up server bus\n"); goto fail; } /* Initialize be_refresh periodic task. */ ctx->refresh_ctx = be_refresh_ctx_init(ctx); if (ctx->refresh_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n"); ret = ENOMEM; goto fail; } if (ctx->domain->refresh_expired_interval > 0) { ret = be_ptask_create(ctx, ctx, ctx->domain->refresh_expired_interval, 30, 5, 0, ctx->domain->refresh_expired_interval, BE_PTASK_OFFLINE_SKIP, 0, be_refresh_send, be_refresh_recv, ctx->refresh_ctx, "Refresh Records", NULL); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh periodic task\n"); goto fail; } } ret = load_backend_module(ctx, BET_ID, &ctx->bet_info[BET_ID], NULL); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing data providers\n"); goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "ID backend target successfully loaded from provider [%s].\n", ctx->bet_info[BET_ID].mod_name); ret = load_backend_module(ctx, BET_AUTH, &ctx->bet_info[BET_AUTH], ctx->bet_info[BET_ID].mod_name); if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing data providers\n"); goto fail; } DEBUG(SSSDBG_MINOR_FAILURE, "No authentication module provided for [%s] !!\n", be_domain); } else { DEBUG(SSSDBG_TRACE_INTERNAL, "AUTH backend target successfully loaded " "from provider [%s].\n", ctx->bet_info[BET_AUTH].mod_name); } ret = load_backend_module(ctx, BET_ACCESS, &ctx->bet_info[BET_ACCESS], ACCESS_PERMIT); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to setup ACCESS backend.\n"); goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "ACCESS backend target successfully loaded " "from provider [%s].\n", ctx->bet_info[BET_ACCESS].mod_name); ret = load_backend_module(ctx, BET_CHPASS, &ctx->bet_info[BET_CHPASS], ctx->bet_info[BET_AUTH].mod_name); if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing data providers\n"); goto fail; } DEBUG(SSSDBG_MINOR_FAILURE, "No change password module provided for [%s] !!\n", be_domain); } else { DEBUG(SSSDBG_TRACE_INTERNAL, "CHPASS backend target successfully loaded " "from provider [%s].\n", ctx->bet_info[BET_CHPASS].mod_name); } ret = be_process_init_sudo(ctx); if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing data providers\n"); goto fail; } DEBUG(SSSDBG_MINOR_FAILURE, "No SUDO module provided for [%s] !!\n", be_domain); } else { DEBUG(SSSDBG_TRACE_INTERNAL, "SUDO backend target successfully loaded " "from provider [%s].\n", ctx->bet_info[BET_SUDO].mod_name); } ret = load_backend_module(ctx, BET_AUTOFS, &ctx->bet_info[BET_AUTOFS], ctx->bet_info[BET_ID].mod_name); if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing data providers\n"); goto fail; } DEBUG(SSSDBG_MINOR_FAILURE, "No autofs module provided for [%s] !!\n", be_domain); } else { DEBUG(SSSDBG_TRACE_INTERNAL, "autofs backend target successfully loaded " "from provider [%s].\n", ctx->bet_info[BET_AUTOFS].mod_name); } ret = load_backend_module(ctx, BET_SELINUX, &ctx->bet_info[BET_SELINUX], ctx->bet_info[BET_ID].mod_name); if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing data providers\n"); goto fail; } DEBUG(SSSDBG_CRIT_FAILURE, "No selinux module provided for [%s] !!\n", be_domain); } else { DEBUG(SSSDBG_TRACE_ALL, "selinux backend target successfully loaded " "from provider [%s].\n", ctx->bet_info[BET_SELINUX].mod_name); } ret = load_backend_module(ctx, BET_HOSTID, &ctx->bet_info[BET_HOSTID], ctx->bet_info[BET_ID].mod_name); if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing data providers\n"); goto fail; } DEBUG(SSSDBG_CRIT_FAILURE, "No host info module provided for [%s] !!\n", be_domain); } else { DEBUG(SSSDBG_TRACE_ALL, "HOST backend target successfully loaded from provider [%s].\n", ctx->bet_info[BET_HOSTID].mod_name); } ret = load_backend_module(ctx, BET_SUBDOMAINS, &ctx->bet_info[BET_SUBDOMAINS], ctx->bet_info[BET_ID].mod_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Subdomains are not supported for [%s] !!\n", be_domain); } else { DEBUG(SSSDBG_TRACE_ALL, "Get-Subdomains backend target successfully loaded " "from provider [%s].\n", ctx->bet_info[BET_SUBDOMAINS].mod_name); } /* Handle SIGUSR1 to force offline behavior */ BlockSignals(false, SIGUSR1); tes = tevent_add_signal(ctx->ev, ctx, SIGUSR1, 0, signal_be_offline, ctx); if (tes == NULL) { ret = EIO; goto fail; } /* Handle SIGUSR2 to force going online */ BlockSignals(false, SIGUSR2); tes = tevent_add_signal(ctx->ev, ctx, SIGUSR2, 0, signal_be_reset_offline, ctx); if (tes == NULL) { ret = EIO; goto fail; } return EOK; fail: talloc_free(ctx); return ret; } #ifndef UNIT_TESTING int main(int argc, const char *argv[]) { int opt; poptContext pc; char *be_domain = NULL; char *srv_name = NULL; struct main_context *main_ctx; char *confdb_path; int ret; uid_t uid; gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS SSSD_SERVER_OPTS(uid, gid) {"domain", 0, POPT_ARG_STRING, &be_domain, 0, _("Domain of the information provider (mandatory)"), NULL }, POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } if (be_domain == NULL) { fprintf(stderr, "\nMissing option, --domain is a mandatory option.\n\n"); poptPrintUsage(pc, stderr, 0); return 1; } poptFreeContext(pc); DEBUG_INIT(debug_level); /* set up things like debug , signals, daemonization, etc... */ debug_log_file = talloc_asprintf(NULL, "sssd_%s", be_domain); if (!debug_log_file) return 2; srv_name = talloc_asprintf(NULL, "sssd[be[%s]]", be_domain); if (!srv_name) return 2; confdb_path = talloc_asprintf(NULL, CONFDB_DOMAIN_PATH_TMPL, be_domain); if (!confdb_path) return 2; ret = server_setup(srv_name, 0, 0, 0, confdb_path, &main_ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up mainloop [%d]\n", ret); return 2; } ret = setenv(SSS_DOM_ENV, be_domain, 1); if (ret != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Setting "SSS_DOM_ENV" failed, journald " "logging mightnot work as expected\n"); } ret = die_if_parent_died(); if (ret != EOK) { /* This is not fatal, don't return */ DEBUG(SSSDBG_OP_FAILURE, "Could not set up to exit when parent process does\n"); } ret = be_process_init(main_ctx, be_domain, uid, gid, main_ctx->event_ctx, main_ctx->confdb_ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize backend [%d]\n", ret); return 3; } ret = chown_debug_file(NULL, uid, gid); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot chown the debug files, debugging might not work!\n"); } ret = become_user(uid, gid); if (ret != EOK) { DEBUG(SSSDBG_FUNC_DATA, "Cannot become user [%"SPRIuid"][%"SPRIgid"].\n", uid, gid); return ret; } DEBUG(SSSDBG_TRACE_FUNC, "Backend provider (%s) started!\n", be_domain); /* loop on main */ server_loop(main_ctx); return 0; } #endif static int data_provider_res_init(struct sbus_request *dbus_req, void *data) { struct be_ctx *be_ctx; be_ctx = talloc_get_type(data, struct be_ctx); resolv_reread_configuration(be_ctx->be_res->resolv); check_if_online(be_ctx); return monitor_common_res_init(dbus_req, data); } static int data_provider_go_offline(struct sbus_request *dbus_req, void *data) { struct be_ctx *be_ctx; be_ctx = talloc_get_type(data, struct be_ctx); be_mark_offline(be_ctx); return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } static int data_provider_reset_offline(struct sbus_request *dbus_req, void *data) { struct be_ctx *be_ctx; be_ctx = talloc_get_type(data, struct be_ctx); check_if_online(be_ctx); return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } static int data_provider_logrotate(struct sbus_request *dbus_req, void *data) { errno_t ret; struct be_ctx *be_ctx = talloc_get_type(data, struct be_ctx); ret = server_common_rotate_logs(be_ctx->cdb, be_ctx->conf_path); if (ret != EOK) return ret; return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } sssd-1.13.4/src/providers/PaxHeaders.16287/dp_refresh.h0000644000000000000000000000007412703456111017423 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.530793208 sssd-1.13.4/src/providers/dp_refresh.h0000644002412700241270000000420412703456111021072 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _DP_REFRESH_H_ #define _DP_REFRESH_H_ #include #include #include "providers/dp_ptask.h" /* solve circular dependency */ struct be_ctx; /** * name_list contains SYSDB_NAME of all expired records. */ typedef struct tevent_req * (*be_refresh_send_t)(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, char **values, void *pvt); typedef errno_t (*be_refresh_recv_t)(struct tevent_req *req); enum be_refresh_type { BE_REFRESH_TYPE_USERS, BE_REFRESH_TYPE_GROUPS, BE_REFRESH_TYPE_NETGROUPS, BE_REFRESH_TYPE_SENTINEL }; struct be_refresh_ctx; struct be_refresh_ctx *be_refresh_ctx_init(TALLOC_CTX *mem_ctx); errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, enum be_refresh_type type, be_refresh_send_t send_fn, be_refresh_recv_t recv_fn, void *pvt); struct tevent_req *be_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt); errno_t be_refresh_recv(struct tevent_req *req); #endif /* _DP_REFRESH_H_ */ sssd-1.13.4/src/providers/PaxHeaders.16287/dp_backend.h0000644000000000000000000000007412703456111017354 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.524793188 sssd-1.13.4/src/providers/dp_backend.h0000644002412700241270000002350512703456111021030 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider, private header file Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __DP_BACKEND_H__ #define __DP_BACKEND_H__ #include "providers/data_provider.h" #include "providers/fail_over.h" #include "providers/dp_refresh.h" #include "util/child_common.h" #include "db/sysdb.h" /* a special token, if used in place of the hostname, denotes that real * hostnames should be looked up from DNS using SRV requests */ #define BE_SRV_IDENTIFIER "_srv_" struct be_ctx; struct bet_ops; struct be_req; typedef int (*bet_init_fn_t)(TALLOC_CTX *, struct bet_ops **, void **); typedef void (*be_shutdown_fn)(void *); typedef void (*be_req_fn_t)(struct be_req *); typedef void (*be_async_callback_t)(struct be_req *, int, int, const char *); typedef void (*be_callback_t)(void *); enum bet_type { BET_NULL = 0, BET_ID, BET_AUTH, BET_ACCESS, BET_CHPASS, BET_SUDO, BET_AUTOFS, BET_SELINUX, BET_HOSTID, BET_SUBDOMAINS, BET_MAX }; struct bet_data { enum bet_type bet_type; const char *option_name; const char *mod_init_fn_name_fmt; }; struct loaded_be { char *be_name; void *handle; }; struct bet_info { enum bet_type bet_type; struct bet_ops *bet_ops; void *pvt_bet_data; char *mod_name; struct bet_queue_item *req_queue; }; struct be_offline_status { time_t went_offline; bool offline; }; struct be_resolv_ctx { struct resolv_ctx *resolv; struct dp_option *opts; enum restrict_family family_order; }; struct be_client { struct be_ctx *bectx; struct sbus_connection *conn; struct tevent_timer *timeout; bool initialized; }; struct be_failover_ctx; struct be_cb; struct be_ctx { struct tevent_context *ev; struct confdb_ctx *cdb; struct sss_domain_info *domain; const char *identity; const char *conf_path; uid_t uid; gid_t gid; struct be_failover_ctx *be_fo; struct be_resolv_ctx *be_res; /* Functions to be invoked when the * backend goes online or offline */ struct be_cb *online_cb_list; bool run_online_cb; struct be_cb *offline_cb_list; struct be_cb *reconnect_cb_list; /* In contrast to online_cb_list which are only run if the backend is * offline the unconditional_online_cb_list should be run whenever the * backend receives a request to go online. The typical use case is to * reset timers independenly of the state of the backend. */ struct be_cb *unconditional_online_cb_list; struct be_offline_status offstat; /* Periodicly check if we can go online. */ struct be_ptask *check_if_online_ptask; struct sbus_connection *mon_conn; struct sbus_connection *sbus_srv; struct be_client *nss_cli; struct be_client *pam_cli; struct be_client *sudo_cli; struct be_client *autofs_cli; struct be_client *ssh_cli; struct be_client *pac_cli; struct be_client *ifp_cli; struct loaded_be loaded_be[BET_MAX]; struct bet_info bet_info[BET_MAX]; struct be_refresh_ctx *refresh_ctx; size_t check_online_ref_count; /* List of ongoing requests */ struct be_req *active_requests; }; struct bet_ops { be_req_fn_t check_online; be_req_fn_t handler; be_req_fn_t finalize; }; struct be_acct_req { int entry_type; int attr_type; int filter_type; char *filter_value; char *extra_value; char *domain; }; struct be_sudo_req { uint32_t type; char **rules; }; struct be_autofs_req { char *mapname; bool invalidate; }; struct be_subdom_req { bool force; char *domain_hint; }; struct be_host_req { uint32_t type; int filter_type; char *name; char *alias; }; bool be_is_offline(struct be_ctx *ctx); void be_mark_offline(struct be_ctx *ctx); void be_mark_dom_offline(struct sss_domain_info *dom, struct be_ctx *ctx); int be_add_reconnect_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, void *pvt, struct be_cb **reconnect_cb); void be_run_reconnect_cb(struct be_ctx *be); int be_add_online_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, void *pvt, struct be_cb **online_cb); void be_run_online_cb(struct be_ctx *be); int be_add_unconditional_online_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, void *pvt, struct be_cb **unconditional_online_cb); void be_run_unconditional_online_cb(struct be_ctx *be); int be_add_offline_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, void *pvt, struct be_cb **online_cb); void be_run_offline_cb(struct be_ctx *be); /* from data_provider_fo.c */ enum be_fo_protocol { BE_FO_PROTO_TCP, BE_FO_PROTO_UDP, BE_FO_PROTO_SENTINEL }; typedef void (be_svc_callback_fn_t)(void *, struct fo_server *); int be_init_failover(struct be_ctx *ctx); int be_fo_is_srv_identifier(const char *server); int be_fo_add_service(struct be_ctx *ctx, const char *service_name, datacmp_fn user_data_cmp); int be_fo_service_add_callback(TALLOC_CTX *memctx, struct be_ctx *ctx, const char *service_name, be_svc_callback_fn_t *fn, void *private_data); int be_fo_get_server_count(struct be_ctx *ctx, const char *service_name); void be_fo_set_srv_lookup_plugin(struct be_ctx *ctx, fo_srv_lookup_plugin_send_t send_fn, fo_srv_lookup_plugin_recv_t recv_fn, void *pvt, const char *plugin_name); errno_t be_fo_set_dns_srv_lookup_plugin(struct be_ctx *be_ctx, const char *hostname); int be_fo_add_srv_server(struct be_ctx *ctx, const char *service_name, const char *query_service, const char *default_discovery_domain, enum be_fo_protocol proto, bool proto_fallback, void *user_data); int be_fo_add_server(struct be_ctx *ctx, const char *service_name, const char *server, int port, void *user_data, bool primary); struct tevent_req *be_resolve_server_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct be_ctx *ctx, const char *service_name, bool first_try); int be_resolve_server_recv(struct tevent_req *req, TALLOC_CTX *ref_ctx, struct fo_server **srv); #define be_fo_set_port_status(ctx, service_name, server, status) \ _be_fo_set_port_status(ctx, service_name, server, status, \ __LINE__, __FILE__, __FUNCTION__) void _be_fo_set_port_status(struct be_ctx *ctx, const char *service_name, struct fo_server *server, enum port_status status, int line, const char *file, const char *function); /* * Instruct fail-over to try next server on the next connect attempt. * Should be used after connection to service was unexpectedly dropped * but there is no authoritative information on whether active server is down. */ void be_fo_try_next_server(struct be_ctx *ctx, const char *service_name); int be_fo_run_callbacks_at_next_request(struct be_ctx *ctx, const char *service_name); void reset_fo(struct be_ctx *be_ctx); void be_fo_reset_svc(struct be_ctx *be_ctx, const char *svc_name); const char *be_fo_get_active_server_name(struct be_ctx *ctx, const char *service_name); errno_t be_res_init(struct be_ctx *ctx); /* be_req helpers */ struct be_req *be_req_create(TALLOC_CTX *mem_ctx, struct be_client *becli, struct be_ctx *be_ctx, be_async_callback_t fn, void *pvt_fn_data); struct be_ctx *be_req_get_be_ctx(struct be_req *be_req); void *be_req_get_data(struct be_req *be_req); void be_req_terminate(struct be_req *be_req, int dp_err_type, int errnum, const char *errstr); void be_terminate_domain_requests(struct be_ctx *be_ctx, const char *domain); /* Request account information */ struct tevent_req * be_get_account_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_client *becli, struct be_ctx *be_ctx, struct be_acct_req *ar); errno_t be_get_account_info_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, int *_err_maj, int *_err_min, const char **_err_msg); #endif /* __DP_BACKEND_H___ */ sssd-1.13.4/src/providers/PaxHeaders.16287/proxy0000644000000000000000000000013212703463556016243 xustar0030 mtime=1460561774.955794649 30 atime=1460561776.118798593 30 ctime=1460561774.955794649 sssd-1.13.4/src/providers/proxy/0000755002412700241270000000000012703463556017774 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/providers/proxy/PaxHeaders.16287/proxy_child.c0000644000000000000000000000007412703456111021002 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.956794653 sssd-1.13.4/src/providers/proxy/proxy_child.c0000644002412700241270000004412212703456111022454 0ustar00jhrozekjhrozek00000000000000/* SSSD Pam Proxy Child Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "confdb/confdb.h" #include "sbus/sssd_dbus.h" #include "providers/proxy/proxy.h" #include "providers/dp_backend.h" static int pc_pam_handler(struct sbus_request *dbus_req, void *user_data); struct data_provider_iface pc_methods = { { &data_provider_iface_meta, 0 }, .RegisterService = NULL, .pamHandler = pc_pam_handler, .sudoHandler = NULL, .autofsHandler = NULL, .hostHandler = NULL, .getDomains = NULL, .getAccountInfo = NULL, }; struct pc_ctx { struct tevent_context *ev; struct confdb_ctx *cdb; struct sss_domain_info *domain; const char *identity; const char *conf_path; struct sbus_connection *mon_conn; struct sbus_connection *conn; const char *pam_target; uint32_t id; }; static int proxy_internal_conv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *appdata_ptr) { int i; struct pam_response *reply; struct authtok_conv *auth_data; const char *password; size_t pwlen; errno_t ret; auth_data = talloc_get_type(appdata_ptr, struct authtok_conv); if (num_msg <= 0) return PAM_CONV_ERR; reply = (struct pam_response *) calloc(num_msg, sizeof(struct pam_response)); if (reply == NULL) return PAM_CONV_ERR; for (i=0; i < num_msg; i++) { switch( msgm[i]->msg_style ) { case PAM_PROMPT_ECHO_OFF: DEBUG(SSSDBG_CONF_SETTINGS, "Conversation message: [%s]\n", msgm[i]->msg); reply[i].resp_retcode = 0; ret = sss_authtok_get_password(auth_data->authtok, &password, &pwlen); if (ret) goto failed; reply[i].resp = calloc(pwlen + 1, sizeof(char)); if (reply[i].resp == NULL) goto failed; memcpy(reply[i].resp, password, pwlen + 1); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Conversation style %d not supported.\n", msgm[i]->msg_style); goto failed; } } *response = reply; reply = NULL; return PAM_SUCCESS; failed: free(reply); return PAM_CONV_ERR; } static int proxy_chauthtok_conv(int num_msg, const struct pam_message **msgm, struct pam_response **response, void *appdata_ptr) { int i; struct pam_response *reply; struct authtok_conv *auth_data; const char *password; size_t pwlen; errno_t ret; auth_data = talloc_get_type(appdata_ptr, struct authtok_conv); if (num_msg <= 0) return PAM_CONV_ERR; reply = (struct pam_response *) calloc(num_msg, sizeof(struct pam_response)); if (reply == NULL) return PAM_CONV_ERR; for (i=0; i < num_msg; i++) { switch( msgm[i]->msg_style ) { case PAM_PROMPT_ECHO_OFF: DEBUG(SSSDBG_CONF_SETTINGS, "Conversation message: [%s]\n", msgm[i]->msg); reply[i].resp_retcode = 0; if (!auth_data->sent_old) { /* The first prompt will be asking for the old authtok */ ret = sss_authtok_get_password(auth_data->authtok, &password, &pwlen); if (ret) goto failed; reply[i].resp = calloc(pwlen + 1, sizeof(char)); if (reply[i].resp == NULL) goto failed; memcpy(reply[i].resp, password, pwlen + 1); auth_data->sent_old = true; } else { /* Subsequent prompts are looking for the new authtok */ ret = sss_authtok_get_password(auth_data->newauthtok, &password, &pwlen); if (ret) goto failed; reply[i].resp = calloc(pwlen + 1, sizeof(char)); if (reply[i].resp == NULL) goto failed; memcpy(reply[i].resp, password, pwlen + 1); auth_data->sent_old = true; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Conversation style %d not supported.\n", msgm[i]->msg_style); goto failed; } } *response = reply; reply = NULL; return PAM_SUCCESS; failed: free(reply); return PAM_CONV_ERR; } static errno_t call_pam_stack(const char *pam_target, struct pam_data *pd) { int ret; int pam_status; pam_handle_t *pamh=NULL; struct authtok_conv *auth_data; struct pam_conv conv; if (pd->cmd == SSS_PAM_CHAUTHTOK) { conv.conv=proxy_chauthtok_conv; } else { conv.conv=proxy_internal_conv; } auth_data = talloc_zero(pd, struct authtok_conv); if (auth_data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } auth_data->authtok = sss_authtok_new(auth_data); if (auth_data->authtok == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_authtok_new failed.\n"); ret = ENOMEM; goto fail; } auth_data->newauthtok = sss_authtok_new(auth_data); if (auth_data->newauthtok == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_authtok_new failed.\n"); ret = ENOMEM; goto fail; } conv.appdata_ptr=auth_data; ret = pam_start(pam_target, pd->user, &conv, &pamh); if (ret == PAM_SUCCESS) { DEBUG(SSSDBG_TRACE_LIBS, "Pam transaction started with service name [%s].\n", pam_target); ret = pam_set_item(pamh, PAM_TTY, pd->tty); if (ret != PAM_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Setting PAM_TTY failed: %s.\n", pam_strerror(pamh, ret)); } ret = pam_set_item(pamh, PAM_RUSER, pd->ruser); if (ret != PAM_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Setting PAM_RUSER failed: %s.\n", pam_strerror(pamh, ret)); } ret = pam_set_item(pamh, PAM_RHOST, pd->rhost); if (ret != PAM_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Setting PAM_RHOST failed: %s.\n", pam_strerror(pamh, ret)); } switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: sss_authtok_copy(pd->authtok, auth_data->authtok); pam_status = pam_authenticate(pamh, 0); break; case SSS_PAM_SETCRED: pam_status=pam_setcred(pamh, 0); break; case SSS_PAM_ACCT_MGMT: pam_status=pam_acct_mgmt(pamh, 0); break; case SSS_PAM_OPEN_SESSION: pam_status=pam_open_session(pamh, 0); break; case SSS_PAM_CLOSE_SESSION: pam_status=pam_close_session(pamh, 0); break; case SSS_PAM_CHAUTHTOK: sss_authtok_copy(pd->authtok, auth_data->authtok); if (pd->priv != 1) { pam_status = pam_authenticate(pamh, 0); auth_data->sent_old = false; if (pam_status != PAM_SUCCESS) break; } sss_authtok_copy(pd->newauthtok, auth_data->newauthtok); pam_status = pam_chauthtok(pamh, 0); break; case SSS_PAM_CHAUTHTOK_PRELIM: if (pd->priv != 1) { sss_authtok_copy(pd->authtok, auth_data->authtok); pam_status = pam_authenticate(pamh, 0); } else { pam_status = PAM_SUCCESS; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "unknown PAM call\n"); pam_status=PAM_ABORT; } DEBUG(SSSDBG_CONF_SETTINGS, "Pam result: [%d][%s]\n", pam_status, pam_strerror(pamh, pam_status)); ret = pam_end(pamh, pam_status); if (ret != PAM_SUCCESS) { pamh=NULL; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot terminate pam transaction.\n"); } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize pam transaction.\n"); pam_status = PAM_SYSTEM_ERR; } pd->pam_status = pam_status; return EOK; fail: talloc_free(auth_data); return ret; } static int pc_pam_handler(struct sbus_request *dbus_req, void *user_data) { DBusError dbus_error; DBusMessage *reply; struct pc_ctx *pc_ctx; errno_t ret; struct pam_data *pd = NULL; pc_ctx = talloc_get_type(user_data, struct pc_ctx); if (!pc_ctx) { ret = EINVAL; goto done; } reply = dbus_message_new_method_return(dbus_req->message); if (!reply) { DEBUG(SSSDBG_CRIT_FAILURE, "dbus_message_new_method_return failed, " "cannot send reply.\n"); ret = ENOMEM; goto done; } dbus_error_init(&dbus_error); ret = dp_unpack_pam_request(dbus_req->message, pc_ctx, &pd, &dbus_error); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE,"Failed, to parse message!\n"); ret = EIO; goto done; } pd->pam_status = PAM_SYSTEM_ERR; pd->domain = talloc_strdup(pd, pc_ctx->domain->name); if (pd->domain == NULL) { talloc_free(pd); ret = ENOMEM; goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Got request with the following data\n"); DEBUG_PAM_DATA(SSSDBG_CONF_SETTINGS, pd); ret = call_pam_stack(pc_ctx->pam_target, pd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "call_pam_stack failed.\n"); } DEBUG(SSSDBG_CONF_SETTINGS, "Sending result [%d][%s]\n", pd->pam_status, pd->domain); ret = dp_pack_pam_response(reply, pd); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate dbus reply\n"); talloc_free(pd); dbus_message_unref(reply); ret = EIO; goto done; } ret = sbus_request_finish(dbus_req, reply); dbus_message_unref(reply); talloc_free(pd); /* We'll return the message and let the * parent process kill us. */ return ret; done: exit(ret); } int proxy_child_send_id(struct sbus_connection *conn, uint16_t version, uint32_t id); static int proxy_cli_init(struct pc_ctx *ctx) { char *sbus_address; int ret; sbus_address = talloc_asprintf(ctx, "unix:path=%s/%s_%s", PIPE_PATH, PROXY_CHILD_PIPE, ctx->domain->name); if (sbus_address == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); return ENOMEM; } ret = sbus_client_init(ctx, ctx->ev, sbus_address, &ctx->conn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sbus_client_init failed.\n"); return ret; } ret = sbus_conn_register_iface(ctx->conn, &pc_methods.vtable, DP_PATH, ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to export proxy.\n"); return ret; } ret = proxy_child_send_id(ctx->conn, DATA_PROVIDER_VERSION, ctx->id); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "dp_common_send_id failed.\n"); return ret; } return EOK; } int proxy_child_send_id(struct sbus_connection *conn, uint16_t version, uint32_t id) { DBusMessage *msg; dbus_bool_t ret; int retval; /* create the message */ msg = dbus_message_new_method_call(NULL, DP_PATH, DATA_PROVIDER_IFACE, DATA_PROVIDER_IFACE_REGISTERSERVICE); if (msg == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?!\n"); return ENOMEM; } DEBUG(SSSDBG_FUNC_DATA, "Sending ID to Proxy Backend: (%d,%"PRIu32")\n", version, id); ret = dbus_message_append_args(msg, DBUS_TYPE_UINT16, &version, DBUS_TYPE_UINT32, &id, DBUS_TYPE_INVALID); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n"); return EIO; } retval = sbus_conn_send(conn, msg, 30000, dp_id_callback, NULL, NULL); dbus_message_unref(msg); return retval; } int proxy_child_process_init(TALLOC_CTX *mem_ctx, const char *domain, struct tevent_context *ev, struct confdb_ctx *cdb, const char *pam_target, uint32_t id) { struct pc_ctx *ctx; int ret; ctx = talloc_zero(mem_ctx, struct pc_ctx); if (!ctx) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing pc_ctx\n"); return ENOMEM; } ctx->ev = ev; ctx->cdb = cdb; ctx->pam_target = talloc_steal(ctx, pam_target); ctx->id = id; ctx->conf_path = talloc_asprintf(ctx, CONFDB_DOMAIN_PATH_TMPL, domain); if (!ctx->conf_path) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory!?\n"); return ENOMEM; } ret = confdb_get_domain(cdb, domain, &ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error retrieving domain configuration\n"); return ret; } ret = proxy_cli_init(ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error setting up server bus\n"); return ret; } return EOK; } int main(int argc, const char *argv[]) { int opt; poptContext pc; char *domain = NULL; char *srv_name = NULL; char *conf_entry = NULL; struct main_context *main_ctx; int ret; long id; char *pam_target = NULL; uid_t uid; gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS SSSD_SERVER_OPTS(uid, gid) {"domain", 0, POPT_ARG_STRING, &domain, 0, _("Domain of the information provider (mandatory)"), NULL }, {"id", 0, POPT_ARG_LONG, &id, 0, _("Child identifier (mandatory)"), NULL }, POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } if (domain == NULL) { fprintf(stderr, "\nMissing option, " "--domain is a mandatory option.\n\n"); poptPrintUsage(pc, stderr, 0); return 1; } if (id == 0) { fprintf(stderr, "\nMissing option, " "--id is a mandatory option.\n\n"); poptPrintUsage(pc, stderr, 0); return 1; } poptFreeContext(pc); DEBUG_INIT(debug_level); /* set up things like debug , signals, daemonization, etc... */ debug_log_file = talloc_asprintf(NULL, "proxy_child_%s", domain); if (!debug_log_file) return 2; srv_name = talloc_asprintf(NULL, "sssd[proxy_child[%s]]", domain); if (!srv_name) return 2; conf_entry = talloc_asprintf(NULL, CONFDB_DOMAIN_PATH_TMPL, domain); if (!conf_entry) return 2; ret = server_setup(srv_name, 0, 0, 0, conf_entry, &main_ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up mainloop [%d]\n", ret); return 2; } ret = unsetenv("_SSS_LOOPS"); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unset _SSS_LOOPS, " "pam modules might not work as expected.\n"); } ret = confdb_get_string(main_ctx->confdb_ctx, main_ctx, conf_entry, CONFDB_PROXY_PAM_TARGET, NULL, &pam_target); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n", ret, strerror(ret)); return 4; } if (pam_target == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing option proxy_pam_target.\n"); return 4; } ret = die_if_parent_died(); if (ret != EOK) { /* This is not fatal, don't return */ DEBUG(SSSDBG_OP_FAILURE, "Could not set up to exit when parent process does\n"); } ret = proxy_child_process_init(main_ctx, domain, main_ctx->event_ctx, main_ctx->confdb_ctx, pam_target, (uint32_t)id); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize proxy child [%d].\n", ret); return 3; } DEBUG(SSSDBG_CRIT_FAILURE, "Proxy child for domain [%s] started!\n", domain); /* loop on main */ server_loop(main_ctx); return 0; } sssd-1.13.4/src/providers/proxy/PaxHeaders.16287/proxy_netgroup.c0000644000000000000000000000007412703456111021562 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.810794158 sssd-1.13.4/src/providers/proxy/proxy_netgroup.c0000644002412700241270000001373012703456111023235 0ustar00jhrozekjhrozek00000000000000/* SSSD Proxy netgroup handler Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/proxy/proxy.h" #include "util/util.h" #define BUFLEN 1024 #define get_triple_el(s) ((s) ? (s) : "") static errno_t make_netgroup_attr(struct __netgrent netgrent, struct sysdb_attrs *attrs) { int ret; char *dummy; if (netgrent.type == group_val) { ret =sysdb_attrs_add_string(attrs, SYSDB_NETGROUP_MEMBER, netgrent.val.group); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n"); return ret; } } else if (netgrent.type == triple_val) { dummy = talloc_asprintf(attrs, "(%s,%s,%s)", get_triple_el(netgrent.val.triple.host), get_triple_el(netgrent.val.triple.user), get_triple_el(netgrent.val.triple.domain)); if (dummy == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); return ENOMEM; } ret = sysdb_attrs_add_string(attrs, SYSDB_NETGROUP_TRIPLE, dummy); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n"); return ret; } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown netgrent entry type [%d].\n", netgrent.type); return EINVAL; } return EOK; } static errno_t save_netgroup(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, bool lowercase, uint64_t cache_timeout) { errno_t ret; if (lowercase) { ret = sysdb_attrs_add_lc_name_alias(attrs, name); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not add name alias\n"); return ret; } } ret = sysdb_add_netgroup(domain, name, NULL, attrs, NULL, cache_timeout, 0); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_netgroup failed.\n"); return ret; } return EOK; } static errno_t handle_error(enum nss_status status, struct sss_domain_info *domain, const char *name) { errno_t ret; switch (status) { case NSS_STATUS_SUCCESS: DEBUG(SSSDBG_TRACE_INTERNAL, "Netgroup lookup succeeded\n"); ret = EOK; break; case NSS_STATUS_NOTFOUND: DEBUG(SSSDBG_MINOR_FAILURE, "The netgroup was not found\n"); ret = sysdb_delete_netgroup(domain, name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot delete netgroup: %d\n", ret); ret = EIO; } break; case NSS_STATUS_UNAVAIL: DEBUG(SSSDBG_TRACE_LIBS, "The proxy target did not respond, going offline\n"); ret = ENXIO; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected error looking up netgroup\n"); ret = EIO; break; } return ret; } errno_t get_netgroup(struct proxy_id_ctx *ctx, struct sss_domain_info *dom, const char *name) { struct __netgrent result; enum nss_status status; char buffer[BUFLEN]; int ret; TALLOC_CTX *tmp_ctx = NULL; struct sysdb_attrs *attrs; memset(&result, 0, sizeof(result)); status = ctx->ops.setnetgrent(name, &result); if (status != NSS_STATUS_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "setnetgrent failed for netgroup [%s].\n", name); ret = handle_error(status, dom, name); goto done; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); ret = ENOMEM; goto done; } attrs = sysdb_new_attrs(tmp_ctx); if (attrs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_new_attrs failed.\n"); ret = ENOMEM; goto done; } do { status = ctx->ops.getnetgrent_r(&result, buffer, BUFLEN, &ret); if (status != NSS_STATUS_SUCCESS && status != NSS_STATUS_RETURN && status != NSS_STATUS_NOTFOUND) { ret = handle_error(status, dom, name); DEBUG(SSSDBG_OP_FAILURE, "getnetgrent_r failed for netgroup [%s]: [%d][%s].\n", name, ret, strerror(ret)); goto done; } if (status == NSS_STATUS_SUCCESS) { ret = make_netgroup_attr(result, attrs); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "make_netgroup_attr failed.\n"); goto done; } } } while (status != NSS_STATUS_RETURN && status != NSS_STATUS_NOTFOUND); status = ctx->ops.endnetgrent(&result); if (status != NSS_STATUS_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "endnetgrent failed.\n"); ret = handle_error(status, dom, name); goto done; } ret = save_netgroup(dom, name, attrs, !dom->case_sensitive, dom->netgroup_timeout); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "save_netgroup failed.\n"); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/providers/proxy/PaxHeaders.16287/proxy_services.c0000644000000000000000000000007412703456111021542 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.811794161 sssd-1.13.4/src/providers/proxy/proxy_services.c0000644002412700241270000002516612703456111023223 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/proxy/proxy.h" #include "util/util.h" #include "util/strtonum.h" #include "db/sysdb_services.h" #define BUFLEN 1024 errno_t proxy_save_service(struct sss_domain_info *domain, struct servent *svc, bool lowercase, uint64_t cache_timeout) { errno_t ret; char *cased_name; const char **protocols; const char **cased_aliases; TALLOC_CTX *tmp_ctx; char *lc_alias = NULL; time_t now = time(NULL); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; cased_name = sss_get_cased_name(tmp_ctx, svc->s_name, domain->case_preserve); if (!cased_name) { ret = ENOMEM; goto done; } protocols = talloc_array(tmp_ctx, const char *, 2); if (!protocols) { ret = ENOMEM; goto done; } protocols[0] = sss_get_cased_name(protocols, svc->s_proto, !lowercase); if (!protocols[0]) { ret = ENOMEM; goto done; } protocols[1] = NULL; /* Count the aliases */ ret = sss_get_cased_name_list(tmp_ctx, (const char * const *) svc->s_aliases, !lowercase, &cased_aliases); if (ret != EOK) { goto done; } if (domain->case_preserve) { /* Add lowercased alias to allow case-insensitive lookup */ lc_alias = sss_tc_utf8_str_tolower(tmp_ctx, svc->s_name); if (lc_alias == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot convert name to lowercase.\n"); ret = ENOMEM; goto done; } ret = add_string_to_list(tmp_ctx, lc_alias, discard_const_p(char **, &cased_aliases)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to add lowercased name alias.\n"); goto done; } } ret = sysdb_store_service(domain, cased_name, ntohs(svc->s_port), cased_aliases, protocols, NULL, NULL, cache_timeout, now); done: talloc_free(tmp_ctx); return ret; } errno_t get_serv_byname(struct proxy_id_ctx *ctx, struct sss_domain_info *dom, const char *name, const char *protocol) { errno_t ret; enum nss_status status; struct servent *result; TALLOC_CTX *tmp_ctx; char buffer[BUFLEN]; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; result = talloc_zero(tmp_ctx, struct servent); if (!result) { ret = ENOMEM; goto done; } status = ctx->ops.getservbyname_r(name, protocol, result, buffer, BUFLEN, &ret); if (status != NSS_STATUS_SUCCESS && status != NSS_STATUS_NOTFOUND) { DEBUG(SSSDBG_MINOR_FAILURE, "getservbyname_r failed for service [%s].\n", name); return ret; } if (status == NSS_STATUS_NOTFOUND) { /* Make sure we remove it from the cache */ ret = sysdb_svc_delete(dom, name, 0, protocol); } else { /* Results found. Save them into the cache */ ret = proxy_save_service(dom, result, !dom->case_sensitive, dom->service_timeout); } done: talloc_free(tmp_ctx); return ret; } errno_t get_serv_byport(struct proxy_id_ctx *ctx, struct sss_domain_info *dom, const char *be_filter, const char *protocol) { errno_t ret; enum nss_status status; struct servent *result; TALLOC_CTX *tmp_ctx; uint16_t port; char buffer[BUFLEN]; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; result = talloc_zero(tmp_ctx, struct servent); if (!result) { ret = ENOMEM; goto done; } errno = 0; port = htons(strtouint16(be_filter, NULL, 0)); if (errno) { ret = errno; goto done; } status = ctx->ops.getservbyport_r(port, protocol, result, buffer, BUFLEN, &ret); if (status != NSS_STATUS_SUCCESS && status != NSS_STATUS_NOTFOUND) { DEBUG(SSSDBG_MINOR_FAILURE, "getservbyport_r failed for service [%s].\n", be_filter); return ret; } if (status == NSS_STATUS_NOTFOUND) { /* Make sure we remove it from the cache */ ret = sysdb_svc_delete(dom, NULL, port, protocol); } else { /* Results found. Save them into the cache */ ret = proxy_save_service(dom, result, !dom->case_sensitive, dom->service_timeout); } done: talloc_free(tmp_ctx); return ret; } errno_t enum_services(struct proxy_id_ctx *ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom) { TALLOC_CTX *tmpctx; bool in_transaction = false; struct servent *svc; enum nss_status status; size_t buflen; char *buffer; char *newbuf; errno_t ret, sret; time_t now = time(NULL); const char **protocols; const char **cased_aliases; bool again; DEBUG(SSSDBG_TRACE_FUNC, "Enumerating services\n"); tmpctx = talloc_new(NULL); if (!tmpctx) { return ENOMEM; } svc = talloc(tmpctx, struct servent); if (!svc) { ret = ENOMEM; goto done; } buflen = DEFAULT_BUFSIZE; buffer = talloc_size(tmpctx, buflen); if (!buffer) { ret = ENOMEM; goto done; } protocols = talloc_zero_array(tmpctx, const char *, 2); if (protocols == NULL) { ret = ENOMEM; goto done; } ret = sysdb_transaction_start(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; status = ctx->ops.setservent(); if (status != NSS_STATUS_SUCCESS) { ret = EIO; goto done; } do { again = false; /* always zero out the svc structure */ memset(svc, 0, sizeof(struct servent)); /* get entry */ status = ctx->ops.getservent_r(svc, buffer, buflen, &ret); switch (status) { case NSS_STATUS_TRYAGAIN: /* buffer too small ? */ if (buflen < MAX_BUF_SIZE) { buflen *= 2; } if (buflen > MAX_BUF_SIZE) { buflen = MAX_BUF_SIZE; } newbuf = talloc_realloc_size(tmpctx, buffer, buflen); if (!newbuf) { ret = ENOMEM; goto done; } buffer = newbuf; again = true; break; case NSS_STATUS_NOTFOUND: /* we are done here */ DEBUG(SSSDBG_TRACE_FUNC, "Enumeration completed.\n"); ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; break; case NSS_STATUS_SUCCESS: DEBUG(SSSDBG_TRACE_INTERNAL, "Service found (%s, %d/%s)\n", svc->s_name, svc->s_port, svc->s_proto); protocols[0] = sss_get_cased_name(protocols, svc->s_proto, dom->case_sensitive); if (!protocols[0]) { ret = ENOMEM; goto done; } protocols[1] = NULL; ret = sss_get_cased_name_list(tmpctx, (const char * const *) svc->s_aliases, dom->case_sensitive, &cased_aliases); if (ret != EOK) { /* Do not fail completely on errors. * Just report the failure to save and go on */ DEBUG(SSSDBG_OP_FAILURE, "Failed to store service [%s]. Ignoring.\n", strerror(ret)); again = true; break; } ret = sysdb_store_service(dom, svc->s_name, svc->s_port, cased_aliases, protocols, NULL, NULL, dom->service_timeout, now); if (ret) { /* Do not fail completely on errors. * Just report the failure to save and go on */ DEBUG(SSSDBG_OP_FAILURE, "Failed to store service [%s]. Ignoring.\n", strerror(ret)); } again = true; break; case NSS_STATUS_UNAVAIL: /* "remote" backend unavailable. Enter offline mode */ ret = ENXIO; break; default: ret = EIO; DEBUG(SSSDBG_CRIT_FAILURE, "proxy -> getservent_r failed (%d)[%s]\n", ret, strerror(ret)); break; } } while (again); done: talloc_zfree(tmpctx); if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction! [%s]\n", strerror(sret)); } } ctx->ops.endservent(); return ret; } sssd-1.13.4/src/providers/proxy/PaxHeaders.16287/proxy_auth.c0000644000000000000000000000007412703456111020660 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.812794165 sssd-1.13.4/src/providers/proxy/proxy_auth.c0000644002412700241270000006670012703456111022340 0ustar00jhrozekjhrozek00000000000000/* SSSD proxy_auth.c Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/proxy/proxy.h" struct proxy_client_ctx { struct be_req *be_req; struct proxy_auth_ctx *auth_ctx; }; static struct tevent_req *proxy_child_send(TALLOC_CTX *mem_ctx, struct proxy_auth_ctx *ctx, struct be_req *be_req); static void proxy_child_done(struct tevent_req *child_req); void proxy_pam_handler(struct be_req *req) { struct be_ctx *be_ctx = be_req_get_be_ctx(req); struct pam_data *pd; struct proxy_auth_ctx *ctx; struct tevent_req *child_req = NULL; struct proxy_client_ctx *client_ctx; pd = talloc_get_type(be_req_get_data(req), struct pam_data); switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: ctx = talloc_get_type(be_ctx->bet_info[BET_AUTH].pvt_bet_data, struct proxy_auth_ctx); break; case SSS_PAM_CHAUTHTOK: case SSS_PAM_CHAUTHTOK_PRELIM: ctx = talloc_get_type(be_ctx->bet_info[BET_CHPASS].pvt_bet_data, struct proxy_auth_ctx); break; case SSS_PAM_ACCT_MGMT: ctx = talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data, struct proxy_auth_ctx); break; case SSS_PAM_SETCRED: case SSS_PAM_OPEN_SESSION: case SSS_PAM_CLOSE_SESSION: pd->pam_status = PAM_SUCCESS; be_req_terminate(req, DP_ERR_OK, EOK, NULL); return; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported PAM task.\n"); pd->pam_status = PAM_MODULE_UNKNOWN; be_req_terminate(req, DP_ERR_OK, EINVAL, "Unsupported PAM task"); return; } client_ctx = talloc(req, struct proxy_client_ctx); if (client_ctx == NULL) { be_req_terminate(req, DP_ERR_FATAL, ENOMEM, NULL); return; } client_ctx->auth_ctx = ctx; client_ctx->be_req = req; /* Queue the request and spawn a child if there * is an available slot. */ child_req = proxy_child_send(req, ctx, req); if (child_req == NULL) { /* Could not queue request * Return an error */ be_req_terminate(req, DP_ERR_FATAL, EINVAL, "Could not queue request\n"); return; } tevent_req_set_callback(child_req, proxy_child_done, client_ctx); return; } struct pc_init_ctx; static int proxy_child_destructor(TALLOC_CTX *ctx) { struct proxy_child_ctx *child_ctx = talloc_get_type(ctx, struct proxy_child_ctx); hash_key_t key; int hret; DEBUG(SSSDBG_TRACE_INTERNAL, "Removing proxy child id [%d]\n", child_ctx->id); key.type = HASH_KEY_ULONG; key.ul = child_ctx->id; hret = hash_delete(child_ctx->auth_ctx->request_table, &key); if (!(hret == HASH_SUCCESS || hret == HASH_ERROR_KEY_NOT_FOUND)) { DEBUG(SSSDBG_CRIT_FAILURE, "Hash error [%d][%s]\n", hret, hash_error_string(hret)); /* Nothing we can do about this, so just continue */ } return 0; } static struct tevent_req *proxy_child_init_send(TALLOC_CTX *mem_ctx, struct proxy_child_ctx *child_ctx, struct proxy_auth_ctx *auth_ctx); static void proxy_child_init_done(struct tevent_req *subreq); static struct tevent_req *proxy_child_send(TALLOC_CTX *mem_ctx, struct proxy_auth_ctx *auth_ctx, struct be_req *be_req) { struct tevent_req *req; struct tevent_req *subreq; struct proxy_child_ctx *state; int hret; hash_key_t key; hash_value_t value; uint32_t first; req = tevent_req_create(mem_ctx, &state, struct proxy_child_ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not send PAM request to child\n"); return NULL; } state->be_req = be_req; state->auth_ctx = auth_ctx; state->pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); /* Find an available key */ key.type = HASH_KEY_ULONG; key.ul = auth_ctx->next_id; first = auth_ctx->next_id; while (auth_ctx->next_id == 0 || hash_has_key(auth_ctx->request_table, &key)) { /* Handle overflow, zero is a reserved value * Also handle the unlikely case where the next ID * is still awaiting being run */ auth_ctx->next_id++; key.ul = auth_ctx->next_id; if (auth_ctx->next_id == first) { /* We've looped through all possible integers! */ DEBUG(SSSDBG_FATAL_FAILURE, "Serious error: queue is too long!\n"); talloc_zfree(req); return NULL; } } state->id = auth_ctx->next_id; auth_ctx->next_id++; value.type = HASH_VALUE_PTR; value.ptr = req; DEBUG(SSSDBG_TRACE_INTERNAL, "Queueing request [%lu]\n", key.ul); hret = hash_enter(auth_ctx->request_table, &key, &value); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add request to the queue\n"); talloc_zfree(req); return NULL; } talloc_set_destructor((TALLOC_CTX *) state, proxy_child_destructor); if (auth_ctx->running < auth_ctx->max_children) { /* There's an available slot; start a child * to handle the request */ auth_ctx->running++; subreq = proxy_child_init_send(auth_ctx, state, auth_ctx); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not fork child process\n"); auth_ctx->running--; talloc_zfree(req); return NULL; } tevent_req_set_callback(subreq, proxy_child_init_done, req); state->running = true; } else { /* If there was no available slot, it will be queued * until a slot is available */ DEBUG(SSSDBG_TRACE_INTERNAL, "All available child slots are full, queuing request\n"); } return req; } static int pc_init_destructor (TALLOC_CTX *ctx) { struct pc_init_ctx *init_ctx = talloc_get_type(ctx, struct pc_init_ctx); /* If the init request has died, forcibly kill the child */ kill(init_ctx->pid, SIGKILL); return 0; } static void pc_init_sig_handler(struct tevent_context *ev, struct tevent_signal *sige, int signum, int count, void *__siginfo, void *pvt); static void pc_init_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr); static struct tevent_req *proxy_child_init_send(TALLOC_CTX *mem_ctx, struct proxy_child_ctx *child_ctx, struct proxy_auth_ctx *auth_ctx) { struct tevent_req *req; struct pc_init_ctx *state; char **proxy_child_args; struct timeval tv; errno_t ret; pid_t pid; req = tevent_req_create(mem_ctx, &state, struct pc_init_ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not create tevent_req\n"); return NULL; } state->child_ctx = child_ctx; state->command = talloc_asprintf(req, "%s/proxy_child -d %#.4x --debug-timestamps=%d " "--debug-microseconds=%d%s --domain %s --id %d", SSSD_LIBEXEC_PATH, debug_level, debug_timestamps, debug_microseconds, (debug_to_file ? " --debug-to-files" : ""), auth_ctx->be->domain->name, child_ctx->id); if (state->command == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); return NULL; } DEBUG(SSSDBG_TRACE_LIBS, "Starting proxy child with args [%s]\n", state->command); pid = fork(); if (pid < 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n", ret, strerror(ret)); talloc_zfree(req); return NULL; } if (pid == 0) { /* child */ proxy_child_args = parse_args(state->command); execvp(proxy_child_args[0], proxy_child_args); ret = errno; DEBUG(SSSDBG_FATAL_FAILURE, "Could not start proxy child [%s]: [%d][%s].\n", state->command, ret, strerror(ret)); _exit(1); } else { /* parent */ state->pid = pid; /* Make sure to kill the child process if we abort */ talloc_set_destructor((TALLOC_CTX *)state, pc_init_destructor); state->sige = tevent_add_signal(auth_ctx->be->ev, req, SIGCHLD, 0, pc_init_sig_handler, req); if (state->sige == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_signal failed.\n"); talloc_zfree(req); return NULL; } /* Save the init request to the child context. * This is technically a layering violation, * but it's the only sane way to be able to * identify which client is which when it * connects to the backend in * client_registration() */ child_ctx->init_req = req; /* Wait six seconds for the child to connect * This is because the connection handler will add * its own five-second timeout, and we don't want to * be faster here. */ tv = tevent_timeval_current_ofs(6, 0); state->timeout = tevent_add_timer(auth_ctx->be->ev, req, tv, pc_init_timeout, req); /* processing will continue once the connection is received * in proxy_client_init() */ return req; } } static void pc_init_sig_handler(struct tevent_context *ev, struct tevent_signal *sige, int signum, int count, void *__siginfo, void *pvt) { int ret; int child_status; struct tevent_req *req; struct pc_init_ctx *init_ctx; if (count <= 0) { DEBUG(SSSDBG_FATAL_FAILURE, "SIGCHLD handler called with invalid child count\n"); return; } req = talloc_get_type(pvt, struct tevent_req); init_ctx = tevent_req_data(req, struct pc_init_ctx); DEBUG(SSSDBG_TRACE_LIBS, "Waiting for child [%d].\n", init_ctx->pid); errno = 0; ret = waitpid(init_ctx->pid, &child_status, WNOHANG); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "waitpid failed [%d][%s].\n", ret, strerror(ret)); } else if (ret == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "waitpid did not find a child with changed status.\n"); } else { if (WIFEXITED(child_status)) { DEBUG(SSSDBG_CONF_SETTINGS, "child [%d] exited with status [%d].\n", ret, WEXITSTATUS(child_status)); tevent_req_error(req, EIO); } else if (WIFSIGNALED(child_status)) { DEBUG(SSSDBG_CONF_SETTINGS, "child [%d] was terminate by signal [%d].\n", ret, WTERMSIG(child_status)); tevent_req_error(req, EIO); } else { if (WIFSTOPPED(child_status)) { DEBUG(SSSDBG_CRIT_FAILURE, "child [%d] was stopped by signal [%d].\n", ret, WSTOPSIG(child_status)); } if (WIFCONTINUED(child_status) == true) { DEBUG(SSSDBG_CRIT_FAILURE, "child [%d] was resumed by delivery of SIGCONT.\n", ret); } DEBUG(SSSDBG_CRIT_FAILURE, "Child is still running, no new child is started.\n"); return; } } } static void pc_init_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { struct tevent_req *req; DEBUG(SSSDBG_OP_FAILURE, "Client timed out before Identification!\n"); req = talloc_get_type(ptr, struct tevent_req); tevent_req_error(req, ETIMEDOUT); } static errno_t proxy_child_init_recv(struct tevent_req *req, pid_t *pid, struct sbus_connection **conn) { struct pc_init_ctx *state; TEVENT_REQ_RETURN_ON_ERROR(req); state = tevent_req_data(req, struct pc_init_ctx); /* Unset the destructor since we initialized successfully. * We don't want to kill the child now that it's properly * set up. */ talloc_set_destructor((TALLOC_CTX *)state, NULL); *pid = state->pid; *conn = state->conn; return EOK; } struct proxy_child_sig_ctx { struct proxy_auth_ctx *auth_ctx; pid_t pid; }; static void proxy_child_sig_handler(struct tevent_context *ev, struct tevent_signal *sige, int signum, int count, void *__siginfo, void *pvt); static struct tevent_req *proxy_pam_conv_send(TALLOC_CTX *mem_ctx, struct proxy_auth_ctx *auth_ctx, struct sbus_connection *conn, struct pam_data *pd, pid_t pid); static void proxy_pam_conv_done(struct tevent_req *subreq); static void proxy_child_init_done(struct tevent_req *subreq) { int ret; struct tevent_signal *sige; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct proxy_child_ctx *child_ctx = tevent_req_data(req, struct proxy_child_ctx); struct proxy_child_sig_ctx *sig_ctx; ret = proxy_child_init_recv(subreq, &child_ctx->pid, &child_ctx->conn); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Proxy child init failed [%d]\n", ret); tevent_req_error(req, ret); return; } /* An initialized child is available, awaiting the PAM command */ subreq = proxy_pam_conv_send(req, child_ctx->auth_ctx, child_ctx->conn, child_ctx->pd, child_ctx->pid); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE,"Could not start PAM conversation\n"); tevent_req_error(req, EIO); return; } tevent_req_set_callback(subreq, proxy_pam_conv_done, req); /* Add a signal handler for the child under the auth_ctx, * that way if the child exits after completion of the * request, it will still be handled. */ sig_ctx = talloc_zero(child_ctx->auth_ctx, struct proxy_child_sig_ctx); if(sig_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_signal failed.\n"); tevent_req_error(req, ENOMEM); return; } sig_ctx->auth_ctx = child_ctx->auth_ctx; sig_ctx->pid = child_ctx->pid; sige = tevent_add_signal(child_ctx->auth_ctx->be->ev, child_ctx->auth_ctx, SIGCHLD, 0, proxy_child_sig_handler, sig_ctx); if (sige == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_signal failed.\n"); tevent_req_error(req, ENOMEM); return; } /* Steal the signal context onto the signal event * so that when the signal is freed, the context * will go with it. */ talloc_steal(sige, sig_ctx); } static void remove_sige(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt); static void run_proxy_child_queue(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt); static void proxy_child_sig_handler(struct tevent_context *ev, struct tevent_signal *sige, int signum, int count, void *__siginfo, void *pvt) { int ret; int child_status; struct proxy_child_sig_ctx *sig_ctx; struct tevent_immediate *imm; struct tevent_immediate *imm2; if (count <= 0) { DEBUG(SSSDBG_FATAL_FAILURE, "SIGCHLD handler called with invalid child count\n"); return; } sig_ctx = talloc_get_type(pvt, struct proxy_child_sig_ctx); DEBUG(SSSDBG_TRACE_LIBS, "Waiting for child [%d].\n", sig_ctx->pid); errno = 0; ret = waitpid(sig_ctx->pid, &child_status, WNOHANG); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "waitpid failed [%d][%s].\n", ret, strerror(ret)); } else if (ret == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "waitpid did not found a child with changed status.\n"); } else { if (WIFEXITED(child_status)) { DEBUG(SSSDBG_CONF_SETTINGS, "child [%d] exited with status [%d].\n", ret, WEXITSTATUS(child_status)); } else if (WIFSIGNALED(child_status) == true) { DEBUG(SSSDBG_CONF_SETTINGS, "child [%d] was terminated by signal [%d].\n", ret, WTERMSIG(child_status)); } else { if (WIFSTOPPED(child_status)) { DEBUG(SSSDBG_CRIT_FAILURE, "child [%d] was stopped by signal [%d].\n", ret, WSTOPSIG(child_status)); } if (WIFCONTINUED(child_status) == true) { DEBUG(SSSDBG_CRIT_FAILURE, "child [%d] was resumed by delivery of SIGCONT.\n", ret); } DEBUG(SSSDBG_CRIT_FAILURE, "Child is still running, no new child is started.\n"); return; } imm = tevent_create_immediate(ev); if (imm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_create_immediate failed.\n"); return; } tevent_schedule_immediate(imm, ev, run_proxy_child_queue, sig_ctx->auth_ctx); /* schedule another immediate timer to delete the sigchld handler */ imm2 = tevent_create_immediate(ev); if (imm2 == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_create_immediate failed.\n"); return; } tevent_schedule_immediate(imm2, ev, remove_sige, sige); } return; } static void remove_sige(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt) { talloc_free(pvt); } struct proxy_conv_ctx { struct proxy_auth_ctx *auth_ctx; struct sbus_connection *conn; struct pam_data *pd; pid_t pid; }; static void proxy_pam_conv_reply(DBusPendingCall *pending, void *ptr); static struct tevent_req *proxy_pam_conv_send(TALLOC_CTX *mem_ctx, struct proxy_auth_ctx *auth_ctx, struct sbus_connection *conn, struct pam_data *pd, pid_t pid) { errno_t ret; bool dp_ret; DBusMessage *msg; struct tevent_req *req; struct proxy_conv_ctx *state; req = tevent_req_create(mem_ctx, &state, struct proxy_conv_ctx); if (req == NULL) { return NULL; } state->auth_ctx = auth_ctx; state->conn = conn; state->pd = pd; state->pid = pid; msg = dbus_message_new_method_call(NULL, DP_PATH, DATA_PROVIDER_IFACE, DATA_PROVIDER_IFACE_PAMHANDLER); if (msg == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "dbus_message_new_method_call failed.\n"); talloc_zfree(req); return NULL; } DEBUG(SSSDBG_CONF_SETTINGS, "Sending request with the following data:\n"); DEBUG_PAM_DATA(SSSDBG_CONF_SETTINGS, pd); dp_ret = dp_pack_pam_request(msg, pd); if (!dp_ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n"); dbus_message_unref(msg); talloc_zfree(req); return NULL; } ret = sbus_conn_send(state->conn, msg, state->auth_ctx->timeout_ms, proxy_pam_conv_reply, req, NULL); if (ret != EOK) { dbus_message_unref(msg); talloc_zfree(req); return NULL; } dbus_message_unref(msg); return req; } static void proxy_pam_conv_reply(DBusPendingCall *pending, void *ptr) { struct tevent_req *req; struct proxy_conv_ctx *state; DBusError dbus_error; DBusMessage *reply; int type; int ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Handling pam conversation reply\n"); req = talloc_get_type(ptr, struct tevent_req); state = tevent_req_data(req, struct proxy_conv_ctx); dbus_error_init(&dbus_error); reply = dbus_pending_call_steal_reply(pending); dbus_pending_call_unref(pending); if (reply == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Severe error. A reply callback was called but no reply was" "received and no timeout occurred\n"); state->pd->pam_status = PAM_SYSTEM_ERR; tevent_req_error(req, EIO); } type = dbus_message_get_type(reply); switch (type) { case DBUS_MESSAGE_TYPE_METHOD_RETURN: ret = dp_unpack_pam_response(reply, state->pd, &dbus_error); if (!ret) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse reply.\n"); state->pd->pam_status = PAM_SYSTEM_ERR; dbus_message_unref(reply); tevent_req_error(req, EIO); return; } DEBUG(SSSDBG_CONF_SETTINGS, "received: [%d][%s]\n", state->pd->pam_status, state->pd->domain); break; case DBUS_MESSAGE_TYPE_ERROR: DEBUG(SSSDBG_FATAL_FAILURE, "Reply error [%s].\n", dbus_message_get_error_name(reply)); state->pd->pam_status = PAM_SYSTEM_ERR; break; default: DEBUG(SSSDBG_FATAL_FAILURE, "Default... what now?.\n"); state->pd->pam_status = PAM_SYSTEM_ERR; } dbus_message_unref(reply); /* Kill the child */ kill(state->pid, SIGKILL); /* Conversation is finished */ tevent_req_done(req); } static errno_t proxy_pam_conv_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void proxy_pam_conv_done(struct tevent_req *subreq) { struct tevent_req *req; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); ret = proxy_pam_conv_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Proxy PAM conversation failed [%d]\n", ret); tevent_req_error(req, ret); return; } tevent_req_done(req); } static int proxy_child_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct pam_data **pd) { struct proxy_child_ctx *ctx; TEVENT_REQ_RETURN_ON_ERROR(req); ctx = tevent_req_data(req, struct proxy_child_ctx); *pd = talloc_steal(mem_ctx, ctx->pd); return EOK; } static void proxy_child_done(struct tevent_req *req) { struct proxy_client_ctx *client_ctx = tevent_req_callback_data(req, struct proxy_client_ctx); struct be_ctx *be_ctx = be_req_get_be_ctx(client_ctx->be_req); struct pam_data *pd = NULL; const char *password; int ret; struct tevent_immediate *imm; ret = proxy_child_recv(req, client_ctx, &pd); talloc_zfree(req); /* Start the next auth in the queue, if any */ client_ctx->auth_ctx->running--; imm = tevent_create_immediate(be_ctx->ev); if (imm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_create_immediate failed.\n"); /* We'll still finish the current request, but we're * likely to have problems if there are queued events * if we've gotten into this state. * Hopefully this is impossible, since freeing req * above should guarantee that we have enough memory * to create this immediate event. */ } else { tevent_schedule_immediate(imm, be_ctx->ev, run_proxy_child_queue, client_ctx->auth_ctx); } if (ret != EOK) { /* Pam child failed */ be_req_terminate(client_ctx->be_req, DP_ERR_FATAL, ret, "PAM child failed"); return; } /* Check if we need to save the cached credentials */ if ((pd->cmd == SSS_PAM_AUTHENTICATE || pd->cmd == SSS_PAM_CHAUTHTOK) && (pd->pam_status == PAM_SUCCESS) && be_ctx->domain->cache_credentials) { ret = sss_authtok_get_password(pd->authtok, &password, NULL); if (ret) { /* password caching failures are not fatal errors */ DEBUG(SSSDBG_OP_FAILURE, "Failed to cache password\n"); goto done; } ret = sysdb_cache_password(be_ctx->domain, pd->user, password); /* password caching failures are not fatal errors */ /* so we just log it any return */ if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to cache password (%d)[%s]!?\n", ret, strerror(ret)); } } done: be_req_terminate(client_ctx->be_req, DP_ERR_OK, EOK, NULL); } static void run_proxy_child_queue(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt) { struct proxy_auth_ctx *auth_ctx; struct hash_iter_context_t *iter; struct hash_entry_t *entry; struct tevent_req *req; struct tevent_req *subreq; struct proxy_child_ctx *state; auth_ctx = talloc_get_type(pvt, struct proxy_auth_ctx); /* Launch next queued request */ iter = new_hash_iter_context(auth_ctx->request_table); while ((entry = iter->next(iter)) != NULL) { req = talloc_get_type(entry->value.ptr, struct tevent_req); state = tevent_req_data(req, struct proxy_child_ctx); if (!state->running) { break; } } free(iter); if (!entry) { /* Nothing pending on the queue */ return; } if (auth_ctx->running < auth_ctx->max_children) { /* There's an available slot; start a child * to handle the request */ auth_ctx->running++; subreq = proxy_child_init_send(auth_ctx, state, auth_ctx); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not fork child process\n"); auth_ctx->running--; talloc_zfree(req); return; } tevent_req_set_callback(subreq, proxy_child_init_done, req); state->running = true; } } sssd-1.13.4/src/providers/proxy/PaxHeaders.16287/proxy.h0000644000000000000000000000007412703456111017644 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.579793374 sssd-1.13.4/src/providers/proxy/proxy.h0000644002412700241270000001266512703456111021325 0ustar00jhrozekjhrozek00000000000000/* SSSD Proxy provider, private header file Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __PROXY_H__ #define __PROXY_H__ #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "providers/dp_backend.h" #include "db/sysdb.h" #include "sss_client/nss_compat.h" #include struct proxy_nss_ops { enum nss_status (*getpwnam_r)(const char *name, struct passwd *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*setpwent)(void); enum nss_status (*getpwent_r)(struct passwd *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*endpwent)(void); enum nss_status (*getgrnam_r)(const char *name, struct group *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*getgrgid_r)(gid_t gid, struct group *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*setgrent)(void); enum nss_status (*getgrent_r)(struct group *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*endgrent)(void); enum nss_status (*initgroups_dyn)(const char *user, gid_t group, long int *start, long int *size, gid_t **groups, long int limit, int *errnop); enum nss_status (*setnetgrent)(const char *netgroup, struct __netgrent *result); enum nss_status (*getnetgrent_r)(struct __netgrent *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*endnetgrent)(struct __netgrent *result); /* Services */ enum nss_status (*getservbyname_r)(const char *name, const char *protocol, struct servent *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*getservbyport_r)(int port, const char *protocol, struct servent *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*setservent)(void); enum nss_status (*getservent_r)(struct servent *result, char *buffer, size_t buflen, int *errnop); enum nss_status (*endservent)(void); }; struct authtok_conv { struct sss_auth_token *authtok; struct sss_auth_token *newauthtok; bool sent_old; }; struct proxy_id_ctx { struct be_ctx *be; bool fast_alias; struct proxy_nss_ops ops; void *handle; }; struct proxy_auth_ctx { struct be_ctx *be; char *pam_target; uint32_t max_children; uint32_t running; uint32_t next_id; hash_table_t *request_table; struct sbus_connection *sbus_srv; int timeout_ms; }; struct proxy_child_ctx { struct proxy_auth_ctx *auth_ctx; struct be_req *be_req; struct pam_data *pd; uint32_t id; pid_t pid; bool running; struct sbus_connection *conn; struct tevent_timer *timer; struct tevent_req *init_req; }; struct pc_init_ctx { char *command; pid_t pid; struct tevent_timer *timeout; struct tevent_signal *sige; struct proxy_child_ctx *child_ctx; struct sbus_connection *conn; }; #define PROXY_CHILD_PIPE "private/proxy_child" #define DEFAULT_BUFSIZE 4096 #define MAX_BUF_SIZE 1024*1024 /* max 1MiB */ /* From proxy_id.c */ void proxy_get_account_info(struct be_req *breq); /* From proxy_auth.c */ void proxy_pam_handler(struct be_req *req); /* From proxy_netgroup.c */ errno_t get_netgroup(struct proxy_id_ctx *ctx, struct sss_domain_info *dom, const char *name); errno_t get_serv_byname(struct proxy_id_ctx *ctx, struct sss_domain_info *dom, const char *name, const char *protocol); errno_t get_serv_byport(struct proxy_id_ctx *ctx, struct sss_domain_info *dom, const char *be_filter, const char *protocol); errno_t enum_services(struct proxy_id_ctx *ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom); #endif /* __PROXY_H__ */ sssd-1.13.4/src/providers/proxy/PaxHeaders.16287/proxy_init.c0000644000000000000000000000007412703456111020662 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.809794154 sssd-1.13.4/src/providers/proxy/proxy_init.c0000644002412700241270000004276612703456111022350 0ustar00jhrozekjhrozek00000000000000/* SSSD proxy_init.c Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include "util/sss_format.h" #include "providers/proxy/proxy.h" static int client_registration(struct sbus_request *dbus_req, void *data); static struct data_provider_iface proxy_methods = { { &data_provider_iface_meta, 0 }, .RegisterService = client_registration, .pamHandler = NULL, .sudoHandler = NULL, .autofsHandler = NULL, .hostHandler = NULL, .getDomains = NULL, .getAccountInfo = NULL, }; static void proxy_shutdown(struct be_req *req) { /* TODO: Clean up any internal data */ be_req_terminate(req, DP_ERR_OK, EOK, NULL); } static void proxy_auth_shutdown(struct be_req *req) { struct be_ctx *be_ctx = be_req_get_be_ctx(req); talloc_free(be_ctx->bet_info[BET_AUTH].pvt_bet_data); be_req_terminate(req, DP_ERR_OK, EOK, NULL); } struct bet_ops proxy_id_ops = { .handler = proxy_get_account_info, .finalize = proxy_shutdown, .check_online = NULL }; struct bet_ops proxy_auth_ops = { .handler = proxy_pam_handler, .finalize = proxy_auth_shutdown }; struct bet_ops proxy_access_ops = { .handler = proxy_pam_handler, .finalize = proxy_auth_shutdown }; struct bet_ops proxy_chpass_ops = { .handler = proxy_pam_handler, .finalize = proxy_auth_shutdown }; static void *proxy_dlsym(void *handle, const char *functemp, char *libname) { char *funcname; void *funcptr; funcname = talloc_asprintf(NULL, functemp, libname); if (funcname == NULL) return NULL; funcptr = dlsym(handle, funcname); talloc_free(funcname); return funcptr; } int sssm_proxy_id_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { struct proxy_id_ctx *ctx; char *libname; char *libpath; int ret; ctx = talloc_zero(bectx, struct proxy_id_ctx); if (!ctx) { return ENOMEM; } ctx->be = bectx; ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path, CONFDB_PROXY_LIBNAME, NULL, &libname); if (ret != EOK) goto done; if (libname == NULL) { ret = ENOENT; goto done; } ret = confdb_get_bool(bectx->cdb, bectx->conf_path, CONFDB_PROXY_FAST_ALIAS, false, &ctx->fast_alias); if (ret != EOK) goto done; libpath = talloc_asprintf(ctx, "libnss_%s.so.2", libname); if (!libpath) { ret = ENOMEM; goto done; } ctx->handle = dlopen(libpath, RTLD_NOW); if (!ctx->handle) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load %s module with path, error: %s\n", libpath, dlerror()); ret = ELIBACC; goto done; } ctx->ops.getpwnam_r = proxy_dlsym(ctx->handle, "_nss_%s_getpwnam_r", libname); if (!ctx->ops.getpwnam_r) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load NSS fns, error: %s\n", dlerror()); ret = ELIBBAD; goto done; } ctx->ops.getpwuid_r = proxy_dlsym(ctx->handle, "_nss_%s_getpwuid_r", libname); if (!ctx->ops.getpwuid_r) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load NSS fns, error: %s\n", dlerror()); ret = ELIBBAD; goto done; } ctx->ops.setpwent = proxy_dlsym(ctx->handle, "_nss_%s_setpwent", libname); if (!ctx->ops.setpwent) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load NSS fns, error: %s\n", dlerror()); ret = ELIBBAD; goto done; } ctx->ops.getpwent_r = proxy_dlsym(ctx->handle, "_nss_%s_getpwent_r", libname); if (!ctx->ops.getpwent_r) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load NSS fns, error: %s\n", dlerror()); ret = ELIBBAD; goto done; } ctx->ops.endpwent = proxy_dlsym(ctx->handle, "_nss_%s_endpwent", libname); if (!ctx->ops.endpwent) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load NSS fns, error: %s\n", dlerror()); ret = ELIBBAD; goto done; } ctx->ops.getgrnam_r = proxy_dlsym(ctx->handle, "_nss_%s_getgrnam_r", libname); if (!ctx->ops.getgrnam_r) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load NSS fns, error: %s\n", dlerror()); ret = ELIBBAD; goto done; } ctx->ops.getgrgid_r = proxy_dlsym(ctx->handle, "_nss_%s_getgrgid_r", libname); if (!ctx->ops.getgrgid_r) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load NSS fns, error: %s\n", dlerror()); ret = ELIBBAD; goto done; } ctx->ops.setgrent = proxy_dlsym(ctx->handle, "_nss_%s_setgrent", libname); if (!ctx->ops.setgrent) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load NSS fns, error: %s\n", dlerror()); ret = ELIBBAD; goto done; } ctx->ops.getgrent_r = proxy_dlsym(ctx->handle, "_nss_%s_getgrent_r", libname); if (!ctx->ops.getgrent_r) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load NSS fns, error: %s\n", dlerror()); ret = ELIBBAD; goto done; } ctx->ops.endgrent = proxy_dlsym(ctx->handle, "_nss_%s_endgrent", libname); if (!ctx->ops.endgrent) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load NSS fns, error: %s\n", dlerror()); ret = ELIBBAD; goto done; } ctx->ops.initgroups_dyn = proxy_dlsym(ctx->handle, "_nss_%s_initgroups_dyn", libname); if (!ctx->ops.initgroups_dyn) { DEBUG(SSSDBG_CRIT_FAILURE, "The '%s' library does not provides the " "_nss_XXX_initgroups_dyn function!\n" "initgroups will be slow as it will require " "full groups enumeration!\n", libname); } ctx->ops.setnetgrent = proxy_dlsym(ctx->handle, "_nss_%s_setnetgrent", libname); if (!ctx->ops.setnetgrent) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load _nss_%s_setnetgrent, error: %s. " "The library does not support netgroups.\n", libname, dlerror()); } ctx->ops.getnetgrent_r = proxy_dlsym(ctx->handle, "_nss_%s_getnetgrent_r", libname); if (!ctx->ops.getgrent_r) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load _nss_%s_getnetgrent_r, error: %s. " "The library does not support netgroups.\n", libname, dlerror()); } ctx->ops.endnetgrent = proxy_dlsym(ctx->handle, "_nss_%s_endnetgrent", libname); if (!ctx->ops.endnetgrent) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load _nss_%s_endnetgrent, error: %s. " "The library does not support netgroups.\n", libname, dlerror()); } ctx->ops.getservbyname_r = proxy_dlsym(ctx->handle, "_nss_%s_getservbyname_r", libname); if (!ctx->ops.getservbyname_r) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to load _nss_%s_getservbyname_r, error: %s. " "The library does not support services.\n", libname, dlerror()); } ctx->ops.getservbyport_r = proxy_dlsym(ctx->handle, "_nss_%s_getservbyport_r", libname); if (!ctx->ops.getservbyport_r) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to load _nss_%s_getservbyport_r, error: %s. " "The library does not support services.\n", libname, dlerror()); } ctx->ops.setservent = proxy_dlsym(ctx->handle, "_nss_%s_setservent", libname); if (!ctx->ops.setservent) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to load _nss_%s_setservent, error: %s. " "The library does not support services.\n", libname, dlerror()); } ctx->ops.getservent_r = proxy_dlsym(ctx->handle, "_nss_%s_getservent_r", libname); if (!ctx->ops.getservent_r) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to load _nss_%s_getservent_r, error: %s. " "The library does not support services.\n", libname, dlerror()); } ctx->ops.endservent = proxy_dlsym(ctx->handle, "_nss_%s_endservent", libname); if (!ctx->ops.endservent) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to load _nss_%s_endservent, error: %s. " "The library does not support services.\n", libname, dlerror()); } *ops = &proxy_id_ops; *pvt_data = ctx; ret = EOK; done: if (ret != EOK) { talloc_free(ctx); } return ret; } struct proxy_client { struct proxy_auth_ctx *proxy_auth_ctx; struct sbus_connection *conn; struct tevent_timer *timeout; bool initialized; }; static void init_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr); static int proxy_client_init(struct sbus_connection *conn, void *data) { struct proxy_auth_ctx *proxy_auth_ctx; struct proxy_client *proxy_cli; struct timeval tv; proxy_auth_ctx = talloc_get_type(data, struct proxy_auth_ctx); /* hang off this memory to the connection so that when the connection * is freed we can potentially call a destructor */ proxy_cli = talloc_zero(conn, struct proxy_client); if (!proxy_cli) { DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n"); talloc_zfree(conn); return ENOMEM; } proxy_cli->proxy_auth_ctx = proxy_auth_ctx; proxy_cli->conn = conn; proxy_cli->initialized = false; /* 5 seconds should be plenty */ tv = tevent_timeval_current_ofs(5, 0); proxy_cli->timeout = tevent_add_timer(proxy_auth_ctx->be->ev, proxy_cli, tv, init_timeout, proxy_cli); if (!proxy_cli->timeout) { DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n"); talloc_zfree(conn); return ENOMEM; } DEBUG(SSSDBG_CONF_SETTINGS, "Set-up proxy client ID timeout [%p]\n", proxy_cli->timeout); return sbus_conn_register_iface(conn, &proxy_methods.vtable, DP_PATH, proxy_cli); } static void init_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { struct proxy_client *proxy_cli; DEBUG(SSSDBG_OP_FAILURE, "Client timed out before Identification [%p]!\n", te); proxy_cli = talloc_get_type(ptr, struct proxy_client); sbus_disconnect(proxy_cli->conn); talloc_zfree(proxy_cli); /* If we time out here, we will also time out to * pc_init_timeout(), so we'll finish the request * there. */ } static int client_registration(struct sbus_request *dbus_req, void *data) { dbus_uint16_t version = DATA_PROVIDER_VERSION; struct sbus_connection *conn; struct proxy_client *proxy_cli; dbus_uint16_t cli_ver; uint32_t cli_id; int hret; hash_key_t key; hash_value_t value; struct tevent_req *req; struct proxy_child_ctx *child_ctx; struct pc_init_ctx *init_ctx; int ret; conn = dbus_req->conn; proxy_cli = talloc_get_type(data, struct proxy_client); if (!proxy_cli) { DEBUG(SSSDBG_FATAL_FAILURE, "Connection holds no valid init data\n"); return EINVAL; } /* First thing, cancel the timeout */ DEBUG(SSSDBG_CONF_SETTINGS, "Cancel proxy client ID timeout [%p]\n", proxy_cli->timeout); talloc_zfree(proxy_cli->timeout); if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_UINT16, &cli_ver, DBUS_TYPE_UINT32, &cli_id, DBUS_TYPE_INVALID)) { sbus_disconnect(conn); return EOK; /* handled */ } DEBUG(SSSDBG_FUNC_DATA, "Proxy client [%"PRIu32"] connected\n", cli_id); /* Check the hash table */ key.type = HASH_KEY_ULONG; key.ul = cli_id; if (!hash_has_key(proxy_cli->proxy_auth_ctx->request_table, &key)) { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown child ID. Killing the connection\n"); sbus_disconnect(proxy_cli->conn); return EIO; } /* reply that all is ok */ ret = sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &version, DBUS_TYPE_INVALID); if (ret != EOK) { sbus_disconnect(conn); return ret; } hret = hash_lookup(proxy_cli->proxy_auth_ctx->request_table, &key, &value); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Hash error [%d][%s]\n", hret, hash_error_string(hret)); sbus_disconnect(conn); } /* Signal that the child is up and ready to receive the request */ req = talloc_get_type(value.ptr, struct tevent_req); child_ctx = tevent_req_data(req, struct proxy_child_ctx); if (!child_ctx->running) { /* This should hopefully be impossible, but protect * against it anyway. If we're not marked running, then * the init_req will be NULL below and things will * break. */ DEBUG(SSSDBG_CRIT_FAILURE, "Client connection from a request " "that's not marked as running\n"); return EIO; } init_ctx = tevent_req_data(child_ctx->init_req, struct pc_init_ctx); init_ctx->conn = conn; tevent_req_done(child_ctx->init_req); child_ctx->init_req = NULL; return EOK; } int sssm_proxy_auth_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { struct proxy_auth_ctx *ctx; int ret; int hret; char *sbus_address; /* If we're already set up, just return that */ if(bectx->bet_info[BET_AUTH].mod_name && strcmp("proxy", bectx->bet_info[BET_AUTH].mod_name) == 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "Re-using proxy_auth_ctx for this provider\n"); *ops = bectx->bet_info[BET_AUTH].bet_ops; *pvt_data = bectx->bet_info[BET_AUTH].pvt_bet_data; return EOK; } ctx = talloc_zero(bectx, struct proxy_auth_ctx); if (!ctx) { return ENOMEM; } ctx->be = bectx; ctx->timeout_ms = SSS_CLI_SOCKET_TIMEOUT/4; ctx->next_id = 1; ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path, CONFDB_PROXY_PAM_TARGET, NULL, &ctx->pam_target); if (ret != EOK) goto done; if (!ctx->pam_target) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing option proxy_pam_target.\n"); ret = EINVAL; goto done; } sbus_address = talloc_asprintf(ctx, "unix:path=%s/%s_%s", PIPE_PATH, PROXY_CHILD_PIPE, bectx->domain->name); if (sbus_address == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } ret = sbus_new_server(ctx, bectx->ev, sbus_address, 0, bectx->gid, false, &ctx->sbus_srv, proxy_client_init, ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up sbus server.\n"); goto done; } /* Set up request hash table */ /* FIXME: get max_children from configuration file */ ctx->max_children = 10; hret = hash_create(ctx->max_children * 2, &ctx->request_table, NULL, NULL); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize request table\n"); ret = EIO; goto done; } *ops = &proxy_auth_ops; *pvt_data = ctx; done: if (ret != EOK) { talloc_free(ctx); } return ret; } int sssm_proxy_access_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret; ret = sssm_proxy_auth_init(bectx, ops, pvt_data); *ops = &proxy_access_ops; return ret; } int sssm_proxy_chpass_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret; ret = sssm_proxy_auth_init(bectx, ops, pvt_data); *ops = &proxy_chpass_ops; return ret; } sssd-1.13.4/src/providers/proxy/PaxHeaders.16287/proxy_id.c0000644000000000000000000000007412703456111020313 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.810794158 sssd-1.13.4/src/providers/proxy/proxy_id.c0000644002412700241270000012706312703456111021773 0ustar00jhrozekjhrozek00000000000000/* SSSD proxy_id.c Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include "util/sss_format.h" #include "util/strtonum.h" #include "providers/proxy/proxy.h" /* =Getpwnam-wrapper======================================================*/ static int save_user(struct sss_domain_info *domain, bool lowercase, struct passwd *pwd, const char *real_name, const char *alias, uint64_t cache_timeout); static int handle_getpw_result(enum nss_status status, struct passwd *pwd, struct sss_domain_info *dom, bool *del_user); static int delete_user(struct sss_domain_info *domain, const char *name, uid_t uid); static int get_pw_name(struct proxy_id_ctx *ctx, struct sss_domain_info *dom, const char *name) { TALLOC_CTX *tmpctx; struct passwd *pwd; enum nss_status status; char *buffer; size_t buflen; int ret; uid_t uid; bool del_user; struct ldb_result *cached_pwd = NULL; const char *real_name = NULL; DEBUG(SSSDBG_TRACE_FUNC, "Searching user by name (%s)\n", name); tmpctx = talloc_new(NULL); if (!tmpctx) { return ENOMEM; } pwd = talloc_zero(tmpctx, struct passwd); if (!pwd) { ret = ENOMEM; goto done; } buflen = DEFAULT_BUFSIZE; buffer = talloc_size(tmpctx, buflen); if (!buffer) { ret = ENOMEM; goto done; } /* FIXME: should we move this call outside the transaction to keep the * transaction as short as possible ? */ status = ctx->ops.getpwnam_r(name, pwd, buffer, buflen, &ret); ret = handle_getpw_result(status, pwd, dom, &del_user); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "getpwnam failed [%d]: %s\n", ret, strerror(ret)); goto done; } if (del_user) { ret = delete_user(dom, name, 0); goto done; } uid = pwd->pw_uid; /* Canonicalize the username in case it was actually an alias */ if (ctx->fast_alias == true) { ret = sysdb_getpwuid(tmpctx, dom, uid, &cached_pwd); if (ret != EOK) { /* Non-fatal, attempt to canonicalize online */ DEBUG(SSSDBG_TRACE_FUNC, "Request to cache failed [%d]: %s\n", ret, strerror(ret)); } if (ret == EOK && cached_pwd->count == 1) { real_name = ldb_msg_find_attr_as_string(cached_pwd->msgs[0], SYSDB_NAME, NULL); if (!real_name) { DEBUG(SSSDBG_MINOR_FAILURE, "Cached user has no name?\n"); } } } if (real_name == NULL) { memset(buffer, 0, buflen); status = ctx->ops.getpwuid_r(uid, pwd, buffer, buflen, &ret); ret = handle_getpw_result(status, pwd, dom, &del_user); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "getpwuid failed [%d]: %s\n", ret, strerror(ret)); goto done; } real_name = pwd->pw_name; } if (del_user) { ret = delete_user(dom, name, uid); goto done; } /* Both lookups went fine, we can save the user now */ ret = save_user(dom, !dom->case_sensitive, pwd, real_name, name, dom->user_timeout); done: talloc_zfree(tmpctx); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "proxy -> getpwnam_r failed for '%s' <%d>: %s\n", name, ret, strerror(ret)); } return ret; } static int handle_getpw_result(enum nss_status status, struct passwd *pwd, struct sss_domain_info *dom, bool *del_user) { int ret = EOK; if (!del_user) { return EINVAL; } *del_user = false; switch (status) { case NSS_STATUS_NOTFOUND: DEBUG(SSSDBG_MINOR_FAILURE, "User not found.\n"); *del_user = true; break; case NSS_STATUS_SUCCESS: DEBUG(SSSDBG_TRACE_FUNC, "User found: (%s, %"SPRIuid", %"SPRIgid")\n", pwd->pw_name, pwd->pw_uid, pwd->pw_gid); /* uid=0 or gid=0 are invalid values */ /* also check that the id is in the valid range for this domain */ if (OUT_OF_ID_RANGE(pwd->pw_uid, dom->id_min, dom->id_max) || OUT_OF_ID_RANGE(pwd->pw_gid, dom->id_min, dom->id_max)) { DEBUG(SSSDBG_MINOR_FAILURE, "User filtered out! (id out of range)\n"); *del_user = true; break; } break; case NSS_STATUS_UNAVAIL: DEBUG(SSSDBG_MINOR_FAILURE, "Remote back end is not available. Entering offline mode\n"); ret = ENXIO; break; default: DEBUG(SSSDBG_OP_FAILURE, "Unknown return code %d\n", status); ret = EIO; break; } return ret; } static int delete_user(struct sss_domain_info *domain, const char *name, uid_t uid) { int ret = EOK; DEBUG(SSSDBG_TRACE_FUNC, "User %s does not exist (or is invalid) on remote server," " deleting!\n", name); ret = sysdb_delete_user(domain, name, uid); if (ret == ENOENT) { ret = EOK; } return ret; } static int save_user(struct sss_domain_info *domain, bool lowercase, struct passwd *pwd, const char *real_name, const char *alias, uint64_t cache_timeout) { const char *shell; const char *gecos; struct sysdb_attrs *attrs = NULL; errno_t ret; const char *cased_alias; const char *lc_pw_name = NULL; if (pwd->pw_shell && pwd->pw_shell[0] != '\0') { shell = pwd->pw_shell; } else { shell = NULL; } if (pwd->pw_gecos && pwd->pw_gecos[0] != '\0') { gecos = pwd->pw_gecos; } else { gecos = NULL; } if (lowercase || alias) { attrs = sysdb_new_attrs(NULL); if (!attrs) { DEBUG(SSSDBG_CRIT_FAILURE, "Allocation error ?!\n"); ret = ENOMEM; goto done; } } if (lowercase) { lc_pw_name = sss_tc_utf8_str_tolower(attrs, pwd->pw_name); if (lc_pw_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot convert name to lowercase.\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, lc_pw_name); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not add name alias\n"); ret = ENOMEM; goto done; } } if (alias) { cased_alias = sss_get_cased_name(attrs, alias, !lowercase); if (!cased_alias) { ret = ENOMEM; goto done; } /* Add the alias only if it differs from lowercased pw_name */ if (lc_pw_name == NULL || strcmp(cased_alias, lc_pw_name) != 0) { ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, cased_alias); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not add name alias\n"); goto done; } } } ret = sysdb_store_user(domain, real_name, pwd->pw_passwd, pwd->pw_uid, pwd->pw_gid, gecos, pwd->pw_dir, shell, NULL, attrs, NULL, cache_timeout, 0); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not add user to cache\n"); goto done; } done: talloc_zfree(attrs); return ret; } /* =Getpwuid-wrapper======================================================*/ static int get_pw_uid(struct proxy_id_ctx *ctx, struct sss_domain_info *dom, uid_t uid) { TALLOC_CTX *tmpctx; struct passwd *pwd; enum nss_status status; char *buffer; size_t buflen; bool del_user = false; int ret; DEBUG(SSSDBG_TRACE_FUNC, "Searching user by uid (%"SPRIuid")\n", uid); tmpctx = talloc_new(NULL); if (!tmpctx) { return ENOMEM; } pwd = talloc_zero(tmpctx, struct passwd); if (!pwd) { ret = ENOMEM; goto done; } buflen = DEFAULT_BUFSIZE; buffer = talloc_size(tmpctx, buflen); if (!buffer) { ret = ENOMEM; goto done; } status = ctx->ops.getpwuid_r(uid, pwd, buffer, buflen, &ret); ret = handle_getpw_result(status, pwd, dom, &del_user); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "getpwuid failed [%d]: %s\n", ret, strerror(ret)); goto done; } if (del_user) { ret = delete_user(dom, NULL, uid); goto done; } ret = save_user(dom, !dom->case_sensitive, pwd, pwd->pw_name, NULL, dom->user_timeout); done: talloc_zfree(tmpctx); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "proxy -> getpwuid_r failed for '%"SPRIuid"' <%d>: %s\n", uid, ret, strerror(ret)); } return ret; } /* =Getpwent-wrapper======================================================*/ static int enum_users(TALLOC_CTX *mem_ctx, struct proxy_id_ctx *ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom) { TALLOC_CTX *tmpctx; bool in_transaction = false; struct passwd *pwd; enum nss_status status; size_t buflen; char *buffer; char *newbuf; int ret; errno_t sret; bool again; DEBUG(SSSDBG_TRACE_LIBS, "Enumerating users\n"); tmpctx = talloc_new(mem_ctx); if (!tmpctx) { return ENOMEM; } pwd = talloc_zero(tmpctx, struct passwd); if (!pwd) { ret = ENOMEM; goto done; } buflen = DEFAULT_BUFSIZE; buffer = talloc_size(tmpctx, buflen); if (!buffer) { ret = ENOMEM; goto done; } ret = sysdb_transaction_start(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; status = ctx->ops.setpwent(); if (status != NSS_STATUS_SUCCESS) { ret = EIO; goto done; } do { again = false; /* always zero out the pwd structure */ memset(pwd, 0, sizeof(struct passwd)); /* get entry */ status = ctx->ops.getpwent_r(pwd, buffer, buflen, &ret); switch (status) { case NSS_STATUS_TRYAGAIN: /* buffer too small ? */ if (buflen < MAX_BUF_SIZE) { buflen *= 2; } if (buflen > MAX_BUF_SIZE) { buflen = MAX_BUF_SIZE; } newbuf = talloc_realloc_size(tmpctx, buffer, buflen); if (!newbuf) { ret = ENOMEM; goto done; } buffer = newbuf; again = true; break; case NSS_STATUS_NOTFOUND: /* we are done here */ DEBUG(SSSDBG_TRACE_LIBS, "Enumeration completed.\n"); ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; break; case NSS_STATUS_SUCCESS: DEBUG(SSSDBG_TRACE_LIBS, "User found (%s, %"SPRIuid", %"SPRIgid")\n", pwd->pw_name, pwd->pw_uid, pwd->pw_gid); /* uid=0 or gid=0 are invalid values */ /* also check that the id is in the valid range for this domain */ if (OUT_OF_ID_RANGE(pwd->pw_uid, dom->id_min, dom->id_max) || OUT_OF_ID_RANGE(pwd->pw_gid, dom->id_min, dom->id_max)) { DEBUG(SSSDBG_OP_FAILURE, "User [%s] filtered out! (id out" " of range)\n", pwd->pw_name); again = true; break; } ret = save_user(dom, !dom->case_sensitive, pwd, pwd->pw_name, NULL, dom->user_timeout); if (ret) { /* Do not fail completely on errors. * Just report the failure to save and go on */ DEBUG(SSSDBG_OP_FAILURE, "Failed to store user %s." " Ignoring.\n", pwd->pw_name); } again = true; break; case NSS_STATUS_UNAVAIL: /* "remote" backend unavailable. Enter offline mode */ ret = ENXIO; break; default: ret = EIO; DEBUG(SSSDBG_OP_FAILURE, "proxy -> getpwent_r failed (%d)[%s]" "\n", ret, strerror(ret)); break; } } while (again); done: talloc_zfree(tmpctx); if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } ctx->ops.endpwent(); return ret; } /* =Save-group-utilities=================================================*/ #define DEBUG_GR_MEM(level, grp) \ do { \ if (DEBUG_IS_SET(level)) { \ if (!grp->gr_mem || !grp->gr_mem[0]) { \ DEBUG(level, "Group %s has no members!\n", \ grp->gr_name); \ } else { \ int i = 0; \ while (grp->gr_mem[i]) { \ /* count */ \ i++; \ } \ DEBUG(level, "Group %s has %d members!\n", \ grp->gr_name, i); \ } \ } \ } while(0) static errno_t proxy_process_missing_users(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sysdb_attrs *group_attrs, struct group *grp, time_t now); static int save_group(struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct group *grp, const char *real_name, const char *alias, uint64_t cache_timeout) { errno_t ret, sret; struct sysdb_attrs *attrs = NULL; const char *cased_alias; const char *lc_gr_name = NULL; TALLOC_CTX *tmp_ctx; time_t now = time(NULL); bool in_transaction = false; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } DEBUG_GR_MEM(SSSDBG_TRACE_LIBS, grp); ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; if (grp->gr_mem && grp->gr_mem[0]) { attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { DEBUG(SSSDBG_CRIT_FAILURE, "Allocation error ?!\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_users_from_str_list( attrs, SYSDB_MEMBER, dom->name, (const char *const *)grp->gr_mem); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not add group members\n"); goto done; } /* Create ghost users */ ret = proxy_process_missing_users(sysdb, dom, attrs, grp, now); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not add missing members\n"); goto done; } } if (dom->case_sensitive == false || alias) { if (!attrs) { attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { DEBUG(SSSDBG_CRIT_FAILURE, "Allocation error ?!\n"); ret = ENOMEM; goto done; } } } if (dom->case_sensitive == false) { lc_gr_name = sss_tc_utf8_str_tolower(attrs, grp->gr_name); if (lc_gr_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot convert name to lowercase.\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, lc_gr_name); if (ret != EOK) { goto done; } } if (alias) { cased_alias = sss_get_cased_name(attrs, alias, dom->case_sensitive); if (!cased_alias) { ret = ENOMEM; DEBUG(SSSDBG_OP_FAILURE, "Could not add name alias\n"); goto done; } if (lc_gr_name == NULL || strcmp(cased_alias, lc_gr_name)) { ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, cased_alias); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not add name alias\n"); goto done; } } } ret = sysdb_store_group(dom, real_name, grp->gr_gid, attrs, cache_timeout, now); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not add group to cache\n"); goto done; } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not commit transaction: [%s]\n", strerror(ret)); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } static errno_t proxy_process_missing_users(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sysdb_attrs *group_attrs, struct group *grp, time_t now) { errno_t ret; size_t i; TALLOC_CTX *tmp_ctx = NULL; struct ldb_message *msg; if (!sysdb || !grp) return EINVAL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; for (i = 0; grp->gr_mem[i]; i++) { ret = sysdb_search_user_by_name(tmp_ctx, domain, grp->gr_mem[i], NULL, &msg); if (ret == EOK) { /* Member already exists in the cache */ DEBUG(SSSDBG_TRACE_INTERNAL, "Member [%s] already cached\n", grp->gr_mem[i]); /* clean up */ talloc_zfree(msg); continue; } else if (ret == ENOENT) { /* No entry for this user. Create a ghost user */ DEBUG(SSSDBG_TRACE_LIBS, "Member [%s] not cached, creating ghost user entry\n", grp->gr_mem[i]); ret = sysdb_attrs_add_string(group_attrs, SYSDB_GHOST, grp->gr_mem[i]); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot store ghost user entry: [%d]: %s\n", ret, strerror(ret)); goto done; } } else { /* Unexpected error */ DEBUG(SSSDBG_MINOR_FAILURE, "Error searching cache for user [%s]: [%s]\n", grp->gr_mem[i], strerror(ret)); goto done; } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* =Getgrnam-wrapper======================================================*/ static char * grow_group_buffer(TALLOC_CTX *mem_ctx, char **buffer, size_t *buflen) { char *newbuf; if (*buflen == 0) { *buflen = DEFAULT_BUFSIZE; } if (*buflen < MAX_BUF_SIZE) { *buflen *= 2; } if (*buflen > MAX_BUF_SIZE) { *buflen = MAX_BUF_SIZE; } newbuf = talloc_realloc_size(mem_ctx, *buffer, *buflen); if (!newbuf) { return NULL; } *buffer = newbuf; return *buffer; } static errno_t handle_getgr_result(enum nss_status status, struct group *grp, struct sss_domain_info *dom, bool *delete_group) { switch (status) { case NSS_STATUS_TRYAGAIN: DEBUG(SSSDBG_MINOR_FAILURE, "Buffer too small\n"); return EAGAIN; case NSS_STATUS_NOTFOUND: DEBUG(SSSDBG_MINOR_FAILURE, "Group not found.\n"); *delete_group = true; break; case NSS_STATUS_SUCCESS: DEBUG(SSSDBG_FUNC_DATA, "Group found: (%s, %"SPRIgid")\n", grp->gr_name, grp->gr_gid); /* gid=0 is an invalid value */ /* also check that the id is in the valid range for this domain */ if (OUT_OF_ID_RANGE(grp->gr_gid, dom->id_min, dom->id_max)) { DEBUG(SSSDBG_MINOR_FAILURE, "Group filtered out! (id out of range)\n"); *delete_group = true; break; } break; case NSS_STATUS_UNAVAIL: DEBUG(SSSDBG_MINOR_FAILURE, "Remote back end is not available. Entering offline mode\n"); return ENXIO; default: DEBUG(SSSDBG_OP_FAILURE, "Unknown return code %d\n", status); return EIO; } return EOK; } static int get_gr_name(struct proxy_id_ctx *ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, const char *name) { TALLOC_CTX *tmpctx; struct group *grp; enum nss_status status; char *buffer = 0; size_t buflen = 0; bool delete_group = false; int ret; gid_t gid; struct ldb_result *cached_grp = NULL; const char *real_name = NULL; DEBUG(SSSDBG_FUNC_DATA, "Searching group by name (%s)\n", name); tmpctx = talloc_new(NULL); if (!tmpctx) { return ENOMEM; } grp = talloc(tmpctx, struct group); if (!grp) { ret = ENOMEM; DEBUG(SSSDBG_CRIT_FAILURE, "proxy -> getgrnam_r failed for '%s': [%d] %s\n", name, ret, strerror(ret)); goto done; } do { /* always zero out the grp structure */ memset(grp, 0, sizeof(struct group)); buffer = grow_group_buffer(tmpctx, &buffer, &buflen); if (!buffer) { ret = ENOMEM; goto done; } status = ctx->ops.getgrnam_r(name, grp, buffer, buflen, &ret); ret = handle_getgr_result(status, grp, dom, &delete_group); } while (ret == EAGAIN); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "getgrnam failed [%d]: %s\n", ret, strerror(ret)); goto done; } gid = grp->gr_gid; /* Canonicalize the group name in case it was actually an alias */ if (ctx->fast_alias == true) { ret = sysdb_getgrgid(tmpctx, dom, gid, &cached_grp); if (ret != EOK) { /* Non-fatal, attempt to canonicalize online */ DEBUG(SSSDBG_TRACE_FUNC, "Request to cache failed [%d]: %s\n", ret, strerror(ret)); } if (ret == EOK && cached_grp->count == 1) { real_name = ldb_msg_find_attr_as_string(cached_grp->msgs[0], SYSDB_NAME, NULL); if (!real_name) { DEBUG(SSSDBG_MINOR_FAILURE, "Cached group has no name?\n"); } } } if (real_name == NULL) { talloc_zfree(buffer); buflen = 0; do { memset(grp, 0, sizeof(struct group)); buffer = grow_group_buffer(tmpctx, &buffer, &buflen); if (!buffer) { ret = ENOMEM; goto done; } status = ctx->ops.getgrgid_r(gid, grp, buffer, buflen, &ret); ret = handle_getgr_result(status, grp, dom, &delete_group); } while (ret == EAGAIN); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "getgrgid failed [%d]: %s\n", ret, strerror(ret)); goto done; } real_name = grp->gr_name; } if (delete_group) { DEBUG(SSSDBG_TRACE_FUNC, "Group %s does not exist (or is invalid) on remote server," " deleting!\n", name); ret = sysdb_delete_group(dom, NULL, gid); if (ret == ENOENT) { ret = EOK; } goto done; } ret = save_group(sysdb, dom, grp, real_name, name, dom->group_timeout); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Cannot save group [%d]: %s\n", ret, strerror(ret)); goto done; } done: talloc_zfree(tmpctx); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "proxy -> getgrnam_r failed for '%s' <%d>: %s\n", name, ret, strerror(ret)); } return ret; } /* =Getgrgid-wrapper======================================================*/ static int get_gr_gid(TALLOC_CTX *mem_ctx, struct proxy_id_ctx *ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, gid_t gid, time_t now) { TALLOC_CTX *tmpctx; struct group *grp; enum nss_status status; char *buffer = NULL; size_t buflen = 0; bool delete_group = false; int ret; DEBUG(SSSDBG_TRACE_FUNC, "Searching group by gid (%"SPRIgid")\n", gid); tmpctx = talloc_new(mem_ctx); if (!tmpctx) { return ENOMEM; } grp = talloc(tmpctx, struct group); if (!grp) { ret = ENOMEM; goto done; } do { /* always zero out the grp structure */ memset(grp, 0, sizeof(struct group)); buffer = grow_group_buffer(tmpctx, &buffer, &buflen); if (!buffer) { ret = ENOMEM; goto done; } status = ctx->ops.getgrgid_r(gid, grp, buffer, buflen, &ret); ret = handle_getgr_result(status, grp, dom, &delete_group); } while (ret == EAGAIN); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "getgrgid failed [%d]: %s\n", ret, strerror(ret)); goto done; } if (delete_group) { DEBUG(SSSDBG_TRACE_FUNC, "Group %"SPRIgid" does not exist (or is invalid) on remote " "server, deleting!\n", gid); ret = sysdb_delete_group(dom, NULL, gid); if (ret == ENOENT) { ret = EOK; } goto done; } ret = save_group(sysdb, dom, grp, grp->gr_name, NULL, dom->group_timeout); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Cannot save user [%d]: %s\n", ret, strerror(ret)); goto done; } done: talloc_zfree(tmpctx); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "proxy -> getgrgid_r failed for '%"SPRIgid"' <%d>: %s\n", gid, ret, strerror(ret)); } return ret; } /* =Getgrent-wrapper======================================================*/ static int enum_groups(TALLOC_CTX *mem_ctx, struct proxy_id_ctx *ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom) { TALLOC_CTX *tmpctx; bool in_transaction = false; struct group *grp; enum nss_status status; size_t buflen; char *buffer; char *newbuf; int ret; errno_t sret; bool again; DEBUG(SSSDBG_TRACE_LIBS, "Enumerating groups\n"); tmpctx = talloc_new(mem_ctx); if (!tmpctx) { return ENOMEM; } grp = talloc(tmpctx, struct group); if (!grp) { ret = ENOMEM; goto done; } buflen = DEFAULT_BUFSIZE; buffer = talloc_size(tmpctx, buflen); if (!buffer) { ret = ENOMEM; goto done; } ret = sysdb_transaction_start(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; status = ctx->ops.setgrent(); if (status != NSS_STATUS_SUCCESS) { ret = EIO; goto done; } do { again = false; /* always zero out the grp structure */ memset(grp, 0, sizeof(struct group)); /* get entry */ status = ctx->ops.getgrent_r(grp, buffer, buflen, &ret); switch (status) { case NSS_STATUS_TRYAGAIN: /* buffer too small ? */ if (buflen < MAX_BUF_SIZE) { buflen *= 2; } if (buflen > MAX_BUF_SIZE) { buflen = MAX_BUF_SIZE; } newbuf = talloc_realloc_size(tmpctx, buffer, buflen); if (!newbuf) { ret = ENOMEM; goto done; } buffer = newbuf; again = true; break; case NSS_STATUS_NOTFOUND: /* we are done here */ DEBUG(SSSDBG_TRACE_LIBS, "Enumeration completed.\n"); ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; break; case NSS_STATUS_SUCCESS: DEBUG(SSSDBG_OP_FAILURE, "Group found (%s, %"SPRIgid")\n", grp->gr_name, grp->gr_gid); /* gid=0 is an invalid value */ /* also check that the id is in the valid range for this domain */ if (OUT_OF_ID_RANGE(grp->gr_gid, dom->id_min, dom->id_max)) { DEBUG(SSSDBG_OP_FAILURE, "Group [%s] filtered out! (id" "out of range)\n", grp->gr_name); again = true; break; } ret = save_group(sysdb, dom, grp, grp->gr_name, NULL, dom->group_timeout); if (ret) { /* Do not fail completely on errors. * Just report the failure to save and go on */ DEBUG(SSSDBG_OP_FAILURE, "Failed to store group." "Ignoring\n"); } again = true; break; case NSS_STATUS_UNAVAIL: /* "remote" backend unavailable. Enter offline mode */ ret = ENXIO; break; default: ret = EIO; DEBUG(SSSDBG_OP_FAILURE, "proxy -> getgrent_r failed (%d)[%s]" "\n", ret, strerror(ret)); break; } } while (again); done: talloc_zfree(tmpctx); if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } ctx->ops.endgrent(); return ret; } /* =Initgroups-wrapper====================================================*/ static int get_initgr_groups_process(TALLOC_CTX *memctx, struct proxy_id_ctx *ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct passwd *pwd); static int get_initgr(TALLOC_CTX *mem_ctx, struct proxy_id_ctx *ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, const char *name) { TALLOC_CTX *tmpctx; bool in_transaction = false; struct passwd *pwd; enum nss_status status; char *buffer; size_t buflen; int ret; errno_t sret; bool del_user; uid_t uid; struct ldb_result *cached_pwd = NULL; const char *real_name = NULL; tmpctx = talloc_new(mem_ctx); if (!tmpctx) { return ENOMEM; } pwd = talloc_zero(tmpctx, struct passwd); if (!pwd) { ret = ENOMEM; goto fail; } buflen = DEFAULT_BUFSIZE; buffer = talloc_size(tmpctx, buflen); if (!buffer) { ret = ENOMEM; goto fail; } ret = sysdb_transaction_start(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto fail; } in_transaction = true; /* FIXME: should we move this call outside the transaction to keep the * transaction as short as possible ? */ status = ctx->ops.getpwnam_r(name, pwd, buffer, buflen, &ret); ret = handle_getpw_result(status, pwd, dom, &del_user); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "getpwnam failed [%d]: %s\n", ret, strerror(ret)); goto fail; } if (del_user) { ret = delete_user(dom, name, 0); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not delete user\n"); goto fail; } goto done; } uid = pwd->pw_uid; memset(buffer, 0, buflen); /* Canonicalize the username in case it was actually an alias */ if (ctx->fast_alias == true) { ret = sysdb_getpwuid(tmpctx, dom, uid, &cached_pwd); if (ret != EOK) { /* Non-fatal, attempt to canonicalize online */ DEBUG(SSSDBG_TRACE_FUNC, "Request to cache failed [%d]: %s\n", ret, strerror(ret)); } if (ret == EOK && cached_pwd->count == 1) { real_name = ldb_msg_find_attr_as_string(cached_pwd->msgs[0], SYSDB_NAME, NULL); if (!real_name) { DEBUG(SSSDBG_MINOR_FAILURE, "Cached user has no name?\n"); } } } if (real_name == NULL) { memset(buffer, 0, buflen); status = ctx->ops.getpwuid_r(uid, pwd, buffer, buflen, &ret); ret = handle_getpw_result(status, pwd, dom, &del_user); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "getpwuid failed [%d]: %s\n", ret, strerror(ret)); goto done; } real_name = pwd->pw_name; } if (del_user) { ret = delete_user(dom, name, uid); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not delete user\n"); goto fail; } goto done; } ret = save_user(dom, !dom->case_sensitive, pwd, real_name, name, dom->user_timeout); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not save user\n"); goto fail; } ret = get_initgr_groups_process(tmpctx, ctx, sysdb, dom, pwd); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not process initgroups\n"); goto fail; } done: ret = sysdb_transaction_commit(sysdb); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to commit transaction\n"); goto fail; } in_transaction = false; fail: talloc_zfree(tmpctx); if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } return ret; } static int get_initgr_groups_process(TALLOC_CTX *memctx, struct proxy_id_ctx *ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct passwd *pwd) { enum nss_status status; long int limit; long int size; long int num; long int num_gids; gid_t *gids; int ret; int i; time_t now; num_gids = 0; limit = 4096; num = 4096; size = num*sizeof(gid_t); gids = talloc_size(memctx, size); if (!gids) { return ENOMEM; } /* nss modules may skip the primary group when we pass it in so always add * it in advance */ gids[0] = pwd->pw_gid; num_gids++; /* FIXME: should we move this call outside the transaction to keep the * transaction as short as possible ? */ do { status = ctx->ops.initgroups_dyn(pwd->pw_name, pwd->pw_gid, &num_gids, &num, &gids, limit, &ret); if (status == NSS_STATUS_TRYAGAIN) { /* buffer too small ? */ if (size < MAX_BUF_SIZE) { num *= 2; size = num*sizeof(gid_t); } if (size > MAX_BUF_SIZE) { size = MAX_BUF_SIZE; num = size/sizeof(gid_t); } limit = num; gids = talloc_realloc_size(memctx, gids, size); if (!gids) { return ENOMEM; } } } while(status == NSS_STATUS_TRYAGAIN); switch (status) { case NSS_STATUS_NOTFOUND: DEBUG(SSSDBG_FUNC_DATA, "The initgroups call returned 'NOTFOUND'. " "Assume the user is only member of its " "primary group (%"SPRIgid")\n", pwd->pw_gid); /* fall through */ case NSS_STATUS_SUCCESS: DEBUG(SSSDBG_CONF_SETTINGS, "User [%s] appears to be member of %lu " "groups\n", pwd->pw_name, num_gids); now = time(NULL); for (i = 0; i < num_gids; i++) { ret = get_gr_gid(memctx, ctx, sysdb, dom, gids[i], now); if (ret) { return ret; } } ret = EOK; break; default: DEBUG(SSSDBG_OP_FAILURE, "proxy -> initgroups_dyn failed (%d)[%s]\n", ret, strerror(ret)); ret = EIO; break; } return ret; } /* =Proxy_Id-Functions====================================================*/ void proxy_get_account_info(struct be_req *breq) { struct be_ctx *be_ctx = be_req_get_be_ctx(breq); struct be_acct_req *ar; struct proxy_id_ctx *ctx; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; uid_t uid; gid_t gid; int ret; char *endptr; ar = talloc_get_type(be_req_get_data(breq), struct be_acct_req); ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data, struct proxy_id_ctx); sysdb = be_ctx->domain->sysdb; domain = be_ctx->domain; if (be_is_offline(be_ctx)) { return be_req_terminate(breq, DP_ERR_OFFLINE, EAGAIN, "Offline"); } /* for now we support only core attrs */ if (ar->attr_type != BE_ATTR_CORE) { return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid attr type"); } /* proxy provider does not support security ID lookups */ if (ar->filter_type == BE_FILTER_SECID) { return be_req_terminate(breq, DP_ERR_FATAL, ENOSYS, "Invalid filter type"); } switch (ar->entry_type & BE_REQ_TYPE_MASK) { case BE_REQ_USER: /* user */ switch (ar->filter_type) { case BE_FILTER_ENUM: ret = enum_users(breq, ctx, sysdb, domain); break; case BE_FILTER_NAME: ret = get_pw_name(ctx, domain, ar->filter_value); break; case BE_FILTER_IDNUM: uid = (uid_t) strtouint32(ar->filter_value, &endptr, 10); if (errno || *endptr || (ar->filter_value == endptr)) { return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid attr type"); } ret = get_pw_uid(ctx, domain, uid); break; default: return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid filter type"); } break; case BE_REQ_GROUP: /* group */ switch (ar->filter_type) { case BE_FILTER_ENUM: ret = enum_groups(breq, ctx, sysdb, domain); break; case BE_FILTER_NAME: ret = get_gr_name(ctx, sysdb, domain, ar->filter_value); break; case BE_FILTER_IDNUM: gid = (gid_t) strtouint32(ar->filter_value, &endptr, 10); if (errno || *endptr || (ar->filter_value == endptr)) { return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid attr type"); } ret = get_gr_gid(breq, ctx, sysdb, domain, gid, 0); break; default: return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid filter type"); } break; case BE_REQ_INITGROUPS: /* init groups for user */ if (ar->filter_type != BE_FILTER_NAME) { return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid filter type"); } if (ctx->ops.initgroups_dyn == NULL) { return be_req_terminate(breq, DP_ERR_FATAL, ENODEV, "Initgroups call not supported"); } ret = get_initgr(breq, ctx, sysdb, domain, ar->filter_value); break; case BE_REQ_NETGROUP: if (ar->filter_type != BE_FILTER_NAME) { return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid filter type"); } if (ctx->ops.setnetgrent == NULL || ctx->ops.getnetgrent_r == NULL || ctx->ops.endnetgrent == NULL) { return be_req_terminate(breq, DP_ERR_FATAL, ENODEV, "Netgroups are not supported"); } ret = get_netgroup(ctx, domain, ar->filter_value); break; case BE_REQ_SERVICES: switch (ar->filter_type) { case BE_FILTER_NAME: if (ctx->ops.getservbyname_r == NULL) { return be_req_terminate(breq, DP_ERR_FATAL, ENODEV, "Services are not supported"); } ret = get_serv_byname(ctx, domain, ar->filter_value, ar->extra_value); break; case BE_FILTER_IDNUM: if (ctx->ops.getservbyport_r == NULL) { return be_req_terminate(breq, DP_ERR_FATAL, ENODEV, "Services are not supported"); } ret = get_serv_byport(ctx, domain, ar->filter_value, ar->extra_value); break; case BE_FILTER_ENUM: if (!ctx->ops.setservent || !ctx->ops.getservent_r || !ctx->ops.endservent) { return be_req_terminate(breq, DP_ERR_FATAL, ENODEV, "Services are not supported"); } ret = enum_services(ctx, sysdb, domain); break; default: return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid filter type"); } break; default: /*fail*/ return be_req_terminate(breq, DP_ERR_FATAL, EINVAL, "Invalid request type"); } if (ret) { if (ret == ENXIO) { DEBUG(SSSDBG_OP_FAILURE, "proxy returned UNAVAIL error, going offline!\n"); be_mark_offline(be_ctx); } be_req_terminate(breq, DP_ERR_FATAL, ret, NULL); return; } be_req_terminate(breq, DP_ERR_OK, EOK, NULL); } sssd-1.13.4/src/providers/PaxHeaders.16287/dp_dyndns.c0000644000000000000000000000007412703456111017257 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.658793642 sssd-1.13.4/src/providers/dp_dyndns.c0000644002412700241270000011145512703456111020735 0ustar00jhrozekjhrozek00000000000000/* SSSD dp_dyndns.c Authors: Stephen Gallagher Jakub Hrozek Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "util/util.h" #include "confdb/confdb.h" #include "util/child_common.h" #include "providers/data_provider.h" #include "providers/dp_backend.h" #include "providers/dp_dyndns.h" #include "resolv/async_resolv.h" #ifndef DYNDNS_TIMEOUT #define DYNDNS_TIMEOUT 15 #endif /* DYNDNS_TIMEOUT */ /* MASK represents special value for matching all interfaces */ #define MASK "*" struct sss_iface_addr { struct sss_iface_addr *next; struct sss_iface_addr *prev; struct sockaddr_storage *addr; }; struct sockaddr_storage* sss_iface_addr_get_address(struct sss_iface_addr *address) { if (address == NULL) { return NULL; } return address->addr; } struct sss_iface_addr *sss_iface_addr_get_next(struct sss_iface_addr *address) { if (address) { return address->next; } return NULL; } void sss_iface_addr_concatenate(struct sss_iface_addr **list, struct sss_iface_addr *list2) { DLIST_CONCATENATE((*list), list2, struct sss_iface_addr*); } static errno_t addr_to_str(struct sockaddr_storage *addr, char *dst, size_t size) { const void *src; const char *res; errno_t ret; switch(addr->ss_family) { case AF_INET: src = &(((struct sockaddr_in *)addr)->sin_addr); break; case AF_INET6: src = &(((struct sockaddr_in6 *)addr)->sin6_addr); break; default: ret = ERR_ADDR_FAMILY_NOT_SUPPORTED; goto done; } res = inet_ntop(addr->ss_family, src, dst, size); if (res == NULL) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "inet_ntop failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = EOK; done: return ret; } errno_t sss_iface_addr_list_as_str_list(TALLOC_CTX *mem_ctx, struct sss_iface_addr *ifaddr_list, char ***_straddrs) { struct sss_iface_addr *ifaddr; size_t count; int ai; char **straddrs; char ip_addr[INET6_ADDRSTRLEN]; errno_t ret; count = 0; DLIST_FOR_EACH(ifaddr, ifaddr_list) { count++; } straddrs = talloc_array(mem_ctx, char *, count+1); if (straddrs == NULL) { return ENOMEM; } ai = 0; DLIST_FOR_EACH(ifaddr, ifaddr_list) { ret = addr_to_str(ifaddr->addr, ip_addr, INET6_ADDRSTRLEN); if (ret == ERR_ADDR_FAMILY_NOT_SUPPORTED) { continue; } else if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "addr_to_str failed: %d:[%s],\n", ret, sss_strerror(ret)); goto fail; } straddrs[ai] = talloc_strdup(straddrs, ip_addr); if (straddrs[ai] == NULL) { ret = ENOMEM; goto fail; } ai++; } straddrs[count] = NULL; *_straddrs = straddrs; return EOK; fail: talloc_free(straddrs); return ret; } static bool ok_for_dns(struct sockaddr *sa) { struct sockaddr_in sa4; struct sockaddr_in6 sa6; switch (sa->sa_family) { case AF_INET6: memcpy(&sa6, sa, sizeof(struct sockaddr_in6)); return check_ipv6_addr(&sa6.sin6_addr, SSS_NO_SPECIAL); case AF_INET: memcpy(&sa4, sa, sizeof(struct sockaddr_in)); return check_ipv4_addr(&sa4.sin_addr, SSS_NO_SPECIAL); default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown address family\n"); return false; } return true; } static bool supported_address_family(sa_family_t sa_family) { return sa_family == AF_INET || sa_family == AF_INET6; } static bool matching_name(const char *ifname, const char *ifname2) { return (strcmp(MASK, ifname) == 0) || (strcasecmp(ifname, ifname2) == 0); } /* Collect IP addresses associated with an interface */ errno_t sss_iface_addr_list_get(TALLOC_CTX *mem_ctx, const char *ifname, struct sss_iface_addr **_addrlist) { struct ifaddrs *ifaces = NULL; struct ifaddrs *ifa; errno_t ret; size_t addrsize; struct sss_iface_addr *address; struct sss_iface_addr *addrlist = NULL; /* Get the IP addresses associated with the * specified interface */ errno = 0; ret = getifaddrs(&ifaces); if (ret == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "Could not read interfaces [%d][%s]\n", ret, strerror(ret)); goto done; } for (ifa = ifaces; ifa != NULL; ifa = ifa->ifa_next) { /* Some interfaces don't have an ifa_addr */ if (!ifa->ifa_addr) continue; /* Add IP addresses to the list */ if (supported_address_family(ifa->ifa_addr->sa_family) && matching_name(ifname, ifa->ifa_name) && ok_for_dns(ifa->ifa_addr)) { /* Add this address to the IP address list */ address = talloc_zero(mem_ctx, struct sss_iface_addr); if (!address) { ret = ENOMEM; goto done; } addrsize = ifa->ifa_addr->sa_family == AF_INET ? \ sizeof(struct sockaddr_in) : \ sizeof(struct sockaddr_in6); address->addr = talloc_memdup(address, ifa->ifa_addr, addrsize); if (address->addr == NULL) { ret = ENOMEM; goto done; } /* steal old dlist to the new head */ talloc_steal(address, addrlist); DLIST_ADD(addrlist, address); } } if (addrlist != NULL) { /* OK, some result was found */ ret = EOK; *_addrlist = addrlist; } else { /* No result was found */ DEBUG(SSSDBG_TRACE_FUNC, "No IPs usable for DNS was found for interface: %s.\n", ifname); ret = ENOENT; } done: freeifaddrs(ifaces); return ret; } static char * nsupdate_msg_add_fwd(char *update_msg, struct sss_iface_addr *addresses, const char *hostname, int ttl, uint8_t remove_af) { struct sss_iface_addr *new_record; char ip_addr[INET6_ADDRSTRLEN]; errno_t ret; /* Remove existing entries as needed */ if (remove_af & DYNDNS_REMOVE_A) { update_msg = talloc_asprintf_append(update_msg, "update delete %s. in A\nsend\n", hostname); if (update_msg == NULL) { return NULL; } } if (remove_af & DYNDNS_REMOVE_AAAA) { update_msg = talloc_asprintf_append(update_msg, "update delete %s. in AAAA\nsend\n", hostname); if (update_msg == NULL) { return NULL; } } DLIST_FOR_EACH(new_record, addresses) { ret = addr_to_str(new_record->addr, ip_addr, INET6_ADDRSTRLEN); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "addr_to_str failed: %d:[%s],\n", ret, sss_strerror(ret)); return NULL; } /* Format the record update */ update_msg = talloc_asprintf_append(update_msg, "update add %s. %d in %s %s\n", hostname, ttl, new_record->addr->ss_family == AF_INET ? "A" : "AAAA", ip_addr); if (update_msg == NULL) { return NULL; } } return talloc_asprintf_append(update_msg, "send\n"); } static uint8_t *nsupdate_convert_address(struct sockaddr_storage *add_address) { uint8_t *addr; switch(add_address->ss_family) { case AF_INET: addr = (uint8_t *) &((struct sockaddr_in *) add_address)->sin_addr; break; case AF_INET6: addr = (uint8_t *) &((struct sockaddr_in6 *) add_address)->sin6_addr; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown address family\n"); addr = NULL; break; } return addr; } static char *nsupdate_msg_add_ptr(char *update_msg, struct sockaddr_storage *address, const char *hostname, int ttl, bool delete) { char *strptr; uint8_t *addr; addr = nsupdate_convert_address(address); if (addr == NULL) { return NULL; } strptr = resolv_get_string_ptr_address(update_msg, address->ss_family, addr); if (strptr == NULL) { return NULL; } if (delete) { /* example: update delete 38.78.16.10.in-addr.arpa. in PTR */ update_msg = talloc_asprintf_append(update_msg, "update delete %s in PTR\n" "send\n", strptr); } else { /* example: update delete 38.78.16.10.in-addr.arpa. in PTR */ update_msg = talloc_asprintf_append(update_msg, "update add %s %d in PTR %s.\n" "send\n", strptr, ttl, hostname); } talloc_free(strptr); if (update_msg == NULL) { return NULL; } return update_msg; } static char * nsupdate_msg_create_common(TALLOC_CTX *mem_ctx, const char *realm, const char *servername) { char *realm_directive; char *update_msg; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return NULL; #ifdef HAVE_NSUPDATE_REALM realm_directive = talloc_asprintf(tmp_ctx, "realm %s\n", realm); #else realm_directive = talloc_asprintf(tmp_ctx, "\n"); #endif if (!realm_directive) { goto fail; } /* The realm_directive would now either contain an empty string or be * completely empty so we don't need to add another newline here */ if (servername) { DEBUG(SSSDBG_FUNC_DATA, "Creating update message for server [%s] and realm [%s].\n", servername, realm); /* Add the server, realm and headers */ update_msg = talloc_asprintf(tmp_ctx, "server %s\n%s", servername, realm_directive); } else { DEBUG(SSSDBG_FUNC_DATA, "Creating update message for realm [%s].\n", realm); /* Add the realm headers */ update_msg = talloc_asprintf(tmp_ctx, "%s", realm_directive); } talloc_free(realm_directive); if (update_msg == NULL) { goto fail; } update_msg = talloc_steal(mem_ctx, update_msg); talloc_free(tmp_ctx); return update_msg; fail: talloc_free(tmp_ctx); return NULL; } errno_t be_nsupdate_create_fwd_msg(TALLOC_CTX *mem_ctx, const char *realm, const char *servername, const char *hostname, const unsigned int ttl, uint8_t remove_af, struct sss_iface_addr *addresses, char **_update_msg) { int ret; char *update_msg; TALLOC_CTX *tmp_ctx; /* in some cases realm could have been NULL if we weren't using TSIG */ if (hostname == NULL) { return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; update_msg = nsupdate_msg_create_common(tmp_ctx, realm, servername); if (update_msg == NULL) { ret = ENOMEM; goto done; } update_msg = nsupdate_msg_add_fwd(update_msg, addresses, hostname, ttl, remove_af); if (update_msg == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, " -- Begin nsupdate message -- \n" "%s" " -- End nsupdate message -- \n", update_msg); ret = ERR_OK; *_update_msg = talloc_steal(mem_ctx, update_msg); done: talloc_free(tmp_ctx); return ret; } errno_t be_nsupdate_create_ptr_msg(TALLOC_CTX *mem_ctx, const char *realm, const char *servername, const char *hostname, const unsigned int ttl, struct sockaddr_storage *address, bool delete, char **_update_msg) { errno_t ret; char *update_msg; /* in some cases realm could have been NULL if we weren't using TSIG */ if (hostname == NULL) { return EINVAL; } update_msg = nsupdate_msg_create_common(mem_ctx, realm, servername); if (update_msg == NULL) { ret = ENOMEM; goto done; } update_msg = nsupdate_msg_add_ptr(update_msg, address, hostname, ttl, delete); if (update_msg == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, " -- Begin nsupdate message -- \n" "%s" " -- End nsupdate message -- \n", update_msg); ret = ERR_OK; *_update_msg = update_msg; done: return ret; } struct nsupdate_get_addrs_state { struct tevent_context *ev; struct be_resolv_ctx *be_res; enum host_database *db; const char *hostname; /* Use sss_addr in this request */ struct sss_iface_addr *addrlist; size_t count; }; static void nsupdate_get_addrs_done(struct tevent_req *subreq); struct tevent_req * nsupdate_get_addrs_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_resolv_ctx *be_res, const char *hostname) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct nsupdate_get_addrs_state *state; req = tevent_req_create(mem_ctx, &state, struct nsupdate_get_addrs_state); if (req == NULL) { return NULL; } state->be_res = be_res; state->ev = ev; state->hostname = talloc_strdup(state, hostname); if (state->hostname == NULL) { ret = ENOMEM; goto done; } state->db = talloc_array(state, enum host_database, 2); if (state->db == NULL) { ret = ENOMEM; goto done; } state->db[0] = DB_DNS; state->db[1] = DB_SENTINEL; subreq = resolv_gethostbyname_send(state, ev, be_res->resolv, hostname, state->be_res->family_order, state->db); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, nsupdate_get_addrs_done, req); ret = ERR_OK; done: if (ret != ERR_OK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void nsupdate_get_addrs_done(struct tevent_req *subreq) { errno_t ret; size_t count; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct nsupdate_get_addrs_state *state = tevent_req_data(req, struct nsupdate_get_addrs_state); struct resolv_hostent *rhostent; struct sss_iface_addr *addr; int i; int resolv_status; enum restrict_family retry_family_order; ret = resolv_gethostbyname_recv(subreq, state, &resolv_status, NULL, &rhostent); talloc_zfree(subreq); /* If the retry did not match, simply quit */ if (ret == ENOENT) { /* If the resolver is set to honor both address families * it automatically retries the other one internally, so ENOENT * means neither matched and we can simply quit. */ ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not resolve address for this machine, error [%d]: %s, " "resolver returned: [%d]: %s\n", ret, sss_strerror(ret), resolv_status, resolv_strerror(resolv_status)); goto done; } /* EOK */ if (rhostent->addr_list) { for (count=0; rhostent->addr_list[count]; count++); } else { /* The address list is NULL. This is probably a bug in * c-ares, but we need to handle it gracefully. */ DEBUG(SSSDBG_MINOR_FAILURE, "Lookup of [%s] returned no addresses. Skipping.\n", rhostent->name); count = 0; } for (i=0; i < count; i++) { addr = talloc(state, struct sss_iface_addr); if (addr == NULL) { ret = ENOMEM; goto done; } addr->addr = resolv_get_sockaddr_address_index(addr, rhostent, 0, i); if (addr->addr == NULL) { ret = ENOMEM; goto done; } if (state->addrlist) { talloc_steal(state->addrlist, addr); } /* steal old dlist to the new head */ talloc_steal(addr, state->addrlist); DLIST_ADD(state->addrlist, addr); } state->count += count; /* If the resolver is set to honor both address families * and the first one matched, retry the second one to * get the complete list. */ if (((state->be_res->family_order == IPV4_FIRST && rhostent->family == AF_INET) || (state->be_res->family_order == IPV6_FIRST && rhostent->family == AF_INET6))) { retry_family_order = (state->be_res->family_order == IPV4_FIRST) ? \ IPV6_ONLY : \ IPV4_ONLY; subreq = resolv_gethostbyname_send(state, state->ev, state->be_res->resolv, state->hostname, retry_family_order, state->db); if (!subreq) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, nsupdate_get_addrs_done, req); return; } /* The second address matched either immediatelly or after a retry. * No need to retry again. */ ret = EOK; done: if (ret == EOK) { /* All done */ tevent_req_done(req); } else if (ret != EAGAIN) { DEBUG(SSSDBG_OP_FAILURE, "nsupdate_get_addrs_done failed: [%d]: [%s]\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); } /* EAGAIN - another lookup in progress */ } errno_t nsupdate_get_addrs_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sss_iface_addr **_addrlist, size_t *_count) { struct nsupdate_get_addrs_state *state = tevent_req_data(req, struct nsupdate_get_addrs_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_addrlist) { *_addrlist = talloc_steal(mem_ctx, state->addrlist); } if (_count) { *_count = state->count; } return EOK; } /* Write the nsupdate_msg into the already forked child, wait until * the child finishes * * This is not a typical tevent_req styled request as it ends either after * a timeout or when the child finishes operation. */ struct nsupdate_child_state { int pipefd_to_child; struct tevent_timer *timeout_handler; struct sss_child_ctx_old *child_ctx; int child_status; }; static void nsupdate_child_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt); static void nsupdate_child_handler(int child_status, struct tevent_signal *sige, void *pvt); static void nsupdate_child_stdin_done(struct tevent_req *subreq); static struct tevent_req * nsupdate_child_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int pipefd_to_child, pid_t child_pid, char *child_stdin) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct nsupdate_child_state *state; struct timeval tv; req = tevent_req_create(mem_ctx, &state, struct nsupdate_child_state); if (req == NULL) { return NULL; } state->pipefd_to_child = pipefd_to_child; /* Set up SIGCHLD handler */ ret = child_handler_setup(ev, child_pid, nsupdate_child_handler, req, &state->child_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set up child handlers [%d]: %s\n", ret, sss_strerror(ret)); ret = ERR_DYNDNS_FAILED; goto done; } /* Set up timeout handler */ tv = tevent_timeval_current_ofs(DYNDNS_TIMEOUT, 0); state->timeout_handler = tevent_add_timer(ev, req, tv, nsupdate_child_timeout, req); if(state->timeout_handler == NULL) { ret = ERR_DYNDNS_FAILED; goto done; } /* Write the update message to the nsupdate child */ subreq = write_pipe_send(req, ev, (uint8_t *) child_stdin, strlen(child_stdin)+1, state->pipefd_to_child); if (subreq == NULL) { ret = ERR_DYNDNS_FAILED; goto done; } tevent_req_set_callback(subreq, nsupdate_child_stdin_done, req); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void nsupdate_child_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct nsupdate_child_state *state = tevent_req_data(req, struct nsupdate_child_state); DEBUG(SSSDBG_CRIT_FAILURE, "Timeout reached for dynamic DNS update\n"); child_handler_destroy(state->child_ctx); state->child_ctx = NULL; state->child_status = ETIMEDOUT; tevent_req_error(req, ERR_DYNDNS_TIMEOUT); } static void nsupdate_child_stdin_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct nsupdate_child_state *state = tevent_req_data(req, struct nsupdate_child_state); /* Verify that the buffer was sent, then return * and wait for the sigchld handler to finish. */ DEBUG(SSSDBG_TRACE_LIBS, "Sending nsupdate data complete\n"); ret = write_pipe_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Sending nsupdate data failed [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ERR_DYNDNS_FAILED); return; } close(state->pipefd_to_child); state->pipefd_to_child = -1; /* Now either wait for the timeout to fire or the child * to finish */ } static void nsupdate_child_handler(int child_status, struct tevent_signal *sige, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct nsupdate_child_state *state = tevent_req_data(req, struct nsupdate_child_state); state->child_status = child_status; if (WIFEXITED(child_status) && WEXITSTATUS(child_status) != 0) { DEBUG(SSSDBG_OP_FAILURE, "Dynamic DNS child failed with status [%d]\n", child_status); tevent_req_error(req, ERR_DYNDNS_FAILED); return; } if (WIFSIGNALED(child_status)) { DEBUG(SSSDBG_OP_FAILURE, "Dynamic DNS child was terminated by signal [%d]\n", WTERMSIG(child_status)); tevent_req_error(req, ERR_DYNDNS_FAILED); return; } tevent_req_done(req); } static errno_t nsupdate_child_recv(struct tevent_req *req, int *child_status) { struct nsupdate_child_state *state = tevent_req_data(req, struct nsupdate_child_state); *child_status = state->child_status; TEVENT_REQ_RETURN_ON_ERROR(req); return ERR_OK; } /* Fork a nsupdate child, write the nsupdate_msg into stdin and wait for the child * to finish one way or another */ struct be_nsupdate_state { int child_status; }; static void be_nsupdate_done(struct tevent_req *subreq); static char **be_nsupdate_args(TALLOC_CTX *mem_ctx, enum be_nsupdate_auth auth_type, bool force_tcp); struct tevent_req *be_nsupdate_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, enum be_nsupdate_auth auth_type, char *nsupdate_msg, bool force_tcp) { int pipefd_to_child[2]; pid_t child_pid; errno_t ret; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct be_nsupdate_state *state; char **args; int debug_fd; req = tevent_req_create(mem_ctx, &state, struct be_nsupdate_state); if (req == NULL) { return NULL; } state->child_status = 0; ret = pipe(pipefd_to_child); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", ret, strerror(ret)); goto done; } child_pid = fork(); if (child_pid == 0) { /* child */ close(pipefd_to_child[1]); ret = dup2(pipefd_to_child[0], STDIN_FILENO); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "dup2 failed [%d][%s].\n", ret, strerror(ret)); goto done; } if (debug_level >= SSSDBG_TRACE_LIBS) { debug_fd = get_fd_from_debug_file(); ret = dup2(debug_fd, STDERR_FILENO); if (ret == -1) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "dup2 failed [%d][%s].\n", ret, strerror(ret)); /* stderr is not fatal */ } } args = be_nsupdate_args(state, auth_type, force_tcp); if (args == NULL) { ret = ENOMEM; goto done; } errno = 0; execv(NSUPDATE_PATH, args); /* The child should never end up here */ ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "execv failed [%d][%s].\n", ret, strerror(ret)); goto done; } else if (child_pid > 0) { /* parent */ close(pipefd_to_child[0]); subreq = nsupdate_child_send(state, ev, pipefd_to_child[1], child_pid, nsupdate_msg); if (subreq == NULL) { ret = ERR_DYNDNS_FAILED; goto done; } tevent_req_set_callback(subreq, be_nsupdate_done, req); } else { /* error */ ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static char ** be_nsupdate_args(TALLOC_CTX *mem_ctx, enum be_nsupdate_auth auth_type, bool force_tcp) { char **argv; int argc = 0; argv = talloc_zero_array(mem_ctx, char *, 6); if (argv == NULL) { return NULL; } argv[argc] = talloc_strdup(argv, NSUPDATE_PATH); if (argv[argc] == NULL) { goto fail; } argc++; switch (auth_type) { case BE_NSUPDATE_AUTH_NONE: DEBUG(SSSDBG_FUNC_DATA, "nsupdate auth type: none\n"); break; case BE_NSUPDATE_AUTH_GSS_TSIG: DEBUG(SSSDBG_FUNC_DATA, "nsupdate auth type: GSS-TSIG\n"); argv[argc] = talloc_strdup(argv, "-g"); if (argv[argc] == NULL) { goto fail; } argc++; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown nsupdate auth type\n"); goto fail; } if (force_tcp) { DEBUG(SSSDBG_FUNC_DATA, "TCP is set to on\n"); argv[argc] = talloc_strdup(argv, "-v"); if (argv[argc] == NULL) { goto fail; } argc++; } if (debug_level >= SSSDBG_TRACE_LIBS) { argv[argc] = talloc_strdup(argv, "-d"); if (argv[argc] == NULL) { goto fail; } argc++; } if (debug_level >= SSSDBG_TRACE_INTERNAL) { argv[argc] = talloc_strdup(argv, "-D"); if (argv[argc] == NULL) { goto fail; } argc++; } return argv; fail: talloc_free(argv); return NULL; } static void be_nsupdate_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct be_nsupdate_state *state = tevent_req_data(req, struct be_nsupdate_state); errno_t ret; ret = nsupdate_child_recv(subreq, &state->child_status); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "nsupdate child execution failed [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } DEBUG(SSSDBG_FUNC_DATA, "nsupdate child status: %d\n", state->child_status); tevent_req_done(req); } errno_t be_nsupdate_recv(struct tevent_req *req, int *child_status) { struct be_nsupdate_state *state = tevent_req_data(req, struct be_nsupdate_state); *child_status = state->child_status; TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void be_nsupdate_timer(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { struct be_nsupdate_ctx *ctx = talloc_get_type(pvt, struct be_nsupdate_ctx); talloc_zfree(ctx->refresh_timer); ctx->timer_callback(ctx->timer_pvt); /* timer_callback is responsible for calling be_nsupdate_timer_schedule * again */ } void be_nsupdate_timer_schedule(struct tevent_context *ev, struct be_nsupdate_ctx *ctx) { int refresh; struct timeval tv; if (ctx->refresh_timer) { DEBUG(SSSDBG_FUNC_DATA, "Timer already scheduled\n"); return; } refresh = dp_opt_get_int(ctx->opts, DP_OPT_DYNDNS_REFRESH_INTERVAL); if (refresh == 0) return; DEBUG(SSSDBG_FUNC_DATA, "Scheduling timer in %d seconds\n", refresh); tv = tevent_timeval_current_ofs(refresh, 0); ctx->refresh_timer = tevent_add_timer(ev, ctx, tv, be_nsupdate_timer, ctx); if (!ctx->refresh_timer) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add dyndns refresh timer event\n"); } } errno_t be_nsupdate_check(void) { errno_t ret; struct stat stat_buf; /* Ensure that nsupdate exists */ errno = 0; ret = stat(NSUPDATE_PATH, &stat_buf); if (ret == -1) { ret = errno; if (ret == ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "%s does not exist. Dynamic DNS updates disabled\n", NSUPDATE_PATH); } else { DEBUG(SSSDBG_OP_FAILURE, "Could not set up dynamic DNS updates: [%d][%s]\n", ret, strerror(ret)); } } return ret; } static struct dp_option default_dyndns_opts[] = { { "dyndns_update", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "dyndns_refresh_interval", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER }, { "dyndns_iface", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "dyndns_ttl", DP_OPT_NUMBER, { .number = 1200 }, NULL_NUMBER }, { "dyndns_update_ptr", DP_OPT_BOOL, BOOL_TRUE, BOOL_FALSE }, { "dyndns_force_tcp", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "dyndns_auth", DP_OPT_STRING, { "gss-tsig" }, NULL_STRING }, { "dyndns_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, DP_OPTION_TERMINATOR }; errno_t be_nsupdate_init(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct dp_option *defopts, struct be_nsupdate_ctx **_ctx) { errno_t ret; struct dp_option *src_opts; struct be_nsupdate_ctx *ctx; char *strauth; ctx = talloc_zero(mem_ctx, struct be_nsupdate_ctx); if (ctx == NULL) return ENOMEM; src_opts = defopts ? defopts : default_dyndns_opts; ret = dp_get_options(ctx, be_ctx->cdb, be_ctx->conf_path, src_opts, DP_OPT_DYNDNS, &ctx->opts); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot retrieve dynamic DNS options\n"); return ret; } strauth = dp_opt_get_string(ctx->opts, DP_OPT_DYNDNS_AUTH); if (strcasecmp(strauth, "gss-tsig") == 0) { ctx->auth_type = BE_NSUPDATE_AUTH_GSS_TSIG; } else if (strcasecmp(strauth, "none") == 0) { ctx->auth_type = BE_NSUPDATE_AUTH_NONE; } else { DEBUG(SSSDBG_OP_FAILURE, "Uknown dyndns auth type %s\n", strauth); return EINVAL; } *_ctx = ctx; return ERR_OK; } errno_t be_nsupdate_init_timer(struct be_nsupdate_ctx *ctx, struct tevent_context *ev, nsupdate_timer_fn_t timer_callback, void *timer_pvt) { if (ctx == NULL) return EINVAL; ctx->timer_callback = timer_callback; ctx->timer_pvt = timer_pvt; be_nsupdate_timer_schedule(ev, ctx); return ERR_OK; } static bool match_ip(const struct sockaddr *sa, const struct sockaddr *sb) { size_t addrsize; bool res; const void *addr_a; const void *addr_b; if (sa->sa_family == AF_INET) { addrsize = sizeof(struct in_addr); addr_a = (const void *) &((const struct sockaddr_in *) sa)->sin_addr; addr_b = (const void *) &((const struct sockaddr_in *) sb)->sin_addr; } else if (sa->sa_family == AF_INET6) { addrsize = sizeof(struct in6_addr); addr_a = (const void *) &((const struct sockaddr_in6 *) sa)->sin6_addr; addr_b = (const void *) &((const struct sockaddr_in6 *) sb)->sin6_addr; } else { res = false; goto done; } if (sa->sa_family != sb->sa_family) { res = false; goto done; } res = memcmp(addr_a, addr_b, addrsize) == 0; done: return res; } static errno_t find_iface_by_addr(TALLOC_CTX *mem_ctx, const struct sockaddr *ss, const char **_iface_name) { struct ifaddrs *ifaces = NULL; struct ifaddrs *ifa; errno_t ret; ret = getifaddrs(&ifaces); if (ret == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "Could not read interfaces [%d][%s]\n", ret, sss_strerror(ret)); goto done; } for (ifa = ifaces; ifa != NULL; ifa = ifa->ifa_next) { /* Some interfaces don't have an ifa_addr */ if (!ifa->ifa_addr) continue; if (match_ip(ss, ifa->ifa_addr)) { const char *iface_name; iface_name = talloc_strdup(mem_ctx, ifa->ifa_name); if (iface_name == NULL) { ret = ENOMEM; } else { *_iface_name = iface_name; ret = EOK; } goto done; } } ret = ENOENT; done: freeifaddrs(ifaces); return ret; } errno_t sss_get_dualstack_addresses(TALLOC_CTX *mem_ctx, struct sockaddr *ss, struct sss_iface_addr **_iface_addrs) { struct sss_iface_addr *iface_addrs; const char *iface_name = NULL; TALLOC_CTX *tmp_ctx; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ret = find_iface_by_addr(tmp_ctx, ss, &iface_name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "find_iface_by_addr failed: %d:[%s]\n", ret, sss_strerror(ret)); goto done; } ret = sss_iface_addr_list_get(tmp_ctx, iface_name, &iface_addrs); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_iface_addr_list_get failed: %d:[%s]\n", ret, sss_strerror(ret)); goto done; } ret = EOK; *_iface_addrs = talloc_steal(mem_ctx, iface_addrs); done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/providers/PaxHeaders.16287/ad0000644000000000000000000000013212703463556015446 xustar0030 mtime=1460561774.922794537 30 atime=1460561776.118798593 30 ctime=1460561774.922794537 sssd-1.13.4/src/providers/ad/0000755002412700241270000000000012703463556017177 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_common.h0000644000000000000000000000007412703456111017622 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.686793737 sssd-1.13.4/src/providers/ad/ad_common.h0000644002412700241270000001316512703456111021277 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef AD_COMMON_H_ #define AD_COMMON_H_ #include "util/util.h" #include "providers/ldap/ldap_common.h" #define AD_SERVICE_NAME "AD" #define AD_GC_SERVICE_NAME "AD_GC" /* The port the Global Catalog runs on */ #define AD_GC_PORT 3268 #define AD_AT_OBJECT_SID "objectSID" #define AD_AT_DNS_DOMAIN "DnsDomain" #define AD_AT_NT_VERSION "NtVer" #define AD_AT_NETLOGON "netlogon" #define MASTER_DOMAIN_SID_FILTER "objectclass=domain" struct ad_options; enum ad_basic_opt { AD_DOMAIN = 0, AD_SERVER, AD_BACKUP_SERVER, AD_HOSTNAME, AD_KEYTAB, AD_KRB5_REALM, AD_ENABLE_DNS_SITES, AD_ACCESS_FILTER, AD_ENABLE_GC, AD_GPO_ACCESS_CONTROL, AD_GPO_CACHE_TIMEOUT, AD_GPO_MAP_INTERACTIVE, AD_GPO_MAP_REMOTE_INTERACTIVE, AD_GPO_MAP_NETWORK, AD_GPO_MAP_BATCH, AD_GPO_MAP_SERVICE, AD_GPO_MAP_PERMIT, AD_GPO_MAP_DENY, AD_GPO_DEFAULT_RIGHT, AD_SITE, AD_KRB5_CONFD_PATH, AD_MAXIMUM_MACHINE_ACCOUNT_PASSWORD_AGE, AD_MACHINE_ACCOUNT_PASSWORD_RENEWAL_OPTS, AD_OPTS_BASIC /* opts counter */ }; struct ad_id_ctx { struct sdap_id_ctx *sdap_id_ctx; struct sdap_id_conn_ctx *ldap_ctx; struct sdap_id_conn_ctx *gc_ctx; struct ad_options *ad_options; }; struct ad_service { struct sdap_service *sdap; struct sdap_service *gc; struct krb5_service *krb5_service; }; struct ad_options { /* Common options */ struct dp_option *basic; struct ad_service *service; /* ID Provider */ struct sdap_options *id; struct ad_id_ctx *id_ctx; /* Auth and chpass Provider */ struct krb5_ctx *auth_ctx; /* Dynamic DNS updates */ struct be_resolv_ctx *be_res; struct be_nsupdate_ctx *dyndns_ctx; }; errno_t ad_get_common_options(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, const char *conf_path, struct sss_domain_info *dom, struct ad_options **_opts); struct ad_options *ad_create_default_options(TALLOC_CTX *mem_ctx); struct ad_options *ad_create_2way_trust_options(TALLOC_CTX *mem_ctx, const char *realm, const char *ad_domain, const char *hostname); struct ad_options *ad_create_1way_trust_options(TALLOC_CTX *mem_ctx, const char *ad_domain, const char *hostname, const char *keytab, const char *sasl_authid); errno_t ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, const char *primary_servers, const char *backup_servers, const char *krb5_realm, const char *ad_service, const char *ad_gc_service, const char *ad_domain, struct ad_service **_service); errno_t ad_get_id_options(struct ad_options *ad_opts, struct confdb_ctx *cdb, const char *conf_path, struct sdap_options **_opts); errno_t ad_get_autofs_options(struct ad_options *ad_opts, struct confdb_ctx *cdb, const char *conf_path); errno_t ad_get_auth_options(TALLOC_CTX *mem_ctx, struct ad_options *ad_opts, struct be_ctx *bectx, struct dp_option **_opts); errno_t ad_get_dyndns_options(struct be_ctx *be_ctx, struct ad_options *ad_opts); struct ad_id_ctx * ad_id_ctx_init(struct ad_options *ad_opts, struct be_ctx *bectx); struct sdap_id_conn_ctx ** ad_gc_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom); struct sdap_id_conn_ctx ** ad_ldap_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom); struct sdap_id_conn_ctx ** ad_user_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom); struct sdap_id_conn_ctx * ad_get_dom_ldap_conn(struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom); /* AD dynamic DNS updates */ errno_t ad_dyndns_init(struct be_ctx *be_ctx, struct ad_options *ctx); void ad_dyndns_timer(void *pvt); int ad_sudo_init(struct be_ctx *be_ctx, struct ad_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data); int ad_autofs_init(struct be_ctx *be_ctx, struct ad_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data); errno_t ad_machine_account_password_renewal_init(struct be_ctx *be_ctx, struct ad_options *ad_opts); #endif /* AD_COMMON_H_ */ sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_subdomains.c0000644000000000000000000000007412703456111020471 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.697793774 sssd-1.13.4/src/providers/ad/ad_subdomains.c0000644002412700241270000011224112703456111022141 0ustar00jhrozekjhrozek00000000000000/* SSSD AD Subdomains Module Authors: Sumit Bose Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ldap/sdap_async.h" #include "providers/ad/ad_subdomains.h" #include "providers/ad/ad_domain_info.h" #include "providers/ad/ad_srv.h" #include "providers/ad/ad_common.h" #include "providers/ldap/sdap_idmap.h" #include "util/util_sss_idmap.h" #include #include #include /* Attributes of AD trusted domains */ #define AD_AT_FLATNAME "flatName" #define AD_AT_SID "securityIdentifier" #define AD_AT_TRUST_TYPE "trustType" #define AD_AT_TRUST_PARTNER "trustPartner" #define AD_AT_TRUST_ATTRS "trustAttributes" /* trustType=2 denotes uplevel (NT5 and later) trusted domains. See * http://msdn.microsoft.com/en-us/library/windows/desktop/ms680342%28v=vs.85%29.aspx * for example. * * The absence of msDS-TrustForestTrustInfo attribute denotes a domain from * the same forest. See http://msdn.microsoft.com/en-us/library/cc223786.aspx * for more information. */ #define SLAVE_DOMAIN_FILTER_BASE "(objectclass=trustedDomain)(trustType=2)(!(msDS-TrustForestTrustInfo=*))" #define SLAVE_DOMAIN_FILTER "(&"SLAVE_DOMAIN_FILTER_BASE")" #define FOREST_ROOT_FILTER_FMT "(&"SLAVE_DOMAIN_FILTER_BASE"(cn=%s))" /* do not refresh more often than every 5 seconds for now */ #define AD_SUBDOMAIN_REFRESH_LIMIT 5 struct ad_subdomains_ctx { struct be_ctx *be_ctx; struct sdap_id_ctx *sdap_id_ctx; struct sdap_domain *sdom; struct sdap_id_conn_ctx *ldap_ctx; struct sss_idmap_ctx *idmap_ctx; char *domain_name; time_t last_refreshed; struct tevent_timer *timer_event; struct ad_id_ctx *ad_id_ctx; }; struct ad_subdomains_req_ctx { struct be_req *be_req; struct ad_subdomains_ctx *sd_ctx; struct sdap_id_op *sdap_op; char *current_filter; size_t base_iter; struct ad_id_ctx *root_id_ctx; struct sdap_id_op *root_op; size_t root_base_iter; struct sysdb_attrs *root_domain_attrs; struct sss_domain_info *root_domain; size_t reply_count; struct sysdb_attrs **reply; char *master_sid; char *flat_name; char *site; char *forest; }; static errno_t ad_subdom_ad_ctx_new(struct be_ctx *be_ctx, struct ad_id_ctx *id_ctx, struct sss_domain_info *subdom, struct ad_id_ctx **_subdom_id_ctx) { struct ad_options *ad_options; struct ad_id_ctx *ad_id_ctx; const char *gc_service_name; struct ad_srv_plugin_ctx *srv_ctx; char *ad_domain; char *ad_site_override; struct sdap_domain *sdom; errno_t ret; const char *realm; const char *hostname; realm = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_KRB5_REALM); hostname = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_HOSTNAME); ad_domain = subdom->name; if (realm == NULL || hostname == NULL || ad_domain == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm or hostname.\n"); return EINVAL; } ad_options = ad_create_2way_trust_options(id_ctx, realm, ad_domain, hostname); if (ad_options == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n"); talloc_free(ad_options); return ENOMEM; } ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE); gc_service_name = talloc_asprintf(ad_options, "%s%s", "gc_", subdom->name); if (gc_service_name == NULL) { talloc_free(ad_options); return ENOMEM; } ret = ad_failover_init(ad_options, be_ctx, NULL, NULL, realm, subdom->name, gc_service_name, subdom->name, &ad_options->service); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD failover\n"); talloc_free(ad_options); return ret; } ad_id_ctx = ad_id_ctx_init(ad_options, be_ctx); if (ad_id_ctx == NULL) { talloc_free(ad_options); return ENOMEM; } ad_id_ctx->sdap_id_ctx->opts = ad_options->id; ad_options->id_ctx = ad_id_ctx; /* use AD plugin */ srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res, default_host_dbs, ad_id_ctx->ad_options->id, hostname, ad_domain, ad_site_override); if (srv_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n"); return ENOMEM; } be_fo_set_srv_lookup_plugin(be_ctx, ad_srv_plugin_send, ad_srv_plugin_recv, srv_ctx, "AD"); ret = sdap_domain_subdom_add(ad_id_ctx->sdap_id_ctx, ad_id_ctx->sdap_id_ctx->opts->sdom, subdom->parent); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize sdap domain\n"); talloc_free(ad_options); return ret; } sdom = sdap_domain_get(ad_id_ctx->sdap_id_ctx->opts, subdom); if (sdom == NULL) { return EFAULT; } sdap_inherit_options(subdom->parent->sd_inherit, id_ctx->sdap_id_ctx->opts, ad_id_ctx->sdap_id_ctx->opts); /* Set up the ID mapping object */ ad_id_ctx->sdap_id_ctx->opts->idmap_ctx = id_ctx->sdap_id_ctx->opts->idmap_ctx; *_subdom_id_ctx = ad_id_ctx; return EOK; } static errno_t ads_store_sdap_subdom(struct ad_subdomains_ctx *ctx, struct sss_domain_info *parent) { int ret; struct sdap_domain *sditer; struct ad_id_ctx *subdom_id_ctx; ret = sdap_domain_subdom_add(ctx->sdap_id_ctx, ctx->sdom, parent); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_domain_subdom_add failed.\n"); return ret; } DLIST_FOR_EACH(sditer, ctx->sdom) { if (IS_SUBDOMAIN(sditer->dom) && sditer->pvt == NULL) { ret = ad_subdom_ad_ctx_new(ctx->be_ctx, ctx->ad_id_ctx, sditer->dom, &subdom_id_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ad_subdom_ad_ctx_new failed.\n"); } else { sditer->pvt = subdom_id_ctx; } } } return EOK; } static errno_t ad_subdom_enumerates(struct sss_domain_info *parent, struct sysdb_attrs *attrs, bool *_enumerates) { errno_t ret; const char *name; ret = sysdb_attrs_get_string(attrs, AD_AT_TRUST_PARTNER, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); return ret; } *_enumerates = subdomain_enumerates(parent, name); return EOK; } static errno_t ad_subdom_store(struct ad_subdomains_ctx *ctx, struct sss_domain_info *domain, struct sysdb_attrs *subdom_attrs, bool enumerate) { TALLOC_CTX *tmp_ctx; const char *name; char *realm; const char *flat; errno_t ret; enum idmap_error_code err; struct ldb_message_element *el; char *sid_str = NULL; uint32_t trust_type; bool mpg; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ret = sysdb_attrs_get_uint32_t(subdom_attrs, AD_AT_TRUST_TYPE, &trust_type); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_uint32_t failed.\n"); goto done; } ret = sysdb_attrs_get_string(subdom_attrs, AD_AT_TRUST_PARTNER, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "failed to get subdomain name\n"); goto done; } realm = get_uppercase_realm(tmp_ctx, name); if (!realm) { ret = ENOMEM; goto done; } ret = sysdb_attrs_get_string(subdom_attrs, AD_AT_FLATNAME, &flat); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "failed to get flat name of subdomain %s\n", name); goto done; } ret = sysdb_attrs_get_el(subdom_attrs, AD_AT_SID, &el); if (ret != EOK || el->num_values != 1) { DEBUG(SSSDBG_OP_FAILURE, "sdap_attrs_get_el failed.\n"); goto done; } err = sss_idmap_bin_sid_to_sid(ctx->idmap_ctx, el->values[0].data, el->values[0].length, &sid_str); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not convert SID: [%s].\n", idmap_error_string(err)); ret = EFAULT; goto done; } mpg = sdap_idmap_domain_has_algorithmic_mapping( ctx->sdap_id_ctx->opts->idmap_ctx, name, sid_str); ret = sysdb_subdomain_store(domain->sysdb, name, realm, flat, sid_str, mpg, enumerate, domain->forest, 0); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_subdomain_store failed.\n"); goto done; } ret = EOK; done: sss_idmap_free_sid(ctx->sdap_id_ctx->opts->idmap_ctx->map, sid_str); talloc_free(tmp_ctx); return ret; } static errno_t ad_subdomains_refresh(struct ad_subdomains_ctx *ctx, int count, bool root_domain, struct sysdb_attrs **reply, bool *changes) { struct sdap_domain *sdom; struct sss_domain_info *domain, *dom; bool handled[count]; const char *value; const char *root_name = NULL; int c, h; int ret; bool enumerate; domain = ctx->be_ctx->domain; memset(handled, 0, sizeof(bool) * count); h = 0; if (root_domain) { ret = sysdb_attrs_get_string(reply[0], AD_AT_TRUST_PARTNER, &root_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } } /* check existing subdomains */ for (dom = get_next_domain(domain, SSS_GND_DESCEND); dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */ dom = get_next_domain(dom, 0)) { /* If we are handling root domain, skip all the other domains. We don't * want to accidentally remove non-root domains */ if (root_name && strcmp(root_name, dom->name) != 0) { continue; } for (c = 0; c < count; c++) { if (handled[c]) { continue; } ret = sysdb_attrs_get_string(reply[c], AD_AT_TRUST_PARTNER, &value); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } if (strcmp(value, dom->name) == 0) { break; } } if (c >= count) { /* ok this subdomain does not exist anymore, let's clean up */ sss_domain_set_state(dom, DOM_DISABLED); ret = sysdb_subdomain_delete(dom->sysdb, dom->name); if (ret != EOK) { goto done; } sdom = sdap_domain_get(ctx->sdap_id_ctx->opts, dom); if (sdom == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Domain does not exist?\n"); continue; } /* Remove the subdomain from the list of LDAP domains */ sdap_domain_remove(ctx->sdap_id_ctx->opts, dom); be_ptask_destroy(&sdom->enum_task); be_ptask_destroy(&sdom->cleanup_task); /* terminate all requests for this subdomain so we can free it */ be_terminate_domain_requests(ctx->be_ctx, dom->name); talloc_zfree(sdom); } else { /* ok let's try to update it */ ret = ad_subdom_enumerates(domain, reply[c], &enumerate); if (ret != EOK) { goto done; } ret = ad_subdom_store(ctx, domain, reply[c], enumerate); if (ret) { /* Nothing we can do about the error. Let's at least try * to reuse the existing domains */ DEBUG(SSSDBG_MINOR_FAILURE, "Failed to parse subdom data, " "will try to use cached subdomain\n"); } handled[c] = true; h++; } } if (count == h) { /* all domains were already accounted for and have been updated */ ret = EOK; *changes = false; goto done; } /* if we get here it means we have changes to the subdomains list */ *changes = true; for (c = 0; c < count; c++) { if (handled[c]) { continue; } /* Nothing we can do about the error. Let's at least try * to reuse the existing domains. */ ret = ad_subdom_enumerates(domain, reply[c], &enumerate); if (ret != EOK) { goto done; } ret = ad_subdom_store(ctx, domain, reply[c], enumerate); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to parse subdom data, " "will try to use cached subdomain\n"); } } ret = EOK; done: if (ret != EOK) { ctx->last_refreshed = 0; } else { ctx->last_refreshed = time(NULL); } return ret; } static errno_t ad_subdom_reinit(struct ad_subdomains_ctx *ctx) { errno_t ret; ret = sss_write_krb5_conf_snippet( dp_opt_get_string(ctx->ad_id_ctx->ad_options->basic, AD_KRB5_CONFD_PATH)); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_write_krb5_conf_snippet failed.\n"); /* Just continue */ } ret = sysdb_update_subdomains(ctx->be_ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_subdomains failed.\n"); return ret; } ret = sss_write_domain_mappings(ctx->be_ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_krb5_write_mappings failed.\n"); /* Just continue */ } ret = ads_store_sdap_subdom(ctx, ctx->be_ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ads_store_sdap_subdom failed.\n"); return ret; } return EOK; } static void ad_subdomains_get_conn_done(struct tevent_req *req); static void ad_subdomains_master_dom_done(struct tevent_req *req); static errno_t ad_subdomains_get_root(struct ad_subdomains_req_ctx *ctx); static errno_t ad_subdomains_get_slave(struct ad_subdomains_req_ctx *ctx); static void ad_subdomains_retrieve(struct ad_subdomains_ctx *ctx, struct be_req *be_req) { struct ad_subdomains_req_ctx *req_ctx = NULL; struct tevent_req *req; int dp_error = DP_ERR_FATAL; int ret; req_ctx = talloc_zero(be_req, struct ad_subdomains_req_ctx); if (req_ctx == NULL) { ret = ENOMEM; goto done; } req_ctx->be_req = be_req; req_ctx->sd_ctx = ctx; req_ctx->current_filter = NULL; req_ctx->base_iter = 0; req_ctx->root_base_iter = 0; req_ctx->root_id_ctx = NULL; req_ctx->root_op = NULL; req_ctx->root_domain = NULL; req_ctx->root_domain_attrs = NULL; req_ctx->reply_count = 0; req_ctx->reply = NULL; req_ctx->sdap_op = sdap_id_op_create(req_ctx, ctx->ldap_ctx->conn_cache); if (req_ctx->sdap_op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n"); ret = ENOMEM; goto done; } req = sdap_id_op_connect_send(req_ctx->sdap_op, req_ctx, &ret); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n", ret, strerror(ret)); goto done; } tevent_req_set_callback(req, ad_subdomains_get_conn_done, req_ctx); return; done: talloc_free(req_ctx); if (ret == EOK) { dp_error = DP_ERR_OK; } be_req_terminate(be_req, dp_error, ret, NULL); } static void ad_subdomains_get_conn_done(struct tevent_req *req) { int ret; int dp_error = DP_ERR_FATAL; struct ad_subdomains_req_ctx *ctx; ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx); ret = sdap_id_op_connect_recv(req, &dp_error); talloc_zfree(req); if (ret) { if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_MINOR_FAILURE, "No AD server is available, cannot get the " "subdomain list while offline\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to AD server: [%d](%s)\n", ret, strerror(ret)); } goto fail; } req = ad_master_domain_send(ctx, ctx->sd_ctx->be_ctx->ev, ctx->sd_ctx->ldap_ctx, ctx->sdap_op, ctx->sd_ctx->domain_name); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ad_master_domain_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(req, ad_subdomains_master_dom_done, ctx); return; fail: be_req_terminate(ctx->be_req, dp_error, ret, NULL); } static void ad_subdomains_master_dom_done(struct tevent_req *req) { struct ad_subdomains_req_ctx *ctx; errno_t ret; const char *realm; ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx); ret = ad_master_domain_recv(req, ctx, &ctx->flat_name, &ctx->master_sid, &ctx->site, &ctx->forest); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot retrieve master domain info\n"); goto done; } realm = dp_opt_get_cstring(ctx->sd_ctx->ad_id_ctx->ad_options->basic, AD_KRB5_REALM); if (realm == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm.\n"); ret = EINVAL; goto done; } ret = sysdb_master_domain_add_info(ctx->sd_ctx->be_ctx->domain, realm, ctx->flat_name, ctx->master_sid, ctx->forest); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot save master domain info\n"); goto done; } if (ctx->forest == NULL || strcasecmp(ctx->sd_ctx->be_ctx->domain->name, ctx->forest) != 0) { DEBUG(SSSDBG_TRACE_FUNC, "SSSD needs to look up the forest root domain\n"); ret = ad_subdomains_get_root(ctx); } else { DEBUG(SSSDBG_TRACE_FUNC, "Connected to forest root, looking up child domains..\n"); ctx->root_op = ctx->sdap_op; ctx->root_id_ctx = ctx->sd_ctx->ad_id_ctx; ret = ad_subdomains_get_slave(ctx); } if (ret == EAGAIN) { return; } else if (ret != EOK) { goto done; } done: be_req_terminate(ctx->be_req, DP_ERR_FATAL, ret, NULL); } static void ad_subdomains_get_root_domain_done(struct tevent_req *req); static errno_t ad_subdomains_get_root(struct ad_subdomains_req_ctx *ctx) { struct tevent_req *req; struct sdap_search_base *base; struct sdap_id_ctx *sdap_id_ctx; char *filter; const char *forest_root_attrs[] = { AD_AT_FLATNAME, AD_AT_TRUST_PARTNER, AD_AT_SID, AD_AT_TRUST_TYPE, AD_AT_TRUST_ATTRS, NULL }; sdap_id_ctx = ctx->sd_ctx->sdap_id_ctx; base = sdap_id_ctx->opts->sdom->search_bases[ctx->root_base_iter]; if (base == NULL) { return EOK; } filter = talloc_asprintf(ctx, FOREST_ROOT_FILTER_FMT, ctx->forest); if (filter == NULL) { return ENOMEM; } req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev, sdap_id_ctx->opts, sdap_id_op_handle(ctx->sdap_op), base->basedn, LDAP_SCOPE_SUBTREE, filter, forest_root_attrs, NULL, 0, dp_opt_get_int(sdap_id_ctx->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); return ENOMEM; } tevent_req_set_callback(req, ad_subdomains_get_root_domain_done, ctx); return EAGAIN; } static struct sss_domain_info *ads_get_root_domain(struct ad_subdomains_req_ctx *ctx); static struct ad_id_ctx *ads_get_root_id_ctx(struct ad_subdomains_req_ctx *ctx); static void ad_subdomains_root_conn_done(struct tevent_req *req); static void ad_subdomains_get_root_domain_done(struct tevent_req *req) { int ret; size_t reply_count; struct sysdb_attrs **reply = NULL; struct ad_subdomains_req_ctx *ctx; int dp_error = DP_ERR_FATAL; bool has_changes = false; ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx); ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send request failed.\n"); goto fail; } if (reply_count == 0) { /* If no root domain was found in the default search base, try the * next one, if available */ ctx->root_base_iter++; ret = ad_subdomains_get_root(ctx); if (ret == EAGAIN) { return; } goto fail; } else if (reply_count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Multiple results for root domain search, " "domain list might be incomplete!\n"); ctx->root_op = ctx->sdap_op; ctx->root_id_ctx = ctx->sd_ctx->ad_id_ctx; ret = ad_subdomains_get_slave(ctx); if (ret == EAGAIN) { return; } goto fail; } /* Exactly one result, good. */ /* We won't use the operation to the local LDAP anymore, but * read from the forest root */ ret = sdap_id_op_done(ctx->sdap_op, ret, &dp_error); if (ret != EOK) { if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_MINOR_FAILURE, "No AD server is available, cannot get the " "subdomain list while offline\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "Failed to search the AD server: [%d](%s)\n", ret, strerror(ret)); } goto fail; } ret = ad_subdomains_refresh(ctx->sd_ctx, 1, true, reply, &has_changes); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ad_subdomains_refresh failed.\n"); goto fail; } if (has_changes) { ret = ad_subdom_reinit(ctx->sd_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not reinitialize subdomains\n"); goto fail; } } ctx->root_domain_attrs = reply[0]; ctx->root_domain = ads_get_root_domain(ctx); if (ctx->root_domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Could not find the root domain\n"); ret = EFAULT; goto fail; } ctx->root_id_ctx = ads_get_root_id_ctx(ctx); if (ctx->root_id_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot create id ctx for the root domain\n"); ret = EFAULT; goto fail; } ctx->root_op = sdap_id_op_create(ctx, ctx->root_id_ctx->ldap_ctx->conn_cache); if (ctx->root_op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n"); ret = ENOMEM; goto fail; } req = sdap_id_op_connect_send(ctx->root_op, ctx, &ret); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n", ret, strerror(ret)); goto fail; } tevent_req_set_callback(req, ad_subdomains_root_conn_done, ctx); return; fail: if (ret == EOK) { ctx->sd_ctx->last_refreshed = time(NULL); dp_error = DP_ERR_OK; } be_req_terminate(ctx->be_req, dp_error, ret, NULL); } static struct sss_domain_info *ads_get_root_domain(struct ad_subdomains_req_ctx *ctx) { errno_t ret; const char *name; struct sss_domain_info *root; ret = sysdb_attrs_get_string(ctx->root_domain_attrs, AD_AT_TRUST_PARTNER, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); return NULL; } /* With a subsequent run, the root should already be known */ root = find_domain_by_name(ctx->sd_ctx->be_ctx->domain, name, false); return root; } static struct ad_id_ctx *ads_get_root_id_ctx(struct ad_subdomains_req_ctx *ctx) { errno_t ret; struct sdap_domain *sdom; struct ad_id_ctx *root_id_ctx; sdom = sdap_domain_get(ctx->sd_ctx->ad_id_ctx->sdap_id_ctx->opts, ctx->root_domain); if (sdom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get the sdom for %s!\n", ctx->root_domain->name); return NULL; } if (sdom->pvt == NULL) { ret = ad_subdom_ad_ctx_new(ctx->sd_ctx->be_ctx, ctx->sd_ctx->ad_id_ctx, ctx->root_domain, &root_id_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ad_subdom_ad_ctx_new failed.\n"); return NULL; } sdom->pvt = root_id_ctx; } else { root_id_ctx = sdom->pvt; } root_id_ctx->ldap_ctx->ignore_mark_offline = true; return root_id_ctx; } static void ad_subdomains_root_conn_done(struct tevent_req *req) { int ret; int dp_error = DP_ERR_FATAL; struct ad_subdomains_req_ctx *ctx; ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx); ret = sdap_id_op_connect_recv(req, &dp_error); talloc_zfree(req); if (ret) { be_mark_dom_offline(ctx->root_domain, be_req_get_be_ctx(ctx->be_req)); DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to AD server: [%d](%s)\n", ret, strerror(ret)); goto fail; } ret = ad_subdomains_get_slave(ctx); if (ret == EAGAIN) { return; } else if (ret != EOK) { goto fail; } fail: be_req_terminate(ctx->be_req, dp_error, ret, NULL); } static void ad_subdomains_get_slave_domain_done(struct tevent_req *req); static errno_t ad_subdomains_get_slave(struct ad_subdomains_req_ctx *ctx) { struct tevent_req *req; struct sdap_search_base *base; const char *slave_dom_attrs[] = { AD_AT_FLATNAME, AD_AT_TRUST_PARTNER, AD_AT_SID, AD_AT_TRUST_TYPE, AD_AT_TRUST_ATTRS, NULL }; base = ctx->root_id_ctx->sdap_id_ctx->opts->sdom->search_bases[ctx->base_iter]; if (base == NULL) { return EOK; } req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev, ctx->root_id_ctx->sdap_id_ctx->opts, sdap_id_op_handle(ctx->root_op), base->basedn, LDAP_SCOPE_SUBTREE, SLAVE_DOMAIN_FILTER, slave_dom_attrs, NULL, 0, dp_opt_get_int(ctx->root_id_ctx->sdap_id_ctx->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); return ENOMEM; } tevent_req_set_callback(req, ad_subdomains_get_slave_domain_done, ctx); return EAGAIN; } static errno_t ad_subdomains_process(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, size_t nsd, struct sysdb_attrs **sd, struct sysdb_attrs *root, size_t *_nsd_out, struct sysdb_attrs ***_sd_out) { size_t i, sdi; struct sysdb_attrs **sd_out; const char *sd_name; errno_t ret; if (root == NULL) { /* We are connected directly to the root domain. The 'sd' * list is complete and we can just use it */ *_nsd_out = nsd; *_sd_out = sd; return EOK; } /* If we searched for root separately, we must: * a) treat the root domain as a subdomain * b) filter the subdomain we are connected to from the subdomain * list, from our point of view, it's the master domain */ sd_out = talloc_zero_array(mem_ctx, struct sysdb_attrs *, nsd+1); if (sd_out == NULL) { return ENOMEM; } sdi = 0; for (i = 0; i < nsd; i++) { ret = sysdb_attrs_get_string(sd[i], AD_AT_TRUST_PARTNER, &sd_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto fail; } if (strcasecmp(sd_name, domain->name) == 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "Not including primary domain %s in the subdomain list\n", domain->name); continue; } sd_out[sdi] = talloc_steal(sd_out, sd[i]); sdi++; } /* Now include the root */ sd_out[sdi] = talloc_steal(sd_out, root); *_nsd_out = sdi+1; *_sd_out = sd_out; return EOK; fail: talloc_free(sd_out); return ret; } static void ad_subdomains_get_slave_domain_done(struct tevent_req *req) { int ret; size_t reply_count; struct sysdb_attrs **reply = NULL; struct ad_subdomains_req_ctx *ctx; int dp_error = DP_ERR_FATAL; bool refresh_has_changes = false; size_t nsubdoms; struct sysdb_attrs **subdoms; ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx); ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send request failed.\n"); goto done; } if (reply_count) { ctx->reply = talloc_realloc(ctx, ctx->reply, struct sysdb_attrs *, ctx->reply_count + reply_count); if (ctx->reply == NULL) { ret = ENOMEM; goto done; } memcpy(ctx->reply+ctx->reply_count, reply, reply_count * sizeof(struct sysdb_attrs *)); ctx->reply_count += reply_count; } ctx->base_iter++; ret = ad_subdomains_get_slave(ctx); if (ret == EAGAIN) { /* Search in progress */ return; } ret = sdap_id_op_done(ctx->root_op, ret, &dp_error); if (ret != EOK) { if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_MINOR_FAILURE, "No AD server is available, cannot get the " "subdomain list while offline\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "Failed to search the AD server: [%d](%s)\n", ret, strerror(ret)); } tevent_req_error(req, ret); return; } /* Based on whether we are connected to the forest root or not, we might * need to exclude the subdomain we are connected to from the list of * subdomains */ ret = ad_subdomains_process(ctx, ctx->sd_ctx->be_ctx->domain, ctx->reply_count, ctx->reply, ctx->root_domain_attrs, &nsubdoms, &subdoms); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Cannot process subdomain list\n")); tevent_req_error(req, ret); return; } /* Got all the subdomains, let's process them */ ret = ad_subdomains_refresh(ctx->sd_ctx, nsubdoms, false, subdoms, &refresh_has_changes); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to refresh subdomains.\n"); goto done; } DEBUG(SSSDBG_TRACE_LIBS, "There are %schanges\n", refresh_has_changes ? "" : "no "); if (refresh_has_changes) { ret = ad_subdom_reinit(ctx->sd_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not reinitialize subdomains\n"); goto done; } } ret = EOK; done: if (ret == EOK) { ctx->sd_ctx->last_refreshed = time(NULL); dp_error = DP_ERR_OK; } be_req_terminate(ctx->be_req, dp_error, ret, NULL); } static void ad_subdom_online_cb(void *pvt); static void ad_subdom_timer_refresh(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { ad_subdom_online_cb(pvt); } static void ad_subdom_be_req_callback(struct be_req *be_req, int dp_err, int dp_ret, const char *errstr) { talloc_free(be_req); } static void ad_subdom_online_cb(void *pvt) { struct ad_subdomains_ctx *ctx; struct be_req *be_req; struct timeval tv; uint32_t refresh_interval; ctx = talloc_get_type(pvt, struct ad_subdomains_ctx); if (!ctx) { DEBUG(SSSDBG_CRIT_FAILURE, "Bad private pointer\n"); return; } refresh_interval = ctx->be_ctx->domain->subdomain_refresh_interval; be_req = be_req_create(ctx, NULL, ctx->be_ctx, ad_subdom_be_req_callback, NULL); if (be_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "be_req_create() failed.\n"); return; } ad_subdomains_retrieve(ctx, be_req); tv = tevent_timeval_current_ofs(refresh_interval, 0); ctx->timer_event = tevent_add_timer(ctx->be_ctx->ev, ctx, tv, ad_subdom_timer_refresh, ctx); if (!ctx->timer_event) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add subdom timer event\n"); } } static void ad_subdom_offline_cb(void *pvt) { struct ad_subdomains_ctx *ctx; ctx = talloc_get_type(pvt, struct ad_subdomains_ctx); if (ctx) { talloc_zfree(ctx->timer_event); } } void ad_subdomains_handler(struct be_req *be_req) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct ad_subdomains_ctx *ctx; time_t now; ctx = talloc_get_type(be_ctx->bet_info[BET_SUBDOMAINS].pvt_bet_data, struct ad_subdomains_ctx); if (!ctx) { be_req_terminate(be_req, DP_ERR_FATAL, EINVAL, NULL); return; } now = time(NULL); if (ctx->last_refreshed > now - AD_SUBDOMAIN_REFRESH_LIMIT) { be_req_terminate(be_req, DP_ERR_OK, EOK, NULL); return; } ad_subdomains_retrieve(ctx, be_req); } struct bet_ops ad_subdomains_ops = { .handler = ad_subdomains_handler, .finalize = NULL }; int ad_subdom_init(struct be_ctx *be_ctx, struct ad_id_ctx *id_ctx, const char *ad_domain, struct bet_ops **ops, void **pvt_data) { struct ad_subdomains_ctx *ctx; int ret; enum idmap_error_code err; ctx = talloc_zero(id_ctx, struct ad_subdomains_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ctx->be_ctx = be_ctx; ctx->sdom = id_ctx->sdap_id_ctx->opts->sdom; ctx->ldap_ctx = id_ctx->ldap_ctx; ctx->sdap_id_ctx = id_ctx->sdap_id_ctx; ctx->domain_name = talloc_strdup(ctx, ad_domain); if (ctx->domain_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); return ENOMEM; } ctx->ad_id_ctx = id_ctx; *ops = &ad_subdomains_ops; *pvt_data = ctx; ret = be_add_online_cb(ctx, be_ctx, ad_subdom_online_cb, ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add subdom online callback\n"); } ret = be_add_offline_cb(ctx, be_ctx, ad_subdom_offline_cb, ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add subdom offline callback\n"); } err = sss_idmap_init(sss_idmap_talloc, ctx, sss_idmap_talloc_free, &ctx->idmap_ctx); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize idmap context.\n"); return EFAULT; } ret = ad_subdom_reinit(ctx); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not reinitialize subdomains. " "Users from trusted domains might not be resolved correctly\n"); /* Ignore this error and try to discover the subdomains later */ } return EOK; } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_id.c0000644000000000000000000000007412703456111016721 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.690793751 sssd-1.13.4/src/providers/ad/ad_id.c0000644002412700241270000007574612703456111020413 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/strtonum.h" #include "providers/ad/ad_common.h" #include "providers/ad/ad_id.h" #include "providers/ad/ad_domain_info.h" #include "providers/ldap/sdap_async_enum.h" #include "providers/ldap/sdap_idmap.h" static void disable_gc(struct ad_options *ad_options) { errno_t ret; if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_GC) == false) { return; } DEBUG(SSSDBG_IMPORTANT_INFO, "POSIX attributes were requested " "but are not present on the server side. Global Catalog " "lookups will be disabled\n"); ret = dp_opt_set_bool(ad_options->basic, AD_ENABLE_GC, false); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not turn off GC support\n"); /* Not fatal */ } } struct ad_handle_acct_info_state { struct be_req *breq; struct be_acct_req *ar; struct sdap_id_ctx *ctx; struct sdap_id_conn_ctx **conn; struct sdap_domain *sdom; size_t cindex; struct ad_options *ad_options; int dp_error; const char *err; }; static errno_t ad_handle_acct_info_step(struct tevent_req *req); static void ad_handle_acct_info_done(struct tevent_req *subreq); struct tevent_req * ad_handle_acct_info_send(TALLOC_CTX *mem_ctx, struct be_req *breq, struct be_acct_req *ar, struct sdap_id_ctx *ctx, struct ad_options *ad_options, struct sdap_domain *sdom, struct sdap_id_conn_ctx **conn) { struct tevent_req *req; struct ad_handle_acct_info_state *state; struct be_ctx *be_ctx = be_req_get_be_ctx(breq); errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ad_handle_acct_info_state); if (req == NULL) { return NULL; } state->breq = breq; state->ar = ar; state->ctx = ctx; state->sdom = sdom; state->conn = conn; state->ad_options = ad_options; state->cindex = 0; if (sss_domain_get_state(sdom->dom) == DOM_INACTIVE) { ret = ERR_SUBDOM_INACTIVE; goto immediate; } ret = ad_handle_acct_info_step(req); if (ret != EAGAIN) { goto immediate; } /* Lookup in progress */ return req; immediate: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } tevent_req_post(req, be_ctx->ev); return req; } static errno_t ad_handle_acct_info_step(struct tevent_req *req) { struct tevent_req *subreq; struct ad_handle_acct_info_state *state = tevent_req_data(req, struct ad_handle_acct_info_state); bool noexist_delete = false; if (state->conn[state->cindex] == NULL) { return EOK; } if (state->conn[state->cindex+1] == NULL) { noexist_delete = true; } subreq = sdap_handle_acct_req_send(state, state->ctx->be, state->ar, state->ctx, state->sdom, state->conn[state->cindex], noexist_delete); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, ad_handle_acct_info_done, req); return EAGAIN; } static void ad_handle_acct_info_done(struct tevent_req *subreq) { errno_t ret; int dp_error; int sdap_err; const char *err; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ad_handle_acct_info_state *state = tevent_req_data(req, struct ad_handle_acct_info_state); ret = sdap_handle_acct_req_recv(subreq, &dp_error, &err, &sdap_err); if (dp_error == DP_ERR_OFFLINE && state->conn[state->cindex+1] != NULL && state->conn[state->cindex]->ignore_mark_offline) { /* This is a special case: GC does not work. * We need to Fall back to ldap */ ret = EOK; sdap_err = ENOENT; } talloc_zfree(subreq); if (ret != EOK) { /* if GC was not used dp error should be set */ state->dp_error = dp_error; state->err = err; goto fail; } if (sdap_err == EOK) { tevent_req_done(req); return; } else if (sdap_err == ERR_NO_POSIX) { disable_gc(state->ad_options); } else if (sdap_err != ENOENT) { ret = EIO; goto fail; } /* Ret is only ENOENT or ERR_NO_POSIX now. Try the next connection */ state->cindex++; ret = ad_handle_acct_info_step(req); if (ret != EAGAIN) { /* No additional search in progress. Save the last * error status, we'll be returning it. */ state->dp_error = dp_error; state->err = err; if (ret == EOK) { /* No more connections */ tevent_req_done(req); } else { goto fail; } return; } /* Another lookup in progress */ return; fail: if (IS_SUBDOMAIN(state->sdom->dom)) { /* Deactivate subdomain on lookup errors instead of going * offline completely. * This is a stopgap, until our failover is per-domain, * not per-backend. Unfortunately, we can't rewrite the error * code on some reported codes only, because sdap_id_op code * encapsulated the failover as well.. */ ret = ERR_SUBDOM_INACTIVE; } tevent_req_error(req, ret); return; } errno_t ad_handle_acct_info_recv(struct tevent_req *req, int *_dp_error, const char **_err) { struct ad_handle_acct_info_state *state = tevent_req_data(req, struct ad_handle_acct_info_state); if (_dp_error) { *_dp_error = state->dp_error; } if (_err) { *_err = state->err; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct sdap_id_conn_ctx ** get_conn_list(struct be_req *breq, struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom, struct be_acct_req *ar) { struct sdap_id_conn_ctx **clist; switch (ar->entry_type & BE_REQ_TYPE_MASK) { case BE_REQ_USER: /* user */ clist = ad_user_conn_list(breq, ad_ctx, dom); break; case BE_REQ_BY_SECID: /* by SID */ case BE_REQ_USER_AND_GROUP: /* get SID */ case BE_REQ_GROUP: /* group */ case BE_REQ_INITGROUPS: /* init groups for user */ clist = ad_gc_conn_list(breq, ad_ctx, dom); break; default: /* Requests for other object should only contact LDAP by default */ clist = ad_ldap_conn_list(breq, ad_ctx, dom); break; } return clist; } static bool ad_account_can_shortcut(struct be_ctx *be_ctx, struct sdap_idmap_ctx *idmap_ctx, int filter_type, const char *filter_value, const char *filter_domain) { struct sss_domain_info *domain = be_ctx->domain; struct sss_domain_info *req_dom = NULL; enum idmap_error_code err; char *sid = NULL; const char *csid = NULL; uint32_t id; bool shortcut = false; errno_t ret; if (!sdap_idmap_domain_has_algorithmic_mapping(idmap_ctx, domain->name, domain->domain_id)) { goto done; } switch (filter_type) { case BE_FILTER_IDNUM: /* convert value to ID */ errno = 0; id = strtouint32(filter_value, NULL, 10); if (errno != 0) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Unable to convert filter value to " "number [%d]: %s\n", ret, strerror(ret)); goto done; } /* convert the ID to its SID equivalent */ err = sss_idmap_unix_to_sid(idmap_ctx->map, id, &sid); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Mapping ID [%s] to SID failed: " "[%s]\n", filter_value, idmap_error_string(err)); goto done; } /* fall through */ case BE_FILTER_SECID: csid = sid == NULL ? filter_value : sid; req_dom = find_domain_by_sid(domain, csid); if (req_dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Invalid domain\n"); goto done; } if (strcasecmp(req_dom->name, filter_domain) != 0) { shortcut = true; } break; default: break; } done: if (sid != NULL) { sss_idmap_free_sid(idmap_ctx->map, sid); } return shortcut; } static void ad_account_info_complete(struct tevent_req *req); struct ad_account_info_state { struct be_req *be_req; struct sss_domain_info *dom; }; void ad_account_info_handler(struct be_req *be_req) { struct ad_id_ctx *ad_ctx; struct be_acct_req *ar; struct sdap_id_ctx *sdap_id_ctx; struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct tevent_req *req; struct sss_domain_info *dom; struct sdap_domain *sdom; struct sdap_id_conn_ctx **clist; bool shortcut; errno_t ret; struct ad_account_info_state *state; ad_ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data, struct ad_id_ctx); ar = talloc_get_type(be_req_get_data(be_req), struct be_acct_req); sdap_id_ctx = ad_ctx->sdap_id_ctx; if (be_is_offline(be_ctx)) { return be_req_terminate(be_req, DP_ERR_OFFLINE, EAGAIN, "Offline"); } if (sdap_is_enum_request(ar)) { DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n"); return sdap_handler_done(be_req, DP_ERR_OK, EOK, "Success"); } /* Try to shortcut if this is ID or SID search and it belongs to * other domain range than is in ar->domain. */ shortcut = ad_account_can_shortcut(be_ctx, sdap_id_ctx->opts->idmap_ctx, ar->filter_type, ar->filter_value, ar->domain); if (shortcut) { DEBUG(SSSDBG_TRACE_FUNC, "This ID is from different domain\n"); be_req_terminate(be_req, DP_ERR_OK, EOK, NULL); return; } dom = be_ctx->domain; if (strcasecmp(ar->domain, be_ctx->domain->name) != 0) { /* Subdomain request, verify subdomain */ dom = find_domain_by_name(be_ctx->domain, ar->domain, true); } if (dom == NULL) { ret = EINVAL; goto fail; } /* Determine whether to connect to GC, LDAP or try both */ clist = get_conn_list(be_req, ad_ctx, dom, ar); if (clist == NULL) { ret = EIO; goto fail; } sdom = sdap_domain_get(sdap_id_ctx->opts, dom); if (sdom == NULL) { ret = EIO; goto fail; } state = talloc(be_req, struct ad_account_info_state); if (state == NULL) { ret = ENOMEM; goto fail; } state->dom = sdom->dom; state->be_req = be_req; req = ad_handle_acct_info_send(be_req, be_req, ar, sdap_id_ctx, ad_ctx->ad_options, sdom, clist); if (req == NULL) { ret = ENOMEM; goto fail; } tevent_req_set_callback(req, ad_account_info_complete, state); return; fail: be_req_terminate(be_req, DP_ERR_FATAL, ret, NULL); } static void ad_account_info_complete(struct tevent_req *req) { struct be_req *be_req; errno_t ret; int dp_error; const char *error_text = "Internal error"; const char *req_error_text; struct ad_account_info_state *state; state = tevent_req_callback_data(req, struct ad_account_info_state); be_req = state->be_req; ret = ad_handle_acct_info_recv(req, &dp_error, &req_error_text); talloc_zfree(req); if (ret == ERR_SUBDOM_INACTIVE) { be_mark_dom_offline(state->dom, be_req_get_be_ctx(be_req)); return be_req_terminate(be_req, DP_ERR_OFFLINE, EAGAIN, "Offline"); } else if (dp_error == DP_ERR_OK) { if (ret == EOK) { error_text = NULL; } else { DEBUG(SSSDBG_FATAL_FAILURE, "Bug: dp_error is OK on failed request\n"); dp_error = DP_ERR_FATAL; error_text = req_error_text; } } else if (dp_error == DP_ERR_OFFLINE) { error_text = "Offline"; } else if (dp_error == DP_ERR_FATAL && ret == ENOMEM) { error_text = "Out of memory"; } else { error_text = req_error_text; } return be_req_terminate(be_req, dp_error, ret, error_text); } void ad_check_online(struct be_req *be_req) { struct ad_id_ctx *ad_ctx; struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); ad_ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data, struct ad_id_ctx); return sdap_do_online_check(be_req, ad_ctx->sdap_id_ctx); } struct ad_enumeration_state { struct ad_id_ctx *id_ctx; struct ldap_enum_ctx *ectx; struct sdap_id_op *sdap_op; struct tevent_context *ev; const char *realm; struct sdap_domain *sdom; struct sdap_domain *sditer; }; static void ad_enumeration_conn_done(struct tevent_req *subreq); static void ad_enumeration_master_done(struct tevent_req *subreq); static errno_t ad_enum_sdom(struct tevent_req *req, struct sdap_domain *sd, struct ad_id_ctx *id_ctx); static void ad_enumeration_done(struct tevent_req *subreq); struct tevent_req * ad_enumeration_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct tevent_req *req; struct tevent_req *subreq; struct ad_enumeration_state *state; struct ldap_enum_ctx *ectx; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ad_enumeration_state); if (req == NULL) return NULL; ectx = talloc_get_type(pvt, struct ldap_enum_ctx); if (ectx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot retrieve ldap_enum_ctx!\n"); ret = EFAULT; goto fail; } state->ectx = ectx; state->ev = ev; state->sdom = ectx->sdom; state->sditer = state->sdom; state->id_ctx = talloc_get_type(ectx->pvt, struct ad_id_ctx); state->realm = dp_opt_get_cstring(state->id_ctx->ad_options->basic, AD_KRB5_REALM); if (state->realm == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm\n"); ret = EINVAL; goto fail; } state->sdap_op = sdap_id_op_create(state, state->id_ctx->ldap_ctx->conn_cache); if (state->sdap_op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n"); ret = ENOMEM; goto fail; } subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n", ret, strerror(ret)); goto fail; } tevent_req_set_callback(subreq, ad_enumeration_conn_done, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void ad_enumeration_conn_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ad_enumeration_state *state = tevent_req_data(req, struct ad_enumeration_state); int ret, dp_error; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_TRACE_FUNC, "Backend is marked offline, retry later!\n"); tevent_req_done(req); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Domain enumeration failed to connect to " \ "LDAP server: (%d)[%s]\n", ret, strerror(ret)); tevent_req_error(req, ret); } return; } subreq = ad_master_domain_send(state, state->ev, state->id_ctx->ldap_ctx, state->sdap_op, state->sdom->dom->name); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ad_master_domain_send failed.\n"); tevent_req_error(req, ret); return; } tevent_req_set_callback(subreq, ad_enumeration_master_done, req); } static void ad_enumeration_master_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ad_enumeration_state *state = tevent_req_data(req, struct ad_enumeration_state); char *flat_name; char *master_sid; char *forest; ret = ad_master_domain_recv(subreq, state, &flat_name, &master_sid, NULL, &forest); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot retrieve master domain info\n"); tevent_req_error(req, ret); return; } ret = sysdb_master_domain_add_info(state->sdom->dom, state->realm, flat_name, master_sid, forest); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot save master domain info\n"); tevent_req_error(req, ret); return; } ret = ad_enum_sdom(req, state->sdom, state->id_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not enumerate domain %s\n", state->sdom->dom->name); tevent_req_error(req, ret); return; } /* Execution will resume in ad_enumeration_done */ } static errno_t ad_enum_sdom(struct tevent_req *req, struct sdap_domain *sd, struct ad_id_ctx *id_ctx) { struct sdap_id_conn_ctx *user_conn; struct tevent_req *subreq; struct ad_enumeration_state *state = tevent_req_data(req, struct ad_enumeration_state); if (dp_opt_get_bool(id_ctx->ad_options->basic, AD_ENABLE_GC)) { user_conn = id_ctx->gc_ctx; } else { user_conn = id_ctx->ldap_ctx; } /* Groups are searched for in LDAP, users in GC. Services (if present, * which is unlikely in AD) from LDAP as well */ subreq = sdap_dom_enum_ex_send(state, state->ev, id_ctx->sdap_id_ctx, sd, user_conn, /* Users */ id_ctx->ldap_ctx, /* Groups */ id_ctx->ldap_ctx); /* Services */ if (subreq == NULL) { /* The ptask API will reschedule the enumeration on its own on * failure */ DEBUG(SSSDBG_OP_FAILURE, "Failed to schedule enumeration, retrying later!\n"); return ENOMEM; } tevent_req_set_callback(subreq, ad_enumeration_done, req); return EOK; } static errno_t ad_enum_cross_dom_members(struct sdap_options *opts, struct sss_domain_info *dom); static void ad_enumeration_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ad_enumeration_state *state = tevent_req_data(req, struct ad_enumeration_state); ret = sdap_dom_enum_ex_recv(subreq); talloc_zfree(subreq); if (ret == ERR_NO_POSIX) { /* Retry enumerating the same domain again, this time w/o * connecting to GC */ disable_gc(state->id_ctx->ad_options); ret = ad_enum_sdom(req, state->sditer, state->id_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not retry domain %s\n", state->sditer->dom->name); tevent_req_error(req, ret); return; } /* Execution will resume in ad_enumeration_done */ return; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not enumerate domain %s\n", state->sditer->dom->name); tevent_req_error(req, ret); return; } do { state->sditer = state->sditer->next; } while (state->sditer && state->sditer->dom->enumerate == false); if (state->sditer != NULL) { ret = ad_enum_sdom(req, state->sditer, state->sditer->pvt); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not enumerate domain %s\n", state->sditer->dom->name); tevent_req_error(req, ret); return; } /* Execution will resume in ad_enumeration_done */ return; } /* No more subdomains to enumerate. Check if we need to fixup * cross-domain membership */ if (state->sditer != state->sdom) { /* We did enumerate at least one subdomain. Walk the subdomains * and fixup members for each of them */ for (state->sditer = state->sdom; state->sditer; state->sditer = state->sditer->next) { ret = ad_enum_cross_dom_members(state->id_ctx->ad_options->id, state->sditer->dom); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not check cross-domain " "memberships for %s, group memberships might be " "incomplete!\n", state->sdom->dom->name); continue; } } } tevent_req_done(req); } static errno_t ad_group_extra_members(TALLOC_CTX *mem_ctx, const struct ldb_message *group, struct sss_domain_info *dom, char ***_group_only); static errno_t ad_group_add_member(struct sdap_options *opts, struct sss_domain_info *group_domain, struct ldb_dn *group_dn, const char *member); static errno_t ad_enum_cross_dom_members(struct sdap_options *opts, struct sss_domain_info *dom) { errno_t ret; errno_t sret; char *filter; TALLOC_CTX *tmp_ctx; const char *attrs[] = { SYSDB_NAME, SYSDB_MEMBER, SYSDB_ORIG_MEMBER, NULL }; size_t count, i, mi; struct ldb_message **msgs; bool in_transaction = false; char **group_only; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; ret = sysdb_transaction_start(dom->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; filter = talloc_asprintf(tmp_ctx, "(%s=*)", SYSDB_NAME); if (filter == NULL) { ret = ENOMEM; goto done; } ret = sysdb_search_groups(tmp_ctx, dom, filter, attrs, &count, &msgs); if (ret != EOK) { goto done; } for (i = 0; i < count; i++) { ret = ad_group_extra_members(tmp_ctx, msgs[i], dom, &group_only); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to check extra members\n"); continue; } else if (group_only == NULL) { DEBUG(SSSDBG_TRACE_INTERNAL, "No extra members\n"); continue; } /* Group has extra members */ for (mi = 0; group_only[mi]; mi++) { ret = ad_group_add_member(opts, dom, msgs[i]->dn, group_only[mi]); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add [%s]: %s\n", group_only[mi], strerror(ret)); continue; } } talloc_zfree(group_only); } ret = sysdb_transaction_commit(dom->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = sysdb_transaction_cancel(dom->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } static errno_t ad_group_stored_orig_members(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, struct ldb_dn *dn, char ***_odn_list); static errno_t ad_group_extra_members(TALLOC_CTX *mem_ctx, const struct ldb_message *group, struct sss_domain_info *dom, char ***_group_only) { TALLOC_CTX *tmp_ctx; struct ldb_message_element *m, *om; const char *name; errno_t ret; char **sysdb_odn_list; const char **group_odn_list; char **group_only = NULL; if (_group_only == NULL) return EINVAL; *_group_only = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; om = ldb_msg_find_element(group, SYSDB_ORIG_MEMBER); m = ldb_msg_find_element(group, SYSDB_MEMBER); name = ldb_msg_find_attr_as_string(group, SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "A group with no name!\n"); ret = EFAULT; goto done; } if (om == NULL || om->num_values == 0) { DEBUG(SSSDBG_TRACE_FUNC, "Group %s has no original members\n", name); ret = EOK; goto done; } if (m == NULL || (m->num_values < om->num_values)) { DEBUG(SSSDBG_TRACE_FUNC, "Group %s has %d members but %d original members\n", name, m ? m->num_values : 0, om->num_values); /* Get the list of originalDN attributes that are already * linked to the group */ ret = ad_group_stored_orig_members(tmp_ctx, dom, group->dn, &sysdb_odn_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not retrieve list of original members for %s\n", name); goto done; } /* Get the list of original DN attributes the group had in AD */ group_odn_list = sss_ldb_el_to_string_list(tmp_ctx, om); if (group_odn_list == NULL) { ret = EFAULT; goto done; } /* Compare the two lists */ ret = diff_string_lists(tmp_ctx, discard_const(group_odn_list), sysdb_odn_list, &group_only, NULL, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not compare lists of members for %s\n", name); goto done; } } ret = EOK; *_group_only = talloc_steal(mem_ctx, group_only); done: talloc_free(tmp_ctx); return ret; } static errno_t ad_group_stored_orig_members(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, struct ldb_dn *dn, char ***_odn_list) { errno_t ret; TALLOC_CTX *tmp_ctx; size_t m_count, i; struct ldb_message **members; const char *attrs[] = { SYSDB_NAME, SYSDB_ORIG_DN, NULL }; char **odn_list; const char *odn; size_t oi; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; /* Get all entries member element points to */ ret = sysdb_asq_search(tmp_ctx, dom, dn, NULL, SYSDB_MEMBER, attrs, &m_count, &members); if (ret != EOK) { goto done; } odn_list = talloc_zero_array(tmp_ctx, char *, m_count + 1); if (odn_list == NULL) { ret = ENOMEM; goto done; } /* Get a list of their original DNs */ oi = 0; for (i = 0; i < m_count; i++) { odn = ldb_msg_find_attr_as_string(members[i], SYSDB_ORIG_DN, NULL); if (odn == NULL) { continue; } odn_list[oi] = talloc_strdup(odn_list, odn); if (odn_list[oi] == NULL) { ret = ENOMEM; goto done; } oi++; DEBUG(SSSDBG_TRACE_INTERNAL, "Member %s already in sysdb\n", odn); } ret = EOK; *_odn_list = talloc_steal(mem_ctx, odn_list); done: talloc_free(tmp_ctx); return ret; } static errno_t ad_group_add_member(struct sdap_options *opts, struct sss_domain_info *group_domain, struct ldb_dn *group_dn, const char *member) { struct sdap_domain *sd; struct ldb_dn *base_dn; TALLOC_CTX *tmp_ctx; errno_t ret; const char *mem_filter; size_t msgs_count; struct ldb_message **msgs; /* This member would be from a different domain */ sd = sdap_domain_get_by_dn(opts, member); if (sd == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "No matching domain for %s\n", member); return ENOENT; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; mem_filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_ORIG_DN, member); if (mem_filter == NULL) { ret = ENOMEM; goto done; } base_dn = sysdb_domain_dn(tmp_ctx, sd->dom); if (base_dn == NULL) { ret = ENOMEM; goto done; } ret = sysdb_search_entry(tmp_ctx, sd->dom->sysdb, base_dn, LDB_SCOPE_SUBTREE, mem_filter, NULL, &msgs_count, &msgs); if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No member [%s] in sysdb\n", member); ret = EOK; goto done; } else if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "[%s] found in sysdb\n", member); if (msgs_count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Search by orig DN returned %zd results!\n", msgs_count); ret = EFAULT; goto done; } ret = sysdb_mod_group_member(group_domain, msgs[0]->dn, group_dn, SYSDB_MOD_ADD); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not add [%s] as a member of [%s]\n", ldb_dn_get_linearized(msgs[0]->dn), ldb_dn_get_linearized(group_dn)); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t ad_enumeration_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_gpo_child.c0000644000000000000000000000007412703456111020255 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.922794537 sssd-1.13.4/src/providers/ad/ad_gpo_child.c0000644002412700241270000005717612703456111021744 0ustar00jhrozekjhrozek00000000000000/* SSSD AD GPO Backend Module -- perform SMB and CSE processing in a child process Authors: Yassir Elley Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "util/util.h" #include "util/child_common.h" #include "providers/dp_backend.h" #include "providers/ad/ad_gpo.h" #include "sss_cli.h" #define SMB_BUFFER_SIZE 65536 #define GPT_INI "/GPT.INI" #define INI_GENERAL_SECTION "General" #define GPT_INI_VERSION "Version" struct input_buffer { int cached_gpt_version; const char *smb_server; const char *smb_share; const char *smb_path; const char *smb_cse_suffix; }; static errno_t unpack_buffer(uint8_t *buf, size_t size, struct input_buffer *ibuf) { size_t p = 0; uint32_t len; uint32_t cached_gpt_version; /* cached_gpt_version */ SAFEALIGN_COPY_UINT32_CHECK(&cached_gpt_version, buf + p, size, &p); DEBUG(SSSDBG_TRACE_FUNC, "cached_gpt_version: %d\n", cached_gpt_version); ibuf->cached_gpt_version = cached_gpt_version; /* smb_server */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); DEBUG(SSSDBG_TRACE_ALL, "smb_server length: %d\n", len); if (len == 0) { return EINVAL; } else { if (len > size - p) return EINVAL; ibuf->smb_server = talloc_strndup(ibuf, (char *)(buf + p), len); if (ibuf->smb_server == NULL) return ENOMEM; DEBUG(SSSDBG_TRACE_ALL, "smb_server: %s\n", ibuf->smb_server); p += len; } /* smb_share */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); DEBUG(SSSDBG_TRACE_ALL, "smb_share length: %d\n", len); if (len == 0) { return EINVAL; } else { if (len > size - p) return EINVAL; ibuf->smb_share = talloc_strndup(ibuf, (char *)(buf + p), len); if (ibuf->smb_share == NULL) return ENOMEM; DEBUG(SSSDBG_TRACE_ALL, "smb_share: %s\n", ibuf->smb_share); p += len; } /* smb_path */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); DEBUG(SSSDBG_TRACE_ALL, "smb_path length: %d\n", len); if (len == 0) { return EINVAL; } else { if (len > size - p) return EINVAL; ibuf->smb_path = talloc_strndup(ibuf, (char *)(buf + p), len); if (ibuf->smb_path == NULL) return ENOMEM; DEBUG(SSSDBG_TRACE_ALL, "smb_path: %s\n", ibuf->smb_path); p += len; } /* smb_cse_suffix */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); DEBUG(SSSDBG_TRACE_ALL, "smb_cse_suffix length: %d\n", len); if (len == 0) { return EINVAL; } else { if (len > size - p) return EINVAL; ibuf->smb_cse_suffix = talloc_strndup(ibuf, (char *)(buf + p), len); if (ibuf->smb_cse_suffix == NULL) return ENOMEM; DEBUG(SSSDBG_TRACE_ALL, "smb_cse_suffix: %s\n", ibuf->smb_cse_suffix); p += len; } return EOK; } static errno_t pack_buffer(struct response *r, int sysvol_gpt_version, int result) { size_t p = 0; /* A buffer with the following structure must be created: * uint32_t sysvol_gpt_version (required) * uint32_t status of the request (required) */ r->size = 2 * sizeof(uint32_t); r->buf = talloc_array(r, uint8_t, r->size); if(r->buf == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "result [%d]\n", result); /* sysvol_gpt_version */ SAFEALIGN_SET_UINT32(&r->buf[p], sysvol_gpt_version, &p); /* result */ SAFEALIGN_SET_UINT32(&r->buf[p], result, &p); return EOK; } static errno_t prepare_response(TALLOC_CTX *mem_ctx, int sysvol_gpt_version, int result, struct response **rsp) { int ret; struct response *r = NULL; r = talloc_zero(mem_ctx, struct response); if (r == NULL) { return ENOMEM; } r->buf = NULL; r->size = 0; ret = pack_buffer(r, sysvol_gpt_version, result); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_buffer failed\n"); return ret; } *rsp = r; DEBUG(SSSDBG_TRACE_ALL, "r->size: %zu\n", r->size); return EOK; } static void sssd_krb_get_auth_data_fn(const char * pServer, const char * pShare, char * pWorkgroup, int maxLenWorkgroup, char * pUsername, int maxLenUsername, char * pPassword, int maxLenPassword) { /* since we are using kerberos for authentication, we simply return */ return; } /* * This function prepares the gpo_cache by: * - parsing the input_smb_path into its component directories * - creating each component directory (if it doesn't already exist) */ static errno_t prepare_gpo_cache(TALLOC_CTX *mem_ctx, const char *cache_dir, const char *input_smb_path_with_suffix) { char *current_dir; char *ptr; const char delim = '/'; int num_dirs = 0; int i; char *first = NULL; char *last = NULL; char *smb_path_with_suffix = NULL; errno_t ret; mode_t old_umask; smb_path_with_suffix = talloc_strdup(mem_ctx, input_smb_path_with_suffix); if (smb_path_with_suffix == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_ALL, "smb_path_with_suffix: %s\n", smb_path_with_suffix); current_dir = talloc_strdup(mem_ctx, cache_dir); if (current_dir == NULL) { return ENOMEM; } ptr = smb_path_with_suffix + 1; while ((ptr = strchr(ptr, delim))) { ptr++; num_dirs++; } ptr = smb_path_with_suffix + 1; old_umask = umask(SSS_DFL_X_UMASK); for (i = 0; i < num_dirs; i++) { first = ptr; last = strchr(first, delim); if (last == NULL) { ret = EINVAL; goto done; } *last = '\0'; last++; current_dir = talloc_asprintf(mem_ctx, "%s/%s", current_dir, first); if (current_dir == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Storing GPOs in %s\n", current_dir); if ((mkdir(current_dir, 0700)) < 0 && errno != EEXIST) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "mkdir(%s) failed: %d\n", current_dir, ret); goto done; } ptr = last; } ret = EOK; done: umask(old_umask); return ret; } /* * This function stores the input buf to a local file, whose file path * is constructed by concatenating: * GPO_CACHE_PATH, * input smb_path, * input smb_cse_suffix * Note that the backend will later read the file from the same file path. */ static errno_t gpo_cache_store_file(const char *smb_path, const char *smb_cse_suffix, uint8_t *buf, int buflen) { int ret; int fret; int fd = -1; char *tmp_name = NULL; ssize_t written; char *filename = NULL; char *smb_path_with_suffix = NULL; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } smb_path_with_suffix = talloc_asprintf(tmp_ctx, "%s%s", smb_path, smb_cse_suffix); if (smb_path_with_suffix == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } /* create component directories of smb_path, if needed */ ret = prepare_gpo_cache(tmp_ctx, GPO_CACHE_PATH, smb_path_with_suffix); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "prepare_gpo_cache failed [%d][%s]\n", ret, strerror(ret)); goto done; } filename = talloc_asprintf(tmp_ctx, GPO_CACHE_PATH"%s", smb_path_with_suffix); if (filename == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } tmp_name = talloc_asprintf(tmp_ctx, "%sXXXXXX", filename); if (tmp_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } fd = sss_unique_file(tmp_ctx, tmp_name, &ret); if (fd == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_unique_file failed [%d][%s].\n", ret, strerror(ret)); goto done; } errno = 0; written = sss_atomic_write_s(fd, buf, buflen); if (written == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret, strerror(ret)); goto done; } if (written != buflen) { DEBUG(SSSDBG_CRIT_FAILURE, "Write error, wrote [%zd] bytes, expected [%d]\n", written, buflen); ret = EIO; goto done; } ret = fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fchmod failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = rename(tmp_name, filename); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "rename failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = EOK; done: if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret); } if (fd != -1) { fret = close(fd); if (fret == -1) { fret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "close failed [%d][%s].\n", fret, strerror(fret)); } } talloc_free(tmp_ctx); return ret; } static errno_t parse_ini_file_with_libini(struct ini_cfgobj *ini_config, int *_gpt_version) { int ret; struct value_obj *vobj = NULL; int gpt_version; ret = ini_get_config_valueobj(INI_GENERAL_SECTION, GPT_INI_VERSION, ini_config, INI_GET_FIRST_VALUE, &vobj); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "ini_get_config_valueobj failed [%d][%s]\n", ret, strerror(ret)); goto done; } if (vobj == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "section/name not found: [%s][%s]\n", INI_GENERAL_SECTION, GPT_INI_VERSION); ret = EINVAL; goto done; } gpt_version = ini_get_int32_config_value(vobj, 0, -1, &ret); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "ini_get_int32_config_value failed [%d][%s]\n", ret, strerror(ret)); goto done; } *_gpt_version = gpt_version; ret = EOK; done: return ret; } /* * This function parses the GPT_INI file stored in the gpo_cache, and uses the * results to populate the output parameters ... */ static errno_t ad_gpo_parse_ini_file(const char *smb_path, int *_gpt_version) { struct ini_cfgfile *file_ctx = NULL; struct ini_cfgobj *ini_config = NULL; const char *ini_filename; int ret; int gpt_version = -1; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ini_filename = talloc_asprintf(tmp_ctx, GPO_CACHE_PATH"%s%s", smb_path, GPT_INI); if (ini_filename == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "ini_filename:%s\n", ini_filename); ret = ini_config_create(&ini_config); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "ini_config_create failed [%d][%s]\n", ret, strerror(ret)); goto done; } ret = ini_config_file_open(ini_filename, 0, &file_ctx); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "ini_config_file_open failed [%d][%s]\n", ret, strerror(ret)); goto done; } ret = ini_config_parse(file_ctx, INI_STOP_ON_NONE, 0, 0, ini_config); if (ret != 0) { int lret; char **errors; DEBUG(SSSDBG_CRIT_FAILURE, "[%s]: ini_config_parse failed [%d][%s]\n", ini_filename, ret, strerror(ret)); /* Now get specific errors if there are any */ lret = ini_config_get_errors(ini_config, &errors); if (lret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get specific parse error [%d][%s]\n", lret, strerror(lret)); goto done; } for (int i = 0; errors[i]; i++) { DEBUG(SSSDBG_CRIT_FAILURE, "%s\n", errors[i]); } ini_config_free_errors(errors); goto done; } ret = parse_ini_file_with_libini(ini_config, &gpt_version); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "parse_ini_file_with_libini failed [%d][%s]\n", ret, strerror(ret)); goto done; } *_gpt_version = gpt_version; done: if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret); } ini_config_file_destroy(file_ctx); ini_config_destroy(ini_config); talloc_free(tmp_ctx); return ret; } /* * This function uses the input smb uri components to download a sysvol file * (e.g. INI file, policy file, etc) and store it to the GPO_CACHE directory. */ static errno_t copy_smb_file_to_gpo_cache(SMBCCTX *smbc_ctx, const char *smb_server, const char *smb_share, const char *smb_path, const char *smb_cse_suffix) { char *smb_uri = NULL; SMBCFILE *file; int ret; uint8_t *buf = NULL; int buflen = 0; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } smb_uri = talloc_asprintf(tmp_ctx, "%s%s%s%s", smb_server, smb_share, smb_path, smb_cse_suffix); if (smb_uri == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "smb_uri: %s\n", smb_uri); errno = 0; file = smbc_getFunctionOpen(smbc_ctx)(smbc_ctx, smb_uri, O_RDONLY, 0755); if (file == NULL) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "smbc_getFunctionOpen failed [%d][%s]\n", ret, strerror(ret)); goto done; } buf = talloc_array(tmp_ctx, uint8_t, SMB_BUFFER_SIZE); if (buf == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } errno = 0; buflen = smbc_getFunctionRead(smbc_ctx)(smbc_ctx, file, buf, SMB_BUFFER_SIZE); if (buflen < 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "smbc_getFunctionRead failed [%d][%s]\n", ret, strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_ALL, "smb_buflen: %d\n", buflen); ret = gpo_cache_store_file(smb_path, smb_cse_suffix, buf, buflen); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "gpo_cache_store_file failed [%d][%s]\n", ret, strerror(ret)); goto done; } done: talloc_free(tmp_ctx); return ret; } /* * Using its smb_uri components and cached_gpt_version inputs, this function * does several things: * - it downloads the GPT_INI file to GPO_CACHE * - it parses the sysvol_gpt_version field from the GPT_INI file * - if the sysvol_gpt_version is greater than the cached_gpt_version * - it downloads the policy file to GPO_CACHE * - else * - it doesn't retrieve the policy file * - in this case, the backend will use the existing policy file in GPO_CACHE * - it returns the sysvol_gpt_version in the _sysvol_gpt_version output param * * Note that if the cached_gpt_version sent by the backend is -1 (to indicate * that no gpt_version has been set in the cache for the corresponding gpo_guid), * then the parsed sysvol_gpt_version (which must be at least 0) will be greater * than the cached_gpt_version, thereby triggering a fresh download. * * Note that the backend will later do the following: * - backend will save the sysvol_gpt_version to sysdb cache * - backend will read the policy file from the GPO_CACHE */ static errno_t perform_smb_operations(int cached_gpt_version, const char *smb_server, const char *smb_share, const char *smb_path, const char *smb_cse_suffix, int *_sysvol_gpt_version) { SMBCCTX *smbc_ctx; int ret; int sysvol_gpt_version; smbc_ctx = smbc_new_context(); if (smbc_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate new smbc context\n"); ret = ENOMEM; goto done; } smbc_setOptionDebugToStderr(smbc_ctx, 1); smbc_setFunctionAuthData(smbc_ctx, sssd_krb_get_auth_data_fn); smbc_setOptionUseKerberos(smbc_ctx, 1); /* Initialize the context using the previously specified options */ if (smbc_init_context(smbc_ctx) == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize smbc context\n"); ret = ENOMEM; goto done; } /* download ini file */ ret = copy_smb_file_to_gpo_cache(smbc_ctx, smb_server, smb_share, smb_path, GPT_INI); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "copy_smb_file_to_gpo_cache failed [%d][%s]\n", ret, strerror(ret)); goto done; } ret = ad_gpo_parse_ini_file(smb_path, &sysvol_gpt_version); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse ini file: [%d][%s]\n", ret, strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "sysvol_gpt_version: %d\n", sysvol_gpt_version); if (sysvol_gpt_version > cached_gpt_version) { /* download policy file */ ret = copy_smb_file_to_gpo_cache(smbc_ctx, smb_server, smb_share, smb_path, smb_cse_suffix); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "copy_smb_file_to_gpo_cache failed [%d][%s]\n", ret, strerror(ret)); goto done; } } *_sysvol_gpt_version = sysvol_gpt_version; done: smbc_free_context(smbc_ctx, 0); return ret; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int debug_fd = -1; errno_t ret; int sysvol_gpt_version; int result; TALLOC_CTX *main_ctx = NULL; uint8_t *buf = NULL; ssize_t len = 0; struct input_buffer *ibuf = NULL; struct response *resp = NULL; ssize_t written; struct poptOption long_options[] = { POPT_AUTOHELP {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, _("Debug level"), NULL}, {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0, _("Add debug timestamps"), NULL}, {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0, _("Show timestamps with microseconds"), NULL}, {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0, _("An open file descriptor for the debug logs"), NULL}, {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, _("Send the debug output to stderr directly."), NULL }, POPT_TABLEEND }; /* Set debug level to invalid value so we can decide if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); _exit(-1); } } poptFreeContext(pc); DEBUG_INIT(debug_level); debug_prg_name = talloc_asprintf(NULL, "[sssd[gpo_child[%d]]]", getpid()); if (debug_prg_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); goto fail; } if (debug_fd != -1) { ret = set_debug_file_from_fd(debug_fd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n"); } } DEBUG(SSSDBG_TRACE_FUNC, "gpo_child started.\n"); main_ctx = talloc_new(NULL); if (main_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); talloc_free(discard_const(debug_prg_name)); goto fail; } talloc_steal(main_ctx, debug_prg_name); buf = talloc_size(main_ctx, sizeof(uint8_t)*IN_BUF_SIZE); if (buf == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); goto fail; } ibuf = talloc_zero(main_ctx, struct input_buffer); if (ibuf == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "context initialized\n"); errno = 0; len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE); if (len == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret)); goto fail; } close(STDIN_FILENO); ret = unpack_buffer(buf, len, ibuf); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "unpack_buffer failed.[%d][%s].\n", ret, strerror(ret)); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "performing smb operations\n"); result = perform_smb_operations(ibuf->cached_gpt_version, ibuf->smb_server, ibuf->smb_share, ibuf->smb_path, ibuf->smb_cse_suffix, &sysvol_gpt_version); if (result != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "perform_smb_operations failed.[%d][%s].\n", result, strerror(result)); goto fail; } ret = prepare_response(main_ctx, sysvol_gpt_version, result, &resp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "prepare_response failed. [%d][%s].\n", ret, strerror(ret)); goto fail; } errno = 0; written = sss_atomic_write_s(AD_GPO_CHILD_OUT_FILENO, resp->buf, resp->size); if (written == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret, strerror(ret)); goto fail; } if (written != resp->size) { DEBUG(SSSDBG_CRIT_FAILURE, "Expected to write %zu bytes, wrote %zu\n", resp->size, written); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "gpo_child completed successfully\n"); close(AD_GPO_CHILD_OUT_FILENO); talloc_free(main_ctx); return EXIT_SUCCESS; fail: DEBUG(SSSDBG_CRIT_FAILURE, "gpo_child failed!\n"); close(AD_GPO_CHILD_OUT_FILENO); talloc_free(main_ctx); return EXIT_FAILURE; } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_init.c0000644000000000000000000000007412703456111017270 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.687793741 sssd-1.13.4/src/providers/ad/ad_init.c0000644002412700241270000004305612703456111020747 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "providers/ad/ad_common.h" #include "providers/ad/ad_access.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_access.h" #include "providers/ldap/sdap_idmap.h" #include "providers/krb5/krb5_auth.h" #include "providers/krb5/krb5_init_shared.h" #include "providers/ad/ad_id.h" #include "providers/ad/ad_srv.h" #include "providers/dp_dyndns.h" #include "providers/ad/ad_subdomains.h" #include "providers/ad/ad_domain_info.h" struct ad_options *ad_options = NULL; static void ad_shutdown(struct be_req *req); struct bet_ops ad_id_ops = { .handler = ad_account_info_handler, .finalize = ad_shutdown, .check_online = ad_check_online }; struct bet_ops ad_auth_ops = { .handler = krb5_pam_handler, .finalize = NULL }; struct bet_ops ad_chpass_ops = { .handler = krb5_pam_handler, .finalize = NULL }; struct bet_ops ad_access_ops = { .handler = ad_access_handler, .finalize = NULL }; #define AD_COMPAT_ON "1" static int ad_sasl_getopt(void *context, const char *plugin_name, const char *option, const char **result, unsigned *len) { if (!plugin_name || !result) { return SASL_FAIL; } if (strcmp(plugin_name, "GSSAPI") != 0) { return SASL_FAIL; } if (strcmp(option, "ad_compat") != 0) { return SASL_FAIL; } *result = AD_COMPAT_ON; if (len) { *len = 2; } return SASL_OK; } typedef int (*sss_sasl_gen_cb_fn)(void); static int map_sasl2sssd_log_level(int sasl_level) { int sssd_level; switch(sasl_level) { case SASL_LOG_ERR: /* log unusual errors (default) */ sssd_level = SSSDBG_CRIT_FAILURE; break; case SASL_LOG_FAIL: /* log all authentication failures */ sssd_level = SSSDBG_OP_FAILURE; break; case SASL_LOG_WARN: /* log non-fatal warnings */ sssd_level = SSSDBG_MINOR_FAILURE; break; case SASL_LOG_NOTE: /* more verbose than LOG_WARN */ case SASL_LOG_DEBUG: /* more verbose than LOG_NOTE */ case SASL_LOG_TRACE: /* traces of internal protocols */ case SASL_LOG_PASS: /* traces of internal protocols, including */ sssd_level = SSSDBG_TRACE_ALL; break; default: sssd_level = SSSDBG_TRACE_ALL; break; } return sssd_level; } int ad_sasl_log(void *context, int level, const char *message) { int sssd_level; if (level == SASL_LOG_ERR || level == SASL_LOG_FAIL) { sss_log(SSS_LOG_ERR, "%s\n", message); } sssd_level = map_sasl2sssd_log_level(level); DEBUG(sssd_level, "SASL: %s\n", message); return SASL_OK; } static const sasl_callback_t ad_sasl_callbacks[] = { { SASL_CB_GETOPT, (sss_sasl_gen_cb_fn)ad_sasl_getopt, NULL }, { SASL_CB_LOG, (sss_sasl_gen_cb_fn)ad_sasl_log, NULL }, { SASL_CB_LIST_END, NULL, NULL } }; /* This is quite a hack, we *try* to fool openldap libraries by initializing * sasl first so we can pass in the SASL_CB_GETOPT callback we need to set some * options. Should be removed as soon as openldap exposes a way to do that */ static void ad_sasl_initialize(void) { /* NOTE: this may fail if soe other library in the system happens to * initialize and use openldap libraries or directly the cyrus-sasl * library as this initialization function can be called only once per * process */ (void)sasl_client_init(ad_sasl_callbacks); } static errno_t common_ad_init(struct be_ctx *bectx) { errno_t ret; char *ad_servers = NULL; char *ad_backup_servers = NULL; char *ad_realm; ad_sasl_initialize(); /* Get AD-specific options */ ret = ad_get_common_options(bectx, bectx->cdb, bectx->conf_path, bectx->domain, &ad_options); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not parse common options: [%s]\n", strerror(ret)); goto done; } ad_servers = dp_opt_get_string(ad_options->basic, AD_SERVER); ad_backup_servers = dp_opt_get_string(ad_options->basic, AD_BACKUP_SERVER); ad_realm = dp_opt_get_string(ad_options->basic, AD_KRB5_REALM); /* Set up the failover service */ ret = ad_failover_init(ad_options, bectx, ad_servers, ad_backup_servers, ad_realm, AD_SERVICE_NAME, AD_GC_SERVICE_NAME, dp_opt_get_string(ad_options->basic, AD_DOMAIN), &ad_options->service); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init AD failover service: [%s]\n", strerror(ret)); goto done; } ret = EOK; done: return ret; } int sssm_ad_id_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { errno_t ret; struct ad_id_ctx *ad_ctx; const char *hostname; const char *ad_domain; const char *ad_site_override; struct ad_srv_plugin_ctx *srv_ctx; if (!ad_options) { ret = common_ad_init(bectx); if (ret != EOK) { return ret; } } if (ad_options->id_ctx) { /* already initialized */ *ops = &ad_id_ops; *pvt_data = ad_options->id_ctx; return EOK; } ad_ctx = ad_id_ctx_init(ad_options, bectx); if (ad_ctx == NULL) { return ENOMEM; } ad_options->id_ctx = ad_ctx; ret = ad_dyndns_init(ad_ctx->sdap_id_ctx->be, ad_options); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failure setting up automatic DNS update\n"); /* Continue without DNS updates */ } ret = sdap_setup_child(); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "setup_child failed [%d][%s].\n", ret, strerror(ret)); goto done; } /* Set up various SDAP options */ ret = ad_get_id_options(ad_options, bectx->cdb, bectx->conf_path, &ad_ctx->sdap_id_ctx->opts); if (ret != EOK) { goto done; } ret = sdap_id_setup_tasks(bectx, ad_ctx->sdap_id_ctx, ad_ctx->sdap_id_ctx->opts->sdom, ad_enumeration_send, ad_enumeration_recv, ad_ctx); if (ret != EOK) { goto done; } ad_ctx->sdap_id_ctx->opts->sdom->pvt = ad_ctx; /* Set up the ID mapping object */ ret = sdap_idmap_init(ad_ctx->sdap_id_ctx, ad_ctx->sdap_id_ctx, &ad_ctx->sdap_id_ctx->opts->idmap_ctx); if (ret != EOK) goto done; ret = setup_tls_config(ad_ctx->sdap_id_ctx->opts->basic); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "setup_tls_config failed [%s]\n", strerror(ret)); goto done; } /* setup SRV lookup plugin */ hostname = dp_opt_get_string(ad_options->basic, AD_HOSTNAME); if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_DNS_SITES)) { /* use AD plugin */ ad_domain = dp_opt_get_string(ad_options->basic, AD_DOMAIN); ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE); srv_ctx = ad_srv_plugin_ctx_init(bectx, bectx->be_res, default_host_dbs, ad_options->id, hostname, ad_domain, ad_site_override); if (srv_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n"); ret = ENOMEM; goto done; } be_fo_set_srv_lookup_plugin(bectx, ad_srv_plugin_send, ad_srv_plugin_recv, srv_ctx, "AD"); } else { /* fall back to standard plugin */ ret = be_fo_set_dns_srv_lookup_plugin(bectx, hostname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin " "[%d]: %s\n", ret, strerror(ret)); goto done; } } /* setup periodical refresh of expired records */ ret = sdap_refresh_init(bectx->refresh_ctx, ad_ctx->sdap_id_ctx); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh " "will not work [%d]: %s\n", ret, strerror(ret)); } ret = ad_machine_account_password_renewal_init(bectx, ad_options); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot setup task for machine account " "password renewal.\n"); goto done; } *ops = &ad_id_ops; *pvt_data = ad_ctx; ret = EOK; done: if (ret != EOK) { talloc_zfree(ad_options->id_ctx); } return ret; } int sssm_ad_auth_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { errno_t ret; struct krb5_ctx *krb5_auth_ctx = NULL; if (!ad_options) { ret = common_ad_init(bectx); if (ret != EOK) { return ret; } } if (ad_options->auth_ctx) { /* Already initialized */ *ops = &ad_auth_ops; *pvt_data = ad_options->auth_ctx; return EOK; } krb5_auth_ctx = talloc_zero(NULL, struct krb5_ctx); if (!krb5_auth_ctx) { ret = ENOMEM; goto done; } krb5_auth_ctx->config_type = K5C_GENERIC; krb5_auth_ctx->service = ad_options->service->krb5_service; ret = ad_get_auth_options(krb5_auth_ctx, ad_options, bectx, &krb5_auth_ctx->opts); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not determine Kerberos options\n"); goto done; } ret = krb5_child_init(krb5_auth_ctx, bectx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize krb5_child settings: [%s]\n", strerror(ret)); goto done; } ad_options->auth_ctx = talloc_steal(ad_options, krb5_auth_ctx); *ops = &ad_auth_ops; *pvt_data = ad_options->auth_ctx; done: if (ret != EOK) { talloc_free(krb5_auth_ctx); } return ret; } int sssm_ad_chpass_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { errno_t ret; if (!ad_options) { ret = common_ad_init(bectx); if (ret != EOK) { return ret; } } if (ad_options->auth_ctx) { /* Already initialized */ *ops = &ad_chpass_ops; *pvt_data = ad_options->auth_ctx; return EOK; } ret = sssm_ad_auth_init(bectx, ops, pvt_data); *ops = &ad_chpass_ops; ad_options->auth_ctx = *pvt_data; return ret; } /* GPO parsing of PAM service names to Windows Logon Rights*/ errno_t ad_gpo_parse_map_options(struct ad_access_ctx *access_ctx); int sssm_ad_access_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { errno_t ret; struct ad_access_ctx *access_ctx; struct ad_id_ctx *ad_id_ctx; const char *filter; const char *gpo_access_control_mode; int gpo_cache_timeout; access_ctx = talloc_zero(bectx, struct ad_access_ctx); if (!access_ctx) return ENOMEM; ret = sssm_ad_id_init(bectx, ops, (void **)&ad_id_ctx); if (ret != EOK) { goto fail; } access_ctx->ad_id_ctx = ad_id_ctx; ret = dp_copy_options(access_ctx, ad_options->basic, AD_OPTS_BASIC, &access_ctx->ad_options); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize access provider options: [%s]\n", strerror(ret)); goto fail; } /* Set up an sdap_access_ctx for checking expired/locked accounts */ access_ctx->sdap_access_ctx = talloc_zero(access_ctx, struct sdap_access_ctx); if (!access_ctx->sdap_access_ctx) { ret = ENOMEM; goto fail; } access_ctx->sdap_access_ctx->id_ctx = ad_id_ctx->sdap_id_ctx; /* If ad_access_filter is set, the value of ldap_acess_order is * expire, filter, otherwise only expire */ access_ctx->sdap_access_ctx->access_rule[0] = LDAP_ACCESS_EXPIRE; filter = dp_opt_get_cstring(access_ctx->ad_options, AD_ACCESS_FILTER); if (filter != NULL) { /* The processing of the extended filter is performed during the access * check itself */ access_ctx->sdap_access_ctx->filter = talloc_strdup( access_ctx->sdap_access_ctx, filter); if (access_ctx->sdap_access_ctx->filter == NULL) { ret = ENOMEM; goto fail; } access_ctx->sdap_access_ctx->access_rule[1] = LDAP_ACCESS_FILTER; access_ctx->sdap_access_ctx->access_rule[2] = LDAP_ACCESS_EMPTY; } else { access_ctx->sdap_access_ctx->access_rule[1] = LDAP_ACCESS_EMPTY; } /* GPO access control mode */ gpo_access_control_mode = dp_opt_get_string(access_ctx->ad_options, AD_GPO_ACCESS_CONTROL); if (strcasecmp(gpo_access_control_mode, "disabled") == 0) { access_ctx->gpo_access_control_mode = GPO_ACCESS_CONTROL_DISABLED; } else if (strcasecmp(gpo_access_control_mode, "permissive") == 0) { access_ctx->gpo_access_control_mode = GPO_ACCESS_CONTROL_PERMISSIVE; } else if (strcasecmp(gpo_access_control_mode, "enforcing") == 0) { access_ctx->gpo_access_control_mode = GPO_ACCESS_CONTROL_ENFORCING; } else { DEBUG(SSSDBG_FATAL_FAILURE, "Unrecognized GPO access control mode: %s\n", gpo_access_control_mode); ret = EINVAL; goto fail; } /* GPO cache timeout */ gpo_cache_timeout = dp_opt_get_int(access_ctx->ad_options, AD_GPO_CACHE_TIMEOUT); access_ctx->gpo_cache_timeout = gpo_cache_timeout; /* GPO logon maps */ ret = sss_hash_create(access_ctx, 10, &access_ctx->gpo_map_options_table); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not create gpo_map_options hash table: [%s]\n", strerror(ret)); goto fail; } ret = ad_gpo_parse_map_options(access_ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not parse gpo_map_options (invalid config): [%s]\n", strerror(ret)); goto fail; } *ops = &ad_access_ops; *pvt_data = access_ctx; return EOK; fail: talloc_free(access_ctx); return ret; } static void ad_shutdown(struct be_req *req) { /* TODO: Clean up any internal data */ sdap_handler_done(req, DP_ERR_OK, EOK, NULL); } int sssm_ad_subdomains_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret; struct ad_id_ctx *id_ctx; const char *ad_domain; ret = sssm_ad_id_init(bectx, ops, (void **) &id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ad_id_init failed.\n"); return ret; } if (ad_options == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Global AD options not available.\n"); return EINVAL; } ad_domain = dp_opt_get_string(ad_options->basic, AD_DOMAIN); ret = ad_subdom_init(bectx, id_ctx, ad_domain, ops, pvt_data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "ad_subdom_init failed.\n"); return ret; } return EOK; } int sssm_ad_sudo_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { #ifdef BUILD_SUDO struct ad_id_ctx *id_ctx; int ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing AD sudo handler\n"); ret = sssm_ad_id_init(bectx, ops, (void **) &id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ad_id_init failed.\n"); return ret; } return ad_sudo_init(bectx, id_ctx, ops, pvt_data); #else DEBUG(SSSDBG_MINOR_FAILURE, "Sudo init handler called but SSSD is " "built without sudo support, ignoring\n"); return EOK; #endif } int sssm_ad_autofs_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { #ifdef BUILD_AUTOFS struct ad_id_ctx *id_ctx; int ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing AD autofs handler\n"); ret = sssm_ad_id_init(bectx, ops, (void **) &id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ad_id_init failed.\n"); return ret; } return ad_autofs_init(bectx, id_ctx, ops, pvt_data); #else DEBUG(SSSDBG_MINOR_FAILURE, "Autofs init handler called but SSSD is " "built without autofs support, ignoring\n"); return EOK; #endif } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_id.h0000644000000000000000000000007412703456111016726 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.690793751 sssd-1.13.4/src/providers/ad/ad_id.h0000644002412700241270000000324112703456111020375 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef AD_ID_H_ #define AD_ID_H_ void ad_account_info_handler(struct be_req *breq); struct tevent_req * ad_handle_acct_info_send(TALLOC_CTX *mem_ctx, struct be_req *breq, struct be_acct_req *ar, struct sdap_id_ctx *ctx, struct ad_options *ad_options, struct sdap_domain *sdom, struct sdap_id_conn_ctx **conn); errno_t ad_handle_acct_info_recv(struct tevent_req *req, int *_dp_error, const char **_err); struct tevent_req * ad_enumeration_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt); errno_t ad_enumeration_recv(struct tevent_req *req); void ad_check_online(struct be_req *be_req); #endif /* AD_ID_H_ */ sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_opts.h0000644000000000000000000000007412703456111017317 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.695793768 sssd-1.13.4/src/providers/ad/ad_opts.h0000644002412700241270000000263612703456111020775 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef AD_OPTS_H_ #define AD_OPTS_H_ #include "src/providers/data_provider.h" #include "providers/ldap/ldap_common.h" extern struct dp_option ad_basic_opts[]; extern struct dp_option ad_def_ldap_opts[]; extern struct dp_option ad_def_krb5_opts[]; extern struct sdap_attr_map ad_2008r2_attr_map[]; extern struct sdap_attr_map ad_2008r2_user_map[]; extern struct sdap_attr_map ad_2008r2_group_map[]; extern struct sdap_attr_map ad_netgroup_map[]; extern struct sdap_attr_map ad_service_map[]; extern struct sdap_attr_map ad_autofs_mobject_map[]; extern struct sdap_attr_map ad_autofs_entry_map[]; extern struct dp_option ad_dyndns_opts[]; #endif /* AD_OPTS_H_ */ sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_domain_info.c0000644000000000000000000000007412703456111020607 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.699793781 sssd-1.13.4/src/providers/ad/ad_domain_info.c0000644002412700241270000003120512703456111022257 0ustar00jhrozekjhrozek00000000000000/* SSSD AD Domain Info Module Authors: Sumit Bose Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ad/ad_domain_info.h" #include "providers/ad/ad_common.h" #include "util/util.h" static errno_t netlogon_get_domain_info(TALLOC_CTX *mem_ctx, struct sysdb_attrs *reply, char **_flat_name, char **_site, char **_forest) { errno_t ret; struct ldb_message_element *el; DATA_BLOB blob; struct ndr_pull *ndr_pull = NULL; enum ndr_err_code ndr_err; struct netlogon_samlogon_response response; const char *flat_name; const char *site; const char *forest; ret = sysdb_attrs_get_el(reply, AD_AT_NETLOGON, &el); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n"); return ret; } if (el->num_values == 0) { DEBUG(SSSDBG_OP_FAILURE, "netlogon has no value\n"); return ENOENT; } else if (el->num_values > 1) { DEBUG(SSSDBG_OP_FAILURE, "More than one netlogon value?\n"); return EIO; } blob.data = el->values[0].data; blob.length = el->values[0].length; ndr_pull = ndr_pull_init_blob(&blob, mem_ctx); if (ndr_pull == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_init_blob() failed.\n"); return ENOMEM; } ndr_err = ndr_pull_netlogon_samlogon_response(ndr_pull, NDR_SCALARS, &response); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_netlogon_samlogon_response() " "failed [%d]\n", ndr_err); ret = EBADMSG; goto done; } if (!(response.ntver & NETLOGON_NT_VERSION_5EX)) { DEBUG(SSSDBG_OP_FAILURE, "Wrong version returned [%x]\n", response.ntver); ret = EBADMSG; goto done; } /* get flat name */ if (response.data.nt5_ex.domain_name != NULL && *response.data.nt5_ex.domain_name != '\0') { flat_name = response.data.nt5_ex.domain_name; } else { DEBUG(SSSDBG_MINOR_FAILURE, "No netlogon domain name data available\n"); ret = ENOENT; goto done; } *_flat_name = talloc_strdup(mem_ctx, flat_name); if (*_flat_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } /* get forest */ if (response.data.nt5_ex.forest != NULL && *response.data.nt5_ex.forest != '\0') { forest = response.data.nt5_ex.forest; } else { DEBUG(SSSDBG_MINOR_FAILURE, "No netlogon forest data available\n"); ret = ENOENT; goto done; } *_forest = talloc_strdup(mem_ctx, forest); if (*_forest == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } /* get site name */ if (response.data.nt5_ex.client_site != NULL && response.data.nt5_ex.client_site[0] != '\0') { site = response.data.nt5_ex.client_site; } else { DEBUG(SSSDBG_MINOR_FAILURE, "No netlogon site name data available\n"); ret = ENOENT; goto done; } *_site = talloc_strdup(mem_ctx, site); if (*_site == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } ret = EOK; done: talloc_free(ndr_pull); return ret; } struct ad_master_domain_state { struct tevent_context *ev; struct sdap_id_conn_ctx *conn; struct sdap_id_op *id_op; struct sdap_id_ctx *id_ctx; struct sdap_options *opts; const char *dom_name; int base_iter; char *flat; char *site; char *forest; char *sid; }; static errno_t ad_master_domain_next(struct tevent_req *req); static void ad_master_domain_next_done(struct tevent_req *subreq); static void ad_master_domain_netlogon_done(struct tevent_req *req); struct tevent_req * ad_master_domain_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_conn_ctx *conn, struct sdap_id_op *op, const char *dom_name) { errno_t ret; struct tevent_req *req; struct ad_master_domain_state *state; req = tevent_req_create(mem_ctx, &state, struct ad_master_domain_state); if (!req) return NULL; state->ev = ev; state->id_op = op; state->conn = conn; state->id_ctx = conn->id_ctx; state->opts = conn->id_ctx->opts; state->dom_name = dom_name; ret = ad_master_domain_next(req); if (ret != EOK && ret != EAGAIN) { goto immediate; } return req; immediate: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } tevent_req_post(req, ev); return req; } static errno_t ad_master_domain_next(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_search_base *base; const char *master_sid_attrs[] = {AD_AT_OBJECT_SID, NULL}; struct ad_master_domain_state *state = tevent_req_data(req, struct ad_master_domain_state); base = state->opts->sdom->search_bases[state->base_iter]; if (base == NULL) { return EOK; } subreq = sdap_get_generic_send(state, state->ev, state->id_ctx->opts, sdap_id_op_handle(state->id_op), base->basedn, LDAP_SCOPE_BASE, MASTER_DOMAIN_SID_FILTER, master_sid_attrs, NULL, 0, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, ad_master_domain_next_done, req); return EAGAIN; } static void ad_master_domain_next_done(struct tevent_req *subreq) { errno_t ret; size_t reply_count; struct sysdb_attrs **reply = NULL; struct ldb_message_element *el; char *sid_str; enum idmap_error_code err; static const char *attrs[] = {AD_AT_NETLOGON, NULL}; char *filter; char *ntver; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ad_master_domain_state *state = tevent_req_data(req, struct ad_master_domain_state); ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send request failed.\n"); goto done; } if (reply_count == 0) { state->base_iter++; ret = ad_master_domain_next(req); if (ret == EAGAIN) { /* Async request will get us back here again */ return; } else if (ret != EOK) { goto done; } /* EOK */ tevent_req_done(req); return; } else if (reply_count == 1) { ret = sysdb_attrs_get_el(reply[0], AD_AT_OBJECT_SID, &el); if (ret != EOK || el->num_values != 1) { DEBUG(SSSDBG_OP_FAILURE, "sdap_attrs_get_el failed.\n"); goto done; } err = sss_idmap_bin_sid_to_sid(state->opts->idmap_ctx->map, el->values[0].data, el->values[0].length, &sid_str); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not convert SID: [%s].\n", idmap_error_string(err)); ret = EFAULT; goto done; } state->sid = talloc_steal(state, sid_str); } else { DEBUG(SSSDBG_OP_FAILURE, "More than one result for domain SID found.\n"); ret = EINVAL; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Found SID [%s].\n", state->sid); ntver = sss_ldap_encode_ndr_uint32(state, NETLOGON_NT_VERSION_5EX | NETLOGON_NT_VERSION_WITH_CLOSEST_SITE); if (ntver == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_ldap_encode_ndr_uint32 failed.\n"); ret = ENOMEM; goto done; } filter = talloc_asprintf(state, "(&(%s=%s)(%s=%s))", AD_AT_DNS_DOMAIN, state->dom_name, AD_AT_NT_VERSION, ntver); if (filter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } subreq = sdap_get_generic_send(state, state->ev, state->id_ctx->opts, sdap_id_op_handle(state->id_op), "", LDAP_SCOPE_BASE, filter, attrs, NULL, 0, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ad_master_domain_netlogon_done, req); return; done: tevent_req_error(req, ret); } static void ad_master_domain_netlogon_done(struct tevent_req *subreq) { int ret; size_t reply_count; struct sysdb_attrs **reply = NULL; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ad_master_domain_state *state = tevent_req_data(req, struct ad_master_domain_state); ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send request failed.\n"); tevent_req_error(req, ret); return; } /* Failure to get the flat name is not fatal. Just quit. */ if (reply_count == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "No netlogon data available. Flat name " \ "might not be usable\n"); goto done; } else if (reply_count > 1) { DEBUG(SSSDBG_MINOR_FAILURE, "More than one netlogon info returned.\n"); goto done; } /* Exactly one flat name. Carry on */ ret = netlogon_get_domain_info(state, reply[0], &state->flat, &state->site, &state->forest); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not get the flat name or forest: %d:[%s]\n", ret, sss_strerror(ret)); /* Not fatal. Just quit. */ goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Found flat name [%s].\n", state->flat); DEBUG(SSSDBG_TRACE_FUNC, "Found site [%s].\n", state->site); DEBUG(SSSDBG_TRACE_FUNC, "Found forest [%s].\n", state->forest); done: tevent_req_done(req); return; } errno_t ad_master_domain_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **_flat, char **_id, char **_site, char **_forest) { struct ad_master_domain_state *state = tevent_req_data(req, struct ad_master_domain_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_flat) { *_flat = talloc_steal(mem_ctx, state->flat); } if (_site) { *_site = talloc_steal(mem_ctx, state->site); } if (_forest) { *_forest = talloc_steal(mem_ctx, state->forest); } if (_id) { *_id = talloc_steal(mem_ctx, state->sid); } return EOK; } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_gpo.h0000644000000000000000000000007412703456111017117 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.694793764 sssd-1.13.4/src/providers/ad/ad_gpo.h0000644002412700241270000000436612703456111020577 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Yassir Elley Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef AD_GPO_H_ #define AD_GPO_H_ #include "providers/ad/ad_access.h" #define AD_GPO_CHILD_OUT_FILENO 3 #define AD_GPO_ATTRS {AD_AT_NT_SEC_DESC, \ AD_AT_CN, AD_AT_FILE_SYS_PATH, \ AD_AT_MACHINE_EXT_NAMES, \ AD_AT_FUNC_VERSION, \ AD_AT_FLAGS, \ NULL} /* * This pair of functions provides client-side GPO processing. * * While a GPO can target both user and computer objects, this * implementation only supports targetting of computer objects. * * A GPO overview is at https://fedorahosted.org/sssd/wiki/GpoOverview * * In summary, client-side processing involves: * - determining the target's DN * - extracting the SOM object DNs (i.e. OUs and Domain) from target's DN * - including the target's Site as another SOM object * - determining which GPOs apply to the target's SOMs * - prioritizing GPOs based on SOM, link order, and whether GPO is "enforced" * - retrieving the corresponding GPO objects * - sending the GPO DNs to the CSE processing engine for policy application * - policy application currently consists of HBAC-like functionality */ struct tevent_req * ad_gpo_access_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sss_domain_info *domain, struct ad_access_ctx *ctx, const char *user, const char *service); errno_t ad_gpo_access_recv(struct tevent_req *req); #endif /* AD_GPO_H_ */ sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_common.c0000644000000000000000000000007412703456111017615 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.685793734 sssd-1.13.4/src/providers/ad/ad_common.c0000644002412700241270000011620012703456111021264 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "providers/ad/ad_common.h" #include "providers/ad/ad_opts.h" #include "providers/dp_dyndns.h" struct ad_server_data { bool gc; }; errno_t ad_set_search_bases(struct sdap_options *id_opts); static errno_t ad_set_sdap_options(struct ad_options *ad_opts, struct sdap_options *id_opts); static struct sdap_options * ad_create_default_sdap_options(TALLOC_CTX *mem_ctx) { struct sdap_options *id_opts; errno_t ret; id_opts = talloc_zero(mem_ctx, struct sdap_options); if (!id_opts) { return NULL; } ret = dp_copy_defaults(id_opts, ad_def_ldap_opts, SDAP_OPTS_BASIC, &id_opts->basic); if (ret != EOK) { goto fail; } /* Get sdap option maps */ /* General Attribute Map */ ret = sdap_copy_map(id_opts, ad_2008r2_attr_map, SDAP_AT_GENERAL, &id_opts->gen_map); if (ret != EOK) { goto fail; } /* User map */ ret = sdap_copy_map(id_opts, ad_2008r2_user_map, SDAP_OPTS_USER, &id_opts->user_map); if (ret != EOK) { goto fail; } id_opts->user_map_cnt = SDAP_OPTS_USER; /* Group map */ ret = sdap_copy_map(id_opts, ad_2008r2_group_map, SDAP_OPTS_GROUP, &id_opts->group_map); if (ret != EOK) { goto fail; } /* Netgroup map */ ret = sdap_copy_map(id_opts, ad_netgroup_map, SDAP_OPTS_NETGROUP, &id_opts->netgroup_map); if (ret != EOK) { goto fail; } /* Services map */ ret = sdap_copy_map(id_opts, ad_service_map, SDAP_OPTS_SERVICES, &id_opts->service_map); if (ret != EOK) { goto fail; } return id_opts; fail: talloc_free(id_opts); return NULL; } struct ad_options * ad_create_default_options(TALLOC_CTX *mem_ctx) { struct ad_options *ad_options; errno_t ret; ad_options = talloc_zero(mem_ctx, struct ad_options); if (ad_options == NULL) return NULL; ret = dp_copy_defaults(ad_options, ad_basic_opts, AD_OPTS_BASIC, &ad_options->basic); if (ret != EOK) { talloc_free(ad_options); return NULL; } ad_options->id = ad_create_default_sdap_options(ad_options); if (ad_options->id == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD LDAP options\n"); talloc_free(ad_options); return NULL; } return ad_options; } static errno_t set_common_ad_trust_opts(struct ad_options *ad_options, const char *realm, const char *ad_domain, const char *hostname) { errno_t ret; ret = dp_opt_set_string(ad_options->basic, AD_KRB5_REALM, realm); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD krb5 realm\n"); return ret; } ret = dp_opt_set_string(ad_options->basic, AD_DOMAIN, ad_domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD domain\n"); return ret; } ret = dp_opt_set_string(ad_options->basic, AD_HOSTNAME, hostname); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set AD hostname\n"); return ret; } return EOK; } struct ad_options * ad_create_2way_trust_options(TALLOC_CTX *mem_ctx, const char *realm, const char *ad_domain, const char *hostname) { struct ad_options *ad_options; errno_t ret; ad_options = ad_create_default_options(mem_ctx); if (ad_options == NULL) return NULL; ret = set_common_ad_trust_opts(ad_options, realm, ad_domain, hostname); if (ret != EOK) { talloc_free(ad_options); return NULL; } ret = ad_set_sdap_options(ad_options, ad_options->id); if (ret != EOK) { talloc_free(ad_options); return NULL; } return ad_options; } struct ad_options * ad_create_1way_trust_options(TALLOC_CTX *mem_ctx, const char *ad_domain, const char *hostname, const char *keytab, const char *sasl_authid) { struct ad_options *ad_options; const char *realm; errno_t ret; ad_options = ad_create_default_options(mem_ctx); if (ad_options == NULL) return NULL; realm = get_uppercase_realm(ad_options, ad_domain); if (!realm) { talloc_free(ad_options); return NULL; } ret = set_common_ad_trust_opts(ad_options, realm, ad_domain, hostname); if (ret != EOK) { talloc_free(ad_options); return NULL; } /* Set AD_KEYTAB to the special 1way keytab */ ret = dp_opt_set_string(ad_options->basic, AD_KEYTAB, keytab); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set trust keytab\n"); talloc_free(ad_options); return NULL; } /* Set SDAP_SASL_AUTHID to the trust principal */ ret = dp_opt_set_string(ad_options->id->basic, SDAP_SASL_AUTHID, sasl_authid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set SASL authid\n"); talloc_free(ad_options); return NULL; } ret = ad_set_sdap_options(ad_options, ad_options->id); if (ret != EOK) { talloc_free(ad_options); return NULL; } return ad_options; } static errno_t ad_create_sdap_options(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, const char *conf_path, struct sdap_options **_id_opts) { struct sdap_options *id_opts; errno_t ret; id_opts = talloc_zero(mem_ctx, struct sdap_options); if (!id_opts) { ret = ENOMEM; goto done; } ret = dp_get_options(id_opts, cdb, conf_path, ad_def_ldap_opts, SDAP_OPTS_BASIC, &id_opts->basic); if (ret != EOK) { goto done; } /* Get sdap option maps */ /* General Attribute Map */ ret = sdap_get_map(id_opts, cdb, conf_path, ad_2008r2_attr_map, SDAP_AT_GENERAL, &id_opts->gen_map); if (ret != EOK) { goto done; } /* User map */ ret = sdap_get_map(id_opts, cdb, conf_path, ad_2008r2_user_map, SDAP_OPTS_USER, &id_opts->user_map); if (ret != EOK) { goto done; } ret = sdap_extend_map_with_list(id_opts, id_opts, SDAP_USER_EXTRA_ATTRS, id_opts->user_map, SDAP_OPTS_USER, &id_opts->user_map, &id_opts->user_map_cnt); if (ret != EOK) { goto done; } /* Group map */ ret = sdap_get_map(id_opts, cdb, conf_path, ad_2008r2_group_map, SDAP_OPTS_GROUP, &id_opts->group_map); if (ret != EOK) { goto done; } /* Netgroup map */ ret = sdap_get_map(id_opts, cdb, conf_path, ad_netgroup_map, SDAP_OPTS_NETGROUP, &id_opts->netgroup_map); if (ret != EOK) { goto done; } /* Services map */ ret = sdap_get_map(id_opts, cdb, conf_path, ad_service_map, SDAP_OPTS_SERVICES, &id_opts->service_map); if (ret != EOK) { goto done; } ret = EOK; *_id_opts = id_opts; done: return ret; } errno_t ad_get_common_options(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, const char *conf_path, struct sss_domain_info *dom, struct ad_options **_opts) { errno_t ret; int gret; struct ad_options *opts = NULL; char *domain; char *server; char *realm; char *ad_hostname; char hostname[HOST_NAME_MAX + 1]; char *case_sensitive_opt; const char *opt_override; opts = talloc_zero(mem_ctx, struct ad_options); if (!opts) return ENOMEM; ret = dp_get_options(opts, cdb, conf_path, ad_basic_opts, AD_OPTS_BASIC, &opts->basic); if (ret != EOK) { goto done; } /* If the AD domain name wasn't explicitly set, assume that it * matches the SSSD domain name */ domain = dp_opt_get_string(opts->basic, AD_DOMAIN); if (!domain) { ret = dp_opt_set_string(opts->basic, AD_DOMAIN, dom->name); if (ret != EOK) { goto done; } domain = dom->name; } /* Did we get an explicit server name, or are we discovering it? */ server = dp_opt_get_string(opts->basic, AD_SERVER); if (!server) { DEBUG(SSSDBG_CONF_SETTINGS, "No AD server set, will use service discovery!\n"); } /* Set the machine's hostname to the local host name if it * wasn't explicitly specified. */ ad_hostname = dp_opt_get_string(opts->basic, AD_HOSTNAME); if (ad_hostname == NULL) { gret = gethostname(hostname, HOST_NAME_MAX); if (gret != 0) { ret = errno; DEBUG(SSSDBG_FATAL_FAILURE, "gethostname failed [%s].\n", strerror(ret)); goto done; } hostname[HOST_NAME_MAX] = '\0'; DEBUG(SSSDBG_CONF_SETTINGS, "Setting ad_hostname to [%s].\n", hostname); ret = dp_opt_set_string(opts->basic, AD_HOSTNAME, hostname); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Setting ad_hostname failed [%s].\n", strerror(ret)); goto done; } } /* Always use the upper-case AD domain for the kerberos realm */ realm = get_uppercase_realm(opts, domain); if (!realm) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(opts->basic, AD_KRB5_REALM, realm); if (ret != EOK) { goto done; } /* Active Directory is always case-insensitive */ ret = confdb_get_string(cdb, mem_ctx, conf_path, CONFDB_DOMAIN_CASE_SENSITIVE, "false", &case_sensitive_opt); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "condb_get_string failed.\n"); goto done; } if (strcasecmp(case_sensitive_opt, "true") == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Warning: AD domain can not be set as case-sensitive.\n"); dom->case_sensitive = false; dom->case_preserve = false; } else if (strcasecmp(case_sensitive_opt, "false") == 0) { dom->case_sensitive = false; dom->case_preserve = false; } else if (strcasecmp(case_sensitive_opt, "preserving") == 0) { dom->case_sensitive = false; dom->case_preserve = true; } else { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for %s\n", CONFDB_DOMAIN_CASE_SENSITIVE); goto done; } opt_override = dom->case_preserve ? "preserving" : "false"; /* Set this in the confdb so that the responders pick it * up when they start up. */ ret = confdb_set_string(cdb, conf_path, "case_sensitive", opt_override); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set domain option case_sensitive: [%s]\n", strerror(ret)); goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Setting domain option case_sensitive to [%s]\n", opt_override); ret = EOK; *_opts = opts; done: if (ret != EOK) { talloc_zfree(opts); } return ret; } static void ad_resolve_callback(void *private_data, struct fo_server *server); static errno_t _ad_servers_init(struct ad_service *service, struct be_ctx *bectx, const char *fo_service, const char *fo_gc_service, const char *servers, const char *ad_domain, bool primary) { size_t i; errno_t ret = 0; char **list; struct ad_server_data *sdata; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; /* Split the server list */ ret = split_on_separator(tmp_ctx, servers, ',', true, true, &list, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse server list!\n"); goto done; } /* Add each of these servers to the failover service */ for (i = 0; list[i]; i++) { if (be_fo_is_srv_identifier(list[i])) { if (!primary) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add server [%s] to failover service: " "SRV resolution only allowed for primary servers!\n", list[i]); continue; } sdata = talloc(service, struct ad_server_data); if (sdata == NULL) { ret = ENOMEM; goto done; } sdata->gc = true; ret = be_fo_add_srv_server(bectx, fo_gc_service, "gc", ad_domain, BE_FO_PROTO_TCP, false, sdata); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add service discovery to failover: [%s]\n", strerror(ret)); goto done; } sdata = talloc(service, struct ad_server_data); if (sdata == NULL) { ret = ENOMEM; goto done; } sdata->gc = false; ret = be_fo_add_srv_server(bectx, fo_service, "ldap", ad_domain, BE_FO_PROTO_TCP, false, sdata); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add service discovery to failover: [%s]\n", strerror(ret)); goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Added service discovery for AD\n"); continue; } /* It could be ipv6 address in square brackets. Remove * the brackets if needed. */ ret = remove_ipv6_brackets(list[i]); if (ret != EOK) { goto done; } sdata = talloc(service, struct ad_server_data); if (sdata == NULL) { ret = ENOMEM; goto done; } sdata->gc = true; ret = be_fo_add_server(bectx, fo_gc_service, list[i], 0, sdata, primary); if (ret && ret != EEXIST) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n"); goto done; } sdata = talloc(service, struct ad_server_data); if (sdata == NULL) { ret = ENOMEM; goto done; } sdata->gc = false; ret = be_fo_add_server(bectx, fo_service, list[i], 0, sdata, primary); if (ret && ret != EEXIST) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n"); goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Added failover server %s\n", list[i]); } done: talloc_free(tmp_ctx); return ret; } static inline errno_t ad_primary_servers_init(struct ad_service *service, struct be_ctx *bectx, const char *servers, const char *fo_service, const char *fo_gc_service, const char *ad_domain) { return _ad_servers_init(service, bectx, fo_service, fo_gc_service, servers, ad_domain, true); } static inline errno_t ad_backup_servers_init(struct ad_service *service, struct be_ctx *bectx, const char *servers, const char *fo_service, const char *fo_gc_service, const char *ad_domain) { return _ad_servers_init(service, bectx, fo_service, fo_gc_service, servers, ad_domain, false); } static int ad_user_data_cmp(void *ud1, void *ud2) { struct ad_server_data *sd1, *sd2; sd1 = talloc_get_type(ud1, struct ad_server_data); sd2 = talloc_get_type(ud2, struct ad_server_data); if (sd1 == NULL || sd2 == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "No user data\n"); return sd1 == sd2 ? 0 : 1; } if (sd1->gc == sd2->gc) { return 0; } return 1; } static void ad_online_cb(void *pvt) { struct ad_service *service = talloc_get_type(pvt, struct ad_service); if (service == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid private pointer\n"); return; } DEBUG(SSSDBG_TRACE_FUNC, "The AD provider is online\n"); } errno_t ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, const char *primary_servers, const char *backup_servers, const char *krb5_realm, const char *ad_service, const char *ad_gc_service, const char *ad_domain, struct ad_service **_service) { errno_t ret; TALLOC_CTX *tmp_ctx; struct ad_service *service; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) return ENOMEM; service = talloc_zero(tmp_ctx, struct ad_service); if (!service) { ret = ENOMEM; goto done; } service->sdap = talloc_zero(service, struct sdap_service); service->gc = talloc_zero(service, struct sdap_service); if (!service->sdap || !service->gc) { ret = ENOMEM; goto done; } service->sdap->name = talloc_strdup(service->sdap, ad_service); service->gc->name = talloc_strdup(service->gc, ad_gc_service); if (!service->sdap->name || !service->gc->name) { ret = ENOMEM; goto done; } service->krb5_service = talloc_zero(service, struct krb5_service); if (!service->krb5_service) { ret = ENOMEM; goto done; } ret = be_fo_add_service(bectx, ad_service, ad_user_data_cmp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create failover service!\n"); goto done; } ret = be_fo_add_service(bectx, ad_gc_service, ad_user_data_cmp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create GC failover service!\n"); goto done; } service->krb5_service->name = talloc_strdup(service->krb5_service, ad_service); if (!service->krb5_service->name) { ret = ENOMEM; goto done; } service->sdap->kinit_service_name = service->krb5_service->name; service->gc->kinit_service_name = service->krb5_service->name; if (!krb5_realm) { DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm set\n"); ret = EINVAL; goto done; } service->krb5_service->realm = talloc_strdup(service->krb5_service, krb5_realm); if (!service->krb5_service->realm) { ret = ENOMEM; goto done; } if (!primary_servers) { DEBUG(SSSDBG_CONF_SETTINGS, "No primary servers defined, using service discovery\n"); primary_servers = BE_SRV_IDENTIFIER; } ret = ad_primary_servers_init(service, bectx, primary_servers, ad_service, ad_gc_service, ad_domain); if (ret != EOK) { goto done; } if (backup_servers) { ret = ad_backup_servers_init(service, bectx, backup_servers, ad_service, ad_gc_service, ad_domain); if (ret != EOK) { goto done; } } ret = be_add_online_cb(bectx, bectx, ad_online_cb, service, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up AD online callback\n"); return ret; } ret = be_fo_service_add_callback(mem_ctx, bectx, ad_service, ad_resolve_callback, service); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add failover callback! [%s]\n", strerror(ret)); goto done; } ret = be_fo_service_add_callback(mem_ctx, bectx, ad_gc_service, ad_resolve_callback, service); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add failover callback! [%s]\n", strerror(ret)); goto done; } *_service = talloc_steal(mem_ctx, service); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static void ad_resolve_callback(void *private_data, struct fo_server *server) { errno_t ret; TALLOC_CTX *tmp_ctx; struct ad_service *service; struct resolv_hostent *srvaddr; struct sockaddr_storage *sockaddr; char *address; const char *safe_address; char *new_uri; int new_port; const char *srv_name; struct ad_server_data *sdata = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); return; } sdata = fo_get_server_user_data(server); if (fo_is_srv_lookup(server) == false && sdata == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No user data?\n"); return; } service = talloc_get_type(private_data, struct ad_service); if (!service) { ret = EINVAL; goto done; } srvaddr = fo_get_server_hostent(server); if (!srvaddr) { DEBUG(SSSDBG_CRIT_FAILURE, "No hostent available for server (%s)\n", fo_get_server_str_name(server)); ret = EINVAL; goto done; } address = resolv_get_string_address(tmp_ctx, srvaddr); if (address == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_string_address failed.\n"); ret = EIO; goto done; } srv_name = fo_get_server_name(server); if (srv_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get server host name\n"); ret = EINVAL; goto done; } new_uri = talloc_asprintf(service->sdap, "ldap://%s", srv_name); if (!new_uri) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy URI\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Constructed uri '%s'\n", new_uri); sockaddr = resolv_get_sockaddr_address(tmp_ctx, srvaddr, LDAP_PORT); if (sockaddr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_sockaddr_address failed.\n"); ret = EIO; goto done; } /* free old one and replace with new one */ talloc_zfree(service->sdap->uri); service->sdap->uri = new_uri; talloc_zfree(service->sdap->sockaddr); service->sdap->sockaddr = talloc_steal(service->sdap, sockaddr); talloc_zfree(service->gc->uri); talloc_zfree(service->gc->sockaddr); if (sdata && sdata->gc) { new_port = fo_get_server_port(server); new_port = (new_port == 0) ? AD_GC_PORT : new_port; service->gc->uri = talloc_asprintf(service->gc, "%s:%d", new_uri, new_port); service->gc->sockaddr = resolv_get_sockaddr_address(service->gc, srvaddr, new_port); } else { /* Make sure there always is an URI even if we know that this * server doesn't support GC. That way the lookup would go through * just not return anything */ service->gc->uri = talloc_strdup(service->gc, service->sdap->uri); service->gc->sockaddr = talloc_memdup(service->gc, service->sdap->sockaddr, sizeof(struct sockaddr_storage)); } if (!service->gc->uri) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to append to URI\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Constructed GC uri '%s'\n", service->gc->uri); if (service->gc->sockaddr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_sockaddr_address failed.\n"); ret = EIO; goto done; } /* Only write kdcinfo files for local servers */ if ((sdata == NULL || sdata->gc == false) && service->krb5_service->write_kdcinfo) { /* Write krb5 info files */ safe_address = sss_escape_ip_address(tmp_ctx, srvaddr->family, address); if (safe_address == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_escape_ip_address failed.\n"); ret = ENOMEM; goto done; } ret = write_krb5info_file(service->krb5_service->realm, safe_address, SSS_KRB5KDC_FO_SRV); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "write_krb5info_file failed, authentication might fail.\n"); } } ret = EOK; done: if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error: [%s]\n", strerror(ret)); } talloc_free(tmp_ctx); return; } static errno_t ad_set_sdap_options(struct ad_options *ad_opts, struct sdap_options *id_opts) { errno_t ret; char *krb5_realm; char *keytab_path; /* We only support Kerberos password policy with AD, so * force that on. */ ret = dp_opt_set_string(id_opts->basic, SDAP_PWD_POLICY, PWD_POL_OPT_MIT); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not set password policy\n"); goto done; } /* Set the Kerberos Realm for GSSAPI */ krb5_realm = dp_opt_get_string(ad_opts->basic, AD_KRB5_REALM); if (!krb5_realm) { /* Should be impossible, this is set in ad_get_common_options() */ DEBUG(SSSDBG_FATAL_FAILURE, "No Kerberos realm\n"); ret = EINVAL; goto done; } ret = dp_opt_set_string(id_opts->basic, SDAP_KRB5_REALM, krb5_realm); if (ret != EOK) goto done; DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", id_opts->basic[SDAP_KRB5_REALM].opt_name, krb5_realm); keytab_path = dp_opt_get_string(ad_opts->basic, AD_KEYTAB); if (keytab_path) { ret = dp_opt_set_string(id_opts->basic, SDAP_KRB5_KEYTAB, keytab_path); if (ret != EOK) goto done; DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", id_opts->basic[SDAP_KRB5_KEYTAB].opt_name, keytab_path); } ret = sdap_set_sasl_options(id_opts, dp_opt_get_string(ad_opts->basic, AD_HOSTNAME), dp_opt_get_string(ad_opts->basic, AD_KRB5_REALM), keytab_path); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set the SASL-related options\n"); goto done; } /* fix schema to AD */ id_opts->schema_type = SDAP_SCHEMA_AD; ad_opts->id = id_opts; ret = EOK; done: return ret; } errno_t ad_get_id_options(struct ad_options *ad_opts, struct confdb_ctx *cdb, const char *conf_path, struct sdap_options **_opts) { struct sdap_options *id_opts; errno_t ret; ret = ad_create_sdap_options(ad_opts, cdb, conf_path, &id_opts); if (ret != EOK) { return ENOMEM; } ret = ad_set_sdap_options(ad_opts, id_opts); if (ret != EOK) { talloc_free(id_opts); return ret; } ret = sdap_domain_add(id_opts, ad_opts->id_ctx->sdap_id_ctx->be->domain, NULL); if (ret != EOK) { talloc_free(id_opts); return ret; } /* Set up search bases if they were assigned explicitly */ ret = ad_set_search_bases(id_opts); if (ret != EOK) { talloc_free(id_opts); return ret; } *_opts = id_opts; return EOK; } errno_t ad_get_autofs_options(struct ad_options *ad_opts, struct confdb_ctx *cdb, const char *conf_path) { errno_t ret; /* autofs maps */ ret = sdap_get_map(ad_opts->id, cdb, conf_path, ad_autofs_mobject_map, SDAP_OPTS_AUTOFS_MAP, &ad_opts->id->autofs_mobject_map); if (ret != EOK) { return ret; } ret = sdap_get_map(ad_opts->id, cdb, conf_path, ad_autofs_entry_map, SDAP_OPTS_AUTOFS_ENTRY, &ad_opts->id->autofs_entry_map); if (ret != EOK) { return ret; } return EOK; } errno_t ad_set_search_bases(struct sdap_options *id_opts) { errno_t ret; char *default_search_base; size_t o; const int search_base_options[] = { SDAP_USER_SEARCH_BASE, SDAP_GROUP_SEARCH_BASE, SDAP_NETGROUP_SEARCH_BASE, SDAP_SERVICE_SEARCH_BASE, -1 }; /* AD servers provide defaultNamingContext, so we will * rely on that to specify the search base unless it has * been specifically overridden. */ default_search_base = dp_opt_get_string(id_opts->basic, SDAP_SEARCH_BASE); if (default_search_base) { /* set search bases if they are not */ for (o = 0; search_base_options[o] != -1; o++) { if (NULL == dp_opt_get_string(id_opts->basic, search_base_options[o])) { ret = dp_opt_set_string(id_opts->basic, search_base_options[o], default_search_base); if (ret != EOK) { goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", id_opts->basic[search_base_options[o]].opt_name, dp_opt_get_string(id_opts->basic, search_base_options[o])); } } } else { DEBUG(SSSDBG_CONF_SETTINGS, "Search base not set. SSSD will attempt to discover it later, " "when connecting to the LDAP server.\n"); } /* Default search */ ret = sdap_parse_search_base(id_opts, id_opts->basic, SDAP_SEARCH_BASE, &id_opts->sdom->search_bases); if (ret != EOK && ret != ENOENT) goto done; /* User search */ ret = sdap_parse_search_base(id_opts, id_opts->basic, SDAP_USER_SEARCH_BASE, &id_opts->sdom->user_search_bases); if (ret != EOK && ret != ENOENT) goto done; /* Group search base */ ret = sdap_parse_search_base(id_opts, id_opts->basic, SDAP_GROUP_SEARCH_BASE, &id_opts->sdom->group_search_bases); if (ret != EOK && ret != ENOENT) goto done; /* Netgroup search */ ret = sdap_parse_search_base(id_opts, id_opts->basic, SDAP_NETGROUP_SEARCH_BASE, &id_opts->sdom->netgroup_search_bases); if (ret != EOK && ret != ENOENT) goto done; /* Service search */ ret = sdap_parse_search_base(id_opts, id_opts->basic, SDAP_SERVICE_SEARCH_BASE, &id_opts->sdom->service_search_bases); if (ret != EOK && ret != ENOENT) goto done; ret = EOK; done: return ret; } errno_t ad_get_auth_options(TALLOC_CTX *mem_ctx, struct ad_options *ad_opts, struct be_ctx *bectx, struct dp_option **_opts) { errno_t ret; struct dp_option *krb5_options; const char *ad_servers; const char *krb5_realm; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; /* Get krb5 options */ ret = dp_get_options(tmp_ctx, bectx->cdb, bectx->conf_path, ad_def_krb5_opts, KRB5_OPTS, &krb5_options); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not read Kerberos options from the configuration\n"); goto done; } ad_servers = dp_opt_get_string(ad_opts->basic, AD_SERVER); /* Force the krb5_servers to match the ad_servers */ ret = dp_opt_set_string(krb5_options, KRB5_KDC, ad_servers); if (ret != EOK) goto done; DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", krb5_options[KRB5_KDC].opt_name, ad_servers); /* Set krb5 realm */ /* Set the Kerberos Realm for GSSAPI */ krb5_realm = dp_opt_get_string(ad_opts->basic, AD_KRB5_REALM); if (!krb5_realm) { /* Should be impossible, this is set in ad_get_common_options() */ DEBUG(SSSDBG_FATAL_FAILURE, "No Kerberos realm\n"); ret = EINVAL; goto done; } /* Force the kerberos realm to match the AD_KRB5_REALM (which may have * been upper-cased in ad_common_options() */ ret = dp_opt_set_string(krb5_options, KRB5_REALM, krb5_realm); if (ret != EOK) goto done; DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", krb5_options[KRB5_REALM].opt_name, krb5_realm); /* Set flag that controls whether we want to write the * kdcinfo files at all */ ad_opts->service->krb5_service->write_kdcinfo = \ dp_opt_get_bool(krb5_options, KRB5_USE_KDCINFO); DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", krb5_options[KRB5_USE_KDCINFO].opt_name, ad_opts->service->krb5_service->write_kdcinfo ? "true" : "false"); *_opts = talloc_steal(mem_ctx, krb5_options); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t ad_get_dyndns_options(struct be_ctx *be_ctx, struct ad_options *ad_opts) { errno_t ret; ret = be_nsupdate_init(ad_opts, be_ctx, ad_dyndns_opts, &ad_opts->dyndns_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD dyndns opts [%d]: %s\n", ret, sss_strerror(ret)); return ret; } return EOK; } struct ad_id_ctx * ad_id_ctx_init(struct ad_options *ad_opts, struct be_ctx *bectx) { struct sdap_id_ctx *sdap_ctx; struct ad_id_ctx *ad_ctx; ad_ctx = talloc_zero(ad_opts, struct ad_id_ctx); if (ad_ctx == NULL) { return NULL; } ad_ctx->ad_options = ad_opts; sdap_ctx = sdap_id_ctx_new(ad_ctx, bectx, ad_opts->service->sdap); if (sdap_ctx == NULL) { talloc_free(ad_ctx); return NULL; } ad_ctx->sdap_id_ctx = sdap_ctx; ad_ctx->ldap_ctx = sdap_ctx->conn; ad_ctx->gc_ctx = sdap_id_ctx_conn_add(sdap_ctx, ad_opts->service->gc); if (ad_ctx->gc_ctx == NULL) { talloc_free(ad_ctx); return NULL; } return ad_ctx; } struct sdap_id_conn_ctx * ad_get_dom_ldap_conn(struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom) { struct sdap_id_conn_ctx *conn; struct sdap_domain *sdom; struct ad_id_ctx *subdom_id_ctx; sdom = sdap_domain_get(ad_ctx->sdap_id_ctx->opts, dom); if (sdom == NULL || sdom->pvt == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n", dom->name); return NULL; } subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx); conn = subdom_id_ctx->ldap_ctx; if (IS_SUBDOMAIN(sdom->dom) == true && conn != NULL) { /* Regardless of connection types, a subdomain error must not be * allowed to set the whole back end offline, rather report an error * and let the caller deal with it (normally disable the subdomain */ conn->ignore_mark_offline = true; } return conn; } struct sdap_id_conn_ctx ** ad_gc_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom) { struct sdap_id_conn_ctx **clist; int cindex = 0; clist = talloc_zero_array(mem_ctx, struct sdap_id_conn_ctx *, 3); if (clist == NULL) return NULL; /* Always try GC first */ if (dp_opt_get_bool(ad_ctx->ad_options->basic, AD_ENABLE_GC)) { clist[cindex] = ad_ctx->gc_ctx; clist[cindex]->ignore_mark_offline = true; cindex++; } clist[cindex] = ad_get_dom_ldap_conn(ad_ctx, dom); return clist; } struct sdap_id_conn_ctx ** ad_ldap_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom) { struct sdap_id_conn_ctx **clist; clist = talloc_zero_array(mem_ctx, struct sdap_id_conn_ctx *, 2); if (clist == NULL) { return NULL; } clist[0] = ad_get_dom_ldap_conn(ad_ctx, dom); clist[1] = NULL; return clist; } struct sdap_id_conn_ctx ** ad_user_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom) { struct sdap_id_conn_ctx **clist; int cindex = 0; clist = talloc_zero_array(ad_ctx, struct sdap_id_conn_ctx *, 3); if (clist == NULL) { return NULL; } /* Try GC first for users from trusted domains, but go to LDAP * for users from non-trusted domains to get all POSIX attrs */ if (dp_opt_get_bool(ad_ctx->ad_options->basic, AD_ENABLE_GC) && IS_SUBDOMAIN(dom)) { clist[cindex] = ad_ctx->gc_ctx; clist[cindex]->ignore_mark_offline = true; cindex++; } /* Users from primary domain can be just downloaded from LDAP. * The domain's LDAP connection also works as a fallback */ clist[cindex] = ad_get_dom_ldap_conn(ad_ctx, dom); return clist; } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_srv.h0000644000000000000000000000007412703456111017144 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.578793371 sssd-1.13.4/src/providers/ad/ad_srv.h0000644002412700241270000000376212703456111020623 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __AD_SRV_H__ #define __AD_SRV_H__ struct ad_srv_plugin_ctx; struct ad_srv_plugin_ctx * ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx, struct be_resolv_ctx *be_res, enum host_database *host_dbs, struct sdap_options *opts, const char *hostname, const char *ad_domain, const char *ad_site_override); struct tevent_req *ad_srv_plugin_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *service, const char *protocol, const char *discovery_domain, void *pvt); errno_t ad_srv_plugin_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain, uint32_t *_ttl, struct fo_server_info **_primary_servers, size_t *_num_primary_servers, struct fo_server_info **_backup_servers, size_t *_num_backup_servers); #endif /* __AD_SRV_H__ */ sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_sudo.c0000644000000000000000000000007412703456111017277 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.700793785 sssd-1.13.4/src/providers/ad/ad_sudo.c0000644002412700241270000000310412703456111020744 0ustar00jhrozekjhrozek00000000000000/* SSSD AD SUDO Provider Initialization functions Authors: Sumit Bose Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ad/ad_common.h" #include "providers/ldap/sdap_sudo.h" int ad_sudo_init(struct be_ctx *be_ctx, struct ad_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data) { int ret; struct ad_options *ad_options; struct sdap_options *ldap_options; DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing sudo AD back end\n"); ret = sdap_sudo_init(be_ctx, id_ctx->sdap_id_ctx, ops, pvt_data); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize LDAP SUDO [%d]: %s\n", ret, strerror(ret)); return ret; } ad_options = id_ctx->ad_options; ldap_options = id_ctx->sdap_id_ctx->opts; ad_options->id->sudorule_map = ldap_options->sudorule_map; return EOK; } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_domain_info.h0000644000000000000000000000007412703456111020614 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.699793781 sssd-1.13.4/src/providers/ad/ad_domain_info.h0000644002412700241270000000253612703456111022271 0ustar00jhrozekjhrozek00000000000000/* SSSD AD Master Domain Module Authors: Sumit Bose Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _AD_MASTER_DOMAIN_H_ #define _AD_MASTER_DOMAIN_H_ struct tevent_req * ad_master_domain_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_conn_ctx *conn, struct sdap_id_op *op, const char *dom_name); errno_t ad_master_domain_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **_flat, char **_id, char **_site, char **_forest); #endif /* _AD_MASTER_DOMAIN_H_ */ sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_gpo_ndr.c0000644000000000000000000000007412703456111017755 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.695793768 sssd-1.13.4/src/providers/ad/ad_gpo_ndr.c0000644002412700241270000004324712703456111021436 0ustar00jhrozekjhrozek00000000000000/* SSSD ad_gpo_ndr.c Authors: Yassir Elley Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* * This file contains a copy of samba's ndr_pull_* functions needed * to parse a security_descriptor. We are copying them here so that we don't * have to link against libsamba-security, which is a private samba library * These functions are taken from: * librpc/ndr/gen_ndr/ndr_security.c * librpc/ndr/ndr_misc.c * librpc/ndr/ndr_sec_helper.c */ #include "util/util.h" #include #include static enum ndr_err_code ndr_pull_GUID(struct ndr_pull *ndr, int ndr_flags, struct GUID *r) { uint32_t size_clock_seq_0 = 0; uint32_t size_node_0 = 0; NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->time_low)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->time_mid)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->time_hi_and_version)); size_clock_seq_0 = 2; NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->clock_seq, size_clock_seq_0)); size_node_0 = 6; NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->node, size_node_0)); NDR_CHECK(ndr_pull_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { } return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_ace_flags(struct ndr_pull *ndr, int ndr_flags, uint8_t *r) { uint8_t v; NDR_CHECK(ndr_pull_uint8(ndr, ndr_flags, &v)); *r = v; return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_ace_type(struct ndr_pull *ndr, int ndr_flags, enum security_ace_type *r) { uint8_t v; NDR_CHECK(ndr_pull_enum_uint8(ndr, ndr_flags, &v)); *r = v; return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_ace_object_flags(struct ndr_pull *ndr, int ndr_flags, uint32_t *r) { uint32_t v; NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &v)); *r = v; return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_ace_object_type(struct ndr_pull *ndr, int ndr_flags, union security_ace_object_type *r) { uint32_t level; level = ndr_pull_get_switch_value(ndr, r); NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_union_align(ndr, 4)); switch (level) { case SEC_ACE_OBJECT_TYPE_PRESENT: { NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->type)); break; } default: { break; } } } if (ndr_flags & NDR_BUFFERS) { switch (level) { case SEC_ACE_OBJECT_TYPE_PRESENT: break; default: break; } } return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_ace_object_inherited_type(struct ndr_pull *ndr, int ndr_flags, union security_ace_object_inherited_type *r) { uint32_t level; level = ndr_pull_get_switch_value(ndr, r); NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_union_align(ndr, 4)); switch (level) { case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT: { NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->inherited_type)); break; } default: { break; } } } if (ndr_flags & NDR_BUFFERS) { switch (level) { case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT: break; default: break; } } return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_ace_object(struct ndr_pull *ndr, int ndr_flags, struct security_ace_object *r) { NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_security_ace_object_flags (ndr, NDR_SCALARS, &r->flags)); NDR_CHECK(ndr_pull_set_switch_value (ndr, &r->type, r->flags & SEC_ACE_OBJECT_TYPE_PRESENT)); NDR_CHECK(ndr_pull_security_ace_object_type (ndr, NDR_SCALARS, &r->type)); NDR_CHECK(ndr_pull_set_switch_value (ndr, &r->inherited_type, r->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)); NDR_CHECK(ndr_pull_security_ace_object_inherited_type (ndr, NDR_SCALARS, &r->inherited_type)); NDR_CHECK(ndr_pull_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { NDR_CHECK(ndr_pull_security_ace_object_type (ndr, NDR_BUFFERS, &r->type)); NDR_CHECK(ndr_pull_security_ace_object_inherited_type (ndr, NDR_BUFFERS, &r->inherited_type)); } return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_ace_object_ctr(struct ndr_pull *ndr, int ndr_flags, union security_ace_object_ctr *r) { uint32_t level; level = ndr_pull_get_switch_value(ndr, r); NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_union_align(ndr, 4)); switch (level) { case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: { NDR_CHECK(ndr_pull_security_ace_object (ndr, NDR_SCALARS, &r->object)); break; } case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: { NDR_CHECK(ndr_pull_security_ace_object (ndr, NDR_SCALARS, &r->object)); break; } case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: { NDR_CHECK(ndr_pull_security_ace_object (ndr, NDR_SCALARS, &r->object)); break; } case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: { NDR_CHECK(ndr_pull_security_ace_object (ndr, NDR_SCALARS, &r->object)); break; } default: { break; } } } if (ndr_flags & NDR_BUFFERS) { switch (level) { case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: NDR_CHECK(ndr_pull_security_ace_object (ndr, NDR_BUFFERS, &r->object)); break; case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: NDR_CHECK(ndr_pull_security_ace_object (ndr, NDR_BUFFERS, &r->object)); break; case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: NDR_CHECK(ndr_pull_security_ace_object (ndr, NDR_BUFFERS, &r->object)); break; case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: NDR_CHECK(ndr_pull_security_ace_object (ndr, NDR_BUFFERS, &r->object)); break; default: break; } } return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_dom_sid(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *r) { uint32_t cntr_sub_auths_0; if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->sid_rev_num)); NDR_CHECK(ndr_pull_int8(ndr, NDR_SCALARS, &r->num_auths)); if (r->num_auths < 0 || r->num_auths > ARRAY_SIZE(r->sub_auths)) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->id_auth, 6)); ZERO_STRUCT(r->sub_auths); for (cntr_sub_auths_0 = 0; cntr_sub_auths_0 < r->num_auths; cntr_sub_auths_0++) { NDR_CHECK(ndr_pull_uint32 (ndr, NDR_SCALARS, &r->sub_auths[cntr_sub_auths_0])); } } return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, int ndr_flags, struct security_ace *r) { if (ndr_flags & NDR_SCALARS) { uint32_t start_ofs = ndr->offset; uint32_t size = 0; uint32_t pad = 0; NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type)); NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask)); NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type)); NDR_CHECK(ndr_pull_security_ace_object_ctr (ndr, NDR_SCALARS, &r->object)); NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee)); size = ndr->offset - start_ofs; if (r->size < size) { return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "ndr_pull_security_ace: r->size %u < size %u", (unsigned)r->size, size); } pad = r->size - size; NDR_PULL_NEED_BYTES(ndr, pad); ndr->offset += pad; } if (ndr_flags & NDR_BUFFERS) { NDR_CHECK(ndr_pull_security_ace_object_ctr (ndr, NDR_BUFFERS, &r->object)); } return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_acl_revision(struct ndr_pull *ndr, int ndr_flags, enum security_acl_revision *r) { uint16_t v; NDR_CHECK(ndr_pull_enum_uint1632(ndr, ndr_flags, &v)); *r = v; return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_acl(struct ndr_pull *ndr, int ndr_flags, struct security_acl *r) { uint32_t size_aces_0 = 0; uint32_t cntr_aces_0; TALLOC_CTX *_mem_save_aces_0; NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); NDR_CHECK(ndr_pull_security_acl_revision (ndr, NDR_SCALARS, &r->revision)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_aces)); if (r->num_aces > 1000) { return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); } size_aces_0 = r->num_aces; NDR_PULL_ALLOC_N(ndr, r->aces, size_aces_0); _mem_save_aces_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->aces, 0); for (cntr_aces_0 = 0; cntr_aces_0 < size_aces_0; cntr_aces_0++) { NDR_CHECK(ndr_pull_security_ace (ndr, NDR_SCALARS, &r->aces[cntr_aces_0])); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_aces_0, 0); NDR_CHECK(ndr_pull_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { size_aces_0 = r->num_aces; _mem_save_aces_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->aces, 0); for (cntr_aces_0 = 0; cntr_aces_0 < size_aces_0; cntr_aces_0++) { NDR_CHECK(ndr_pull_security_ace (ndr, NDR_BUFFERS, &r->aces[cntr_aces_0])); } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_aces_0, 0); } return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_descriptor_revision(struct ndr_pull *ndr, int ndr_flags, enum security_descriptor_revision *r) { uint8_t v; NDR_CHECK(ndr_pull_enum_uint8(ndr, ndr_flags, &v)); *r = v; return NDR_ERR_SUCCESS; } static enum ndr_err_code ndr_pull_security_descriptor_type(struct ndr_pull *ndr, int ndr_flags, uint16_t *r) { uint16_t v; NDR_CHECK(ndr_pull_uint16(ndr, ndr_flags, &v)); *r = v; return NDR_ERR_SUCCESS; } enum ndr_err_code ad_gpo_ndr_pull_security_descriptor(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor *r) { uint32_t _ptr_owner_sid; TALLOC_CTX *_mem_save_owner_sid_0; uint32_t _ptr_group_sid; TALLOC_CTX *_mem_save_group_sid_0; uint32_t _ptr_sacl; TALLOC_CTX *_mem_save_sacl_0; uint32_t _ptr_dacl; TALLOC_CTX *_mem_save_dacl_0; uint32_t _flags_save_STRUCT = ndr->flags; uint32_t _relative_save_offset; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_LITTLE_ENDIAN); NDR_PULL_CHECK_FLAGS(ndr, ndr_flags); if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 5)); NDR_CHECK(ndr_pull_security_descriptor_revision(ndr, NDR_SCALARS, &r->revision)); NDR_CHECK(ndr_pull_security_descriptor_type(ndr, NDR_SCALARS, &r->type)); NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_owner_sid)); if (_ptr_owner_sid) { NDR_PULL_ALLOC(ndr, r->owner_sid); NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->owner_sid, _ptr_owner_sid)); } else { r->owner_sid = NULL; } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_group_sid)); if (_ptr_group_sid) { NDR_PULL_ALLOC(ndr, r->group_sid); NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->group_sid, _ptr_group_sid)); } else { r->group_sid = NULL; } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sacl)); if (_ptr_sacl) { NDR_PULL_ALLOC(ndr, r->sacl); NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->sacl, _ptr_sacl)); } else { r->sacl = NULL; } NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_dacl)); if (_ptr_dacl) { NDR_PULL_ALLOC(ndr, r->dacl); NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->dacl, _ptr_dacl)); } else { r->dacl = NULL; } NDR_CHECK(ndr_pull_trailer_align(ndr, 5)); } if (ndr_flags & NDR_BUFFERS) { if (r->owner_sid) { _relative_save_offset = ndr->offset; NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->owner_sid)); _mem_save_owner_sid_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->owner_sid, 0); NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, r->owner_sid)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_owner_sid_0, 0); if (ndr->offset > ndr->relative_highest_offset) { ndr->relative_highest_offset = ndr->offset; } ndr->offset = _relative_save_offset; } if (r->group_sid) { _relative_save_offset = ndr->offset; NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->group_sid)); _mem_save_group_sid_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->group_sid, 0); NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, r->group_sid)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_group_sid_0, 0); if (ndr->offset > ndr->relative_highest_offset) { ndr->relative_highest_offset = ndr->offset; } ndr->offset = _relative_save_offset; } if (r->sacl) { _relative_save_offset = ndr->offset; NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->sacl)); _mem_save_sacl_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->sacl, 0); NDR_CHECK(ndr_pull_security_acl(ndr, NDR_SCALARS|NDR_BUFFERS, r->sacl)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sacl_0, 0); if (ndr->offset > ndr->relative_highest_offset) { ndr->relative_highest_offset = ndr->offset; } ndr->offset = _relative_save_offset; } if (r->dacl) { _relative_save_offset = ndr->offset; NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->dacl)); _mem_save_dacl_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->dacl, 0); NDR_CHECK(ndr_pull_security_acl(ndr, NDR_SCALARS|NDR_BUFFERS, r->dacl)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_dacl_0, 0); if (ndr->offset > ndr->relative_highest_offset) { ndr->relative_highest_offset = ndr->offset; } ndr->offset = _relative_save_offset; } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_subdomains.h0000644000000000000000000000007412703456111020476 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.698793778 sssd-1.13.4/src/providers/ad/ad_subdomains.h0000644002412700241270000000216612703456111022152 0ustar00jhrozekjhrozek00000000000000/* SSSD AD Subdomains Module Authors: Sumit Bose Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _AD_SUBDOMAINS_H_ #define _AD_SUBDOMAINS_H_ #include "providers/dp_backend.h" #include "providers/ad/ad_common.h" int ad_subdom_init(struct be_ctx *be_ctx, struct ad_id_ctx *id_ctx, const char *ad_domain, struct bet_ops **ops, void **pvt_data); #endif /* _AD_SUBDOMAINS_H_ */ sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_access.c0000644000000000000000000000007412703456111017566 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.691793754 sssd-1.13.4/src/providers/ad/ad_access.c0000644002412700241270000003665712703456111021256 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "src/util/util.h" #include "src/providers/data_provider.h" #include "src/providers/dp_backend.h" #include "src/providers/ad/ad_access.h" #include "providers/ad/ad_gpo.h" #include "src/providers/ad/ad_common.h" #include "src/providers/ldap/sdap_access.h" /* * More advanced format can be used to restrict the filter to a specific * domain or a specific forest. This format is KEYWORD:NAME:FILTER * * KEYWORD can be one of DOM or FOREST * KEYWORD can be missing * NAME is a label. * - if KEYWORD equals DOM or missing completely, the filter is applied * for users from domain named NAME only * - if KEYWORD equals FOREST, the filter is applied on users from * forest named NAME only * examples of valid filters are: * apply filter on domain called dom1 only: * dom1:(memberOf=cn=admins,ou=groups,dc=dom1,dc=com) * apply filter on domain called dom2 only: * DOM:dom2:(memberOf=cn=admins,ou=groups,dc=dom2,dc=com) * apply filter on forest called EXAMPLE.COM only: * FOREST:EXAMPLE.COM:(memberOf=cn=admins,ou=groups,dc=example,dc=com) * * If any of the extended formats are used, the filter MUST be enclosed * already. */ /* From least specific */ #define AD_FILTER_GENERIC 0x01 #define AD_FILTER_FOREST 0x02 #define AD_FILTER_DOMAIN 0x04 #define KW_FOREST "FOREST" #define KW_DOMAIN "DOM" /* parse filter in the format domain_name:filter */ static errno_t parse_sub_filter(TALLOC_CTX *mem_ctx, const char *full_filter, char **filter, char **sub_name, int *flags, const int flagconst) { char *specdelim; specdelim = strchr(full_filter, ':'); if (specdelim == NULL) return EINVAL; /* Make sure the filter is already enclosed in brackets */ if (*(specdelim+1) != '(') return EINVAL; *sub_name = talloc_strndup(mem_ctx, full_filter, specdelim - full_filter); *filter = talloc_strdup(mem_ctx, specdelim+1); if (*sub_name == NULL || *filter == NULL) return ENOMEM; *flags = flagconst; return EOK; } static inline errno_t parse_dom_filter(TALLOC_CTX *mem_ctx, const char *dom_filter, char **filter, char **domname, int *flags) { return parse_sub_filter(mem_ctx, dom_filter, filter, domname, flags, AD_FILTER_DOMAIN); } static inline errno_t parse_forest_filter(TALLOC_CTX *mem_ctx, const char *forest_filter, char **filter, char **forest_name, int *flags) { return parse_sub_filter(mem_ctx, forest_filter, filter, forest_name, flags, AD_FILTER_FOREST); } static errno_t parse_filter(TALLOC_CTX *mem_ctx, const char *full_filter, char **filter, char **spec, int *flags) { char *kwdelim, *specdelim; if (filter == NULL || spec == NULL || flags == NULL) return EINVAL; kwdelim = strchr(full_filter, ':'); if (kwdelim != NULL) { specdelim = strchr(kwdelim+1, ':'); if (specdelim == NULL) { /* There is a single keyword. Treat it as a domain name */ return parse_dom_filter(mem_ctx, full_filter, filter, spec, flags); } else if (strncmp(full_filter, "DOM", kwdelim-full_filter) == 0) { /* The format must be DOM:domain_name:filter */ if (specdelim && specdelim-kwdelim <= 1) { /* Check if there is some domain_name */ return EINVAL; } return parse_dom_filter(mem_ctx, kwdelim + 1, filter, spec, flags); } else if (strncmp(full_filter, "FOREST", kwdelim-full_filter) == 0) { /* The format must be FOREST:forest_name:filter */ if (specdelim && specdelim-kwdelim <= 1) { /* Check if there is some domain_name */ return EINVAL; } return parse_forest_filter(mem_ctx, kwdelim + 1, filter, spec, flags); } /* Malformed option */ DEBUG(SSSDBG_CRIT_FAILURE, "Keyword in filter [%s] did not match expected format\n", full_filter); return EINVAL; } /* No keyword. Easy. */ *filter = talloc_strdup(mem_ctx, full_filter); if (*filter == NULL) return ENOMEM; *spec = NULL; *flags = AD_FILTER_GENERIC; return EOK; } static errno_t ad_parse_access_filter(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *filter_list, char **_filter) { char **filters; int nfilters; errno_t ret; char *best_match; int best_flags; char *filter; char *spec; int flags; TALLOC_CTX *tmp_ctx; int i = 0; if (_filter == NULL) return EINVAL; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } if (filter_list == NULL) { *_filter = NULL; ret = EOK; goto done; } ret = split_on_separator(tmp_ctx, filter_list, '?', true, true, &filters, &nfilters); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse the list of ad_access_filters\n"); goto done; } best_match = NULL; best_flags = 0; for (i=0; i < nfilters; i++) { ret = parse_filter(tmp_ctx, filters[i], &filter, &spec, &flags); if (ret != EOK) { /* Skip the faulty filter. At worst, the user won't be * allowed access */ DEBUG(SSSDBG_MINOR_FAILURE, "Access filter [%s] could not be " "parsed, skipping\n", filters[i]); continue; } if (flags & AD_FILTER_DOMAIN && strcasecmp(spec, dom->name) != 0) { /* If the filter specifies a domain, it must match the * domain the user comes from */ continue; } if (flags & AD_FILTER_FOREST && strcasecmp(spec, dom->forest) != 0) { /* If the filter specifies a forest, it must match the * forest the user comes from */ continue; } if (flags > best_flags) { best_flags = flags; best_match = filter; } } ret = EOK; /* Make sure the result is enclosed in brackets */ *_filter = sdap_get_access_filter(mem_ctx, best_match); done: talloc_free(tmp_ctx); return ret; } struct ad_access_state { struct tevent_context *ev; struct ad_access_ctx *ctx; struct pam_data *pd; struct be_ctx *be_ctx; struct sss_domain_info *domain; char *filter; struct sdap_id_conn_ctx **clist; int cindex; }; static errno_t ad_sdap_access_step(struct tevent_req *req, struct sdap_id_conn_ctx *conn); static void ad_sdap_access_done(struct tevent_req *req); static struct tevent_req * ad_access_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, struct ad_access_ctx *ctx, struct pam_data *pd) { struct tevent_req *req; struct ad_access_state *state; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ad_access_state); if (req == NULL) { return NULL; } state->ev = ev; state->ctx = ctx; state->pd = pd; state->be_ctx = be_ctx; state->domain = domain; ret = ad_parse_access_filter(state, domain, ctx->sdap_access_ctx->filter, &state->filter); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not determine the best filter\n"); ret = ERR_ACCESS_DENIED; goto done; } state->clist = ad_gc_conn_list(state, ctx->ad_id_ctx, domain); if (state->clist == NULL) { ret = ENOMEM; goto done; } ret = ad_sdap_access_step(req, state->clist[state->cindex]); if (ret != EOK) { goto done; } ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static errno_t ad_sdap_access_step(struct tevent_req *req, struct sdap_id_conn_ctx *conn) { struct tevent_req *subreq; struct ad_access_state *state; struct sdap_access_ctx *req_ctx; state = tevent_req_data(req, struct ad_access_state); req_ctx = talloc(state, struct sdap_access_ctx); if (req_ctx == NULL) { return ENOMEM; } req_ctx->id_ctx = state->ctx->sdap_access_ctx->id_ctx; req_ctx->filter = state->filter; memcpy(&req_ctx->access_rule, state->ctx->sdap_access_ctx->access_rule, sizeof(int) * LDAP_ACCESS_LAST); subreq = sdap_access_send(state, state->ev, state->be_ctx, state->domain, req_ctx, conn, state->pd); if (req == NULL) { talloc_free(req_ctx); return ENOMEM; } tevent_req_set_callback(subreq, ad_sdap_access_done, req); return EOK; } static void ad_gpo_access_done(struct tevent_req *subreq); static void ad_sdap_access_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_access_state *state; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_access_state); ret = sdap_access_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { switch (ret) { case ERR_ACCOUNT_EXPIRED: tevent_req_error(req, ret); return; case ERR_ACCESS_DENIED: /* Retry on ACCESS_DENIED, too, to make sure that we don't * miss out any attributes not present in GC * FIXME - this is slow. We should retry only if GC failed * and LDAP succeeded after the first ACCESS_DENIED */ break; default: break; } /* If possible, retry with LDAP */ state->cindex++; if (state->clist[state->cindex] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Error retrieving access check result: %s\n", sss_strerror(ret)); tevent_req_error(req, ret); return; } ret = ad_sdap_access_step(req, state->clist[state->cindex]); if (ret != EOK) { tevent_req_error(req, ret); return; } /* Another check in progress */ return; } switch (state->ctx->gpo_access_control_mode) { case GPO_ACCESS_CONTROL_DISABLED: /* do not evaluate gpos; mark request done */ tevent_req_done(req); return; case GPO_ACCESS_CONTROL_PERMISSIVE: case GPO_ACCESS_CONTROL_ENFORCING: /* continue on to evaluate gpos */ break; default: tevent_req_error(req, EINVAL); return; } subreq = ad_gpo_access_send(state, state->be_ctx->ev, state->domain, state->ctx, state->pd->user, state->pd->service); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, ad_gpo_access_done, req); } static void ad_gpo_access_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_access_state *state; errno_t ret; enum gpo_access_control_mode mode; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_access_state); mode = state->ctx->gpo_access_control_mode; ret = ad_gpo_access_recv(subreq); talloc_zfree(subreq); if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "GPO-based access control successful.\n"); tevent_req_done(req); } else { DEBUG(SSSDBG_OP_FAILURE, "GPO-based access control failed.\n"); if (mode == GPO_ACCESS_CONTROL_ENFORCING) { tevent_req_error(req, ret); } else { DEBUG(SSSDBG_OP_FAILURE, "Ignoring error: [%d](%s); GPO-based access control failed, " "but GPO is not in enforcing mode.\n", ret, sss_strerror(ret)); sss_log_ext(SSS_LOG_WARNING, LOG_AUTHPRIV, "Warning: user would " "have been denied GPO-based logon access if the " "ad_gpo_access_control option were set to enforcing mode."); tevent_req_done(req); } } } static errno_t ad_access_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void ad_access_done(struct tevent_req *req); void ad_access_handler(struct be_req *breq) { struct tevent_req *req; struct be_ctx *be_ctx = be_req_get_be_ctx(breq); struct ad_access_ctx *access_ctx = talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data, struct ad_access_ctx); struct pam_data *pd = talloc_get_type(be_req_get_data(breq), struct pam_data); struct sss_domain_info *domain; /* Handle subdomains */ if (strcasecmp(pd->domain, be_ctx->domain->name) != 0) { domain = find_domain_by_name(be_ctx->domain, pd->domain, true); if (domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed.\n"); be_req_terminate(breq, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL); return; } } else { domain = be_ctx->domain; } /* Verify access control: locked accounts, ldap policies, GPOs, etc */ req = ad_access_send(breq, be_ctx->ev, be_ctx, domain, access_ctx, pd); if (!req) { be_req_terminate(breq, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL); return; } tevent_req_set_callback(req, ad_access_done, breq); } static void ad_access_done(struct tevent_req *req) { errno_t ret; struct be_req *breq = tevent_req_callback_data(req, struct be_req); struct pam_data *pd = talloc_get_type(be_req_get_data(breq), struct pam_data); ret = ad_access_recv(req); talloc_zfree(req); switch (ret) { case EOK: pd->pam_status = PAM_SUCCESS; be_req_terminate(breq, DP_ERR_OK, PAM_SUCCESS, NULL); return; case ERR_ACCESS_DENIED: /* We got the proper denial */ pd->pam_status = PAM_PERM_DENIED; be_req_terminate(breq, DP_ERR_OK, PAM_PERM_DENIED, NULL); return; case ERR_ACCOUNT_EXPIRED: pd->pam_status = PAM_ACCT_EXPIRED; be_req_terminate(breq, DP_ERR_OK, PAM_ACCT_EXPIRED, NULL); return; default: /* Something went wrong */ pd->pam_status = PAM_SYSTEM_ERR; be_req_terminate(breq, DP_ERR_FATAL, PAM_SYSTEM_ERR, sss_strerror(ret)); return; } } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_access.h0000644000000000000000000000007412703456111017573 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.692793758 sssd-1.13.4/src/providers/ad/ad_access.h0000644002412700241270000000315312703456111021244 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef AD_ACCESS_H_ #define AD_ACCESS_H_ struct ad_access_ctx { struct dp_option *ad_options; struct sdap_access_ctx *sdap_access_ctx; struct ad_id_ctx *ad_id_ctx; /* supported GPO access control modes */ enum gpo_access_control_mode { GPO_ACCESS_CONTROL_DISABLED, GPO_ACCESS_CONTROL_PERMISSIVE, GPO_ACCESS_CONTROL_ENFORCING } gpo_access_control_mode; int gpo_cache_timeout; /* supported GPO map options */ enum gpo_map_type { GPO_MAP_INTERACTIVE = 0, GPO_MAP_REMOTE_INTERACTIVE, GPO_MAP_NETWORK, GPO_MAP_BATCH, GPO_MAP_SERVICE, GPO_MAP_PERMIT, GPO_MAP_DENY, GPO_MAP_NUM_OPTS } gpo_map_type; hash_table_t *gpo_map_options_table; enum gpo_map_type gpo_default_right; }; void ad_access_handler(struct be_req *breq); #endif /* AD_ACCESS_H_ */ sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_srv.c0000644000000000000000000000007412703456111017137 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.696793771 sssd-1.13.4/src/providers/ad/ad_srv.c0000644002412700241270000006704112703456111020616 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "util/sss_ldap.h" #include "resolv/async_resolv.h" #include "providers/dp_backend.h" #include "providers/ad/ad_srv.h" #include "providers/ad/ad_common.h" #include "providers/fail_over.h" #include "providers/fail_over_srv.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_async.h" #define AD_SITE_DOMAIN_FMT "%s._sites.%s" static errno_t ad_sort_servers_by_dns(TALLOC_CTX *mem_ctx, const char *domain, struct fo_server_info **_srv, size_t num) { struct fo_server_info *out = NULL; struct fo_server_info *srv = NULL; struct fo_server_info in_domain[num]; struct fo_server_info out_domain[num]; size_t srv_index = 0; size_t in_index = 0; size_t out_index = 0; size_t i, j; if (_srv == NULL) { return EINVAL; } srv = *_srv; if (num <= 1) { return EOK; } out = talloc_zero_array(mem_ctx, struct fo_server_info, num); if (out == NULL) { return ENOMEM; } /* When several servers share priority, we will prefer the one that * is located in the same domain as client (e.g. child domain instead * of forest root) but obey their weight. We will use the fact that * the servers are already sorted by priority. */ for (i = 0; i < num; i++) { if (is_host_in_domain(srv[i].host, domain)) { /* this is a preferred server, push it to the in domain list */ in_domain[in_index] = srv[i]; in_index++; } else { /* this is a normal server, push it to the out domain list */ out_domain[out_index] = srv[i]; out_index++; } if (i + 1 == num || srv[i].priority != srv[i + 1].priority) { /* priority has changed or we have reached the end of the srv list, * we will merge the list into final list and start over with * next priority */ for (j = 0; j < in_index; j++) { out[srv_index] = in_domain[j]; talloc_steal(out, out[srv_index].host); srv_index++; } for (j = 0; j < out_index; j++) { out[srv_index] = out_domain[j]; talloc_steal(out, out[srv_index].host); srv_index++; } in_index = 0; out_index = 0; } } talloc_free(*_srv); *_srv = out; return EOK; } struct ad_get_dc_servers_state { struct fo_server_info *servers; size_t num_servers; }; static void ad_get_dc_servers_done(struct tevent_req *subreq); static struct tevent_req *ad_get_dc_servers_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv_ctx, const char *discovery_domain, const char *site) { struct ad_get_dc_servers_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; const char **domains = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ad_get_dc_servers_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } domains = talloc_zero_array(state, const char *, 3); if (domains == NULL) { ret = ENOMEM; goto immediately; } if (site == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "Looking up domain controllers in domain " "%s\n", discovery_domain); domains[0] = talloc_strdup(domains, discovery_domain); if (domains[0] == NULL) { ret = ENOMEM; goto immediately; } } else { DEBUG(SSSDBG_TRACE_FUNC, "Looking up domain controllers in domain " "%s and site %s\n", discovery_domain, site); domains[0] = talloc_asprintf(state, AD_SITE_DOMAIN_FMT, site, discovery_domain); if (domains[0] == NULL) { ret = ENOMEM; goto immediately; } domains[1] = talloc_strdup(domains, discovery_domain); if (domains[1] == NULL) { ret = ENOMEM; goto immediately; } } subreq = fo_discover_srv_send(state, ev, resolv_ctx, "ldap", FO_PROTO_TCP, domains); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, ad_get_dc_servers_done, req); return req; immediately: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void ad_get_dc_servers_done(struct tevent_req *subreq) { struct ad_get_dc_servers_state *state = NULL; struct tevent_req *req = NULL; char *domain = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_get_dc_servers_state); ret = fo_discover_srv_recv(state, subreq, &domain, NULL, &state->servers, &state->num_servers); talloc_zfree(subreq); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Found %zu domain controllers in domain %s\n", state->num_servers, domain); done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static int ad_get_dc_servers_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct fo_server_info **_dcs, size_t *_num_dcs) { struct ad_get_dc_servers_state *state = NULL; state = tevent_req_data(req, struct ad_get_dc_servers_state); TEVENT_REQ_RETURN_ON_ERROR(req); *_dcs = talloc_steal(mem_ctx, state->servers); *_num_dcs = state->num_servers; return EOK; } struct ad_get_client_site_state { struct tevent_context *ev; struct be_resolv_ctx *be_res; enum host_database *host_db; struct sdap_options *opts; const char *ad_domain; struct fo_server_info *dcs; size_t num_dcs; size_t dc_index; struct fo_server_info dc; struct sdap_handle *sh; char *site; char *forest; }; static errno_t ad_get_client_site_next_dc(struct tevent_req *req); static void ad_get_client_site_connect_done(struct tevent_req *subreq); static void ad_get_client_site_done(struct tevent_req *subreq); struct tevent_req *ad_get_client_site_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_resolv_ctx *be_res, enum host_database *host_db, struct sdap_options *opts, const char *ad_domain, struct fo_server_info *dcs, size_t num_dcs) { struct ad_get_client_site_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ad_get_client_site_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } if (be_res == NULL || host_db == NULL || opts == NULL) { ret = EINVAL; goto immediately; } state->ev = ev; state->be_res = be_res; state->host_db = host_db; state->opts = opts; state->ad_domain = ad_domain; state->dcs = dcs; state->num_dcs = num_dcs; state->dc_index = 0; ret = ad_get_client_site_next_dc(req); if (ret == EOK) { ret = ENOENT; goto immediately; } else if (ret != EAGAIN) { goto immediately; } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t ad_get_client_site_next_dc(struct tevent_req *req) { struct ad_get_client_site_state *state = NULL; struct tevent_req *subreq = NULL; errno_t ret; state = tevent_req_data(req, struct ad_get_client_site_state); if (state->dc_index >= state->num_dcs) { ret = EOK; goto done; } state->dc = state->dcs[state->dc_index]; subreq = sdap_connect_host_send(state, state->ev, state->opts, state->be_res->resolv, state->be_res->family_order, state->host_db, "ldap", state->dc.host, state->dc.port, false); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ad_get_client_site_connect_done, req); state->dc_index++; ret = EAGAIN; done: return ret; } static void ad_get_client_site_connect_done(struct tevent_req *subreq) { struct ad_get_client_site_state *state = NULL; struct tevent_req *req = NULL; static const char *attrs[] = {AD_AT_NETLOGON, NULL}; char *filter = NULL; char *ntver = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_get_client_site_state); ret = sdap_connect_host_recv(state, subreq, &state->sh); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to connect to domain controller " "[%s:%d]\n", state->dc.host, state->dc.port); ret = ad_get_client_site_next_dc(req); if (ret == EOK) { ret = ENOENT; } goto done; } ntver = sss_ldap_encode_ndr_uint32(state, NETLOGON_NT_VERSION_5EX | NETLOGON_NT_VERSION_WITH_CLOSEST_SITE); if (ntver == NULL) { ret = ENOMEM; goto done; } filter = talloc_asprintf(state, "(&(%s=%s)(%s=%s))", AD_AT_DNS_DOMAIN, state->ad_domain, AD_AT_NT_VERSION, ntver); if (filter == NULL) { ret = ENOMEM; goto done; } subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, "", LDAP_SCOPE_BASE, filter, attrs, NULL, 0, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ad_get_client_site_done, req); ret = EAGAIN; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static errno_t ad_get_client_site_parse_ndr(TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, char **_site_name, char **_forest_name) { TALLOC_CTX *tmp_ctx = NULL; struct ndr_pull *ndr_pull = NULL; struct netlogon_samlogon_response response; enum ndr_err_code ndr_err; char *site = NULL; char *forest = NULL; DATA_BLOB blob; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } blob.data = data; blob.length = length; ndr_pull = ndr_pull_init_blob(&blob, mem_ctx); if (ndr_pull == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_init_blob() failed.\n"); ret = ENOMEM; goto done; } ndr_err = ndr_pull_netlogon_samlogon_response(ndr_pull, NDR_SCALARS, &response); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_netlogon_samlogon_response() " "failed [%d]\n", ndr_err); ret = EBADMSG; goto done; } if (!(response.ntver & NETLOGON_NT_VERSION_5EX)) { DEBUG(SSSDBG_OP_FAILURE, "This NT version does not provide site " "information [%x]\n", response.ntver); ret = EBADMSG; goto done; } if (response.data.nt5_ex.client_site != NULL && response.data.nt5_ex.client_site[0] != '\0') { site = talloc_strdup(tmp_ctx, response.data.nt5_ex.client_site); } else if (response.data.nt5_ex.next_closest_site != NULL && response.data.nt5_ex.next_closest_site[0] != '\0') { site = talloc_strdup(tmp_ctx, response.data.nt5_ex.next_closest_site); } else { ret = ENOENT; goto done; } if (response.data.nt5_ex.forest != NULL && response.data.nt5_ex.forest[0] != '\0') { forest = talloc_strdup(tmp_ctx, response.data.nt5_ex.forest); } else { ret = ENOENT; goto done; } if (site == NULL || forest == NULL) { ret = ENOMEM; goto done; } *_site_name = talloc_steal(mem_ctx, site); *_forest_name = talloc_steal(mem_ctx, forest); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static void ad_get_client_site_done(struct tevent_req *subreq) { struct ad_get_client_site_state *state = NULL; struct tevent_req *req = NULL; struct ldb_message_element *el = NULL; struct sysdb_attrs **reply = NULL; size_t reply_count; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_get_client_site_state); ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply); talloc_zfree(subreq); /* we're done with this LDAP, close connection */ talloc_zfree(state->sh); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get netlogon information\n"); ret = ad_get_client_site_next_dc(req); if (ret == EOK) { ret = ENOENT; } goto done; } if (reply_count == 0) { DEBUG(SSSDBG_OP_FAILURE, "No netlogon information retrieved\n"); ret = ENOENT; goto done; } ret = sysdb_attrs_get_el(reply[0], AD_AT_NETLOGON, &el); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n"); goto done; } if (el->num_values == 0) { DEBUG(SSSDBG_OP_FAILURE, "netlogon has no value\n"); ret = ENOENT; goto done; } else if (el->num_values > 1) { DEBUG(SSSDBG_OP_FAILURE, "More than one netlogon value?\n"); ret = EIO; goto done; } ret = ad_get_client_site_parse_ndr(state, el->values[0].data, el->values[0].length, &state->site, &state->forest); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve site name [%d]: %s\n", ret, strerror(ret)); ret = ENOENT; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Found site: %s\n", state->site); done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } int ad_get_client_site_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, const char **_site, const char **_forest) { struct ad_get_client_site_state *state = NULL; state = tevent_req_data(req, struct ad_get_client_site_state); TEVENT_REQ_RETURN_ON_ERROR(req); *_site = talloc_steal(mem_ctx, state->site); *_forest = talloc_steal(mem_ctx, state->forest); return EOK; } struct ad_srv_plugin_ctx { struct be_resolv_ctx *be_res; enum host_database *host_dbs; struct sdap_options *opts; const char *hostname; const char *ad_domain; const char *ad_site_override; }; struct ad_srv_plugin_ctx * ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx, struct be_resolv_ctx *be_res, enum host_database *host_dbs, struct sdap_options *opts, const char *hostname, const char *ad_domain, const char *ad_site_override) { struct ad_srv_plugin_ctx *ctx = NULL; ctx = talloc_zero(mem_ctx, struct ad_srv_plugin_ctx); if (ctx == NULL) { return NULL; } ctx->be_res = be_res; ctx->host_dbs = host_dbs; ctx->opts = opts; ctx->hostname = talloc_strdup(ctx, hostname); if (ctx->hostname == NULL) { goto fail; } ctx->ad_domain = talloc_strdup(ctx, ad_domain); if (ctx->ad_domain == NULL) { goto fail; } if (ad_site_override != NULL) { ctx->ad_site_override = talloc_strdup(ctx, ad_site_override); if (ctx->ad_site_override == NULL) { goto fail; } } return ctx; fail: talloc_free(ctx); return NULL; } struct ad_srv_plugin_state { struct tevent_context *ev; struct ad_srv_plugin_ctx *ctx; const char *service; const char *protocol; const char *discovery_domain; const char *site; char *dns_domain; uint32_t ttl; const char *forest; struct fo_server_info *primary_servers; size_t num_primary_servers; struct fo_server_info *backup_servers; size_t num_backup_servers; }; static void ad_srv_plugin_dcs_done(struct tevent_req *subreq); static void ad_srv_plugin_site_done(struct tevent_req *subreq); static void ad_srv_plugin_servers_done(struct tevent_req *subreq); /* 1. Do a DNS lookup to find any DC in domain * _ldap._tcp.domain.name * 2. Send a CLDAP ping to the found DC to get the desirable site * 3. Do a DNS lookup to find SRV in the site (a) * _service._protocol.site-name._sites.domain.name * 4. Do a DNS lookup to find global SRV records (b) * _service._protocol.domain.name * 5. If the site is found, use (a) as primary and (b) as backup servers, * otherwise use (b) as primary servers */ struct tevent_req *ad_srv_plugin_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *service, const char *protocol, const char *discovery_domain, void *pvt) { struct ad_srv_plugin_state *state = NULL; struct ad_srv_plugin_ctx *ctx = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ad_srv_plugin_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } ctx = talloc_get_type(pvt, struct ad_srv_plugin_ctx); if (ctx == NULL) { ret = EINVAL; goto immediately; } state->ev = ev; state->ctx = ctx; state->service = talloc_strdup(state, service); if (state->service == NULL) { ret = ENOMEM; goto immediately; } state->protocol = talloc_strdup(state, protocol); if (state->protocol == NULL) { ret = ENOMEM; goto immediately; } if (discovery_domain != NULL) { state->discovery_domain = talloc_strdup(state, discovery_domain); } else { state->discovery_domain = talloc_strdup(state, ctx->ad_domain); } if (state->discovery_domain == NULL) { ret = ENOMEM; goto immediately; } DEBUG(SSSDBG_TRACE_FUNC, "About to find domain controllers\n"); subreq = ad_get_dc_servers_send(state, ev, ctx->be_res->resolv, state->discovery_domain, state->ctx->ad_site_override); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, ad_srv_plugin_dcs_done, req); return req; immediately: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void ad_srv_plugin_dcs_done(struct tevent_req *subreq) { struct ad_srv_plugin_state *state = NULL; struct tevent_req *req = NULL; struct fo_server_info *dcs = NULL; size_t num_dcs = 0; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_srv_plugin_state); ret = ad_get_dc_servers_recv(state, subreq, &dcs, &num_dcs); talloc_zfree(subreq); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "About to locate suitable site\n"); subreq = ad_get_client_site_send(state, state->ev, state->ctx->be_res, state->ctx->host_dbs, state->ctx->opts, state->discovery_domain, dcs, num_dcs); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ad_srv_plugin_site_done, req); ret = EAGAIN; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static void ad_srv_plugin_site_done(struct tevent_req *subreq) { struct ad_srv_plugin_state *state = NULL; struct tevent_req *req = NULL; const char *primary_domain = NULL; const char *backup_domain = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_srv_plugin_state); ret = ad_get_client_site_recv(state, subreq, &state->site, &state->forest); talloc_zfree(subreq); /* Ignore AD site found by dns discovery if specific site is set in * configuration file. */ if (state->ctx->ad_site_override != NULL) { DEBUG(SSSDBG_TRACE_INTERNAL, "Ignoring AD site found by DNS discovery: '%s', " "using configured value: '%s' instead.\n", state->site, state->ctx->ad_site_override); state->site = state->ctx->ad_site_override; if (state->forest == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "Missing forest information, using %s\n", state->discovery_domain); state->forest = state->discovery_domain; } ret = EOK; } if (ret == EOK) { if (strcmp(state->service, "gc") == 0) { primary_domain = talloc_asprintf(state, AD_SITE_DOMAIN_FMT, state->site, state->forest); if (primary_domain == NULL) { ret = ENOMEM; goto done; } backup_domain = state->forest; } else { primary_domain = talloc_asprintf(state, AD_SITE_DOMAIN_FMT, state->site, state->discovery_domain); if (primary_domain == NULL) { ret = ENOMEM; goto done; } backup_domain = state->discovery_domain; } } else if (ret == ENOENT) { primary_domain = state->discovery_domain; backup_domain = NULL; } else { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "About to discover primary and " "backup servers\n"); subreq = fo_discover_servers_send(state, state->ev, state->ctx->be_res->resolv, state->service, state->protocol, primary_domain, backup_domain); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ad_srv_plugin_servers_done, req); ret = EAGAIN; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static void ad_srv_plugin_servers_done(struct tevent_req *subreq) { struct ad_srv_plugin_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_srv_plugin_state); ret = fo_discover_servers_recv(state, subreq, &state->dns_domain, &state->ttl, &state->primary_servers, &state->num_primary_servers, &state->backup_servers, &state->num_backup_servers); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_FUNC, "Got %zu primary and %zu backup servers\n", state->num_primary_servers, state->num_backup_servers); ret = ad_sort_servers_by_dns(state, state->discovery_domain, &state->primary_servers, state->num_primary_servers); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to sort primary servers by DNS" "[%d]: %s\n", ret, sss_strerror(ret)); /* continue */ } ret = ad_sort_servers_by_dns(state, state->discovery_domain, &state->backup_servers, state->num_backup_servers); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to sort backup servers by DNS" "[%d]: %s\n", ret, sss_strerror(ret)); /* continue */ } tevent_req_done(req); } errno_t ad_srv_plugin_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain, uint32_t *_ttl, struct fo_server_info **_primary_servers, size_t *_num_primary_servers, struct fo_server_info **_backup_servers, size_t *_num_backup_servers) { struct ad_srv_plugin_state *state = NULL; state = tevent_req_data(req, struct ad_srv_plugin_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_primary_servers) { *_primary_servers = talloc_steal(mem_ctx, state->primary_servers); } if (_num_primary_servers) { *_num_primary_servers = state->num_primary_servers; } if (_backup_servers) { *_backup_servers = talloc_steal(mem_ctx, state->backup_servers); } if (_num_backup_servers) { *_num_backup_servers = state->num_backup_servers; } if (_dns_domain) { *_dns_domain = talloc_steal(mem_ctx, state->dns_domain); } if (_ttl) { *_ttl = state->ttl; } return EOK; } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_dyndns.c0000644000000000000000000000007412703456111017624 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.688793744 sssd-1.13.4/src/providers/ad/ad_dyndns.c0000644002412700241270000002127412703456111021301 0ustar00jhrozekjhrozek00000000000000/* SSSD ad_dyndns.c Authors: Jakub Hrozek Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "providers/ldap/sdap_dyndns.h" #include "providers/data_provider.h" #include "providers/dp_dyndns.h" #include "providers/ad/ad_common.h" void ad_dyndns_update(void *pvt); errno_t ad_dyndns_init(struct be_ctx *be_ctx, struct ad_options *ad_opts) { errno_t ret; /* nsupdate is available. Dynamic updates * are supported */ ret = ad_get_dyndns_options(be_ctx, ad_opts); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set AD options\n"); return ret; } if (dp_opt_get_bool(ad_opts->dyndns_ctx->opts, DP_OPT_DYNDNS_UPDATE) == false) { DEBUG(SSSDBG_CONF_SETTINGS, "Dynamic DNS updates not set\n"); return EOK; } DEBUG(SSSDBG_CONF_SETTINGS, "Dynamic DNS updates are on. Checking for nsupdate..\n"); ret = be_nsupdate_check(); if (ret == ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "DNS updates requested but nsupdate not available\n"); return EOK; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not check for nsupdate\n"); return ret; } ad_opts->be_res = be_ctx->be_res; if (ad_opts->be_res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Resolver must be initialized in order " "to use the AD dynamic DNS updates\n"); return EINVAL; } ret = be_nsupdate_init_timer(ad_opts->dyndns_ctx, be_ctx->ev, ad_dyndns_timer, ad_opts); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up periodic update\n"); return ret; } ret = be_add_online_cb(be_ctx, be_ctx, ad_dyndns_update, ad_opts, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up online callback\n"); return ret; } return EOK; } static void ad_dyndns_timer_connected(struct tevent_req *req); void ad_dyndns_timer(void *pvt) { struct ad_options *ctx = talloc_get_type(pvt, struct ad_options); struct sdap_id_ctx *sdap_ctx = ctx->id_ctx->sdap_id_ctx; struct tevent_req *req; req = sdap_dyndns_timer_conn_send(ctx, sdap_ctx->be->ev, sdap_ctx, ctx->dyndns_ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); /* Not much we can do. Just attempt to reschedule */ be_nsupdate_timer_schedule(sdap_ctx->be->ev, ctx->dyndns_ctx); return; } tevent_req_set_callback(req, ad_dyndns_timer_connected, ctx); } static void ad_dyndns_timer_connected(struct tevent_req *req) { errno_t ret; struct ad_options *ctx = tevent_req_callback_data(req, struct ad_options); ret = sdap_dyndns_timer_conn_recv(req); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to AD: [%d](%s)\n", ret, sss_strerror(ret)); return; } return ad_dyndns_update(ctx); } static struct tevent_req *ad_dyndns_update_send(struct ad_options *ctx); static errno_t ad_dyndns_update_recv(struct tevent_req *req); static void ad_dyndns_nsupdate_done(struct tevent_req *req); void ad_dyndns_update(void *pvt) { struct ad_options *ctx = talloc_get_type(pvt, struct ad_options); struct sdap_id_ctx *sdap_ctx = ctx->id_ctx->sdap_id_ctx; struct tevent_req *req; /* Schedule timer after provider went offline */ be_nsupdate_timer_schedule(sdap_ctx->be->ev, ctx->dyndns_ctx); req = ad_dyndns_update_send(ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not update DNS\n"); return; } tevent_req_set_callback(req, ad_dyndns_nsupdate_done, NULL); } static void ad_dyndns_nsupdate_done(struct tevent_req *req) { int ret = ad_dyndns_update_recv(req); talloc_free(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Updating DNS entry failed [%d]: %s\n", ret, sss_strerror(ret)); return; } DEBUG(SSSDBG_TRACE_FUNC, "DNS update finished\n"); } struct ad_dyndns_update_state { struct ad_options *ad_ctx; const char *servername; }; static void ad_dyndns_sdap_update_done(struct tevent_req *subreq); static struct tevent_req * ad_dyndns_update_send(struct ad_options *ctx) { int ret; struct ad_dyndns_update_state *state; struct tevent_req *req, *subreq; struct sdap_id_ctx *sdap_ctx = ctx->id_ctx->sdap_id_ctx; LDAPURLDesc *lud; DEBUG(SSSDBG_TRACE_FUNC, "Performing update\n"); req = tevent_req_create(ctx, &state, struct ad_dyndns_update_state); if (req == NULL) { return NULL; } state->ad_ctx = ctx; if (ctx->dyndns_ctx->last_refresh + 60 > time(NULL) || ctx->dyndns_ctx->timer_in_progress) { DEBUG(SSSDBG_FUNC_DATA, "Last periodic update ran recently or timer " "in progress, not scheduling another update\n"); tevent_req_done(req); tevent_req_post(req, sdap_ctx->be->ev); return req; } state->ad_ctx->dyndns_ctx->last_refresh = time(NULL); ret = ldap_url_parse(ctx->service->sdap->uri, &lud); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse ldap URI (%s)!\n", ctx->service->sdap->uri); ret = EINVAL; goto done; } if (lud->lud_scheme != NULL && strcasecmp(lud->lud_scheme, "ldapi") == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "The LDAP scheme is ldapi://, cannot proceed with update\n"); ldap_free_urldesc(lud); ret = EINVAL; goto done; } if (lud->lud_host == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "The LDAP URI (%s) did not contain a host name\n", ctx->service->sdap->uri); ldap_free_urldesc(lud); ret = EINVAL; goto done; } state->servername = talloc_strdup(state, lud->lud_host); ldap_free_urldesc(lud); if (!state->servername) { ret = ENOMEM; goto done; } subreq = sdap_dyndns_update_send(state, sdap_ctx->be->ev, sdap_ctx->be, ctx->dyndns_ctx->opts, sdap_ctx, ctx->dyndns_ctx->auth_type, dp_opt_get_string(ctx->dyndns_ctx->opts, DP_OPT_DYNDNS_IFACE), dp_opt_get_string(ctx->basic, AD_HOSTNAME), dp_opt_get_string(ctx->basic, AD_KRB5_REALM), state->servername, dp_opt_get_int(ctx->dyndns_ctx->opts, DP_OPT_DYNDNS_TTL), false); if (!subreq) { ret = EIO; DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } tevent_req_set_callback(subreq, ad_dyndns_sdap_update_done, req); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, sdap_ctx->be->ev); } return req; } static void ad_dyndns_sdap_update_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); errno_t ret; ret = sdap_dyndns_update_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Dynamic DNS update failed [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t ad_dyndns_update_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_gpo.c0000644000000000000000000000007412703456111017112 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.693793761 sssd-1.13.4/src/providers/ad/ad_gpo.c0000644002412700241270000043110712703456111020567 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Yassir Elley Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* * This file implements the following pair of *public* functions (see header): * ad_gpo_access_send/recv: provides client-side GPO processing * * This file also implements the following pairs of *private* functions (which * are used by the public functions): * ad_gpo_process_som_send/recv: populate list of gp_som objects * ad_gpo_process_gpo_send/recv: populate list of gp_gpo objects * ad_gpo_process_cse_send/recv: retrieve policy file data */ #include #include #include #include #include "util/util.h" #include "util/strtonum.h" #include "util/child_common.h" #include "providers/data_provider.h" #include "providers/dp_backend.h" #include "providers/ad/ad_access.h" #include "providers/ad/ad_common.h" #include "providers/ad/ad_domain_info.h" #include "providers/ad/ad_gpo.h" #include "providers/ldap/sdap_access.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_idmap.h" #include "util/util_sss_idmap.h" #include #include /* == gpo-ldap constants =================================================== */ #define AD_AT_DN "distinguishedName" #define AD_AT_UAC "userAccountControl" #define AD_AT_CONFIG_NC "configurationNamingContext" #define AD_AT_GPLINK "gPLink" #define AD_AT_GPOPTIONS "gpOptions" #define AD_AT_NT_SEC_DESC "nTSecurityDescriptor" #define AD_AT_CN "cn" #define AD_AT_FILE_SYS_PATH "gPCFileSysPath" #define AD_AT_MACHINE_EXT_NAMES "gPCMachineExtensionNames" #define AD_AT_FUNC_VERSION "gPCFunctionalityVersion" #define AD_AT_FLAGS "flags" #define UAC_WORKSTATION_TRUST_ACCOUNT 0x00001000 #define AD_AGP_GUID "edacfd8f-ffb3-11d1-b41d-00a0c968f939" #define AD_AUTHENTICATED_USERS_SID "S-1-5-11" /* == gpo-smb constants ==================================================== */ #define SMB_STANDARD_URI "smb://" #define BUFSIZE 65536 #define RIGHTS_SECTION "Privilege Rights" #define ALLOW_LOGON_INTERACTIVE "SeInteractiveLogonRight" #define DENY_LOGON_INTERACTIVE "SeDenyInteractiveLogonRight" #define ALLOW_LOGON_REMOTE_INTERACTIVE "SeRemoteInteractiveLogonRight" #define DENY_LOGON_REMOTE_INTERACTIVE "SeDenyRemoteInteractiveLogonRight" #define ALLOW_LOGON_NETWORK "SeNetworkLogonRight" #define DENY_LOGON_NETWORK "SeDenyNetworkLogonRight" #define ALLOW_LOGON_BATCH "SeBatchLogonRight" #define DENY_LOGON_BATCH "SeDenyBatchLogonRight" #define ALLOW_LOGON_SERVICE "SeServiceLogonRight" #define DENY_LOGON_SERVICE "SeDenyServiceLogonRight" #define GP_EXT_GUID_SECURITY "{827D319E-6EAC-11D2-A4EA-00C04F79F83A}" #define GP_EXT_GUID_SECURITY_SUFFIX "/Machine/Microsoft/Windows NT/SecEdit/GptTmpl.inf" #ifndef SSSD_LIBEXEC_PATH #error "SSSD_LIBEXEC_PATH not defined" #else #define GPO_CHILD SSSD_LIBEXEC_PATH"/gpo_child" #endif /* fd used by the gpo_child process for logging */ int gpo_child_debug_fd = -1; /* == common data structures and declarations ============================= */ struct gp_som { const char *som_dn; struct gp_gplink **gplink_list; int num_gplinks; }; struct gp_gplink { const char *gpo_dn; bool enforced; }; struct gp_gpo { struct security_descriptor *gpo_sd; const char *gpo_dn; const char *gpo_guid; const char *smb_server; const char *smb_share; const char *smb_path; const char **gpo_cse_guids; int num_gpo_cse_guids; int gpo_func_version; int gpo_flags; bool send_to_child; const char *policy_filename; }; enum ace_eval_status { AD_GPO_ACE_DENIED, AD_GPO_ACE_ALLOWED, AD_GPO_ACE_NEUTRAL }; struct tevent_req *ad_gpo_process_som_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_conn_ctx *conn, struct ldb_context *ldb_ctx, struct sdap_id_op *sdap_op, struct sdap_options *opts, int timeout, const char *target_dn, const char *domain_name); int ad_gpo_process_som_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct gp_som ***som_list); struct tevent_req * ad_gpo_process_gpo_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_op *sdap_op, struct sdap_options *opts, char *server_hostname, struct sss_domain_info *host_domain, struct ad_access_ctx *access_ctx, int timeout, struct gp_som **som_list); int ad_gpo_process_gpo_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct gp_gpo ***candidate_gpos, int *num_candidate_gpos); struct tevent_req *ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, bool send_to_child, struct sss_domain_info *domain, const char *gpo_guid, const char *smb_server, const char *smb_share, const char *smb_path, const char *smb_cse_suffix, int cached_gpt_version, int gpo_timeout_option); int ad_gpo_process_cse_recv(struct tevent_req *req); /* == ad_gpo_parse_map_options and helpers ==================================*/ #define GPO_LOGIN "login" #define GPO_SU "su" #define GPO_SU_L "su-l" #define GPO_GDM_FINGERPRINT "gdm-fingerprint" #define GPO_GDM_PASSWORD "gdm-password" #define GPO_GDM_SMARTCARD "gdm-smartcard" #define GPO_KDM "kdm" #define GPO_LIGHTDM "lightdm" #define GPO_LXDM "lxdm" #define GPO_SDDM "sddm" #define GPO_XDM "xdm" #define GPO_SSHD "sshd" #define GPO_FTP "ftp" #define GPO_SAMBA "samba" #define GPO_CROND "crond" #define GPO_SUDO "sudo" #define GPO_SUDO_I "sudo-i" #define GPO_SYSTEMD_USER "systemd-user" #define GPO_COCKPIT "cockpit" struct gpo_map_option_entry { enum gpo_map_type gpo_map_type; enum ad_basic_opt ad_basic_opt; const char **gpo_map_defaults; const char *allow_key; const char *deny_key; }; const char *gpo_map_interactive_defaults[] = {GPO_LOGIN, GPO_SU, GPO_SU_L, GPO_GDM_FINGERPRINT, GPO_GDM_PASSWORD, GPO_GDM_SMARTCARD, GPO_KDM, GPO_LIGHTDM, GPO_LXDM, GPO_SDDM, GPO_XDM, NULL}; const char *gpo_map_remote_interactive_defaults[] = {GPO_SSHD, GPO_COCKPIT, NULL}; const char *gpo_map_network_defaults[] = {GPO_FTP, GPO_SAMBA, NULL}; const char *gpo_map_batch_defaults[] = {GPO_CROND, NULL}; const char *gpo_map_service_defaults[] = {NULL}; const char *gpo_map_permit_defaults[] = {GPO_SUDO, GPO_SUDO_I, GPO_SYSTEMD_USER, NULL}; const char *gpo_map_deny_defaults[] = {NULL}; struct gpo_map_option_entry gpo_map_option_entries[] = { {GPO_MAP_INTERACTIVE, AD_GPO_MAP_INTERACTIVE, gpo_map_interactive_defaults, ALLOW_LOGON_INTERACTIVE, DENY_LOGON_INTERACTIVE}, {GPO_MAP_REMOTE_INTERACTIVE, AD_GPO_MAP_REMOTE_INTERACTIVE, gpo_map_remote_interactive_defaults, ALLOW_LOGON_REMOTE_INTERACTIVE, DENY_LOGON_REMOTE_INTERACTIVE}, {GPO_MAP_NETWORK, AD_GPO_MAP_NETWORK, gpo_map_network_defaults, ALLOW_LOGON_NETWORK, DENY_LOGON_NETWORK}, {GPO_MAP_BATCH, AD_GPO_MAP_BATCH, gpo_map_batch_defaults, ALLOW_LOGON_BATCH, DENY_LOGON_BATCH}, {GPO_MAP_SERVICE, AD_GPO_MAP_SERVICE, gpo_map_service_defaults, ALLOW_LOGON_SERVICE, DENY_LOGON_SERVICE}, {GPO_MAP_PERMIT, AD_GPO_MAP_PERMIT, gpo_map_permit_defaults, NULL, NULL}, {GPO_MAP_DENY, AD_GPO_MAP_DENY, gpo_map_deny_defaults, NULL, NULL}, }; const char* gpo_map_type_string(int gpo_map_type) { switch(gpo_map_type) { case GPO_MAP_INTERACTIVE: return "Interactive"; case GPO_MAP_REMOTE_INTERACTIVE: return "Remote Interactive"; case GPO_MAP_NETWORK: return "Network"; case GPO_MAP_BATCH: return "Batch"; case GPO_MAP_SERVICE: return "Service"; case GPO_MAP_PERMIT: return "Permitted"; case GPO_MAP_DENY: return "Denied"; } return NULL; } static inline bool ad_gpo_service_in_list(char **list, size_t nlist, const char *str) { size_t i; for (i = 0; i < nlist; i++) { if (strcasecmp(list[i], str) == 0) { break; } } return (i < nlist) ? true : false; } errno_t ad_gpo_parse_map_option_helper(enum gpo_map_type gpo_map_type, hash_key_t key, hash_table_t *options_table) { hash_value_t val; int hret; int ret; hret = hash_lookup(options_table, &key, &val); if (hret != HASH_SUCCESS && hret != HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_OP_FAILURE, "Error checking hash table: [%s]\n", hash_error_string(hret)); ret = EINVAL; goto done; } else if (hret == HASH_SUCCESS) { /* handle unexpected case where mapping for key already exists */ if (val.i == gpo_map_type) { /* mapping for key exists for same map type; no error */ DEBUG(SSSDBG_TRACE_FUNC, "PAM service %s maps to %s multiple times\n", key.str, gpo_map_type_string(gpo_map_type)); ret = EOK; } else { /* mapping for key exists for different map type; error! */ DEBUG(SSSDBG_CRIT_FAILURE, "PAM service %s maps to both %s and %s\n", key.str, gpo_map_type_string(val.i), gpo_map_type_string(gpo_map_type)); ret = EINVAL; } goto done; } else { /* handle expected case where mapping for key doesn't already exist */ val.type = HASH_VALUE_INT; val.i = gpo_map_type; hret = hash_enter(options_table, &key, &val); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Error checking hash table: [%s]\n", hash_error_string(hret)); ret = EIO; goto done; } ret = EOK; } done: return ret; } errno_t ad_gpo_parse_map_option(TALLOC_CTX *mem_ctx, enum gpo_map_type gpo_map_type, hash_table_t *options_table, char *conf_str, const char **defaults) { TALLOC_CTX *tmp_ctx; errno_t ret; char **conf_list = NULL; int conf_list_size = 0; char **add_list = NULL; char **remove_list = NULL; int ai = 0, ri = 0; int i; hash_key_t key; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_ALL, "gpo_map_type: %s\n", gpo_map_type_string(gpo_map_type)); if (conf_str) { ret = split_on_separator(tmp_ctx, conf_str, ',', true, true, &conf_list, &conf_list_size); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot parse list of service names %s: %d\n", conf_str, ret); ret = EINVAL; goto done; } add_list = talloc_zero_array(tmp_ctx, char *, conf_list_size); remove_list = talloc_zero_array(tmp_ctx, char *, conf_list_size); if (add_list == NULL || remove_list == NULL) { ret = ENOMEM; goto done; } } for (i = 0; i < conf_list_size; i++) { switch (conf_list[i][0]) { case '+': add_list[ai] = conf_list[i] + 1; ai++; continue; case '-': remove_list[ri] = conf_list[i] + 1; ri++; continue; default: DEBUG(SSSDBG_CRIT_FAILURE, "ad_gpo_map values must start with" "either '+' (for adding service) or '-' (for removing service), " "got '%s'\n", conf_list[i]); ret = EINVAL; goto done; } } /* Start by adding explicitly added services ('+') to hashtable */ for (i = 0; i < ai; i++) { /* if the service is explicitly configured to be removed, skip it */ if (ad_gpo_service_in_list(remove_list, ri, add_list[i])) { continue; } key.type = HASH_KEY_STRING; key.str = (char *)add_list[i]; ret = ad_gpo_parse_map_option_helper(gpo_map_type, key, options_table); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Invalid configuration: %d\n", ret); goto done; } DEBUG(SSSDBG_TRACE_ALL, "Explicitly added service: %s\n", key.str); } /* Add defaults to hashtable */ for (i = 0; defaults[i]; i++) { /* if the service is explicitly configured to be removed, skip it */ if (ad_gpo_service_in_list(remove_list, ri, defaults[i])) { continue; } key.type = HASH_KEY_STRING; key.str = talloc_strdup(mem_ctx, defaults[i]); ret = ad_gpo_parse_map_option_helper(gpo_map_type, key, options_table); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Invalid configuration: %d\n", ret); goto done; } DEBUG(SSSDBG_TRACE_ALL, "Default service (not explicitly removed): %s\n", key.str); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t ad_gpo_parse_map_options(struct ad_access_ctx *access_ctx) { char *gpo_default_right_config; enum gpo_map_type gpo_default_right; errno_t ret; int i; for (i = 0; i < GPO_MAP_NUM_OPTS; i++) { struct gpo_map_option_entry entry = gpo_map_option_entries[i]; char *entry_config = dp_opt_get_string(access_ctx->ad_options, entry.ad_basic_opt); ret = ad_gpo_parse_map_option(access_ctx, entry.gpo_map_type, access_ctx->gpo_map_options_table, entry_config, entry.gpo_map_defaults); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Invalid configuration: %d\n", ret); ret = EINVAL; goto fail; } } /* default right (applicable for services without any mapping) */ gpo_default_right_config = dp_opt_get_string(access_ctx->ad_options, AD_GPO_DEFAULT_RIGHT); DEBUG(SSSDBG_TRACE_ALL, "gpo_default_right_config: %s\n", gpo_default_right_config); /* if default right not set in config, set them to DENY */ if (gpo_default_right_config == NULL) { gpo_default_right = GPO_MAP_DENY; } else if (strncasecmp(gpo_default_right_config, "interactive", strlen("interactive")) == 0) { gpo_default_right = GPO_MAP_INTERACTIVE; } else if (strncasecmp(gpo_default_right_config, "remote_interactive", strlen("remote_interactive")) == 0) { gpo_default_right = GPO_MAP_REMOTE_INTERACTIVE; } else if (strncasecmp(gpo_default_right_config, "network", strlen("network")) == 0) { gpo_default_right = GPO_MAP_NETWORK; } else if (strncasecmp(gpo_default_right_config, "batch", strlen("batch")) == 0) { gpo_default_right = GPO_MAP_BATCH; } else if (strncasecmp(gpo_default_right_config, "service", strlen("service")) == 0) { gpo_default_right = GPO_MAP_SERVICE; } else if (strncasecmp(gpo_default_right_config, "permit", strlen("permit")) == 0) { gpo_default_right = GPO_MAP_PERMIT; } else if (strncasecmp(gpo_default_right_config, "deny", strlen("deny")) == 0) { gpo_default_right = GPO_MAP_DENY; } else { ret = EINVAL; goto fail; } DEBUG(SSSDBG_TRACE_ALL, "gpo_default_right: %d\n", gpo_default_right); access_ctx->gpo_default_right = gpo_default_right; fail: return ret; } /* == ad_gpo_access_send/recv helpers =======================================*/ static bool ad_gpo_dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2) { int i; if (sid1 == sid2) { return true; } if (!sid1 || !sid2) { return false; } if (sid1->sid_rev_num != sid2->sid_rev_num) { return false; } for (i = 0; i < 6; i++) { if (sid1->id_auth[i] != sid2->id_auth[i]) { return false; } } if (sid1->num_auths != sid2->num_auths) { return false; } for (i = 0; i < sid1->num_auths; i++) { if (sid1->sub_auths[i] != sid2->sub_auths[i]) { return false; } } return true; } /* * This function retrieves the SIDs corresponding to the input user and returns * the user_sid, group_sids, and group_size in their respective output params. * * Note: since authentication must complete successfully before the * gpo access checks are called, we can safely assume that the user/computer * has been authenticated. As such, this function always adds the * AD_AUTHENTICATED_USERS_SID to the group_sids. */ static errno_t ad_gpo_get_sids(TALLOC_CTX *mem_ctx, const char *user, struct sss_domain_info *domain, const char **_user_sid, const char ***_group_sids, int *_group_size) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_result *res; int ret = 0; int i = 0; int num_group_sids = 0; const char *user_sid = NULL; const char *group_sid = NULL; const char **group_sids = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } /* first result from sysdb_initgroups is user_sid; rest are group_sids */ ret = sysdb_initgroups(tmp_ctx, domain, user, &res); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_initgroups failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } if (res->count == 0) { ret = ENOENT; DEBUG(SSSDBG_OP_FAILURE, "sysdb_initgroups returned empty result\n"); goto done; } user_sid = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SID_STR, NULL); num_group_sids = (res->count) - 1; /* include space for AD_AUTHENTICATED_USERS_SID and NULL */ group_sids = talloc_array(tmp_ctx, const char *, num_group_sids + 1 + 1); if (group_sids == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < num_group_sids; i++) { group_sid = ldb_msg_find_attr_as_string(res->msgs[i+1], SYSDB_SID_STR, NULL); if (group_sid == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing SID for cache entry [%s].\n", ldb_dn_get_linearized(res->msgs[i+1]->dn)); ret = EINVAL; goto done; } group_sids[i] = talloc_steal(group_sids, group_sid); if (group_sids[i] == NULL) { ret = ENOMEM; goto done; } } group_sids[i++] = talloc_strdup(group_sids, AD_AUTHENTICATED_USERS_SID); group_sids[i] = NULL; *_group_size = num_group_sids + 1; *_group_sids = talloc_steal(mem_ctx, group_sids); *_user_sid = talloc_steal(mem_ctx, user_sid); ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* * This function determines whether the input ace_dom_sid matches any of the * client's SIDs. The boolean result is assigned to the _included output param. */ static errno_t ad_gpo_ace_includes_client_sid(const char *user_sid, const char **group_sids, int group_size, struct dom_sid ace_dom_sid, struct sss_idmap_ctx *idmap_ctx, bool *_included) { int i = 0; struct dom_sid *user_dom_sid; struct dom_sid *group_dom_sid; enum idmap_error_code err; bool included = false; err = sss_idmap_sid_to_smb_sid(idmap_ctx, user_sid, &user_dom_sid); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize idmap context.\n"); return EFAULT; } included = ad_gpo_dom_sid_equal(&ace_dom_sid, user_dom_sid); sss_idmap_free_smb_sid(idmap_ctx, user_dom_sid); if (included) { *_included = true; return EOK; } for (i = 0; i < group_size; i++) { err = sss_idmap_sid_to_smb_sid(idmap_ctx, group_sids[i], &group_dom_sid); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize idmap context.\n"); return EFAULT; } included = ad_gpo_dom_sid_equal(&ace_dom_sid, group_dom_sid); sss_idmap_free_smb_sid(idmap_ctx, group_dom_sid); if (included) { *_included = true; return EOK; } } *_included = false; return EOK; } /* * This function determines whether use of the extended right * named "ApplyGroupPolicy" (AGP) is allowed, by comparing the specified * user_sid and group_sids against the specified access control entry (ACE). * This function returns ALLOWED, DENIED, or NEUTRAL depending on whether * the ACE explictly allows, explicitly denies, or does neither. * * Note that the 'M' abbreviation used in the evaluation algorithm stands for * "access_mask", which represents the set of access rights associated with an * individual ACE. The access right of interest to the GPO code is * RIGHT_DS_CONTROL_ACCESS, which serves as a container for all control access * rights. The specific control access right is identified by a GUID in the * ACE's ObjectType. In our case, this is the GUID corresponding to AGP. * * The ACE evaluation algorithm is specified in [MS-ADTS] 5.1.3.3.4: * - Deny access by default * - If the "Inherit Only" (IO) flag is set in the ACE, skip the ACE. * - If the SID in the ACE does not match any SID in the requester's * security context, skip the ACE * - If the ACE type is "Object Access Allowed", the access right * RIGHT_DS_CONTROL_ACCESS (CR) is present in M, and the ObjectType * field in the ACE is either not present OR contains a GUID value equal * to AGP, then grant requested control access right. Stop access checking. * - If the ACE type is "Object Access Denied", the access right * RIGHT_DS_CONTROL_ACCESS (CR) is present in M, and the ObjectType * field in the ACE is either not present OR contains a GUID value equal to * AGP, then deny the requested control access right. Stop access checking. */ static enum ace_eval_status ad_gpo_evaluate_ace(struct security_ace *ace, struct sss_idmap_ctx *idmap_ctx, const char *user_sid, const char **group_sids, int group_size) { bool agp_included = false; bool included = false; int ret = 0; struct security_ace_object object; struct GUID ext_right_agp_guid; if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { return AD_GPO_ACE_NEUTRAL; } ret = ad_gpo_ace_includes_client_sid(user_sid, group_sids, group_size, ace->trustee, idmap_ctx, &included); if (ret != EOK) { return AD_GPO_ACE_DENIED; } if (!included) { return AD_GPO_ACE_NEUTRAL; } object = ace->object.object; GUID_from_string(AD_AGP_GUID, &ext_right_agp_guid); if (object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) { if (GUID_equal(&object.type.type, &ext_right_agp_guid)) { agp_included = true; } } else { agp_included = false; } if (ace->access_mask & SEC_ADS_CONTROL_ACCESS) { if (agp_included) { if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) { return AD_GPO_ACE_ALLOWED; } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT) { return AD_GPO_ACE_DENIED; } } } return AD_GPO_ACE_DENIED; } /* * This function extracts the GPO's DACL (discretionary access control list) * from the GPO's specified security descriptor, and determines whether * the GPO is applicable to the policy target, by comparing the specified * user_sid and group_sids against each access control entry (ACE) in the DACL. * The boolean result is assigned to the _access_allowed output parameter. */ static errno_t ad_gpo_evaluate_dacl(struct security_acl *dacl, struct sss_idmap_ctx *idmap_ctx, const char *user_sid, const char **group_sids, int group_size, bool *_dacl_access_allowed) { uint32_t num_aces = 0; enum ace_eval_status ace_status; int i = 0; struct security_ace *ace = NULL; num_aces = dacl->num_aces; /* * [MS-ADTS] 5.1.3.3.4: * If the DACL does not have any ACE, then deny the requester the * requested control access right. */ if (num_aces == 0) { *_dacl_access_allowed = false; return EOK; } for (i = 0; i < dacl->num_aces; i ++) { ace = &dacl->aces[i]; ace_status = ad_gpo_evaluate_ace(ace, idmap_ctx, user_sid, group_sids, group_size); switch (ace_status) { case AD_GPO_ACE_NEUTRAL: continue; case AD_GPO_ACE_ALLOWED: *_dacl_access_allowed = true; return EOK; case AD_GPO_ACE_DENIED: *_dacl_access_allowed = false; return EOK; } } *_dacl_access_allowed = false; return EOK; } /* * This function takes candidate_gpos as input, filters out any gpo that is * not applicable to the policy target and assigns the result to the * _dacl_filtered_gpos output parameter. The filtering algorithm is * defined in [MS-GPOL] 3.2.5.1.6 */ static errno_t ad_gpo_filter_gpos_by_dacl(TALLOC_CTX *mem_ctx, const char *user, struct sss_domain_info *domain, struct sss_idmap_ctx *idmap_ctx, struct gp_gpo **candidate_gpos, int num_candidate_gpos, struct gp_gpo ***_dacl_filtered_gpos, int *_num_dacl_filtered_gpos) { TALLOC_CTX *tmp_ctx = NULL; int i = 0; int ret = 0; struct gp_gpo *candidate_gpo = NULL; struct security_descriptor *sd = NULL; struct security_acl *dacl = NULL; const char *user_sid = NULL; const char **group_sids = NULL; int group_size = 0; int gpo_dn_idx = 0; bool access_allowed = false; struct gp_gpo **dacl_filtered_gpos = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ret = ad_gpo_get_sids(tmp_ctx, user, domain, &user_sid, &group_sids, &group_size); if (ret != EOK) { ret = ERR_NO_SIDS; DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve SIDs: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } dacl_filtered_gpos = talloc_array(tmp_ctx, struct gp_gpo *, num_candidate_gpos + 1); if (dacl_filtered_gpos == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < num_candidate_gpos; i++) { access_allowed = false; candidate_gpo = candidate_gpos[i]; sd = candidate_gpo->gpo_sd; dacl = candidate_gpo->gpo_sd->dacl; DEBUG(SSSDBG_TRACE_ALL, "examining dacl candidate_gpo_guid:%s\n", candidate_gpo->gpo_guid); /* gpo_func_version must be set to version 2 */ if (candidate_gpo->gpo_func_version != 2) { DEBUG(SSSDBG_TRACE_ALL, "GPO not applicable to target per security filtering\n"); continue; } /* gpo_flags value of 2 means that GPO's computer portion is disabled */ if (candidate_gpo->gpo_flags == 2) { DEBUG(SSSDBG_TRACE_ALL, "GPO not applicable to target per security filtering\n"); continue; } /* * [MS-ADTS] 5.1.3.3.4: * If the security descriptor has no DACL or its "DACL Present" bit * is not set, then grant requester the requested control access right. */ if ((!(sd->type & SEC_DESC_DACL_PRESENT)) || (dacl == NULL)) { DEBUG(SSSDBG_TRACE_ALL, "DACL is not present\n"); access_allowed = true; break; } ret = ad_gpo_evaluate_dacl(dacl, idmap_ctx, user_sid, group_sids, group_size, &access_allowed); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not determine if GPO is applicable\n"); continue; } if (access_allowed) { DEBUG(SSSDBG_TRACE_ALL, "GPO applicable to target per security filtering\n"); dacl_filtered_gpos[gpo_dn_idx] = talloc_steal(dacl_filtered_gpos, candidate_gpo); gpo_dn_idx++; } else { DEBUG(SSSDBG_TRACE_ALL, "GPO not applicable to target per security filtering\n"); continue; } } dacl_filtered_gpos[gpo_dn_idx] = NULL; *_dacl_filtered_gpos = talloc_steal(mem_ctx, dacl_filtered_gpos); *_num_dacl_filtered_gpos = gpo_dn_idx; ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* * This function determines whether the input cse_guid matches any of the input * gpo_cse_guids. The boolean result is assigned to the _included output param. */ static bool ad_gpo_includes_cse_guid(const char *cse_guid, const char **gpo_cse_guids, int num_gpo_cse_guids) { int i = 0; const char *gpo_cse_guid = NULL; for (i = 0; i < num_gpo_cse_guids; i++) { gpo_cse_guid = gpo_cse_guids[i]; if (strcmp(gpo_cse_guid, cse_guid) == 0) { return true; } } return false; } /* * This function takes an input dacl_filtered_gpos list, filters out any gpo * that does not contain the input cse_guid, and assigns the result to the * _cse_filtered_gpos output parameter. */ static errno_t ad_gpo_filter_gpos_by_cse_guid(TALLOC_CTX *mem_ctx, const char *cse_guid, struct gp_gpo **dacl_filtered_gpos, int num_dacl_filtered_gpos, struct gp_gpo ***_cse_filtered_gpos, int *_num_cse_filtered_gpos) { TALLOC_CTX *tmp_ctx = NULL; int i = 0; int ret = 0; struct gp_gpo *dacl_filtered_gpo = NULL; int gpo_dn_idx = 0; struct gp_gpo **cse_filtered_gpos = NULL; bool included; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } cse_filtered_gpos = talloc_array(tmp_ctx, struct gp_gpo *, num_dacl_filtered_gpos + 1); if (cse_filtered_gpos == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < num_dacl_filtered_gpos; i++) { dacl_filtered_gpo = dacl_filtered_gpos[i]; DEBUG(SSSDBG_TRACE_ALL, "examining cse candidate_gpo_guid: %s\n", dacl_filtered_gpo->gpo_guid); included = ad_gpo_includes_cse_guid(cse_guid, dacl_filtered_gpo->gpo_cse_guids, dacl_filtered_gpo->num_gpo_cse_guids); if (included) { DEBUG(SSSDBG_TRACE_ALL, "GPO applicable to target per cse_guid filtering\n"); cse_filtered_gpos[gpo_dn_idx] = talloc_steal(cse_filtered_gpos, dacl_filtered_gpo); dacl_filtered_gpos[i] = NULL; gpo_dn_idx++; } else { DEBUG(SSSDBG_TRACE_ALL, "GPO not applicable to target per cse_guid filtering\n"); continue; } } cse_filtered_gpos[gpo_dn_idx] = NULL; *_cse_filtered_gpos = talloc_steal(mem_ctx, cse_filtered_gpos); *_num_cse_filtered_gpos = gpo_dn_idx; ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* * This cse-specific function (GP_EXT_GUID_SECURITY) returns a boolean value * based on whether the input user_sid or any of the input group_sids appear * in the input list of privilege_sids. */ static bool check_rights(char **privilege_sids, int privilege_size, const char *user_sid, const char **group_sids, int group_size) { int i, j; for (i = 0; i < privilege_size; i++) { if (strcmp(user_sid, privilege_sids[i]) == 0) { return true; } for (j = 0; j < group_size; j++) { if (strcmp(group_sids[j], privilege_sids[i]) == 0) { return true; } } } return false; } /* * This function parses the input ini_config object (which represents * the cse-specific filename), and returns the policy_setting_value * corresponding to the input policy_setting_key. */ static errno_t ad_gpo_extract_policy_setting(TALLOC_CTX *mem_ctx, struct ini_cfgobj *ini_config, const char *policy_setting_key, char **_policy_setting_value) { struct value_obj *vobj = NULL; int ret; const char *policy_setting_value; ret = ini_get_config_valueobj(RIGHTS_SECTION, policy_setting_key, ini_config, INI_GET_FIRST_VALUE, &vobj); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "ini_get_config_valueobj failed [%d][%s]\n", ret, strerror(ret)); goto done; } if (vobj == NULL) { DEBUG(SSSDBG_TRACE_ALL, "section/name not found: [%s][%s]\n", RIGHTS_SECTION, policy_setting_key); ret = ENOENT; goto done; } policy_setting_value = ini_get_string_config_value(vobj, &ret); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "ini_get_string_config_value failed [%d][%s]\n", ret, strerror(ret)); goto done; } if (policy_setting_value[0]) { *_policy_setting_value = talloc_strdup(mem_ctx, policy_setting_value); if (!*_policy_setting_value) { ret = ENOMEM; goto done; } } else { /* This is an explicitly empty policy setting. * We need to remove this from the LDB. */ *_policy_setting_value = NULL; } ret = EOK; done: return ret; } /* * This function parses the cse-specific (GP_EXT_GUID_SECURITY) filename, * and stores the allow_key and deny_key of all of the gpo_map_types present * in the file (as part of the GPO Result object in the sysdb cache). */ static errno_t ad_gpo_store_policy_settings(struct sss_domain_info *domain, const char *filename) { struct ini_cfgfile *file_ctx = NULL; struct ini_cfgobj *ini_config = NULL; int ret; int i; char *allow_value = NULL; char *deny_value = NULL; const char *allow_key = NULL; const char *deny_key = NULL; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ret = ini_config_create(&ini_config); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "ini_config_create failed [%d][%s]\n", ret, strerror(ret)); goto done; } ret = ini_config_file_open(filename, 0, &file_ctx); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "ini_config_file_open failed [%d][%s]\n", ret, strerror(ret)); goto done; } ret = ini_config_parse(file_ctx, INI_STOP_ON_NONE, 0, 0, ini_config); if (ret != 0) { int lret; char **errors; DEBUG(SSSDBG_CRIT_FAILURE, "[%s]: ini_config_parse failed [%d][%s]\n", filename, ret, strerror(ret)); /* Now get specific errors if there are any */ lret = ini_config_get_errors(ini_config, &errors); if (lret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get specific parse error [%d][%s]\n", lret, strerror(lret)); goto done; } for (int a = 0; errors[a]; a++) { DEBUG(SSSDBG_CRIT_FAILURE, "%s\n", errors[a]); } ini_config_free_errors(errors); goto done; } for (i = 0; i < GPO_MAP_NUM_OPTS; i++) { struct gpo_map_option_entry entry = gpo_map_option_entries[i]; allow_key = entry.allow_key; if (allow_key != NULL) { DEBUG(SSSDBG_TRACE_ALL, "allow_key = %s\n", allow_key); ret = ad_gpo_extract_policy_setting(tmp_ctx, ini_config, allow_key, &allow_value); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "ad_gpo_extract_policy_setting failed for %s [%d][%s]\n", allow_key, ret, sss_strerror(ret)); goto done; } else if (ret != ENOENT) { ret = sysdb_gpo_store_gpo_result_setting(domain, allow_key, allow_value); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_gpo_store_gpo_result_setting failed for key:" "'%s' value:'%s' [%d][%s]\n", allow_key, allow_value, ret, sss_strerror(ret)); goto done; } } } deny_key = entry.deny_key; if (deny_key != NULL) { DEBUG(SSSDBG_TRACE_ALL, "deny_key = %s\n", deny_key); ret = ad_gpo_extract_policy_setting(tmp_ctx, ini_config, deny_key, &deny_value); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "ad_gpo_extract_policy_setting failed for %s [%d][%s]\n", deny_key, ret, sss_strerror(ret)); goto done; } else if (ret != ENOENT) { ret = sysdb_gpo_store_gpo_result_setting(domain, deny_key, deny_value); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_gpo_store_gpo_result_setting failed for key:" "'%s' value:'%s' [%d][%s]\n", deny_key, deny_value, ret, sss_strerror(ret)); goto done; } } } } ret = EOK; done: if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret); } ini_config_file_destroy(file_ctx); ini_config_destroy(ini_config); talloc_free(tmp_ctx); return ret; } /* * This cse-specific function (GP_EXT_GUID_SECURITY) performs the access * check for determining whether logon access is granted or denied for * the {user,domain} tuple specified in the inputs. This function returns EOK * to indicate that access is granted. Any other return value indicates that * access is denied. * * The access control algorithm first determines whether the "principal_sids" * (i.e. user_sid or group_sids) appear in allowed_sids and denied_sids. * * For access to be granted, both the "allowed_sids_condition" *and* the * "denied_sids_condition" must be met (in all other cases, access is denied). * 1) The "allowed_sids_condition" is satisfied if any of the principal_sids * appears in allowed_sids OR if the allowed_sids list is empty * 2) The "denied_sids_condition" is satisfied if none of the principal_sids * appear in denied_sids * * Note that a deployment that is unaware of GPO-based access-control policy * settings is unaffected by them (b/c absence of allowed_sids grants access). * * Note that if a principal_sid appears in both allowed_sids and denied_sids, * the "allowed_sids_condition" is met, but the "denied_sids_condition" is not. * In other words, Deny takes precedence over Allow. */ static errno_t ad_gpo_access_check(TALLOC_CTX *mem_ctx, enum gpo_access_control_mode gpo_mode, enum gpo_map_type gpo_map_type, const char *user, struct sss_domain_info *domain, char **allowed_sids, int allowed_size, char **denied_sids, int denied_size) { const char *user_sid; const char **group_sids; int group_size = 0; bool access_granted = false; bool access_denied = false; int ret; int j; DEBUG(SSSDBG_TRACE_FUNC, "RESULTANT POLICY:\n"); DEBUG(SSSDBG_TRACE_FUNC, "gpo_map_type: %s\n", gpo_map_type_string(gpo_map_type)); DEBUG(SSSDBG_TRACE_FUNC, "allowed_size = %d\n", allowed_size); for (j= 0; j < allowed_size; j++) { DEBUG(SSSDBG_TRACE_FUNC, "allowed_sids[%d] = %s\n", j, allowed_sids[j]); } DEBUG(SSSDBG_TRACE_FUNC, "denied_size = %d\n", denied_size); for (j= 0; j < denied_size; j++) { DEBUG(SSSDBG_TRACE_FUNC, " denied_sids[%d] = %s\n", j, denied_sids[j]); } ret = ad_gpo_get_sids(mem_ctx, user, domain, &user_sid, &group_sids, &group_size); if (ret != EOK) { ret = ERR_NO_SIDS; DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve SIDs: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "CURRENT USER:\n"); DEBUG(SSSDBG_TRACE_FUNC, " user_sid = %s\n", user_sid); for (j= 0; j < group_size; j++) { DEBUG(SSSDBG_TRACE_FUNC, " group_sids[%d] = %s\n", j, group_sids[j]); } if (allowed_size == 0) { access_granted = true; } else { access_granted = check_rights(allowed_sids, allowed_size, user_sid, group_sids, group_size); } DEBUG(SSSDBG_TRACE_FUNC, "POLICY DECISION:\n"); DEBUG(SSSDBG_TRACE_FUNC, " access_granted = %d\n", access_granted); access_denied = check_rights(denied_sids, denied_size, user_sid, group_sids, group_size); DEBUG(SSSDBG_TRACE_FUNC, " access_denied = %d\n", access_denied); if (access_granted && !access_denied) { return EOK; } else { switch (gpo_mode) { case GPO_ACCESS_CONTROL_ENFORCING: return ERR_ACCESS_DENIED; case GPO_ACCESS_CONTROL_PERMISSIVE: DEBUG(SSSDBG_TRACE_FUNC, "access denied: permissive mode\n"); sss_log_ext(SSS_LOG_WARNING, LOG_AUTHPRIV, "Warning: user would " \ "have been denied GPO-based logon access if the " \ "ad_gpo_access_control option were set to enforcing " \ "mode."); return EOK; default: return EINVAL; } } done: if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Error encountered: %d.\n", ret); } return ret; } #define GPO_CHILD_LOG_FILE "gpo_child" static errno_t gpo_child_init(void) { return child_debug_init(GPO_CHILD_LOG_FILE, &gpo_child_debug_fd); } /* * This function retrieves the raw policy_setting_value for the input key from * the GPO_Result object in the sysdb cache. It then parses the raw value and * uses the results to populate the output parameters with the sids_list and * the size of the sids_list. */ errno_t parse_policy_setting_value(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *key, char ***_sids_list, int *_sids_list_size) { int ret; int i; const char *value; int sids_list_size; char **sids_list = NULL; ret = sysdb_gpo_get_gpo_result_setting(mem_ctx, domain, key, &value); if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No previous GPO result\n"); value = NULL; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot retrieve settings from sysdb for key: '%s' [%d][%s].\n", key, ret, sss_strerror(ret)); goto done; } if (value == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "No value for key [%s] found in gpo result\n", key); sids_list_size = 0; } else { ret = split_on_separator(mem_ctx, value, ',', true, true, &sids_list, &sids_list_size); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot parse list of sids %s: %d\n", value, ret); ret = EINVAL; goto done; } for (i = 0; i < sids_list_size; i++) { /* remove the asterisk prefix found on sids */ sids_list[i]++; } } *_sids_list = talloc_steal(mem_ctx, sids_list); *_sids_list_size = sids_list_size; ret = EOK; done: return ret; } /* * This cse-specific function (GP_EXT_GUID_SECURITY) performs HBAC policy * processing and determines whether logon access is granted or denied for * the {user,domain} tuple specified in the inputs. This function returns EOK * to indicate that access is granted. Any other return value indicates that * access is denied. * * Internally, this function retrieves the allow_value and deny_value for the * input gpo_map_type from the GPO Result object in the sysdb cache, parses * the values into allow_sids and deny_sids, and executes the access control * algorithm which compares the allow_sids and deny_sids against the user_sid * and group_sids for the input user. */ static errno_t ad_gpo_perform_hbac_processing(TALLOC_CTX *mem_ctx, enum gpo_access_control_mode gpo_mode, enum gpo_map_type gpo_map_type, const char *user, struct sss_domain_info *user_domain, struct sss_domain_info *host_domain) { int ret; const char *allow_key = NULL; char **allow_sids; int allow_size ; const char *deny_key = NULL; char **deny_sids; int deny_size; allow_key = gpo_map_option_entries[gpo_map_type].allow_key; DEBUG(SSSDBG_TRACE_ALL, "allow_key: %s\n", allow_key); deny_key = gpo_map_option_entries[gpo_map_type].deny_key; DEBUG(SSSDBG_TRACE_ALL, "deny_key: %s\n", deny_key); ret = parse_policy_setting_value(mem_ctx, host_domain, allow_key, &allow_sids, &allow_size); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "parse_policy_setting_value failed for key %s: [%d](%s)\n", allow_key, ret, sss_strerror(ret)); ret = EINVAL; goto done; } ret = parse_policy_setting_value(mem_ctx, host_domain, deny_key, &deny_sids, &deny_size); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "parse_policy_setting_value failed for key %s: [%d](%s)\n", deny_key, ret, sss_strerror(ret)); ret = EINVAL; goto done; } /* perform access check with the final resultant allow_sids and deny_sids */ ret = ad_gpo_access_check(mem_ctx, gpo_mode, gpo_map_type, user, user_domain, allow_sids, allow_size, deny_sids, deny_size); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "GPO access check failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } done: return ret; } /* == ad_gpo_access_send/recv implementation ================================*/ struct ad_gpo_access_state { struct tevent_context *ev; struct ldb_context *ldb_ctx; struct ad_access_ctx *access_ctx; enum gpo_access_control_mode gpo_mode; enum gpo_map_type gpo_map_type; struct sdap_id_conn_ctx *conn; struct sdap_id_op *sdap_op; char *server_hostname; struct sdap_options *opts; int timeout; struct sss_domain_info *user_domain; struct sss_domain_info *host_domain; const char *user; int gpo_timeout_option; const char *ad_hostname; const char *target_dn; struct gp_gpo **dacl_filtered_gpos; int num_dacl_filtered_gpos; struct gp_gpo **cse_filtered_gpos; int num_cse_filtered_gpos; int cse_gpo_index; }; static void ad_gpo_connect_done(struct tevent_req *subreq); static void ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq); static void ad_gpo_process_som_done(struct tevent_req *subreq); static void ad_gpo_process_gpo_done(struct tevent_req *subreq); static errno_t ad_gpo_cse_step(struct tevent_req *req); static void ad_gpo_cse_done(struct tevent_req *subreq); struct tevent_req * ad_gpo_access_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sss_domain_info *domain, struct ad_access_ctx *ctx, const char *user, const char *service) { struct tevent_req *req; struct tevent_req *subreq; struct ad_gpo_access_state *state; errno_t ret; int hret; hash_key_t key; hash_value_t val; enum gpo_map_type gpo_map_type; /* setup logging for gpo child */ gpo_child_init(); req = tevent_req_create(mem_ctx, &state, struct ad_gpo_access_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } /* determine service's option_type (e.g. interactive, network, etc) */ key.type = HASH_KEY_STRING; key.str = talloc_strdup(state, service); hret = hash_lookup(ctx->gpo_map_options_table, &key, &val); if (hret != HASH_SUCCESS && hret != HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_OP_FAILURE, "Error checking hash table: [%s]\n", hash_error_string(hret)); ret = EINVAL; goto immediately; } /* if service isn't mapped, map it to value of ad_gpo_default_right option */ if (hret == HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_TRACE_FUNC, "using default right\n"); gpo_map_type = ctx->gpo_default_right; } else { gpo_map_type = (enum gpo_map_type) val.i; } DEBUG(SSSDBG_TRACE_FUNC, "service %s maps to %s\n", service, gpo_map_type_string(gpo_map_type)); if (gpo_map_type == GPO_MAP_PERMIT) { ret = EOK; goto immediately; } if (gpo_map_type == GPO_MAP_DENY) { switch (ctx->gpo_access_control_mode) { case GPO_ACCESS_CONTROL_ENFORCING: ret = ERR_ACCESS_DENIED; goto immediately; case GPO_ACCESS_CONTROL_PERMISSIVE: DEBUG(SSSDBG_TRACE_FUNC, "access denied: permissive mode\n"); sss_log_ext(SSS_LOG_WARNING, LOG_AUTHPRIV, "Warning: user would " \ "have been denied GPO-based logon access if the " \ "ad_gpo_access_control option were set to enforcing " \ "mode."); ret = EOK; goto immediately; default: ret = EINVAL; goto immediately; } } /* GPO Operations all happen against the enrolled domain, * not the user's domain (which may be a trusted realm) */ state->user_domain = domain; state->host_domain = get_domains_head(domain); state->gpo_map_type = gpo_map_type; state->dacl_filtered_gpos = NULL; state->num_dacl_filtered_gpos = 0; state->cse_filtered_gpos = NULL; state->num_cse_filtered_gpos = 0; state->cse_gpo_index = 0; state->ev = ev; state->user = user; state->ldb_ctx = sysdb_ctx_get_ldb(state->host_domain->sysdb); state->gpo_mode = ctx->gpo_access_control_mode; state->gpo_timeout_option = ctx->gpo_cache_timeout; state->ad_hostname = dp_opt_get_string(ctx->ad_options, AD_HOSTNAME); state->access_ctx = ctx; state->opts = ctx->sdap_access_ctx->id_ctx->opts; state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT); state->conn = ad_get_dom_ldap_conn(ctx->ad_id_ctx, state->host_domain); state->sdap_op = sdap_id_op_create(state, state->conn->conn_cache); if (state->sdap_op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n"); ret = ENOMEM; goto immediately; } subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: [%d](%s)\n", ret, sss_strerror(ret)); goto immediately; } tevent_req_set_callback(subreq, ad_gpo_connect_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t process_offline_gpos(TALLOC_CTX *mem_ctx, const char *user, enum gpo_access_control_mode gpo_mode, struct sss_domain_info *user_domain, struct sss_domain_info *host_domain, enum gpo_map_type gpo_map_type) { errno_t ret; ret = ad_gpo_perform_hbac_processing(mem_ctx, gpo_mode, gpo_map_type, user, user_domain, host_domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "HBAC processing failed: [%d](%s}\n", ret, sss_strerror(ret)); goto done; } /* we have successfully processed all offline gpos */ ret = EOK; done: return ret; } static void ad_gpo_connect_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_gpo_access_state *state; char *filter; const char *sam_account_name; char *domain_dn; int dp_error; errno_t ret; char *server_uri; LDAPURLDesc *lud; const char *attrs[] = {AD_AT_DN, AD_AT_UAC, NULL}; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_access_state); ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { if (dp_error != DP_ERR_OFFLINE) { DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to AD server: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } else { DEBUG(SSSDBG_TRACE_FUNC, "Preparing for offline operation.\n"); ret = process_offline_gpos(state, state->user, state->gpo_mode, state->user_domain, state->host_domain, state->gpo_map_type); if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "process_offline_gpos succeeded\n"); tevent_req_done(req); goto done; } else { DEBUG(SSSDBG_OP_FAILURE, "process_offline_gpos failed [%d](%s)\n", ret, sss_strerror(ret)); goto done; } } } /* extract server_hostname from server_uri */ server_uri = state->conn->service->uri; ret = ldap_url_parse(server_uri, &lud); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse ldap URI (%s)!\n", server_uri); ret = EINVAL; goto done; } if (lud->lud_host == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "The LDAP URI (%s) did not contain a host name\n", server_uri); ldap_free_urldesc(lud); ret = EINVAL; goto done; } state->server_hostname = talloc_strdup(state, lud->lud_host); ldap_free_urldesc(lud); if (!state->server_hostname) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_ALL, "server_hostname from uri: %s\n", state->server_hostname); /* SDAP_SASL_AUTHID contains the name used for kinit and SASL bind which * in the AD case is the NetBIOS name. */ sam_account_name = dp_opt_get_string(state->opts->basic, SDAP_SASL_AUTHID); if (sam_account_name == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "sam_account_name is %s\n", sam_account_name); /* Convert the domain name into domain DN */ ret = domain_to_basedn(state, state->host_domain->name, &domain_dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot convert domain name [%s] to base DN [%d]: %s\n", state->host_domain->name, ret, sss_strerror(ret)); goto done; } /* SDAP_OC_USER objectclass covers both users and computers */ filter = talloc_asprintf(state, "(&(objectclass=%s)(%s=%s))", state->opts->user_map[SDAP_OC_USER].name, state->opts->user_map[SDAP_AT_USER_NAME].name, sam_account_name); if (filter == NULL) { ret = ENOMEM; goto done; } subreq = sdap_get_generic_send(state, state->ev, state->opts, sdap_id_op_handle(state->sdap_op), domain_dn, LDAP_SCOPE_SUBTREE, filter, attrs, NULL, 0, state->timeout, false); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); ret = EIO; goto done; } tevent_req_set_callback(subreq, ad_gpo_target_dn_retrieval_done, req); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); } } static void ad_gpo_target_dn_retrieval_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_gpo_access_state *state; int ret; int dp_error; size_t reply_count; struct sysdb_attrs **reply; const char *target_dn = NULL; uint32_t uac; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_access_state); ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply); talloc_zfree(subreq); if (ret != EOK) { ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); if (ret == EAGAIN && dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_TRACE_FUNC, "Preparing for offline operation.\n"); ret = process_offline_gpos(state, state->user, state->gpo_mode, state->user_domain, state->host_domain, state->gpo_map_type); if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "process_offline_gpos succeeded\n"); tevent_req_done(req); goto done; } else { DEBUG(SSSDBG_OP_FAILURE, "process_offline_gpos failed [%d](%s)\n", ret, sss_strerror(ret)); goto done; } } DEBUG(SSSDBG_OP_FAILURE, "Unable to get policy target's DN: [%d](%s)\n", ret, sss_strerror(ret)); ret = ENOENT; goto done; } /* make sure there is only one non-NULL reply returned */ if (reply_count < 1) { DEBUG(SSSDBG_OP_FAILURE, "No DN retrieved for policy target.\n"); ret = ENOENT; goto done; } else if (reply_count > 1) { DEBUG(SSSDBG_OP_FAILURE, "Multiple replies for policy target\n"); ret = ERR_INTERNAL; goto done; } else if (reply == NULL) { DEBUG(SSSDBG_OP_FAILURE, "reply_count is 1, but reply is NULL\n"); ret = ERR_INTERNAL; goto done; } /* reply[0] holds requested attributes of single reply */ ret = sysdb_attrs_get_string(reply[0], AD_AT_DN, &target_dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } state->target_dn = talloc_steal(state, target_dn); if (state->target_dn == NULL) { ret = ENOMEM; goto done; } ret = sysdb_attrs_get_uint32_t(reply[0], AD_AT_UAC, &uac); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_uint32_t failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } /* we only support computer policy targets, not users */ if (!(uac & UAC_WORKSTATION_TRUST_ACCOUNT)) { ret = EINVAL; goto done; } subreq = ad_gpo_process_som_send(state, state->ev, state->conn, state->ldb_ctx, state->sdap_op, state->opts, state->timeout, state->target_dn, state->host_domain->name); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ad_gpo_process_som_done, req); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); } } static void ad_gpo_process_som_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_gpo_access_state *state; int ret; struct gp_som **som_list; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_access_state); ret = ad_gpo_process_som_recv(subreq, state, &som_list); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get som list: [%d](%s)\n", ret, sss_strerror(ret)); ret = ENOENT; goto done; } subreq = ad_gpo_process_gpo_send(state, state->ev, state->sdap_op, state->opts, state->server_hostname, state->host_domain, state->access_ctx, state->timeout, som_list); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ad_gpo_process_gpo_done, req); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); } } /* * This function retrieves a list of candidate_gpos and potentially reduces it * to a list of dacl_filtered_gpos, based on each GPO's DACL. * * This function then takes the list of dacl_filtered_gpos and potentially * reduces it to a list of cse_filtered_gpos, based on whether each GPO's list * of cse_guids includes the "SecuritySettings" CSE GUID (used for HBAC). * * Ultimately, this function then sends each cse_filtered_gpo to the gpo_child, * which retrieves the GPT.INI and policy files (as needed). Once all files * have been downloaded, the ad_gpo_cse_done function performs HBAC processing. */ static void ad_gpo_process_gpo_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_gpo_access_state *state; int ret; int dp_error; struct gp_gpo **candidate_gpos = NULL; int num_candidate_gpos = 0; int i = 0; const char **cse_filtered_gpo_guids; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_access_state); ret = ad_gpo_process_gpo_recv(subreq, state, &candidate_gpos, &num_candidate_gpos); talloc_zfree(subreq); ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get GPO list: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No GPOs found that apply to this system.\n"); /* * Delete the result object list, since there are no * GPOs to include in it. */ ret = sysdb_gpo_delete_gpo_result_object(state, state->host_domain); if (ret != EOK) { switch (ret) { case ENOENT: DEBUG(SSSDBG_TRACE_FUNC, "No GPO Result available in cache\n"); break; default: DEBUG(SSSDBG_FATAL_FAILURE, "Could not delete GPO Result from cache: [%s]\n", sss_strerror(ret)); goto done; } } ret = EOK; goto done; } ret = ad_gpo_filter_gpos_by_dacl(state, state->user, state->user_domain, state->opts->idmap_ctx->map, candidate_gpos, num_candidate_gpos, &state->dacl_filtered_gpos, &state->num_dacl_filtered_gpos); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to filter GPO list by DACKL: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } if (state->dacl_filtered_gpos[0] == NULL) { /* since no applicable gpos were found, there is nothing to enforce */ DEBUG(SSSDBG_TRACE_FUNC, "no applicable gpos found after dacl filtering\n"); /* * Delete the result object list, since there are no * GPOs to include in it. */ ret = sysdb_gpo_delete_gpo_result_object(state, state->host_domain); if (ret != EOK) { switch (ret) { case ENOENT: DEBUG(SSSDBG_TRACE_FUNC, "No GPO Result available in cache\n"); break; default: DEBUG(SSSDBG_FATAL_FAILURE, "Could not delete GPO Result from cache: [%s]\n", sss_strerror(ret)); goto done; } } ret = EOK; goto done; } for (i = 0; i < state->num_dacl_filtered_gpos; i++) { DEBUG(SSSDBG_TRACE_FUNC, "dacl_filtered_gpos[%d]->gpo_guid is %s\n", i, state->dacl_filtered_gpos[i]->gpo_guid); } ret = ad_gpo_filter_gpos_by_cse_guid(state, GP_EXT_GUID_SECURITY, state->dacl_filtered_gpos, state->num_dacl_filtered_gpos, &state->cse_filtered_gpos, &state->num_cse_filtered_gpos); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to filter GPO list by CSE_GUID: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } if (state->cse_filtered_gpos[0] == NULL) { /* no gpos contain "SecuritySettings" cse_guid, nothing to enforce */ DEBUG(SSSDBG_TRACE_FUNC, "no applicable gpos found after cse_guid filtering\n"); ret = EOK; goto done; } /* we create and populate an array of applicable gpo-guids */ cse_filtered_gpo_guids = talloc_array(state, const char *, state->num_cse_filtered_gpos); if (cse_filtered_gpo_guids == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < state->num_cse_filtered_gpos; i++) { DEBUG(SSSDBG_TRACE_FUNC, "cse_filtered_gpos[%d]->gpo_guid is %s\n", i, state->cse_filtered_gpos[i]->gpo_guid); cse_filtered_gpo_guids[i] = talloc_steal(cse_filtered_gpo_guids, state->cse_filtered_gpos[i]->gpo_guid); if (cse_filtered_gpo_guids[i] == NULL) { ret = ENOMEM; goto done; } } DEBUG(SSSDBG_TRACE_FUNC, "num_cse_filtered_gpos: %d\n", state->num_cse_filtered_gpos); /* * before we start processing each gpo, we delete the GPO Result object * from the sysdb cache so that any previous policy settings are cleared; * subsequent functions will add the GPO Result object (and populate it * with resultant policy settings) for this policy application */ ret = sysdb_gpo_delete_gpo_result_object(state, state->host_domain); if (ret != EOK) { switch (ret) { case ENOENT: DEBUG(SSSDBG_TRACE_FUNC, "No GPO Result available in cache\n"); break; default: DEBUG(SSSDBG_FATAL_FAILURE, "Could not delete GPO Result from cache: [%s]\n", sss_strerror(ret)); goto done; } } ret = ad_gpo_cse_step(req); done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static errno_t ad_gpo_cse_step(struct tevent_req *req) { struct tevent_req *subreq; struct ad_gpo_access_state *state; int i = 0; struct ldb_result *res; errno_t ret; bool send_to_child = true; int cached_gpt_version = 0; time_t policy_file_timeout = 0; state = tevent_req_data(req, struct ad_gpo_access_state); struct gp_gpo *cse_filtered_gpo = state->cse_filtered_gpos[state->cse_gpo_index]; /* cse_filtered_gpo is NULL after all GPO policy files have been downloaded */ if (cse_filtered_gpo == NULL) return EOK; DEBUG(SSSDBG_TRACE_FUNC, "cse filtered_gpos[%d]->gpo_guid is %s\n", state->cse_gpo_index, cse_filtered_gpo->gpo_guid); for (i = 0; i < cse_filtered_gpo->num_gpo_cse_guids; i++) { DEBUG(SSSDBG_TRACE_ALL, "cse_filtered_gpos[%d]->gpo_cse_guids[%d]->gpo_guid is %s\n", state->cse_gpo_index, i, cse_filtered_gpo->gpo_cse_guids[i]); } DEBUG(SSSDBG_TRACE_FUNC, "smb_server: %s\n", cse_filtered_gpo->smb_server); DEBUG(SSSDBG_TRACE_FUNC, "smb_share: %s\n", cse_filtered_gpo->smb_share); DEBUG(SSSDBG_TRACE_FUNC, "smb_path: %s\n", cse_filtered_gpo->smb_path); DEBUG(SSSDBG_TRACE_FUNC, "gpo_guid: %s\n", cse_filtered_gpo->gpo_guid); cse_filtered_gpo->policy_filename = talloc_asprintf(state, GPO_CACHE_PATH"%s%s", cse_filtered_gpo->smb_path, GP_EXT_GUID_SECURITY_SUFFIX); if (cse_filtered_gpo->policy_filename == NULL) { return ENOMEM; } /* retrieve gpo cache entry; set cached_gpt_version to -1 if unavailable */ DEBUG(SSSDBG_TRACE_FUNC, "retrieving GPO from cache [%s]\n", cse_filtered_gpo->gpo_guid); ret = sysdb_gpo_get_gpo_by_guid(state, state->host_domain, cse_filtered_gpo->gpo_guid, &res); if (ret == EOK) { /* * Note: if the timeout is valid, then we can later avoid downloading * the GPT.INI file, as well as any policy files (i.e. we don't need * to interact with the gpo_child at all). However, even if the timeout * is not valid, while we will have to interact with the gpo child to * download the GPT.INI file, we may still be able to avoid downloading * the policy files (if the cached_gpt_version is the same as the * GPT.INI version). In other words, the timeout is *not* an expiration * for the entire cache entry; the cached_gpt_version never expires. */ cached_gpt_version = ldb_msg_find_attr_as_int(res->msgs[0], SYSDB_GPO_VERSION_ATTR, 0); policy_file_timeout = ldb_msg_find_attr_as_uint64 (res->msgs[0], SYSDB_GPO_TIMEOUT_ATTR, 0); if (policy_file_timeout >= time(NULL)) { send_to_child = false; } } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "ENOENT\n"); cached_gpt_version = -1; } else { DEBUG(SSSDBG_FATAL_FAILURE, "Could not read GPO from cache: [%s]\n", sss_strerror(ret)); return ret; } DEBUG(SSSDBG_TRACE_FUNC, "send_to_child: %d\n", send_to_child); DEBUG(SSSDBG_TRACE_FUNC, "cached_gpt_version: %d\n", cached_gpt_version); cse_filtered_gpo->send_to_child = send_to_child; subreq = ad_gpo_process_cse_send(state, state->ev, send_to_child, state->host_domain, cse_filtered_gpo->gpo_guid, cse_filtered_gpo->smb_server, cse_filtered_gpo->smb_share, cse_filtered_gpo->smb_path, GP_EXT_GUID_SECURITY_SUFFIX, cached_gpt_version, state->gpo_timeout_option); tevent_req_set_callback(subreq, ad_gpo_cse_done, req); return EAGAIN; } /* * This cse-specific function (GP_EXT_GUID_SECURITY) increments the * cse_gpo_index until the policy settings for all applicable GPOs have been * stored as part of the GPO Result object in the sysdb cache. Once all * GPOs have been processed, this functions performs HBAC processing by * comparing the resultant policy setting values in the GPO Result object * with the user_sid/group_sids of interest. */ static void ad_gpo_cse_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_gpo_access_state *state; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_access_state); struct gp_gpo *cse_filtered_gpo = state->cse_filtered_gpos[state->cse_gpo_index]; const char *gpo_guid = cse_filtered_gpo->gpo_guid; DEBUG(SSSDBG_TRACE_FUNC, "gpo_guid: %s\n", gpo_guid); ret = ad_gpo_process_cse_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve policy data: [%d](%s}\n", ret, sss_strerror(ret)); goto done; } /* * now that the policy file for this gpo have been downloaded to the * GPO CACHE, we store all of the supported keys present in the file * (as part of the GPO Result object in the sysdb cache). */ ret = ad_gpo_store_policy_settings(state->host_domain, cse_filtered_gpo->policy_filename); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ad_gpo_store_policy_settings failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } state->cse_gpo_index++; ret = ad_gpo_cse_step(req); if (ret == EOK) { /* ret is EOK only after all GPO policy files have been downloaded */ ret = ad_gpo_perform_hbac_processing(state, state->gpo_mode, state->gpo_map_type, state->user, state->user_domain, state->host_domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "HBAC processing failed: [%d](%s}\n", ret, sss_strerror(ret)); goto done; } } done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } errno_t ad_gpo_access_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* == ad_gpo_process_som_send/recv helpers ================================= */ /* * This function returns the parent of an LDAP DN */ static errno_t ad_gpo_parent_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, const char *dn, const char **_parent_dn) { struct ldb_dn *ldb_dn; struct ldb_dn *parent_ldb_dn; const char *p; int ret; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ldb_dn = ldb_dn_new(tmp_ctx, ldb_ctx, dn); parent_ldb_dn = ldb_dn_get_parent(tmp_ctx, ldb_dn); p = ldb_dn_get_linearized(parent_ldb_dn); *_parent_dn = talloc_steal(mem_ctx, p); ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* * This function populates the _som_list output parameter by parsing the input * DN into a list of gp_som objects. This function essentially repeatedly * appends the input DN's parent to the SOM List (if the parent starts with * "OU=" or "DC="), until the first "DC=" component is reached. * Example: if input DN is "CN=MyComputer,CN=Computers,OU=Sales,DC=FOO,DC=COM", * then SOM List has 2 SOM entries: {[OU=Sales,DC=FOO,DC=COM], [DC=FOO, DC=COM]} */ static errno_t ad_gpo_populate_som_list(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, const char *target_dn, int *_num_soms, struct gp_som ***_som_list) { TALLOC_CTX *tmp_ctx = NULL; int ret; int rdn_count = 0; int som_idx = 0; struct gp_som **som_list; const char *parent_dn = NULL; const char *tmp_dn = NULL; struct ldb_dn *ldb_target_dn; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ldb_target_dn = ldb_dn_new(tmp_ctx, ldb_ctx, target_dn); if (ldb_target_dn == NULL) { ret = EINVAL; goto done; } rdn_count = ldb_dn_get_comp_num(ldb_target_dn); if (rdn_count == -1) { ret = EINVAL; goto done; } if (rdn_count == 0) { *_som_list = NULL; ret = EOK; goto done; } /* assume the worst-case, in which every parent is a SOM */ /* include space for Site SOM and NULL: rdn_count + 1 + 1 */ som_list = talloc_array(tmp_ctx, struct gp_som *, rdn_count + 1 + 1); if (som_list == NULL) { ret = ENOMEM; goto done; } /* first, populate the OU and Domain SOMs */ tmp_dn = target_dn;; while ((ad_gpo_parent_dn(tmp_ctx, ldb_ctx, tmp_dn, &parent_dn)) == EOK) { if ((strncasecmp(parent_dn, "OU=", strlen("OU=")) == 0) || (strncasecmp(parent_dn, "DC=", strlen("DC=")) == 0)) { som_list[som_idx] = talloc_zero(som_list, struct gp_som); if (som_list[som_idx] == NULL) { ret = ENOMEM; goto done; } som_list[som_idx]->som_dn = talloc_steal(som_list[som_idx], parent_dn); if (som_list[som_idx]->som_dn == NULL) { ret = ENOMEM; goto done; } som_idx++; } if (strncasecmp(parent_dn, "DC=", strlen("DC=")) == 0) { break; } tmp_dn = parent_dn; } som_list[som_idx] = NULL; *_num_soms = som_idx; *_som_list = talloc_steal(mem_ctx, som_list); ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* * This function populates the _gplink_list output parameter by parsing the * input raw_gplink_value into an array of gp_gplink objects, each consisting of * a GPO DN and bool enforced field. * * The raw_gplink_value is single string consisting of multiple gplink strings. * The raw_gplink_value is in the following format: * "[GPO_DN_1;GPLinkOptions_1]...[GPO_DN_n;GPLinkOptions_n]" * * Each gplink string consists of a GPO DN and a GPLinkOptions field (which * indicates whether its associated GPO DN is ignored, unenforced, or enforced). * If a GPO DN is flagged as ignored, it is discarded and will not be added to * the _gplink_list. If the allow_enforced_only input is true, AND a GPO DN is * flagged as unenforced, it will also be discarded. * * Example: if raw_gplink_value="[OU=Sales,DC=FOO,DC=COM;0][DC=FOO,DC=COM;2]" * and allow_enforced_only=FALSE, then the output would consist of following: * _gplink_list[0]: {GPO DN: "OU=Sales,DC=FOO,DC=COM", enforced: FALSE} * _gplink_list[1]: {GPO DN: "DC=FOO,DC=COM", enforced: TRUE} */ static errno_t ad_gpo_populate_gplink_list(TALLOC_CTX *mem_ctx, const char *som_dn, char *raw_gplink_value, struct gp_gplink ***_gplink_list, bool allow_enforced_only) { TALLOC_CTX *tmp_ctx = NULL; char *ptr; char *first; char *last; char *dn; char *gplink_options; const char delim = ']'; struct gp_gplink **gplink_list; int i; int ret; uint32_t gplink_number; int gplink_count = 0; int num_enabled = 0; if (raw_gplink_value == NULL || *raw_gplink_value == '\0' || _gplink_list == NULL) { return EINVAL; } DEBUG(SSSDBG_TRACE_FUNC, "som_dn: %s\n", som_dn); tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ptr = raw_gplink_value; while ((ptr = strchr(ptr, delim))) { ptr++; gplink_count++; } if (gplink_count == 0) { ret = EOK; goto done; } gplink_list = talloc_array(tmp_ctx, struct gp_gplink *, gplink_count + 1); if (gplink_list == NULL) { ret = ENOMEM; goto done; } num_enabled = 0; ptr = raw_gplink_value; for (i = 0; i < gplink_count; i++) { first = ptr + 1; last = strchr(first, delim); if (last == NULL) { ret = EINVAL; goto done; } *last = '\0'; last++; dn = first; if ( strncasecmp(dn, "LDAP://", 7)== 0 ) { dn = dn + 7; } gplink_options = strchr(first, ';'); if (gplink_options == NULL) { ret = EINVAL; goto done; } *gplink_options = '\0'; gplink_options++; gplink_number = strtouint32(gplink_options, NULL, 10); if (errno != 0) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "strtouint32 failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_ALL, "gplink_list[%d]: [%s; %d]\n", num_enabled, dn, gplink_number); if ((gplink_number == 1) || (gplink_number ==3)) { /* ignore flag is set */ DEBUG(SSSDBG_TRACE_ALL, "ignored gpo skipped\n"); ptr = last; continue; } if (allow_enforced_only && (gplink_number == 0)) { /* unenforced flag is set; only enforced gpos allowed */ DEBUG(SSSDBG_TRACE_ALL, "unenforced gpo skipped\n"); ptr = last; continue; } gplink_list[num_enabled] = talloc_zero(gplink_list, struct gp_gplink); if (gplink_list[num_enabled] == NULL) { ret = ENOMEM; goto done; } gplink_list[num_enabled]->gpo_dn = talloc_strdup(gplink_list[num_enabled], dn); if (gplink_list[num_enabled]->gpo_dn == NULL) { ret = ENOMEM; goto done; } if (gplink_number == 0) { gplink_list[num_enabled]->enforced = 0; num_enabled++; } else if (gplink_number == 2) { gplink_list[num_enabled]->enforced = 1; num_enabled++; } else { ret = EINVAL; goto done; } ptr = last; } gplink_list[num_enabled] = NULL; *_gplink_list = talloc_steal(mem_ctx, gplink_list); ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* == ad_gpo_process_som_send/recv implementation ========================== */ struct ad_gpo_process_som_state { struct tevent_context *ev; struct sdap_id_op *sdap_op; struct sdap_options *opts; int timeout; bool allow_enforced_only; char *site_name; char *site_dn; struct gp_som **som_list; int som_index; int num_soms; }; static void ad_gpo_site_name_retrieval_done(struct tevent_req *subreq); static void ad_gpo_site_dn_retrieval_done(struct tevent_req *subreq); static errno_t ad_gpo_get_som_attrs_step(struct tevent_req *req); static void ad_gpo_get_som_attrs_done(struct tevent_req *subreq); /* * This function uses the input target_dn and input domain_name to populate * a list of gp_som objects. Each object in this list represents a SOM * associated with the target (such as OU, Domain, and Site). * * The inputs are used to determine the DNs of each SOM associated with the * target. In turn, the SOM object DNs are used to retrieve certain LDAP * attributes of each SOM object, that are parsed into an array of gp_gplink * objects, essentially representing the GPOs that have been linked to each * SOM object. Note that it is perfectly valid for there to be *no* GPOs * linked to a SOM object. */ struct tevent_req * ad_gpo_process_som_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_conn_ctx *conn, struct ldb_context *ldb_ctx, struct sdap_id_op *sdap_op, struct sdap_options *opts, int timeout, const char *target_dn, const char *domain_name) { struct tevent_req *req; struct tevent_req *subreq; struct ad_gpo_process_som_state *state; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ad_gpo_process_som_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->sdap_op = sdap_op; state->opts = opts; state->timeout = timeout; state->som_index = 0; state->allow_enforced_only = 0; ret = ad_gpo_populate_som_list(state, ldb_ctx, target_dn, &state->num_soms, &state->som_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve SOM List : [%d](%s)\n", ret, sss_strerror(ret)); ret = ENOENT; goto immediately; } if (state->som_list == NULL) { DEBUG(SSSDBG_OP_FAILURE, "target dn must have at least one parent\n"); ret = EINVAL; goto immediately; } subreq = ad_master_domain_send(state, state->ev, conn, state->sdap_op, domain_name); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ad_master_domain_send failed.\n"); ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, ad_gpo_site_name_retrieval_done, req); ret = EOK; immediately: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void ad_gpo_site_name_retrieval_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_gpo_process_som_state *state; int ret; char *site; const char *attrs[] = {AD_AT_CONFIG_NC, NULL}; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_process_som_state); /* gpo code only cares about the site name */ ret = ad_master_domain_recv(subreq, state, NULL, NULL, &site, NULL); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot retrieve master domain info\n"); tevent_req_error(req, ENOENT); return; } state->site_name = talloc_asprintf(state, "cn=%s", site); if (state->site_name == NULL) { tevent_req_error(req, ENOMEM); return; } /* * note: the configNC attribute is being retrieved here from the rootDSE * entry. In future, since we already make an LDAP query for the rootDSE * entry when LDAP connection is made, this attribute should really be * retrieved at that point (see https://fedorahosted.org/sssd/ticket/2276) */ subreq = sdap_get_generic_send(state, state->ev, state->opts, sdap_id_op_handle(state->sdap_op), "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, NULL, 0, state->timeout, false); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, ad_gpo_site_dn_retrieval_done, req); } static void ad_gpo_site_dn_retrieval_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_gpo_process_som_state *state; int ret; int dp_error; int i = 0; size_t reply_count; struct sysdb_attrs **reply; const char *configNC; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_process_som_state); ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply); talloc_zfree(subreq); if (ret != EOK) { ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); DEBUG(SSSDBG_OP_FAILURE, "Unable to get configNC: [%d](%s)\n", ret, sss_strerror(ret)); ret = ENOENT; goto done; } /* make sure there is only one non-NULL reply returned */ if (reply_count < 1) { DEBUG(SSSDBG_OP_FAILURE, "No configNC retrieved\n"); ret = ENOENT; goto done; } else if (reply_count > 1) { DEBUG(SSSDBG_OP_FAILURE, "Multiple replies for configNC\n"); ret = ERR_INTERNAL; goto done; } else if (reply == NULL) { DEBUG(SSSDBG_OP_FAILURE, "reply_count is 1, but reply is NULL\n"); ret = ERR_INTERNAL; goto done; } /* reply[0] holds requested attributes of single reply */ ret = sysdb_attrs_get_string(reply[0], AD_AT_CONFIG_NC, &configNC); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } state->site_dn = talloc_asprintf(state, "%s,cn=Sites,%s", state->site_name, configNC); if (state->site_dn == NULL) { ret = ENOMEM; goto done; } /* note that space was allocated for site_dn when allocating som_list */ state->som_list[state->num_soms] = talloc_zero(state->som_list, struct gp_som); if (state->som_list[state->num_soms] == NULL) { ret = ENOMEM; goto done; } state->som_list[state->num_soms]->som_dn = talloc_steal(state->som_list[state->num_soms], state->site_dn); if (state->som_list[state->num_soms]->som_dn == NULL) { ret = ENOMEM; goto done; } state->num_soms++; state->som_list[state->num_soms] = NULL; i = 0; while (state->som_list[i]) { DEBUG(SSSDBG_TRACE_FUNC, "som_list[%d]->som_dn is %s\n", i, state->som_list[i]->som_dn); i++; } ret = ad_gpo_get_som_attrs_step(req); done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static errno_t ad_gpo_get_som_attrs_step(struct tevent_req *req) { const char *attrs[] = {AD_AT_GPLINK, AD_AT_GPOPTIONS, NULL}; struct tevent_req *subreq; struct ad_gpo_process_som_state *state; state = tevent_req_data(req, struct ad_gpo_process_som_state); struct gp_som *gp_som = state->som_list[state->som_index]; /* gp_som is NULL only after all SOMs have been processed */ if (gp_som == NULL) return EOK; const char *som_dn = gp_som->som_dn; subreq = sdap_get_generic_send(state, state->ev, state->opts, sdap_id_op_handle(state->sdap_op), som_dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, NULL, 0, state->timeout, false); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, ad_gpo_get_som_attrs_done, req); return EAGAIN; } static void ad_gpo_get_som_attrs_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_gpo_process_som_state *state; int ret; int dp_error; size_t num_results; struct sysdb_attrs **results; struct ldb_message_element *el = NULL; uint8_t *raw_gplink_value; uint8_t *raw_gpoptions_value; uint32_t allow_enforced_only = 0; struct gp_som *gp_som; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_process_som_state); ret = sdap_get_generic_recv(subreq, state, &num_results, &results); talloc_zfree(subreq); if (ret != EOK) { ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); DEBUG(SSSDBG_OP_FAILURE, "Unable to get SOM attributes: [%d](%s)\n", ret, sss_strerror(ret)); ret = ENOENT; goto done; } if ((num_results < 1) || (results == NULL)) { DEBUG(SSSDBG_OP_FAILURE, "no attrs found for SOM; try next SOM.\n"); state->som_index++; ret = ad_gpo_get_som_attrs_step(req); goto done; } else if (num_results > 1) { DEBUG(SSSDBG_OP_FAILURE, "Received multiple replies\n"); ret = ERR_INTERNAL; goto done; } /* Get the gplink value, if available */ ret = sysdb_attrs_get_el(results[0], AD_AT_GPLINK, &el); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } if ((ret == ENOENT) || (el->num_values == 0)) { DEBUG(SSSDBG_OP_FAILURE, "no attrs found for SOM; try next SOM\n"); state->som_index++; ret = ad_gpo_get_som_attrs_step(req); goto done; } raw_gplink_value = el[0].values[0].data; ret = sysdb_attrs_get_el(results[0], AD_AT_GPOPTIONS, &el); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n"); goto done; } if ((ret == ENOENT) || (el->num_values == 0)) { DEBUG(SSSDBG_TRACE_ALL, "gpoptions attr not found or has no value; defaults to 0\n"); allow_enforced_only = 0; } else { raw_gpoptions_value = el[0].values[0].data; allow_enforced_only = strtouint32((char *)raw_gpoptions_value, NULL, 10); if (errno != 0) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "strtouint32 failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } } gp_som = state->som_list[state->som_index]; ret = ad_gpo_populate_gplink_list(gp_som, gp_som->som_dn, (char *)raw_gplink_value, &gp_som->gplink_list, state->allow_enforced_only); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ad_gpo_populate_gplink_list() failed\n"); goto done; } if (allow_enforced_only) { state->allow_enforced_only = 1; } state->som_index++; ret = ad_gpo_get_som_attrs_step(req); done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } int ad_gpo_process_som_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct gp_som ***som_list) { struct ad_gpo_process_som_state *state = tevent_req_data(req, struct ad_gpo_process_som_state); TEVENT_REQ_RETURN_ON_ERROR(req); *som_list = talloc_steal(mem_ctx, state->som_list); return EOK; } /* == ad_gpo_process_gpo_send/recv helpers ================================= */ /* * This function examines the gp_gplink objects in each gp_som object specified * in the input som_list, and populates the _candidate_gpos output parameter's * gpo_dn fields with prioritized list of GPO DNs. Prioritization ensures that: * - GPOs linked to an OU will be applied after GPOs linked to a Domain, * which will be applied after GPOs linked to a Site. * - multiple GPOs linked to a single SOM are applied in their link order * (i.e. 1st GPO linked to SOM is applied after 2nd GPO linked to SOM, etc). * - enforced GPOs are applied after unenforced GPOs. * * As such, the _candidate_gpos output's dn fields looks like (in link order): * [unenforced {Site, Domain, OU}; enforced {Site, Domain, OU}] * * Note that in the case of conflicting policy settings, GPOs appearing later * in the list will trump GPOs appearing earlier in the list. */ static errno_t ad_gpo_populate_candidate_gpos(TALLOC_CTX *mem_ctx, struct gp_som **som_list, struct gp_gpo ***_candidate_gpos, int *_num_candidate_gpos) { TALLOC_CTX *tmp_ctx = NULL; struct gp_som *gp_som = NULL; struct gp_gplink *gp_gplink = NULL; struct gp_gpo **candidate_gpos = NULL; int num_candidate_gpos = 0; const char **enforced_gpo_dns = NULL; const char **unenforced_gpo_dns = NULL; int gpo_dn_idx = 0; int num_enforced = 0; int enforced_idx = 0; int num_unenforced = 0; int unenforced_idx = 0; int i = 0; int j = 0; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } while (som_list[i]) { gp_som = som_list[i]; j = 0; while (gp_som && gp_som->gplink_list && gp_som->gplink_list[j]) { gp_gplink = gp_som->gplink_list[j]; if (gp_gplink == NULL) { DEBUG(SSSDBG_OP_FAILURE, "unexpected null gp_gplink\n"); ret = EINVAL; goto done; } if (gp_gplink->enforced) { num_enforced++; } else { num_unenforced++; } j++; } i++; } num_candidate_gpos = num_enforced + num_unenforced; if (num_candidate_gpos == 0) { *_candidate_gpos = NULL; *_num_candidate_gpos = 0; ret = EOK; goto done; } enforced_gpo_dns = talloc_array(tmp_ctx, const char *, num_enforced + 1); if (enforced_gpo_dns == NULL) { ret = ENOMEM; goto done; } unenforced_gpo_dns = talloc_array(tmp_ctx, const char *, num_unenforced + 1); if (unenforced_gpo_dns == NULL) { ret = ENOMEM; goto done; } i = 0; while (som_list[i]) { gp_som = som_list[i]; j = 0; while (gp_som && gp_som->gplink_list && gp_som->gplink_list[j]) { gp_gplink = gp_som->gplink_list[j]; if (gp_gplink == NULL) { DEBUG(SSSDBG_OP_FAILURE, "unexpected null gp_gplink\n"); ret = EINVAL; goto done; } if (gp_gplink->enforced) { enforced_gpo_dns[enforced_idx] = talloc_steal(enforced_gpo_dns, gp_gplink->gpo_dn); if (enforced_gpo_dns[enforced_idx] == NULL) { ret = ENOMEM; goto done; } enforced_idx++; } else { unenforced_gpo_dns[unenforced_idx] = talloc_steal(unenforced_gpo_dns, gp_gplink->gpo_dn); if (unenforced_gpo_dns[unenforced_idx] == NULL) { ret = ENOMEM; goto done; } unenforced_idx++; } j++; } i++; } enforced_gpo_dns[num_enforced] = NULL; unenforced_gpo_dns[num_unenforced] = NULL; candidate_gpos = talloc_array(tmp_ctx, struct gp_gpo *, num_candidate_gpos + 1); if (candidate_gpos == NULL) { ret = ENOMEM; goto done; } gpo_dn_idx = 0; for (i = num_unenforced - 1; i >= 0; i--) { candidate_gpos[gpo_dn_idx] = talloc_zero(candidate_gpos, struct gp_gpo); if (candidate_gpos[gpo_dn_idx] == NULL) { ret = ENOMEM; goto done; } candidate_gpos[gpo_dn_idx]->gpo_dn = talloc_steal(candidate_gpos[gpo_dn_idx], unenforced_gpo_dns[i]); if (candidate_gpos[gpo_dn_idx]->gpo_dn == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "candidate_gpos[%d]->gpo_dn: %s\n", gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn); gpo_dn_idx++; } for (i = 0; i < num_enforced; i++) { candidate_gpos[gpo_dn_idx] = talloc_zero(candidate_gpos, struct gp_gpo); if (candidate_gpos[gpo_dn_idx] == NULL) { ret = ENOMEM; goto done; } candidate_gpos[gpo_dn_idx]->gpo_dn = talloc_steal(candidate_gpos[gpo_dn_idx], enforced_gpo_dns[i]); if (candidate_gpos[gpo_dn_idx]->gpo_dn == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "candidate_gpos[%d]->gpo_dn: %s\n", gpo_dn_idx, candidate_gpos[gpo_dn_idx]->gpo_dn); gpo_dn_idx++; } candidate_gpos[gpo_dn_idx] = NULL; *_candidate_gpos = talloc_steal(mem_ctx, candidate_gpos); *_num_candidate_gpos = num_candidate_gpos; ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* * This function parses the input_path into its components, replaces each * back slash ('\') with a forward slash ('/'), and populates the output params. * * The smb_server output is constructed by concatenating the following elements: * - SMB_STANDARD_URI ("smb://") * - server_hostname (which replaces domain_name in input path) * The smb_share and smb_path outputs are extracted from the input_path. * * Example: if input_path = "\\foo.com\SysVol\foo.com\..." and * server_hostname = "adserver.foo.com", then * _smb_server = "smb://adserver.foo.com" * _smb_share = "SysVol" * _smb_path = "/foo.com/..." * * Note that the input_path must have at least four forward slash separators. * For example, input_path = "\\foo.com\SysVol" is not a valid input_path, * because it has only three forward slash separators. */ static errno_t ad_gpo_extract_smb_components(TALLOC_CTX *mem_ctx, char *server_hostname, char *input_path, const char **_smb_server, const char **_smb_share, const char **_smb_path) { char *ptr; const char delim = '\\'; int ret; int num_seps = 0; char *smb_path = NULL; char *smb_share = NULL; DEBUG(SSSDBG_TRACE_ALL, "input_path: %s\n", input_path); if (input_path == NULL || *input_path == '\0' || _smb_server == NULL || _smb_share == NULL || _smb_path == NULL) { ret = EINVAL; goto done; } ptr = input_path; while ((ptr = strchr(ptr, delim))) { num_seps++; if (num_seps == 3) { /* replace the slash before the share name with null string */ *ptr = '\0'; ptr++; smb_share = ptr; continue; } else if (num_seps == 4) { /* replace the slash after the share name with null string */ *ptr = '\0'; ptr++; smb_path = ptr; continue; } *ptr = '/'; ptr++; } if (num_seps == 0) { ret = EINVAL; goto done; } if (smb_path == NULL) { ret = EINVAL; goto done; } *_smb_server = talloc_asprintf(mem_ctx, "%s%s", SMB_STANDARD_URI, server_hostname); if (*_smb_server == NULL) { ret = ENOMEM; goto done; } *_smb_share = talloc_asprintf(mem_ctx, "/%s", smb_share); if (*_smb_share == NULL) { ret = ENOMEM; goto done; } *_smb_path = talloc_asprintf(mem_ctx, "/%s", smb_path); if (*_smb_path == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: return ret; } /* * This function populates the _cse_guid_list output parameter by parsing the * input raw_machine_ext_names_value into an array of cse_guid strings. * * The raw_machine_ext_names_value is a single string in the following format: * "[{cse_guid_1}{tool_guid1}]...[{cse_guid_n}{tool_guid_n}]" */ static errno_t ad_gpo_parse_machine_ext_names(TALLOC_CTX *mem_ctx, char *raw_machine_ext_names_value, const char ***_gpo_cse_guids, int *_num_gpo_cse_guids) { TALLOC_CTX *tmp_ctx = NULL; char *ptr; char *first; char *last; char *cse_guid; char *tool_guid; const char delim = ']'; const char **gpo_cse_guids; int i; int ret; int num_gpo_cse_guids = 0; if (raw_machine_ext_names_value == NULL || *raw_machine_ext_names_value == '\0' || _gpo_cse_guids == NULL) { return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ptr = raw_machine_ext_names_value; while ((ptr = strchr(ptr, delim))) { ptr++; num_gpo_cse_guids++; } if (num_gpo_cse_guids == 0) { ret = EINVAL; goto done; } gpo_cse_guids = talloc_array(tmp_ctx, const char *, num_gpo_cse_guids + 1); if (gpo_cse_guids == NULL) { ret = ENOMEM; goto done; } ptr = raw_machine_ext_names_value; for (i = 0; i < num_gpo_cse_guids; i++) { first = ptr + 1; last = strchr(first, delim); if (last == NULL) { break; } *last = '\0'; last++; cse_guid = first; first ++; tool_guid = strchr(first, '{'); if (tool_guid == NULL) { break; } *tool_guid = '\0'; gpo_cse_guids[i] = talloc_strdup(gpo_cse_guids, cse_guid); ptr = last; } gpo_cse_guids[i] = NULL; DEBUG(SSSDBG_TRACE_ALL, "num_gpo_cse_guids: %d\n", num_gpo_cse_guids); for (i = 0; i < num_gpo_cse_guids; i++) { DEBUG(SSSDBG_TRACE_ALL, "gpo_cse_guids[%d] is %s\n", i, gpo_cse_guids[i]); } *_gpo_cse_guids = talloc_steal(mem_ctx, gpo_cse_guids); *_num_gpo_cse_guids = num_gpo_cse_guids; ret = EOK; done: talloc_free(tmp_ctx); return ret; } enum ndr_err_code ad_gpo_ndr_pull_security_descriptor(struct ndr_pull *ndr, int ndr_flags, struct security_descriptor *r); /* * This function parses the input data blob and assigns the resulting * security_descriptor object to the _gpo_sd output parameter. */ static errno_t ad_gpo_parse_sd(TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, struct security_descriptor **_gpo_sd) { struct ndr_pull *ndr_pull = NULL; struct security_descriptor sd; DATA_BLOB blob; enum ndr_err_code ndr_err; blob.data = data; blob.length = length; ndr_pull = ndr_pull_init_blob(&blob, mem_ctx); if (ndr_pull == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_init_blob() failed.\n"); return EINVAL; } ndr_err = ad_gpo_ndr_pull_security_descriptor(ndr_pull, NDR_SCALARS|NDR_BUFFERS, &sd); if (ndr_err != NDR_ERR_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to pull security descriptor\n"); return EINVAL; } *_gpo_sd = talloc_memdup(mem_ctx, &sd, sizeof(struct security_descriptor)); return EOK; } /* == ad_gpo_process_gpo_send/recv implementation ========================== */ struct ad_gpo_process_gpo_state { struct ad_access_ctx *access_ctx; struct tevent_context *ev; struct sdap_id_op *sdap_op; struct sdap_options *opts; char *server_hostname; struct sss_domain_info *host_domain; int timeout; struct gp_gpo **candidate_gpos; int num_candidate_gpos; int gpo_index; }; static errno_t ad_gpo_get_gpo_attrs_step(struct tevent_req *req); static void ad_gpo_get_gpo_attrs_done(struct tevent_req *subreq); /* * This function uses the input som_list to populate a prioritized list of * gp_gpo objects, prioritized based on SOM type, link order, and whether the * GPO is "enforced". This list represents the initial set of candidate GPOs * that might be applicable to the target. This list can not be expanded, but * it might be reduced based on subsequent filtering steps. The GPO object DNs * are used to retrieve certain LDAP attributes of each GPO object, that are * parsed into the various fields of the gp_gpo object. */ struct tevent_req * ad_gpo_process_gpo_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_op *sdap_op, struct sdap_options *opts, char *server_hostname, struct sss_domain_info *host_domain, struct ad_access_ctx *access_ctx, int timeout, struct gp_som **som_list) { struct tevent_req *req; struct ad_gpo_process_gpo_state *state; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ad_gpo_process_gpo_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->sdap_op = sdap_op; state->opts = opts; state->server_hostname = server_hostname; state->host_domain = host_domain; state->access_ctx = access_ctx; state->timeout = timeout; state->gpo_index = 0; state->candidate_gpos = NULL; state->num_candidate_gpos = 0; ret = ad_gpo_populate_candidate_gpos(state, som_list, &state->candidate_gpos, &state->num_candidate_gpos); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve GPO List: [%d](%s)\n", ret, sss_strerror(ret)); goto immediately; } if (state->candidate_gpos == NULL) { DEBUG(SSSDBG_OP_FAILURE, "no gpos found\n"); ret = ENOENT; goto immediately; } ret = ad_gpo_get_gpo_attrs_step(req); immediately: if (ret == EOK) { tevent_req_done(req); tevent_req_post(req, ev); } else if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static errno_t ad_gpo_get_gpo_attrs_step(struct tevent_req *req) { const char *attrs[] = AD_GPO_ATTRS; struct tevent_req *subreq; struct ad_gpo_process_gpo_state *state; state = tevent_req_data(req, struct ad_gpo_process_gpo_state); struct gp_gpo *gp_gpo = state->candidate_gpos[state->gpo_index]; /* gp_gpo is NULL only after all GPOs have been processed */ if (gp_gpo == NULL) return EOK; const char *gpo_dn = gp_gpo->gpo_dn; subreq = sdap_sd_search_send(state, state->ev, state->opts, sdap_id_op_handle(state->sdap_op), gpo_dn, SECINFO_DACL, attrs, state->timeout); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_sd_search_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, ad_gpo_get_gpo_attrs_done, req); return EAGAIN; } static errno_t ad_gpo_sd_process_attrs(struct tevent_req *req, char *smb_host, struct sysdb_attrs *result); void ad_gpo_get_sd_referral_done(struct tevent_req *subreq); static struct tevent_req * ad_gpo_get_sd_referral_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ad_access_ctx *access_ctx, struct sdap_options *opts, const char *referral, struct sss_domain_info *host_domain, int timeout); errno_t ad_gpo_get_sd_referral_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **_smb_host, struct sysdb_attrs **_reply); static void ad_gpo_get_gpo_attrs_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_gpo_process_gpo_state *state; int ret; int dp_error; size_t num_results, refcount; struct sysdb_attrs **results; char **refs; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_process_gpo_state); ret = sdap_sd_search_recv(subreq, state, &num_results, &results, &refcount, &refs); talloc_zfree(subreq); if (ret != EOK) { ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); DEBUG(SSSDBG_OP_FAILURE, "Unable to get GPO attributes: [%d](%s)\n", ret, sss_strerror(ret)); ret = ENOENT; goto done; } if ((num_results < 1) || (results == NULL)) { if (refcount == 1) { /* If we were redirected to a referral, process it. * There must be a single referral result here; if we get * more than one (or zero) it's a bug. */ subreq = ad_gpo_get_sd_referral_send(state, state->ev, state->access_ctx, state->opts, refs[0], state->host_domain, state->timeout); if (!subreq) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ad_gpo_get_sd_referral_done, req); ret = EAGAIN; goto done; } else { const char *gpo_dn = state->candidate_gpos[state->gpo_index]->gpo_dn; DEBUG(SSSDBG_OP_FAILURE, "No attrs found for GPO [%s].\n", gpo_dn); ret = ENOENT; goto done; } } else if (num_results > 1) { DEBUG(SSSDBG_OP_FAILURE, "Received multiple replies\n"); ret = ERR_INTERNAL; goto done; } ret = ad_gpo_sd_process_attrs(req, state->server_hostname, results[0]); done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } void ad_gpo_get_sd_referral_done(struct tevent_req *subreq) { errno_t ret; int dp_error; struct sysdb_attrs *reply; char *smb_host; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ad_gpo_process_gpo_state *state = tevent_req_data(req, struct ad_gpo_process_gpo_state); ret = ad_gpo_get_sd_referral_recv(subreq, state, &smb_host, &reply); talloc_zfree(subreq); if (ret != EOK) { /* Terminate the sdap_id_op */ ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); DEBUG(SSSDBG_OP_FAILURE, "Unable to get referred GPO attributes: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } /* Lookup succeeded. Process it */ ret = ad_gpo_sd_process_attrs(req, smb_host, reply); done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static errno_t ad_gpo_sd_process_attrs(struct tevent_req *req, char *smb_host, struct sysdb_attrs *result) { struct ad_gpo_process_gpo_state *state; struct gp_gpo *gp_gpo; int ret; struct ldb_message_element *el = NULL; const char *gpo_guid = NULL; const char *raw_file_sys_path = NULL; char *file_sys_path = NULL; uint8_t *raw_machine_ext_names = NULL; state = tevent_req_data(req, struct ad_gpo_process_gpo_state); gp_gpo = state->candidate_gpos[state->gpo_index]; /* retrieve AD_AT_CN */ ret = sysdb_attrs_get_string(result, AD_AT_CN, &gpo_guid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } gp_gpo->gpo_guid = talloc_steal(gp_gpo, gpo_guid); if (gp_gpo->gpo_guid == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_ALL, "populating attrs for gpo_guid: %s\n", gp_gpo->gpo_guid); /* retrieve AD_AT_FILE_SYS_PATH */ ret = sysdb_attrs_get_string(result, AD_AT_FILE_SYS_PATH, &raw_file_sys_path); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } file_sys_path = talloc_strdup(gp_gpo, raw_file_sys_path); ret = ad_gpo_extract_smb_components(gp_gpo, smb_host, file_sys_path, &gp_gpo->smb_server, &gp_gpo->smb_share, &gp_gpo->smb_path); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "unable to extract smb components from file_sys_path: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_ALL, "smb_server: %s\n", gp_gpo->smb_server); DEBUG(SSSDBG_TRACE_ALL, "smb_share: %s\n", gp_gpo->smb_share); DEBUG(SSSDBG_TRACE_ALL, "smb_path: %s\n", gp_gpo->smb_path); /* retrieve AD_AT_FUNC_VERSION */ ret = sysdb_attrs_get_int32_t(result, AD_AT_FUNC_VERSION, &gp_gpo->gpo_func_version); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_int32_t failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_ALL, "gpo_func_version: %d\n", gp_gpo->gpo_func_version); /* retrieve AD_AT_FLAGS */ ret = sysdb_attrs_get_int32_t(result, AD_AT_FLAGS, &gp_gpo->gpo_flags); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_int32_t failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_ALL, "gpo_flags: %d\n", gp_gpo->gpo_flags); /* retrieve AD_AT_NT_SEC_DESC */ ret = sysdb_attrs_get_el(result, AD_AT_NT_SEC_DESC, &el); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n"); goto done; } if ((ret == ENOENT) || (el->num_values == 0)) { DEBUG(SSSDBG_OP_FAILURE, "nt_sec_desc attribute not found or has no value\n"); ret = ENOENT; goto done; } ret = ad_gpo_parse_sd(gp_gpo, el[0].values[0].data, el[0].values[0].length, &gp_gpo->gpo_sd); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ad_gpo_parse_sd() failed\n"); goto done; } /* retrieve AD_AT_MACHINE_EXT_NAMES */ ret = sysdb_attrs_get_el(result, AD_AT_MACHINE_EXT_NAMES, &el); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n"); goto done; } if ((ret == ENOENT) || (el->num_values == 0)) { /* * if gpo has no machine_ext_names (which is perfectly valid: it could * have only user_ext_names, for example), we continue to next gpo */ DEBUG(SSSDBG_TRACE_ALL, "machine_ext_names attribute not found or has no value\n"); state->gpo_index++; } else { raw_machine_ext_names = el[0].values[0].data; ret = ad_gpo_parse_machine_ext_names(gp_gpo, (char *)raw_machine_ext_names, &gp_gpo->gpo_cse_guids, &gp_gpo->num_gpo_cse_guids); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ad_gpo_parse_machine_ext_names() failed\n"); goto done; } state->gpo_index++; } ret = ad_gpo_get_gpo_attrs_step(req); done: return ret; } int ad_gpo_process_gpo_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct gp_gpo ***candidate_gpos, int *num_candidate_gpos) { struct ad_gpo_process_gpo_state *state = tevent_req_data(req, struct ad_gpo_process_gpo_state); TEVENT_REQ_RETURN_ON_ERROR(req); *candidate_gpos = talloc_steal(mem_ctx, state->candidate_gpos); *num_candidate_gpos = state->num_candidate_gpos; return EOK; } /* == ad_gpo_process_cse_send/recv helpers ================================= */ static errno_t create_cse_send_buffer(TALLOC_CTX *mem_ctx, const char *smb_server, const char *smb_share, const char *smb_path, const char *smb_cse_suffix, int cached_gpt_version, struct io_buffer **io_buf) { struct io_buffer *buf; size_t rp; int smb_server_length; int smb_share_length; int smb_path_length; int smb_cse_suffix_length; smb_server_length = strlen(smb_server); smb_share_length = strlen(smb_share); smb_path_length = strlen(smb_path); smb_cse_suffix_length = strlen(smb_cse_suffix); buf = talloc(mem_ctx, struct io_buffer); if (buf == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); return ENOMEM; } buf->size = 5 * sizeof(uint32_t); buf->size += smb_server_length + smb_share_length + smb_path_length + smb_cse_suffix_length; DEBUG(SSSDBG_TRACE_ALL, "buffer size: %zu\n", buf->size); buf->data = talloc_size(buf, buf->size); if (buf->data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); talloc_free(buf); return ENOMEM; } rp = 0; /* cached_gpt_version */ SAFEALIGN_SET_UINT32(&buf->data[rp], cached_gpt_version, &rp); /* smb_server */ SAFEALIGN_SET_UINT32(&buf->data[rp], smb_server_length, &rp); safealign_memcpy(&buf->data[rp], smb_server, smb_server_length, &rp); /* smb_share */ SAFEALIGN_SET_UINT32(&buf->data[rp], smb_share_length, &rp); safealign_memcpy(&buf->data[rp], smb_share, smb_share_length, &rp); /* smb_path */ SAFEALIGN_SET_UINT32(&buf->data[rp], smb_path_length, &rp); safealign_memcpy(&buf->data[rp], smb_path, smb_path_length, &rp); /* smb_cse_suffix */ SAFEALIGN_SET_UINT32(&buf->data[rp], smb_cse_suffix_length, &rp); safealign_memcpy(&buf->data[rp], smb_cse_suffix, smb_cse_suffix_length, &rp); *io_buf = buf; return EOK; } static errno_t ad_gpo_parse_gpo_child_response(uint8_t *buf, ssize_t size, uint32_t *_sysvol_gpt_version, uint32_t *_result) { int ret; size_t p = 0; uint32_t sysvol_gpt_version; uint32_t result; /* sysvol_gpt_version */ SAFEALIGN_COPY_UINT32_CHECK(&sysvol_gpt_version, buf + p, size, &p); /* operation result code */ SAFEALIGN_COPY_UINT32_CHECK(&result, buf + p, size, &p); *_sysvol_gpt_version = sysvol_gpt_version; *_result = result; ret = EOK; return ret; } /* == ad_gpo_process_cse_send/recv implementation ========================== */ struct ad_gpo_process_cse_state { struct tevent_context *ev; struct sss_domain_info *domain; int gpo_timeout_option; const char *gpo_guid; const char *smb_path; const char *smb_cse_suffix; pid_t child_pid; uint8_t *buf; ssize_t len; struct child_io_fds *io; }; static errno_t gpo_fork_child(struct tevent_req *req); static void gpo_cse_step(struct tevent_req *subreq); static void gpo_cse_done(struct tevent_req *subreq); /* * This cse-specific function (GP_EXT_GUID_SECURITY) sends the input smb uri * components and cached_gpt_version to the gpo child, which, in turn, * will download the GPT.INI file and policy files (as needed) and store * them in the GPO_CACHE directory. Note that if the send_to_child input is * false, this function simply completes the request. */ struct tevent_req * ad_gpo_process_cse_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, bool send_to_child, struct sss_domain_info *domain, const char *gpo_guid, const char *smb_server, const char *smb_share, const char *smb_path, const char *smb_cse_suffix, int cached_gpt_version, int gpo_timeout_option) { struct tevent_req *req; struct tevent_req *subreq; struct ad_gpo_process_cse_state *state; struct io_buffer *buf = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ad_gpo_process_cse_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } if (!send_to_child) { /* * if we don't need to talk to child (b/c cache timeout is still valid), * we simply complete the request */ ret = EOK; goto immediately; } state->ev = ev; state->buf = NULL; state->len = 0; state->domain = domain; state->gpo_timeout_option = gpo_timeout_option; state->gpo_guid = gpo_guid; state->smb_path = smb_path; state->smb_cse_suffix = smb_cse_suffix; state->io = talloc(state, struct child_io_fds); if (state->io == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); ret = ENOMEM; goto immediately; } state->io->write_to_child_fd = -1; state->io->read_from_child_fd = -1; talloc_set_destructor((void *) state->io, child_io_destructor); /* prepare the data to pass to child */ ret = create_cse_send_buffer(state, smb_server, smb_share, smb_path, smb_cse_suffix, cached_gpt_version, &buf); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "create_cse_send_buffer failed.\n"); goto immediately; } ret = gpo_fork_child(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "gpo_fork_child failed.\n"); goto immediately; } subreq = write_pipe_send(state, ev, buf->data, buf->size, state->io->write_to_child_fd); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, gpo_cse_step, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); tevent_req_post(req, ev); } else { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void gpo_cse_step(struct tevent_req *subreq) { struct tevent_req *req; struct ad_gpo_process_cse_state *state; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_process_cse_state); ret = write_pipe_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } close(state->io->write_to_child_fd); state->io->write_to_child_fd = -1; subreq = read_pipe_send(state, state->ev, state->io->read_from_child_fd); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, gpo_cse_done, req); } static void gpo_cse_done(struct tevent_req *subreq) { struct tevent_req *req; struct ad_gpo_process_cse_state *state; uint32_t sysvol_gpt_version = -1; uint32_t child_result; time_t now; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ad_gpo_process_cse_state); int ret; ret = read_pipe_recv(subreq, state, &state->buf, &state->len); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } close(state->io->read_from_child_fd); state->io->read_from_child_fd = -1; ret = ad_gpo_parse_gpo_child_response(state->buf, state->len, &sysvol_gpt_version, &child_result); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "ad_gpo_parse_gpo_child_response failed: [%d][%s]\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } else if (child_result != 0){ DEBUG(SSSDBG_CRIT_FAILURE, "Error in gpo_child: [%d][%s]\n", child_result, strerror(child_result)); tevent_req_error(req, child_result); return; } now = time(NULL); DEBUG(SSSDBG_TRACE_FUNC, "sysvol_gpt_version: %d\n", sysvol_gpt_version); ret = sysdb_gpo_store_gpo(state->domain, state->gpo_guid, sysvol_gpt_version, state->gpo_timeout_option, now); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to store gpo cache entry: [%d](%s}\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } tevent_req_done(req); return; } int ad_gpo_process_cse_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static errno_t gpo_fork_child(struct tevent_req *req) { int pipefd_to_child[2]; int pipefd_from_child[2]; pid_t pid; int ret; errno_t err; struct ad_gpo_process_cse_state *state; state = tevent_req_data(req, struct ad_gpo_process_cse_state); ret = pipe(pipefd_from_child); if (ret == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", errno, strerror(errno)); return err; } ret = pipe(pipefd_to_child); if (ret == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", errno, strerror(errno)); return err; } pid = fork(); if (pid == 0) { /* child */ err = exec_child_ex(state, pipefd_to_child, pipefd_from_child, GPO_CHILD, gpo_child_debug_fd, NULL, false, STDIN_FILENO, AD_GPO_CHILD_OUT_FILENO); DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec gpo_child: [%d][%s].\n", err, strerror(err)); return err; } else if (pid > 0) { /* parent */ state->child_pid = pid; state->io->read_from_child_fd = pipefd_from_child[0]; close(pipefd_from_child[1]); state->io->write_to_child_fd = pipefd_to_child[1]; close(pipefd_to_child[0]); sss_fd_nonblocking(state->io->read_from_child_fd); sss_fd_nonblocking(state->io->write_to_child_fd); ret = child_handler_setup(state->ev, pid, NULL, NULL, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up child signal handler\n"); return ret; } } else { /* error */ err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n", errno, strerror(errno)); return err; } return EOK; } struct ad_gpo_get_sd_referral_state { struct tevent_context *ev; struct ad_access_ctx *access_ctx; struct sdap_options *opts; struct sss_domain_info *host_domain; struct sss_domain_info *ref_domain; struct sdap_id_conn_ctx *conn; struct sdap_id_op *ref_op; int timeout; char *gpo_dn; char *smb_host; struct sysdb_attrs *reply; }; static void ad_gpo_get_sd_referral_conn_done(struct tevent_req *subreq); static struct tevent_req * ad_gpo_get_sd_referral_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ad_access_ctx *access_ctx, struct sdap_options *opts, const char *referral, struct sss_domain_info *host_domain, int timeout) { errno_t ret; struct tevent_req *req; struct ad_gpo_get_sd_referral_state *state; struct tevent_req *subreq; LDAPURLDesc *lud; req = tevent_req_create(mem_ctx, &state, struct ad_gpo_get_sd_referral_state); if (!req) return NULL; state->ev = ev; state->access_ctx = access_ctx; state->opts = opts; state->host_domain = host_domain; state->timeout = timeout; /* Parse the URL for the domain */ ret = ldap_url_parse(referral, &lud); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse referral URI (%s)!\n", referral); ret = EINVAL; goto done; } state->gpo_dn = talloc_strdup(state, lud->lud_dn); if (!state->gpo_dn) { DEBUG(SSSDBG_OP_FAILURE, "Could not copy referral DN (%s)!\n", lud->lud_dn); ldap_free_urldesc(lud); ret = ENOMEM; goto done; } /* Active Directory returns the domain name as the hostname * in these referrals, so we can use that to look up the * necessary connection. */ state->ref_domain = find_domain_by_name(state->host_domain, lud->lud_host, true); ldap_free_urldesc(lud); if (!state->ref_domain) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not find domain matching [%s]\n", lud->lud_host); ret = EIO; goto done; } state->conn = ad_get_dom_ldap_conn(state->access_ctx->ad_id_ctx, state->ref_domain); if (!state->conn) { DEBUG(SSSDBG_OP_FAILURE, "No connection for %s\n", state->ref_domain->name); ret = EINVAL; goto done; } /* Get the hostname we're going to connect to. * We'll need this later for performing the samba * connection. */ ret = ldap_url_parse(state->conn->service->uri, &lud); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse service URI (%s)!\n", referral); ret = EINVAL; goto done; } state->smb_host = talloc_strdup(state, lud->lud_host); ldap_free_urldesc(lud); if (!state->smb_host) { ret = ENOMEM; goto done; } /* Start an ID operation for the referral */ state->ref_op = sdap_id_op_create(state, state->conn->conn_cache); if (!state->ref_op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n"); ret = ENOMEM; goto done; } /* Establish the sdap_id_op connection */ subreq = sdap_id_op_connect_send(state->ref_op, state, &ret); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n", ret, sss_strerror(ret)); goto done; } tevent_req_set_callback(subreq, ad_gpo_get_sd_referral_conn_done, req); done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void ad_gpo_get_sd_referral_search_done(struct tevent_req *subreq); static void ad_gpo_get_sd_referral_conn_done(struct tevent_req *subreq) { errno_t ret; int dp_error; const char *attrs[] = AD_GPO_ATTRS; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ad_gpo_get_sd_referral_state *state = tevent_req_data(req, struct ad_gpo_get_sd_referral_state); ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_TRACE_FUNC, "Backend is marked offline, retry later!\n"); tevent_req_done(req); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Cross-realm GPO processing failed to connect to " \ "referred LDAP server: (%d)[%s]\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); } return; } /* Request the referred GPO data */ subreq = sdap_sd_search_send(state, state->ev, state->opts, sdap_id_op_handle(state->ref_op), state->gpo_dn, SECINFO_DACL, attrs, state->timeout); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_sd_search_send failed.\n"); tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, ad_gpo_get_sd_referral_search_done, req); } static void ad_gpo_get_sd_referral_search_done(struct tevent_req *subreq) { errno_t ret; int dp_error; size_t num_results, num_refs; struct sysdb_attrs **results = NULL; char **refs; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ad_gpo_get_sd_referral_state *state = tevent_req_data(req, struct ad_gpo_get_sd_referral_state); ret = sdap_sd_search_recv(subreq, NULL, &num_results, &results, &num_refs, &refs); talloc_zfree(subreq); if (ret != EOK) { ret = sdap_id_op_done(state->ref_op, ret, &dp_error); DEBUG(SSSDBG_OP_FAILURE, "Unable to get GPO attributes: [%d](%s)\n", ret, sss_strerror(ret)); ret = ENOENT; goto done; } if ((num_results < 1) || (results == NULL)) { /* TODO: * It's strictly possible for the referral search to return * another referral value here, but it shouldn't actually * happen with Active Directory. Properly handling (and * limiting) the referral chain would be fairly complex, so * we will do it later if it ever becomes necessary. */ DEBUG(SSSDBG_OP_FAILURE, "No attrs found for referred GPO [%s].\n", state->gpo_dn); ret = ENOENT; goto done; } else if (num_results > 1) { DEBUG(SSSDBG_OP_FAILURE, "Received multiple replies\n"); ret = ERR_INTERNAL; goto done; } state->reply = talloc_steal(state, results[0]); done: talloc_free(results); if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } errno_t ad_gpo_get_sd_referral_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **_smb_host, struct sysdb_attrs **_reply) { struct ad_gpo_get_sd_referral_state *state = tevent_req_data(req, struct ad_gpo_get_sd_referral_state); TEVENT_REQ_RETURN_ON_ERROR(req); *_smb_host = talloc_steal(mem_ctx, state->smb_host); *_reply = talloc_steal(mem_ctx, state->reply); return EOK; } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_opts.c0000644000000000000000000000007312703456111017311 xustar0030 atime=1460561751.643715604 29 ctime=1460561774.68479373 sssd-1.13.4/src/providers/ad/ad_opts.c0000644002412700241270000004066512703456111020774 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "src/providers/data_provider.h" #include "db/sysdb_services.h" #include "db/sysdb_autofs.h" #include "providers/ldap/ldap_common.h" #include "config.h" struct dp_option ad_basic_opts[] = { { "ad_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ad_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ad_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ad_hostname", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "ad_enable_dns_sites", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ad_access_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "ad_enable_gc", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ad_gpo_access_control", DP_OPT_STRING, { AD_GPO_ACCESS_MODE_DEFAULT }, NULL_STRING }, { "ad_gpo_cache_timeout", DP_OPT_NUMBER, { .number = 5 }, NULL_NUMBER }, { "ad_gpo_map_interactive", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ad_gpo_map_remote_interactive", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ad_gpo_map_network", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ad_gpo_map_batch", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ad_gpo_map_service", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ad_gpo_map_permit", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ad_gpo_map_deny", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ad_gpo_default_right", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ad_site", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_confd_path", DP_OPT_STRING, { KRB5_MAPPING_DIR }, NULL_STRING }, { "ad_maximum_machine_account_password_age", DP_OPT_NUMBER, { .number = 30 }, NULL_NUMBER }, { "ad_machine_account_password_renewal_opts", DP_OPT_STRING, { "86400:750" }, NULL_STRING }, DP_OPTION_TERMINATOR }; struct dp_option ad_def_ldap_opts[] = { { "ldap_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_backup_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_default_bind_dn", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_default_authtok_type", DP_OPT_STRING, { "password" }, NULL_STRING}, { "ldap_default_authtok", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB }, { "ldap_search_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "ldap_network_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "ldap_tls_reqcert", DP_OPT_STRING, { "hard" }, NULL_STRING }, { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, { "ldap_user_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_user_extra_attrs", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, { "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_service_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_full_refresh_interval", DP_OPT_NUMBER, { .number = 21600 }, NULL_NUMBER }, /* 360 mins */ { "ldap_sudo_smart_refresh_interval", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER }, /* 15 mins */ { "ldap_sudo_use_host_filter", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_sudo_hostnames", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_ip", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_include_netgroups", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_sudo_include_regexp", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_autofs_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_autofs_map_master_name", DP_OPT_STRING, { "auto.master" }, NULL_STRING }, { "ldap_schema", DP_OPT_STRING, { "ad" }, NULL_STRING }, { "ldap_offline_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, { "ldap_force_upper_case_realm", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_enumeration_refresh_timeout", DP_OPT_NUMBER, { .number = 300 }, NULL_NUMBER }, { "ldap_purge_cache_timeout", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, { "ldap_tls_cacert", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_tls_cacertdir", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_tls_cert", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_tls_key", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_tls_cipher_suite", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_id_use_start_tls", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_id_mapping", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_sasl_mech", DP_OPT_STRING, { "gssapi" }, NULL_STRING }, { "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sasl_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sasl_minssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER }, { "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, /* use the same parm name as the krb5 module so we set it only once */ { "krb5_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "krb5_use_kdcinfo", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_pwd_policy", DP_OPT_STRING, { "none" }, NULL_STRING }, { "ldap_referrals", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "account_cache_expiration", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, { "ldap_dns_service_name", DP_OPT_STRING, { SSS_LDAP_SRV_NAME }, NULL_STRING }, { "ldap_krb5_ticket_lifetime", DP_OPT_NUMBER, { .number = (24 * 60 * 60) }, NULL_NUMBER }, { "ldap_access_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_netgroup_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_group_nesting_level", DP_OPT_NUMBER, { .number = 2 }, NULL_NUMBER }, { "ldap_deref", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_account_expire_policy", DP_OPT_STRING, { "ad" }, NULL_STRING }, { "ldap_access_order", DP_OPT_STRING, { "filter" }, NULL_STRING }, { "ldap_chpass_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_chpass_backup_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_chpass_dns_service_name", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_chpass_update_last_change", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_enumeration_search_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, /* Do not include ldap_auth_disable_tls_never_use_in_production in the * manpages or SSSDConfig API */ { "ldap_auth_disable_tls_never_use_in_production", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_page_size", DP_OPT_NUMBER, { .number = 1000 }, NULL_NUMBER }, { "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER }, { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER }, { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER }, { "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER }, { "ldap_idmap_range_size", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER }, { "ldap_idmap_autorid_compat", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_idmap_default_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_idmap_default_domain_sid", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_idmap_helper_table_size", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER }, { "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_use_tokengroups", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE}, { "ldap_rfc2307_fallback_to_local_users", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_disable_range_retrieval", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_min_id", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER}, { "ldap_max_id", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER}, { "ldap_pwdlockout_dn", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "wildcard_limit", DP_OPT_NUMBER, { .number = 1000 }, NULL_NUMBER}, DP_OPTION_TERMINATOR }; struct dp_option ad_def_krb5_opts[] = { { "krb5_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_ccachedir", DP_OPT_STRING, { DEFAULT_CCACHE_DIR }, NULL_STRING }, { "krb5_ccname_template", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING }, { "krb5_validate", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "krb5_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_backup_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_store_password_if_offline", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "krb5_renewable_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_renew_interval", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_use_fast", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_fast_principal", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "krb5_use_enterprise_principal", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "krb5_use_kdcinfo", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "krb5_map_user", DP_OPT_STRING, NULL_STRING, NULL_STRING }, DP_OPTION_TERMINATOR }; struct sdap_attr_map ad_2008r2_attr_map[] = { { "ldap_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL }, { "ldap_rootdse_last_usn", SDAP_AD_LAST_USN, SYSDB_HIGH_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ad_2008r2_user_map[] = { { "ldap_user_object_class", "user", SYSDB_USER_CLASS, NULL }, { "ldap_user_name", "sAMAccountName", SYSDB_NAME, NULL }, { "ldap_user_pwd", "unixUserPassword", SYSDB_PWD, NULL }, { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL }, { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL }, { "ldap_user_home_directory", "unixHomeDirectory", SYSDB_HOMEDIR, NULL }, { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL }, { "ldap_user_principal", "userPrincipalName", SYSDB_UPN, NULL }, { "ldap_user_fullname", "name", SYSDB_FULLNAME, NULL }, { "ldap_user_member_of", "memberOf", SYSDB_MEMBEROF, NULL }, { "ldap_user_uuid", "objectGUID", SYSDB_UUID, NULL }, { "ldap_user_objectsid", "objectSID", SYSDB_SID, NULL }, { "ldap_user_primary_group", "primaryGroupID", SYSDB_PRIMARY_GROUP, NULL }, { "ldap_user_modify_timestamp", "whenChanged", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_user_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL }, { "ldap_user_shadow_last_change", NULL, SYSDB_SHADOWPW_LASTCHANGE, NULL }, { "ldap_user_shadow_min", NULL, SYSDB_SHADOWPW_MIN, NULL }, { "ldap_user_shadow_max", NULL, SYSDB_SHADOWPW_MAX, NULL }, { "ldap_user_shadow_warning", NULL, SYSDB_SHADOWPW_WARNING, NULL }, { "ldap_user_shadow_inactive", NULL, SYSDB_SHADOWPW_INACTIVE, NULL }, { "ldap_user_shadow_expire", NULL, SYSDB_SHADOWPW_EXPIRE, NULL }, { "ldap_user_shadow_flag", NULL, SYSDB_SHADOWPW_FLAG, NULL }, { "ldap_user_krb_last_pwd_change", NULL, SYSDB_KRBPW_LASTCHANGE, NULL }, { "ldap_user_krb_password_expiration", NULL, SYSDB_KRBPW_EXPIRATION, NULL }, { "ldap_pwd_attribute", NULL, SYSDB_PWD_ATTRIBUTE, NULL }, { "ldap_user_authorized_service", NULL, SYSDB_AUTHORIZED_SERVICE, NULL }, { "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL}, { "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL}, { "ldap_ns_account_lock", NULL, SYSDB_NS_ACCOUNT_LOCK, NULL}, { "ldap_user_authorized_host", NULL, SYSDB_AUTHORIZED_HOST, NULL }, { "ldap_user_nds_login_disabled", NULL, SYSDB_NDS_LOGIN_DISABLED, NULL }, { "ldap_user_nds_login_expiration_time", NULL, SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL }, { "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL }, { "ldap_user_ssh_public_key", NULL, SYSDB_SSH_PUBKEY, NULL }, { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL }, { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ad_2008r2_group_map[] = { { "ldap_group_object_class", "group", SYSDB_GROUP_CLASS, NULL }, { "ldap_group_object_class_alt", NULL, SYSDB_GROUP_CLASS, NULL }, { "ldap_group_name", "sAMAccountName", SYSDB_NAME, NULL }, { "ldap_group_pwd", NULL, SYSDB_PWD, NULL }, { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_group_member", "member", SYSDB_MEMBER, NULL }, { "ldap_group_uuid", "objectGUID", SYSDB_UUID, NULL }, { "ldap_group_objectsid", "objectSID", SYSDB_SID, NULL }, { "ldap_group_modify_timestamp", "whenChanged", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_group_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL }, { "ldap_group_type", "groupType", SYSDB_GROUP_TYPE, NULL }, { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ad_netgroup_map[] = { { "ldap_netgroup_object_class", "nisNetgroup", SYSDB_NETGROUP_CLASS, NULL }, { "ldap_netgroup_name", "cn", SYSDB_NAME, NULL }, { "ldap_netgroup_member", "memberNisNetgroup", SYSDB_ORIG_NETGROUP_MEMBER, NULL }, { "ldap_netgroup_triple", "nisNetgroupTriple", SYSDB_NETGROUP_TRIPLE, NULL }, { "ldap_netgroup_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ad_service_map[] = { { "ldap_service_object_class", "ipService", SYSDB_SVC_CLASS, NULL }, { "ldap_service_name", "cn", SYSDB_NAME, NULL }, { "ldap_service_port", "ipServicePort", SYSDB_SVC_PORT, NULL }, { "ldap_service_proto", "ipServiceProtocol", SYSDB_SVC_PROTO, NULL }, { "ldap_service_entry_usn", NULL, SYSDB_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ad_autofs_mobject_map[] = { { "ldap_autofs_map_object_class", "nisMap", SYSDB_AUTOFS_MAP_OC, NULL }, { "ldap_autofs_map_name", "nisMapName", SYSDB_AUTOFS_MAP_NAME, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ad_autofs_entry_map[] = { { "ldap_autofs_entry_object_class", "nisObject", SYSDB_AUTOFS_ENTRY_OC, NULL }, { "ldap_autofs_entry_key", "cn", SYSDB_AUTOFS_ENTRY_KEY, NULL }, { "ldap_autofs_entry_value", "nisMapEntry", SYSDB_AUTOFS_ENTRY_VALUE, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct dp_option ad_dyndns_opts[] = { { "dyndns_update", DP_OPT_BOOL, BOOL_TRUE, BOOL_FALSE }, { "dyndns_refresh_interval", DP_OPT_NUMBER, { .number = 86400 }, NULL_NUMBER }, { "dyndns_iface", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "dyndns_ttl", DP_OPT_NUMBER, { .number = 3600 }, NULL_NUMBER }, { "dyndns_update_ptr", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "dyndns_force_tcp", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "dyndns_auth", DP_OPT_STRING, { "gss-tsig" }, NULL_STRING }, { "dyndns_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, DP_OPTION_TERMINATOR }; sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_autofs.c0000644000000000000000000000007412703456111017626 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.701793788 sssd-1.13.4/src/providers/ad/ad_autofs.c0000644002412700241270000000316212703456111021277 0ustar00jhrozekjhrozek00000000000000/* SSSD AD autofs Provider Initialization functions Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ad/ad_common.h" #include "providers/ldap/sdap_autofs.h" int ad_autofs_init(struct be_ctx *be_ctx, struct ad_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data) { int ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing autofs AD back end\n"); ret = sdap_autofs_init(be_ctx, id_ctx->sdap_id_ctx, ops, pvt_data); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD autofs [%d]: %s\n", ret, sss_strerror(ret)); return ret; } ret = ad_get_autofs_options(id_ctx->ad_options, be_ctx->cdb, be_ctx->conf_path); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD autofs [%d]: %s\n", ret, sss_strerror(ret)); return ret; } return EOK; } sssd-1.13.4/src/providers/ad/PaxHeaders.16287/ad_machine_pw_renewal.c0000644000000000000000000000007412703456111022154 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.689793747 sssd-1.13.4/src/providers/ad/ad_machine_pw_renewal.c0000644002412700241270000003060412703456111023626 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Sumit Bose Copyright (C) 2016 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/strtonum.h" #include "providers/dp_ptask.h" #include "providers/ad/ad_common.h" #ifndef RENEWAL_PROG_PATH #define RENEWAL_PROG_PATH "/usr/sbin/adcli" #endif struct renewal_data { struct be_ctx *be_ctx; char *prog_path; const char **extra_args; }; static errno_t get_adcli_extra_args(const char *ad_domain, const char *ad_hostname, const char *ad_keytab, size_t pw_lifetime_in_days, size_t period, size_t initial_delay, struct renewal_data *renewal_data) { const char **args; size_t c = 0; if (ad_domain == NULL || ad_hostname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing AD domain or hostname.\n"); return EINVAL; } renewal_data->prog_path = talloc_strdup(renewal_data, RENEWAL_PROG_PATH); if (renewal_data->prog_path == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); return ENOMEM; } args = talloc_array(renewal_data, const char *, 8); if (args == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); return ENOMEM; } /* extra_args are added in revers order */ /* first add NULL as a placeholder for the server name which is determined * at runtime */ args[c++] = NULL; args[c++] = talloc_asprintf(args, "--computer-password-lifetime=%zu", pw_lifetime_in_days); args[c++] = talloc_asprintf(args, "--host-fqdn=%s", ad_hostname); if (ad_keytab != NULL) { args[c++] = talloc_asprintf(args, "--host-keytab=%s", ad_keytab); } args[c++] = talloc_asprintf(args, "--domain=%s", ad_domain); if (DEBUG_IS_SET(SSSDBG_TRACE_LIBS)) { args[c++] = talloc_strdup(args, "--verbose"); } args[c++] = talloc_strdup(args, "update"); args[c] = NULL; do { if (args[--c] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc failed while copying arguments.\n"); talloc_free(args); return ENOMEM; } } while (c != 1); /* is is expected that the first element is NULL */ renewal_data->extra_args = args; return EOK; } struct renewal_state { int child_status; struct sss_child_ctx_old *child_ctx; struct tevent_timer *timeout_handler; struct tevent_context *ev; int write_to_child_fd; int read_from_child_fd; }; static void ad_machine_account_password_renewal_done(struct tevent_req *subreq); static void ad_machine_account_password_renewal_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt); static struct tevent_req * ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct renewal_data *renewal_data; struct renewal_state *state; struct tevent_req *req; struct tevent_req *subreq; pid_t child_pid; struct timeval tv; int pipefd_to_child[2]; int pipefd_from_child[2]; int ret; const char **extra_args; const char *server_name; req = tevent_req_create(mem_ctx, &state, struct renewal_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; } renewal_data = talloc_get_type(pvt, struct renewal_data); state->ev = ev; state->child_status = EFAULT; state->read_from_child_fd = -1; state->write_to_child_fd = -1; server_name = be_fo_get_active_server_name(be_ctx, AD_SERVICE_NAME); talloc_zfree(renewal_data->extra_args[0]); if (server_name != NULL) { renewal_data->extra_args[0] = talloc_asprintf(renewal_data->extra_args, "--domain-controller=%s", server_name); /* if talloc_asprintf() fails we let adcli try to find a server */ } extra_args = renewal_data->extra_args; if (extra_args[0] == NULL) { extra_args = &renewal_data->extra_args[1]; } ret = pipe(pipefd_from_child); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = pipe(pipefd_to_child); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", ret, strerror(ret)); goto done; } child_pid = fork(); if (child_pid == 0) { /* child */ ret = exec_child_ex(state, pipefd_to_child, pipefd_from_child, renewal_data->prog_path, -1, extra_args, true, STDIN_FILENO, STDERR_FILENO); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec renewal child: [%d][%s].\n", ret, strerror(ret)); goto done; } } else if (child_pid > 0) { /* parent */ state->read_from_child_fd = pipefd_from_child[0]; close(pipefd_from_child[1]); sss_fd_nonblocking(state->read_from_child_fd); state->write_to_child_fd = pipefd_to_child[1]; close(pipefd_to_child[0]); sss_fd_nonblocking(state->write_to_child_fd); /* Set up SIGCHLD handler */ ret = child_handler_setup(ev, child_pid, NULL, NULL, &state->child_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set up child handlers [%d]: %s\n", ret, sss_strerror(ret)); ret = ERR_RENEWAL_CHILD; goto done; } /* Set up timeout handler */ tv = tevent_timeval_current_ofs(be_ptask_get_timeout(be_ptask), 0); state->timeout_handler = tevent_add_timer(ev, req, tv, ad_machine_account_password_renewal_timeout, req); if(state->timeout_handler == NULL) { ret = ERR_RENEWAL_CHILD; goto done; } subreq = read_pipe_send(state, ev, state->read_from_child_fd); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "read_pipe_send failed.\n"); ret = ERR_RENEWAL_CHILD; goto done; } tevent_req_set_callback(subreq, ad_machine_account_password_renewal_done, req); /* Now either wait for the timeout to fire or the child * to finish */ } else { /* error */ ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n", ret, sss_strerror(ret)); goto done; } ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void ad_machine_account_password_renewal_done(struct tevent_req *subreq) { uint8_t *buf; ssize_t buf_len; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct renewal_state *state = tevent_req_data(req, struct renewal_state); int ret; talloc_zfree(state->timeout_handler); ret = read_pipe_recv(subreq, state, &buf, &buf_len); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_LIBS, "--- adcli output start---\n" "%.*s" "---adcli output end---\n", (int) buf_len, buf); close(state->read_from_child_fd); state->read_from_child_fd = -1; tevent_req_done(req); return; } static void ad_machine_account_password_renewal_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct renewal_state *state = tevent_req_data(req, struct renewal_state); DEBUG(SSSDBG_CRIT_FAILURE, "Timeout reached for AD renewal child.\n"); child_handler_destroy(state->child_ctx); state->child_ctx = NULL; state->child_status = ETIMEDOUT; tevent_req_error(req, ERR_RENEWAL_CHILD); } static errno_t ad_machine_account_password_renewal_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } errno_t ad_machine_account_password_renewal_init(struct be_ctx *be_ctx, struct ad_options *ad_opts) { int ret; struct renewal_data *renewal_data; int lifetime; size_t period; size_t initial_delay; const char *dummy; char **opt_list; int opt_list_size; char *endptr; lifetime = dp_opt_get_int(ad_opts->basic, AD_MAXIMUM_MACHINE_ACCOUNT_PASSWORD_AGE); if (lifetime == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Automatic machine account renewal disabled.\n"); return EOK; } if (lifetime < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Illegal value [%d] for password lifetime.\n", lifetime); return EINVAL; } renewal_data = talloc(be_ctx, struct renewal_data); if (renewal_data == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc failed.\n"); return ENOMEM; } dummy = dp_opt_get_cstring(ad_opts->basic, AD_MACHINE_ACCOUNT_PASSWORD_RENEWAL_OPTS); ret = split_on_separator(renewal_data, dummy, ':', true, false, &opt_list, &opt_list_size); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "split_on_separator failed.\n"); goto done; } if (opt_list_size != 2) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrong number of renewal options.\n"); ret = EINVAL; goto done; } errno = 0; period = strtouint32(opt_list[0], &endptr, 10); if (errno != 0 || *endptr != '\0' || opt_list[0] == endptr) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse first renewal option.\n"); ret = EINVAL; goto done; } errno = 0; initial_delay = strtouint32(opt_list[1], &endptr, 10); if (errno != 0 || *endptr != '\0' || opt_list[0] == endptr) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse second renewal option.\n"); ret = EINVAL; goto done; } ret = get_adcli_extra_args(dp_opt_get_cstring(ad_opts->basic, AD_DOMAIN), dp_opt_get_cstring(ad_opts->basic, AD_HOSTNAME), dp_opt_get_cstring(ad_opts->id_ctx->sdap_id_ctx->opts->basic, SDAP_KRB5_KEYTAB), lifetime, period, initial_delay, renewal_data); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_adcli_extra_args failed.\n"); goto done; } ret = be_ptask_create(be_ctx, be_ctx, period, initial_delay, 0, 0, 60, BE_PTASK_OFFLINE_DISABLE, 0, ad_machine_account_password_renewal_send, ad_machine_account_password_renewal_recv, renewal_data, "AD machine account password renewal", NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "be_ptask_create failed.\n"); goto done; } ret = EOK; done: if (ret != EOK) { talloc_free(renewal_data); } return ret; } sssd-1.13.4/src/providers/PaxHeaders.16287/data_provider.h0000644000000000000000000000007412703456111020125 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.521793178 sssd-1.13.4/src/providers/data_provider.h0000644002412700241270000002612312703456111021600 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider, private header file Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __DATA_PROVIDER_H__ #define __DATA_PROVIDER_H__ #include "config.h" #include #include #include #include #ifdef USE_KEYRING #include #include #endif #include #include #include #include #include "util/util.h" #include "confdb/confdb.h" #include "sbus/sssd_dbus.h" #include "sbus/sbus_client.h" #include "sss_client/sss_cli.h" #include "util/authtok.h" #include "providers/data_provider_req.h" #include "providers/data_provider_iface_generated.h" #define DATA_PROVIDER_VERSION 0x0001 #define DATA_PROVIDER_PIPE "private/sbus-dp" #define DP_PATH "/org/freedesktop/sssd/dataprovider" /** * @defgroup pamHandler PAM DBUS request * @ingroup sss_pam * * The PAM responder send all the data it has received from the PAM client to * the authentication backend with a DBUS message. * * As a response it expects a PAM return value (see pam(3) for details). * The backend may send any number of additional messages (see ...) which are * forwarded by the PAM responder to the PAM client. * @{ */ /** Then pamHandler Request * * The following two functions can help you to pack and unpack the DBUS * message for a PAM request. If it is necessary to create the DBUS message by * hand it must have the following elements: * * @param DBUS_TYPE_INT32 PAM Command, see #sss_cli_command for allowed values * @param DBUS_TYPE_STRING User name, this value is send by the PAM client and * contains the value of the PAM item PAM_USER * @param DBUS_TYPE_STRING Service name, this value is send by the PAM client * and contains the value of the PAM item PAM_SERVICE * @param DBUS_TYPE_STRING TTY name this value is send by the PAM client and * contains the value of the PAM item PAM_TTY * @param DBUS_TYPE_STRING Remote user, this value is send by the PAM client * and contains the value of the PAM item PAM_RUSER * @param DBUS_TYPE_STRING Remote host, this value is send by the PAM client * and contains the value of the PAM item PAM_RHOST * @param DBUS_TYPE_UINT32 Type of the authentication token, see #sss_authtok_type * for allowed values * @param DBUS_TYPE_ARRAY__(BYTE) Authentication token, DBUS array which * contains the authentication token, it is not required that passwords have a * trailing \\0, this value is send by the PAM client and contains the value of * the PAM item PAM_AUTHTOK or PAM_OLDAUTHTOK if the PAM command is * #SSS_PAM_CHAUTHTOK or #SSS_PAM_CHAUTHTOK_PRELIM * @param DBUS_TYPE_UINT32 Type of the new authentication token, see * #sss_authtok_type for allowed values * @param DBUS_TYPE_ARRAY__(BYTE) New authentication token, DBUS array which * contains the new authentication token for a password change, it is not * required that passwords have a trailing \\0, this value is send by the PAM * client and contains the value of the PAM item PAM_AUTHTOK if the PAM * command is #SSS_PAM_CHAUTHTOK or #SSS_PAM_CHAUTHTOK_PRELIM * @param DBUS_TYPE_INT32 Privileged flag is set to a non-zero value if the * PAM client connected to the PAM responder via the privileged pipe, i.e. if * the PAM client is running with root privileges * @param DBUS_TYPE_UINT32 * * @retval DBUS_TYPE_UINT32 PAM return value, PAM_AUTHINFO_UNAVAIL is used to * indicate that the provider is offline and that the PAM responder should try * a chached authentication, for all other return value see the man pages for * the corresponding PAM service functions * @retval DBUS_TYPE_ARRAY__(STRUCT) Zero or more additional getAccountInfo * messages, here the DBUS_TYPE_STRUCT is build of a DBUS_TYPE_UINT32 holding * an identifier (see #response_type) and DBUS_TYPE_G_BYTE_ARRAY with the data * of the message. */ /** * @} */ /* end of group pamHandler */ #define DP_ERR_OK 0 #define DP_ERR_OFFLINE 1 #define DP_ERR_TIMEOUT 2 #define DP_ERR_FATAL 3 #define BE_ATTR_CORE 1 #define BE_ATTR_MEM 2 #define BE_ATTR_ALL 3 #define BE_FILTER_NAME 1 #define BE_FILTER_IDNUM 2 #define BE_FILTER_ENUM 3 #define BE_FILTER_SECID 4 #define BE_FILTER_UUID 5 #define BE_FILTER_CERT 6 #define BE_FILTER_WILDCARD 7 #define DP_SEC_ID "secid" #define DP_CERT "cert" /* sizeof() counts the trailing \0 so we must substract 1 for the string * length */ #define DP_SEC_ID_LEN (sizeof(DP_SEC_ID) - 1) #define DP_CERT_LEN (sizeof(DP_CERT) - 1) #define DP_WILDCARD "wildcard" #define DP_WILDCARD_LEN (sizeof(DP_WILDCARD) - 1) #define EXTRA_NAME_IS_UPN "U" #define EXTRA_INPUT_MAYBE_WITH_VIEW "V" /* AUTH related common data and functions */ #define DEBUG_PAM_DATA(level, pd) do { \ if (DEBUG_IS_SET(level)) pam_print_data(level, pd); \ } while(0) struct response_data { int32_t type; int32_t len; uint8_t *data; bool do_not_send_to_client; struct response_data *next; }; struct pam_data { int cmd; char *domain; char *user; char *service; char *tty; char *ruser; char *rhost; char **requested_domains; struct sss_auth_token *authtok; struct sss_auth_token *newauthtok; uint32_t cli_pid; char *logon_name; bool name_is_upn; int pam_status; int response_delay; struct response_data *resp_list; bool offline_auth; bool last_auth_saved; int priv; int account_locked; #ifdef USE_KEYRING key_serial_t key_serial; #endif }; /* from dp_auth_util.c */ #define SSS_SERVER_INFO 0x80000000 #define SSS_KRB5_INFO 0x40000000 #define SSS_LDAP_INFO 0x20000000 #define SSS_PROXY_INFO 0x10000000 #define SSS_KRB5_INFO_TGT_LIFETIME (SSS_SERVER_INFO|SSS_KRB5_INFO|0x01) #define SSS_KRB5_INFO_UPN (SSS_SERVER_INFO|SSS_KRB5_INFO|0x02) /** * @brief Create new zero initialized struct pam_data. * * @param mem_ctx A memory context use to allocate the internal data * @return A pointer to new struct pam_data * NULL on error * * NOTE: This function should be the only way, how to create new empty * struct pam_data, because this function automatically initialize sub * structures and set destructor to created object. */ struct pam_data *create_pam_data(TALLOC_CTX *mem_ctx); errno_t copy_pam_data(TALLOC_CTX *mem_ctx, struct pam_data *old_pd, struct pam_data **new_pd); void pam_print_data(int l, struct pam_data *pd); int pam_add_response(struct pam_data *pd, enum response_type type, int len, const uint8_t *data); bool dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd); bool dp_unpack_pam_request(DBusMessage *msg, TALLOC_CTX *mem_ctx, struct pam_data **new_pd, DBusError *dbus_error); bool dp_pack_pam_response(DBusMessage *msg, struct pam_data *pd); bool dp_unpack_pam_response(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error); int dp_common_send_id(struct sbus_connection *conn, uint16_t version, const char *name); void dp_id_callback(DBusPendingCall *pending, void *ptr); /* from dp_sbus.c */ int dp_get_sbus_address(TALLOC_CTX *mem_ctx, char **address, const char *domain_name); /* Helpers */ #define NULL_STRING { .string = NULL } #define NULL_BLOB { .blob = { NULL, 0 } } #define NULL_NUMBER { .number = 0 } #define BOOL_FALSE { .boolean = false } #define BOOL_TRUE { .boolean = true } enum dp_opt_type { DP_OPT_STRING, DP_OPT_BLOB, DP_OPT_NUMBER, DP_OPT_BOOL }; struct dp_opt_blob { uint8_t *data; size_t length; }; union dp_opt_value { const char *cstring; char *string; struct dp_opt_blob blob; int number; bool boolean; }; struct dp_option { const char *opt_name; enum dp_opt_type type; union dp_opt_value def_val; union dp_opt_value val; }; #define DP_OPTION_TERMINATOR { NULL, 0, NULL_STRING, NULL_STRING } void dp_option_inherit(char **inherit_opt_list, int option, struct dp_option *parent_opts, struct dp_option *subdom_opts); int dp_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, struct dp_option *def_opts, int num_opts, struct dp_option **_opts); int dp_copy_options(TALLOC_CTX *memctx, struct dp_option *src_opts, int num_opts, struct dp_option **_opts); int dp_copy_defaults(TALLOC_CTX *memctx, struct dp_option *src_opts, int num_opts, struct dp_option **_opts); const char *_dp_opt_get_cstring(struct dp_option *opts, int id, const char *location); char *_dp_opt_get_string(struct dp_option *opts, int id, const char *location); struct dp_opt_blob _dp_opt_get_blob(struct dp_option *opts, int id, const char *location); int _dp_opt_get_int(struct dp_option *opts, int id, const char *location); bool _dp_opt_get_bool(struct dp_option *opts, int id, const char *location); #define dp_opt_get_cstring(o, i) _dp_opt_get_cstring(o, i, __FUNCTION__) #define dp_opt_get_string(o, i) _dp_opt_get_string(o, i, __FUNCTION__) #define dp_opt_get_blob(o, i) _dp_opt_get_blob(o, i, __FUNCTION__) #define dp_opt_get_int(o, i) _dp_opt_get_int(o, i, __FUNCTION__) #define dp_opt_get_bool(o, i) _dp_opt_get_bool(o, i, __FUNCTION__) int _dp_opt_set_string(struct dp_option *opts, int id, const char *s, const char *location); int _dp_opt_set_blob(struct dp_option *opts, int id, struct dp_opt_blob b, const char *location); int _dp_opt_set_int(struct dp_option *opts, int id, int i, const char *location); int _dp_opt_set_bool(struct dp_option *opts, int id, bool b, const char *location); #define dp_opt_set_string(o, i, v) _dp_opt_set_string(o, i, v, __FUNCTION__) #define dp_opt_set_blob(o, i, v) _dp_opt_set_blob(o, i, v, __FUNCTION__) #define dp_opt_set_int(o, i, v) _dp_opt_set_int(o, i, v, __FUNCTION__) #define dp_opt_set_bool(o, i, v) _dp_opt_set_bool(o, i, v, __FUNCTION__) /* Generic Data Provider options */ /* Resolver DP options */ enum dp_res_opts { DP_RES_OPT_FAMILY_ORDER, DP_RES_OPT_RESOLVER_TIMEOUT, DP_RES_OPT_RESOLVER_OP_TIMEOUT, DP_RES_OPT_DNS_DOMAIN, DP_RES_OPTS /* attrs counter */ }; #endif /* __DATA_PROVIDER_ */ sssd-1.13.4/src/providers/PaxHeaders.16287/data_provider_iface.xml0000644000000000000000000000007412703456111021625 xustar0030 atime=1460561751.644715607 30 ctime=1460561775.059795002 sssd-1.13.4/src/providers/data_provider_iface.xml0000644002412700241270000000450312703456111023276 0ustar00jhrozekjhrozek00000000000000 sssd-1.13.4/src/providers/PaxHeaders.16287/data_provider_opts.c0000644000000000000000000000007412703456111021165 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.656793635 sssd-1.13.4/src/providers/data_provider_opts.c0000644002412700241270000003662212703456111022645 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider Helpers Copyright (C) Simo Sorce 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "data_provider.h" /* =Copy-Option-From-Subdomain-If-Allowed================================= */ void dp_option_inherit(char **inherit_opt_list, int option, struct dp_option *parent_opts, struct dp_option *subdom_opts) { errno_t ret; bool inherit_option; inherit_option = string_in_list(parent_opts[option].opt_name, inherit_opt_list, false); if (inherit_option == false) { DEBUG(SSSDBG_CONF_SETTINGS, "Option %s is not set up to be inherited\n", parent_opts[option].opt_name); return; } DEBUG(SSSDBG_CONF_SETTINGS, "Will inherit option %s\n", parent_opts[option].opt_name); switch (parent_opts[option].type) { case DP_OPT_NUMBER: ret = dp_opt_set_int(subdom_opts, option, dp_opt_get_int(parent_opts, option)); break; case DP_OPT_STRING: ret = dp_opt_set_string(subdom_opts, option, dp_opt_get_string(parent_opts, option)); break; case DP_OPT_BLOB: ret = dp_opt_set_blob(subdom_opts, option, dp_opt_get_blob(parent_opts, option)); break; case DP_OPT_BOOL: ret = dp_opt_set_bool(subdom_opts, option, dp_opt_get_bool(parent_opts, option)); break; default: ret = EINVAL; break; } if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to inherit option %s\n", parent_opts[option].opt_name); /* Not fatal */ } } /* =Retrieve-Options====================================================== */ int dp_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, struct dp_option *def_opts, int num_opts, struct dp_option **_opts) { struct dp_option *opts; int i, ret; opts = talloc_zero_array(memctx, struct dp_option, num_opts); if (!opts) return ENOMEM; for (i = 0; i < num_opts; i++) { char *tmp; opts[i].opt_name = def_opts[i].opt_name; opts[i].type = def_opts[i].type; opts[i].def_val = def_opts[i].def_val; switch (def_opts[i].type) { case DP_OPT_STRING: ret = confdb_get_string(cdb, opts, conf_path, opts[i].opt_name, opts[i].def_val.cstring, &opts[i].val.string); if (ret != EOK || ((opts[i].def_val.string != NULL) && (opts[i].val.string == NULL))) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve value for option (%s)\n", opts[i].opt_name); if (ret == EOK) ret = EINVAL; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s has%s value %s\n", opts[i].opt_name, opts[i].val.cstring ? "" : " no", opts[i].val.cstring ? opts[i].val.cstring : ""); break; case DP_OPT_BLOB: ret = confdb_get_string(cdb, opts, conf_path, opts[i].opt_name, NULL, &tmp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve value for option (%s)\n", opts[i].opt_name); goto done; } if (tmp) { opts[i].val.blob.data = (uint8_t *)tmp; opts[i].val.blob.length = strlen(tmp); } else if (opts[i].def_val.blob.data != NULL) { opts[i].val.blob.data = opts[i].def_val.blob.data; opts[i].val.blob.length = opts[i].def_val.blob.length; } else { opts[i].val.blob.data = NULL; opts[i].val.blob.length = 0; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s has %s binary value.\n", opts[i].opt_name, opts[i].val.blob.length?"a":"no"); break; case DP_OPT_NUMBER: ret = confdb_get_int(cdb, conf_path, opts[i].opt_name, opts[i].def_val.number, &opts[i].val.number); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve value for option (%s)\n", opts[i].opt_name); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s has value %d\n", opts[i].opt_name, opts[i].val.number); break; case DP_OPT_BOOL: ret = confdb_get_bool(cdb, conf_path, opts[i].opt_name, opts[i].def_val.boolean, &opts[i].val.boolean); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve value for option (%s)\n", opts[i].opt_name); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s is %s\n", opts[i].opt_name, opts[i].val.boolean?"TRUE":"FALSE"); break; } } ret = EOK; *_opts = opts; done: if (ret != EOK) talloc_zfree(opts); return ret; } /* =Basic-Option-Helpers================================================== */ static int dp_copy_options_ex(TALLOC_CTX *memctx, bool copy_values, struct dp_option *src_opts, int num_opts, struct dp_option **_opts) { struct dp_option *opts; int i, ret = EOK; opts = talloc_zero_array(memctx, struct dp_option, num_opts); if (!opts) return ENOMEM; for (i = 0; i < num_opts; i++) { opts[i].opt_name = src_opts[i].opt_name; opts[i].type = src_opts[i].type; opts[i].def_val = src_opts[i].def_val; ret = EOK; switch (src_opts[i].type) { case DP_OPT_STRING: if (copy_values) { ret = dp_opt_set_string(opts, i, src_opts[i].val.string); } else { ret = dp_opt_set_string(opts, i, src_opts[i].def_val.string); } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy value for option (%s)\n", opts[i].opt_name); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s has%s value %s\n", opts[i].opt_name, opts[i].val.cstring ? "" : " no", opts[i].val.cstring ? opts[i].val.cstring : ""); break; case DP_OPT_BLOB: if (copy_values) { ret = dp_opt_set_blob(opts, i, src_opts[i].val.blob); } else { ret = dp_opt_set_blob(opts, i, src_opts[i].def_val.blob); } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve value for option (%s)\n", opts[i].opt_name); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s has %s binary value.\n", opts[i].opt_name, opts[i].val.blob.length?"a":"no"); break; case DP_OPT_NUMBER: if (copy_values) { ret = dp_opt_set_int(opts, i, src_opts[i].val.number); } else { ret = dp_opt_set_int(opts, i, src_opts[i].def_val.number); } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve value for option (%s)\n", opts[i].opt_name); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s has value %d\n", opts[i].opt_name, opts[i].val.number); break; case DP_OPT_BOOL: if (copy_values) { ret = dp_opt_set_bool(opts, i, src_opts[i].val.boolean); } else { ret = dp_opt_set_bool(opts, i, src_opts[i].def_val.boolean); } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve value for option (%s)\n", opts[i].opt_name); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s is %s\n", opts[i].opt_name, opts[i].val.boolean?"TRUE":"FALSE"); break; } } *_opts = opts; done: if (ret != EOK) talloc_zfree(opts); return ret; } int dp_copy_options(TALLOC_CTX *memctx, struct dp_option *src_opts, int num_opts, struct dp_option **_opts) { return dp_copy_options_ex(memctx, true, src_opts, num_opts, _opts); } int dp_copy_defaults(TALLOC_CTX *memctx, struct dp_option *src_opts, int num_opts, struct dp_option **_opts) { return dp_copy_options_ex(memctx, false, src_opts, num_opts, _opts); } static const char *dp_opt_type_to_string(enum dp_opt_type type) { switch (type) { case DP_OPT_STRING: return "String"; case DP_OPT_BLOB: return "Blob"; case DP_OPT_NUMBER: return "Number"; case DP_OPT_BOOL: return "Boolean"; } return NULL; } /* Getters */ const char *_dp_opt_get_cstring(struct dp_option *opts, int id, const char *location) { if (opts[id].type != DP_OPT_STRING) { DEBUG(SSSDBG_FATAL_FAILURE, "[%s] Requested type 'String' for option '%s'" " but value is of type '%s'!\n", location, opts[id].opt_name, dp_opt_type_to_string(opts[id].type)); return NULL; } return opts[id].val.cstring; } char *_dp_opt_get_string(struct dp_option *opts, int id, const char *location) { if (opts[id].type != DP_OPT_STRING) { DEBUG(SSSDBG_FATAL_FAILURE, "[%s] Requested type 'String' for option '%s'" " but value is of type '%s'!\n", location, opts[id].opt_name, dp_opt_type_to_string(opts[id].type)); return NULL; } return opts[id].val.string; } struct dp_opt_blob _dp_opt_get_blob(struct dp_option *opts, int id, const char *location) { struct dp_opt_blob null_blob = { NULL, 0 }; if (opts[id].type != DP_OPT_BLOB) { DEBUG(SSSDBG_FATAL_FAILURE, "[%s] Requested type 'Blob' for option '%s'" " but value is of type '%s'!\n", location, opts[id].opt_name, dp_opt_type_to_string(opts[id].type)); return null_blob; } return opts[id].val.blob; } int _dp_opt_get_int(struct dp_option *opts, int id, const char *location) { if (opts[id].type != DP_OPT_NUMBER) { DEBUG(SSSDBG_FATAL_FAILURE, "[%s] Requested type 'Number' for option '%s'" " but value is of type '%s'!\n", location, opts[id].opt_name, dp_opt_type_to_string(opts[id].type)); return 0; } return opts[id].val.number; } bool _dp_opt_get_bool(struct dp_option *opts, int id, const char *location) { if (opts[id].type != DP_OPT_BOOL) { DEBUG(SSSDBG_FATAL_FAILURE, "[%s] Requested type 'Boolean' for option '%s'" " but value is of type '%s'!\n", location, opts[id].opt_name, dp_opt_type_to_string(opts[id].type)); return false; } return opts[id].val.boolean; } /* Setters */ int _dp_opt_set_string(struct dp_option *opts, int id, const char *s, const char *location) { if (opts[id].type != DP_OPT_STRING) { DEBUG(SSSDBG_FATAL_FAILURE, "[%s] Requested type 'String' for option '%s'" " but type is '%s'!\n", location, opts[id].opt_name, dp_opt_type_to_string(opts[id].type)); return EINVAL; } if (opts[id].val.string) { talloc_zfree(opts[id].val.string); } if (s) { opts[id].val.string = talloc_strdup(opts, s); if (!opts[id].val.string) { DEBUG(SSSDBG_FATAL_FAILURE, "talloc_strdup() failed!\n"); return ENOMEM; } } return EOK; } int _dp_opt_set_blob(struct dp_option *opts, int id, struct dp_opt_blob b, const char *location) { if (opts[id].type != DP_OPT_BLOB) { DEBUG(SSSDBG_FATAL_FAILURE, "[%s] Requested type 'Blob' for option '%s'" " but type is '%s'!\n", location, opts[id].opt_name, dp_opt_type_to_string(opts[id].type)); return EINVAL; } if (opts[id].val.blob.data) { talloc_zfree(opts[id].val.blob.data); opts[id].val.blob.length = 0; } if (b.data) { opts[id].val.blob.data = talloc_memdup(opts, b.data, b.length); if (!opts[id].val.blob.data) { DEBUG(SSSDBG_FATAL_FAILURE, "talloc_memdup() failed!\n"); return ENOMEM; } } opts[id].val.blob.length = b.length; return EOK; } int _dp_opt_set_int(struct dp_option *opts, int id, int i, const char *location) { if (opts[id].type != DP_OPT_NUMBER) { DEBUG(SSSDBG_FATAL_FAILURE, "[%s] Requested type 'Number' for option '%s'" " but type is '%s'!\n", location, opts[id].opt_name, dp_opt_type_to_string(opts[id].type)); return EINVAL; } opts[id].val.number = i; return EOK; } int _dp_opt_set_bool(struct dp_option *opts, int id, bool b, const char *location) { if (opts[id].type != DP_OPT_BOOL) { DEBUG(SSSDBG_FATAL_FAILURE, "[%s] Requested type 'Boolean' for option '%s'" " but type is '%s'!\n", location, opts[id].opt_name, dp_opt_type_to_string(opts[id].type)); return EINVAL; } opts[id].val.boolean = b; return EOK; } sssd-1.13.4/src/providers/PaxHeaders.16287/sssd_be.exports0000644000000000000000000000007312703456111020200 xustar0030 atime=1460561751.649715624 29 ctime=1460561774.37779269 sssd-1.13.4/src/providers/sssd_be.exports0000644002412700241270000000003012703456111021641 0ustar00jhrozekjhrozek00000000000000{ global: *; }; sssd-1.13.4/src/providers/PaxHeaders.16287/ipa0000644000000000000000000000013212703463556015633 xustar0030 mtime=1460561774.969794697 30 atime=1460561776.118798593 30 ctime=1460561774.969794697 sssd-1.13.4/src/providers/ipa/0000755002412700241270000000000012703463556017364 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_dn.h0000644000000000000000000000007312703456111017304 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.577793368 sssd-1.13.4/src/providers/ipa/ipa_dn.h0000644002412700241270000000272312703456111020760 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IPA_DN_H_ #define IPA_DN_H_ #include #include "db/sysdb.h" errno_t _ipa_get_rdn(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, const char *obj_dn, char **_rdn_val, const char *rdn_attr, ...); #define ipa_get_rdn(mem_ctx, sysdb, dn, _rdn_val, rdn_attr, ...) \ _ipa_get_rdn(mem_ctx, sysdb, dn, _rdn_val, rdn_attr, ##__VA_ARGS__, NULL) #define ipa_check_rdn(sysdb, dn, rdn_attr, ...) \ _ipa_get_rdn(NULL, sysdb, dn, NULL, rdn_attr, ##__VA_ARGS__, NULL) #define ipa_check_rdn_bool(sysdb, dn, rdn_attr, ...) \ ((bool)(ipa_check_rdn(sysdb, dn, rdn_attr, ##__VA_ARGS__) == EOK)) #endif /* IPA_DN_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_config.c0000644000000000000000000000007312703456111020143 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.725793869 sssd-1.13.4/src/providers/ipa/ipa_config.c0000644002412700241270000001070412703456111021615 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- configuration retrieval Authors: Jan Zeleny Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ipa/ipa_config.h" #include "providers/ipa/ipa_common.h" #include "providers/ldap/sdap_async.h" struct ipa_get_config_state { char *base; const char **attrs; struct sysdb_attrs *config; }; static void ipa_get_config_done(struct tevent_req *subreq); struct tevent_req * ipa_get_config_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, struct sdap_options *opts, const char *domain, const char **attrs) { struct tevent_req *req; struct tevent_req *subreq; struct ipa_get_config_state *state; errno_t ret; char *ldap_basedn; req = tevent_req_create(mem_ctx, &state, struct ipa_get_config_state); if (req == NULL) { return NULL; } if (attrs == NULL) { state->attrs = talloc_zero_array(state, const char *, 4); if (state->attrs == NULL) { ret = ENOMEM; goto done; } state->attrs[0] = IPA_CONFIG_MIGRATION_ENABLED; state->attrs[1] = IPA_CONFIG_SELINUX_DEFAULT_USER_CTX; state->attrs[2] = IPA_CONFIG_SELINUX_MAP_ORDER; state->attrs[3] = NULL; } else { state->attrs = attrs; } ret = domain_to_basedn(state, domain, &ldap_basedn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n"); goto done; } state->base = talloc_asprintf(state, IPA_CONFIG_SEARCH_BASE_TEMPLATE, ldap_basedn); if (state->base == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } subreq = sdap_get_generic_send(state, ev, opts, sh, state->base, LDAP_SCOPE_SUBTREE, IPA_CONFIG_FILTER, state->attrs, NULL, 0, dp_opt_get_int(opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), false); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ipa_get_config_done, req); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void ipa_get_config_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_config_state *state = tevent_req_data(req, struct ipa_get_config_state); size_t reply_count; struct sysdb_attrs **reply = NULL; errno_t ret; ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply); talloc_zfree(subreq); if (ret) { goto done; } if (reply_count != 1) { DEBUG(SSSDBG_OP_FAILURE, "Unexpected number of results, expected 1, " "got %zu.\n", reply_count); ret = EINVAL; goto done; } state->config = reply[0]; ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } } errno_t ipa_get_config_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sysdb_attrs **config) { struct ipa_get_config_state *state = tevent_req_data(req, struct ipa_get_config_state); TEVENT_REQ_RETURN_ON_ERROR(req); *config = talloc_steal(mem_ctx, state->config); return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_subdomains_ext_groups.c0000644000000000000000000000007412703456111023322 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.735793903 sssd-1.13.4/src/providers/ipa/ipa_subdomains_ext_groups.c0000644002412700241270000011442312703456111024776 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Identity Backend Module for sub-domains - evaluate external group memberships Authors: Sumit Bose Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" #include "providers/ipa/ipa_id.h" #include "providers/ad/ad_id.h" #include "providers/ipa/ipa_subdomains.h" #define IPA_EXT_GROUPS_FILTER "objectClass=ipaexternalgroup" struct ipa_ext_groups { time_t next_update; hash_table_t *ext_groups; }; static errno_t process_ext_groups(TALLOC_CTX *mem_ctx, size_t reply_count, struct sysdb_attrs **reply, hash_table_t **_ext_group_hash) { int ret; hash_table_t *ext_group_hash = NULL; hash_key_t key; hash_value_t value; hash_table_t *m_hash = NULL; hash_key_t m_key; hash_value_t m_value; size_t g; size_t s; size_t m; TALLOC_CTX *tmp_ctx = NULL; const char **ext_sids; const char **mof; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); ret = ENOMEM; goto done; } ret = sss_hash_create(mem_ctx, reply_count, &ext_group_hash); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); goto done; } key.type = HASH_KEY_STRING; m_key.type = HASH_KEY_STRING; m_value.type = HASH_VALUE_PTR; m_value.ptr = NULL; for (g = 0; g < reply_count; g++) { ret = sysdb_attrs_get_string_array(reply[g], "ipaExternalMember", tmp_ctx, &ext_sids); if (ret == ENOENT) { /* no external members, try next external group. */ continue; } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string_array failed.\n"); goto done; } ret = sysdb_attrs_get_string_array(reply[g], "memberOf", tmp_ctx, &mof); if (ret == ENOENT) { /* no IPA groups, try next external group. */ continue; } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string_array failed.\n"); goto done; } for (s = 0; ext_sids[s] != NULL; s++) { /* hash_lookup does not modify key.str. */ key.str = discard_const(ext_sids[s]); ret = hash_lookup(ext_group_hash, &key, &value); if (ret == HASH_SUCCESS) { if (value.type != HASH_VALUE_PTR) { DEBUG(SSSDBG_OP_FAILURE, "Unexpected value type.\n"); ret = EINVAL; goto done; } for (m = 0; mof[m] != NULL; m++) { /* hash_enter does not modify m_key.str. */ m_key.str = discard_const(mof[m]); DEBUG(SSSDBG_TRACE_ALL, "Adding group [%s] to SID [%s].\n", m_key.str, key.str); ret = hash_enter(value.ptr, &m_key, &m_value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed.\n"); goto done; } } } else if (ret == HASH_ERROR_KEY_NOT_FOUND) { ret = sss_hash_create(ext_group_hash, 5, &m_hash); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); goto done; } value.type = HASH_VALUE_PTR; value.ptr = m_hash; DEBUG(SSSDBG_TRACE_ALL, "Adding SID [%s] to external group hash.\n", key.str); ret = hash_enter(ext_group_hash, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed.\n"); goto done; } for (m = 0; mof[m] != NULL; m++) { /* hash_enter does not modify m_key.str. */ m_key.str = discard_const(mof[m]); DEBUG(SSSDBG_TRACE_ALL, "Adding group [%s] to SID [%s].\n", m_key.str, key.str); ret = hash_enter(m_hash, &m_key, &m_value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed.\n"); goto done; } } } else { DEBUG(SSSDBG_OP_FAILURE, "hash_lookup failed.\n"); goto done; } } } ret = EOK; done: if (ret != EOK) { talloc_free(ext_group_hash); } else { *_ext_group_hash = ext_group_hash; } talloc_free(tmp_ctx); return ret; } static errno_t find_ipa_ext_memberships(TALLOC_CTX *mem_ctx, const char *user_name, struct sss_domain_info *user_dom, hash_table_t *ext_group_hash, struct ldb_dn **_user_dn, char ***_groups) { int ret; TALLOC_CTX *tmp_ctx = NULL; struct ldb_result *result; char **groups = NULL; size_t c; const char *sid; hash_key_t key; hash_value_t value; hash_entry_t *entry; struct hash_iter_context_t *iter; hash_table_t *group_hash; size_t g_count; struct ldb_dn *user_dn = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = sysdb_initgroups(tmp_ctx, user_dom, user_name, &result); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_initgroups failed.\n"); goto done; } if (result->count == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "User [%s] not found in cache.\n", user_name); ret = EOK; goto done; } ret = sss_hash_create(tmp_ctx, 10, &group_hash); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); goto done; } key.type = HASH_KEY_STRING; /* The IPA external domains can have references to group and user SIDs. * This means that we not only want to look up the group SIDs but the SID * of the user (first element of result) as well. */ for (c = 0; c < result->count; c++) { sid = ldb_msg_find_attr_as_string(result->msgs[c], SYSDB_SID_STR, NULL); if (sid == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Group [%s] does not have a SID.\n", ldb_dn_get_linearized(result->msgs[c]->dn)); continue; } key.str = discard_const(sid); ret = hash_lookup(ext_group_hash, &key, &value); if (ret == HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_TRACE_ALL, "SID [%s] not found in ext group hash.\n", sid); } else if (ret == HASH_SUCCESS) { iter = new_hash_iter_context(value.ptr); if (iter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "new_hash_iter_context failed.\n"); ret = EINVAL; goto done; } while ((entry = iter->next(iter)) != NULL) { ret = hash_enter(group_hash, &entry->key, &entry->value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Failed to add group [%s].\n", entry->key.str); } } talloc_free(iter); } else { DEBUG(SSSDBG_OP_FAILURE, "hash_lookup failed for SID [%s].\n", sid); } } g_count = hash_count(group_hash); if (g_count == 0) { DEBUG(SSSDBG_TRACE_FUNC, "No external groupmemberships found.\n"); ret = EOK; goto done; } groups = talloc_zero_array(mem_ctx, char *, g_count + 1); if (groups == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } iter = new_hash_iter_context(group_hash); if (iter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "new_hash_iter_context failed.\n"); ret = EINVAL; goto done; } c = 0; while ((entry = iter->next(iter)) != NULL) { groups[c] = talloc_strdup(groups, entry->key.str); if (groups[c] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } c++; } user_dn = ldb_dn_copy(mem_ctx, result->msgs[0]->dn); if (user_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_copy failed.\n"); ret = ENOMEM; goto done; } ret = EOK; done: *_user_dn = user_dn; *_groups = groups; talloc_free(tmp_ctx); return ret; } static errno_t add_ad_user_to_cached_groups(struct ldb_dn *user_dn, struct sss_domain_info *user_dom, struct sss_domain_info *group_dom, char **groups, bool *missing_groups) { size_t c; struct sysdb_attrs *user_attrs; size_t msgs_count; struct ldb_message **msgs; char *subfilter; TALLOC_CTX *tmp_ctx; int ret; *missing_groups = false; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } for (c = 0; groups[c] != NULL; c++) { if (groups[c][0] == '\0') { continue; } subfilter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_ORIG_DN, groups[c]); if (subfilter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_search_groups(tmp_ctx, group_dom, subfilter, NULL, &msgs_count, &msgs); if (ret != EOK) { if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "Group [%s] not in the cache.\n", groups[c]); *missing_groups = true; continue; } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed.\n"); goto done; } } /* TODO? Do we have to remove members as well? I think not because the AD * query before removes all memberships. */ ret = sysdb_mod_group_member(group_dom, user_dn, msgs[0]->dn, LDB_FLAG_MOD_ADD); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_mod_group_member failed.\n"); goto done; } user_attrs = sysdb_new_attrs(tmp_ctx); if (user_attrs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF, groups[c]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } ret = sysdb_set_entry_attr(user_dom->sysdb, user_dn, user_attrs, LDB_FLAG_MOD_ADD); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_entry_attr failed.\n"); goto done; } /* mark group as already processed */ groups[c][0] = '\0'; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static struct tevent_req *ipa_add_ad_memberships_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_id_ctx, struct ldb_dn *user_dn, struct sss_domain_info *user_dom, char **groups, struct sss_domain_info *group_dom); static void ipa_add_ad_memberships_done(struct tevent_req *subreq); struct get_ad_membership_state { struct tevent_context *ev; struct ipa_server_mode_ctx *server_mode; struct sdap_id_op *sdap_op; struct sdap_id_ctx *sdap_id_ctx; struct fo_server *srv; char *user_name; struct sss_domain_info *user_dom; int dp_error; const char *domain; size_t reply_count; struct sysdb_attrs **reply; }; static void ipa_get_ad_memberships_connect_done(struct tevent_req *subreq); static void ipa_get_ext_groups_done(struct tevent_req *subreq); static errno_t ipa_add_ext_groups_step(struct tevent_req *req); static errno_t ipa_add_ad_memberships_recv(struct tevent_req *req, int *dp_error_out); struct tevent_req *ipa_get_ad_memberships_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_acct_req *ar, struct ipa_server_mode_ctx *server_mode, struct sss_domain_info *user_dom, struct sdap_id_ctx *sdap_id_ctx, const char *domain) { int ret; struct tevent_req *req; struct tevent_req *subreq; struct get_ad_membership_state *state; req = tevent_req_create(mem_ctx, &state, struct get_ad_membership_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->user_dom = user_dom; state->sdap_id_ctx = sdap_id_ctx; state->srv = NULL; state->domain = domain; state->dp_error = -1; if (((ar->entry_type & BE_REQ_TYPE_MASK) != BE_REQ_INITGROUPS && (ar->entry_type & BE_REQ_TYPE_MASK) != BE_REQ_USER) || ar->filter_type != BE_FILTER_NAME) { DEBUG(SSSDBG_OP_FAILURE, "Unsupported request type.\n"); ret = EINVAL; goto done; } state->user_name = talloc_strdup(state, ar->filter_value); if (state->user_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_Strdup failed.\n"); ret = ENOMEM; goto done; } state->sdap_op = sdap_id_op_create(state, state->sdap_id_ctx->conn->conn_cache); if (state->sdap_op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto done; } state->server_mode = server_mode; if (server_mode->ext_groups == NULL) { server_mode->ext_groups = talloc_zero(server_mode, struct ipa_ext_groups); if (server_mode->ext_groups == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; goto done; } } if (server_mode->ext_groups->next_update > time(NULL)) { DEBUG(SSSDBG_TRACE_FUNC, "External group information still valid.\n"); ret = ipa_add_ext_groups_step(req); if (ret == EOK) { goto done; } else if (ret == EAGAIN) { return req; } else { DEBUG(SSSDBG_OP_FAILURE, "ipa_add_ext_groups_step failed.\n"); goto done; } } subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n", ret, strerror(ret)); goto done; } tevent_req_set_callback(subreq, ipa_get_ad_memberships_connect_done, req); return req; done: if (ret != EOK) { state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); } else { state->dp_error = DP_ERR_OK; tevent_req_done(req); } tevent_req_post(req, state->ev); return req; } static void ipa_get_ad_memberships_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct get_ad_membership_state *state = tevent_req_data(req, struct get_ad_membership_state); int ret; char *basedn; ret = sdap_id_op_connect_recv(subreq, &state->dp_error); talloc_zfree(subreq); if (ret != EOK) { if (state->dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_MINOR_FAILURE, "No IPA server is available, going offline\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to IPA server: [%d](%s)\n", ret, strerror(ret)); } goto fail; } ret = domain_to_basedn(state, state->domain, &basedn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n"); goto fail; } subreq = sdap_get_generic_send(state, state->ev, state->sdap_id_ctx->opts, sdap_id_op_handle(state->sdap_op), basedn, LDAP_SCOPE_SUBTREE, IPA_EXT_GROUPS_FILTER, NULL, NULL, 0, dp_opt_get_int(state->sdap_id_ctx->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), false); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_get_ext_groups_done, req); return; fail: tevent_req_error(req, ret); return; } static void ipa_get_ext_groups_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct get_ad_membership_state *state = tevent_req_data(req, struct get_ad_membership_state); int ret; hash_table_t *ext_group_hash; ret = sdap_get_generic_recv(subreq, state, &state->reply_count, &state->reply); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ext_groups request failed.\n"); tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_FUNC, "[%zu] external groups found.\n", state->reply_count); ret = process_ext_groups(state->server_mode->ext_groups, state->reply_count, state->reply, &ext_group_hash); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "process_ext_groups failed.\n"); goto fail; } state->server_mode->ext_groups->ext_groups = ext_group_hash; /* Do we have to make the update timeout configurable? */ state->server_mode->ext_groups->next_update = time(NULL) + 10; ret = ipa_add_ext_groups_step(req); if (ret == EOK) { tevent_req_done(req); return; } else if (ret == EAGAIN) { return; } else { DEBUG(SSSDBG_OP_FAILURE, "ipa_add_ext_groups_step failed.\n"); goto fail; } fail: tevent_req_error(req, ret); return; } static errno_t ipa_add_ext_groups_step(struct tevent_req *req) { struct get_ad_membership_state *state = tevent_req_data(req, struct get_ad_membership_state); struct ldb_dn *user_dn; int ret; char **groups = NULL; struct tevent_req *subreq; ret = find_ipa_ext_memberships(state, state->user_name, state->user_dom, state->server_mode->ext_groups->ext_groups, &user_dn, &groups); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "find_ipa_ext_memberships failed.\n"); goto fail; } if (groups == NULL) { DEBUG(SSSDBG_TRACE_ALL, "No external groups memberships found.\n"); state->dp_error = DP_ERR_OK; return EOK; } subreq = ipa_add_ad_memberships_send(state, state->ev, state->sdap_id_ctx, user_dn, state->user_dom, groups, state->sdap_id_ctx->be->domain); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_add_ad_memberships_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_add_ad_memberships_done, req); return EAGAIN; fail: tevent_req_error(req, ret); return ret; } static void ipa_add_ad_memberships_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct get_ad_membership_state *state = tevent_req_data(req, struct get_ad_membership_state); int ret; ret = ipa_add_ad_memberships_recv(subreq, &state->dp_error); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_add_ad_memberships request failed.\n"); tevent_req_error(req, ret); return; } state->dp_error = DP_ERR_OK; tevent_req_done(req); return; } errno_t ipa_get_ad_memberships_recv(struct tevent_req *req, int *dp_error_out) { struct get_ad_membership_state *state = tevent_req_data(req, struct get_ad_membership_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (dp_error_out) { *dp_error_out = state->dp_error; } return EOK; } struct add_ad_membership_state { struct tevent_context *ev; struct sdap_id_ctx *sdap_id_ctx; struct sdap_id_op *sdap_op; struct ldb_dn *user_dn; struct sss_domain_info *user_dom; struct sss_domain_info *group_dom; char **groups; int dp_error; size_t iter; struct sdap_domain *group_sdom; }; static void ipa_add_ad_memberships_connect_done(struct tevent_req *subreq); static void ipa_add_ad_memberships_get_next(struct tevent_req *req); static void ipa_add_ad_memberships_get_group_done(struct tevent_req *subreq); static struct tevent_req *ipa_add_ad_memberships_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_id_ctx, struct ldb_dn *user_dn, struct sss_domain_info *user_dom, char **groups, struct sss_domain_info *group_dom) { int ret; struct tevent_req *req; struct tevent_req *subreq; struct add_ad_membership_state *state; bool missing_groups = false; req = tevent_req_create(mem_ctx, &state, struct add_ad_membership_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->user_dom = user_dom; state->sdap_id_ctx = sdap_id_ctx; state->user_dn = user_dn; state->group_dom = group_dom; state->groups = groups; state->dp_error = -1; state->iter = 0; state->group_sdom = sdap_domain_get(sdap_id_ctx->opts, group_dom); if (state->group_sdom == NULL) { ret = EIO; goto done; } ret = add_ad_user_to_cached_groups(user_dn, user_dom, group_dom, groups, &missing_groups); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_ad_user_to_cached_groups failed.\n"); goto done; } if (!missing_groups) { DEBUG(SSSDBG_TRACE_ALL, "All groups found in cache.\n"); ret = EOK; goto done; } state->sdap_op = sdap_id_op_create(state, state->sdap_id_ctx->conn->conn_cache); if (state->sdap_op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto done; } subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n", ret, strerror(ret)); goto done; } tevent_req_set_callback(subreq, ipa_add_ad_memberships_connect_done, req); return req; done: if (ret != EOK) { state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); } else { state->dp_error = DP_ERR_OK; tevent_req_done(req); } tevent_req_post(req, state->ev); return req; } static void ipa_add_ad_memberships_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct add_ad_membership_state *state = tevent_req_data(req, struct add_ad_membership_state); int ret; ret = sdap_id_op_connect_recv(subreq, &state->dp_error); talloc_zfree(subreq); if (ret != EOK) { if (state->dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_MINOR_FAILURE, "No IPA server is available, going offline\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to IPA server: [%d](%s)\n", ret, strerror(ret)); } tevent_req_error(req, ret); return; } state->iter = 0; ipa_add_ad_memberships_get_next(req); } static void ipa_add_ad_memberships_get_next(struct tevent_req *req) { struct add_ad_membership_state *state = tevent_req_data(req, struct add_ad_membership_state); struct tevent_req *subreq; struct ldb_dn *group_dn; int ret; const struct ldb_val *val; bool missing_groups; while (state->groups[state->iter] != NULL && state->groups[state->iter][0] == '\0') { state->iter++; } if (state->groups[state->iter] == NULL) { ret = add_ad_user_to_cached_groups(state->user_dn, state->user_dom, state->group_dom, state->groups, &missing_groups); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_ad_user_to_cached_groups failed.\n"); goto fail; } if (missing_groups) { DEBUG(SSSDBG_CRIT_FAILURE, "There are unresolved external group " "memberships even after all groups " "have been looked up on the LDAP " "server.\n"); } tevent_req_done(req); return; } group_dn = ldb_dn_new(state, sysdb_ctx_get_ldb(state->group_dom->sysdb), state->groups[state->iter]); if (group_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); ret = ENOMEM; goto fail; } val = ldb_dn_get_rdn_val(group_dn); if (val == NULL || val->data == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Invalid group DN [%s].\n", state->groups[state->iter]); ret = EINVAL; goto fail; } /* TODO: here is would be useful for have a filter type like BE_FILTER_DN to * directly fetch the group with the corresponding DN. */ subreq = groups_get_send(state, state->ev, state->sdap_id_ctx, state->group_sdom, state->sdap_id_ctx->conn, (const char *) val->data, BE_FILTER_NAME, BE_ATTR_CORE, false, false); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "groups_get_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_add_ad_memberships_get_group_done, req); return; fail: tevent_req_error(req, ret); } static void ipa_add_ad_memberships_get_group_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct add_ad_membership_state *state = tevent_req_data(req, struct add_ad_membership_state); int ret; ret = groups_get_recv(subreq, &state->dp_error, NULL); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to read group [%s] from LDAP [%d](%s)\n", state->groups[state->iter], ret, strerror(ret)); tevent_req_error(req, ret); return; } state->iter++; ipa_add_ad_memberships_get_next(req); } static errno_t ipa_add_ad_memberships_recv(struct tevent_req *req, int *dp_error_out) { struct add_ad_membership_state *state = tevent_req_data(req, struct add_ad_membership_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (dp_error_out) { *dp_error_out = state->dp_error; } return EOK; } static errno_t search_user_or_group_by_sid_str(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sid_str, enum sysdb_member_type *_member_type, struct ldb_message **_msg) { errno_t ret; struct ldb_message *msg = NULL; const char *attrs[] = { SYSDB_NAME, SYSDB_SID_STR, SYSDB_ORIG_DN, SYSDB_OBJECTCLASS, SYSDB_CACHE_EXPIRE, NULL }; TALLOC_CTX *tmp_ctx = NULL; char *sanitized_sid = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } /* In theory SID shouldn't contain any special LDAP characters, but let's * be paranoid */ ret = sss_filter_sanitize(tmp_ctx, sid_str, &sanitized_sid); if (ret != EOK) { goto done; } ret = sysdb_search_user_by_sid_str(tmp_ctx, domain, sid_str, attrs, &msg); if (ret == EOK) { *_member_type = SYSDB_MEMBER_USER; } else if (ret == ENOENT) { ret = sysdb_search_group_by_sid_str(tmp_ctx, domain, sid_str, attrs, &msg); if (ret == EOK) { *_member_type = SYSDB_MEMBER_GROUP; } } switch (ret) { case EOK: DEBUG(SSSDBG_TRACE_FUNC, "Found %s in sysdb\n", sid_str); *_msg = talloc_steal(mem_ctx, msg); break; case ENOENT: DEBUG(SSSDBG_TRACE_FUNC, "Could not find %s in sysdb", sid_str); break; default: DEBUG(SSSDBG_OP_FAILURE, "Error looking for %s in sysdb [%d]: %s\n", sid_str, ret, sss_strerror(ret)); break; } done: talloc_free(tmp_ctx); return ret; } static errno_t ipa_ext_group_member_check(TALLOC_CTX *mem_ctx, struct ipa_id_ctx *ipa_ctx, struct sss_domain_info *member_dom, const char *ext_member, enum sysdb_member_type *_member_type, struct sysdb_attrs **_member) { TALLOC_CTX *tmp_ctx = NULL; errno_t ret; uint64_t expire; time_t now = time(NULL); struct ldb_message *msg; struct sysdb_attrs **members; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } ret = search_user_or_group_by_sid_str(tmp_ctx, member_dom, ext_member, _member_type, &msg); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error looking up sid %s: [%d]: %s\n", ext_member, ret, sss_strerror(ret)); goto done; } ret = sysdb_msg2attrs(tmp_ctx, 1, &msg, &members); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not convert result to sysdb_attrs [%d]: %s\n", ret, sss_strerror(ret)); goto done; } /* Return the member both expired and valid */ *_member = talloc_steal(mem_ctx, members[0]); expire = ldb_msg_find_attr_as_uint64(msg, SYSDB_CACHE_EXPIRE, 0); if (expire != 0 && expire <= now) { DEBUG(SSSDBG_TRACE_FUNC, "%s is expired", ext_member); ret = EAGAIN; goto done; } done: talloc_free(tmp_ctx); return ret; } /* For the IPA external member resolution, we expect a SID as the input. * The _recv() function output is the member and a type (user/group) * since nothing else can be a group member. */ struct ipa_ext_member_state { const char *ext_member; struct sss_domain_info *dom; enum sysdb_member_type member_type; struct sysdb_attrs *member; }; static void ipa_ext_group_member_done(struct tevent_req *subreq); struct tevent_req *ipa_ext_group_member_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *ext_member, void *pvt) { struct ipa_id_ctx *ipa_ctx; struct ipa_ext_member_state *state; struct tevent_req *req; struct tevent_req *subreq; struct be_acct_req *ar; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ipa_ext_member_state); if (req == NULL) { return NULL; } state->ext_member = ext_member; ipa_ctx = talloc_get_type(pvt, struct ipa_id_ctx); if (ipa_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrong private context!\n"); ret = EINVAL; goto immediate; } state->dom = find_domain_by_sid(ipa_ctx->sdap_id_ctx->be->domain, ext_member); if (state->dom == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot find domain of SID [%s]\n", ext_member); ret = ENOENT; goto immediate; } ret = ipa_ext_group_member_check(state, ipa_ctx, state->dom, ext_member, &state->member_type, &state->member); if (ret == EOK) { DEBUG(SSSDBG_TRACE_INTERNAL, "external member %s already cached\n", ext_member); goto immediate; } ret = get_be_acct_req_for_sid(state, ext_member, state->dom->name, &ar); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot create the account request for [%s]\n", ext_member); goto immediate; } subreq = be_get_account_info_send(state, ev, NULL, ipa_ctx->sdap_id_ctx->be, ar); if (subreq == NULL) { ret = ENOMEM; goto immediate; } tevent_req_set_callback(subreq, ipa_ext_group_member_done, req); return req; immediate: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } tevent_req_post(req, ev); return req; } static void ipa_ext_group_member_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_ext_member_state *state = tevent_req_data(req, struct ipa_ext_member_state); errno_t ret; int err_maj; int err_min; const char *err_msg; struct ldb_message *msg; struct sysdb_attrs **members; ret = be_get_account_info_recv(subreq, state, &err_maj, &err_min, &err_msg); talloc_free(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "be request failed %d:%d: %s\n", err_maj, err_min, err_msg); tevent_req_error(req, ret); return; } ret = search_user_or_group_by_sid_str(state, state->dom, state->ext_member, &state->member_type, &msg); if (ret != EOK) { DEBUG(ret == ENOENT ? SSSDBG_TRACE_FUNC : SSSDBG_OP_FAILURE, "Could not find %s in sysdb [%d]: %s\n", state->ext_member, ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } ret = sysdb_msg2attrs(state, 1, &msg, &members); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not convert result to sysdb_attrs [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } state->member = members[0]; tevent_req_done(req); } errno_t ipa_ext_group_member_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, enum sysdb_member_type *_member_type, struct sss_domain_info **_dom, struct sysdb_attrs **_member) { struct ipa_ext_member_state *state = tevent_req_data(req, struct ipa_ext_member_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_member_type != NULL) { *_member_type = state->member_type; } if (_dom) { *_dom = state->dom; } if (_member != NULL) { *_member = talloc_steal(mem_ctx, state->member); } return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hbac_services.c0000644000000000000000000000007312703456111021476 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.743793931 sssd-1.13.4/src/providers/ipa/ipa_hbac_services.c0000644002412700241270000005216512703456111023157 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "providers/ipa/ipa_hbac_private.h" #include "providers/ldap/sdap_async.h" struct ipa_hbac_service_state { struct tevent_context *ev; struct sdap_handle *sh; struct sdap_options *opts; const char **attrs; char *service_filter; char *cur_filter; struct sdap_search_base **search_bases; int search_base_iter; /* Return values */ size_t service_count; struct sysdb_attrs **services; size_t servicegroup_count; struct sysdb_attrs **servicegroups; }; static errno_t ipa_hbac_service_info_next(struct tevent_req *req, struct ipa_hbac_service_state *state); static void ipa_hbac_service_info_done(struct tevent_req *subreq); static errno_t ipa_hbac_servicegroup_info_next(struct tevent_req *req, struct ipa_hbac_service_state *state); static void ipa_hbac_servicegroup_info_done(struct tevent_req *subreq); struct tevent_req * ipa_hbac_service_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, struct sdap_options *opts, struct sdap_search_base **search_bases) { errno_t ret; struct ipa_hbac_service_state *state; struct tevent_req *req; char *service_filter; req = tevent_req_create(mem_ctx, &state, struct ipa_hbac_service_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->sh = sh; state->opts = opts; state->search_bases = search_bases; state->search_base_iter = 0; service_filter = talloc_asprintf(state, "(objectClass=%s)", IPA_HBAC_SERVICE); if (service_filter == NULL) { ret = ENOMEM; goto immediate; } state->service_filter = service_filter; state->cur_filter = NULL; state->attrs = talloc_array(state, const char *, 6); if (state->attrs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to allocate service attribute list.\n"); ret = ENOMEM; goto immediate; } state->attrs[0] = OBJECTCLASS; state->attrs[1] = IPA_CN; state->attrs[2] = IPA_UNIQUE_ID; state->attrs[3] = IPA_MEMBER; state->attrs[4] = IPA_MEMBEROF; state->attrs[5] = NULL; ret = ipa_hbac_service_info_next(req, state); if (ret == EOK) { ret = EINVAL; } if (ret != EAGAIN) { goto immediate; } return req; immediate: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t ipa_hbac_service_info_next(struct tevent_req *req, struct ipa_hbac_service_state *state) { struct tevent_req *subreq; struct sdap_search_base *base; base = state->search_bases[state->search_base_iter]; if (base == NULL) { return EOK; } talloc_zfree(state->cur_filter); state->cur_filter = sdap_combine_filters(state, state->service_filter, base->filter); if (state->cur_filter == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Sending request for next search base: " "[%s][%d][%s]\n", base->basedn, base->scope, state->cur_filter); subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, base->basedn, base->scope, state->cur_filter, state->attrs, NULL, 0, dp_opt_get_int(state->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), true); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Error requesting service info\n"); return EIO; } tevent_req_set_callback(subreq, ipa_hbac_service_info_done, req); return EAGAIN; } static void ipa_hbac_service_info_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_hbac_service_state *state = tevent_req_data(req, struct ipa_hbac_service_state); char *servicegroup_filter; ret = sdap_get_generic_recv(subreq, state, &state->service_count, &state->services); talloc_zfree(subreq); if (ret != EOK && ret != ENOENT) { goto done; } if (ret == ENOENT || state->service_count == 0) { /* If there are no services, we'll shortcut out * This is still valid, as rules can apply to * all services * * There's no reason to try to process groups */ state->search_base_iter++; ret = ipa_hbac_service_info_next(req, state); if (ret == EAGAIN) { return; } state->service_count = 0; state->services = NULL; goto done; } ret = replace_attribute_name(IPA_MEMBEROF, SYSDB_ORIG_MEMBEROF, state->service_count, state->services); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not replace attribute names\n"); goto done; } servicegroup_filter = talloc_asprintf(state, "(objectClass=%s)", IPA_HBAC_SERVICE_GROUP); if (servicegroup_filter == NULL) { ret = ENOMEM; goto done; } talloc_zfree(state->service_filter); state->service_filter = servicegroup_filter; state->search_base_iter = 0; ret = ipa_hbac_servicegroup_info_next(req, state); if (ret == EOK) { ret = EINVAL; } if (ret != EAGAIN) { goto done; } return; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } static errno_t ipa_hbac_servicegroup_info_next(struct tevent_req *req, struct ipa_hbac_service_state *state) { struct tevent_req *subreq; struct sdap_search_base *base; base = state->search_bases[state->search_base_iter]; if (base == NULL) { return EOK; } talloc_zfree(state->cur_filter); state->cur_filter = sdap_combine_filters(state, state->service_filter, base->filter); if (state->cur_filter == NULL) { return ENOMEM; } /* Look up service groups */ DEBUG(SSSDBG_TRACE_FUNC, "Sending request for next search base: " "[%s][%d][%s]\n", base->basedn, base->scope, state->cur_filter); subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, base->basedn, base->scope, state->cur_filter, state->attrs, NULL, 0, dp_opt_get_int(state->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), true); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Error requesting servicegroup info\n"); return EIO; } tevent_req_set_callback(subreq, ipa_hbac_servicegroup_info_done, req); return EAGAIN; } static void ipa_hbac_servicegroup_info_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_hbac_service_state *state = tevent_req_data(req, struct ipa_hbac_service_state); size_t total_count; size_t group_count; struct sysdb_attrs **groups; struct sysdb_attrs **target; int i; ret = sdap_get_generic_recv(subreq, state, &group_count, &groups); talloc_zfree(subreq); if (ret != EOK) { goto done; } if (group_count > 0) { ret = replace_attribute_name(IPA_MEMBER, SYSDB_ORIG_MEMBER, group_count, groups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not replace attribute names\n"); goto done; } ret = replace_attribute_name(IPA_MEMBEROF, SYSDB_ORIG_MEMBEROF, state->servicegroup_count, state->servicegroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not replace attribute names\n"); goto done; } total_count = state->servicegroup_count + group_count; state->servicegroups = talloc_realloc(state, state->servicegroups, struct sysdb_attrs *, total_count); if (state->servicegroups == NULL) { ret = ENOMEM; goto done; } i = 0; while (state->servicegroup_count < total_count) { target = &state->servicegroups[state->servicegroup_count]; *target = talloc_steal(state->servicegroups, groups[i]); state->servicegroup_count++; i++; } } state->search_base_iter++; ret = ipa_hbac_servicegroup_info_next(req, state); if (ret == EAGAIN) { return; } else if (ret != EOK) { goto done; } done: if (ret == EOK) { tevent_req_done(req); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Error [%d][%s]\n", ret, strerror(ret)); tevent_req_error(req, ret); } } errno_t ipa_hbac_service_info_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *service_count, struct sysdb_attrs ***services, size_t *servicegroup_count, struct sysdb_attrs ***servicegroups) { size_t c; struct ipa_hbac_service_state *state = tevent_req_data(req, struct ipa_hbac_service_state); TEVENT_REQ_RETURN_ON_ERROR(req); *service_count = state->service_count; *services = talloc_steal(mem_ctx, state->services); for (c = 0; c < state->service_count; c++) { /* Guarantee the memory heirarchy of the list */ talloc_steal(state->services, state->services[c]); } *servicegroup_count = state->servicegroup_count; *servicegroups = talloc_steal(mem_ctx, state->servicegroups); return EOK; } errno_t hbac_service_attrs_to_rule(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *rule_name, struct sysdb_attrs *rule_attrs, struct hbac_rule_element **services) { errno_t ret; TALLOC_CTX *tmp_ctx; struct hbac_rule_element *new_services; const char *attrs[] = { IPA_CN, NULL }; struct ldb_message_element *el; size_t num_services = 0; size_t num_servicegroups = 0; size_t i; char *member_dn; char *filter; size_t count; struct ldb_message **msgs; const char *name; DEBUG(SSSDBG_TRACE_LIBS, "Processing PAM services for rule [%s]\n", rule_name); tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return ENOMEM; new_services = talloc_zero(tmp_ctx, struct hbac_rule_element); if (new_services == NULL) { ret = ENOMEM; goto done; } /* First check for service category */ ret = hbac_get_category(rule_attrs, IPA_SERVICE_CATEGORY, &new_services->category); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not identify service categories\n"); goto done; } if (new_services->category & HBAC_CATEGORY_ALL) { /* Short-cut to the exit */ ret = EOK; goto done; } /* Get the list of DNs from the member attr */ ret = sysdb_attrs_get_el(rule_attrs, IPA_MEMBER_SERVICE, &el); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_get_el failed.\n"); goto done; } if (ret == ENOENT || el->num_values == 0) { el->num_values = 0; DEBUG(SSSDBG_CONF_SETTINGS, "No services specified, rule will never apply.\n"); } /* Assume maximum size; We'll trim it later */ new_services->names = talloc_array(new_services, const char *, el->num_values +1); if (new_services->names == NULL) { ret = ENOMEM; goto done; } new_services->groups = talloc_array(new_services, const char *, el->num_values + 1); if (new_services->groups == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < el->num_values; i++) { ret = sss_filter_sanitize(tmp_ctx, (const char *)el->values[i].data, &member_dn); if (ret != EOK) goto done; filter = talloc_asprintf(member_dn, "(%s=%s)", SYSDB_ORIG_DN, member_dn); if (filter == NULL) { ret = ENOMEM; goto done; } /* First check if this is a specific service */ ret = sysdb_search_custom(tmp_ctx, domain, filter, HBAC_SERVICES_SUBDIR, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) goto done; if (ret == EOK && count == 0) { ret = ENOENT; } if (ret == EOK) { if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Original DN matched multiple services. " "Skipping \n"); talloc_zfree(member_dn); continue; } /* Original DN matched a single service. Get the service name */ name = ldb_msg_find_attr_as_string(msgs[0], IPA_CN, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Attribute is missing!\n"); ret = EFAULT; goto done; } new_services->names[num_services] = talloc_strdup(new_services->names, name); if (new_services->names[num_services] == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Added service [%s] to rule [%s]\n", name, rule_name); num_services++; } else { /* ret == ENOENT */ /* Check if this is a service group */ ret = sysdb_search_custom(tmp_ctx, domain, filter, HBAC_SERVICEGROUPS_SUBDIR, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) goto done; if (ret == EOK && count == 0) { ret = ENOENT; } if (ret == EOK) { if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Original DN matched multiple service groups. " "Skipping\n"); talloc_zfree(member_dn); continue; } /* Original DN matched a single group. Get the groupname */ name = ldb_msg_find_attr_as_string(msgs[0], IPA_CN, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Attribute is missing!\n"); ret = EFAULT; goto done; } new_services->groups[num_servicegroups] = talloc_strdup(new_services->groups, name); if (new_services->groups[num_servicegroups] == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Added service group [%s] to rule [%s]\n", name, rule_name); num_servicegroups++; } else { /* ret == ENOENT */ /* Neither a service nor a service group? Skip it */ DEBUG(SSSDBG_CRIT_FAILURE, "[%s] does not map to either a service or " "service group. Skipping\n", member_dn); } } talloc_zfree(member_dn); } new_services->names[num_services] = NULL; new_services->groups[num_servicegroups] = NULL; /* Shrink the arrays down to their real sizes */ new_services->names = talloc_realloc(new_services, new_services->names, const char *, num_services + 1); if (new_services->names == NULL) { ret = ENOMEM; goto done; } new_services->groups = talloc_realloc(new_services, new_services->groups, const char *, num_servicegroups + 1); if (new_services->groups == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: if (ret == EOK) { *services = talloc_steal(mem_ctx, new_services); } talloc_free(tmp_ctx); return ret; } errno_t get_ipa_servicegroupname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, const char *service_dn, char **servicegroupname) { errno_t ret; struct ldb_dn *dn; const char *rdn_name; const char *svc_comp_name; const char *hbac_comp_name; const struct ldb_val *rdn_val; const struct ldb_val *svc_comp_val; const struct ldb_val *hbac_comp_val; /* This is an IPA-specific hack. It may not * work for non-IPA servers and will need to * be changed if SSSD ever supports HBAC on * a non-IPA server. */ *servicegroupname = NULL; dn = ldb_dn_new(mem_ctx, sysdb_ctx_get_ldb(sysdb), service_dn); if (dn == NULL) { ret = ENOMEM; goto done; } if (!ldb_dn_validate(dn)) { ret = ERR_MALFORMED_ENTRY; goto done; } if (ldb_dn_get_comp_num(dn) < 4) { /* RDN, services, hbac, and at least one DC= */ /* If it's fewer, it's not a group DN */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* If the RDN name is 'cn' */ rdn_name = ldb_dn_get_rdn_name(dn); if (rdn_name == NULL) { /* Shouldn't happen if ldb_dn_validate() * passed, but we'll be careful. */ ret = ERR_MALFORMED_ENTRY; goto done; } if (strcasecmp("cn", rdn_name) != 0) { /* RDN has the wrong attribute name. * It's not a service. */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* and the second component is "cn=hbacservicegroups" */ svc_comp_name = ldb_dn_get_component_name(dn, 1); if (strcasecmp("cn", svc_comp_name) != 0) { /* The second component name is not "cn" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } svc_comp_val = ldb_dn_get_component_val(dn, 1); if (strncasecmp("hbacservicegroups", (const char *) svc_comp_val->data, svc_comp_val->length) != 0) { /* The second component value is not "hbacservicegroups" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* and the third component is "hbac" */ hbac_comp_name = ldb_dn_get_component_name(dn, 2); if (strcasecmp("cn", hbac_comp_name) != 0) { /* The third component name is not "cn" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } hbac_comp_val = ldb_dn_get_component_val(dn, 2); if (strncasecmp("hbac", (const char *) hbac_comp_val->data, hbac_comp_val->length) != 0) { /* The third component value is not "hbac" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* Then the value of the RDN is the group name */ rdn_val = ldb_dn_get_rdn_val(dn); *servicegroupname = talloc_strndup(mem_ctx, (const char *)rdn_val->data, rdn_val->length); if (*servicegroupname == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: talloc_free(dn); return ret; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hbac.exports0000644000000000000000000000007312703456111021055 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.370792666 sssd-1.13.4/src/providers/ipa/ipa_hbac.exports0000644002412700241270000000036412703456111022530 0ustar00jhrozekjhrozek00000000000000IPA_HBAC_0.0.1 { # public functions global: hbac_evaluate; hbac_result_string; hbac_error_string; hbac_free_info; hbac_rule_is_complete; # everything else is local local: *; }; sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_id.h0000644000000000000000000000007312703456111017277 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.573793354 sssd-1.13.4/src/providers/ipa/ipa_id.h0000644002412700241270000001315012703456111020747 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Identity Backend Module Authors: Jan Zeleny Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _IPA_ID_H_ #define _IPA_ID_H_ #include "providers/ldap/ldap_common.h" #include "providers/ipa/ipa_common.h" #include "providers/ldap/sdap.h" #include "providers/ipa/ipa_subdomains.h" #define IPA_DEFAULT_VIEW_NAME "Default Trust View" void ipa_account_info_handler(struct be_req *breq); struct tevent_req *ipa_get_netgroups_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct sdap_options *opts, struct ipa_options *ipa_options, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout); int ipa_get_netgroups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sysdb_attrs ***reply); void ipa_check_online(struct be_req *be_req); struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct sdap_options *opts, struct sss_domain_info *dom, struct sysdb_attrs *override_attrs, struct sdap_handle *sh, int entry_type, struct req_input *req_input); int ipa_s2n_get_acct_info_recv(struct tevent_req *req); struct tevent_req *ipa_get_subdom_acct_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct sysdb_attrs *override_attrs, struct be_acct_req *ar); int ipa_get_subdom_acct_recv(struct tevent_req *req, int *dp_error_out); errno_t get_be_acct_req_for_sid(TALLOC_CTX *mem_ctx, const char *sid, const char *domain_name, struct be_acct_req **_ar); errno_t get_be_acct_req_for_uuid(TALLOC_CTX *mem_ctx, const char *uuid, const char *domain_name, struct be_acct_req **_ar); errno_t get_be_acct_req_for_user_name(TALLOC_CTX *mem_ctx, const char *user_name, const char *domain_name, struct be_acct_req **_ar); struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_id_ctx, struct ipa_options *ipa_options, const char *ipa_realm, const char *view_name, struct be_acct_req *ar); errno_t ipa_get_ad_override_recv(struct tevent_req *req, int *dp_error_out, TALLOC_CTX *mem_ctx, struct sysdb_attrs **override_attrs); struct tevent_req *ipa_subdomain_account_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct be_req *be_req, struct be_acct_req *ar); errno_t ipa_subdomain_account_recv(struct tevent_req *req, int *dp_error_out); errno_t split_ipa_anchor(TALLOC_CTX *mem_ctx, const char *anchor, char **_anchor_domain, char **_ipa_uuid); errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, struct be_acct_req *ar, struct ldb_message **_msg); struct tevent_req * ipa_initgr_get_overrides_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct sss_domain_info *user_dom, size_t groups_count, struct ldb_message **groups, const char *groups_id_attr); int ipa_initgr_get_overrides_recv(struct tevent_req *req, int *dp_error); #endif sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_selinux.h0000644000000000000000000000007412703456111020373 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.567793334 sssd-1.13.4/src/providers/ipa/ipa_selinux.h0000644002412700241270000000256112703456111022046 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- selinux loading Authors: Jan Zeleny Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _IPA_SELINUX_H_ #define _IPA_SELINUX_H_ #include "providers/ldap/ldap_common.h" #ifdef HAVE_SELINUX_LOGIN_DIR #define ALL_SERVICES "*" #define selogin_path(mem_ctx, username) \ talloc_asprintf(mem_ctx, "%s/logins/%s", selinux_policy_root(), username) #endif /* HAVE_SELINUX_LOGIN_DIR */ struct ipa_selinux_ctx { struct ipa_id_ctx *id_ctx; time_t last_update; struct sdap_search_base **selinux_search_bases; struct sdap_search_base **host_search_bases; struct sdap_search_base **hbac_search_bases; }; void ipa_selinux_handler(struct be_req *be_req); #endif sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/hbac_evaluator.c0000644000000000000000000000007312703456111021024 xustar0030 atime=1460561751.644715607 29 ctime=1460561774.66979368 sssd-1.13.4/src/providers/ipa/hbac_evaluator.c0000644002412700241270000002307512703456111022503 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- Access control Authors: Sumit Bose Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "providers/ipa/ipa_hbac.h" #include "util/sss_utf8.h" #ifndef HAVE_ERRNO_T #define HAVE_ERRNO_T typedef int errno_t; #endif #ifndef EOK #define EOK 0 #endif /* Placeholder structure for future HBAC time-based * evaluation rules */ struct hbac_time_rules { int not_yet_implemented; }; enum hbac_eval_result_int { HBAC_EVAL_MATCH_ERROR = -1, HBAC_EVAL_MATCHED, HBAC_EVAL_UNMATCHED }; static bool hbac_rule_element_is_complete(struct hbac_rule_element *el) { if (el == NULL) return false; if (el->category == HBAC_CATEGORY_ALL) return true; if (el->names == NULL && el->groups == NULL) return false; if ((el->names && el->names[0] != NULL) || (el->groups && el->groups[0] != NULL)) return true; /* If other categories are added, handle them here */ return false; } bool hbac_rule_is_complete(struct hbac_rule *rule, uint32_t *missing_attrs) { bool complete = true; *missing_attrs = 0; if (rule == NULL) { /* No rule passed in? */ return false; } /* Make sure we have all elements */ if (!hbac_rule_element_is_complete(rule->users)) { complete = false; *missing_attrs |= HBAC_RULE_ELEMENT_USERS; } if (!hbac_rule_element_is_complete(rule->services)) { complete = false; *missing_attrs |= HBAC_RULE_ELEMENT_SERVICES; } if (!hbac_rule_element_is_complete(rule->targethosts)) { complete = false; *missing_attrs |= HBAC_RULE_ELEMENT_TARGETHOSTS; } if (!hbac_rule_element_is_complete(rule->srchosts)) { complete = false; *missing_attrs |= HBAC_RULE_ELEMENT_SOURCEHOSTS; } return complete; } enum hbac_eval_result_int hbac_evaluate_rule(struct hbac_rule *rule, struct hbac_eval_req *hbac_req, enum hbac_error_code *error); enum hbac_eval_result hbac_evaluate(struct hbac_rule **rules, struct hbac_eval_req *hbac_req, struct hbac_info **info) { enum hbac_error_code ret; enum hbac_eval_result result = HBAC_EVAL_DENY; enum hbac_eval_result_int intermediate_result; if (info) { *info = malloc(sizeof(struct hbac_info)); if (!*info) { return HBAC_EVAL_OOM; } (*info)->code = HBAC_ERROR_UNKNOWN; (*info)->rule_name = NULL; } uint32_t i; for (i = 0; rules[i]; i++) { intermediate_result = hbac_evaluate_rule(rules[i], hbac_req, &ret); if (intermediate_result == HBAC_EVAL_UNMATCHED) { /* This rule did not match at all. Skip it */ continue; } else if (intermediate_result == HBAC_EVAL_MATCHED) { /* This request matched an ALLOW rule * Set the result to ALLOW but continue checking * the other rules in case a DENY rule trumps it. */ result = HBAC_EVAL_ALLOW; if (info) { (*info)->code = HBAC_SUCCESS; (*info)->rule_name = strdup(rules[i]->name); if (!(*info)->rule_name) { result = HBAC_EVAL_ERROR; (*info)->code = HBAC_ERROR_OUT_OF_MEMORY; } } break; } else { /* An error occurred processing this rule */ result = HBAC_EVAL_ERROR; if (info) { (*info)->code = ret; (*info)->rule_name = strdup(rules[i]->name); } /* Explicitly not checking the result of strdup(), since if * it's NULL, we can't do anything anyway. */ goto done; } } /* If we've reached the end of the loop, we have either set the * result to ALLOW explicitly or we'll stick with the default DENY. */ done: return result; } static errno_t hbac_evaluate_element(struct hbac_rule_element *rule_el, struct hbac_request_element *req_el, bool *matched); enum hbac_eval_result_int hbac_evaluate_rule(struct hbac_rule *rule, struct hbac_eval_req *hbac_req, enum hbac_error_code *error) { errno_t ret; bool matched; if (!rule->enabled) return HBAC_EVAL_UNMATCHED; /* Make sure we have all elements */ if (!rule->users || !rule->services || !rule->targethosts || !rule->srchosts) { *error = HBAC_ERROR_UNPARSEABLE_RULE; return HBAC_EVAL_MATCH_ERROR; } /* Check users */ ret = hbac_evaluate_element(rule->users, hbac_req->user, &matched); if (ret != EOK) { *error = HBAC_ERROR_UNPARSEABLE_RULE; return HBAC_EVAL_MATCH_ERROR; } else if (!matched) { return HBAC_EVAL_UNMATCHED; } /* Check services */ ret = hbac_evaluate_element(rule->services, hbac_req->service, &matched); if (ret != EOK) { *error = HBAC_ERROR_UNPARSEABLE_RULE; return HBAC_EVAL_MATCH_ERROR; } else if (!matched) { return HBAC_EVAL_UNMATCHED; } /* Check target hosts */ ret = hbac_evaluate_element(rule->targethosts, hbac_req->targethost, &matched); if (ret != EOK) { *error = HBAC_ERROR_UNPARSEABLE_RULE; return HBAC_EVAL_MATCH_ERROR; } else if (!matched) { return HBAC_EVAL_UNMATCHED; } /* Check source hosts */ ret = hbac_evaluate_element(rule->srchosts, hbac_req->srchost, &matched); if (ret != EOK) { *error = HBAC_ERROR_UNPARSEABLE_RULE; return HBAC_EVAL_MATCH_ERROR; } else if (!matched) { return HBAC_EVAL_UNMATCHED; } return HBAC_EVAL_MATCHED; } static errno_t hbac_evaluate_element(struct hbac_rule_element *rule_el, struct hbac_request_element *req_el, bool *matched) { size_t i, j; const uint8_t *rule_name; const uint8_t *req_name; int ret; if (rule_el->category & HBAC_CATEGORY_ALL) { *matched = true; return EOK; } /* First check the name list */ if (rule_el->names) { for (i = 0; rule_el->names[i]; i++) { if (req_el->name != NULL) { rule_name = (const uint8_t *) rule_el->names[i]; req_name = (const uint8_t *) req_el->name; /* Do a case-insensitive comparison. */ ret = sss_utf8_case_eq(rule_name, req_name); if (ret != EOK && ret != ENOMATCH) { return ret; } else if (ret == EOK) { *matched = true; return EOK; } } } } if (rule_el->groups) { /* Not found in the name list * Check for group membership */ for (i = 0; rule_el->groups[i]; i++) { rule_name = (const uint8_t *) rule_el->groups[i]; for (j = 0; req_el->groups[j]; j++) { req_name = (const uint8_t *) req_el->groups[j]; /* Do a case-insensitive comparison. */ ret = sss_utf8_case_eq(rule_name, req_name); if (ret != EOK && ret != ENOMATCH) { return ret; } else if (ret == EOK) { *matched = true; return EOK; } } } } /* Not found in groups either */ *matched = false; return EOK; } const char *hbac_result_string(enum hbac_eval_result result) { switch(result) { case HBAC_EVAL_ALLOW: return "HBAC_EVAL_ALLOW"; case HBAC_EVAL_DENY: return "HBAC_EVAL_DENY"; case HBAC_EVAL_ERROR: return "HBAC_EVAL_ERROR"; case HBAC_EVAL_OOM: return "Could not allocate memory for hbac_info object"; } return "HBAC_EVAL_ERROR"; } void hbac_free_info(struct hbac_info *info) { if (info == NULL) return; free(info->rule_name); free(info); } const char *hbac_error_string(enum hbac_error_code code) { switch(code) { case HBAC_SUCCESS: return "Success"; case HBAC_ERROR_NOT_IMPLEMENTED: return "Function is not yet implemented"; case HBAC_ERROR_OUT_OF_MEMORY: return "Out of memory"; case HBAC_ERROR_UNPARSEABLE_RULE: return "Rule could not be evaluated"; case HBAC_ERROR_UNKNOWN: default: return "Unknown error code"; } } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hostid.c0000644000000000000000000000007312703456111020170 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.755793971 sssd-1.13.4/src/providers/ipa/ipa_hostid.c0000644002412700241270000002142412703456111021643 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/crypto/sss_crypto.h" #include "db/sysdb_ssh.h" #include "providers/ldap/ldap_common.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_hostid.h" #include "providers/ipa/ipa_hosts.h" struct hosts_get_state { struct tevent_context *ev; struct ipa_hostid_ctx *ctx; struct sdap_id_op *op; struct sss_domain_info *domain; const char *name; const char *alias; size_t count; struct sysdb_attrs **hosts; int dp_error; }; struct tevent_req * hosts_get_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_hostid_ctx *hostid_ctx, const char *name, const char *alias); static errno_t hosts_get_recv(struct tevent_req *req, int *dp_error_out); static void ipa_host_info_hosts_done(struct tevent_req *req); void ipa_host_info_handler(struct be_req *breq) { struct be_ctx *be_ctx = be_req_get_be_ctx(breq); struct ipa_hostid_ctx *hostid_ctx; struct sdap_id_ctx *ctx; struct be_host_req *hr; struct tevent_req *req; int dp_error = DP_ERR_FATAL; errno_t ret = EOK; const char *err = "Unknown Error"; hostid_ctx = talloc_get_type(be_ctx->bet_info[BET_HOSTID].pvt_bet_data, struct ipa_hostid_ctx); ctx = hostid_ctx->sdap_id_ctx; if (be_is_offline(ctx->be)) { dp_error = DP_ERR_OFFLINE; ret = EAGAIN; err = "Offline"; goto done; } hr = talloc_get_type(be_req_get_data(breq), struct be_host_req); if (hr->filter_type != BE_FILTER_NAME) { ret = EINVAL; err = "Invalid filter type"; goto done; } req = hosts_get_send(breq, be_ctx->ev, hostid_ctx, hr->name, hr->alias); if (!req) { ret = ENOMEM; err = "Out of memory"; goto done; } tevent_req_set_callback(req, ipa_host_info_hosts_done, breq); ret = EOK; done: if (ret != EOK) return sdap_handler_done(breq, dp_error, ret, err); } static void ipa_host_info_complete(struct be_req *breq, int dp_error, errno_t ret, const char *default_error_text) { const char* error_text; if (dp_error == DP_ERR_OK) { if (ret == EOK) { error_text = NULL; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: dp_error is OK on failed request\n"); dp_error = DP_ERR_FATAL; error_text = default_error_text; } } else if (dp_error == DP_ERR_OFFLINE) { error_text = "Offline"; } else if (dp_error == DP_ERR_FATAL && ret == ENOMEM) { error_text = "Out of memory"; } else { error_text = default_error_text; } sdap_handler_done(breq, dp_error, ret, error_text); } static void ipa_host_info_hosts_done(struct tevent_req *req) { struct be_req *breq = tevent_req_callback_data(req, struct be_req); int ret, dp_error; ret = hosts_get_recv(req, &dp_error); talloc_zfree(req); ipa_host_info_complete(breq, dp_error, ret, "Host lookup failed"); } static errno_t hosts_get_retry(struct tevent_req *req); static void hosts_get_connect_done(struct tevent_req *subreq); static void hosts_get_done(struct tevent_req *subreq); struct tevent_req * hosts_get_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_hostid_ctx *hostid_ctx, const char *name, const char *alias) { struct tevent_req *req; struct hosts_get_state *state; struct sdap_id_ctx *ctx; errno_t ret; ctx = hostid_ctx->sdap_id_ctx; req = tevent_req_create(memctx, &state, struct hosts_get_state); if (!req) return NULL; state->ev = ev; state->ctx = hostid_ctx; state->dp_error = DP_ERR_FATAL; state->op = sdap_id_op_create(state, ctx->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto fail; } state->domain = ctx->be->domain; state->name = name; state->alias = alias; ret = hosts_get_retry(req); if (ret != EOK) { goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static errno_t hosts_get_retry(struct tevent_req *req) { struct hosts_get_state *state = tevent_req_data(req, struct hosts_get_state); struct tevent_req *subreq; errno_t ret = EOK; subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { return ret; } tevent_req_set_callback(subreq, hosts_get_connect_done, req); return EOK; } static void hosts_get_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct hosts_get_state *state = tevent_req_data(req, struct hosts_get_state); int dp_error = DP_ERR_FATAL; errno_t ret; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } subreq = ipa_host_info_send(state, state->ev, sdap_id_op_handle(state->op), state->ctx->sdap_id_ctx->opts, state->name, state->ctx->ipa_opts->host_map, NULL, state->ctx->host_search_bases); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, hosts_get_done, req); } static void hosts_get_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct hosts_get_state *state = tevent_req_data(req, struct hosts_get_state); int dp_error = DP_ERR_FATAL; errno_t ret; struct sysdb_attrs *attrs; time_t now = time(NULL); ret = ipa_host_info_recv(subreq, state, &state->count, &state->hosts, NULL, NULL); talloc_zfree(subreq); ret = sdap_id_op_done(state->op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = hosts_get_retry(req); if (ret != EOK) { goto done; } return; } if (ret != EOK && ret != ENOENT) { goto done; } if (state->count == 0) { DEBUG(SSSDBG_OP_FAILURE, "No host with name [%s] found.\n", state->name); ret = sysdb_delete_ssh_host(state->domain, state->name); if (ret != EOK && ret != ENOENT) { goto done; } ret = EINVAL; goto done; } if (state->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Found more than one host with name [%s].\n", state->name); ret = EINVAL; goto done; } attrs = sysdb_new_attrs(state); if (!attrs) { ret = ENOMEM; goto done; } /* we are interested only in the host keys */ ret = sysdb_attrs_copy_values(state->hosts[0], attrs, SYSDB_SSH_PUBKEY); if (ret != EOK) { goto done; } ret = sysdb_store_ssh_host(state->domain, state->name, state->alias, state->domain->ssh_host_timeout, now, attrs); if (ret != EOK) { goto done; } dp_error = DP_ERR_OK; done: state->dp_error = dp_error; if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } static errno_t hosts_get_recv(struct tevent_req *req, int *dp_error_out) { struct hosts_get_state *state = tevent_req_data(req, struct hosts_get_state); if (dp_error_out) { *dp_error_out = state->dp_error; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_subdomains_utils.c0000644000000000000000000000007212703456111022261 xustar0030 atime=1460561751.646715613 28 ctime=1460561774.7347939 sssd-1.13.4/src/providers/ipa/ipa_subdomains_utils.c0000644002412700241270000000605612703456111023741 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Subdomains Module - utilities Authors: Sumit Bose Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ipa/ipa_subdomains.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_id.h" struct ldb_dn *ipa_subdom_ldb_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct sysdb_attrs *attrs) { int ret; const char *orig_dn; struct ldb_dn *dn = NULL; if (attrs == NULL || ldb_ctx == NULL) { return NULL; } ret = sysdb_attrs_get_string(attrs, SYSDB_ORIG_DN, &orig_dn); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed: %d\n", ret); return NULL; } dn = ldb_dn_new(mem_ctx, ldb_ctx, orig_dn); if (dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); return NULL; } if (!ldb_dn_validate(dn)) { DEBUG(SSSDBG_OP_FAILURE, "Original DN [%s] is not a valid DN.\n", orig_dn); talloc_free(dn); return NULL; } return dn; } bool ipa_subdom_is_member_dom(struct ldb_dn *dn) { const struct ldb_val *val; if (dn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrong input!\n"); return false; } if (ldb_dn_get_comp_num(dn) < 5) { /* We are only interested in the member domain objects. In IPA the * forest root object is stored as e.g. * cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com. Member domains in the * forest are children of the forest root object e.g. * cn=SUB.AD.DOM,cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com. Since * the forest name is not stored in the member objects we derive it * from the RDN of the forest root object. */ DEBUG(SSSDBG_TRACE_FUNC, "DN too short, not a member domain\n"); return false; } val = ldb_dn_get_component_val(dn, 3); if (strncasecmp("trusts", (const char *) val->data, val->length) != 0) { DEBUG(SSSDBG_TRACE_FUNC, "4th component is not 'trust', not a member domain\n"); return false; } val = ldb_dn_get_component_val(dn, 2); if (strncasecmp("ad", (const char *) val->data, val->length) != 0) { DEBUG(SSSDBG_TRACE_FUNC, "3rd component is not 'ad', not a member domain\n"); return false; } return true; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_access.h0000644000000000000000000000007212703456111020143 xustar0029 atime=1460561751.64571561 29 ctime=1460561774.56679333 sssd-1.13.4/src/providers/ipa/ipa_access.h0000644002412700241270000000442512703456111021621 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- Access control Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _IPA_ACCESS_H_ #define _IPA_ACCESS_H_ #include "providers/ldap/ldap_common.h" enum ipa_access_mode { IPA_ACCESS_DENY = 0, IPA_ACCESS_ALLOW }; struct ipa_access_ctx { struct sdap_id_ctx *sdap_ctx; struct dp_option *ipa_options; struct time_rules_ctx *tr_ctx; time_t last_update; struct sdap_access_ctx *sdap_access_ctx; struct sdap_attr_map *host_map; struct sdap_attr_map *hostgroup_map; struct sdap_search_base **host_search_bases; struct sdap_search_base **hbac_search_bases; }; struct hbac_ctx { struct sdap_id_ctx *sdap_ctx; struct ipa_access_ctx *access_ctx; struct sdap_id_op *sdap_op; struct dp_option *ipa_options; struct time_rules_ctx *tr_ctx; struct be_req *be_req; struct pam_data *pd; struct sdap_search_base **search_bases; /* Hosts */ size_t host_count; struct sysdb_attrs **hosts; size_t hostgroup_count; struct sysdb_attrs **hostgroups; struct sysdb_attrs *ipa_host; /* Rules */ size_t rule_count; struct sysdb_attrs **rules; /* Services */ size_t service_count; struct sysdb_attrs **services; size_t servicegroup_count; struct sysdb_attrs **servicegroups; }; void ipa_access_handler(struct be_req *be_req); errno_t hbac_get_cached_rules(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, size_t *_rule_count, struct sysdb_attrs ***_rules); #endif /* _IPA_ACCESS_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_subdomains_server.c0000644000000000000000000000007412703456111022431 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.733793897 sssd-1.13.4/src/providers/ipa/ipa_subdomains_server.c0000644002412700241270000010753612703456111024114 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Subdomains Module - server mode Authors: Sumit Bose Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ipa/ipa_subdomains.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_id.h" /* These constants are defined in MS-ADTS 6.1.6.7.1 * https://msdn.microsoft.com/en-us/library/cc223768.aspx */ #define LSA_TRUST_DIRECTION_INBOUND 0x00000001 #define LSA_TRUST_DIRECTION_OUTBOUND 0x00000002 static char *forest_keytab(TALLOC_CTX *mem_ctx, const char *forest) { return talloc_asprintf(mem_ctx, "%s/%s.keytab", IPA_TRUST_KEYTAB_DIR, forest); } static char *subdomain_trust_princ(TALLOC_CTX *mem_ctx, const char *forest_realm, struct sss_domain_info *sd) { if (sd->parent->flat_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown flat name for parent %s\n", sd->parent->name); return NULL; } return talloc_asprintf(mem_ctx, "%s$@%s", sd->parent->flat_name, forest_realm); } static uint32_t default_direction(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct sysdb_attrs *attrs) { struct ldb_dn *dn = NULL; uint32_t direction; dn = ipa_subdom_ldb_dn(mem_ctx, ldb_ctx, attrs); if (dn == NULL) { /* Shouldn't happen, but let's try system keytab in this case */ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot determine subdomain DN, falling back to two-way trust\n"); return (LSA_TRUST_DIRECTION_INBOUND|LSA_TRUST_DIRECTION_OUTBOUND); } if (ipa_subdom_is_member_dom(dn) == true) { /* It's expected member domains do not have the direction */ direction = 0; } else { /* Old server? Default to 2way trust */ direction = (LSA_TRUST_DIRECTION_INBOUND|LSA_TRUST_DIRECTION_OUTBOUND); } talloc_free(dn); return direction; } errno_t ipa_server_get_trust_direction(struct sysdb_attrs *sd, struct ldb_context *ldb_ctx, uint32_t *_direction) { uint32_t ipa_trust_direction = 0; uint32_t direction; int ret; ret = sysdb_attrs_get_uint32_t(sd, IPA_TRUST_DIRECTION, &ipa_trust_direction); DEBUG(SSSDBG_TRACE_INTERNAL, "Raw %s value: %d\n", IPA_TRUST_DIRECTION, ipa_trust_direction); if (ret == ENOENT) { direction = default_direction(sd, ldb_ctx, sd); } else if (ret == EOK) { /* Just store the AD value in SYSDB, we will check it while we're * trying to use the trust */ direction = ipa_trust_direction; } else { return ret; } *_direction = direction; return EOK; } const char *ipa_trust_dir2str(uint32_t direction) { if ((direction & LSA_TRUST_DIRECTION_OUTBOUND) && (direction & LSA_TRUST_DIRECTION_INBOUND)) { return "two-way trust"; } else if (direction & LSA_TRUST_DIRECTION_OUTBOUND) { return "one-way outbound: local domain is trusted by remote domain"; } else if (direction & LSA_TRUST_DIRECTION_INBOUND) { return "one-way inbound: local domain trusts the remote domain"; } else if (direction == 0) { return "trust direction not set"; } return "unknown"; } #ifndef IPA_GETKEYTAB_TIMEOUT #define IPA_GETKEYTAB_TIMEOUT 5 #endif /* IPA_GETKEYTAB_TIMEOUT */ static struct ad_options * ipa_create_1way_trust_ctx(struct ipa_id_ctx *id_ctx, const char *forest, const char *forest_realm, struct sss_domain_info *subdom) { char *keytab; char *principal; struct ad_options *ad_options; const char *ad_domain; ad_domain = subdom->name; keytab = forest_keytab(id_ctx, forest); principal = subdomain_trust_princ(id_ctx, forest_realm, subdom); if (keytab == NULL || principal == NULL) { return NULL; } ad_options = ad_create_1way_trust_options(id_ctx, ad_domain, id_ctx->server_mode->hostname, keytab, principal); if (ad_options == NULL) { talloc_free(keytab); talloc_free(principal); return NULL; } return ad_options; } static struct ad_options *ipa_ad_options_new(struct ipa_id_ctx *id_ctx, struct sss_domain_info *subdom) { struct ad_options *ad_options = NULL; uint32_t direction; const char *forest; const char *forest_realm; /* Trusts are only established with forest roots */ direction = subdom->forest_root->trust_direction; forest_realm = subdom->forest_root->realm; forest = subdom->forest_root->forest; if (direction & LSA_TRUST_DIRECTION_OUTBOUND) { ad_options = ad_create_2way_trust_options(id_ctx, id_ctx->server_mode->realm, subdom->name, id_ctx->server_mode->hostname); } else if (direction & LSA_TRUST_DIRECTION_INBOUND) { ad_options = ipa_create_1way_trust_ctx(id_ctx, forest, forest_realm, subdom); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported trust direction!\n"); ad_options = NULL; } if (ad_options == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n"); return NULL; } return ad_options; } static errno_t ipa_ad_ctx_new(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct sss_domain_info *subdom, struct ad_id_ctx **_ad_id_ctx) { struct ad_options *ad_options; struct ad_id_ctx *ad_id_ctx; const char *gc_service_name; struct ad_srv_plugin_ctx *srv_ctx; const char *ad_domain; const char *ad_site_override; struct sdap_domain *sdom; errno_t ret; const char *extra_attrs; ad_domain = subdom->name; DEBUG(SSSDBG_TRACE_LIBS, "Setting up AD subdomain %s\n", subdom->name); ad_options = ipa_ad_options_new(id_ctx, subdom); if (ad_options == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n"); talloc_free(ad_options); return ENOMEM; } extra_attrs = dp_opt_get_string(id_ctx->sdap_id_ctx->opts->basic, SDAP_USER_EXTRA_ATTRS); if (extra_attrs != NULL) { DEBUG(SSSDBG_TRACE_ALL, "Setting extra attrs for subdomain [%s] to [%s].\n", ad_domain, extra_attrs); ret = dp_opt_set_string(ad_options->id->basic, SDAP_USER_EXTRA_ATTRS, extra_attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "dp_opt_get_string failed.\n"); talloc_free(ad_options); return ret; } ret = sdap_extend_map_with_list(ad_options->id, ad_options->id, SDAP_USER_EXTRA_ATTRS, ad_options->id->user_map, SDAP_OPTS_USER, &ad_options->id->user_map, &ad_options->id->user_map_cnt); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_extend_map_with_list failed.\n"); talloc_free(ad_options); return ret; } } else { DEBUG(SSSDBG_TRACE_ALL, "No extra attrs set.\n"); } gc_service_name = talloc_asprintf(ad_options, "%s%s", "gc_", subdom->name); if (gc_service_name == NULL) { talloc_free(ad_options); return ENOMEM; } /* Set KRB5 realm to same as the one of IPA when IPA * is able to attach PAC. For testing, use hardcoded. */ ret = ad_failover_init(ad_options, be_ctx, NULL, NULL, id_ctx->server_mode->realm, subdom->name, gc_service_name, subdom->name, &ad_options->service); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD failover\n"); talloc_free(ad_options); return ret; } ad_id_ctx = ad_id_ctx_init(ad_options, be_ctx); if (ad_id_ctx == NULL) { talloc_free(ad_options); return ENOMEM; } ad_id_ctx->sdap_id_ctx->opts = ad_options->id; ad_options->id_ctx = ad_id_ctx; ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE); /* use AD plugin */ srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res, default_host_dbs, ad_id_ctx->ad_options->id, id_ctx->server_mode->hostname, ad_domain, ad_site_override); if (srv_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n"); return ENOMEM; } be_fo_set_srv_lookup_plugin(be_ctx, ad_srv_plugin_send, ad_srv_plugin_recv, srv_ctx, "AD"); ret = sdap_domain_subdom_add(ad_id_ctx->sdap_id_ctx, ad_id_ctx->sdap_id_ctx->opts->sdom, subdom->parent); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize sdap domain\n"); talloc_free(ad_options); return ret; } sdom = sdap_domain_get(ad_id_ctx->sdap_id_ctx->opts, subdom); if (sdom == NULL) { return EFAULT; } sdap_inherit_options(subdom->parent->sd_inherit, id_ctx->sdap_id_ctx->opts, ad_id_ctx->sdap_id_ctx->opts); ret = sdap_id_setup_tasks(be_ctx, ad_id_ctx->sdap_id_ctx, sdom, ldap_enumeration_send, ldap_enumeration_recv, ad_id_ctx->sdap_id_ctx); if (ret != EOK) { talloc_free(ad_options); return ret; } sdom->pvt = ad_id_ctx; /* Set up the ID mapping object */ ad_id_ctx->sdap_id_ctx->opts->idmap_ctx = id_ctx->sdap_id_ctx->opts->idmap_ctx; *_ad_id_ctx = ad_id_ctx; return EOK; } struct ipa_getkeytab_state { int child_status; struct sss_child_ctx_old *child_ctx; struct tevent_timer *timeout_handler; }; static void ipa_getkeytab_exec(const char *ccache, const char *server, const char *principal, const char *keytab_path); static void ipa_getkeytab_done(int child_status, struct tevent_signal *sige, void *pvt); static void ipa_getkeytab_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt); static struct tevent_req *ipa_getkeytab_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *ccache, const char *server, const char *principal, const char *keytab) { errno_t ret; struct tevent_req *req = NULL; struct ipa_getkeytab_state *state; pid_t child_pid; struct timeval tv; req = tevent_req_create(mem_ctx, &state, struct ipa_getkeytab_state); if (req == NULL) { return NULL; } state->child_status = EFAULT; if (server == NULL || principal == NULL || keytab == NULL) { ret = EINVAL; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Retrieving keytab for %s from %s into %s using ccache %s\n", principal, server, keytab, ccache); child_pid = fork(); if (child_pid == 0) { /* child */ ipa_getkeytab_exec(ccache, server, principal, keytab); } else if (child_pid > 0) { /* parent */ /* Set up SIGCHLD handler */ ret = child_handler_setup(ev, child_pid, ipa_getkeytab_done, req, &state->child_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set up child handlers [%d]: %s\n", ret, sss_strerror(ret)); ret = ERR_IPA_GETKEYTAB_FAILED; goto done; } /* Set up timeout handler */ tv = tevent_timeval_current_ofs(IPA_GETKEYTAB_TIMEOUT, 0); state->timeout_handler = tevent_add_timer(ev, req, tv, ipa_getkeytab_timeout, req); if(state->timeout_handler == NULL) { ret = ERR_IPA_GETKEYTAB_FAILED; goto done; } /* Now either wait for the timeout to fire or the child * to finish */ } else { /* error */ ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n", ret, sss_strerror(ret)); goto done; } ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void ipa_getkeytab_exec(const char *ccache, const char *server, const char *principal, const char *keytab_path) { errno_t ret; int debug_fd; const char *gkt_env[2] = { NULL, NULL }; if (debug_level >= SSSDBG_TRACE_LIBS) { debug_fd = get_fd_from_debug_file(); ret = dup2(debug_fd, STDERR_FILENO); if (ret == -1) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "dup2 failed [%d][%s].\n", ret, sss_strerror(ret)); /* stderr is not fatal */ } } gkt_env[0] = talloc_asprintf(NULL, "KRB5CCNAME=%s", ccache); if (gkt_env[0] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to format KRB5CCNAME\n"); exit(1); } /* ipa-getkeytab cannot add keys to an empty file, let's unlink it and only * use the filename */ ret = unlink(keytab_path); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unlink the temporary ccname [%d][%s]\n", ret, sss_strerror(ret)); exit(1); } errno = 0; ret = execle(IPA_GETKEYTAB_PATH, IPA_GETKEYTAB_PATH, "-r", "-s", server, "-p", principal, "-k", keytab_path, NULL, gkt_env); DEBUG(SSSDBG_CRIT_FAILURE, "execle returned %d, this shouldn't happen!\n", ret); /* The child should never end up here */ ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "execle failed [%d][%s].\n", ret, sss_strerror(ret)); exit(1); } static void ipa_getkeytab_done(int child_status, struct tevent_signal *sige, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct ipa_getkeytab_state *state = tevent_req_data(req, struct ipa_getkeytab_state); state->child_status = child_status; if (WIFEXITED(child_status) && WEXITSTATUS(child_status) != 0) { DEBUG(SSSDBG_OP_FAILURE, "ipa-getkeytab failed with status [%d]\n", child_status); tevent_req_error(req, ERR_IPA_GETKEYTAB_FAILED); return; } if (WIFSIGNALED(child_status)) { DEBUG(SSSDBG_OP_FAILURE, "ipa-getkeytab was terminated by signal [%d]\n", WTERMSIG(child_status)); tevent_req_error(req, ERR_IPA_GETKEYTAB_FAILED); return; } tevent_req_done(req); } static void ipa_getkeytab_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct ipa_getkeytab_state *state = tevent_req_data(req, struct ipa_getkeytab_state); DEBUG(SSSDBG_CRIT_FAILURE, "Timeout reached for retrieving keytab from IPA server\n"); child_handler_destroy(state->child_ctx); state->child_ctx = NULL; state->child_status = ETIMEDOUT; tevent_req_error(req, ERR_IPA_GETKEYTAB_FAILED); } static errno_t ipa_getkeytab_recv(struct tevent_req *req, int *child_status) { struct ipa_getkeytab_state *state = tevent_req_data(req, struct ipa_getkeytab_state); DEBUG(SSSDBG_TRACE_INTERNAL, "ipa-getkeytab status %d\n", state->child_status); if (child_status) { *child_status = state->child_status; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static errno_t ipa_check_keytab(const char *keytab, uid_t kt_owner_uid, gid_t kt_owner_gid) { errno_t ret; ret = check_file(keytab, getuid(), getgid(), S_IFREG|0600, 0, NULL, false); if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "Keytab %s is not present\n", keytab); goto done; } else if (ret != EOK) { if (kt_owner_uid) { ret = check_file(keytab, kt_owner_uid, kt_owner_gid, S_IFREG|0600, 0, NULL, false); } if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Failed to check for %s\n", keytab); } else { DEBUG(SSSDBG_TRACE_FUNC, "Keytab %s is not present\n", keytab); } } goto done; } DEBUG(SSSDBG_TRACE_ALL, "keytab %s already exists\n", keytab); ret = EOK; done: return ret; } struct ipa_server_trusted_dom_setup_state { struct tevent_context *ev; struct be_ctx *be_ctx; struct ipa_id_ctx *id_ctx; struct sss_domain_info *subdom; uint32_t direction; const char *forest; const char *keytab; char *new_keytab; const char *principal; const char *forest_realm; const char *ccache; }; static errno_t ipa_server_trusted_dom_setup_1way(struct tevent_req *req); static void ipa_server_trust_1way_kt_done(struct tevent_req *subreq); struct tevent_req * ipa_server_trusted_dom_setup_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct sss_domain_info *subdom) { struct tevent_req *req = NULL; struct ipa_server_trusted_dom_setup_state *state = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ipa_server_trusted_dom_setup_state); if (req == NULL) { return NULL; } state->ev = ev; state->be_ctx = be_ctx; state->id_ctx = id_ctx; state->subdom = subdom; /* Trusts are only established with forest roots */ if (subdom->forest_root == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Subdomain %s has no forest root?\n", subdom->name); ret = ERR_TRUST_FOREST_UNKNOWN; goto immediate; } state->direction = subdom->forest_root->trust_direction; state->forest = subdom->forest_root->forest; state->forest_realm = subdom->forest_root->realm; state->ccache = talloc_asprintf(state, "%s/ccache_%s", DB_PATH, subdom->parent->realm); if (state->ccache == NULL) { ret = ENOMEM; goto immediate; } DEBUG(SSSDBG_TRACE_LIBS, "Trust direction of subdom %s from forest %s is: %s\n", subdom->name, state->forest, ipa_trust_dir2str(state->direction)); if (state->direction & LSA_TRUST_DIRECTION_OUTBOUND) { /* Use system keytab, nothing to do here */ ret = EOK; goto immediate; } else if (state->direction & LSA_TRUST_DIRECTION_INBOUND) { /* Need special keytab */ ret = ipa_server_trusted_dom_setup_1way(req); if (ret == EAGAIN) { /* In progress.. */ return req; } else if (ret == EOK) { /* Keytab available, shortcut */ ret = EOK; goto immediate; } } else { /* Even unset is an error at this point */ DEBUG(SSSDBG_OP_FAILURE, "Subdomain %s has trust direction %d\n", subdom->name, subdom->trust_direction); ret = ERR_TRUST_NOT_SUPPORTED; } immediate: if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not add trusted subdomain %s from forest %s\n", subdom->name, state->forest); tevent_req_error(req, ret); } else { tevent_req_done(req); } tevent_req_post(req, ev); return req; } static errno_t ipa_server_trusted_dom_setup_1way(struct tevent_req *req) { errno_t ret; struct tevent_req *subreq = NULL; struct ipa_server_trusted_dom_setup_state *state = tevent_req_data(req, struct ipa_server_trusted_dom_setup_state); const char *hostname; state->keytab = forest_keytab(state, state->forest); if (state->keytab == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set up ipa_get_keytab\n"); return EIO; } state->new_keytab = talloc_asprintf(state, "%sXXXXXX", state->keytab); if (state->new_keytab == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set up ipa_get_keytab\n"); return ENOMEM; } ret = sss_unique_filename(state, state->new_keytab); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create temporary keytab name\n"); return ret; } DEBUG(SSSDBG_TRACE_FUNC, "Will re-fetch keytab for %s\n", state->subdom->name); hostname = dp_opt_get_string(state->id_ctx->ipa_options->basic, IPA_HOSTNAME); state->principal = subdomain_trust_princ(state, state->forest_realm, state->subdom); if (state->principal == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set up ipa_get_keytab\n"); return EIO; } subreq = ipa_getkeytab_send(state->be_ctx, state->be_ctx->ev, state->ccache, hostname, state->principal, state->new_keytab); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, ipa_server_trust_1way_kt_done, req); return EAGAIN; } static void ipa_server_trust_1way_kt_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_server_trusted_dom_setup_state *state = tevent_req_data(req, struct ipa_server_trusted_dom_setup_state); ret = ipa_getkeytab_recv(subreq, NULL); talloc_zfree(subreq); if (ret != EOK) { /* Do not fail here, but try to check and use the previous keytab, * if any */ DEBUG(SSSDBG_MINOR_FAILURE, "ipa_getkeytab_recv failed: %d\n", ret); } else { DEBUG(SSSDBG_TRACE_FUNC, "Keytab successfully retrieved to %s\n", state->new_keytab); } ret = ipa_check_keytab(state->new_keytab, state->id_ctx->server_mode->kt_owner_uid, state->id_ctx->server_mode->kt_owner_gid); if (ret == EOK) { ret = rename(state->new_keytab, state->keytab); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "rename failed [%d][%s].\n", ret, strerror(ret)); tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_INTERNAL, "Keytab renamed to %s\n", state->keytab); } else if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Trying to recover and use the previous keytab, if available\n"); ret = ipa_check_keytab(state->keytab, state->id_ctx->server_mode->kt_owner_uid, state->id_ctx->server_mode->kt_owner_gid); if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "The previous keytab %s contains the expected principal\n", state->keytab); } else { DEBUG(SSSDBG_OP_FAILURE, "Cannot use the old keytab: %d\n", ret); /* Nothing we can do now */ tevent_req_error(req, ret); return; } } DEBUG(SSSDBG_TRACE_FUNC, "Keytab %s contains the expected principals\n", state->new_keytab); DEBUG(SSSDBG_TRACE_FUNC, "Established trust context for %s\n", state->subdom->name); tevent_req_done(req); } errno_t ipa_server_trusted_dom_setup_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct ipa_server_create_trusts_state { struct tevent_context *ev; struct be_ctx *be_ctx; struct ipa_id_ctx *id_ctx; struct sss_domain_info *domiter; }; static errno_t ipa_server_create_trusts_step(struct tevent_req *req); static errno_t ipa_server_create_trusts_ctx(struct tevent_req *req); static void ipa_server_create_trusts_done(struct tevent_req *subreq); struct tevent_req * ipa_server_create_trusts_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct sss_domain_info *parent) { struct tevent_req *req = NULL; struct ipa_server_create_trusts_state *state = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ipa_server_create_trusts_state); if (req == NULL) { return NULL; } state->ev = ev; state->be_ctx = be_ctx; state->id_ctx = id_ctx; state->domiter = parent; ret = ipa_server_create_trusts_step(req); if (ret != EAGAIN) { goto immediate; } return req; immediate: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } tevent_req_post(req, ev); return req; } static errno_t ipa_server_create_trusts_step(struct tevent_req *req) { struct tevent_req *subreq = NULL; struct ipa_ad_server_ctx *trust_iter; struct ipa_server_create_trusts_state *state = NULL; state = tevent_req_data(req, struct ipa_server_create_trusts_state); for (state->domiter = get_next_domain(state->domiter, SSS_GND_DESCEND); state->domiter && IS_SUBDOMAIN(state->domiter); state->domiter = get_next_domain(state->domiter, 0)) { /* Check if we already have an ID context for this subdomain */ DLIST_FOR_EACH(trust_iter, state->id_ctx->server_mode->trusts) { if (trust_iter->dom == state->domiter) { break; } } /* Newly detected trust */ if (trust_iter == NULL) { subreq = ipa_server_trusted_dom_setup_send(state, state->ev, state->be_ctx, state->id_ctx, state->domiter); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, ipa_server_create_trusts_done, req); return EAGAIN; } } return EOK; } static void ipa_server_create_trusts_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); ret = ipa_server_trusted_dom_setup_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = ipa_server_create_trusts_ctx(req); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = ipa_server_create_trusts_step(req); if (ret == EOK) { tevent_req_done(req); return; } else if (ret != EAGAIN) { tevent_req_error(req, ret); return; } /* Will cycle back */ } static errno_t ipa_server_create_trusts_ctx(struct tevent_req *req) { struct ipa_ad_server_ctx *trust_ctx; struct ad_id_ctx *ad_id_ctx; errno_t ret; struct ipa_server_create_trusts_state *state = NULL; state = tevent_req_data(req, struct ipa_server_create_trusts_state); ret = ipa_ad_ctx_new(state->be_ctx, state->id_ctx, state->domiter, &ad_id_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot create ad_id_ctx for subdomain %s\n", state->domiter->name); return ret; } trust_ctx = talloc(state->id_ctx->server_mode, struct ipa_ad_server_ctx); if (trust_ctx == NULL) { return ENOMEM; } trust_ctx->dom = state->domiter; trust_ctx->ad_id_ctx = ad_id_ctx; DLIST_ADD(state->id_ctx->server_mode->trusts, trust_ctx); return EOK; } errno_t ipa_server_create_trusts_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } void ipa_ad_subdom_remove(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct sss_domain_info *subdom) { struct ipa_ad_server_ctx *iter; struct sdap_domain *sdom; if (dp_opt_get_bool(id_ctx->ipa_options->basic, IPA_SERVER_MODE) == false) { return; } DLIST_FOR_EACH(iter, id_ctx->server_mode->trusts) { if (iter->dom == subdom) break; } if (iter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No IPA-AD context for subdomain %s\n", subdom->name); return; } sdom = sdap_domain_get(iter->ad_id_ctx->sdap_id_ctx->opts, subdom); if (sdom == NULL) return; be_ptask_destroy(&sdom->enum_task); be_ptask_destroy(&sdom->cleanup_task); sdap_domain_remove(iter->ad_id_ctx->sdap_id_ctx->opts, subdom); DLIST_REMOVE(id_ctx->server_mode->trusts, iter); /* terminate all requests for this subdomain so we can free it */ be_terminate_domain_requests(be_ctx, subdom->name); talloc_zfree(sdom); } struct ipa_ad_subdom_reinit_state { struct tevent_context *ev; struct be_ctx *be_ctx; struct ipa_id_ctx *id_ctx; struct sss_domain_info *parent; }; static void create_trusts_at_startup_done(struct tevent_req *req) { errno_t ret; ret = ipa_server_create_trusts_recv(req); talloc_free(req); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "ipa_server_create_trusts_send request failed [%d]: %s\n", ret, sss_strerror(ret)); } } static void create_trusts_at_startup(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt) { struct tevent_req *req; struct ipa_ad_subdom_reinit_state *state; state = talloc_get_type(pvt, struct ipa_ad_subdom_reinit_state); req = ipa_server_create_trusts_send(state, state->ev, state->be_ctx, state->id_ctx, state->parent); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_server_create_trusts_send failed.\n"); talloc_free(state); return; } tevent_req_set_callback(req, create_trusts_at_startup_done, state); return; } static errno_t ipa_ad_subdom_reinit(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct sss_domain_info *parent) { struct tevent_immediate *imm; struct ipa_ad_subdom_reinit_state *state; state = talloc(mem_ctx, struct ipa_ad_subdom_reinit_state); if (state == NULL) { return ENOMEM; } state->ev = ev; state->be_ctx = be_ctx; state->id_ctx = id_ctx; state->parent = parent; if (dp_opt_get_bool(id_ctx->ipa_options->basic, IPA_SERVER_MODE) == false) { return EOK; } imm = tevent_create_immediate(mem_ctx); if (imm == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_create_immediate failed.\n"); talloc_free(state); return ENOMEM; } tevent_schedule_immediate(imm, ev, create_trusts_at_startup, state); return EOK; } int ipa_ad_subdom_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx) { char *realm; char *hostname; errno_t ret; if (dp_opt_get_bool(id_ctx->ipa_options->basic, IPA_SERVER_MODE) == false) { return EOK; } /* The IPA code relies on the default FQDN format to unparse user * names. Warn loudly if the full_name_format was customized on the * IPA server */ if ((strcmp(be_ctx->domain->names->fq_fmt, CONFDB_DEFAULT_FULL_NAME_FORMAT) != 0) && (strcmp(be_ctx->domain->names->fq_fmt, CONFDB_DEFAULT_FULL_NAME_FORMAT_INTERNAL) != 0)) { DEBUG(SSSDBG_FATAL_FAILURE, "%s is set to a non-default value [%s] " \ "lookups of subdomain users will likely fail!\n", CONFDB_FULL_NAME_FORMAT, be_ctx->domain->names->fq_fmt); sss_log(SSS_LOG_ERR, "%s is set to a non-default value [%s] " \ "lookups of subdomain users will likely fail!\n", CONFDB_FULL_NAME_FORMAT, be_ctx->domain->names->fq_fmt); /* Attempt to continue */ } realm = dp_opt_get_string(id_ctx->ipa_options->basic, IPA_KRB5_REALM); if (realm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n"); return EINVAL; } hostname = dp_opt_get_string(id_ctx->ipa_options->basic, IPA_HOSTNAME); if (hostname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No host name for IPA?\n"); return EINVAL; } id_ctx->server_mode = talloc_zero(id_ctx, struct ipa_server_mode_ctx); if (id_ctx->server_mode == NULL) { return ENOMEM; } id_ctx->server_mode->realm = realm; id_ctx->server_mode->hostname = hostname; id_ctx->server_mode->trusts = NULL; id_ctx->server_mode->ext_groups = NULL; id_ctx->server_mode->kt_owner_uid = 0; id_ctx->server_mode->kt_owner_gid = 0; if (getuid() == 0) { /* We need to handle keytabs created by IPA oddjob script gracefully * even if we're running as root and IPA creates them as the SSSD user */ ret = sss_user_by_name_or_uid(SSSD_USER, &id_ctx->server_mode->kt_owner_uid, &id_ctx->server_mode->kt_owner_gid); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get ID of %s\n", SSSD_USER); } } ret = ipa_ad_subdom_reinit(be_ctx, be_ctx->ev, be_ctx, id_ctx, be_ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_ad_subdom_refresh failed.\n"); return ret; } return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_selinux_maps.h0000644000000000000000000000007412703456111021413 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.569793341 sssd-1.13.4/src/providers/ipa/ipa_selinux_maps.h0000644002412700241270000000301312703456111023057 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- SELinux user maps (maps retrieval) Authors: Jan Zeleny Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IPA_SELINUX_MAPS_H_ #define IPA_SELINUX_MAPS_H_ #include "providers/ldap/sdap_async.h" struct tevent_req * ipa_selinux_get_maps_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sysdb_ctx *sysdb, struct sdap_handle *sh, struct sdap_options *opts, struct ipa_options *ipa_opts, struct sdap_search_base **search_bases); errno_t ipa_selinux_get_maps_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *count, struct sysdb_attrs ***maps); #endif /* IPA_SELINUX_MAPS_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_autofs.c0000644000000000000000000000007312703456111020177 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.751793958 sssd-1.13.4/src/providers/ipa/ipa_autofs.c0000644002412700241270000000345312703456111021654 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Provider Initialization functions Authors: Simo Sorce Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/child_common.h" #include "providers/ipa/ipa_common.h" #include "providers/krb5/krb5_auth.h" #include "providers/ipa/ipa_id.h" #include "providers/ipa/ipa_auth.h" #include "providers/ipa/ipa_access.h" #include "providers/ipa/ipa_dyndns.h" #include "providers/ipa/ipa_selinux.h" struct bet_ops ipa_autofs_ops = { .handler = sdap_autofs_handler, .finalize = NULL, .check_online = sdap_check_online }; int ipa_autofs_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data) { int ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing autofs LDAP back end\n"); *ops = &ipa_autofs_ops; *pvt_data = id_ctx->sdap_id_ctx; ret = ipa_get_autofs_options(id_ctx->ipa_options, be_ctx->cdb, be_ctx->conf_path, &id_ctx->sdap_id_ctx->opts); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get IPA autofs options\n"); return ret; } return ret; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_subdomains.c0000644000000000000000000000007312703456111021042 xustar0030 atime=1460561751.646715613 29 ctime=1460561774.73179389 sssd-1.13.4/src/providers/ipa/ipa_subdomains.c0000644002412700241270000013760612703456111022527 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Subdomains Module Authors: Sumit Bose Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ipa/ipa_subdomains.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_id.h" #include #define SUBDOMAINS_FILTER "objectclass=ipaNTTrustedDomain" #define MASTER_DOMAIN_FILTER "objectclass=ipaNTDomainAttrs" #define RANGE_FILTER "objectclass=ipaIDRange" #define IPA_CN "cn" #define IPA_FLATNAME "ipaNTFlatName" #define IPA_SID "ipaNTSecurityIdentifier" #define IPA_TRUSTED_DOMAIN_SID "ipaNTTrustedDomainSID" #define IPA_RANGE_TYPE "ipaRangeType" #define IPA_BASE_ID "ipaBaseID" #define IPA_ID_RANGE_SIZE "ipaIDRangeSize" #define IPA_BASE_RID "ipaBaseRID" #define IPA_SECONDARY_BASE_RID "ipaSecondaryBaseRID" #define OBJECTCLASS "objectClass" #define IPA_ASSIGNED_ID_VIEW "ipaAssignedIDView" /* do not refresh more often than every 5 seconds for now */ #define IPA_SUBDOMAIN_REFRESH_LIMIT 5 #define IPA_SUBDOMAIN_DISABLED_PERIOD 3600 enum ipa_subdomains_req_type { IPA_SUBDOMAINS_MASTER, IPA_SUBDOMAINS_SLAVE, IPA_SUBDOMAINS_RANGES, IPA_SUBDOMAINS_MAX /* Counter */ }; struct ipa_subdomains_req_params { const char *filter; tevent_req_fn cb; const char *attrs[9]; }; struct ipa_subdomains_ctx { struct be_ctx *be_ctx; struct ipa_id_ctx *id_ctx; struct sdap_id_ctx *sdap_id_ctx; struct sdap_search_base **search_bases; struct sdap_search_base **master_search_bases; struct sdap_search_base **ranges_search_bases; struct sdap_search_base **host_search_bases; time_t last_refreshed; struct tevent_timer *timer_event; bool configured_explicit; time_t disabled_until; bool view_read_at_init; }; static void ipa_subdomains_done(struct ipa_subdomains_ctx *sd_ctx, struct be_req *req, int dp_err, int error, const char *errstr) { sd_ctx->view_read_at_init = true; return be_req_terminate(req, dp_err, error, errstr); } struct be_ctx *ipa_get_subdomains_be_ctx(struct be_ctx *be_ctx) { struct ipa_subdomains_ctx *subdom_ctx; subdom_ctx = talloc_get_type(be_ctx->bet_info[BET_SUBDOMAINS].pvt_bet_data, struct ipa_subdomains_ctx); if (subdom_ctx == NULL) { DEBUG(SSSDBG_TRACE_ALL, "Subdomains are not configured.\n"); return NULL; } return subdom_ctx->be_ctx; } static errno_t ipa_subdom_reinit(struct ipa_subdomains_ctx *ctx) { errno_t ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Re-initializing domain %s\n", ctx->be_ctx->domain->name); ret = sss_write_krb5_conf_snippet( dp_opt_get_string(ctx->id_ctx->ipa_options->basic, IPA_KRB5_CONFD_PATH)); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_write_krb5_conf_snippet failed.\n"); /* Just continue */ } ret = sysdb_master_domain_update(ctx->be_ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_master_domain_update failed.\n"); return ret; } ret = sysdb_update_subdomains(ctx->be_ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_subdomains failed.\n"); return ret; } ret = sss_write_domain_mappings(ctx->be_ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_krb5_write_mappings failed.\n"); /* Just continue */ } return EOK; } static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx, char *domain_name, size_t count, struct sysdb_attrs **reply, struct range_info ***_range_list) { struct range_info **range_list = NULL; struct range_info *r; const char *value; size_t c; size_t d; int ret; enum idmap_error_code err; char *name1; char *name2; char *sid1; char *sid2; uint32_t rid1; uint32_t rid2; struct sss_idmap_range range1; struct sss_idmap_range range2; bool mapping1; bool mapping2; range_list = talloc_array(mem_ctx, struct range_info *, count + 1); if (range_list == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); return ENOMEM; } for (c = 0; c < count; c++) { r = talloc_zero(range_list, struct range_info); if (r == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_get_string(reply[c], IPA_CN, &value); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } r->name = talloc_strdup(r, value); if (r->name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_get_string(reply[c], IPA_TRUSTED_DOMAIN_SID, &value); if (ret == EOK) { r->trusted_dom_sid = talloc_strdup(r, value); if (r->trusted_dom_sid == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } else if (ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } ret = sysdb_attrs_get_uint32_t(reply[c], IPA_BASE_ID, &r->base_id); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } ret = sysdb_attrs_get_uint32_t(reply[c], IPA_ID_RANGE_SIZE, &r->id_range_size); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } ret = sysdb_attrs_get_uint32_t(reply[c], IPA_BASE_RID, &r->base_rid); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } ret = sysdb_attrs_get_uint32_t(reply[c], IPA_SECONDARY_BASE_RID, &r->secondary_base_rid); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } ret = sysdb_attrs_get_string(reply[c], IPA_RANGE_TYPE, &value); if (ret == EOK) { r->range_type = talloc_strdup(r, value); if (r->range_type == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } else if (ret == ENOENT) { /* Older IPA servers might not have the range_type attribute, but * only support local ranges and trusts with algorithmic mapping. */ if (r->trusted_dom_sid == NULL) { r->range_type = talloc_strdup(r, IPA_RANGE_LOCAL); } else { r->range_type = talloc_strdup(r, IPA_RANGE_AD_TRUST); } } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } if (r->range_type == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } ret = get_idmap_data_from_range(r, domain_name, &name1, &sid1, &rid1, &range1, &mapping1); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_idmap_data_from_range failed.\n"); goto done; } for (d = 0; d < c; d++) { ret = get_idmap_data_from_range(range_list[d], domain_name, &name2, &sid2, &rid2, &range2, &mapping2); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_idmap_data_from_range failed.\n"); goto done; } err = sss_idmap_check_collision_ex(name1, sid1, &range1, rid1, r->name, mapping1, name2, sid2, &range2, rid2, range_list[d]->name, mapping2); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Collision of ranges [%s] and [%s] detected.\n", r->name, range_list[d]->name); ret = EINVAL; goto done; } } range_list[c] = r; } range_list[c] = NULL; *_range_list = range_list; ret = EOK; done: if (ret != EOK) { talloc_free(range_list); } return ret; } static errno_t ipa_subdom_enumerates(struct sss_domain_info *parent, struct sysdb_attrs *attrs, bool *_enumerates) { errno_t ret; const char *name; ret = sysdb_attrs_get_string(attrs, IPA_CN, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); return ret; } *_enumerates = subdomain_enumerates(parent, name); return EOK; } static errno_t ipa_subdom_get_forest(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct sysdb_attrs *attrs, char **_forest) { int ret; struct ldb_dn *dn = NULL; const char *name; const struct ldb_val *val; char *forest = NULL; dn = ipa_subdom_ldb_dn(mem_ctx, ldb_ctx, attrs); if (dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_subdom_ldb_dn failed.\n"); ret = EIO; goto done; } if (ipa_subdom_is_member_dom(dn) == false) { ret = sysdb_attrs_get_string(attrs, IPA_CN, &name); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } forest = talloc_strdup(mem_ctx, name); if (forest == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "The forest name is %s\n", forest); ret = EOK; goto done; } val = ldb_dn_get_component_val(dn, 1); forest = talloc_strndup(mem_ctx, (const char *) val->data, val->length); if (forest == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); ret = ENOMEM; goto done; } ret = EOK; done: talloc_free(dn); if (ret == EOK) { *_forest = forest; } return ret; } static errno_t ipa_get_sd_trust_direction(struct sysdb_attrs *sd, struct ipa_id_ctx *id_ctx, struct ldb_context *ldb_ctx, uint32_t *_direction) { if (id_ctx->server_mode != NULL) { return ipa_server_get_trust_direction(sd, ldb_ctx, _direction); } else { /* Clients do not have access to the trust objects's trust direction * and don't generally care */ *_direction = 0; return EOK; } } static errno_t ipa_subdom_store(struct sss_domain_info *parent, struct ipa_id_ctx *id_ctx, struct sdap_idmap_ctx *sdap_idmap_ctx, struct sysdb_attrs *attrs) { TALLOC_CTX *tmp_ctx; const char *name; char *realm; const char *flat; const char *id; char *forest = NULL; int ret; bool mpg; bool enumerate; uint32_t direction; tmp_ctx = talloc_new(parent); if (tmp_ctx == NULL) { return ENOMEM; } ret = sysdb_attrs_get_string(attrs, IPA_CN, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } realm = get_uppercase_realm(tmp_ctx, name); if (!realm) { ret = ENOMEM; goto done; } ret = sysdb_attrs_get_string(attrs, IPA_FLATNAME, &flat); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } ret = sysdb_attrs_get_string(attrs, IPA_TRUSTED_DOMAIN_SID, &id); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } mpg = sdap_idmap_domain_has_algorithmic_mapping(sdap_idmap_ctx, name, id); ret = ipa_subdom_get_forest(tmp_ctx, sysdb_ctx_get_ldb(parent->sysdb), attrs, &forest); if (ret != EOK) { goto done; } ret = ipa_subdom_enumerates(parent, attrs, &enumerate); if (ret != EOK) { goto done; } ret = ipa_get_sd_trust_direction(attrs, id_ctx, sysdb_ctx_get_ldb(parent->sysdb), &direction); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_sd_trust_direction failed: %d\n", ret); goto done; } DEBUG(SSSDBG_FUNC_DATA, "Trust direction of %s is %s\n", name, ipa_trust_dir2str(direction)); ret = sysdb_subdomain_store(parent->sysdb, name, realm, flat, id, mpg, enumerate, forest, direction); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_subdomain_store failed.\n"); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static void ipa_subdom_store_step(struct sss_domain_info *parent, struct ipa_id_ctx *id_ctx, struct sdap_idmap_ctx *sdap_idmap_ctx, struct sysdb_attrs *attrs) { int ret; ret = ipa_subdom_store(parent, id_ctx, sdap_idmap_ctx, attrs); if (ret == ERR_TRUST_NOT_SUPPORTED) { DEBUG(SSSDBG_MINOR_FAILURE, "Unsupported trust type, skipping\n"); } else if (ret) { /* Nothing we can do about the error. */ DEBUG(SSSDBG_MINOR_FAILURE, "Failed to parse subdom data, " "will try to use cached subdomain\n"); } } static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx, int count, struct sysdb_attrs **reply, bool *changes) { struct sss_domain_info *parent, *dom; bool handled[count]; const char *value; int c, h; int ret; parent = ctx->be_ctx->domain; memset(handled, 0, sizeof(bool) * count); h = 0; /* check existing subdomains */ for (dom = get_next_domain(parent, SSS_GND_DESCEND); dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */ dom = get_next_domain(dom, 0)) { for (c = 0; c < count; c++) { if (handled[c]) { continue; } ret = sysdb_attrs_get_string(reply[c], IPA_CN, &value); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } if (strcmp(value, dom->name) == 0) { break; } } if (c >= count) { /* ok this subdomain does not exist anymore, let's clean up */ sss_domain_set_state(dom, DOM_DISABLED); ret = sysdb_subdomain_delete(dom->sysdb, dom->name); if (ret != EOK) { goto done; } /* Remove the AD ID ctx from the list of LDAP domains */ ipa_ad_subdom_remove(ctx->be_ctx, ctx->id_ctx, dom); } else { /* ok let's try to update it */ ipa_subdom_store_step(parent, ctx->id_ctx, ctx->sdap_id_ctx->opts->idmap_ctx, reply[c]); handled[c] = true; h++; } } if (count == h) { /* all domains were already accounted for and have been updated */ ret = EOK; goto done; } /* if we get here it means we have changes to the subdomains list */ *changes = true; for (c = 0; c < count; c++) { if (handled[c]) { continue; } ipa_subdom_store_step(parent, ctx->id_ctx, ctx->sdap_id_ctx->opts->idmap_ctx, reply[c]); } ret = EOK; done: if (ret != EOK) { ctx->last_refreshed = 0; } else { ctx->last_refreshed = time(NULL); } return ret; } struct ipa_subdomains_req_ctx { struct be_req *be_req; struct ipa_subdomains_ctx *sd_ctx; struct sdap_id_op *sdap_op; char *current_filter; struct sdap_search_base **search_bases; int search_base_iter; size_t reply_count; struct sysdb_attrs **reply; }; static void ipa_subdomains_get_conn_done(struct tevent_req *req); static errno_t ipa_subdomains_handler_get_start(struct ipa_subdomains_req_ctx *ctx, struct sdap_search_base **search_bases, enum ipa_subdomains_req_type type); static errno_t ipa_subdomains_handler_get_cont(struct ipa_subdomains_req_ctx *ctx, enum ipa_subdomains_req_type type); static void ipa_subdomains_handler_done(struct tevent_req *req); static void ipa_subdomains_handler_master_done(struct tevent_req *req); static void ipa_subdomains_handler_ranges_done(struct tevent_req *req); static struct ipa_subdomains_req_params subdomain_requests[] = { { MASTER_DOMAIN_FILTER, ipa_subdomains_handler_master_done, { IPA_CN, IPA_FLATNAME, IPA_SID, NULL } }, { SUBDOMAINS_FILTER, ipa_subdomains_handler_done, { IPA_CN, IPA_FLATNAME, IPA_TRUSTED_DOMAIN_SID, IPA_TRUST_DIRECTION, NULL } }, { RANGE_FILTER, ipa_subdomains_handler_ranges_done, { OBJECTCLASS, IPA_CN, IPA_BASE_ID, IPA_BASE_RID, IPA_SECONDARY_BASE_RID, IPA_ID_RANGE_SIZE, IPA_TRUSTED_DOMAIN_SID, IPA_RANGE_TYPE, NULL } } }; static void ipa_subdomains_retrieve(struct ipa_subdomains_ctx *ctx, struct be_req *be_req) { struct ipa_subdomains_req_ctx *req_ctx = NULL; struct tevent_req *req; int dp_error = DP_ERR_FATAL; int ret; req_ctx = talloc(be_req, struct ipa_subdomains_req_ctx); if (req_ctx == NULL) { ret = ENOMEM; goto done; } req_ctx->be_req = be_req; req_ctx->sd_ctx = ctx; req_ctx->search_base_iter = 0; req_ctx->search_bases = ctx->ranges_search_bases; req_ctx->current_filter = NULL; req_ctx->reply_count = 0; req_ctx->reply = NULL; req_ctx->sdap_op = sdap_id_op_create(req_ctx, ctx->sdap_id_ctx->conn->conn_cache); if (req_ctx->sdap_op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n"); ret = ENOMEM; goto done; } req = sdap_id_op_connect_send(req_ctx->sdap_op, req_ctx, &ret); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n", ret, strerror(ret)); goto done; } tevent_req_set_callback(req, ipa_subdomains_get_conn_done, req_ctx); return; done: talloc_free(req_ctx); if (ret == EOK) { dp_error = DP_ERR_OK; } ipa_subdomains_done(ctx, be_req, dp_error, ret, NULL); } static void ipa_subdomains_get_conn_done(struct tevent_req *req) { int ret; int dp_error = DP_ERR_FATAL; struct ipa_subdomains_req_ctx *ctx; ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx); ret = sdap_id_op_connect_recv(req, &dp_error); talloc_zfree(req); if (ret) { if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_MINOR_FAILURE, "No IPA server is available, cannot get the " "subdomain list while offline\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to IPA server: [%d](%s)\n", ret, strerror(ret)); } goto fail; } ret = ipa_subdomains_handler_get_start(ctx, ctx->sd_ctx->ranges_search_bases, IPA_SUBDOMAINS_RANGES); if (ret != EOK && ret != EAGAIN) { goto fail; } return; fail: ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL); } static errno_t ipa_subdomains_handler_get(struct ipa_subdomains_req_ctx *ctx, enum ipa_subdomains_req_type type) { struct tevent_req *req; struct sdap_search_base *base; struct ipa_subdomains_req_params *params; if (type >= IPA_SUBDOMAINS_MAX) { return EINVAL; } params = &subdomain_requests[type]; base = ctx->search_bases[ctx->search_base_iter]; if (base == NULL) { return EOK; } talloc_free(ctx->current_filter); ctx->current_filter = sdap_combine_filters(ctx, params->filter, base->filter); if (ctx->current_filter == NULL) { return ENOMEM; } req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev, ctx->sd_ctx->sdap_id_ctx->opts, sdap_id_op_handle(ctx->sdap_op), base->basedn, base->scope, ctx->current_filter, params->attrs, NULL, 0, dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); return ENOMEM; } tevent_req_set_callback(req, params->cb, ctx); return EAGAIN; } static errno_t ipa_subdomains_handler_get_start(struct ipa_subdomains_req_ctx *ctx, struct sdap_search_base **search_bases, enum ipa_subdomains_req_type type) { ctx->search_base_iter = 0; ctx->search_bases = search_bases; return ipa_subdomains_handler_get(ctx, type); } static errno_t ipa_subdomains_handler_get_cont(struct ipa_subdomains_req_ctx *ctx, enum ipa_subdomains_req_type type) { ctx->search_base_iter++; return ipa_subdomains_handler_get(ctx, type); } static void ipa_get_view_name_done(struct tevent_req *req); static void ipa_server_create_trusts_done(struct tevent_req *trust_req); static errno_t ipa_check_master(struct ipa_subdomains_req_ctx *ctx); static errno_t ipa_get_view_name(struct ipa_subdomains_req_ctx *ctx) { struct tevent_req *req; struct sdap_search_base *base; const char *attrs[] = {IPA_CN, OBJECTCLASS, NULL}; struct sdap_attr_map_info *maps; maps = talloc_zero(ctx, struct sdap_attr_map_info); if (maps == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } maps->map = ctx->sd_ctx->id_ctx->ipa_options->view_map; maps->num_attrs = IPA_OPTS_VIEW; base = ctx->search_bases[ctx->search_base_iter]; if (base == NULL) { return EOK; } /* We add SDAP_DEREF_FLG_SILENT because old IPA servers don't have * the attribute we dereference, causing the deref call to fail */ req = sdap_deref_search_with_filter_send(ctx, ctx->sd_ctx->be_ctx->ev, ctx->sd_ctx->sdap_id_ctx->opts, sdap_id_op_handle(ctx->sdap_op), base->basedn, ctx->current_filter, IPA_ASSIGNED_ID_VIEW, attrs, 1, maps, dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic, SDAP_SEARCH_TIMEOUT), SDAP_DEREF_FLG_SILENT); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); return ENOMEM; } tevent_req_set_callback(req, ipa_get_view_name_done, ctx); return EAGAIN; } static void ipa_get_view_name_done(struct tevent_req *req) { int ret; int sret; struct ipa_subdomains_req_ctx *ctx; size_t reply_count; struct sdap_deref_attrs **reply = NULL; const char *view_name; int dp_error = DP_ERR_FATAL; ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx); ret = sdap_deref_search_with_filter_recv(req, ctx, &reply_count, &reply); talloc_zfree(req); if (ret != EOK) { /* Depending on the version 389ds return a different error code if the * search for the view name failed because our dereference attribute * ipaAssignedIDView is not known. Newer version return * LDAP_UNAVAILABLE_CRITICAL_EXTENSION(12) which is translated to * EOPNOTSUPP and older versions return LDAP_PROTOCOL_ERROR(2) which * is returned as EIO. In both cases we have to assume that the server * is not view aware and keep the view name unset. */ if (ret == EOPNOTSUPP || ret == EIO) { DEBUG(SSSDBG_TRACE_FUNC, "get_view_name request failed, looks " \ "like server does not support views.\n"); ret = ipa_check_master(ctx); if (ret == EAGAIN) { return; } else if (ret != EOK) { goto done; } } else { DEBUG(SSSDBG_OP_FAILURE, "get_view_name request failed.\n"); } goto done; } if (reply_count == 0) { ctx->search_base_iter++; ret = ipa_get_view_name(ctx); if (ret == EAGAIN) { return; } else if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "No view found, using default.\n"); view_name = SYSDB_DEFAULT_VIEW_NAME; } else { goto done; } } else if (reply_count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "get_view_name request returned more than one object.\n"); ret = EINVAL; goto done; } else { ret = sysdb_attrs_get_string(reply[0]->attrs, SYSDB_VIEW_NAME, &view_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } } DEBUG(SSSDBG_TRACE_FUNC, "Found view name [%s].\n", view_name); if (is_default_view(view_name)) { DEBUG(SSSDBG_TRACE_ALL, "Found IPA default view name, replacing with sysdb default.\n"); view_name = SYSDB_DEFAULT_VIEW_NAME; } DEBUG(SSSDBG_TRACE_ALL, "read_at_init [%s] current view [%s].\n", ctx->sd_ctx->view_read_at_init ? "true" : "false", ctx->sd_ctx->id_ctx->view_name); if (ctx->sd_ctx->id_ctx->view_name != NULL && strcmp(ctx->sd_ctx->id_ctx->view_name, view_name) != 0 && ctx->sd_ctx->view_read_at_init) { DEBUG(SSSDBG_CRIT_FAILURE, "View name changed, this is not supported at runtime. " \ "Please restart SSSD to get the new view applied.\n"); } else { if (ctx->sd_ctx->id_ctx->view_name == NULL || strcmp(ctx->sd_ctx->id_ctx->view_name, view_name) != 0) { /* View name changed. If there was a non-default non-local view * was used the tree in cache containing the override values is * removed. In all cases sysdb_invalidate_overrides() is called to * remove the override attribute from the cached user objects. * * Typically ctx->sd_ctx->id_ctx->view_name == NULL means that the * cache was empty but there was a bug in with caused that the * view name was not written to the cache at all. In this case the * cache must be invalidated if the new view is not the * default-view as well. */ if (ctx->sd_ctx->id_ctx->view_name != NULL || !is_default_view(view_name)) { ret = sysdb_transaction_start( ctx->sd_ctx->be_ctx->domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_start failed.\n"); goto done; } if (!is_default_view(ctx->sd_ctx->id_ctx->view_name) && !is_local_view(ctx->sd_ctx->id_ctx->view_name)) { /* Old view was not the default view, delete view tree */ ret = sysdb_delete_view_tree( ctx->sd_ctx->be_ctx->domain->sysdb, ctx->sd_ctx->id_ctx->view_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_delete_view_tree failed.\n"); sret = sysdb_transaction_cancel( ctx->sd_ctx->be_ctx->domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_cancel failed.\n"); goto done; } goto done; } } ret = sysdb_invalidate_overrides( ctx->sd_ctx->be_ctx->domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_invalidate_overrides failed.\n"); sret = sysdb_transaction_cancel( ctx->sd_ctx->be_ctx->domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_cancel failed.\n"); goto done; } goto done; } ret = sysdb_transaction_commit( ctx->sd_ctx->be_ctx->domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_commit failed.\n"); goto done; } /* TODO: start referesh task */ } ret = sysdb_update_view_name(ctx->sd_ctx->be_ctx->domain->sysdb, view_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add/update view name to sysdb.\n"); } else { talloc_free(ctx->sd_ctx->id_ctx->view_name); ctx->sd_ctx->id_ctx->view_name = talloc_strdup( ctx->sd_ctx->id_ctx, view_name); if (ctx->sd_ctx->id_ctx->view_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot copy view name.\n"); } } } if (!ctx->sd_ctx->view_read_at_init) { /* refresh view data of all domains at startup */ ret = sysdb_master_domain_update(ctx->sd_ctx->be_ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_master_domain_update failed.\n"); goto done; } ret = sysdb_update_subdomains(ctx->sd_ctx->be_ctx->domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_subdomains failed.\n"); goto done; } } ctx->sd_ctx->view_read_at_init = true; } ret = EOK; done: if (ret == EOK) { dp_error = DP_ERR_OK; } ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL); } static void ipa_subdomains_handler_done(struct tevent_req *req) { int ret; size_t reply_count; struct sysdb_attrs **reply = NULL; struct ipa_subdomains_req_ctx *ctx; struct sss_domain_info *domain; bool refresh_has_changes = false; int dp_error = DP_ERR_FATAL; struct tevent_req *trust_req; ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx); domain = ctx->sd_ctx->be_ctx->domain; ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send request failed.\n"); goto done; } if (reply_count) { ctx->reply = talloc_realloc(ctx, ctx->reply, struct sysdb_attrs *, ctx->reply_count + reply_count); if (ctx->reply == NULL) { ret = ENOMEM; goto done; } memcpy(ctx->reply+ctx->reply_count, reply, reply_count * sizeof(struct sysdb_attrs *)); ctx->reply_count += reply_count; } ret = ipa_subdomains_handler_get_cont(ctx, IPA_SUBDOMAINS_SLAVE); if (ret == EAGAIN) { return; } else if (ret != EOK) { goto done; } ret = ipa_subdomains_refresh(ctx->sd_ctx, ctx->reply_count, ctx->reply, &refresh_has_changes); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to refresh subdomains.\n"); goto done; } if (refresh_has_changes) { ret = ipa_subdom_reinit(ctx->sd_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not reinitialize subdomains\n"); goto done; } if (ctx->sd_ctx->id_ctx->server_mode != NULL) { trust_req = ipa_server_create_trusts_send(ctx, ctx->sd_ctx->be_ctx->ev, ctx->sd_ctx->be_ctx, ctx->sd_ctx->id_ctx, domain); if (trust_req == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(trust_req, ipa_server_create_trusts_done, ctx); return; } } ctx->search_base_iter = 0; ctx->search_bases = ctx->sd_ctx->host_search_bases; talloc_zfree(ctx->current_filter); ctx->current_filter = talloc_asprintf(ctx, "(&(objectClass=%s)(%s=%s))", ctx->sd_ctx->id_ctx->ipa_options->host_map[IPA_OC_HOST].name, ctx->sd_ctx->id_ctx->ipa_options->host_map[IPA_AT_HOST_FQDN].name, dp_opt_get_string(ctx->sd_ctx->id_ctx->ipa_options->basic, IPA_HOSTNAME)); if (ctx->current_filter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } if (ctx->sd_ctx->id_ctx->server_mode == NULL) { /* Only get view on clients, on servers it is always 'default' */ ret = ipa_get_view_name(ctx); if (ret == EAGAIN) { return; } else if (ret != EOK) { goto done; } } ret = EOK; done: if (ret == EOK) { dp_error = DP_ERR_OK; } ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL); } static void ipa_server_create_trusts_done(struct tevent_req *trust_req) { errno_t ret; int dp_error = DP_ERR_FATAL; struct ipa_subdomains_req_ctx *ctx; ctx = tevent_req_callback_data(trust_req, struct ipa_subdomains_req_ctx); ret = ipa_server_create_trusts_recv(trust_req); talloc_zfree(trust_req); if (ret == EOK) { dp_error = DP_ERR_OK; } ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL); } static errno_t ipa_check_master(struct ipa_subdomains_req_ctx *ctx) { int ret; struct sss_domain_info *domain; domain = ctx->sd_ctx->be_ctx->domain; ret = sysdb_master_domain_update(domain); if (ret != EOK) { return ret; } if (domain->flat_name == NULL || domain->domain_id == NULL || domain->realm == NULL) { ret = ipa_subdomains_handler_get_start(ctx, ctx->sd_ctx->master_search_bases, IPA_SUBDOMAINS_MASTER); if (ret == EAGAIN) { return EAGAIN; } else if (ret != EOK) { return ret; } } return EOK; } static void ipa_subdomains_handler_ranges_done(struct tevent_req *req) { errno_t ret; int dp_error = DP_ERR_FATAL; size_t reply_count; struct sysdb_attrs **reply = NULL; struct ipa_subdomains_req_ctx *ctx; struct range_info **range_list = NULL; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx); domain = ctx->sd_ctx->be_ctx->domain; sysdb = domain->sysdb; ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send request failed.\n"); goto done; } ret = ipa_ranges_parse_results(ctx, domain->name, reply_count, reply, &range_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_ranges_parse_results request failed.\n"); goto done; } ret = sysdb_update_ranges(sysdb, range_list); talloc_free(range_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_ranges failed.\n"); goto done; } ret = ipa_check_master(ctx); if (ret == EAGAIN) { DEBUG(SSSDBG_TRACE_ALL, "Checking master record..\n"); return; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_check_master failed.\n"); goto done; } /* Master domain is up-to-date. Continue checking subdomains */ DEBUG(SSSDBG_TRACE_ALL, "Master record up2date, checking subdomains\n"); ret = ipa_subdomains_handler_get_start(ctx, ctx->sd_ctx->search_bases, IPA_SUBDOMAINS_SLAVE); if (ret == EAGAIN) { return; } else if (ret != EOK) { goto done; } DEBUG(SSSDBG_OP_FAILURE, "No search base for ranges available.\n"); ret = EINVAL; done: if (ret == EOK) { dp_error = DP_ERR_OK; } ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL); } static void ipa_subdomains_handler_master_done(struct tevent_req *req) { errno_t ret; int dp_error = DP_ERR_FATAL; size_t reply_count = 0; struct sysdb_attrs **reply = NULL; struct ipa_subdomains_req_ctx *ctx; const char *flat = NULL; const char *id = NULL; const char *realm = NULL; ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx); ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send request failed.\n"); goto done; } if (reply_count) { ret = sysdb_attrs_get_string(reply[0], IPA_FLATNAME, &flat); if (ret != EOK) { goto done; } ret = sysdb_attrs_get_string(reply[0], IPA_SID, &id); if (ret != EOK) { goto done; } /* There is only one master record. Don't bother checking other IPA * search bases; move to checking subdomains instead */ } else { ret = ipa_subdomains_handler_get_cont(ctx, IPA_SUBDOMAINS_MASTER); if (ret == EAGAIN) { return; } else if (ret != EOK) { goto done; } /* All search paths are searched and no master domain record was * found. * * A default IPA installation will not have a master domain record, * this is only created by ipa-adtrust-install. Nevertheless we should * continue to read other data like the idview on IPA clients. */ DEBUG(SSSDBG_TRACE_INTERNAL, "Master domain record not found!\n"); } realm = dp_opt_get_string(ctx->sd_ctx->id_ctx->ipa_options->basic, IPA_KRB5_REALM); if (realm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n"); ret = EINVAL; goto done; } ret = sysdb_master_domain_add_info(ctx->sd_ctx->be_ctx->domain, realm, flat, id, NULL); if (ret != EOK) { goto done; } ret = ipa_subdomains_handler_get_start(ctx, ctx->sd_ctx->search_bases, IPA_SUBDOMAINS_SLAVE); if (ret == EAGAIN) { return; } else if (ret == EOK) { /* If there are no search bases defined for subdomains try to get the * idview before ending the request */ if (ctx->sd_ctx->id_ctx->server_mode == NULL) { /* Only get view on clients, on servers it is always 'default' */ ret = ipa_get_view_name(ctx); if (ret == EAGAIN) { return; } else if (ret != EOK) { goto done; } } } done: if (ret == EOK) { dp_error = DP_ERR_OK; } ipa_subdomains_done(ctx->sd_ctx, ctx->be_req, dp_error, ret, NULL); } static void ipa_subdom_online_cb(void *pvt); static void ipa_subdom_timer_refresh(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { ipa_subdom_online_cb(pvt); } static void ipa_subdom_be_req_callback(struct be_req *be_req, int dp_err, int dp_ret, const char *errstr) { talloc_free(be_req); } static void ipa_subdom_reset_timeouts_cb(void *pvt) { struct ipa_subdomains_ctx *ctx; ctx = talloc_get_type(pvt, struct ipa_subdomains_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bad private pointer\n"); return; } DEBUG(SSSDBG_TRACE_ALL, "Resetting last_refreshed and disabled_until.\n"); ctx->last_refreshed = 0; ctx->disabled_until = 0; } static void ipa_subdom_online_cb(void *pvt) { struct ipa_subdomains_ctx *ctx; struct be_req *be_req; struct timeval tv; uint32_t refresh_interval; ctx = talloc_get_type(pvt, struct ipa_subdomains_ctx); if (!ctx) { DEBUG(SSSDBG_CRIT_FAILURE, "Bad private pointer\n"); return; } ctx->disabled_until = 0; refresh_interval = ctx->be_ctx->domain->subdomain_refresh_interval; be_req = be_req_create(ctx, NULL, ctx->be_ctx, ipa_subdom_be_req_callback, NULL); if (be_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "be_req_create() failed.\n"); return; } ipa_subdomains_retrieve(ctx, be_req); tv = tevent_timeval_current_ofs(refresh_interval, 0); ctx->timer_event = tevent_add_timer(ctx->be_ctx->ev, ctx, tv, ipa_subdom_timer_refresh, ctx); if (!ctx->timer_event) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add subdom timer event\n"); } } static void ipa_subdom_offline_cb(void *pvt) { struct ipa_subdomains_ctx *ctx; ctx = talloc_get_type(pvt, struct ipa_subdomains_ctx); if (ctx) { talloc_zfree(ctx->timer_event); } } static errno_t get_config_status(struct be_ctx *be_ctx, bool *configured_explicit) { int ret; TALLOC_CTX *tmp_ctx = NULL; char *tmp_str; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = confdb_get_string(be_ctx->cdb, tmp_ctx, be_ctx->conf_path, CONFDB_DOMAIN_SUBDOMAINS_PROVIDER, NULL, &tmp_str); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "confdb_get_string failed.\n"); goto done; } if (tmp_str == NULL) { *configured_explicit = false; } else { *configured_explicit = true; } DEBUG(SSSDBG_TRACE_ALL, "IPA subdomain provider is configured %s.\n", *configured_explicit ? "explicit" : "implicit"); ret = EOK; done: talloc_free(tmp_ctx); return ret; } void ipa_subdomains_handler(struct be_req *be_req) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct ipa_subdomains_ctx *ctx; time_t now; ctx = talloc_get_type(be_ctx->bet_info[BET_SUBDOMAINS].pvt_bet_data, struct ipa_subdomains_ctx); if (!ctx) { be_req_terminate(be_req, DP_ERR_FATAL, EINVAL, NULL); return; } now = time(NULL); if (ctx->disabled_until > now) { DEBUG(SSSDBG_TRACE_ALL, "Subdomain provider disabled.\n"); ipa_subdomains_done(ctx, be_req, DP_ERR_OK, EOK, NULL); return; } if (ctx->last_refreshed > now - IPA_SUBDOMAIN_REFRESH_LIMIT) { ipa_subdomains_done(ctx, be_req, DP_ERR_OK, EOK, NULL); return; } ipa_subdomains_retrieve(ctx, be_req); } struct bet_ops ipa_subdomains_ops = { .handler = ipa_subdomains_handler, .finalize = NULL }; int ipa_subdom_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data) { struct ipa_subdomains_ctx *ctx; int ret; bool configured_explicit = false; ret = get_config_status(be_ctx, &configured_explicit); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_config_status failed.\n"); return ret; } ctx = talloc_zero(id_ctx, struct ipa_subdomains_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ctx->be_ctx = be_ctx; ctx->id_ctx = id_ctx; ctx->sdap_id_ctx = id_ctx->sdap_id_ctx; ctx->search_bases = id_ctx->ipa_options->subdomains_search_bases; ctx->master_search_bases = id_ctx->ipa_options->master_domain_search_bases; ctx->ranges_search_bases = id_ctx->ipa_options->ranges_search_bases; ctx->host_search_bases = id_ctx->ipa_options->host_search_bases; ctx->configured_explicit = configured_explicit; ctx->disabled_until = 0; *ops = &ipa_subdomains_ops; *pvt_data = ctx; ret = be_add_unconditional_online_cb(ctx, be_ctx, ipa_subdom_reset_timeouts_cb, ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add subdom reset timeouts callback\n"); } ret = be_add_online_cb(ctx, be_ctx, ipa_subdom_online_cb, ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add subdom online callback\n"); } ret = be_add_offline_cb(ctx, be_ctx, ipa_subdom_offline_cb, ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add subdom offline callback\n"); } ret = ipa_subdom_reinit(ctx); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not load the list of subdomains. " "Users from trusted domains might not be resolved correctly\n"); } ret = ipa_ad_subdom_init(be_ctx, id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "ipa_ad_subdom_init failed.\n"); return ret; } return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hbac_rules.c0000644000000000000000000000007312703456111021005 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.741793924 sssd-1.13.4/src/providers/ipa/ipa_hbac_rules.c0000644002412700241270000002246012703456111022461 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "providers/ipa/ipa_hbac_private.h" #include "providers/ipa/ipa_hbac_rules.h" #include "providers/ldap/sdap_async.h" struct ipa_hbac_rule_state { struct tevent_context *ev; struct sdap_handle *sh; struct sdap_options *opts; int search_base_iter; struct sdap_search_base **search_bases; const char **attrs; char *rules_filter; char *cur_filter; size_t rule_count; struct sysdb_attrs **rules; }; static errno_t ipa_hbac_rule_info_next(struct tevent_req *req, struct ipa_hbac_rule_state *state); static void ipa_hbac_rule_info_done(struct tevent_req *subreq); struct tevent_req * ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, struct sdap_options *opts, struct sdap_search_base **search_bases, struct sysdb_attrs *ipa_host) { errno_t ret; size_t i; struct tevent_req *req = NULL; struct ipa_hbac_rule_state *state; TALLOC_CTX *tmp_ctx; const char *host_dn; char *host_dn_clean; char *host_group_clean; char *rule_filter; const char **memberof_list; if (ipa_host == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing host\n"); return NULL; } tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return NULL; ret = sysdb_attrs_get_string(ipa_host, SYSDB_ORIG_DN, &host_dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not identify IPA hostname\n"); goto error; } ret = sss_filter_sanitize(tmp_ctx, host_dn, &host_dn_clean); if (ret != EOK) goto error; req = tevent_req_create(mem_ctx, &state, struct ipa_hbac_rule_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->sh = sh; state->opts = opts; state->search_bases = search_bases; state->search_base_iter = 0; state->attrs = talloc_zero_array(state, const char *, 15); if (state->attrs == NULL) { ret = ENOMEM; goto immediate; } state->attrs[0] = OBJECTCLASS; state->attrs[1] = IPA_CN; state->attrs[2] = IPA_UNIQUE_ID; state->attrs[3] = IPA_ENABLED_FLAG; state->attrs[4] = IPA_ACCESS_RULE_TYPE; state->attrs[5] = IPA_MEMBER_USER; state->attrs[6] = IPA_USER_CATEGORY; state->attrs[7] = IPA_MEMBER_SERVICE; state->attrs[8] = IPA_SERVICE_CATEGORY; state->attrs[9] = IPA_SOURCE_HOST; state->attrs[10] = IPA_SOURCE_HOST_CATEGORY; state->attrs[11] = IPA_EXTERNAL_HOST; state->attrs[12] = IPA_MEMBER_HOST; state->attrs[13] = IPA_HOST_CATEGORY; state->attrs[14] = NULL; rule_filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)" "(%s=%s)(%s=%s)" "(|(%s=%s)(%s=%s)", IPA_HBAC_RULE, IPA_ENABLED_FLAG, IPA_TRUE_VALUE, IPA_ACCESS_RULE_TYPE, IPA_HBAC_ALLOW, IPA_HOST_CATEGORY, "all", IPA_MEMBER_HOST, host_dn_clean); if (rule_filter == NULL) { ret = ENOMEM; goto immediate; } /* Add all parent groups of ipa_hostname to the filter */ ret = sysdb_attrs_get_string_array(ipa_host, SYSDB_ORIG_MEMBEROF, tmp_ctx, &memberof_list); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not identify.\n"); } if (ret == ENOENT) { /* This host is not a member of any hostgroups */ memberof_list = talloc_array(tmp_ctx, const char *, 1); if (memberof_list == NULL) { ret = ENOMEM; goto immediate; } memberof_list[0] = NULL; } for (i = 0; memberof_list[i]; i++) { ret = sss_filter_sanitize(tmp_ctx, memberof_list[i], &host_group_clean); if (ret != EOK) goto immediate; rule_filter = talloc_asprintf_append(rule_filter, "(%s=%s)", IPA_MEMBER_HOST, host_group_clean); if (rule_filter == NULL) { ret = ENOMEM; goto immediate; } } rule_filter = talloc_asprintf_append(rule_filter, "))"); if (rule_filter == NULL) { ret = ENOMEM; goto immediate; } state->rules_filter = talloc_steal(state, rule_filter); ret = ipa_hbac_rule_info_next(req, state); if (ret == EOK) { ret = EINVAL; } if (ret != EAGAIN) { goto immediate; } talloc_free(tmp_ctx); return req; immediate: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); talloc_free(tmp_ctx); return req; error: talloc_free(tmp_ctx); return NULL; } static errno_t ipa_hbac_rule_info_next(struct tevent_req *req, struct ipa_hbac_rule_state *state) { struct tevent_req *subreq; struct sdap_search_base *base; base = state->search_bases[state->search_base_iter]; if (base == NULL) { return EOK; } talloc_zfree(state->cur_filter); state->cur_filter = sdap_combine_filters(state, state->rules_filter, base->filter); if (state->cur_filter == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Sending request for next search base: " "[%s][%d][%s]\n", base->basedn, base->scope, state->cur_filter); subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, base->basedn, base->scope, state->cur_filter, state->attrs, NULL, 0, dp_opt_get_int(state->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), true); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_get_generic_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, ipa_hbac_rule_info_done, req); return EAGAIN; } static void ipa_hbac_rule_info_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_hbac_rule_state *state = tevent_req_data(req, struct ipa_hbac_rule_state); int i; size_t rule_count; size_t total_count; struct sysdb_attrs **rules; struct sysdb_attrs **target; ret = sdap_get_generic_recv(subreq, state, &rule_count, &rules); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not retrieve HBAC rules\n"); goto fail; } if (rule_count > 0) { total_count = rule_count + state->rule_count; state->rules = talloc_realloc(state, state->rules, struct sysdb_attrs *, total_count); if (state->rules == NULL) { ret = ENOMEM; goto fail; } i = 0; while (state->rule_count < total_count) { target = &state->rules[state->rule_count]; *target = talloc_steal(state->rules, rules[i]); state->rule_count++; i++; } } state->search_base_iter++; ret = ipa_hbac_rule_info_next(req, state); if (ret == EAGAIN) { return; } else if (ret != EOK) { goto fail; } else if (ret == EOK && state->rule_count == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "No rules apply to this host\n"); tevent_req_error(req, ENOENT); return; } /* We went through all search bases and we have some results */ tevent_req_done(req); return; fail: tevent_req_error(req, ret); } errno_t ipa_hbac_rule_info_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *rule_count, struct sysdb_attrs ***rules) { struct ipa_hbac_rule_state *state = tevent_req_data(req, struct ipa_hbac_rule_state); TEVENT_REQ_RETURN_ON_ERROR(req); *rule_count = state->rule_count; *rules = talloc_steal(mem_ctx, state->rules); return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hbac_users.c0000644000000000000000000000007312703456111021014 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.744793934 sssd-1.13.4/src/providers/ipa/ipa_hbac_users.c0000644002412700241270000002570712703456111022477 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "providers/ipa/ipa_hbac_private.h" #include "providers/ldap/sdap_async.h" /* Returns EOK and populates groupname if * the group_dn is actually a group. * Returns ENOENT if group_dn does not point * at a a group. * Returns EINVAL if there is a parsing error. * Returns ENOMEM as appropriate */ errno_t get_ipa_groupname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, const char *group_dn, const char **groupname) { errno_t ret; struct ldb_dn *dn; const char *rdn_name; const char *group_comp_name; const char *account_comp_name; const struct ldb_val *rdn_val; const struct ldb_val *group_comp_val; const struct ldb_val *account_comp_val; /* This is an IPA-specific hack. It may not * work for non-IPA servers and will need to * be changed if SSSD ever supports HBAC on * a non-IPA server. */ *groupname = NULL; dn = ldb_dn_new(mem_ctx, sysdb_ctx_get_ldb(sysdb), group_dn); if (dn == NULL) { ret = ENOMEM; goto done; } if (!ldb_dn_validate(dn)) { ret = ERR_MALFORMED_ENTRY; goto done; } if (ldb_dn_get_comp_num(dn) < 4) { /* RDN, groups, accounts, and at least one DC= */ /* If it's fewer, it's not a group DN */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* If the RDN name is 'cn' */ rdn_name = ldb_dn_get_rdn_name(dn); if (rdn_name == NULL) { /* Shouldn't happen if ldb_dn_validate() * passed, but we'll be careful. */ ret = ERR_MALFORMED_ENTRY; goto done; } if (strcasecmp("cn", rdn_name) != 0) { /* RDN has the wrong attribute name. * It's not a group. */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* and the second component is "cn=groups" */ group_comp_name = ldb_dn_get_component_name(dn, 1); if (strcasecmp("cn", group_comp_name) != 0) { /* The second component name is not "cn" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } group_comp_val = ldb_dn_get_component_val(dn, 1); if (strncasecmp("groups", (const char *) group_comp_val->data, group_comp_val->length) != 0) { /* The second component value is not "groups" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* and the third component is "accounts" */ account_comp_name = ldb_dn_get_component_name(dn, 2); if (strcasecmp("cn", account_comp_name) != 0) { /* The third component name is not "cn" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } account_comp_val = ldb_dn_get_component_val(dn, 2); if (strncasecmp("accounts", (const char *) account_comp_val->data, account_comp_val->length) != 0) { /* The third component value is not "accounts" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* Then the value of the RDN is the group name */ rdn_val = ldb_dn_get_rdn_val(dn); *groupname = talloc_strndup(mem_ctx, (const char *)rdn_val->data, rdn_val->length); if (*groupname == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: talloc_free(dn); return ret; } errno_t hbac_user_attrs_to_rule(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *rule_name, struct sysdb_attrs *rule_attrs, struct hbac_rule_element **users) { errno_t ret; TALLOC_CTX *tmp_ctx = NULL; struct hbac_rule_element *new_users = NULL; struct ldb_message_element *el = NULL; struct ldb_message **msgs = NULL; char *filter; char *member_dn; const char *member_user; const char *attrs[] = { SYSDB_NAME, NULL }; size_t num_users = 0; size_t num_groups = 0; const char *name; size_t count; size_t i; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return ENOMEM; new_users = talloc_zero(tmp_ctx, struct hbac_rule_element); if (new_users == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Processing users for rule [%s]\n", rule_name); ret = hbac_get_category(rule_attrs, IPA_USER_CATEGORY, &new_users->category); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not identify user categories\n"); goto done; } if (new_users->category & HBAC_CATEGORY_ALL) { /* Short-cut to the exit */ ret = EOK; goto done; } ret = sysdb_attrs_get_el(rule_attrs, IPA_MEMBER_USER, &el); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_get_el failed.\n"); goto done; } if (ret == ENOENT || el->num_values == 0) { el->num_values = 0; DEBUG(SSSDBG_CONF_SETTINGS, "No user specified, rule will never apply.\n"); } new_users->names = talloc_array(new_users, const char *, el->num_values + 1); if (new_users->names == NULL) { ret = ENOMEM; goto done; } new_users->groups = talloc_array(new_users, const char *, el->num_values + 1); if (new_users->groups == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < el->num_values; i++) { member_user = (const char *)el->values[i].data; ret = sss_filter_sanitize(tmp_ctx, member_user, &member_dn); if (ret != EOK) goto done; filter = talloc_asprintf(member_dn, "(%s=%s)", SYSDB_ORIG_DN, member_dn); if (filter == NULL) { ret = ENOMEM; goto done; } /* First check if this is a user */ ret = sysdb_search_users(tmp_ctx, domain, filter, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) goto done; if (ret == EOK && count == 0) { ret = ENOENT; } if (ret == EOK) { if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Original DN matched multiple users. Skipping \n"); talloc_zfree(member_dn); continue; } /* Original DN matched a single user. Get the username */ name = ldb_msg_find_attr_as_string(msgs[0], SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Attribute is missing!\n"); ret = EFAULT; goto done; } new_users->names[num_users] = talloc_strdup(new_users->names, name); if (new_users->names[num_users] == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Added user [%s] to rule [%s]\n", name, rule_name); num_users++; } else { /* Check if it is a group instead */ ret = sysdb_search_groups(tmp_ctx, domain, filter, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) goto done; if (ret == EOK && count == 0) { ret = ENOENT; } if (ret == EOK) { if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Original DN matched multiple groups. " "Skipping\n"); talloc_zfree(member_dn); continue; } /* Original DN matched a single group. Get the groupname */ name = ldb_msg_find_attr_as_string(msgs[0], SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Attribute is missing!\n"); ret = EFAULT; goto done; } new_users->groups[num_groups] = talloc_strdup(new_users->groups, name); if (new_users->groups[num_groups] == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Added POSIX group [%s] to rule [%s]\n", name, rule_name); num_groups++; } else { /* If the group still matches the group pattern, * we can assume it is a non-POSIX group. */ ret = get_ipa_groupname(new_users->groups, domain->sysdb, member_user, &new_users->groups[num_groups]); if (ret == EOK) { DEBUG(SSSDBG_TRACE_INTERNAL, "Added non-POSIX group [%s] to rule [%s]\n", new_users->groups[num_groups], rule_name); num_groups++; } else { /* Not a group, so we don't care about it */ DEBUG(SSSDBG_CRIT_FAILURE, "[%s] does not map to either a user or group. " "Skipping\n", member_dn); } } } talloc_zfree(member_dn); } new_users->names[num_users] = NULL; new_users->groups[num_groups] = NULL; /* Shrink the arrays down to their real sizes */ new_users->names = talloc_realloc(new_users, new_users->names, const char *, num_users + 1); if (new_users->names == NULL) { ret = ENOMEM; goto done; } new_users->groups = talloc_realloc(new_users, new_users->groups, const char *, num_groups + 1); if (new_users->groups == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: if (ret == EOK) { *users = talloc_steal(mem_ctx, new_users); } talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_common.h0000644000000000000000000000007312703456111020173 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.564793324 sssd-1.13.4/src/providers/ipa/ipa_common.h0000644002412700241270000002024712703456111021650 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Common utility code Copyright (C) Simo Sorce 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _IPA_COMMON_H_ #define _IPA_COMMON_H_ #include "util/util.h" #include "confdb/confdb.h" #include "providers/ldap/ldap_common.h" #include "providers/krb5/krb5_common.h" #include "providers/ad/ad_common.h" #include "providers/ad/ad_srv.h" struct ipa_service { struct sdap_service *sdap; struct krb5_service *krb5_service; }; enum ipa_basic_opt { IPA_DOMAIN = 0, IPA_SERVER, IPA_BACKUP_SERVER, IPA_HOSTNAME, IPA_HBAC_SEARCH_BASE, IPA_HOST_SEARCH_BASE, IPA_SELINUX_SEARCH_BASE, IPA_SUBDOMAINS_SEARCH_BASE, IPA_MASTER_DOMAIN_SEARCH_BASE, IPA_KRB5_REALM, IPA_HBAC_REFRESH, IPA_SELINUX_REFRESH, IPA_HBAC_SUPPORT_SRCHOST, IPA_AUTOMOUNT_LOCATION, IPA_RANGES_SEARCH_BASE, IPA_ENABLE_DNS_SITES, IPA_SERVER_MODE, IPA_VIEWS_SEARCH_BASE, IPA_KRB5_CONFD_PATH, IPA_OPTS_BASIC /* opts counter */ }; enum ipa_netgroup_attrs { IPA_OC_NETGROUP = 0, IPA_AT_NETGROUP_NAME, IPA_AT_NETGROUP_MEMBER, IPA_AT_NETGROUP_MEMBER_OF, IPA_AT_NETGROUP_MEMBER_USER, IPA_AT_NETGROUP_MEMBER_HOST, IPA_AT_NETGROUP_EXTERNAL_HOST, IPA_AT_NETGROUP_DOMAIN, IPA_AT_NETGROUP_UUID, IPA_OPTS_NETGROUP /* attrs counter */ }; enum ipa_host_attrs { IPA_OC_HOST = 0, IPA_AT_HOST_NAME, IPA_AT_HOST_FQDN, IPA_AT_HOST_SERVERHOSTNAME, IPA_AT_HOST_MEMBER_OF, IPA_AT_HOST_SSH_PUBLIC_KEY, IPA_AT_HOST_UUID, IPA_OPTS_HOST /* attrs counter */ }; enum ipa_hostgroup_attrs { IPA_OC_HOSTGROUP = 0, IPA_AT_HOSTGROUP_NAME, IPA_AT_HOSTGROUP_MEMBER_OF, IPA_AT_HOSTGROUP_UUID, IPA_OPTS_HOSTGROUP /* attrs counter */ }; enum ipa_selinux_usermap_attrs { IPA_OC_SELINUX_USERMAP = 0, IPA_AT_SELINUX_USERMAP_NAME, IPA_AT_SELINUX_USERMAP_MEMBER_USER, IPA_AT_SELINUX_USERMAP_MEMBER_HOST, IPA_AT_SELINUX_USERMAP_SEE_ALSO, IPA_AT_SELINUX_USERMAP_SELINUX_USER, IPA_AT_SELINUX_USERMAP_ENABLED, IPA_AT_SELINUX_USERMAP_USERCAT, IPA_AT_SELINUX_USERMAP_HOSTCAT, IPA_AT_SELINUX_USERMAP_UUID, IPA_OPTS_SELINUX_USERMAP /* attrs counter */ }; enum ipa_view_attrs { IPA_OC_VIEW = 0, IPA_AT_VIEW_NAME, IPA_OPTS_VIEW }; enum ipa_override_attrs { IPA_OC_OVERRIDE = 0, IPA_AT_OVERRIDE_ANCHOR_UUID, IPA_OC_OVERRIDE_USER, IPA_OC_OVERRIDE_GROUP, IPA_AT_OVERRIDE_USER_NAME, IPA_AT_OVERRIDE_UID_NUMBER, IPA_AT_OVERRIDE_USER_GID_NUMBER, IPA_AT_OVERRIDE_GECOS, IPA_AT_OVERRIDE_HOMEDIR, IPA_AT_OVERRIDE_SHELL, IPA_AT_OVERRIDE_GROUP_NAME, IPA_AT_OVERRIDE_GROUP_GID_NUMBER, IPA_AT_OVERRIDE_USER_SSH_PUBLIC_KEY, IPA_OPTS_OVERRIDE }; enum ipa_sudorule_attrs { IPA_OC_SUDORULE = 0, IPA_AT_SUDORULE_NAME, IPA_AT_SUDORULE_UUID, IPA_AT_SUDORULE_ENABLED, IPA_AT_SUDORULE_OPTION, IPA_AT_SUDORULE_RUNASUSER, IPA_AT_SUDORULE_RUNASGROUP, IPA_AT_SUDORULE_ALLOWCMD, IPA_AT_SUDORULE_DENYCMD, IPA_AT_SUDORULE_HOST, IPA_AT_SUDORULE_USER, IPA_AT_SUDORULE_NOTAFTER, IPA_AT_SUDORULE_NOTBEFORE, IPA_AT_SUDORULE_SUDOORDER, IPA_AT_SUDORULE_CMDCATEGORY, IPA_AT_SUDORULE_HOSTCATEGORY, IPA_AT_SUDORULE_USERCATEGORY, IPA_AT_SUDORULE_RUNASUSERCATEGORY, IPA_AT_SUDORULE_RUNASGROUPCATEGORY, IPA_AT_SUDORULE_RUNASEXTUSER, IPA_AT_SUDORULE_RUNASEXTGROUP, IPA_AT_SUDORULE_RUNASEXTUSERGROUP, IPA_AT_SUDORULE_EXTUSER, IPA_AT_SUDORULE_ENTRYUSN, IPA_OPTS_SUDORULE }; enum ipa_sudocmdgroup_attrs { IPA_OC_SUDOCMDGROUP = 0, IPA_AT_SUDOCMDGROUP_UUID, IPA_AT_SUDOCMDGROUP_NAME, IPA_AT_SUDOCMDGROUP_MEMBER, IPA_AT_SUDOCMDGROUP_ENTRYUSN, IPA_OPTS_SUDOCMDGROUP }; enum ipa_sudocmd_attrs { IPA_OC_SUDOCMD = 0, IPA_AT_SUDOCMD_UUID, IPA_AT_SUDOCMD_CMD, IPA_AT_SUDOCMD_MEMBEROF, IPA_OPTS_SUDOCMD }; struct ipa_auth_ctx { struct krb5_ctx *krb5_auth_ctx; struct sdap_id_ctx *sdap_id_ctx; struct sdap_auth_ctx *sdap_auth_ctx; struct dp_option *ipa_options; }; /* In server mode, each subdomain corresponds to an AD context */ struct ipa_id_ctx { struct sdap_id_ctx *sdap_id_ctx; struct ipa_options *ipa_options; char *view_name; /* Only used with server mode */ struct ipa_server_mode_ctx *server_mode; }; struct ipa_options { struct dp_option *basic; struct sdap_attr_map *host_map; struct sdap_attr_map *hostgroup_map; struct sdap_attr_map *selinuxuser_map; struct sdap_attr_map *view_map; struct sdap_attr_map *override_map; struct sdap_search_base **host_search_bases; struct sdap_search_base **hbac_search_bases; struct sdap_search_base **selinux_search_bases; struct sdap_search_base **subdomains_search_bases; struct sdap_search_base **master_domain_search_bases; struct sdap_search_base **ranges_search_bases; struct sdap_search_base **views_search_bases; struct ipa_service *service; /* id provider */ struct sdap_options *id; struct ipa_id_ctx *id_ctx; struct be_resolv_ctx *be_res; struct be_nsupdate_ctx *dyndns_ctx; /* auth and chpass provider */ struct dp_option *auth; struct ipa_auth_ctx *auth_ctx; }; #define IPA_RANGE_LOCAL "ipa-local" #define IPA_RANGE_AD_TRUST "ipa-ad-trust" #define IPA_RANGE_AD_TRUST_POSIX "ipa-ad-trust-posix" /* options parsers */ int ipa_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, struct sss_domain_info *dom, struct ipa_options **_opts); int ipa_get_id_options(struct ipa_options *ipa_opts, struct confdb_ctx *cdb, const char *conf_path, struct sdap_options **_opts); int ipa_get_auth_options(struct ipa_options *ipa_opts, struct confdb_ctx *cdb, const char *conf_path, struct dp_option **_opts); int ipa_get_autofs_options(struct ipa_options *ipa_opts, struct confdb_ctx *cdb, const char *conf_path, struct sdap_options **_opts); errno_t ipa_get_dyndns_options(struct be_ctx *be_ctx, struct ipa_options *ctx); int ipa_autofs_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data); int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, const char *primary_servers, const char *backup_servers, struct ipa_options *options, struct ipa_service **_service); int ipa_sudo_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data); errno_t get_idmap_data_from_range(struct range_info *r, char *domain_name, char **_name, char **_sid, uint32_t *_rid, struct sss_idmap_range *_range, bool *_external_mapping); errno_t ipa_idmap_get_ranges_from_sysdb(struct sdap_idmap_ctx *idmap_ctx, const char *dom_name, const char *dom_sid_str, bool allow_collisions); errno_t ipa_idmap_init(TALLOC_CTX *mem_ctx, struct sdap_id_ctx *id_ctx, struct sdap_idmap_ctx **_idmap_ctx); #endif /* _IPA_COMMON_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_sudo.h0000644000000000000000000000007412703456111017656 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.577793368 sssd-1.13.4/src/providers/ipa/ipa_sudo.h0000644002412700241270000000737612703456111021342 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _IPA_SUDO_H_ #define _IPA_SUDO_H_ #include "providers/ipa/ipa_common.h" struct ipa_sudo_ctx { struct sdap_id_ctx *id_ctx; struct ipa_options *ipa_opts; struct sdap_options *sdap_opts; /* sudo */ struct sdap_attr_map *sudocmdgroup_map; struct sdap_attr_map *sudorule_map; struct sdap_attr_map *sudocmd_map; struct sdap_search_base **sudo_sb; }; errno_t ipa_sudo_ptask_setup(struct be_ctx *be_ctx, struct ipa_sudo_ctx *sudo_ctx); struct tevent_req * ipa_sudo_full_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_sudo_ctx *sudo_ctx); int ipa_sudo_full_refresh_recv(struct tevent_req *req, int *dp_error); int ipa_sudo_rules_refresh_recv(struct tevent_req *req, int *dp_error, bool *deleted); struct tevent_req * ipa_sudo_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_sudo_ctx *sudo_ctx, const char *cmdgroups_filter, const char *search_filter, const char *delete_filter); struct tevent_req * ipa_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_sudo_ctx *sudo_ctx, char **rules); errno_t ipa_sudo_refresh_recv(struct tevent_req *req, int *dp_error, size_t *_num_rules); struct ipa_sudo_conv; struct ipa_sudo_conv * ipa_sudo_conv_init(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sdap_attr_map *map_rule, struct sdap_attr_map *map_cmdgroup, struct sdap_attr_map *map_cmd, struct sdap_attr_map *map_user, struct sdap_attr_map *map_group, struct sdap_attr_map *map_host, struct sdap_attr_map *map_hostgroup); errno_t ipa_sudo_conv_rules(struct ipa_sudo_conv *conv, struct sysdb_attrs **rules, size_t num_rules); errno_t ipa_sudo_conv_cmdgroups(struct ipa_sudo_conv *conv, struct sysdb_attrs **cmdgroups, size_t num_cmdgroups); errno_t ipa_sudo_conv_cmds(struct ipa_sudo_conv *conv, struct sysdb_attrs **cmds, size_t num_cmds); bool ipa_sudo_conv_has_cmdgroups(struct ipa_sudo_conv *conv); bool ipa_sudo_conv_has_cmds(struct ipa_sudo_conv *conv); char * ipa_sudo_conv_cmdgroup_filter(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv); char * ipa_sudo_conv_cmd_filter(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv); errno_t ipa_sudo_conv_result(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv, struct sysdb_attrs ***_rules, size_t *_num_rules); #endif /* _IPA_SUDO_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_srv.h0000644000000000000000000000007412703456111017516 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.576793364 sssd-1.13.4/src/providers/ipa/ipa_srv.h0000644002412700241270000000354312703456111021172 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __IPA_SRV_H__ #define __IPA_SRV_H__ struct ipa_srv_plugin_ctx; struct ipa_srv_plugin_ctx * ipa_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx, struct resolv_ctx *resolv_ctx, const char *hostname, const char *ipa_domain); struct tevent_req *ipa_srv_plugin_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *service, const char *protocol, const char *discovery_domain, void *pvt); errno_t ipa_srv_plugin_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain, uint32_t *_ttl, struct fo_server_info **_primary_servers, size_t *_num_primary_servers, struct fo_server_info **_backup_servers, size_t *_num_backup_servers); #endif /* __IPA_SRV_H__ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_srv.c0000644000000000000000000000007412703456111017511 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.747793944 sssd-1.13.4/src/providers/ipa/ipa_srv.c0000644002412700241270000001513612703456111021166 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "resolv/async_resolv.h" #include "providers/fail_over_srv.h" #include "providers/ipa/ipa_srv.h" #define IPA_DNS_LOCATION "_location" struct ipa_srv_plugin_ctx { struct resolv_ctx *resolv_ctx; const char *hostname; const char *ipa_domain; }; struct ipa_srv_plugin_ctx * ipa_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx, struct resolv_ctx *resolv_ctx, const char *hostname, const char *ipa_domain) { struct ipa_srv_plugin_ctx *ctx = NULL; ctx = talloc_zero(mem_ctx, struct ipa_srv_plugin_ctx); if (ctx == NULL) { return NULL; } ctx->resolv_ctx = resolv_ctx; ctx->hostname = talloc_strdup(ctx, hostname); if (ctx->hostname == NULL) { goto fail; } ctx->ipa_domain = talloc_strdup(ctx, ipa_domain); if (ctx->ipa_domain == NULL) { goto fail; } return ctx; fail: talloc_free(ctx); return NULL; } struct ipa_srv_plugin_state { char *dns_domain; uint32_t ttl; struct fo_server_info *primary_servers; size_t num_primary_servers; struct fo_server_info *backup_servers; size_t num_backup_servers; }; static void ipa_srv_plugin_done(struct tevent_req *subreq); /* If IPA server supports sites, we will use * _locations.hostname.discovery_domain for primary servers and * discovery_domain for backup servers. If the server does not support sites or * client's SRV record is not found, we will use the latter for primary * servers, setting backup servers to NULL */ struct tevent_req *ipa_srv_plugin_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *service, const char *protocol, const char *discovery_domain, void *pvt) { struct ipa_srv_plugin_state *state = NULL; struct ipa_srv_plugin_ctx *ctx = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; const char *primary_domain = NULL; const char *backup_domain = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ipa_srv_plugin_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } ctx = talloc_get_type(pvt, struct ipa_srv_plugin_ctx); if (ctx == NULL) { ret = EINVAL; goto immediately; } if (discovery_domain != NULL) { backup_domain = talloc_strdup(state, discovery_domain); } else { backup_domain = talloc_strdup(state, ctx->ipa_domain); } if (backup_domain == NULL) { ret = ENOMEM; goto immediately; } if (strchr(ctx->hostname, '.') == NULL) { /* not FQDN, append domain name */ primary_domain = talloc_asprintf(state, IPA_DNS_LOCATION ".%s.%s", ctx->hostname, backup_domain); } else { primary_domain = talloc_asprintf(state, IPA_DNS_LOCATION ".%s", ctx->hostname); } if (primary_domain == NULL) { ret = ENOMEM; goto immediately; } DEBUG(SSSDBG_TRACE_FUNC, "About to discover primary and " "backup servers\n"); subreq = fo_discover_servers_send(state, ev, ctx->resolv_ctx, service, protocol, primary_domain, backup_domain); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, ipa_srv_plugin_done, req); return req; immediately: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void ipa_srv_plugin_done(struct tevent_req *subreq) { struct ipa_srv_plugin_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_srv_plugin_state); ret = fo_discover_servers_recv(state, subreq, &state->dns_domain, &state->ttl, &state->primary_servers, &state->num_primary_servers, &state->backup_servers, &state->num_backup_servers); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_FUNC, "Got %zu primary and %zu backup servers\n", state->num_primary_servers, state->num_backup_servers); tevent_req_done(req); } errno_t ipa_srv_plugin_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain, uint32_t *_ttl, struct fo_server_info **_primary_servers, size_t *_num_primary_servers, struct fo_server_info **_backup_servers, size_t *_num_backup_servers) { struct ipa_srv_plugin_state *state = NULL; state = tevent_req_data(req, struct ipa_srv_plugin_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_primary_servers) { *_primary_servers = talloc_steal(mem_ctx, state->primary_servers); } if (_num_primary_servers) { *_num_primary_servers = state->num_primary_servers; } if (_backup_servers) { *_backup_servers = talloc_steal(mem_ctx, state->backup_servers); } if (_num_backup_servers) { *_num_backup_servers = state->num_backup_servers; } if (_dns_domain) { *_dns_domain = talloc_steal(mem_ctx, state->dns_domain); } if (_ttl) { *_ttl = state->ttl; } return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hbac.pc.in0000644000000000000000000000007412703456111020361 xustar0030 atime=1460561772.700787003 30 ctime=1460561774.631793551 sssd-1.13.4/src/providers/ipa/ipa_hbac.pc.in0000644002412700241270000000035112703456111022027 0ustar00jhrozekjhrozek00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: ipa_hbac Description: FreeIPA HBAC Evaluator library Version: @VERSION@ Libs: -L${libdir} -lipa_hbac Cflags: URL: http://fedorahosted.org/sssd/ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_common.c0000644000000000000000000000007312703456111020166 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.724793866 sssd-1.13.4/src/providers/ipa/ipa_common.c0000644002412700241270000011431512703456111021643 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Provider Common Functions Authors: Simo Sorce Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "db/sysdb_selinux.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_dyndns.h" #include "providers/ldap/sdap_async_private.h" #include "providers/dp_dyndns.h" #include "util/sss_krb5.h" #include "db/sysdb_services.h" #include "db/sysdb_autofs.h" #include "providers/ipa/ipa_opts.h" int ipa_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, struct sss_domain_info *dom, struct ipa_options **_opts) { struct ipa_options *opts; char *domain; char *server; char *realm; char *ipa_hostname; int ret; char hostname[HOST_NAME_MAX + 1]; opts = talloc_zero(memctx, struct ipa_options); if (!opts) return ENOMEM; ret = dp_get_options(opts, cdb, conf_path, ipa_basic_opts, IPA_OPTS_BASIC, &opts->basic); if (ret != EOK) { goto done; } domain = dp_opt_get_string(opts->basic, IPA_DOMAIN); if (!domain) { ret = dp_opt_set_string(opts->basic, IPA_DOMAIN, dom->name); if (ret != EOK) { goto done; } domain = dom->name; } server = dp_opt_get_string(opts->basic, IPA_SERVER); if (!server) { DEBUG(SSSDBG_CRIT_FAILURE, "No ipa server set, will use service discovery!\n"); } ipa_hostname = dp_opt_get_string(opts->basic, IPA_HOSTNAME); if (ipa_hostname == NULL) { ret = gethostname(hostname, HOST_NAME_MAX); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "gethostname failed [%d][%s].\n", errno, strerror(errno)); ret = errno; goto done; } hostname[HOST_NAME_MAX] = '\0'; DEBUG(SSSDBG_TRACE_ALL, "Setting ipa_hostname to [%s].\n", hostname); ret = dp_opt_set_string(opts->basic, IPA_HOSTNAME, hostname); if (ret != EOK) { goto done; } } /* First check whether the realm has been manually specified */ realm = dp_opt_get_string(opts->basic, IPA_KRB5_REALM); if (!realm) { /* No explicit krb5_realm, use the IPA domain, transform to upper-case */ realm = get_uppercase_realm(opts, domain); if (!realm) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(opts->basic, IPA_KRB5_REALM, realm); if (ret != EOK) { goto done; } } ret = EOK; *_opts = opts; done: if (ret != EOK) { talloc_zfree(opts); } return ret; } static errno_t ipa_parse_search_base(TALLOC_CTX *mem_ctx, struct dp_option *opts, int class, struct sdap_search_base ***_search_bases) { const char *class_name; char *unparsed_base; *_search_bases = NULL; switch (class) { case IPA_HBAC_SEARCH_BASE: class_name = "IPA_HBAC"; break; case IPA_HOST_SEARCH_BASE: class_name = "IPA_HOST"; break; case IPA_SELINUX_SEARCH_BASE: class_name = "IPA_SELINUX"; break; case IPA_SUBDOMAINS_SEARCH_BASE: class_name = "IPA_SUBDOMAINS"; break; case IPA_MASTER_DOMAIN_SEARCH_BASE: class_name = "IPA_MASTER_DOMAIN"; break; case IPA_RANGES_SEARCH_BASE: class_name = "IPA_RANGES"; break; case IPA_VIEWS_SEARCH_BASE: class_name = "IPA_VIEWS"; break; default: DEBUG(SSSDBG_CONF_SETTINGS, "Unknown search base type: [%d]\n", class); class_name = "UNKNOWN"; /* Non-fatal */ break; } unparsed_base = dp_opt_get_string(opts, class); if (!unparsed_base || unparsed_base[0] == '\0') return ENOENT; return common_parse_search_base(mem_ctx, unparsed_base, class_name, NULL, _search_bases); } int ipa_get_id_options(struct ipa_options *ipa_opts, struct confdb_ctx *cdb, const char *conf_path, struct sdap_options **_opts) { TALLOC_CTX *tmpctx; char *basedn; char *realm; char *value; int ret; int i; tmpctx = talloc_new(ipa_opts); if (!tmpctx) { return ENOMEM; } ipa_opts->id = talloc_zero(ipa_opts, struct sdap_options); if (!ipa_opts->id) { ret = ENOMEM; goto done; } ret = sdap_domain_add(ipa_opts->id, ipa_opts->id_ctx->sdap_id_ctx->be->domain, NULL); if (ret != EOK) { goto done; } /* get sdap options */ ret = dp_get_options(ipa_opts->id, cdb, conf_path, ipa_def_ldap_opts, SDAP_OPTS_BASIC, &ipa_opts->id->basic); if (ret != EOK) { goto done; } ret = domain_to_basedn(tmpctx, dp_opt_get_string(ipa_opts->basic, IPA_KRB5_REALM), &basedn); if (ret != EOK) { goto done; } if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE)) { /* FIXME: get values by querying IPA */ /* set search base */ value = talloc_asprintf(tmpctx, "cn=accounts,%s", basedn); if (!value) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_SEARCH_BASE, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", ipa_opts->id->basic[SDAP_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE)); } ret = sdap_parse_search_base(ipa_opts->id, ipa_opts->id->basic, SDAP_SEARCH_BASE, &ipa_opts->id->sdom->search_bases); if (ret != EOK) goto done; /* set krb realm */ if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_KRB5_REALM)) { realm = dp_opt_get_string(ipa_opts->basic, IPA_KRB5_REALM); value = talloc_strdup(tmpctx, realm); if (value == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_KRB5_REALM, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", ipa_opts->id->basic[SDAP_KRB5_REALM].opt_name, dp_opt_get_string(ipa_opts->id->basic, SDAP_KRB5_REALM)); } ret = sdap_set_sasl_options(ipa_opts->id, dp_opt_get_string(ipa_opts->basic, IPA_HOSTNAME), dp_opt_get_string(ipa_opts->id->basic, SDAP_KRB5_REALM), dp_opt_get_string(ipa_opts->id->basic, SDAP_KRB5_KEYTAB)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set the SASL-related options\n"); goto done; } /* fix schema to IPAv1 for now */ ipa_opts->id->schema_type = SDAP_SCHEMA_IPA_V1; /* set user/group search bases if they are not specified */ if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_USER_SEARCH_BASE)) { ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_USER_SEARCH_BASE, dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE)); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", ipa_opts->id->basic[SDAP_USER_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->id->basic, SDAP_USER_SEARCH_BASE)); } ret = sdap_parse_search_base(ipa_opts->id, ipa_opts->id->basic, SDAP_USER_SEARCH_BASE, &ipa_opts->id->sdom->user_search_bases); if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_GROUP_SEARCH_BASE)) { ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_GROUP_SEARCH_BASE, dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE)); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", ipa_opts->id->basic[SDAP_GROUP_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->id->basic, SDAP_GROUP_SEARCH_BASE)); } ret = sdap_parse_search_base(ipa_opts->id, ipa_opts->id->basic, SDAP_GROUP_SEARCH_BASE, &ipa_opts->id->sdom->group_search_bases); if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_NETGROUP_SEARCH_BASE)) { value = talloc_asprintf(tmpctx, "cn=ng,cn=alt,%s", basedn); if (!value) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_NETGROUP_SEARCH_BASE, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", ipa_opts->id->basic[SDAP_NETGROUP_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->id->basic, SDAP_NETGROUP_SEARCH_BASE)); } ret = sdap_parse_search_base(ipa_opts->id, ipa_opts->id->basic, SDAP_NETGROUP_SEARCH_BASE, &ipa_opts->id->sdom->netgroup_search_bases); if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->basic, IPA_HOST_SEARCH_BASE)) { ret = dp_opt_set_string(ipa_opts->basic, IPA_HOST_SEARCH_BASE, dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE)); if (ret != EOK) { goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", ipa_opts->basic[IPA_HOST_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->basic, IPA_HOST_SEARCH_BASE)); } ret = ipa_parse_search_base(ipa_opts->basic, ipa_opts->basic, IPA_HOST_SEARCH_BASE, &ipa_opts->host_search_bases); if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->basic, IPA_HBAC_SEARCH_BASE)) { value = talloc_asprintf(tmpctx, "cn=hbac,%s", basedn); if (!value) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->basic, IPA_HBAC_SEARCH_BASE, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", ipa_opts->basic[IPA_HBAC_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->basic, IPA_HBAC_SEARCH_BASE)); } ret = ipa_parse_search_base(ipa_opts->basic, ipa_opts->basic, IPA_HBAC_SEARCH_BASE, &ipa_opts->hbac_search_bases); if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->basic, IPA_SELINUX_SEARCH_BASE)) { value = talloc_asprintf(tmpctx, "cn=selinux,%s", basedn); if (!value) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->basic, IPA_SELINUX_SEARCH_BASE, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", ipa_opts->basic[IPA_SELINUX_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->basic, IPA_SELINUX_SEARCH_BASE)); } ret = ipa_parse_search_base(ipa_opts->basic, ipa_opts->basic, IPA_SELINUX_SEARCH_BASE, &ipa_opts->selinux_search_bases); if (ret != EOK) goto done; value = dp_opt_get_string(ipa_opts->id->basic, SDAP_DEREF); if (value != NULL) { ret = deref_string_to_val(value, &i); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to verify ldap_deref option.\n"); goto done; } } if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_SERVICE_SEARCH_BASE)) { ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_SERVICE_SEARCH_BASE, dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE)); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", ipa_opts->id->basic[SDAP_GROUP_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->id->basic, SDAP_GROUP_SEARCH_BASE)); } ret = sdap_parse_search_base(ipa_opts->id, ipa_opts->id->basic, SDAP_SERVICE_SEARCH_BASE, &ipa_opts->id->sdom->service_search_bases); if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->basic, IPA_SUBDOMAINS_SEARCH_BASE)) { value = talloc_asprintf(tmpctx, "cn=trusts,%s", basedn); if (value == NULL) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->basic, IPA_SUBDOMAINS_SEARCH_BASE, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", ipa_opts->basic[IPA_SUBDOMAINS_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->basic, IPA_SUBDOMAINS_SEARCH_BASE)); } ret = ipa_parse_search_base(ipa_opts, ipa_opts->basic, IPA_SUBDOMAINS_SEARCH_BASE, &ipa_opts->subdomains_search_bases); if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->basic, IPA_MASTER_DOMAIN_SEARCH_BASE)) { value = talloc_asprintf(tmpctx, "cn=ad,cn=etc,%s", basedn); if (value == NULL) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->basic, IPA_MASTER_DOMAIN_SEARCH_BASE, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", ipa_opts->basic[IPA_MASTER_DOMAIN_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->basic, IPA_MASTER_DOMAIN_SEARCH_BASE)); } ret = ipa_parse_search_base(ipa_opts, ipa_opts->basic, IPA_MASTER_DOMAIN_SEARCH_BASE, &ipa_opts->master_domain_search_bases); if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->basic, IPA_RANGES_SEARCH_BASE)) { value = talloc_asprintf(tmpctx, "cn=ranges,cn=etc,%s", basedn); if (value == NULL) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->basic, IPA_RANGES_SEARCH_BASE, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", ipa_opts->basic[IPA_RANGES_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->basic, IPA_RANGES_SEARCH_BASE)); } ret = ipa_parse_search_base(ipa_opts, ipa_opts->basic, IPA_RANGES_SEARCH_BASE, &ipa_opts->ranges_search_bases); if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->basic, IPA_VIEWS_SEARCH_BASE)) { value = talloc_asprintf(tmpctx, "cn=views,cn=accounts,%s", basedn); if (value == NULL) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->basic, IPA_VIEWS_SEARCH_BASE, value); if (ret != EOK) { goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", ipa_opts->basic[IPA_VIEWS_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->basic, IPA_VIEWS_SEARCH_BASE)); } ret = ipa_parse_search_base(ipa_opts, ipa_opts->basic, IPA_VIEWS_SEARCH_BASE, &ipa_opts->views_search_bases); if (ret != EOK) goto done; ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_attr_map, SDAP_AT_GENERAL, &ipa_opts->id->gen_map); if (ret != EOK) { goto done; } ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_user_map, SDAP_OPTS_USER, &ipa_opts->id->user_map); if (ret != EOK) { goto done; } ret = sdap_extend_map_with_list(ipa_opts->id, ipa_opts->id, SDAP_USER_EXTRA_ATTRS, ipa_opts->id->user_map, SDAP_OPTS_USER, &ipa_opts->id->user_map, &ipa_opts->id->user_map_cnt); if (ret != EOK) { goto done; } ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_group_map, SDAP_OPTS_GROUP, &ipa_opts->id->group_map); if (ret != EOK) { goto done; } ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_netgroup_map, IPA_OPTS_NETGROUP, &ipa_opts->id->netgroup_map); if (ret != EOK) { goto done; } ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_host_map, IPA_OPTS_HOST, &ipa_opts->host_map); if (ret != EOK) { goto done; } ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_hostgroup_map, IPA_OPTS_HOSTGROUP, &ipa_opts->hostgroup_map); if (ret != EOK) { goto done; } ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_service_map, SDAP_OPTS_SERVICES, &ipa_opts->id->service_map); if (ret != EOK) { goto done; } ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_selinux_user_map, IPA_OPTS_SELINUX_USERMAP, &ipa_opts->selinuxuser_map); if (ret != EOK) { goto done; } ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_view_map, IPA_OPTS_VIEW, &ipa_opts->view_map); if (ret != EOK) { goto done; } ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_override_map, IPA_OPTS_OVERRIDE, &ipa_opts->override_map); if (ret != EOK) { goto done; } ret = EOK; *_opts = ipa_opts->id; done: talloc_zfree(tmpctx); if (ret != EOK) { talloc_zfree(ipa_opts->id); } return ret; } int ipa_get_auth_options(struct ipa_options *ipa_opts, struct confdb_ctx *cdb, const char *conf_path, struct dp_option **_opts) { char *value; char *copy = NULL; int ret; ipa_opts->auth = talloc_zero(ipa_opts, struct dp_option); if (ipa_opts->auth == NULL) { ret = ENOMEM; goto done; } /* get krb5 options */ ret = dp_get_options(ipa_opts, cdb, conf_path, ipa_def_krb5_opts, KRB5_OPTS, &ipa_opts->auth); if (ret != EOK) { goto done; } /* If there is no KDC, try the deprecated krb5_kdcip option, too */ /* FIXME - this can be removed in a future version */ ret = krb5_try_kdcip(cdb, conf_path, ipa_opts->auth, KRB5_KDC); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_try_kdcip failed.\n"); goto done; } /* set krb realm */ if (NULL == dp_opt_get_string(ipa_opts->auth, KRB5_REALM)) { value = dp_opt_get_string(ipa_opts->basic, IPA_KRB5_REALM); if (!value) { ret = ENOMEM; goto done; } copy = talloc_strdup(ipa_opts->auth, value); if (copy == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->auth, KRB5_REALM, copy); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", ipa_opts->auth[KRB5_REALM].opt_name, dp_opt_get_string(ipa_opts->auth, KRB5_REALM)); } /* If krb5_fast_principal was not set explicitly, default to * host/$client_hostname@REALM */ value = dp_opt_get_string(ipa_opts->auth, KRB5_FAST_PRINCIPAL); if (value == NULL) { value = talloc_asprintf(ipa_opts->auth, "host/%s@%s", dp_opt_get_string(ipa_opts->basic, IPA_HOSTNAME), dp_opt_get_string(ipa_opts->auth, KRB5_REALM)); if (value == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set %s!\n", ipa_opts->auth[KRB5_FAST_PRINCIPAL].opt_name); ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->auth, KRB5_FAST_PRINCIPAL, value); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set %s!\n", ipa_opts->auth[KRB5_FAST_PRINCIPAL].opt_name); goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", ipa_opts->auth[KRB5_FAST_PRINCIPAL].opt_name, value); } /* Set flag that controls whether we want to write the * kdcinfo files at all */ ipa_opts->service->krb5_service->write_kdcinfo = \ dp_opt_get_bool(ipa_opts->auth, KRB5_USE_KDCINFO); DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", ipa_opts->auth[KRB5_USE_KDCINFO].opt_name, ipa_opts->service->krb5_service->write_kdcinfo ? "true" : "false"); *_opts = ipa_opts->auth; ret = EOK; done: talloc_free(copy); if (ret != EOK) { talloc_zfree(ipa_opts->auth); } return ret; } static void ipa_resolve_callback(void *private_data, struct fo_server *server) { TALLOC_CTX *tmp_ctx = NULL; struct ipa_service *service; struct resolv_hostent *srvaddr; struct sockaddr_storage *sockaddr; char *address; const char *safe_address; char *new_uri; const char *srv_name; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed\n"); return; } service = talloc_get_type(private_data, struct ipa_service); if (!service) { DEBUG(SSSDBG_CRIT_FAILURE, "FATAL: Bad private_data\n"); talloc_free(tmp_ctx); return; } srvaddr = fo_get_server_hostent(server); if (!srvaddr) { DEBUG(SSSDBG_CRIT_FAILURE, "FATAL: No hostent available for server (%s)\n", fo_get_server_str_name(server)); talloc_free(tmp_ctx); return; } sockaddr = resolv_get_sockaddr_address(tmp_ctx, srvaddr, LDAP_PORT); if (sockaddr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_sockaddr_address failed.\n"); talloc_free(tmp_ctx); return; } address = resolv_get_string_address(tmp_ctx, srvaddr); if (address == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_string_address failed.\n"); talloc_free(tmp_ctx); return; } srv_name = fo_get_server_name(server); if (srv_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get server host name\n"); talloc_free(tmp_ctx); return; } new_uri = talloc_asprintf(service, "ldap://%s", srv_name); if (!new_uri) { DEBUG(SSSDBG_OP_FAILURE, "Failed to copy URI ...\n"); talloc_free(tmp_ctx); return; } DEBUG(SSSDBG_TRACE_FUNC, "Constructed uri '%s'\n", new_uri); /* free old one and replace with new one */ talloc_zfree(service->sdap->uri); service->sdap->uri = new_uri; talloc_zfree(service->sdap->sockaddr); service->sdap->sockaddr = talloc_steal(service, sockaddr); if (service->krb5_service->write_kdcinfo) { safe_address = sss_escape_ip_address(tmp_ctx, srvaddr->family, address); if (safe_address == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_escape_ip_address failed.\n"); talloc_free(tmp_ctx); return; } ret = write_krb5info_file(service->krb5_service->realm, safe_address, SSS_KRB5KDC_FO_SRV); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "write_krb5info_file failed, authentication might fail.\n"); } } talloc_free(tmp_ctx); } static errno_t _ipa_servers_init(struct be_ctx *ctx, struct ipa_service *service, struct ipa_options *options, const char *servers, bool primary) { TALLOC_CTX *tmp_ctx; char **list = NULL; char *ipa_domain; int ret = 0; int i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } /* split server parm into a list */ ret = split_on_separator(tmp_ctx, servers, ',', true, true, &list, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse server list!\n"); goto done; } /* now for each one add a new server to the failover service */ for (i = 0; list[i]; i++) { talloc_steal(service, list[i]); if (be_fo_is_srv_identifier(list[i])) { if (!primary) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add server [%s] to failover service: " "SRV resolution only allowed for primary servers!\n", list[i]); continue; } ipa_domain = dp_opt_get_string(options->basic, IPA_DOMAIN); ret = be_fo_add_srv_server(ctx, "IPA", "ldap", ipa_domain, BE_FO_PROTO_TCP, false, NULL); if (ret) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n"); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Added service lookup for service IPA\n"); continue; } /* It could be ipv6 address in square brackets. Remove * the brackets if needed. */ ret = remove_ipv6_brackets(list[i]); if (ret != EOK) { goto done; } ret = be_fo_add_server(ctx, "IPA", list[i], 0, NULL, primary); if (ret && ret != EEXIST) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n"); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Added Server %s\n", list[i]); } done: talloc_free(tmp_ctx); return ret; } static inline errno_t ipa_primary_servers_init(struct be_ctx *ctx, struct ipa_service *service, struct ipa_options *options, const char *servers) { return _ipa_servers_init(ctx, service, options, servers, true); } static inline errno_t ipa_backup_servers_init(struct be_ctx *ctx, struct ipa_service *service, struct ipa_options *options, const char *servers) { return _ipa_servers_init(ctx, service, options, servers, false); } static int ipa_user_data_cmp(void *ud1, void *ud2) { return strcasecmp((char*) ud1, (char*) ud2); } int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, const char *primary_servers, const char *backup_servers, struct ipa_options *options, struct ipa_service **_service) { TALLOC_CTX *tmp_ctx; struct ipa_service *service; char *realm; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } service = talloc_zero(tmp_ctx, struct ipa_service); if (!service) { ret = ENOMEM; goto done; } service->sdap = talloc_zero(service, struct sdap_service); if (!service->sdap) { ret = ENOMEM; goto done; } service->krb5_service = talloc_zero(service, struct krb5_service); if (!service->krb5_service) { ret = ENOMEM; goto done; } ret = be_fo_add_service(ctx, "IPA", ipa_user_data_cmp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create failover service!\n"); goto done; } service->sdap->name = talloc_strdup(service, "IPA"); if (!service->sdap->name) { ret = ENOMEM; goto done; } service->krb5_service->name = talloc_strdup(service, "IPA"); if (!service->krb5_service->name) { ret = ENOMEM; goto done; } service->sdap->kinit_service_name = service->krb5_service->name; realm = dp_opt_get_string(options->basic, IPA_KRB5_REALM); if (!realm) { DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm set\n"); ret = EINVAL; goto done; } service->krb5_service->realm = talloc_strdup(service->krb5_service, realm); if (!service->krb5_service->realm) { ret = ENOMEM; goto done; } if (!primary_servers) { DEBUG(SSSDBG_CONF_SETTINGS, "No primary servers defined, using service discovery\n"); primary_servers = BE_SRV_IDENTIFIER; } ret = ipa_primary_servers_init(ctx, service, options, primary_servers); if (ret != EOK) { goto done; } if (backup_servers) { ret = ipa_backup_servers_init(ctx, service, options, backup_servers); if (ret != EOK) { goto done; } } ret = be_fo_service_add_callback(memctx, ctx, "IPA", ipa_resolve_callback, service); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add failover callback!\n"); goto done; } ret = EOK; done: if (ret == EOK) { *_service = talloc_steal(memctx, service); } talloc_zfree(tmp_ctx); return ret; } int ipa_get_autofs_options(struct ipa_options *ipa_opts, struct confdb_ctx *cdb, const char *conf_path, struct sdap_options **_opts) { TALLOC_CTX *tmp_ctx; char *basedn; char *autofs_base; errno_t ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = domain_to_basedn(tmp_ctx, dp_opt_get_string(ipa_opts->basic, IPA_KRB5_REALM), &basedn); if (ret != EOK) { goto done; } if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_AUTOFS_SEARCH_BASE)) { autofs_base = talloc_asprintf(tmp_ctx, "cn=%s,cn=automount,%s", dp_opt_get_string(ipa_opts->basic, IPA_AUTOMOUNT_LOCATION), basedn); if (!autofs_base) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_AUTOFS_SEARCH_BASE, autofs_base); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Option %s set to %s\n", ipa_opts->id->basic[SDAP_AUTOFS_SEARCH_BASE].opt_name, dp_opt_get_string(ipa_opts->id->basic, SDAP_AUTOFS_SEARCH_BASE)); } ret = sdap_parse_search_base(ipa_opts->id, ipa_opts->id->basic, SDAP_AUTOFS_SEARCH_BASE, &ipa_opts->id->sdom->autofs_search_bases); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Could not parse autofs search base\n"); goto done; } ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_autofs_mobject_map, SDAP_OPTS_AUTOFS_MAP, &ipa_opts->id->autofs_mobject_map); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not get autofs map object attribute map\n"); goto done; } ret = sdap_get_map(ipa_opts->id, cdb, conf_path, ipa_autofs_entry_map, SDAP_OPTS_AUTOFS_ENTRY, &ipa_opts->id->autofs_entry_map); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not get autofs entry object attribute map\n"); goto done; } *_opts = ipa_opts->id; ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t ipa_get_dyndns_options(struct be_ctx *be_ctx, struct ipa_options *ctx) { errno_t ret; char *val; bool update; int ttl; ret = be_nsupdate_init(ctx, be_ctx, ipa_dyndns_opts, &ctx->dyndns_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize IPA dyndns opts [%d]: %s\n", ret, sss_strerror(ret)); return ret; } if (ctx->basic == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "IPA basic options not (yet) " "initialized, cannot copy legacy options\n"); return EOK; } /* Reuse legacy option values */ ret = confdb_get_string(be_ctx->cdb, ctx, be_ctx->conf_path, "ipa_dyndns_update", NULL, &val); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get the value of %s\n", "ipa_dyndns_update"); /* Not fatal */ } else if (ret == EOK && val) { if (strcasecmp(val, "FALSE") == 0) { update = false; } else if (strcasecmp(val, "TRUE") == 0) { update = true; } else { DEBUG(SSSDBG_MINOR_FAILURE, "ipa_dyndns_update value is not a boolean!\n"); talloc_free(val); return EINVAL; } DEBUG(SSSDBG_MINOR_FAILURE, "Deprecation warning: The option %s is " "deprecated and should not be used in favor of %s\n", "ipa_dyndns_update", "dyndns_update"); ret = dp_opt_set_bool(ctx->dyndns_ctx->opts, DP_OPT_DYNDNS_UPDATE, update); talloc_free(val); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set option value\n"); return ret; } } ret = confdb_get_int(be_ctx->cdb, be_ctx->conf_path, "ipa_dyndns_ttl", -1, &ttl); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get the value of %s\n", "ipa_dyndns_ttl"); /* Not fatal */ } else if (ret == EOK && ttl != -1) { DEBUG(SSSDBG_MINOR_FAILURE, "Deprecation warning: The option %s is " "deprecated and should not be used in favor of %s\n", "ipa_dyndns_ttl", "dyndns_ttl"); ret = dp_opt_set_int(ctx->dyndns_ctx->opts, DP_OPT_DYNDNS_TTL, ttl); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set option value\n"); return ret; } } /* Reuse legacy option values */ ret = confdb_get_string(be_ctx->cdb, ctx, be_ctx->conf_path, "ipa_dyndns_iface", NULL, &val); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get the value of %s\n", "ipa_dyndns_iface"); /* Not fatal */ } else if (ret == EOK && val) { DEBUG(SSSDBG_MINOR_FAILURE, "Deprecation warning: The option %s is " "deprecated and should not be used in favor of %s\n", "ipa_dyndns_iface", "dyndns_iface"); ret = dp_opt_set_string(ctx->dyndns_ctx->opts, DP_OPT_DYNDNS_IFACE, val); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set option value\n"); return ret; } } return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_auth.h0000644000000000000000000000007312703456111017644 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.571793347 sssd-1.13.4/src/providers/ipa/ipa_auth.h0000644002412700241270000000165212703456111021320 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- Authentication Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _IPA_AUTH_H_ #define _IPA_AUTH_H_ #include "providers/dp_backend.h" void ipa_auth(struct be_req *be_req); #endif /* _IPA_AUTH_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_sudo_conversion.c0000644000000000000000000000007412703456111022116 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.753793964 sssd-1.13.4/src/providers/ipa/ipa_sudo_conversion.c0000644002412700241270000010335212703456111023571 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "providers/ldap/sdap.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_dn.h" #include "db/sysdb_sudo.h" #include "db/sysdb.h" #include "util/util.h" #define SUDO_DN_CMDGROUPS "sudocmdgroups" #define SUDO_DN_CMDS "sudocmds" #define SUDO_DN_CONTAINER "sudo" #define SUDO_DN_CN "cn" #define MATCHDN(cat) SUDO_DN_CN, (cat), SUDO_DN_CN, SUDO_DN_CONTAINER #define MATCHDN_CMDGROUPS MATCHDN(SUDO_DN_CMDGROUPS) #define MATCHDN_CMDS MATCHDN(SUDO_DN_CMDS) #define MATCHRDN_CMDGROUPS(map) (map)[IPA_AT_SUDOCMDGROUP_NAME].name, MATCHDN_CMDGROUPS #define MATCHRDN_CMDS(attr, map) (map)[attr].name, MATCHDN_CMDS #define MATCHRDN_USER(map) (map)[SDAP_AT_USER_NAME].name, "cn", "users", "cn", "accounts" #define MATCHRDN_GROUP(map) (map)[SDAP_AT_GROUP_NAME].name, "cn", "groups", "cn", "accounts" #define MATCHRDN_HOST(map) (map)[IPA_AT_HOST_FQDN].name, "cn", "computers", "cn", "accounts" #define MATCHRDN_HOSTGROUP(map) (map)[IPA_AT_HOSTGROUP_NAME].name, "cn", "hostgroups", "cn", "accounts" struct ipa_sudo_conv { struct sysdb_ctx *sysdb; struct sdap_attr_map *map_rule; struct sdap_attr_map *map_cmdgroup; struct sdap_attr_map *map_cmd; struct sdap_attr_map *map_user; struct sdap_attr_map *map_group; struct sdap_attr_map *map_host; struct sdap_attr_map *map_hostgroup; hash_table_t *rules; hash_table_t *cmdgroups; hash_table_t *cmds; }; struct ipa_sudo_dn_list { struct ipa_sudo_dn_list *prev, *next; const char *dn; }; struct ipa_sudo_rulemember { struct ipa_sudo_dn_list *cmdgroups; struct ipa_sudo_dn_list *cmds; }; struct ipa_sudo_rule { struct sysdb_attrs *attrs; struct ipa_sudo_rulemember allow; struct ipa_sudo_rulemember deny; }; struct ipa_sudo_cmdgroup { struct ipa_sudo_dn_list *cmds; const char **expanded; }; static size_t ipa_sudo_dn_list_count(struct ipa_sudo_dn_list *list) { struct ipa_sudo_dn_list *item; size_t i; for (i = 0, item = list; item != NULL; item = item->next, i++) { /* no op */ } return i; } static errno_t ipa_sudo_conv_store(hash_table_t *table, const char *key, void *value) { hash_key_t hkey; hash_value_t hvalue; int hret; if (table == NULL || key == NULL) { return EINVAL; } hkey.type = HASH_KEY_STRING; hkey.str = discard_const(key); /* If value is NULL we don't want to override existing entry. */ if (value == NULL && hash_has_key(table, &hkey)) { return EEXIST; } hvalue.type = HASH_VALUE_PTR; hvalue.ptr = value; hret = hash_enter(table, &hkey, &hvalue); if (hret != HASH_SUCCESS) { return EIO; } if (value != NULL) { talloc_steal(table, value); } return EOK; } static void * ipa_sudo_conv_lookup(hash_table_t *table, const char *key) { hash_key_t hkey; hash_value_t hvalue; int hret; hkey.type = HASH_KEY_STRING; hkey.str = discard_const(key); hret = hash_lookup(table, &hkey, &hvalue); if (hret == HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_OP_FAILURE, "Key not found %s\n", key); return NULL; } else if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup value [%d]\n", hret); return NULL; } return hvalue.ptr; } static errno_t store_rulemember(TALLOC_CTX *mem_ctx, struct ipa_sudo_dn_list **list, hash_table_t *table, const char *dn) { struct ipa_sudo_dn_list *item; errno_t ret; item = talloc_zero(mem_ctx, struct ipa_sudo_dn_list); if (item == NULL) { return ENOMEM; } ret = ipa_sudo_conv_store(table, dn, NULL); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to store DN %s [%d]: %s\n", dn, ret, sss_strerror(ret)); goto done; } item->dn = talloc_steal(item, dn); DLIST_ADD(*list, item); done: if (ret != EOK && ret != EEXIST) { talloc_free(item); } return ret; } static bool is_ipacmdgroup(struct ipa_sudo_conv *conv, const char *dn) { if (ipa_check_rdn_bool(conv->sysdb, dn, MATCHRDN_CMDGROUPS(conv->map_cmdgroup))) { return true; } return false; } static bool is_ipacmd(struct ipa_sudo_conv *conv, const char *dn) { if (ipa_check_rdn_bool(conv->sysdb, dn, MATCHRDN_CMDS(IPA_AT_SUDOCMD_UUID, conv->map_cmd))) { return true; } /* For older versions of FreeIPA than 3.1. */ if (ipa_check_rdn_bool(conv->sysdb, dn, MATCHRDN_CMDS(IPA_AT_SUDOCMD_CMD, conv->map_cmd))) { return true; } return false; } static errno_t process_rulemember(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv, struct ipa_sudo_rulemember *rulemember, struct sysdb_attrs *rule, const char *attr) { TALLOC_CTX *tmp_ctx; const char **members; errno_t ret; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = sysdb_attrs_get_string_array(rule, attr, tmp_ctx, &members); if (ret == ENOENT) { ret = EOK; goto done; } else if (ret != EOK) { goto done; } for (i = 0; members[i] != NULL; i++) { if (is_ipacmdgroup(conv, members[i])) { ret = store_rulemember(mem_ctx, &rulemember->cmdgroups, conv->cmdgroups, members[i]); if (ret == EOK) { DEBUG(SSSDBG_TRACE_INTERNAL, "Found sudo command group %s\n", members[i]); } else if (ret != EEXIST) { goto done; } } else if (is_ipacmd(conv, members[i])) { ret = store_rulemember(mem_ctx, &rulemember->cmds, conv->cmds, members[i]); if (ret == EOK) { DEBUG(SSSDBG_TRACE_INTERNAL, "Found sudo command %s\n", members[i]); } else if (ret != EEXIST) { goto done; } } else { DEBUG(SSSDBG_MINOR_FAILURE, "Invalid member DN %s, skipping...\n", members[i]); continue; } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t process_allowcmd(struct ipa_sudo_conv *conv, struct ipa_sudo_rule *rule) { return process_rulemember(rule, conv, &rule->allow, rule->attrs, SYSDB_IPA_SUDORULE_ALLOWCMD); } static errno_t process_denycmd(struct ipa_sudo_conv *conv, struct ipa_sudo_rule *rule) { return process_rulemember(rule, conv, &rule->deny, rule->attrs, SYSDB_IPA_SUDORULE_DENYCMD); } static errno_t process_cmdgroupmember(struct ipa_sudo_conv *conv, struct ipa_sudo_cmdgroup *cmdgroup, struct sysdb_attrs *attrs) { TALLOC_CTX *tmp_ctx; struct ipa_sudo_dn_list *item; const char **members; errno_t ret; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = sysdb_attrs_get_string_array(attrs, SYSDB_MEMBER, tmp_ctx, &members); if (ret == ENOENT) { ret = EOK; goto done; } else if (ret != EOK) { goto done; } for (i = 0; members[i] != NULL; i++) { ret = ipa_sudo_conv_store(conv->cmds, members[i], NULL); if (ret == EOK) { DEBUG(SSSDBG_TRACE_INTERNAL, "Found sudo command %s\n", members[i]); } else if (ret != EEXIST) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to store DN [%d]: %s\n", ret, sss_strerror(ret)); goto done; } item = talloc_zero(tmp_ctx, struct ipa_sudo_dn_list); if (item == NULL) { ret = ENOMEM; goto done; } item->dn = talloc_steal(item, members[i]); DLIST_ADD(cmdgroup->cmds, item); talloc_steal(cmdgroup, item); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } struct ipa_sudo_conv * ipa_sudo_conv_init(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sdap_attr_map *map_rule, struct sdap_attr_map *map_cmdgroup, struct sdap_attr_map *map_cmd, struct sdap_attr_map *map_user, struct sdap_attr_map *map_group, struct sdap_attr_map *map_host, struct sdap_attr_map *map_hostgroup) { struct ipa_sudo_conv *conv; errno_t ret; conv = talloc_zero(mem_ctx, struct ipa_sudo_conv); if (conv == NULL) { return NULL; } conv->sysdb = sysdb; conv->map_rule = map_rule; conv->map_cmdgroup = map_cmdgroup; conv->map_cmd = map_cmd; conv->map_user = map_user; conv->map_group = map_group; conv->map_host = map_host; conv->map_hostgroup = map_hostgroup; ret = sss_hash_create(conv, 20, &conv->rules); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sss_hash_create(conv, 20, &conv->cmdgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sss_hash_create(conv, 20, &conv->cmds); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n", ret, sss_strerror(ret)); goto done; } done: if (ret != EOK) { talloc_free(conv); return NULL; } return conv; } errno_t ipa_sudo_conv_rules(struct ipa_sudo_conv *conv, struct sysdb_attrs **rules, size_t num_rules) { struct ipa_sudo_rule *rule = NULL; const char *key; errno_t ret; size_t i; if (num_rules == 0) { /* We're done here. */ return EOK; } for (i = 0; i < num_rules; i++) { ret = sysdb_attrs_get_string(rules[i], SYSDB_NAME, &key); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get rule name, skipping " "[%d]: %s\n", ret, sss_strerror(ret)); continue; } rule = talloc_zero(conv->rules, struct ipa_sudo_rule); if (rule == NULL) { ret = ENOMEM; goto done; } rule->attrs = rules[i]; ret = process_allowcmd(conv, rule); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_OP_FAILURE, "Failed to process memberAllowCmd " "[%d]: %s\n", ret, sss_strerror(ret)); return ret; } ret = process_denycmd(conv, rule); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_OP_FAILURE, "Failed to process memberDenyCmd " "[%d]: %s\n", ret, sss_strerror(ret)); return ret; } ret = ipa_sudo_conv_store(conv->rules, key, rule); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store rule into table " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } talloc_steal(rule, rule->attrs); rule = NULL; } ret = EOK; done: if (ret != EOK) { talloc_free(rule); } return ret; } errno_t ipa_sudo_conv_cmdgroups(struct ipa_sudo_conv *conv, struct sysdb_attrs **cmdgroups, size_t num_cmdgroups) { struct ipa_sudo_cmdgroup *cmdgroup = NULL; const char *key; errno_t ret; size_t i; if (num_cmdgroups == 0) { /* We're done here. */ return EOK; } for (i = 0; i < num_cmdgroups; i++) { ret = sysdb_attrs_get_string(cmdgroups[i], SYSDB_ORIG_DN, &key); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get command group DN, " "skipping [%d]: %s\n", ret, sss_strerror(ret)); continue; } cmdgroup = talloc_zero(conv->cmdgroups, struct ipa_sudo_cmdgroup); if (cmdgroup == NULL) { ret = ENOMEM; goto done; } ret = process_cmdgroupmember(conv, cmdgroup, cmdgroups[i]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to process member " "[%d]: %s\n", ret, sss_strerror(ret)); return ret; } ret = ipa_sudo_conv_store(conv->cmdgroups, key, cmdgroup); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store command group into " "table [%d]: %s\n", ret, sss_strerror(ret)); goto done; } cmdgroup = NULL; } ret = EOK; done: if (ret != EOK) { talloc_free(cmdgroup); } return ret; } errno_t ipa_sudo_conv_cmds(struct ipa_sudo_conv *conv, struct sysdb_attrs **cmds, size_t num_cmds) { const char *key; const char *cmd; errno_t ret; size_t i; if (num_cmds == 0) { /* We're done here. */ return EOK; } for (i = 0; i < num_cmds; i++) { ret = sysdb_attrs_get_string(cmds[i], SYSDB_ORIG_DN, &key); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get command DN, skipping " "[%d]: %s\n", ret, sss_strerror(ret)); continue; } ret = sysdb_attrs_get_string(cmds[i], SYSDB_IPA_SUDOCMD_SUDOCMD, &cmd); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get command, skipping " "[%d]: %s\n", ret, sss_strerror(ret)); continue; } ret = ipa_sudo_conv_store(conv->cmds, key, discard_const(cmd)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store command into table " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } } ret = EOK; done: return ret; } bool ipa_sudo_conv_has_cmdgroups(struct ipa_sudo_conv *conv) { return hash_count(conv->cmdgroups) == 0; } bool ipa_sudo_conv_has_cmds(struct ipa_sudo_conv *conv) { return hash_count(conv->cmds) == 0; } typedef errno_t (*ipa_sudo_conv_rdn_fn)(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, struct sysdb_ctx *sysdb, const char *dn, char **_rdn_val, const char **_rdn_attr); static errno_t get_sudo_cmdgroup_rdn(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, struct sysdb_ctx *sysdb, const char *dn, char **_rdn_val, const char **_rdn_attr) { char *rdn_val; errno_t ret; ret = ipa_get_rdn(mem_ctx, sysdb, dn, &rdn_val, MATCHRDN_CMDGROUPS(map)); if (ret != EOK) { return ret; } *_rdn_val = rdn_val; *_rdn_attr = map[IPA_AT_SUDOCMDGROUP_NAME].name; return EOK; } static errno_t get_sudo_cmd_rdn(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, struct sysdb_ctx *sysdb, const char *dn, char **_rdn_val, const char **_rdn_attr) { char *rdn_val; errno_t ret; ret = ipa_get_rdn(mem_ctx, sysdb, dn, &rdn_val, MATCHRDN_CMDS(IPA_AT_SUDOCMD_UUID, map)); if (ret == EOK) { *_rdn_val = rdn_val; *_rdn_attr = map[IPA_AT_SUDOCMD_UUID].name; return EOK; } else if (ret != ENOENT) { return ret; } /* For older versions of FreeIPA than 3.1. */ ret = ipa_get_rdn(mem_ctx, sysdb, dn, &rdn_val, MATCHRDN_CMDS(IPA_AT_SUDOCMD_CMD, map)); if (ret != EOK) { return ret; } *_rdn_val = rdn_val; *_rdn_attr = map[IPA_AT_SUDOCMD_CMD].name;; return EOK; } static char * build_filter(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, hash_table_t *table, struct sdap_attr_map *map, ipa_sudo_conv_rdn_fn rdn_fn) { TALLOC_CTX *tmp_ctx; hash_key_t *keys; unsigned long int count; unsigned long int i; char *filter; char *rdn_val; const char *rdn_attr; char *safe_rdn; errno_t ret; int hret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NULL; } hret = hash_keys(table, &count, &keys); if (hret != HASH_SUCCESS) { ret = ENOMEM; goto done; } talloc_steal(tmp_ctx, keys); filter = talloc_strdup(tmp_ctx, ""); if (filter == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < count; i++) { ret = rdn_fn(tmp_ctx, map, sysdb, keys[i].str, &rdn_val, &rdn_attr); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get member %s [%d]: %s\n", keys[i].str, ret, sss_strerror(ret)); goto done; } ret = sss_filter_sanitize(tmp_ctx, rdn_val, &safe_rdn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to sanitize DN " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } filter = talloc_asprintf_append(filter, "(%s=%s)", rdn_attr, safe_rdn); if (filter == NULL) { ret = ENOMEM; goto done; } } /* objectClass is always first */ filter = talloc_asprintf(filter, "(&(objectClass=%s)(|%s))", map[0].name, filter); if (filter == NULL) { ret = ENOMEM; goto done; } talloc_steal(mem_ctx, filter); ret = EOK; done: talloc_free(tmp_ctx); if (ret != EOK) { return NULL; } return filter; } char * ipa_sudo_conv_cmdgroup_filter(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv) { return build_filter(mem_ctx, conv->sysdb, conv->cmdgroups, conv->map_cmdgroup, get_sudo_cmdgroup_rdn); } char * ipa_sudo_conv_cmd_filter(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv) { return build_filter(mem_ctx, conv->sysdb, conv->cmds, conv->map_cmd, get_sudo_cmd_rdn); } struct ipa_sudo_conv_result_ctx { struct ipa_sudo_conv *conv; struct sysdb_attrs **rules; size_t num_rules; errno_t ret; }; static const char * convert_host(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv, const char *value) { char *rdn; const char *group; errno_t ret; ret = ipa_get_rdn(mem_ctx, conv->sysdb, value, &rdn, MATCHRDN_HOST(conv->map_host)); if (ret == EOK) { return rdn; } else if (ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_rdn() failed on value %s [%d]: %s\n", value, ret, sss_strerror(ret)); return NULL; } ret = ipa_get_rdn(mem_ctx, conv->sysdb, value, &rdn, MATCHRDN_HOSTGROUP(conv->map_hostgroup)); if (ret == ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected DN %s\n", value); return NULL; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_rdn() failed on value %s [%d]: %s\n", value, ret, sss_strerror(ret)); return NULL; } group = talloc_asprintf(mem_ctx, "+%s", rdn); talloc_free(rdn); return group; } static const char * convert_user(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv, const char *value) { char *rdn; const char *group; errno_t ret; ret = ipa_get_rdn(mem_ctx, conv->sysdb, value, &rdn, MATCHRDN_USER(conv->map_user)); if (ret == EOK) { return rdn; } else if (ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_rdn() failed on value %s [%d]: %s\n", value, ret, sss_strerror(ret)); return NULL; } ret = ipa_get_rdn(mem_ctx, conv->sysdb, value, &rdn, MATCHRDN_GROUP(conv->map_group)); if (ret == ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected DN %s\n", value); return NULL; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_rdn() failed on value %s [%d]: %s\n", value, ret, sss_strerror(ret)); return NULL; } group = talloc_asprintf(mem_ctx, "%%%s", rdn); talloc_free(rdn); return group; } static const char * convert_group(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv, const char *value) { char *rdn; errno_t ret; ret = ipa_get_rdn(mem_ctx, conv->sysdb, value, &rdn, MATCHRDN_GROUP(conv->map_group)); if (ret == ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected DN %s\n", value); return NULL; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_rdn() failed on value %s [%d]: %s\n", value, ret, sss_strerror(ret)); return NULL; } return rdn; } static const char * convert_runasextusergroup(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv, const char *value) { return talloc_asprintf(mem_ctx, "%%%s", value); } static const char * convert_cat(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv, const char *value) { if (strcmp(value, "all") == 0) { return talloc_strdup(mem_ctx, "ALL"); } return value; } static errno_t convert_attributes(struct ipa_sudo_conv *conv, struct ipa_sudo_rule *rule, struct sysdb_attrs *attrs) { TALLOC_CTX *tmp_ctx; const char **values; const char *value; errno_t ret; int i, j; static struct { const char *ipa; const char *sudo; const char *(*conv_fn)(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv, const char *value); } table[] = {{SYSDB_NAME, SYSDB_SUDO_CACHE_AT_CN , NULL}, {SYSDB_IPA_SUDORULE_HOST, SYSDB_SUDO_CACHE_AT_HOST , convert_host}, {SYSDB_IPA_SUDORULE_USER, SYSDB_SUDO_CACHE_AT_USER , convert_user}, {SYSDB_IPA_SUDORULE_RUNASUSER, SYSDB_SUDO_CACHE_AT_RUNASUSER , convert_user}, {SYSDB_IPA_SUDORULE_RUNASGROUP, SYSDB_SUDO_CACHE_AT_RUNASGROUP , convert_group}, {SYSDB_IPA_SUDORULE_OPTION, SYSDB_SUDO_CACHE_AT_OPTION , NULL}, {SYSDB_IPA_SUDORULE_NOTAFTER, SYSDB_SUDO_CACHE_AT_NOTAFTER , NULL}, {SYSDB_IPA_SUDORULE_NOTBEFORE, SYSDB_SUDO_CACHE_AT_NOTBEFORE , NULL}, {SYSDB_IPA_SUDORULE_SUDOORDER, SYSDB_SUDO_CACHE_AT_ORDER , NULL}, {SYSDB_IPA_SUDORULE_CMDCATEGORY, SYSDB_SUDO_CACHE_AT_COMMAND , convert_cat}, {SYSDB_IPA_SUDORULE_HOSTCATEGORY, SYSDB_SUDO_CACHE_AT_HOST , convert_cat}, {SYSDB_IPA_SUDORULE_USERCATEGORY, SYSDB_SUDO_CACHE_AT_USER , convert_cat}, {SYSDB_IPA_SUDORULE_RUNASUSERCATEGORY, SYSDB_SUDO_CACHE_AT_RUNASUSER , convert_cat}, {SYSDB_IPA_SUDORULE_RUNASGROUPCATEGORY, SYSDB_SUDO_CACHE_AT_RUNASGROUP , convert_cat}, {SYSDB_IPA_SUDORULE_RUNASEXTUSER, SYSDB_SUDO_CACHE_AT_RUNASUSER , NULL}, {SYSDB_IPA_SUDORULE_RUNASEXTGROUP, SYSDB_SUDO_CACHE_AT_RUNASGROUP , NULL}, {SYSDB_IPA_SUDORULE_RUNASEXTUSERGROUP, SYSDB_SUDO_CACHE_AT_RUNASUSER , convert_runasextusergroup}, {SYSDB_IPA_SUDORULE_EXTUSER, SYSDB_SUDO_CACHE_AT_USER , NULL}, {SYSDB_IPA_SUDORULE_ALLOWCMD, SYSDB_IPA_SUDORULE_ORIGCMD , NULL}, {SYSDB_IPA_SUDORULE_DENYCMD, SYSDB_IPA_SUDORULE_ORIGCMD , NULL}, {NULL, NULL, NULL}}; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } for (i = 0; table[i].ipa != NULL; i++) { ret = sysdb_attrs_get_string_array(rule->attrs, table[i].ipa, tmp_ctx, &values); if (ret == ENOENT) { continue; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read attribute " "%s [%d]: %s\n", table[i].ipa, ret, sss_strerror(ret)); goto done; } for (j = 0; values[j] != NULL; j++) { if (table[i].conv_fn != NULL) { value = table[i].conv_fn(tmp_ctx, conv, values[j]); if (value == NULL) { ret = ENOMEM; goto done; } } else { value = values[j]; } ret = sysdb_attrs_add_string_safe(attrs, table[i].sudo, value); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add attribute " "%s [%d]: %s\n", table[i].sudo, ret, sss_strerror(ret)); goto done; } } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static const char ** combine_cmdgroups(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv, struct ipa_sudo_dn_list *list) { TALLOC_CTX *tmp_ctx; struct ipa_sudo_cmdgroup *cmdgroup; struct ipa_sudo_dn_list *listitem; const char **values = NULL; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NULL; } values = talloc_zero_array(tmp_ctx, const char *, 1); if (values == NULL) { talloc_free(tmp_ctx); return NULL; } DLIST_FOR_EACH(listitem, list) { cmdgroup = ipa_sudo_conv_lookup(conv->cmdgroups, listitem->dn); ret = add_strings_lists(mem_ctx, values, cmdgroup->expanded, false, discard_const(&values)); if (ret != EOK) { talloc_free(tmp_ctx); return NULL; } } talloc_steal(mem_ctx, values); talloc_free(tmp_ctx); return values; } static const char ** combine_cmds(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv, struct ipa_sudo_dn_list *list) { struct ipa_sudo_dn_list *listitem; const char **values; const char *command; size_t count; size_t i; count = ipa_sudo_dn_list_count(list); values = talloc_zero_array(mem_ctx, const char *, count + 1); if (values == NULL) { return NULL; } i = 0; DLIST_FOR_EACH(listitem, list) { command = ipa_sudo_conv_lookup(conv->cmds, listitem->dn); if (command == NULL) { continue; } values[i] = command; i++; } return values; } static errno_t build_sudocommand(struct ipa_sudo_conv *conv, struct ipa_sudo_rulemember *mlist, struct sysdb_attrs *attrs, char prefix) { TALLOC_CTX *tmp_ctx; const char **cmds[2]; const char *command; errno_t ret; int i, j; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } cmds[0] = combine_cmdgroups(tmp_ctx, conv, mlist->cmdgroups); if (cmds[0] == NULL) { ret = ENOMEM; goto done; } cmds[1] = combine_cmds(tmp_ctx, conv, mlist->cmds); if (cmds[1] == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < 2; i++) { for (j = 0; cmds[i][j] != NULL; j++) { if (prefix == '\0') { command = cmds[i][j]; } else { command = talloc_asprintf(tmp_ctx, "%c%s", prefix, cmds[i][j]); if (command == NULL) { ret = ENOMEM; goto done; } } ret = sysdb_attrs_add_string_safe(attrs, SYSDB_SUDO_CACHE_AT_COMMAND, command); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add attribute " "%s [%d]: %s\n", SYSDB_SUDO_CACHE_AT_COMMAND, ret, sss_strerror(ret)); goto done; } } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t convert_sudocommand(struct ipa_sudo_conv *conv, struct ipa_sudo_rule *rule, struct sysdb_attrs *attrs) { TALLOC_CTX *tmp_ctx; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = build_sudocommand(conv, &rule->allow, attrs, '\0'); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build allow commands " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = build_sudocommand(conv, &rule->deny, attrs, '!'); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build deny commands " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static bool rules_iterator(hash_entry_t *item, void *user_data) { struct ipa_sudo_conv_result_ctx *ctx = user_data; struct ipa_sudo_rule *rule = item->value.ptr; struct sysdb_attrs *attrs; if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: ctx is NULL\n"); return false; } if (rule == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: rule is NULL\n"); ctx->ret = ERR_INTERNAL; return false; } attrs = sysdb_new_attrs(ctx->rules); if (attrs == NULL) { ctx->ret = ENOMEM; return false; } ctx->ret = convert_attributes(ctx->conv, rule, attrs); if (ctx->ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to convert attributes [%d]: %s\n", ctx->ret, sss_strerror(ctx->ret)); talloc_free(attrs); return false; } ctx->ret = convert_sudocommand(ctx->conv, rule, attrs); if (ctx->ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to build sudoCommand [%d]: %s\n", ctx->ret, sss_strerror(ctx->ret)); talloc_free(attrs); return false; } ctx->rules[ctx->num_rules] = attrs; ctx->num_rules++; return true; } static bool cmdgroups_iterator(hash_entry_t *item, void *user_data) { struct ipa_sudo_conv_result_ctx *ctx = user_data; struct ipa_sudo_cmdgroup *cmdgroup = item->value.ptr; const char **values; if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: ctx is NULL\n"); return false; } if (cmdgroup == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: rule is NULL\n"); ctx->ret = ERR_INTERNAL; return false; } values = combine_cmds(cmdgroup, ctx->conv, cmdgroup->cmds); if (values == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to expand commands\n"); ctx->ret = ENOMEM; return false; } cmdgroup->expanded = values; ctx->ret = EOK; return true; } errno_t ipa_sudo_conv_result(TALLOC_CTX *mem_ctx, struct ipa_sudo_conv *conv, struct sysdb_attrs ***_rules, size_t *_num_rules) { struct ipa_sudo_conv_result_ctx ctx; struct sysdb_attrs **rules; unsigned long num_rules; int hret; num_rules = hash_count(conv->rules); if (num_rules == 0) { *_rules = NULL; *_num_rules = 0; return EOK; } ctx.conv = conv; ctx.rules = NULL; ctx.num_rules = 0; /* If there are no cmdgroups the iterator is not called and ctx.ret is * uninitialized. Since it is ok that there are no cmdgroups initializing * ctx.ret to EOK. */ ctx.ret = EOK; /* Expand commands in command groups. */ hret = hash_iterate(conv->cmdgroups, cmdgroups_iterator, &ctx); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Unable to iterate over command groups " "[%d]\n", hret); return EIO; } if (ctx.ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to expand command groups " "[%d]: %s\n", ctx.ret, sss_strerror(ctx.ret)); return ctx.ret; } /* Convert rules. */ rules = talloc_zero_array(mem_ctx, struct sysdb_attrs *, num_rules); if (rules == NULL) { return ENOMEM; } ctx.rules = rules; ctx.num_rules = 0; hret = hash_iterate(conv->rules, rules_iterator, &ctx); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Unable to iterate over rules [%d]\n", hret); return EIO; } if (ctx.ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to convert rules [%d]: %s\n", ctx.ret, sss_strerror(ctx.ret)); talloc_free(rules); return ctx.ret; } *_rules = ctx.rules; *_num_rules = ctx.num_rules; return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_s2n_exop.c0000644000000000000000000000007312703456111020433 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.738793913 sssd-1.13.4/src/providers/ipa/ipa_s2n_exop.c0000644002412700241270000023204312703456111022107 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Helper routines - external users and groups with s2n plugin Copyright (C) Sumit Bose - 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/sss_nss.h" #include "db/sysdb.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/ldap_common.h" #include "providers/ipa/ipa_id.h" #include "providers/ipa/ipa_subdomains.h" enum input_types { INP_SID = 1, INP_NAME, INP_POSIX_UID, INP_POSIX_GID }; enum request_types { REQ_SIMPLE = 1, REQ_FULL, REQ_FULL_WITH_MEMBERS }; enum response_types { RESP_SID = 1, RESP_NAME, RESP_USER, RESP_GROUP, RESP_USER_GROUPLIST, RESP_GROUP_MEMBERS }; /* ==Sid2Name Extended Operation============================================= */ struct ipa_s2n_exop_state { struct sdap_handle *sh; struct sdap_op *op; char *retoid; struct berval *retdata; }; static void ipa_s2n_exop_done(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt); static struct tevent_req *ipa_s2n_exop_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, bool is_v1, int timeout, struct berval *bv) { struct tevent_req *req = NULL; struct ipa_s2n_exop_state *state; int ret; int msgid; req = tevent_req_create(mem_ctx, &state, struct ipa_s2n_exop_state); if (!req) return NULL; state->sh = sh; state->retoid = NULL; state->retdata = NULL; DEBUG(SSSDBG_TRACE_FUNC, "Executing extended operation\n"); ret = ldap_extended_operation(state->sh->ldap, is_v1 ? EXOP_SID2NAME_V1_OID : EXOP_SID2NAME_OID, bv, NULL, NULL, &msgid); if (ret == -1 || msgid == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_extended_operation failed\n"); ret = ERR_NETWORK_IO; goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "ldap_extended_operation sent, msgid = %d\n", msgid); ret = sdap_op_add(state, ev, state->sh, msgid, ipa_s2n_exop_done, req, timeout, &state->op); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set up operation!\n"); ret = ERR_INTERNAL; goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void ipa_s2n_exop_done(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct ipa_s2n_exop_state *state = tevent_req_data(req, struct ipa_s2n_exop_state); int ret; char *errmsg = NULL; char *retoid = NULL; struct berval *retdata = NULL; int result; if (error) { tevent_req_error(req, error); return; } ret = ldap_parse_result(state->sh->ldap, reply->msg, &result, NULL, &errmsg, NULL, NULL, 0); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldap_parse_result failed (%d)\n", state->op->msgid); ret = ERR_NETWORK_IO; goto done; } DEBUG(result == LDAP_SUCCESS ? SSSDBG_TRACE_FUNC : SSSDBG_OP_FAILURE, "ldap_extended_operation result: %s(%d), %s.\n", sss_ldap_err2string(result), result, errmsg); if (result != LDAP_SUCCESS) { if (result == LDAP_NO_SUCH_OBJECT) { ret = ENOENT; } else { DEBUG(SSSDBG_OP_FAILURE, "ldap_extended_operation failed, server " \ "logs might contain more details.\n"); ret = ERR_NETWORK_IO; } goto done; } ret = ldap_parse_extended_result(state->sh->ldap, reply->msg, &retoid, &retdata, 0); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldap_parse_extendend_result failed (%d)\n", ret); ret = ERR_NETWORK_IO; goto done; } if (retdata == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing exop result data.\n"); ret = EINVAL; goto done; } state->retoid = talloc_strdup(state, retoid); if (state->retoid == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } state->retdata = talloc(state, struct berval); if (state->retdata == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc failed.\n"); ret = ENOMEM; goto done; } state->retdata->bv_len = retdata->bv_len; state->retdata->bv_val = talloc_memdup(state->retdata, retdata->bv_val, retdata->bv_len); if (state->retdata->bv_val == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_memdup failed.\n"); ret = ENOMEM; goto done; } ret = EOK; done: ldap_memfree(errmsg); ldap_memfree(retoid); ber_bvfree(retdata); if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } static int ipa_s2n_exop_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **retoid, struct berval **retdata) { struct ipa_s2n_exop_state *state = tevent_req_data(req, struct ipa_s2n_exop_state); TEVENT_REQ_RETURN_ON_ERROR(req); *retoid = talloc_steal(mem_ctx, state->retoid); *retdata = talloc_steal(mem_ctx, state->retdata); return EOK; } static errno_t talloc_ber_flatten(TALLOC_CTX *mem_ctx, BerElement *ber, struct berval **_bv) { int ret; struct berval *bv = NULL; struct berval *tbv = NULL; ret = ber_flatten(ber, &bv); if (ret == -1) { ret = EFAULT; goto done; } tbv = talloc_zero(mem_ctx, struct berval); if (tbv == NULL) { ret = ENOMEM; goto done; } tbv->bv_len = bv->bv_len; tbv->bv_val = talloc_memdup(tbv, bv->bv_val, bv->bv_len); if (tbv->bv_val == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: ber_bvfree(bv); if (ret == EOK) { *_bv = tbv; } else { talloc_free(tbv); } return ret; } /* The extended operation expect the following ASN.1 encoded request data: * * ExtdomRequestValue ::= SEQUENCE { * inputType ENUMERATED { * sid (1), * name (2), * posix uid (3), * posix gid (3) * }, * requestType ENUMERATED { * simple (1), * full (2) * full_with_members (3) * }, * data InputData * } * * InputData ::= CHOICE { * sid OCTET STRING, * name NameDomainData * uid PosixUid, * gid PosixGid * } * * NameDomainData ::= SEQUENCE { * domain_name OCTET STRING, * object_name OCTET STRING * } * * PosixUid ::= SEQUENCE { * domain_name OCTET STRING, * uid INTEGER * } * * PosixGid ::= SEQUENCE { * domain_name OCTET STRING, * gid INTEGER * } * */ static errno_t s2n_encode_request(TALLOC_CTX *mem_ctx, const char *domain_name, int entry_type, enum request_types request_type, struct req_input *req_input, struct berval **_bv) { BerElement *ber = NULL; int ret; ber = ber_alloc_t( LBER_USE_DER ); if (ber == NULL) { return ENOMEM; } switch (entry_type) { case BE_REQ_USER: case BE_REQ_USER_AND_GROUP: /* the extdom exop does not care if the ID belongs to a user or a group */ if (req_input->type == REQ_INP_NAME) { ret = ber_printf(ber, "{ee{ss}}", INP_NAME, request_type, domain_name, req_input->inp.name); } else if (req_input->type == REQ_INP_ID) { ret = ber_printf(ber, "{ee{si}}", INP_POSIX_UID, request_type, domain_name, req_input->inp.id); } else { DEBUG(SSSDBG_OP_FAILURE, "Unexpected input type [%d].\n", req_input->type == REQ_INP_ID); ret = EINVAL; goto done; } break; case BE_REQ_GROUP: if (req_input->type == REQ_INP_NAME) { ret = ber_printf(ber, "{ee{ss}}", INP_NAME, request_type, domain_name, req_input->inp.name); } else if (req_input->type == REQ_INP_ID) { ret = ber_printf(ber, "{ee{si}}", INP_POSIX_GID, request_type, domain_name, req_input->inp.id); } else { DEBUG(SSSDBG_OP_FAILURE, "Unexpected input type [%d].\n", req_input->type == REQ_INP_ID); ret = EINVAL; goto done; } break; case BE_REQ_BY_SECID: if (req_input->type == REQ_INP_SECID) { ret = ber_printf(ber, "{ees}", INP_SID, request_type, req_input->inp.secid); } else { DEBUG(SSSDBG_OP_FAILURE, "Unexpected input type [%d].\n", req_input->type == REQ_INP_ID); ret = EINVAL; goto done; } break; default: ret = EINVAL; goto done; } if (ret == -1) { ret = EFAULT; goto done; } ret = talloc_ber_flatten(mem_ctx, ber, _bv); if (ret != EOK) { goto done; } ret = EOK; done: ber_free(ber, 1); return ret; } /* If the extendend operation is successful it returns the following ASN.1 * encoded response: * * ExtdomResponseValue ::= SEQUENCE { * responseType ENUMERATED { * sid (1), * name (2), * posix_user (3), * posix_group (4), * posix_user_grouplist (5), * posix_group_members (6) * }, * data OutputData * } * * OutputData ::= CHOICE { * sid OCTET STRING, * name NameDomainData, * user PosixUser, * group PosixGroup, * usergrouplist PosixUserGrouplist, * groupmembers PosixGroupMembers * * } * * NameDomainData ::= SEQUENCE { * domain_name OCTET STRING, * object_name OCTET STRING * } * * PosixUser ::= SEQUENCE { * domain_name OCTET STRING, * user_name OCTET STRING, * uid INTEGER * gid INTEGER * } * * PosixGroup ::= SEQUENCE { * domain_name OCTET STRING, * group_name OCTET STRING, * gid INTEGER * } * * PosixUserGrouplist ::= SEQUENCE { * domain_name OCTET STRING, * user_name OCTET STRING, * uid INTEGER, * gid INTEGER, * gecos OCTET STRING, * home_directory OCTET STRING, * shell OCTET STRING, * grouplist GroupNameList * } * * GroupNameList ::= SEQUENCE OF OCTET STRING * * PosixGroupMembers ::= SEQUENCE { * domain_name OCTET STRING, * group_name OCTET STRING, * gid INTEGER, * members GroupMemberList * } * * GroupMemberList ::= SEQUENCE OF OCTET STRING */ struct resp_attrs { enum response_types response_type; char *domain_name; union { struct passwd user; struct group group; char *sid_str; char *name; } a; size_t ngroups; char **groups; struct sysdb_attrs *sysdb_attrs; }; static errno_t get_extra_attrs(BerElement *ber, struct resp_attrs *resp_attrs) { ber_tag_t tag; ber_len_t ber_len; char *ber_cookie; char *name; struct berval **values; struct ldb_val v; int ret; size_t c; if (resp_attrs->sysdb_attrs == NULL) { resp_attrs->sysdb_attrs = sysdb_new_attrs(resp_attrs); if (resp_attrs->sysdb_attrs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); return ENOMEM; } } DEBUG(SSSDBG_TRACE_ALL, "Found new sequence.\n"); for (tag = ber_first_element(ber, &ber_len, &ber_cookie); tag != LBER_DEFAULT; tag = ber_next_element(ber, &ber_len, ber_cookie)) { tag = ber_scanf(ber, "{a{V}}", &name, &values); if (tag == LBER_ERROR) { DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n"); return EINVAL; } DEBUG(SSSDBG_TRACE_ALL, "Extra attribute [%s].\n", name); for (c = 0; values[c] != NULL; c++) { v.data = (uint8_t *) values[c]->bv_val; v.length = values[c]->bv_len; ret = sysdb_attrs_add_val(resp_attrs->sysdb_attrs, name, &v); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_val failed.\n"); ldap_memfree(name); ber_bvecfree(values); return ret; } } ldap_memfree(name); ber_bvecfree(values); } return EOK; } static errno_t add_v1_user_data(BerElement *ber, struct resp_attrs *attrs) { ber_tag_t tag; ber_len_t ber_len; int ret; char *gecos = NULL; char *homedir = NULL; char *shell = NULL; char **list = NULL; size_t c; tag = ber_scanf(ber, "aaa", &gecos, &homedir, &shell); if (tag == LBER_ERROR) { DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n"); ret = EINVAL; goto done; } if (gecos == NULL || *gecos == '\0') { attrs->a.user.pw_gecos = NULL; } else { attrs->a.user.pw_gecos = talloc_strdup(attrs, gecos); if (attrs->a.user.pw_gecos == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } if (homedir == NULL || *homedir == '\0') { attrs->a.user.pw_dir = NULL; } else { attrs->a.user.pw_dir = talloc_strdup(attrs, homedir); if (attrs->a.user.pw_dir == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } if (shell == NULL || *shell == '\0') { attrs->a.user.pw_shell = NULL; } else { attrs->a.user.pw_shell = talloc_strdup(attrs, shell); if (attrs->a.user.pw_shell == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } tag = ber_scanf(ber, "{v}", &list); if (tag == LBER_ERROR) { DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n"); ret = EINVAL; goto done; } for (attrs->ngroups = 0; list[attrs->ngroups] != NULL; attrs->ngroups++); if (attrs->ngroups > 0) { attrs->groups = talloc_zero_array(attrs, char *, attrs->ngroups + 1); if (attrs->groups == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } for (c = 0; c < attrs->ngroups; c++) { attrs->groups[c] = talloc_strdup(attrs->groups, list[c]); if (attrs->groups[c] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } } tag = ber_peek_tag(ber, &ber_len); DEBUG(SSSDBG_TRACE_ALL, "BER tag is [%d]\n", (int) tag); if (tag == LBER_SEQUENCE) { ret = get_extra_attrs(ber, attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_extra_attrs failed.\n"); goto done; } } ret = EOK; done: ber_memfree(gecos); ber_memfree(homedir); ber_memfree(shell); ber_memvfree((void **) list); return ret; } static errno_t add_v1_group_data(BerElement *ber, struct resp_attrs *attrs) { ber_tag_t tag; ber_len_t ber_len; int ret; char **list = NULL; size_t c; tag = ber_scanf(ber, "{v}", &list); if (tag == LBER_ERROR) { DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n"); ret = EINVAL; goto done; } if (list != NULL) { for (attrs->ngroups = 0; list[attrs->ngroups] != NULL; attrs->ngroups++); if (attrs->ngroups > 0) { attrs->a.group.gr_mem = talloc_zero_array(attrs, char *, attrs->ngroups + 1); if (attrs->a.group.gr_mem == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } for (c = 0; c < attrs->ngroups; c++) { attrs->a.group.gr_mem[c] = talloc_strdup(attrs->a.group.gr_mem, list[c]); if (attrs->a.group.gr_mem[c] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } } } else { attrs->a.group.gr_mem = talloc_zero_array(attrs, char *, 1); if (attrs->a.group.gr_mem == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } } tag = ber_peek_tag(ber, &ber_len); DEBUG(SSSDBG_TRACE_ALL, "BER tag is [%d]\n", (int) tag); if (tag == LBER_SEQUENCE) { ret = get_extra_attrs(ber, attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_extra_attrs failed.\n"); goto done; } } ret = EOK; done: ber_memvfree((void **) list); return ret; } static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, struct req_input *req_input, struct resp_attrs *attrs, struct resp_attrs *simple_attrs, const char *view_name, struct sysdb_attrs *override_attrs, bool update_initgr_timeout); static errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx, char *retoid, struct berval *retdata, struct resp_attrs **resp_attrs) { BerElement *ber = NULL; ber_tag_t tag; int ret; enum response_types type; char *domain_name = NULL; char *name = NULL; uid_t uid; gid_t gid; struct resp_attrs *attrs = NULL; char *sid_str; bool is_v1 = false; if (retoid == NULL || retdata == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing OID or data.\n"); return EINVAL; } if (strcmp(retoid, EXOP_SID2NAME_V1_OID) == 0) { is_v1 = true; } else if (strcmp(retoid, EXOP_SID2NAME_OID) == 0) { is_v1 = false; } else { DEBUG(SSSDBG_OP_FAILURE, "Result has wrong OID, expected [%s] or [%s], got [%s].\n", EXOP_SID2NAME_OID, EXOP_SID2NAME_V1_OID, retoid); return EINVAL; } ber = ber_init(retdata); if (ber == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ber_init failed.\n"); return EINVAL; } tag = ber_scanf(ber, "{e", &type); if (tag == LBER_ERROR) { DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n"); ret = EINVAL; goto done; } attrs = talloc_zero(mem_ctx, struct resp_attrs); if (attrs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; goto done; } switch (type) { case RESP_USER: case RESP_USER_GROUPLIST: tag = ber_scanf(ber, "{aaii", &domain_name, &name, &uid, &gid); if (tag == LBER_ERROR) { DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n"); ret = EINVAL; goto done; } /* Winbind is not consistent with the case of the returned user * name. In general all names should be lower case but there are * bug in some version of winbind which might lead to upper case * letters in the name. To be on the safe side we explicitly * lowercase the name. */ attrs->a.user.pw_name = sss_tc_utf8_str_tolower(attrs, name); if (attrs->a.user.pw_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } attrs->a.user.pw_uid = uid; attrs->a.user.pw_gid = gid; if (is_v1 && type == RESP_USER_GROUPLIST) { ret = add_v1_user_data(ber, attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_v1_user_data failed.\n"); goto done; } } tag = ber_scanf(ber, "}}"); if (tag == LBER_ERROR) { DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n"); ret = EINVAL; goto done; } break; case RESP_GROUP: case RESP_GROUP_MEMBERS: tag = ber_scanf(ber, "{aai", &domain_name, &name, &gid); if (tag == LBER_ERROR) { DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n"); ret = EINVAL; goto done; } /* Winbind is not consistent with the case of the returned user * name. In general all names should be lower case but there are * bug in some version of winbind which might lead to upper case * letters in the name. To be on the safe side we explicitly * lowercase the name. */ attrs->a.group.gr_name = sss_tc_utf8_str_tolower(attrs, name); if (attrs->a.group.gr_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } attrs->a.group.gr_gid = gid; if (is_v1 && type == RESP_GROUP_MEMBERS) { ret = add_v1_group_data(ber, attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_v1_group_data failed.\n"); goto done; } } tag = ber_scanf(ber, "}}"); if (tag == LBER_ERROR) { DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n"); ret = EINVAL; goto done; } break; case RESP_SID: tag = ber_scanf(ber, "a}", &sid_str); if (tag == LBER_ERROR) { DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n"); ret = EINVAL; goto done; } attrs->a.sid_str = talloc_strdup(attrs, sid_str); if (attrs->a.sid_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } break; case RESP_NAME: tag = ber_scanf(ber, "{aa}", &domain_name, &name); if (tag == LBER_ERROR) { DEBUG(SSSDBG_OP_FAILURE, "ber_scanf failed.\n"); ret = EINVAL; goto done; } attrs->a.name = sss_tc_utf8_str_tolower(attrs, name); if (attrs->a.name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_tc_utf8_str_tolower failed.\n"); ret = ENOMEM; goto done; } break; default: DEBUG(SSSDBG_OP_FAILURE, "Unexpected response type [%d].\n", type); ret = EINVAL; goto done; } attrs->response_type = type; if (type != RESP_SID) { attrs->domain_name = talloc_strdup(attrs, domain_name); if (attrs->domain_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } ret = EOK; done: ber_memfree(domain_name); ber_memfree(name); ber_free(ber, 1); if (ret == EOK) { *resp_attrs = attrs; } else { talloc_free(attrs); } return ret; } struct ipa_s2n_get_fqlist_state { struct tevent_context *ev; struct ipa_id_ctx *ipa_ctx; struct sss_domain_info *dom; struct sdap_handle *sh; struct req_input req_input; char **fqname_list; size_t fqname_idx; int exop_timeout; int entry_type; enum request_types request_type; struct resp_attrs *attrs; struct sss_domain_info *obj_domain; struct sysdb_attrs *override_attrs; }; static errno_t ipa_s2n_get_fqlist_step(struct tevent_req *req); static void ipa_s2n_get_fqlist_get_override_done(struct tevent_req *subreq); static void ipa_s2n_get_fqlist_next(struct tevent_req *subreq); static errno_t ipa_s2n_get_fqlist_save_step(struct tevent_req *req); static struct tevent_req *ipa_s2n_get_fqlist_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct sss_domain_info *dom, struct sdap_handle *sh, int exop_timeout, int entry_type, enum request_types request_type, char **fqname_list) { int ret; struct ipa_s2n_get_fqlist_state *state; struct tevent_req *req; req = tevent_req_create(mem_ctx, &state, struct ipa_s2n_get_fqlist_state); if (req == NULL) { return NULL; } state->ev = ev; state->ipa_ctx = ipa_ctx; state->dom = dom; state->sh = sh; state->fqname_list = fqname_list; state->fqname_idx = 0; state->req_input.type = REQ_INP_NAME; state->req_input.inp.name = NULL; state->exop_timeout = exop_timeout; state->entry_type = entry_type; state->request_type = request_type; state->attrs = NULL; state->override_attrs = NULL; ret = ipa_s2n_get_fqlist_step(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_get_fqlist_step failed.\n"); goto done; } done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static errno_t ipa_s2n_get_fqlist_step(struct tevent_req *req) { int ret; struct ipa_s2n_get_fqlist_state *state = tevent_req_data(req, struct ipa_s2n_get_fqlist_state); struct berval *bv_req; struct tevent_req *subreq; struct sss_domain_info *parent_domain; char *short_name = NULL; char *domain_name = NULL; parent_domain = get_domains_head(state->dom); ret = sss_parse_name(state, parent_domain->names, state->fqname_list[state->fqname_idx], &domain_name, &short_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name '%s' [%d]: %s\n", state->fqname_list[state->fqname_idx], ret, sss_strerror(ret)); return ret; } if (domain_name) { state->obj_domain = find_domain_by_name(parent_domain, domain_name, true); if (state->obj_domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed.\n"); return ENOMEM; } } else { state->obj_domain = parent_domain; } state->req_input.inp.name = short_name; ret = s2n_encode_request(state, state->obj_domain->name, state->entry_type, state->request_type, &state->req_input, &bv_req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "s2n_encode_request failed.\n"); return ret; } subreq = ipa_s2n_exop_send(state, state->ev, state->sh, true, state->exop_timeout, bv_req); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_exop_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, ipa_s2n_get_fqlist_next, req); return EOK; } static void ipa_s2n_get_fqlist_next(struct tevent_req *subreq) { int ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_s2n_get_fqlist_state *state = tevent_req_data(req, struct ipa_s2n_get_fqlist_state); char *retoid = NULL; struct berval *retdata = NULL; const char *sid_str; struct be_acct_req *ar; ret = ipa_s2n_exop_recv(subreq, state, &retoid, &retdata); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "s2n exop request failed.\n"); goto fail; } talloc_zfree(state->attrs); ret = s2n_response_to_attrs(state, retoid, retdata, &state->attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "s2n_response_to_attrs failed.\n"); goto fail; } if (is_default_view(state->ipa_ctx->view_name)) { ret = ipa_s2n_get_fqlist_save_step(req); if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_get_fqlist_save_step failed.\n"); goto fail; } return; } ret = sysdb_attrs_get_string(state->attrs->sysdb_attrs, SYSDB_SID_STR, &sid_str); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto fail; } ret = get_be_acct_req_for_sid(state, sid_str, state->obj_domain->name, &ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); goto fail; } subreq = ipa_get_ad_override_send(state, state->ev, state->ipa_ctx->sdap_id_ctx, state->ipa_ctx->ipa_options, dp_opt_get_string(state->ipa_ctx->ipa_options->basic, IPA_KRB5_REALM), state->ipa_ctx->view_name, ar); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_s2n_get_fqlist_get_override_done, req); return; fail: tevent_req_error(req,ret); return; } static void ipa_s2n_get_fqlist_get_override_done(struct tevent_req *subreq) { int ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_s2n_get_fqlist_state *state = tevent_req_data(req, struct ipa_s2n_get_fqlist_state); ret = ipa_get_ad_override_recv(subreq, NULL, state, &state->override_attrs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); goto fail; } ret = ipa_s2n_get_fqlist_save_step(req); if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_get_fqlist_save_step failed.\n"); goto fail; } return; fail: tevent_req_error(req,ret); return; } static errno_t ipa_s2n_get_fqlist_save_step(struct tevent_req *req) { int ret; struct ipa_s2n_get_fqlist_state *state = tevent_req_data(req, struct ipa_s2n_get_fqlist_state); ret = ipa_s2n_save_objects(state->dom, &state->req_input, state->attrs, NULL, state->ipa_ctx->view_name, state->override_attrs, false); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n"); return ret; } state->fqname_idx++; if (state->fqname_list[state->fqname_idx] == NULL) { return EOK; } ret = ipa_s2n_get_fqlist_step(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_get_fqlist_step failed.\n"); return ret; } return EAGAIN; } static int ipa_s2n_get_fqlist_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct ipa_s2n_get_user_state { struct tevent_context *ev; struct ipa_id_ctx *ipa_ctx; struct sdap_options *opts; struct sss_domain_info *dom; struct sdap_handle *sh; struct req_input *req_input; int entry_type; enum request_types request_type; struct resp_attrs *attrs; struct resp_attrs *simple_attrs; struct sysdb_attrs *override_attrs; int exop_timeout; }; static void ipa_s2n_get_user_done(struct tevent_req *subreq); struct tevent_req *ipa_s2n_get_acct_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct sdap_options *opts, struct sss_domain_info *dom, struct sysdb_attrs *override_attrs, struct sdap_handle *sh, int entry_type, struct req_input *req_input) { struct ipa_s2n_get_user_state *state; struct tevent_req *req; struct tevent_req *subreq; struct berval *bv_req = NULL; int ret = EFAULT; bool is_v1 = false; req = tevent_req_create(mem_ctx, &state, struct ipa_s2n_get_user_state); if (req == NULL) { return NULL; } state->ev = ev; state->ipa_ctx = ipa_ctx; state->opts = opts; state->dom = dom; state->sh = sh; state->req_input = req_input; state->entry_type = entry_type; state->attrs = NULL; state->simple_attrs = NULL; state->exop_timeout = dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT); state->override_attrs = override_attrs; if (sdap_is_extension_supported(sh, EXOP_SID2NAME_V1_OID)) { state->request_type = REQ_FULL_WITH_MEMBERS; is_v1 = true; } else if (sdap_is_extension_supported(sh, EXOP_SID2NAME_OID)) { state->request_type = REQ_FULL; is_v1 = false; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Extdom not supported on the server, " "cannot resolve objects from trusted domains.\n"); ret = EIO; goto fail; } ret = s2n_encode_request(state, dom->name, entry_type, state->request_type, req_input, &bv_req); if (ret != EOK) { goto fail; } subreq = ipa_s2n_exop_send(state, state->ev, state->sh, is_v1, state->exop_timeout, bv_req); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_exop_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_s2n_get_user_done, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static errno_t process_members(struct sss_domain_info *domain, struct sysdb_attrs *group_attrs, char **members, TALLOC_CTX *mem_ctx, char ***_missing_members) { int ret; size_t c; TALLOC_CTX *tmp_ctx; struct ldb_message *msg; const char *dn_str; struct sss_domain_info *obj_domain; struct sss_domain_info *parent_domain; char **missing_members = NULL; size_t miss_count = 0; if (members == NULL) { DEBUG(SSSDBG_TRACE_INTERNAL, "No members\n"); if (_missing_members != NULL) { *_missing_members = NULL; } return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } if (_missing_members != NULL && mem_ctx != NULL) { /* count members */ for (c = 0; members[c] != NULL; c++); missing_members = talloc_zero_array(tmp_ctx, char *, c + 1); if (missing_members == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array_zero failed.\n"); ret = ENOMEM; goto done; } } parent_domain = get_domains_head(domain); for (c = 0; members[c] != NULL; c++) { obj_domain = find_domain_by_object_name(parent_domain, members[c]); if (obj_domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_object_name failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_search_user_by_name(tmp_ctx, obj_domain, members[c], NULL, &msg); if (ret == EOK) { if (group_attrs != NULL) { dn_str = ldb_dn_get_linearized(msg->dn); if (dn_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_get_linearized failed.\n"); ret = EINVAL; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Adding member [%s][%s]\n", members[c], dn_str); ret = sysdb_attrs_add_string_safe(group_attrs, SYSDB_MEMBER, dn_str); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string_safe failed.\n"); goto done; } } } else if (ret == ENOENT) { if (group_attrs != NULL) { DEBUG(SSSDBG_TRACE_ALL, "Adding ghost member [%s]\n", members[c]); /* There were cases where the server returned the same user * multiple times */ ret = sysdb_attrs_add_string_safe(group_attrs, SYSDB_GHOST, members[c]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } } if (missing_members != NULL) { missing_members[miss_count] = talloc_strdup(missing_members, members[c]); if (missing_members[miss_count] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } miss_count++; } } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_name failed.\n"); goto done; } } if (_missing_members != NULL) { if (miss_count == 0) { *_missing_members = NULL; } else { if (mem_ctx != NULL) { *_missing_members = talloc_steal(mem_ctx, missing_members); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Missing memory context for missing members list.\n"); ret = EINVAL; goto done; } } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t get_group_dn_list(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, size_t ngroups, char **groups, struct ldb_dn ***_dn_list, char ***_missing_groups) { int ret; size_t c; TALLOC_CTX *tmp_ctx; struct ldb_dn **dn_list = NULL; char **missing_groups = NULL; struct ldb_message *msg = NULL; size_t n_dns = 0; size_t n_missing = 0; struct sss_domain_info *obj_domain; struct sss_domain_info *parent_domain; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } dn_list = talloc_zero_array(tmp_ctx, struct ldb_dn *, ngroups + 1); missing_groups = talloc_zero_array(tmp_ctx, char *, ngroups + 1); if (dn_list == NULL || missing_groups == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array_zero failed.\n"); ret = ENOMEM; goto done; } parent_domain = (dom->parent == NULL) ? dom : dom->parent; for (c = 0; c < ngroups; c++) { obj_domain = find_domain_by_object_name(parent_domain, groups[c]); if (obj_domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_object_name failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_search_group_by_name(tmp_ctx, obj_domain, groups[c], NULL, &msg); if (ret == EOK) { dn_list[n_dns] = ldb_dn_copy(dn_list, msg->dn); if (dn_list[n_dns] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_copy failed.\n"); ret = ENOMEM; goto done; } n_dns++; } else if (ret == ENOENT) { missing_groups[n_missing] = talloc_strdup(missing_groups, groups[c]); if (missing_groups[n_missing] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } n_missing++; } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_group_by_name failed.\n"); goto done; } } if (n_missing != 0) { *_missing_groups = talloc_steal(mem_ctx, missing_groups); } else { *_missing_groups = NULL; } if (n_dns != 0) { *_dn_list = talloc_steal(mem_ctx, dn_list); } else { *dn_list = NULL; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static void ipa_s2n_get_fqlist_done(struct tevent_req *subreq); static void ipa_s2n_get_user_get_override_done(struct tevent_req *subreq); static void ipa_s2n_get_user_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_s2n_get_user_state *state = tevent_req_data(req, struct ipa_s2n_get_user_state); int ret; char *retoid = NULL; struct berval *retdata = NULL; struct resp_attrs *attrs = NULL; struct berval *bv_req = NULL; char **missing_list = NULL; struct ldb_dn **group_dn_list = NULL; const char *sid_str; struct be_acct_req *ar; ret = ipa_s2n_exop_recv(subreq, state, &retoid, &retdata); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "s2n exop request failed.\n"); goto done; } switch (state->request_type) { case REQ_FULL_WITH_MEMBERS: case REQ_FULL: ret = s2n_response_to_attrs(state, retoid, retdata, &attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "s2n_response_to_attrs failed.\n"); goto done; } if (!(strcasecmp(state->dom->name, attrs->domain_name) == 0 || (state->dom->flat_name != NULL && strcasecmp(state->dom->flat_name, attrs->domain_name) == 0))) { DEBUG(SSSDBG_OP_FAILURE, "Unexpected domain name returned, " "expected [%s] or [%s], got [%s].\n", state->dom->name, state->dom->flat_name == NULL ? "" : state->dom->flat_name, attrs->domain_name); ret = EINVAL; goto done; } state->attrs = attrs; if (attrs->response_type == RESP_USER_GROUPLIST) { ret = get_group_dn_list(state, state->dom, attrs->ngroups, attrs->groups, &group_dn_list, &missing_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_group_dn_list failed.\n"); goto done; } if (missing_list != NULL) { subreq = ipa_s2n_get_fqlist_send(state, state->ev, state->ipa_ctx, state->dom, state->sh, state->exop_timeout, BE_REQ_GROUP, REQ_FULL_WITH_MEMBERS, missing_list); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_get_fqlist_send failed.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ipa_s2n_get_fqlist_done, req); return; } break; } else if (attrs->response_type == RESP_GROUP_MEMBERS) { ret = process_members(state->dom, NULL, attrs->a.group.gr_mem, state, &missing_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "process_members failed.\n"); goto done; } if (missing_list != NULL) { subreq = ipa_s2n_get_fqlist_send(state, state->ev, state->ipa_ctx, state->dom, state->sh, state->exop_timeout, BE_REQ_USER, REQ_FULL_WITH_MEMBERS, missing_list); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_get_fqlist_send failed.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ipa_s2n_get_fqlist_done, req); return; } break; } if (state->req_input->type == REQ_INP_SECID) { /* We already know the SID, we do not have to read it. */ break; } state->request_type = REQ_SIMPLE; ret = s2n_encode_request(state, state->dom->name, state->entry_type, state->request_type, state->req_input, &bv_req); if (ret != EOK) { goto done; } subreq = ipa_s2n_exop_send(state, state->ev, state->sh, false, state->exop_timeout, bv_req); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_exop_send failed.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ipa_s2n_get_user_done, req); return; case REQ_SIMPLE: ret = s2n_response_to_attrs(state, retoid, retdata, &state->simple_attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "s2n_response_to_attrs failed.\n"); goto done; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected request type.\n"); ret = EINVAL; goto done; } if (state->attrs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing data of full request.\n"); ret = EINVAL; goto done; } if (state->simple_attrs != NULL && state->simple_attrs->response_type == RESP_SID) { sid_str = state->simple_attrs->a.sid_str; ret = EOK; } else if (state->attrs->sysdb_attrs != NULL) { ret = sysdb_attrs_get_string(state->attrs->sysdb_attrs, SYSDB_SID_STR, &sid_str); } else if (state->req_input->type == REQ_INP_SECID) { sid_str = state->req_input->inp.secid; ret = EOK; } else { DEBUG(SSSDBG_TRACE_FUNC, "No SID available.\n"); ret = ENOENT; } if (ret == ENOENT || is_default_view(state->ipa_ctx->view_name)) { ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs, state->simple_attrs, NULL, NULL, true); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n"); goto done; } } else if (ret == EOK) { ret = get_be_acct_req_for_sid(state, sid_str, state->dom->name, &ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); goto done; } subreq = ipa_get_ad_override_send(state, state->ev, state->ipa_ctx->sdap_id_ctx, state->ipa_ctx->ipa_options, dp_opt_get_string(state->ipa_ctx->ipa_options->basic, IPA_KRB5_REALM), state->ipa_ctx->view_name, ar); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ipa_s2n_get_user_get_override_done, req); return; } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } return; } static errno_t get_groups_dns(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, char **name_list, char ***_dn_list) { int ret; TALLOC_CTX *tmp_ctx; int c; struct sss_domain_info *root_domain; char **dn_list; if (name_list == NULL) { *_dn_list = NULL; return EOK; } /* To handle cross-domain memberships we have to check the domain for * each group the member should be added or deleted. Since sub-domains * use fully-qualified names by default any short name can only belong * to the root/head domain. find_domain_by_object_name() will return * the domain given in the first argument if the second argument is a * a short name hence we always use root_domain as first argument. */ root_domain = get_domains_head(dom); if (root_domain->fqnames) { DEBUG(SSSDBG_TRACE_FUNC, "Root domain uses fully-qualified names, " \ "objects might not be correctly added to groups with " \ "short names.\n"); } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } for (c = 0; name_list[c] != NULL; c++); dn_list = talloc_zero_array(tmp_ctx, char *, c + 1); if (dn_list == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array failed.\n"); ret = ENOMEM; goto done; } for (c = 0; name_list[c] != NULL; c++) { dom = find_domain_by_object_name(root_domain, name_list[c]); if (dom == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find domain for [%s].\n", name_list[c]); ret = ENOENT; goto done; } /* This might fail if some unexpected cases are used. But current * sysdb code which handles group membership constructs DNs this way * as well, IPA names are lowercased and AD names by default will be * lowercased as well. If there are really use-cases which cause an * issue here, sysdb_group_strdn() has to be replaced by a proper * search. */ dn_list[c] = sysdb_group_strdn(dn_list, dom->name, name_list[c]); if (dn_list[c] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_group_strdn failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Added [%s][%s].\n", name_list[c], dn_list[c]); } *_dn_list = talloc_steal(mem_ctx, dn_list); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, struct req_input *req_input, struct resp_attrs *attrs, struct resp_attrs *simple_attrs, const char *view_name, struct sysdb_attrs *override_attrs, bool update_initgr_timeout) { int ret; time_t now; struct sss_nss_homedir_ctx homedir_ctx; char *name = NULL; char *realm; char *upn = NULL; gid_t gid; gid_t orig_gid = 0; TALLOC_CTX *tmp_ctx; const char *sid_str; const char *tmp_str; struct ldb_result *res; enum sysdb_member_type type; char **sysdb_grouplist; char **add_groups; char **add_groups_dns; char **del_groups; char **del_groups_dns; bool in_transaction = false; int tret; struct sysdb_attrs *gid_override_attrs = NULL; char ** exop_grouplist; struct ldb_message *msg; struct ldb_message_element *el = NULL; const char *missing[] = {NULL, NULL}; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } now = time(NULL); if (attrs->sysdb_attrs == NULL) { attrs->sysdb_attrs = sysdb_new_attrs(attrs); if (attrs->sysdb_attrs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); ret = ENOMEM; goto done; } } if (attrs->sysdb_attrs != NULL) { ret = sysdb_attrs_get_string(attrs->sysdb_attrs, ORIGINALAD_PREFIX SYSDB_NAME, &tmp_str); if (ret == EOK) { name = talloc_strdup(tmp_ctx, tmp_str); if (name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Found original AD name [%s].\n", name); } else if (ret == ENOENT) { name = NULL; } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } ret = sysdb_attrs_get_string(attrs->sysdb_attrs, SYSDB_DEFAULT_OVERRIDE_NAME, &tmp_str); if (ret == EOK) { ret = sysdb_attrs_add_lc_name_alias_safe(attrs->sysdb_attrs, tmp_str); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_lc_name_alias_safe failed.\n"); goto done; } } else if (ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } ret = sysdb_attrs_get_string(attrs->sysdb_attrs, SYSDB_UPN, &tmp_str); if (ret == EOK) { upn = talloc_strdup(tmp_ctx, tmp_str); if (upn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Found original AD upn [%s].\n", upn); } else if (ret == ENOENT) { upn = NULL; } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } } if (strcmp(dom->name, attrs->domain_name) != 0) { dom = find_domain_by_name(get_domains_head(dom), attrs->domain_name, true); if (dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot find domain: [%s]\n", attrs->domain_name); ret = EINVAL; goto done; } } switch (attrs->response_type) { case RESP_USER: case RESP_USER_GROUPLIST: type = SYSDB_MEMBER_USER; if (dom->subdomain_homedir && attrs->a.user.pw_dir == NULL) { ZERO_STRUCT(homedir_ctx); homedir_ctx.username = attrs->a.user.pw_name; homedir_ctx.uid = attrs->a.user.pw_uid; homedir_ctx.domain = dom->name; homedir_ctx.flatname = dom->flat_name; homedir_ctx.config_homedir_substr = dom->homedir_substr; attrs->a.user.pw_dir = expand_homedir_template(attrs, dom->subdomain_homedir, &homedir_ctx); if (attrs->a.user.pw_dir == NULL) { ret = ENOMEM; goto done; } } if (name == NULL) { /* we always use the fully qualified name for subdomain users */ name = sss_tc_fqname(tmp_ctx, dom->names, dom, attrs->a.user.pw_name); if (!name) { DEBUG(SSSDBG_OP_FAILURE, "failed to format user name.\n"); ret = ENOMEM; goto done; } } ret = sysdb_attrs_add_lc_name_alias_safe(attrs->sysdb_attrs, name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_lc_name_alias_safe failed.\n"); goto done; } if (upn == NULL) { /* We also have to store a fake UPN here, because otherwise the * krb5 child later won't be able to properly construct one as * the username is fully qualified but the child doesn't have * access to the regex to deconstruct it */ /* FIXME: The real UPN is available from the PAC, we should get * it from there. */ realm = get_uppercase_realm(tmp_ctx, dom->name); if (!realm) { DEBUG(SSSDBG_OP_FAILURE, "failed to get realm.\n"); ret = ENOMEM; goto done; } upn = talloc_asprintf(tmp_ctx, "%s@%s", attrs->a.user.pw_name, realm); if (!upn) { DEBUG(SSSDBG_OP_FAILURE, "failed to format UPN.\n"); ret = ENOMEM; goto done; } /* We might already have the SID or the UPN from other sources * hence sysdb_attrs_add_string_safe is used to avoid double * entries. */ ret = sysdb_attrs_add_string_safe(attrs->sysdb_attrs, SYSDB_UPN, upn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } } if (req_input->type == REQ_INP_SECID) { ret = sysdb_attrs_add_string_safe(attrs->sysdb_attrs, SYSDB_SID_STR, req_input->inp.secid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } } if (simple_attrs != NULL && simple_attrs->response_type == RESP_SID) { ret = sysdb_attrs_add_string_safe(attrs->sysdb_attrs, SYSDB_SID_STR, simple_attrs->a.sid_str); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } } if (attrs->response_type == RESP_USER_GROUPLIST && update_initgr_timeout) { /* Since RESP_USER_GROUPLIST contains all group memberships it * is effectively an initgroups request hence * SYSDB_INITGR_EXPIRE will be set.*/ ret = sysdb_attrs_add_time_t(attrs->sysdb_attrs, SYSDB_INITGR_EXPIRE, time(NULL) + dom->user_timeout); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_time_t failed.\n"); goto done; } } gid = 0; if (dom->mpg == false) { gid = attrs->a.user.pw_gid; } else { /* The extdom plugin always returns the objects with the * default view applied. Since the GID is handled specially * for MPG domains we have add any overridden GID separately. */ ret = sysdb_attrs_get_uint32_t(attrs->sysdb_attrs, ORIGINALAD_PREFIX SYSDB_GIDNUM, &orig_gid); if (ret == EOK || ret == ENOENT) { if ((orig_gid != 0 && orig_gid != attrs->a.user.pw_gid) || attrs->a.user.pw_uid != attrs->a.user.pw_gid) { gid_override_attrs = sysdb_new_attrs(tmp_ctx); if (gid_override_attrs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_add_uint32(gid_override_attrs, SYSDB_GIDNUM, attrs->a.user.pw_gid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_uint32 failed.\n"); goto done; } } } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_uint32_t failed.\n"); goto done; } } ret = sysdb_attrs_get_el_ext(attrs->sysdb_attrs, SYSDB_ORIG_MEMBEROF, false, &el); if (ret == ENOENT) { missing[0] = SYSDB_ORIG_MEMBEROF; } ret = sysdb_transaction_start(dom->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; ret = sysdb_store_user(dom, name, NULL, attrs->a.user.pw_uid, gid, attrs->a.user.pw_gecos, attrs->a.user.pw_dir, attrs->a.user.pw_shell, NULL, attrs->sysdb_attrs, missing[0] == NULL ? NULL : discard_const(missing), dom->user_timeout, now); if (ret == EEXIST && dom->mpg == true) { /* This handles the case where getgrgid() was called for * this user, so a group was created in the cache */ ret = sysdb_search_group_by_name(tmp_ctx, dom, name, NULL, &msg); if (ret != EOK) { /* Fail even on ENOENT, the group must be around */ DEBUG(SSSDBG_OP_FAILURE, "Could not delete MPG group [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sysdb_delete_group(dom, NULL, attrs->a.user.pw_uid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_delete_group failed for MPG group [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sysdb_store_user(dom, name, NULL, attrs->a.user.pw_uid, gid, attrs->a.user.pw_gecos, attrs->a.user.pw_dir, attrs->a.user.pw_shell, NULL, attrs->sysdb_attrs, NULL, dom->user_timeout, now); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_user failed for MPG user [%d]: %s\n", ret, sss_strerror(ret)); goto done; } } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_user failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } if (gid_override_attrs != NULL) { ret = sysdb_set_user_attr(dom, name, gid_override_attrs, SYSDB_MOD_REP); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_user_attr failed.\n"); goto done; } } if (attrs->response_type == RESP_USER_GROUPLIST) { ret = get_sysdb_grouplist(tmp_ctx, dom->sysdb, dom, name, &sysdb_grouplist); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_sysdb_grouplist failed.\n"); goto done; } /* names returned by extdom exop will be all lower case, since * we handle domain names case sensitve in the cache we have * to make sure we use the right case. */ ret = fix_domain_in_name_list(tmp_ctx, dom, attrs->groups, &exop_grouplist); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "fix_domain_name failed.\n"); goto done; } ret = diff_string_lists(tmp_ctx, exop_grouplist, sysdb_grouplist, &add_groups, &del_groups, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "diff_string_lists failed.\n"); goto done; } ret = get_groups_dns(tmp_ctx, dom, add_groups, &add_groups_dns); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_groups_dns failed.\n"); goto done; } ret = get_groups_dns(tmp_ctx, dom, del_groups, &del_groups_dns); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_groups_dns failed.\n"); goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Updating memberships for %s\n", name); ret = sysdb_update_members_dn(dom, name, SYSDB_MEMBER_USER, (const char *const *) add_groups_dns, (const char *const *) del_groups_dns); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Membership update failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } } ret = sysdb_transaction_commit(dom->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; break; case RESP_GROUP: case RESP_GROUP_MEMBERS: type = SYSDB_MEMBER_GROUP; if (name == NULL) { name = attrs->a.group.gr_name; } if (IS_SUBDOMAIN(dom)) { /* we always use the fully qualified name for subdomain users */ name = sss_get_domain_name(tmp_ctx, name, dom); if (!name) { DEBUG(SSSDBG_OP_FAILURE, "failed to format user name,\n"); ret = ENOMEM; goto done; } } DEBUG(SSSDBG_TRACE_FUNC, "Processing group %s\n", name); ret = sysdb_attrs_add_lc_name_alias_safe(attrs->sysdb_attrs, name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_lc_name_alias_safe failed.\n"); goto done; } /* We might already have the SID from other sources hence * sysdb_attrs_add_string_safe is used to avoid double entries. */ if (req_input->type == REQ_INP_SECID) { ret = sysdb_attrs_add_string_safe(attrs->sysdb_attrs, SYSDB_SID_STR, req_input->inp.secid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } } if (simple_attrs != NULL && simple_attrs->response_type == RESP_SID) { ret = sysdb_attrs_add_string_safe(attrs->sysdb_attrs, SYSDB_SID_STR, simple_attrs->a.sid_str); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } } ret = process_members(dom, attrs->sysdb_attrs, attrs->a.group.gr_mem, NULL, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "process_members failed.\n"); goto done; } ret = sysdb_store_group(dom, name, attrs->a.group.gr_gid, attrs->sysdb_attrs, dom->group_timeout, now); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_group failed.\n"); goto done; } break; default: DEBUG(SSSDBG_OP_FAILURE, "Unexpected response type [%d].\n", attrs->response_type); ret = EINVAL; goto done; } ret = sysdb_attrs_get_string(attrs->sysdb_attrs, SYSDB_SID_STR, &sid_str); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find SID of object with override.\n"); goto done; } ret = sysdb_search_object_by_sid(tmp_ctx, dom, sid_str, NULL, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find object with override with SID [%s].\n", sid_str); goto done; } if (!is_default_view(view_name)) { /* For the default view the data return by the extdom plugin already * contains all needed data and it is not expected to have a separate * override object. */ ret = sysdb_store_override(dom, view_name, type, override_attrs, res->msgs[0]->dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n"); goto done; } } done: if (in_transaction) { tret = sysdb_transaction_cancel(dom->sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } static void ipa_s2n_get_fqlist_done(struct tevent_req *subreq) { int ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_s2n_get_user_state *state = tevent_req_data(req, struct ipa_s2n_get_user_state); const char *sid_str; struct be_acct_req *ar; ret = ipa_s2n_get_fqlist_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "s2n get_fqlist request failed.\n"); tevent_req_error(req, ret); return; } ret = sysdb_attrs_get_string(state->attrs->sysdb_attrs, SYSDB_SID_STR, &sid_str); if (ret == ENOENT) { ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs, state->simple_attrs, NULL, NULL, true); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n"); goto fail; } tevent_req_done(req); return; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto fail; } ret = get_be_acct_req_for_sid(state, sid_str, state->dom->name, &ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); goto fail; } if (state->override_attrs == NULL && !is_default_view(state->ipa_ctx->view_name)) { subreq = ipa_get_ad_override_send(state, state->ev, state->ipa_ctx->sdap_id_ctx, state->ipa_ctx->ipa_options, dp_opt_get_string(state->ipa_ctx->ipa_options->basic, IPA_KRB5_REALM), state->ipa_ctx->view_name, ar); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_s2n_get_user_get_override_done, req); } else { ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs, state->simple_attrs, state->ipa_ctx->view_name, state->override_attrs, true); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n"); tevent_req_error(req, ret); return; } tevent_req_done(req); } return; fail: tevent_req_error(req, ret); return; } static void ipa_s2n_get_user_get_override_done(struct tevent_req *subreq) { int ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_s2n_get_user_state *state = tevent_req_data(req, struct ipa_s2n_get_user_state); struct sysdb_attrs *override_attrs = NULL; ret = ipa_get_ad_override_recv(subreq, NULL, state, &override_attrs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); tevent_req_error(req, ret); return; } ret = ipa_s2n_save_objects(state->dom, state->req_input, state->attrs, state->simple_attrs, state->ipa_ctx->view_name, override_attrs, true); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_s2n_save_objects failed.\n"); tevent_req_error(req, ret); return; } tevent_req_done(req); return; } int ipa_s2n_get_acct_info_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_id.c0000644000000000000000000000007312703456111017272 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.726793873 sssd-1.13.4/src/providers/ipa/ipa_id.c0000644002412700241270000012447412703456111020756 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Identity Backend Module Authors: Jan Zeleny Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" #include "providers/ipa/ipa_id.h" static bool is_object_overridable(struct be_acct_req *ar) { bool ret = false; switch (ar->entry_type & BE_REQ_TYPE_MASK) { case BE_REQ_USER: case BE_REQ_GROUP: case BE_REQ_INITGROUPS: case BE_REQ_BY_SECID: case BE_REQ_USER_AND_GROUP: case BE_REQ_BY_UUID: case BE_REQ_BY_CERT: ret = true; break; default: break; } return ret; } static const char *ipa_account_info_error_text(int ret, int *dp_error, const char *default_text) { switch (*dp_error) { case DP_ERR_OK: if (ret == EOK) { return NULL; } DEBUG(SSSDBG_CRIT_FAILURE, "Bug: dp_error is OK on failed request\n"); *dp_error = DP_ERR_FATAL; break; case DP_ERR_OFFLINE: return "Offline"; case DP_ERR_FATAL: if (ret == ENOMEM) { return "Out of memory"; } break; default: break; } return default_text; } static struct tevent_req * ipa_id_get_account_info_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct be_req *be_req, struct be_acct_req *ar); static int ipa_id_get_account_info_recv(struct tevent_req *req, int *dp_error); static struct tevent_req *ipa_id_get_netgroup_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, const char *name); static int ipa_id_get_netgroup_recv(struct tevent_req *req, int *dp_error); static void ipa_account_info_done(struct tevent_req *req); void ipa_account_info_handler(struct be_req *breq) { struct be_ctx *be_ctx = be_req_get_be_ctx(breq); struct ipa_id_ctx *ipa_ctx; struct sdap_id_ctx *ctx; struct be_acct_req *ar; struct tevent_req *req = NULL; ipa_ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data, struct ipa_id_ctx); ctx = ipa_ctx->sdap_id_ctx; if (be_is_offline(ctx->be)) { return sdap_handler_done(breq, DP_ERR_OFFLINE, EAGAIN, "Offline"); } ar = talloc_get_type(be_req_get_data(breq), struct be_acct_req); if (sdap_is_enum_request(ar)) { DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n"); return sdap_handler_done(breq, DP_ERR_OK, EOK, "Success"); } if (strcasecmp(ar->domain, be_ctx->domain->name) != 0) { /* if domain names do not match, this is a subdomain case * subdomain lookups are handled differently on the server * and the client */ req = ipa_subdomain_account_send(breq, be_ctx->ev, ipa_ctx, breq, ar); } else if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_NETGROUP) { /* netgroups are handled by a separate request function */ if (ar->filter_type != BE_FILTER_NAME) { return sdap_handler_done(breq, DP_ERR_FATAL, EINVAL, "Invalid filter type"); } req = ipa_id_get_netgroup_send(breq, be_ctx->ev, ipa_ctx, ar->filter_value); } else { /* any account request is handled by sdap, * any invalid request is caught there. */ req = ipa_id_get_account_info_send(breq, be_ctx->ev, ipa_ctx, breq, ar); } if (!req) { return sdap_handler_done(breq, DP_ERR_FATAL, ENOMEM, "Out of memory"); } tevent_req_set_callback(req, ipa_account_info_done, breq); } static void ipa_account_info_done(struct tevent_req *req) { struct be_req *breq = tevent_req_callback_data(req, struct be_req); struct be_acct_req *ar = talloc_get_type(be_req_get_data(breq), struct be_acct_req); struct be_ctx *be_ctx = be_req_get_be_ctx(breq); const char *error_text; int ret, dp_error; if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_NETGROUP) { ret = ipa_id_get_netgroup_recv(req, &dp_error); } else { if (strcasecmp(ar->domain, be_ctx->domain->name) != 0) { ret = ipa_subdomain_account_recv(req, &dp_error); } else { ret = ipa_id_get_account_info_recv(req, &dp_error); } } talloc_zfree(req); error_text = ipa_account_info_error_text(ret, &dp_error, "Account info lookup failed"); sdap_handler_done(breq, dp_error, ret, error_text); } struct ipa_resolve_user_list_state { struct tevent_context *ev; struct ipa_id_ctx *ipa_ctx; struct be_req *be_req; struct ldb_message_element *users; const char *domain_name; size_t user_idx; int dp_error; }; static errno_t ipa_resolve_user_list_get_user_step(struct tevent_req *req); static void ipa_resolve_user_list_get_user_done(struct tevent_req *subreq); static struct tevent_req * ipa_resolve_user_list_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct be_req *be_req, struct ipa_id_ctx *ipa_ctx, const char *domain_name, struct ldb_message_element *users) { int ret; struct tevent_req *req; struct ipa_resolve_user_list_state *state; req = tevent_req_create(memctx, &state, struct ipa_resolve_user_list_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->ipa_ctx = ipa_ctx; state->be_req = be_req; state->domain_name = domain_name; state->users = users; state->user_idx = 0; state->dp_error = DP_ERR_FATAL; ret = ipa_resolve_user_list_get_user_step(req); if (ret == EAGAIN) { return req; } else if (ret == EOK) { state->dp_error = DP_ERR_OK; tevent_req_done(req); } else { DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_get_user_step failed.\n"); tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t ipa_resolve_user_list_get_user_step(struct tevent_req *req) { int ret; struct tevent_req *subreq; struct be_acct_req *ar; struct ipa_resolve_user_list_state *state = tevent_req_data(req, struct ipa_resolve_user_list_state); if (state->user_idx >= state->users->num_values) { return EOK; } ret = get_be_acct_req_for_user_name(state, (char *) state->users->values[state->user_idx].data, state->domain_name, &ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_user_name failed.\n"); return ret; } DEBUG(SSSDBG_TRACE_ALL, "Trying to resolve user [%s].\n", ar->filter_value); subreq = ipa_id_get_account_info_send(state, state->ev, state->ipa_ctx, state->be_req, ar); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct_req_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, ipa_resolve_user_list_get_user_done, req); return EAGAIN; } static void ipa_resolve_user_list_get_user_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_resolve_user_list_state *state = tevent_req_data(req, struct ipa_resolve_user_list_state); int ret; ret = ipa_id_get_account_info_recv(subreq, &state->dp_error); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct request failed: %d\n", ret); goto done; } state->user_idx++; ret = ipa_resolve_user_list_get_user_step(req); if (ret == EAGAIN) { return; } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_get_user_step failed.\n"); } done: if (ret == EOK) { state->dp_error = DP_ERR_OK; tevent_req_done(req); } else { if (state->dp_error == DP_ERR_OK) { state->dp_error = DP_ERR_FATAL; } tevent_req_error(req, ret); } return; } static int ipa_resolve_user_list_recv(struct tevent_req *req, int *dp_error) { struct ipa_resolve_user_list_state *state = tevent_req_data(req, struct ipa_resolve_user_list_state); if (dp_error) { *dp_error = state->dp_error; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct ipa_initgr_get_overrides_state { struct tevent_context *ev; struct ipa_id_ctx *ipa_ctx; struct sss_domain_info *user_dom; const char *realm; struct ldb_message **groups; size_t group_count; const char *groups_id_attr; size_t group_idx; struct be_acct_req *ar; int dp_error; }; static int ipa_initgr_get_overrides_step(struct tevent_req *req); struct tevent_req * ipa_initgr_get_overrides_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct sss_domain_info *user_dom, size_t groups_count, struct ldb_message **groups, const char *groups_id_attr) { int ret; struct tevent_req *req; struct ipa_initgr_get_overrides_state *state; req = tevent_req_create(memctx, &state, struct ipa_initgr_get_overrides_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->ipa_ctx = ipa_ctx; state->user_dom = user_dom; state->groups = groups; state->group_count = groups_count; state->group_idx = 0; state->ar = NULL; state->realm = dp_opt_get_string(state->ipa_ctx->ipa_options->basic, IPA_KRB5_REALM); if (state->realm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n"); ret = EINVAL; goto done; } state->groups_id_attr = talloc_strdup(state, groups_id_attr); if (state->groups_id_attr == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } ret = ipa_initgr_get_overrides_step(req); done: if (ret == EOK) { tevent_req_done(req); tevent_req_post(req, ev); } else if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void ipa_initgr_get_overrides_override_done(struct tevent_req *subreq); static int ipa_initgr_get_overrides_step(struct tevent_req *req) { int ret; struct tevent_req *subreq; const char *ipa_uuid; struct ipa_initgr_get_overrides_state *state = tevent_req_data(req, struct ipa_initgr_get_overrides_state); DEBUG(SSSDBG_TRACE_LIBS, "Processing group %zu/%zu\n", state->group_idx, state->group_count); if (state->group_idx >= state->group_count) { return EOK; } ipa_uuid = ldb_msg_find_attr_as_string(state->groups[state->group_idx], state->groups_id_attr, NULL); if (ipa_uuid == NULL) { /* This should never happen, the search filter used to get the list * of groups includes "uuid=*" */ DEBUG(SSSDBG_OP_FAILURE, "The group %s has no UUID attribute %s, error!\n", ldb_dn_get_linearized(state->groups[state->group_idx]->dn), state->groups_id_attr); return EINVAL; } talloc_free(state->ar); /* Avoid spiking memory with many groups */ if (strcmp(state->groups_id_attr, SYSDB_UUID) == 0) { ret = get_be_acct_req_for_uuid(state, ipa_uuid, state->user_dom->name, &state->ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); return ret; } } else if (strcmp(state->groups_id_attr, SYSDB_SID_STR) == 0) { ret = get_be_acct_req_for_sid(state, ipa_uuid, state->user_dom->name, &state->ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); return ret; } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported groups ID type [%s].\n", state->groups_id_attr); return EINVAL; } DEBUG(SSSDBG_TRACE_LIBS, "Fetching group %s\n", ipa_uuid); subreq = ipa_get_ad_override_send(state, state->ev, state->ipa_ctx->sdap_id_ctx, state->ipa_ctx->ipa_options, state->realm, state->ipa_ctx->view_name, state->ar); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, ipa_initgr_get_overrides_override_done, req); return EAGAIN; } static void ipa_initgr_get_overrides_override_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_initgr_get_overrides_state *state = tevent_req_data(req, struct ipa_initgr_get_overrides_state); int ret; struct sysdb_attrs *override_attrs = NULL; ret = ipa_get_ad_override_recv(subreq, &state->dp_error, state, &override_attrs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); tevent_req_error(req, ret); return; } if (is_default_view(state->ipa_ctx->view_name)) { ret = sysdb_apply_default_override(state->user_dom, override_attrs, state->groups[state->group_idx]->dn); } else { ret = sysdb_store_override(state->user_dom, state->ipa_ctx->view_name, SYSDB_MEMBER_GROUP, override_attrs, state->groups[state->group_idx]->dn); } talloc_free(override_attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n"); tevent_req_error(req, ret); return; } state->group_idx++; ret = ipa_initgr_get_overrides_step(req); if (ret == EAGAIN) { return; } else if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } int ipa_initgr_get_overrides_recv(struct tevent_req *req, int *dp_error) { struct ipa_initgr_get_overrides_state *state = tevent_req_data(req, struct ipa_initgr_get_overrides_state); if (dp_error) { *dp_error = state->dp_error; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* Given a user name, retrieve an array of group UUIDs of groups that have * no overrideDN attribute but do have an UUID attribute. */ static errno_t ipa_id_get_group_uuids(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, size_t *_msgs_count, struct ldb_message ***_msgs) { const char *filter; TALLOC_CTX *tmp_ctx; char **uuid_list = NULL; errno_t ret; struct ldb_dn *base_dn; const char *attrs[] = { SYSDB_UUID, NULL }; size_t msgs_count; struct ldb_message **msgs; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { return ENOMEM; } filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)(!(%s=*))(%s=*))", SYSDB_GROUP_CLASS, SYSDB_OVERRIDE_DN, SYSDB_UUID); if (filter == NULL) { ret = ENOMEM; goto done; } base_dn = sysdb_base_dn(sysdb, tmp_ctx); if (base_dn == NULL) { ret = ENOMEM; goto done; } ret = sysdb_search_entry(tmp_ctx, sysdb, base_dn, LDB_SCOPE_SUBTREE, filter, attrs, &msgs_count, &msgs); if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No groups without %s in sysdb\n", SYSDB_OVERRIDE_DN); ret = EOK; goto done; } else if (ret != EOK) { goto done; } uuid_list = talloc_zero_array(tmp_ctx, char *, msgs_count); if (uuid_list == NULL) { goto done; } *_msgs_count = msgs_count; *_msgs = talloc_steal(mem_ctx, msgs); ret = EOK; done: talloc_free(tmp_ctx); return ret; } struct ipa_id_get_account_info_state { struct tevent_context *ev; struct ipa_id_ctx *ipa_ctx; struct sdap_id_ctx *ctx; struct sdap_id_op *op; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; struct be_req *be_req; struct be_acct_req *ar; struct be_acct_req *orig_ar; const char *realm; struct sysdb_attrs *override_attrs; struct ldb_message *obj_msg; struct ldb_message_element *ghosts; struct ldb_message **user_groups; size_t group_cnt; size_t group_idx; int dp_error; }; static void ipa_id_get_account_info_connected(struct tevent_req *subreq); static void ipa_id_get_account_info_got_override(struct tevent_req *subreq); static errno_t ipa_id_get_account_info_get_original_step(struct tevent_req *req, struct be_acct_req *ar); static void ipa_id_get_account_info_orig_done(struct tevent_req *subreq); static void ipa_id_get_account_info_done(struct tevent_req *subreq); static void ipa_id_get_user_list_done(struct tevent_req *subreq); static struct tevent_req * ipa_id_get_account_info_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct be_req *be_req, struct be_acct_req *ar) { int ret; struct tevent_req *req; struct tevent_req *subreq; struct ipa_id_get_account_info_state *state; req = tevent_req_create(memctx, &state, struct ipa_id_get_account_info_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->ipa_ctx = ipa_ctx; state->ctx = ipa_ctx->sdap_id_ctx; state->dp_error = DP_ERR_FATAL; state->op = sdap_id_op_create(state, state->ctx->conn->conn_cache); if (state->op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n"); ret = ENOMEM; goto fail; } state->domain = find_domain_by_name(state->ctx->be->domain, ar->domain, true); if (state->domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed.\n"); ret = ENOMEM; goto fail; } state->sysdb = state->domain->sysdb; state->be_req = be_req; state->ar = ar; state->realm = dp_opt_get_string(state->ipa_ctx->ipa_options->basic, IPA_KRB5_REALM); if (state->realm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n"); ret = EINVAL; goto fail; } /* We can skip the override lookup and go directly to the original object * if * - the lookup is by SID * - there is no view set of it is the default view * - if the EXTRA_INPUT_MAYBE_WITH_VIEW flag is not set */ if (is_default_view(state->ipa_ctx->view_name) || state->ar->filter_type == BE_FILTER_SECID || state->ar->extra_value == NULL || strcmp(state->ar->extra_value, EXTRA_INPUT_MAYBE_WITH_VIEW) != 0 || ! is_object_overridable(state->ar)) { ret = ipa_id_get_account_info_get_original_step(req, ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_subdomain_account_get_original_step failed.\n"); goto fail; } } else { subreq = sdap_id_op_connect_send(state->op, state, &ret); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed.\n"); goto fail; } tevent_req_set_callback(subreq, ipa_id_get_account_info_connected, req); } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void ipa_id_get_account_info_connected(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_id_get_account_info_state *state = tevent_req_data(req, struct ipa_id_get_account_info_state); int dp_error = DP_ERR_FATAL; int ret; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect request failed.\n"); goto fail; } subreq = ipa_get_ad_override_send(state, state->ev, state->ctx, state->ipa_ctx->ipa_options, state->realm, state->ipa_ctx->view_name, state->ar); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_id_get_account_info_got_override, req); return; fail: state->dp_error = dp_error; tevent_req_error(req, ret); return; } static void ipa_id_get_account_info_got_override(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_id_get_account_info_state *state = tevent_req_data(req, struct ipa_id_get_account_info_state); int dp_error = DP_ERR_FATAL; int ret; const char *anchor = NULL; char *anchor_domain; char *ipa_uuid; ret = ipa_get_ad_override_recv(subreq, &dp_error, state, &state->override_attrs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); goto fail; } if (state->override_attrs != NULL) { ret = sysdb_attrs_get_string(state->override_attrs, SYSDB_OVERRIDE_ANCHOR_UUID, &anchor); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto fail; } ret = split_ipa_anchor(state, anchor, &anchor_domain, &ipa_uuid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported override anchor [%s].\n", anchor); ret = EINVAL; goto fail; } if (strcmp(state->ar->domain, anchor_domain) == 0) { state->orig_ar = state->ar; ret = get_be_acct_req_for_uuid(state, ipa_uuid, state->ar->domain, &state->ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_uuid failed.\n"); goto fail; } if ((state->orig_ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_INITGROUPS) { DEBUG(SSSDBG_TRACE_ALL, "Switching back to BE_REQ_INITGROUPS.\n"); state->ar->entry_type = BE_REQ_INITGROUPS; state->ar->filter_type = BE_FILTER_UUID; state->ar->attr_type = BE_ATTR_CORE; } } else { DEBUG(SSSDBG_MINOR_FAILURE, "Anchor from a different domain [%s], expected [%s]. " \ "This is currently not supported, continue lookup in " \ "local IPA domain.\n", anchor_domain, state->ar->domain); } } ret = ipa_id_get_account_info_get_original_step(req, state->ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_subdomain_account_get_original_step failed.\n"); goto fail; } return; fail: state->dp_error = dp_error; tevent_req_error(req, ret); return; } static errno_t ipa_id_get_account_info_get_original_step(struct tevent_req *req, struct be_acct_req *ar) { struct ipa_id_get_account_info_state *state = tevent_req_data(req, struct ipa_id_get_account_info_state); struct tevent_req *subreq; subreq = sdap_handle_acct_req_send(state, state->ctx->be, ar, state->ipa_ctx->sdap_id_ctx, state->ipa_ctx->sdap_id_ctx->opts->sdom, state->ipa_ctx->sdap_id_ctx->conn, true); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct_req_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, ipa_id_get_account_info_orig_done, req); return EOK; } static void ipa_id_get_user_groups_done(struct tevent_req *subreq); static void ipa_id_get_account_info_orig_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_id_get_account_info_state *state = tevent_req_data(req, struct ipa_id_get_account_info_state); int dp_error = DP_ERR_FATAL; int ret; const char *uuid; const char *class; enum sysdb_member_type type; ret = sdap_handle_acct_req_recv(subreq, &dp_error, NULL, NULL); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_handle_acct request failed: %d\n", ret); goto fail; } if (! is_object_overridable(state->ar)) { state->dp_error = DP_ERR_OK; tevent_req_done(req); return; } ret = get_object_from_cache(state, state->domain, state->ar, &state->obj_msg); if (ret == ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "Object not found, ending request\n"); tevent_req_done(req); return; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_object_from_cache failed.\n"); goto fail; } class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCLASS, NULL); if (class == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find an objectclass.\n"); ret = EINVAL; goto fail; } if (!is_default_view(state->ipa_ctx->view_name)) { if ((state->ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_GROUP || ((state->ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_UUID && strcmp(class, SYSDB_GROUP_CLASS) == 0)) { /* check for ghost members because ghost members are not allowed * if a view other than the default view is applied.*/ state->ghosts = ldb_msg_find_element(state->obj_msg, SYSDB_GHOST); } else if ((state->ar->entry_type & BE_REQ_TYPE_MASK) == \ BE_REQ_INITGROUPS) { /* Get UUID list of groups that have no overrideDN set. */ ret = ipa_id_get_group_uuids(state, state->sysdb, &state->group_cnt, &state->user_groups); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get UUID list: %d\n", ret); goto fail; } } } if (state->override_attrs == NULL) { uuid = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_UUID, NULL); if (uuid == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find a UUID.\n"); ret = EINVAL; goto fail; } ret = get_be_acct_req_for_uuid(state, uuid, state->domain->name, &state->ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); goto fail; } subreq = ipa_get_ad_override_send(state, state->ev, state->ipa_ctx->sdap_id_ctx, state->ipa_ctx->ipa_options, state->realm, state->ipa_ctx->view_name, state->ar); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_id_get_account_info_done, req); return; } else { if (strcmp(class, SYSDB_USER_CLASS) == 0) { type = SYSDB_MEMBER_USER; } else { type = SYSDB_MEMBER_GROUP; } ret = sysdb_store_override(state->domain, state->ipa_ctx->view_name, type, state->override_attrs, state->obj_msg->dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n"); goto fail; } } if (state->ghosts != NULL) { /* Resolve ghost members */ subreq = ipa_resolve_user_list_send(state, state->ev, state->be_req, state->ipa_ctx, state->domain->name, state->ghosts); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_id_get_user_list_done, req); return; } if (state->user_groups != NULL) { subreq = ipa_initgr_get_overrides_send(state, state->ev, state->ipa_ctx, state->domain, state->group_cnt, state->user_groups, SYSDB_UUID); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_id_get_user_groups_done, req); return; } state->dp_error = DP_ERR_OK; tevent_req_done(req); return; fail: state->dp_error = dp_error; tevent_req_error(req, ret); return; } static void ipa_id_get_account_info_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_id_get_account_info_state *state = tevent_req_data(req, struct ipa_id_get_account_info_state); int dp_error = DP_ERR_FATAL; int ret; const char *class; enum sysdb_member_type type; ret = ipa_get_ad_override_recv(subreq, &dp_error, state, &state->override_attrs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); goto fail; } class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCLASS, NULL); if (class == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find an objectclass.\n"); ret = EINVAL; goto fail; } if (strcmp(class, SYSDB_USER_CLASS) == 0) { type = SYSDB_MEMBER_USER; } else { type = SYSDB_MEMBER_GROUP; } ret = sysdb_store_override(state->domain, state->ipa_ctx->view_name, type, state->override_attrs, state->obj_msg->dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_override failed.\n"); goto fail; } if (state->ghosts != NULL) { /* Resolve ghost members */ subreq = ipa_resolve_user_list_send(state, state->ev, state->be_req, state->ipa_ctx, state->domain->name, state->ghosts); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_id_get_user_list_done, req); return; } if (state->user_groups != NULL) { subreq = ipa_initgr_get_overrides_send(state, state->ev, state->ipa_ctx, state->domain, state->group_cnt, state->user_groups, SYSDB_UUID); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_resolve_user_list_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_id_get_user_groups_done, req); return; } state->dp_error = DP_ERR_OK; tevent_req_done(req); return; fail: state->dp_error = dp_error; tevent_req_error(req, ret); return; } static void ipa_id_get_user_list_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_id_get_account_info_state *state = tevent_req_data(req, struct ipa_id_get_account_info_state); int dp_error = DP_ERR_FATAL; int ret; ret = ipa_resolve_user_list_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA resolve user list %d\n", ret); goto fail; } state->dp_error = DP_ERR_OK; tevent_req_done(req); return; fail: state->dp_error = dp_error; tevent_req_error(req, ret); return; } static void ipa_id_get_user_groups_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_id_get_account_info_state *state = tevent_req_data(req, struct ipa_id_get_account_info_state); int dp_error = DP_ERR_FATAL; int ret; ret = ipa_initgr_get_overrides_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA resolve user groups %d\n", ret); goto fail; } state->dp_error = DP_ERR_OK; tevent_req_done(req); return; fail: state->dp_error = dp_error; tevent_req_error(req, ret); return; } static int ipa_id_get_account_info_recv(struct tevent_req *req, int *dp_error) { struct ipa_id_get_account_info_state *state = tevent_req_data(req, struct ipa_id_get_account_info_state); if (dp_error) { *dp_error = state->dp_error; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* Request for netgroups * - first start here and then go to ipa_netgroups.c */ struct ipa_id_get_netgroup_state { struct tevent_context *ev; struct ipa_id_ctx *ctx; struct sdap_id_op *op; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; const char *name; int timeout; char *filter; const char **attrs; size_t count; struct sysdb_attrs **netgroups; int dp_error; }; static void ipa_id_get_netgroup_connected(struct tevent_req *subreq); static void ipa_id_get_netgroup_done(struct tevent_req *subreq); static struct tevent_req *ipa_id_get_netgroup_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, const char *name) { struct tevent_req *req; struct ipa_id_get_netgroup_state *state; struct tevent_req *subreq; struct sdap_id_ctx *ctx; char *clean_name; int ret; ctx = ipa_ctx->sdap_id_ctx; req = tevent_req_create(memctx, &state, struct ipa_id_get_netgroup_state); if (!req) return NULL; state->ev = ev; state->ctx = ipa_ctx; state->dp_error = DP_ERR_FATAL; state->op = sdap_id_op_create(state, ctx->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto fail; } state->sysdb = ctx->be->domain->sysdb; state->domain = ctx->be->domain; state->name = name; state->timeout = dp_opt_get_int(ctx->opts->basic, SDAP_SEARCH_TIMEOUT); ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { goto fail; } state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))", ctx->opts->netgroup_map[IPA_AT_NETGROUP_NAME].name, clean_name, ctx->opts->netgroup_map[IPA_OC_NETGROUP].name); if (!state->filter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto fail; } talloc_zfree(clean_name); ret = build_attrs_from_map(state, ctx->opts->netgroup_map, IPA_OPTS_NETGROUP, NULL, &state->attrs, NULL); if (ret != EOK) goto fail; subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { goto fail; } tevent_req_set_callback(subreq, ipa_id_get_netgroup_connected, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void ipa_id_get_netgroup_connected(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_id_get_netgroup_state *state = tevent_req_data(req, struct ipa_id_get_netgroup_state); int dp_error = DP_ERR_FATAL; int ret; struct sdap_id_ctx *sdap_ctx = state->ctx->sdap_id_ctx; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } subreq = ipa_get_netgroups_send(state, state->ev, state->sysdb, state->domain, sdap_ctx->opts, state->ctx->ipa_options, sdap_id_op_handle(state->op), state->attrs, state->filter, state->timeout); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, ipa_id_get_netgroup_done, req); return; } static void ipa_id_get_netgroup_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_id_get_netgroup_state *state = tevent_req_data(req, struct ipa_id_get_netgroup_state); int dp_error = DP_ERR_FATAL; int ret; ret = ipa_get_netgroups_recv(subreq, state, &state->count, &state->netgroups); talloc_zfree(subreq); ret = sdap_id_op_done(state->op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { tevent_req_error(req, ret); return; } tevent_req_set_callback(subreq, ipa_id_get_netgroup_connected, req); return; } if (ret && ret != ENOENT) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } if (ret == EOK && state->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Found more than one netgroup with the name [%s].\n", state->name); tevent_req_error(req, EINVAL); return; } if (ret == ENOENT) { ret = sysdb_delete_netgroup(state->domain, state->name); if (ret != EOK && ret != ENOENT) { tevent_req_error(req, ret); return; } } state->dp_error = DP_ERR_OK; tevent_req_done(req); return; } static int ipa_id_get_netgroup_recv(struct tevent_req *req, int *dp_error) { struct ipa_id_get_netgroup_state *state = tevent_req_data(req, struct ipa_id_get_netgroup_state); if (dp_error) { *dp_error = state->dp_error; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } void ipa_check_online(struct be_req *be_req) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct ipa_id_ctx *ipa_ctx; ipa_ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data, struct ipa_id_ctx); return sdap_do_online_check(be_req, ipa_ctx->sdap_id_ctx); } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hbac.doxy.in0000644000000000000000000000007412703456111020742 xustar0030 atime=1460561772.713787047 30 ctime=1460561774.630793547 sssd-1.13.4/src/providers/ipa/ipa_hbac.doxy.in0000644002412700241270000023502012703456111022413 0ustar00jhrozekjhrozek00000000000000# Doxyfile 1.8.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = ipa_hbac # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = hbac_doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. Note that you specify absolute paths here, but also # relative paths, which will be relative from the directory where doxygen is # started. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, # and language is one of the parsers supported by doxygen: IDL, Java, # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, # C++. For instance to make doxygen treat .inc files as Fortran files (default # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented classes, # or namespaces to their corresponding documentation. Such a link can be # prevented in individual cases by by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES (the # default) will make doxygen replace the get and set methods by a property in # the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if section-label ... \endif # and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. Do not use # file names with spaces, bibtex cannot handle them. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @abs_top_srcdir@/src/providers/ipa/ipa_hbac.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.cpp \ *.cc \ *.c \ *.h \ *.hh \ *.hpp \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.git/* \ */.svn/* \ */cmake/* \ */build/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = # If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page (index.html). # This can be useful if you have a project on for instance GitHub and want reuse # the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If left blank doxygen will # generate a default style sheet. Note that it is recommended to use # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET # since it does not replace the standard style sheet and is therefor more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user # can expand and collapse entries dynamically later on. Doxygen will expand # the tree to such a level that at most the specified number of entries are # visible (unless a fully collapsed tree already exceeds this amount). # So setting the number of entries 1 will produce a full collapsed tree by # default. 0 is a special value representing an infinite number of entries # and will result in a full expanded tree by default. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely # identify the documentation publisher. This should be a reverse domain-name # style string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NONE # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. # There are two flavours of web server based search depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. # See the manual for details. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain # the search results. Doxygen ships with an example indexer (doxyindexer) and # search engine (doxysearch.cgi) which are based on the open source search engine # library Xapian. See the manual for configuration details. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will returned the search results when EXTERNAL_SEARCH is enabled. # Doxygen ships with an example search engine (doxysearch) which is based on # the open source search engine library Xapian. See the manual for configuration # details. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. SEARCHDATA_FILE = searchdata.xml # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through other # doxygen projects that are not otherwise connected via tags files, but are # all added to the same search index. Each project needs to have a tag file set # via GENERATE_TAGFILE. The search mapping then maps the name of the tag file # to a relative location where the documentation can be found, # similar to the # TAGFILES option but without actually processing the tag file. # The format is: EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # managable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_dyndns.h0000644000000000000000000000007312703456111020202 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.571793347 sssd-1.13.4/src/providers/ipa/ipa_dyndns.h0000644002412700241270000000214412703456111021653 0ustar00jhrozekjhrozek00000000000000/* SSSD ipa_dyndns.h Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IPA_DYNDNS_H_ #define IPA_DYNDNS_H_ #include "util/util_errors.h" #include "providers/ipa/ipa_common.h" #include "providers/dp_backend.h" void ipa_dyndns_update(void *pvt); void ipa_dyndns_timer(void *pvt); errno_t ipa_dyndns_init(struct be_ctx *be_ctx, struct ipa_options *ctx); #endif /* IPA_DYNDNS_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_sudo_async.c0000644000000000000000000000007412703456111021046 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.754793968 sssd-1.13.4/src/providers/ipa/ipa_sudo_async.c0000644002412700241270000007705512703456111022533 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "providers/ldap/sdap_ops.h" #include "providers/ldap/sdap_sudo_shared.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_hosts.h" #include "providers/ipa/ipa_sudo.h" #include "providers/ipa/ipa_dn.h" #include "db/sysdb.h" #include "db/sysdb_sudo.h" struct ipa_hostinfo { size_t num_hosts; size_t num_hostgroups; struct sysdb_attrs **hosts; struct sysdb_attrs **hostgroups; }; static char * ipa_sudo_filter_append_origdn(char *filter, struct sysdb_attrs *attrs, const char *attr_name) { const char *origdn; char *sanitizeddn; errno_t ret; ret = sysdb_attrs_get_string(attrs, SYSDB_ORIG_DN, &origdn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get original DN " "[%d]: %s\n", ret, sss_strerror(ret)); return NULL; } ret = sss_filter_sanitize(NULL, origdn, &sanitizeddn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to sanitize DN " "[%d]: %s\n", ret, sss_strerror(ret)); return NULL; } filter = talloc_asprintf_append(filter, "(%s=%s)", attr_name, sanitizeddn); talloc_free(sanitizeddn); if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append() failed\n"); } return filter; } /** * (|(hostCategory=ALL)(memberHost=$DN(fqdn))(memberHost=$DN(hostgroup))...) */ static char * ipa_sudo_host_filter(TALLOC_CTX *mem_ctx, struct ipa_hostinfo *host, struct sdap_attr_map *map) { TALLOC_CTX *tmp_ctx; char *filter; size_t i; /* If realloc fails we will free all data through tmp_ctx. */ tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NULL; } filter = talloc_asprintf(tmp_ctx, "(!(%s=*))", map[IPA_AT_SUDORULE_HOST].name); if (filter == NULL) { goto fail; } /* Append hostCategory=ALL */ filter = talloc_asprintf_append(filter, "(%s=ALL)", map[IPA_AT_SUDORULE_HOSTCATEGORY].name); if (filter == NULL) { goto fail; } /* Append client machine */ for (i = 0; i < host->num_hosts; i++) { filter = ipa_sudo_filter_append_origdn(filter, host->hosts[i], map[IPA_AT_SUDORULE_HOST].name); if (filter == NULL) { goto fail; } } /* Append hostgroups */ for (i = 0; i < host->num_hostgroups; i++) { filter = ipa_sudo_filter_append_origdn(filter, host->hostgroups[i], map[IPA_AT_SUDORULE_HOST].name); if (filter == NULL) { goto fail; } } /* OR filters */ filter = talloc_asprintf(tmp_ctx, "(|%s)", filter); if (filter == NULL) { goto fail; } talloc_steal(mem_ctx, filter); talloc_free(tmp_ctx); return filter; fail: talloc_free(tmp_ctx); return NULL; } static errno_t ipa_sudo_highest_usn(TALLOC_CTX *mem_ctx, struct sysdb_attrs **attrs, size_t num_attrs, char **current_usn) { errno_t ret; char *usn; ret = sysdb_get_highest_usn(mem_ctx, attrs, num_attrs, &usn); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get highest USN [%d]: %s\n", ret, sss_strerror(ret)); return ret; } if (sysdb_compare_usn(usn, *current_usn) > 0) { talloc_free(*current_usn); *current_usn = usn; return EOK; } talloc_free(usn); return EOK; } static errno_t ipa_sudo_assoc_rules_filter(TALLOC_CTX *mem_ctx, struct sysdb_attrs **cmdgroups, size_t num_cmdgroups, char **_filter) { TALLOC_CTX *tmp_ctx; const char *origdn; char *sanitized; char *filter; errno_t ret; size_t i; if (num_cmdgroups == 0) { return ENOENT; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } filter = talloc_strdup(tmp_ctx, ""); if (filter == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < num_cmdgroups; i++) { ret = sysdb_attrs_get_string(cmdgroups[i], SYSDB_ORIG_DN, &origdn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get original dn [%d]: %s\n", ret, sss_strerror(ret)); ret = ERR_INTERNAL; goto done; } ret = sss_filter_sanitize(tmp_ctx, origdn, &sanitized); if (ret != EOK) { goto done; } filter = talloc_asprintf_append(filter, "(%s=%s)", SYSDB_IPA_SUDORULE_ORIGCMD, sanitized); if (filter == NULL) { ret = ENOMEM; goto done; } } filter = talloc_asprintf(tmp_ctx, "(&(objectClass=%s)(|%s)))", SYSDB_SUDO_CACHE_OC, filter); if (filter == NULL) { ret = ENOMEM; goto done; } *_filter = talloc_steal(mem_ctx, filter); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t ipa_sudo_assoc_rules(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct sysdb_attrs **cmdgroups, size_t num_cmdgroups, struct sysdb_attrs ***_rules, size_t *_num_rules) { TALLOC_CTX *tmp_ctx; const char *attrs[] = {SYSDB_NAME, NULL}; struct sysdb_attrs **rules; struct ldb_message **msgs; size_t num_rules; char *filter; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = ipa_sudo_assoc_rules_filter(tmp_ctx, cmdgroups, num_cmdgroups, &filter); if (ret != EOK) { goto done; } ret = sysdb_search_custom(tmp_ctx, domain, filter, SUDORULE_SUBDIR, attrs, &num_rules, &msgs); if (ret == ENOENT) { *_rules = NULL; *_num_rules = 0; ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up sudo rules [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sysdb_msg2attrs(tmp_ctx, num_rules, msgs, &rules); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not convert ldb message to " "sysdb_attrs [%d]: %s\n", ret, sss_strerror(ret)); goto done; } *_rules = talloc_steal(mem_ctx, rules); *_num_rules = num_rules; done: talloc_free(tmp_ctx); return ret; } static errno_t ipa_sudo_filter_rules_bycmdgroups(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct sysdb_attrs **cmdgroups, size_t num_cmdgroups, struct sdap_attr_map *map_rule, char **_filter) { TALLOC_CTX *tmp_ctx; struct sysdb_attrs **rules; size_t num_rules; const char *name; char *sanitized; char *filter; errno_t ret; size_t i; if (num_cmdgroups == 0) { *_filter = NULL; return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = ipa_sudo_assoc_rules(tmp_ctx, domain, cmdgroups, num_cmdgroups, &rules, &num_rules); if (ret != EOK) { goto done; } if (num_rules == 0) { *_filter = NULL; ret = EOK; goto done; } filter = talloc_strdup(tmp_ctx, ""); if (filter == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < num_rules; i++) { ret = sysdb_attrs_get_string(rules[i], SYSDB_NAME, &name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get name [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sss_filter_sanitize(tmp_ctx, name, &sanitized); if (ret != EOK) { goto done; } filter = talloc_asprintf_append(filter, "(%s=%s)", map_rule[IPA_AT_SUDORULE_NAME].name, sanitized); if (filter == NULL) { ret = ENOMEM; goto done; } } filter = talloc_asprintf(tmp_ctx, "(|%s)", filter); if (filter == NULL) { ret = ENOMEM; goto done; } *_filter = talloc_steal(mem_ctx, filter); ret = EOK; done: talloc_free(tmp_ctx); return ret; } struct ipa_sudo_fetch_state { struct tevent_context *ev; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; struct ipa_sudo_ctx *sudo_ctx; struct sdap_options *sdap_opts; struct ipa_hostinfo *host; struct sdap_handle *sh; const char *search_filter; const char *cmdgroups_filter; struct sdap_attr_map *map_cmdgroup; struct sdap_attr_map *map_rule; struct sdap_attr_map *map_cmd; struct sdap_search_base **sudo_sb; struct ipa_sudo_conv *conv; struct sysdb_attrs **rules; size_t num_rules; char *usn; }; static errno_t ipa_sudo_fetch_addtl_cmdgroups(struct tevent_req *req); static void ipa_sudo_fetch_addtl_cmdgroups_done(struct tevent_req *subreq); static errno_t ipa_sudo_fetch_rules(struct tevent_req *req); static void ipa_sudo_fetch_rules_done(struct tevent_req *subreq); static errno_t ipa_sudo_fetch_cmdgroups(struct tevent_req *req); static void ipa_sudo_fetch_cmdgroups_done(struct tevent_req *subreq); static errno_t ipa_sudo_fetch_cmds(struct tevent_req *req); static void ipa_sudo_fetch_cmds_done(struct tevent_req *subreq); static void ipa_sudo_fetch_done(struct tevent_req *req); static struct tevent_req * ipa_sudo_fetch_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sss_domain_info *domain, struct sysdb_ctx *sysdb, struct ipa_sudo_ctx *sudo_ctx, struct ipa_hostinfo *host, struct sdap_attr_map *map_user, struct sdap_attr_map *map_group, struct sdap_attr_map *map_host, struct sdap_attr_map *map_hostgroup, struct sdap_handle *sh, const char *cmdgroups_filter, const char *search_filter) { struct ipa_sudo_fetch_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ipa_sudo_fetch_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n")); return NULL; } state->ev = ev; state->sysdb = sysdb; state->domain = domain; state->sudo_ctx = sudo_ctx; state->sdap_opts = sudo_ctx->sdap_opts; state->host = host; state->sh = sh; state->search_filter = search_filter == NULL ? "" : search_filter; state->cmdgroups_filter = cmdgroups_filter; state->map_cmdgroup = sudo_ctx->sudocmdgroup_map; state->map_rule = sudo_ctx->sudorule_map; state->map_cmd = sudo_ctx->sudocmd_map; state->sudo_sb = sudo_ctx->sudo_sb; state->conv = ipa_sudo_conv_init(state, sysdb, state->map_rule, state->map_cmdgroup, state->map_cmd, map_user, map_group, map_host, map_hostgroup); if (state->conv == NULL) { ret = ENOMEM; goto immediately; } if (state->cmdgroups_filter != NULL) { /* We need to fetch additional cmdgroups that may not be revealed * during normal search. Such as when using entryUSN filter in smart * refresh, some command groups may have change but none rule was * modified but we need to fetch associated rules anyway. */ ret = ipa_sudo_fetch_addtl_cmdgroups(req); } else { ret = ipa_sudo_fetch_rules(req); } if (ret != EAGAIN) { goto immediately; } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, state->ev); return req; } static errno_t ipa_sudo_fetch_addtl_cmdgroups(struct tevent_req *req) { struct ipa_sudo_fetch_state *state; struct tevent_req *subreq; struct sdap_attr_map *map; char *filter; DEBUG(SSSDBG_TRACE_FUNC, "About to fetch additional command groups\n"); state = tevent_req_data(req, struct ipa_sudo_fetch_state); map = state->map_cmdgroup; filter = talloc_asprintf(state, "(&(objectClass=%s)%s)", map[IPA_OC_SUDOCMDGROUP].name, state->cmdgroups_filter); if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n"); return ENOMEM; } subreq = sdap_search_bases_send(state, state->ev, state->sdap_opts, state->sh, state->sudo_sb, map, true, 0, filter, NULL); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, ipa_sudo_fetch_addtl_cmdgroups_done, req); return EAGAIN; } static void ipa_sudo_fetch_addtl_cmdgroups_done(struct tevent_req *subreq) { struct ipa_sudo_fetch_state *state = NULL; struct tevent_req *req = NULL; struct sysdb_attrs **attrs; size_t num_attrs; char *filter; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_sudo_fetch_state); ret = sdap_search_bases_recv(subreq, state, &num_attrs, &attrs); talloc_zfree(subreq); if (ret != EOK) { goto done; } DEBUG(SSSDBG_IMPORTANT_INFO, "Received %zu additional command groups\n", num_attrs); ret = ipa_sudo_filter_rules_bycmdgroups(state, state->domain, attrs, num_attrs, state->map_rule, &filter); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to construct rules filter " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } state->search_filter = sdap_or_filters(state, state->search_filter, filter); if (state->search_filter == NULL) { ret = ENOMEM; goto done; } ret = ipa_sudo_fetch_rules(req); done: if (ret == EOK) { ipa_sudo_fetch_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static errno_t ipa_sudo_fetch_rules(struct tevent_req *req) { struct ipa_sudo_fetch_state *state; struct tevent_req *subreq; struct sdap_attr_map *map; char *host_filter; char *filter; DEBUG(SSSDBG_TRACE_FUNC, "About to fetch sudo rules\n"); state = tevent_req_data(req, struct ipa_sudo_fetch_state); map = state->map_rule; host_filter = ipa_sudo_host_filter(state, state->host, map); if (host_filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build host filter\n"); return ENOMEM; } filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=TRUE)%s%s)", map[IPA_OC_SUDORULE].name, map[IPA_AT_SUDORULE_ENABLED].name, host_filter, state->search_filter); talloc_zfree(host_filter); if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n"); return ENOMEM; } subreq = sdap_search_bases_send(state, state->ev, state->sdap_opts, state->sh, state->sudo_sb, map, true, 0, filter, NULL); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, ipa_sudo_fetch_rules_done, req); return EAGAIN; } static void ipa_sudo_fetch_rules_done(struct tevent_req *subreq) { struct ipa_sudo_fetch_state *state = NULL; struct tevent_req *req = NULL; struct sysdb_attrs **attrs; size_t num_attrs; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_sudo_fetch_state); ret = sdap_search_bases_recv(subreq, state, &num_attrs, &attrs); talloc_zfree(subreq); if (ret != EOK) { goto done; } DEBUG(SSSDBG_IMPORTANT_INFO, "Received %zu sudo rules\n", num_attrs); ret = ipa_sudo_conv_rules(state->conv, attrs, num_attrs); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed when converting rules " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = ipa_sudo_highest_usn(state, attrs, num_attrs, &state->usn); if (ret != EOK) { goto done; } ret = ipa_sudo_fetch_cmdgroups(req); done: if (ret == EOK) { ipa_sudo_fetch_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static errno_t ipa_sudo_fetch_cmdgroups(struct tevent_req *req) { struct ipa_sudo_fetch_state *state; struct tevent_req *subreq; char *filter; DEBUG(SSSDBG_TRACE_FUNC, "About to fetch sudo command groups\n"); state = tevent_req_data(req, struct ipa_sudo_fetch_state); if (ipa_sudo_conv_has_cmdgroups(state->conv)) { DEBUG(SSSDBG_TRACE_FUNC, "No command groups needs to be downloaded\n"); return ipa_sudo_fetch_cmds(req); } filter = ipa_sudo_conv_cmdgroup_filter(state, state->conv); if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n"); return ENOMEM; } subreq = sdap_search_bases_send(state, state->ev, state->sdap_opts, state->sh, state->sudo_sb, state->map_cmdgroup, true, 0, filter, NULL); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, ipa_sudo_fetch_cmdgroups_done, req); return EAGAIN; } static void ipa_sudo_fetch_cmdgroups_done(struct tevent_req *subreq) { struct ipa_sudo_fetch_state *state = NULL; struct tevent_req *req = NULL; struct sysdb_attrs **attrs; size_t num_attrs; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_sudo_fetch_state); ret = sdap_search_bases_recv(subreq, state, &num_attrs, &attrs); talloc_zfree(subreq); if (ret != EOK) { goto done; } DEBUG(SSSDBG_IMPORTANT_INFO, "Received %zu sudo command groups\n", num_attrs); ret = ipa_sudo_conv_cmdgroups(state->conv, attrs, num_attrs); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed when converting command groups " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = ipa_sudo_highest_usn(state, attrs, num_attrs, &state->usn); if (ret != EOK) { goto done; } ret = ipa_sudo_fetch_cmds(req); done: if (ret == EOK) { ipa_sudo_fetch_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static errno_t ipa_sudo_fetch_cmds(struct tevent_req *req) { struct ipa_sudo_fetch_state *state; struct tevent_req *subreq; char *filter; DEBUG(SSSDBG_TRACE_FUNC, "About to fetch sudo commands\n"); state = tevent_req_data(req, struct ipa_sudo_fetch_state); if (ipa_sudo_conv_has_cmds(state->conv)) { DEBUG(SSSDBG_TRACE_FUNC, "No commands needs to be downloaded\n"); return EOK; } filter = ipa_sudo_conv_cmd_filter(state, state->conv); if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n"); return ENOMEM; } subreq = sdap_search_bases_send(state, state->ev, state->sdap_opts, state->sh, state->sudo_sb, state->map_cmd, true, 0, filter, NULL); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, ipa_sudo_fetch_cmds_done, req); return EAGAIN; } static void ipa_sudo_fetch_cmds_done(struct tevent_req *subreq) { struct ipa_sudo_fetch_state *state = NULL; struct tevent_req *req = NULL; struct sysdb_attrs **attrs; size_t num_attrs; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_sudo_fetch_state); ret = sdap_search_bases_recv(subreq, state, &num_attrs, &attrs); talloc_zfree(subreq); if (ret != EOK) { goto done; } DEBUG(SSSDBG_IMPORTANT_INFO, "Received %zu sudo commands\n", num_attrs); ret = ipa_sudo_conv_cmds(state->conv, attrs, num_attrs); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed when converting commands " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } done: if (ret == EOK) { ipa_sudo_fetch_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static void ipa_sudo_fetch_done(struct tevent_req *req) { struct ipa_sudo_fetch_state *state = NULL; errno_t ret; state = tevent_req_data(req, struct ipa_sudo_fetch_state); DEBUG(SSSDBG_TRACE_FUNC, "About to convert rules\n"); ret = ipa_sudo_conv_result(state, state->conv, &state->rules, &state->num_rules); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to convert rules [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t ipa_sudo_fetch_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct sysdb_attrs ***_rules, size_t *_num_rules, char **_usn) { struct ipa_sudo_fetch_state *state = NULL; state = tevent_req_data(req, struct ipa_sudo_fetch_state); TEVENT_REQ_RETURN_ON_ERROR(req); *_rules = talloc_steal(mem_ctx, state->rules); *_num_rules = state->num_rules; *_usn = talloc_steal(mem_ctx, state->usn); return EOK; } struct ipa_sudo_refresh_state { struct tevent_context *ev; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; struct ipa_sudo_ctx *sudo_ctx; struct ipa_options *ipa_opts; struct sdap_options *sdap_opts; const char *cmdgroups_filter; const char *search_filter; const char *delete_filter; struct sdap_id_op *sdap_op; struct sdap_handle *sh; int dp_error; struct sysdb_attrs **rules; size_t num_rules; }; static errno_t ipa_sudo_refresh_retry(struct tevent_req *req); static void ipa_sudo_refresh_connect_done(struct tevent_req *subreq); static void ipa_sudo_refresh_host_done(struct tevent_req *subreq); static void ipa_sudo_refresh_done(struct tevent_req *subreq); struct tevent_req * ipa_sudo_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_sudo_ctx *sudo_ctx, const char *cmdgroups_filter, const char *search_filter, const char *delete_filter) { struct ipa_sudo_refresh_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ipa_sudo_refresh_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n")); return NULL; } state->ev = ev; state->sysdb = sudo_ctx->id_ctx->be->domain->sysdb; state->domain = sudo_ctx->id_ctx->be->domain; state->sudo_ctx = sudo_ctx; state->ipa_opts = sudo_ctx->ipa_opts; state->sdap_opts = sudo_ctx->sdap_opts; state->dp_error = DP_ERR_FATAL; state->sdap_op = sdap_id_op_create(state, sudo_ctx->id_ctx->conn->conn_cache); if (!state->sdap_op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create() failed\n"); ret = ENOMEM; goto immediately; } state->cmdgroups_filter = talloc_strdup(state, cmdgroups_filter); if (cmdgroups_filter != NULL && state->cmdgroups_filter == NULL) { ret = ENOMEM; goto immediately; } state->search_filter = talloc_strdup(state, search_filter); if (search_filter != NULL && state->search_filter == NULL) { ret = ENOMEM; goto immediately; } state->delete_filter = talloc_strdup(state, delete_filter); if (delete_filter != NULL && state->delete_filter == NULL) { ret = ENOMEM; goto immediately; } ret = ipa_sudo_refresh_retry(req); if (ret == EAGAIN) { /* asynchronous processing */ return req; } immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, state->ev); return req; } static errno_t ipa_sudo_refresh_retry(struct tevent_req *req) { struct ipa_sudo_refresh_state *state; struct tevent_req *subreq; int ret; state = tevent_req_data(req, struct ipa_sudo_refresh_state); subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_id_op_connect_send() failed: " "%d(%s)\n", ret, strerror(ret)); return ret; } tevent_req_set_callback(subreq, ipa_sudo_refresh_connect_done, req); return EAGAIN; } static void ipa_sudo_refresh_connect_done(struct tevent_req *subreq) { struct ipa_sudo_refresh_state *state; const char *hostname; struct tevent_req *req; int dp_error; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_sudo_refresh_state); ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "SUDO LDAP connection failed " "[%d]: %s\n", ret, strerror(ret)); state->dp_error = dp_error; tevent_req_error(req, ret); return; } state->sh = sdap_id_op_handle(state->sdap_op); DEBUG(SSSDBG_TRACE_FUNC, "SUDO LDAP connection successful\n"); DEBUG(SSSDBG_TRACE_FUNC, "About to fetch host information\n"); /* Obtain host information. */ hostname = dp_opt_get_string(state->ipa_opts->basic, IPA_HOSTNAME); subreq = ipa_host_info_send(state, state->ev, state->sh, state->sdap_opts, hostname, state->ipa_opts->host_map, state->ipa_opts->hostgroup_map, state->ipa_opts->host_search_bases); if (subreq == NULL) { state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, ipa_sudo_refresh_host_done, req); } static void ipa_sudo_refresh_host_done(struct tevent_req *subreq) { struct ipa_sudo_refresh_state *state; struct ipa_hostinfo *host; struct tevent_req *req; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_sudo_refresh_state); host = talloc_zero(state, struct ipa_hostinfo); if (host == NULL) { state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ENOMEM); return; } ret = ipa_host_info_recv(subreq, host, &host->num_hosts, &host->hosts, &host->num_hostgroups, &host->hostgroups); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve host information " "[%d]: %s\n", ret, sss_strerror(ret)); state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); return; } subreq = ipa_sudo_fetch_send(state, state->ev, state->domain, state->sysdb, state->sudo_ctx, host, state->sdap_opts->user_map, state->sdap_opts->group_map, state->ipa_opts->host_map, state->ipa_opts->hostgroup_map, state->sh, state->cmdgroups_filter, state->search_filter); if (subreq == NULL) { state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, ipa_sudo_refresh_done, req); } static void ipa_sudo_refresh_done(struct tevent_req *subreq) { struct ipa_sudo_refresh_state *state; struct tevent_req *req; char *usn = NULL; bool in_transaction = false; errno_t sret; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_sudo_refresh_state); ret = ipa_sudo_fetch_recv(state, subreq, &state->rules, &state->num_rules, &usn); talloc_zfree(subreq); ret = sdap_id_op_done(state->sdap_op, ret, &state->dp_error); if (state->dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = ipa_sudo_refresh_retry(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } else if (ret != EOK) { tevent_req_error(req, ret); return; } ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; ret = sysdb_sudo_purge(state->domain, state->delete_filter, state->rules, state->num_rules); if (ret != EOK) { goto done; } ret = sysdb_sudo_store(state->domain, state->rules, state->num_rules); if (ret != EOK) { goto done; } ret = sysdb_transaction_commit(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; if (usn != NULL) { sdap_sudo_set_usn(state->sudo_ctx->id_ctx->srv_opts, usn); } DEBUG(SSSDBG_TRACE_FUNC, "Sudo rules are successfully stored in cache\n"); done: if (in_transaction) { sret = sysdb_transaction_cancel(state->sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not cancel transaction\n"); } } if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } errno_t ipa_sudo_refresh_recv(struct tevent_req *req, int *dp_error, size_t *_num_rules) { struct ipa_sudo_refresh_state *state = NULL; state = tevent_req_data(req, struct ipa_sudo_refresh_state); TEVENT_REQ_RETURN_ON_ERROR(req); *dp_error = state->dp_error; if (_num_rules != NULL) { *_num_rules = state->num_rules; } return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_utils.c0000644000000000000000000000007312703456111020036 xustar0030 atime=1460561751.646715613 29 ctime=1460561774.73779391 sssd-1.13.4/src/providers/ipa/ipa_utils.c0000644002412700241270000000400312703456111021503 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Module utility functions Authors: Sumit Bose Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #define OVERRIDE_ANCHOR_IPA_PREFIX ":IPA:" #define OVERRIDE_ANCHOR_IPA_PREFIX_LEN (sizeof(OVERRIDE_ANCHOR_IPA_PREFIX) -1 ) errno_t split_ipa_anchor(TALLOC_CTX *mem_ctx, const char *anchor, char **_anchor_domain, char **_ipa_uuid) { const char *sep; if (anchor == NULL) { return EINVAL; } if (strncmp(OVERRIDE_ANCHOR_IPA_PREFIX, anchor, OVERRIDE_ANCHOR_IPA_PREFIX_LEN) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "No IPA anchor [%s].\n", anchor); return ENOMSG; } sep = strchr(anchor + OVERRIDE_ANCHOR_IPA_PREFIX_LEN, ':'); if (sep == NULL || sep[1] == '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Broken IPA anchor [%s].\n", anchor); return EINVAL; } *_anchor_domain = talloc_strndup(mem_ctx, anchor + OVERRIDE_ANCHOR_IPA_PREFIX_LEN, sep - anchor - OVERRIDE_ANCHOR_IPA_PREFIX_LEN); *_ipa_uuid = talloc_strdup(mem_ctx, sep + 1); if (*_anchor_domain == NULL || *_ipa_uuid == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); talloc_free(*_anchor_domain); talloc_free(*_ipa_uuid); return ENOMEM; } return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hosts.c0000644000000000000000000000007312703456111020036 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.730793887 sssd-1.13.4/src/providers/ipa/ipa_hosts.c0000644002412700241270000003600212703456111021507 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Jan Zeleny Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/sdap_async.h" #include "providers/ipa/ipa_hosts.h" #include "providers/ipa/ipa_common.h" struct ipa_host_state { struct tevent_context *ev; struct sysdb_ctx *sysdb; struct sdap_handle *sh; struct sdap_options *opts; const char **attrs; struct sdap_attr_map *host_map; struct sdap_attr_map *hostgroup_map; struct sdap_search_base **search_bases; int search_base_iter; char *cur_filter; char *host_filter; const char *hostname; /* Return values */ size_t host_count; struct sysdb_attrs **hosts; size_t hostgroup_count; struct sysdb_attrs **hostgroups; struct sdap_attr_map_info *ipa_hostgroup_map; }; static void ipa_host_info_done(struct tevent_req *subreq); static void ipa_hostgroup_info_done(struct tevent_req *subreq); static errno_t ipa_host_info_next(struct tevent_req *req, struct ipa_host_state *state); static errno_t ipa_hostgroup_info_next(struct tevent_req *req, struct ipa_host_state *state); /** * hostname == NULL -> look up all hosts / host groups * hostname != NULL -> look up only given host and groups * it's member of * hostgroup_map == NULL -> skip looking up hostgroups */ struct tevent_req * ipa_host_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, struct sdap_options *opts, const char *hostname, struct sdap_attr_map *host_map, struct sdap_attr_map *hostgroup_map, struct sdap_search_base **search_bases) { errno_t ret; struct ipa_host_state *state; struct tevent_req *req; req = tevent_req_create(mem_ctx, &state, struct ipa_host_state); if (req == NULL) { return NULL; } state->ev = ev; state->sh = sh; state->opts = opts; state->hostname = hostname; state->search_bases = search_bases; state->search_base_iter = 0; state->cur_filter = NULL; state->host_map = host_map; state->hostgroup_map = hostgroup_map; ret = build_attrs_from_map(state, host_map, IPA_OPTS_HOST, NULL, &state->attrs, NULL); if (ret != EOK) { goto immediate; } if (hostname == NULL) { state->host_filter = talloc_asprintf(state, "(objectClass=%s)", host_map[IPA_OC_HOST].name); } else { state->host_filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=%s))", host_map[IPA_OC_HOST].name, host_map[IPA_AT_HOST_FQDN].name, hostname); } if (state->host_filter == NULL) { ret = ENOMEM; goto immediate; } ret = ipa_host_info_next(req, state); if (ret == EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "No host search base configured?\n"); ret = EINVAL; } if (ret != EAGAIN) { goto immediate; } return req; immediate: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t ipa_host_info_next(struct tevent_req *req, struct ipa_host_state *state) { struct sdap_search_base *base; struct tevent_req *subreq; base = state->search_bases[state->search_base_iter]; if (base == NULL) { return EOK; } talloc_zfree(state->cur_filter); state->cur_filter = sdap_combine_filters(state, state->host_filter, base->filter); if (state->cur_filter == NULL) { return ENOMEM; } subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, base->basedn, base->scope, state->cur_filter, state->attrs, state->host_map, IPA_OPTS_HOST, dp_opt_get_int(state->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), true); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Error requesting host info\n"); talloc_zfree(state->cur_filter); return EIO; } tevent_req_set_callback(subreq, ipa_host_info_done, req); return EAGAIN; } static void ipa_host_info_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_host_state *state = tevent_req_data(req, struct ipa_host_state); const char *host_dn; ret = sdap_get_generic_recv(subreq, state, &state->host_count, &state->hosts); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } if (state->host_count == 0) { state->search_base_iter++; ret = ipa_host_info_next(req, state); if (ret == EOK) { /* No more search bases to try */ tevent_req_error(req, ENOENT); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } if (state->hostgroup_map) { talloc_free(state->attrs); ret = build_attrs_from_map(state, state->hostgroup_map, IPA_OPTS_HOSTGROUP, NULL, &state->attrs, NULL); if (ret != EOK) { tevent_req_error(req, ret); return; } /* Look up host groups */ if (state->hostname == NULL) { talloc_zfree(state->host_filter); state->host_filter = talloc_asprintf(state, "(objectClass=%s)", state->hostgroup_map[IPA_OC_HOSTGROUP].name); if (state->host_filter == NULL) { tevent_req_error(req, ENOMEM); return; } state->search_base_iter = 0; ret = ipa_hostgroup_info_next(req, state); if (ret == EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "No host search base configured?\n"); tevent_req_error(req, EINVAL); return; } else if (ret != EAGAIN) { tevent_req_error(req, ret); return; } } else { state->ipa_hostgroup_map = talloc_zero(state, struct sdap_attr_map_info); if (state->ipa_hostgroup_map == NULL) { tevent_req_error(req, ENOMEM); return; } state->ipa_hostgroup_map->map = state->hostgroup_map; state->ipa_hostgroup_map->num_attrs = IPA_OPTS_HOSTGROUP; ret = sysdb_attrs_get_string(state->hosts[0], SYSDB_ORIG_DN, &host_dn); if (ret != EOK) { tevent_req_error(req, ret); return; } if (!sdap_has_deref_support(state->sh, state->opts)) { DEBUG(SSSDBG_CRIT_FAILURE, "Server does not support deref\n"); tevent_req_error(req, EIO); return; } subreq = sdap_deref_search_send(state, state->ev, state->opts, state->sh, host_dn, state->hostgroup_map[IPA_AT_HOSTGROUP_MEMBER_OF].name, state->attrs, 1, state->ipa_hostgroup_map, dp_opt_get_int(state->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT)); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Error requesting host info\n"); tevent_req_error(req, EIO); return; } tevent_req_set_callback(subreq, ipa_hostgroup_info_done, req); } } else { /* Nothing else to do, just complete the req */ tevent_req_done(req); } } static errno_t ipa_hostgroup_info_next(struct tevent_req *req, struct ipa_host_state *state) { struct sdap_search_base *base; struct tevent_req *subreq; base = state->search_bases[state->search_base_iter]; if (base == NULL) { return EOK; } talloc_zfree(state->cur_filter); state->cur_filter = sdap_combine_filters(state, state->host_filter, base->filter); if (state->cur_filter == NULL) { return ENOMEM; } subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, base->basedn, base->scope, state->cur_filter, state->attrs, state->hostgroup_map, IPA_OPTS_HOSTGROUP, dp_opt_get_int(state->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), true); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Error requesting hostgroup info\n"); talloc_zfree(state->cur_filter); return EIO; } tevent_req_set_callback(subreq, ipa_hostgroup_info_done, req); return EAGAIN; } static void ipa_hostgroup_info_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_host_state *state = tevent_req_data(req, struct ipa_host_state); size_t hostgroups_total; size_t hostgroup_count; struct sysdb_attrs **hostgroups; struct sdap_deref_attrs **deref_result; const char *hostgroup_name; const char *hostgroup_dn; int i, j; if (state->hostname == NULL) { ret = sdap_get_generic_recv(subreq, state, &hostgroup_count, &hostgroups); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_recv failed: [%d]\n", ret); tevent_req_error(req, ret); return; } /* Merge the two arrays */ if (hostgroup_count > 0) { hostgroups_total = hostgroup_count + state->hostgroup_count; state->hostgroups = talloc_realloc(state, state->hostgroups, struct sysdb_attrs *, hostgroups_total); if (state->hostgroups == NULL) { tevent_req_error(req, ENOMEM); return; } i = 0; while(state->hostgroup_count < hostgroups_total) { state->hostgroups[state->hostgroup_count] = talloc_steal(state->hostgroups, hostgroups[i]); state->hostgroup_count++; i++; } } /* Now look in the next base */ state->search_base_iter++; ret = ipa_hostgroup_info_next(req, state); if (ret != EOK && ret != EAGAIN) { tevent_req_error(req, ret); } if (ret != EOK) { /* Only continue if no error occurred * and no req was created */ return; } } else { ret = sdap_deref_search_recv(subreq, state, &state->hostgroup_count, &deref_result); talloc_zfree(subreq); if (ret != EOK) goto done; if (state->hostgroup_count == 0) { DEBUG(SSSDBG_FUNC_DATA, "No host groups were dereferenced\n"); } else { state->hostgroups = talloc_zero_array(state, struct sysdb_attrs *, state->hostgroup_count); if (state->hostgroups == NULL) { ret = ENOMEM; goto done; } j = 0; for (i = 0; i < state->hostgroup_count; i++) { ret = sysdb_attrs_get_string(deref_result[i]->attrs, SYSDB_ORIG_DN, &hostgroup_dn); if (ret != EOK) goto done; if (!sss_ldap_dn_in_search_bases(state, hostgroup_dn, state->search_bases, NULL)) { continue; } ret = sysdb_attrs_get_string(deref_result[i]->attrs, state->hostgroup_map[IPA_AT_HOSTGROUP_NAME].sys_name, &hostgroup_name); if (ret != EOK) goto done; DEBUG(SSSDBG_FUNC_DATA, "Dereferenced host group: %s\n", hostgroup_name); state->hostgroups[j] = talloc_steal(state->hostgroups, deref_result[i]->attrs); j++; } state->hostgroup_count = j; } } done: if (ret == EOK) { tevent_req_done(req); } else { DEBUG(SSSDBG_OP_FAILURE, "Error [%d][%s]\n", ret, strerror(ret)); tevent_req_error(req, ret); } } errno_t ipa_host_info_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *host_count, struct sysdb_attrs ***hosts, size_t *hostgroup_count, struct sysdb_attrs ***hostgroups) { size_t c; struct ipa_host_state *state = tevent_req_data(req, struct ipa_host_state); TEVENT_REQ_RETURN_ON_ERROR(req); *host_count = state->host_count; *hosts = talloc_steal(mem_ctx, state->hosts); for (c = 0; c < state->host_count; c++) { /* Guarantee the memory heirarchy of the list */ talloc_steal(state->hosts, state->hosts[c]); } if (hostgroup_count) *hostgroup_count = state->hostgroup_count; if (hostgroups) *hostgroups = talloc_steal(mem_ctx, state->hostgroups); return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_access.c0000644000000000000000000000007312703456111020137 xustar0030 atime=1460561751.644715607 29 ctime=1460561774.72879388 sssd-1.13.4/src/providers/ipa/ipa_access.c0000644002412700241270000005516712703456111021625 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- Access control Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/util.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_access.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_access.h" #include "providers/ipa/ipa_hbac.h" #include "providers/ipa/ipa_hosts.h" #include "providers/ipa/ipa_hbac_private.h" #include "providers/ipa/ipa_hbac_rules.h" static void ipa_access_reply(struct hbac_ctx *hbac_ctx, int pam_status) { struct be_req *be_req = hbac_ctx->be_req; struct pam_data *pd; pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); pd->pam_status = pam_status; /* destroy HBAC context now to release all used resources and LDAP connection */ talloc_zfree(hbac_ctx); if (pam_status == PAM_SUCCESS || pam_status == PAM_PERM_DENIED) { be_req_terminate(be_req, DP_ERR_OK, pam_status, NULL); } else { be_req_terminate(be_req, DP_ERR_FATAL, pam_status, NULL); } } enum hbac_result { HBAC_ALLOW = 1, HBAC_DENY, HBAC_NOT_APPLICABLE }; enum check_result { RULE_APPLICABLE = 0, RULE_NOT_APPLICABLE, RULE_ERROR }; static void ipa_hbac_check(struct tevent_req *req); static int hbac_retry(struct hbac_ctx *hbac_ctx); static void hbac_connect_done(struct tevent_req *subreq); static bool hbac_check_step_result(struct hbac_ctx *hbac_ctx, int ret); static int hbac_get_host_info_step(struct hbac_ctx *hbac_ctx); static void ipa_hbac_evaluate_rules(struct hbac_ctx *hbac_ctx); void ipa_access_handler(struct be_req *be_req) { struct pam_data *pd; struct ipa_access_ctx *ipa_access_ctx; struct tevent_req *req; struct sss_domain_info *dom; struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); ipa_access_ctx = talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data, struct ipa_access_ctx); dom = be_ctx->domain; if (strcasecmp(pd->domain, be_ctx->domain->name) != 0) { /* Subdomain request, verify subdomain */ dom = find_domain_by_name(be_ctx->domain, pd->domain, true); } /* First, verify that this account isn't locked. * We need to do this in case the auth phase was * skipped (such as during GSSAPI single-sign-on * or SSH public key exchange. */ req = sdap_access_send(be_req, be_ctx->ev, be_ctx, dom, ipa_access_ctx->sdap_access_ctx, ipa_access_ctx->sdap_access_ctx->id_ctx->conn, pd); if (!req) { be_req_terminate(be_req, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL); return; } tevent_req_set_callback(req, ipa_hbac_check, be_req); } static void ipa_hbac_check(struct tevent_req *req) { struct be_req *be_req; struct be_ctx *be_ctx; struct pam_data *pd; struct hbac_ctx *hbac_ctx = NULL; struct ipa_access_ctx *ipa_access_ctx; int ret; be_req = tevent_req_callback_data(req, struct be_req); be_ctx = be_req_get_be_ctx(be_req); pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); ret = sdap_access_recv(req); talloc_zfree(req); switch(ret) { case EOK: /* Account wasn't locked. Continue below * to HBAC processing. */ break; case ERR_ACCESS_DENIED: /* Account was locked. Return permission denied * here. */ pd->pam_status = PAM_PERM_DENIED; be_req_terminate(be_req, DP_ERR_OK, pd->pam_status, NULL); return; case ERR_ACCOUNT_EXPIRED: pd->pam_status = PAM_ACCT_EXPIRED; be_req_terminate(be_req, DP_ERR_OK, pd->pam_status, NULL); return; default: /* We got an unexpected error. Return it as-is */ pd->pam_status = PAM_SYSTEM_ERR; be_req_terminate(be_req, DP_ERR_FATAL, pd->pam_status, sss_strerror(ret)); return; } hbac_ctx = talloc_zero(be_req, struct hbac_ctx); if (hbac_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); ret = ENOMEM; goto fail; } hbac_ctx->be_req = be_req; hbac_ctx->pd = pd; ipa_access_ctx = talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data, struct ipa_access_ctx); hbac_ctx->access_ctx = ipa_access_ctx; hbac_ctx->sdap_ctx = ipa_access_ctx->sdap_ctx; hbac_ctx->ipa_options = ipa_access_ctx->ipa_options; hbac_ctx->tr_ctx = ipa_access_ctx->tr_ctx; hbac_ctx->search_bases = ipa_access_ctx->hbac_search_bases; if (hbac_ctx->search_bases == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No HBAC search base found.\n"); ret = EINVAL; goto fail; } ret = hbac_retry(hbac_ctx); if (ret != EOK) { goto fail; } return; fail: if (hbac_ctx) { /* Return an proper error */ ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); } else { be_req_terminate(be_req, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL); } } static int hbac_retry(struct hbac_ctx *hbac_ctx) { struct tevent_req *subreq; int ret; bool offline; time_t now, refresh_interval; struct ipa_access_ctx *access_ctx = hbac_ctx->access_ctx; struct be_ctx *be_ctx = be_req_get_be_ctx(hbac_ctx->be_req); offline = be_is_offline(be_ctx); DEBUG(SSSDBG_TRACE_ALL, "Connection status is [%s].\n", offline ? "offline" : "online"); refresh_interval = dp_opt_get_int(hbac_ctx->ipa_options, IPA_HBAC_REFRESH); now = time(NULL); if (now < access_ctx->last_update + refresh_interval) { /* Simulate offline mode and just go to the cache */ DEBUG(SSSDBG_TRACE_FUNC, "Performing cached HBAC evaluation\n"); offline = true; } if (!offline) { if (hbac_ctx->sdap_op == NULL) { hbac_ctx->sdap_op = sdap_id_op_create(hbac_ctx, hbac_ctx->sdap_ctx->conn->conn_cache); if (hbac_ctx->sdap_op == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_id_op_create failed.\n"); return EIO; } } subreq = sdap_id_op_connect_send(hbac_ctx->sdap_op, hbac_ctx, &ret); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n", ret, strerror(ret)); talloc_zfree(hbac_ctx->sdap_op); return ret; } tevent_req_set_callback(subreq, hbac_connect_done, hbac_ctx); } else { /* Evaluate the rules based on what we have in the * sysdb */ ipa_hbac_evaluate_rules(hbac_ctx); return EOK; } return EOK; } static void hbac_connect_done(struct tevent_req *subreq) { struct hbac_ctx *hbac_ctx = tevent_req_callback_data(subreq, struct hbac_ctx); int ret, dp_error; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (dp_error == DP_ERR_OFFLINE) { /* switching to offline mode */ talloc_zfree(hbac_ctx->sdap_op); ipa_hbac_evaluate_rules(hbac_ctx); return; } else if (ret != EOK) { goto fail; } ret = hbac_get_host_info_step(hbac_ctx); if (ret != EOK) { goto fail; } return; fail: ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); } static void hbac_clear_rule_data(struct hbac_ctx *hbac_ctx) { hbac_ctx->host_count = 0; talloc_zfree(hbac_ctx->hosts); hbac_ctx->hostgroup_count = 0; talloc_zfree(hbac_ctx->hostgroups); hbac_ctx->service_count = 0; talloc_zfree(hbac_ctx->services); hbac_ctx->servicegroup_count = 0; talloc_zfree(hbac_ctx->servicegroups); hbac_ctx->rule_count = 0; talloc_zfree(hbac_ctx->rules); } /* Check whether the current HBAC request is processed in off-line mode */ static inline bool hbac_ctx_is_offline(struct hbac_ctx *ctx) { return ctx == NULL || ctx->sdap_op == NULL; } /* Check the step result code and continue, retry, get offline result or abort accordingly */ static bool hbac_check_step_result(struct hbac_ctx *hbac_ctx, int ret) { int dp_error; if (ret == EOK) { return true; } if (hbac_ctx_is_offline(hbac_ctx)) { /* already offline => the error is fatal */ ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); return false; } ret = sdap_id_op_done(hbac_ctx->sdap_op, ret, &dp_error); if (ret != EOK) { if (dp_error == DP_ERR_OFFLINE) { /* switching to offline mode */ talloc_zfree(hbac_ctx->sdap_op); /* Free any of the results we've gotten */ hbac_clear_rule_data(hbac_ctx); dp_error = DP_ERR_OK; } if (dp_error == DP_ERR_OK) { /* retry */ ret = hbac_retry(hbac_ctx); if (ret == EOK) { return false; } } } ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); return false; } static void hbac_get_service_info_step(struct tevent_req *req); static void hbac_get_rule_info_step(struct tevent_req *req); static void hbac_sysdb_save (struct tevent_req *req); static int hbac_get_host_info_step(struct hbac_ctx *hbac_ctx) { struct be_ctx *be_ctx = be_req_get_be_ctx(hbac_ctx->be_req); const char *hostname; struct tevent_req *req; if (dp_opt_get_bool(hbac_ctx->ipa_options, IPA_HBAC_SUPPORT_SRCHOST)) { /* Support srchost * -> we don't want any particular host, * we want all hosts */ hostname = NULL; /* THIS FEATURE IS DEPRECATED */ DEBUG(SSSDBG_MINOR_FAILURE, "WARNING: Using deprecated option " "ipa_hbac_support_srchost.\n"); sss_log(SSS_LOG_NOTICE, "WARNING: Using deprecated option " "ipa_hbac_support_srchost.\n"); } else { hostname = dp_opt_get_string(hbac_ctx->ipa_options, IPA_HOSTNAME); } req = ipa_host_info_send(hbac_ctx, be_ctx->ev, sdap_id_op_handle(hbac_ctx->sdap_op), hbac_ctx->sdap_ctx->opts, hostname, hbac_ctx->access_ctx->host_map, hbac_ctx->access_ctx->hostgroup_map, hbac_ctx->access_ctx->host_search_bases); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get host info\n"); return ENOMEM; } tevent_req_set_callback(req, hbac_get_service_info_step, hbac_ctx); return EOK; } static void hbac_get_service_info_step(struct tevent_req *req) { errno_t ret; struct hbac_ctx *hbac_ctx = tevent_req_callback_data(req, struct hbac_ctx); struct be_ctx *be_ctx = be_req_get_be_ctx(hbac_ctx->be_req); ret = ipa_host_info_recv(req, hbac_ctx, &hbac_ctx->host_count, &hbac_ctx->hosts, &hbac_ctx->hostgroup_count, &hbac_ctx->hostgroups); talloc_zfree(req); if (!hbac_check_step_result(hbac_ctx, ret)) { return; } /* Get services and service groups */ req = ipa_hbac_service_info_send(hbac_ctx, be_ctx->ev, sdap_id_op_handle(hbac_ctx->sdap_op), hbac_ctx->sdap_ctx->opts, hbac_ctx->search_bases); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE,"Could not get service info\n"); goto fail; } tevent_req_set_callback(req, hbac_get_rule_info_step, hbac_ctx); return; fail: ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); } static void hbac_get_rule_info_step(struct tevent_req *req) { errno_t ret; size_t i; const char *ipa_hostname; const char *hostname; struct hbac_ctx *hbac_ctx = tevent_req_callback_data(req, struct hbac_ctx); struct be_ctx *be_ctx = be_req_get_be_ctx(hbac_ctx->be_req); ret = ipa_hbac_service_info_recv(req, hbac_ctx, &hbac_ctx->service_count, &hbac_ctx->services, &hbac_ctx->servicegroup_count, &hbac_ctx->servicegroups); talloc_zfree(req); if (!hbac_check_step_result(hbac_ctx, ret)) { return; } /* Get the ipa_host attrs */ hbac_ctx->ipa_host = NULL; ipa_hostname = dp_opt_get_cstring(hbac_ctx->ipa_options, IPA_HOSTNAME); if (ipa_hostname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing ipa_hostname, this should never happen.\n"); goto fail; } for (i = 0; i < hbac_ctx->host_count; i++) { ret = sysdb_attrs_get_string(hbac_ctx->hosts[i], SYSDB_FQDN, &hostname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not locate IPA host\n"); goto fail; } if (strcasecmp(hostname, ipa_hostname) == 0) { hbac_ctx->ipa_host = hbac_ctx->hosts[i]; break; } } if (hbac_ctx->ipa_host == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not locate IPA host\n"); goto fail; } /* Get the list of applicable rules */ req = ipa_hbac_rule_info_send(hbac_ctx, be_ctx->ev, sdap_id_op_handle(hbac_ctx->sdap_op), hbac_ctx->sdap_ctx->opts, hbac_ctx->search_bases, hbac_ctx->ipa_host); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get rules\n"); goto fail; } tevent_req_set_callback(req, hbac_sysdb_save, hbac_ctx); return; fail: ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); } static void hbac_sysdb_save(struct tevent_req *req) { errno_t ret; bool in_transaction = false; struct hbac_ctx *hbac_ctx = tevent_req_callback_data(req, struct hbac_ctx); struct be_ctx *be_ctx = be_req_get_be_ctx(hbac_ctx->be_req); struct sss_domain_info *domain = be_ctx->domain; struct ldb_dn *base_dn; struct ipa_access_ctx *access_ctx = talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data, struct ipa_access_ctx); TALLOC_CTX *tmp_ctx; ret = ipa_hbac_rule_info_recv(req, hbac_ctx, &hbac_ctx->rule_count, &hbac_ctx->rules); talloc_zfree(req); if (ret == ENOENT) { /* No rules were found that apply to this * host. */ tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); return; } /* Delete any rules in the sysdb so offline logins * are also denied. */ base_dn = sysdb_custom_subtree_dn(tmp_ctx, domain, HBAC_RULES_SUBDIR); if (base_dn == NULL) { talloc_free(tmp_ctx); ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); return; } ret = sysdb_delete_recursive(domain->sysdb, base_dn, true); talloc_free(tmp_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_delete_recursive failed.\n"); ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); return; } /* If no rules are found, we default to DENY */ ipa_access_reply(hbac_ctx, PAM_PERM_DENIED); return; } if (!hbac_check_step_result(hbac_ctx, ret)) { return; } ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not start transaction\n"); goto fail; } in_transaction = true; /* Save the hosts */ ret = ipa_hbac_sysdb_save(domain, HBAC_HOSTS_SUBDIR, SYSDB_FQDN, hbac_ctx->host_count, hbac_ctx->hosts, HBAC_HOSTGROUPS_SUBDIR, SYSDB_NAME, hbac_ctx->hostgroup_count, hbac_ctx->hostgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error saving hosts: [%d][%s]\n", ret, strerror(ret)); goto fail; } /* Save the services */ ret = ipa_hbac_sysdb_save(domain, HBAC_SERVICES_SUBDIR, IPA_CN, hbac_ctx->service_count, hbac_ctx->services, HBAC_SERVICEGROUPS_SUBDIR, IPA_CN, hbac_ctx->servicegroup_count, hbac_ctx->servicegroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error saving services: [%d][%s]\n", ret, strerror(ret)); goto fail; } /* Save the rules */ ret = ipa_hbac_sysdb_save(domain, HBAC_RULES_SUBDIR, IPA_UNIQUE_ID, hbac_ctx->rule_count, hbac_ctx->rules, NULL, NULL, 0, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error saving rules: [%d][%s]\n", ret, strerror(ret)); goto fail; } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto fail; } in_transaction = false; /* We don't need the rule data any longer, * the rest of the processing relies on * sysdb lookups. */ hbac_clear_rule_data(hbac_ctx); access_ctx->last_update = time(NULL); /* Now evaluate the request against the rules */ ipa_hbac_evaluate_rules(hbac_ctx); return; fail: if (in_transaction) { ret = sysdb_transaction_cancel(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not cancel transaction\n"); } } ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); } void ipa_hbac_evaluate_rules(struct hbac_ctx *hbac_ctx) { struct be_ctx *be_ctx = be_req_get_be_ctx(hbac_ctx->be_req); errno_t ret; struct hbac_rule **hbac_rules; struct hbac_eval_req *eval_req; enum hbac_eval_result result; struct hbac_info *info; /* Get HBAC rules from the sysdb */ ret = hbac_get_cached_rules(hbac_ctx, be_ctx->domain, &hbac_ctx->rule_count, &hbac_ctx->rules); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not retrieve rules from the cache\n"); ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); } ret = hbac_ctx_to_rules(hbac_ctx, hbac_ctx, &hbac_rules, &eval_req); if (ret == EPERM) { DEBUG(SSSDBG_CRIT_FAILURE, "DENY rules detected. Denying access to all users\n"); ipa_access_reply(hbac_ctx, PAM_PERM_DENIED); return; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct HBAC rules\n"); ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); return; } result = hbac_evaluate(hbac_rules, eval_req, &info); if (result == HBAC_EVAL_ALLOW) { DEBUG(SSSDBG_MINOR_FAILURE, "Access granted by HBAC rule [%s]\n", info->rule_name); hbac_free_info(info); ipa_access_reply(hbac_ctx, PAM_SUCCESS); return; } else if (result == HBAC_EVAL_ERROR) { DEBUG(SSSDBG_CRIT_FAILURE, "Error [%s] occurred in rule [%s]\n", hbac_error_string(info->code), info->rule_name); hbac_free_info(info); ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); return; } else if (result == HBAC_EVAL_OOM) { DEBUG(SSSDBG_CRIT_FAILURE, "Insufficient memory\n"); ipa_access_reply(hbac_ctx, PAM_SYSTEM_ERR); return; } DEBUG(SSSDBG_MINOR_FAILURE, "Access denied by HBAC rules\n"); hbac_free_info(info); ipa_access_reply(hbac_ctx, PAM_PERM_DENIED); } errno_t hbac_get_cached_rules(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, size_t *_rule_count, struct sysdb_attrs ***_rules) { errno_t ret; struct ldb_message **msgs; struct sysdb_attrs **rules; size_t rule_count; TALLOC_CTX *tmp_ctx; char *filter; const char *attrs[] = { OBJECTCLASS, IPA_CN, SYSDB_ORIG_DN, IPA_UNIQUE_ID, IPA_ENABLED_FLAG, IPA_ACCESS_RULE_TYPE, IPA_MEMBER_USER, IPA_USER_CATEGORY, IPA_MEMBER_SERVICE, IPA_SERVICE_CATEGORY, IPA_SOURCE_HOST, IPA_SOURCE_HOST_CATEGORY, IPA_EXTERNAL_HOST, IPA_MEMBER_HOST, IPA_HOST_CATEGORY, NULL }; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; filter = talloc_asprintf(tmp_ctx, "(objectClass=%s)", IPA_HBAC_RULE); if (filter == NULL) { ret = ENOMEM; goto done; } ret = sysdb_search_custom(tmp_ctx, domain, filter, HBAC_RULES_SUBDIR, attrs, &rule_count, &msgs); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up HBAC rules\n"); goto done; } if (ret == ENOENT) { rule_count = 0; } ret = sysdb_msg2attrs(tmp_ctx, rule_count, msgs, &rules); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not convert ldb message to sysdb_attrs\n"); goto done; } if (_rules) *_rules = talloc_steal(mem_ctx, rules); if (_rule_count) *_rule_count = rule_count; ret = EOK; done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_selinux_maps.c0000644000000000000000000000007412703456111021406 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.747793944 sssd-1.13.4/src/providers/ipa/ipa_selinux_maps.c0000644002412700241270000001524012703456111023057 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- SELinux user maps (maps retrieval) Authors: Jan Zeleny Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_selinux_maps.h" struct ipa_selinux_get_maps_state { struct tevent_context *ev; struct sysdb_ctx *sysdb; struct sdap_handle *sh; struct sdap_options *opts; struct ipa_options *ipa_opts; const char **attrs; struct sdap_search_base **search_bases; int search_base_iter; char *cur_filter; char *maps_filter; size_t map_count; struct sysdb_attrs **maps; }; static errno_t ipa_selinux_get_maps_next(struct tevent_req *req, struct ipa_selinux_get_maps_state *state); static void ipa_selinux_get_maps_done(struct tevent_req *subreq); struct tevent_req *ipa_selinux_get_maps_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sysdb_ctx *sysdb, struct sdap_handle *sh, struct sdap_options *opts, struct ipa_options *ipa_opts, struct sdap_search_base **search_bases) { struct tevent_req *req; struct ipa_selinux_get_maps_state *state; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ipa_selinux_get_maps_state); if (req == NULL) { return NULL; } state->ev = ev; state->sysdb = sysdb; state->sh = sh; state->opts = opts; state->ipa_opts = ipa_opts; state->search_bases = search_bases; state->search_base_iter = 0; state->map_count = 0; state->maps = NULL; ret = build_attrs_from_map(state, ipa_opts->selinuxuser_map, IPA_OPTS_SELINUX_USERMAP, NULL, &state->attrs, NULL); if (ret != EOK) goto fail; state->cur_filter = NULL; state->maps_filter = talloc_asprintf(state, "(&(objectclass=%s)(%s=TRUE))", ipa_opts->selinuxuser_map[IPA_OC_SELINUX_USERMAP].name, ipa_opts->selinuxuser_map[IPA_AT_SELINUX_USERMAP_ENABLED].name); if (state->maps_filter == NULL) { ret = ENOMEM; goto fail; } ret = ipa_selinux_get_maps_next(req, state); if (ret == EOK) { ret = EINVAL; } if (ret != EAGAIN) { goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static errno_t ipa_selinux_get_maps_next(struct tevent_req *req, struct ipa_selinux_get_maps_state *state) { struct sdap_search_base *base; struct tevent_req *subreq; base = state->search_bases[state->search_base_iter]; if (base == NULL) { return EOK; } talloc_zfree(state->cur_filter); state->cur_filter = sdap_combine_filters(state, state->maps_filter, base->filter); if (state->cur_filter == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Trying to fetch SELinux maps with following " "parameters: [%d][%s][%s]\n", base->scope, state->cur_filter, base->basedn); subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, base->basedn, base->scope, state->cur_filter, state->attrs, state->ipa_opts->selinuxuser_map, IPA_OPTS_SELINUX_USERMAP, dp_opt_get_int(state->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), true); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, ipa_selinux_get_maps_done, req); return EAGAIN; } static void ipa_selinux_get_maps_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_selinux_get_maps_state *state = tevent_req_data(req, struct ipa_selinux_get_maps_state); struct sysdb_attrs **results; size_t total_count; size_t count; int i; ret = sdap_get_generic_recv(subreq, state, &count, &results); if (ret != EOK) { goto done; } if (count > 0) { DEBUG(SSSDBG_TRACE_FUNC, "Found %zu user maps in current search base\n", count); total_count = count + state->map_count; state->maps = talloc_realloc(state, state->maps, struct sysdb_attrs *, total_count); if (state->maps == NULL) { ret = ENOMEM; goto done; } i = 0; while (state->map_count < total_count) { state->maps[state->map_count] = talloc_steal(state->maps, results[i]); state->map_count++; i++; } } state->search_base_iter++; ret = ipa_selinux_get_maps_next(req, state); if (ret == EAGAIN) { return; } else if (ret != EOK) { goto done; } if (state->map_count == 0) { DEBUG(SSSDBG_TRACE_FUNC, "No SELinux user maps found!\n"); ret = ENOENT; } done: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } } errno_t ipa_selinux_get_maps_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *count, struct sysdb_attrs ***maps) { struct ipa_selinux_get_maps_state *state = tevent_req_data(req, struct ipa_selinux_get_maps_state); TEVENT_REQ_RETURN_ON_ERROR(req); *count = state->map_count; *maps = talloc_steal(mem_ctx, state->maps); return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/selinux_child.c0000644000000000000000000000007412703456111020700 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.969794697 sssd-1.13.4/src/providers/ipa/selinux_child.c0000644002412700241270000002462212703456111022355 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA back end -- set SELinux context in a child module Authors: Jakub Hrozek Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "util/child_common.h" #include "providers/dp_backend.h" struct input_buffer { const char *seuser; const char *mls_range; const char *username; }; static errno_t unpack_buffer(uint8_t *buf, size_t size, struct input_buffer *ibuf) { size_t p = 0; uint32_t len; /* seuser */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); DEBUG(SSSDBG_TRACE_INTERNAL, "seuser length: %d\n", len); if (len == 0) { ibuf->seuser = ""; DEBUG(SSSDBG_TRACE_INTERNAL, "Empty SELinux user, will delete the mapping\n"); } else { if (len > size - p) return EINVAL; ibuf->seuser = talloc_strndup(ibuf, (char *)(buf + p), len); if (ibuf->seuser == NULL) return ENOMEM; DEBUG(SSSDBG_TRACE_INTERNAL, "seuser: %s\n", ibuf->seuser); p += len; } /* MLS range */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); DEBUG(SSSDBG_TRACE_INTERNAL, "mls_range length: %d\n", len); if (len == 0) { if (strcmp(ibuf->seuser, "") != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "No MLS mapping!\n"); return EINVAL; } } else { if (len > size - p) return EINVAL; ibuf->mls_range = talloc_strndup(ibuf, (char *)(buf + p), len); if (ibuf->mls_range == NULL) return ENOMEM; DEBUG(SSSDBG_TRACE_INTERNAL, "mls_range: %s\n", ibuf->mls_range); p += len; } /* username */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); DEBUG(SSSDBG_TRACE_INTERNAL, "username length: %d\n", len); if (len == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "No username set!\n"); return EINVAL; } else { if (len > size - p) return EINVAL; ibuf->username = talloc_strndup(ibuf, (char *)(buf + p), len); if (ibuf->username == NULL) return ENOMEM; DEBUG(SSSDBG_TRACE_INTERNAL, "username: %s\n", ibuf->username); p += len; } return EOK; } static errno_t pack_buffer(struct response *r, int result) { size_t p = 0; /* A buffer with the following structure must be created: * uint32_t status of the request (required) */ r->size = sizeof(uint32_t); r->buf = talloc_array(r, uint8_t, r->size); if(r->buf == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "result [%d]\n", result); /* result */ SAFEALIGN_SET_UINT32(&r->buf[p], result, &p); return EOK; } static errno_t prepare_response(TALLOC_CTX *mem_ctx, int result, struct response **rsp) { int ret; struct response *r = NULL; r = talloc_zero(mem_ctx, struct response); if (r == NULL) { return ENOMEM; } r->buf = NULL; r->size = 0; ret = pack_buffer(r, result); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_buffer failed\n"); return ret; } *rsp = r; DEBUG(SSSDBG_TRACE_ALL, "r->size: %zu\n", r->size); return EOK; } static int sc_set_seuser(const char *login_name, const char *seuser_name, const char *mls) { int ret; mode_t old_mask; /* This is a workaround for * https://bugzilla.redhat.com/show_bug.cgi?id=1186422 to make sure * the directories are created with the expected permissions */ old_mask = umask(0); if (strcmp(seuser_name, "") == 0) { /* An empty SELinux user should cause SSSD to use the system * default. We need to remove the SELinux user from the DB * in that case */ ret = del_seuser(login_name); } else { ret = set_seuser(login_name, seuser_name, mls); } umask(old_mask); return ret; } static bool seuser_needs_update(struct input_buffer *ibuf) { bool needs_update = true; char *db_seuser = NULL; char *db_mls_range = NULL; errno_t ret; ret = get_seuser(ibuf, ibuf->username, &db_seuser, &db_mls_range); DEBUG(SSSDBG_TRACE_INTERNAL, "get_seuser: ret: %d seuser: %s mls: %s\n", ret, db_seuser ? db_seuser : "unknown", db_mls_range ? db_mls_range : "unknown"); if (ret == EOK && db_seuser && db_mls_range && strcmp(db_seuser, ibuf->seuser) == 0 && strcmp(db_mls_range, ibuf->mls_range) == 0) { needs_update = false; } talloc_free(db_seuser); talloc_free(db_mls_range); return needs_update; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int debug_fd = -1; errno_t ret; TALLOC_CTX *main_ctx = NULL; uint8_t *buf = NULL; ssize_t len = 0; struct input_buffer *ibuf = NULL; struct response *resp = NULL; ssize_t written; bool needs_update; struct poptOption long_options[] = { POPT_AUTOHELP {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, _("Debug level"), NULL}, {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0, _("Add debug timestamps"), NULL}, {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0, _("Show timestamps with microseconds"), NULL}, {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0, _("An open file descriptor for the debug logs"), NULL}, {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, _("Send the debug output to stderr directly."), NULL }, POPT_TABLEEND }; /* Set debug level to invalid value so we can decide if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); _exit(-1); } } poptFreeContext(pc); DEBUG_INIT(debug_level); debug_prg_name = talloc_asprintf(NULL, "[sssd[selinux_child[%d]]]", getpid()); if (debug_prg_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); goto fail; } if (debug_fd != -1) { ret = set_debug_file_from_fd(debug_fd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n"); } } DEBUG(SSSDBG_TRACE_FUNC, "selinux_child started.\n"); DEBUG(SSSDBG_TRACE_INTERNAL, "Running with effective IDs: [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid()); /* libsemanage calls access(2) which works with real IDs, not effective. * We need to switch also the real ID to 0. */ if (getuid() != 0) { ret = setuid(0); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setuid failed: %d, selinux_child might not work!\n", ret); } } if (getgid() != 0) { ret = setgid(0); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setgid failed: %d, selinux_child might not work!\n", ret); } } DEBUG(SSSDBG_TRACE_INTERNAL, "Running with real IDs [%"SPRIuid"][%"SPRIgid"].\n", getuid(), getgid()); main_ctx = talloc_new(NULL); if (main_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); talloc_free(discard_const(debug_prg_name)); goto fail; } talloc_steal(main_ctx, debug_prg_name); buf = talloc_size(main_ctx, sizeof(uint8_t)*IN_BUF_SIZE); if (buf == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); goto fail; } ibuf = talloc_zero(main_ctx, struct input_buffer); if (ibuf == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "context initialized\n"); errno = 0; len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE); if (len == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret)); goto fail; } close(STDIN_FILENO); ret = unpack_buffer(buf, len, ibuf); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "unpack_buffer failed.[%d][%s].\n", ret, strerror(ret)); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "performing selinux operations\n"); needs_update = seuser_needs_update(ibuf); if (needs_update == true) { ret = sc_set_seuser(ibuf->username, ibuf->seuser, ibuf->mls_range); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set SELinux login context.\n"); goto fail; } } ret = prepare_response(main_ctx, ret, &resp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to prepare response buffer.\n"); goto fail; } errno = 0; written = sss_atomic_write_s(STDOUT_FILENO, resp->buf, resp->size); if (written == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret, strerror(ret)); goto fail; } if (written != resp->size) { DEBUG(SSSDBG_CRIT_FAILURE, "Expected to write %zu bytes, wrote %zu\n", resp->size, written); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "selinux_child completed successfully\n"); close(STDOUT_FILENO); talloc_free(main_ctx); return EXIT_SUCCESS; fail: DEBUG(SSSDBG_CRIT_FAILURE, "selinux_child failed!\n"); close(STDOUT_FILENO); talloc_free(main_ctx); return EXIT_FAILURE; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_opts.h0000644000000000000000000000007312703456111017670 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.575793361 sssd-1.13.4/src/providers/ipa/ipa_opts.h0000644002412700241270000000343712703456111021347 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IPA_OPTS_H_ #define IPA_OPTS_H_ #include "src/providers/data_provider.h" #include "providers/ldap/ldap_common.h" extern struct dp_option ipa_basic_opts[]; extern struct dp_option ipa_dyndns_opts[]; extern struct dp_option ipa_def_ldap_opts[]; extern struct sdap_attr_map ipa_attr_map[]; extern struct sdap_attr_map ipa_user_map[]; extern struct sdap_attr_map ipa_group_map[]; extern struct sdap_attr_map ipa_netgroup_map[]; extern struct sdap_attr_map ipa_host_map[]; extern struct sdap_attr_map ipa_hostgroup_map[]; extern struct sdap_attr_map ipa_selinux_user_map[]; extern struct sdap_attr_map ipa_view_map[]; extern struct sdap_attr_map ipa_override_map[]; extern struct dp_option ipa_def_krb5_opts[]; extern struct sdap_attr_map ipa_service_map[]; extern struct sdap_attr_map ipa_autofs_mobject_map[]; extern struct sdap_attr_map ipa_autofs_entry_map[]; extern struct sdap_attr_map ipa_sudorule_map[]; extern struct sdap_attr_map ipa_sudocmdgroup_map[]; extern struct sdap_attr_map ipa_sudocmd_map[]; #endif /* IPA_OPTS_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_subdomains_id.c0000644000000000000000000000007412703456111021517 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.732793893 sssd-1.13.4/src/providers/ipa/ipa_subdomains_id.c0000644002412700241270000014070312703456111023173 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Identity Backend Module for sub-domains Authors: Sumit Bose Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "util/sss_nss.h" #include "util/strtonum.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" #include "providers/ipa/ipa_id.h" #include "providers/ad/ad_id.h" #include "providers/ipa/ipa_subdomains.h" static struct tevent_req * ipa_srv_ad_acct_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct be_req *be_req, struct sysdb_attrs *override_attrs, struct be_acct_req *ar); static errno_t ipa_srv_ad_acct_recv(struct tevent_req *req, int *dp_error_out); struct ipa_subdomain_account_state { struct tevent_context *ev; struct ipa_id_ctx *ipa_ctx; struct sdap_id_ctx *ctx; struct sdap_id_op *op; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; struct be_req *be_req; struct be_acct_req *ar; bool ipa_server_mode; bool server_retry; int entry_type; const char *filter; int filter_type; struct sysdb_attrs *override_attrs; int dp_error; }; static void ipa_subdomain_account_connected(struct tevent_req *subreq); static void ipa_subdomain_account_got_override(struct tevent_req *subreq); static void ipa_subdomain_account_done(struct tevent_req *subreq); static errno_t ipa_subdomain_account_get_original_step(struct tevent_req *req, struct be_acct_req *ar); struct tevent_req *ipa_subdomain_account_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct be_req *be_req, struct be_acct_req *ar) { struct tevent_req *req; struct ipa_subdomain_account_state *state; struct tevent_req *subreq; int ret; req = tevent_req_create(memctx, &state, struct ipa_subdomain_account_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->ipa_ctx = ipa_ctx; state->ctx = ipa_ctx->sdap_id_ctx; state->dp_error = DP_ERR_FATAL; state->op = sdap_id_op_create(state, state->ctx->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto fail; } state->domain = find_domain_by_name(state->ctx->be->domain, ar->domain, true); if (state->domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed.\n"); ret = ENOMEM; goto fail; } state->sysdb = state->domain->sysdb; state->be_req = be_req; state->ar = ar; state->ipa_server_mode = dp_opt_get_bool(state->ipa_ctx->ipa_options->basic, IPA_SERVER_MODE); state->override_attrs = NULL; /* With views we cannot got directly to the look up the AD objects but * have to check first if the request matches an override in the given * view. But there are cases where this can be skipped and the AD object * can be searched directly: * - if no view is defined, i.e. the server does not supprt views yet * - searches by SID: because we do not override the SID * - if the responder does not send the EXTRA_INPUT_MAYBE_WITH_VIEW flags, * because in this case the entry was found in the cache and the * original value is used for the search (e.g. during cache updates) */ if (state->ipa_ctx->view_name == NULL || state->ar->filter_type == BE_FILTER_SECID || (!state->ipa_server_mode && state->ar->extra_value != NULL && strcmp(state->ar->extra_value, EXTRA_INPUT_MAYBE_WITH_VIEW) != 0 )) { ret = ipa_subdomain_account_get_original_step(req, state->ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_subdomain_account_get_original_step failed.\n"); goto fail; } return req; } subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { goto fail; } tevent_req_set_callback(subreq, ipa_subdomain_account_connected, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void ipa_subdomain_account_connected(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_subdomain_account_state *state = tevent_req_data(req, struct ipa_subdomain_account_state); int dp_error = DP_ERR_FATAL; int ret; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect request failed.\n"); goto fail; } subreq = ipa_get_ad_override_send(state, state->ev, state->ctx, state->ipa_ctx->ipa_options, dp_opt_get_string(state->ipa_ctx->ipa_options->basic, IPA_KRB5_REALM), state->ipa_ctx->view_name, state->ar); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_subdomain_account_got_override, req); return; fail: state->dp_error = dp_error; tevent_req_error(req, ret); return; } #define OVERRIDE_ANCHOR_SID_PREFIX ":SID:" #define OVERRIDE_ANCHOR_SID_PREFIX_LEN (sizeof(OVERRIDE_ANCHOR_SID_PREFIX) -1 ) static void ipa_subdomain_account_got_override(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_subdomain_account_state *state = tevent_req_data(req, struct ipa_subdomain_account_state); int dp_error = DP_ERR_FATAL; int ret; const char *anchor = NULL; struct be_acct_req *ar; ret = ipa_get_ad_override_recv(subreq, &dp_error, state, &state->override_attrs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); goto fail; } if (state->override_attrs != NULL) { DEBUG(SSSDBG_TRACE_ALL, "Processing override.\n"); ret = sysdb_attrs_get_string(state->override_attrs, SYSDB_OVERRIDE_ANCHOR_UUID, &anchor); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto fail; } if (anchor != NULL && strncmp(OVERRIDE_ANCHOR_SID_PREFIX, anchor, OVERRIDE_ANCHOR_SID_PREFIX_LEN) == 0) { ret = get_be_acct_req_for_sid(state, anchor + OVERRIDE_ANCHOR_SID_PREFIX_LEN, state->ar->domain, &ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); goto fail; } if (state->ipa_server_mode && (state->ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_INITGROUPS) { DEBUG(SSSDBG_TRACE_ALL, "Switching back to BE_REQ_INITGROUPS.\n"); ar->entry_type = BE_REQ_INITGROUPS; ar->filter_type = BE_FILTER_SECID; ar->attr_type = BE_ATTR_CORE; } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported override anchor type [%s].\n", anchor); ret = EINVAL; goto fail; } } else { ar = state->ar; } ret = ipa_subdomain_account_get_original_step(req, ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_subdomain_account_get_original_step failed.\n"); goto fail; } return; fail: state->dp_error = dp_error; tevent_req_error(req, ret); return; } static errno_t ipa_subdomain_account_get_original_step(struct tevent_req *req, struct be_acct_req *ar) { struct ipa_subdomain_account_state *state = tevent_req_data(req, struct ipa_subdomain_account_state); struct tevent_req *subreq; if (state->ipa_server_mode) { subreq = ipa_srv_ad_acct_send(state, state->ev, state->ipa_ctx, state->be_req, state->override_attrs, ar); } else { subreq = ipa_get_subdom_acct_send(state, state->ev, state->ipa_ctx, state->override_attrs, ar); } if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_*_acct_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, ipa_subdomain_account_done, req); return EOK; } static void ipa_subdomain_account_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_subdomain_account_state *state = tevent_req_data(req, struct ipa_subdomain_account_state); int dp_error = DP_ERR_FATAL; int ret; if (state->ipa_server_mode) { ret = ipa_srv_ad_acct_recv(subreq, &dp_error); } else { ret = ipa_get_subdom_acct_recv(subreq, &dp_error); } talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_*_acct request failed: [%d]: %s.\n", ret, sss_strerror(ret)); state->dp_error = dp_error; tevent_req_error(req, ret); return; } state->dp_error = DP_ERR_OK; tevent_req_done(req); return; } errno_t ipa_subdomain_account_recv(struct tevent_req *req, int *dp_error_out) { struct ipa_subdomain_account_state *state = tevent_req_data(req, struct ipa_subdomain_account_state); if (dp_error_out) { *dp_error_out = state->dp_error; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct ipa_get_subdom_acct { struct tevent_context *ev; struct ipa_id_ctx *ipa_ctx; struct sdap_id_ctx *ctx; struct sdap_id_op *op; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; struct sysdb_attrs *override_attrs; int entry_type; const char *filter; int filter_type; int dp_error; }; static void ipa_get_subdom_acct_connected(struct tevent_req *subreq); static void ipa_get_subdom_acct_done(struct tevent_req *subreq); struct tevent_req *ipa_get_subdom_acct_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct sysdb_attrs *override_attrs, struct be_acct_req *ar) { struct tevent_req *req; struct ipa_get_subdom_acct *state; struct tevent_req *subreq; int ret; req = tevent_req_create(memctx, &state, struct ipa_get_subdom_acct); if (!req) return NULL; state->ev = ev; state->ipa_ctx = ipa_ctx; state->ctx = ipa_ctx->sdap_id_ctx; state->dp_error = DP_ERR_FATAL; state->override_attrs = override_attrs; state->op = sdap_id_op_create(state, state->ctx->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto fail; } state->domain = find_domain_by_name(state->ctx->be->domain, ar->domain, true); if (state->domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed.\n"); ret = ENOMEM; goto fail; } state->sysdb = state->domain->sysdb; state->entry_type = (ar->entry_type & BE_REQ_TYPE_MASK); state->filter = ar->filter_value; state->filter_type = ar->filter_type; switch (state->entry_type) { case BE_REQ_USER: case BE_REQ_GROUP: case BE_REQ_BY_SECID: case BE_REQ_USER_AND_GROUP: case BE_REQ_INITGROUPS: ret = EOK; break; default: ret = EINVAL; DEBUG(SSSDBG_OP_FAILURE, "Invalid sub-domain request type.\n"); } if (ret != EOK) goto fail; subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { goto fail; } tevent_req_set_callback(subreq, ipa_get_subdom_acct_connected, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void ipa_get_subdom_acct_connected(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_subdom_acct *state = tevent_req_data(req, struct ipa_get_subdom_acct); int dp_error = DP_ERR_FATAL; int ret; char *endptr; struct req_input *req_input; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } if (state->entry_type == BE_REQ_INITGROUPS) { /* With V1 of the extdom plugin a user lookup will resolve the full * group membership of the user. */ if (sdap_is_extension_supported(sdap_id_op_handle(state->op), EXOP_SID2NAME_V1_OID)) { state->entry_type = BE_REQ_USER; } else { DEBUG(SSSDBG_TRACE_FUNC, "Initgroups requests are not handled " \ "by the IPA provider but are resolved " \ "by the responder directly from the " \ "cache.\n"); tevent_req_error(req, ENOTSUP); return; } } req_input = talloc(state, struct req_input); if (req_input == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc failed.\n"); tevent_req_error(req, ENOMEM); return; } switch (state->filter_type) { case BE_FILTER_NAME: req_input->type = REQ_INP_NAME; req_input->inp.name = talloc_strdup(req_input, state->filter); if (req_input->inp.name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); tevent_req_error(req, ENOMEM); return; } break; case BE_FILTER_IDNUM: req_input->type = REQ_INP_ID; req_input->inp.id = strtouint32(state->filter, &endptr, 10); if (errno || *endptr || (state->filter == endptr)) { tevent_req_error(req, errno ? errno : EINVAL); return; } break; case BE_FILTER_SECID: req_input->type = REQ_INP_SECID; req_input->inp.secid = talloc_strdup(req_input, state->filter); if (req_input->inp.secid == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); tevent_req_error(req, ENOMEM); return; } break; default: DEBUG(SSSDBG_OP_FAILURE, "Invalid sub-domain filter type.\n"); state->dp_error = dp_error; tevent_req_error(req, EINVAL); return; } subreq = ipa_s2n_get_acct_info_send(state, state->ev, state->ipa_ctx, state->ctx->opts, state->domain, state->override_attrs, sdap_id_op_handle(state->op), state->entry_type, req_input); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, ipa_get_subdom_acct_done, req); return; } static void ipa_get_subdom_acct_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_subdom_acct *state = tevent_req_data(req, struct ipa_get_subdom_acct); int dp_error = DP_ERR_FATAL; int ret; ret = ipa_s2n_get_acct_info_recv(subreq); talloc_zfree(subreq); ret = sdap_id_op_done(state->op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { tevent_req_error(req, ret); return; } tevent_req_set_callback(subreq, ipa_get_subdom_acct_connected, req); return; } if (ret && ret != ENOENT) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } /* FIXME: do we need some special handling of ENOENT */ state->dp_error = DP_ERR_OK; tevent_req_done(req); } int ipa_get_subdom_acct_recv(struct tevent_req *req, int *dp_error_out) { struct ipa_get_subdom_acct *state = tevent_req_data(req, struct ipa_get_subdom_acct); if (dp_error_out) { *dp_error_out = state->dp_error; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* IPA lookup for server mode. Directly to AD. */ struct ipa_get_ad_acct_state { int dp_error; struct tevent_context *ev; struct ipa_id_ctx *ipa_ctx; struct be_req *be_req; struct be_acct_req *ar; struct sss_domain_info *obj_dom; char *object_sid; struct sysdb_attrs *override_attrs; struct ldb_message *obj_msg; }; static void ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq); static void ipa_get_ad_override_done(struct tevent_req *subreq); static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req); static errno_t ipa_get_ad_ipa_membership_step(struct tevent_req *req); static void ipa_id_get_groups_overrides_done(struct tevent_req *subreq); static void ipa_get_ad_acct_done(struct tevent_req *subreq); static struct ad_id_ctx *ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx, struct sss_domain_info *dom); static struct tevent_req * ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct be_req *be_req, struct sysdb_attrs *override_attrs, struct be_acct_req *ar) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct ipa_get_ad_acct_state *state; struct sdap_domain *sdom; struct sdap_id_conn_ctx **clist; struct sdap_id_ctx *sdap_id_ctx;; struct ad_id_ctx *ad_id_ctx; req = tevent_req_create(mem_ctx, &state, struct ipa_get_ad_acct_state); if (req == NULL) return NULL; state->dp_error = -1; state->ev = ev; state->ipa_ctx = ipa_ctx; state->be_req = be_req; state->ar = ar; state->obj_msg = NULL; state->override_attrs = override_attrs; /* This can only be a subdomain request, verify subdomain */ state->obj_dom = find_domain_by_name(ipa_ctx->sdap_id_ctx->be->domain, ar->domain, true); if (state->obj_dom == NULL) { ret = EINVAL; goto fail; } /* Let's see if this subdomain has a ad_id_ctx */ ad_id_ctx = ipa_get_ad_id_ctx(ipa_ctx, state->obj_dom); if (ad_id_ctx == NULL) { ret = EINVAL; goto fail; } sdap_id_ctx = ad_id_ctx->sdap_id_ctx; /* We read users and groups from GC. From groups, we may switch to * using LDAP connection in the group request itself, but in order * to resolve Universal group memberships, we also need the GC * connection */ switch (state->ar->entry_type & BE_REQ_TYPE_MASK) { case BE_REQ_INITGROUPS: case BE_REQ_BY_SECID: case BE_REQ_GROUP: clist = ad_gc_conn_list(req, ad_id_ctx, state->obj_dom); break; default: clist = ad_ldap_conn_list(req, ad_id_ctx, state->obj_dom); break; } if (clist == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot generate AD connection list!\n"); ret = ENOMEM; goto fail; } /* Now we already need ad_id_ctx in particular sdap_id_conn_ctx */ sdom = sdap_domain_get(sdap_id_ctx->opts, state->obj_dom); if (sdom == NULL) { ret = EIO; goto fail; } subreq = ad_handle_acct_info_send(req, be_req, ar, sdap_id_ctx, ad_id_ctx->ad_options, sdom, clist); if (subreq == NULL) { ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_get_ad_acct_ad_part_done, req); return req; fail: state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static struct ad_id_ctx * ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx, struct sss_domain_info *dom) { struct ipa_ad_server_ctx *iter; DLIST_FOR_EACH(iter, ipa_ctx->server_mode->trusts) { if (iter->dom == dom) break; } return (iter) ? iter->ad_id_ctx : NULL; } static errno_t get_subdomain_homedir_of_user(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *fqname, uint32_t uid, const char *original, const char **_homedir) { errno_t ret; const char *name; const char *homedir; TALLOC_CTX *tmp_ctx; struct sss_nss_homedir_ctx homedir_ctx; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } if (strstr(dom->subdomain_homedir, "%o") != NULL && original == NULL) { DEBUG(SSSDBG_TRACE_ALL, "Original home directory for user: %s is empty.\n", fqname); ret = ERR_HOMEDIR_IS_NULL; goto done; } ZERO_STRUCT(homedir_ctx); homedir_ctx.uid = uid; homedir_ctx.domain = dom->name; homedir_ctx.flatname = dom->flat_name; homedir_ctx.config_homedir_substr = dom->homedir_substr; homedir_ctx.original = original; ret = sss_parse_name_const(tmp_ctx, dom->names, fqname, NULL, &name); if (ret != EOK) { goto done; } /* To be compatible with the old winbind based user lookups and IPA * clients the user name in the home directory path will be lower-case. */ homedir_ctx.username = sss_tc_utf8_str_tolower(tmp_ctx, name); if (homedir_ctx.username == NULL) { ret = ENOMEM; goto done; } homedir = expand_homedir_template(tmp_ctx, dom->subdomain_homedir, &homedir_ctx); if (homedir == NULL) { DEBUG(SSSDBG_OP_FAILURE, "expand_homedir_template failed\n"); ret = ENOMEM; goto done; } if (_homedir == NULL) { ret = EINVAL; goto done; } *_homedir = talloc_steal(mem_ctx, homedir); done: talloc_free(tmp_ctx); return ret; } static errno_t store_homedir_of_user(struct sss_domain_info *domain, const char *fqname, const char *homedir) { errno_t ret; errno_t sret; TALLOC_CTX *tmp_ctx; bool in_transaction = false; struct sysdb_attrs *attrs; struct sysdb_ctx *sysdb = domain->sysdb; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } attrs = sysdb_new_attrs(tmp_ctx); if (attrs == NULL) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_HOMEDIR, homedir); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error setting homedir: [%s]\n", strerror(ret)); goto done; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; ret = sysdb_set_user_attr(domain, fqname, attrs, SYSDB_MOD_REP); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to update homedir information!\n"); goto done; } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot commit sysdb transaction [%d]: %s.\n", ret, strerror(ret)); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction.\n"); } } talloc_free(tmp_ctx); return ret; } static errno_t apply_subdomain_homedir(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, struct ldb_message *msg) { errno_t ret; uint32_t uid; const char *fqname; const char *original; const char *homedir = NULL; struct ldb_message_element *msg_el = NULL; size_t c; msg_el = ldb_msg_find_element(msg, SYSDB_OBJECTCLASS); if (msg_el == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_find_element failed.\n"); ret = ENOENT; goto done; } for (c = 0; c < msg_el->num_values; c++) { if (strncmp(SYSDB_USER_CLASS, (const char *)msg_el->values[c].data, msg_el->values[c].length) == 0) { break; } } if (c == msg_el->num_values) { DEBUG(SSSDBG_TRACE_ALL, "User objectclass not found, object is not a user.\n"); ret = ENOENT; goto done; } fqname = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); if (fqname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing user name.\n"); ret = EINVAL; goto done; } uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0); if (uid == 0) { DEBUG(SSSDBG_OP_FAILURE, "UID for user [%s] is not known.\n", fqname); ret = ENOENT; goto done; } original = ldb_msg_find_attr_as_string(msg, SYSDB_HOMEDIR, NULL); if (original == NULL) { DEBUG(SSSDBG_TRACE_ALL, "Missing homedir of %s.\n", fqname); } ret = get_subdomain_homedir_of_user(mem_ctx, dom, fqname, uid, original, &homedir); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_subdomain_homedir_of_user failed: [%d]: [%s]\n", ret, sss_strerror(ret)); if (ret == ERR_HOMEDIR_IS_NULL) { /* This is not fatal, fallback_homedir will be used. */ ret = EOK; } goto done; } ret = store_homedir_of_user(dom, fqname, homedir); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "store_homedir_of_user failed: [%d]: [%s]\n", ret, sss_strerror(ret)); goto done; } done: return ret; } errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, struct be_acct_req *ar, struct ldb_message **_msg) { errno_t ret; uint32_t id; struct ldb_message *msg = NULL; struct ldb_result *res = NULL; const char *attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, SYSDB_SID_STR, SYSDB_OBJECTCLASS, SYSDB_UUID, SYSDB_GHOST, SYSDB_HOMEDIR, NULL }; char *name; if (ar->filter_type == BE_FILTER_SECID) { ret = sysdb_search_object_by_sid(mem_ctx, dom, ar->filter_value, attrs, &res); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to make request to our cache: [%d]: [%s]\n", ret, sss_strerror(ret)); goto done; } *_msg = res->msgs[0]; ret = EOK; goto done; } else if (ar->filter_type == BE_FILTER_UUID) { ret = sysdb_search_object_by_uuid(mem_ctx, dom, ar->filter_value, attrs, &res); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to make request to our cache: [%d]: [%s]\n", ret, sss_strerror(ret)); goto done; } *_msg = res->msgs[0]; ret = EOK; goto done; } else if (ar->filter_type == BE_FILTER_CERT) { ret = sysdb_search_object_by_cert(mem_ctx, dom, ar->filter_value, attrs, &res); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to make request to our cache: [%d]: [%s]\n", ret, sss_strerror(ret)); goto done; } *_msg = res->msgs[0]; ret = EOK; goto done; } else if (ar->filter_type == BE_FILTER_IDNUM) { errno = 0; id = strtouint32(ar->filter_value, NULL, 10); if (errno != 0) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "strtouint32 failed.\n"); goto done; } switch (ar->entry_type & BE_REQ_TYPE_MASK) { case BE_REQ_GROUP: ret = sysdb_search_group_by_gid(mem_ctx, dom, id, attrs, &msg); break; case BE_REQ_INITGROUPS: case BE_REQ_USER: case BE_REQ_USER_AND_GROUP: ret = sysdb_search_user_by_uid(mem_ctx, dom, id, attrs, &msg); if (ret == ENOENT && (ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_USER_AND_GROUP) { ret = sysdb_search_group_by_gid(mem_ctx, dom, id, attrs, &msg); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected entry type [%d].\n", (ar->entry_type & BE_REQ_TYPE_MASK)); ret = EINVAL; goto done; } } else if (ar->filter_type == BE_FILTER_NAME) { name = sss_get_domain_name(mem_ctx, ar->filter_value, dom); if (name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_get_domain_name failed\n"); ret = ENOMEM; goto done; } switch (ar->entry_type & BE_REQ_TYPE_MASK) { case BE_REQ_GROUP: ret = sysdb_search_group_by_name(mem_ctx, dom, name, attrs, &msg); break; case BE_REQ_INITGROUPS: case BE_REQ_USER: case BE_REQ_USER_AND_GROUP: ret = sysdb_search_user_by_name(mem_ctx, dom, name, attrs, &msg); if (ret == ENOENT && (ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_USER_AND_GROUP) { ret = sysdb_search_group_by_name(mem_ctx, dom, name, attrs, &msg); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected entry type [%d].\n", (ar->entry_type & BE_REQ_TYPE_MASK)); ret = EINVAL; goto done; } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected filter type.\n"); ret = EINVAL; goto done; } if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Failed to make request to our cache: [%d]: [%s]\n", ret, sss_strerror(ret)); goto done; } *_msg = msg; done: return ret; } static void ipa_get_ad_acct_ad_part_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_ad_acct_state *state = tevent_req_data(req, struct ipa_get_ad_acct_state); errno_t ret; const char *sid; struct be_acct_req *ar; ret = ad_handle_acct_info_recv(subreq, &state->dp_error, NULL); talloc_zfree(subreq); if (ret == ERR_SUBDOM_INACTIVE) { tevent_req_error(req, ret); return; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "AD lookup failed: %d\n", ret); tevent_req_error(req, ret); return; } ret = get_object_from_cache(state, state->obj_dom, state->ar, &state->obj_msg); if (ret == ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "Object not found, ending request\n"); tevent_req_done(req); return; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_object_from_cache failed.\n"); goto fail; } ret = apply_subdomain_homedir(state, state->obj_dom, state->obj_msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "apply_subdomain_homedir failed: [%d]: [%s].\n", ret, sss_strerror(ret)); goto fail; } if (state->override_attrs == NULL) { sid = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_SID_STR, NULL); if (sid == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find a SID.\n"); ret = EINVAL; goto fail; } state->object_sid = talloc_strdup(state, sid); if (state->object_sid == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto fail; } ret = get_be_acct_req_for_sid(state, state->object_sid, state->obj_dom->name, &ar); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_be_acct_req_for_sid failed.\n"); goto fail; } subreq = ipa_get_ad_override_send(state, state->ev, state->ipa_ctx->sdap_id_ctx, state->ipa_ctx->ipa_options, state->ipa_ctx->server_mode->realm, state->ipa_ctx->view_name, ar); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_get_ad_override_done, req); } else { ret = ipa_get_ad_apply_override_step(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_apply_override_step failed.\n"); goto fail; } } return; fail: state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); return; } static void ipa_get_ad_override_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_ad_acct_state *state = tevent_req_data(req, struct ipa_get_ad_acct_state); errno_t ret; ret = ipa_get_ad_override_recv(subreq, &state->dp_error, state, &state->override_attrs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA override lookup failed: %d\n", ret); tevent_req_error(req, ret); return; } ret = ipa_get_ad_apply_override_step(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_apply_override_step failed.\n"); goto fail; } return; fail: state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); return; } static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req) { struct ipa_get_ad_acct_state *state = tevent_req_data(req, struct ipa_get_ad_acct_state); errno_t ret; struct tevent_req *subreq; const char *obj_name; int entry_type; size_t groups_count = 0; struct ldb_message **groups = NULL; const char *attrs[] = SYSDB_INITGR_ATTRS; if (state->override_attrs != NULL) { /* We are in ipa-server-mode, so the view is the default view by * definition. */ ret = sysdb_apply_default_override(state->obj_dom, state->override_attrs, state->obj_msg->dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_apply_default_override failed.\n"); return ret; } } entry_type = (state->ar->entry_type & BE_REQ_TYPE_MASK); if (entry_type != BE_REQ_INITGROUPS && entry_type != BE_REQ_USER && entry_type != BE_REQ_BY_SECID) { tevent_req_done(req); return EOK; } /* Replace ID with name in search filter */ if ((entry_type == BE_REQ_USER && state->ar->filter_type == BE_FILTER_IDNUM) || (entry_type == BE_REQ_INITGROUPS && state->ar->filter_type == BE_FILTER_SECID) || entry_type == BE_REQ_BY_SECID) { if (state->obj_msg == NULL) { ret = get_object_from_cache(state, state->obj_dom, state->ar, &state->obj_msg); if (ret == ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "Object not found, ending request\n"); tevent_req_done(req); return EOK; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_object_from_cache failed.\n"); return ret; } } obj_name = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_NAME, NULL); if (obj_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cached object has no name.\n"); return EINVAL; } state->ar->filter_value = talloc_strdup(state->ar, obj_name); if (state->ar->filter_value == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); return ENOMEM; } state->ar->filter_type = BE_FILTER_NAME; state->ar->entry_type = BE_REQ_USER; } /* Lookup all groups the user is a member of which do not have ORIGINALAD * attributes set, i.e. where overrides might not have been applied. */ ret = sysdb_asq_search(state, state->obj_dom, state->obj_msg->dn, "(&("SYSDB_GC")("SYSDB_GIDNUM"=*)" \ "("SYSDB_POSIX"=TRUE)" \ "(!("ORIGINALAD_PREFIX SYSDB_GIDNUM"=*))" \ "(!("ORIGINALAD_PREFIX SYSDB_NAME"=*)))", SYSDB_INITGR_ATTR, attrs, &groups_count, &groups); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_groups_without_orig failed.\n"); return ret; } if (groups != NULL) { subreq = ipa_initgr_get_overrides_send(state, state->ev, state->ipa_ctx, state->obj_dom, groups_count, groups, SYSDB_SID_STR); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_initgr_get_overrides_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, ipa_id_get_groups_overrides_done, req); return EOK; } ret = ipa_get_ad_ipa_membership_step(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_ipa_membership_step failed.\n"); return ret; } return EOK; } static void ipa_id_get_groups_overrides_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); errno_t ret; ret = ipa_initgr_get_overrides_recv(subreq, NULL); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA resolve user groups overrides failed [%d].\n", ret); tevent_req_error(req, ret); return; } ret = ipa_get_ad_ipa_membership_step(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_ipa_membership_step failed.\n"); tevent_req_error(req, ret); return; } return; } static errno_t ipa_get_ad_ipa_membership_step(struct tevent_req *req) { struct ipa_get_ad_acct_state *state = tevent_req_data(req, struct ipa_get_ad_acct_state); struct tevent_req *subreq; /* For initgroups request we have to check IPA group memberships of AD * users. This has to be done for other user-request as well to make sure * IPA related attributes are not overwritten. */ subreq = ipa_get_ad_memberships_send(state, state->ev, state->ar, state->ipa_ctx->server_mode, state->obj_dom, state->ipa_ctx->sdap_id_ctx, state->ipa_ctx->server_mode->realm); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_memberships_send failed.\n"); return ENOMEM; } tevent_req_set_callback(subreq, ipa_get_ad_acct_done, req); return EOK; } static void ipa_get_ad_acct_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_ad_acct_state *state = tevent_req_data(req, struct ipa_get_ad_acct_state); errno_t ret; ret = ipa_get_ad_memberships_recv(subreq, &state->dp_error); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "IPA external groups lookup failed: %d\n", ret); tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t ipa_get_ad_acct_recv(struct tevent_req *req, int *dp_error_out) { struct ipa_get_ad_acct_state *state = tevent_req_data(req, struct ipa_get_ad_acct_state); if (dp_error_out) { *dp_error_out = state->dp_error; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct ipa_srv_ad_acct_state { struct tevent_context *ev; struct ipa_id_ctx *ipa_ctx; struct be_req *be_req; struct sysdb_attrs *override_attrs; struct be_acct_req *ar; struct sss_domain_info *obj_dom; struct be_ctx *be_ctx; bool retry; int dp_error; }; static int ipa_srv_ad_acct_lookup_step(struct tevent_req *req); static void ipa_srv_ad_acct_lookup_done(struct tevent_req *subreq); static void ipa_srv_ad_acct_retried(struct tevent_req *subreq); static struct tevent_req * ipa_srv_ad_acct_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_id_ctx *ipa_ctx, struct be_req *be_req, struct sysdb_attrs *override_attrs, struct be_acct_req *ar) { errno_t ret; struct tevent_req *req; struct ipa_srv_ad_acct_state *state; req = tevent_req_create(mem_ctx, &state, struct ipa_srv_ad_acct_state); if (req == NULL) { return NULL; } state->ev = ev; state->ipa_ctx = ipa_ctx; state->be_req = be_req; state->override_attrs = override_attrs; state->ar = ar; state->retry = true; state->dp_error = DP_ERR_FATAL; state->be_ctx = be_req_get_be_ctx(state->be_req); state->obj_dom = find_domain_by_name( state->ipa_ctx->sdap_id_ctx->be->domain, state->ar->domain, true); if (state->obj_dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Domain not found\n"); ret = ERR_DOMAIN_NOT_FOUND; goto fail; } ret = ipa_srv_ad_acct_lookup_step(req); if (ret != EOK) { goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static int ipa_srv_ad_acct_lookup_step(struct tevent_req *req) { struct tevent_req *subreq; struct ipa_srv_ad_acct_state *state = tevent_req_data(req, struct ipa_srv_ad_acct_state); DEBUG(SSSDBG_TRACE_FUNC, "Looking up AD account\n"); subreq = ipa_get_ad_acct_send(state, state->ev, state->ipa_ctx, state->be_req, state->override_attrs, state->ar); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, ipa_srv_ad_acct_lookup_done, req); return EOK; } static void ipa_srv_ad_acct_lookup_done(struct tevent_req *subreq) { errno_t ret; int dp_error = DP_ERR_FATAL; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_srv_ad_acct_state *state = tevent_req_data(req, struct ipa_srv_ad_acct_state); ret = ipa_get_ad_acct_recv(subreq, &dp_error); talloc_free(subreq); if (ret == ERR_SUBDOM_INACTIVE && state->retry == true) { state->retry = false; DEBUG(SSSDBG_MINOR_FAILURE, "Sudomain lookup failed, will try to reset sudomain..\n"); subreq = ipa_server_trusted_dom_setup_send(state, state->ev, state->be_ctx, state->ipa_ctx, state->obj_dom); if (subreq == NULL) { goto fail; } tevent_req_set_callback(subreq, ipa_srv_ad_acct_retried, req); return; } else if (ret != EOK) { be_mark_dom_offline(state->obj_dom, state->be_ctx); DEBUG(SSSDBG_OP_FAILURE, "ipa_get_*_acct request failed: [%d]: %s.\n", ret, sss_strerror(ret)); goto fail; } state->dp_error = DP_ERR_OK; tevent_req_done(req); return; fail: state->dp_error = dp_error; tevent_req_error(req, ret); } static void ipa_srv_ad_acct_retried(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_srv_ad_acct_state *state = tevent_req_data(req, struct ipa_srv_ad_acct_state); ret = ipa_server_trusted_dom_setup_recv(subreq); talloc_free(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to re-set subdomain [%d]: %s\n", ret, sss_strerror(ret)); state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); } DEBUG(SSSDBG_TRACE_FUNC, "Sudomain re-set, will retry lookup\n"); be_fo_reset_svc(state->be_ctx, state->obj_dom->name); ret = ipa_srv_ad_acct_lookup_step(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to look up AD acct [%d]: %s\n", ret, sss_strerror(ret)); state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); } } static errno_t ipa_srv_ad_acct_recv(struct tevent_req *req, int *dp_error_out) { struct ipa_srv_ad_acct_state *state = tevent_req_data(req, struct ipa_srv_ad_acct_state); if (dp_error_out) { *dp_error_out = state->dp_error; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hosts.h0000644000000000000000000000007312703456111020043 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.568793337 sssd-1.13.4/src/providers/ipa/ipa_hosts.h0000644002412700241270000000274112703456111021517 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Jan Zeleny Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IPA_HOSTS_H_ #define IPA_HOSTS_H_ struct tevent_req * ipa_host_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, struct sdap_options *opts, const char *hostname, struct sdap_attr_map *host_map, struct sdap_attr_map *hostgroup_map, struct sdap_search_base **search_bases); errno_t ipa_host_info_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *host_count, struct sysdb_attrs ***hosts, size_t *hostgroup_count, struct sysdb_attrs ***hostgroups); #endif /* IPA_HOSTS_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_idmap.c0000644000000000000000000000007312703456111017770 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.748793947 sssd-1.13.4/src/providers/ipa/ipa_idmap.c0000644002412700241270000002661312703456111021450 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Sumit Bose Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ipa/ipa_common.h" #include "util/util_sss_idmap.h" static errno_t ipa_idmap_check_posix_child(struct sdap_idmap_ctx *idmap_ctx, const char *dom_name, const char *dom_sid_str, size_t range_count, struct range_info **range_list) { bool has_algorithmic_mapping; enum idmap_error_code err; struct sss_domain_info *dom; struct sss_domain_info *forest_root; size_t c; struct sss_idmap_range range; struct range_info *r; char *range_id; TALLOC_CTX *tmp_ctx; bool found = false; int ret; err = sss_idmap_domain_has_algorithmic_mapping(idmap_ctx->map, dom_sid_str, &has_algorithmic_mapping); if (err == IDMAP_SUCCESS) { DEBUG(SSSDBG_TRACE_ALL, "Idmap of domain [%s] already known, nothing to do.\n", dom_sid_str); return EOK; } else { err = sss_idmap_domain_by_name_has_algorithmic_mapping(idmap_ctx->map, dom_name, &has_algorithmic_mapping); if (err == IDMAP_SUCCESS) { DEBUG(SSSDBG_TRACE_ALL, "Idmap of domain [%s] already known, nothing to do.\n", dom_sid_str); return EOK; } } DEBUG(SSSDBG_TRACE_ALL, "Trying to add idmap for domain [%s].\n", dom_sid_str); if (err != IDMAP_SID_UNKNOWN && err != IDMAP_NAME_UNKNOWN) { DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_domain_has_algorithmic_mapping failed.\n"); return EINVAL; } dom = find_domain_by_sid(idmap_ctx->id_ctx->be->domain, dom_sid_str); if (dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_sid failed with SID [%s].\n", dom_sid_str); return EINVAL; } if (dom->forest == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "No forest available for domain [%s].\n", dom_sid_str); return EINVAL; } forest_root = find_domain_by_name(idmap_ctx->id_ctx->be->domain, dom->forest, true); if (forest_root == NULL) { DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed to find forest root [%s].\n", dom->forest); return ENOENT; } if (forest_root->domain_id == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Forest root [%s] does not have a SID.\n", dom->forest); return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } for (c = 0; c < range_count; c++) { r = range_list[c]; if (r->trusted_dom_sid != NULL && strcmp(r->trusted_dom_sid, forest_root->domain_id) == 0) { if (r->range_type == NULL || strcmp(r->range_type, IPA_RANGE_AD_TRUST_POSIX) != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Forest root does not have range type [%s].\n", IPA_RANGE_AD_TRUST_POSIX); ret = EINVAL; goto done; } range.min = r->base_id; range.max = r->base_id + r->id_range_size -1; range_id = talloc_asprintf(tmp_ctx, "%s-%s", dom_sid_str, r->name); if (range_id == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } err = sss_idmap_add_domain_ex(idmap_ctx->map, dom_name, dom_sid_str, &range, range_id, 0, true); if (err != IDMAP_SUCCESS && err != IDMAP_COLLISION) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add range [%s] to ID map\n", range_id); ret = EIO; goto done; } found = true; } } if (!found) { DEBUG(SSSDBG_MINOR_FAILURE, "No idrange found for forest root [%s].\n", forest_root->domain_id); ret = ENOENT; goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t get_idmap_data_from_range(struct range_info *r, char *domain_name, char **_name, char **_sid, uint32_t *_rid, struct sss_idmap_range *_range, bool *_external_mapping) { if (r->range_type == NULL) { /* Older IPA servers might not have the range_type attribute, but * only support local ranges and trusts with algorithmic mapping. */ if (r->trusted_dom_sid == NULL && r->secondary_base_rid != 0) { /* local IPA domain */ *_rid = 0; *_external_mapping = true; *_name = domain_name; *_sid = NULL; } else if (r->trusted_dom_sid != NULL && r->secondary_base_rid == 0) { /* trusted domain */ *_rid = r->base_rid; *_external_mapping = false; *_name = r->trusted_dom_sid; *_sid = r->trusted_dom_sid; } else { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot determine range type, " \ "for id range [%s].\n", r->name); return EINVAL; } } else { if (strcmp(r->range_type, IPA_RANGE_LOCAL) == 0) { *_rid = 0; *_external_mapping = true; *_name = domain_name; *_sid = NULL; } else if (strcmp(r->range_type, IPA_RANGE_AD_TRUST_POSIX) == 0) { *_rid = 0; *_external_mapping = true; *_name = r->trusted_dom_sid; *_sid = r->trusted_dom_sid; } else if (strcmp(r->range_type, IPA_RANGE_AD_TRUST) == 0) { *_rid = r->base_rid; *_external_mapping = false; *_name = r->trusted_dom_sid; *_sid = r->trusted_dom_sid; } else { DEBUG(SSSDBG_MINOR_FAILURE, "Range type [%s] of id range " \ "[%s] not supported.\n", \ r->range_type, r->name); return EINVAL; } } _range->min = r->base_id; _range->max = r->base_id + r->id_range_size -1; return EOK; } errno_t ipa_idmap_get_ranges_from_sysdb(struct sdap_idmap_ctx *idmap_ctx, const char *dom_name, const char *dom_sid_str, bool allow_collisions) { int ret; size_t range_count; struct range_info **range_list; TALLOC_CTX *tmp_ctx; size_t c; enum idmap_error_code err; struct sss_idmap_range range; uint32_t rid; bool external_mapping; char *name; char *sid; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = sysdb_get_ranges(tmp_ctx, idmap_ctx->id_ctx->be->domain->sysdb, &range_count, &range_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_ranges failed.\n"); goto done; } for (c = 0; c < range_count; c++) { ret = get_idmap_data_from_range(range_list[c], idmap_ctx->id_ctx->be->domain->name, &name, &sid, &rid, &range, &external_mapping); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_idmap_data_from_range failed for " \ "id range [%s], skipping.\n", range_list[c]->name); continue; } err = sss_idmap_add_domain_ex(idmap_ctx->map, name, sid, &range, range_list[c]->name, rid, external_mapping); if (err != IDMAP_SUCCESS) { if (!allow_collisions || err != IDMAP_COLLISION) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add range [%s] to ID map\n", range_list[c]->name); ret = EIO; goto done; } } } if (dom_name != NULL || dom_sid_str != NULL) { ret = ipa_idmap_check_posix_child(idmap_ctx, dom_name, dom_sid_str, range_count, range_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_idmap_check_posix_child failed.\n"); goto done; } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t ipa_idmap_find_new_domain(struct sdap_idmap_ctx *idmap_ctx, const char *dom_name, const char *dom_sid_str) { return ipa_idmap_get_ranges_from_sysdb(idmap_ctx, dom_name, dom_sid_str, true); } errno_t ipa_idmap_init(TALLOC_CTX *mem_ctx, struct sdap_id_ctx *id_ctx, struct sdap_idmap_ctx **_idmap_ctx) { errno_t ret; TALLOC_CTX *tmp_ctx; enum idmap_error_code err; struct sdap_idmap_ctx *idmap_ctx = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx); if (!idmap_ctx) { ret = ENOMEM; goto done; } idmap_ctx->id_ctx = id_ctx; idmap_ctx->find_new_domain = ipa_idmap_find_new_domain; /* Initialize the map */ err = sss_idmap_init(sss_idmap_talloc, idmap_ctx, sss_idmap_talloc_free, &idmap_ctx->map); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize the ID map: [%s]\n", idmap_error_string(err)); if (err == IDMAP_OUT_OF_MEMORY) { ret = ENOMEM; } else { ret = EINVAL; } goto done; } ret = ipa_idmap_get_ranges_from_sysdb(idmap_ctx, NULL, NULL, false); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_idmap_get_ranges_from_sysdb failed.\n"); goto done; } *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx); ret = EOK; done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hostid.h0000644000000000000000000000007312703456111020175 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.574793357 sssd-1.13.4/src/providers/ipa/ipa_hostid.h0000644002412700241270000000200012703456111021635 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _IPA_HOSTID_H_ #define _IPA_HOSTID_H_ struct ipa_hostid_ctx { struct sdap_id_ctx *sdap_id_ctx; struct ipa_options *ipa_opts; struct sdap_search_base **host_search_bases; }; void ipa_host_info_handler(struct be_req *be_req); #endif /* _IPA_HOSTID_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_config.h0000644000000000000000000000007312703456111020150 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.565793327 sssd-1.13.4/src/providers/ipa/ipa_config.h0000644002412700241270000000346712703456111021632 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- configuration retrieval header Authors: Jan Zeleny Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IPA_CONFIG_H_ #define IPA_CONFIG_H_ #include #include #include "providers/ldap/ldap_common.h" #include "db/sysdb.h" #define IPA_CONFIG_SELINUX_DEFAULT_USER_CTX "ipaSELinuxUserMapDefault" #define IPA_CONFIG_SELINUX_MAP_ORDER "ipaSELinuxUserMapOrder" #define IPA_CONFIG_MIGRATION_ENABLED "ipaMigrationEnabled" #define IPA_CONFIG_SEARCH_BASE_TEMPLATE "cn=etc,%s" #define IPA_CONFIG_FILTER "(&(cn=ipaConfig)(objectClass=ipaGuiConfig))" struct tevent_req * ipa_get_config_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, struct sdap_options *opts, const char *domain, const char **attrs); errno_t ipa_get_config_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sysdb_attrs **config); #endif /* IPA_CONFIG_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_views.c0000644000000000000000000000007412703456111020034 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.736793907 sssd-1.13.4/src/providers/ipa/ipa_views.c0000644002412700241270000003646712703456111021523 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Identity Backend Module for views and overrides Authors: Sumit Bose Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/strtonum.h" #include "providers/ldap/sdap_async.h" #include "providers/ipa/ipa_id.h" static errno_t be_acct_req_to_override_filter(TALLOC_CTX *mem_ctx, struct ipa_options *ipa_opts, struct be_acct_req *ar, char **override_filter) { char *filter; uint32_t id; char *endptr; switch (ar->filter_type) { case BE_FILTER_NAME: switch ((ar->entry_type & BE_REQ_TYPE_MASK)) { case BE_REQ_USER: case BE_REQ_INITGROUPS: filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))", ipa_opts->override_map[IPA_OC_OVERRIDE_USER].name, ipa_opts->override_map[IPA_AT_OVERRIDE_USER_NAME].name, ar->filter_value); break; case BE_REQ_GROUP: filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%s))", ipa_opts->override_map[IPA_OC_OVERRIDE_GROUP].name, ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_NAME].name, ar->filter_value); break; case BE_REQ_USER_AND_GROUP: filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))", ipa_opts->override_map[IPA_OC_OVERRIDE].name, ipa_opts->override_map[IPA_AT_OVERRIDE_USER_NAME].name, ar->filter_value, ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_NAME].name, ar->filter_value); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected entry type [%d] for name filter.\n", ar->entry_type); return EINVAL; } break; case BE_FILTER_IDNUM: errno = 0; id = strtouint32(ar->filter_value, &endptr, 10); if (errno != 0|| *endptr != '\0' || (ar->filter_value == endptr)) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid id value [%s].\n", ar->filter_value); return EINVAL; } switch ((ar->entry_type & BE_REQ_TYPE_MASK)) { case BE_REQ_USER: case BE_REQ_INITGROUPS: filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%"PRIu32"))", ipa_opts->override_map[IPA_OC_OVERRIDE_USER].name, ipa_opts->override_map[IPA_AT_OVERRIDE_UID_NUMBER].name, id); break; case BE_REQ_GROUP: filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=%"PRIu32"))", ipa_opts->override_map[IPA_OC_OVERRIDE_GROUP].name, ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_GID_NUMBER].name, id); break; case BE_REQ_USER_AND_GROUP: filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|(%s=%"PRIu32")(%s=%"PRIu32")))", ipa_opts->override_map[IPA_OC_OVERRIDE].name, ipa_opts->override_map[IPA_AT_OVERRIDE_UID_NUMBER].name, id, ipa_opts->override_map[IPA_AT_OVERRIDE_GROUP_GID_NUMBER].name, id); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected entry type [%d] for id filter.\n", ar->entry_type); return EINVAL; } break; case BE_FILTER_SECID: if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_SECID) { filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=:SID:%s))", ipa_opts->override_map[IPA_OC_OVERRIDE].name, ipa_opts->override_map[IPA_AT_OVERRIDE_ANCHOR_UUID].name, ar->filter_value); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected entry type [%d] for SID filter.\n", ar->entry_type); return EINVAL; } break; case BE_FILTER_UUID: if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_UUID) { filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(%s=:IPA:%s:%s))", ipa_opts->override_map[IPA_OC_OVERRIDE].name, ipa_opts->override_map[IPA_AT_OVERRIDE_ANCHOR_UUID].name, dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN), ar->filter_value); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected entry type [%d] for UUID filter.\n", ar->entry_type); return EINVAL; } break; default: DEBUG(SSSDBG_OP_FAILURE, "Invalid sub-domain filter type.\n"); return EINVAL; } if (filter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); return ENOMEM; } *override_filter = filter; return EOK; } static errno_t get_be_acct_req_for_xyz(TALLOC_CTX *mem_ctx, const char *val, const char *domain_name, int type, struct be_acct_req **_ar) { struct be_acct_req *ar; ar = talloc_zero(mem_ctx, struct be_acct_req); if (ar == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } switch (type) { case BE_REQ_BY_SECID: ar->entry_type = BE_REQ_BY_SECID; ar->filter_type = BE_FILTER_SECID; break; case BE_REQ_BY_UUID: ar->entry_type = BE_REQ_BY_UUID; ar->filter_type = BE_FILTER_UUID; break; case BE_REQ_USER: ar->entry_type = BE_REQ_USER; ar->filter_type = BE_FILTER_NAME; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported request type [%d].\n", type); talloc_free(ar); return EINVAL; } ar->filter_value = talloc_strdup(ar, val); ar->domain = talloc_strdup(ar, domain_name); if (ar->filter_value == NULL || ar->domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); talloc_free(ar); return ENOMEM; } *_ar = ar; return EOK; } errno_t get_be_acct_req_for_sid(TALLOC_CTX *mem_ctx, const char *sid, const char *domain_name, struct be_acct_req **_ar) { return get_be_acct_req_for_xyz(mem_ctx, sid, domain_name, BE_REQ_BY_SECID, _ar); } errno_t get_be_acct_req_for_uuid(TALLOC_CTX *mem_ctx, const char *uuid, const char *domain_name, struct be_acct_req **_ar) { return get_be_acct_req_for_xyz(mem_ctx, uuid, domain_name, BE_REQ_BY_UUID, _ar); } errno_t get_be_acct_req_for_user_name(TALLOC_CTX *mem_ctx, const char *user_name, const char *domain_name, struct be_acct_req **_ar) { return get_be_acct_req_for_xyz(mem_ctx, user_name, domain_name, BE_REQ_USER, _ar); } struct ipa_get_ad_override_state { struct tevent_context *ev; struct sdap_id_ctx *sdap_id_ctx; struct ipa_options *ipa_options; const char *ipa_realm; const char *ipa_view_name; struct be_acct_req *ar; struct sdap_id_op *sdap_op; int dp_error; struct sysdb_attrs *override_attrs; char *filter; }; static void ipa_get_ad_override_connect_done(struct tevent_req *subreq); static void ipa_get_ad_override_done(struct tevent_req *subreq); struct tevent_req *ipa_get_ad_override_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_id_ctx, struct ipa_options *ipa_options, const char *ipa_realm, const char *view_name, struct be_acct_req *ar) { int ret; struct tevent_req *req; struct tevent_req *subreq; struct ipa_get_ad_override_state *state; req = tevent_req_create(mem_ctx, &state, struct ipa_get_ad_override_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->sdap_id_ctx = sdap_id_ctx; state->ipa_options = ipa_options; state->ipa_realm = ipa_realm; state->ar = ar; state->dp_error = -1; state->override_attrs = NULL; state->filter = NULL; if (view_name == NULL) { DEBUG(SSSDBG_TRACE_ALL, "View not defined, nothing to do.\n"); ret = EOK; goto done; } if (is_default_view(view_name)) { state->ipa_view_name = IPA_DEFAULT_VIEW_NAME; } else { state->ipa_view_name = view_name; } state->sdap_op = sdap_id_op_create(state, state->sdap_id_ctx->conn->conn_cache); if (state->sdap_op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto done; } subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n", ret, strerror(ret)); goto done; } tevent_req_set_callback(subreq, ipa_get_ad_override_connect_done, req); return req; done: if (ret != EOK) { state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); } else { state->dp_error = DP_ERR_OK; tevent_req_done(req); } tevent_req_post(req, state->ev); return req; } static void ipa_get_ad_override_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_ad_override_state *state = tevent_req_data(req, struct ipa_get_ad_override_state); int ret; char *basedn; char *search_base; struct ipa_options *ipa_opts = state->ipa_options; ret = sdap_id_op_connect_recv(subreq, &state->dp_error); talloc_zfree(subreq); if (ret != EOK) { if (state->dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_MINOR_FAILURE, "No IPA server is available, going offline\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to IPA server: [%d](%s)\n", ret, strerror(ret)); } goto fail; } ret = domain_to_basedn(state, state->ipa_realm, &basedn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n"); goto fail; } search_base = talloc_asprintf(state, "cn=%s,%s", state->ipa_view_name, ipa_opts->views_search_bases[0]->basedn); if (search_base == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto fail; } ret = be_acct_req_to_override_filter(state, state->ipa_options, state->ar, &state->filter); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "be_acct_req_to_override_filter failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_ALL, "Searching for overrides in view [%s] with filter [%s].\n", state->ipa_view_name, state->filter); subreq = sdap_get_generic_send(state, state->ev, state->sdap_id_ctx->opts, sdap_id_op_handle(state->sdap_op), search_base, LDAP_SCOPE_SUBTREE, state->filter, NULL, state->ipa_options->override_map, IPA_OPTS_OVERRIDE, dp_opt_get_int(state->sdap_id_ctx->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_get_ad_override_done, req); return; fail: state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); return; } static void ipa_get_ad_override_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_ad_override_state *state = tevent_req_data(req, struct ipa_get_ad_override_state); int ret; size_t reply_count = 0; struct sysdb_attrs **reply = NULL; ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ipa_get_ad_override request failed.\n"); goto fail; } if (reply_count == 0) { DEBUG(SSSDBG_TRACE_ALL, "No override found with filter [%s].\n", state->filter); state->dp_error = DP_ERR_OK; tevent_req_done(req); return; } else if (reply_count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Found [%zu] overrides with filter [%s], expected only 1.\n", reply_count, state->filter); ret = EINVAL; goto fail; } DEBUG(SSSDBG_TRACE_ALL, "Found override for object with filter [%s].\n", state->filter); state->override_attrs = reply[0]; state->dp_error = DP_ERR_OK; tevent_req_done(req); return; fail: state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); return; } errno_t ipa_get_ad_override_recv(struct tevent_req *req, int *dp_error_out, TALLOC_CTX *mem_ctx, struct sysdb_attrs **override_attrs) { struct ipa_get_ad_override_state *state = tevent_req_data(req, struct ipa_get_ad_override_state); if (dp_error_out != NULL) { *dp_error_out = state->dp_error; } TEVENT_REQ_RETURN_ON_ERROR(req); if (override_attrs != NULL) { *override_attrs = talloc_steal(mem_ctx, state->override_attrs); } return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hbac_private.h0000644000000000000000000000007212703456111021331 xustar0029 atime=1460561751.64571561 29 ctime=1460561774.74079392 sssd-1.13.4/src/providers/ipa/ipa_hbac_private.h0000644002412700241270000001257312703456111023012 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IPA_HBAC_PRIVATE_H_ #define IPA_HBAC_PRIVATE_H_ #include "providers/ipa/ipa_access.h" #include "providers/ipa/ipa_hbac.h" #define IPA_HBAC_RULE "ipaHBACRule" #define IPA_HBAC_SERVICE "ipaHBACService" #define IPA_HBAC_SERVICE_GROUP "ipaHBACServiceGroup" #define IPA_UNIQUE_ID "ipauniqueid" #define IPA_MEMBER "member" #define HBAC_HOSTS_SUBDIR "hbac_hosts" #define HBAC_HOSTGROUPS_SUBDIR "hbac_hostgroups" #define OBJECTCLASS "objectclass" #define IPA_MEMBEROF "memberOf" #define IPA_ACCESS_RULE_TYPE "accessRuleType" #define IPA_HBAC_ALLOW "allow" #define IPA_MEMBER_USER "memberUser" #define IPA_USER_CATEGORY "userCategory" #define IPA_SERVICE_NAME "serviceName" #define IPA_SOURCE_HOST "sourceHost" #define IPA_SOURCE_HOST_CATEGORY "sourceHostCategory" #define IPA_EXTERNAL_HOST "externalHost" #define IPA_ENABLED_FLAG "ipaenabledflag" #define IPA_MEMBER_HOST "memberHost" #define IPA_HOST_CATEGORY "hostCategory" #define IPA_CN "cn" #define IPA_MEMBER_SERVICE "memberService" #define IPA_SERVICE_CATEGORY "serviceCategory" #define IPA_TRUE_VALUE "TRUE" #define IPA_HBAC_BASE_TMPL "cn=hbac,%s" #define IPA_SERVICES_BASE_TMPL "cn=hbacservices,cn=accounts,%s" #define SYSDB_HBAC_BASE_TMPL "cn=hbac,"SYSDB_TMPL_CUSTOM_BASE #define HBAC_RULES_SUBDIR "hbac_rules" #define HBAC_SERVICES_SUBDIR "hbac_services" #define HBAC_SERVICEGROUPS_SUBDIR "hbac_servicegroups" /* From ipa_hbac_common.c */ errno_t ipa_hbac_sysdb_save(struct sss_domain_info *domain, const char *primary_subdir, const char *attr_name, size_t primary_count, struct sysdb_attrs **primary, const char *group_subdir, const char *groupattr_name, size_t group_count, struct sysdb_attrs **groups); errno_t replace_attribute_name(const char *old_name, const char *new_name, const size_t count, struct sysdb_attrs **list); errno_t hbac_ctx_to_rules(TALLOC_CTX *mem_ctx, struct hbac_ctx *hbac_ctx, struct hbac_rule ***rules, struct hbac_eval_req **request); errno_t hbac_get_category(struct sysdb_attrs *attrs, const char *category_attr, uint32_t *_categories); errno_t hbac_thost_attrs_to_rule(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *rule_name, struct sysdb_attrs *rule_attrs, struct hbac_rule_element **thosts); errno_t hbac_shost_attrs_to_rule(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *rule_name, struct sysdb_attrs *rule_attrs, bool support_srchost, struct hbac_rule_element **source_hosts); errno_t get_ipa_hostgroupname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, const char *host_dn, char **hostgroupname); /* From ipa_hbac_services.c */ struct tevent_req * ipa_hbac_service_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, struct sdap_options *opts, struct sdap_search_base **search_bases); errno_t ipa_hbac_service_info_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *service_count, struct sysdb_attrs ***services, size_t *servicegroup_count, struct sysdb_attrs ***servicegroups); errno_t hbac_service_attrs_to_rule(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *rule_name, struct sysdb_attrs *rule_attrs, struct hbac_rule_element **services); errno_t get_ipa_servicegroupname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, const char *service_dn, char **servicename); /* From ipa_hbac_users.c */ errno_t hbac_user_attrs_to_rule(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *rule_name, struct sysdb_attrs *rule_attrs, struct hbac_rule_element **users); errno_t get_ipa_groupname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, const char *group_dn, const char **groupname); #endif /* IPA_HBAC_PRIVATE_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hbac_common.c0000644000000000000000000000007312703456111021143 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.745793937 sssd-1.13.4/src/providers/ipa/ipa_hbac_common.c0000644002412700241270000006042212703456111022617 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ipa/ipa_hbac_private.h" #include "providers/ipa/ipa_hbac.h" #include "providers/ipa/ipa_common.h" static errno_t ipa_hbac_save_list(struct sss_domain_info *domain, bool delete_subdir, const char *subdir, const char *naming_attribute, size_t count, struct sysdb_attrs **list) { int ret; size_t c; struct ldb_dn *base_dn; const char *object_name; struct ldb_message_element *el; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); return ENOMEM; } if (delete_subdir) { base_dn = sysdb_custom_subtree_dn(tmp_ctx, domain, subdir); if (base_dn == NULL) { ret = ENOMEM; goto done; } ret = sysdb_delete_recursive(domain->sysdb, base_dn, true); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_delete_recursive failed.\n"); goto done; } } for (c = 0; c < count; c++) { ret = sysdb_attrs_get_el(list[c], naming_attribute, &el); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_get_el failed.\n"); goto done; } if (el->num_values == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "[%s] not found.\n", naming_attribute); ret = EINVAL; goto done; } object_name = talloc_strndup(tmp_ctx, (const char *)el->values[0].data, el->values[0].length); if (object_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Object name: [%s].\n", object_name); ret = sysdb_store_custom(domain, object_name, subdir, list[c]); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_store_custom failed.\n"); goto done; } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t ipa_hbac_sysdb_save(struct sss_domain_info *domain, const char *primary_subdir, const char *attr_name, size_t primary_count, struct sysdb_attrs **primary, const char *group_subdir, const char *groupattr_name, size_t group_count, struct sysdb_attrs **groups) { errno_t ret, sret; bool in_transaction = false; if ((primary_count == 0 || primary == NULL) || (group_count > 0 && groups == NULL)) { /* There always has to be at least one * primary entry. */ return EINVAL; } /* Save the entries and groups to the cache */ ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; }; in_transaction = true; /* First, save the specific entries */ ret = ipa_hbac_save_list(domain, true, primary_subdir, attr_name, primary_count, primary); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not save %s. [%d][%s]\n", primary_subdir, ret, strerror(ret)); goto done; } /* Second, save the groups */ if (group_count > 0) { ret = ipa_hbac_save_list(domain, true, group_subdir, groupattr_name, group_count, groups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not save %s. [%d][%s]\n", group_subdir, ret, strerror(ret)); goto done; } } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not cancel sysdb transaction\n"); } } if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error [%d][%s]\n", ret, strerror(ret)); } return ret; } errno_t replace_attribute_name(const char *old_name, const char *new_name, const size_t count, struct sysdb_attrs **list) { int ret; int i; for (i = 0; i < count; i++) { ret = sysdb_attrs_replace_name(list[i], old_name, new_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_replace_name failed.\n"); return ret; } } return EOK; } static errno_t create_empty_grouplist(struct hbac_request_element *el) { el->groups = talloc_array(el, const char *, 1); if (!el->groups) return ENOMEM; el->groups[0] = NULL; return EOK; } /******************************************** * Functions for handling conversion to the * * HBAC evaluator format * ********************************************/ static errno_t hbac_attrs_to_rule(TALLOC_CTX *mem_ctx, struct hbac_ctx *hbac_ctx, size_t index, struct hbac_rule **rule); static errno_t hbac_ctx_to_eval_request(TALLOC_CTX *mem_ctx, struct hbac_ctx *hbac_ctx, struct hbac_eval_req **request); errno_t hbac_ctx_to_rules(TALLOC_CTX *mem_ctx, struct hbac_ctx *hbac_ctx, struct hbac_rule ***rules, struct hbac_eval_req **request) { errno_t ret; struct hbac_rule **new_rules; struct hbac_eval_req *new_request = NULL; size_t i; TALLOC_CTX *tmp_ctx = NULL; if (!rules || !request) return EINVAL; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return ENOMEM; /* First create an array of rules */ new_rules = talloc_array(tmp_ctx, struct hbac_rule *, hbac_ctx->rule_count + 1); if (new_rules == NULL) { ret = ENOMEM; goto done; } /* Create each rule one at a time */ for (i = 0; i < hbac_ctx->rule_count ; i++) { ret = hbac_attrs_to_rule(new_rules, hbac_ctx, i, &(new_rules[i])); if (ret == EPERM) { goto done; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct rules\n"); goto done; } } new_rules[i] = NULL; /* Create the eval request */ ret = hbac_ctx_to_eval_request(tmp_ctx, hbac_ctx, &new_request); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct eval request\n"); goto done; } *rules = talloc_steal(mem_ctx, new_rules); *request = talloc_steal(mem_ctx, new_request); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t hbac_attrs_to_rule(TALLOC_CTX *mem_ctx, struct hbac_ctx *hbac_ctx, size_t idx, struct hbac_rule **rule) { struct be_ctx *be_ctx = be_req_get_be_ctx(hbac_ctx->be_req); errno_t ret; struct hbac_rule *new_rule; struct ldb_message_element *el; const char *rule_type; new_rule = talloc_zero(mem_ctx, struct hbac_rule); if (new_rule == NULL) return ENOMEM; ret = sysdb_attrs_get_el(hbac_ctx->rules[idx], IPA_CN, &el); if (ret != EOK || el->num_values == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "rule has no name, assuming '(none)'.\n"); new_rule->name = talloc_strdup(new_rule, "(none)"); } else { new_rule->name = talloc_strndup(new_rule, (const char*) el->values[0].data, el->values[0].length); } DEBUG(SSSDBG_TRACE_LIBS, "Processing rule [%s]\n", new_rule->name); ret = sysdb_attrs_get_bool(hbac_ctx->rules[idx], IPA_ENABLED_FLAG, &new_rule->enabled); if (ret != EOK) goto done; if (!new_rule->enabled) { ret = EOK; goto done; } ret = sysdb_attrs_get_string(hbac_ctx->rules[idx], IPA_ACCESS_RULE_TYPE, &rule_type); if (ret != EOK) goto done; if (strcasecmp(rule_type, IPA_HBAC_ALLOW) != 0) { DEBUG(SSSDBG_TRACE_LIBS, "Rule [%s] is not an ALLOW rule\n", new_rule->name); ret = EPERM; goto done; } /* Get the users */ ret = hbac_user_attrs_to_rule(new_rule, be_ctx->domain, new_rule->name, hbac_ctx->rules[idx], &new_rule->users); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not parse users for rule [%s]\n", new_rule->name); goto done; } /* Get the services */ ret = hbac_service_attrs_to_rule(new_rule, be_ctx->domain, new_rule->name, hbac_ctx->rules[idx], &new_rule->services); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not parse services for rule [%s]\n", new_rule->name); goto done; } /* Get the target hosts */ ret = hbac_thost_attrs_to_rule(new_rule, be_ctx->domain, new_rule->name, hbac_ctx->rules[idx], &new_rule->targethosts); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not parse target hosts for rule [%s]\n", new_rule->name); goto done; } /* Get the source hosts */ ret = hbac_shost_attrs_to_rule(new_rule, be_ctx->domain, new_rule->name, hbac_ctx->rules[idx], dp_opt_get_bool(hbac_ctx->ipa_options, IPA_HBAC_SUPPORT_SRCHOST), &new_rule->srchosts); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not parse source hosts for rule [%s]\n", new_rule->name); goto done; } *rule = new_rule; ret = EOK; done: if (ret != EOK) talloc_free(new_rule); return ret; } errno_t hbac_get_category(struct sysdb_attrs *attrs, const char *category_attr, uint32_t *_categories) { errno_t ret; size_t i; uint32_t cats = HBAC_CATEGORY_NULL; const char **categories; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; ret = sysdb_attrs_get_string_array(attrs, category_attr, tmp_ctx, &categories); if (ret != EOK && ret != ENOENT) goto done; if (ret != ENOENT) { for (i = 0; categories[i]; i++) { if (strcasecmp("all", categories[i]) == 0) { DEBUG(SSSDBG_FUNC_DATA, "Category is set to 'all'.\n"); cats |= HBAC_CATEGORY_ALL; continue; } DEBUG(SSSDBG_TRACE_ALL, "Unsupported user category [%s].\n", categories[i]); } } *_categories = cats; ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t hbac_eval_user_element(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *username, struct hbac_request_element **user_element); static errno_t hbac_eval_service_element(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *servicename, struct hbac_request_element **svc_element); static errno_t hbac_eval_host_element(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *hostname, struct hbac_request_element **host_element); static errno_t hbac_ctx_to_eval_request(TALLOC_CTX *mem_ctx, struct hbac_ctx *hbac_ctx, struct hbac_eval_req **request) { errno_t ret; struct pam_data *pd = hbac_ctx->pd; TALLOC_CTX *tmp_ctx; struct hbac_eval_req *eval_req; struct be_ctx *be_ctx = be_req_get_be_ctx(hbac_ctx->be_req); struct sss_domain_info *domain = be_ctx->domain; const char *rhost; const char *thost; struct sss_domain_info *user_dom; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return ENOMEM; eval_req = talloc_zero(tmp_ctx, struct hbac_eval_req); if (eval_req == NULL) { ret = ENOMEM; goto done; } eval_req->request_time = time(NULL); /* Get user the user name and groups, * take care of subdomain users as well */ if (strcasecmp(pd->domain, domain->name) != 0) { user_dom = find_domain_by_name(domain, pd->domain, true); if (user_dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed.\n"); ret = ENOMEM; goto done; } ret = hbac_eval_user_element(eval_req, user_dom, pd->user, &eval_req->user); } else { ret = hbac_eval_user_element(eval_req, domain, pd->user, &eval_req->user); } if (ret != EOK) goto done; /* Get the PAM service and service groups */ ret = hbac_eval_service_element(eval_req, domain, pd->service, &eval_req->service); if (ret != EOK) goto done; /* Get the source host */ if (pd->rhost == NULL || pd->rhost[0] == '\0') { /* If we haven't been passed an rhost, * the rhost is unknown. This will fail * to match any rule requiring the * source host. */ rhost = NULL; } else { rhost = pd->rhost; } ret = hbac_eval_host_element(eval_req, domain, rhost, &eval_req->srchost); if (ret != EOK) goto done; /* The target host is always the current machine */ thost = dp_opt_get_cstring(hbac_ctx->ipa_options, IPA_HOSTNAME); if (thost == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing ipa_hostname, this should never happen.\n"); ret = EINVAL; goto done; } ret = hbac_eval_host_element(eval_req, domain, thost, &eval_req->targethost); if (ret != EOK) goto done; *request = talloc_steal(mem_ctx, eval_req); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t hbac_eval_user_element(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *username, struct hbac_request_element **user_element) { errno_t ret; unsigned int i; unsigned int num_groups = 0; TALLOC_CTX *tmp_ctx; const char *member_dn; struct hbac_request_element *users; struct ldb_message *msg; struct ldb_message_element *el; const char *attrs[] = { SYSDB_ORIG_MEMBEROF, NULL }; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return ENOMEM; users = talloc_zero(tmp_ctx, struct hbac_request_element); if (users == NULL) { ret = ENOMEM; goto done; } users->name = username; /* Read the originalMemberOf attribute * This will give us the list of both POSIX and * non-POSIX groups that this user belongs to. */ ret = sysdb_search_user_by_name(tmp_ctx, domain, users->name, attrs, &msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not determine user memberships for [%s]\n", users->name); goto done; } el = ldb_msg_find_element(msg, SYSDB_ORIG_MEMBEROF); if (el == NULL || el->num_values == 0) { DEBUG(SSSDBG_TRACE_LIBS, "No groups for [%s]\n", users->name); ret = create_empty_grouplist(users); goto done; } DEBUG(SSSDBG_TRACE_LIBS, "[%d] groups for [%s]\n", el->num_values, users->name); users->groups = talloc_array(users, const char *, el->num_values + 1); if (users->groups == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < el->num_values; i++) { member_dn = (const char *)el->values[i].data; ret = get_ipa_groupname(users->groups, domain->sysdb, member_dn, &users->groups[num_groups]); if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) { DEBUG(SSSDBG_MINOR_FAILURE, "Skipping malformed entry [%s]\n", member_dn); continue; } else if (ret == EOK) { DEBUG(SSSDBG_TRACE_LIBS, "Added group [%s] for user [%s]\n", users->groups[num_groups], users->name); num_groups++; continue; } /* Skip entries that are not groups */ DEBUG(SSSDBG_TRACE_INTERNAL, "Skipping non-group memberOf [%s]\n", member_dn); } users->groups[num_groups] = NULL; if (num_groups < el->num_values) { /* Shrink the array memory */ users->groups = talloc_realloc(users, users->groups, const char *, num_groups+1); if (users->groups == NULL) { ret = ENOMEM; goto done; } } ret = EOK; done: if (ret == EOK) { *user_element = talloc_steal(mem_ctx, users); } talloc_free(tmp_ctx); return ret; } static errno_t hbac_eval_service_element(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *servicename, struct hbac_request_element **svc_element) { errno_t ret; size_t i, j, count; TALLOC_CTX *tmp_ctx; struct hbac_request_element *svc; struct ldb_message **msgs; struct ldb_message_element *el; struct ldb_dn *svc_dn; const char *memberof_attrs[] = { SYSDB_ORIG_MEMBEROF, NULL }; char *name; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return ENOMEM; svc = talloc_zero(tmp_ctx, struct hbac_request_element); if (svc == NULL) { ret = ENOMEM; goto done; } svc->name = servicename; svc_dn = sysdb_custom_dn(tmp_ctx, domain, svc->name, HBAC_SERVICES_SUBDIR); if (svc_dn == NULL) { ret = ENOMEM; goto done; } /* Look up the service to get its originalMemberOf entries */ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, svc_dn, LDB_SCOPE_BASE, NULL, memberof_attrs, &count, &msgs); if (ret == ENOENT || count == 0) { /* We won't be able to identify any groups * This rule will only match the name or * a service category of ALL */ ret = create_empty_grouplist(svc); goto done; } else if (ret != EOK) { goto done; } else if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "More than one result for a BASE search!\n"); ret = EIO; goto done; } el = ldb_msg_find_element(msgs[0], SYSDB_ORIG_MEMBEROF); if (!el) { /* Service is not a member of any groups * This rule will only match the name or * a service category of ALL */ ret = create_empty_grouplist(svc); goto done; } svc->groups = talloc_array(svc, const char *, el->num_values + 1); if (svc->groups == NULL) { ret = ENOMEM; goto done; } for (i = j = 0; i < el->num_values; i++) { ret = get_ipa_servicegroupname(tmp_ctx, domain->sysdb, (const char *)el->values[i].data, &name); if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) { DEBUG(SSSDBG_MINOR_FAILURE, "Skipping malformed entry [%s]\n", (const char *)el->values[i].data); continue; } /* ERR_UNEXPECTED_ENTRY_TYPE means we had a memberOf entry that wasn't a * service group. We'll just ignore those (could be * HBAC rules) */ if (ret == EOK) { svc->groups[j] = talloc_steal(svc->groups, name); j++; } } svc->groups[j] = NULL; ret = EOK; done: if (ret == EOK) { *svc_element = talloc_steal(mem_ctx, svc); } talloc_free(tmp_ctx); return ret; } static errno_t hbac_eval_host_element(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *hostname, struct hbac_request_element **host_element) { errno_t ret; size_t i, j, count; TALLOC_CTX *tmp_ctx; struct hbac_request_element *host; struct ldb_message **msgs; struct ldb_message_element *el; struct ldb_dn *host_dn; const char *memberof_attrs[] = { SYSDB_ORIG_MEMBEROF, NULL }; char *name; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return ENOMEM; host = talloc_zero(tmp_ctx, struct hbac_request_element); if (host == NULL) { ret = ENOMEM; goto done; } host->name = hostname; if (host->name == NULL) { /* We don't know the host (probably an rhost) * So we can't determine it's groups either. */ ret = create_empty_grouplist(host); goto done; } host_dn = sysdb_custom_dn(tmp_ctx, domain, host->name, HBAC_HOSTS_SUBDIR); if (host_dn == NULL) { ret = ENOMEM; goto done; } /* Look up the host to get its originalMemberOf entries */ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, host_dn, LDB_SCOPE_BASE, NULL, memberof_attrs, &count, &msgs); if (ret == ENOENT || count == 0) { /* We won't be able to identify any groups * This rule will only match the name or * a host category of ALL */ ret = create_empty_grouplist(host); goto done; } else if (ret != EOK) { goto done; } else if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "More than one result for a BASE search!\n"); ret = EIO; goto done; } el = ldb_msg_find_element(msgs[0], SYSDB_ORIG_MEMBEROF); if (!el) { /* Host is not a member of any groups * This rule will only match the name or * a host category of ALL */ ret = create_empty_grouplist(host); goto done; } host->groups = talloc_array(host, const char *, el->num_values + 1); if (host->groups == NULL) { ret = ENOMEM; goto done; } for (i = j = 0; i < el->num_values; i++) { ret = get_ipa_hostgroupname(tmp_ctx, domain->sysdb, (const char *)el->values[i].data, &name); if (ret != EOK && ret != ERR_UNEXPECTED_ENTRY_TYPE) { DEBUG(SSSDBG_MINOR_FAILURE, "Skipping malformed entry [%s]\n", (const char *)el->values[i].data); continue; } /* ERR_UNEXPECTED_ENTRY_TYPE means we had a memberOf entry that wasn't a * host group. We'll just ignore those (could be * HBAC rules) */ if (ret == EOK) { host->groups[j] = talloc_steal(host->groups, name); j++; } } host->groups[j] = NULL; ret = EOK; done: if (ret == EOK) { *host_element = talloc_steal(mem_ctx, host); } talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_opts.c0000644000000000000000000000007312703456111017663 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.723793863 sssd-1.13.4/src/providers/ipa/ipa_opts.c0000644002412700241270000005475612703456111021354 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "src/providers/data_provider.h" #include "db/sysdb.h" #include "db/sysdb_sudo.h" #include "db/sysdb_autofs.h" #include "db/sysdb_services.h" #include "db/sysdb_selinux.h" #include "providers/ldap/ldap_common.h" struct dp_option ipa_basic_opts[] = { { "ipa_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ipa_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ipa_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ipa_hostname", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ipa_hbac_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "ipa_host_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ipa_selinux_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ipa_subdomains_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ipa_master_domain_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "ipa_hbac_refresh", DP_OPT_NUMBER, { .number = 5 }, NULL_NUMBER }, { "ipa_selinux_refresh", DP_OPT_NUMBER, { .number = 5 }, NULL_NUMBER }, { "ipa_hbac_support_srchost", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ipa_automount_location", DP_OPT_STRING, { "default" }, NULL_STRING }, { "ipa_ranges_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ipa_enable_dns_sites", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ipa_server_mode", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ipa_views_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_confd_path", DP_OPT_STRING, { KRB5_MAPPING_DIR }, NULL_STRING }, DP_OPTION_TERMINATOR }; struct dp_option ipa_dyndns_opts[] = { { "dyndns_update", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "dyndns_refresh_interval", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER }, { "dyndns_iface", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "dyndns_ttl", DP_OPT_NUMBER, { .number = 1200 }, NULL_NUMBER }, { "dyndns_update_ptr", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "dyndns_force_tcp", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "dyndns_auth", DP_OPT_STRING, { "gss-tsig" }, NULL_STRING }, { "dyndns_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, DP_OPTION_TERMINATOR }; struct dp_option ipa_def_ldap_opts[] = { { "ldap_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_backup_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_default_bind_dn", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_default_authtok_type", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "ldap_default_authtok", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB }, { "ldap_search_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "ldap_network_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "ldap_tls_reqcert", DP_OPT_STRING, { "hard" }, NULL_STRING }, { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, { "ldap_user_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_user_extra_attrs", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, { "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_service_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_full_refresh_interval", DP_OPT_NUMBER, { .number = 21600 }, NULL_NUMBER }, { "ldap_sudo_smart_refresh_interval", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER }, /* 15 mins */ { "ldap_sudo_use_host_filter", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_sudo_hostnames", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_ip", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_include_netgroups", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_sudo_include_regexp", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_autofs_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_autofs_map_master_name", DP_OPT_STRING, { "auto.master" }, NULL_STRING }, { "ldap_schema", DP_OPT_STRING, { "ipa_v1" }, NULL_STRING }, { "ldap_offline_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, { "ldap_force_upper_case_realm", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_enumeration_refresh_timeout", DP_OPT_NUMBER, { .number = 300 }, NULL_NUMBER }, { "ldap_purge_cache_timeout", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, { "ldap_tls_cacert", DP_OPT_STRING, { "/etc/ipa/ca.crt" }, NULL_STRING }, { "ldap_tls_cacertdir", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_tls_cert", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_tls_key", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_tls_cipher_suite", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_id_use_start_tls", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_id_mapping", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_sasl_mech", DP_OPT_STRING, { "GSSAPI" } , NULL_STRING }, { "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sasl_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sasl_minssf", DP_OPT_NUMBER, { .number = 56 }, NULL_NUMBER }, { "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, /* use the same parm name as the krb5 module so we set it only once */ { "krb5_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_canonicalize", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "krb5_use_kdcinfo", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_pwd_policy", DP_OPT_STRING, { "none" } , NULL_STRING }, { "ldap_referrals", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "account_cache_expiration", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, { "ldap_dns_service_name", DP_OPT_STRING, { SSS_LDAP_SRV_NAME }, NULL_STRING }, { "ldap_krb5_ticket_lifetime", DP_OPT_NUMBER, { .number = (24 * 60 * 60) }, NULL_NUMBER }, { "ldap_access_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_netgroup_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_group_nesting_level", DP_OPT_NUMBER, { .number = 2 }, NULL_NUMBER }, { "ldap_deref", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_account_expire_policy", DP_OPT_STRING, { "ipa" }, NULL_STRING }, { "ldap_access_order", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_chpass_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_chpass_backup_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_chpass_dns_service_name", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_chpass_update_last_change", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_enumeration_search_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, /* Do not include ldap_auth_disable_tls_never_use_in_production in the * manpages or SSSDConfig API */ { "ldap_auth_disable_tls_never_use_in_production", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_page_size", DP_OPT_NUMBER, { .number = 1000 }, NULL_NUMBER }, { "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER }, { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER }, { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER }, { "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER }, { "ldap_idmap_range_size", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER }, { "ldap_idmap_autorid_compat", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_idmap_default_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_idmap_default_domain_sid", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_idmap_helper_table_size", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER }, { "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_use_tokengroups", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE}, { "ldap_rfc2307_fallback_to_local_users", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_disable_range_retrieval", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_min_id", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER}, { "ldap_max_id", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER}, { "ldap_pwdlockout_dn", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "wildcard_limit", DP_OPT_NUMBER, { .number = 1000 }, NULL_NUMBER}, DP_OPTION_TERMINATOR }; struct sdap_attr_map ipa_attr_map[] = { { "ldap_entry_usn", "entryUSN", SYSDB_USN, NULL }, { "ldap_rootdse_last_usn", "lastUSN", SYSDB_HIGH_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_user_map[] = { { "ldap_user_object_class", "posixAccount", SYSDB_USER_CLASS, NULL }, { "ldap_user_name", "uid", SYSDB_NAME, NULL }, { "ldap_user_pwd", "userPassword", SYSDB_PWD, NULL }, { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL }, { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL }, { "ldap_user_home_directory", "homeDirectory", SYSDB_HOMEDIR, NULL }, { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL }, { "ldap_user_principal", "krbPrincipalName", SYSDB_UPN, NULL }, { "ldap_user_fullname", "cn", SYSDB_FULLNAME, NULL }, { "ldap_user_member_of", "memberOf", SYSDB_MEMBEROF, NULL }, { "ldap_user_uuid", "ipaUniqueID", SYSDB_UUID, NULL }, { "ldap_user_objectsid", "ipaNTSecurityIdentifier", SYSDB_SID_STR, NULL }, { "ldap_user_primary_group", NULL, SYSDB_PRIMARY_GROUP, NULL }, { "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_user_entry_usn", NULL, SYSDB_USN, NULL }, { "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL }, { "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL }, { "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL }, { "ldap_user_shadow_warning", "shadowWarning", SYSDB_SHADOWPW_WARNING, NULL }, { "ldap_user_shadow_inactive", "shadowInactive", SYSDB_SHADOWPW_INACTIVE, NULL }, { "ldap_user_shadow_expire", "shadowExpire", SYSDB_SHADOWPW_EXPIRE, NULL }, { "ldap_user_shadow_flag", "shadowFlag", SYSDB_SHADOWPW_FLAG, NULL }, { "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL }, { "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL }, { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL }, { "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL }, { "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL}, { "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL}, { "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL}, { "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL }, { "ldap_user_nds_login_disabled", "loginDisabled", SYSDB_NDS_LOGIN_DISABLED, NULL }, { "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL }, { "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL }, { "ldap_user_ssh_public_key", "ipaSshPubKey", SYSDB_SSH_PUBKEY, NULL }, { "ldap_user_auth_type", "ipaUserAuthType", SYSDB_AUTH_TYPE, NULL }, { "ldap_user_certificate", "userCertificate;binary", SYSDB_USER_CERT, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_group_map[] = { { "ldap_group_object_class", "ipaUserGroup", SYSDB_GROUP_CLASS, NULL }, { "ldap_group_object_class_alt", "posixGroup", SYSDB_GROUP_CLASS, NULL }, { "ldap_group_name", "cn", SYSDB_NAME, NULL }, { "ldap_group_pwd", "userPassword", SYSDB_PWD, NULL }, { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_group_member", "member", SYSDB_MEMBER, NULL }, { "ldap_group_uuid", "ipaUniqueID", SYSDB_UUID, NULL }, { "ldap_group_objectsid", "ipaNTSecurityIdentifier", SYSDB_SID_STR, NULL }, { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_group_entry_usn", NULL, SYSDB_USN, NULL }, { "ldap_group_type", NULL, SYSDB_GROUP_TYPE, NULL }, { "ldap_group_external_member", "ipaExternalMember", SYSDB_EXTERNAL_MEMBER, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_netgroup_map[] = { { "ipa_netgroup_object_class", "ipaNisNetgroup", SYSDB_NETGROUP_CLASS, NULL }, { "ipa_netgroup_name", "cn", SYSDB_NAME, NULL }, { "ipa_netgroup_member", "member", SYSDB_ORIG_NETGROUP_MEMBER, NULL }, { "ipa_netgroup_member_of", "memberOf", SYSDB_MEMBEROF, NULL }, { "ipa_netgroup_member_user", "memberUser", SYSDB_ORIG_MEMBER_USER, NULL }, { "ipa_netgroup_member_host", "memberHost", SYSDB_ORIG_MEMBER_HOST, NULL }, { "ipa_netgroup_member_ext_host", "externalHost", SYSDB_ORIG_NETGROUP_EXTERNAL_HOST, NULL }, { "ipa_netgroup_domain", "nisDomainName", SYSDB_NETGROUP_DOMAIN, NULL }, { "ipa_netgroup_uuid", "ipaUniqueID", SYSDB_UUID, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_host_map[] = { { "ipa_host_object_class", "ipaHost", SYSDB_HOST_CLASS, NULL }, { "ipa_host_name", "cn", SYSDB_NAME, NULL }, { "ipa_host_fqdn", "fqdn", SYSDB_FQDN, NULL }, { "ipa_host_serverhostname", "serverHostname", SYSDB_SERVERHOSTNAME, NULL }, { "ipa_host_member_of", "memberOf", SYSDB_ORIG_MEMBEROF, NULL }, { "ipa_host_ssh_public_key", "ipaSshPubKey", SYSDB_SSH_PUBKEY, NULL }, { "ipa_host_uuid", "ipaUniqueID", SYSDB_UUID, NULL}, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_hostgroup_map[] = { { "ipa_hostgroup_objectclass", "ipaHostgroup", SYSDB_HOSTGROUP_CLASS, NULL}, { "ipa_hostgroup_name", "cn", SYSDB_NAME, NULL}, { "ipa_hostgroup_memberof", "memberOf", SYSDB_ORIG_MEMBEROF, NULL}, { "ipa_hostgroup_uuid", "ipaUniqueID", SYSDB_UUID, NULL}, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_selinux_user_map[] = { { "ipa_selinux_usermap_object_class", "ipaselinuxusermap", SYSDB_SELINUX_USERMAP_CLASS, NULL}, { "ipa_selinux_usermap_name", "cn", SYSDB_NAME, NULL}, { "ipa_selinux_usermap_member_user", "memberUser", SYSDB_ORIG_MEMBER_USER, NULL}, { "ipa_selinux_usermap_member_host", "memberHost", SYSDB_ORIG_MEMBER_HOST, NULL}, { "ipa_selinux_usermap_see_also", "seeAlso", SYSDB_SELINUX_SEEALSO, NULL}, { "ipa_selinux_usermap_selinux_user", "ipaSELinuxUser", SYSDB_SELINUX_USER, NULL}, { "ipa_selinux_usermap_enabled", "ipaEnabledFlag", SYSDB_SELINUX_ENABLED, NULL}, { "ipa_selinux_usermap_user_category", "userCategory", SYSDB_USER_CATEGORY, NULL}, { "ipa_selinux_usermap_host_category", "hostCategory", SYSDB_HOST_CATEGORY, NULL}, { "ipa_selinux_usermap_uuid", "ipaUniqueID", SYSDB_UUID, NULL}, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_view_map[] = { { "ipa_view_class", "nsContainer", SYSDB_VIEW_CLASS, NULL}, { "ipa_view_name", "cn", SYSDB_VIEW_NAME, NULL}, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_override_map[] = { { "ipa_overide_object_class", "ipaOverrideAnchor", SYSDB_OVERRIDE_CLASS, NULL}, { "ipa_anchor_uuid", "ipaAnchorUUID", SYSDB_OVERRIDE_ANCHOR_UUID, NULL}, { "ipa_user_override_object_class", "ipaUserOverride", SYSDB_OVERRIDE_USER_CLASS, NULL}, { "ipa_group_override_object_class", "ipaGroupOverride", SYSDB_OVERRIDE_GROUP_CLASS, NULL}, { "ldap_user_name", "uid", SYSDB_NAME, NULL }, { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL }, { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL }, { "ldap_user_home_directory", "homeDirectory", SYSDB_HOMEDIR, NULL }, { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL }, { "ldap_group_name", "cn", SYSDB_NAME, NULL }, { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_user_ssh_public_key", "ipaSshPubKey", SYSDB_SSH_PUBKEY, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct dp_option ipa_def_krb5_opts[] = { { "krb5_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_ccachedir", DP_OPT_STRING, { DEFAULT_CCACHE_DIR }, NULL_STRING }, { "krb5_ccname_template", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING }, { "krb5_validate", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "krb5_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_backup_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_store_password_if_offline", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "krb5_renewable_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_renew_interval", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_use_fast", DP_OPT_STRING, { "try" }, NULL_STRING }, { "krb5_fast_principal", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_canonicalize", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "krb5_use_enterprise_principal", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "krb5_use_kdcinfo", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "krb5_map_user", DP_OPT_STRING, NULL_STRING, NULL_STRING }, DP_OPTION_TERMINATOR }; struct sdap_attr_map ipa_service_map[] = { { "ldap_service_object_class", "ipService", SYSDB_SVC_CLASS, NULL }, { "ldap_service_name", "cn", SYSDB_NAME, NULL }, { "ldap_service_port", "ipServicePort", SYSDB_SVC_PORT, NULL }, { "ldap_service_proto", "ipServiceProtocol", SYSDB_SVC_PROTO, NULL }, { "ldap_service_entry_usn", NULL, SYSDB_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_autofs_mobject_map[] = { { "ldap_autofs_map_object_class", "automountMap", SYSDB_AUTOFS_MAP_OC, NULL }, { "ldap_autofs_map_name", "automountMapName", SYSDB_AUTOFS_MAP_NAME, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_autofs_entry_map[] = { { "ldap_autofs_entry_object_class", "automount", SYSDB_AUTOFS_ENTRY_OC, NULL }, { "ldap_autofs_entry_key", "automountKey", SYSDB_AUTOFS_ENTRY_KEY, NULL }, { "ldap_autofs_entry_value", "automountInformation", SYSDB_AUTOFS_ENTRY_VALUE, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_sudorule_map[] = { { "ipa_sudorule_object_class", "ipasudorule", SYSDB_IPA_SUDORULE_OC, NULL }, { "ipa_sudorule_name", "cn", SYSDB_NAME, NULL }, { "ipa_sudorule_uuid", "ipaUniqueID", SYSDB_UUID, NULL }, { "ipa_sudorule_enabled_flag", "ipaEnabledFlag", SYSDB_IPA_SUDORULE_ENABLED, NULL }, { "ipa_sudorule_option", "ipaSudoOpt", SYSDB_IPA_SUDORULE_OPTION, NULL }, { "ipa_sudorule_runasuser", "ipaSudoRunAs", SYSDB_IPA_SUDORULE_RUNASUSER, NULL }, { "ipa_sudorule_runasgroup", "ipaSudoRunAsGroup", SYSDB_IPA_SUDORULE_RUNASGROUP, NULL }, { "ipa_sudorule_allowcmd", "memberAllowCmd", SYSDB_IPA_SUDORULE_ALLOWCMD, NULL }, { "ipa_sudorule_denycmd", "memberDenyCmd", SYSDB_IPA_SUDORULE_DENYCMD, NULL }, { "ipa_sudorule_host", "memberHost", SYSDB_IPA_SUDORULE_HOST, NULL }, { "ipa_sudorule_user", "memberUser", SYSDB_IPA_SUDORULE_USER, NULL }, { "ipa_sudorule_notafter", "sudoNotAfter", SYSDB_IPA_SUDORULE_NOTAFTER, NULL }, { "ipa_sudorule_notbefore", "sudoNotBefore", SYSDB_IPA_SUDORULE_NOTBEFORE, NULL }, { "ipa_sudorule_sudoorder", "sudoOrder", SYSDB_IPA_SUDORULE_SUDOORDER, NULL }, { "ipa_sudorule_cmdcategory", "cmdCategory", SYSDB_IPA_SUDORULE_CMDCATEGORY, NULL }, { "ipa_sudorule_hostcategory", "hostCategory", SYSDB_IPA_SUDORULE_HOSTCATEGORY, NULL }, { "ipa_sudorule_usercategory", "userCategory", SYSDB_IPA_SUDORULE_USERCATEGORY, NULL }, { "ipa_sudorule_runasusercategory", "ipaSudoRunAsUserCategory", SYSDB_IPA_SUDORULE_RUNASUSERCATEGORY, NULL }, { "ipa_sudorule_runasgroupcategory", "ipaSudoRunAsGroupCategory", SYSDB_IPA_SUDORULE_RUNASGROUPCATEGORY, NULL }, { "ipa_sudorule_runasextuser", "ipaSudoRunAsExtUser", SYSDB_IPA_SUDORULE_RUNASEXTUSER, NULL }, { "ipa_sudorule_runasextgroup", "ipaSudoRunAsExtGroup", SYSDB_IPA_SUDORULE_RUNASEXTGROUP, NULL }, { "ipa_sudorule_runasextusergroup", "ipaSudoRunAsExtUserGroup", SYSDB_IPA_SUDORULE_RUNASEXTUSERGROUP, NULL }, { "ipa_sudorule_externaluser", "externalUser", SYSDB_IPA_SUDORULE_EXTUSER, NULL }, { "ipa_sudorule_entry_usn", "entryUSN", SYSDB_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_sudocmdgroup_map[] = { { "ipa_sudocmdgroup_object_class", "ipasudocmdgrp", SYSDB_IPA_SUDOCMDGROUP_OC, NULL }, { "ipa_sudocmdgroup_uuid", "ipaUniqueID", SYSDB_UUID, NULL }, { "ipa_sudocmdgroup_name", "cn", SYSDB_NAME, NULL }, { "ipa_sudocmdgroup_member", "member", SYSDB_MEMBER, NULL }, { "ipa_sudocmdgroup_entry_usn", "entryUSN", SYSDB_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map ipa_sudocmd_map[] = { { "ipa_sudocmd_object_class", "ipasudocmd", SYSDB_IPA_SUDOCMD_OC, NULL }, { "ipa_sudocmd_uuid", "ipaUniqueID", SYSDB_UUID, NULL }, { "ipa_sudocmd_sudoCmd", "sudoCmd", SYSDB_IPA_SUDOCMD_SUDOCMD, NULL }, { "ipa_sudocmd_memberof", "memberOf", SYSDB_MEMBEROF, NULL }, SDAP_ATTR_MAP_TERMINATOR }; sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hbac_rules.h0000644000000000000000000000007312703456111021012 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.742793927 sssd-1.13.4/src/providers/ipa/ipa_hbac_rules.h0000644002412700241270000000257212703456111022470 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Jan Zeleny Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IPA_HBAC_RULES_H_ #define IPA_HBAC_RULES_H_ /* From ipa_hbac_rules.c */ struct tevent_req * ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, struct sdap_options *opts, struct sdap_search_base **search_bases, struct sysdb_attrs *ipa_host); errno_t ipa_hbac_rule_info_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *rule_count, struct sysdb_attrs ***rules); #endif /* IPA_HBAC_RULES_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_sudo_refresh.c0000644000000000000000000000007412703456111021367 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.752793961 sssd-1.13.4/src/providers/ipa/ipa_sudo_refresh.c0000644002412700241270000003136712703456111023050 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "providers/dp_ptask.h" #include "providers/ipa/ipa_sudo.h" #include "providers/ldap/sdap_sudo_shared.h" #include "db/sysdb_sudo.h" struct ipa_sudo_full_refresh_state { struct ipa_sudo_ctx *sudo_ctx; struct sss_domain_info *domain; int dp_error; }; static void ipa_sudo_full_refresh_done(struct tevent_req *subreq); struct tevent_req * ipa_sudo_full_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_sudo_ctx *sudo_ctx) { struct ipa_sudo_full_refresh_state *state; struct tevent_req *subreq; struct tevent_req *req; char *delete_filter; int ret; req = tevent_req_create(mem_ctx, &state, struct ipa_sudo_full_refresh_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->domain = sudo_ctx->id_ctx->be->domain; state->sudo_ctx = sudo_ctx; /* Remove all rules from cache */ delete_filter = talloc_asprintf(state, "(%s=%s)", SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC); if (delete_filter == NULL) { ret = ENOMEM; goto immediately; } DEBUG(SSSDBG_TRACE_FUNC, "Issuing a full refresh of sudo rules\n"); subreq = ipa_sudo_refresh_send(state, ev, sudo_ctx, NULL, NULL, delete_filter); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, ipa_sudo_full_refresh_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void ipa_sudo_full_refresh_done(struct tevent_req *subreq) { struct ipa_sudo_full_refresh_state *state; struct tevent_req *req; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_sudo_full_refresh_state); ret = ipa_sudo_refresh_recv(subreq, &state->dp_error, NULL); talloc_zfree(subreq); if (ret != EOK || state->dp_error != DP_ERR_OK) { goto done; } ret = sysdb_sudo_set_last_full_refresh(state->domain, time(NULL)); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to save time of " "a successful full refresh\n"); } DEBUG(SSSDBG_TRACE_FUNC, "Successful full refresh of sudo rules\n"); done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } int ipa_sudo_full_refresh_recv(struct tevent_req *req, int *dp_error) { struct ipa_sudo_full_refresh_state *state; state = tevent_req_data(req, struct ipa_sudo_full_refresh_state); TEVENT_REQ_RETURN_ON_ERROR(req); *dp_error = state->dp_error; return EOK; } struct ipa_sudo_smart_refresh_state { int dp_error; }; static void ipa_sudo_smart_refresh_done(struct tevent_req *subreq); static struct tevent_req * ipa_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_sudo_ctx *sudo_ctx) { struct sdap_server_opts *srv_opts = sudo_ctx->id_ctx->srv_opts; struct ipa_sudo_smart_refresh_state *state; struct tevent_req *subreq; struct tevent_req *req; char *cmdgroups_filter; char *search_filter; const char *usn; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ipa_sudo_smart_refresh_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } /* Download all rules from LDAP that are newer than usn */ if (srv_opts == NULL || srv_opts->max_sudo_value == 0) { DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero.\n"); usn = "0"; search_filter = NULL; } else { usn = srv_opts->max_sudo_value; search_filter = talloc_asprintf(state, "(%s>=%s)", sudo_ctx->sudorule_map[IPA_AT_SUDORULE_ENTRYUSN].name, usn); if (search_filter == NULL) { ret = ENOMEM; goto immediately; } } cmdgroups_filter = talloc_asprintf(state, "(%s>=%s)", sudo_ctx->sudocmdgroup_map[IPA_AT_SUDOCMDGROUP_ENTRYUSN].name, usn); if (cmdgroups_filter == NULL) { ret = ENOMEM; goto immediately; } /* Do not remove any rules that are already in the sysdb. */ DEBUG(SSSDBG_TRACE_FUNC, "Issuing a smart refresh of sudo rules " "(USN >= %s)\n", usn); subreq = ipa_sudo_refresh_send(state, ev, sudo_ctx, cmdgroups_filter, search_filter, NULL); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, ipa_sudo_smart_refresh_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void ipa_sudo_smart_refresh_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; struct ipa_sudo_smart_refresh_state *state = NULL; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_sudo_smart_refresh_state); ret = ipa_sudo_refresh_recv(subreq, &state->dp_error, NULL); talloc_zfree(subreq); if (ret != EOK || state->dp_error != DP_ERR_OK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Successful smart refresh of sudo rules\n"); done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } int ipa_sudo_smart_refresh_recv(struct tevent_req *req, int *dp_error) { struct ipa_sudo_smart_refresh_state *state = NULL; state = tevent_req_data(req, struct ipa_sudo_smart_refresh_state); TEVENT_REQ_RETURN_ON_ERROR(req); *dp_error = state->dp_error; return EOK; } struct ipa_sudo_rules_refresh_state { size_t num_rules; int dp_error; bool deleted; }; static void ipa_sudo_rules_refresh_done(struct tevent_req *subreq); struct tevent_req * ipa_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ipa_sudo_ctx *sudo_ctx, char **rules) { TALLOC_CTX *tmp_ctx; struct ipa_sudo_rules_refresh_state *state; struct tevent_req *subreq; struct tevent_req *req; char *search_filter; char *delete_filter; char *safe_rule; errno_t ret; int i; req = tevent_req_create(mem_ctx, &state, struct ipa_sudo_rules_refresh_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); ret = ENOMEM; goto immediately; } if (rules == NULL || rules[0] == NULL) { state->dp_error = DP_ERR_OK; state->num_rules = 0; state->deleted = false; ret = EOK; goto immediately; } search_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */ delete_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */ /* Download only selected rules from LDAP. */ /* Remove all selected rules from cache. */ for (i = 0; rules[i] != NULL; i++) { ret = sss_filter_sanitize(tmp_ctx, rules[i], &safe_rule); if (ret != EOK) { ret = ENOMEM; goto immediately; } search_filter = talloc_asprintf_append_buffer(search_filter, "(%s=%s)", sudo_ctx->sudorule_map[IPA_AT_SUDORULE_NAME].name, safe_rule); if (search_filter == NULL) { ret = ENOMEM; goto immediately; } delete_filter = talloc_asprintf_append_buffer(delete_filter, "(%s=%s)", SYSDB_NAME, safe_rule); if (delete_filter == NULL) { ret = ENOMEM; goto immediately; } } state->num_rules = i; search_filter = talloc_asprintf(tmp_ctx, "(|%s)", search_filter); if (search_filter == NULL) { ret = ENOMEM; goto immediately; } delete_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(|%s))", SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC, delete_filter); if (delete_filter == NULL) { ret = ENOMEM; goto immediately; } subreq = ipa_sudo_refresh_send(req, ev, sudo_ctx, NULL, search_filter, delete_filter); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, ipa_sudo_rules_refresh_done, req); ret = EOK; immediately: talloc_free(tmp_ctx); if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void ipa_sudo_rules_refresh_done(struct tevent_req *subreq) { struct ipa_sudo_rules_refresh_state *state; struct tevent_req *req = NULL; size_t downloaded_rules_num; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_sudo_rules_refresh_state); ret = ipa_sudo_refresh_recv(subreq, &state->dp_error, &downloaded_rules_num); talloc_zfree(subreq); if (ret != EOK || state->dp_error != DP_ERR_OK) { goto done; } state->deleted = downloaded_rules_num != state->num_rules ? true : false; done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } int ipa_sudo_rules_refresh_recv(struct tevent_req *req, int *dp_error, bool *deleted) { struct ipa_sudo_rules_refresh_state *state; state = tevent_req_data(req, struct ipa_sudo_rules_refresh_state); TEVENT_REQ_RETURN_ON_ERROR(req); *dp_error = state->dp_error; *deleted = state->deleted; return EOK; } static struct tevent_req * ipa_sudo_ptask_full_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct ipa_sudo_ctx *sudo_ctx; sudo_ctx = talloc_get_type(pvt, struct ipa_sudo_ctx); return ipa_sudo_full_refresh_send(mem_ctx, be_ctx->ev, sudo_ctx); } static errno_t ipa_sudo_ptask_full_refresh_recv(struct tevent_req *req) { int dp_error; return ipa_sudo_full_refresh_recv(req, &dp_error); } static struct tevent_req * ipa_sudo_ptask_smart_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct ipa_sudo_ctx *sudo_ctx; sudo_ctx = talloc_get_type(pvt, struct ipa_sudo_ctx); return ipa_sudo_smart_refresh_send(mem_ctx, be_ctx->ev, sudo_ctx); } static errno_t ipa_sudo_ptask_smart_refresh_recv(struct tevent_req *req) { int dp_error; return ipa_sudo_smart_refresh_recv(req, &dp_error); } errno_t ipa_sudo_ptask_setup(struct be_ctx *be_ctx, struct ipa_sudo_ctx *sudo_ctx) { return sdap_sudo_ptask_setup_generic(be_ctx, sudo_ctx->id_ctx->opts->basic, ipa_sudo_ptask_full_refresh_send, ipa_sudo_ptask_full_refresh_recv, ipa_sudo_ptask_smart_refresh_send, ipa_sudo_ptask_smart_refresh_recv, sudo_ctx); } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_dyndns.c0000644000000000000000000000007312703456111020175 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.729793883 sssd-1.13.4/src/providers/ipa/ipa_dyndns.c0000644002412700241270000001661612703456111021657 0ustar00jhrozekjhrozek00000000000000/* SSSD ipa_dyndns.c Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "providers/ldap/sdap_dyndns.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_dyndns.h" #include "providers/data_provider.h" #include "providers/dp_dyndns.h" void ipa_dyndns_update(void *pvt); errno_t ipa_dyndns_init(struct be_ctx *be_ctx, struct ipa_options *ctx) { errno_t ret; ctx->be_res = be_ctx->be_res; if (ctx->be_res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Resolver must be initialized in order " "to use the IPA dynamic DNS updates\n"); return EINVAL; } ret = be_nsupdate_init_timer(ctx->dyndns_ctx, be_ctx->ev, ipa_dyndns_timer, ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up periodic update\n"); return ret; } ret = be_add_online_cb(be_ctx, be_ctx, ipa_dyndns_update, ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up online callback\n"); return ret; } return EOK; } struct ipa_dyndns_timer_ctx { struct sdap_id_op *sdap_op; struct tevent_context *ev; struct ipa_options *ctx; }; static void ipa_dyndns_timer_connected(struct tevent_req *req); void ipa_dyndns_timer(void *pvt) { struct ipa_options *ctx = talloc_get_type(pvt, struct ipa_options); struct sdap_id_ctx *sdap_ctx = ctx->id_ctx->sdap_id_ctx; struct tevent_req *req; req = sdap_dyndns_timer_conn_send(ctx, sdap_ctx->be->ev, sdap_ctx, ctx->dyndns_ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); /* Not much we can do. Just attempt to reschedule */ be_nsupdate_timer_schedule(sdap_ctx->be->ev, ctx->dyndns_ctx); return; } tevent_req_set_callback(req, ipa_dyndns_timer_connected, ctx); } static void ipa_dyndns_timer_connected(struct tevent_req *req) { errno_t ret; struct ipa_options *ctx = tevent_req_callback_data(req, struct ipa_options); ret = sdap_dyndns_timer_conn_recv(req); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to IPA: [%d](%s)\n", ret, sss_strerror(ret)); return; } return ipa_dyndns_update(ctx); } static struct tevent_req *ipa_dyndns_update_send(struct ipa_options *ctx); static errno_t ipa_dyndns_update_recv(struct tevent_req *req); static void ipa_dyndns_nsupdate_done(struct tevent_req *subreq); void ipa_dyndns_update(void *pvt) { struct ipa_options *ctx = talloc_get_type(pvt, struct ipa_options); struct sdap_id_ctx *sdap_ctx = ctx->id_ctx->sdap_id_ctx; /* Schedule timer after provider went offline */ be_nsupdate_timer_schedule(sdap_ctx->be->ev, ctx->dyndns_ctx); struct tevent_req *req = ipa_dyndns_update_send(ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not update DNS\n"); return; } tevent_req_set_callback(req, ipa_dyndns_nsupdate_done, NULL); } static void ipa_dyndns_nsupdate_done(struct tevent_req *req) { int ret = ipa_dyndns_update_recv(req); talloc_free(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Updating DNS entry failed [%d]: %s\n", ret, sss_strerror(ret)); return; } DEBUG(SSSDBG_OP_FAILURE, "DNS update finished\n"); } struct ipa_dyndns_update_state { struct ipa_options *ipa_ctx; }; static void ipa_dyndns_sdap_update_done(struct tevent_req *subreq); static struct tevent_req * ipa_dyndns_update_send(struct ipa_options *ctx) { int ret; struct ipa_dyndns_update_state *state; struct tevent_req *req, *subreq; struct sdap_id_ctx *sdap_ctx = ctx->id_ctx->sdap_id_ctx; const char *servername; DEBUG(SSSDBG_TRACE_FUNC, "Performing update\n"); req = tevent_req_create(ctx, &state, struct ipa_dyndns_update_state); if (req == NULL) { return NULL; } state->ipa_ctx = ctx; if (ctx->dyndns_ctx->last_refresh + 60 > time(NULL) || ctx->dyndns_ctx->timer_in_progress) { DEBUG(SSSDBG_FUNC_DATA, "Last periodic update ran recently or timer " "in progress, not scheduling another update\n"); tevent_req_done(req); tevent_req_post(req, sdap_ctx->be->ev); return req; } state->ipa_ctx->dyndns_ctx->last_refresh = time(NULL); if (strncmp(ctx->service->sdap->uri, "ldap://", 7) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected format of LDAP URI.\n"); ret = EIO; goto done; } servername = ctx->service->sdap->uri + 7; if (servername[0] == '\0') { ret = EIO; goto done; } subreq = sdap_dyndns_update_send(state, sdap_ctx->be->ev, sdap_ctx->be, ctx->dyndns_ctx->opts, sdap_ctx, ctx->dyndns_ctx->auth_type, dp_opt_get_string(ctx->dyndns_ctx->opts, DP_OPT_DYNDNS_IFACE), dp_opt_get_string(ctx->basic, IPA_HOSTNAME), dp_opt_get_string(ctx->basic, IPA_KRB5_REALM), servername, dp_opt_get_int(ctx->dyndns_ctx->opts, DP_OPT_DYNDNS_TTL), true); if (!subreq) { ret = EIO; DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } tevent_req_set_callback(subreq, ipa_dyndns_sdap_update_done, req); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, sdap_ctx->be->ev); } return req; } static void ipa_dyndns_sdap_update_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); errno_t ret; ret = sdap_dyndns_update_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Dynamic DNS update failed [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t ipa_dyndns_update_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_init.c0000644000000000000000000000007312703456111017641 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.722793859 sssd-1.13.4/src/providers/ipa/ipa_init.c0000644002412700241270000005604712703456111021325 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Provider Initialization functions Authors: Simo Sorce Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/child_common.h" #include "providers/ipa/ipa_common.h" #include "providers/krb5/krb5_auth.h" #include "providers/krb5/krb5_init_shared.h" #include "providers/ipa/ipa_id.h" #include "providers/ipa/ipa_auth.h" #include "providers/ipa/ipa_access.h" #include "providers/ipa/ipa_hostid.h" #include "providers/ipa/ipa_dyndns.h" #include "providers/ipa/ipa_selinux.h" #include "providers/ldap/sdap_access.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ipa/ipa_subdomains.h" #include "providers/ipa/ipa_srv.h" #include "providers/dp_dyndns.h" struct ipa_options *ipa_options = NULL; /* Id Handler */ struct bet_ops ipa_id_ops = { .handler = ipa_account_info_handler, .finalize = NULL, .check_online = ipa_check_online }; struct bet_ops ipa_auth_ops = { .handler = ipa_auth, .finalize = NULL, }; struct bet_ops ipa_chpass_ops = { .handler = ipa_auth, .finalize = NULL, }; struct bet_ops ipa_access_ops = { .handler = ipa_access_handler, .finalize = NULL }; struct bet_ops ipa_selinux_ops = { .handler = ipa_selinux_handler, .finalize = NULL }; #ifdef BUILD_SSH struct bet_ops ipa_hostid_ops = { .handler = ipa_host_info_handler, .finalize = NULL }; #endif static bool srv_in_server_list(const char *servers) { TALLOC_CTX *tmp_ctx; char **list = NULL; int ret = 0; bool has_srv = false; if (servers == NULL) return true; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return false; } /* split server parm into a list */ ret = split_on_separator(tmp_ctx, servers, ',', true, true, &list, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse server list!\n"); goto done; } for (int i = 0; list[i]; i++) { has_srv = be_fo_is_srv_identifier(list[i]); if (has_srv == true) { break; } } done: talloc_free(tmp_ctx); return has_srv; } int common_ipa_init(struct be_ctx *bectx) { const char *ipa_servers; const char *ipa_backup_servers; int ret; ret = ipa_get_options(bectx, bectx->cdb, bectx->conf_path, bectx->domain, &ipa_options); if (ret != EOK) { return ret; } ipa_servers = dp_opt_get_string(ipa_options->basic, IPA_SERVER); ipa_backup_servers = dp_opt_get_string(ipa_options->basic, IPA_BACKUP_SERVER); ret = ipa_service_init(ipa_options, bectx, ipa_servers, ipa_backup_servers, ipa_options, &ipa_options->service); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init IPA failover service!\n"); return ret; } return EOK; } static struct sdap_ext_member_ctx * ipa_create_ext_members_ctx(TALLOC_CTX *mem_ctx, struct ipa_id_ctx *id_ctx) { struct sdap_ext_member_ctx *ext_ctx = NULL; ext_ctx = talloc_zero(mem_ctx, struct sdap_ext_member_ctx); if (ext_ctx == NULL) { return NULL; } ext_ctx->pvt = id_ctx; ext_ctx->ext_member_resolve_send = ipa_ext_group_member_send; ext_ctx->ext_member_resolve_recv = ipa_ext_group_member_recv; return ext_ctx; } int sssm_ipa_id_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { struct ipa_id_ctx *ipa_ctx; struct sdap_id_ctx *sdap_ctx; const char *hostname; const char *ipa_domain; const char *ipa_servers; struct ipa_srv_plugin_ctx *srv_ctx; bool server_mode; int ret; if (!ipa_options) { ret = common_ipa_init(bectx); if (ret != EOK) { return ret; } } if (ipa_options->id_ctx) { /* already initialized */ *ops = &ipa_id_ops; *pvt_data = ipa_options->id_ctx; return EOK; } ipa_ctx = talloc_zero(ipa_options, struct ipa_id_ctx); if (!ipa_ctx) { return ENOMEM; } ipa_options->id_ctx = ipa_ctx; ipa_ctx->ipa_options = ipa_options; sdap_ctx = sdap_id_ctx_new(ipa_options, bectx, ipa_options->service->sdap); if (sdap_ctx == NULL) { return ENOMEM; } ipa_ctx->sdap_id_ctx = sdap_ctx; ret = ipa_get_id_options(ipa_options, bectx->cdb, bectx->conf_path, &sdap_ctx->opts); if (ret != EOK) { goto done; } ret = ipa_get_dyndns_options(bectx, ipa_options); if (ret != EOK) { goto done; } if (dp_opt_get_bool(ipa_options->dyndns_ctx->opts, DP_OPT_DYNDNS_UPDATE)) { /* Perform automatic DNS updates when the * IP address changes. * Register a callback for successful LDAP * reconnections. This is the easiest way to * identify that we have gone online. */ DEBUG(SSSDBG_CONF_SETTINGS, "Dynamic DNS updates are on. Checking for nsupdate..\n"); ret = be_nsupdate_check(); if (ret == EOK) { /* nsupdate is available. Dynamic updates * are supported */ ret = ipa_dyndns_init(sdap_ctx->be, ipa_options); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failure setting up automatic DNS update\n"); /* We will continue without DNS updating */ } } } ret = setup_tls_config(sdap_ctx->opts->basic); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "setup_tls_config failed [%d][%s].\n", ret, strerror(ret)); goto done; } /* Set up the ID mapping object */ ret = ipa_idmap_init(sdap_ctx, sdap_ctx, &sdap_ctx->opts->idmap_ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize ID mapping. In case ID mapping properties " "changed on the server, please remove the SSSD database\n"); goto done; } ret = ldap_id_setup_tasks(sdap_ctx); if (ret != EOK) { goto done; } ret = sdap_setup_child(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "setup_child failed [%d][%s].\n", ret, strerror(ret)); goto done; } /* setup SRV lookup plugin */ hostname = dp_opt_get_string(ipa_options->basic, IPA_HOSTNAME); server_mode = dp_opt_get_bool(ipa_options->basic, IPA_SERVER_MODE); if (server_mode == true) { ipa_ctx->view_name = talloc_strdup(ipa_ctx, SYSDB_DEFAULT_VIEW_NAME); if (ipa_ctx->view_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_update_view_name(bectx->domain->sysdb, ipa_ctx->view_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add/update view name to sysdb.\n"); goto done; } ipa_servers = dp_opt_get_string(ipa_options->basic, IPA_SERVER); if (srv_in_server_list(ipa_servers) == true || dp_opt_get_bool(ipa_options->basic, IPA_ENABLE_DNS_SITES) == true) { DEBUG(SSSDBG_MINOR_FAILURE, "SRV resolution or IPA sites enabled " "on the IPA server. Site discovery of trusted AD servers " "might not work\n"); /* If SRV discovery is enabled on the server and * dns_discovery_domain is set explicitly, then * the current failover code would use the dns_discovery * domain to try to find AD servers and fail */ if (dp_opt_get_string(bectx->be_res->opts, DP_RES_OPT_DNS_DOMAIN)) { sss_log(SSS_LOG_ERR, ("SRV discovery is enabled on the IPA " "server while using custom dns_discovery_domain. " "DNS discovery of trusted AD domain will likely fail. " "It is recommended not to use SRV discovery or the " "dns_discovery_domain option for the IPA domain while " "running on the server itself\n")); DEBUG(SSSDBG_CRIT_FAILURE, "SRV discovery is enabled on IPA " "server while using custom dns_discovery_domain. " "DNS discovery of trusted AD domain will likely fail. " "It is recommended not to use SRV discovery or the " "dns_discovery_domain option for the IPA domain while " "running on the server itself\n"); } ret = be_fo_set_dns_srv_lookup_plugin(bectx, hostname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin " "[%d]: %s\n", ret, strerror(ret)); goto done; } } else { /* In server mode we need to ignore the dns_discovery_domain if set * and only discover servers based on AD domains */ ret = dp_opt_set_string(bectx->be_res->opts, DP_RES_OPT_DNS_DOMAIN, NULL); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not reset the " "dns_discovery_domain, trusted AD domains discovery " "might fail. Please remove dns_discovery_domain " "from the config file and restart the SSSD\n"); } else { DEBUG(SSSDBG_CONF_SETTINGS, "The value of dns_discovery_domain " "will be ignored in ipa_server_mode\n"); } } } else { ret = sysdb_get_view_name(ipa_ctx, bectx->domain->sysdb, &ipa_ctx->view_name); if (ret != EOK) { if (ret == ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find view name in the cache. " \ "Will do online lookup later.\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_view_name failed.\n"); goto done; } } if (dp_opt_get_bool(ipa_options->basic, IPA_ENABLE_DNS_SITES)) { /* use IPA plugin */ ipa_domain = dp_opt_get_string(ipa_options->basic, IPA_DOMAIN); srv_ctx = ipa_srv_plugin_ctx_init(bectx, bectx->be_res->resolv, hostname, ipa_domain); if (srv_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n"); ret = ENOMEM; goto done; } be_fo_set_srv_lookup_plugin(bectx, ipa_srv_plugin_send, ipa_srv_plugin_recv, srv_ctx, "IPA"); } else { /* fall back to standard plugin on clients. */ ret = be_fo_set_dns_srv_lookup_plugin(bectx, hostname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin " "[%d]: %s\n", ret, strerror(ret)); goto done; } } } /* setup periodical refresh of expired records */ ret = sdap_refresh_init(bectx->refresh_ctx, sdap_ctx); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh " "will not work [%d]: %s\n", ret, strerror(ret)); } ipa_ctx->sdap_id_ctx->opts->ext_ctx = ipa_create_ext_members_ctx( ipa_ctx->sdap_id_ctx->opts, ipa_ctx); if (ipa_ctx->sdap_id_ctx->opts->ext_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV the extrernal group ctx\n"); ret = ENOMEM; goto done; } *ops = &ipa_id_ops; *pvt_data = ipa_ctx; ret = EOK; done: if (ret != EOK) { talloc_zfree(ipa_options->id_ctx); } return ret; } void cleanup_ipa_preauth_indicator(void) { int ret; ret = unlink(PAM_PREAUTH_INDICATOR); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to remove preauth indicator file [%s].\n", PAM_PREAUTH_INDICATOR); } } static errno_t create_ipa_preauth_indicator(void) { int ret; TALLOC_CTX *tmp_ctx = NULL; int fd; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } fd = open(PAM_PREAUTH_INDICATOR, O_CREAT | O_EXCL | O_WRONLY | O_NOFOLLOW, 0644); if (fd < 0) { if (errno != EEXIST) { DEBUG(SSSDBG_OP_FAILURE, "Failed to create preauth indicator file [%s].\n", PAM_PREAUTH_INDICATOR); ret = EOK; goto done; } DEBUG(SSSDBG_CRIT_FAILURE, "Preauth indicator file [%s] already exists. " "Maybe it is left after an unplanned exit. Continuing.\n", PAM_PREAUTH_INDICATOR); } else { close(fd); } ret = atexit(cleanup_ipa_preauth_indicator); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "atexit failed. Continuing.\n"); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } int sssm_ipa_auth_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { struct ipa_auth_ctx *ipa_auth_ctx; struct ipa_id_ctx *id_ctx; struct krb5_ctx *krb5_auth_ctx; struct sdap_auth_ctx *sdap_auth_ctx; struct bet_ops *id_ops; int ret; if (!ipa_options) { ret = common_ipa_init(bectx); if (ret != EOK) { return ret; } } if (ipa_options->auth_ctx) { /* already initialized */ *ops = &ipa_auth_ops; *pvt_data = ipa_options->auth_ctx; return EOK; } ipa_auth_ctx = talloc_zero(ipa_options, struct ipa_auth_ctx); if (!ipa_auth_ctx) { return ENOMEM; } ipa_options->auth_ctx = ipa_auth_ctx; ret = sssm_ipa_id_init(bectx, &id_ops, (void **) &id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ipa_id_init failed.\n"); goto done; } ipa_auth_ctx->sdap_id_ctx = id_ctx->sdap_id_ctx; ret = dp_copy_options(ipa_auth_ctx, ipa_options->basic, IPA_OPTS_BASIC, &ipa_auth_ctx->ipa_options); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "dp_copy_options failed.\n"); goto done; } krb5_auth_ctx = talloc_zero(ipa_auth_ctx, struct krb5_ctx); if (!krb5_auth_ctx) { ret = ENOMEM; goto done; } krb5_auth_ctx->service = ipa_options->service->krb5_service; if (dp_opt_get_bool(id_ctx->ipa_options->basic, IPA_SERVER_MODE) == true) { krb5_auth_ctx->config_type = K5C_IPA_SERVER; } else { krb5_auth_ctx->config_type = K5C_IPA_CLIENT; } ipa_options->auth_ctx->krb5_auth_ctx = krb5_auth_ctx; ret = ipa_get_auth_options(ipa_options, bectx->cdb, bectx->conf_path, &krb5_auth_ctx->opts); if (ret != EOK) { goto done; } sdap_auth_ctx = talloc_zero(ipa_auth_ctx, struct sdap_auth_ctx); if (!sdap_auth_ctx) { ret = ENOMEM; goto done; } sdap_auth_ctx->be = bectx; sdap_auth_ctx->service = ipa_options->service->sdap; if (ipa_options->id == NULL) { ret = EINVAL; goto done; } sdap_auth_ctx->opts = ipa_options->id; ipa_options->auth_ctx->sdap_auth_ctx = sdap_auth_ctx; ret = setup_tls_config(sdap_auth_ctx->opts->basic); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "setup_tls_config failed [%d][%s].\n", ret, strerror(ret)); goto done; } /* Initialize features needed by the krb5_child */ ret = krb5_child_init(krb5_auth_ctx, bectx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize krb5_child settings: [%s]\n", strerror(ret)); goto done; } ret = create_ipa_preauth_indicator(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create preauth indicator file, special password " "prompting might not be available.\n"); sss_log(SSSDBG_CRIT_FAILURE, "Failed to create preauth indicator file, special password " "prompting might not be available.\n"); } *ops = &ipa_auth_ops; *pvt_data = ipa_auth_ctx; ret = EOK; done: if (ret != EOK) { talloc_zfree(ipa_options->auth_ctx); } return ret; } int sssm_ipa_chpass_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret; ret = sssm_ipa_auth_init(bectx, ops, pvt_data); *ops = &ipa_chpass_ops; return ret; } int sssm_ipa_access_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret; struct ipa_access_ctx *ipa_access_ctx; struct ipa_id_ctx *id_ctx; ipa_access_ctx = talloc_zero(bectx, struct ipa_access_ctx); if (ipa_access_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ret = sssm_ipa_id_init(bectx, ops, (void **) &id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ipa_id_init failed.\n"); goto done; } ipa_access_ctx->sdap_ctx = id_ctx->sdap_id_ctx; ipa_access_ctx->host_map = id_ctx->ipa_options->host_map; ipa_access_ctx->hostgroup_map = id_ctx->ipa_options->hostgroup_map; ipa_access_ctx->host_search_bases = id_ctx->ipa_options->host_search_bases; ipa_access_ctx->hbac_search_bases = id_ctx->ipa_options->hbac_search_bases; ret = dp_copy_options(ipa_access_ctx, ipa_options->basic, IPA_OPTS_BASIC, &ipa_access_ctx->ipa_options); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "dp_copy_options failed.\n"); goto done; } /* Set up an sdap_access_ctx for checking expired/locked * accounts. */ ipa_access_ctx->sdap_access_ctx = talloc_zero(ipa_access_ctx, struct sdap_access_ctx); ipa_access_ctx->sdap_access_ctx->id_ctx = ipa_access_ctx->sdap_ctx; ipa_access_ctx->sdap_access_ctx->access_rule[0] = LDAP_ACCESS_EXPIRE; ipa_access_ctx->sdap_access_ctx->access_rule[1] = LDAP_ACCESS_EMPTY; *ops = &ipa_access_ops; *pvt_data = ipa_access_ctx; done: if (ret != EOK) { talloc_free(ipa_access_ctx); } return ret; } int sssm_ipa_selinux_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret; struct ipa_selinux_ctx *selinux_ctx; struct ipa_options *opts; selinux_ctx = talloc_zero(bectx, struct ipa_selinux_ctx); if (selinux_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ret = sssm_ipa_id_init(bectx, ops, (void **) &selinux_ctx->id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ipa_id_init failed.\n"); goto done; } opts = selinux_ctx->id_ctx->ipa_options; selinux_ctx->hbac_search_bases = opts->hbac_search_bases; selinux_ctx->host_search_bases = opts->host_search_bases; selinux_ctx->selinux_search_bases = opts->selinux_search_bases; *ops = &ipa_selinux_ops; *pvt_data = selinux_ctx; done: if (ret != EOK) { talloc_free(selinux_ctx); } return ret; } #ifdef BUILD_SSH int sssm_ipa_hostid_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret; struct ipa_hostid_ctx *hostid_ctx; struct ipa_id_ctx *id_ctx; hostid_ctx = talloc_zero(bectx, struct ipa_hostid_ctx); if (hostid_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ret = sssm_ipa_id_init(bectx, ops, (void **) &id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ipa_id_init failed.\n"); goto done; } hostid_ctx->sdap_id_ctx = id_ctx->sdap_id_ctx; hostid_ctx->host_search_bases = id_ctx->ipa_options->host_search_bases; hostid_ctx->ipa_opts = ipa_options; *ops = &ipa_hostid_ops; *pvt_data = hostid_ctx; done: if (ret != EOK) { talloc_free(hostid_ctx); } return ret; } #endif int sssm_ipa_autofs_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { #ifdef BUILD_AUTOFS struct ipa_id_ctx *id_ctx; int ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing IPA autofs handler\n"); ret = sssm_ipa_id_init(bectx, ops, (void **) &id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ipa_id_init failed.\n"); return ret; } return ipa_autofs_init(bectx, id_ctx, ops, pvt_data); #else DEBUG(SSSDBG_MINOR_FAILURE, "Autofs init handler called but SSSD is " "built without autofs support, ignoring\n"); return EOK; #endif } int sssm_ipa_subdomains_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret; struct ipa_id_ctx *id_ctx; ret = sssm_ipa_id_init(bectx, ops, (void **) &id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ipa_id_init failed.\n"); return ret; } ret = ipa_subdom_init(bectx, id_ctx, ops, pvt_data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "ipa_subdom_init failed.\n"); return ret; } return EOK; } int sssm_ipa_sudo_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { #ifdef BUILD_SUDO struct ipa_id_ctx *id_ctx; int ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing IPA sudo handler\n"); ret = sssm_ipa_id_init(bectx, ops, (void **) &id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ipa_id_init failed.\n"); return ret; } return ipa_sudo_init(bectx, id_ctx, ops, pvt_data); #else DEBUG(SSSDBG_MINOR_FAILURE, "Sudo init handler called but SSSD is " "built without sudo support, ignoring\n"); return EOK; #endif } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_sudo.c0000644000000000000000000000007412703456111017651 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.751793958 sssd-1.13.4/src/providers/ipa/ipa_sudo.c0000644002412700241270000002035712703456111021327 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ipa/ipa_opts.h" #include "providers/ipa/ipa_common.h" #include "providers/ldap/sdap_sudo.h" #include "providers/ipa/ipa_sudo.h" #include "db/sysdb_sudo.h" static void ipa_sudo_handler(struct be_req *breq); struct bet_ops ipa_sudo_ops = { .handler = ipa_sudo_handler, .finalize = NULL, }; enum sudo_schema { SUDO_SCHEMA_IPA, SUDO_SCHEMA_LDAP }; static errno_t ipa_sudo_choose_schema(struct dp_option *ipa_opts, struct dp_option *sdap_opts, enum sudo_schema *_schema) { TALLOC_CTX *tmp_ctx; char *ipa_search_base; char *search_base; char *basedn; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } ret = domain_to_basedn(tmp_ctx, dp_opt_get_string(ipa_opts, IPA_KRB5_REALM), &basedn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain basedn\n"); goto done; } ipa_search_base = talloc_asprintf(tmp_ctx, "cn=sudo,%s", basedn); if (ipa_search_base == NULL) { ret = ENOMEM; goto done; } search_base = dp_opt_get_string(sdap_opts, SDAP_SUDO_SEARCH_BASE); if (search_base == NULL) { ret = dp_opt_set_string(sdap_opts, SDAP_SUDO_SEARCH_BASE, ipa_search_base); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", sdap_opts[SDAP_SUDO_SEARCH_BASE].opt_name, ipa_search_base); search_base = ipa_search_base; } /* Use IPA schema only if search base is cn=sudo,$dc. */ if (strcmp(ipa_search_base, search_base) == 0) { *_schema = SUDO_SCHEMA_IPA; } else { *_schema = SUDO_SCHEMA_LDAP; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static int ipa_sudo_init_ipa_schema(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data) { struct ipa_sudo_ctx *sudo_ctx; errno_t ret; sudo_ctx = talloc_zero(be_ctx, struct ipa_sudo_ctx); if (sudo_ctx == NULL) { return ENOMEM; } sudo_ctx->id_ctx = id_ctx->sdap_id_ctx; sudo_ctx->ipa_opts = id_ctx->ipa_options; sudo_ctx->sdap_opts = id_ctx->sdap_id_ctx->opts; ret = sdap_get_map(sudo_ctx, be_ctx->cdb, be_ctx->conf_path, ipa_sudorule_map, IPA_OPTS_SUDORULE, &sudo_ctx->sudorule_map); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse attribute map " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sdap_get_map(sudo_ctx, be_ctx->cdb, be_ctx->conf_path, ipa_sudocmdgroup_map, IPA_OPTS_SUDOCMDGROUP, &sudo_ctx->sudocmdgroup_map); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse attribute map " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sdap_get_map(sudo_ctx, be_ctx->cdb, be_ctx->conf_path, ipa_sudocmd_map, IPA_OPTS_SUDOCMD, &sudo_ctx->sudocmd_map); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse attribute map " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sdap_parse_search_base(sudo_ctx, sudo_ctx->sdap_opts->basic, SDAP_SUDO_SEARCH_BASE, &sudo_ctx->sudo_sb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not parse sudo search base\n"); return ret; } ret = ipa_sudo_ptask_setup(be_ctx, sudo_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup periodic tasks " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } *ops = &ipa_sudo_ops; *pvt_data = sudo_ctx; ret = EOK; done: if (ret != EOK) { talloc_free(sudo_ctx); } return ret; } int ipa_sudo_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data) { enum sudo_schema schema; errno_t ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing IPA sudo back end\n"); ret = ipa_sudo_choose_schema(id_ctx->ipa_options->basic, id_ctx->ipa_options->id->basic, &schema); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to choose sudo schema [%d]: %s\n", ret, sss_strerror(ret)); return ret; } switch (schema) { case SUDO_SCHEMA_IPA: DEBUG(SSSDBG_TRACE_FUNC, "Using IPA schema for sudo\n"); ret = ipa_sudo_init_ipa_schema(be_ctx, id_ctx, ops, pvt_data); break; case SUDO_SCHEMA_LDAP: DEBUG(SSSDBG_TRACE_FUNC, "Using LDAP schema for sudo\n"); ret = sdap_sudo_init(be_ctx, id_ctx->sdap_id_ctx, ops, pvt_data); break; } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize sudo provider" "[%d]: %s\n", ret, sss_strerror(ret)); return ret; } return EOK; } static void ipa_sudo_reply(struct tevent_req *req) { struct be_sudo_req *sudo_req; struct be_req *be_req; bool deleted; int dp_error; int ret; be_req = tevent_req_callback_data(req, struct be_req); sudo_req = talloc_get_type(be_req_get_data(be_req), struct be_sudo_req); switch (sudo_req->type) { case BE_REQ_SUDO_FULL: ret = ipa_sudo_full_refresh_recv(req, &dp_error); break; case BE_REQ_SUDO_RULES: ret = ipa_sudo_rules_refresh_recv(req, &dp_error, &deleted); if (ret == EOK && deleted == true) { ret = ENOENT; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n", sudo_req->type); dp_error = DP_ERR_FATAL; ret = ERR_INTERNAL; break; } talloc_zfree(req); sdap_handler_done(be_req, dp_error, ret, sss_strerror(ret)); } static void ipa_sudo_handler(struct be_req *be_req) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct ipa_sudo_ctx *sudo_ctx; struct be_sudo_req *sudo_req; struct tevent_req *req; int ret; if (be_is_offline(be_ctx)) { sdap_handler_done(be_req, DP_ERR_OFFLINE, EAGAIN, "Offline"); return; } sudo_ctx = talloc_get_type(be_ctx->bet_info[BET_SUDO].pvt_bet_data, struct ipa_sudo_ctx); sudo_req = talloc_get_type(be_req_get_data(be_req), struct be_sudo_req); switch (sudo_req->type) { case BE_REQ_SUDO_FULL: req = ipa_sudo_full_refresh_send(be_req, be_ctx->ev, sudo_ctx); break; case BE_REQ_SUDO_RULES: req = ipa_sudo_rules_refresh_send(be_req, be_ctx->ev, sudo_ctx, sudo_req->rules); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n", sudo_req->type); ret = EINVAL; goto fail; } if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send request: %d\n", sudo_req->type); ret = ENOMEM; goto fail; } tevent_req_set_callback(req, ipa_sudo_reply, be_req); return; fail: sdap_handler_done(be_req, DP_ERR_FATAL, ret, NULL); } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_selinux.c0000644000000000000000000000007412703456111020366 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.746793941 sssd-1.13.4/src/providers/ipa/ipa_selinux.c0000644002412700241270000015142512703456111022045 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- selinux loading Authors: Jan Zeleny Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "db/sysdb_selinux.h" #include "util/child_common.h" #include "util/sss_selinux.h" #include "providers/ldap/sdap_async.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_config.h" #include "providers/ipa/ipa_selinux.h" #include "providers/ipa/ipa_hosts.h" #include "providers/ipa/ipa_hbac_rules.h" #include "providers/ipa/ipa_hbac_private.h" #include "providers/ipa/ipa_access.h" #include "providers/ipa/ipa_selinux_maps.h" #include "providers/ipa/ipa_subdomains.h" #if defined HAVE_SELINUX && defined HAVE_SELINUX_LOGIN_DIR #ifndef SELINUX_CHILD_DIR #ifndef SSSD_LIBEXEC_PATH #error "SSSD_LIBEXEC_PATH not defined" #endif /* SSSD_LIBEXEC_PATH */ #define SELINUX_CHILD_DIR SSSD_LIBEXEC_PATH #endif /* SELINUX_CHILD_DIR */ #define SELINUX_CHILD SELINUX_CHILD_DIR"/selinux_child" #define SELINUX_CHILD_LOG_FILE "selinux_child" #include /* fd used by the selinux_child process for logging */ int selinux_child_debug_fd = -1; static struct tevent_req * ipa_get_selinux_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct sysdb_attrs *user, struct sysdb_attrs *host, struct ipa_selinux_ctx *selinux_ctx); static errno_t ipa_get_selinux_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *count, struct sysdb_attrs ***maps, size_t *hbac_count, struct sysdb_attrs ***hbac_rules, char **default_user, char **map_order); static struct ipa_selinux_op_ctx * ipa_selinux_create_op_ctx(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *ipa_domain, struct sss_domain_info *user_domain, struct be_req *be_req, const char *username, const char *hostname, struct ipa_selinux_ctx *selinux_ctx); static void ipa_selinux_handler_done(struct tevent_req *subreq); static void ipa_get_selinux_connect_done(struct tevent_req *subreq); static void ipa_get_selinux_hosts_done(struct tevent_req *subreq); static void ipa_get_config_step(struct tevent_req *req); static void ipa_get_selinux_config_done(struct tevent_req *subreq); static void ipa_get_selinux_maps_done(struct tevent_req *subreq); static void ipa_get_selinux_hbac_done(struct tevent_req *subreq); static errno_t ipa_selinux_process_maps(TALLOC_CTX *mem_ctx, struct sysdb_attrs *user, struct sysdb_attrs *host, struct sysdb_attrs **selinux_maps, size_t selinux_map_count, struct sysdb_attrs **hbac_rules, size_t hbac_rule_count, struct sysdb_attrs ***usermaps); struct ipa_selinux_op_ctx { struct be_req *be_req; struct sss_domain_info *user_domain; struct sss_domain_info *ipa_domain; struct ipa_selinux_ctx *selinux_ctx; struct sysdb_attrs *user; struct sysdb_attrs *host; }; void ipa_selinux_handler(struct be_req *be_req) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct ipa_selinux_ctx *selinux_ctx; struct ipa_selinux_op_ctx *op_ctx; struct tevent_req *req; struct pam_data *pd; const char *hostname; struct sss_domain_info *user_domain; struct be_ctx *subdom_be_ctx; pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); selinux_ctx = talloc_get_type(be_ctx->bet_info[BET_SELINUX].pvt_bet_data, struct ipa_selinux_ctx); hostname = dp_opt_get_string(selinux_ctx->id_ctx->ipa_options->basic, IPA_HOSTNAME); if (!hostname) { DEBUG(SSSDBG_OP_FAILURE, "Cannot determine this machine's host name\n"); goto fail; } if (strcasecmp(pd->domain, be_ctx->domain->name) != 0) { subdom_be_ctx = ipa_get_subdomains_be_ctx(be_ctx); if (subdom_be_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Subdomains are not configured, " \ "cannot lookup domain [%s].\n", pd->domain); goto fail; } else { user_domain = find_domain_by_name(subdom_be_ctx->domain, pd->domain, true); if (user_domain == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "No domain entry found " \ "for [%s].\n", pd->domain); goto fail; } } } else { user_domain = be_ctx->domain; } op_ctx = ipa_selinux_create_op_ctx(be_req, user_domain->sysdb, be_ctx->domain, user_domain, be_req, pd->user, hostname, selinux_ctx); if (op_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot create op context\n"); goto fail; } req = ipa_get_selinux_send(be_req, be_ctx, op_ctx->user, op_ctx->host, selinux_ctx); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot initiate the search\n"); goto fail; } tevent_req_set_callback(req, ipa_selinux_handler_done, op_ctx); return; fail: be_req_terminate(be_req, DP_ERR_FATAL, PAM_SYSTEM_ERR, NULL); } static errno_t ipa_save_user_maps(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, size_t map_count, struct sysdb_attrs **maps) { errno_t ret; errno_t sret; bool in_transaction = false; int i; ret = sysdb_transaction_start(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; for (i = 0; i < map_count; i++) { ret = sysdb_store_selinux_usermap(domain, maps[i]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store user map %d. " "Ignoring.\n", i); } else { DEBUG(SSSDBG_TRACE_FUNC, "User map %d processed.\n", i); } } ret = sysdb_transaction_commit(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction!\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } return ret; } static struct ipa_selinux_op_ctx * ipa_selinux_create_op_ctx(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *ipa_domain, struct sss_domain_info *user_domain, struct be_req *be_req, const char *username, const char *hostname, struct ipa_selinux_ctx *selinux_ctx) { struct ipa_selinux_op_ctx *op_ctx; struct ldb_dn *host_dn; const char *attrs[] = { SYSDB_ORIG_DN, SYSDB_ORIG_MEMBEROF, NULL }; size_t count; struct ldb_message **msgs; struct sysdb_attrs **hosts; errno_t ret; op_ctx = talloc_zero(mem_ctx, struct ipa_selinux_op_ctx); if (op_ctx == NULL) { return NULL; } op_ctx->be_req = be_req; op_ctx->ipa_domain = ipa_domain; op_ctx->user_domain = user_domain; op_ctx->selinux_ctx = selinux_ctx; ret = sss_selinux_extract_user(op_ctx, user_domain, username, &op_ctx->user); if (ret != EOK) { goto fail; } host_dn = sysdb_custom_dn(op_ctx, ipa_domain, hostname, HBAC_HOSTS_SUBDIR); if (host_dn == NULL) { goto fail; } /* Look up the host to get its originalMemberOf entries */ ret = sysdb_search_entry(op_ctx, sysdb, host_dn, LDB_SCOPE_BASE, NULL, attrs, &count, &msgs); if (ret == ENOENT || count == 0) { op_ctx->host = NULL; return op_ctx; } else if (ret != EOK) { goto fail; } else if (count > 1) { DEBUG(SSSDBG_OP_FAILURE, "More than one result for a BASE search!\n"); goto fail; } ret = sysdb_msg2attrs(op_ctx, count, msgs, &hosts); talloc_free(msgs); if (ret != EOK) { goto fail; } op_ctx->host = hosts[0]; return op_ctx; fail: talloc_free(op_ctx); return NULL; } struct map_order_ctx { char *order; char **order_array; size_t order_count; }; static errno_t init_map_order_ctx(TALLOC_CTX *mem_ctx, const char *map_order, struct map_order_ctx **_mo_ctx); struct selinux_child_input { const char *seuser; const char *mls_range; const char *username; }; static errno_t choose_best_seuser(TALLOC_CTX *mem_ctx, struct sysdb_attrs **usermaps, struct pam_data *pd, struct sss_domain_info *user_domain, struct map_order_ctx *mo_ctx, const char *default_user, struct selinux_child_input **_sci); static struct tevent_req *selinux_child_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct selinux_child_input *sci); static errno_t selinux_child_recv(struct tevent_req *req); static void ipa_selinux_child_done(struct tevent_req *child_req); static void ipa_selinux_handler_done(struct tevent_req *req) { struct ipa_selinux_op_ctx *op_ctx = tevent_req_callback_data(req, struct ipa_selinux_op_ctx); struct be_req *breq = op_ctx->be_req; struct be_ctx *be_ctx = be_req_get_be_ctx(breq); struct sysdb_ctx *sysdb = op_ctx->ipa_domain->sysdb; errno_t ret, sret; size_t map_count = 0; struct sysdb_attrs **maps = NULL; bool in_transaction = false; char *default_user = NULL; struct pam_data *pd = talloc_get_type(be_req_get_data(breq), struct pam_data); char *map_order = NULL; size_t hbac_count = 0; struct sysdb_attrs **hbac_rules = 0; struct sysdb_attrs **best_match_maps; struct map_order_ctx *map_order_ctx; struct selinux_child_input *sci = NULL; struct tevent_req *child_req; ret = ipa_get_selinux_recv(req, breq, &map_count, &maps, &hbac_count, &hbac_rules, &default_user, &map_order); if (ret != EOK) { goto fail; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto fail; } in_transaction = true; ret = sysdb_delete_usermaps(op_ctx->ipa_domain); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot delete existing maps from sysdb\n"); goto fail; } ret = sysdb_store_selinux_config(op_ctx->ipa_domain, default_user, map_order); if (ret != EOK) { goto fail; } if (map_count > 0) { ret = ipa_save_user_maps(sysdb, op_ctx->ipa_domain, map_count, maps); if (ret != EOK) { goto fail; } } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not commit transaction\n"); goto fail; } in_transaction = false; /* Process the maps and return list of best matches (maps with * highest priority). The input maps are also parent memory * context for the output list of best matches. The best match * maps should never be freed explicitly but always through * their parent (or any indirect parent) */ ret = ipa_selinux_process_maps(maps, op_ctx->user, op_ctx->host, maps, map_count, hbac_rules, hbac_count, &best_match_maps); if (ret != EOK) { goto fail; } ret = init_map_order_ctx(op_ctx, map_order, &map_order_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create ordered SELinux users array.\n"); goto fail; } ret = choose_best_seuser(breq, best_match_maps, pd, op_ctx->user_domain, map_order_ctx, default_user, &sci); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to evaluate ordered SELinux users array.\n"); goto fail; } /* Update the SELinux context in a privileged child as the back end is * running unprivileged */ child_req = selinux_child_send(breq, be_ctx->ev, sci); if (child_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "selinux_child_send() failed\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(child_req, ipa_selinux_child_done, op_ctx); return; fail: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not cancel transaction\n"); } } if (ret == EAGAIN) { be_req_terminate(breq, DP_ERR_OFFLINE, EAGAIN, "Offline"); } else { be_req_terminate(breq, DP_ERR_FATAL, ret, NULL); } } static void ipa_selinux_child_done(struct tevent_req *child_req) { errno_t ret; struct ipa_selinux_op_ctx *op_ctx; struct be_req *breq; struct pam_data *pd; struct be_ctx *be_ctx; op_ctx = tevent_req_callback_data(child_req, struct ipa_selinux_op_ctx); breq = op_ctx->be_req; pd = talloc_get_type(be_req_get_data(breq), struct pam_data); be_ctx = be_req_get_be_ctx(breq); ret = selinux_child_recv(child_req); talloc_free(child_req); if (ret != EOK) { be_req_terminate(breq, DP_ERR_FATAL, ret, NULL); return; } /* If we got here in online mode, set last_update to current time */ if (!be_is_offline(be_ctx)) { op_ctx->selinux_ctx->last_update = time(NULL); } pd->pam_status = PAM_SUCCESS; be_req_terminate(breq, DP_ERR_OK, EOK, "Success"); } static errno_t ipa_selinux_process_seealso_maps(struct sysdb_attrs *user, struct sysdb_attrs *host, struct sysdb_attrs **seealso_rules, size_t seealso_rules_count, struct sysdb_attrs **hbac_rules, size_t hbac_rule_count, uint32_t top_priority, struct sysdb_attrs **usermaps, size_t best_match_maps_cnt); static errno_t ipa_selinux_process_maps(TALLOC_CTX *mem_ctx, struct sysdb_attrs *user, struct sysdb_attrs *host, struct sysdb_attrs **selinux_maps, size_t selinux_map_count, struct sysdb_attrs **hbac_rules, size_t hbac_rule_count, struct sysdb_attrs ***_usermaps) { TALLOC_CTX *tmp_ctx; int i; errno_t ret; uint32_t priority = 0; uint32_t top_priority = 0; struct sysdb_attrs **seealso_rules; size_t num_seealso_rules = 0; const char *seealso_str; struct sysdb_attrs **usermaps; size_t best_match_maps_cnt = 0; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } seealso_rules = talloc_zero_array(tmp_ctx, struct sysdb_attrs *, selinux_map_count + 1); if (seealso_rules == NULL) { ret = ENOMEM; goto done; } usermaps = talloc_zero_array(tmp_ctx, struct sysdb_attrs *, selinux_map_count + 1); if (usermaps == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < selinux_map_count; i++) { if (sss_selinux_match(selinux_maps[i], user, host, &priority)) { if (priority < top_priority) { /* This rule has lower priority than what we already have, * skip it. */ continue; } else if (priority > top_priority) { /* This rule has higher priority, drop what we already have */ while (best_match_maps_cnt > 0) { best_match_maps_cnt--; usermaps[best_match_maps_cnt] = NULL; } top_priority = priority; } usermaps[best_match_maps_cnt] = selinux_maps[i]; best_match_maps_cnt++; continue; } /* SELinux map did not matched -> check sealso attribute for * possible HBAC match */ ret = sysdb_attrs_get_string(selinux_maps[i], SYSDB_SELINUX_SEEALSO, &seealso_str); if (ret == ENOENT) { continue; } else if (ret != EOK) { goto done; } seealso_rules[num_seealso_rules] = selinux_maps[i]; num_seealso_rules++; } ret = ipa_selinux_process_seealso_maps(user, host, seealso_rules, num_seealso_rules, hbac_rules, hbac_rule_count, top_priority, usermaps, best_match_maps_cnt); if (ret != EOK) { goto done; } *_usermaps = talloc_steal(mem_ctx, usermaps); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t ipa_selinux_process_seealso_maps(struct sysdb_attrs *user, struct sysdb_attrs *host, struct sysdb_attrs **seealso_rules, size_t seealso_rules_count, struct sysdb_attrs **hbac_rules, size_t hbac_rule_count, uint32_t top_priority, struct sysdb_attrs **usermaps, size_t best_match_maps_cnt) { int i, j; errno_t ret; struct ldb_message_element *el; struct sysdb_attrs *usermap; const char *seealso_dn; const char *hbac_dn; uint32_t priority; for (i = 0; i < hbac_rule_count; i++) { ret = sysdb_attrs_get_string(hbac_rules[i], SYSDB_ORIG_DN, &hbac_dn); if (ret != EOK) { return ret; } /* We need to do this translation for further processing. We have to * do it manually because no map was used to retrieve HBAC rules. */ ret = sysdb_attrs_get_el(hbac_rules[i], IPA_MEMBER_HOST, &el); if (ret != EOK) return ret; el->name = SYSDB_ORIG_MEMBER_HOST; ret = sysdb_attrs_get_el(hbac_rules[i], IPA_MEMBER_USER, &el); if (ret != EOK) return ret; el->name = SYSDB_ORIG_MEMBER_USER; DEBUG(SSSDBG_TRACE_ALL, "Matching HBAC rule %s with SELinux mappings\n", hbac_dn); if (!sss_selinux_match(hbac_rules[i], user, host, &priority)) { DEBUG(SSSDBG_TRACE_ALL, "Rule did not match\n"); continue; } /* HBAC rule matched, find if it is in the "possible" list */ for (j = 0; j < seealso_rules_count; j++) { usermap = seealso_rules[j]; if (usermap == NULL) { continue; } ret = sysdb_attrs_get_string(usermap, SYSDB_SELINUX_SEEALSO, &seealso_dn); if (ret != EOK) { return ret; } if (strcasecmp(hbac_dn, seealso_dn) == 0) { DEBUG(SSSDBG_TRACE_FUNC, "HBAC rule [%s] matched, copying its" "attributes to SELinux user map [%s]\n", hbac_dn, seealso_dn); /* Selinux maps priority evaluation removed --DELETE this comment before pushing*/ if (priority < top_priority) { /* This rule has lower priority than what we already have, * skip it. */ continue; } else if (priority > top_priority) { /* This rule has higher priority, drop what we already have */ while (best_match_maps_cnt > 0) { best_match_maps_cnt--; usermaps[best_match_maps_cnt] = NULL; } top_priority = priority; } usermaps[best_match_maps_cnt] = usermap; best_match_maps_cnt++; ret = sysdb_attrs_copy_values(hbac_rules[i], usermap, SYSDB_ORIG_MEMBER_USER); if (ret != EOK) { return ret; } ret = sysdb_attrs_copy_values(hbac_rules[i], usermap, SYSDB_USER_CATEGORY); if (ret != EOK) { return ret; } /* Speed up the next iteration */ seealso_rules[j] = NULL; } } } return EOK; } static errno_t init_map_order_ctx(TALLOC_CTX *mem_ctx, const char *map_order, struct map_order_ctx **_mo_ctx) { TALLOC_CTX *tmp_ctx; errno_t ret; int i; int len; struct map_order_ctx *mo_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } mo_ctx = talloc(tmp_ctx, struct map_order_ctx); if (mo_ctx == NULL) { ret = ENOMEM; goto done; } /* The "order" string contains one or more SELinux user records * separated by $. Now we need to create an array of string from * this one string. First find out how many elements in the array * will be. This way only one alloc will be necessary for the array */ mo_ctx->order_count = 1; len = strlen(map_order); for (i = 0; i < len; i++) { if (map_order[i] == '$') mo_ctx->order_count++; } mo_ctx->order_array = talloc_array(mo_ctx, char *, mo_ctx->order_count); if (mo_ctx->order_array == NULL) { ret = ENOMEM; goto done; } mo_ctx->order = talloc_strdup(mo_ctx, map_order); if (mo_ctx->order == NULL) { ret = ENOMEM; goto done; } /* Now fill the array with pointers to the original string. Also * use binary zeros to make multiple string out of the one. */ mo_ctx->order_array[0] = mo_ctx->order; mo_ctx->order_count = 1; for (i = 0; i < len; i++) { if (mo_ctx->order[i] == '$') { mo_ctx->order[i] = '\0'; mo_ctx->order_array[mo_ctx->order_count] = &mo_ctx->order[i+1]; mo_ctx->order_count++; } } *_mo_ctx = talloc_steal(mem_ctx, mo_ctx); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t selinux_child_setup(TALLOC_CTX *mem_ctx, const char *orig_name, struct sss_domain_info *dom, const char *seuser_mls_string, struct selinux_child_input **_sci); /* Choose best selinux user based on given order and write * the user to selinux login file. */ static errno_t choose_best_seuser(TALLOC_CTX *mem_ctx, struct sysdb_attrs **usermaps, struct pam_data *pd, struct sss_domain_info *user_domain, struct map_order_ctx *mo_ctx, const char *default_user, struct selinux_child_input **_sci) { TALLOC_CTX *tmp_ctx; char *seuser_mls_str = NULL; const char *tmp_str; errno_t ret; int i, j; struct selinux_child_input *sci; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } /* If no maps match, we'll use the default SELinux user from the * config */ seuser_mls_str = talloc_strdup(tmp_ctx, default_user ? default_user : ""); if (seuser_mls_str == NULL) { ret = ENOMEM; goto done; } /* Iterate through the order array and try to find SELinux users * in fetched maps. The order array contains all SELinux users * allowed in the domain in the same order they should appear * in the SELinux config file. If any user from the order array * is not in fetched user maps, it means it should not be allowed * for the user who is just logging in. * * Right now we have empty content of the SELinux config file, * we shall add only those SELinux users that are present both in * the order array and user maps applicable to the user who is * logging in. */ for (i = 0; i < mo_ctx->order_count; i++) { for (j = 0; usermaps[j] != NULL; j++) { tmp_str = sss_selinux_map_get_seuser(usermaps[j]); if (tmp_str && !strcasecmp(tmp_str, mo_ctx->order_array[i])) { /* If seuser_mls_str contained something, overwrite it. * This record has higher priority. */ talloc_zfree(seuser_mls_str); seuser_mls_str = talloc_strdup(tmp_ctx, tmp_str); if (seuser_mls_str == NULL) { ret = ENOMEM; goto done; } break; } } } ret = selinux_child_setup(tmp_ctx, pd->user, user_domain, seuser_mls_str, &sci); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set up child input buffer\n"); goto done; } *_sci = talloc_steal(mem_ctx, sci); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t selinux_child_setup(TALLOC_CTX *mem_ctx, const char *orig_name, struct sss_domain_info *dom, const char *seuser_mls_string, struct selinux_child_input **_sci) { errno_t ret; char *seuser; const char *mls_range; char *ptr; char *username; char *username_final; char *domain_name = NULL; TALLOC_CTX *tmp_ctx; struct selinux_child_input *sci; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } /* Split seuser and mls_range */ seuser = talloc_strdup(tmp_ctx, seuser_mls_string); if (seuser == NULL) { ret = ENOMEM; goto done; } ptr = seuser; while (*ptr != ':' && *ptr != '\0') { ptr++; } if (*ptr == '\0') { /* No mls_range specified */ mls_range = ""; } else { *ptr = '\0'; /* split */ mls_range = ptr + 1; } /* pam_selinux needs the username in the same format getpwnam() would * return it */ username = sss_get_cased_name(tmp_ctx, orig_name, dom->case_preserve); if (username == NULL) { ret = ENOMEM; goto done; } if (dom->fqnames) { ret = sss_parse_name(tmp_ctx, dom->names, username, &domain_name, NULL); if (ret == EOK && domain_name != NULL) { /* username is already a fully qualified name */ username_final = username; } else if ((ret == EOK && domain_name == NULL) || ret == ERR_REGEX_NOMATCH) { username_final = talloc_asprintf(tmp_ctx, dom->names->fq_fmt, username, dom->name); if (username_final == NULL) { ret = ENOMEM; goto done; } } else { DEBUG(SSSDBG_OP_FAILURE, "sss_parse_name failed: [%d] %s\n", ret, sss_strerror(ret)); goto done; } } else { username_final = username; } sci = talloc(tmp_ctx, struct selinux_child_input); if (sci == NULL) { ret = ENOMEM; goto done; } sci->seuser = talloc_strdup(sci, seuser); sci->mls_range = talloc_strdup(sci, mls_range); sci->username = talloc_strdup(sci, username_final); if (sci->seuser == NULL || sci->mls_range == NULL || sci->username == NULL) { ret = ENOMEM; goto done; } *_sci = talloc_steal(mem_ctx, sci); ret = EOK; done: talloc_free(tmp_ctx); return ret; } struct selinux_child_state { struct selinux_child_input *sci; struct tevent_context *ev; struct io_buffer *buf; struct child_io_fds *io; }; static errno_t selinux_child_init(void); static errno_t selinux_child_create_buffer(struct selinux_child_state *state); static errno_t selinux_fork_child(struct selinux_child_state *state); static void selinux_child_step(struct tevent_req *subreq); static void selinux_child_done(struct tevent_req *subreq); static errno_t selinux_child_parse_response(uint8_t *buf, ssize_t len, uint32_t *_child_result); static struct tevent_req *selinux_child_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct selinux_child_input *sci) { struct tevent_req *req; struct tevent_req *subreq; struct selinux_child_state *state; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct selinux_child_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->sci = sci; state->ev = ev; state->io = talloc(state, struct child_io_fds); state->buf = talloc(state, struct io_buffer); if (state->io == NULL || state->buf == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); ret = ENOMEM; goto immediately; } state->io->write_to_child_fd = -1; state->io->read_from_child_fd = -1; talloc_set_destructor((void *) state->io, child_io_destructor); ret = selinux_child_init(); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to init the child\n"); goto immediately; } ret = selinux_child_create_buffer(state); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to create the send buffer\n"); ret = ENOMEM; goto immediately; } ret = selinux_fork_child(state); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to fork the child\n"); goto immediately; } subreq = write_pipe_send(state, ev, state->buf->data, state->buf->size, state->io->write_to_child_fd); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, selinux_child_step, req); ret = EOK; immediately: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static errno_t selinux_child_init(void) { return child_debug_init(SELINUX_CHILD_LOG_FILE, &selinux_child_debug_fd); } static errno_t selinux_child_create_buffer(struct selinux_child_state *state) { size_t rp; size_t seuser_len; size_t mls_range_len; size_t username_len; seuser_len = strlen(state->sci->seuser); mls_range_len = strlen(state->sci->mls_range); username_len = strlen(state->sci->username); state->buf->size = 3 * sizeof(uint32_t); state->buf->size += seuser_len + mls_range_len + username_len; DEBUG(SSSDBG_TRACE_ALL, "buffer size: %zu\n", state->buf->size); state->buf->data = talloc_size(state->buf, state->buf->size); if (state->buf->data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); return ENOMEM; } rp = 0; /* seuser */ SAFEALIGN_SET_UINT32(&state->buf->data[rp], seuser_len, &rp); safealign_memcpy(&state->buf->data[rp], state->sci->seuser, seuser_len, &rp); /* mls_range */ SAFEALIGN_SET_UINT32(&state->buf->data[rp], mls_range_len, &rp); safealign_memcpy(&state->buf->data[rp], state->sci->mls_range, mls_range_len, &rp); /* username */ SAFEALIGN_SET_UINT32(&state->buf->data[rp], username_len, &rp); safealign_memcpy(&state->buf->data[rp], state->sci->username, username_len, &rp); return EOK; } static errno_t selinux_fork_child(struct selinux_child_state *state) { int pipefd_to_child[2]; int pipefd_from_child[2]; pid_t pid; errno_t ret; ret = pipe(pipefd_from_child); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", errno, sss_strerror(errno)); return ret; } ret = pipe(pipefd_to_child); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", errno, sss_strerror(errno)); return ret; } pid = fork(); if (pid == 0) { /* child */ ret = exec_child(state, pipefd_to_child, pipefd_from_child, SELINUX_CHILD, selinux_child_debug_fd); DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec selinux_child: [%d][%s].\n", ret, sss_strerror(ret)); return ret; } else if (pid > 0) { /* parent */ state->io->read_from_child_fd = pipefd_from_child[0]; close(pipefd_from_child[1]); state->io->write_to_child_fd = pipefd_to_child[1]; close(pipefd_to_child[0]); sss_fd_nonblocking(state->io->read_from_child_fd); sss_fd_nonblocking(state->io->write_to_child_fd); ret = child_handler_setup(state->ev, pid, NULL, NULL, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up child signal handler\n"); return ret; } } else { /* error */ ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n", errno, sss_strerror(errno)); return ret; } return EOK; } static void selinux_child_step(struct tevent_req *subreq) { struct tevent_req *req; errno_t ret; struct selinux_child_state *state; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct selinux_child_state); ret = write_pipe_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } close(state->io->write_to_child_fd); state->io->write_to_child_fd = -1; subreq = read_pipe_send(state, state->ev, state->io->read_from_child_fd); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, selinux_child_done, req); } static void selinux_child_done(struct tevent_req *subreq) { struct tevent_req *req; struct selinux_child_state *state; uint32_t child_result; errno_t ret; ssize_t len; uint8_t *buf; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct selinux_child_state); ret = read_pipe_recv(subreq, state, &buf, &len); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } close(state->io->read_from_child_fd); state->io->read_from_child_fd = -1; ret = selinux_child_parse_response(buf, len, &child_result); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "selinux_child_parse_response failed: [%d][%s]\n", ret, strerror(ret)); tevent_req_error(req, ret); return; } else if (child_result != 0){ DEBUG(SSSDBG_CRIT_FAILURE, "Error in selinux_child: [%d][%s]\n", child_result, strerror(child_result)); tevent_req_error(req, ERR_SELINUX_CONTEXT); return; } tevent_req_done(req); return; } static errno_t selinux_child_parse_response(uint8_t *buf, ssize_t len, uint32_t *_child_result) { size_t p = 0; uint32_t child_result; /* semanage retval */ SAFEALIGN_COPY_UINT32_CHECK(&child_result, buf + p, len, &p); *_child_result = child_result; return EOK; } static errno_t selinux_child_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* A more generic request to gather all SELinux and HBAC rules. Updates * cache if necessary */ struct ipa_get_selinux_state { struct be_ctx *be_ctx; struct ipa_selinux_ctx *selinux_ctx; struct sdap_id_op *op; struct sysdb_attrs *host; struct sysdb_attrs *user; struct sysdb_attrs *defaults; struct sysdb_attrs **selinuxmaps; size_t nmaps; struct sysdb_attrs **hbac_rules; size_t hbac_rule_count; }; static errno_t ipa_get_selinux_maps_offline(struct tevent_req *req); static struct tevent_req * ipa_get_selinux_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct sysdb_attrs *user, struct sysdb_attrs *host, struct ipa_selinux_ctx *selinux_ctx) { struct tevent_req *req; struct tevent_req *subreq; struct ipa_get_selinux_state *state; bool offline; int ret = EOK; time_t now; time_t refresh_interval; struct ipa_options *ipa_options = selinux_ctx->id_ctx->ipa_options; DEBUG(SSSDBG_TRACE_FUNC, "Retrieving SELinux user mapping\n"); req = tevent_req_create(mem_ctx, &state, struct ipa_get_selinux_state); if (req == NULL) { return NULL; } state->be_ctx = be_ctx; state->selinux_ctx = selinux_ctx; state->user = user; state->host = host; offline = be_is_offline(be_ctx); DEBUG(SSSDBG_TRACE_INTERNAL, "Connection status is [%s].\n", offline ? "offline" : "online"); if (!offline) { refresh_interval = dp_opt_get_int(ipa_options->basic, IPA_SELINUX_REFRESH); now = time(NULL); if (now < selinux_ctx->last_update + refresh_interval) { /* SELinux maps were recently updated -> force offline */ DEBUG(SSSDBG_TRACE_INTERNAL, "Performing cached SELinux processing\n"); offline = true; } } if (!offline) { state->op = sdap_id_op_create(state, selinux_ctx->id_ctx->sdap_id_ctx->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto immediate; } subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_id_op_connect_send failed: " "%d(%s).\n", ret, strerror(ret)); talloc_zfree(state->op); goto immediate; } tevent_req_set_callback(subreq, ipa_get_selinux_connect_done, req); } else { ret = ipa_get_selinux_maps_offline(req); goto immediate; } return req; immediate: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, be_ctx->ev); return req; } static void ipa_get_selinux_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_selinux_state *state = tevent_req_data(req, struct ipa_get_selinux_state); int dp_error = DP_ERR_FATAL; int ret; struct ipa_id_ctx *id_ctx = state->selinux_ctx->id_ctx; const char *access_name; const char *selinux_name; const char *hostname; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (dp_error == DP_ERR_OFFLINE) { talloc_zfree(state->op); ret = ipa_get_selinux_maps_offline(req); if (ret == EOK) { tevent_req_done(req); return; } goto fail; } if (ret != EOK) { goto fail; } access_name = state->be_ctx->bet_info[BET_ACCESS].mod_name; selinux_name = state->be_ctx->bet_info[BET_SELINUX].mod_name; if (strcasecmp(access_name, selinux_name) == 0 && state->host != NULL) { /* If the access control module is the same as the selinux module * and the access control had already discovered the host */ return ipa_get_config_step(req); } hostname = dp_opt_get_string(state->selinux_ctx->id_ctx->ipa_options->basic, IPA_HOSTNAME); if (hostname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot determine the host name\n"); goto fail; } subreq = ipa_host_info_send(state, state->be_ctx->ev, sdap_id_op_handle(state->op), id_ctx->sdap_id_ctx->opts, hostname, id_ctx->ipa_options->host_map, NULL, state->selinux_ctx->host_search_bases); if (subreq == NULL) { ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, ipa_get_selinux_hosts_done, req); return; fail: tevent_req_error(req, ret); } static errno_t ipa_get_selinux_maps_offline(struct tevent_req *req) { errno_t ret; size_t nmaps; struct ldb_message **maps; struct ldb_message *defaults; const char *attrs[] = { SYSDB_NAME, SYSDB_USER_CATEGORY, SYSDB_HOST_CATEGORY, SYSDB_ORIG_MEMBER_USER, SYSDB_ORIG_MEMBER_HOST, SYSDB_SELINUX_SEEALSO, SYSDB_SELINUX_USER, NULL }; const char *default_user; const char *order; struct ipa_get_selinux_state *state = tevent_req_data(req, struct ipa_get_selinux_state); /* read the config entry */ ret = sysdb_search_selinux_config(state, state->be_ctx->domain, NULL, &defaults); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_selinux_config failed [%d]: %s\n", ret, strerror(ret)); return ret; } default_user = ldb_msg_find_attr_as_string(defaults, SYSDB_SELINUX_DEFAULT_USER, NULL); order = ldb_msg_find_attr_as_string(defaults, SYSDB_SELINUX_DEFAULT_ORDER, NULL); state->defaults = sysdb_new_attrs(state); if (state->defaults == NULL) { return ENOMEM; } if (default_user) { ret = sysdb_attrs_add_string(state->defaults, IPA_CONFIG_SELINUX_DEFAULT_USER_CTX, default_user); if (ret != EOK) { return ret; } } ret = sysdb_attrs_add_string(state->defaults, IPA_CONFIG_SELINUX_MAP_ORDER, order); if (ret != EOK) { return ret; } /* read all the SELinux rules */ ret = sysdb_get_selinux_usermaps(state, state->be_ctx->domain, attrs, &nmaps, &maps); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_selinux_usermaps failed [%d]: %s\n", ret, strerror(ret)); return ret; } ret = sysdb_msg2attrs(state, nmaps, maps, &state->selinuxmaps); if (ret != EOK) { return ret; } state->nmaps = nmaps; /* read all the HBAC rules */ ret = hbac_get_cached_rules(state, state->be_ctx->domain, &state->hbac_rule_count, &state->hbac_rules); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "hbac_get_cached_rules failed [%d]: %s\n", ret, strerror(ret)); return ret; } return EOK; } static void ipa_get_selinux_hosts_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_selinux_state *state = tevent_req_data(req, struct ipa_get_selinux_state); size_t host_count, hostgroup_count; struct sysdb_attrs **hostgroups; struct sysdb_attrs **host; ret = ipa_host_info_recv(subreq, state, &host_count, &host, &hostgroup_count, &hostgroups); talloc_free(subreq); if (ret != EOK) { goto done; } state->host = host[0]; return ipa_get_config_step(req); done: if (ret != EOK) { tevent_req_error(req, ret); } } static void ipa_get_config_step(struct tevent_req *req) { const char *domain; struct tevent_req *subreq; struct ipa_get_selinux_state *state = tevent_req_data(req, struct ipa_get_selinux_state); struct ipa_id_ctx *id_ctx = state->selinux_ctx->id_ctx; domain = dp_opt_get_string(state->selinux_ctx->id_ctx->ipa_options->basic, IPA_KRB5_REALM); subreq = ipa_get_config_send(state, state->be_ctx->ev, sdap_id_op_handle(state->op), id_ctx->sdap_id_ctx->opts, domain, NULL); if (subreq == NULL) { tevent_req_error(req, ENOMEM); } tevent_req_set_callback(subreq, ipa_get_selinux_config_done, req); } static void ipa_get_selinux_config_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_selinux_state *state = tevent_req_data(req, struct ipa_get_selinux_state); struct sdap_id_ctx *id_ctx = state->selinux_ctx->id_ctx->sdap_id_ctx; errno_t ret; ret = ipa_get_config_recv(subreq, state, &state->defaults); talloc_free(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not get IPA config\n"); goto done; } subreq = ipa_selinux_get_maps_send(state, state->be_ctx->ev, state->be_ctx->domain->sysdb, sdap_id_op_handle(state->op), id_ctx->opts, state->selinux_ctx->id_ctx->ipa_options, state->selinux_ctx->selinux_search_bases); if (!subreq) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ipa_get_selinux_maps_done, req); return; done: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } } static void ipa_get_selinux_maps_done(struct tevent_req *subreq) { struct tevent_req *req; struct ipa_get_selinux_state *state; struct ipa_id_ctx *id_ctx; char *selinux_name; char *access_name; const char *tmp_str; bool check_hbac; errno_t ret; int i; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ipa_get_selinux_state); id_ctx = state->selinux_ctx->id_ctx; ret = ipa_selinux_get_maps_recv(subreq, state, &state->nmaps, &state->selinuxmaps); talloc_free(subreq); if (ret != EOK) { if (ret == ENOENT) { /* This is returned if no SELinux mapping * rules were found. In that case no error * occurred, but we don't want any more processing.*/ ret = EOK; } goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Found %zu SELinux user maps\n", state->nmaps); check_hbac = false; for (i = 0; i < state->nmaps; i++) { ret = sysdb_attrs_get_string(state->selinuxmaps[i], SYSDB_SELINUX_SEEALSO, &tmp_str); if (ret == EOK) { check_hbac = true; break; } } if (check_hbac) { access_name = state->be_ctx->bet_info[BET_ACCESS].mod_name; selinux_name = state->be_ctx->bet_info[BET_SELINUX].mod_name; if (strcasecmp(access_name, selinux_name) == 0) { ret = hbac_get_cached_rules(state, state->be_ctx->domain, &state->hbac_rule_count, &state->hbac_rules); /* Terminates the request */ goto done; } DEBUG(SSSDBG_TRACE_FUNC, "SELinux maps referenced an HBAC rule. " "Need to refresh HBAC rules\n"); subreq = ipa_hbac_rule_info_send(state, state->be_ctx->ev, sdap_id_op_handle(state->op), id_ctx->sdap_id_ctx->opts, state->selinux_ctx->hbac_search_bases, state->host); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ipa_get_selinux_hbac_done, req); return; } ret = EOK; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } static void ipa_get_selinux_hbac_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_selinux_state *state = tevent_req_data(req, struct ipa_get_selinux_state); errno_t ret; ret = ipa_hbac_rule_info_recv(subreq, state, &state->hbac_rule_count, &state->hbac_rules); DEBUG(SSSDBG_TRACE_INTERNAL, "Received %zu HBAC rules\n", state->hbac_rule_count); talloc_free(subreq); if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } } static errno_t ipa_get_selinux_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *count, struct sysdb_attrs ***maps, size_t *hbac_count, struct sysdb_attrs ***hbac_rules, char **default_user, char **map_order) { struct ipa_get_selinux_state *state = tevent_req_data(req, struct ipa_get_selinux_state); const char *tmp_str; errno_t ret; TEVENT_REQ_RETURN_ON_ERROR(req); ret = sysdb_attrs_get_string(state->defaults, IPA_CONFIG_SELINUX_DEFAULT_USER_CTX, &tmp_str); if (ret != EOK && ret != ENOENT) { return ret; } if (ret == EOK) { *default_user = talloc_strdup(mem_ctx, tmp_str); if (*default_user == NULL) { return ENOMEM; } } ret = sysdb_attrs_get_string(state->defaults, IPA_CONFIG_SELINUX_MAP_ORDER, &tmp_str); if (ret != EOK) { return ret; } *map_order = talloc_strdup(mem_ctx, tmp_str); if (*map_order == NULL) { talloc_zfree(*default_user); return ENOMEM; } *count = state->nmaps; *maps = talloc_steal(mem_ctx, state->selinuxmaps); *hbac_count = state->hbac_rule_count; *hbac_rules = talloc_steal(mem_ctx, state->hbac_rules); return EOK; } /*end of #if defined HAVE_SELINUX && defined HAVE_SELINUX_LOGIN_DIR */ #else /* Simply return success if HAVE_SELINUX_LOGIN_DIR is not defined. */ void ipa_selinux_handler(struct be_req *be_req) { struct pam_data *pd; pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); pd->pam_status = PAM_SUCCESS; be_req_terminate(be_req, DP_ERR_OK, EOK, "Success"); } #endif sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hbac_hosts.c0000644000000000000000000000007312703456111021013 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.739793917 sssd-1.13.4/src/providers/ipa/ipa_hbac_hosts.c0000644002412700241270000003442712703456111022475 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "providers/ipa/ipa_hbac_private.h" #include "providers/ldap/sdap_async.h" /* * Functions to convert sysdb_attrs to the hbac_rule format */ static errno_t hbac_host_attrs_to_rule(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *rule_name, struct sysdb_attrs *rule_attrs, const char *category_attr, const char *member_attr, size_t *host_count, struct hbac_rule_element **hosts) { errno_t ret; TALLOC_CTX *tmp_ctx; struct hbac_rule_element *new_hosts; const char *attrs[] = { SYSDB_FQDN, SYSDB_NAME, NULL }; struct ldb_message_element *el; size_t num_hosts = 0; size_t num_hostgroups = 0; size_t i; char *member_dn; char *filter; size_t count; struct ldb_message **msgs; const char *name; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return ENOMEM; new_hosts = talloc_zero(tmp_ctx, struct hbac_rule_element); if (new_hosts == NULL) { ret = ENOMEM; goto done; } /* First check for host category */ ret = hbac_get_category(rule_attrs, category_attr, &new_hosts->category); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not identify host categories\n"); goto done; } if (new_hosts->category & HBAC_CATEGORY_ALL) { /* Short-cut to the exit */ ret = EOK; goto done; } /* Get the list of DNs from the member_attr */ ret = sysdb_attrs_get_el(rule_attrs, member_attr, &el); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_get_el failed.\n"); goto done; } if (ret == ENOENT || el->num_values == 0) { el->num_values = 0; DEBUG(SSSDBG_CONF_SETTINGS, "No host specified, rule will never apply.\n"); } /* Assume maximum size; We'll trim it later */ new_hosts->names = talloc_array(new_hosts, const char *, el->num_values +1); if (new_hosts->names == NULL) { ret = ENOMEM; goto done; } new_hosts->groups = talloc_array(new_hosts, const char *, el->num_values + 1); if (new_hosts->groups == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < el->num_values; i++) { ret = sss_filter_sanitize(tmp_ctx, (const char *)el->values[i].data, &member_dn); if (ret != EOK) goto done; filter = talloc_asprintf(member_dn, "(%s=%s)", SYSDB_ORIG_DN, member_dn); if (filter == NULL) { ret = ENOMEM; goto done; } /* First check if this is a specific host */ ret = sysdb_search_custom(tmp_ctx, domain, filter, HBAC_HOSTS_SUBDIR, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) goto done; if (ret == EOK && count == 0) { ret = ENOENT; } if (ret == EOK) { if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Original DN matched multiple hosts. Skipping \n"); talloc_zfree(member_dn); continue; } /* Original DN matched a single host. Get the hostname */ name = ldb_msg_find_attr_as_string(msgs[0], SYSDB_FQDN, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "FQDN is missing!\n"); ret = EFAULT; goto done; } new_hosts->names[num_hosts] = talloc_strdup(new_hosts->names, name); if (new_hosts->names[num_hosts] == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Added host [%s] to rule [%s]\n", name, rule_name); num_hosts++; } else { /* ret == ENOENT */ /* Check if this is a hostgroup */ ret = sysdb_search_custom(tmp_ctx, domain, filter, HBAC_HOSTGROUPS_SUBDIR, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) goto done; if (ret == EOK && count == 0) { ret = ENOENT; } if (ret == EOK) { if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Original DN matched multiple hostgroups. " "Skipping\n"); talloc_zfree(member_dn); continue; } /* Original DN matched a single group. Get the groupname */ name = ldb_msg_find_attr_as_string(msgs[0], SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Hostgroup name is missing!\n"); ret = EFAULT; goto done; } new_hosts->groups[num_hostgroups] = talloc_strdup(new_hosts->groups, name); if (new_hosts->groups[num_hostgroups] == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Added hostgroup [%s] to rule [%s]\n", name, rule_name); num_hostgroups++; } else { /* ret == ENOENT */ /* Neither a host nor a hostgroup? Skip it */ DEBUG(SSSDBG_TRACE_LIBS, "[%s] does not map to either a host or hostgroup. " "Skipping\n", member_dn); } } talloc_zfree(member_dn); } new_hosts->names[num_hosts] = NULL; new_hosts->groups[num_hostgroups] = NULL; /* Shrink the arrays down to their real sizes */ new_hosts->names = talloc_realloc(new_hosts, new_hosts->names, const char *, num_hosts + 1); if (new_hosts->names == NULL) { ret = ENOMEM; goto done; } new_hosts->groups = talloc_realloc(new_hosts, new_hosts->groups, const char *, num_hostgroups + 1); if (new_hosts->groups == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: if (ret == EOK) { *hosts = talloc_steal(mem_ctx, new_hosts); if (host_count) *host_count = num_hosts; } talloc_free(tmp_ctx); return ret; } errno_t hbac_thost_attrs_to_rule(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *rule_name, struct sysdb_attrs *rule_attrs, struct hbac_rule_element **thosts) { DEBUG(SSSDBG_TRACE_LIBS, "Processing target hosts for rule [%s]\n", rule_name); return hbac_host_attrs_to_rule(mem_ctx, domain, rule_name, rule_attrs, IPA_HOST_CATEGORY, IPA_MEMBER_HOST, NULL, thosts); } errno_t hbac_shost_attrs_to_rule(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *rule_name, struct sysdb_attrs *rule_attrs, bool support_srchost, struct hbac_rule_element **source_hosts) { errno_t ret; size_t host_count; TALLOC_CTX *tmp_ctx; size_t idx; struct ldb_message_element *el; struct hbac_rule_element *shosts; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) return ENOMEM; DEBUG(SSSDBG_TRACE_FUNC, "Processing source hosts for rule [%s]\n", rule_name); if (!support_srchost) { DEBUG(SSSDBG_TRACE_INTERNAL, "Source hosts disabled, setting ALL\n"); shosts = talloc_zero(tmp_ctx, struct hbac_rule_element); if (shosts == NULL) { ret = ENOMEM; goto done; } shosts->category = HBAC_CATEGORY_ALL; ret = EOK; goto done; } else { DEBUG(SSSDBG_MINOR_FAILURE, "WARNING: Using deprecated option " "ipa_hbac_support_srchost.\n"); sss_log(SSS_LOG_NOTICE, "WARNING: Using deprecated option " "ipa_hbac_support_srchost.\n"); } ret = hbac_host_attrs_to_rule(tmp_ctx, domain, rule_name, rule_attrs, IPA_SOURCE_HOST_CATEGORY, IPA_SOURCE_HOST, &host_count, &shosts); if (ret != EOK) { goto done; } if (shosts->category & HBAC_CATEGORY_ALL) { /* All hosts (including external) are * allowed. */ goto done; } /* Include external (non-IPA-managed) source hosts */ ret = sysdb_attrs_get_el(rule_attrs, IPA_EXTERNAL_HOST, &el); if (ret != EOK && ret != ENOENT) goto done; if (ret == EOK && el->num_values == 0) ret = ENOENT; if (ret != ENOENT) { shosts->names = talloc_realloc(shosts, shosts->names, const char *, host_count + el->num_values + 1); if (shosts->names == NULL) { ret = ENOMEM; goto done; } for (idx = host_count; idx < host_count + el->num_values; idx++) { shosts->names[idx] = talloc_strdup(shosts->names, (const char *)el->values[idx - host_count].data); if (shosts->names[idx] == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Added external source host [%s] to rule [%s]\n", shosts->names[idx], rule_name); } shosts->names[idx] = NULL; } ret = EOK; done: if (ret == EOK) { *source_hosts = talloc_steal(mem_ctx, shosts); } talloc_free(tmp_ctx); return ret; } errno_t get_ipa_hostgroupname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, const char *host_dn, char **hostgroupname) { errno_t ret; struct ldb_dn *dn; const char *rdn_name; const char *hostgroup_comp_name; const char *account_comp_name; const struct ldb_val *rdn_val; const struct ldb_val *hostgroup_comp_val; const struct ldb_val *account_comp_val; /* This is an IPA-specific hack. It may not * work for non-IPA servers and will need to * be changed if SSSD ever supports HBAC on * a non-IPA server. */ *hostgroupname = NULL; dn = ldb_dn_new(mem_ctx, sysdb_ctx_get_ldb(sysdb), host_dn); if (dn == NULL) { ret = ENOMEM; goto done; } if (!ldb_dn_validate(dn)) { ret = ERR_MALFORMED_ENTRY; goto done; } if (ldb_dn_get_comp_num(dn) < 4) { /* RDN, hostgroups, accounts, and at least one DC= */ /* If it's fewer, it's not a group DN */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* If the RDN name is 'cn' */ rdn_name = ldb_dn_get_rdn_name(dn); if (rdn_name == NULL) { /* Shouldn't happen if ldb_dn_validate() * passed, but we'll be careful. */ ret = ERR_MALFORMED_ENTRY; goto done; } if (strcasecmp("cn", rdn_name) != 0) { /* RDN has the wrong attribute name. * It's not a host. */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* and the second component is "cn=hostgroups" */ hostgroup_comp_name = ldb_dn_get_component_name(dn, 1); if (strcasecmp("cn", hostgroup_comp_name) != 0) { /* The second component name is not "cn" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } hostgroup_comp_val = ldb_dn_get_component_val(dn, 1); if (strncasecmp("hostgroups", (const char *) hostgroup_comp_val->data, hostgroup_comp_val->length) != 0) { /* The second component value is not "hostgroups" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* and the third component is "accounts" */ account_comp_name = ldb_dn_get_component_name(dn, 2); if (strcasecmp("cn", account_comp_name) != 0) { /* The third component name is not "cn" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } account_comp_val = ldb_dn_get_component_val(dn, 2); if (strncasecmp("accounts", (const char *) account_comp_val->data, account_comp_val->length) != 0) { /* The third component value is not "accounts" */ ret = ERR_UNEXPECTED_ENTRY_TYPE; goto done; } /* Then the value of the RDN is the group name */ rdn_val = ldb_dn_get_rdn_val(dn); *hostgroupname = talloc_strndup(mem_ctx, (const char *)rdn_val->data, rdn_val->length); if (*hostgroupname == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: talloc_free(dn); return ret; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_subdomains.h0000644000000000000000000000007412703456111021050 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.572793351 sssd-1.13.4/src/providers/ipa/ipa_subdomains.h0000644002412700241270000001211212703456111022514 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Subdomains Module Authors: Sumit Bose Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _IPA_SUBDOMAINS_H_ #define _IPA_SUBDOMAINS_H_ #include "providers/dp_backend.h" #include "providers/ipa/ipa_common.h" #include "config.h" #ifndef IPA_TRUST_KEYTAB_DIR #define IPA_TRUST_KEYTAB_DIR SSS_STATEDIR"/keytabs" #endif /* IPA_TRUST_KEYTAB_DIR */ /* ==Sid2Name Extended Operation============================================= */ #define EXOP_SID2NAME_OID "2.16.840.1.113730.3.8.10.4" #define EXOP_SID2NAME_V1_OID "2.16.840.1.113730.3.8.10.4.1" struct be_ctx *ipa_get_subdomains_be_ctx(struct be_ctx *be_ctx); int ipa_subdom_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data); /* The following are used in server mode only */ struct ipa_ad_server_ctx { struct sss_domain_info *dom; struct ad_id_ctx *ad_id_ctx; struct ipa_ad_server_ctx *next, *prev; }; /* Can be used to set up trusted subdomain, for example fetch * keytab in server mode */ struct tevent_req * ipa_server_trusted_dom_setup_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct sss_domain_info *subdom); errno_t ipa_server_trusted_dom_setup_recv(struct tevent_req *req); /* To be used by ipa_subdomains.c only */ struct tevent_req * ipa_server_create_trusts_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct sss_domain_info *parent); errno_t ipa_server_create_trusts_recv(struct tevent_req *req); void ipa_ad_subdom_remove(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx, struct sss_domain_info *subdom); int ipa_ad_subdom_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx); errno_t ipa_server_get_trust_direction(struct sysdb_attrs *sd, struct ldb_context *ldb_ctx, uint32_t *_direction); const char *ipa_trust_dir2str(uint32_t direction); /* Utilities */ #define IPA_TRUST_DIRECTION "ipaNTTrustDirection" struct ldb_dn *ipa_subdom_ldb_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, struct sysdb_attrs *attrs); bool ipa_subdom_is_member_dom(struct ldb_dn *dn); /* struct for external group memberships, defined in * ipa_subdomains_ext_groups.c */ struct ipa_ext_groups; struct ipa_server_mode_ctx { const char *realm; const char *hostname; struct ipa_ad_server_ctx *trusts; struct ipa_ext_groups *ext_groups; uid_t kt_owner_uid; uid_t kt_owner_gid; }; int ipa_ad_subdom_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx); enum req_input_type { REQ_INP_NAME, REQ_INP_ID, REQ_INP_SECID }; struct req_input { enum req_input_type type; union { const char *name; uint32_t id; const char *secid; } inp; }; struct tevent_req *ipa_get_ad_memberships_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_acct_req *ar, struct ipa_server_mode_ctx *server_mode, struct sss_domain_info *user_dom, struct sdap_id_ctx *sdap_id_ctx, const char *domain); errno_t ipa_get_ad_memberships_recv(struct tevent_req *req, int *dp_error_out); struct tevent_req *ipa_ext_group_member_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *ext_member, void *pvt); errno_t ipa_ext_group_member_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, enum sysdb_member_type *_member_type, struct sss_domain_info **_dom, struct sysdb_attrs **_member); #endif /* _IPA_SUBDOMAINS_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_hbac.h0000644000000000000000000000007312703456111017600 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.603793456 sssd-1.13.4/src/providers/ipa/ipa_hbac.h0000644002412700241270000001743512703456111021262 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- Access control Authors: Sumit Bose Stephen Gallagher Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IPA_HBAC_H_ #define IPA_HBAC_H_ /** * @defgroup ipa_hbac Host-Based Access Control Resolver * Libipa_hbac provides a mechanism to validate FreeIPA * HBAC rules as well as evaluate whether they apply to * a particular user login attempt. * * Libipa_hbac is case-insensitive and compatible with * UTF-8. * @{ */ #include #include #include /** Result of HBAC evaluation */ enum hbac_eval_result { /** An error occurred * See the #hbac_info for more details */ HBAC_EVAL_ERROR = -1, /** Evaluation grants access */ HBAC_EVAL_ALLOW, /** Evaluation denies access */ HBAC_EVAL_DENY, /** Evaluation failed due to lack of memory * #hbac_info is not available */ HBAC_EVAL_OOM }; /** * No service category specified */ #define HBAC_CATEGORY_NULL 0x0000 /** * Rule should apply to all */ #define HBAC_CATEGORY_ALL 0x0001 /** * Opaque type contained in hbac_evaluator.c */ struct hbac_time_rules; /** * Component of an HBAC rule * * Components can be one of users, target hosts, * source hosts, or services. */ struct hbac_rule_element { /** * Category for this element * * This value is a bitmask. * See #HBAC_CATEGORY_NULL and * #HBAC_CATEGORY_ALL */ uint32_t category; /** * List of explicit members of this rule component * * - Users: usernames * - Hosts: hostnames * - Services: PAM service names */ const char **names; /** * List of group members of this rule component * * - Users: user groups (POSIX or non-POSIX) * - Hosts: hostgroups * - Services: PAM service groups. */ const char **groups; }; /** * HBAC rule object for evaluation */ struct hbac_rule { const char *name; bool enabled; /** * Services and service groups * for which this rule applies */ struct hbac_rule_element *services; /** * Users and groups for which this * rule applies */ struct hbac_rule_element *users; /** * Target hosts for which this rule apples */ struct hbac_rule_element *targethosts; /** * Source hosts for which this rule applies */ struct hbac_rule_element *srchosts; /** * For future use */ struct hbac_time_rules *timerules; }; /** * Component of an HBAC request */ struct hbac_request_element { /** * List of explicit members of this request component * * - Users: usernames * - Hosts: hostnames * - Services: PAM service names */ const char *name; /** * List of group members of this request component * * - Users: user groups (POSIX or non-POSIX) * - Hosts: hostgroups * - Services: PAM service groups. */ const char **groups; }; /** * Request object for an HBAC rule evaluation * * */ struct hbac_eval_req { /** This is a list of service DNs to check, * it must consist of the actual service * requested, as well as all parent groups * containing that service. */ struct hbac_request_element *service; /** This is a list of user DNs to check, * it must consist of the actual user * requested, as well as all parent groups * containing that user. */ struct hbac_request_element *user; /** This is a list of target hosts to check, * it must consist of the actual target host * requested, as well as all parent groups * containing that target host. */ struct hbac_request_element *targethost; /** This is a list of source hosts to check, * it must consist of the actual source host * requested, as well as all parent groups * containing that source host. */ struct hbac_request_element *srchost; /** For future use */ time_t request_time; }; /** * Error code returned by the evaluator */ enum hbac_error_code { /** Unexpected error */ HBAC_ERROR_UNKNOWN = -1, /** Successful evaluation */ HBAC_SUCCESS, /** Function is not yet implemented */ HBAC_ERROR_NOT_IMPLEMENTED, /** Ran out of memory during processing */ HBAC_ERROR_OUT_OF_MEMORY, /** Parse error while evaluating rule */ HBAC_ERROR_UNPARSEABLE_RULE }; /** Extended information */ struct hbac_info { /** * If the hbac_eval_result was HBAC_EVAL_ERROR, * this will be an error code. * Otherwise it will be HBAC_SUCCESS */ enum hbac_error_code code; /** * Specify the name of the rule that matched or * threw an error */ char *rule_name; }; /** * @brief Evaluate an authorization request against a set of HBAC rules * * @param[in] rules A NULL-terminated list of rules to evaluate against * @param[in] hbac_req A user authorization request * @param[out] info Extended information (including the name of the * rule that allowed access (or caused a parse error) * @return * - #HBAC_EVAL_ERROR: An error occurred * - #HBAC_EVAL_ALLOW: Access is granted * - #HBAC_EVAL_DENY: Access is denied * - #HBAC_EVAL_OOM: Insufficient memory to complete the evaluation */ enum hbac_eval_result hbac_evaluate(struct hbac_rule **rules, struct hbac_eval_req *hbac_req, struct hbac_info **info); /** * @brief Display result of hbac evaluation in human-readable form * @param[in] result Return value of #hbac_evaluate * @return English string describing the evaluation result */ const char *hbac_result_string(enum hbac_eval_result result); /** * @brief Display error description * @param code Error code returned in #hbac_info * @return English string describing the error */ const char *hbac_error_string(enum hbac_error_code code); /** * @brief Function to safely free #hbac_info returned by #hbac_evaluate * @param info #hbac_info returned by #hbac_evaluate */ void hbac_free_info(struct hbac_info *info); /** User element */ #define HBAC_RULE_ELEMENT_USERS 0x01 /** Service element */ #define HBAC_RULE_ELEMENT_SERVICES 0x02 /** Target host element */ #define HBAC_RULE_ELEMENT_TARGETHOSTS 0x04 /** Source host element */ #define HBAC_RULE_ELEMENT_SOURCEHOSTS 0x08 /** * @brief Evaluate whether an HBAC rule contains all necessary elements * * @param[in] rule An HBAC rule to evaluate * @param[out] missing_attrs A list of attributes missing from the rule * This is a bitmask that may contain one or more * of #HBAC_RULE_ELEMENT_USERS, * #HBAC_RULE_ELEMENT_SERVICES, * #HBAC_RULE_ELEMENT_TARGETHOSTS and * #HBAC_RULE_ELEMENT_SOURCEHOSTS * * @return True if the rule contains all mandatory attributes * * @note This function does not care if the rule is enabled or disabled */ bool hbac_rule_is_complete(struct hbac_rule *rule, uint32_t *missing_attrs); /** * @} */ #endif /* IPA_HBAC_H_ */ sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_dn.c0000644000000000000000000000007312703456111017277 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.749793951 sssd-1.13.4/src/providers/ipa/ipa_dn.c0000644002412700241270000000665112703456111020757 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "db/sysdb.h" #include "providers/ipa/ipa_dn.h" static bool check_dn(struct ldb_dn *dn, const char *rdn_attr, va_list in_ap) { const struct ldb_val *ldbval; const char *strval; const char *ldbattr; const char *attr; const char *val; va_list ap; int num_comp; int comp; /* check RDN attribute */ ldbattr = ldb_dn_get_rdn_name(dn); if (ldbattr == NULL || strcasecmp(ldbattr, rdn_attr) != 0) { return false; } /* Check DN components. First we check if all attr=value pairs match input. * Then we check that the next attribute is a domain component. */ comp = 1; num_comp = ldb_dn_get_comp_num(dn); va_copy(ap, in_ap); while ((attr = va_arg(ap, const char *)) != NULL) { val = va_arg(ap, const char *); if (val == NULL) { goto vafail; } if (comp > num_comp) { goto vafail; } ldbattr = ldb_dn_get_component_name(dn, comp); if (ldbattr == NULL || strcasecmp(ldbattr, attr) != 0) { goto vafail; } ldbval = ldb_dn_get_component_val(dn, comp); if (ldbval == NULL) { goto vafail; } strval = (const char *)ldbval->data; if (strval == NULL || strncasecmp(strval, val, ldbval->length) != 0) { goto vafail; } comp++; } va_end(ap); ldbattr = ldb_dn_get_component_name(dn, comp); if (ldbattr == NULL || strcmp(ldbattr, "dc") != 0) { return false; } return true; vafail: va_end(ap); return false; } errno_t _ipa_get_rdn(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, const char *obj_dn, char **_rdn_val, const char *rdn_attr, ...) { const struct ldb_val *val; struct ldb_dn *dn; errno_t ret; bool bret; va_list ap; char *rdn; dn = ldb_dn_new(mem_ctx, sysdb_ctx_get_ldb(sysdb), obj_dn); if (dn == NULL) { return ENOMEM; } va_start(ap, rdn_attr); bret = check_dn(dn, rdn_attr, ap); va_end(ap); if (bret == false) { ret = ENOENT; goto done; } if (_rdn_val == NULL) { ret = EOK; goto done; } val = ldb_dn_get_rdn_val(dn); if (val == NULL || val->data == NULL) { ret = EINVAL; goto done; } rdn = talloc_strndup(mem_ctx, (const char*)val->data, val->length); if (rdn == NULL) { ret = ENOMEM; goto done; } *_rdn_val = rdn; ret = EOK; done: talloc_free(dn); return ret; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_netgroups.c0000644000000000000000000000007312703456111020724 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.726793873 sssd-1.13.4/src/providers/ipa/ipa_netgroups.c0000644002412700241270000010135412703456111022400 0ustar00jhrozekjhrozek00000000000000/* SSSD Async IPA Helper routines for netgroups Authors: Jan Zeleny Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ipa/ipa_id.h" #include "db/sysdb.h" #include #define ENTITY_NG 1 #define ENTITY_USER 2 #define ENTITY_HOST 4 struct ipa_get_netgroups_state { struct tevent_context *ev; struct sdap_options *opts; struct ipa_options *ipa_opts; struct sdap_handle *sh; struct sysdb_ctx *sysdb; struct sss_domain_info *dom; const char **attrs; int timeout; char *filter; const char *base_filter; size_t netgr_base_iter; size_t host_base_iter; size_t user_base_iter; /* Entities which have been already asked for * and are scheduled for inspection */ hash_table_t *new_netgroups; hash_table_t *new_users; hash_table_t *new_hosts; int current_entity; int entities_found; struct sysdb_attrs **netgroups; int netgroups_count; }; static errno_t ipa_save_netgroup(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, struct sdap_options *opts, struct sysdb_attrs *attrs) { struct ldb_message_element *el; struct sysdb_attrs *netgroup_attrs; const char *name = NULL; int ret; size_t c; ret = sysdb_attrs_get_el(attrs, opts->netgroup_map[IPA_AT_NETGROUP_NAME].sys_name, &el); if (ret) goto fail; if (el->num_values == 0) { ret = EINVAL; goto fail; } name = (const char *)el->values[0].data; DEBUG(SSSDBG_TRACE_INTERNAL, "Storing netgroup %s\n", name); netgroup_attrs = sysdb_new_attrs(mem_ctx); if (!netgroup_attrs) { ret = ENOMEM; goto fail; } ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el); if (ret) { goto fail; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_LIBS, "Original DN is not available for [%s].\n", name); } else { DEBUG(SSSDBG_TRACE_LIBS, "Adding original DN [%s] to attributes of [%s].\n", el->values[0].data, name); ret = sysdb_attrs_add_string(netgroup_attrs, SYSDB_ORIG_DN, (const char *)el->values[0].data); if (ret) { goto fail; } } ret = sysdb_attrs_get_el(attrs, SYSDB_NETGROUP_TRIPLE, &el); if (ret) { goto fail; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "No netgroup triples for netgroup [%s].\n", name); ret = sysdb_attrs_get_el(netgroup_attrs, SYSDB_NETGROUP_TRIPLE, &el); if (ret != EOK) { goto fail; } } else { for(c = 0; c < el->num_values; c++) { ret = sysdb_attrs_add_string_safe(netgroup_attrs, SYSDB_NETGROUP_TRIPLE, (const char*)el->values[c].data); if (ret) { goto fail; } } } ret = sysdb_attrs_get_el(attrs, opts->netgroup_map[IPA_AT_NETGROUP_MEMBER].sys_name, &el); if (ret != EOK) { goto fail; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_LIBS, "No original members for netgroup [%s]\n", name); } else { DEBUG(SSSDBG_TRACE_LIBS, "Adding original members to netgroup [%s]\n", name); for(c = 0; c < el->num_values; c++) { ret = sysdb_attrs_add_string(netgroup_attrs, opts->netgroup_map[IPA_AT_NETGROUP_MEMBER].sys_name, (const char*)el->values[c].data); if (ret) { goto fail; } } } ret = sysdb_attrs_get_el(attrs, SYSDB_NETGROUP_MEMBER, &el); if (ret != EOK) { goto fail; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_LIBS, "No members for netgroup [%s]\n", name); } else { DEBUG(SSSDBG_TRACE_LIBS, "Adding members to netgroup [%s]\n", name); for(c = 0; c < el->num_values; c++) { ret = sysdb_attrs_add_string(netgroup_attrs, SYSDB_NETGROUP_MEMBER, (const char*)el->values[c].data); if (ret) { goto fail; } } } DEBUG(SSSDBG_TRACE_FUNC, "Storing info for netgroup %s\n", name); ret = sysdb_add_netgroup(dom, name, NULL, netgroup_attrs, NULL, dom->netgroup_timeout, 0); if (ret) goto fail; return EOK; fail: DEBUG(SSSDBG_OP_FAILURE, "Failed to save netgroup %s\n", name); return ret; } static errno_t ipa_netgr_next_base(struct tevent_req *req); static void ipa_get_netgroups_process(struct tevent_req *subreq); static int ipa_netgr_process_all(struct ipa_get_netgroups_state *state); struct tevent_req *ipa_get_netgroups_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct sdap_options *opts, struct ipa_options *ipa_options, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout) { struct tevent_req *req; struct ipa_get_netgroups_state *state; int ret; req = tevent_req_create(memctx, &state, struct ipa_get_netgroups_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->ipa_opts = ipa_options; state->sh = sh; state->sysdb = sysdb; state->attrs = attrs; state->timeout = timeout; state->base_filter = filter; state->netgr_base_iter = 0; state->dom = dom; if (!ipa_options->id->sdom->netgroup_search_bases) { DEBUG(SSSDBG_CRIT_FAILURE, "Netgroup lookup request without a search base\n"); ret = EINVAL; goto done; } ret = sss_hash_create(state, 32, &state->new_netgroups); if (ret != EOK) goto done; ret = sss_hash_create(state, 32, &state->new_users); if (ret != EOK) goto done; ret = sss_hash_create(state, 32, &state->new_hosts); if (ret != EOK) goto done; ret = ipa_netgr_next_base(req); done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static errno_t ipa_netgr_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct ipa_get_netgroups_state *state; struct sdap_search_base **netgr_bases; state = tevent_req_data(req, struct ipa_get_netgroups_state); netgr_bases = state->ipa_opts->id->sdom->netgroup_search_bases; talloc_zfree(state->filter); state->filter = sdap_combine_filters( state, state->base_filter, netgr_bases[state->netgr_base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for netgroups with base [%s]\n", netgr_bases[state->netgr_base_iter]->basedn); subreq = sdap_get_generic_send( state, state->ev, state->opts, state->sh, netgr_bases[state->netgr_base_iter]->basedn, netgr_bases[state->netgr_base_iter]->scope, state->filter, state->attrs, state->opts->netgroup_map, IPA_OPTS_NETGROUP, state->timeout, true); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, ipa_get_netgroups_process, req); return EOK; } static int ipa_netgr_fetch_netgroups(struct ipa_get_netgroups_state *state, struct tevent_req *req); static int ipa_netgr_fetch_users(struct ipa_get_netgroups_state *state, struct tevent_req *req); static int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state, struct tevent_req *req); static void ipa_netgr_members_process(struct tevent_req *subreq); static void ipa_get_netgroups_process(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_netgroups_state *state = tevent_req_data(req, struct ipa_get_netgroups_state); int i, ret; struct ldb_message_element *el; struct sdap_search_base **netgr_bases; struct sysdb_attrs **netgroups; size_t netgroups_count; const char *orig_dn; char *dn; char *filter; bool fetch_members = false; hash_key_t key; hash_value_t value; netgr_bases = state->ipa_opts->id->sdom->netgroup_search_bases; ret = sdap_get_generic_recv(subreq, state, &netgroups_count, &netgroups); talloc_zfree(subreq); if (ret) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Search for netgroups, returned %zu results.\n", netgroups_count); if (netgroups_count == 0) { /* No netgroups found in this search */ state->netgr_base_iter++; if (netgr_bases[state->netgr_base_iter]) { /* There are more search bases to try */ ret = ipa_netgr_next_base(req); if (ret != EOK) { tevent_req_error(req, ENOENT); } return; } ret = ENOENT; goto done; } filter = talloc_strdup(state, "(|"); if (filter == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < netgroups_count; i++) { ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_NETGROUP_MEMBER, &el); if (ret != EOK) goto done; if (el->num_values) state->entities_found |= ENTITY_NG; ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_MEMBER_USER, &el); if (ret != EOK) goto done; if (el->num_values) state->entities_found |= ENTITY_USER; ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_MEMBER_HOST, &el); if (ret != EOK) goto done; if (el->num_values) state->entities_found |= ENTITY_HOST; ret = sysdb_attrs_get_string(netgroups[i], SYSDB_ORIG_DN, &orig_dn); if (ret != EOK) { goto done; } key.type = HASH_KEY_STRING; value.type = HASH_VALUE_PTR; key.str = discard_const(orig_dn); value.ptr = netgroups[i]; ret = hash_enter(state->new_netgroups, &key, &value); if (ret != HASH_SUCCESS) { ret = ENOMEM; goto done; } if (state->entities_found == 0) { continue; } ret = sss_filter_sanitize(state, orig_dn, &dn); if (ret != EOK) { goto done; } /* Add this to the filter */ filter = talloc_asprintf_append(filter, "(%s=%s)", state->opts->netgroup_map[IPA_AT_NETGROUP_MEMBER_OF].name, dn); if (filter == NULL) { ret = ENOMEM; goto done; } fetch_members = true; } if (!fetch_members) { ret = ipa_netgr_process_all(state); if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } return; } state->filter = talloc_asprintf_append(filter, ")"); if (state->filter == NULL) { ret = ENOMEM; goto done; } if (state->entities_found & ENTITY_NG) { state->netgr_base_iter = 0; ret = ipa_netgr_fetch_netgroups(state, req); if (ret != EOK) goto done; } else if (state->entities_found & ENTITY_USER) { ret = ipa_netgr_fetch_users(state, req); if (ret != EOK) goto done; } else if (state->entities_found & ENTITY_HOST) { ret = ipa_netgr_fetch_hosts(state, req); if (ret != EOK) goto done; } return; done: tevent_req_error(req, ret); return; } static int ipa_netgr_fetch_netgroups(struct ipa_get_netgroups_state *state, struct tevent_req *req) { char *filter; const char *base_filter; struct tevent_req *subreq; struct sdap_search_base **bases; bases = state->ipa_opts->id->sdom->netgroup_search_bases; if (bases[state->netgr_base_iter] == NULL) { /* No more bases to try */ return ENOENT; } base_filter = bases[state->netgr_base_iter]->filter; filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))", state->filter, base_filter?base_filter:"", state->opts->netgroup_map[SDAP_OC_NETGROUP].name); if (filter == NULL) return ENOMEM; subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, bases[state->netgr_base_iter]->basedn, bases[state->netgr_base_iter]->scope, filter, state->attrs, state->opts->netgroup_map, IPA_OPTS_NETGROUP, state->timeout, true); state->current_entity = ENTITY_NG; if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, ipa_netgr_members_process, req); return EOK; } static int ipa_netgr_fetch_users(struct ipa_get_netgroups_state *state, struct tevent_req *req) { const char *attrs[] = { state->opts->user_map[SDAP_AT_USER_NAME].name, state->opts->user_map[SDAP_AT_USER_MEMBEROF].name, "objectclass", NULL }; char *filter; const char *base_filter; struct tevent_req *subreq; struct sdap_search_base **bases; bases = state->ipa_opts->id->sdom->user_search_bases; if (bases[state->user_base_iter] == NULL) { return ENOENT; } base_filter = bases[state->user_base_iter]->filter; filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))", state->filter, base_filter?base_filter:"", state->opts->user_map[SDAP_OC_USER].name); if (filter == NULL) return ENOMEM; subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, dp_opt_get_string(state->opts->basic, SDAP_USER_SEARCH_BASE), LDAP_SCOPE_SUBTREE, filter, attrs, state->opts->user_map, state->opts->user_map_cnt, state->timeout, true); state->current_entity = ENTITY_USER; if (subreq == NULL) { talloc_free(attrs); return ENOMEM; } tevent_req_set_callback(subreq, ipa_netgr_members_process, req); return EOK; } static int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state, struct tevent_req *req) { const char **attrs; char *filter; const char *base_filter; struct tevent_req *subreq; int ret; struct sdap_search_base **bases; bases = state->ipa_opts->host_search_bases; if (bases[state->host_base_iter] == NULL) { return ENOENT; } base_filter = bases[state->host_base_iter]->filter; filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))", state->filter, base_filter?base_filter:"", state->ipa_opts->host_map[IPA_OC_HOST].name); if (filter == NULL) return ENOMEM; ret = build_attrs_from_map(state, state->ipa_opts->host_map, IPA_OPTS_HOST, NULL, &attrs, NULL); if (ret != EOK) { talloc_free(filter); return ret; } subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, bases[state->host_base_iter]->basedn, bases[state->host_base_iter]->scope, filter, attrs, state->ipa_opts->host_map, IPA_OPTS_HOST, state->timeout, true); state->current_entity = ENTITY_HOST; if (subreq == NULL) { talloc_free(filter); return ENOMEM; } tevent_req_set_callback(subreq, ipa_netgr_members_process, req); return EOK; } static void ipa_netgr_members_process(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ipa_get_netgroups_state *state = tevent_req_data(req, struct ipa_get_netgroups_state); struct sysdb_attrs **entities; size_t count; int ret, i; const char *orig_dn; char *orig_dn_lower; hash_table_t *table; hash_key_t key; hash_value_t value; int (* next_call)(struct ipa_get_netgroups_state *, struct tevent_req *); bool next_batch_scheduled = false; ret = sdap_get_generic_recv(subreq, state, &count, &entities); talloc_zfree(subreq); if (ret) { goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "Found %zu members in current search base\n", count); next_call = NULL; /* While processing a batch of entities from one search base, * schedule query for another search base if there is one * * If there is no other search base, another class of entities * will be scheduled for lookup after processing of current * batch. The order of lookup is: netgroups -> users -> hosts */ if (state->current_entity == ENTITY_NG) { /* We just received a batch of netgroups */ state->netgr_base_iter++; ret = ipa_netgr_fetch_netgroups(state, req); table = state->new_netgroups; /* If there is a member netgroup, we always have to * ask for both member users and hosts * -> now schedule users */ next_call = ipa_netgr_fetch_users; } else if (state->current_entity == ENTITY_USER) { /* We just received a batch of users */ state->user_base_iter++; ret = ipa_netgr_fetch_users(state, req); table = state->new_users; if (state->entities_found & ENTITY_HOST || state->entities_found & ENTITY_NG) { next_call = ipa_netgr_fetch_hosts; } } else if (state->current_entity == ENTITY_HOST) { /* We just received a batch of hosts */ state->host_base_iter++; ret = ipa_netgr_fetch_hosts(state, req); table = state->new_hosts; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid entity type given for processing: %d\n", state->current_entity); ret = EINVAL; goto fail; } if (ret == EOK) { /* Next search base has been scheduled for inspection, * don't try to look for other type of entities */ next_batch_scheduled = true; } else if (ret != ENOENT) { goto fail; } /* Process all member entites and store them in the designated hash table */ key.type = HASH_KEY_STRING; value.type = HASH_VALUE_PTR; for (i = 0; i < count; i++) { ret = sysdb_attrs_get_string(entities[i], SYSDB_ORIG_DN, &orig_dn); if (ret != EOK) { goto fail; } orig_dn_lower = talloc_strdup(table, orig_dn); if (orig_dn_lower == NULL) { ret = ENOMEM; goto fail; } /* Transform the DN to lower case. * this is important, as the member/memberof attributes * have the value also in lower-case */ key.str = orig_dn_lower; while (*orig_dn_lower != '\0') { *orig_dn_lower = tolower(*orig_dn_lower); orig_dn_lower++; } value.ptr = entities[i]; ret = hash_enter(table, &key, &value); if (ret != HASH_SUCCESS) { goto fail; } } if (next_batch_scheduled) { /* The next search base is already scheduled to be searched */ return; } if (next_call) { /* There is another class of members that has to be retrieved * - schedule the lookup */ ret = next_call(state, req); if (ret != EOK) goto fail; } else { /* All members, that could have been fetched, were fetched */ ret = ipa_netgr_process_all(state); if (ret != EOK) goto fail; tevent_req_done(req); } return; fail: tevent_req_error(req, ret); return; } static bool extract_netgroups(hash_entry_t *entry, void *pvt) { struct ipa_get_netgroups_state *state; state = talloc_get_type(pvt, struct ipa_get_netgroups_state); state->netgroups[state->netgroups_count] = talloc_get_type(entry->value.ptr, struct sysdb_attrs); state->netgroups_count++; return true; } struct extract_state { const char *group; const char *appropriateMemberOf; const char **entries; int entries_count; }; static bool extract_entities(hash_entry_t *entry, void *pvt) { int ret; struct extract_state *state; struct sysdb_attrs *member; struct ldb_message_element *el; struct ldb_message_element *name_el; state = talloc_get_type(pvt, struct extract_state); member = talloc_get_type(entry->value.ptr, struct sysdb_attrs); ret = sysdb_attrs_get_el(member, state->appropriateMemberOf, &el); if (ret != EOK) { return false; } ret = sysdb_attrs_get_el(member, SYSDB_NAME, &name_el); if (ret != EOK || name_el == NULL || name_el->num_values == 0) { return false; } for (int j = 0; j < el->num_values; j++) { if (strcmp((char *)el->values[j].data, state->group) == 0) { state->entries = talloc_realloc(state, state->entries, const char *, state->entries_count + 1); if (state->entries == NULL) { return false; } state->entries[state->entries_count] = (char *)name_el->values[0].data; state->entries_count++; break; } } return true; } static int extract_members(TALLOC_CTX *mem_ctx, struct sysdb_attrs *netgroup, const char *member_type, const char *appropriateMemberOf, hash_table_t *lookup_table, const char ***_ret_array, int *_ret_count) { struct extract_state *state; struct ldb_message_element *el; struct sysdb_attrs *member; hash_key_t key; hash_value_t value; const char **process = NULL; const char **ret_array = NULL; int process_count = 0; int ret_count = 0; int ret, i, pi; key.type = HASH_KEY_STRING; value.type = HASH_VALUE_PTR; state = talloc_zero(mem_ctx, struct extract_state); if (state == NULL) { ret = ENOMEM; goto done; } state->appropriateMemberOf = appropriateMemberOf; ret = sysdb_attrs_get_el(netgroup, member_type, &el); if (ret != EOK && ret != ENOENT) { goto done; } if (ret == EOK) { for (i = 0; i < el->num_values; i++) { key.str = (char *)el->values[i].data; ret = hash_lookup(lookup_table, &key, &value); if (ret != HASH_SUCCESS && ret != HASH_ERROR_KEY_NOT_FOUND) { ret = ENOENT; goto done; } if (ret == HASH_ERROR_KEY_NOT_FOUND) { process = talloc_realloc(mem_ctx, process, const char *, process_count + 1); if (process == NULL) { ret = ENOMEM; goto done; } process[process_count] = (char *)el->values[i].data; process_count++; } else { ret_array = talloc_realloc(mem_ctx, ret_array, const char *, ret_count + 1); if (ret_array == NULL) { ret = ENOMEM; goto done; } member = talloc_get_type(value.ptr, struct sysdb_attrs); ret = sysdb_attrs_get_string(member, SYSDB_NAME, &ret_array[ret_count]); if (ret != EOK) { goto done; } ret_count++; } for (pi = 0; pi < process_count; pi++) { state->group = process[pi]; hash_iterate(lookup_table, extract_entities, state); if (state->entries_count > 0) { ret_array = talloc_realloc(mem_ctx, ret_array, const char *, ret_count + state->entries_count); if (ret_array == NULL) { ret = ENOMEM; goto done; } memcpy(&ret_array[ret_count], state->entries, state->entries_count*sizeof(const char *)); ret_count += state->entries_count; } state->entries_count = 0; talloc_zfree(state->entries); } } } else { ret_array = NULL; } *_ret_array = ret_array; *_ret_count = ret_count; ret = EOK; done: return ret; } static int ipa_netgr_process_all(struct ipa_get_netgroups_state *state) { int i, j, k, ret; const char **members; struct sysdb_attrs *member; const char *member_name; struct extract_state *extract_state; struct ldb_message_element *external_hosts; const char *dash[] = {"-"}; const char **uids = NULL; const char **hosts = NULL; int uids_count = 0; int hosts_count = 0; hash_key_t key; hash_value_t value; const char *domain; char *triple; state->netgroups = talloc_zero_array(state, struct sysdb_attrs *, hash_count(state->new_netgroups)); if (state->netgroups == NULL) { return ENOMEM; } extract_state = talloc_zero(state, struct extract_state); if (extract_state == NULL) { ret = ENOMEM; goto done; } key.type = HASH_KEY_STRING; value.type = HASH_VALUE_PTR; hash_iterate(state->new_netgroups, extract_netgroups, state); for (i = 0; i < state->netgroups_count; i++) { /* load all its member netgroups, translate */ DEBUG(SSSDBG_TRACE_INTERNAL, "Extracting netgroup members of netgroup %d\n", i); ret = sysdb_attrs_get_string_array(state->netgroups[i], SYSDB_ORIG_NETGROUP_MEMBER, state, &members); if (ret != EOK && ret != ENOENT) { goto done; } j = 0; if (ret == EOK) { for (j = 0; members[j]; j++) { key.str = discard_const(members[j]); ret = hash_lookup(state->new_netgroups, &key, &value); if (ret != HASH_SUCCESS) { ret = ENOENT; goto done; } member = talloc_get_type(value.ptr, struct sysdb_attrs); ret = sysdb_attrs_get_string(member, SYSDB_NAME, &member_name); if (ret != EOK) { goto done; } ret = sysdb_attrs_add_string(state->netgroups[i], SYSDB_NETGROUP_MEMBER, member_name); if (ret != EOK) { goto done; } } talloc_zfree(members); } DEBUG(SSSDBG_TRACE_INTERNAL, "Extracted %d netgroup members\n", j); /* Load all UIDs */ DEBUG(SSSDBG_TRACE_ALL, "Extracting user members of netgroup %d\n", i); ret = extract_members(state, state->netgroups[i], SYSDB_ORIG_MEMBER_USER, state->ipa_opts->id->user_map[SDAP_AT_USER_MEMBEROF].sys_name, state->new_users, &uids, &uids_count); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Extracted %d user members\n", uids_count); DEBUG(SSSDBG_TRACE_ALL, "Extracting host members of netgroup %d\n", i); ret = extract_members(state, state->netgroups[i], SYSDB_ORIG_MEMBER_HOST, state->ipa_opts->host_map[IPA_AT_HOST_MEMBER_OF].sys_name, state->new_hosts, &hosts, &hosts_count); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Extracted %d host members\n", hosts_count); ret = sysdb_attrs_get_el(state->netgroups[i], SYSDB_ORIG_NETGROUP_EXTERNAL_HOST, &external_hosts); if (ret != EOK) { goto done; } if (external_hosts->num_values > 0) { hosts = talloc_realloc(state, hosts, const char *, hosts_count + external_hosts->num_values); if (hosts == NULL) { ret = ENOMEM; goto done; } for (j = 0; j < external_hosts->num_values; j++) { hosts[hosts_count] = talloc_strdup(hosts, (char *)external_hosts->values[j].data); if (hosts[hosts_count] == NULL) { ret = ENOMEM; goto done; } hosts_count++; } } ret = sysdb_attrs_get_string(state->netgroups[i], SYSDB_NETGROUP_DOMAIN, &domain); if (ret != EOK) { goto done; } if (uids_count > 0 || hosts_count > 0) { if (uids_count == 0) { uids_count = 1; uids = dash; } if (hosts_count == 0) { hosts_count = 1; hosts = dash; } DEBUG(SSSDBG_TRACE_INTERNAL, "Putting together triples of " "netgroup %d\n", i); for (j = 0; j < uids_count; j++) { for (k = 0; k < hosts_count; k++) { triple = talloc_asprintf(state, "(%s,%s,%s)", hosts[k], uids[j], domain); if (triple == NULL) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(state->netgroups[i], SYSDB_NETGROUP_TRIPLE, triple); if (ret != EOK) { goto done; } } } } ret = ipa_save_netgroup(state, state->dom, state->opts, state->netgroups[i]); if (ret != EOK) { goto done; } } ret = EOK; done: return ret; } int ipa_get_netgroups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sysdb_attrs ***reply) { struct ipa_get_netgroups_state *state = tevent_req_data(req, struct ipa_get_netgroups_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (reply_count) { *reply_count = state->netgroups_count; } if (reply) { *reply = talloc_steal(mem_ctx, state->netgroups); } return EOK; } sssd-1.13.4/src/providers/ipa/PaxHeaders.16287/ipa_auth.c0000644000000000000000000000007312703456111017637 xustar0029 atime=1460561751.64571561 30 ctime=1460561774.727793876 sssd-1.13.4/src/providers/ipa/ipa_auth.c0000644002412700241270000003532012703456111021312 0ustar00jhrozekjhrozek00000000000000/* SSSD IPA Backend Module -- Authentication Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/util.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" #include "providers/krb5/krb5_auth.h" #include "providers/ipa/ipa_auth.h" #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_config.h" struct get_password_migration_flag_state { struct tevent_context *ev; struct sdap_id_op *sdap_op; struct sdap_id_ctx *sdap_id_ctx; struct fo_server *srv; char *ipa_realm; bool password_migration; }; static void get_password_migration_flag_auth_done(struct tevent_req *subreq); static void get_password_migration_flag_done(struct tevent_req *subreq); static struct tevent_req *get_password_migration_flag_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_id_ctx, char *ipa_realm) { int ret; struct tevent_req *req, *subreq; struct get_password_migration_flag_state *state; if (sdap_id_ctx == NULL || ipa_realm == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing parameter.\n"); return NULL; } req = tevent_req_create(memctx, &state, struct get_password_migration_flag_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->sdap_id_ctx = sdap_id_ctx; state->srv = NULL; state->password_migration = false; state->ipa_realm = ipa_realm; state->sdap_op = sdap_id_op_create(state, state->sdap_id_ctx->conn->conn_cache); if (state->sdap_op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed.\n"); goto fail; } subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (!subreq) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d(%s).\n", ret, strerror(ret)); goto fail; } tevent_req_set_callback(subreq, get_password_migration_flag_auth_done, req); return req; fail: talloc_zfree(req); return NULL; } static void get_password_migration_flag_auth_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct get_password_migration_flag_state *state = tevent_req_data(req, struct get_password_migration_flag_state); int ret, dp_error; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret) { if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_MINOR_FAILURE, "No IPA server is available, cannot get the " "migration flag while offline\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to IPA server: [%d](%s)\n", ret, strerror(ret)); } tevent_req_error(req, ret); return; } subreq = ipa_get_config_send(state, state->ev, sdap_id_op_handle(state->sdap_op), state->sdap_id_ctx->opts, state->ipa_realm, NULL); tevent_req_set_callback(subreq, get_password_migration_flag_done, req); } static void get_password_migration_flag_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct get_password_migration_flag_state *state = tevent_req_data(req, struct get_password_migration_flag_state); int ret; struct sysdb_attrs *reply = NULL; const char *value = NULL; ret = ipa_get_config_recv(subreq, state, &reply); talloc_zfree(subreq); if (ret) { goto done; } ret = sysdb_attrs_get_string(reply, IPA_CONFIG_MIGRATION_ENABLED, &value); if (ret == EOK && strcasecmp(value, "true") == 0) { state->password_migration = true; } done: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } } static int get_password_migration_flag_recv(struct tevent_req *req, bool *password_migration) { struct get_password_migration_flag_state *state = tevent_req_data(req, struct get_password_migration_flag_state); TEVENT_REQ_RETURN_ON_ERROR(req); *password_migration = state->password_migration; return EOK; } struct ipa_auth_state { struct be_req *be_req; struct tevent_context *ev; struct ipa_auth_ctx *ipa_auth_ctx; struct pam_data *pd; bool password_migration; struct sdap_handle *sh; }; static void ipa_auth_handler_done(struct tevent_req *req); static void ipa_get_migration_flag_done(struct tevent_req *req); static void ipa_migration_flag_connect_done(struct tevent_req *req); static void ipa_auth_ldap_done(struct tevent_req *req); static void ipa_auth_handler_retry_done(struct tevent_req *req); void ipa_auth(struct be_req *be_req) { struct tevent_req *req; struct ipa_auth_state *state; struct pam_data *pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); state = talloc_zero(be_req, struct ipa_auth_state); if (state == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); goto fail; } state->password_migration = false; state->sh = NULL; state->be_req = be_req; state->ev = be_ctx->ev; state->pd = pd; switch (state->pd->cmd) { case SSS_PAM_AUTHENTICATE: case SSS_PAM_PREAUTH: state->ipa_auth_ctx = talloc_get_type( be_ctx->bet_info[BET_AUTH].pvt_bet_data, struct ipa_auth_ctx); break; case SSS_PAM_CHAUTHTOK: case SSS_PAM_CHAUTHTOK_PRELIM: state->ipa_auth_ctx = talloc_get_type( be_ctx->bet_info[BET_CHPASS].pvt_bet_data, struct ipa_auth_ctx); break; default: DEBUG(SSSDBG_OP_FAILURE, "Unsupported PAM task.\n"); goto fail; } req = krb5_auth_queue_send(state, state->ev, be_ctx, state->pd, state->ipa_auth_ctx->krb5_auth_ctx); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "krb5_auth_send failed.\n"); goto fail; } tevent_req_set_callback(req, ipa_auth_handler_done, state); return; fail: talloc_free(state); pd->pam_status = PAM_SYSTEM_ERR; be_req_terminate(be_req, DP_ERR_FATAL, pd->pam_status, NULL); } static void ipa_auth_handler_done(struct tevent_req *req) { struct ipa_auth_state *state = tevent_req_callback_data(req, struct ipa_auth_state); int ret; int pam_status = PAM_SYSTEM_ERR; int dp_err; ret = krb5_auth_queue_recv(req, &pam_status, &dp_err); talloc_zfree(req); state->pd->pam_status = pam_status; if (ret != EOK && pam_status != PAM_CRED_ERR) { DEBUG(SSSDBG_OP_FAILURE, "krb5_auth_recv request failed.\n"); dp_err = DP_ERR_OK; goto done; } if (dp_err != DP_ERR_OK) { goto done; } if (state->pd->cmd == SSS_PAM_AUTHENTICATE && state->pd->pam_status == PAM_CRED_ERR) { req = get_password_migration_flag_send(state, state->ev, state->ipa_auth_ctx->sdap_id_ctx, dp_opt_get_string( state->ipa_auth_ctx->ipa_options, IPA_KRB5_REALM)); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "get_password_migration_flag failed.\n"); goto done; } tevent_req_set_callback(req, ipa_get_migration_flag_done, state); return; } done: be_req_terminate(state->be_req, dp_err, state->pd->pam_status, NULL); } static void ipa_get_migration_flag_done(struct tevent_req *req) { struct ipa_auth_state *state = tevent_req_callback_data(req, struct ipa_auth_state); int ret; int dp_err = DP_ERR_FATAL; ret = get_password_migration_flag_recv(req, &state->password_migration); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_password_migration_flag " "request failed.\n"); state->pd->pam_status = PAM_SYSTEM_ERR; dp_err = DP_ERR_OK; goto done; } if (state->password_migration) { req = sdap_cli_connect_send(state, state->ev, state->ipa_auth_ctx->sdap_auth_ctx->opts, state->ipa_auth_ctx->sdap_auth_ctx->be, state->ipa_auth_ctx->sdap_auth_ctx->service, true, CON_TLS_ON, true); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_cli_connect_send failed.\n"); goto done; } tevent_req_set_callback(req, ipa_migration_flag_connect_done, state); return; } DEBUG(SSSDBG_CONF_SETTINGS, "Password migration is not enabled.\n"); dp_err = DP_ERR_OK; done: be_req_terminate(state->be_req, dp_err, state->pd->pam_status, NULL); } static void ipa_migration_flag_connect_done(struct tevent_req *req) { struct ipa_auth_state *state = tevent_req_callback_data(req, struct ipa_auth_state); struct be_ctx *be_ctx = be_req_get_be_ctx(state->be_req); const char **attrs; struct ldb_message *user_msg; const char *dn; int dp_err = DP_ERR_FATAL; int ret; int auth_timeout; ret = sdap_cli_connect_recv(req, state, NULL, &state->sh, NULL); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot connect to LDAP server to perform migration\n"); goto done; } state->pd->pam_status = PAM_SYSTEM_ERR; DEBUG(SSSDBG_TRACE_FUNC, "Assuming Kerberos password is missing, " "starting password migration.\n"); attrs = talloc_array(state, const char *, 2); if (attrs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array failed.\n"); state->pd->pam_status = PAM_SYSTEM_ERR; dp_err = DP_ERR_OK; goto done; } attrs[0] = SYSDB_ORIG_DN; attrs[1] = NULL; ret = sysdb_search_user_by_name(state, be_ctx->domain, state->pd->user, attrs, &user_msg); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_name failed.\n"); goto done; } dn = ldb_msg_find_attr_as_string(user_msg, SYSDB_ORIG_DN, NULL); if (dn == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Missing original DN for user [%s].\n", state->pd->user); state->pd->pam_status = PAM_SYSTEM_ERR; dp_err = DP_ERR_OK; goto done; } auth_timeout = dp_opt_get_int( state->ipa_auth_ctx->sdap_auth_ctx->opts->basic, SDAP_OPT_TIMEOUT); req = sdap_auth_send(state, state->ev, state->sh, NULL, NULL, dn, state->pd->authtok, auth_timeout); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_auth_send failed.\n"); goto done; } tevent_req_set_callback(req, ipa_auth_ldap_done, state); return; done: be_req_terminate(state->be_req, dp_err, state->pd->pam_status, NULL); } static void ipa_auth_ldap_done(struct tevent_req *req) { struct ipa_auth_state *state = tevent_req_callback_data(req, struct ipa_auth_state); struct be_ctx *be_ctx = be_req_get_be_ctx(state->be_req); int ret; int dp_err = DP_ERR_FATAL; ret = sdap_auth_recv(req, state, NULL); talloc_zfree(req); switch (ret) { case EOK: break; case ERR_AUTH_DENIED: case ERR_AUTH_FAILED: case ERR_PASSWORD_EXPIRED: /* TODO: do we need to handle expired passwords? */ DEBUG(SSSDBG_MINOR_FAILURE, "LDAP authentication failed, " "Password migration not possible.\n"); state->pd->pam_status = PAM_CRED_INSUFFICIENT; dp_err = DP_ERR_OK; goto done; default: DEBUG(SSSDBG_OP_FAILURE, "auth_send request failed.\n"); state->pd->pam_status = PAM_SYSTEM_ERR; dp_err = DP_ERR_OK; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "LDAP authentication succeded, " "trying Kerberos authentication again.\n"); req = krb5_auth_queue_send(state, state->ev, be_ctx, state->pd, state->ipa_auth_ctx->krb5_auth_ctx); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "krb5_auth_send failed.\n"); goto done; } tevent_req_set_callback(req, ipa_auth_handler_retry_done, state); return; done: be_req_terminate(state->be_req, dp_err, state->pd->pam_status, NULL); } static void ipa_auth_handler_retry_done(struct tevent_req *req) { struct ipa_auth_state *state = tevent_req_callback_data(req, struct ipa_auth_state); int ret; int pam_status; int dp_err; ret = krb5_auth_queue_recv(req, &pam_status, &dp_err); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "krb5_auth_recv request failed.\n"); state->pd->pam_status = PAM_SYSTEM_ERR; dp_err = DP_ERR_OK; goto done; } state->pd->pam_status = pam_status; done: be_req_terminate(state->be_req, dp_err, state->pd->pam_status, NULL); } sssd-1.13.4/src/providers/PaxHeaders.16287/ldap0000644000000000000000000000013212703463556016002 xustar0030 mtime=1460561774.940794598 30 atime=1460561776.118798593 30 ctime=1460561774.940794598 sssd-1.13.4/src/providers/ldap/0000755002412700241270000000000012703463556017533 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_id_op.c0000644000000000000000000000007312703456111020315 xustar0030 atime=1460561751.649715624 29 ctime=1460561774.79079409 sssd-1.13.4/src/providers/ldap/sdap_id_op.c0000644002412700241270000006737612703456111022010 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP ID backend operation retry logic and connection cache Authors: Eugene Indenbom Copyright (C) 2008-2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_id_op.h" /* LDAP async connection cache */ struct sdap_id_conn_cache { struct sdap_id_conn_ctx *id_conn; /* list of all open connections */ struct sdap_id_conn_data *connections; /* cached (current) connection */ struct sdap_id_conn_data *cached_connection; }; /* LDAP async operation tracker: * - keeps track of connection usage * - keeps track of operation retries */ struct sdap_id_op { /* ID backend context */ struct sdap_id_conn_cache *conn_cache; /* double linked list pointers */ struct sdap_id_op *prev, *next; /* current connection */ struct sdap_id_conn_data *conn_data; /* number of reconnects for this operation */ int reconnect_retry_count; /* connection request * It is required as we need to know which requests to notify * when shared connection request to sdap_handle completes. * This member is cleared when sdap_id_op_connect_state * associated with request is destroyed */ struct tevent_req *connect_req; }; /* LDAP connection cache connection attempt/established connection data */ struct sdap_id_conn_data { /* LDAP connection cache */ struct sdap_id_conn_cache *conn_cache; /* double linked list pointers */ struct sdap_id_conn_data *prev, *next; /* sdap handle */ struct sdap_handle *sh; /* connection request */ struct tevent_req *connect_req; /* timer for connection expiration */ struct tevent_timer *expire_timer; /* number of running connection notifies */ int notify_lock; /* list of operations using connect */ struct sdap_id_op *ops; /* A flag which is signalizing that this * connection will be disconnected and should * not be used any more */ bool disconnecting; }; static void sdap_id_conn_cache_be_offline_cb(void *pvt); static void sdap_id_conn_cache_fo_reconnect_cb(void *pvt); static void sdap_id_release_conn_data(struct sdap_id_conn_data *conn_data); static int sdap_id_conn_data_destroy(struct sdap_id_conn_data *conn_data); static bool sdap_is_connection_expired(struct sdap_id_conn_data *conn_data, int timeout); static bool sdap_can_reuse_connection(struct sdap_id_conn_data *conn_data); static void sdap_id_conn_data_expire_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt); static int sdap_id_conn_data_set_expire_timer(struct sdap_id_conn_data *conn_data); static void sdap_id_op_hook_conn_data(struct sdap_id_op *op, struct sdap_id_conn_data *conn_data); static int sdap_id_op_destroy(void *pvt); static bool sdap_id_op_can_reconnect(struct sdap_id_op *op); static void sdap_id_op_connect_req_complete(struct sdap_id_op *op, int dp_error, int ret); static int sdap_id_op_connect_state_destroy(void *pvt); static int sdap_id_op_connect_step(struct tevent_req *req); static void sdap_id_op_connect_done(struct tevent_req *subreq); /* Create a connection cache */ int sdap_id_conn_cache_create(TALLOC_CTX *memctx, struct sdap_id_ctx *id_ctx, struct sdap_id_conn_ctx *id_conn, struct sdap_id_conn_cache** conn_cache_out) { int ret; struct sdap_id_conn_cache *conn_cache = talloc_zero(memctx, struct sdap_id_conn_cache); if (!conn_cache) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero(struct sdap_id_conn_cache) failed.\n"); ret = ENOMEM; goto fail; } conn_cache->id_conn = id_conn; ret = be_add_offline_cb(conn_cache, id_conn->id_ctx->be, sdap_id_conn_cache_be_offline_cb, conn_cache, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_add_offline_cb failed.\n"); goto fail; } ret = be_add_reconnect_cb(conn_cache, id_conn->id_ctx->be, sdap_id_conn_cache_fo_reconnect_cb, conn_cache, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_add_reconnect_cb failed.\n"); goto fail; } *conn_cache_out = conn_cache; return EOK; fail: talloc_zfree(conn_cache); return ret; } /* Callback on BE going offline */ static void sdap_id_conn_cache_be_offline_cb(void *pvt) { struct sdap_id_conn_cache *conn_cache = talloc_get_type(pvt, struct sdap_id_conn_cache); struct sdap_id_conn_data *cached_connection = conn_cache->cached_connection; /* Release any cached connection on going offline */ if (cached_connection != NULL) { conn_cache->cached_connection = NULL; sdap_id_release_conn_data(cached_connection); } } /* Callback for attempt to reconnect to primary server */ static void sdap_id_conn_cache_fo_reconnect_cb(void *pvt) { struct sdap_id_conn_cache *conn_cache = talloc_get_type(pvt, struct sdap_id_conn_cache); struct sdap_id_conn_data *cached_connection = conn_cache->cached_connection; /* Release any cached connection on going offline */ if (cached_connection != NULL) { cached_connection->disconnecting = true; } } /* Release sdap_id_conn_data and destroy it if no longer needed */ static void sdap_id_release_conn_data(struct sdap_id_conn_data *conn_data) { struct sdap_id_conn_cache *conn_cache; if (!conn_data || conn_data->ops || conn_data->notify_lock) { /* connection is in use */ return; } conn_cache = conn_data->conn_cache; if (conn_data == conn_cache->cached_connection) { return; } DEBUG(SSSDBG_TRACE_ALL, "releasing unused connection\n"); DLIST_REMOVE(conn_cache->connections, conn_data); talloc_zfree(conn_data); } /* Destructor for struct sdap_id_conn_data */ static int sdap_id_conn_data_destroy(struct sdap_id_conn_data *conn_data) { struct sdap_id_op *op; /* we clean out list of ops to make sure that order of destruction does not matter */ while ((op = conn_data->ops) != NULL) { op->conn_data = NULL; DLIST_REMOVE(conn_data->ops, op); } return 0; } /* Check whether connection will expire after timeout seconds */ static bool sdap_is_connection_expired(struct sdap_id_conn_data *conn_data, int timeout) { time_t expire_time; if (!conn_data || !conn_data->sh || !conn_data->sh->connected) { return true; } expire_time = conn_data->sh->expire_time; if ((expire_time != 0) && (expire_time < time( NULL ) + timeout) ) { return true; } return false; } /* Check whether connection can be reused for next LDAP ID operation */ static bool sdap_can_reuse_connection(struct sdap_id_conn_data *conn_data) { int timeout; if (!conn_data || !conn_data->sh || !conn_data->sh->connected || conn_data->disconnecting) { return false; } timeout = dp_opt_get_int(conn_data->conn_cache->id_conn->id_ctx->opts->basic, SDAP_OPT_TIMEOUT); return !sdap_is_connection_expired(conn_data, timeout); } /* Set expiration timer for connection if needed */ static int sdap_id_conn_data_set_expire_timer(struct sdap_id_conn_data *conn_data) { int timeout; struct timeval tv; memset(&tv, 0, sizeof(tv)); tv.tv_sec = conn_data->sh->expire_time; if (tv.tv_sec <= 0) { return EOK; } timeout = dp_opt_get_int(conn_data->conn_cache->id_conn->id_ctx->opts->basic, SDAP_OPT_TIMEOUT); if (timeout > 0) { tv.tv_sec -= timeout; } if (tv.tv_sec <= time(NULL)) { return EOK; } talloc_zfree(conn_data->expire_timer); conn_data->expire_timer = tevent_add_timer(conn_data->conn_cache->id_conn->id_ctx->be->ev, conn_data, tv, sdap_id_conn_data_expire_handler, conn_data); if (!conn_data->expire_timer) { return ENOMEM; } return EOK; } /* Handler for connection expiration timer */ static void sdap_id_conn_data_expire_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { struct sdap_id_conn_data *conn_data = talloc_get_type(pvt, struct sdap_id_conn_data); struct sdap_id_conn_cache *conn_cache = conn_data->conn_cache; DEBUG(SSSDBG_MINOR_FAILURE, "connection is about to expire, releasing it\n"); if (conn_cache->cached_connection == conn_data) { conn_cache->cached_connection = NULL; sdap_id_release_conn_data(conn_data); } } /* Create an operation object */ struct sdap_id_op *sdap_id_op_create(TALLOC_CTX *memctx, struct sdap_id_conn_cache *conn_cache) { struct sdap_id_op *op = talloc_zero(memctx, struct sdap_id_op); if (!op) { return NULL; } op->conn_cache = conn_cache; talloc_set_destructor((void*)op, sdap_id_op_destroy); return op; } /* Attach/detach connection to sdap_id_op */ static void sdap_id_op_hook_conn_data(struct sdap_id_op *op, struct sdap_id_conn_data *conn_data) { if (!op) { DEBUG(SSSDBG_FATAL_FAILURE, "NULL op passed!!!\n"); return; } struct sdap_id_conn_data *current = op->conn_data; if (conn_data == current) { return; } if (current) { DLIST_REMOVE(current->ops, op); } op->conn_data = conn_data; if (conn_data) { DLIST_ADD_END(conn_data->ops, op, struct sdap_id_op*); } if (current) { sdap_id_release_conn_data(current); } } /* Destructor for sdap_id_op */ static int sdap_id_op_destroy(void *pvt) { struct sdap_id_op *op = talloc_get_type(pvt, struct sdap_id_op); if (op->conn_data) { DEBUG(SSSDBG_TRACE_ALL, "releasing operation connection\n"); sdap_id_op_hook_conn_data(op, NULL); } return 0; } /* Check whether retry with reconnect can be performed for the operation */ static bool sdap_id_op_can_reconnect(struct sdap_id_op *op) { /* we allow 2 retries for failover server configured: * - one for connection broken during request execution * - one for the following (probably failed) reconnect attempt */ int max_retries; int count; count = be_fo_get_server_count(op->conn_cache->id_conn->id_ctx->be, op->conn_cache->id_conn->service->name); max_retries = 2 * count -1; if (max_retries < 1) { max_retries = 1; } return op->reconnect_retry_count < max_retries; } /* state of connect request */ struct sdap_id_op_connect_state { struct sdap_id_conn_ctx *id_conn; struct tevent_context *ev; struct sdap_id_op *op; int dp_error; int result; }; /* Destructor for operation connection request */ static int sdap_id_op_connect_state_destroy(void *pvt) { struct sdap_id_op_connect_state *state = talloc_get_type(pvt, struct sdap_id_op_connect_state); if (state->op != NULL) { /* clear destroyed connection request */ state->op->connect_req = NULL; } return 0; } /* Begin to connect to LDAP server */ struct tevent_req *sdap_id_op_connect_send(struct sdap_id_op *op, TALLOC_CTX *memctx, int *ret_out) { struct tevent_req *req = NULL; struct sdap_id_op_connect_state *state; int ret = EOK; if (!memctx) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: no memory context passed.\n"); ret = EINVAL; goto done; } if (op->connect_req) { /* Connection already in progress, invalid operation */ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: connection request is already running or completed and leaked.\n"); ret = EINVAL; goto done; } req = tevent_req_create(memctx, &state, struct sdap_id_op_connect_state); if (!req) { ret = ENOMEM; goto done; } talloc_set_destructor((void*)state, sdap_id_op_connect_state_destroy); state->id_conn = op->conn_cache->id_conn; state->ev = state->id_conn->id_ctx->be->ev; state->op = op; op->connect_req = req; if (op->conn_data) { /* If the operation is already connected, * reuse existing connection regardless of its status */ DEBUG(SSSDBG_TRACE_ALL, "reusing operation connection\n"); ret = EOK; goto done; } ret = sdap_id_op_connect_step(req); if (ret != EOK) { goto done; } done: if (ret != EOK) { talloc_zfree(req); } else if (op->conn_data && !op->conn_data->connect_req) { /* Connection is already established */ tevent_req_done(req); tevent_req_post(req, state->ev); } if (ret_out) { *ret_out = ret; } return req; } /* Begin a connection retry to LDAP server */ static int sdap_id_op_connect_step(struct tevent_req *req) { struct sdap_id_op_connect_state *state = tevent_req_data(req, struct sdap_id_op_connect_state); struct sdap_id_op *op = state->op; struct sdap_id_conn_cache *conn_cache = op->conn_cache; int ret = EOK; struct sdap_id_conn_data *conn_data; struct tevent_req *subreq = NULL; /* Try to reuse context cached connection */ conn_data = conn_cache->cached_connection; if (conn_data) { if (conn_data->connect_req) { DEBUG(SSSDBG_TRACE_ALL, "waiting for connection to complete\n"); sdap_id_op_hook_conn_data(op, conn_data); goto done; } if (sdap_can_reuse_connection(conn_data)) { DEBUG(SSSDBG_TRACE_ALL, "reusing cached connection\n"); sdap_id_op_hook_conn_data(op, conn_data); goto done; } DEBUG(SSSDBG_TRACE_ALL, "releasing expired cached connection\n"); conn_cache->cached_connection = NULL; sdap_id_release_conn_data(conn_data); } DEBUG(SSSDBG_TRACE_ALL, "beginning to connect\n"); conn_data = talloc_zero(conn_cache, struct sdap_id_conn_data); if (!conn_data) { ret = ENOMEM; goto done; } talloc_set_destructor(conn_data, sdap_id_conn_data_destroy); conn_data->conn_cache = conn_cache; subreq = sdap_cli_connect_send(conn_data, state->ev, state->id_conn->id_ctx->opts, state->id_conn->id_ctx->be, state->id_conn->service, false, CON_TLS_DFL, false); if (!subreq) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_id_op_connect_done, conn_data); conn_data->connect_req = subreq; DLIST_ADD(conn_cache->connections, conn_data); conn_cache->cached_connection = conn_data; sdap_id_op_hook_conn_data(op, conn_data); done: if (ret != EOK && conn_data) { sdap_id_release_conn_data(conn_data); } if (ret != EOK) { talloc_zfree(subreq); } return ret; } static void sdap_id_op_connect_reinit_done(struct tevent_req *req); /* Subrequest callback for connection completion */ static void sdap_id_op_connect_done(struct tevent_req *subreq) { struct sdap_id_conn_data *conn_data = tevent_req_callback_data(subreq, struct sdap_id_conn_data); struct sdap_id_conn_cache *conn_cache = conn_data->conn_cache; struct sdap_server_opts *srv_opts = NULL; struct sdap_server_opts *current_srv_opts = NULL; bool can_retry = false; bool is_offline = false; struct tevent_req *reinit_req = NULL; bool reinit = false; int ret; ret = sdap_cli_connect_recv(subreq, conn_data, &can_retry, &conn_data->sh, &srv_opts); conn_data->connect_req = NULL; talloc_zfree(subreq); conn_data->notify_lock++; if (ret == ENOTSUP) { DEBUG(SSSDBG_FATAL_FAILURE, "Authentication mechanism not Supported by server\n"); } if (ret == EOK && (!conn_data->sh || !conn_data->sh->connected)) { DEBUG(SSSDBG_FATAL_FAILURE, "sdap_cli_connect_recv returned bogus connection\n"); ret = EFAULT; } if (ret != EOK && !can_retry) { if (conn_cache->id_conn->ignore_mark_offline) { DEBUG(SSSDBG_TRACE_FUNC, "Failed to connect to server, but ignore mark offline " "is enabled.\n"); } else { /* be is going offline as there is no more servers to try */ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to connect, going offline (%d [%s])\n", ret, strerror(ret)); is_offline = true; be_mark_offline(conn_cache->id_conn->id_ctx->be); } } if (ret == EOK) { current_srv_opts = conn_cache->id_conn->id_ctx->srv_opts; if (current_srv_opts) { DEBUG(SSSDBG_TRACE_INTERNAL, "Old USN: %lu, New USN: %lu\n", current_srv_opts->last_usn, srv_opts->last_usn); if (strcmp(srv_opts->server_id, current_srv_opts->server_id) == 0 && srv_opts->supports_usn && current_srv_opts->last_usn > srv_opts->last_usn) { DEBUG(SSSDBG_FUNC_DATA, "Server was probably re-initialized\n"); current_srv_opts->max_user_value = 0; current_srv_opts->max_group_value = 0; current_srv_opts->max_service_value = 0; current_srv_opts->max_sudo_value = 0; current_srv_opts->last_usn = srv_opts->last_usn; reinit = true; } } ret = sdap_id_conn_data_set_expire_timer(conn_data); sdap_steal_server_opts(conn_cache->id_conn->id_ctx, &srv_opts); } if (can_retry) { switch (ret) { case EOK: case ENOTSUP: case EACCES: case EIO: case EFAULT: case ETIMEDOUT: break; default: /* do not attempt to retry on errors like ENOMEM */ can_retry = false; is_offline = true; be_mark_offline(conn_cache->id_conn->id_ctx->be); break; } } int notify_count = 0; /* Notify about connection */ for(;;) { struct sdap_id_op *op; if (ret == EOK && !conn_data->sh->connected) { DEBUG(SSSDBG_TRACE_ALL, "connection was broken after %d notifies\n", notify_count); } DLIST_FOR_EACH(op, conn_data->ops) { if (op->connect_req) { break; } } if (!op) { break; } /* another operation to notify */ notify_count++; if (ret != EOK || !conn_data->sh->connected) { /* failed to connect or connection got broken during notify */ bool retry = false; /* drop connection from cache now */ if (conn_cache->cached_connection == conn_data) { conn_cache->cached_connection = NULL; } if (can_retry) { /* determining whether retry is possible */ if (be_is_offline(conn_cache->id_conn->id_ctx->be)) { /* be is offline, no retry possible */ if (ret == EOK) { DEBUG(SSSDBG_TRACE_ALL, "skipping automatic retry on op #%d as be is offline\n", notify_count); ret = EIO; } can_retry = false; is_offline = true; } else { if (ret == EOK) { DEBUG(SSSDBG_TRACE_ALL, "attempting automatic retry on op #%d\n", notify_count); retry = true; } else if (sdap_id_op_can_reconnect(op)) { DEBUG(SSSDBG_TRACE_ALL, "attempting failover retry on op #%d\n", notify_count); op->reconnect_retry_count++; retry = true; } } } if (retry && op->connect_req) { int retry_ret = sdap_id_op_connect_step(op->connect_req); if (retry_ret != EOK) { can_retry = false; sdap_id_op_connect_req_complete(op, DP_ERR_FATAL, retry_ret); } continue; } } if (ret == EOK) { DEBUG(SSSDBG_TRACE_ALL, "notify connected to op #%d\n", notify_count); sdap_id_op_connect_req_complete(op, DP_ERR_OK, ret); } else if (is_offline) { DEBUG(SSSDBG_TRACE_ALL, "notify offline to op #%d\n", notify_count); sdap_id_op_connect_req_complete(op, DP_ERR_OFFLINE, EAGAIN); } else { DEBUG(SSSDBG_TRACE_ALL, "notify error to op #%d: %d [%s]\n", notify_count, ret, strerror(ret)); sdap_id_op_connect_req_complete(op, DP_ERR_FATAL, ret); } } /* all operations notified */ if (conn_data->notify_lock > 0) { conn_data->notify_lock--; } if ((ret == EOK) && conn_data->sh->connected && !be_is_offline(conn_cache->id_conn->id_ctx->be)) { DEBUG(SSSDBG_TRACE_ALL, "caching successful connection after %d notifies\n", notify_count); conn_cache->cached_connection = conn_data; /* Run any post-connection routines */ be_run_unconditional_online_cb(conn_cache->id_conn->id_ctx->be); be_run_online_cb(conn_cache->id_conn->id_ctx->be); } else { if (conn_cache->cached_connection == conn_data) { conn_cache->cached_connection = NULL; } sdap_id_release_conn_data(conn_data); } if (reinit) { DEBUG(SSSDBG_TRACE_FUNC, "Server reinitialization detected. " "Cleaning cache.\n"); reinit_req = sdap_reinit_cleanup_send(conn_cache->id_conn->id_ctx->be, conn_cache->id_conn->id_ctx->be, conn_cache->id_conn->id_ctx); if (reinit_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to perform reinitialization " "clean up.\n"); return; } tevent_req_set_callback(reinit_req, sdap_id_op_connect_reinit_done, NULL); } } static void sdap_id_op_connect_reinit_done(struct tevent_req *req) { errno_t ret; ret = sdap_reinit_cleanup_recv(req); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to perform reinitialization " "clean up [%d]: %s\n", ret, strerror(ret)); /* not fatal */ return; } DEBUG(SSSDBG_TRACE_FUNC, "Reinitialization clean up completed\n"); } /* Mark operation connection request as complete */ static void sdap_id_op_connect_req_complete(struct sdap_id_op *op, int dp_error, int ret) { struct tevent_req *req = op->connect_req; struct sdap_id_op_connect_state *state; if (!req) { return; } op->connect_req = NULL; state = tevent_req_data(req, struct sdap_id_op_connect_state); state->dp_error = dp_error; state->result = ret; if (ret == EOK) { tevent_req_done(req); } else { sdap_id_op_hook_conn_data(op, NULL); tevent_req_error(req, ret); } } /* Get the result of an asynchronous connect operation on sdap_id_op * * In dp_error data provider error code is returned: * DP_ERR_OK - connection established * DP_ERR_OFFLINE - backend is offline, operation result is set EAGAIN * DP_ERR_FATAL - operation failed */ int sdap_id_op_connect_recv(struct tevent_req *req, int *dp_error) { struct sdap_id_op_connect_state *state = tevent_req_data(req, struct sdap_id_op_connect_state); *dp_error = state->dp_error; return state->result; } /* Report completion of LDAP operation and release associated connection. * Returns operation result (possible updated) passed in ret parameter. * * In dp_error data provider error code is returned: * DP_ERR_OK (operation result = EOK) - operation completed * DP_ERR_OK (operation result != EOK) - operation can be retried * DP_ERR_OFFLINE - backend is offline, operation result is set EAGAIN * DP_ERR_FATAL - operation failed */ int sdap_id_op_done(struct sdap_id_op *op, int retval, int *dp_err_out) { bool communication_error; struct sdap_id_conn_data *current_conn = op->conn_data; switch (retval) { case EIO: case ETIMEDOUT: /* this currently the only possible communication error after connection is established */ communication_error = true; break; default: communication_error = false; break; } if (communication_error && current_conn != 0 && current_conn == op->conn_cache->cached_connection) { /* do not reuse failed connection */ op->conn_cache->cached_connection = NULL; DEBUG(SSSDBG_FUNC_DATA, "communication error on cached connection, moving to next server\n"); be_fo_try_next_server(op->conn_cache->id_conn->id_ctx->be, op->conn_cache->id_conn->service->name); } int dp_err; if (retval == EOK) { dp_err = DP_ERR_OK; } else if (be_is_offline(op->conn_cache->id_conn->id_ctx->be)) { /* if backend is already offline, just report offline, do not duplicate errors */ dp_err = DP_ERR_OFFLINE; retval = EAGAIN; DEBUG(SSSDBG_TRACE_ALL, "falling back to offline data...\n"); } else if (communication_error) { /* communication error, can try to reconnect */ if (!sdap_id_op_can_reconnect(op)) { dp_err = DP_ERR_FATAL; DEBUG(SSSDBG_TRACE_ALL, "too many communication failures, giving up...\n"); } else { dp_err = DP_ERR_OK; retval = EAGAIN; } } else { dp_err = DP_ERR_FATAL; } if (dp_err == DP_ERR_OK && retval != EOK) { /* reconnect retry */ op->reconnect_retry_count++; DEBUG(SSSDBG_TRACE_ALL, "advising for connection retry #%i\n", op->reconnect_retry_count); } else { /* end of request */ op->reconnect_retry_count = 0; } if (current_conn) { DEBUG(SSSDBG_TRACE_ALL, "releasing operation connection\n"); sdap_id_op_hook_conn_data(op, NULL); } *dp_err_out = dp_err; return retval; } /* Get SDAP handle associated with operation by sdap_id_op_connect */ struct sdap_handle *sdap_id_op_handle(struct sdap_id_op *op) { return op && op->conn_data ? op->conn_data->sh : NULL; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_ad_groups.c0000644000000000000000000000007212703456111021205 xustar0029 atime=1460561751.64871562 29 ctime=1460561774.78779408 sssd-1.13.4/src/providers/ldap/sdap_ad_groups.c0000644002412700241270000000451112703456111022657 0ustar00jhrozekjhrozek00000000000000/* SSSD AD groups helper routines Authors: Lukas Slebodnik Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "db/sysdb.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_async_private.h" /* ==Group-Parsing Routines=============================================== */ errno_t sdap_check_ad_group_type(struct sss_domain_info *dom, struct sdap_options *opts, struct sysdb_attrs *group_attrs, const char *group_name, bool *_need_filter) { int32_t ad_group_type; errno_t ret = EOK; *_need_filter = false; if (opts->schema_type == SDAP_SCHEMA_AD) { ret = sysdb_attrs_get_int32_t(group_attrs, SYSDB_GROUP_TYPE, &ad_group_type); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_int32_t failed.\n"); return ret; } DEBUG(SSSDBG_TRACE_ALL, "AD group [%s] has type flags %#x.\n", group_name, ad_group_type); /* Only security groups from AD are considered for POSIX groups. * Additionally only global and universal group are taken to account * for trusted domains. */ if (!(ad_group_type & SDAP_AD_GROUP_TYPE_SECURITY) || (IS_SUBDOMAIN(dom) && (!((ad_group_type & SDAP_AD_GROUP_TYPE_GLOBAL) || (ad_group_type & SDAP_AD_GROUP_TYPE_UNIVERSAL))))) { DEBUG(SSSDBG_TRACE_FUNC, "Filtering AD group [%s].\n", group_name); *_need_filter = true; } } return ret; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async.c0000644000000000000000000000007312703456111020340 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.779794053 sssd-1.13.4/src/providers/ldap/sdap_async.c0000644002412700241270000027175212703456111022026 0ustar00jhrozekjhrozek00000000000000/* SSSD Async LDAP Helper routines Copyright (C) Simo Sorce - 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "util/strtonum.h" #include "providers/ldap/sdap_async_private.h" #define REPLY_REALLOC_INCREMENT 10 /* ==LDAP-Memory-Handling================================================= */ static int lmsg_destructor(void *mem) { ldap_msgfree((LDAPMessage *)mem); return 0; } static int sdap_msg_attach(TALLOC_CTX *memctx, LDAPMessage *msg) { void *h; if (!msg) return EINVAL; h = sss_mem_attach(memctx, msg, lmsg_destructor); if (!h) return ENOMEM; return EOK; } /* ==sdap-hanlde-utility-functions======================================== */ static inline void sdap_handle_release(struct sdap_handle *sh); static int sdap_handle_destructor(void *mem); struct sdap_handle *sdap_handle_create(TALLOC_CTX *memctx) { struct sdap_handle *sh; sh = talloc_zero(memctx, struct sdap_handle); if (!sh) return NULL; talloc_set_destructor((TALLOC_CTX *)sh, sdap_handle_destructor); return sh; } static int sdap_handle_destructor(void *mem) { struct sdap_handle *sh = talloc_get_type(mem, struct sdap_handle); /* if the structure is currently locked, then mark it to be released * and prevent talloc from freeing the memory */ if (sh->destructor_lock) { sh->release_memory = true; return -1; } sdap_handle_release(sh); return 0; } static void sdap_handle_release(struct sdap_handle *sh) { struct sdap_op *op; DEBUG(SSSDBG_TRACE_INTERNAL, "Trace: sh[%p], connected[%d], ops[%p], ldap[%p], " "destructor_lock[%d], release_memory[%d]\n", sh, (int)sh->connected, sh->ops, sh->ldap, (int)sh->destructor_lock, (int)sh->release_memory); if (sh->destructor_lock) return; sh->destructor_lock = true; /* make sure nobody tries to reuse this connection from now on */ sh->connected = false; remove_ldap_connection_callbacks(sh); while (sh->ops) { op = sh->ops; op->callback(op, NULL, EIO, op->data); /* calling the callback may result in freeing the op */ /* check if it is still the same or avoid freeing */ if (op == sh->ops) talloc_free(op); } if (sh->ldap) { ldap_unbind_ext(sh->ldap, NULL, NULL); sh->ldap = NULL; } /* ok, we have done the job, unlock now */ sh->destructor_lock = false; /* finally if a destructor was ever called, free sh before * exiting */ if (sh->release_memory) { /* neutralize the destructor as we already handled * all was needed to be released */ talloc_set_destructor((TALLOC_CTX *)sh, NULL); talloc_free(sh); } } /* ==Parse-Results-And-Handle-Disconnections============================== */ static void sdap_process_message(struct tevent_context *ev, struct sdap_handle *sh, LDAPMessage *msg); static void sdap_process_result(struct tevent_context *ev, void *pvt); static void sdap_process_next_reply(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt); void sdap_ldap_result(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *pvt) { sdap_process_result(ev, pvt); } static void sdap_ldap_next_result(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { sdap_process_result(ev, pvt); } static void sdap_process_result(struct tevent_context *ev, void *pvt) { struct sdap_handle *sh = talloc_get_type(pvt, struct sdap_handle); struct timeval no_timeout = {0, 0}; struct tevent_timer *te; LDAPMessage *msg; int ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Trace: sh[%p], connected[%d], ops[%p], ldap[%p]\n", sh, (int)sh->connected, sh->ops, sh->ldap); if (!sh->connected || !sh->ldap) { DEBUG(SSSDBG_OP_FAILURE, "ERROR: LDAP connection is not connected!\n"); sdap_handle_release(sh); return; } ret = ldap_result(sh->ldap, LDAP_RES_ANY, 0, &no_timeout, &msg); if (ret == 0) { /* this almost always means we have reached the end of * the list of received messages */ DEBUG(SSSDBG_TRACE_INTERNAL, "Trace: ldap_result found nothing!\n"); return; } if (ret == -1) { ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &ret); DEBUG(SSSDBG_OP_FAILURE, "ldap_result error: [%s]\n", ldap_err2string(ret)); sdap_handle_release(sh); return; } /* We don't know if this will be the last result. * * important: we must do this before actually processing the message * because the message processing might even free the sdap_handler * so it must be the last operation. * FIXME: use tevent_immediate/tevent_queues, when avilable */ memset(&no_timeout, 0, sizeof(struct timeval)); te = tevent_add_timer(ev, sh, no_timeout, sdap_ldap_next_result, sh); if (!te) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add critical timer to fetch next result!\n"); } /* now process this message */ sdap_process_message(ev, sh, msg); } static const char *sdap_ldap_result_str(int msgtype) { switch (msgtype) { case LDAP_RES_BIND: return "LDAP_RES_BIND"; case LDAP_RES_SEARCH_ENTRY: return "LDAP_RES_SEARCH_ENTRY"; case LDAP_RES_SEARCH_REFERENCE: return "LDAP_RES_SEARCH_REFERENCE"; case LDAP_RES_SEARCH_RESULT: return "LDAP_RES_SEARCH_RESULT"; case LDAP_RES_MODIFY: return "LDAP_RES_MODIFY"; case LDAP_RES_ADD: return "LDAP_RES_ADD"; case LDAP_RES_DELETE: return "LDAP_RES_DELETE"; case LDAP_RES_MODDN: /* These are the same result case LDAP_RES_MODRDN: case LDAP_RES_RENAME: */ return "LDAP_RES_RENAME"; case LDAP_RES_COMPARE: return "LDAP_RES_COMPARE"; case LDAP_RES_EXTENDED: return "LDAP_RES_EXTENDED"; case LDAP_RES_INTERMEDIATE: return "LDAP_RES_INTERMEDIATE"; case LDAP_RES_ANY: return "LDAP_RES_ANY"; case LDAP_RES_UNSOLICITED: return "LDAP_RES_UNSOLICITED"; default: /* Unmatched, fall through */ break; } /* Unknown result type */ return "Unknown result type!"; } /* process a messgae calling the right operation callback. * msg is completely taken care of (including freeeing it) * NOTE: this function may even end up freeing the sdap_handle * so sdap_hanbdle must not be used after this function is called */ static void sdap_process_message(struct tevent_context *ev, struct sdap_handle *sh, LDAPMessage *msg) { struct sdap_msg *reply; struct sdap_op *op; int msgid; int msgtype; int ret; msgid = ldap_msgid(msg); if (msgid == -1) { DEBUG(SSSDBG_OP_FAILURE, "can't fire callback, message id invalid!\n"); ldap_msgfree(msg); return; } msgtype = ldap_msgtype(msg); for (op = sh->ops; op; op = op->next) { if (op->msgid == msgid) break; } if (op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Unmatched msgid, discarding message (type: %0x)\n", msgtype); ldap_msgfree(msg); return; } /* shouldn't happen */ if (op->done) { DEBUG(SSSDBG_OP_FAILURE, "Operation [%p] already handled (type: %0x)\n", op, msgtype); ldap_msgfree(msg); return; } DEBUG(SSSDBG_TRACE_ALL, "Message type: [%s]\n", sdap_ldap_result_str(msgtype)); switch (msgtype) { case LDAP_RES_SEARCH_ENTRY: case LDAP_RES_SEARCH_REFERENCE: /* go and process entry */ break; case LDAP_RES_BIND: case LDAP_RES_SEARCH_RESULT: case LDAP_RES_MODIFY: case LDAP_RES_ADD: case LDAP_RES_DELETE: case LDAP_RES_MODDN: case LDAP_RES_COMPARE: case LDAP_RES_EXTENDED: case LDAP_RES_INTERMEDIATE: /* no more results expected with this msgid */ op->done = true; break; default: /* unkwon msg type ?? */ DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't figure out the msg type! [%0x]\n", msgtype); ldap_msgfree(msg); return; } reply = talloc_zero(op, struct sdap_msg); if (!reply) { ldap_msgfree(msg); ret = ENOMEM; } else { reply->msg = msg; ret = sdap_msg_attach(reply, msg); if (ret != EOK) { ldap_msgfree(msg); talloc_zfree(reply); } } if (op->list) { /* list exist, queue it */ op->last->next = reply; op->last = reply; } else { /* create list, then call callback */ op->list = op->last = reply; /* must be the last operation as it may end up freeing all memory * including all ops handlers */ op->callback(op, reply, ret, op->data); } } static void sdap_unlock_next_reply(struct sdap_op *op) { struct timeval tv; struct tevent_timer *te; struct sdap_msg *next_reply; if (op->list) { next_reply = op->list->next; /* get rid of the previous reply, it has been processed already */ talloc_zfree(op->list); op->list = next_reply; } /* if there are still replies to parse, queue a new operation */ if (op->list) { /* use a very small timeout, so that fd operations have a chance to be * served while processing a long reply */ tv = tevent_timeval_current(); /* wait 5 microsecond */ tv.tv_usec += 5; tv.tv_sec += tv.tv_usec / 1000000; tv.tv_usec = tv.tv_usec % 1000000; te = tevent_add_timer(op->ev, op, tv, sdap_process_next_reply, op); if (!te) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add critical timer for next reply!\n"); op->callback(op, NULL, EFAULT, op->data); } } } static void sdap_process_next_reply(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct sdap_op *op = talloc_get_type(pvt, struct sdap_op); op->callback(op, op->list, EOK, op->data); } /* ==LDAP-Operations-Helpers============================================== */ static int sdap_op_destructor(void *mem) { struct sdap_op *op = (struct sdap_op *)mem; DLIST_REMOVE(op->sh->ops, op); if (op->done) { DEBUG(SSSDBG_TRACE_INTERNAL, "Operation %d finished\n", op->msgid); return 0; } /* we don't check the result here, if a message was really abandoned, * hopefully the server will get an abandon. * If the operation was already fully completed, this is going to be * just a noop */ DEBUG(SSSDBG_TRACE_LIBS, "Abandoning operation %d\n", op->msgid); ldap_abandon_ext(op->sh->ldap, op->msgid, NULL, NULL); return 0; } static void sdap_op_timeout(struct tevent_req *req) { struct sdap_op *op = tevent_req_callback_data(req, struct sdap_op); /* should never happen, but just in case */ if (op->done) { DEBUG(SSSDBG_OP_FAILURE, "Timeout happened after op was finished !?\n"); return; } /* signal the caller that we have a timeout */ DEBUG(SSSDBG_TRACE_LIBS, "Issuing timeout for %d\n", op->msgid); op->callback(op, NULL, ETIMEDOUT, op->data); } int sdap_op_add(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_handle *sh, int msgid, sdap_op_callback_t *callback, void *data, int timeout, struct sdap_op **_op) { struct sdap_op *op; op = talloc_zero(memctx, struct sdap_op); if (!op) return ENOMEM; op->sh = sh; op->msgid = msgid; op->callback = callback; op->data = data; op->ev = ev; DEBUG(SSSDBG_TRACE_INTERNAL, "New operation %d timeout %d\n", op->msgid, timeout); /* check if we need to set a timeout */ if (timeout) { struct tevent_req *req; struct timeval tv; tv = tevent_timeval_current(); tv = tevent_timeval_add(&tv, timeout, 0); /* allocate on op, so when it get freed the timeout is removed */ req = tevent_wakeup_send(op, ev, tv); if (!req) { talloc_zfree(op); return ENOMEM; } tevent_req_set_callback(req, sdap_op_timeout, op); } DLIST_ADD(sh->ops, op); talloc_set_destructor((TALLOC_CTX *)op, sdap_op_destructor); *_op = op; return EOK; } /* ==Modify-Password====================================================== */ struct sdap_exop_modify_passwd_state { struct sdap_handle *sh; struct sdap_op *op; char *user_error_message; }; static void sdap_exop_modify_passwd_done(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt); struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_handle *sh, char *user_dn, const char *password, const char *new_password, int timeout) { struct tevent_req *req = NULL; struct sdap_exop_modify_passwd_state *state; int ret; BerElement *ber = NULL; struct berval *bv = NULL; int msgid; LDAPControl **request_controls = NULL; LDAPControl *ctrls[2] = { NULL, NULL }; req = tevent_req_create(memctx, &state, struct sdap_exop_modify_passwd_state); if (!req) return NULL; state->sh = sh; state->user_error_message = NULL; ber = ber_alloc_t( LBER_USE_DER ); if (ber == NULL) { DEBUG(SSSDBG_TRACE_LIBS, "ber_alloc_t failed.\n"); talloc_zfree(req); return NULL; } ret = ber_printf( ber, "{tststs}", LDAP_TAG_EXOP_MODIFY_PASSWD_ID, user_dn, LDAP_TAG_EXOP_MODIFY_PASSWD_OLD, password, LDAP_TAG_EXOP_MODIFY_PASSWD_NEW, new_password); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "ber_printf failed.\n"); ber_free(ber, 1); talloc_zfree(req); return NULL; } ret = ber_flatten(ber, &bv); ber_free(ber, 1); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "ber_flatten failed.\n"); talloc_zfree(req); return NULL; } ret = sdap_control_create(state->sh, LDAP_CONTROL_PASSWORDPOLICYREQUEST, 0, NULL, 0, &ctrls[0]); if (ret != LDAP_SUCCESS && ret != LDAP_NOT_SUPPORTED) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_control_create failed to create " "Password Policy control.\n"); ret = ERR_INTERNAL; goto fail; } request_controls = ctrls; DEBUG(SSSDBG_CONF_SETTINGS, "Executing extended operation\n"); ret = ldap_extended_operation(state->sh->ldap, LDAP_EXOP_MODIFY_PASSWD, bv, request_controls, NULL, &msgid); ber_bvfree(bv); if (ctrls[0]) ldap_control_free(ctrls[0]); if (ret == -1 || msgid == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_extended_operation failed\n"); ret = ERR_NETWORK_IO; goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "ldap_extended_operation sent, msgid = %d\n", msgid); ret = sdap_op_add(state, ev, state->sh, msgid, sdap_exop_modify_passwd_done, req, timeout, &state->op); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set up operation!\n"); ret = ERR_INTERNAL; goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void sdap_exop_modify_passwd_done(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct sdap_exop_modify_passwd_state *state = tevent_req_data(req, struct sdap_exop_modify_passwd_state); char *errmsg = NULL; int ret; LDAPControl **response_controls = NULL; int c; ber_int_t pp_grace; ber_int_t pp_expire; LDAPPasswordPolicyError pp_error; int result; if (error) { tevent_req_error(req, error); return; } ret = ldap_parse_result(state->sh->ldap, reply->msg, &result, NULL, &errmsg, NULL, &response_controls, 0); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldap_parse_result failed (%d)\n", state->op->msgid); ret = ERR_INTERNAL; goto done; } if (response_controls == NULL) { DEBUG(SSSDBG_FUNC_DATA, "Server returned no controls.\n"); } else { for (c = 0; response_controls[c] != NULL; c++) { DEBUG(SSSDBG_TRACE_ALL, "Server returned control [%s].\n", response_controls[c]->ldctl_oid); if (strcmp(response_controls[c]->ldctl_oid, LDAP_CONTROL_PASSWORDPOLICYRESPONSE) == 0) { ret = ldap_parse_passwordpolicy_control(state->sh->ldap, response_controls[c], &pp_expire, &pp_grace, &pp_error); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_parse_passwordpolicy_control failed.\n"); ret = ERR_NETWORK_IO; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Password Policy Response: expire [%d] grace [%d] " "error [%s].\n", pp_expire, pp_grace, ldap_passwordpolicy_err2txt(pp_error)); } } } DEBUG(SSSDBG_MINOR_FAILURE, "ldap_extended_operation result: %s(%d), %s\n", sss_ldap_err2string(result), result, errmsg); switch (result) { case LDAP_SUCCESS: ret = EOK; break; case LDAP_CONSTRAINT_VIOLATION: if (errmsg && strlen(errmsg) != 0) { state->user_error_message = talloc_strdup(state, errmsg); } else { state->user_error_message = talloc_strdup(state, "Please make sure the password meets the " "complexity constraints."); } if (state->user_error_message == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed\n"); ret = ENOMEM; goto done; } ret = ERR_CHPASS_DENIED; break; default: if (errmsg) { state->user_error_message = talloc_strdup(state, errmsg); if (state->user_error_message == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } ret = ERR_NETWORK_IO; break; } done: ldap_controls_free(response_controls); ldap_memfree(errmsg); if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } errno_t sdap_exop_modify_passwd_recv(struct tevent_req *req, TALLOC_CTX * mem_ctx, char **user_error_message) { struct sdap_exop_modify_passwd_state *state = tevent_req_data(req, struct sdap_exop_modify_passwd_state); *user_error_message = talloc_steal(mem_ctx, state->user_error_message); TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==Update-passwordLastChanged-attribute====================== */ struct update_last_changed_state { struct tevent_context *ev; struct sdap_handle *sh; struct sdap_op *op; const char *dn; LDAPMod **mods; }; static void sdap_modify_shadow_lastchange_done(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt); struct tevent_req * sdap_modify_shadow_lastchange_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, const char *dn, char *lastchanged_name) { struct tevent_req *req; struct update_last_changed_state *state; char **values; errno_t ret; int msgid; req = tevent_req_create(mem_ctx, &state, struct update_last_changed_state); if (req == NULL) { return NULL; } state->ev = ev; state->sh = sh; state->dn = dn; state->mods = talloc_zero_array(state, LDAPMod *, 2); if (state->mods == NULL) { ret = ENOMEM; goto done; } state->mods[0] = talloc_zero(state->mods, LDAPMod); state->mods[1] = talloc_zero(state->mods, LDAPMod); if (!state->mods[0] || !state->mods[1]) { ret = ENOMEM; goto done; } values = talloc_zero_array(state->mods[0], char *, 2); if (values == NULL) { ret = ENOMEM; goto done; } /* The attribute contains number of days since the epoch */ values[0] = talloc_asprintf(values, "%ld", (long)time(NULL)/86400); if (values[0] == NULL) { ret = ENOMEM; goto done; } state->mods[0]->mod_op = LDAP_MOD_REPLACE; state->mods[0]->mod_type = lastchanged_name; state->mods[0]->mod_vals.modv_strvals = values; state->mods[1] = NULL; ret = ldap_modify_ext(state->sh->ldap, state->dn, state->mods, NULL, NULL, &msgid); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to send operation!\n"); goto done; } ret = sdap_op_add(state, state->ev, state->sh, msgid, sdap_modify_shadow_lastchange_done, req, 5, &state->op); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set up operation!\n"); goto done; } done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void sdap_modify_shadow_lastchange_done(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct update_last_changed_state *state; state = tevent_req_data(req, struct update_last_changed_state); char *errmsg; int result; errno_t ret = EOK; int lret; if (error) { tevent_req_error(req, error); return; } lret = ldap_parse_result(state->sh->ldap, reply->msg, &result, NULL, &errmsg, NULL, NULL, 0); if (lret != LDAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldap_parse_result failed (%d)\n", state->op->msgid); ret = EIO; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Updating lastPwdChange result: %s(%d), %s\n", sss_ldap_err2string(result), result, errmsg); done: ldap_memfree(errmsg); if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } errno_t sdap_modify_shadow_lastchange_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==Fetch-RootDSE============================================= */ struct sdap_get_rootdse_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; struct sysdb_attrs *rootdse; }; static void sdap_get_rootdse_done(struct tevent_req *subreq); static void sdap_get_matching_rule_done(struct tevent_req *subreq); struct tevent_req *sdap_get_rootdse_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh) { struct tevent_req *req, *subreq; struct sdap_get_rootdse_state *state; const char *attrs[] = { "*", "altServer", SDAP_ROOTDSE_ATTR_NAMING_CONTEXTS, "supportedControl", "supportedExtension", "supportedFeatures", "supportedLDAPVersion", "supportedSASLMechanisms", SDAP_ROOTDSE_ATTR_AD_VERSION, SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT, SDAP_IPA_LAST_USN, SDAP_AD_LAST_USN, NULL }; DEBUG(SSSDBG_TRACE_ALL, "Getting rootdse\n"); req = tevent_req_create(memctx, &state, struct sdap_get_rootdse_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->sh = sh; state->rootdse = NULL; subreq = sdap_get_generic_send(state, ev, opts, sh, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, NULL, 0, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (!subreq) { talloc_zfree(req); return NULL; } tevent_req_set_callback(subreq, sdap_get_rootdse_done, req); return req; } /* This is not a real attribute, it's just there to avoid * actually pulling real data down, to save bandwidth */ #define SDAP_MATCHING_RULE_TEST_ATTR "sssmatchingruletest" static void sdap_get_rootdse_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_rootdse_state *state = tevent_req_data(req, struct sdap_get_rootdse_state); struct sysdb_attrs **results; size_t num_results; int ret; const char *filter; const char *attrs[] = { SDAP_MATCHING_RULE_TEST_ATTR, NULL }; ret = sdap_get_generic_recv(subreq, state, &num_results, &results); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } if (num_results == 0 || !results) { DEBUG(SSSDBG_OP_FAILURE, "RootDSE could not be retrieved. " "Please check that anonymous access to RootDSE is allowed\n" ); tevent_req_error(req, ENOENT); return; } if (num_results > 1) { DEBUG(SSSDBG_OP_FAILURE, "Multiple replies when searching for RootDSE ??\n"); tevent_req_error(req, EIO); return; } state->rootdse = talloc_steal(state, results[0]); talloc_zfree(results); DEBUG(SSSDBG_TRACE_INTERNAL, "Got rootdse\n"); /* Auto-detect the ldap matching rule if requested */ if ((!dp_opt_get_bool(state->opts->basic, SDAP_AD_MATCHING_RULE_INITGROUPS)) && !dp_opt_get_bool(state->opts->basic, SDAP_AD_MATCHING_RULE_GROUPS)) { /* This feature is disabled for both groups * and initgroups. Skip the auto-detection * lookup. */ DEBUG(SSSDBG_TRACE_INTERNAL, "Skipping auto-detection of match rule\n"); tevent_req_done(req); return; } DEBUG(SSSDBG_TRACE_INTERNAL, "Auto-detecting support for match rule\n"); /* Create a filter using the matching rule. It need not point * at any valid data. We're only going to be looking for the * error code. */ filter = "("SDAP_MATCHING_RULE_TEST_ATTR":" SDAP_MATCHING_RULE_IN_CHAIN":=)"; /* Perform a trivial query with the matching rule in play. * If it returns success, we know it is available. If it * returns EIO, we know it isn't. */ subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, "", LDAP_SCOPE_BASE, filter, attrs, NULL, 0, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_get_matching_rule_done, req); } static void sdap_get_matching_rule_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_rootdse_state *state = tevent_req_data(req, struct sdap_get_rootdse_state); size_t num_results; struct sysdb_attrs **results; ret = sdap_get_generic_recv(subreq, state, &num_results, &results); talloc_zfree(subreq); if (ret == EOK) { /* The search succeeded */ state->opts->support_matching_rule = true; } else if (ret == EIO) { /* The search failed. Disable support for * matching rule lookups. */ state->opts->support_matching_rule = false; } else { DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected error while testing for matching rule support\n"); tevent_req_error(req, ret); return; } DEBUG(SSSDBG_CONF_SETTINGS, "LDAP server %s the matching rule extension\n", state->opts->support_matching_rule ? "supports" : "does not support"); tevent_req_done(req); } int sdap_get_rootdse_recv(struct tevent_req *req, TALLOC_CTX *memctx, struct sysdb_attrs **rootdse) { struct sdap_get_rootdse_state *state = tevent_req_data(req, struct sdap_get_rootdse_state); TEVENT_REQ_RETURN_ON_ERROR(req); *rootdse = talloc_steal(memctx, state->rootdse); return EOK; } /* ==Helpers for parsing replies============================== */ struct sdap_reply { size_t reply_max; size_t reply_count; struct sysdb_attrs **reply; }; static errno_t add_to_reply(TALLOC_CTX *mem_ctx, struct sdap_reply *sreply, struct sysdb_attrs *msg) { if (sreply->reply == NULL || sreply->reply_max == sreply->reply_count) { sreply->reply_max += REPLY_REALLOC_INCREMENT; sreply->reply = talloc_realloc(mem_ctx, sreply->reply, struct sysdb_attrs *, sreply->reply_max); if (sreply->reply == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_realloc failed.\n"); return ENOMEM; } } sreply->reply[sreply->reply_count++] = talloc_steal(sreply->reply, msg); return EOK; } struct sdap_deref_reply { size_t reply_max; size_t reply_count; struct sdap_deref_attrs **reply; }; static errno_t add_to_deref_reply(TALLOC_CTX *mem_ctx, int num_maps, struct sdap_deref_reply *dreply, struct sdap_deref_attrs **res) { int i; if (res == NULL) { /* Nothing to add, probably ACIs prevented us from dereferencing * the attribute */ return EOK; } for (i=0; i < num_maps; i++) { if (res[i]->attrs == NULL) continue; /* Nothing in this map */ if (dreply->reply == NULL || dreply->reply_max == dreply->reply_count) { dreply->reply_max += REPLY_REALLOC_INCREMENT; dreply->reply = talloc_realloc(mem_ctx, dreply->reply, struct sdap_deref_attrs *, dreply->reply_max); if (dreply->reply == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_realloc failed.\n"); return ENOMEM; } } dreply->reply[dreply->reply_count++] = talloc_steal(dreply->reply, res[i]); } return EOK; } static void sdap_print_server(struct sdap_handle *sh) { int ret; int fd; struct sockaddr_storage ss; socklen_t ss_len = sizeof(ss); char ip[NI_MAXHOST]; if (!DEBUG_IS_SET(SSSDBG_TRACE_INTERNAL)) { return; } ret = get_fd_from_ldap(sh->ldap, &fd); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "cannot get sdap fd\n"); return; } ret = getpeername(fd, (struct sockaddr *) &ss, &ss_len); if (ret == -1) { DEBUG(SSSDBG_MINOR_FAILURE, "getsockname failed\n"); return; } ret = getnameinfo((struct sockaddr *) &ss, ss_len, ip, sizeof(ip), NULL, 0, NI_NUMERICHOST); if (ret != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "getnameinfo failed\n"); return; } DEBUG(SSSDBG_TRACE_INTERNAL, "Searching %s\n", ip); } /* ==Generic Search exposing all options======================= */ typedef errno_t (*sdap_parse_cb)(struct sdap_handle *sh, struct sdap_msg *msg, void *pvt); struct sdap_get_generic_ext_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; const char *search_base; int scope; const char *filter; const char **attrs; int timeout; int sizelimit; struct sdap_op *op; struct berval cookie; LDAPControl **serverctrls; int nserverctrls; LDAPControl **clientctrls; size_t ref_count; char **refs; sdap_parse_cb parse_cb; void *cb_data; unsigned int flags; }; static errno_t sdap_get_generic_ext_step(struct tevent_req *req); static void sdap_get_generic_op_finished(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt); enum { /* Be silent about exceeded size limit */ SDAP_SRCH_FLG_SIZELIMIT_SILENT = 1 << 0, /* Allow paging */ SDAP_SRCH_FLG_PAGING = 1 << 1, /* Only attribute descriptions are requested */ SDAP_SRCH_FLG_ATTRS_ONLY = 1 << 2, }; static struct tevent_req * sdap_get_generic_ext_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *search_base, int scope, const char *filter, const char **attrs, LDAPControl **serverctrls, LDAPControl **clientctrls, int sizelimit, int timeout, sdap_parse_cb parse_cb, void *cb_data, unsigned int flags) { errno_t ret; struct sdap_get_generic_ext_state *state; struct tevent_req *req; int i; LDAPControl *control; req = tevent_req_create(memctx, &state, struct sdap_get_generic_ext_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->sh = sh; state->search_base = search_base; state->scope = scope; state->filter = filter; state->attrs = attrs; state->op = NULL; state->sizelimit = sizelimit; state->timeout = timeout; state->cookie.bv_len = 0; state->cookie.bv_val = NULL; state->parse_cb = parse_cb; state->cb_data = cb_data; state->clientctrls = clientctrls; state->flags = flags; if (state->sh == NULL || state->sh->ldap == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Trying LDAP search while not connected.\n"); tevent_req_error(req, EIO); tevent_req_post(req, ev); return req; } sdap_print_server(sh); /* Be extra careful and never allow paging for BASE searches, * even if requested. */ if (scope == LDAP_SCOPE_BASE && (flags & SDAP_SRCH_FLG_PAGING)) { /* Disable paging */ flags &= ~SDAP_SRCH_FLG_PAGING; DEBUG(SSSDBG_TRACE_FUNC, "WARNING: Disabling paging because scope is set to base.\n"); } /* Also check for deref/asq requests and force * paging on for those requests */ /* X-DEREF */ control = ldap_control_find(LDAP_CONTROL_X_DEREF, serverctrls, NULL); if (control) { flags |= SDAP_SRCH_FLG_PAGING; } /* ASQ */ control = ldap_control_find(LDAP_SERVER_ASQ_OID, serverctrls, NULL); if (control) { flags |= SDAP_SRCH_FLG_PAGING; } for (state->nserverctrls=0; serverctrls && serverctrls[state->nserverctrls]; state->nserverctrls++) ; /* One extra space for NULL, one for page control */ state->serverctrls = talloc_array(state, LDAPControl *, state->nserverctrls+2); if (!state->serverctrls) { tevent_req_error(req, ENOMEM); tevent_req_post(req, ev); return req; } for (i=0; i < state->nserverctrls; i++) { state->serverctrls[i] = serverctrls[i]; } state->serverctrls[i] = NULL; ret = sdap_get_generic_ext_step(req); if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } return req; } static errno_t sdap_get_generic_ext_step(struct tevent_req *req) { struct sdap_get_generic_ext_state *state = tevent_req_data(req, struct sdap_get_generic_ext_state); char *errmsg; int lret; int optret; errno_t ret; int msgid; bool disable_paging; LDAPControl *page_control = NULL; /* Make sure to free any previous operations so * if we are handling a large number of pages we * don't waste memory. */ talloc_zfree(state->op); DEBUG(SSSDBG_TRACE_FUNC, "calling ldap_search_ext with [%s][%s].\n", state->filter ? state->filter : "no filter", state->search_base); if (DEBUG_IS_SET(SSSDBG_TRACE_LIBS)) { int i; if (state->attrs) { for (i = 0; state->attrs[i]; i++) { DEBUG(SSSDBG_TRACE_LIBS, "Requesting attrs: [%s]\n", state->attrs[i]); } } } disable_paging = dp_opt_get_bool(state->opts->basic, SDAP_DISABLE_PAGING); if (!disable_paging && (state->flags & SDAP_SRCH_FLG_PAGING) && sdap_is_control_supported(state->sh, LDAP_CONTROL_PAGEDRESULTS)) { lret = ldap_create_page_control(state->sh->ldap, state->sh->page_size, state->cookie.bv_val ? &state->cookie : NULL, false, &page_control); if (lret != LDAP_SUCCESS) { ret = EIO; goto done; } state->serverctrls[state->nserverctrls] = page_control; state->serverctrls[state->nserverctrls+1] = NULL; } lret = ldap_search_ext(state->sh->ldap, state->search_base, state->scope, state->filter, discard_const(state->attrs), (state->flags & SDAP_SRCH_FLG_ATTRS_ONLY), state->serverctrls, state->clientctrls, NULL, state->sizelimit, &msgid); ldap_control_free(page_control); state->serverctrls[state->nserverctrls] = NULL; if (lret != LDAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_search_ext failed: %s\n", sss_ldap_err2string(lret)); if (lret == LDAP_SERVER_DOWN) { ret = ETIMEDOUT; optret = sss_ldap_get_diagnostic_msg(state, state->sh->ldap, &errmsg); if (optret == LDAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Connection error: %s\n", errmsg); sss_log(SSS_LOG_ERR, "LDAP connection error: %s", errmsg); } else { sss_log(SSS_LOG_ERR, "LDAP connection error, %s", sss_ldap_err2string(lret)); } } else if (lret == LDAP_FILTER_ERROR) { ret = ERR_INVALID_FILTER; } else { ret = EIO; } goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "ldap_search_ext called, msgid = %d\n", msgid); ret = sdap_op_add(state, state->ev, state->sh, msgid, sdap_get_generic_op_finished, req, state->timeout, &state->op); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set up operation!\n"); goto done; } done: return ret; } static errno_t sdap_get_generic_ext_add_references(struct sdap_get_generic_ext_state *state, char **refs) { int i; if (refs == NULL) { /* Rare, but it's possible that we might get a reference result with * no references attached. */ return EOK; } for (i = 0; refs[i]; i++) { DEBUG(SSSDBG_TRACE_LIBS, "Additional References: %s\n", refs[i]); } /* Extend the size of the ref array */ state->refs = talloc_realloc(state, state->refs, char *, state->ref_count + i); if (state->refs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_realloc failed extending ref_array.\n"); return ENOMEM; } /* Copy in all the references */ for (i = 0; refs[i]; i++) { state->refs[state->ref_count + i] = talloc_strdup(state->refs, refs[i]); if (state->refs[state->ref_count + i] == NULL) { return ENOMEM; } } state->ref_count += i; return EOK; } static void sdap_get_generic_op_finished(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct sdap_get_generic_ext_state *state = tevent_req_data(req, struct sdap_get_generic_ext_state); char *errmsg = NULL; char **refs = NULL; int result; int ret; int lret; ber_int_t total_count; struct berval cookie; LDAPControl **returned_controls = NULL; LDAPControl *page_control; if (error) { tevent_req_error(req, error); return; } switch (ldap_msgtype(reply->msg)) { case LDAP_RES_SEARCH_REFERENCE: ret = ldap_parse_reference(state->sh->ldap, reply->msg, &refs, NULL, 0); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldap_parse_reference failed (%d)\n", state->op->msgid); tevent_req_error(req, EIO); return; } ret = sdap_get_generic_ext_add_references(state, refs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_ext_add_references failed: %s(%d)\n", sss_strerror(ret), ret); ldap_memvfree((void **)refs); tevent_req_error(req, ret); return; } /* Remove the original strings */ ldap_memvfree((void **)refs); /* unlock the operation so that we can proceed with the next result */ sdap_unlock_next_reply(state->op); break; case LDAP_RES_SEARCH_ENTRY: ret = state->parse_cb(state->sh, reply, state->cb_data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "reply parsing callback failed.\n"); tevent_req_error(req, ret); return; } sdap_unlock_next_reply(state->op); break; case LDAP_RES_SEARCH_RESULT: ret = ldap_parse_result(state->sh->ldap, reply->msg, &result, NULL, &errmsg, &refs, &returned_controls, 0); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldap_parse_result failed (%d)\n", state->op->msgid); tevent_req_error(req, EIO); return; } DEBUG(SSSDBG_TRACE_FUNC, "Search result: %s(%d), %s\n", sss_ldap_err2string(result), result, errmsg ? errmsg : "no errmsg set"); if (result == LDAP_SIZELIMIT_EXCEEDED) { /* Try to return what we've got */ if ( ! (state->flags & SDAP_SRCH_FLG_SIZELIMIT_SILENT)) { DEBUG(SSSDBG_MINOR_FAILURE, "LDAP sizelimit was exceeded, " "returning incomplete data\n"); } } else if (result == LDAP_INAPPROPRIATE_MATCHING) { /* This error should only occur when we're testing for * specialized functionality like the ldap matching rule * filter for Active Directory. Warn at a higher log * level and return EIO. */ DEBUG(SSSDBG_TRACE_INTERNAL, "LDAP_INAPPROPRIATE_MATCHING: %s\n", errmsg ? errmsg : "no errmsg set"); ldap_memfree(errmsg); tevent_req_error(req, EIO); return; } else if (result == LDAP_UNAVAILABLE_CRITICAL_EXTENSION) { ldap_memfree(errmsg); tevent_req_error(req, ENOTSUP); return; } else if (result == LDAP_REFERRAL) { ret = sdap_get_generic_ext_add_references(state, refs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_ext_add_references failed: %s(%d)\n", sss_strerror(ret), ret); tevent_req_error(req, ret); } /* For referrals, we need to fall through as if it was LDAP_SUCCESS */ } else if (result != LDAP_SUCCESS && result != LDAP_NO_SUCH_OBJECT) { DEBUG(SSSDBG_OP_FAILURE, "Unexpected result from ldap: %s(%d), %s\n", sss_ldap_err2string(result), result, errmsg ? errmsg : "no errmsg set"); ldap_memfree(errmsg); tevent_req_error(req, EIO); return; } ldap_memfree(errmsg); /* Determine if there are more pages to retrieve */ page_control = ldap_control_find(LDAP_CONTROL_PAGEDRESULTS, returned_controls, NULL ); if (!page_control) { /* No paging support. We are done */ tevent_req_done(req); return; } lret = ldap_parse_pageresponse_control(state->sh->ldap, page_control, &total_count, &cookie); ldap_controls_free(returned_controls); if (lret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not determine page control\n"); tevent_req_error(req, EIO); return; } DEBUG(SSSDBG_TRACE_INTERNAL, "Total count [%d]\n", total_count); if (cookie.bv_val != NULL && cookie.bv_len > 0) { /* Cookie contains data, which means there are more requests * to be processed. */ talloc_zfree(state->cookie.bv_val); state->cookie.bv_len = cookie.bv_len; state->cookie.bv_val = talloc_memdup(state, cookie.bv_val, cookie.bv_len); if (!state->cookie.bv_val) { tevent_req_error(req, ENOMEM); return; } ber_memfree(cookie.bv_val); ret = sdap_get_generic_ext_step(req); if (ret != EOK) { tevent_req_error(req, ENOMEM); return; } return; } /* The cookie must be freed even if len == 0 */ ber_memfree(cookie.bv_val); /* This was the last page. We're done */ tevent_req_done(req); return; default: /* what is going on here !? */ tevent_req_error(req, EIO); return; } } static int sdap_get_generic_ext_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *ref_count, char ***refs) { struct sdap_get_generic_ext_state *state = tevent_req_data(req, struct sdap_get_generic_ext_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (ref_count) { *ref_count = state->ref_count; } if (refs) { *refs = talloc_steal(mem_ctx, state->refs); } return EOK; } /* This search handler can be used by most calls */ static void generic_ext_search_handler(struct tevent_req *subreq, struct sdap_options *opts) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); int ret; size_t ref_count, i; char **refs; ret = sdap_get_generic_ext_recv(subreq, req, &ref_count, &refs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_ext_recv failed [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } if (ref_count > 0) { /* We will ignore referrals in the generic handler */ DEBUG(SSSDBG_TRACE_ALL, "Request included referrals which were ignored.\n"); if (debug_level & SSSDBG_TRACE_ALL) { for(i = 0; i < ref_count; i++) { DEBUG(SSSDBG_TRACE_ALL, " Ref: %s\n", refs[i]); } } } talloc_free(refs); tevent_req_done(req); } /* ==Generic Search exposing all options======================= */ struct sdap_get_and_parse_generic_state { struct sdap_attr_map *map; int map_num_attrs; struct sdap_reply sreply; struct sdap_options *opts; }; static void sdap_get_and_parse_generic_done(struct tevent_req *subreq); static errno_t sdap_get_and_parse_generic_parse_entry(struct sdap_handle *sh, struct sdap_msg *msg, void *pvt); struct tevent_req *sdap_get_and_parse_generic_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *search_base, int scope, const char *filter, const char **attrs, struct sdap_attr_map *map, int map_num_attrs, int attrsonly, LDAPControl **serverctrls, LDAPControl **clientctrls, int sizelimit, int timeout, bool allow_paging) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_get_and_parse_generic_state *state = NULL; unsigned int flags = 0; req = tevent_req_create(memctx, &state, struct sdap_get_and_parse_generic_state); if (!req) return NULL; state->map = map; state->map_num_attrs = map_num_attrs; state->opts = opts; if (allow_paging) { flags |= SDAP_SRCH_FLG_PAGING; } if (attrsonly) { flags |= SDAP_SRCH_FLG_ATTRS_ONLY; } subreq = sdap_get_generic_ext_send(state, ev, opts, sh, search_base, scope, filter, attrs, serverctrls, clientctrls, sizelimit, timeout, sdap_get_and_parse_generic_parse_entry, state, flags); if (!subreq) { talloc_zfree(req); return NULL; } tevent_req_set_callback(subreq, sdap_get_and_parse_generic_done, req); return req; } static errno_t sdap_get_and_parse_generic_parse_entry(struct sdap_handle *sh, struct sdap_msg *msg, void *pvt) { errno_t ret; struct sysdb_attrs *attrs; struct sdap_get_and_parse_generic_state *state = talloc_get_type(pvt, struct sdap_get_and_parse_generic_state); bool disable_range_rtrvl = dp_opt_get_bool(state->opts->basic, SDAP_DISABLE_RANGE_RETRIEVAL); ret = sdap_parse_entry(state, sh, msg, state->map, state->map_num_attrs, &attrs, disable_range_rtrvl); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sdap_parse_entry failed [%d]: %s\n", ret, strerror(ret)); return ret; } ret = add_to_reply(state, &state->sreply, attrs); if (ret != EOK) { talloc_free(attrs); DEBUG(SSSDBG_CRIT_FAILURE, "add_to_reply failed.\n"); return ret; } /* add_to_reply steals attrs, no need to free them here */ return EOK; } static void sdap_get_and_parse_generic_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_and_parse_generic_state *state = tevent_req_data(req, struct sdap_get_and_parse_generic_state); return generic_ext_search_handler(subreq, state->opts); } int sdap_get_and_parse_generic_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sysdb_attrs ***reply) { struct sdap_get_and_parse_generic_state *state = tevent_req_data(req, struct sdap_get_and_parse_generic_state); TEVENT_REQ_RETURN_ON_ERROR(req); *reply_count = state->sreply.reply_count; *reply = talloc_steal(mem_ctx, state->sreply.reply); return EOK; } /* ==Simple generic search============================================== */ struct sdap_get_generic_state { size_t reply_count; struct sysdb_attrs **reply; }; static void sdap_get_generic_done(struct tevent_req *subreq); struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *search_base, int scope, const char *filter, const char **attrs, struct sdap_attr_map *map, int map_num_attrs, int timeout, bool allow_paging) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_get_generic_state *state = NULL; req = tevent_req_create(memctx, &state, struct sdap_get_generic_state); if (!req) return NULL; subreq = sdap_get_and_parse_generic_send(memctx, ev, opts, sh, search_base, scope, filter, attrs, map, map_num_attrs, false, NULL, NULL, 0, timeout, allow_paging); if (subreq == NULL) { return NULL; } tevent_req_set_callback(subreq, sdap_get_generic_done, req); return req; } static void sdap_get_generic_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_generic_state *state = tevent_req_data(req, struct sdap_get_generic_state); errno_t ret; ret = sdap_get_and_parse_generic_recv(subreq, state, &state->reply_count, &state->reply); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } int sdap_get_generic_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sysdb_attrs ***reply) { struct sdap_get_generic_state *state = tevent_req_data(req, struct sdap_get_generic_state); TEVENT_REQ_RETURN_ON_ERROR(req); *reply_count = state->reply_count; *reply = talloc_steal(mem_ctx, state->reply); return EOK; } /* ==OpenLDAP deref search============================================== */ static int sdap_x_deref_create_control(struct sdap_handle *sh, const char *deref_attr, const char **attrs, LDAPControl **ctrl); static void sdap_x_deref_search_done(struct tevent_req *subreq); static int sdap_x_deref_search_ctrls_destructor(void *ptr); static errno_t sdap_x_deref_parse_entry(struct sdap_handle *sh, struct sdap_msg *msg, void *pvt); struct sdap_x_deref_search_state { struct sdap_handle *sh; struct sdap_op *op; struct sdap_attr_map_info *maps; LDAPControl **ctrls; struct sdap_options *opts; struct sdap_deref_reply dreply; int num_maps; }; static struct tevent_req * sdap_x_deref_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *base_dn, const char *filter, const char *deref_attr, const char **attrs, struct sdap_attr_map_info *maps, int num_maps, int timeout) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_x_deref_search_state *state; int ret; req = tevent_req_create(memctx, &state, struct sdap_x_deref_search_state); if (!req) return NULL; state->sh = sh; state->maps = maps; state->op = NULL; state->opts = opts; state->num_maps = num_maps; state->ctrls = talloc_zero_array(state, LDAPControl *, 2); if (state->ctrls == NULL) { talloc_zfree(req); return NULL; } talloc_set_destructor((TALLOC_CTX *) state->ctrls, sdap_x_deref_search_ctrls_destructor); ret = sdap_x_deref_create_control(sh, deref_attr, attrs, &state->ctrls[0]); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not create OpenLDAP deref control\n"); talloc_zfree(req); return NULL; } DEBUG(SSSDBG_TRACE_FUNC, "Dereferencing entry [%s] using OpenLDAP deref\n", base_dn); subreq = sdap_get_generic_ext_send(state, ev, opts, sh, base_dn, filter == NULL ? LDAP_SCOPE_BASE : LDAP_SCOPE_SUBTREE, filter, attrs, state->ctrls, NULL, 0, timeout, sdap_x_deref_parse_entry, state, SDAP_SRCH_FLG_PAGING); if (!subreq) { talloc_zfree(req); return NULL; } tevent_req_set_callback(subreq, sdap_x_deref_search_done, req); return req; } static int sdap_x_deref_create_control(struct sdap_handle *sh, const char *deref_attr, const char **attrs, LDAPControl **ctrl) { struct berval derefval; int ret; struct LDAPDerefSpec ds[2]; ds[0].derefAttr = discard_const(deref_attr); ds[0].attributes = discard_const(attrs); ds[1].derefAttr = NULL; /* sentinel */ ret = ldap_create_deref_control_value(sh->ldap, ds, &derefval); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_ldap_control_create failed: %s\n", ldap_err2string(ret)); return ret; } ret = sdap_control_create(sh, LDAP_CONTROL_X_DEREF, 1, &derefval, 1, ctrl); ldap_memfree(derefval.bv_val); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_ldap_control_create failed\n"); return ret; } return EOK; } static errno_t sdap_x_deref_parse_entry(struct sdap_handle *sh, struct sdap_msg *msg, void *pvt) { errno_t ret; LDAPControl **ctrls = NULL; LDAPControl *derefctrl = NULL; LDAPDerefRes *deref_res = NULL; LDAPDerefRes *dref; struct sdap_deref_attrs **res; TALLOC_CTX *tmp_ctx; struct sdap_x_deref_search_state *state = talloc_get_type(pvt, struct sdap_x_deref_search_state); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; ret = ldap_get_entry_controls(state->sh->ldap, msg->msg, &ctrls); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldap_parse_result failed\n"); goto done; } if (!ctrls) { /* When we attempt to request attributes that are not present in * the dereferenced links, some serves might not send the dereference * control back at all. Be permissive and treat the search as if * it didn't find anything. */ DEBUG(SSSDBG_MINOR_FAILURE, "No controls found for entry\n"); ret = EOK; goto done; } res = NULL; derefctrl = ldap_control_find(LDAP_CONTROL_X_DEREF, ctrls, NULL); if (!derefctrl) { DEBUG(SSSDBG_FUNC_DATA, "No deref controls found\n"); ret = EOK; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Got deref control\n"); ret = ldap_parse_derefresponse_control(state->sh->ldap, derefctrl, &deref_res); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldap_parse_derefresponse_control failed: %s\n", ldap_err2string(ret)); goto done; } for (dref = deref_res; dref; dref=dref->next) { ret = sdap_parse_deref(tmp_ctx, state->maps, state->num_maps, dref, &res); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sdap_parse_deref failed [%d]: %s\n", ret, strerror(ret)); goto done; } ret = add_to_deref_reply(state, state->num_maps, &state->dreply, res); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_to_deref_reply failed.\n"); goto done; } } DEBUG(SSSDBG_TRACE_FUNC, "All deref results from a single control parsed\n"); ldap_derefresponse_free(deref_res); deref_res = NULL; ret = EOK; done: talloc_zfree(tmp_ctx); ldap_controls_free(ctrls); ldap_derefresponse_free(deref_res); return ret; } static void sdap_x_deref_search_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_x_deref_search_state *state = tevent_req_data(req, struct sdap_x_deref_search_state); return generic_ext_search_handler(subreq, state->opts); } static int sdap_x_deref_search_ctrls_destructor(void *ptr) { LDAPControl **ctrls = talloc_get_type(ptr, LDAPControl *);; if (ctrls && ctrls[0]) { ldap_control_free(ctrls[0]); } return 0; } static int sdap_x_deref_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sdap_deref_attrs ***reply) { struct sdap_x_deref_search_state *state = tevent_req_data(req, struct sdap_x_deref_search_state); TEVENT_REQ_RETURN_ON_ERROR(req); *reply_count = state->dreply.reply_count; *reply = talloc_steal(mem_ctx, state->dreply.reply); return EOK; } /* ==Security Descriptor (ACL) search=================================== */ struct sdap_sd_search_state { LDAPControl **ctrls; struct sdap_options *opts; size_t reply_count; struct sysdb_attrs **reply; struct sdap_reply sreply; /* Referrals returned by the search */ size_t ref_count; char **refs; }; static int sdap_sd_search_create_control(struct sdap_handle *sh, int val, LDAPControl **ctrl); static int sdap_sd_search_ctrls_destructor(void *ptr); static errno_t sdap_sd_search_parse_entry(struct sdap_handle *sh, struct sdap_msg *msg, void *pvt); static void sdap_sd_search_done(struct tevent_req *subreq); struct tevent_req * sdap_sd_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *base_dn, int sd_flags, const char **attrs, int timeout) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_sd_search_state *state; int ret; req = tevent_req_create(memctx, &state, struct sdap_sd_search_state); if (!req) return NULL; state->ctrls = talloc_zero_array(state, LDAPControl *, 2); state->opts = opts; if (state->ctrls == NULL) { ret = EIO; goto fail; } talloc_set_destructor((TALLOC_CTX *) state->ctrls, sdap_sd_search_ctrls_destructor); ret = sdap_sd_search_create_control(sh, sd_flags, &state->ctrls[0]); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not create SD control\n"); ret = EIO; goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "Searching entry [%s] using SD\n", base_dn); subreq = sdap_get_generic_ext_send(state, ev, opts, sh, base_dn, LDAP_SCOPE_BASE, "(objectclass=*)", attrs, state->ctrls, NULL, 0, timeout, sdap_sd_search_parse_entry, state, SDAP_SRCH_FLG_PAGING); if (!subreq) { ret = EIO; goto fail; } tevent_req_set_callback(subreq, sdap_sd_search_done, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static int sdap_sd_search_create_control(struct sdap_handle *sh, int val, LDAPControl **ctrl) { struct berval *sdval; int ret; BerElement *ber = NULL; ber = ber_alloc_t(LBER_USE_DER); if (ber == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ber_alloc_t failed.\n"); return ENOMEM; } ret = ber_printf(ber, "{i}", val); if (ret == -1) { DEBUG(SSSDBG_OP_FAILURE, "ber_printf failed.\n"); ber_free(ber, 1); return EIO; } ret = ber_flatten(ber, &sdval); ber_free(ber, 1); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "ber_flatten failed.\n"); return EIO; } ret = sdap_control_create(sh, LDAP_SERVER_SD_OID, 1, sdval, 1, ctrl); ber_bvfree(sdval); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_control_create failed\n"); return ret; } return EOK; } static errno_t sdap_sd_search_parse_entry(struct sdap_handle *sh, struct sdap_msg *msg, void *pvt) { errno_t ret; struct sysdb_attrs *attrs; struct sdap_sd_search_state *state = talloc_get_type(pvt, struct sdap_sd_search_state); bool disable_range_rtrvl = dp_opt_get_bool(state->opts->basic, SDAP_DISABLE_RANGE_RETRIEVAL); ret = sdap_parse_entry(state, sh, msg, NULL, 0, &attrs, disable_range_rtrvl); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sdap_parse_entry failed [%d]: %s\n", ret, strerror(ret)); return ret; } ret = add_to_reply(state, &state->sreply, attrs); if (ret != EOK) { talloc_free(attrs); DEBUG(SSSDBG_CRIT_FAILURE, "add_to_reply failed.\n"); return ret; } /* add_to_reply steals attrs, no need to free them here */ return EOK; } static void sdap_sd_search_done(struct tevent_req *subreq) { int ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_sd_search_state *state = tevent_req_data(req, struct sdap_sd_search_state); ret = sdap_get_generic_ext_recv(subreq, state, &state->ref_count, &state->refs); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_ext_recv failed [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } tevent_req_done(req); } static int sdap_sd_search_ctrls_destructor(void *ptr) { LDAPControl **ctrls = talloc_get_type(ptr, LDAPControl *);; if (ctrls && ctrls[0]) { ldap_control_free(ctrls[0]); } return 0; } int sdap_sd_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *_reply_count, struct sysdb_attrs ***_reply, size_t *_ref_count, char ***_refs) { struct sdap_sd_search_state *state = tevent_req_data(req, struct sdap_sd_search_state); TEVENT_REQ_RETURN_ON_ERROR(req); *_reply_count = state->sreply.reply_count; *_reply = talloc_steal(mem_ctx, state->sreply.reply); if(_ref_count) { *_ref_count = state->ref_count; } if (_refs) { *_refs = talloc_steal(mem_ctx, state->refs); } return EOK; } /* ==Attribute scoped search============================================ */ struct sdap_asq_search_state { struct sdap_attr_map_info *maps; int num_maps; LDAPControl **ctrls; struct sdap_options *opts; struct sdap_deref_reply dreply; }; static int sdap_asq_search_create_control(struct sdap_handle *sh, const char *attr, LDAPControl **ctrl); static int sdap_asq_search_ctrls_destructor(void *ptr); static errno_t sdap_asq_search_parse_entry(struct sdap_handle *sh, struct sdap_msg *msg, void *pvt); static void sdap_asq_search_done(struct tevent_req *subreq); static struct tevent_req * sdap_asq_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *base_dn, const char *deref_attr, const char **attrs, struct sdap_attr_map_info *maps, int num_maps, int timeout) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_asq_search_state *state; int ret; req = tevent_req_create(memctx, &state, struct sdap_asq_search_state); if (!req) return NULL; state->maps = maps; state->num_maps = num_maps; state->ctrls = talloc_zero_array(state, LDAPControl *, 2); state->opts = opts; if (state->ctrls == NULL) { talloc_zfree(req); return NULL; } talloc_set_destructor((TALLOC_CTX *) state->ctrls, sdap_asq_search_ctrls_destructor); ret = sdap_asq_search_create_control(sh, deref_attr, &state->ctrls[0]); if (ret != EOK) { talloc_zfree(req); DEBUG(SSSDBG_CRIT_FAILURE, "Could not create ASQ control\n"); return NULL; } DEBUG(SSSDBG_TRACE_FUNC, "Dereferencing entry [%s] using ASQ\n", base_dn); subreq = sdap_get_generic_ext_send(state, ev, opts, sh, base_dn, LDAP_SCOPE_BASE, NULL, attrs, state->ctrls, NULL, 0, timeout, sdap_asq_search_parse_entry, state, SDAP_SRCH_FLG_PAGING); if (!subreq) { talloc_zfree(req); return NULL; } tevent_req_set_callback(subreq, sdap_asq_search_done, req); return req; } static int sdap_asq_search_create_control(struct sdap_handle *sh, const char *attr, LDAPControl **ctrl) { struct berval *asqval; int ret; BerElement *ber = NULL; ber = ber_alloc_t(LBER_USE_DER); if (ber == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ber_alloc_t failed.\n"); return ENOMEM; } ret = ber_printf(ber, "{s}", attr); if (ret == -1) { DEBUG(SSSDBG_OP_FAILURE, "ber_printf failed.\n"); ber_free(ber, 1); return EIO; } ret = ber_flatten(ber, &asqval); ber_free(ber, 1); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "ber_flatten failed.\n"); return EIO; } ret = sdap_control_create(sh, LDAP_SERVER_ASQ_OID, 1, asqval, 1, ctrl); ber_bvfree(asqval); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_control_create failed\n"); return ret; } return EOK; } static errno_t sdap_asq_search_parse_entry(struct sdap_handle *sh, struct sdap_msg *msg, void *pvt) { errno_t ret; struct sdap_asq_search_state *state = talloc_get_type(pvt, struct sdap_asq_search_state); struct berval **vals; int i, mi; struct sdap_attr_map *map; int num_attrs; struct sdap_deref_attrs **res; char *tmp; char *dn; TALLOC_CTX *tmp_ctx; bool disable_range_rtrvl; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; res = talloc_array(tmp_ctx, struct sdap_deref_attrs *, state->num_maps); if (!res) { ret = ENOMEM; goto done; } for (mi =0; mi < state->num_maps; mi++) { res[mi] = talloc_zero(res, struct sdap_deref_attrs); if (!res[mi]) { ret = ENOMEM; goto done; } res[mi]->map = state->maps[mi].map; res[mi]->attrs = NULL; } tmp = ldap_get_dn(sh->ldap, msg->msg); if (!tmp) { ret = EINVAL; goto done; } dn = talloc_strdup(tmp_ctx, tmp); ldap_memfree(tmp); if (!dn) { ret = ENOMEM; goto done; } /* Find all suitable maps in the list */ vals = ldap_get_values_len(sh->ldap, msg->msg, "objectClass"); if (!vals) { DEBUG(SSSDBG_OP_FAILURE, "Unknown entry type, no objectClass found for DN [%s]!\n", dn); ret = EINVAL; goto done; } for (mi =0; mi < state->num_maps; mi++) { map = NULL; for (i = 0; vals[i]; i++) { /* the objectclass is always the first name in the map */ if (strncasecmp(state->maps[mi].map[0].name, vals[i]->bv_val, vals[i]->bv_len) == 0) { /* it's an entry of the right type */ DEBUG(SSSDBG_TRACE_INTERNAL, "Matched objectclass [%s] on DN [%s], will use associated map\n", state->maps[mi].map[0].name, dn); map = state->maps[mi].map; num_attrs = state->maps[mi].num_attrs; break; } } if (!map) { DEBUG(SSSDBG_TRACE_INTERNAL, "DN [%s] did not match the objectClass [%s]\n", dn, state->maps[mi].map[0].name); continue; } disable_range_rtrvl = dp_opt_get_bool(state->opts->basic, SDAP_DISABLE_RANGE_RETRIEVAL); ret = sdap_parse_entry(res[mi], sh, msg, map, num_attrs, &res[mi]->attrs, disable_range_rtrvl); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sdap_parse_entry failed [%d]: %s\n", ret, strerror(ret)); goto done; } } ldap_value_free_len(vals); ret = add_to_deref_reply(state, state->num_maps, &state->dreply, res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "add_to_deref_reply failed.\n"); goto done; } ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } static void sdap_asq_search_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_asq_search_state *state = tevent_req_data(req, struct sdap_asq_search_state); return generic_ext_search_handler(subreq, state->opts); } static int sdap_asq_search_ctrls_destructor(void *ptr) { LDAPControl **ctrls = talloc_get_type(ptr, LDAPControl *);; if (ctrls && ctrls[0]) { ldap_control_free(ctrls[0]); } return 0; } int sdap_asq_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sdap_deref_attrs ***reply) { struct sdap_asq_search_state *state = tevent_req_data(req, struct sdap_asq_search_state); TEVENT_REQ_RETURN_ON_ERROR(req); *reply_count = state->dreply.reply_count; *reply = talloc_steal(mem_ctx, state->dreply.reply); return EOK; } /* ==Posix attribute presence test================================= */ static errno_t sdap_posix_check_next(struct tevent_req *req); static void sdap_posix_check_done(struct tevent_req *subreq); static errno_t sdap_posix_check_parse(struct sdap_handle *sh, struct sdap_msg *msg, void *pvt); struct sdap_posix_check_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; struct sdap_search_base **search_bases; int timeout; const char **attrs; const char *filter; size_t base_iter; bool has_posix; }; struct tevent_req * sdap_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, struct sdap_search_base **search_bases, int timeout) { struct tevent_req *req = NULL; struct sdap_posix_check_state *state; errno_t ret; req = tevent_req_create(memctx, &state, struct sdap_posix_check_state); if (req == NULL) { return NULL; } state->ev = ev; state->sh = sh; state->opts = opts; state->search_bases = search_bases; state->timeout = timeout; state->attrs = talloc_array(state, const char *, 4); if (state->attrs == NULL) { ret = ENOMEM; goto fail; } state->attrs[0] = "objectclass"; state->attrs[1] = opts->user_map[SDAP_AT_USER_UID].name; state->attrs[2] = opts->group_map[SDAP_AT_GROUP_GID].name; state->attrs[3] = NULL; state->filter = talloc_asprintf(state, "(|(&(%s=*)(objectclass=%s))(&(%s=*)(objectclass=%s)))", opts->user_map[SDAP_AT_USER_UID].name, opts->user_map[SDAP_OC_USER].name, opts->group_map[SDAP_AT_GROUP_GID].name, opts->group_map[SDAP_OC_GROUP].name); if (state->filter == NULL) { ret = ENOMEM; goto fail; } ret = sdap_posix_check_next(req); if (ret != EOK) { goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static errno_t sdap_posix_check_next(struct tevent_req *req) { struct tevent_req *subreq = NULL; struct sdap_posix_check_state *state = tevent_req_data(req, struct sdap_posix_check_state); DEBUG(SSSDBG_TRACE_FUNC, "Searching for POSIX attributes with base [%s]\n", state->search_bases[state->base_iter]->basedn); subreq = sdap_get_generic_ext_send(state, state->ev, state->opts, state->sh, state->search_bases[state->base_iter]->basedn, LDAP_SCOPE_SUBTREE, state->filter, state->attrs, NULL, NULL, 1, state->timeout, sdap_posix_check_parse, state, SDAP_SRCH_FLG_SIZELIMIT_SILENT); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_posix_check_done, req); return EOK; } static errno_t sdap_posix_check_parse(struct sdap_handle *sh, struct sdap_msg *msg, void *pvt) { struct berval **vals = NULL; struct sdap_posix_check_state *state = talloc_get_type(pvt, struct sdap_posix_check_state); char *dn; char *endptr; dn = ldap_get_dn(sh->ldap, msg->msg); if (dn == NULL) { DEBUG(SSSDBG_TRACE_LIBS, "Search did not find any entry with POSIX attributes\n"); goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Found [%s] with POSIX attributes\n", dn); ldap_memfree(dn); vals = ldap_get_values_len(sh->ldap, msg->msg, state->opts->user_map[SDAP_AT_USER_UID].name); if (vals == NULL) { vals = ldap_get_values_len(sh->ldap, msg->msg, state->opts->group_map[SDAP_AT_GROUP_GID].name); if (vals == NULL) { DEBUG(SSSDBG_TRACE_LIBS, "Entry does not have POSIX attrs?\n"); goto done; } } if (vals[0] == NULL) { DEBUG(SSSDBG_TRACE_LIBS, "No value for POSIX attr\n"); goto done; } errno = 0; strtouint32(vals[0]->bv_val, &endptr, 10); if (errno || *endptr || (vals[0]->bv_val == endptr)) { DEBUG(SSSDBG_MINOR_FAILURE, "POSIX attribute is not a number: %s\n", vals[0]->bv_val); } state->has_posix = true; done: ldap_value_free_len(vals); return EOK; } static void sdap_posix_check_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_posix_check_state *state = tevent_req_data(req, struct sdap_posix_check_state); errno_t ret; ret = sdap_get_generic_ext_recv(subreq, NULL, NULL, NULL); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_ext_recv failed [%d]: %s\n", ret, strerror(ret)); tevent_req_error(req, ret); return; } /* Positive hit is definitve, no need to search other bases */ if (state->has_posix == true) { DEBUG(SSSDBG_FUNC_DATA, "Server has POSIX attributes\n"); tevent_req_done(req); return; } state->base_iter++; if (state->search_bases[state->base_iter]) { /* There are more search bases to try */ ret = sdap_posix_check_next(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } /* All bases done! */ DEBUG(SSSDBG_TRACE_LIBS, "Cycled through all bases\n"); tevent_req_done(req); } int sdap_posix_check_recv(struct tevent_req *req, bool *_has_posix) { struct sdap_posix_check_state *state = tevent_req_data(req, struct sdap_posix_check_state); TEVENT_REQ_RETURN_ON_ERROR(req); *_has_posix = state->has_posix; return EOK; } /* ==Generic Deref Search============================================ */ enum sdap_deref_type { SDAP_DEREF_OPENLDAP, SDAP_DEREF_ASQ }; struct sdap_deref_search_state { struct sdap_handle *sh; size_t reply_count; struct sdap_deref_attrs **reply; enum sdap_deref_type deref_type; unsigned flags; }; static void sdap_deref_search_done(struct tevent_req *subreq); static void sdap_deref_search_with_filter_done(struct tevent_req *subreq); struct tevent_req * sdap_deref_search_with_filter_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *search_base, const char *filter, const char *deref_attr, const char **attrs, int num_maps, struct sdap_attr_map_info *maps, int timeout, unsigned flags) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_deref_search_state *state; req = tevent_req_create(memctx, &state, struct sdap_deref_search_state); if (!req) return NULL; state->sh = sh; state->reply_count = 0; state->reply = NULL; state->flags = flags; if (sdap_is_control_supported(sh, LDAP_CONTROL_X_DEREF)) { DEBUG(SSSDBG_TRACE_INTERNAL, "Server supports OpenLDAP deref\n"); state->deref_type = SDAP_DEREF_OPENLDAP; subreq = sdap_x_deref_search_send(state, ev, opts, sh, search_base, filter, deref_attr, attrs, maps, num_maps, timeout); if (!subreq) { DEBUG(SSSDBG_OP_FAILURE, "Cannot start OpenLDAP deref search\n"); goto fail; } } else { DEBUG(SSSDBG_OP_FAILURE, "Server does not support any known deref method!\n"); goto fail; } tevent_req_set_callback(subreq, sdap_deref_search_with_filter_done, req); return req; fail: talloc_zfree(req); return NULL; } static void sdap_deref_search_with_filter_done(struct tevent_req *subreq) { sdap_deref_search_done(subreq); } int sdap_deref_search_with_filter_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sdap_deref_attrs ***reply) { return sdap_deref_search_recv(req, mem_ctx, reply_count, reply); } struct tevent_req * sdap_deref_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *base_dn, const char *deref_attr, const char **attrs, int num_maps, struct sdap_attr_map_info *maps, int timeout) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_deref_search_state *state; req = tevent_req_create(memctx, &state, struct sdap_deref_search_state); if (!req) return NULL; state->sh = sh; state->reply_count = 0; state->reply = NULL; if (sdap_is_control_supported(sh, LDAP_SERVER_ASQ_OID)) { DEBUG(SSSDBG_TRACE_INTERNAL, "Server supports ASQ\n"); state->deref_type = SDAP_DEREF_ASQ; subreq = sdap_asq_search_send(state, ev, opts, sh, base_dn, deref_attr, attrs, maps, num_maps, timeout); if (!subreq) { DEBUG(SSSDBG_OP_FAILURE, "Cannot start ASQ search\n"); goto fail; } } else if (sdap_is_control_supported(sh, LDAP_CONTROL_X_DEREF)) { DEBUG(SSSDBG_TRACE_INTERNAL, "Server supports OpenLDAP deref\n"); state->deref_type = SDAP_DEREF_OPENLDAP; subreq = sdap_x_deref_search_send(state, ev, opts, sh, base_dn, NULL, deref_attr, attrs, maps, num_maps, timeout); if (!subreq) { DEBUG(SSSDBG_OP_FAILURE, "Cannot start OpenLDAP deref search\n"); goto fail; } } else { DEBUG(SSSDBG_OP_FAILURE, "Server does not support any known deref method!\n"); goto fail; } tevent_req_set_callback(subreq, sdap_deref_search_done, req); return req; fail: talloc_zfree(req); return NULL; } static void sdap_deref_search_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_deref_search_state *state = tevent_req_data(req, struct sdap_deref_search_state); int ret; switch (state->deref_type) { case SDAP_DEREF_OPENLDAP: ret = sdap_x_deref_search_recv(subreq, state, &state->reply_count, &state->reply); break; case SDAP_DEREF_ASQ: ret = sdap_asq_search_recv(subreq, state, &state->reply_count, &state->reply); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown deref method\n"); tevent_req_error(req, EINVAL); return; } talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "dereference processing failed [%d]: %s\n", ret, strerror(ret)); if (ret == ENOTSUP) { state->sh->disable_deref = true; } if (!(state->flags & SDAP_DEREF_FLG_SILENT)) { if (ret == ENOTSUP) { sss_log(SSS_LOG_WARNING, "LDAP server claims to support deref, but deref search " "failed. Disabling deref for further requests. You can " "permanently disable deref by setting " "ldap_deref_threshold to 0 in domain configuration."); } else { sss_log(SSS_LOG_WARNING, "dereference processing failed : %s", strerror(ret)); } } tevent_req_error(req, ret); return; } tevent_req_done(req); } int sdap_deref_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sdap_deref_attrs ***reply) { struct sdap_deref_search_state *state = tevent_req_data(req, struct sdap_deref_search_state); TEVENT_REQ_RETURN_ON_ERROR(req); *reply_count = state->reply_count; *reply = talloc_steal(mem_ctx, state->reply); return EOK; } bool sdap_has_deref_support(struct sdap_handle *sh, struct sdap_options *opts) { const char *deref_oids[][2] = { { LDAP_SERVER_ASQ_OID, "ASQ" }, { LDAP_CONTROL_X_DEREF, "OpenLDAP" }, { NULL, NULL } }; int i; int deref_threshold; if (sh->disable_deref) { return false; } deref_threshold = dp_opt_get_int(opts->basic, SDAP_DEREF_THRESHOLD); if (deref_threshold == 0) { return false; } for (i=0; deref_oids[i][0]; i++) { if (sdap_is_control_supported(sh, deref_oids[i][0])) { DEBUG(SSSDBG_TRACE_FUNC, "The server supports deref method %s\n", deref_oids[i][1]); return true; } } return false; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_sudo.h0000644000000000000000000000007412703456111020203 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.553793286 sssd-1.13.4/src/providers/ldap/sdap_sudo.h0000644002412700241270000000713212703456111021655 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SDAP_SUDO_H_ #define _SDAP_SUDO_H_ #include "providers/dp_backend.h" #include "providers/ldap/ldap_common.h" struct sdap_sudo_ctx { struct sdap_id_ctx *id_ctx; char **hostnames; char **ip_addr; bool include_netgroups; bool include_regexp; bool use_host_filter; bool full_refresh_done; bool run_hostinfo; }; /* Common functions from ldap_sudo.c */ int sdap_sudo_init(struct be_ctx *be_ctx, struct sdap_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data); /* sdap async interface */ struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx, struct sdap_sudo_ctx *sudo_ctx, const char *ldap_filter, const char *sysdb_filter); int sdap_sudo_refresh_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *dp_error, size_t *num_rules); struct tevent_req *sdap_sudo_full_refresh_send(TALLOC_CTX *mem_ctx, struct sdap_sudo_ctx *sudo_ctx); int sdap_sudo_full_refresh_recv(struct tevent_req *req, int *dp_error); struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx, struct sdap_sudo_ctx *sudo_ctx); int sdap_sudo_smart_refresh_recv(struct tevent_req *req, int *dp_error); struct tevent_req *sdap_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx, struct sdap_sudo_ctx *sudo_ctx, char **rules); int sdap_sudo_rules_refresh_recv(struct tevent_req *req, int *dp_error, bool *deleted); errno_t sdap_sudo_ptask_setup(struct be_ctx *be_ctx, struct sdap_sudo_ctx *sudo_ctx); /* host info */ struct tevent_req * sdap_sudo_get_hostinfo_send(TALLOC_CTX *mem_ctx, struct sdap_options *opts, struct be_ctx *be_ctx); int sdap_sudo_get_hostinfo_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char ***hostnames, char ***ip_addr); /* (&(objectClass=sudoRole)(|(cn=defaults)(sudoUser=ALL)%s)) */ #define SDAP_SUDO_FILTER_USER "(&(objectClass=%s)(|(%s=%s)(%s=ALL)%s))" #define SDAP_SUDO_FILTER_CLASS "(objectClass=%s)" #define SDAP_SUDO_FILTER_DEFAULTS "(&(objectClass=%s)(%s=%s))" #define SDAP_SUDO_DEFAULTS "defaults" #define SDAP_SUDO_FILTER_USERNAME "(%s=%s)" #define SDAP_SUDO_FILTER_UID "(%s=#%u)" #define SDAP_SUDO_FILTER_GROUP "(%s=%%%s)" #define SDAP_SUDO_FILTER_NETGROUP "(%s=+%s)" #endif /* _SDAP_SUDO_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_child.c0000644000000000000000000000007412703456111020300 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.940794598 sssd-1.13.4/src/providers/ldap/ldap_child.c0000644002412700241270000005534512703456111021763 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Backend Module -- prime ccache with TGT in a child process Authors: Jakub Hrozek Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "util/sss_krb5.h" #include "util/child_common.h" #include "providers/dp_backend.h" #include "providers/krb5/krb5_common.h" static krb5_context krb5_error_ctx; #define LDAP_CHILD_DEBUG(level, error) KRB5_DEBUG(level, krb5_error_ctx, error) static const char *__ldap_child_krb5_error_msg; #define KRB5_SYSLOG(krb5_error) do { \ __ldap_child_krb5_error_msg = sss_krb5_get_error_message(krb5_error_ctx, krb5_error); \ sss_log(SSS_LOG_ERR, "%s", __ldap_child_krb5_error_msg); \ sss_krb5_free_error_message(krb5_error_ctx, __ldap_child_krb5_error_msg); \ } while(0) struct input_buffer { const char *realm_str; const char *princ_str; char *keytab_name; krb5_deltat lifetime; krb5_context context; uid_t uid; gid_t gid; }; static errno_t unpack_buffer(uint8_t *buf, size_t size, struct input_buffer *ibuf) { size_t p = 0; uint32_t len; DEBUG(SSSDBG_TRACE_LIBS, "total buffer size: %zu\n", size); /* realm_str size and length */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); DEBUG(SSSDBG_TRACE_LIBS, "realm_str size: %d\n", len); if (len) { if (len > size - p) return EINVAL; ibuf->realm_str = talloc_strndup(ibuf, (char *)(buf + p), len); DEBUG(SSSDBG_TRACE_LIBS, "got realm_str: %s\n", ibuf->realm_str); if (ibuf->realm_str == NULL) return ENOMEM; p += len; } /* princ_str size and length */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); DEBUG(SSSDBG_TRACE_LIBS, "princ_str size: %d\n", len); if (len) { if (len > size - p) return EINVAL; ibuf->princ_str = talloc_strndup(ibuf, (char *)(buf + p), len); DEBUG(SSSDBG_TRACE_LIBS, "got princ_str: %s\n", ibuf->princ_str); if (ibuf->princ_str == NULL) return ENOMEM; p += len; } /* keytab_name size and length */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); DEBUG(SSSDBG_TRACE_LIBS, "keytab_name size: %d\n", len); if (len) { if (len > size - p) return EINVAL; ibuf->keytab_name = talloc_strndup(ibuf, (char *)(buf + p), len); DEBUG(SSSDBG_TRACE_LIBS, "got keytab_name: %s\n", ibuf->keytab_name); if (ibuf->keytab_name == NULL) return ENOMEM; p += len; } /* ticket lifetime */ SAFEALIGN_COPY_UINT32_CHECK(&ibuf->lifetime, buf + p, size, &p); DEBUG(SSSDBG_TRACE_LIBS, "lifetime: %u\n", ibuf->lifetime); /* UID and GID to run as */ SAFEALIGN_COPY_UINT32_CHECK(&ibuf->uid, buf + p, size, &p); SAFEALIGN_COPY_UINT32_CHECK(&ibuf->gid, buf + p, size, &p); DEBUG(SSSDBG_FUNC_DATA, "Will run as [%"SPRIuid"][%"SPRIgid"].\n", ibuf->uid, ibuf->gid); return EOK; } static int pack_buffer(struct response *r, int result, krb5_error_code krberr, const char *msg, time_t expire_time) { int len; size_t p = 0; len = strlen(msg); r->size = 2 * sizeof(uint32_t) + sizeof(krb5_error_code) + len + sizeof(time_t); DEBUG(SSSDBG_TRACE_INTERNAL, "response size: %zu\n",r->size); r->buf = talloc_array(r, uint8_t, r->size); if(!r->buf) { return ENOMEM; } DEBUG(SSSDBG_TRACE_LIBS, "result [%d] krberr [%d] msgsize [%d] msg [%s]\n", result, krberr, len, msg); /* result */ SAFEALIGN_SET_UINT32(&r->buf[p], result, &p); /* krb5 error code */ safealign_memcpy(&r->buf[p], &krberr, sizeof(krberr), &p); /* message size */ SAFEALIGN_SET_UINT32(&r->buf[p], len, &p); /* message itself */ safealign_memcpy(&r->buf[p], msg, len, &p); /* ticket expiration time */ safealign_memcpy(&r->buf[p], &expire_time, sizeof(expire_time), &p); return EOK; } static errno_t set_child_debugging(krb5_context ctx) { krb5_error_code kerr; /* Set the global error context */ krb5_error_ctx = ctx; if (debug_level & SSSDBG_TRACE_ALL) { kerr = sss_child_set_krb5_tracing(ctx); if (kerr) { LDAP_CHILD_DEBUG(SSSDBG_MINOR_FAILURE, kerr); return EIO; } } return EOK; } static int lc_verify_keytab_ex(const char *principal, const char *keytab_name, krb5_context context, krb5_keytab keytab) { bool found; char *kt_principal; krb5_error_code krberr; krb5_kt_cursor cursor; krb5_keytab_entry entry; krberr = krb5_kt_start_seq_get(context, keytab, &cursor); if (krberr) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot read keytab [%s].\n", KEYTAB_CLEAN_NAME); sss_log(SSS_LOG_ERR, "Error reading keytab file [%s]: [%d][%s]. " "Unable to create GSSAPI-encrypted LDAP " "connection.", KEYTAB_CLEAN_NAME, krberr, sss_krb5_get_error_message(context, krberr)); return EIO; } found = false; while ((krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0) { krberr = krb5_unparse_name(context, entry.principal, &kt_principal); if (krberr) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not parse keytab entry\n"); sss_log(SSS_LOG_ERR, "Could not parse keytab entry\n"); return EIO; } if (strcmp(principal, kt_principal) == 0) { found = true; } free(kt_principal); krberr = sss_krb5_free_keytab_entry_contents(context, &entry); if (krberr) { /* This should never happen. The API docs for this function * specify only success for this function */ DEBUG(SSSDBG_CRIT_FAILURE,"Could not free keytab entry contents\n"); /* This is non-fatal, so we'll continue here */ } if (found) { break; } } krberr = krb5_kt_end_seq_get(context, keytab, &cursor); if (krberr) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not close keytab.\n"); sss_log(SSS_LOG_ERR, "Could not close keytab file [%s].", KEYTAB_CLEAN_NAME); return EIO; } if (!found) { DEBUG(SSSDBG_FATAL_FAILURE, "Principal [%s] not found in keytab [%s]\n", principal, KEYTAB_CLEAN_NAME); sss_log(SSS_LOG_ERR, "Error processing keytab file [%s]: " "Principal [%s] was not found. " "Unable to create GSSAPI-encrypted LDAP connection.", KEYTAB_CLEAN_NAME, principal); return EFAULT; } return EOK; } static krb5_error_code ldap_child_get_tgt_sync(TALLOC_CTX *memctx, krb5_context context, const char *realm_str, const char *princ_str, const char *keytab_name, const krb5_deltat lifetime, const char **ccname_out, time_t *expire_time_out) { char *ccname; char *ccname_dummy; char *realm_name = NULL; char *full_princ = NULL; char *default_realm = NULL; char *tmp_str = NULL; krb5_keytab keytab = NULL; krb5_ccache ccache = NULL; krb5_principal kprinc; krb5_creds my_creds; krb5_get_init_creds_opt options; krb5_error_code krberr; krb5_timestamp kdc_time_offset; int canonicalize = 0; int kdc_time_offset_usec; int ret; TALLOC_CTX *tmp_ctx; char *ccname_file_dummy = NULL; char *ccname_file; tmp_ctx = talloc_new(memctx); if (tmp_ctx == NULL) { krberr = KRB5KRB_ERR_GENERIC; goto done; } krberr = set_child_debugging(context); if (krberr != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set krb5_child debugging\n"); } if (!realm_str) { krberr = krb5_get_default_realm(context, &default_realm); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get default realm name: %s\n", sss_krb5_get_error_message(context, krberr)); goto done; } realm_name = talloc_strdup(tmp_ctx, default_realm); krb5_free_default_realm(context, default_realm); if (!realm_name) { krberr = KRB5KRB_ERR_GENERIC; goto done; } } else { realm_name = talloc_strdup(tmp_ctx, realm_str); if (!realm_name) { krberr = KRB5KRB_ERR_GENERIC; goto done; } } DEBUG(SSSDBG_TRACE_INTERNAL, "got realm_name: [%s]\n", realm_name); if (princ_str) { if (!strchr(princ_str, '@')) { full_princ = talloc_asprintf(tmp_ctx, "%s@%s", princ_str, realm_name); } else { full_princ = talloc_strdup(tmp_ctx, princ_str); } } else { char hostname[HOST_NAME_MAX + 1]; ret = gethostname(hostname, HOST_NAME_MAX); if (ret == -1) { krberr = KRB5KRB_ERR_GENERIC; goto done; } hostname[HOST_NAME_MAX] = '\0'; DEBUG(SSSDBG_TRACE_LIBS, "got hostname: [%s]\n", hostname); ret = select_principal_from_keytab(tmp_ctx, hostname, realm_name, keytab_name, &full_princ, NULL, NULL); if (ret) { krberr = KRB5_KT_IOERR; goto done; } } if (!full_princ) { krberr = KRB5KRB_ERR_GENERIC; goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Principal name is: [%s]\n", full_princ); krberr = krb5_parse_name(context, full_princ, &kprinc); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, "Unable to build principal: %s\n", sss_krb5_get_error_message(context, krberr)); goto done; } if (keytab_name) { krberr = krb5_kt_resolve(context, keytab_name, &keytab); } else { krberr = krb5_kt_default(context, &keytab); } DEBUG(SSSDBG_CONF_SETTINGS, "Using keytab [%s]\n", KEYTAB_CLEAN_NAME); if (krberr) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to read keytab file [%s]: %s\n", KEYTAB_CLEAN_NAME, sss_krb5_get_error_message(context, krberr)); goto done; } /* Verify the keytab */ ret = lc_verify_keytab_ex(full_princ, keytab_name, context, keytab); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Unable to verify principal is present in the keytab\n"); krberr = KRB5_KT_IOERR; goto done; } memset(&my_creds, 0, sizeof(my_creds)); memset(&options, 0, sizeof(options)); krb5_get_init_creds_opt_set_address_list(&options, NULL); krb5_get_init_creds_opt_set_forwardable(&options, 0); krb5_get_init_creds_opt_set_proxiable(&options, 0); krb5_get_init_creds_opt_set_tkt_life(&options, lifetime); tmp_str = getenv("KRB5_CANONICALIZE"); if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Will canonicalize principals\n"); canonicalize = 1; } sss_krb5_get_init_creds_opt_set_canonicalize(&options, canonicalize); ccname_file = talloc_asprintf(tmp_ctx, "%s/ccache_%s", DB_PATH, realm_name); if (ccname_file == NULL) { krberr = ENOMEM; DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed: %s:[%d].\n", strerror(krberr), krberr); goto done; } ccname_file_dummy = talloc_asprintf(tmp_ctx, "%s/ccache_%s_XXXXXX", DB_PATH, realm_name); if (ccname_file_dummy == NULL) { krberr = ENOMEM; DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed: %s:[%d].\n", strerror(krberr), krberr); goto done; } ret = sss_unique_filename(tmp_ctx, ccname_file_dummy); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_unique_filename failed: %s:[%d].\n", strerror(ret), ret); krberr = KRB5KRB_ERR_GENERIC; goto done; } krberr = krb5_get_init_creds_keytab(context, &my_creds, kprinc, keytab, 0, NULL, &options); krb5_kt_close(context, keytab); keytab = NULL; if (krberr) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init credentials: %s\n", sss_krb5_get_error_message(context, krberr)); sss_log(SSS_LOG_ERR, "Failed to initialize credentials using keytab [%s]: %s. " "Unable to create GSSAPI-encrypted LDAP connection.", KEYTAB_CLEAN_NAME, sss_krb5_get_error_message(context, krberr)); goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "credentials initialized\n"); ccname_dummy = talloc_asprintf(tmp_ctx, "FILE:%s", ccname_file_dummy); ccname = talloc_asprintf(tmp_ctx, "FILE:%s", ccname_file); if (ccname_dummy == NULL || ccname == NULL) { krberr = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "keytab ccname: [%s]\n", ccname_dummy); krberr = krb5_cc_resolve(context, ccname_dummy, &ccache); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, "Failed to set cache name: %s\n", sss_krb5_get_error_message(context, krberr)); goto done; } /* Use updated principal if changed due to canonicalization. */ krberr = krb5_cc_initialize(context, ccache, my_creds.client); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, "Failed to init ccache: %s\n", sss_krb5_get_error_message(context, krberr)); goto done; } krberr = krb5_cc_store_cred(context, ccache, &my_creds); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store creds: %s\n", sss_krb5_get_error_message(context, krberr)); goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "credentials stored\n"); #ifdef HAVE_KRB5_GET_TIME_OFFSETS krberr = krb5_get_time_offsets(context, &kdc_time_offset, &kdc_time_offset_usec); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get KDC time offset: %s\n", sss_krb5_get_error_message(context, krberr)); kdc_time_offset = 0; } else { if (kdc_time_offset_usec > 0) { kdc_time_offset++; } } DEBUG(SSSDBG_TRACE_INTERNAL, "Got KDC time offset\n"); #else /* If we don't have this function, just assume no offset */ kdc_time_offset = 0; #endif DEBUG(SSSDBG_TRACE_INTERNAL, "Renaming [%s] to [%s]\n", ccname_file_dummy, ccname_file); ret = rename(ccname_file_dummy, ccname_file); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "rename failed [%d][%s].\n", ret, strerror(ret)); goto done; } krberr = 0; *ccname_out = talloc_steal(memctx, ccname); *expire_time_out = my_creds.times.endtime - kdc_time_offset; done: if (krberr != 0) KRB5_SYSLOG(krberr); if (keytab) krb5_kt_close(context, keytab); if (context) krb5_free_context(context); talloc_free(tmp_ctx); return krberr; } static int prepare_response(TALLOC_CTX *mem_ctx, const char *ccname, time_t expire_time, krb5_error_code kerr, struct response **rsp) { int ret; struct response *r = NULL; const char *krb5_msg = NULL; r = talloc_zero(mem_ctx, struct response); if (!r) return ENOMEM; r->buf = NULL; r->size = 0; DEBUG(SSSDBG_TRACE_FUNC, "Building response for result [%d]\n", kerr); if (kerr == 0) { ret = pack_buffer(r, EOK, kerr, ccname, expire_time); } else { krb5_msg = sss_krb5_get_error_message(krb5_error_ctx, kerr); if (krb5_msg == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_get_error_message failed.\n"); return ENOMEM; } ret = pack_buffer(r, EFAULT, kerr, krb5_msg, 0); sss_krb5_free_error_message(krb5_error_ctx, krb5_msg); } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_buffer failed\n"); return ret; } *rsp = r; return EOK; } static krb5_error_code privileged_krb5_setup(struct input_buffer *ibuf) { krb5_error_code kerr; char *keytab_name; kerr = krb5_init_context(&ibuf->context); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to init kerberos context\n"); return kerr; } DEBUG(SSSDBG_TRACE_INTERNAL, "Kerberos context initialized\n"); kerr = copy_keytab_into_memory(ibuf, ibuf->context, ibuf->keytab_name, &keytab_name, NULL); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "copy_keytab_into_memory failed.\n"); return kerr; } talloc_free(ibuf->keytab_name); ibuf->keytab_name = keytab_name; return 0; } int main(int argc, const char *argv[]) { int ret; int kerr; int opt; int debug_fd = -1; poptContext pc; TALLOC_CTX *main_ctx = NULL; uint8_t *buf = NULL; ssize_t len = 0; const char *ccname = NULL; time_t expire_time = 0; struct input_buffer *ibuf = NULL; struct response *resp = NULL; ssize_t written; struct poptOption long_options[] = { POPT_AUTOHELP {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, _("Debug level"), NULL}, {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0, _("Add debug timestamps"), NULL}, {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0, _("Show timestamps with microseconds"), NULL}, {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0, _("An open file descriptor for the debug logs"), NULL}, {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, \ _("Send the debug output to stderr directly."), NULL }, \ POPT_TABLEEND }; /* Set debug level to invalid value so we can decide if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); _exit(-1); } } poptFreeContext(pc); DEBUG_INIT(debug_level); debug_prg_name = talloc_asprintf(NULL, "[sssd[ldap_child[%d]]]", getpid()); if (!debug_prg_name) { debug_prg_name = "[sssd[ldap_child]]"; DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); goto fail; } if (debug_fd != -1) { ret = set_debug_file_from_fd(debug_fd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n"); } } DEBUG(SSSDBG_TRACE_FUNC, "ldap_child started.\n"); main_ctx = talloc_new(NULL); if (main_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); talloc_free(discard_const(debug_prg_name)); goto fail; } talloc_steal(main_ctx, debug_prg_name); buf = talloc_size(main_ctx, sizeof(uint8_t)*IN_BUF_SIZE); if (buf == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); goto fail; } ibuf = talloc_zero(main_ctx, struct input_buffer); if (ibuf == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "context initialized\n"); errno = 0; len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE); if (len == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret)); goto fail; } close(STDIN_FILENO); ret = unpack_buffer(buf, len, ibuf); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "unpack_buffer failed.[%d][%s].\n", ret, strerror(ret)); goto fail; } kerr = privileged_krb5_setup(ibuf); if (kerr != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Privileged Krb5 setup failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "Kerberos context initialized\n"); kerr = become_user(ibuf->uid, ibuf->gid); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid()); DEBUG(SSSDBG_TRACE_INTERNAL, "getting TGT sync\n"); kerr = ldap_child_get_tgt_sync(main_ctx, ibuf->context, ibuf->realm_str, ibuf->princ_str, ibuf->keytab_name, ibuf->lifetime, &ccname, &expire_time); if (kerr != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_child_get_tgt_sync failed.\n"); /* Do not return, must report failure */ } ret = prepare_response(main_ctx, ccname, expire_time, kerr, &resp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "prepare_response failed. [%d][%s].\n", ret, strerror(ret)); goto fail; } errno = 0; written = sss_atomic_write_s(STDOUT_FILENO, resp->buf, resp->size); if (written == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret, strerror(ret)); goto fail; } if (written != resp->size) { DEBUG(SSSDBG_CRIT_FAILURE, "Expected to write %zu bytes, wrote %zu\n", resp->size, written); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "ldap_child completed successfully\n"); close(STDOUT_FILENO); talloc_free(main_ctx); _exit(0); fail: DEBUG(SSSDBG_CRIT_FAILURE, "ldap_child failed!\n"); close(STDOUT_FILENO); talloc_free(main_ctx); _exit(-1); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_connection.c0000644000000000000000000000007312703456111022557 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.785794073 sssd-1.13.4/src/providers/ldap/sdap_async_connection.c0000644002412700241270000022022212703456111024227 0ustar00jhrozekjhrozek00000000000000/* SSSD Async LDAP Helper routines Copyright (C) Simo Sorce - 2009 Copyright (C) 2010, rhafer@suse.de, Novell Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "util/sss_krb5.h" #include "util/sss_ldap.h" #include "util/strtonum.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/ldap_common.h" /* ==Connect-to-LDAP-Server=============================================== */ struct sdap_rebind_proc_params { struct sdap_options *opts; struct sdap_handle *sh; bool use_start_tls; }; static int sdap_rebind_proc(LDAP *ldap, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *params); struct sdap_connect_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; const char *uri; bool use_start_tls; struct sdap_op *op; struct sdap_msg *reply; int result; }; static void sdap_sys_connect_done(struct tevent_req *subreq); static void sdap_connect_done(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt); struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, const char *uri, struct sockaddr_storage *sockaddr, bool use_start_tls) { struct tevent_req *req; struct tevent_req *subreq; struct sdap_connect_state *state; int ret; int timeout; req = tevent_req_create(memctx, &state, struct sdap_connect_state); if (!req) return NULL; if (uri == NULL || sockaddr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid uri or sockaddr\n"); ret = EINVAL; goto fail; } state->reply = talloc(state, struct sdap_msg); if (!state->reply) { talloc_zfree(req); return NULL; } state->ev = ev; state->opts = opts; state->use_start_tls = use_start_tls; state->uri = talloc_asprintf(state, "%s", uri); if (!state->uri) { talloc_zfree(req); return NULL; } state->sh = sdap_handle_create(state); if (!state->sh) { talloc_zfree(req); return NULL; } state->sh->page_size = dp_opt_get_int(state->opts->basic, SDAP_PAGE_SIZE); timeout = dp_opt_get_int(state->opts->basic, SDAP_NETWORK_TIMEOUT); subreq = sss_ldap_init_send(state, ev, state->uri, sockaddr, sizeof(struct sockaddr_storage), timeout); if (subreq == NULL) { ret = ENOMEM; DEBUG(SSSDBG_CRIT_FAILURE, "sss_ldap_init_send failed.\n"); goto fail; } tevent_req_set_callback(subreq, sdap_sys_connect_done, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void sdap_sys_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_connect_state *state = tevent_req_data(req, struct sdap_connect_state); struct timeval tv; int ver; int lret; int optret; int ret = EOK; int msgid; char *errmsg = NULL; bool ldap_referrals; const char *ldap_deref; int ldap_deref_val; struct sdap_rebind_proc_params *rebind_proc_params; int sd; bool sasl_nocanon; const char *sasl_mech; int sasl_minssf; ber_len_t ber_sasl_minssf; ret = sss_ldap_init_recv(subreq, &state->sh->ldap, &sd); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_async_connect_call request failed: [%d]: %s.\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } ret = setup_ldap_connection_callbacks(state->sh, state->ev); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "setup_ldap_connection_callbacks failed: [%d]: %s.\n", ret, sss_strerror(ret)); goto fail; } /* If sss_ldap_init_recv() does not return a valid file descriptor we have * to assume that the connection callback will be called by internally by * the OpenLDAP client library. */ if (sd != -1) { ret = sdap_call_conn_cb(state->uri, sd, state->sh); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_call_conn_cb failed.\n"); goto fail; } } /* Force ldap version to 3 */ ver = LDAP_VERSION3; lret = ldap_set_option(state->sh->ldap, LDAP_OPT_PROTOCOL_VERSION, &ver); if (lret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set ldap version to 3\n"); goto fail; } /* TODO: maybe this can be remove when we go async, currently we need it * to handle EINTR during poll(). */ ret = ldap_set_option(state->sh->ldap, LDAP_OPT_RESTART, LDAP_OPT_ON); if (ret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set restart option.\n"); } /* Set Network Timeout */ tv.tv_sec = dp_opt_get_int(state->opts->basic, SDAP_NETWORK_TIMEOUT); tv.tv_usec = 0; lret = ldap_set_option(state->sh->ldap, LDAP_OPT_NETWORK_TIMEOUT, &tv); if (lret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set network timeout to %d\n", dp_opt_get_int(state->opts->basic, SDAP_NETWORK_TIMEOUT)); goto fail; } /* Set Default Timeout */ tv.tv_sec = dp_opt_get_int(state->opts->basic, SDAP_OPT_TIMEOUT); tv.tv_usec = 0; lret = ldap_set_option(state->sh->ldap, LDAP_OPT_TIMEOUT, &tv); if (lret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set default timeout to %d\n", dp_opt_get_int(state->opts->basic, SDAP_OPT_TIMEOUT)); goto fail; } /* Set Referral chasing */ ldap_referrals = dp_opt_get_bool(state->opts->basic, SDAP_REFERRALS); lret = ldap_set_option(state->sh->ldap, LDAP_OPT_REFERRALS, (ldap_referrals ? LDAP_OPT_ON : LDAP_OPT_OFF)); if (lret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set referral chasing to %s\n", (ldap_referrals ? "LDAP_OPT_ON" : "LDAP_OPT_OFF")); goto fail; } if (ldap_referrals) { rebind_proc_params = talloc_zero(state->sh, struct sdap_rebind_proc_params); if (rebind_proc_params == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; goto fail; } rebind_proc_params->opts = state->opts; rebind_proc_params->sh = state->sh; rebind_proc_params->use_start_tls = state->use_start_tls; lret = ldap_set_rebind_proc(state->sh->ldap, sdap_rebind_proc, rebind_proc_params); if (lret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_set_rebind_proc failed.\n"); goto fail; } } /* Set alias dereferencing */ ldap_deref = dp_opt_get_string(state->opts->basic, SDAP_DEREF); if (ldap_deref != NULL) { ret = deref_string_to_val(ldap_deref, &ldap_deref_val); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "deref_string_to_val failed.\n"); goto fail; } lret = ldap_set_option(state->sh->ldap, LDAP_OPT_DEREF, &ldap_deref_val); if (lret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set deref option to %d\n", ldap_deref_val); goto fail; } } /* Set host name canonicalization for LDAP SASL bind */ sasl_nocanon = !dp_opt_get_bool(state->opts->basic, SDAP_SASL_CANONICALIZE); lret = ldap_set_option(state->sh->ldap, LDAP_OPT_X_SASL_NOCANON, sasl_nocanon ? LDAP_OPT_ON : LDAP_OPT_OFF); if (lret != LDAP_OPT_SUCCESS) { /* Do not fail, just warn into both debug logs and syslog */ DEBUG(SSSDBG_MINOR_FAILURE, "Failed to set LDAP SASL nocanon option to %s. If your system " "is configured to use SASL, LDAP operations might fail.\n", sasl_nocanon ? "true" : "false"); sss_log(SSS_LOG_INFO, "Failed to set LDAP SASL nocanon option to %s. If your system " "is configured to use SASL, LDAP operations might fail.\n", sasl_nocanon ? "true" : "false"); } sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH); if (sasl_mech != NULL) { sasl_minssf = dp_opt_get_int(state->opts->basic, SDAP_SASL_MINSSF); if (sasl_minssf >= 0) { ber_sasl_minssf = (ber_len_t)sasl_minssf; lret = ldap_set_option(state->sh->ldap, LDAP_OPT_X_SASL_SSF_MIN, &ber_sasl_minssf); if (lret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set LDAP MIN SSF option " "to %d\n", sasl_minssf); goto fail; } } } /* if we do not use start_tls the connection is not really connected yet * just fake an async procedure and leave connection to the bind call */ if (!state->use_start_tls) { tevent_req_done(req); return; } DEBUG(SSSDBG_CONF_SETTINGS, "Executing START TLS\n"); lret = ldap_start_tls(state->sh->ldap, NULL, NULL, &msgid); if (lret != LDAP_SUCCESS) { optret = sss_ldap_get_diagnostic_msg(state, state->sh->ldap, &errmsg); if (optret == LDAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_start_tls failed: [%s] [%s]\n", sss_ldap_err2string(lret), errmsg); sss_log(SSS_LOG_ERR, "Could not start TLS. %s", errmsg); } else { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_start_tls failed: [%s]\n", sss_ldap_err2string(lret)); sss_log(SSS_LOG_ERR, "Could not start TLS. " "Check for certificate issues."); } goto fail; } ret = sdap_set_connected(state->sh, state->ev); if (ret) goto fail; ret = sdap_op_add(state, state->ev, state->sh, msgid, sdap_connect_done, req, dp_opt_get_int(state->opts->basic, SDAP_OPT_TIMEOUT), &state->op); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set up operation!\n"); goto fail; } return; fail: if (ret) { tevent_req_error(req, ret); } else { if (lret == LDAP_SERVER_DOWN) { tevent_req_error(req, ETIMEDOUT); } else { tevent_req_error(req, EIO); } } return; } static void sdap_connect_done(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct sdap_connect_state *state = tevent_req_data(req, struct sdap_connect_state); char *errmsg = NULL; char *tlserr; int ret; int optret; if (error) { tevent_req_error(req, error); return; } state->reply = talloc_steal(state, reply); ret = ldap_parse_result(state->sh->ldap, state->reply->msg, &state->result, NULL, &errmsg, NULL, NULL, 0); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldap_parse_result failed (%d)\n", state->op->msgid); tevent_req_error(req, EIO); return; } DEBUG(SSSDBG_MINOR_FAILURE, "START TLS result: %s(%d), %s\n", sss_ldap_err2string(state->result), state->result, errmsg); ldap_memfree(errmsg); if (ldap_tls_inplace(state->sh->ldap)) { DEBUG(SSSDBG_TRACE_ALL, "SSL/TLS handler already in place.\n"); tevent_req_done(req); return; } /* FIXME: take care that ldap_install_tls might block */ ret = ldap_install_tls(state->sh->ldap); if (ret != LDAP_SUCCESS) { optret = sss_ldap_get_diagnostic_msg(state, state->sh->ldap, &tlserr); if (optret == LDAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_install_tls failed: [%s] [%s]\n", sss_ldap_err2string(ret), tlserr); sss_log(SSS_LOG_ERR, "Could not start TLS encryption. %s", tlserr); } else { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_install_tls failed: [%s]\n", sss_ldap_err2string(ret)); sss_log(SSS_LOG_ERR, "Could not start TLS encryption. " "Check for certificate issues."); } state->result = ret; tevent_req_error(req, EIO); return; } tevent_req_done(req); } int sdap_connect_recv(struct tevent_req *req, TALLOC_CTX *memctx, struct sdap_handle **sh) { struct sdap_connect_state *state = tevent_req_data(req, struct sdap_connect_state); TEVENT_REQ_RETURN_ON_ERROR(req); *sh = talloc_steal(memctx, state->sh); if (!*sh) { return ENOMEM; } return EOK; } struct sdap_connect_host_state { struct tevent_context *ev; struct sdap_options *opts; char *uri; char *protocol; char *host; int port; bool use_start_tls; struct sdap_handle *sh; }; static void sdap_connect_host_resolv_done(struct tevent_req *subreq); static void sdap_connect_host_done(struct tevent_req *subreq); struct tevent_req *sdap_connect_host_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct resolv_ctx *resolv_ctx, enum restrict_family family_order, enum host_database *host_db, const char *protocol, const char *host, int port, bool use_start_tls) { struct sdap_connect_host_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_connect_host_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->opts = opts; state->port = port; state->use_start_tls = use_start_tls; state->protocol = talloc_strdup(state, protocol); if (state->protocol == NULL) { ret = ENOMEM; goto immediately; } state->host = talloc_strdup(state, host); if (state->host == NULL) { ret = ENOMEM; goto immediately; } state->uri = talloc_asprintf(state, "%s://%s:%d", protocol, host, port); if (state->uri == NULL) { ret = ENOMEM; goto immediately; } DEBUG(SSSDBG_TRACE_FUNC, "Resolving host %s\n", host); subreq = resolv_gethostbyname_send(state, state->ev, resolv_ctx, host, family_order, host_db); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_connect_host_resolv_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sdap_connect_host_resolv_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; struct sdap_connect_host_state *state = NULL; struct resolv_hostent *hostent = NULL; struct sockaddr_storage *sockaddr = NULL; int status; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_connect_host_state); ret = resolv_gethostbyname_recv(subreq, state, &status, NULL, &hostent); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to resolve host %s: %s\n", state->host, resolv_strerror(status)); goto done; } sockaddr = resolv_get_sockaddr_address(state, hostent, state->port); if (sockaddr == NULL) { DEBUG(SSSDBG_OP_FAILURE, "resolv_get_sockaddr_address() failed\n"); ret = EIO; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Connecting to %s\n", state->uri); subreq = sdap_connect_send(state, state->ev, state->opts, state->uri, sockaddr, state->use_start_tls); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_connect_host_done, req); ret = EAGAIN; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static void sdap_connect_host_done(struct tevent_req *subreq) { struct sdap_connect_host_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_connect_host_state); ret = sdap_connect_recv(subreq, state, &state->sh); talloc_zfree(subreq); if (ret != EOK) { goto done; } /* if TLS was used, the sdap handle is already marked as connected */ if (!state->use_start_tls) { /* we need to mark handle as connected to allow anonymous bind */ ret = sdap_set_connected(state->sh, state->ev); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_set_connected() failed\n"); goto done; } } DEBUG(SSSDBG_TRACE_FUNC, "Successful connection to %s\n", state->uri); done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } errno_t sdap_connect_host_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct sdap_handle **_sh) { struct sdap_connect_host_state *state = NULL; state = tevent_req_data(req, struct sdap_connect_host_state); TEVENT_REQ_RETURN_ON_ERROR(req); *_sh = talloc_steal(mem_ctx, state->sh); return EOK; } /* ==Simple-Bind========================================================== */ struct simple_bind_state { struct tevent_context *ev; struct sdap_handle *sh; const char *user_dn; struct berval *pw; struct sdap_op *op; struct sdap_msg *reply; struct sdap_ppolicy_data *ppolicy; }; static void simple_bind_done(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt); static struct tevent_req *simple_bind_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_handle *sh, int timeout, const char *user_dn, struct berval *pw) { struct tevent_req *req; struct simple_bind_state *state; int ret = EOK; int msgid; int ldap_err; LDAPControl **request_controls = NULL; LDAPControl *ctrls[2] = { NULL, NULL }; req = tevent_req_create(memctx, &state, struct simple_bind_state); if (!req) return NULL; state->reply = talloc(state, struct sdap_msg); if (!state->reply) { talloc_zfree(req); return NULL; } state->ev = ev; state->sh = sh; state->user_dn = user_dn; state->pw = pw; ret = sss_ldap_control_create(LDAP_CONTROL_PASSWORDPOLICYREQUEST, 0, NULL, 0, &ctrls[0]); if (ret != LDAP_SUCCESS && ret != LDAP_NOT_SUPPORTED) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_ldap_control_create failed to create " "Password Policy control.\n"); goto fail; } request_controls = ctrls; DEBUG(SSSDBG_CONF_SETTINGS, "Executing simple bind as: %s\n", state->user_dn); ret = ldap_sasl_bind(state->sh->ldap, state->user_dn, LDAP_SASL_SIMPLE, pw, request_controls, NULL, &msgid); if (ctrls[0]) ldap_control_free(ctrls[0]); if (ret == -1 || msgid == -1) { ret = ldap_get_option(state->sh->ldap, LDAP_OPT_RESULT_CODE, &ldap_err); if (ret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_bind failed (couldn't get ldap error)\n"); ret = LDAP_LOCAL_ERROR; } else { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_bind failed (%d)[%s]\n", ldap_err, sss_ldap_err2string(ldap_err)); ret = ldap_err; } goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "ldap simple bind sent, msgid = %d\n", msgid); if (!sh->connected) { ret = sdap_set_connected(sh, ev); if (ret) goto fail; } ret = sdap_op_add(state, ev, sh, msgid, simple_bind_done, req, timeout, &state->op); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set up operation!\n"); goto fail; } return req; fail: if (ret == LDAP_SERVER_DOWN) { tevent_req_error(req, ETIMEDOUT); } else { tevent_req_error(req, ERR_NETWORK_IO); } tevent_req_post(req, ev); return req; } static void simple_bind_done(struct sdap_op *op, struct sdap_msg *reply, int error, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct simple_bind_state *state = tevent_req_data(req, struct simple_bind_state); char *errmsg = NULL; char *nval; errno_t ret = ERR_INTERNAL; int lret; LDAPControl **response_controls; int c; ber_int_t pp_grace; ber_int_t pp_expire; LDAPPasswordPolicyError pp_error; int result = LDAP_OTHER; if (error) { tevent_req_error(req, error); return; } state->reply = talloc_steal(state, reply); lret = ldap_parse_result(state->sh->ldap, state->reply->msg, &result, NULL, &errmsg, NULL, &response_controls, 0); if (lret != LDAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_parse_result failed (%d)\n", state->op->msgid); ret = ERR_INTERNAL; goto done; } if (result == LDAP_SUCCESS) { ret = EOK; } else if (result == LDAP_INVALID_CREDENTIALS && errmsg != NULL && strstr(errmsg, "data 775,") != NULL) { /* Value 775 is described in * https://msdn.microsoft.com/en-us/library/windows/desktop/ms681386%28v=vs.85%29.aspx * for more details please see commit message. */ ret = ERR_ACCOUNT_LOCKED; } else { ret = ERR_AUTH_FAILED; } if (response_controls == NULL) { DEBUG(SSSDBG_TRACE_LIBS, "Server returned no controls.\n"); state->ppolicy = NULL; } else { for (c = 0; response_controls[c] != NULL; c++) { DEBUG(SSSDBG_TRACE_INTERNAL, "Server returned control [%s].\n", response_controls[c]->ldctl_oid); if (strcmp(response_controls[c]->ldctl_oid, LDAP_CONTROL_PASSWORDPOLICYRESPONSE) == 0) { lret = ldap_parse_passwordpolicy_control(state->sh->ldap, response_controls[c], &pp_expire, &pp_grace, &pp_error); if (lret != LDAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_parse_passwordpolicy_control failed.\n"); ret = ERR_INTERNAL; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Password Policy Response: expire [%d] grace [%d] " "error [%s].\n", pp_expire, pp_grace, ldap_passwordpolicy_err2txt(pp_error)); if (!state->ppolicy) state->ppolicy = talloc_zero(state, struct sdap_ppolicy_data); if (state->ppolicy == NULL) { ret = ENOMEM; goto done; } state->ppolicy->grace = pp_grace; state->ppolicy->expire = pp_expire; if (result == LDAP_SUCCESS) { if (pp_error == PP_changeAfterReset) { DEBUG(SSSDBG_TRACE_LIBS, "Password was reset. " "User must set a new password.\n"); ret = ERR_PASSWORD_EXPIRED; } else if (pp_grace >= 0) { DEBUG(SSSDBG_TRACE_LIBS, "Password expired. " "[%d] grace logins remaining.\n", pp_grace); } else if (pp_expire > 0) { DEBUG(SSSDBG_TRACE_LIBS, "Password will expire in [%d] seconds.\n", pp_expire); } } else if (result == LDAP_INVALID_CREDENTIALS && pp_error == PP_passwordExpired) { DEBUG(SSSDBG_TRACE_LIBS, "Password expired user must set a new password.\n"); ret = ERR_PASSWORD_EXPIRED; } } else if (strcmp(response_controls[c]->ldctl_oid, LDAP_CONTROL_PWEXPIRED) == 0) { DEBUG(SSSDBG_TRACE_LIBS, "Password expired user must set a new password.\n"); ret = ERR_PASSWORD_EXPIRED; } else if (strcmp(response_controls[c]->ldctl_oid, LDAP_CONTROL_PWEXPIRING) == 0) { /* ignore controls with suspiciously long values */ if (response_controls[c]->ldctl_value.bv_len > 32) { continue; } if (!state->ppolicy) { state->ppolicy = talloc(state, struct sdap_ppolicy_data); } if (state->ppolicy == NULL) { ret = ENOMEM; goto done; } /* ensure that bv_val is a null-terminated string */ nval = talloc_strndup(NULL, response_controls[c]->ldctl_value.bv_val, response_controls[c]->ldctl_value.bv_len); if (nval == NULL) { ret = ENOMEM; goto done; } state->ppolicy->expire = strtouint32(nval, NULL, 10); lret = errno; talloc_zfree(nval); if (lret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Couldn't convert control response " "to an integer [%s].\n", strerror(lret)); ret = ERR_INTERNAL; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Password will expire in [%d] seconds.\n", state->ppolicy->expire); } } } DEBUG(SSSDBG_TRACE_FUNC, "Bind result: %s(%d), %s\n", sss_ldap_err2string(result), result, errmsg ? errmsg : "no errmsg set"); if (result != LDAP_SUCCESS && ret == EOK) { ret = ERR_AUTH_FAILED; } done: ldap_controls_free(response_controls); ldap_memfree(errmsg); if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } static errno_t simple_bind_recv(struct tevent_req *req, TALLOC_CTX *memctx, struct sdap_ppolicy_data **ppolicy) { struct simple_bind_state *state = tevent_req_data(req, struct simple_bind_state); if (ppolicy != NULL) { *ppolicy = talloc_steal(memctx, state->ppolicy); } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==SASL-Bind============================================================ */ struct sasl_bind_state { struct tevent_context *ev; struct sdap_handle *sh; const char *sasl_mech; const char *sasl_user; struct berval *sasl_cred; }; static int sdap_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *interact); static struct tevent_req *sasl_bind_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_handle *sh, const char *sasl_mech, const char *sasl_user, struct berval *sasl_cred) { struct tevent_req *req; struct sasl_bind_state *state; int ret = EOK; int optret; char *diag_msg = NULL; req = tevent_req_create(memctx, &state, struct sasl_bind_state); if (!req) return NULL; state->ev = ev; state->sh = sh; state->sasl_mech = sasl_mech; state->sasl_user = sasl_user; state->sasl_cred = sasl_cred; DEBUG(SSSDBG_CONF_SETTINGS, "Executing sasl bind mech: %s, user: %s\n", sasl_mech, sasl_user); /* FIXME: Warning, this is a sync call! * No async variant exist in openldap libraries yet */ if (state->sh == NULL || state->sh->ldap == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Trying LDAP search while not connected.\n"); ret = ERR_NETWORK_IO; goto fail; } ret = ldap_sasl_interactive_bind_s(state->sh->ldap, NULL, sasl_mech, NULL, NULL, LDAP_SASL_QUIET, (*sdap_sasl_interact), state); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_sasl_bind failed (%d)[%s]\n", ret, sss_ldap_err2string(ret)); optret = sss_ldap_get_diagnostic_msg(state, state->sh->ldap, &diag_msg); if (optret == EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Extended failure message: [%s]\n", diag_msg); } talloc_zfree(diag_msg); goto fail; } if (!sh->connected) { ret = sdap_set_connected(sh, ev); if (ret) goto fail; } /* This is a hack, relies on the fact that tevent_req_done() will always * set the state but will not complain if no callback has been set. * tevent_req_post() will only set the immediate event and then just call * the async callback set by the caller right after we return using the * state value set previously by tevent_req_done() */ tevent_req_done(req); tevent_req_post(req, ev); return req; fail: if (ret == LDAP_SERVER_DOWN || ret == LDAP_TIMEOUT) { tevent_req_error(req, ETIMEDOUT); } else { tevent_req_error(req, ERR_AUTH_FAILED); } tevent_req_post(req, ev); return req; } static int sdap_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *interact) { struct sasl_bind_state *state = talloc_get_type(defaults, struct sasl_bind_state); sasl_interact_t *in = (sasl_interact_t *)interact; if (!ld) return LDAP_PARAM_ERROR; while (in->id != SASL_CB_LIST_END) { switch (in->id) { case SASL_CB_GETREALM: case SASL_CB_USER: case SASL_CB_PASS: if (in->defresult) { in->result = in->defresult; } else { in->result = ""; } in->len = strlen(in->result); break; case SASL_CB_AUTHNAME: if (state->sasl_user) { in->result = state->sasl_user; } else if (in->defresult) { in->result = in->defresult; } else { in->result = ""; } in->len = strlen(in->result); break; case SASL_CB_NOECHOPROMPT: case SASL_CB_ECHOPROMPT: goto fail; } in++; } return LDAP_SUCCESS; fail: return LDAP_UNAVAILABLE; } static errno_t sasl_bind_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==Perform-Kinit-given-keytab-and-principal============================= */ struct sdap_kinit_state { const char *keytab; const char *principal; const char *realm; int timeout; int lifetime; const char *krb_service_name; struct tevent_context *ev; struct be_ctx *be; struct fo_server *kdc_srv; time_t expire_time; }; static void sdap_kinit_done(struct tevent_req *subreq); static struct tevent_req *sdap_kinit_next_kdc(struct tevent_req *req); static void sdap_kinit_kdc_resolved(struct tevent_req *subreq); static struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct be_ctx *be, struct sdap_handle *sh, const char *krb_service_name, int timeout, const char *keytab, const char *principal, const char *realm, bool canonicalize, int lifetime) { struct tevent_req *req; struct tevent_req *subreq; struct sdap_kinit_state *state; int ret; DEBUG(SSSDBG_TRACE_FUNC, "Attempting kinit (%s, %s, %s, %d)\n", keytab ? keytab : "default", principal, realm, lifetime); if (lifetime < 0 || lifetime > INT32_MAX) { DEBUG(SSSDBG_CRIT_FAILURE, "Ticket lifetime out of range.\n"); return NULL; } req = tevent_req_create(memctx, &state, struct sdap_kinit_state); if (!req) return NULL; state->keytab = keytab; state->principal = principal; state->realm = realm; state->ev = ev; state->be = be; state->timeout = timeout; state->lifetime = lifetime; state->krb_service_name = krb_service_name; if (canonicalize) { ret = setenv("KRB5_CANONICALIZE", "true", 1); } else { ret = setenv("KRB5_CANONICALIZE", "false", 1); } if (ret == -1) { DEBUG(SSSDBG_OP_FAILURE, "Failed to set KRB5_CANONICALIZE to %s\n", ((canonicalize)?"true":"false")); talloc_free(req); return NULL; } subreq = sdap_kinit_next_kdc(req); if (!subreq) { talloc_free(req); return NULL; } return req; } static struct tevent_req *sdap_kinit_next_kdc(struct tevent_req *req) { struct tevent_req *next_req; struct sdap_kinit_state *state = tevent_req_data(req, struct sdap_kinit_state); DEBUG(SSSDBG_TRACE_LIBS, "Resolving next KDC for service %s\n", state->krb_service_name); next_req = be_resolve_server_send(state, state->ev, state->be, state->krb_service_name, state->kdc_srv == NULL ? true : false); if (next_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "be_resolve_server_send failed.\n"); return NULL; } tevent_req_set_callback(next_req, sdap_kinit_kdc_resolved, req); return next_req; } static void sdap_kinit_kdc_resolved(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_kinit_state *state = tevent_req_data(req, struct sdap_kinit_state); struct tevent_req *tgtreq; int ret; ret = be_resolve_server_recv(subreq, state, &state->kdc_srv); talloc_zfree(subreq); if (ret != EOK) { /* all servers have been tried and none * was found good, go offline */ tevent_req_error(req, ERR_NETWORK_IO); return; } DEBUG(SSSDBG_TRACE_LIBS, "KDC resolved, attempting to get TGT...\n"); tgtreq = sdap_get_tgt_send(state, state->ev, state->realm, state->principal, state->keytab, state->lifetime, state->timeout); if (!tgtreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(tgtreq, sdap_kinit_done, req); } static void sdap_kinit_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_kinit_state *state = tevent_req_data(req, struct sdap_kinit_state); int ret; int result; char *ccname = NULL; time_t expire_time = 0; krb5_error_code kerr; struct tevent_req *nextreq; ret = sdap_get_tgt_recv(subreq, state, &result, &kerr, &ccname, &expire_time); talloc_zfree(subreq); if (ret == ETIMEDOUT) { /* The child didn't even respond. Perhaps the KDC is too busy, * retry with another KDC */ DEBUG(SSSDBG_MINOR_FAILURE, "Communication with KDC timed out, trying the next one\n"); be_fo_set_port_status(state->be, state->krb_service_name, state->kdc_srv, PORT_NOT_WORKING); nextreq = sdap_kinit_next_kdc(req); if (!nextreq) { tevent_req_error(req, ENOMEM); } return; } else if (ret != EOK) { /* A severe error while executing the child. Abort the operation. */ DEBUG(SSSDBG_CRIT_FAILURE, "child failed (%d [%s])\n", ret, strerror(ret)); tevent_req_error(req, ret); return; } if (result == EOK) { ret = setenv("KRB5CCNAME", ccname, 1); if (ret == -1) { DEBUG(SSSDBG_OP_FAILURE, "Unable to set env. variable KRB5CCNAME!\n"); tevent_req_error(req, ERR_AUTH_FAILED); return; } state->expire_time = expire_time; tevent_req_done(req); return; } else { if (kerr == KRB5_KDC_UNREACH) { be_fo_set_port_status(state->be, state->krb_service_name, state->kdc_srv, PORT_NOT_WORKING); nextreq = sdap_kinit_next_kdc(req); if (!nextreq) { tevent_req_error(req, ENOMEM); } return; } } DEBUG(SSSDBG_CONF_SETTINGS, "Could not get TGT: %d [%s]\n", result, sss_strerror(result)); tevent_req_error(req, ERR_AUTH_FAILED); } static errno_t sdap_kinit_recv(struct tevent_req *req, time_t *expire_time) { struct sdap_kinit_state *state = tevent_req_data(req, struct sdap_kinit_state); enum tevent_req_state tstate; uint64_t err = ERR_INTERNAL; if (tevent_req_is_error(req, &tstate, &err)) { if (tstate != TEVENT_REQ_IN_PROGRESS) { return err; } } *expire_time = state->expire_time; return EOK; } /* ==Authenticaticate-User-by-DN========================================== */ struct sdap_auth_state { struct sdap_ppolicy_data *ppolicy; bool is_sasl; }; static void sdap_auth_done(struct tevent_req *subreq); /* TODO: handle sasl_cred */ struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_handle *sh, const char *sasl_mech, const char *sasl_user, const char *user_dn, struct sss_auth_token *authtok, int simple_bind_timeout) { struct tevent_req *req, *subreq; struct sdap_auth_state *state; req = tevent_req_create(memctx, &state, struct sdap_auth_state); if (!req) return NULL; if (sasl_mech) { state->is_sasl = true; subreq = sasl_bind_send(state, ev, sh, sasl_mech, sasl_user, NULL); if (!subreq) { tevent_req_error(req, ENOMEM); return tevent_req_post(req, ev); } } else { const char *password = NULL; struct berval pw; size_t pwlen; errno_t ret; ret = sss_authtok_get_password(authtok, &password, &pwlen); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse authtok.\n"); tevent_req_error(req, ret); return tevent_req_post(req, ev); } /* Treat a zero-length password as a failure */ if (*password == '\0') { tevent_req_error(req, ENOENT); return tevent_req_post(req, ev); } pw.bv_val = discard_const(password); pw.bv_len = pwlen; state->is_sasl = false; subreq = simple_bind_send(state, ev, sh, simple_bind_timeout, user_dn, &pw); if (!subreq) { tevent_req_error(req, ENOMEM); return tevent_req_post(req, ev); } } tevent_req_set_callback(subreq, sdap_auth_done, req); return req; } static int sdap_auth_get_authtok(const char *authtok_type, struct dp_opt_blob authtok, struct berval *pw) { if (!authtok_type) return EOK; if (!pw) return EINVAL; if (strcasecmp(authtok_type,"password") == 0) { pw->bv_len = authtok.length; pw->bv_val = (char *) authtok.data; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Authentication token type [%s] is not supported\n", authtok_type); return EINVAL; } return EOK; } static void sdap_auth_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_auth_state *state = tevent_req_data(req, struct sdap_auth_state); int ret; if (state->is_sasl) { ret = sasl_bind_recv(subreq); state->ppolicy = NULL; } else { ret = simple_bind_recv(subreq, state, &state->ppolicy); } if (tevent_req_error(req, ret)) { return; } tevent_req_done(req); } errno_t sdap_auth_recv(struct tevent_req *req, TALLOC_CTX *memctx, struct sdap_ppolicy_data **ppolicy) { struct sdap_auth_state *state = tevent_req_data(req, struct sdap_auth_state); if (ppolicy != NULL) { *ppolicy = talloc_steal(memctx, state->ppolicy); } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==Client connect============================================ */ struct sdap_cli_connect_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_service *service; struct be_ctx *be; bool use_rootdse; struct sysdb_attrs *rootdse; struct sdap_handle *sh; struct fo_server *srv; struct sdap_server_opts *srv_opts; enum connect_tls force_tls; bool do_auth; bool use_tls; }; static int sdap_cli_resolve_next(struct tevent_req *req); static void sdap_cli_resolve_done(struct tevent_req *subreq); static void sdap_cli_connect_done(struct tevent_req *subreq); static void sdap_cli_rootdse_step(struct tevent_req *req); static void sdap_cli_rootdse_done(struct tevent_req *subreq); static errno_t sdap_cli_use_rootdse(struct sdap_cli_connect_state *state); static void sdap_cli_kinit_step(struct tevent_req *req); static void sdap_cli_kinit_done(struct tevent_req *subreq); static void sdap_cli_auth_step(struct tevent_req *req); static void sdap_cli_auth_done(struct tevent_req *subreq); static errno_t sdap_cli_auth_reconnect(struct tevent_req *subreq); static void sdap_cli_auth_reconnect_done(struct tevent_req *subreq); static void sdap_cli_rootdse_auth_done(struct tevent_req *subreq); static errno_t decide_tls_usage(enum connect_tls force_tls, struct dp_option *basic, const char *uri, bool *_use_tls) { bool use_tls = true; switch (force_tls) { case CON_TLS_DFL: use_tls = dp_opt_get_bool(basic, SDAP_ID_TLS); break; case CON_TLS_ON: use_tls = true; break; case CON_TLS_OFF: use_tls = false; break; default: return EINVAL; break; } if (use_tls && sdap_is_secure_uri(uri)) { DEBUG(SSSDBG_TRACE_INTERNAL, "[%s] is a secure channel. No need to run START_TLS\n", uri); use_tls = false; } *_use_tls = use_tls; return EOK; } struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct be_ctx *be, struct sdap_service *service, bool skip_rootdse, enum connect_tls force_tls, bool skip_auth) { struct sdap_cli_connect_state *state; struct tevent_req *req; int ret; req = tevent_req_create(memctx, &state, struct sdap_cli_connect_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->service = service; state->be = be; state->srv = NULL; state->srv_opts = NULL; state->use_rootdse = !skip_rootdse; state->force_tls = force_tls; state->do_auth = !skip_auth; ret = sdap_cli_resolve_next(req); if (ret) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static int sdap_cli_resolve_next(struct tevent_req *req) { struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); struct tevent_req *subreq; /* Before stepping to next server destroy any connection from previous attempt */ talloc_zfree(state->sh); /* NOTE: this call may cause service->uri to be refreshed * with a new valid server. Do not use service->uri before */ subreq = be_resolve_server_send(state, state->ev, state->be, state->service->name, state->srv == NULL ? true : false); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_cli_resolve_done, req); return EOK; } static void sdap_cli_resolve_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); int ret; ret = be_resolve_server_recv(subreq, state, &state->srv); talloc_zfree(subreq); if (ret) { state->srv = NULL; /* all servers have been tried and none * was found good, go offline */ tevent_req_error(req, EIO); return; } ret = decide_tls_usage(state->force_tls, state->opts->basic, state->service->uri, &state->use_tls); if (ret != EOK) { tevent_req_error(req, EINVAL); return; } subreq = sdap_connect_send(state, state->ev, state->opts, state->service->uri, state->service->sockaddr, state->use_tls); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_cli_connect_done, req); } static void sdap_cli_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); const char *sasl_mech; int ret; talloc_zfree(state->sh); ret = sdap_connect_recv(subreq, state, &state->sh); talloc_zfree(subreq); if (ret) { /* retry another server */ be_fo_set_port_status(state->be, state->service->name, state->srv, PORT_NOT_WORKING); ret = sdap_cli_resolve_next(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } if (state->use_rootdse) { /* fetch the rootDSE this time */ sdap_cli_rootdse_step(req); return; } sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH); if (state->do_auth && sasl_mech && state->use_rootdse) { /* check if server claims to support GSSAPI */ if (!sdap_is_sasl_mech_supported(state->sh, sasl_mech)) { tevent_req_error(req, ENOTSUP); return; } } if (state->do_auth && sasl_mech && (strcasecmp(sasl_mech, "GSSAPI") == 0)) { if (dp_opt_get_bool(state->opts->basic, SDAP_KRB5_KINIT)) { sdap_cli_kinit_step(req); return; } } sdap_cli_auth_step(req); } static void sdap_cli_rootdse_step(struct tevent_req *req) { struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); struct tevent_req *subreq; int ret; subreq = sdap_get_rootdse_send(state, state->ev, state->opts, state->sh); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_cli_rootdse_done, req); if (!state->sh->connected) { /* this rootdse search is performed before we actually do a bind, * so we need to set up the callbacks or we will never get notified * of a reply */ ret = sdap_set_connected(state->sh, state->ev); if (ret) { tevent_req_error(req, ret); } } } static void sdap_cli_rootdse_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); const char *sasl_mech; int ret; ret = sdap_get_rootdse_recv(subreq, state, &state->rootdse); talloc_zfree(subreq); if (ret) { if (ret == ETIMEDOUT) { /* retry another server */ be_fo_set_port_status(state->be, state->service->name, state->srv, PORT_NOT_WORKING); ret = sdap_cli_resolve_next(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } /* RootDSE was not available on * the server. * Continue, and just assume that the * features requested by the config * work properly. */ state->rootdse = NULL; } ret = sdap_cli_use_rootdse(state); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_cli_use_rootdse failed\n"); tevent_req_error(req, ret); return; } sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH); if (state->do_auth && sasl_mech && state->rootdse) { /* check if server claims to support GSSAPI */ if (!sdap_is_sasl_mech_supported(state->sh, sasl_mech)) { tevent_req_error(req, ENOTSUP); return; } } if (state->do_auth && sasl_mech && (strcasecmp(sasl_mech, "GSSAPI") == 0)) { if (dp_opt_get_bool(state->opts->basic, SDAP_KRB5_KINIT)) { sdap_cli_kinit_step(req); return; } } sdap_cli_auth_step(req); } static errno_t sdap_cli_use_rootdse(struct sdap_cli_connect_state *state) { errno_t ret; if (state->rootdse) { /* save rootdse data about supported features */ ret = sdap_set_rootdse_supported_lists(state->rootdse, state->sh); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sdap_set_rootdse_supported_lists failed\n"); return ret; } ret = sdap_set_config_options_with_rootdse(state->rootdse, state->opts, state->opts->sdom); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sdap_set_config_options_with_rootdse failed.\n"); return ret; } } ret = sdap_get_server_opts_from_rootdse(state, state->service->uri, state->rootdse, state->opts, &state->srv_opts); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_server_opts_from_rootdse failed.\n"); return ret; } return EOK; } static void sdap_cli_kinit_step(struct tevent_req *req) { struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); struct tevent_req *subreq; subreq = sdap_kinit_send(state, state->ev, state->be, state->sh, state->service->kinit_service_name, dp_opt_get_int(state->opts->basic, SDAP_OPT_TIMEOUT), dp_opt_get_string(state->opts->basic, SDAP_KRB5_KEYTAB), dp_opt_get_string(state->opts->basic, SDAP_SASL_AUTHID), sdap_gssapi_realm(state->opts->basic), dp_opt_get_bool(state->opts->basic, SDAP_KRB5_CANONICALIZE), dp_opt_get_int(state->opts->basic, SDAP_KRB5_TICKET_LIFETIME)); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_cli_kinit_done, req); } static void sdap_cli_kinit_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); time_t expire_time = 0; errno_t ret; ret = sdap_kinit_recv(subreq, &expire_time); talloc_zfree(subreq); if (ret != EOK) { /* We're not able to authenticate to the LDAP server. * There's not much we can do except for going offline */ DEBUG(SSSDBG_TRACE_FUNC, "Cannot get a TGT: ret [%d](%s)\n", ret, sss_strerror(ret)); tevent_req_error(req, EACCES); return; } state->sh->expire_time = expire_time; sdap_cli_auth_step(req); } static void sdap_cli_auth_step(struct tevent_req *req) { struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); struct tevent_req *subreq; time_t now; int expire_timeout; const char *sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH); const char *user_dn = dp_opt_get_string(state->opts->basic, SDAP_DEFAULT_BIND_DN); const char *authtok_type; struct dp_opt_blob authtok_blob; struct sss_auth_token *authtok; errno_t ret; /* It's possible that connection was terminated by server (e.g. #2435), to overcome this try to connect again. */ if (state->sh == NULL || !state->sh->connected) { DEBUG(SSSDBG_TRACE_FUNC, "No connection available. " "Trying to reconnect.\n"); ret = sdap_cli_auth_reconnect(req); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sdap_cli_auth_reconnect failed: %d:[%s]\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); } return; } /* Set the LDAP expiration time * If SASL has already set it, use the sooner of the two */ now = time(NULL); expire_timeout = dp_opt_get_int(state->opts->basic, SDAP_EXPIRE_TIMEOUT); DEBUG(SSSDBG_CONF_SETTINGS, "expire timeout is %d\n", expire_timeout); if (!state->sh->expire_time || (state->sh->expire_time > (now + expire_timeout))) { state->sh->expire_time = now + expire_timeout; DEBUG(SSSDBG_TRACE_LIBS, "the connection will expire at %ld\n", state->sh->expire_time); } if (!state->do_auth || (sasl_mech == NULL && user_dn == NULL)) { DEBUG(SSSDBG_TRACE_LIBS, "No authentication requested or SASL auth forced off\n"); tevent_req_done(req); return; } authtok_type = dp_opt_get_string(state->opts->basic, SDAP_DEFAULT_AUTHTOK_TYPE); authtok = sss_authtok_new(state); if(authtok == NULL) { tevent_req_error(req, ENOMEM); return; } if (authtok_type != NULL) { if (strcasecmp(authtok_type, "password") != 0) { DEBUG(SSSDBG_TRACE_LIBS, "Invalid authtoken type\n"); tevent_req_error(req, EINVAL); return; } authtok_blob = dp_opt_get_blob(state->opts->basic, SDAP_DEFAULT_AUTHTOK); if (authtok_blob.data) { ret = sss_authtok_set_password(authtok, (const char *)authtok_blob.data, authtok_blob.length); if (ret) { tevent_req_error(req, ret); return; } } } subreq = sdap_auth_send(state, state->ev, state->sh, sasl_mech, dp_opt_get_string(state->opts->basic, SDAP_SASL_AUTHID), user_dn, authtok, dp_opt_get_int(state->opts->basic, SDAP_OPT_TIMEOUT)); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_cli_auth_done, req); } static errno_t sdap_cli_auth_reconnect(struct tevent_req *req) { struct sdap_cli_connect_state *state; struct tevent_req *subreq; errno_t ret; state = tevent_req_data(req, struct sdap_cli_connect_state); ret = decide_tls_usage(state->force_tls, state->opts->basic, state->service->uri, &state->use_tls); if (ret != EOK) { goto done; } subreq = sdap_connect_send(state, state->ev, state->opts, state->service->uri, state->service->sockaddr, state->use_tls); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_cli_auth_reconnect_done, req); ret = EOK; done: return ret; } static void sdap_cli_auth_reconnect_done(struct tevent_req *subreq) { struct sdap_cli_connect_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_cli_connect_state); talloc_zfree(state->sh); ret = sdap_connect_recv(subreq, state, &state->sh); talloc_zfree(subreq); if (ret != EOK) { goto done; } /* if TLS was used, the sdap handle is already marked as connected */ if (!state->use_tls) { /* we need to mark handle as connected to allow anonymous bind */ ret = sdap_set_connected(state->sh, state->ev); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_set_connected() failed.\n"); goto done; } } /* End request if reconnecting failed to avoid endless loop */ if (state->sh == NULL || !state->sh->connected) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to reconnect.\n"); ret = EIO; goto done; } sdap_cli_auth_step(req); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); } } static void sdap_cli_auth_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); int ret; ret = sdap_auth_recv(subreq, NULL, NULL); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } if (state->use_rootdse && !state->rootdse) { /* We weren't able to read rootDSE during unauthenticated bind. * Let's try again now that we are authenticated */ subreq = sdap_get_rootdse_send(state, state->ev, state->opts, state->sh); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_cli_rootdse_auth_done, req); return; } tevent_req_done(req); } static void sdap_cli_rootdse_auth_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); ret = sdap_get_rootdse_recv(subreq, state, &state->rootdse); talloc_zfree(subreq); if (ret) { if (ret == ETIMEDOUT) { /* The server we authenticated against went down. Retry another * one */ be_fo_set_port_status(state->be, state->service->name, state->srv, PORT_NOT_WORKING); ret = sdap_cli_resolve_next(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } /* RootDSE was not available on * the server. * Continue, and just assume that the * features requested by the config * work properly. */ state->use_rootdse = false; state->rootdse = NULL; tevent_req_done(req); return; } /* We were able to get rootDSE after authentication */ ret = sdap_cli_use_rootdse(state); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_cli_use_rootdse failed\n"); tevent_req_error(req, ret); return; } tevent_req_done(req); } int sdap_cli_connect_recv(struct tevent_req *req, TALLOC_CTX *memctx, bool *can_retry, struct sdap_handle **gsh, struct sdap_server_opts **srv_opts) { struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); enum tevent_req_state tstate; uint64_t err; if (can_retry) { *can_retry = true; } if (tevent_req_is_error(req, &tstate, &err)) { /* mark the server as bad if connection failed */ if (state->srv) { be_fo_set_port_status(state->be, state->service->name, state->srv, PORT_NOT_WORKING); } else { if (can_retry) { *can_retry = false; } } if (tstate == TEVENT_REQ_USER_ERROR) { return err; } return EIO; } else if (state->srv) { be_fo_set_port_status(state->be, state->service->name, state->srv, PORT_WORKING); } if (gsh) { if (*gsh) { talloc_zfree(*gsh); } *gsh = talloc_steal(memctx, state->sh); if (!*gsh) { return ENOMEM; } } else { talloc_zfree(state->sh); } if (srv_opts) { *srv_opts = talloc_steal(memctx, state->srv_opts); } return EOK; } static int synchronous_tls_setup(LDAP *ldap) { int lret; int optret; int ldaperr; int msgid; char *errmsg = NULL; char *diag_msg; LDAPMessage *result = NULL; TALLOC_CTX *tmp_ctx; DEBUG(SSSDBG_CONF_SETTINGS, "Executing START TLS\n"); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return LDAP_NO_MEMORY; lret = ldap_start_tls(ldap, NULL, NULL, &msgid); if (lret != LDAP_SUCCESS) { optret = sss_ldap_get_diagnostic_msg(tmp_ctx, ldap, &diag_msg); if (optret == LDAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_start_tls failed: [%s] [%s]\n", sss_ldap_err2string(lret), diag_msg); sss_log(SSS_LOG_ERR, "Could not start TLS. %s", diag_msg); } else { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_start_tls failed: [%s]\n", sss_ldap_err2string(lret)); sss_log(SSS_LOG_ERR, "Could not start TLS. " "Check for certificate issues."); } goto done; } lret = ldap_result(ldap, msgid, 1, NULL, &result); if (lret != LDAP_RES_EXTENDED) { DEBUG(SSSDBG_OP_FAILURE, "Unexpected ldap_result, expected [%lu] got [%d].\n", LDAP_RES_EXTENDED, lret); lret = LDAP_PARAM_ERROR; goto done; } lret = ldap_parse_result(ldap, result, &ldaperr, NULL, &errmsg, NULL, NULL, 0); if (lret != LDAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldap_parse_result failed (%d) [%d][%s]\n", msgid, lret, sss_ldap_err2string(lret)); goto done; } DEBUG(SSSDBG_MINOR_FAILURE, "START TLS result: %s(%d), %s\n", sss_ldap_err2string(ldaperr), ldaperr, errmsg); if (ldap_tls_inplace(ldap)) { DEBUG(SSSDBG_TRACE_ALL, "SSL/TLS handler already in place.\n"); lret = LDAP_SUCCESS; goto done; } lret = ldap_install_tls(ldap); if (lret != LDAP_SUCCESS) { optret = sss_ldap_get_diagnostic_msg(tmp_ctx, ldap, &diag_msg); if (optret == LDAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_install_tls failed: [%s] [%s]\n", sss_ldap_err2string(lret), diag_msg); sss_log(SSS_LOG_ERR, "Could not start TLS encryption. %s", diag_msg); } else { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_install_tls failed: [%s]\n", sss_ldap_err2string(lret)); sss_log(SSS_LOG_ERR, "Could not start TLS encryption. " "Check for certificate issues."); } goto done; } lret = LDAP_SUCCESS; done: if (result) ldap_msgfree(result); if (errmsg) ldap_memfree(errmsg); talloc_zfree(tmp_ctx); return lret; } static int sdap_rebind_proc(LDAP *ldap, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *params) { struct sdap_rebind_proc_params *p = talloc_get_type(params, struct sdap_rebind_proc_params); const char *sasl_mech; const char *user_dn; struct berval password = {0, NULL}; LDAPControl **request_controls = NULL; LDAPControl *ctrls[2] = { NULL, NULL }; TALLOC_CTX *tmp_ctx = NULL; struct sasl_bind_state *sasl_bind_state; int ret; if (ldap == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Trying LDAP rebind while not connected.\n"); return ERR_NETWORK_IO; } if (p->use_start_tls) { ret = synchronous_tls_setup(ldap); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "synchronous_tls_setup failed.\n"); return ret; } } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); return LDAP_NO_MEMORY; } sasl_mech = dp_opt_get_string(p->opts->basic, SDAP_SASL_MECH); if (sasl_mech == NULL) { ret = sss_ldap_control_create(LDAP_CONTROL_PASSWORDPOLICYREQUEST, 0, NULL, 0, &ctrls[0]); if (ret != LDAP_SUCCESS && ret != LDAP_NOT_SUPPORTED) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_ldap_control_create failed to create " "Password Policy control.\n"); goto done; } request_controls = ctrls; user_dn = dp_opt_get_string(p->opts->basic, SDAP_DEFAULT_BIND_DN); if (user_dn != NULL) { ret = sdap_auth_get_authtok(dp_opt_get_string(p->opts->basic, SDAP_DEFAULT_AUTHTOK_TYPE), dp_opt_get_blob(p->opts->basic, SDAP_DEFAULT_AUTHTOK), &password); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_auth_get_authtok failed.\n"); ret = LDAP_LOCAL_ERROR; goto done; } } ret = ldap_sasl_bind_s(ldap, user_dn, LDAP_SASL_SIMPLE, &password, request_controls, NULL, NULL); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_sasl_bind_s failed (%d)[%s]\n", ret, sss_ldap_err2string(ret)); } } else { sasl_bind_state = talloc_zero(tmp_ctx, struct sasl_bind_state); if (sasl_bind_state == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); ret = LDAP_NO_MEMORY; goto done; } sasl_bind_state->sasl_user = dp_opt_get_string(p->opts->basic, SDAP_SASL_AUTHID); ret = ldap_sasl_interactive_bind_s(ldap, NULL, sasl_mech, NULL, NULL, LDAP_SASL_QUIET, (*sdap_sasl_interact), sasl_bind_state); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_sasl_interactive_bind_s failed (%d)[%s]\n", ret, sss_ldap_err2string(ret)); } } DEBUG(SSSDBG_TRACE_LIBS, "%s bind to [%s].\n", (ret == LDAP_SUCCESS ? "Successfully" : "Failed to"), url); done: if (ctrls[0]) ldap_control_free(ctrls[0]); talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_enum.h0000644000000000000000000000007312703456111021371 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.561793313 sssd-1.13.4/src/providers/ldap/sdap_async_enum.h0000644002412700241270000000316412703456111023045 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Enumeration Module Authors: Simo Sorce Jakub Hrozek Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SDAP_ASYNC_ENUM_H_ #define _SDAP_ASYNC_ENUM_H_ struct tevent_req * sdap_dom_enum_ex_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *user_conn, struct sdap_id_conn_ctx *group_conn, struct sdap_id_conn_ctx *svc_conn); errno_t sdap_dom_enum_ex_recv(struct tevent_req *req); struct tevent_req * sdap_dom_enum_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn); errno_t sdap_dom_enum_recv(struct tevent_req *req); #endif /* _SDAP_ASYNC_ENUM_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_idmap.c0000644000000000000000000000007412703456111020316 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.791794093 sssd-1.13.4/src/providers/ldap/sdap_idmap.c0000644002412700241270000004762512703456111022003 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/dlinklist.h" #include "util/murmurhash3.h" #include "providers/ldap/sdap_idmap.h" #include "util/util_sss_idmap.h" static errno_t sdap_idmap_get_configured_external_range(struct sdap_idmap_ctx *idmap_ctx, struct sss_idmap_range *range) { int int_id; struct sdap_id_ctx *id_ctx; uint32_t min; uint32_t max; if (idmap_ctx == NULL) { return EINVAL; } id_ctx = idmap_ctx->id_ctx; int_id = dp_opt_get_int(id_ctx->opts->basic, SDAP_MIN_ID); if (int_id < 0) { DEBUG(SSSDBG_CONF_SETTINGS, "ldap_min_id must be greater than 0.\n"); return EINVAL; } min = int_id; int_id = dp_opt_get_int(id_ctx->opts->basic, SDAP_MAX_ID); if (int_id < 0) { DEBUG(SSSDBG_CONF_SETTINGS, "ldap_max_id must be greater than 0.\n"); return EINVAL; } max = int_id; if ((min == 0 && max != 0) || (min != 0 && max == 0)) { DEBUG(SSSDBG_CONF_SETTINGS, "Both ldap_min_id and ldap_max_id " \ "either must be 0 (not set) " \ "or positive integers.\n"); return EINVAL; } if (min == 0 && max == 0) { /* ldap_min_id and ldap_max_id not set, using min_id and max_id */ min = id_ctx->be->domain->id_min; max = id_ctx->be->domain->id_max; if (max == 0) { max = UINT32_MAX; } } range->min = min; range->max =max; return EOK; } static errno_t sdap_idmap_add_configured_external_range(struct sdap_idmap_ctx *idmap_ctx) { int ret; struct sss_idmap_range range; struct sdap_id_ctx *id_ctx; enum idmap_error_code err; ret = sdap_idmap_get_configured_external_range(idmap_ctx, &range); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_idmap_get_configured_external_range failed.\n"); return ret; } id_ctx = idmap_ctx->id_ctx; err = sss_idmap_add_auto_domain_ex(idmap_ctx->map, id_ctx->be->domain->name, id_ctx->be->domain->domain_id, &range, NULL, 0, true, NULL, NULL); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add domain [%s] to the map: [%d]\n", id_ctx->be->domain->name, err); return EIO; } return EOK; } errno_t sdap_idmap_find_new_domain(struct sdap_idmap_ctx *idmap_ctx, const char *dom_name, const char *dom_sid_str) { int ret; ret = sdap_idmap_add_domain(idmap_ctx, dom_name, dom_sid_str, -1); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add new domain [%s]\n", dom_name); return ret; } return EOK; } errno_t sdap_idmap_init(TALLOC_CTX *mem_ctx, struct sdap_id_ctx *id_ctx, struct sdap_idmap_ctx **_idmap_ctx) { errno_t ret; TALLOC_CTX *tmp_ctx; enum idmap_error_code err; size_t i; struct ldb_result *res; const char *dom_name; const char *sid_str; id_t slice_num; id_t idmap_lower; id_t idmap_upper; id_t rangesize; bool autorid_mode; int extra_slice_init; struct sdap_idmap_ctx *idmap_ctx = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; idmap_ctx = talloc_zero(tmp_ctx, struct sdap_idmap_ctx); if (!idmap_ctx) { ret = ENOMEM; goto done; } idmap_ctx->id_ctx = id_ctx; idmap_ctx->find_new_domain = sdap_idmap_find_new_domain; idmap_lower = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_LOWER); idmap_upper = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_UPPER); rangesize = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_RANGESIZE); autorid_mode = dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_AUTORID_COMPAT); extra_slice_init = dp_opt_get_int(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_EXTRA_SLICE_INIT); /* Validate that the values make sense */ if (rangesize <= 0 || idmap_upper <= idmap_lower || (idmap_upper-idmap_lower) < rangesize) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid settings for range selection: " "[%"SPRIid"][%"SPRIid"][%"SPRIid"]\n", idmap_lower, idmap_upper, rangesize); ret = EINVAL; goto done; } if (((idmap_upper - idmap_lower) % rangesize) != 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Range size does not divide evenly. Uppermost range will " "not be used\n"); } /* Initialize the map */ err = sss_idmap_init(sss_idmap_talloc, idmap_ctx, sss_idmap_talloc_free, &idmap_ctx->map); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize the ID map: [%s]\n", idmap_error_string(err)); if (err == IDMAP_OUT_OF_MEMORY) { ret = ENOMEM; } else { ret = EINVAL; } goto done; } err = sss_idmap_ctx_set_autorid(idmap_ctx->map, autorid_mode); err |= sss_idmap_ctx_set_lower(idmap_ctx->map, idmap_lower); err |= sss_idmap_ctx_set_upper(idmap_ctx->map, idmap_upper); err |= sss_idmap_ctx_set_rangesize(idmap_ctx->map, rangesize); err |= sss_idmap_ctx_set_extra_slice_init(idmap_ctx->map, extra_slice_init); if (err != IDMAP_SUCCESS) { /* This should never happen */ DEBUG(SSSDBG_CRIT_FAILURE, "sss_idmap_ctx corrupted\n"); return EIO; } /* Setup range for externally managed IDs, i.e. IDs are read from the * ldap_user_uid_number and ldap_group_gid_number attributes. */ if (!dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) { ret = sdap_idmap_add_configured_external_range(idmap_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_idmap_add_configured_external_range failed.\n"); goto done; } } /* Read in any existing mappings from the cache */ ret = sysdb_idmap_get_mappings(tmp_ctx, id_ctx->be->domain, &res); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not read ID mappings from the cache: [%s]\n", strerror(ret)); goto done; } if (ret == EOK) { DEBUG(SSSDBG_CONF_SETTINGS, "Initializing [%d] domains for ID-mapping\n", res->count); for (i = 0; i < res->count; i++) { dom_name = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_NAME, NULL); if (!dom_name) { /* This should never happen */ ret = EINVAL; goto done; } sid_str = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_IDMAP_SID_ATTR, NULL); if (!sid_str) { /* This should never happen */ ret = EINVAL; goto done; } slice_num = ldb_msg_find_attr_as_int(res->msgs[i], SYSDB_IDMAP_SLICE_ATTR, -1); if (slice_num == -1) { /* This should never happen */ ret = EINVAL; goto done; } ret = sdap_idmap_add_domain(idmap_ctx, dom_name, sid_str, slice_num); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add domain [%s][%s][%"SPRIid"] " "to ID map: [%s]\n", dom_name, sid_str, slice_num, strerror(ret)); goto done; } } } else { /* This is the first time we're setting up id-mapping * Store the default domain as slice 0 */ dom_name = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN); if (!dom_name) { /* If it's not explicitly specified, use the SSSD domain name */ dom_name = idmap_ctx->id_ctx->be->domain->name; ret = dp_opt_set_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN, dom_name); if (ret != EOK) goto done; } sid_str = dp_opt_get_string(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_DEFAULT_DOMAIN_SID); if (sid_str) { struct sss_domain_info *domain = idmap_ctx->id_ctx->be->domain; domain->domain_id = talloc_strdup(domain, sid_str); if (domain->domain_id == NULL) { ret = ENOMEM; goto done; } /* Set the default domain as slice 0 */ ret = sdap_idmap_add_domain(idmap_ctx, dom_name, sid_str, 0); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add domain [%s][%s][%u] to ID map: [%s]\n", dom_name, sid_str, 0, strerror(ret)); goto done; } } else { if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_AUTORID_COMPAT)) { /* In autorid compatibility mode, we MUST have a slice 0 */ DEBUG(SSSDBG_CRIT_FAILURE, "WARNING: Autorid compatibility mode selected, " "but %s is not set. UID/GID values may differ " "between clients.\n", idmap_ctx->id_ctx->opts->basic[SDAP_IDMAP_DEFAULT_DOMAIN_SID].opt_name); } /* Otherwise, we'll just fall back to hash values as they are seen */ } } *_idmap_ctx = talloc_steal(mem_ctx, idmap_ctx); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx, const char *dom_name, const char *dom_sid, id_t slice) { errno_t ret; struct sss_idmap_range range; enum idmap_error_code err; id_t idmap_upper; bool external_mapping = true; ret = sss_idmap_ctx_get_upper(idmap_ctx->map, &idmap_upper); if (ret != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get upper bound of available ID range.\n"); ret = EIO; goto done; } if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_ID_MAPPING)) { external_mapping = false; ret = sss_idmap_calculate_range(idmap_ctx->map, dom_sid, &slice, &range); if (ret != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to calculate range for domain [%s]: [%d]\n", dom_name, ret); ret = EIO; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Adding domain [%s] as slice [%"SPRIid"]\n", dom_sid, slice); if (range.max > idmap_upper) { /* This should never happen */ DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Range maximum exceeds the global maximum: " "%u > %"SPRIid"\n", range.max, idmap_upper); ret = EINVAL; goto done; } } else { ret = sdap_idmap_get_configured_external_range(idmap_ctx, &range); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_idmap_get_configured_external_range failed.\n"); return ret; } } /* Add this domain to the map */ err = sss_idmap_add_auto_domain_ex(idmap_ctx->map, dom_name, dom_sid, &range, NULL, 0, external_mapping, NULL, NULL); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add domain [%s] to the map: [%d]\n", dom_name, err); ret = EIO; goto done; } /* If algorithmic mapping is used add this domain to the SYSDB cache so it * will survive reboot */ if (!external_mapping) { ret = sysdb_idmap_store_mapping(idmap_ctx->id_ctx->be->domain, dom_name, dom_sid, slice); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_idmap_store_mapping failed.\n"); goto done; } } done: return ret; } errno_t sdap_idmap_get_dom_sid_from_object(TALLOC_CTX *mem_ctx, const char *object_sid, char **dom_sid_str) { const char *p; long long a; size_t c; char *endptr; if (object_sid == NULL || strncmp(object_sid, DOM_SID_PREFIX, DOM_SID_PREFIX_LEN) != 0) { return EINVAL; } p = object_sid + DOM_SID_PREFIX_LEN; c = 0; do { errno = 0; a = strtoull(p, &endptr, 10); if (errno != 0 || a > UINT32_MAX) { return EINVAL; } if (*endptr == '-') { p = endptr + 1; } else { return EINVAL; } c++; } while(c < 3); /* If we made it here, we are now one character past * the last hyphen in the object-sid. * Copy the dom-sid substring. */ *dom_sid_str = talloc_strndup(mem_ctx, object_sid, (endptr-object_sid)); if (!*dom_sid_str) return ENOMEM; return EOK; } errno_t sdap_idmap_sid_to_unix(struct sdap_idmap_ctx *idmap_ctx, const char *sid_str, id_t *id) { errno_t ret; enum idmap_error_code err; char *dom_sid_str = NULL; /* Convert the SID into a UNIX ID */ err = sss_idmap_sid_to_unix(idmap_ctx->map, sid_str, (uint32_t *)id); switch (err) { case IDMAP_SUCCESS: break; case IDMAP_NO_DOMAIN: /* This is the first time we've seen this domain * Create a new domain for it. We'll use the dom-sid * as the domain name for now, since we don't have * any way to get the real name. */ ret = sdap_idmap_get_dom_sid_from_object(NULL, sid_str, &dom_sid_str); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not parse domain SID from [%s]\n", sid_str); goto done; } ret = idmap_ctx->find_new_domain(idmap_ctx, dom_sid_str, dom_sid_str); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add new domain for sid [%s]\n", sid_str); goto done; } /* Now try converting to a UNIX ID again */ err = sss_idmap_sid_to_unix(idmap_ctx->map, sid_str, (uint32_t *)id); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not convert objectSID [%s] to a UNIX ID\n", sid_str); ret = EIO; goto done; } break; case IDMAP_BUILTIN_SID: DEBUG(SSSDBG_TRACE_FUNC, "Object SID [%s] is a built-in one.\n", sid_str); /* ENOTSUP indicates built-in SID */ ret = ENOTSUP; goto done; break; case IDMAP_NO_RANGE: DEBUG(SSSDBG_IMPORTANT_INFO, "Object SID [%s] has a RID that is larger than the " "ldap_idmap_range_size. See the \"ID MAPPING\" section of " "sssd-ad(5) for an explanation of how to resolve this issue.\n", sid_str); /* Fall through intentionally */ default: DEBUG(SSSDBG_MINOR_FAILURE, "Could not convert objectSID [%s] to a UNIX ID\n", sid_str); ret = EIO; goto done; } ret = EOK; done: talloc_free(dom_sid_str); return ret; } bool sdap_idmap_domain_has_algorithmic_mapping(struct sdap_idmap_ctx *ctx, const char *dom_name, const char *dom_sid) { enum idmap_error_code err; bool has_algorithmic_mapping; char *new_dom_sid; int ret; TALLOC_CTX *tmp_ctx = NULL; if (dp_opt_get_bool(ctx->id_ctx->opts->basic, SDAP_ID_MAPPING) && 0 == strcmp("ldap", ctx->id_ctx->be->bet_info[BET_ID].mod_name)) { return true; } err = sss_idmap_domain_has_algorithmic_mapping(ctx->map, dom_sid, &has_algorithmic_mapping); switch (err){ case IDMAP_SUCCESS: return has_algorithmic_mapping; case IDMAP_SID_INVALID: /* FALLTHROUGH */ case IDMAP_SID_UNKNOWN: /* FALLTHROUGH */ case IDMAP_NO_DOMAIN: /* FALLTHROUGH */ /* continue with idmap_domain_by_name */ break; default: return false; } err = sss_idmap_domain_by_name_has_algorithmic_mapping(ctx->map, dom_name, &has_algorithmic_mapping); if (err == IDMAP_SUCCESS) { return has_algorithmic_mapping; } else if (err != IDMAP_NAME_UNKNOWN && err != IDMAP_NO_DOMAIN) { return false; } /* If there is no SID, e.g. IPA without enabled trust support, we cannot * have algorithmic mapping */ if (dom_sid == NULL) { return false; } /* This is the first time we've seen this domain * Create a new domain for it. We'll use the dom-sid * as the domain name for now, since we don't have * any way to get the real name. */ if (is_domain_sid(dom_sid)) { new_dom_sid = discard_const(dom_sid); } else { tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return false; } ret = sdap_idmap_get_dom_sid_from_object(tmp_ctx, dom_sid, &new_dom_sid); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not parse domain SID from [%s]\n", dom_sid); talloc_free(tmp_ctx); return false; } } ret = ctx->find_new_domain(ctx, dom_name, new_dom_sid); talloc_free(tmp_ctx); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add new domain for sid [%s]\n", dom_sid); return false; } err = sss_idmap_domain_has_algorithmic_mapping(ctx->map, dom_sid, &has_algorithmic_mapping); if (err == IDMAP_SUCCESS) { return has_algorithmic_mapping; } return false; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_id_services.c0000644000000000000000000000007412703456111021514 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.774794035 sssd-1.13.4/src/providers/ldap/ldap_id_services.c0000644002412700241270000002105512703456111023166 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "util/strtonum.h" #include "db/sysdb.h" #include "db/sysdb_services.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" struct sdap_services_get_state { struct tevent_context *ev; struct sdap_id_ctx *id_ctx; struct sdap_domain *sdom; struct sdap_id_op *op; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; struct sdap_id_conn_ctx *conn; const char *name; const char *protocol; char *filter; const char **attrs; int filter_type; int dp_error; int sdap_ret; bool noexist_delete; }; static errno_t services_get_retry(struct tevent_req *req); static void services_get_connect_done(struct tevent_req *subreq); static void services_get_done(struct tevent_req *subreq); struct tevent_req * services_get_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *id_ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, const char *name, const char *protocol, int filter_type, bool noexist_delete) { errno_t ret; struct tevent_req *req; struct sdap_services_get_state *state; const char *attr_name; char *clean_name; char *clean_protocol = NULL; req = tevent_req_create(mem_ctx, &state, struct sdap_services_get_state); if (!req) return NULL; state->ev = ev; state->id_ctx = id_ctx; state->sdom = sdom; state->conn = conn; state->dp_error = DP_ERR_FATAL; state->domain = sdom->dom; state->sysdb = sdom->dom->sysdb; state->name = name; state->protocol = protocol; state->filter_type = filter_type; state->noexist_delete = noexist_delete; state->op = sdap_id_op_create(state, state->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_MINOR_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto error; } switch(filter_type) { case BE_FILTER_NAME: attr_name = id_ctx->opts->service_map[SDAP_AT_SERVICE_NAME].name; break; case BE_FILTER_IDNUM: attr_name = id_ctx->opts->service_map[SDAP_AT_SERVICE_PORT].name; break; default: ret = EINVAL; goto error; } ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) goto error; if (protocol) { ret = sss_filter_sanitize(state, protocol, &clean_protocol); if (ret != EOK) goto error; } if (clean_protocol) { state->filter = talloc_asprintf( state, "(&(%s=%s)(%s=%s)(objectclass=%s))", attr_name, clean_name, id_ctx->opts->service_map[SDAP_AT_SERVICE_PROTOCOL].name, clean_protocol, id_ctx->opts->service_map[SDAP_OC_SERVICE].name); } else { state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))", attr_name, clean_name, id_ctx->opts->service_map[SDAP_OC_SERVICE].name); } talloc_zfree(clean_name); talloc_zfree(clean_protocol); if (!state->filter) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to build the base filter\n"); ret = ENOMEM; goto error; } DEBUG(SSSDBG_TRACE_LIBS, "Preparing to search for services with filter [%s]\n", state->filter); ret = build_attrs_from_map(state, id_ctx->opts->service_map, SDAP_OPTS_SERVICES, NULL, &state->attrs, NULL); if (ret != EOK) goto error; ret = services_get_retry(req); if (ret != EOK) goto error; return req; error: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static errno_t services_get_retry(struct tevent_req *req) { errno_t ret; struct sdap_services_get_state *state = tevent_req_data(req, struct sdap_services_get_state); struct tevent_req *subreq; subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { return ret; } tevent_req_set_callback(subreq, services_get_connect_done, req); return EOK; } static void services_get_connect_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_services_get_state *state = tevent_req_data(req, struct sdap_services_get_state); int dp_error = DP_ERR_FATAL; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } subreq = sdap_get_services_send(state, state->ev, state->domain, state->sysdb, state->id_ctx->opts, state->sdom->service_search_bases, sdap_id_op_handle(state->op), state->attrs, state->filter, dp_opt_get_int(state->id_ctx->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, services_get_done, req); } static void services_get_done(struct tevent_req *subreq) { errno_t ret; uint16_t port; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_services_get_state *state = tevent_req_data(req, struct sdap_services_get_state); int dp_error = DP_ERR_FATAL; ret = sdap_get_services_recv(NULL, subreq, NULL); talloc_zfree(subreq); /* Check whether we need to try again with another * failover server. */ ret = sdap_id_op_done(state->op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = services_get_retry(req); if (ret != EOK) { tevent_req_error(req, ret); return; } /* Return to the mainloop to retry */ return; } state->sdap_ret = ret; /* An error occurred. */ if (ret && ret != ENOENT) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } if (ret == ENOENT && state->noexist_delete == true) { /* Ensure that this entry is removed from the sysdb */ switch(state->filter_type) { case BE_FILTER_NAME: ret = sysdb_svc_delete(state->domain, state->name, 0, state->protocol); if (ret != EOK) { tevent_req_error(req, ret); return; } break; case BE_FILTER_IDNUM: port = strtouint16(state->name, NULL, 10); if (errno) { tevent_req_error(req, errno); return; } ret = sysdb_svc_delete(state->domain, NULL, port, state->protocol); if (ret != EOK) { tevent_req_error(req, ret); return; } break; default: tevent_req_error(req, EINVAL); return; } } state->dp_error = DP_ERR_OK; tevent_req_done(req); } errno_t services_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret) { struct sdap_services_get_state *state = tevent_req_data(req, struct sdap_services_get_state); if (dp_error_out) { *dp_error_out = state->dp_error; } if (sdap_ret) { *sdap_ret = state->sdap_ret; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_domain.c0000644000000000000000000000007312703456111020472 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.797794114 sssd-1.13.4/src/providers/ldap/sdap_domain.c0000644002412700241270000001355712703456111022155 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Copyright (C) 2008-2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ldap/ldap_common.h" int sdap_domain_destructor(void *mem) { struct sdap_domain *dom = talloc_get_type(mem, struct sdap_domain); DLIST_REMOVE(*(dom->head), dom); return 0; } struct sdap_domain * sdap_domain_get(struct sdap_options *opts, struct sss_domain_info *dom) { struct sdap_domain *sditer = NULL; DLIST_FOR_EACH(sditer, opts->sdom) { if (sditer->dom == dom) { break; } } return sditer; } struct sdap_domain * sdap_domain_get_by_dn(struct sdap_options *opts, const char *dn) { struct sdap_domain *sditer = NULL; struct sdap_domain *sdmatch = NULL; TALLOC_CTX *tmp_ctx = NULL; int match_len; int best_match_len = 0; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NULL; } DLIST_FOR_EACH(sditer, opts->sdom) { if (sss_ldap_dn_in_search_bases_len(tmp_ctx, dn, sditer->search_bases, NULL, &match_len) || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn, sditer->user_search_bases, NULL, &match_len) || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn, sditer->group_search_bases, NULL, &match_len) || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn, sditer->netgroup_search_bases, NULL, &match_len) || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn, sditer->sudo_search_bases, NULL, &match_len) || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn, sditer->service_search_bases, NULL, &match_len) || sss_ldap_dn_in_search_bases_len(tmp_ctx, dn, sditer->autofs_search_bases, NULL, &match_len)) { if (best_match_len < match_len) { /*this is a longer match*/ best_match_len = match_len; sdmatch = sditer; } } } talloc_free(tmp_ctx); return sdmatch; } errno_t sdap_domain_add(struct sdap_options *opts, struct sss_domain_info *dom, struct sdap_domain **_sdom) { struct sdap_domain *sdom; errno_t ret; sdom = talloc_zero(opts, struct sdap_domain); if (sdom == NULL) { return ENOMEM; } sdom->dom = dom; sdom->head = &opts->sdom; /* Convert the domain name into search base */ ret = domain_to_basedn(sdom, sdom->dom->name, &sdom->basedn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot convert domain name [%s] to base DN [%d]: %s\n", dom->name, ret, strerror(ret)); goto done; } talloc_set_destructor((TALLOC_CTX *)sdom, sdap_domain_destructor); DLIST_ADD_END(opts->sdom, sdom, struct sdap_domain *); if (_sdom) *_sdom = sdom; ret = EOK; done: if (ret != EOK) { talloc_free(sdom); } return ret; } errno_t sdap_domain_subdom_add(struct sdap_id_ctx *sdap_id_ctx, struct sdap_domain *sdom_list, struct sss_domain_info *parent) { struct sss_domain_info *dom; struct sdap_domain *sdom, *sditer; errno_t ret; for (dom = get_next_domain(parent, SSS_GND_DESCEND); dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */ dom = get_next_domain(dom, 0)) { DLIST_FOR_EACH(sditer, sdom_list) { if (sditer->dom == dom) { break; } } if (sditer == NULL) { /* New sdap domain */ DEBUG(SSSDBG_TRACE_FUNC, "subdomain %s is a new one, will " "create a new sdap domain object\n", dom->name); ret = sdap_domain_add(sdap_id_ctx->opts, dom, &sdom); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot add new sdap domain for domain %s [%d]: %s\n", parent->name, ret, strerror(ret)); return ret; } } else { sdom = sditer; } /* Update search bases */ talloc_zfree(sdom->search_bases); sdom->search_bases = talloc_array(sdom, struct sdap_search_base *, 2); if (sdom->search_bases == NULL) { return ENOMEM; } sdom->search_bases[1] = NULL; ret = sdap_create_search_base(sdom, sdom->basedn, LDAP_SCOPE_SUBTREE, NULL, &sdom->search_bases[0]); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Cannot create new sdap search base\n"); return ret; } sdom->user_search_bases = sdom->search_bases; sdom->group_search_bases = sdom->search_bases; sdom->netgroup_search_bases = sdom->search_bases; sdom->sudo_search_bases = sdom->search_bases; sdom->service_search_bases = sdom->search_bases; sdom->autofs_search_bases = sdom->search_bases; } return EOK; } void sdap_domain_remove(struct sdap_options *opts, struct sss_domain_info *dom) { struct sdap_domain *sdom; sdom = sdap_domain_get(opts, dom); if (sdom == NULL) return; DLIST_REMOVE(*(sdom->head), sdom); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_autofs.c0000644000000000000000000000007312703456111021721 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.806794144 sssd-1.13.4/src/providers/ldap/sdap_async_autofs.c0000644002412700241270000007015112703456111023375 0ustar00jhrozekjhrozek00000000000000/* SSSD Async LDAP Helper routines for autofs Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/sdap_async_private.h" #include "db/sysdb_autofs.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_autofs.h" enum autofs_map_op { AUTOFS_MAP_OP_ADD, AUTOFS_MAP_OP_DEL }; /* ====== Utility functions ====== */ static const char * get_autofs_map_name(struct sysdb_attrs *map, struct sdap_options *opts) { errno_t ret; struct ldb_message_element *el; ret = sysdb_attrs_get_el(map, opts->autofs_mobject_map[SDAP_AT_AUTOFS_MAP_NAME].sys_name, &el); if (ret) return NULL; if (el->num_values == 0) return NULL; return (const char *)el->values[0].data; } static const char * get_autofs_entry_attr(struct sysdb_attrs *entry, struct sdap_options *opts, enum sdap_autofs_entry_attrs attr) { errno_t ret; struct ldb_message_element *el; ret = sysdb_attrs_get_el(entry, opts->autofs_entry_map[attr].sys_name, &el); if (ret) return NULL; if (el->num_values != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Expected one entry got %d\n", el->num_values); return NULL; } return (const char *)el->values[0].data; } static const char * get_autofs_entry_key(struct sysdb_attrs *entry, struct sdap_options *opts) { return get_autofs_entry_attr(entry, opts, SDAP_AT_AUTOFS_ENTRY_KEY); } static const char * get_autofs_entry_value(struct sysdb_attrs *entry, struct sdap_options *opts) { return get_autofs_entry_attr(entry, opts, SDAP_AT_AUTOFS_ENTRY_VALUE); } static errno_t add_autofs_entry(struct sss_domain_info *domain, const char *map, struct sdap_options *opts, struct sysdb_attrs *entry) { const char *key; const char *value; key = get_autofs_entry_key(entry, opts); if (!key) { DEBUG(SSSDBG_OP_FAILURE, "Could not get autofs entry key\n"); return EINVAL; } value = get_autofs_entry_value(entry, opts); if (!value) { DEBUG(SSSDBG_OP_FAILURE, "Could not get autofs entry value\n"); return EINVAL; } return sysdb_save_autofsentry(domain, map, key, value, NULL); } static errno_t save_autofs_entries(struct sss_domain_info *domain, struct sdap_options *opts, const char *map, char **add_dn_list, hash_table_t *entry_hash) { hash_key_t key; hash_value_t value; size_t i; int hret; errno_t ret; struct sysdb_attrs *entry; if (!add_dn_list) { return EOK; } for (i=0; add_dn_list[i]; i++) { key.type = HASH_KEY_STRING; key.str = (char *) add_dn_list[i]; hret = hash_lookup(entry_hash, &key, &value); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot retrieve entry [%s] from hash\n", add_dn_list[i]); continue; } entry = talloc_get_type(value.ptr, struct sysdb_attrs); if (!entry) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot retrieve entry [%s] from ptr\n", add_dn_list[i]); continue; } DEBUG(SSSDBG_TRACE_FUNC, "Saving autofs entry [%s]\n", add_dn_list[i]); ret = add_autofs_entry(domain, map, opts, entry); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot save entry [%s] to cache\n", add_dn_list[i]); continue; } DEBUG(SSSDBG_TRACE_FUNC, "Saved entry [%s]\n", add_dn_list[i]); } DEBUG(SSSDBG_TRACE_INTERNAL, "All entries saved\n"); return EOK; } static errno_t del_autofs_entries(struct sss_domain_info *dom, struct sdap_options *opts, const char *map, char **del_dn_list) { size_t i; errno_t ret; for (i=0; del_dn_list[i]; i++) { DEBUG(SSSDBG_TRACE_FUNC, "Removing autofs entry [%s]\n", del_dn_list[i]); ret = sysdb_del_autofsentry(dom, del_dn_list[i]); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot delete entry %s\n", del_dn_list[i]); continue; } } DEBUG(SSSDBG_TRACE_INTERNAL, "All entries removed\n"); return EOK; } static errno_t save_autofs_map(struct sss_domain_info *dom, struct sdap_options *opts, struct sysdb_attrs *map) { const char *mapname; errno_t ret; time_t now; mapname = get_autofs_map_name(map, opts); if (!mapname) return EINVAL; now = time(NULL); ret = sysdb_save_autofsmap(dom, mapname, mapname, NULL, dom->autofsmap_timeout, now); if (ret != EOK) { return ret; } return EOK; } struct automntmaps_process_members_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; struct sss_domain_info *dom; int timeout; const char *orig_dn; char *base_filter; char *filter; const char **attrs; size_t base_iter; struct sdap_search_base **search_bases; struct sysdb_attrs *map; struct sysdb_attrs **entries; size_t entries_count; }; static void automntmaps_process_members_done(struct tevent_req *subreq); static errno_t automntmaps_process_members_next_base(struct tevent_req *req); static struct tevent_req * automntmaps_process_members_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, struct sss_domain_info *dom, struct sdap_search_base **search_bases, int timeout, struct sysdb_attrs *map) { errno_t ret; struct tevent_req *req; struct automntmaps_process_members_state *state; req = tevent_req_create(mem_ctx, &state, struct automntmaps_process_members_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->dom = dom; state->sh = sh; state->timeout = timeout; state->base_iter = 0; state->map = map; state->search_bases = search_bases; state->base_filter = talloc_asprintf(state, "(&(%s=*)(objectclass=%s))", opts->autofs_entry_map[SDAP_AT_AUTOFS_ENTRY_KEY].name, opts->autofs_entry_map[SDAP_OC_AUTOFS_ENTRY].name); if (!state->base_filter) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto immediate; } ret = build_attrs_from_map(state, opts->autofs_entry_map, SDAP_OPTS_AUTOFS_ENTRY, NULL, &state->attrs, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build attributes from map\n"); ret = ENOMEM; goto immediate; } ret = sysdb_attrs_get_string(state->map, SYSDB_ORIG_DN, &state->orig_dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get originalDN\n"); goto immediate; } DEBUG(SSSDBG_TRACE_FUNC, "Examining autofs map [%s]\n", state->orig_dn); ret = automntmaps_process_members_next_base(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "search failed [%d]: %s\n", ret, strerror(ret)); goto immediate; } return req; immediate: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } tevent_req_post(req, ev); return req; } static errno_t automntmaps_process_members_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct automntmaps_process_members_state *state = tevent_req_data(req, struct automntmaps_process_members_state); talloc_zfree(state->filter); state->filter = sdap_combine_filters(state, state->base_filter, state->search_bases[state->base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for automount map entries with base [%s]\n", state->search_bases[state->base_iter]->basedn); subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, state->orig_dn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->autofs_entry_map, SDAP_OPTS_AUTOFS_ENTRY, state->timeout, true); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot start search for entries\n"); return EIO; } tevent_req_set_callback(subreq, automntmaps_process_members_done, req); return EOK; } static void automntmaps_process_members_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct automntmaps_process_members_state *state = tevent_req_data(req, struct automntmaps_process_members_state); errno_t ret; struct sysdb_attrs **entries; size_t entries_count, i; ret = sdap_get_generic_recv(subreq, state, &entries_count, &entries); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } if (entries_count > 0) { state->entries = talloc_realloc(state, state->entries, struct sysdb_attrs *, state->entries_count + entries_count + 1); if (state->entries == NULL) { tevent_req_error(req, ENOMEM); return; } for (i=0; i < entries_count; i++) { state->entries[state->entries_count + i] = talloc_steal(state->entries, entries[i]); } state->entries_count += entries_count; state->entries[state->entries_count] = NULL; } state->base_iter++; if (state->search_bases[state->base_iter]) { ret = automntmaps_process_members_next_base(req); if (ret != EOK) { tevent_req_error(req, ret); return; } } DEBUG(SSSDBG_TRACE_INTERNAL, "No more search bases to try\n"); DEBUG(SSSDBG_TRACE_FUNC, "Search for autofs entries, returned %zu results.\n", state->entries_count); tevent_req_done(req); return; } static errno_t automntmaps_process_members_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *entries_count, struct sysdb_attrs ***entries) { struct automntmaps_process_members_state *state; state = tevent_req_data(req, struct automntmaps_process_members_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (entries_count) { *entries_count = state->entries_count; } if (entries) { *entries = talloc_steal(mem_ctx, state->entries); } return EOK; } struct sdap_get_automntmap_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; struct sss_domain_info *dom; const char **attrs; const char *base_filter; char *filter; int timeout; char *higher_timestamp; struct sysdb_attrs **map; size_t count; struct sysdb_attrs **entries; size_t entries_count; size_t base_iter; struct sdap_search_base **search_bases; }; static errno_t sdap_get_automntmap_next_base(struct tevent_req *req); static void sdap_get_automntmap_process(struct tevent_req *subreq); static struct tevent_req * sdap_get_automntmap_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sdap_options *opts, struct sdap_search_base **search_bases, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout) { errno_t ret; struct tevent_req *req; struct sdap_get_automntmap_state *state; req = tevent_req_create(memctx, &state, struct sdap_get_automntmap_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->dom = dom; state->sh = sh; state->attrs = attrs; state->higher_timestamp = NULL; state->map = NULL; state->count = 0; state->timeout = timeout; state->base_filter = filter; state->base_iter = 0; state->search_bases = search_bases; ret = sdap_get_automntmap_next_base(req); if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, state->ev); } return req; } static errno_t sdap_get_automntmap_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_get_automntmap_state *state; state = tevent_req_data(req, struct sdap_get_automntmap_state); talloc_zfree(state->filter); state->filter = sdap_combine_filters(state, state->base_filter, state->search_bases[state->base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for automount maps with base [%s]\n", state->search_bases[state->base_iter]->basedn); subreq = sdap_get_generic_send( state, state->ev, state->opts, state->sh, state->search_bases[state->base_iter]->basedn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->autofs_mobject_map, SDAP_OPTS_AUTOFS_MAP, state->timeout, false); if (!subreq) { return EIO; } tevent_req_set_callback(subreq, sdap_get_automntmap_process, req); return EOK; } static void sdap_get_automntmap_done(struct tevent_req *subreq); static void sdap_get_automntmap_process(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_automntmap_state *state = tevent_req_data(req, struct sdap_get_automntmap_state); errno_t ret; ret = sdap_get_generic_recv(subreq, state, &state->count, &state->map); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_FUNC, "Search for autofs maps, returned %zu results.\n", state->count); if (state->count == 0) { /* No maps found in this search */ state->base_iter++; if (state->search_bases[state->base_iter]) { /* There are more search bases to try */ ret = sdap_get_automntmap_next_base(req); if (ret != EOK) { tevent_req_error(req, ENOENT); } return; } tevent_req_error(req, ENOENT); return; } else if (state->count > 1) { DEBUG(SSSDBG_OP_FAILURE, "The search yielded more than one autofs map\n"); tevent_req_error(req, EIO); return; } DEBUG(SSSDBG_TRACE_INTERNAL, "Processing autofs maps\n"); subreq = automntmaps_process_members_send(state, state->ev, state->opts, state->sh, state->dom, state->search_bases, state->timeout, state->map[0]); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_get_automntmap_done, req); return; } static void sdap_get_automntmap_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_automntmap_state *state = tevent_req_data(req, struct sdap_get_automntmap_state); errno_t ret; ret = automntmaps_process_members_recv(subreq, state, &state->entries_count, &state->entries); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_FUNC, "automount map members received\n"); tevent_req_done(req); return; } static errno_t sdap_get_automntmap_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sysdb_attrs **map, size_t *entries_count, struct sysdb_attrs ***entries) { struct sdap_get_automntmap_state *state = tevent_req_data(req, struct sdap_get_automntmap_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (map) { *map = talloc_steal(mem_ctx, state->map[0]); } if (entries_count) { *entries_count = state->entries_count; } if (entries) { *entries = talloc_steal(mem_ctx, state->entries); } return EOK; } struct sdap_autofs_setautomntent_state { char *filter; const char **attrs; struct sdap_options *opts; struct sdap_handle *sh; struct sysdb_ctx *sysdb; struct sdap_id_op *sdap_op; struct sss_domain_info *dom; const char *mapname; struct sysdb_attrs *map; struct sysdb_attrs **entries; size_t entries_count; int dp_error; }; static void sdap_autofs_setautomntent_done(struct tevent_req *subreq); struct tevent_req * sdap_autofs_setautomntent_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sysdb_ctx *sysdb, struct sdap_handle *sh, struct sdap_id_op *op, struct sdap_options *opts, const char *mapname) { struct tevent_req *req; struct tevent_req *subreq; struct sdap_autofs_setautomntent_state *state; char *clean_mapname; errno_t ret; req = tevent_req_create(memctx, &state, struct sdap_autofs_setautomntent_state); if (!req) return NULL; if (!mapname) { DEBUG(SSSDBG_CRIT_FAILURE, "No map name given\n"); ret = EINVAL; goto fail; } state->sh = sh; state->sysdb = sysdb; state->opts = opts; state->sdap_op = op; state->dom = dom; state->mapname = mapname; ret = sss_filter_sanitize(state, mapname, &clean_mapname); if (ret != EOK) { goto fail; } state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))", state->opts->autofs_mobject_map[SDAP_AT_AUTOFS_MAP_NAME].name, clean_mapname, state->opts->autofs_mobject_map[SDAP_OC_AUTOFS_MAP].name); if (!state->filter) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto fail; } talloc_free(clean_mapname); ret = build_attrs_from_map(state, state->opts->autofs_mobject_map, SDAP_OPTS_AUTOFS_MAP, NULL, &state->attrs, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build attributes from map\n"); ret = ENOMEM; goto fail; } subreq = sdap_get_automntmap_send(state, ev, dom, state->opts, state->opts->sdom->autofs_search_bases, state->sh, state->attrs, state->filter, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT)); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, sdap_autofs_setautomntent_done, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static errno_t sdap_autofs_setautomntent_save(struct tevent_req *req); static void sdap_autofs_setautomntent_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_autofs_setautomntent_state *state = tevent_req_data(req, struct sdap_autofs_setautomntent_state); ret = sdap_get_automntmap_recv(subreq, state, &state->map, &state->entries_count, &state->entries); talloc_zfree(subreq); if (ret != EOK) { if (ret == ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not find automount map\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "sdap_get_automntmap_recv failed [%d]: %s\n", ret, strerror(ret)); } tevent_req_error(req, ret); return; } ret = sdap_autofs_setautomntent_save(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not save automount map\n"); tevent_req_error(req, ret); return; } state->dp_error = DP_ERR_OK; tevent_req_done(req); return; } static errno_t sdap_autofs_setautomntent_save(struct tevent_req *req) { struct sdap_autofs_setautomntent_state *state = tevent_req_data(req, struct sdap_autofs_setautomntent_state); errno_t ret, tret; bool in_transaction = false; TALLOC_CTX *tmp_ctx; struct ldb_message **entries = NULL; size_t count; const char *key; const char *val; char **sysdb_entrylist; char **ldap_entrylist; char **add_entries; char **del_entries; size_t i, j; hash_table_t *entry_hash; hash_key_t hkey; hash_value_t value; int hret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; DEBUG(SSSDBG_TRACE_LIBS, "Got %zu map entries from LDAP\n", state->entries_count); if (state->entries_count == 0) { /* No entries for this map in LDAP. * We need to ensure that there are no entries * in the sysdb either. */ ldap_entrylist = NULL; } else { ldap_entrylist = talloc_array(tmp_ctx, char *, state->entries_count+1); if (!ldap_entrylist) { ret = ENOMEM; goto done; } ret = sss_hash_create(state, 32, &entry_hash); if (ret) { goto done; } /* Get a list of the map members by DN */ for (i=0, j=0; i < state->entries_count; i++) { key = get_autofs_entry_key(state->entries[i], state->opts); val = get_autofs_entry_value(state->entries[i], state->opts); if (!key || !val) { DEBUG(SSSDBG_MINOR_FAILURE, "Malformed entry, skipping\n"); continue; } ldap_entrylist[j] = sysdb_autofsentry_strdn(ldap_entrylist, state->dom, state->mapname, key, val); if (!ldap_entrylist[j]) { ret = ENOMEM; goto done; } hkey.type = HASH_KEY_STRING; hkey.str = ldap_entrylist[j]; value.type = HASH_VALUE_PTR; value.ptr = state->entries[i]; hret = hash_enter(entry_hash, &hkey, &value); if (hret != HASH_SUCCESS) { ret = EIO; goto done; } j++; } /* terminate array with NULL after the last retrieved entry */ ldap_entrylist[j] = NULL; } ret = sysdb_autofs_entries_by_map(tmp_ctx, state->dom, state->mapname, &count, &entries); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "cache lookup for the map failed [%d]: %s\n", ret, strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Got %zu map entries from sysdb\n", count); if (count == 0) { /* No map members for this map in sysdb currently */ sysdb_entrylist = NULL; } else { sysdb_entrylist = talloc_array(state, char *, count+1); if (!sysdb_entrylist) { ret = ENOMEM; goto done; } /* Get a list of the map members by DN */ for (i=0; i < count; i++) { sysdb_entrylist[i] = talloc_strdup(sysdb_entrylist, ldb_dn_get_linearized(entries[i]->dn)); if (!sysdb_entrylist[i]) { ret = ENOMEM; goto done; } } sysdb_entrylist[count] = NULL; } /* Find the differences between the sysdb and LDAP lists * Entries in the sysdb only must be removed. */ ret = diff_string_lists(tmp_ctx, ldap_entrylist, sysdb_entrylist, &add_entries, &del_entries, NULL); if (ret != EOK) goto done; ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot start sysdb transaction [%d]: %s\n", ret, strerror(ret)); goto done; } in_transaction = true; /* Save the map itself */ ret = save_autofs_map(state->dom, state->opts, state->map); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot save autofs map entry [%d]: %s\n", ret, strerror(ret)); goto done; } /* Create entries that don't exist yet */ if (add_entries && add_entries[0]) { ret = save_autofs_entries(state->dom, state->opts, state->mapname, add_entries, entry_hash); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot save autofs entries [%d]: %s\n", ret, strerror(ret)); goto done; } } /* Delete entries that don't exist anymore */ if (del_entries && del_entries[0]) { ret = del_autofs_entries(state->dom, state->opts, state->mapname, del_entries); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot delete autofs entries [%d]: %s\n", ret, strerror(ret)); goto done; } } ret = sysdb_transaction_commit(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot commit sysdb transaction [%d]: %s\n", ret, strerror(ret)); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { tret = sysdb_transaction_cancel(state->sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot cancel sysdb transaction [%d]: %s\n", ret, strerror(ret)); } } talloc_zfree(tmp_ctx); return ret; } errno_t sdap_autofs_setautomntent_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_access.h0000644000000000000000000000007312703456111020471 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.550793276 sssd-1.13.4/src/providers/ldap/sdap_access.h0000644002412700241270000000555712703456111022155 0ustar00jhrozekjhrozek00000000000000/* SSSD sdap_access.h Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SDAP_ACCESS_H_ #define SDAP_ACCESS_H_ #include "providers/dp_backend.h" #include "providers/ldap/ldap_common.h" /* Attributes in sysdb, used for caching last values of lockout or filter * access control checks. */ #define SYSDB_LDAP_ACCESS_FILTER "ldap_access_filter_allow" #define SYSDB_LDAP_ACCESS_CACHED_LOCKOUT "ldap_access_lockout_allow" /* names of ppolicy attributes */ #define SYSDB_LDAP_ACCESS_LOCKED_TIME "pwdAccountLockedTime" #define SYSDB_LDAP_ACESS_LOCKOUT_DURATION "pwdLockoutDuration" #define SYSDB_LDAP_ACCESS_LOCKOUT "pwdLockout" #define LDAP_ACCESS_FILTER_NAME "filter" #define LDAP_ACCESS_EXPIRE_NAME "expire" #define LDAP_ACCESS_EXPIRE_POLICY_REJECT_NAME "pwd_expire_policy_reject" #define LDAP_ACCESS_EXPIRE_POLICY_WARN_NAME "pwd_expire_policy_warn" #define LDAP_ACCESS_EXPIRE_POLICY_RENEW_NAME "pwd_expire_policy_renew" #define LDAP_ACCESS_SERVICE_NAME "authorized_service" #define LDAP_ACCESS_HOST_NAME "host" #define LDAP_ACCESS_LOCK_NAME "lockout" #define LDAP_ACCESS_PPOLICY_NAME "ppolicy" #define LDAP_ACCOUNT_EXPIRE_SHADOW "shadow" #define LDAP_ACCOUNT_EXPIRE_AD "ad" #define LDAP_ACCOUNT_EXPIRE_RHDS "rhds" #define LDAP_ACCOUNT_EXPIRE_IPA "ipa" #define LDAP_ACCOUNT_EXPIRE_389DS "389ds" #define LDAP_ACCOUNT_EXPIRE_NDS "nds" enum ldap_access_rule { LDAP_ACCESS_EMPTY = -1, LDAP_ACCESS_FILTER = 0, LDAP_ACCESS_EXPIRE, LDAP_ACCESS_SERVICE, LDAP_ACCESS_HOST, LDAP_ACCESS_LOCKOUT, LDAP_ACCESS_EXPIRE_POLICY_REJECT, LDAP_ACCESS_EXPIRE_POLICY_WARN, LDAP_ACCESS_EXPIRE_POLICY_RENEW, LDAP_ACCESS_PPOLICY, LDAP_ACCESS_LAST }; struct sdap_access_ctx { struct sdap_id_ctx *id_ctx; const char *filter; int access_rule[LDAP_ACCESS_LAST + 1]; }; struct tevent_req * sdap_access_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, struct sdap_access_ctx *access_ctx, struct sdap_id_conn_ctx *conn, struct pam_data *pd); errno_t sdap_access_recv(struct tevent_req *req); #endif /* SDAP_ACCESS_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap.c0000644000000000000000000000007312703456111017143 xustar0030 atime=1460561751.647715617 29 ctime=1460561774.79979412 sssd-1.13.4/src/providers/ldap/sdap.c0000644002412700241270000015077312703456111020630 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Helper routines Copyright (C) Simo Sorce This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/crypto/sss_crypto.h" #include "confdb/confdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_range.h" /* =Retrieve-Options====================================================== */ errno_t sdap_copy_map_entry(const struct sdap_attr_map *src_map, struct sdap_attr_map *dst_map, int entry_index) { if (src_map[entry_index].name != NULL) { dst_map[entry_index].name = talloc_strdup(dst_map, src_map[entry_index].name); if (dst_map[entry_index].name == NULL) { return ENOMEM; } } else { dst_map->name = NULL; } return EOK; } int sdap_copy_map(TALLOC_CTX *memctx, struct sdap_attr_map *src_map, int num_entries, struct sdap_attr_map **_map) { struct sdap_attr_map *map; int i; map = talloc_array(memctx, struct sdap_attr_map, num_entries + 1); if (!map) { return ENOMEM; } for (i = 0; i < num_entries; i++) { map[i].opt_name = talloc_strdup(map, src_map[i].opt_name); map[i].sys_name = talloc_strdup(map, src_map[i].sys_name); if (map[i].opt_name == NULL || map[i].sys_name == NULL) { return ENOMEM; } if (src_map[i].def_name != NULL) { map[i].def_name = talloc_strdup(map, src_map[i].def_name); map[i].name = talloc_strdup(map, src_map[i].def_name); if (map[i].def_name == NULL || map[i].name == NULL) { return ENOMEM; } } else { map[i].def_name = NULL; map[i].name = NULL; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s has%s value %s\n", map[i].opt_name, map[i].name ? "" : " no", map[i].name ? map[i].name : ""); } /* Include the sentinel */ memset(&map[num_entries], 0, sizeof(struct sdap_attr_map)); *_map = map; return EOK; } static errno_t split_extra_attr(TALLOC_CTX *mem_ctx, char *conf_attr, char **_sysdb_attr, char **_ldap_attr) { char *ldap_attr; char *sysdb_attr; char *sep; ldap_attr = conf_attr; sep = strchr(conf_attr, ':'); if (sep == NULL) { sysdb_attr = talloc_strdup(mem_ctx, conf_attr); ldap_attr = talloc_strdup(mem_ctx, conf_attr); } else { if (sep == conf_attr || *(sep + 1) == '\0') { return ERR_INVALID_EXTRA_ATTR; } sysdb_attr = talloc_strndup(mem_ctx, ldap_attr, sep - ldap_attr); ldap_attr = talloc_strdup(mem_ctx, sep+1); } if (sysdb_attr == NULL || ldap_attr == NULL) { return ENOMEM; } *_sysdb_attr = sysdb_attr; *_ldap_attr = ldap_attr; return EOK; } static bool is_sysdb_duplicate(struct sdap_attr_map *map, int num_entries, const char *sysdb_attr) { int i; for (i = 0; i < num_entries; i++) { if (strcmp(map[i].sys_name, sysdb_attr) == 0) { return true; } } return false; } int sdap_extend_map(TALLOC_CTX *memctx, struct sdap_attr_map *src_map, size_t num_entries, char **extra_attrs, struct sdap_attr_map **_map, size_t *_new_size) { struct sdap_attr_map *map; size_t nextra = 0; size_t i; char *ldap_attr; char *sysdb_attr; errno_t ret; if (extra_attrs == NULL) { DEBUG(SSSDBG_FUNC_DATA, "No extra attributes\n"); *_map = src_map; *_new_size = num_entries; return EOK; } for (nextra = 0; extra_attrs[nextra]; nextra++) ; DEBUG(SSSDBG_FUNC_DATA, "%zu extra attributes\n", nextra); map = talloc_realloc(memctx, src_map, struct sdap_attr_map, num_entries + nextra + 1); if (map == NULL) { return ENOMEM; } for (i = 0; extra_attrs[i]; i++) { ret = split_extra_attr(map, extra_attrs[i], &sysdb_attr, &ldap_attr); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot split %s\n", extra_attrs[i]); continue; } if (is_sysdb_duplicate(map, num_entries, sysdb_attr)) { DEBUG(SSSDBG_FATAL_FAILURE, "Attribute %s (%s in LDAP) is already used by SSSD, please " "choose a different cache name\n", sysdb_attr, ldap_attr); return ERR_DUP_EXTRA_ATTR; } map[num_entries+i].name = ldap_attr; map[num_entries+i].sys_name = sysdb_attr; map[num_entries+i].opt_name = talloc_strdup(map, map[num_entries+i].name); map[num_entries+i].def_name = talloc_strdup(map, map[num_entries+i].name); if (map[num_entries+i].opt_name == NULL || map[num_entries+i].sys_name == NULL || map[num_entries+i].name == NULL || map[num_entries+i].def_name == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Extending map with %s\n", extra_attrs[i]); } /* Sentinel */ memset(&map[num_entries+nextra], 0, sizeof(struct sdap_attr_map)); *_map = map; *_new_size = num_entries + nextra; return EOK; } int sdap_extend_map_with_list(TALLOC_CTX *mem_ctx, struct sdap_options *opts, int extra_attr_index, struct sdap_attr_map *src_map, size_t num_entries, struct sdap_attr_map **_map, size_t *_new_size) { const char *extra_attrs; char **extra_attrs_list; errno_t ret; extra_attrs = dp_opt_get_string(opts->basic, extra_attr_index); if (extra_attrs == NULL) { *_map = src_map; *_new_size = num_entries; return EOK; } /* split server parm into a list */ ret = split_on_separator(mem_ctx, extra_attrs, ',', true, true, &extra_attrs_list, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, ("Failed to parse server list!\n")); return ret; } ret = sdap_extend_map(mem_ctx, src_map, num_entries, extra_attrs_list, _map, _new_size); talloc_free(extra_attrs_list); if (ret != EOK) { return ret; } return EOK; } static void sdap_inherit_basic_options(char **inherit_opt_list, struct dp_option *parent_opts, struct dp_option *subdom_opts) { int inherit_options[] = { SDAP_PURGE_CACHE_TIMEOUT, SDAP_AD_USE_TOKENGROUPS, SDAP_OPTS_BASIC /* sentinel */ }; int i; for (i = 0; inherit_options[i] != SDAP_OPTS_BASIC; i++) { dp_option_inherit(inherit_opt_list, inherit_options[i], parent_opts, subdom_opts); } } static void sdap_inherit_user_options(char **inherit_opt_list, struct sdap_attr_map *parent_user_map, struct sdap_attr_map *child_user_map) { int inherit_options[] = { SDAP_AT_USER_PRINC, SDAP_OPTS_USER /* sentinel */ }; int i; int opt_index; bool inherit_option; for (i = 0; inherit_options[i] != SDAP_OPTS_USER; i++) { opt_index = inherit_options[i]; inherit_option = string_in_list(parent_user_map[opt_index].opt_name, inherit_opt_list, false); if (inherit_option == false) { continue; } sdap_copy_map_entry(parent_user_map, child_user_map, opt_index); } } void sdap_inherit_options(char **inherit_opt_list, struct sdap_options *parent_sdap_opts, struct sdap_options *child_sdap_opts) { sdap_inherit_basic_options(inherit_opt_list, parent_sdap_opts->basic, child_sdap_opts->basic); sdap_inherit_user_options(inherit_opt_list, parent_sdap_opts->user_map, child_sdap_opts->user_map); } int sdap_get_map(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, struct sdap_attr_map *def_map, int num_entries, struct sdap_attr_map **_map) { struct sdap_attr_map *map; char *name; int i, ret; map = talloc_zero_array(memctx, struct sdap_attr_map, num_entries + 1); if (!map) { return ENOMEM; } for (i = 0; i < num_entries; i++) { map[i].opt_name = def_map[i].opt_name; map[i].def_name = def_map[i].def_name; map[i].sys_name = def_map[i].sys_name; ret = confdb_get_string(cdb, map, conf_path, map[i].opt_name, map[i].def_name, &name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve value for %s\n", map[i].opt_name); talloc_zfree(map); return EINVAL; } if (name) { ret = sss_filter_sanitize(map, name, &map[i].name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not sanitize attribute [%s]\n", name); talloc_zfree(map); return EINVAL; } talloc_zfree(name); } else { map[i].name = NULL; } if (map[i].def_name && !map[i].name) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve value for %s\n", map[i].opt_name); talloc_zfree(map); return EINVAL; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s has%s value %s\n", map[i].opt_name, map[i].name ? "" : " no", map[i].name ? map[i].name : ""); } *_map = map; return EOK; } /* =Parse-msg============================================================= */ static bool objectclass_matched(struct sdap_attr_map *map, const char *objcl, int len); int sdap_parse_entry(TALLOC_CTX *memctx, struct sdap_handle *sh, struct sdap_msg *sm, struct sdap_attr_map *map, int attrs_num, struct sysdb_attrs **_attrs, bool disable_range_retrieval) { struct sysdb_attrs *attrs; BerElement *ber = NULL; struct berval **vals; struct ldb_val v; char *str; int lerrno; int i, ret, ai; int base_attr_idx = 0; const char *name; bool store; bool base64; char *base_attr; uint32_t range_offset; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; lerrno = 0; ret = ldap_set_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); if (ret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_set_option failed [%s], ignored.\n", sss_ldap_err2string(ret)); } attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } str = ldap_get_dn(sh->ldap, sm->msg); if (!str) { ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); DEBUG(SSSDBG_CRIT_FAILURE, "ldap_get_dn failed: %d(%s)\n", lerrno, sss_ldap_err2string(lerrno)); ret = EIO; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "OriginalDN: [%s].\n", str); ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_DN, str); ldap_memfree(str); if (ret) goto done; if (map) { vals = ldap_get_values_len(sh->ldap, sm->msg, "objectClass"); if (!vals) { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown entry type, no objectClasses found!\n"); ret = EINVAL; goto done; } for (i = 0; vals[i]; i++) { if (objectclass_matched(map, vals[i]->bv_val, vals[i]->bv_len)) { /* ok it's an entry of the right type */ break; } } if (!vals[i]) { DEBUG(SSSDBG_CRIT_FAILURE, "objectClass not matching: %s\n", map[0].name); ldap_value_free_len(vals); ret = EINVAL; goto done; } ldap_value_free_len(vals); } str = ldap_first_attribute(sh->ldap, sm->msg, &ber); if (!str) { ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); DEBUG(lerrno == LDAP_SUCCESS ? SSSDBG_TRACE_LIBS : SSSDBG_MINOR_FAILURE, "Entry has no attributes [%d(%s)]!?\n", lerrno, sss_ldap_err2string(lerrno)); if (map) { ret = EINVAL; goto done; } } while (str) { base64 = false; ret = sdap_parse_range(tmp_ctx, str, &base_attr, &range_offset, disable_range_retrieval); switch(ret) { case EAGAIN: /* This attribute contained range values and needs more to * be retrieved */ /* TODO: return the set of attributes that need additional retrieval * For now, we'll continue below and treat it as regular values. */ /* FALLTHROUGH */ case ECANCELED: /* FALLTHROUGH */ case EOK: break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Could not determine if attribute [%s] was ranged\n", str); goto done; } if (map) { for (i = 1; i < attrs_num; i++) { /* check if this attr is valid with the chosen schema */ if (!map[i].name) continue; /* check if it is an attr we are interested in */ if (strcasecmp(base_attr, map[i].name) == 0) break; } /* interesting attr */ if (i < attrs_num) { store = true; name = map[i].sys_name; base_attr_idx = i; if (strcmp(name, SYSDB_SSH_PUBKEY) == 0) { base64 = true; } } else { store = false; name = NULL; } } else { name = base_attr; store = true; } if (ret == ECANCELED) { ret = EOK; store = false; } if (store) { vals = ldap_get_values_len(sh->ldap, sm->msg, str); if (!vals) { ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); if (lerrno != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "LDAP Library error: %d(%s)\n", lerrno, sss_ldap_err2string(lerrno)); ret = EIO; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Attribute [%s] has no values, skipping.\n", str); } else { if (!vals[0]) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing value after ldap_get_values() ??\n"); ldap_value_free_len(vals); ret = EINVAL; goto done; } for (i = 0; vals[i]; i++) { if (vals[i]->bv_len == 0) { DEBUG(SSSDBG_TRACE_LIBS, "Value of attribute [%s] is empty. " "Skipping this value.\n", str); continue; } if (base64) { v.data = (uint8_t *) sss_base64_encode(attrs, (uint8_t *) vals[i]->bv_val, vals[i]->bv_len); if (!v.data) { ldap_value_free_len(vals); ret = ENOMEM; goto done; } v.length = strlen((const char *)v.data); } else { v.data = (uint8_t *)vals[i]->bv_val; v.length = vals[i]->bv_len; } if (map) { /* The same LDAP attr might be used for more sysdb * attrs in case there is a map. Find all that match * and copy the value */ for (ai = base_attr_idx; ai < attrs_num; ai++) { /* check if this attr is valid with the chosen * schema */ if (!map[ai].name) continue; /* check if it is an attr we are interested in */ if (strcasecmp(base_attr, map[ai].name) == 0) { ret = sysdb_attrs_add_val(attrs, map[ai].sys_name, &v); if (ret) { ldap_value_free_len(vals); goto done; } } } } else { /* No map, just store the attribute */ ret = sysdb_attrs_add_val(attrs, name, &v); if (ret) { ldap_value_free_len(vals); goto done; } } } ldap_value_free_len(vals); } } ldap_memfree(str); str = ldap_next_attribute(sh->ldap, sm->msg, ber); } ber_free(ber, 0); ber = NULL; ldap_get_option(sh->ldap, LDAP_OPT_RESULT_CODE, &lerrno); if (lerrno) { DEBUG(SSSDBG_CRIT_FAILURE, "LDAP Library error: %d(%s)\n", lerrno, sss_ldap_err2string(lerrno)); ret = EIO; goto done; } *_attrs = talloc_steal(memctx, attrs); ret = EOK; done: if (ber) ber_free(ber, 0); talloc_free(tmp_ctx); return ret; } static bool objectclass_matched(struct sdap_attr_map *map, const char *objcl, int len) { if (len == 0) { len = strlen(objcl) + 1; } if (strncasecmp(map[SDAP_OC_GROUP].name, objcl, len) == 0) { return true; } if (map[SDAP_OC_GROUP_ALT].name != NULL && strncasecmp(map[SDAP_OC_GROUP_ALT].name, objcl, len) == 0) { return true; } return false; } /* Parses an LDAPDerefRes into sdap_deref_attrs structure */ errno_t sdap_parse_deref(TALLOC_CTX *mem_ctx, struct sdap_attr_map_info *minfo, size_t num_maps, LDAPDerefRes *dref, struct sdap_deref_attrs ***_deref_res) { TALLOC_CTX *tmp_ctx; LDAPDerefVal *dval; const char *orig_dn; const char **ocs; struct sdap_attr_map *map; int num_attrs; int ret, i, a, mi; const char *name; size_t len; struct sdap_deref_attrs **res; if (!dref || !minfo) return EINVAL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; res = talloc_array(tmp_ctx, struct sdap_deref_attrs *, num_maps); if (!res) { ret = ENOMEM; goto done; } for (i=0; i < num_maps; i++) { res[i] = talloc_zero(res, struct sdap_deref_attrs); if (!res[i]) { ret = ENOMEM; goto done; } res[i]->map = minfo[i].map; } if (!dref->derefVal.bv_val) { DEBUG(SSSDBG_OP_FAILURE, "Entry has no DN?\n"); ret = EINVAL; goto done; } orig_dn = dref->derefVal.bv_val; DEBUG(SSSDBG_TRACE_LIBS, "Dereferenced DN: %s\n", orig_dn); if (!dref->attrVals) { DEBUG(SSSDBG_FUNC_DATA, "Dereferenced entry [%s] has no attributes, skipping\n", orig_dn); *_deref_res = NULL; ret = EOK; goto done; } ocs = NULL; for (dval = dref->attrVals; dval != NULL; dval = dval->next) { if (strcasecmp("objectClass", dval->type) == 0) { if (dval->vals == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "No value for objectClass, skipping\n"); continue; } for(len=0; dval->vals[len].bv_val; len++); ocs = talloc_array(tmp_ctx, const char *, len+1); if (!ocs) { ret = ENOMEM; goto done; } for (i=0; ivals[i].bv_val); ocs[i] = talloc_strdup(ocs, dval->vals[i].bv_val); if (!ocs[i]) { ret = ENOMEM; goto done; } } ocs[i] = NULL; break; } } if (!ocs) { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown entry type, no objectClasses found!\n"); ret = EINVAL; goto done; } for (mi = 0; mi < num_maps; mi++) { map = NULL; for (i=0; ocs[i]; i++) { /* the objectclass is always the first name in the map */ if (objectclass_matched(minfo[mi].map, ocs[i], 0)) { DEBUG(SSSDBG_TRACE_ALL, "Found map for objectclass '%s'\n", ocs[i]); map = minfo[mi].map; num_attrs = minfo[mi].num_attrs; break; } } if (!map) continue; res[mi]->attrs = sysdb_new_attrs(res[mi]); if (!res[mi]->attrs) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(res[mi]->attrs, SYSDB_ORIG_DN, orig_dn); if (ret) { goto done; } for (dval = dref->attrVals; dval != NULL; dval = dval->next) { DEBUG(SSSDBG_TRACE_INTERNAL, "Dereferenced attribute: %s\n", dval->type); for (a = 1; a < num_attrs; a++) { /* check if this attr is valid with the chosen schema */ if (!map[a].name) continue; /* check if it is an attr we are interested in */ if (strcasecmp(dval->type, map[a].name) == 0) break; } /* interesting attr */ if (a < num_attrs) { name = map[a].sys_name; } else { continue; } if (dval->vals == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "No value for attribute %s, skipping\n", name); continue; } for (i=0; dval->vals[i].bv_val; i++) { DEBUG(SSSDBG_TRACE_ALL, "Dereferenced attribute value: %s\n", dval->vals[i].bv_val); ret = sysdb_attrs_add_mem(res[mi]->attrs, name, dval->vals[i].bv_val, dval->vals[i].bv_len); if (ret) goto done; } } } *_deref_res = talloc_steal(mem_ctx, res); ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } errno_t setup_tls_config(struct dp_option *basic_opts) { int ret; int ldap_opt_x_tls_require_cert; const char *tls_opt; tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_REQCERT); if (tls_opt) { if (strcasecmp(tls_opt, "never") == 0) { ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_NEVER; } else if (strcasecmp(tls_opt, "allow") == 0) { ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_ALLOW; } else if (strcasecmp(tls_opt, "try") == 0) { ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_TRY; } else if (strcasecmp(tls_opt, "demand") == 0) { ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_DEMAND; } else if (strcasecmp(tls_opt, "hard") == 0) { ldap_opt_x_tls_require_cert = LDAP_OPT_X_TLS_HARD; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown value for tls_reqcert.\n"); return EINVAL; } /* LDAP_OPT_X_TLS_REQUIRE_CERT has to be set as a global option, * because the SSL/TLS context is initialized from this value. */ ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_opt_x_tls_require_cert); if (ret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_set_option failed: %s\n", sss_ldap_err2string(ret)); return EIO; } } tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CACERT); if (tls_opt) { ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, tls_opt); if (ret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_set_option failed: %s\n", sss_ldap_err2string(ret)); return EIO; } } tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CACERTDIR); if (tls_opt) { ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR, tls_opt); if (ret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_set_option failed: %s\n", sss_ldap_err2string(ret)); return EIO; } } tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CERT); if (tls_opt) { ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, tls_opt); if (ret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_set_option failed: %s\n", sss_ldap_err2string(ret)); return EIO; } } tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_KEY); if (tls_opt) { ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, tls_opt); if (ret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_set_option failed: %s\n", sss_ldap_err2string(ret)); return EIO; } } tls_opt = dp_opt_get_string(basic_opts, SDAP_TLS_CIPHER_SUITE); if (tls_opt) { ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, tls_opt); if (ret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_set_option failed: %s\n", sss_ldap_err2string(ret)); return EIO; } } return EOK; } bool sdap_check_sup_list(struct sup_list *l, const char *val) { int i; if (!val) { return false; } for (i = 0; i < l->num_vals; i++) { if (strcasecmp(val, (char *)l->vals[i])) { continue; } return true; } return false; } static int sdap_init_sup_list(TALLOC_CTX *memctx, struct sup_list *list, int num, struct ldb_val *vals) { int i; list->vals = talloc_array(memctx, char *, num); if (!list->vals) { return ENOMEM; } for (i = 0; i < num; i++) { list->vals[i] = talloc_strndup(list->vals, (char *)vals[i].data, vals[i].length); if (!list->vals[i]) { return ENOMEM; } } list->num_vals = num; return EOK; } int sdap_set_rootdse_supported_lists(struct sysdb_attrs *rootdse, struct sdap_handle *sh) { struct ldb_message_element *el = NULL; int ret; int i; for (i = 0; i < rootdse->num; i++) { el = &rootdse->a[i]; if (strcasecmp(el->name, "supportedControl") == 0) { ret = sdap_init_sup_list(sh, &sh->supported_controls, el->num_values, el->values); if (ret) { return ret; } } else if (strcasecmp(el->name, "supportedExtension") == 0) { ret = sdap_init_sup_list(sh, &sh->supported_extensions, el->num_values, el->values); if (ret) { return ret; } } else if (strcasecmp(el->name, "supportedSASLMechanisms") == 0) { ret = sdap_init_sup_list(sh, &sh->supported_saslmechs, el->num_values, el->values); if (ret) { return ret; } } } return EOK; } static char *get_single_value_as_string(TALLOC_CTX *mem_ctx, struct ldb_message_element *el) { char *str = NULL; if (el->num_values == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Missing value.\n"); } else if (el->num_values == 1) { str = talloc_strndup(mem_ctx, (char *) el->values[0].data, el->values[0].length); if (str == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n"); } } else { DEBUG(SSSDBG_MINOR_FAILURE, "More than one value found.\n"); } return str; } static char *get_naming_context(TALLOC_CTX *mem_ctx, struct sysdb_attrs *rootdse) { struct ldb_message_element *nc = NULL; struct ldb_message_element *dnc = NULL; int i; char *naming_context = NULL; for (i = 0; i < rootdse->num; i++) { if (strcasecmp(rootdse->a[i].name, SDAP_ROOTDSE_ATTR_NAMING_CONTEXTS) == 0) { nc = &rootdse->a[i]; } else if (strcasecmp(rootdse->a[i].name, SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT) == 0) { dnc = &rootdse->a[i]; } } if (dnc == NULL && nc == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "No attributes [%s] or [%s] found in rootDSE.\n", SDAP_ROOTDSE_ATTR_NAMING_CONTEXTS, SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT); } else { if (dnc != NULL) { DEBUG(SSSDBG_FUNC_DATA, "Using value from [%s] as naming context.\n", SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT); naming_context = get_single_value_as_string(mem_ctx, dnc); } if (naming_context == NULL && nc != NULL) { DEBUG(SSSDBG_FUNC_DATA, "Using value from [%s] as naming context.\n", SDAP_ROOTDSE_ATTR_NAMING_CONTEXTS); naming_context = get_single_value_as_string(mem_ctx, nc); } } /* Some directory servers such as Novell eDirectory will return * a zero-length namingContexts value in some situations. In this * case, we should return it as NULL so things fail gracefully. */ if (naming_context && naming_context[0] == '\0') { talloc_zfree(naming_context); } return naming_context; } errno_t sdap_create_search_base(TALLOC_CTX *mem_ctx, const char *unparsed_base, int scope, const char *filter, struct sdap_search_base **_base) { struct sdap_search_base *base; TALLOC_CTX *tmp_ctx; errno_t ret; struct ldb_dn *ldn; struct ldb_context *ldb; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } /* Create a throwaway LDB context for validating the DN */ ldb = ldb_init(tmp_ctx, NULL); if (!ldb) { ret = ENOMEM; goto done; } base = talloc_zero(tmp_ctx, struct sdap_search_base); if (base == NULL) { ret = ENOMEM; goto done; } base->basedn = talloc_strdup(base, unparsed_base); if (base->basedn == NULL) { ret = ENOMEM; goto done; } /* Validate the basedn */ ldn = ldb_dn_new(tmp_ctx, ldb, unparsed_base); if (!ldn) { ret = ENOMEM; goto done; } if (!ldb_dn_validate(ldn)) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid base DN [%s]\n", unparsed_base); ret = EINVAL; goto done; } base->scope = scope; base->filter = filter; *_base = talloc_steal(mem_ctx, base); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t sdap_set_search_base(struct sdap_options *opts, struct sdap_domain *sdom, enum sdap_basic_opt class, char *naming_context) { errno_t ret; struct sdap_search_base ***bases; switch(class) { case SDAP_SEARCH_BASE: bases = &sdom->search_bases; break; case SDAP_USER_SEARCH_BASE: bases = &sdom->user_search_bases; break; case SDAP_GROUP_SEARCH_BASE: bases = &sdom->group_search_bases; break; case SDAP_NETGROUP_SEARCH_BASE: bases = &sdom->netgroup_search_bases; break; case SDAP_SUDO_SEARCH_BASE: bases = &sdom->sudo_search_bases; break; case SDAP_SERVICE_SEARCH_BASE: bases = &sdom->service_search_bases; break; case SDAP_AUTOFS_SEARCH_BASE: bases = &sdom->autofs_search_bases; break; default: return EINVAL; } DEBUG(SSSDBG_CONF_SETTINGS, "Setting option [%s] to [%s].\n", opts->basic[class].opt_name, naming_context); ret = dp_opt_set_string(opts->basic, class, naming_context); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed.\n"); goto done; } ret = sdap_parse_search_base(opts, opts->basic, class, bases); if (ret != EOK) goto done; ret = EOK; done: return ret; } errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, struct sdap_options *opts, struct sdap_domain *sdom) { int ret; char *naming_context = NULL; if (!sdom->search_bases || !sdom->user_search_bases || !sdom->group_search_bases || !sdom->netgroup_search_bases || !sdom->sudo_search_bases || !sdom->autofs_search_bases) { naming_context = get_naming_context(opts->basic, rootdse); if (naming_context == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "get_naming_context failed.\n"); /* This has to be non-fatal, since some servers offer * multiple namingContexts entries. We will just * add NULL checks for the search bases in the lookups. */ ret = EOK; goto done; } } /* Default */ if (!sdom->search_bases) { ret = sdap_set_search_base(opts, sdom, SDAP_SEARCH_BASE, naming_context); if (ret != EOK) goto done; } /* Users */ if (!sdom->user_search_bases) { ret = sdap_set_search_base(opts, sdom, SDAP_USER_SEARCH_BASE, naming_context); if (ret != EOK) goto done; } /* Groups */ if (!sdom->group_search_bases) { ret = sdap_set_search_base(opts, sdom, SDAP_GROUP_SEARCH_BASE, naming_context); if (ret != EOK) goto done; } /* Netgroups */ if (!sdom->netgroup_search_bases) { ret = sdap_set_search_base(opts, sdom, SDAP_NETGROUP_SEARCH_BASE, naming_context); if (ret != EOK) goto done; } /* Sudo */ if (!sdom->sudo_search_bases) { ret = sdap_set_search_base(opts, sdom, SDAP_SUDO_SEARCH_BASE, naming_context); if (ret != EOK) goto done; } /* Services */ if (!sdom->service_search_bases) { ret = sdap_set_search_base(opts, sdom, SDAP_SERVICE_SEARCH_BASE, naming_context); if (ret != EOK) goto done; } /* autofs */ if (!sdom->autofs_search_bases) { ret = sdap_set_search_base(opts, sdom, SDAP_AUTOFS_SEARCH_BASE, naming_context); if (ret != EOK) goto done; } ret = EOK; done: talloc_free(naming_context); return ret; } int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx, const char *server, struct sysdb_attrs *rootdse, struct sdap_options *opts, struct sdap_server_opts **srv_opts) { struct sdap_server_opts *so; struct { const char *last_name; const char *entry_name; } usn_attrs[] = { { SDAP_IPA_LAST_USN, SDAP_IPA_USN }, { SDAP_AD_LAST_USN, SDAP_AD_USN }, { NULL, NULL } }; const char *last_usn_name; const char *last_usn_value; const char *entry_usn_name; char *endptr = NULL; int ret; int i; uint32_t dc_level; so = talloc_zero(memctx, struct sdap_server_opts); if (!so) { return ENOMEM; } so->server_id = talloc_strdup(so, server); if (!so->server_id) { talloc_zfree(so); return ENOMEM; } last_usn_name = opts->gen_map[SDAP_AT_LAST_USN].name; entry_usn_name = opts->gen_map[SDAP_AT_ENTRY_USN].name; if (rootdse) { if (last_usn_name) { ret = sysdb_attrs_get_string(rootdse, last_usn_name, &last_usn_value); if (ret != EOK) { switch (ret) { case ENOENT: DEBUG(SSSDBG_CRIT_FAILURE, "%s configured but not found in rootdse!\n", opts->gen_map[SDAP_AT_LAST_USN].opt_name); break; case ERANGE: DEBUG(SSSDBG_CRIT_FAILURE, "Multiple values of %s found in rootdse!\n", opts->gen_map[SDAP_AT_LAST_USN].opt_name); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown error (%d) checking rootdse!\n", ret); } } else { if (!entry_usn_name) { DEBUG(SSSDBG_CRIT_FAILURE, "%s found in rootdse but %s is not set!\n", last_usn_name, opts->gen_map[SDAP_AT_ENTRY_USN].opt_name); } else { so->supports_usn = true; so->last_usn = strtoul(last_usn_value, &endptr, 10); if (endptr != NULL && (*endptr != '\0' || endptr == last_usn_value)) { DEBUG(SSSDBG_MINOR_FAILURE, "USN is not valid (value: %s)\n", last_usn_value); so->last_usn = 0; } else { DEBUG(SSSDBG_TRACE_ALL, "USN value: %s (int: %lu)\n", last_usn_value, so->last_usn); } } } } else { /* no usn option configure, let's try to autodetect. */ for (i = 0; usn_attrs[i].last_name; i++) { ret = sysdb_attrs_get_string(rootdse, usn_attrs[i].last_name, &last_usn_value); if (ret == EOK) { /* Fixate discovered configuration */ opts->gen_map[SDAP_AT_LAST_USN].name = talloc_strdup(opts->gen_map, usn_attrs[i].last_name); opts->gen_map[SDAP_AT_ENTRY_USN].name = talloc_strdup(opts->gen_map, usn_attrs[i].entry_name); so->supports_usn = true; so->last_usn = strtoul(last_usn_value, &endptr, 10); if (endptr != NULL && (*endptr != '\0' || endptr == last_usn_value)) { DEBUG(SSSDBG_MINOR_FAILURE, "USN is not valid (value: %s)\n", last_usn_value); so->last_usn = 0; } else { DEBUG(SSSDBG_TRACE_ALL, "USN value: %s (int: %lu)\n", last_usn_value, so->last_usn); } last_usn_name = usn_attrs[i].last_name; break; } } } /* Detect Active Directory version if available */ ret = sysdb_attrs_get_uint32_t(rootdse, SDAP_ROOTDSE_ATTR_AD_VERSION, &dc_level); if (ret == EOK) { /* Validate that the DC level matches an expected value */ switch(dc_level) { case DS_BEHAVIOR_WIN2000: case DS_BEHAVIOR_WIN2003: case DS_BEHAVIOR_WIN2008: case DS_BEHAVIOR_WIN2008R2: case DS_BEHAVIOR_WIN2012: case DS_BEHAVIOR_WIN2012R2: case DS_BEHAVIOR_WIN2016: opts->dc_functional_level = dc_level; DEBUG(SSSDBG_CONF_SETTINGS, "Setting AD compatibility level to [%d]\n", opts->dc_functional_level); break; default: DEBUG(SSSDBG_MINOR_FAILURE, "Received invalid value [%d] for AD compatibility level. " "Using the lowest-common compatibility level\n", dc_level); opts->dc_functional_level = DS_BEHAVIOR_WIN2003; } } else if (ret != ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "Error detecting Active Directory compatibility level " "(%s). Continuing without AD performance enhancements\n", strerror(ret)); } } if (!last_usn_name) { DEBUG(SSSDBG_FUNC_DATA, "No known USN scheme is supported by this server!\n"); if (!entry_usn_name) { DEBUG(SSSDBG_FUNC_DATA, "Will use modification timestamp as usn!\n"); opts->gen_map[SDAP_AT_ENTRY_USN].name = talloc_strdup(opts->gen_map, "modifyTimestamp"); } } if (!opts->user_map[SDAP_AT_USER_USN].name) { opts->user_map[SDAP_AT_USER_USN].name = talloc_strdup(opts->user_map, opts->gen_map[SDAP_AT_ENTRY_USN].name); } if (!opts->group_map[SDAP_AT_GROUP_USN].name) { opts->group_map[SDAP_AT_GROUP_USN].name = talloc_strdup(opts->group_map, opts->gen_map[SDAP_AT_ENTRY_USN].name); } if (!opts->service_map[SDAP_AT_SERVICE_USN].name) { opts->service_map[SDAP_AT_SERVICE_USN].name = talloc_strdup(opts->service_map, opts->gen_map[SDAP_AT_ENTRY_USN].name); } if (opts->sudorule_map && !opts->sudorule_map[SDAP_AT_SUDO_USN].name) { opts->sudorule_map[SDAP_AT_SUDO_USN].name = talloc_strdup(opts->sudorule_map, opts->gen_map[SDAP_AT_ENTRY_USN].name); } *srv_opts = so; return EOK; } void sdap_steal_server_opts(struct sdap_id_ctx *id_ctx, struct sdap_server_opts **srv_opts) { if (!id_ctx || !srv_opts || !*srv_opts) { return; } if (!id_ctx->srv_opts) { id_ctx->srv_opts = talloc_move(id_ctx, srv_opts); return; } /* discard if same as previous so we do not reset max usn values * unnecessarily */ if (strcmp(id_ctx->srv_opts->server_id, (*srv_opts)->server_id) == 0) { talloc_zfree(*srv_opts); return; } talloc_zfree(id_ctx->srv_opts); id_ctx->srv_opts = talloc_move(id_ctx, srv_opts); } static bool attr_is_filtered(const char *attr, const char **filter) { int i; if (filter) { i = 0; while (filter[i]) { if (filter[i] == attr || strcasecmp(filter[i], attr) == 0) { return true; } i++; } } return false; } int build_attrs_from_map(TALLOC_CTX *memctx, struct sdap_attr_map *map, size_t size, const char **filter, const char ***_attrs, size_t *attr_count) { errno_t ret; const char **attrs; int i, j; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; /* Assume that all entries in the map have values */ attrs = talloc_zero_array(tmp_ctx, const char *, size + 1); if (!attrs) { ret = ENOMEM; goto done; } /* first attribute is "objectclass" not the specifc one */ attrs[0] = talloc_strdup(memctx, "objectClass"); if (!attrs[0]) return ENOMEM; /* add the others */ for (i = j = 1; i < size; i++) { if (map[i].name && !attr_is_filtered(map[i].name, filter)) { attrs[j] = map[i].name; j++; } } attrs[j] = NULL; /* Trim down the used memory if some attributes were NULL */ attrs = talloc_realloc(tmp_ctx, attrs, const char *, j + 1); if (!attrs) { ret = ENOMEM; goto done; } *_attrs = talloc_steal(memctx, attrs); if (attr_count) *attr_count = j; ret = EOK; done: talloc_free(tmp_ctx); return ret; } int sdap_control_create(struct sdap_handle *sh, const char *oid, int iscritical, struct berval *value, int dupval, LDAPControl **ctrlp) { int ret; if (sdap_is_control_supported(sh, oid)) { ret = sss_ldap_control_create(oid, iscritical, value, dupval, ctrlp); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_ldap_control_create failed [%d][%s].\n", ret, sss_ldap_err2string(ret)); } } else { DEBUG(SSSDBG_MINOR_FAILURE, "Server does not support the requested control [%s].\n", oid); ret = LDAP_NOT_SUPPORTED; } return ret; } int sdap_replace_id(struct sysdb_attrs *entry, const char *attr, id_t val) { char *str; errno_t ret; struct ldb_message_element *el; ret = sysdb_attrs_get_el_ext(entry, attr, false, &el); if (ret == ENOENT) { return sysdb_attrs_add_uint32(entry, attr, val); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get attribute [%s]\n", attr); return ret; } if (el->num_values != 1) { DEBUG(SSSDBG_OP_FAILURE, "Expected 1 value for %s, got %d\n", attr, el->num_values); return EINVAL; } str = talloc_asprintf(entry, "%llu", (unsigned long long) val); if (!str) { return ENOMEM; } el->values[0].data = (uint8_t *) str; el->values[0].length = strlen(str); return EOK; } static errno_t sdap_get_primary_name(TALLOC_CTX *memctx, const char *attr_name, struct sysdb_attrs *attrs, struct sss_domain_info *dom, const char **_primary_name) { errno_t ret; const char *orig_name = NULL; char *name; ret = sysdb_attrs_primary_name(dom->sysdb, attrs, attr_name, &orig_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "The object has no name attribute\n"); return EINVAL; } name = sss_get_domain_name(memctx, orig_name, dom); if (name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to format original name [%s]\n", orig_name); return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Processing object %s\n", name); *_primary_name = name; return EOK; } errno_t sdap_get_user_primary_name(TALLOC_CTX *memctx, struct sdap_options *opts, struct sysdb_attrs *attrs, struct sss_domain_info *dom, const char **_user_name) { return sdap_get_primary_name(memctx, opts->user_map[SDAP_AT_USER_NAME].name, attrs, dom, _user_name); } errno_t sdap_get_group_primary_name(TALLOC_CTX *memctx, struct sdap_options *opts, struct sysdb_attrs *attrs, struct sss_domain_info *dom, const char **_group_name) { return sdap_get_primary_name(memctx, opts->group_map[SDAP_AT_GROUP_NAME].name, attrs, dom, _group_name); } errno_t sdap_get_netgroup_primary_name(TALLOC_CTX *memctx, struct sdap_options *opts, struct sysdb_attrs *attrs, struct sss_domain_info *dom, const char **_netgroup_name) { return sdap_get_primary_name(memctx, opts->netgroup_map[SDAP_AT_NETGROUP_NAME].name, attrs, dom, _netgroup_name); } char *sdap_make_oc_list(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map) { if (map[SDAP_OC_GROUP_ALT].name == NULL) { return talloc_asprintf(mem_ctx, "objectClass=%s", map[SDAP_OC_GROUP].name); } else { return talloc_asprintf(mem_ctx, "|(objectClass=%s)(objectClass=%s)", map[SDAP_OC_GROUP].name, map[SDAP_OC_GROUP_ALT].name); } } static bool sdap_object_in_domain(struct sdap_options *opts, struct sysdb_attrs *obj, struct sss_domain_info *dom) { errno_t ret; const char *original_dn = NULL; struct sdap_domain *sdmatch = NULL; ret = sysdb_attrs_get_string(obj, SYSDB_ORIG_DN, &original_dn); if (ret) { DEBUG(SSSDBG_FUNC_DATA, "The group has no original DN, assuming our domain\n"); return true; } sdmatch = sdap_domain_get_by_dn(opts, original_dn); if (sdmatch == NULL) { DEBUG(SSSDBG_FUNC_DATA, "The group has no original DN, assuming our domain\n"); return true; } return (sdmatch->dom == dom); } size_t sdap_steal_objects_in_dom(struct sdap_options *opts, struct sysdb_attrs **dom_objects, size_t offset, struct sss_domain_info *dom, struct sysdb_attrs **all_objects, size_t count, bool filter) { size_t copied = 0; /* Own objects from all_objects by dom_objects in case they belong * to domain dom. * * Don't copy objects from other domains in case * the search was for parent domain but a child domain would match, * too, such as: * dc=example,dc=com * dc=child,dc=example,dc=com * while searching for an object from dc=example. */ for (size_t i = 0; i < count; i++) { if (filter && sdap_object_in_domain(opts, all_objects[i], dom) == false) { continue; } dom_objects[offset + copied] = talloc_steal(dom_objects, all_objects[i]); copied++; } return copied; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_groups_ad.c0000644000000000000000000000007312703456111022403 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.782794063 sssd-1.13.4/src/providers/ldap/sdap_async_groups_ad.c0000644002412700241270000001707712703456111024067 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/ldap_common.h" struct sdap_ad_match_rule_state { struct tevent_context *ev; struct sdap_handle *sh; const char **attrs; struct sdap_options *opts; const char *base_filter; char *filter; int timeout; size_t base_iter; struct sdap_search_base **search_bases; size_t count; struct sysdb_attrs **users; }; static errno_t sdap_get_ad_match_rule_members_next_base(struct tevent_req *req); static void sdap_get_ad_match_rule_members_step(struct tevent_req *subreq); struct tevent_req * sdap_get_ad_match_rule_members_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, struct sysdb_attrs *group, int timeout) { errno_t ret; struct tevent_req *req; struct sdap_ad_match_rule_state *state; const char *group_dn; char *sanitized_group_dn; req = tevent_req_create(mem_ctx, &state, struct sdap_ad_match_rule_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->sh = sh; state->timeout = timeout; state->count = 0; state->base_iter = 0; state->search_bases = opts->sdom->user_search_bases; /* Request all of the user attributes that we know about. */ ret = build_attrs_from_map(state, opts->user_map, opts->user_map_cnt, NULL, &state->attrs, NULL); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not build attribute map: [%s]\n", strerror(ret)); goto immediate; } /* Get the DN of the group */ ret = sysdb_attrs_get_string(group, SYSDB_ORIG_DN, &group_dn); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not retrieve originalDN for group: %s\n", strerror(ret)); goto immediate; } /* Sanitize it in case we have special characters in DN */ ret = sss_filter_sanitize(state, group_dn, &sanitized_group_dn); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not sanitize group DN: %s\n", strerror(ret)); goto immediate; } /* Craft a special filter according to * http://msdn.microsoft.com/en-us/library/windows/desktop/aa746475%28v=vs.85%29.aspx */ state->base_filter = talloc_asprintf(state, "(&(%s:%s:=%s)(objectClass=%s))", state->opts->user_map[SDAP_AT_USER_MEMBEROF].name, SDAP_MATCHING_RULE_IN_CHAIN, sanitized_group_dn, state->opts->user_map[SDAP_OC_USER].name); talloc_zfree(sanitized_group_dn); if (!state->base_filter) { ret = ENOMEM; goto immediate; } /* Start the loop through the search bases to get all of the users */ ret = sdap_get_ad_match_rule_members_next_base(req); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sdap_get_ad_match_rule_members_next_base failed: [%s]\n", strerror(ret)); goto immediate; } return req; immediate: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static errno_t sdap_get_ad_match_rule_members_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_ad_match_rule_state *state; state = tevent_req_data(req, struct sdap_ad_match_rule_state); talloc_zfree(state->filter); state->filter = sdap_combine_filters(state, state->base_filter, state->search_bases[state->base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for users with base [%s]\n", state->search_bases[state->base_iter]->basedn); subreq = sdap_get_generic_send( state, state->ev, state->opts, state->sh, state->search_bases[state->base_iter]->basedn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->user_map, state->opts->user_map_cnt, state->timeout, true); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_get_ad_match_rule_members_step, req); return EOK; } static void sdap_get_ad_match_rule_members_step(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_ad_match_rule_state *state = tevent_req_data(req, struct sdap_ad_match_rule_state); size_t count, i; struct sysdb_attrs **users; ret = sdap_get_generic_recv(subreq, state, &count, &users); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "LDAP search failed: [%s]\n", sss_strerror(ret)); tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_LIBS, "Search for users returned %zu results\n", count); /* Add this batch of users to the list */ if (count > 0) { state->users = talloc_realloc(state, state->users, struct sysdb_attrs *, state->count + count + 1); if (!state->users) { tevent_req_error(req, ENOMEM); return; } /* Copy the new users into the list */ for (i = 0; i < count; i++) { state->users[state->count + i] = talloc_steal(state->users, users[i]); } state->count += count; state->users[state->count] = NULL; } /* Continue checking other search bases */ state->base_iter++; if (state->search_bases[state->base_iter]) { /* There are more search bases to try */ ret = sdap_get_ad_match_rule_members_next_base(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } /* No more search bases. We're done here. */ if (state->count == 0) { DEBUG(SSSDBG_TRACE_LIBS, "No users matched in any search base\n"); tevent_req_error(req, ENOENT); return; } tevent_req_done(req); } errno_t sdap_get_ad_match_rule_members_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *num_users, struct sysdb_attrs ***users) { struct sdap_ad_match_rule_state *state = tevent_req_data(req, struct sdap_ad_match_rule_state); TEVENT_REQ_RETURN_ON_ERROR(req); *num_users = state->count; *users = talloc_steal(mem_ctx, state->users); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async.h0000644000000000000000000000007212703456111020344 xustar0029 atime=1460561751.64871562 29 ctime=1460561774.55179328 sssd-1.13.4/src/providers/ldap/sdap_async.h0000644002412700241270000004413212703456111022021 0ustar00jhrozekjhrozek00000000000000/* SSSD Async LDAP Helper routines Copyright (C) Simo Sorce This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SDAP_ASYNC_H_ #define _SDAP_ASYNC_H_ #include #include #include #include #include "providers/dp_backend.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_id_op.h" #include "providers/fail_over.h" #define AD_TOKENGROUPS_ATTR "tokenGroups" struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, const char *uri, struct sockaddr_storage *sockaddr, bool use_start_tls); int sdap_connect_recv(struct tevent_req *req, TALLOC_CTX *memctx, struct sdap_handle **sh); struct tevent_req *sdap_connect_host_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct resolv_ctx *resolv_ctx, enum restrict_family family_order, enum host_database *host_db, const char *protocol, const char *host, int port, bool use_start_tls); errno_t sdap_connect_host_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct sdap_handle **_sh); /* Search users in LDAP, return them as attrs */ enum sdap_entry_lookup_type { SDAP_LOOKUP_SINGLE, /* Direct single-user/group lookup */ SDAP_LOOKUP_WILDCARD, /* Multiple entries with a limit */ SDAP_LOOKUP_ENUMERATE, /* Fetch all entries from the server */ }; struct tevent_req *sdap_search_user_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sdap_options *opts, struct sdap_search_base **search_bases, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout, enum sdap_entry_lookup_type lookup_type); int sdap_search_user_recv(TALLOC_CTX *memctx, struct tevent_req *req, char **higher_usn, struct sysdb_attrs ***users, size_t *count); /* Search users in LDAP using the request above, save them to cache */ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sysdb_ctx *sysdb, struct sdap_options *opts, struct sdap_search_base **search_bases, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout, enum sdap_entry_lookup_type lookup_type); int sdap_get_users_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **timestamp); struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_domain *sdom, struct sdap_options *opts, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout, enum sdap_entry_lookup_type lookup_type, bool no_members); int sdap_get_groups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **timestamp); struct tevent_req *sdap_get_netgroups_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sysdb_ctx *sysdb, struct sdap_options *opts, struct sdap_search_base **search_bases, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout); int sdap_get_netgroups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **timestamp, size_t *reply_count, struct sysdb_attrs ***reply); struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_handle *sh, const char *sasl_mech, const char *sasl_user, const char *user_dn, struct sss_auth_token *authtok, int simple_bind_timeout); errno_t sdap_auth_recv(struct tevent_req *req, TALLOC_CTX *memctx, struct sdap_ppolicy_data **ppolicy); struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_domain *sdom, struct sdap_handle *sh, struct sdap_id_ctx *id_ctx, struct sdap_id_conn_ctx *conn, const char *name, int name_type, const char *extra_value, const char **grp_attrs); int sdap_get_initgr_recv(struct tevent_req *req); struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_handle *sh, char *user_dn, const char *password, const char *new_password, int timeout); errno_t sdap_exop_modify_passwd_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **user_error_msg); struct tevent_req * sdap_modify_shadow_lastchange_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_handle *sh, const char *dn, char *lastchanged_name); errno_t sdap_modify_shadow_lastchange_recv(struct tevent_req *req); enum connect_tls { CON_TLS_DFL, CON_TLS_ON, CON_TLS_OFF }; struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct be_ctx *be, struct sdap_service *service, bool skip_rootdse, enum connect_tls force_tls, bool skip_auth); int sdap_cli_connect_recv(struct tevent_req *req, TALLOC_CTX *memctx, bool *can_retry, struct sdap_handle **gsh, struct sdap_server_opts **srv_opts); /* Exposes all options of generic send while allowing to parse by map */ struct tevent_req *sdap_get_and_parse_generic_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *search_base, int scope, const char *filter, const char **attrs, struct sdap_attr_map *map, int map_num_attrs, int attrsonly, LDAPControl **serverctrls, LDAPControl **clientctrls, int sizelimit, int timeout, bool allow_paging); int sdap_get_and_parse_generic_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sysdb_attrs ***reply); struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *search_base, int scope, const char *filter, const char **attrs, struct sdap_attr_map *map, int map_num_attrs, int timeout, bool allow_paging); int sdap_get_generic_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sysdb_attrs ***reply_list); bool sdap_has_deref_support(struct sdap_handle *sh, struct sdap_options *opts); enum sdap_deref_flags { SDAP_DEREF_FLG_SILENT = 1 << 0, /* Do not warn if dereference fails */ }; struct tevent_req * sdap_deref_search_with_filter_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *search_base, const char *filter, const char *deref_attr, const char **attrs, int num_maps, struct sdap_attr_map_info *maps, int timeout, unsigned flags); int sdap_deref_search_with_filter_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sdap_deref_attrs ***reply); struct tevent_req * sdap_deref_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *base_dn, const char *deref_attr, const char **attrs, int num_maps, struct sdap_attr_map_info *maps, int timeout); int sdap_deref_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sdap_deref_attrs ***reply); struct tevent_req * sdap_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, struct sdap_search_base **search_bases, int timeout); int sdap_posix_check_recv(struct tevent_req *req, bool *_has_posix); struct tevent_req * sdap_sd_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *base_dn, int sd_flags, const char **attrs, int timeout); int sdap_sd_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *_reply_count, struct sysdb_attrs ***_reply, size_t *_ref_count, char ***_refs); errno_t sdap_attrs_add_ldap_attr(struct sysdb_attrs *ldap_attrs, const char *attr_name, const char *attr_desc, bool multivalued, const char *name, struct sysdb_attrs *attrs); #define sdap_attrs_add_string(ldap_attrs, attr_name, attr_desc, name, attrs) \ sdap_attrs_add_ldap_attr(ldap_attrs, attr_name, attr_desc, \ false, name, attrs) #define sdap_attrs_add_list(ldap_attrs, attr_name, attr_desc, name, attrs) \ sdap_attrs_add_ldap_attr(ldap_attrs, attr_name, attr_desc, \ true, name, attrs) errno_t sdap_save_all_names(const char *name, struct sysdb_attrs *ldap_attrs, struct sss_domain_info *dom, struct sysdb_attrs *attrs); struct tevent_req * sdap_get_services_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sysdb_ctx *sysdb, struct sdap_options *opts, struct sdap_search_base **search_bases, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout, bool enumeration); errno_t sdap_get_services_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **usn_value); struct tevent_req * enum_services_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *id_ctx, struct sdap_id_op *op, bool purge); errno_t enum_services_recv(struct tevent_req *req); /* OID documented in * http://msdn.microsoft.com/en-us/library/windows/desktop/aa746475%28v=vs.85%29.aspx */ #define SDAP_MATCHING_RULE_IN_CHAIN "1.2.840.113556.1.4.1941" struct tevent_req * sdap_get_ad_match_rule_members_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, struct sysdb_attrs *group, int timeout); errno_t sdap_get_ad_match_rule_members_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *num_users, struct sysdb_attrs ***users); struct tevent_req * sdap_get_ad_match_rule_initgroups_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_handle *sh, const char *name, const char *orig_dn, int timeout); errno_t sdap_get_ad_match_rule_initgroups_recv(struct tevent_req *req); struct tevent_req * sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *id_ctx, struct sdap_id_conn_ctx *conn, struct sdap_options *opts, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_handle *sh, const char *name, const char *orig_dn, int timeout, bool use_id_mapping); errno_t sdap_ad_tokengroups_initgroups_recv(struct tevent_req *req); #endif /* _SDAP_ASYNC_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_utils.c0000644000000000000000000000007312703456111020363 xustar0030 atime=1460561751.649715624 29 ctime=1460561774.79679411 sssd-1.13.4/src/providers/ldap/sdap_utils.c0000644002412700241270000001341112703456111022033 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "providers/ldap/sdap_async.h" errno_t sdap_attrs_add_ldap_attr(struct sysdb_attrs *ldap_attrs, const char *attr_name, const char *attr_desc, bool multivalued, const char *name, struct sysdb_attrs *attrs) { errno_t ret; struct ldb_message_element *el; const char *objname = name ?: "object"; const char *desc = attr_desc ?: attr_name; unsigned int num_values, i; char *printable; ret = sysdb_attrs_get_el(ldap_attrs, attr_name, &el); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not get %s from the " "list of the LDAP attributes [%d]: %s\n", attr_name, ret, strerror(ret)); return ret; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "%s is not available " "for [%s].\n", desc, objname); } else { num_values = multivalued ? el->num_values : 1; for (i = 0; i < num_values; i++) { printable = ldb_binary_encode(ldap_attrs, el->values[i]); if (printable == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_binary_encode failed..\n"); continue; } DEBUG(SSSDBG_TRACE_INTERNAL, "Adding %s [%s] to attributes " "of [%s].\n", desc, printable, objname); talloc_zfree(printable); ret = sysdb_attrs_add_mem(attrs, attr_name, el->values[i].data, el->values[i].length); if (ret) { return ret; } } } return EOK; } errno_t sdap_save_all_names(const char *name, struct sysdb_attrs *ldap_attrs, struct sss_domain_info *dom, struct sysdb_attrs *attrs) { const char **aliases = NULL; const char *domname; errno_t ret; TALLOC_CTX *tmp_ctx; int i; bool lowercase = !dom->case_sensitive; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } ret = sysdb_attrs_get_aliases(tmp_ctx, ldap_attrs, name, lowercase, &aliases); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get the alias list\n"); goto done; } for (i = 0; aliases[i]; i++) { domname = sss_get_domain_name(tmp_ctx, aliases[i], dom); if (domname == NULL) { ret = ENOMEM; goto done; } if (lowercase) { ret = sysdb_attrs_add_lc_name_alias(attrs, domname); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to add lower-cased version " "of alias [%s] into the " "attribute list\n", aliases[i]); goto done; } } else { ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, domname); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to add alias [%s] into the " "attribute list\n", aliases[i]); goto done; } } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t deref_string_to_val(const char *str, int *val) { if (strcasecmp(str, "never") == 0) { *val = LDAP_DEREF_NEVER; } else if (strcasecmp(str, "searching") == 0) { *val = LDAP_DEREF_SEARCHING; } else if (strcasecmp(str, "finding") == 0) { *val = LDAP_DEREF_FINDING; } else if (strcasecmp(str, "always") == 0) { *val = LDAP_DEREF_ALWAYS; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Illegal deref option [%s].\n", str); return EINVAL; } return EOK; } static char * sdap_combine_filters_ex(TALLOC_CTX *mem_ctx, char operator, const char *base_filter, const char *extra_filter) { char *filter = NULL; if (extra_filter == NULL || extra_filter[0] == '\0') { return talloc_strdup(mem_ctx, base_filter); } else if (base_filter == NULL || base_filter[0] == '\0') { return talloc_strdup(mem_ctx, extra_filter); } if (extra_filter[0] == '(') { filter = talloc_asprintf(mem_ctx, "(%c%s%s)", operator, base_filter, extra_filter); } else { filter = talloc_asprintf(mem_ctx, "(%c%s(%s))", operator, base_filter, extra_filter); } return filter; /* NULL or not */ } char *sdap_or_filters(TALLOC_CTX *mem_ctx, const char *base_filter, const char *extra_filter) { return sdap_combine_filters_ex(mem_ctx, '|', base_filter, extra_filter); } char *sdap_combine_filters(TALLOC_CTX *mem_ctx, const char *base_filter, const char *extra_filter) { return sdap_combine_filters_ex(mem_ctx, '&', base_filter, extra_filter); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_initgroups_ad.c0000644000000000000000000000007212703456111023266 xustar0029 atime=1460561751.64871562 29 ctime=1460561774.78479407 sssd-1.13.4/src/providers/ldap/sdap_async_initgroups_ad.c0000644002412700241270000014072412703456111024747 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ad/ad_common.h" #include "lib/idmap/sss_idmap.h" struct sdap_ad_match_rule_initgr_state { struct tevent_context *ev; struct sdap_options *opts; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; struct sdap_handle *sh; const char *name; const char *orig_dn; const char **attrs; int timeout; const char *base_filter; char *filter; size_t count; struct sysdb_attrs **groups; size_t base_iter; struct sdap_search_base **search_bases; }; static errno_t sdap_get_ad_match_rule_initgroups_next_base(struct tevent_req *req); static void sdap_get_ad_match_rule_initgroups_step(struct tevent_req *subreq); struct tevent_req * sdap_get_ad_match_rule_initgroups_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_handle *sh, const char *name, const char *orig_dn, int timeout) { errno_t ret; struct tevent_req *req; struct sdap_ad_match_rule_initgr_state *state; const char **filter_members; char *sanitized_user_dn; char *oc_list; req = tevent_req_create(mem_ctx, &state, struct sdap_ad_match_rule_initgr_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->sysdb = sysdb; state->domain = domain; state->sh = sh; state->name = name; state->orig_dn = orig_dn; state->base_iter = 0; state->search_bases = opts->sdom->group_search_bases; /* Request all of the group attributes that we know * about, except for 'member' because that wastes a * lot of bandwidth here and we only really * care about a single member (the one we already * have). */ filter_members = talloc_array(state, const char *, 2); if (!filter_members) { ret = ENOMEM; goto immediate; } filter_members[0] = opts->group_map[SDAP_AT_GROUP_MEMBER].name; filter_members[1] = NULL; ret = build_attrs_from_map(state, opts->group_map, SDAP_OPTS_GROUP, filter_members, &state->attrs, NULL); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not build attribute map: [%s]\n", strerror(ret)); goto immediate; } /* Sanitize the user DN in case we have special characters in DN */ ret = sss_filter_sanitize(state, state->orig_dn, &sanitized_user_dn); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not sanitize user DN: %s\n", strerror(ret)); goto immediate; } /* Craft a special filter according to * http://msdn.microsoft.com/en-us/library/windows/desktop/aa746475%28v=vs.85%29.aspx */ oc_list = sdap_make_oc_list(state, state->opts->group_map); if (oc_list == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n"); ret = ENOMEM; goto immediate; } state->base_filter = talloc_asprintf(state, "(&(%s:%s:=%s)(%s))", state->opts->group_map[SDAP_AT_GROUP_MEMBER].name, SDAP_MATCHING_RULE_IN_CHAIN, sanitized_user_dn, oc_list); talloc_zfree(sanitized_user_dn); if (!state->base_filter) { ret = ENOMEM; goto immediate; } /* Start the loop through the search bases to get all of the * groups to which this user belongs. */ ret = sdap_get_ad_match_rule_initgroups_next_base(req); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sdap_get_ad_match_rule_members_next_base failed: [%s]\n", strerror(ret)); goto immediate; } return req; immediate: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static errno_t sdap_get_ad_match_rule_initgroups_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_ad_match_rule_initgr_state *state; state = tevent_req_data(req, struct sdap_ad_match_rule_initgr_state); talloc_zfree(state->filter); state->filter = sdap_combine_filters(state, state->base_filter, state->search_bases[state->base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for groups with base [%s]\n", state->search_bases[state->base_iter]->basedn); subreq = sdap_get_generic_send( state, state->ev, state->opts, state->sh, state->search_bases[state->base_iter]->basedn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->group_map, SDAP_OPTS_GROUP, state->timeout, true); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_get_ad_match_rule_initgroups_step, req); return EOK; } static void sdap_get_ad_match_rule_initgroups_step(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_ad_match_rule_initgr_state *state = tevent_req_data(req, struct sdap_ad_match_rule_initgr_state); size_t count, i; struct sysdb_attrs **groups; char **sysdb_grouplist; ret = sdap_get_generic_recv(subreq, state, &count, &groups); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "LDAP search failed: [%s]\n", sss_strerror(ret)); goto error; } DEBUG(SSSDBG_TRACE_LIBS, "Search for users returned %zu results\n", count); /* Add this batch of groups to the list */ if (count > 0) { state->groups = talloc_realloc(state, state->groups, struct sysdb_attrs *, state->count + count + 1); if (!state->groups) { tevent_req_error(req, ENOMEM); return; } /* Copy the new groups into the list */ for (i = 0; i < count; i++) { state->groups[state->count + i] = talloc_steal(state->groups, groups[i]); } state->count += count; state->groups[state->count] = NULL; } /* Continue checking other search bases */ state->base_iter++; if (state->search_bases[state->base_iter]) { /* There are more search bases to try */ ret = sdap_get_ad_match_rule_initgroups_next_base(req); if (ret != EOK) { goto error; } return; } /* No more search bases. Save the groups. */ if (state->count == 0) { DEBUG(SSSDBG_TRACE_LIBS, "User is not a member of any group in the search bases\n"); } /* Get the current sysdb group list for this user * so we can update it. */ ret = get_sysdb_grouplist(state, state->sysdb, state->domain, state->name, &sysdb_grouplist); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not get the list of groups for [%s] in the sysdb: " "[%s]\n", state->name, strerror(ret)); goto error; } /* The extensibleMatch search rule eliminates the need for * nested group searches, so we can just update the * memberships now. */ ret = sdap_initgr_common_store(state->sysdb, state->domain, state->opts, state->name, SYSDB_MEMBER_USER, sysdb_grouplist, state->groups, state->count); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not store groups for user [%s]: [%s]\n", state->name, strerror(ret)); goto error; } tevent_req_done(req); return; error: tevent_req_error(req, ret); } errno_t sdap_get_ad_match_rule_initgroups_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct sdap_get_ad_tokengroups_state { struct tevent_context *ev; struct sss_idmap_ctx *idmap_ctx; const char *username; char **sids; size_t num_sids; }; static void sdap_get_ad_tokengroups_done(struct tevent_req *subreq); static struct tevent_req * sdap_get_ad_tokengroups_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *name, const char *orig_dn, int timeout) { struct sdap_get_ad_tokengroups_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; const char *attrs[] = {AD_TOKENGROUPS_ATTR, NULL}; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_get_ad_tokengroups_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->idmap_ctx = opts->idmap_ctx->map; state->ev = ev; state->username = talloc_strdup(state, name); if (state->username == NULL) { ret = ENOMEM; goto immediately; } subreq = sdap_get_generic_send(state, state->ev, opts, sh, orig_dn, LDAP_SCOPE_BASE, NULL, attrs, NULL, 0, timeout, false); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_get_ad_tokengroups_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sdap_get_ad_tokengroups_done(struct tevent_req *subreq) { TALLOC_CTX *tmp_ctx = NULL; struct sdap_get_ad_tokengroups_state *state = NULL; struct tevent_req *req = NULL; struct sysdb_attrs **users = NULL; struct ldb_message_element *el = NULL; enum idmap_error_code err; char *sid_str = NULL; size_t num_users; size_t i; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_get_ad_tokengroups_state); ret = sdap_get_generic_recv(subreq, tmp_ctx, &num_users, &users); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "LDAP search failed: [%s]\n", sss_strerror(ret)); goto done; } if (num_users != 1) { DEBUG(SSSDBG_MINOR_FAILURE, "More than one result on a base search!\n"); ret = EINVAL; goto done; } /* get the list of sids from tokengroups */ ret = sysdb_attrs_get_el_ext(users[0], AD_TOKENGROUPS_ATTR, false, &el); if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_LIBS, "No tokenGroups entries for [%s]\n", state->username); state->sids = NULL; state->num_sids = 0; ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not read tokenGroups attribute: " "[%s]\n", strerror(ret)); goto done; } state->num_sids = 0; state->sids = talloc_zero_array(state, char*, el->num_values); if (state->sids == NULL) { ret = ENOMEM; goto done; } /* convert binary sid to string */ for (i = 0; i < el->num_values; i++) { err = sss_idmap_bin_sid_to_sid(state->idmap_ctx, el->values[i].data, el->values[i].length, &sid_str); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not convert binary SID to string: [%s]. Skipping\n", idmap_error_string(err)); continue; } state->sids[i] = talloc_move(state->sids, &sid_str); state->num_sids++; } /* shrink array to final number of elements */ state->sids = talloc_realloc(state, state->sids, char*, state->num_sids); if (state->sids == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: talloc_free(tmp_ctx); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t sdap_get_ad_tokengroups_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, size_t *_num_sids, char ***_sids) { struct sdap_get_ad_tokengroups_state *state = NULL; state = tevent_req_data(req, struct sdap_get_ad_tokengroups_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_num_sids != NULL) { *_num_sids = state->num_sids; } if (_sids != NULL) { *_sids = talloc_steal(mem_ctx, state->sids); } return EOK; } static errno_t sdap_ad_tokengroups_update_members(const char *username, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, char **ldap_groups) { TALLOC_CTX *tmp_ctx = NULL; char **sysdb_groups = NULL; char **add_groups = NULL; char **del_groups = NULL; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } /* Get the current sysdb group list for this user so we can update it. */ ret = get_sysdb_grouplist_dn(tmp_ctx, sysdb, domain, username, &sysdb_groups); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not get the list of groups for " "[%s] in the sysdb: [%s]\n", username, strerror(ret)); goto done; } /* Find the differences between the sysdb and LDAP lists. * Groups in the sysdb only must be removed. */ ret = diff_string_lists(tmp_ctx, ldap_groups, sysdb_groups, &add_groups, &del_groups, NULL); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Updating memberships for [%s]\n", username); ret = sysdb_update_members_dn(domain, username, SYSDB_MEMBER_USER, (const char *const *) add_groups, (const char *const *) del_groups); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Membership update failed [%d]: %s\n", ret, strerror(ret)); goto done; } done: talloc_free(tmp_ctx); return ret; } struct sdap_ad_resolve_sids_state { struct tevent_context *ev; struct sdap_id_ctx *id_ctx; struct sdap_id_conn_ctx *conn; struct sdap_options *opts; struct sss_domain_info *domain; char **sids; const char *current_sid; int index; }; static errno_t sdap_ad_resolve_sids_step(struct tevent_req *req); static void sdap_ad_resolve_sids_done(struct tevent_req *subreq); static struct tevent_req * sdap_ad_resolve_sids_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *id_ctx, struct sdap_id_conn_ctx *conn, struct sdap_options *opts, struct sss_domain_info *domain, char **sids) { struct sdap_ad_resolve_sids_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_ad_resolve_sids_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->id_ctx = id_ctx; state->conn = conn; state->opts = opts; state->domain = get_domains_head(domain); state->sids = sids; state->index = 0; if (state->sids == NULL || state->sids[0] == NULL) { ret = EOK; goto immediately; } ret = sdap_ad_resolve_sids_step(req); if (ret != EAGAIN) { goto immediately; } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t sdap_ad_resolve_sids_step(struct tevent_req *req) { struct sdap_ad_resolve_sids_state *state = NULL; struct tevent_req *subreq = NULL; struct sdap_domain *sdap_domain = NULL; struct sss_domain_info *domain = NULL; state = tevent_req_data(req, struct sdap_ad_resolve_sids_state); do { state->current_sid = state->sids[state->index]; if (state->current_sid == NULL) { return EOK; } state->index++; domain = sss_get_domain_by_sid_ldap_fallback(state->domain, state->current_sid); if (domain == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "SID %s does not belong to any known " "domain\n", state->current_sid); } } while (domain == NULL); sdap_domain = sdap_domain_get(state->opts, domain); if (sdap_domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "SDAP domain does not exist?\n"); return ERR_INTERNAL; } subreq = groups_get_send(state, state->ev, state->id_ctx, sdap_domain, state->conn, state->current_sid, BE_FILTER_SECID, BE_ATTR_CORE, false, true); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_ad_resolve_sids_done, req); return EAGAIN; } static void sdap_ad_resolve_sids_done(struct tevent_req *subreq) { struct sdap_ad_resolve_sids_state *state = NULL; struct tevent_req *req = NULL; int dp_error; int sdap_error; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_ad_resolve_sids_state); ret = groups_get_recv(subreq, &dp_error, &sdap_error); talloc_zfree(subreq); if (ret == EOK && sdap_error == ENOENT && dp_error == DP_ERR_OK) { /* Group was not found, we will ignore the error and continue with * next group. This may happen for example if the group is built-in, * but a custom search base is provided. */ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to resolve SID %s - will try next sid.\n", state->current_sid); } else if (ret != EOK || sdap_error != EOK || dp_error != DP_ERR_OK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to resolve SID %s [dp_error: %d, " "sdap_error: %d, ret: %d]: %s\n", state->current_sid, dp_error, sdap_error, ret, strerror(ret)); goto done; } ret = sdap_ad_resolve_sids_step(req); if (ret == EAGAIN) { /* continue with next SID */ return; } done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t sdap_ad_resolve_sids_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct sdap_ad_tokengroups_initgr_mapping_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; struct sdap_idmap_ctx *idmap_ctx; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; const char *orig_dn; int timeout; const char *username; struct sdap_id_op *op; }; static void sdap_ad_tokengroups_initgr_mapping_connect_done(struct tevent_req *subreq); static void sdap_ad_tokengroups_initgr_mapping_done(struct tevent_req *subreq); static errno_t handle_missing_pvt(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, const char *orig_dn, int timeout, const char *username, struct sdap_handle *sh, struct tevent_req *req, tevent_req_fn callback); static struct tevent_req * sdap_ad_tokengroups_initgr_mapping_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_handle *sh, const char *name, const char *orig_dn, int timeout) { struct sdap_ad_tokengroups_initgr_mapping_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_domain *sdom; struct ad_id_ctx *subdom_id_ctx; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_ad_tokengroups_initgr_mapping_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->opts = opts; state->sh = sh; state->idmap_ctx = opts->idmap_ctx; state->sysdb = sysdb; state->domain = domain; state->timeout = timeout; state->orig_dn = orig_dn; state->username = talloc_strdup(state, name); if (state->username == NULL) { ret = ENOMEM; goto immediately; } sdom = sdap_domain_get(opts, domain); if (sdom == NULL || sdom->pvt == NULL) { ret = handle_missing_pvt(mem_ctx, ev, opts, orig_dn, timeout, state->username, sh, req, sdap_ad_tokengroups_initgr_mapping_done); if (ret == EOK) { return req; } else { DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n", domain->name); goto immediately; } } subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx); state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto immediately; } subreq = sdap_id_op_connect_send(state->op, state, &ret); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_mapping_connect_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sdap_ad_tokengroups_initgr_mapping_connect_done(struct tevent_req *subreq) { struct sdap_ad_tokengroups_initgr_mapping_state *state = NULL; struct tevent_req *req = NULL; int ret; int dp_error = DP_ERR_FATAL; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_ad_tokengroups_initgr_mapping_state); ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } subreq = sdap_get_ad_tokengroups_send(state, state->ev, state->opts, sdap_id_op_handle(state->op), state->username, state->orig_dn, state->timeout); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_mapping_done, req); return; } static void sdap_ad_tokengroups_initgr_mapping_done(struct tevent_req *subreq) { TALLOC_CTX *tmp_ctx = NULL; struct sdap_ad_tokengroups_initgr_mapping_state *state = NULL; struct tevent_req *req = NULL; struct sss_domain_info *domain = NULL; struct ldb_message *msg = NULL; const char *attrs[] = {SYSDB_NAME, NULL}; const char *name = NULL; const char *sid = NULL; char **sids = NULL; size_t num_sids = 0; size_t i; time_t now; gid_t gid; char **groups = NULL; size_t num_groups; errno_t ret, sret; bool in_transaction = false; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); ret = ENOMEM; goto done; } req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_ad_tokengroups_initgr_mapping_state); ret = sdap_get_ad_tokengroups_recv(state, subreq, &num_sids, &sids); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to acquire tokengroups [%d]: %s\n", ret, strerror(ret)); goto done; } num_groups = 0; groups = talloc_zero_array(tmp_ctx, char*, num_sids + 1); if (groups == NULL) { ret = ENOMEM; goto done; } now = time(NULL); ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { goto done; } in_transaction = true; for (i = 0; i < num_sids; i++) { sid = sids[i]; DEBUG(SSSDBG_TRACE_LIBS, "Processing membership SID [%s]\n", sid); ret = sdap_idmap_sid_to_unix(state->idmap_ctx, sid, &gid); if (ret == ENOTSUP) { DEBUG(SSSDBG_TRACE_FUNC, "Skipping built-in object.\n"); continue; } else if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not convert SID to GID: [%s]. " "Skipping\n", strerror(ret)); continue; } domain = sss_get_domain_by_sid_ldap_fallback(state->domain, sid); if (domain == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Domain not found for SID %s\n", sid); continue; } DEBUG(SSSDBG_TRACE_LIBS, "SID [%s] maps to GID [%"SPRIgid"]\n", sid, gid); /* Check whether this GID already exists in the sysdb */ ret = sysdb_search_group_by_gid(tmp_ctx, domain, gid, attrs, &msg); if (ret == EOK) { name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not retrieve group name from sysdb\n"); ret = EINVAL; goto done; } } else if (ret == ENOENT) { /* This is a new group. For now, we will store it under the name * of its SID. When a direct lookup of the group or its GID occurs, * it will replace this temporary entry. */ name = sid; ret = sysdb_add_incomplete_group(domain, name, gid, NULL, sid, NULL, false, now); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not create incomplete " "group: [%s]\n", strerror(ret)); goto done; } } else { /* Unexpected error */ DEBUG(SSSDBG_MINOR_FAILURE, "Could not look up group in sysdb: " "[%s]\n", strerror(ret)); goto done; } groups[num_groups] = sysdb_group_strdn(tmp_ctx, domain->name, name); if (groups[num_groups] == NULL) { ret = ENOMEM; goto done; } num_groups++; } groups[num_groups] = NULL; ret = sdap_ad_tokengroups_update_members(state->username, state->sysdb, state->domain, groups); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Membership update failed [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_transaction_commit(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not commit transaction! [%s]\n", strerror(ret)); goto done; } in_transaction = false; done: talloc_free(tmp_ctx); if (in_transaction) { sret = sysdb_transaction_cancel(state->sysdb); DEBUG(SSSDBG_FATAL_FAILURE, "Could not cancel transaction! [%s]\n", strerror(sret)); } if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static int sdap_ad_tokengroups_initgr_mapping_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct sdap_ad_tokengroups_initgr_posix_state { struct tevent_context *ev; struct sdap_id_ctx *id_ctx; struct sdap_id_conn_ctx *conn; struct sdap_options *opts; struct sdap_handle *sh; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; const char *orig_dn; int timeout; const char *username; struct sdap_id_op *op; char **missing_sids; size_t num_missing_sids; char **cached_groups; size_t num_cached_groups; }; static void sdap_ad_tokengroups_initgr_posix_tg_done(struct tevent_req *subreq); static void sdap_ad_tokengroups_initgr_posix_sids_connect_done(struct tevent_req *subreq); static void sdap_ad_tokengroups_initgr_posix_sids_done(struct tevent_req *subreq); static struct tevent_req * sdap_ad_tokengroups_initgr_posix_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *id_ctx, struct sdap_id_conn_ctx *conn, struct sdap_options *opts, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_handle *sh, const char *name, const char *orig_dn, int timeout) { struct sdap_ad_tokengroups_initgr_posix_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_domain *sdom; struct ad_id_ctx *subdom_id_ctx; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_ad_tokengroups_initgr_posix_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->id_ctx = id_ctx; state->conn = conn; state->opts = opts; state->sh = sh; state->sysdb = sysdb; state->domain = domain; state->orig_dn = orig_dn; state->timeout = timeout; state->username = talloc_strdup(state, name); if (state->username == NULL) { ret = ENOMEM; goto immediately; } sdom = sdap_domain_get(opts, domain); if (sdom == NULL || sdom->pvt == NULL) { ret = handle_missing_pvt(mem_ctx, ev, opts, orig_dn, timeout, state->username, sh, req, sdap_ad_tokengroups_initgr_posix_tg_done); if (ret == EOK) { return req; } else { DEBUG(SSSDBG_CRIT_FAILURE, "No ID ctx available for [%s].\n", domain->name); goto immediately; } } subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx); state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto immediately; } subreq = sdap_id_op_connect_send(state->op, state, &ret); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_posix_sids_connect_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sdap_ad_tokengroups_initgr_posix_sids_connect_done(struct tevent_req *subreq) { struct sdap_ad_tokengroups_initgr_posix_state *state = NULL; struct tevent_req *req = NULL; int ret; int dp_error = DP_ERR_FATAL; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_ad_tokengroups_initgr_posix_state); ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } subreq = sdap_get_ad_tokengroups_send(state, state->ev, state->opts, sdap_id_op_handle(state->op), state->username, state->orig_dn, state->timeout); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_posix_tg_done, req); return; } static errno_t sdap_ad_tokengroups_get_posix_members(TALLOC_CTX *mem_ctx, struct sdap_ad_tokengroups_initgr_posix_state *state, size_t num_sids, char **sids, size_t *_num_missing, char ***_missing, size_t *_num_valid, char ***_valid_groups) { TALLOC_CTX *tmp_ctx = NULL; struct sss_domain_info *domain = NULL; struct ldb_message *msg = NULL; const char *attrs[] = {SYSDB_NAME, NULL}; const char *name = NULL; char *sid = NULL; char **valid_groups = NULL; size_t num_valid_groups; char **missing_sids = NULL; size_t num_missing_sids; size_t i; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); ret = ENOMEM; goto done; } num_valid_groups = 0; valid_groups = talloc_zero_array(tmp_ctx, char*, num_sids + 1); if (valid_groups == NULL) { ret = ENOMEM; goto done; } num_missing_sids = 0; missing_sids = talloc_zero_array(tmp_ctx, char*, num_sids + 1); if (missing_sids == NULL) { ret = ENOMEM; goto done; } /* For each SID check if it is already present in the cache. If yes, we * will get name of the group and update the membership. Otherwise we need * to remember the SID and download missing groups one by one. */ for (i = 0; i < num_sids; i++) { sid = sids[i]; DEBUG(SSSDBG_TRACE_LIBS, "Processing membership SID [%s]\n", sid); domain = sss_get_domain_by_sid_ldap_fallback(state->domain, sid); if (domain == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Domain not found for SID %s\n", sid); continue; } ret = sysdb_search_group_by_sid_str(tmp_ctx, domain, sid, attrs, &msg); if (ret == EOK) { /* we will update membership of this group */ name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not retrieve group name from sysdb\n"); ret = EINVAL; goto done; } valid_groups[num_valid_groups] = sysdb_group_strdn(valid_groups, domain->name, name); if (valid_groups[num_valid_groups] == NULL) { ret = ENOMEM; goto done; } num_valid_groups++; } else if (ret == ENOENT) { if (_missing != NULL) { /* we need to download this group */ missing_sids[num_missing_sids] = talloc_steal(missing_sids, sid); num_missing_sids++; DEBUG(SSSDBG_TRACE_FUNC, "Missing SID %s will be downloaded\n", sid); } /* else: We have downloaded missing groups but some of them may * remained missing because they are outside of search base. We * will just ignore them and continue with the next group. */ } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not look up SID %s in sysdb: " "[%s]\n", sid, strerror(ret)); goto done; } } valid_groups[num_valid_groups] = NULL; missing_sids[num_missing_sids] = NULL; /* return list of missing groups */ if (_missing != NULL) { *_missing = talloc_steal(mem_ctx, missing_sids); *_num_missing = num_missing_sids; } /* return list of missing groups */ if (_valid_groups != NULL) { *_valid_groups = talloc_steal(mem_ctx, valid_groups); *_num_valid = num_valid_groups; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static void sdap_ad_tokengroups_initgr_posix_tg_done(struct tevent_req *subreq) { struct sdap_ad_tokengroups_initgr_posix_state *state = NULL; struct tevent_req *req = NULL; char **sids = NULL; size_t num_sids = 0; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_ad_tokengroups_initgr_posix_state); ret = sdap_get_ad_tokengroups_recv(state, subreq, &num_sids, &sids); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to acquire tokengroups [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sdap_ad_tokengroups_get_posix_members(state, state, num_sids, sids, &state->num_missing_sids, &state->missing_sids, &state->num_cached_groups, &state->cached_groups); if (ret != EOK) { goto done; } /* download missing SIDs */ subreq = sdap_ad_resolve_sids_send(state, state->ev, state->id_ctx, state->conn, state->opts, state->domain, state->missing_sids); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgr_posix_sids_done, req); return; done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static char **concatenate_string_array(TALLOC_CTX *mem_ctx, char **arr1, size_t len1, char **arr2, size_t len2); static void sdap_ad_tokengroups_initgr_posix_sids_done(struct tevent_req *subreq) { struct sdap_ad_tokengroups_initgr_posix_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; char **cached_groups; size_t num_cached_groups; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_ad_tokengroups_initgr_posix_state); ret = sdap_ad_resolve_sids_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to resolve missing SIDs " "[%d]: %s\n", ret, strerror(ret)); goto done; } ret = sdap_ad_tokengroups_get_posix_members(state, state, state->num_missing_sids, state->missing_sids, NULL, NULL, &num_cached_groups, &cached_groups); if (ret != EOK){ DEBUG(SSSDBG_MINOR_FAILURE, "sdap_ad_tokengroups_get_posix_members failed [%d]: %s\n", ret, strerror(ret)); goto done; } state->cached_groups = concatenate_string_array(state, state->cached_groups, state->num_cached_groups, cached_groups, num_cached_groups); if (state->cached_groups == NULL) { ret = ENOMEM; goto done; } /* update membership of existing groups */ ret = sdap_ad_tokengroups_update_members(state->username, state->sysdb, state->domain, state->cached_groups); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Membership update failed [%d]: %s\n", ret, strerror(ret)); goto done; } done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static char **concatenate_string_array(TALLOC_CTX *mem_ctx, char **arr1, size_t len1, char **arr2, size_t len2) { size_t i, j; size_t new_size = len1 + len2; char ** string_array = talloc_realloc(mem_ctx, arr1, char *, new_size + 1); if (string_array == NULL) { return NULL; } for (i=len1, j=0; i < new_size; ++i,++j) { string_array[i] = talloc_steal(string_array, arr2[j]); } string_array[i] = NULL; return string_array; } static errno_t sdap_ad_tokengroups_initgr_posix_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct sdap_ad_tokengroups_initgroups_state { bool use_id_mapping; struct sss_domain_info *domain; }; static void sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq); struct tevent_req * sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *id_ctx, struct sdap_id_conn_ctx *conn, struct sdap_options *opts, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_handle *sh, const char *name, const char *orig_dn, int timeout, bool use_id_mapping) { struct sdap_ad_tokengroups_initgroups_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_ad_tokengroups_initgroups_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->use_id_mapping = use_id_mapping; state->domain = domain; /* We can compute the gidNumber attribute from SIDs obtained from * the tokenGroups lookup in case ID mapping is used for a user from the * parent domain. For trusted domains, we need to know the group type * to be able to filter out domain-local groups. Additionally, as a * temporary workaround until https://fedorahosted.org/sssd/ticket/2656 * is fixed, we also fetch the group object if group members are ignored * to avoid having to transfer and retain members when the fake * tokengroups object without name is replaced by the full group object */ if (state->use_id_mapping && !IS_SUBDOMAIN(state->domain) && state->domain->ignore_group_members == false) { subreq = sdap_ad_tokengroups_initgr_mapping_send(state, ev, opts, sysdb, domain, sh, name, orig_dn, timeout); } else { subreq = sdap_ad_tokengroups_initgr_posix_send(state, ev, id_ctx, conn, opts, sysdb, domain, sh, name, orig_dn, timeout); } if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_ad_tokengroups_initgroups_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq) { struct sdap_ad_tokengroups_initgroups_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_ad_tokengroups_initgroups_state); if (state->use_id_mapping && !IS_SUBDOMAIN(state->domain) && state->domain->ignore_group_members == false) { ret = sdap_ad_tokengroups_initgr_mapping_recv(subreq); } else { ret = sdap_ad_tokengroups_initgr_posix_recv(subreq); } talloc_zfree(subreq); if (ret != EOK) { goto done; } done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } errno_t sdap_ad_tokengroups_initgroups_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static errno_t handle_missing_pvt(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, const char *orig_dn, int timeout, const char *username, struct sdap_handle *sh, struct tevent_req *req, tevent_req_fn callback) { struct tevent_req *subreq = NULL; errno_t ret; if (sh != NULL) { /* plain LDAP provider already has a sdap_handle */ subreq = sdap_get_ad_tokengroups_send(mem_ctx, ev, opts, sh, username, orig_dn, timeout); if (subreq == NULL) { ret = ENOMEM; tevent_req_error(req, ret); goto done; } tevent_req_set_callback(subreq, callback, req); ret = EOK; goto done; } else { ret = EINVAL; goto done; } done: return ret; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_dyndns.h0000644000000000000000000000007212703456111020526 xustar0029 atime=1460561751.64871562 29 ctime=1460561774.56079331 sssd-1.13.4/src/providers/ldap/sdap_dyndns.h0000644002412700241270000000424312703456111022202 0ustar00jhrozekjhrozek00000000000000/* SSSD sdap_dyndns.h: LDAP specific dynamic DNS update Authors: Jakub Hrozek Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SDAP_DYNDNS_H_ #define SDAP_DYNDNS_H_ #include "util/util.h" #include "providers/dp_backend.h" #include "providers/dp_dyndns.h" #include "providers/ldap/ldap_common.h" struct tevent_req * sdap_dyndns_update_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct dp_option *opts, struct sdap_id_ctx *sdap_ctx, enum be_nsupdate_auth auth_type, const char *ifname, const char *hostname, const char *realm, const char *servername, const int ttl, bool check_diff); errno_t sdap_dyndns_update_recv(struct tevent_req *req); /* Connects to the LDAP server in order to read the address from the * socket and be able to perform dynamic DNS updates. Reschedules the * task automatically on errors and sets/resets the timer_in_progress * guard in be_nsupdate_ctx. */ struct tevent_req * sdap_dyndns_timer_conn_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_ctx, struct be_nsupdate_ctx *dyndns_ctx); errno_t sdap_dyndns_timer_conn_recv(struct tevent_req *req); #endif /* SDAP_DYNDNS_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_common.h0000644000000000000000000000007412703456111020512 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.547793266 sssd-1.13.4/src/providers/ldap/ldap_common.h0000644002412700241270000002762112703456111022171 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Common utility code Copyright (C) Simo Sorce 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _LDAP_COMMON_H_ #define _LDAP_COMMON_H_ #include "providers/dp_backend.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_id_op.h" #include "providers/fail_over.h" #include "providers/krb5/krb5_common.h" #include "lib/idmap/sss_idmap.h" #define PWD_POL_OPT_NONE "none" #define PWD_POL_OPT_SHADOW "shadow" #define PWD_POL_OPT_MIT "mit_kerberos" #define SSS_LDAP_SRV_NAME "ldap" #define LDAP_STANDARD_URI "ldap://" #define LDAP_SSL_URI "ldaps://" #define LDAP_LDAPI_URI "ldapi://" /* Only the asterisk is allowed in wildcard requests */ #define LDAP_ALLOWED_WILDCARDS "*" /* a fd the child process would log into */ extern int ldap_child_debug_fd; struct sdap_id_ctx; struct sdap_id_conn_ctx { struct sdap_id_ctx *id_ctx; struct sdap_service *service; /* LDAP connection cache */ struct sdap_id_conn_cache *conn_cache; /* dlinklist pointers */ struct sdap_id_conn_ctx *prev, *next; /* do not go offline, try another connection */ bool ignore_mark_offline; }; struct sdap_id_ctx { struct be_ctx *be; struct sdap_options *opts; /* If using GSSAPI */ struct krb5_service *krb5_service; /* connection to a server */ struct sdap_id_conn_ctx *conn; struct sdap_server_opts *srv_opts; }; struct sdap_auth_ctx { struct be_ctx *be; struct sdap_options *opts; struct sdap_service *service; struct sdap_service *chpass_service; }; int sssm_ldap_id_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data); void sdap_check_online(struct be_req *breq); void sdap_do_online_check(struct be_req *be_req, struct sdap_id_ctx *ctx); struct tevent_req* sdap_reinit_cleanup_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct sdap_id_ctx *id_ctx); errno_t sdap_reinit_cleanup_recv(struct tevent_req *req); /* id */ void sdap_account_info_handler(struct be_req *breq); void sdap_handle_account_info(struct be_req *breq, struct sdap_id_ctx *ctx, struct sdap_id_conn_ctx *conn); /* Set up enumeration and/or cleanup */ int ldap_id_setup_tasks(struct sdap_id_ctx *ctx); int sdap_id_setup_tasks(struct be_ctx *be_ctx, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, be_ptask_send_t send_fn, be_ptask_recv_t recv_fn, void *pvt); /* Allow shortcutting an enumeration request */ bool sdap_is_enum_request(struct be_acct_req *ar); struct tevent_req * sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct be_acct_req *ar, struct sdap_id_ctx *id_ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, bool noexist_delete); errno_t sdap_handle_acct_req_recv(struct tevent_req *req, int *_dp_error, const char **_err, int *sdap_ret); /* auth */ void sdap_pam_auth_handler(struct be_req *breq); /* chpass */ void sdap_pam_chpass_handler(struct be_req *breq); /* access */ void sdap_pam_access_handler(struct be_req *breq); /* autofs */ void sdap_autofs_handler(struct be_req *breq); void sdap_handler_done(struct be_req *req, int dp_err, int error, const char *errstr); int sdap_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, const char *service_name, const char *dns_service_name, const char *urls, const char *backup_urls, struct sdap_service **_service); const char *sdap_gssapi_realm(struct dp_option *opts); int sdap_gssapi_init(TALLOC_CTX *mem_ctx, struct dp_option *opts, struct be_ctx *bectx, struct sdap_service *sdap_service, struct krb5_service **krb5_service); errno_t sdap_install_offline_callback(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, const char *realm, const char *service_name); errno_t sdap_install_sigterm_handler(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *realm); void sdap_remove_kdcinfo_files_callback(void *pvt); /* options parser */ int ldap_get_options(TALLOC_CTX *memctx, struct sss_domain_info *dom, struct confdb_ctx *cdb, const char *conf_path, struct sdap_options **_opts); int ldap_get_sudo_options(struct confdb_ctx *cdb, const char *conf_path, struct sdap_options *opts, bool *use_host_filter, bool *include_regexp, bool *include_netgroups); int ldap_get_autofs_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, struct sdap_options *opts); /* Calling ldap_setup_enumeration will set up a periodic task * that would periodically call send_fn/recv_fn request. The * send_fn's pvt parameter will be a pointer to ldap_enum_ctx * structure that contains the request data */ struct ldap_enum_ctx { struct sdap_domain *sdom; void *pvt; }; errno_t ldap_setup_enumeration(struct be_ctx *be_ctx, struct sdap_options *opts, struct sdap_domain *sdom, be_ptask_send_t send_fn, be_ptask_recv_t recv_fn, void *pvt); struct tevent_req * ldap_enumeration_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt); errno_t ldap_enumeration_recv(struct tevent_req *req); errno_t ldap_setup_cleanup(struct sdap_id_ctx *id_ctx, struct sdap_domain *sdom); errno_t ldap_id_cleanup(struct sdap_options *opts, struct sdap_domain *sdom); struct tevent_req *groups_get_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, const char *name, int filter_type, int attrs_type, bool noexist_delete, bool no_members); int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret); struct tevent_req *ldap_netgroup_get_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, const char *name, bool noexist_delete); int ldap_netgroup_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret); struct tevent_req * services_get_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *id_ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, const char *name, const char *protocol, int filter_type, bool noexist_delete); errno_t services_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret); /* setup child logging */ int sdap_setup_child(void); errno_t string_to_shadowpw_days(const char *s, long *d); errno_t get_sysdb_attr_name(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, size_t map_size, const char *ldap_name, char **sysdb_name); errno_t list_missing_attrs(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, size_t map_size, struct sysdb_attrs *recvd_attrs, char ***missing_attrs); bool sdap_is_secure_uri(const char *uri); char *sdap_or_filters(TALLOC_CTX *mem_ctx, const char *base_filter, const char *extra_filter); char *sdap_combine_filters(TALLOC_CTX *mem_ctx, const char *base_filter, const char *extra_filter); char *sdap_get_access_filter(TALLOC_CTX *mem_ctx, const char *base_filter); errno_t msgs2attrs_array(TALLOC_CTX *mem_ctx, size_t count, struct ldb_message **msgs, struct sysdb_attrs ***attrs); errno_t sdap_domain_add(struct sdap_options *opts, struct sss_domain_info *dom, struct sdap_domain **_sdom); errno_t sdap_domain_subdom_add(struct sdap_id_ctx *sdap_id_ctx, struct sdap_domain *sdom_list, struct sss_domain_info *parent); void sdap_domain_remove(struct sdap_options *opts, struct sss_domain_info *dom); struct sdap_domain *sdap_domain_get(struct sdap_options *opts, struct sss_domain_info *dom); struct sdap_domain *sdap_domain_get_by_dn(struct sdap_options *opts, const char *dn); errno_t sdap_parse_search_base(TALLOC_CTX *mem_ctx, struct dp_option *opts, int class, struct sdap_search_base ***_search_bases); errno_t common_parse_search_base(TALLOC_CTX *mem_ctx, const char *unparsed_base, const char *class_name, const char *old_filter, struct sdap_search_base ***_search_bases); errno_t sdap_attrs_get_sid_str(TALLOC_CTX *mem_ctx, struct sdap_idmap_ctx *idmap_ctx, struct sysdb_attrs *sysdb_attrs, const char *sid_attr, char **_sid_str); errno_t sdap_set_sasl_options(struct sdap_options *id_opts, char *default_primary, char *default_realm, const char *keytab_path); struct sdap_id_conn_ctx * sdap_id_ctx_conn_add(struct sdap_id_ctx *id_ctx, struct sdap_service *sdap_service); struct sdap_id_ctx * sdap_id_ctx_new(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, struct sdap_service *sdap_service); errno_t sdap_refresh_init(struct be_refresh_ctx *refresh_ctx, struct sdap_id_ctx *id_ctx); #endif /* _LDAP_COMMON_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_id.c0000644000000000000000000000007412703456111017611 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.769794019 sssd-1.13.4/src/providers/ldap/ldap_id.c0000644002412700241270000017573512703456111021302 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Identity Backend Module Authors: Simo Sorce Copyright (C) 2008 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "util/strtonum.h" #include "util/cert.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ldap/sdap_users.h" #include "providers/ad/ad_common.h" /* =Users-Related-Functions-(by-name,by-uid)============================== */ struct users_get_state { struct tevent_context *ev; struct sdap_id_ctx *ctx; struct sdap_domain *sdom; struct sdap_id_conn_ctx *conn; struct sdap_id_op *op; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; const char *name; int filter_type; char *filter; const char **attrs; bool use_id_mapping; int dp_error; int sdap_ret; bool noexist_delete; }; static int users_get_retry(struct tevent_req *req); static void users_get_connect_done(struct tevent_req *subreq); static void users_get_posix_check_done(struct tevent_req *subreq); static void users_get_search(struct tevent_req *req); static void users_get_done(struct tevent_req *subreq); struct tevent_req *users_get_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, const char *name, int filter_type, const char *extra_value, int attrs_type, bool noexist_delete) { struct tevent_req *req; struct users_get_state *state; const char *attr_name = NULL; char *clean_name = NULL; char *endptr; int ret; uid_t uid; enum idmap_error_code err; char *sid; char *user_filter = NULL; req = tevent_req_create(memctx, &state, struct users_get_state); if (!req) return NULL; state->ev = ev; state->ctx = ctx; state->sdom = sdom; state->conn = conn; state->dp_error = DP_ERR_FATAL; state->noexist_delete = noexist_delete; state->op = sdap_id_op_create(state, state->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto done; } state->domain = sdom->dom; state->sysdb = sdom->dom->sysdb; state->name = name; state->filter_type = filter_type; state->use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( ctx->opts->idmap_ctx, sdom->dom->name, sdom->dom->domain_id); switch (filter_type) { case BE_FILTER_WILDCARD: attr_name = ctx->opts->user_map[SDAP_AT_USER_NAME].name; ret = sss_filter_sanitize_ex(state, name, &clean_name, LDAP_ALLOWED_WILDCARDS); if (ret != EOK) { goto done; } break; case BE_FILTER_NAME: if (extra_value && strcmp(extra_value, EXTRA_NAME_IS_UPN) == 0) { attr_name = ctx->opts->user_map[SDAP_AT_USER_PRINC].name; } else { attr_name = ctx->opts->user_map[SDAP_AT_USER_NAME].name; } ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { goto done; } break; case BE_FILTER_IDNUM: if (state->use_id_mapping) { /* If we're ID-mapping, we need to use the objectSID * in the search filter. */ uid = strtouint32(name, &endptr, 10); if (errno != EOK) { ret = EINVAL; goto done; } /* Convert the UID to its objectSID */ err = sss_idmap_unix_to_sid(ctx->opts->idmap_ctx->map, uid, &sid); if (err == IDMAP_NO_DOMAIN) { DEBUG(SSSDBG_MINOR_FAILURE, "[%s] did not match any configured ID mapping domain\n", name); ret = sysdb_delete_user(state->domain, NULL, uid); if (ret == ENOENT) { /* Ignore errors to remove users that were not cached previously */ ret = EOK; } goto done; } else if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Mapping ID [%s] to SID failed: [%s]\n", name, idmap_error_string(err)); ret = EIO; goto done; } attr_name = ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name; ret = sss_filter_sanitize(state, sid, &clean_name); sss_idmap_free_sid(ctx->opts->idmap_ctx->map, sid); if (ret != EOK) { goto done; } } else { attr_name = ctx->opts->user_map[SDAP_AT_USER_UID].name; ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { goto done; } } break; case BE_FILTER_SECID: attr_name = ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name; ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { goto done; } break; case BE_FILTER_UUID: attr_name = ctx->opts->user_map[SDAP_AT_USER_UUID].name; if (attr_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "UUID search not configured for this backend.\n"); ret = EINVAL; goto done; } ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { goto done; } break; case BE_FILTER_CERT: attr_name = ctx->opts->user_map[SDAP_AT_USER_CERT].name; if (attr_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Certificate search not configured for this backend.\n"); ret = EINVAL; goto done; } ret = sss_cert_derb64_to_ldap_filter(state, name, attr_name, &user_filter); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n"); goto done; } break; default: ret = EINVAL; goto done; } if (attr_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing search attribute name.\n"); ret = EINVAL; goto done; } if (user_filter == NULL) { user_filter = talloc_asprintf(state, "(%s=%s)", attr_name, clean_name); talloc_free(clean_name); if (user_filter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } } if (state->use_id_mapping || filter_type == BE_FILTER_SECID) { /* When mapping IDs or looking for SIDs, we don't want to limit * ourselves to users with a UID value. But there must be a SID to map * from. */ state->filter = talloc_asprintf(state, "(&%s(objectclass=%s)(%s=*)(%s=*))", user_filter, ctx->opts->user_map[SDAP_OC_USER].name, ctx->opts->user_map[SDAP_AT_USER_NAME].name, ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name); } else { /* When not ID-mapping, make sure there is a non-NULL UID */ state->filter = talloc_asprintf(state, "(&%s(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))", user_filter, ctx->opts->user_map[SDAP_OC_USER].name, ctx->opts->user_map[SDAP_AT_USER_NAME].name, ctx->opts->user_map[SDAP_AT_USER_UID].name, ctx->opts->user_map[SDAP_AT_USER_UID].name); } talloc_zfree(user_filter); if (!state->filter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build the base filter\n"); ret = ENOMEM; goto done; } /* TODO: handle attrs_type */ ret = build_attrs_from_map(state, ctx->opts->user_map, ctx->opts->user_map_cnt, NULL, &state->attrs, NULL); if (ret != EOK) goto done; ret = users_get_retry(req); if (ret != EOK) { goto done; } return req; done: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } return tevent_req_post(req, ev); } static int users_get_retry(struct tevent_req *req) { struct users_get_state *state = tevent_req_data(req, struct users_get_state); struct tevent_req *subreq; int ret = EOK; subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { return ret; } tevent_req_set_callback(subreq, users_get_connect_done, req); return EOK; } static void users_get_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct users_get_state *state = tevent_req_data(req, struct users_get_state); int dp_error = DP_ERR_FATAL; int ret; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } /* If POSIX attributes have been requested with an AD server and we * have no idea about POSIX attributes support, run a one-time check */ if (state->use_id_mapping == false && state->ctx->opts->schema_type == SDAP_SCHEMA_AD && state->ctx->srv_opts && state->ctx->srv_opts->posix_checked == false) { subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, sdap_id_op_handle(state->op), state->sdom->user_search_bases, dp_opt_get_int(state->ctx->opts->basic, SDAP_SEARCH_TIMEOUT)); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, users_get_posix_check_done, req); return; } users_get_search(req); } static void users_get_posix_check_done(struct tevent_req *subreq) { errno_t ret; errno_t ret2; bool has_posix; int dp_error; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct users_get_state *state = tevent_req_data(req, struct users_get_state); ret = sdap_posix_check_recv(subreq, &has_posix); talloc_zfree(subreq); if (ret != EOK) { /* We can only finish the id_op on error as the connection * is re-used by the user search */ ret2 = sdap_id_op_done(state->op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret2 != EOK) { /* retry */ ret = users_get_retry(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } } state->ctx->srv_opts->posix_checked = true; /* If the check ran to completion, we know for certain about the attributes */ if (ret == EOK && has_posix == false) { state->sdap_ret = ERR_NO_POSIX; tevent_req_done(req); return; } users_get_search(req); } static void users_get_search(struct tevent_req *req) { struct users_get_state *state = tevent_req_data(req, struct users_get_state); struct tevent_req *subreq; enum sdap_entry_lookup_type lookup_type; if (state->filter_type == BE_FILTER_WILDCARD) { lookup_type = SDAP_LOOKUP_WILDCARD; } else { lookup_type = SDAP_LOOKUP_SINGLE; } subreq = sdap_get_users_send(state, state->ev, state->domain, state->sysdb, state->ctx->opts, state->sdom->user_search_bases, sdap_id_op_handle(state->op), state->attrs, state->filter, dp_opt_get_int(state->ctx->opts->basic, SDAP_SEARCH_TIMEOUT), lookup_type); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, users_get_done, req); } static void users_get_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct users_get_state *state = tevent_req_data(req, struct users_get_state); char *endptr; uid_t uid; int dp_error = DP_ERR_FATAL; int ret; ret = sdap_get_users_recv(subreq, NULL, NULL); talloc_zfree(subreq); ret = sdap_id_op_done(state->op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = users_get_retry(req); if (ret != EOK) { tevent_req_error(req, ret); return; } return; } if ((ret == ENOENT) && (state->ctx->opts->schema_type == SDAP_SCHEMA_RFC2307) && (dp_opt_get_bool(state->ctx->opts->basic, SDAP_RFC2307_FALLBACK_TO_LOCAL_USERS) == true)) { struct sysdb_attrs **usr_attrs; const char *name = NULL; bool fallback; switch (state->filter_type) { case BE_FILTER_NAME: name = state->name; uid = -1; fallback = true; break; case BE_FILTER_IDNUM: uid = (uid_t) strtouint32(state->name, &endptr, 10); if (errno || *endptr || (state->name == endptr)) { tevent_req_error(req, errno ? errno : EINVAL); return; } fallback = true; break; default: fallback = false; break; } if (fallback) { ret = sdap_fallback_local_user(state, state->ctx->opts, name, uid, &usr_attrs); if (ret == EOK) { ret = sdap_save_user(state, state->ctx->opts, state->domain, usr_attrs[0], NULL, 0); } } } state->sdap_ret = ret; if (ret && ret != ENOENT) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } if (ret == ENOENT && state->noexist_delete == true) { switch (state->filter_type) { case BE_FILTER_ENUM: tevent_req_error(req, ret); return; case BE_FILTER_NAME: ret = sysdb_delete_user(state->domain, state->name, 0); if (ret != EOK && ret != ENOENT) { tevent_req_error(req, ret); return; } break; case BE_FILTER_IDNUM: uid = (uid_t) strtouint32(state->name, &endptr, 10); if (errno || *endptr || (state->name == endptr)) { tevent_req_error(req, errno ? errno : EINVAL); return; } ret = sysdb_delete_user(state->domain, NULL, uid); if (ret != EOK && ret != ENOENT) { tevent_req_error(req, ret); return; } break; case BE_FILTER_SECID: case BE_FILTER_UUID: /* Since it is not clear if the SID/UUID belongs to a user or a * group we have nothing to do here. */ break; case BE_FILTER_WILDCARD: /* We can't know if all users are up-to-date, especially in a large * environment. Do not delete any records, let the responder fetch * the entries they are requested in */ break; case BE_FILTER_CERT: ret = sysdb_remove_cert(state->domain, state->name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to remove user certificate" "[%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } break; default: tevent_req_error(req, EINVAL); return; } } state->dp_error = DP_ERR_OK; /* FIXME - return sdap error so that we know the user was not found */ tevent_req_done(req); } int users_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret) { struct users_get_state *state = tevent_req_data(req, struct users_get_state); if (dp_error_out) { *dp_error_out = state->dp_error; } if (sdap_ret) { *sdap_ret = state->sdap_ret; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* =Groups-Related-Functions-(by-name,by-uid)============================= */ struct groups_get_state { struct tevent_context *ev; struct sdap_id_ctx *ctx; struct sdap_domain *sdom; struct sdap_id_conn_ctx *conn; struct sdap_id_op *op; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; const char *name; int filter_type; char *filter; const char **attrs; bool use_id_mapping; int dp_error; int sdap_ret; bool noexist_delete; bool no_members; }; static int groups_get_retry(struct tevent_req *req); static void groups_get_connect_done(struct tevent_req *subreq); static void groups_get_posix_check_done(struct tevent_req *subreq); static void groups_get_search(struct tevent_req *req); static void groups_get_done(struct tevent_req *subreq); struct tevent_req *groups_get_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, const char *name, int filter_type, int attrs_type, bool noexist_delete, bool no_members) { struct tevent_req *req; struct groups_get_state *state; const char *attr_name = NULL; char *clean_name; char *endptr; int ret; gid_t gid; enum idmap_error_code err; char *sid; const char *member_filter[2]; char *oc_list; req = tevent_req_create(memctx, &state, struct groups_get_state); if (!req) return NULL; state->ev = ev; state->ctx = ctx; state->sdom = sdom; state->conn = conn; state->dp_error = DP_ERR_FATAL; state->noexist_delete = noexist_delete; state->no_members = no_members; state->op = sdap_id_op_create(state, state->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto done; } state->domain = sdom->dom; state->sysdb = sdom->dom->sysdb; state->name = name; state->filter_type = filter_type; state->use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( ctx->opts->idmap_ctx, sdom->dom->name, sdom->dom->domain_id); switch(filter_type) { case BE_FILTER_WILDCARD: attr_name = ctx->opts->group_map[SDAP_AT_GROUP_NAME].name; ret = sss_filter_sanitize_ex(state, name, &clean_name, LDAP_ALLOWED_WILDCARDS); if (ret != EOK) { goto done; } break; case BE_FILTER_NAME: attr_name = ctx->opts->group_map[SDAP_AT_GROUP_NAME].name; ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { goto done; } break; case BE_FILTER_IDNUM: if (state->use_id_mapping) { /* If we're ID-mapping, we need to use the objectSID * in the search filter. */ gid = strtouint32(name, &endptr, 10); if (errno != EOK) { ret = EINVAL; goto done; } /* Convert the GID to its objectSID */ err = sss_idmap_unix_to_sid(ctx->opts->idmap_ctx->map, gid, &sid); if (err == IDMAP_NO_DOMAIN) { DEBUG(SSSDBG_MINOR_FAILURE, "[%s] did not match any configured ID mapping domain\n", name); ret = sysdb_delete_group(state->domain, NULL, gid); if (ret == ENOENT) { /* Ignore errors to remove users that were not cached previously */ ret = EOK; } goto done; } else if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Mapping ID [%s] to SID failed: [%s]\n", name, idmap_error_string(err)); ret = EIO; goto done; } attr_name = ctx->opts->group_map[SDAP_AT_GROUP_OBJECTSID].name; ret = sss_filter_sanitize(state, sid, &clean_name); sss_idmap_free_sid(ctx->opts->idmap_ctx->map, sid); if (ret != EOK) { goto done; } } else { attr_name = ctx->opts->group_map[SDAP_AT_GROUP_GID].name; ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { goto done; } } break; case BE_FILTER_SECID: attr_name = ctx->opts->group_map[SDAP_AT_GROUP_OBJECTSID].name; ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { goto done; } break; case BE_FILTER_UUID: attr_name = ctx->opts->group_map[SDAP_AT_GROUP_UUID].name; if (attr_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "UUID search not configured for this backend.\n"); ret = EINVAL; goto done; } ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { goto done; } break; default: ret = EINVAL; goto done; } if (attr_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing search attribute name.\n"); ret = EINVAL; goto done; } oc_list = sdap_make_oc_list(state, ctx->opts->group_map); if (oc_list == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n"); ret = ENOMEM; goto done; } if (state->use_id_mapping || filter_type == BE_FILTER_SECID) { /* When mapping IDs or looking for SIDs, we don't want to limit * ourselves to groups with a GID value */ state->filter = talloc_asprintf(state, "(&(%s=%s)(%s)(%s=*))", attr_name, clean_name, oc_list, ctx->opts->group_map[SDAP_AT_GROUP_NAME].name); } else { state->filter = talloc_asprintf(state, "(&(%s=%s)(%s)(%s=*)(&(%s=*)(!(%s=0))))", attr_name, clean_name, oc_list, ctx->opts->group_map[SDAP_AT_GROUP_NAME].name, ctx->opts->group_map[SDAP_AT_GROUP_GID].name, ctx->opts->group_map[SDAP_AT_GROUP_GID].name); } talloc_zfree(clean_name); if (!state->filter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto done; } member_filter[0] = (const char *)ctx->opts->group_map[SDAP_AT_GROUP_MEMBER].name; member_filter[1] = NULL; /* TODO: handle attrs_type */ ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP, (state->domain->ignore_group_members || state->no_members) ? (const char **)member_filter : NULL, &state->attrs, NULL); if (ret != EOK) goto done; ret = groups_get_retry(req); if (ret != EOK) { goto done; } return req; done: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } return tevent_req_post(req, ev); } static int groups_get_retry(struct tevent_req *req) { struct groups_get_state *state = tevent_req_data(req, struct groups_get_state); struct tevent_req *subreq; int ret = EOK; subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { return ret; } tevent_req_set_callback(subreq, groups_get_connect_done, req); return EOK; } static void groups_get_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct groups_get_state *state = tevent_req_data(req, struct groups_get_state); int dp_error = DP_ERR_FATAL; int ret; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } /* If POSIX attributes have been requested with an AD server and we * have no idea about POSIX attributes support, run a one-time check */ if (state->use_id_mapping == false && state->ctx->opts->schema_type == SDAP_SCHEMA_AD && state->ctx->srv_opts && state->ctx->srv_opts->posix_checked == false) { subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, sdap_id_op_handle(state->op), state->sdom->user_search_bases, dp_opt_get_int(state->ctx->opts->basic, SDAP_SEARCH_TIMEOUT)); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, groups_get_posix_check_done, req); return; } groups_get_search(req); } static void groups_get_posix_check_done(struct tevent_req *subreq) { errno_t ret; bool has_posix; int dp_error; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct groups_get_state *state = tevent_req_data(req, struct groups_get_state); ret = sdap_posix_check_recv(subreq, &has_posix); talloc_zfree(subreq); if (ret != EOK) { /* We can only finish the id_op on error as the connection * is re-used by the group search */ ret = sdap_id_op_done(state->op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = groups_get_retry(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } } state->ctx->srv_opts->posix_checked = true; /* If the check ran to completion, we know for certain about the attributes */ if (has_posix == false) { state->sdap_ret = ERR_NO_POSIX; tevent_req_done(req); return; } groups_get_search(req); } static void groups_get_search(struct tevent_req *req) { struct groups_get_state *state = tevent_req_data(req, struct groups_get_state); struct tevent_req *subreq; enum sdap_entry_lookup_type lookup_type; if (state->filter_type == BE_FILTER_WILDCARD) { lookup_type = SDAP_LOOKUP_WILDCARD; } else { lookup_type = SDAP_LOOKUP_SINGLE; } subreq = sdap_get_groups_send(state, state->ev, state->sdom, state->ctx->opts, sdap_id_op_handle(state->op), state->attrs, state->filter, dp_opt_get_int(state->ctx->opts->basic, SDAP_SEARCH_TIMEOUT), lookup_type, state->no_members); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, groups_get_done, req); } static void groups_get_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct groups_get_state *state = tevent_req_data(req, struct groups_get_state); char *endptr; gid_t gid; int dp_error = DP_ERR_FATAL; int ret; ret = sdap_get_groups_recv(subreq, NULL, NULL); talloc_zfree(subreq); ret = sdap_id_op_done(state->op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = groups_get_retry(req); if (ret != EOK) { tevent_req_error(req, ret); return; } return; } state->sdap_ret = ret; if (ret && ret != ENOENT) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } if (ret == ENOENT && state->noexist_delete == true) { switch (state->filter_type) { case BE_FILTER_ENUM: tevent_req_error(req, ret); return; case BE_FILTER_NAME: ret = sysdb_delete_group(state->domain, state->name, 0); if (ret != EOK && ret != ENOENT) { tevent_req_error(req, ret); return; } break; case BE_FILTER_IDNUM: gid = (gid_t) strtouint32(state->name, &endptr, 10); if (errno || *endptr || (state->name == endptr)) { tevent_req_error(req, errno ? errno : EINVAL); return; } ret = sysdb_delete_group(state->domain, NULL, gid); if (ret != EOK && ret != ENOENT) { tevent_req_error(req, ret); return; } break; case BE_FILTER_SECID: case BE_FILTER_UUID: /* Since it is not clear if the SID/UUID belongs to a user or a * group we have nothing to do here. */ break; case BE_FILTER_WILDCARD: /* We can't know if all groups are up-to-date, especially in * a large environment. Do not delete any records, let the * responder fetch the entries they are requested in. */ break; default: tevent_req_error(req, EINVAL); return; } } state->dp_error = DP_ERR_OK; tevent_req_done(req); } int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret) { struct groups_get_state *state = tevent_req_data(req, struct groups_get_state); if (dp_error_out) { *dp_error_out = state->dp_error; } if (sdap_ret) { *sdap_ret = state->sdap_ret; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* =Get-Groups-for-User================================================== */ struct groups_by_user_state { struct tevent_context *ev; struct sdap_id_ctx *ctx; struct sdap_domain *sdom; struct sdap_id_conn_ctx *conn; struct sdap_id_op *op; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; const char *name; int name_type; const char *extra_value; const char **attrs; int dp_error; int sdap_ret; bool noexist_delete; }; static int groups_by_user_retry(struct tevent_req *req); static void groups_by_user_connect_done(struct tevent_req *subreq); static void groups_by_user_done(struct tevent_req *subreq); static errno_t set_initgroups_expire_attribute(struct sss_domain_info *domain, const char *name) { errno_t ret; time_t cache_timeout; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(NULL); if (attrs == NULL) { return ENOMEM; } cache_timeout = domain->user_timeout ? time(NULL) + domain->user_timeout : 0; ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, cache_timeout); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up attrs\n"); goto done; } ret = sysdb_set_user_attr(domain, name, attrs, SYSDB_MOD_REP); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set initgroups expire attribute\n"); goto done; } done: talloc_zfree(attrs); return ret; } static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, const char *name, int name_type, const char *extra_value, bool noexist_delete) { struct tevent_req *req; struct groups_by_user_state *state; int ret; req = tevent_req_create(memctx, &state, struct groups_by_user_state); if (!req) return NULL; state->ev = ev; state->ctx = ctx; state->dp_error = DP_ERR_FATAL; state->conn = conn; state->sdom = sdom; state->noexist_delete = noexist_delete; state->op = sdap_id_op_create(state, state->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto fail; } state->name = name; state->name_type = name_type; state->extra_value = extra_value; state->domain = sdom->dom; state->sysdb = sdom->dom->sysdb; ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP, NULL, &state->attrs, NULL); if (ret != EOK) goto fail; ret = groups_by_user_retry(req); if (ret != EOK) { goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static int groups_by_user_retry(struct tevent_req *req) { struct groups_by_user_state *state = tevent_req_data(req, struct groups_by_user_state); struct tevent_req *subreq; int ret = EOK; subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { return ret; } tevent_req_set_callback(subreq, groups_by_user_connect_done, req); return EOK; } static void groups_by_user_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct groups_by_user_state *state = tevent_req_data(req, struct groups_by_user_state); int dp_error = DP_ERR_FATAL; int ret; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } subreq = sdap_get_initgr_send(state, state->ev, state->sdom, sdap_id_op_handle(state->op), state->ctx, state->conn, state->name, state->name_type, state->extra_value, state->attrs); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, groups_by_user_done, req); } static void groups_by_user_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct groups_by_user_state *state = tevent_req_data(req, struct groups_by_user_state); int dp_error = DP_ERR_FATAL; int ret; const char *cname; ret = sdap_get_initgr_recv(subreq); talloc_zfree(subreq); ret = sdap_id_op_done(state->op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = groups_by_user_retry(req); if (ret != EOK) { tevent_req_error(req, ret); return; } return; } state->sdap_ret = ret; if (ret == EOK || ret == ENOENT) { /* state->name is still the name used for the original req. The cached * object might have a different name, e.g. a fully-qualified name. */ ret = sysdb_get_real_name(state, state->domain, state->name, &cname); if (ret != EOK) { cname = state->name; DEBUG(SSSDBG_TRACE_INTERNAL, "Failed to canonicalize name, using [%s] [%d]: %s.\n", cname, ret, sss_strerror(ret)); } } switch (state->sdap_ret) { case ENOENT: if (state->noexist_delete == true) { ret = sysdb_delete_user(state->domain, cname, 0); if (ret != EOK && ret != ENOENT) { tevent_req_error(req, ret); return; } } break; case EOK: ret = set_initgroups_expire_attribute(state->domain, cname); if (ret != EOK) { state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); return; } break; default: state->dp_error = dp_error; tevent_req_error(req, ret); return; } state->dp_error = DP_ERR_OK; tevent_req_done(req); } int groups_by_user_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret) { struct groups_by_user_state *state = tevent_req_data(req, struct groups_by_user_state); if (dp_error_out) { *dp_error_out = state->dp_error; } if (sdap_ret) { *sdap_ret = state->sdap_ret; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void sdap_check_online_done(struct tevent_req *req); void sdap_check_online(struct be_req *be_req) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct sdap_id_ctx *ctx; ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data, struct sdap_id_ctx); return sdap_do_online_check(be_req, ctx); } struct sdap_online_check_ctx { struct be_req *be_req; struct sdap_id_ctx *id_ctx; }; void sdap_do_online_check(struct be_req *be_req, struct sdap_id_ctx *ctx) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct tevent_req *req; struct sdap_online_check_ctx *check_ctx; errno_t ret; check_ctx = talloc_zero(be_req, struct sdap_online_check_ctx); if (!check_ctx) { ret = ENOMEM; DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed\n"); goto fail; } check_ctx->id_ctx = ctx; check_ctx->be_req = be_req; req = sdap_cli_connect_send(be_req, be_ctx->ev, ctx->opts, be_ctx, ctx->conn->service, false, CON_TLS_DFL, false); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_cli_connect_send failed.\n"); ret = EIO; goto fail; } tevent_req_set_callback(req, sdap_check_online_done, check_ctx); return; fail: sdap_handler_done(be_req, DP_ERR_FATAL, ret, NULL); } static void sdap_check_online_reinit_done(struct tevent_req *req); static void sdap_check_online_done(struct tevent_req *req) { struct sdap_online_check_ctx *check_ctx = tevent_req_callback_data(req, struct sdap_online_check_ctx); int ret; int dp_err = DP_ERR_FATAL; bool can_retry; struct sdap_server_opts *srv_opts; struct be_req *be_req; struct sdap_id_ctx *id_ctx; struct tevent_req *reinit_req = NULL; bool reinit = false; struct be_ctx *be_ctx; ret = sdap_cli_connect_recv(req, NULL, &can_retry, NULL, &srv_opts); talloc_zfree(req); if (ret != EOK) { if (!can_retry) { dp_err = DP_ERR_OFFLINE; } } else { dp_err = DP_ERR_OK; if (!check_ctx->id_ctx->srv_opts) { srv_opts->max_user_value = 0; srv_opts->max_group_value = 0; srv_opts->max_service_value = 0; srv_opts->max_sudo_value = 0; } else if (strcmp(srv_opts->server_id, check_ctx->id_ctx->srv_opts->server_id) == 0 && srv_opts->supports_usn && check_ctx->id_ctx->srv_opts->last_usn > srv_opts->last_usn) { check_ctx->id_ctx->srv_opts->max_user_value = 0; check_ctx->id_ctx->srv_opts->max_group_value = 0; check_ctx->id_ctx->srv_opts->max_service_value = 0; check_ctx->id_ctx->srv_opts->max_sudo_value = 0; check_ctx->id_ctx->srv_opts->last_usn = srv_opts->last_usn; reinit = true; } sdap_steal_server_opts(check_ctx->id_ctx, &srv_opts); } be_req = check_ctx->be_req; be_ctx = be_req_get_be_ctx(be_req); id_ctx = check_ctx->id_ctx; talloc_free(check_ctx); if (reinit) { DEBUG(SSSDBG_TRACE_FUNC, "Server reinitialization detected. " "Cleaning cache.\n"); reinit_req = sdap_reinit_cleanup_send(be_req, be_ctx, id_ctx); if (reinit_req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to perform reinitialization " "clean up.\n"); /* not fatal */ goto done; } tevent_req_set_callback(reinit_req, sdap_check_online_reinit_done, be_req); return; } done: sdap_handler_done(be_req, dp_err, 0, NULL); } static void sdap_check_online_reinit_done(struct tevent_req *req) { struct be_req *be_req = NULL; errno_t ret; be_req = tevent_req_callback_data(req, struct be_req); ret = sdap_reinit_cleanup_recv(req); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to perform reinitialization " "clean up [%d]: %s\n", ret, strerror(ret)); /* not fatal */ } else { DEBUG(SSSDBG_TRACE_FUNC, "Reinitialization clean up completed\n"); } sdap_handler_done(be_req, DP_ERR_OK, 0, NULL); } /* =Get-Account-Info-Call================================================= */ /* FIXME: embed this function in sssd_be and only call out * specific functions from modules ? */ void sdap_handle_account_info(struct be_req *breq, struct sdap_id_ctx *ctx, struct sdap_id_conn_ctx *conn); static struct tevent_req *get_user_and_group_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, const char *name, int filter_type, int attrs_type, bool noexist_delete); errno_t sdap_get_user_and_group_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret); void sdap_account_info_handler(struct be_req *breq) { struct be_ctx *be_ctx = be_req_get_be_ctx(breq); struct sdap_id_ctx *ctx; ctx = talloc_get_type(be_ctx->bet_info[BET_ID].pvt_bet_data, struct sdap_id_ctx); if (!ctx) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get sdap ctx\n"); return sdap_handler_done(breq, DP_ERR_FATAL, EINVAL, "Invalid request data\n"); } return sdap_handle_account_info(breq, ctx, ctx->conn); } bool sdap_is_enum_request(struct be_acct_req *ar) { switch (ar->entry_type & BE_REQ_TYPE_MASK) { case BE_REQ_USER: case BE_REQ_GROUP: case BE_REQ_SERVICES: if (ar->filter_type == BE_FILTER_ENUM) { return true; } } return false; } /* A generic LDAP account info handler */ struct sdap_handle_acct_req_state { struct be_acct_req *ar; const char *err; int dp_error; int sdap_ret; }; static void sdap_handle_acct_req_done(struct tevent_req *subreq); struct tevent_req * sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct be_acct_req *ar, struct sdap_id_ctx *id_ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, bool noexist_delete) { struct tevent_req *req; struct tevent_req *subreq; struct sdap_handle_acct_req_state *state; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_handle_acct_req_state); if (!req) { ret = ENOMEM; goto done; } state->ar = ar; if (ar == NULL) { ret = EINVAL; goto done; } switch (ar->entry_type & BE_REQ_TYPE_MASK) { case BE_REQ_USER: /* user */ subreq = users_get_send(state, be_ctx->ev, id_ctx, sdom, conn, ar->filter_value, ar->filter_type, ar->extra_value, ar->attr_type, noexist_delete); break; case BE_REQ_GROUP: /* group */ subreq = groups_get_send(state, be_ctx->ev, id_ctx, sdom, conn, ar->filter_value, ar->filter_type, ar->attr_type, noexist_delete, false); break; case BE_REQ_INITGROUPS: /* init groups for user */ if (ar->filter_type != BE_FILTER_NAME && ar->filter_type != BE_FILTER_SECID && ar->filter_type != BE_FILTER_UUID) { ret = EINVAL; state->err = "Invalid filter type"; goto done; } if (ar->attr_type != BE_ATTR_CORE) { ret = EINVAL; state->err = "Invalid attr type"; goto done; } subreq = groups_by_user_send(state, be_ctx->ev, id_ctx, sdom, conn, ar->filter_value, ar->filter_type, ar->extra_value, noexist_delete); break; case BE_REQ_NETGROUP: if (ar->filter_type != BE_FILTER_NAME) { ret = EINVAL; state->err = "Invalid filter type"; goto done; } subreq = ldap_netgroup_get_send(state, be_ctx->ev, id_ctx, sdom, conn, ar->filter_value, noexist_delete); break; case BE_REQ_SERVICES: if (ar->filter_type == BE_FILTER_SECID || ar->filter_type == BE_FILTER_UUID) { ret = EINVAL; state->err = "Invalid filter type"; goto done; } subreq = services_get_send(state, be_ctx->ev, id_ctx, sdom, conn, ar->filter_value, ar->extra_value, ar->filter_type, noexist_delete); break; case BE_REQ_BY_SECID: if (ar->filter_type != BE_FILTER_SECID) { ret = EINVAL; state->err = "Invalid filter type"; goto done; } subreq = get_user_and_group_send(state, be_ctx->ev, id_ctx, sdom, conn, ar->filter_value, ar->filter_type, ar->attr_type, noexist_delete); break; case BE_REQ_BY_UUID: if (ar->filter_type != BE_FILTER_UUID) { ret = EINVAL; state->err = "Invalid filter type"; goto done; } subreq = get_user_and_group_send(state, be_ctx->ev, id_ctx, sdom, conn, ar->filter_value, ar->filter_type, ar->attr_type, noexist_delete); break; case BE_REQ_USER_AND_GROUP: if (!(ar->filter_type == BE_FILTER_NAME || ar->filter_type == BE_FILTER_IDNUM)) { ret = EINVAL; state->err = "Invalid filter type"; goto done; } subreq = get_user_and_group_send(state, be_ctx->ev, id_ctx, sdom, conn, ar->filter_value, ar->filter_type, ar->attr_type, noexist_delete); break; case BE_REQ_BY_CERT: subreq = users_get_send(state, be_ctx->ev, id_ctx, sdom, conn, ar->filter_value, ar->filter_type, ar->extra_value, ar->attr_type, noexist_delete); break; default: /*fail*/ ret = EINVAL; state->err = "Invalid request type"; goto done; } if (!subreq) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_handle_acct_req_done, req); return req; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, be_ctx->ev); return req; } static void sdap_handle_acct_req_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_handle_acct_req_state *state; errno_t ret; const char *err = "Invalid request type"; state = tevent_req_data(req, struct sdap_handle_acct_req_state); switch (state->ar->entry_type & BE_REQ_TYPE_MASK) { case BE_REQ_USER: /* user */ err = "User lookup failed"; ret = users_get_recv(subreq, &state->dp_error, &state->sdap_ret); break; case BE_REQ_GROUP: /* group */ err = "Group lookup failed"; ret = groups_get_recv(subreq, &state->dp_error, &state->sdap_ret); break; case BE_REQ_INITGROUPS: /* init groups for user */ err = "Init group lookup failed"; ret = groups_by_user_recv(subreq, &state->dp_error, &state->sdap_ret); break; case BE_REQ_NETGROUP: err = "Netgroup lookup failed"; ret = ldap_netgroup_get_recv(subreq, &state->dp_error, &state->sdap_ret); break; case BE_REQ_SERVICES: err = "Service lookup failed"; ret = services_get_recv(subreq, &state->dp_error, &state->sdap_ret); break; case BE_REQ_BY_SECID: /* Fallthrough */ case BE_REQ_BY_UUID: /* Fallthrough */ case BE_REQ_USER_AND_GROUP: err = "Lookup by SID failed"; ret = sdap_get_user_and_group_recv(subreq, &state->dp_error, &state->sdap_ret); break; case BE_REQ_BY_CERT: err = "User lookup by certificate failed"; ret = users_get_recv(subreq, &state->dp_error, &state->sdap_ret); break; default: /*fail*/ ret = EINVAL; break; } talloc_zfree(subreq); if (ret != EOK) { state->err = err; tevent_req_error(req, ret); return; } state->err = "Success"; tevent_req_done(req); } errno_t sdap_handle_acct_req_recv(struct tevent_req *req, int *_dp_error, const char **_err, int *sdap_ret) { struct sdap_handle_acct_req_state *state; state = tevent_req_data(req, struct sdap_handle_acct_req_state); if (_dp_error) { *_dp_error = state->dp_error; } if (_err) { *_err = state->err; } if (sdap_ret) { *sdap_ret = state->sdap_ret; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void sdap_account_info_complete(struct tevent_req *req); void sdap_handle_account_info(struct be_req *breq, struct sdap_id_ctx *ctx, struct sdap_id_conn_ctx *conn) { struct be_acct_req *ar; struct tevent_req *req; if (be_is_offline(ctx->be)) { return sdap_handler_done(breq, DP_ERR_OFFLINE, EAGAIN, "Offline"); } ar = talloc_get_type(be_req_get_data(breq), struct be_acct_req); if (ar == NULL) { return sdap_handler_done(breq, DP_ERR_FATAL, EINVAL, "Invalid private data"); } if (sdap_is_enum_request(ar)) { DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n"); return sdap_handler_done(breq, DP_ERR_OK, EOK, "Success"); } req = sdap_handle_acct_req_send(breq, ctx->be, ar, ctx, ctx->opts->sdom, conn, true); if (req == NULL) { return sdap_handler_done(breq, DP_ERR_FATAL, ENOMEM, "Out of memory"); } tevent_req_set_callback(req, sdap_account_info_complete, breq); } static void sdap_account_info_complete(struct tevent_req *req) { const char *error_text; const char *req_error_text; struct be_req *breq = tevent_req_callback_data(req, struct be_req); int ret, dp_error; ret = sdap_handle_acct_req_recv(req, &dp_error, &req_error_text, NULL); talloc_zfree(req); if (dp_error == DP_ERR_OK) { if (ret == EOK) { error_text = NULL; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: dp_error is OK on failed request\n"); dp_error = DP_ERR_FATAL; error_text = req_error_text; } } else if (dp_error == DP_ERR_OFFLINE) { error_text = "Offline"; } else if (dp_error == DP_ERR_FATAL && ret == ENOMEM) { error_text = "Out of memory"; } else { error_text = req_error_text; } sdap_handler_done(breq, dp_error, ret, error_text); } struct get_user_and_group_state { struct tevent_context *ev; struct sdap_id_ctx *id_ctx; struct sdap_domain *sdom; struct sdap_id_conn_ctx *conn; struct sdap_id_op *op; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; const char *filter_val; int filter_type; int attrs_type; char *filter; const char **attrs; int dp_error; int sdap_ret; bool noexist_delete; }; static void get_user_and_group_users_done(struct tevent_req *subreq); static void get_user_and_group_groups_done(struct tevent_req *subreq); static struct tevent_req *get_user_and_group_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *id_ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, const char *filter_val, int filter_type, int attrs_type, bool noexist_delete) { struct tevent_req *req; struct tevent_req *subreq; struct get_user_and_group_state *state; int ret; req = tevent_req_create(memctx, &state, struct get_user_and_group_state); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->id_ctx = id_ctx; state->sdom = sdom; state->conn = conn; state->dp_error = DP_ERR_FATAL; state->noexist_delete = noexist_delete; state->op = sdap_id_op_create(state, state->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto fail; } state->domain = sdom->dom; state->sysdb = sdom->dom->sysdb; state->filter_val = filter_val; state->filter_type = filter_type; state->attrs_type = attrs_type; subreq = groups_get_send(req, state->ev, state->id_ctx, state->sdom, state->conn, state->filter_val, state->filter_type, state->attrs_type, state->noexist_delete, false); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "users_get_send failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, get_user_and_group_groups_done, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void get_user_and_group_groups_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct get_user_and_group_state *state = tevent_req_data(req, struct get_user_and_group_state); int ret; struct ad_id_ctx *ad_id_ctx; struct sdap_id_conn_ctx *user_conn; ret = groups_get_recv(subreq, &state->dp_error, &state->sdap_ret); talloc_zfree(subreq); if (ret != EOK) { /* Fatal error while looking up group */ tevent_req_error(req, ret); return; } if (state->sdap_ret == EOK) { /* Matching group found */ tevent_req_done(req); return; } else if (state->sdap_ret != ENOENT) { tevent_req_error(req, EIO); return; } /* Now the search finished fine but did not find an entry. * Retry with users. */ user_conn = state->conn; /* Prefer LDAP over GC for users */ if (state->id_ctx->opts->schema_type == SDAP_SCHEMA_AD && state->sdom->pvt != NULL) { ad_id_ctx = talloc_get_type(state->sdom->pvt, struct ad_id_ctx); if (ad_id_ctx != NULL && ad_id_ctx->ldap_ctx != NULL && state->conn == ad_id_ctx->gc_ctx) { DEBUG(SSSDBG_TRACE_ALL, "Switching to LDAP connection for user lookup.\n"); user_conn = ad_id_ctx->ldap_ctx; } } subreq = users_get_send(req, state->ev, state->id_ctx, state->sdom, user_conn, state->filter_val, state->filter_type, NULL, state->attrs_type, state->noexist_delete); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "groups_get_send failed.\n"); tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, get_user_and_group_users_done, req); } static void get_user_and_group_users_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct get_user_and_group_state *state = tevent_req_data(req, struct get_user_and_group_state); int ret; ret = users_get_recv(subreq, &state->dp_error, &state->sdap_ret); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } if (state->sdap_ret == ENOENT) { if (state->noexist_delete == true) { /* The search ran to completion, but nothing was found. * Delete the existing entry, if any. */ ret = sysdb_delete_by_sid(state->sysdb, state->domain, state->filter_val); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not delete entry by SID!\n"); tevent_req_error(req, ret); return; } } } else if (state->sdap_ret != EOK) { tevent_req_error(req, EIO); return; } /* Both ret and sdap->ret are EOK. Matching user found */ tevent_req_done(req); return; } errno_t sdap_get_user_and_group_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret) { struct get_user_and_group_state *state = tevent_req_data(req, struct get_user_and_group_state); if (dp_error_out) { *dp_error_out = state->dp_error; } if (sdap_ret) { *sdap_ret = state->sdap_ret; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_id_op.h0000644000000000000000000000007412703456111020323 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.556793296 sssd-1.13.4/src/providers/ldap/sdap_id_op.h0000644002412700241270000000551212703456111021775 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP ID backend operation retry logic and connection cache Authors: Eugene Indenbom Copyright (C) 2008-2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SDAP_ID_OP_H_ #define _SDAP_ID_OP_H_ struct sdap_id_ctx; struct sdap_id_conn_ctx; /* LDAP async connection cache */ struct sdap_id_conn_cache; /* LDAP async operation tracker: * - keeps track of connection usage * - keeps track of operation retries */ struct sdap_id_op; /* Create a connection cache */ int sdap_id_conn_cache_create(TALLOC_CTX *memctx, struct sdap_id_ctx *id_ctx, struct sdap_id_conn_ctx *id_conn, struct sdap_id_conn_cache** conn_cache_out); /* Create an operation object */ struct sdap_id_op *sdap_id_op_create(TALLOC_CTX *memctx, struct sdap_id_conn_cache *cache); /* Begin to connect to LDAP server. */ struct tevent_req *sdap_id_op_connect_send(struct sdap_id_op *op, TALLOC_CTX *memctx, int *ret_out); /* Get the result of an asynchronous connect operation on sdap_id_op * * In dp_error data provider error code is returned: * DP_ERR_OK - connection established * DP_ERR_OFFLINE - backend is offline, operation result is set EAGAIN * DP_ERR_FATAL - operation failed */ int sdap_id_op_connect_recv(struct tevent_req *req, int *dp_error); /* Report completion of LDAP operation and release associated connection. * Returns operation result (possible updated) passed in ret parameter. * * In dp_error data provider error code is returned: * DP_ERR_OK (operation result = EOK) - operation completed * DP_ERR_OK (operation result != EOK) - operation can be retried * DP_ERR_OFFLINE - backend is offline, operation result is set EAGAIN * DP_ERR_FATAL - operation failed */ int sdap_id_op_done(struct sdap_id_op*, int ret, int *dp_error); /* Get SDAP handle associated with operation by sdap_id_op_connect */ struct sdap_handle *sdap_id_op_handle(struct sdap_id_op *op); /* Get root DSE entry of connected LDAP server */ const struct sysdb_attrs *sdap_id_op_rootDSE(struct sdap_id_op *op); #endif /* _SDAP_ID_OP_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_reinit.c0000644000000000000000000000007412703456111020516 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.794794103 sssd-1.13.4/src/providers/ldap/sdap_reinit.c0000644002412700241270000002251612703456111022173 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async_enum.h" #include "db/sysdb.h" #include "db/sysdb_services.h" struct sdap_reinit_cleanup_state { struct sss_domain_info *domain; struct sysdb_ctx *sysdb; }; static errno_t sdap_reinit_clear_usn(struct sysdb_ctx *sysdb, struct sss_domain_info *domain); static void sdap_reinit_cleanup_done(struct tevent_req *subreq); static errno_t sdap_reinit_delete_records(struct sss_domain_info *domain); struct tevent_req* sdap_reinit_cleanup_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct sdap_id_ctx *id_ctx) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_reinit_cleanup_state *state; int ret; /* * 1. remove entryUSN attribute from all entries * 2. run enumeration * 3. remove records that doesn't have entryUSN attribute updated * * We don't need to do this for sudo rules, they will be refreshed * automatically during next smart/full refresh, or when an expired rule * is deleted. */ req = tevent_req_create(mem_ctx, &state, struct sdap_reinit_cleanup_state); if (req == NULL) { return NULL; } state->sysdb = be_ctx->domain->sysdb; state->domain = be_ctx->domain; if (!be_ctx->domain->enumerate) { /* enumeration is disabled, this whole process is meaningless */ ret = EOK; goto immediately; } ret = sdap_reinit_clear_usn(state->sysdb, state->domain); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to clear USN attributes [%d]: %s\n", ret, strerror(ret)); goto immediately; } subreq = sdap_dom_enum_send(id_ctx, be_ctx->ev, id_ctx, id_ctx->opts->sdom, id_ctx->conn); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to issue enumeration request\n"); ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_reinit_cleanup_done, req); return req; immediately: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } tevent_req_post(req, be_ctx->ev); return req; } static void sdap_delete_msgs_usn(struct sysdb_ctx *sysdb, struct ldb_message **msgs, size_t msgs_num) { struct ldb_message_element el = { 0, SYSDB_USN, 0, NULL }; struct sysdb_attrs usn_el = { 1, &el }; errno_t ret; int i; for (i = 0; i < msgs_num; i++) { ret = sysdb_set_entry_attr(sysdb, msgs[i]->dn, &usn_el, SYSDB_MOD_DEL); if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Failed to clean USN on entry: [%s]\n", ldb_dn_get_linearized(msgs[i]->dn)); } } } static errno_t sdap_reinit_clear_usn(struct sysdb_ctx *sysdb, struct sss_domain_info *domain) { TALLOC_CTX *tmp_ctx = NULL; bool in_transaction = false; struct ldb_message **msgs = NULL; size_t msgs_num = 0; const char *attrs[] = { "dn", NULL }; int sret; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { goto done; } in_transaction = true; /* reset users' usn */ ret = sysdb_search_users(tmp_ctx, domain, "", attrs, &msgs_num, &msgs); if (ret != EOK) { goto done; } sdap_delete_msgs_usn(sysdb, msgs, msgs_num); talloc_zfree(msgs); msgs_num = 0; /* reset groups' usn */ ret = sysdb_search_groups(tmp_ctx, domain, "", attrs, &msgs_num, &msgs); if (ret != EOK) { goto done; } sdap_delete_msgs_usn(sysdb, msgs, msgs_num); talloc_zfree(msgs); msgs_num = 0; /* reset services' usn */ ret = sysdb_search_services(tmp_ctx, domain, "", attrs, &msgs_num, &msgs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot search services [%d]: %s\n", ret, strerror(ret)); goto done; } sdap_delete_msgs_usn(sysdb, msgs, msgs_num); talloc_zfree(msgs); msgs_num = 0; ret = sysdb_transaction_commit(sysdb); if (ret == EOK) { in_transaction = false; } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not commit transaction\n"); } done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } static void sdap_reinit_cleanup_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; struct sdap_reinit_cleanup_state *state = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_reinit_cleanup_state); ret = sdap_dom_enum_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Domain enumeration failed [%d]: %s\n", ret, strerror(ret)); goto fail; } /* Ok, we've completed an enumeration. Save this to the * sysdb so we can postpone starting up the enumeration * process on the next SSSD service restart (to avoid * slowing down system boot-up */ ret = sysdb_set_enumerated(state->domain, true); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not mark domain as having " "enumerated.\n"); /* This error is non-fatal, so continue */ } ret = sdap_reinit_delete_records(state->domain); if (ret != EOK) { goto fail; } tevent_req_done(req); return; fail: tevent_req_error(req, ret); } static void sdap_delete_msgs_dn(struct sysdb_ctx *sysdb, struct ldb_message **msgs, size_t msgs_num) { errno_t ret; int i; for (i = 0; i < msgs_num; i++) { ret = sysdb_delete_entry(sysdb, msgs[i]->dn, true); if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Failed to delete entry: [%s]\n", ldb_dn_get_linearized(msgs[i]->dn)); } } } static errno_t sdap_reinit_delete_records(struct sss_domain_info *domain) { TALLOC_CTX *tmp_ctx = NULL; bool in_transaction = false; struct ldb_message **msgs = NULL; size_t msgs_num = 0; const char *attrs[] = { "dn", NULL }; int sret; errno_t ret; struct sysdb_ctx *sysdb = domain->sysdb; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { goto done; } in_transaction = true; /* purge untouched users */ ret = sysdb_search_users(tmp_ctx, domain, "(!("SYSDB_USN"=*))", attrs, &msgs_num, &msgs); if (ret != EOK) { goto done; } sdap_delete_msgs_dn(sysdb, msgs, msgs_num); talloc_zfree(msgs); msgs_num = 0; /* purge untouched groups */ ret = sysdb_search_groups(tmp_ctx, domain, "(!("SYSDB_USN"=*))", attrs, &msgs_num, &msgs); if (ret != EOK) { goto done; } sdap_delete_msgs_dn(sysdb, msgs, msgs_num); talloc_zfree(msgs); msgs_num = 0; /* purge untouched services */ ret = sysdb_search_services(tmp_ctx, domain, "(!("SYSDB_USN"=*))", attrs, &msgs_num, &msgs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot search services [%d]: %s\n", ret, strerror(ret)); goto done; } sdap_delete_msgs_dn(sysdb, msgs, msgs_num); talloc_zfree(msgs); msgs_num = 0; ret = sysdb_transaction_commit(sysdb); if (ret == EOK) { in_transaction = false; } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not commit transaction\n"); } done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } errno_t sdap_reinit_cleanup_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_users.c0000644000000000000000000000007312703456111021561 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.779794053 sssd-1.13.4/src/providers/ldap/sdap_async_users.c0000644002412700241270000007541612703456111023246 0ustar00jhrozekjhrozek00000000000000/* SSSD Async LDAP Helper routines - retrieving users Copyright (C) Simo Sorce - 2009 Copyright (C) 2010, Ralf Haferkamp , Novell Inc. Copyright (C) Jan Zeleny - 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ldap/sdap_users.h" #define REALM_SEPARATOR '@' static void make_realm_upper_case(const char *upn) { char *c; c = strchr(upn, REALM_SEPARATOR); if (c == NULL) { DEBUG(SSSDBG_TRACE_ALL, "No realm delimiter found in upn [%s].\n", upn); return; } while(*(++c) != '\0') { c[0] = toupper(*c); } return; } /* ==Save-User-Entry====================================================== */ static errno_t sdap_get_idmap_primary_gid(struct sdap_options *opts, struct sysdb_attrs *attrs, char *sid_str, char *dom_sid_str, gid_t *_gid) { errno_t ret; TALLOC_CTX *tmpctx = NULL; gid_t gid, primary_gid; char *group_sid_str; tmpctx = talloc_new(NULL); if (!tmpctx) { ret = ENOMEM; goto done; } ret = sysdb_attrs_get_uint32_t(attrs, opts->user_map[SDAP_AT_USER_PRIMARY_GROUP].sys_name, &primary_gid); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "no primary group ID provided\n"); ret = EINVAL; goto done; } /* The primary group ID is just the RID part of the objectSID * of the group. Generate the GID by adding this to the domain * SID value. */ /* First, get the domain SID if we didn't do so above */ if (!dom_sid_str) { ret = sdap_idmap_get_dom_sid_from_object(tmpctx, sid_str, &dom_sid_str); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not parse domain SID from [%s]\n", sid_str); goto done; } } /* Add the RID to the end */ group_sid_str = talloc_asprintf(tmpctx, "%s-%lu", dom_sid_str, (unsigned long) primary_gid); if (!group_sid_str) { ret = ENOMEM; goto done; } /* Convert the SID into a UNIX group ID */ ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, group_sid_str, &gid); if (ret != EOK) goto done; ret = EOK; *_gid = gid; done: talloc_free(tmpctx); return ret; } /* FIXME: support storing additional attributes */ int sdap_save_user(TALLOC_CTX *memctx, struct sdap_options *opts, struct sss_domain_info *dom, struct sysdb_attrs *attrs, char **_usn_value, time_t now) { struct ldb_message_element *el; int ret; const char *user_name = NULL; const char *fullname = NULL; const char *pwd; const char *gecos; const char *homedir; const char *shell; const char *orig_dn = NULL; uid_t uid; gid_t gid; struct sysdb_attrs *user_attrs; char *upn = NULL; size_t i; int cache_timeout; char *usn_value = NULL; char **missing = NULL; TALLOC_CTX *tmpctx = NULL; bool use_id_mapping; char *sid_str; char *dom_sid_str = NULL; struct sss_domain_info *subdomain; DEBUG(SSSDBG_TRACE_FUNC, "Save user\n"); tmpctx = talloc_new(NULL); if (!tmpctx) { ret = ENOMEM; goto done; } user_attrs = sysdb_new_attrs(tmpctx); if (user_attrs == NULL) { ret = ENOMEM; goto done; } /* Always store SID string if available */ ret = sdap_attrs_get_sid_str(tmpctx, opts->idmap_ctx, attrs, opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name, &sid_str); if (ret == EOK) { ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, sid_str); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add SID string: [%s]\n", sss_strerror(ret)); goto done; } } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "objectSID: not available for user\n"); sid_str = NULL; } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not identify objectSID: [%s]\n", sss_strerror(ret)); sid_str = NULL; } /* Always store UUID if available */ ret = sysdb_handle_original_uuid(opts->user_map[SDAP_AT_USER_UUID].def_name, attrs, opts->user_map[SDAP_AT_USER_UUID].sys_name, user_attrs, SYSDB_UUID); if (ret != EOK) { DEBUG((ret == ENOENT) ? SSSDBG_TRACE_ALL : SSSDBG_MINOR_FAILURE, "Failed to retrieve UUID [%d][%s].\n", ret, sss_strerror(ret)); } /* If this object has a SID available, we will determine the correct * domain by its SID. */ if (sid_str != NULL) { subdomain = find_domain_by_sid(get_domains_head(dom), sid_str); if (subdomain) { dom = subdomain; } else { DEBUG(SSSDBG_TRACE_FUNC, "SID %s does not belong to any known " "domain\n", sid_str); } } ret = sdap_get_user_primary_name(memctx, opts, attrs, dom, &user_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get user name\n"); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Processing user %s\n", user_name); if (opts->schema_type == SDAP_SCHEMA_AD) { ret = sysdb_attrs_get_string(attrs, opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &fullname); if (ret == EOK) { ret = sysdb_attrs_add_string(user_attrs, SYSDB_FULLNAME, fullname); if (ret != EOK) { goto done; } } else if (ret != ENOENT) { goto done; } } ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_PWD].sys_name, &el); if (ret) goto done; if (el->num_values == 0) pwd = NULL; else pwd = (const char *)el->values[0].data; ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_GECOS].sys_name, &el); if (ret) goto done; if (el->num_values == 0) gecos = NULL; else gecos = (const char *)el->values[0].data; if (!gecos) { /* Fall back to the user's full name */ ret = sysdb_attrs_get_el( attrs, opts->user_map[SDAP_AT_USER_FULLNAME].sys_name, &el); if (ret) goto done; if (el->num_values > 0) gecos = (const char *)el->values[0].data; } ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_HOME].sys_name, &el); if (ret) goto done; if (el->num_values == 0) homedir = NULL; else homedir = (const char *)el->values[0].data; ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_SHELL].sys_name, &el); if (ret) goto done; if (el->num_values == 0) shell = NULL; else shell = (const char *)el->values[0].data; use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx, dom->name, sid_str); /* Retrieve or map the UID as appropriate */ if (use_id_mapping) { if (sid_str == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "SID not available, cannot map a " \ "unix ID to user [%s].\n", user_name); ret = ENOENT; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Mapping user [%s] objectSID [%s] to unix ID\n", user_name, sid_str); /* Convert the SID into a UNIX user ID */ ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &uid); if (ret == ENOTSUP) { DEBUG(SSSDBG_TRACE_FUNC, "Skipping built-in object.\n"); ret = EOK; goto done; } else if (ret != EOK) { goto done; } /* Store the UID in the ldap_attrs so it doesn't get * treated as a missing attribute from LDAP and removed. */ ret = sdap_replace_id(attrs, SYSDB_UIDNUM, uid); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set the id-mapped UID\n"); goto done; } } else { ret = sysdb_attrs_get_uint32_t(attrs, opts->user_map[SDAP_AT_USER_UID].sys_name, &uid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "no uid provided for [%s] in domain [%s].\n", user_name, dom->name); ret = EINVAL; goto done; } } /* check that the uid is valid for this domain */ if (OUT_OF_ID_RANGE(uid, dom->id_min, dom->id_max)) { DEBUG(SSSDBG_OP_FAILURE, "User [%s] filtered out! (uid out of range)\n", user_name); ret = EINVAL; goto done; } if (use_id_mapping) { ret = sdap_get_idmap_primary_gid(opts, attrs, sid_str, dom_sid_str, &gid); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get the GID for [%s] in domain [%s].\n", user_name, dom->name); goto done; } if (IS_SUBDOMAIN(dom)) { /* For subdomain users, only create the private group as * the subdomain is an MPG domain. * But we have to save the GID of the original primary group * becasuse otherwise this information might be lost because * typically (Unix and AD) the user is not listed in his primary * group as a member. */ ret = sysdb_attrs_add_uint32(user_attrs, SYSDB_PRIMARY_GROUP_GIDNUM, (uint32_t) gid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_uint32 failed.\n"); goto done; } gid = 0; } /* Store the GID in the ldap_attrs so it doesn't get * treated as a missing attribute from LDAP and removed. */ ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid); if (ret != EOK) goto done; } else { ret = sysdb_attrs_get_uint32_t(attrs, opts->user_map[SDAP_AT_USER_GID].sys_name, &gid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "no gid provided for [%s] in domain [%s].\n", user_name, dom->name); ret = EINVAL; goto done; } } /* check that the gid is valid for this domain */ if (IS_SUBDOMAIN(dom) == false && OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) { DEBUG(SSSDBG_CRIT_FAILURE, "User [%s] filtered out! (primary gid out of range)\n", user_name); ret = EINVAL; goto done; } ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el); if (ret) { goto done; } if (!el || el->num_values == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "originalDN is not available for [%s].\n", user_name); } else { orig_dn = (const char *) el->values[0].data; DEBUG(SSSDBG_TRACE_INTERNAL, "Adding originalDN [%s] to attributes " "of [%s].\n", orig_dn, user_name); ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_DN, orig_dn); if (ret) { goto done; } } ret = sysdb_attrs_get_el(attrs, SYSDB_MEMBEROF, &el); if (ret) { goto done; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_FUNC, "Original memberOf is not available for [%s].\n", user_name); } else { DEBUG(SSSDBG_TRACE_FUNC, "Adding original memberOf attributes to [%s].\n", user_name); for (i = 0; i < el->num_values; i++) { ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF, (const char *) el->values[i].data); if (ret) { goto done; } } } ret = sdap_attrs_add_string(attrs, opts->user_map[SDAP_AT_USER_MODSTAMP].sys_name, "original mod-Timestamp", user_name, user_attrs); if (ret != EOK) { goto done; } ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_USN].sys_name, &el); if (ret) { goto done; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_FUNC, "Original USN value is not available for [%s].\n", user_name); } else { ret = sysdb_attrs_add_string(user_attrs, opts->user_map[SDAP_AT_USER_USN].sys_name, (const char*)el->values[0].data); if (ret) { goto done; } usn_value = talloc_strdup(tmpctx, (const char*)el->values[0].data); if (!usn_value) { ret = ENOMEM; goto done; } } ret = sysdb_attrs_get_el(attrs, opts->user_map[SDAP_AT_USER_PRINC].sys_name, &el); if (ret) { goto done; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_FUNC, "User principal is not available for [%s].\n", user_name); } else { upn = talloc_strdup(user_attrs, (const char*) el->values[0].data); if (!upn) { ret = ENOMEM; goto done; } if (dp_opt_get_bool(opts->basic, SDAP_FORCE_UPPER_CASE_REALM)) { make_realm_upper_case(upn); } DEBUG(SSSDBG_TRACE_FUNC, "Adding user principal [%s] to attributes of [%s].\n", upn, user_name); ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN, upn); if (ret) { goto done; } } for (i = SDAP_FIRST_EXTRA_USER_AT; i < opts->user_map_cnt; i++) { ret = sdap_attrs_add_list(attrs, opts->user_map[i].sys_name, NULL, user_name, user_attrs); if (ret) { goto done; } } cache_timeout = dom->user_timeout; ret = sdap_save_all_names(user_name, attrs, dom, user_attrs); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save user names\n"); goto done; } /* Make sure that any attributes we requested from LDAP that we * did not receive are also removed from the sysdb */ ret = list_missing_attrs(user_attrs, opts->user_map, opts->user_map_cnt, attrs, &missing); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Storing info for user %s\n", user_name); ret = sysdb_store_user(dom, user_name, pwd, uid, gid, gecos, homedir, shell, orig_dn, user_attrs, missing, cache_timeout, now); if (ret) goto done; if (_usn_value) { *_usn_value = talloc_steal(memctx, usn_value); } talloc_steal(memctx, user_attrs); ret = EOK; done: if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save user [%s]\n", user_name ? user_name : "Unknown"); } talloc_free(tmpctx); return ret; } /* ==Generic-Function-to-save-multiple-users============================= */ int sdap_save_users(TALLOC_CTX *memctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct sdap_options *opts, struct sysdb_attrs **users, int num_users, char **_usn_value) { TALLOC_CTX *tmpctx; char *higher_usn = NULL; char *usn_value; int ret; errno_t sret; int i; time_t now; bool in_transaction = false; if (num_users == 0) { /* Nothing to do if there are no users */ return EOK; } tmpctx = talloc_new(memctx); if (!tmpctx) { return ENOMEM; } ret = sysdb_transaction_start(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; now = time(NULL); for (i = 0; i < num_users; i++) { usn_value = NULL; ret = sdap_save_user(tmpctx, opts, dom, users[i], &usn_value, now); /* Do not fail completely on errors. * Just report the failure to save and go on */ if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store user %d. Ignoring.\n", i); } else { DEBUG(SSSDBG_TRACE_ALL, "User %d processed!\n", i); } if (usn_value) { if (higher_usn) { if ((strlen(usn_value) > strlen(higher_usn)) || (strcmp(usn_value, higher_usn) > 0)) { talloc_zfree(higher_usn); higher_usn = usn_value; } else { talloc_zfree(usn_value); } } else { higher_usn = usn_value; } } } ret = sysdb_transaction_commit(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction!\n"); goto done; } in_transaction = false; if (_usn_value) { *_usn_value = talloc_steal(memctx, higher_usn); } done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_zfree(tmpctx); return ret; } /* ==Search-Users-with-filter============================================= */ struct sdap_search_user_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; struct sss_domain_info *dom; const char **attrs; const char *base_filter; const char *filter; int timeout; enum sdap_entry_lookup_type lookup_type; char *higher_usn; struct sysdb_attrs **users; size_t count; size_t base_iter; struct sdap_search_base **search_bases; }; static errno_t sdap_search_user_next_base(struct tevent_req *req); static void sdap_search_user_copy_batch(struct sdap_search_user_state *state, struct sysdb_attrs **users, size_t count); static void sdap_search_user_process(struct tevent_req *subreq); struct tevent_req *sdap_search_user_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sdap_options *opts, struct sdap_search_base **search_bases, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout, enum sdap_entry_lookup_type lookup_type) { errno_t ret; struct tevent_req *req; struct sdap_search_user_state *state; req = tevent_req_create(memctx, &state, struct sdap_search_user_state); if (req == NULL) return NULL; state->ev = ev; state->opts = opts; state->dom = dom; state->sh = sh; state->attrs = attrs; state->higher_usn = NULL; state->users = NULL; state->count = 0; state->timeout = timeout; state->base_filter = filter; state->base_iter = 0; state->search_bases = search_bases; state->lookup_type = lookup_type; if (!state->search_bases) { DEBUG(SSSDBG_CRIT_FAILURE, "User lookup request without a search base\n"); ret = EINVAL; goto done; } ret = sdap_search_user_next_base(req); done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, state->ev); } return req; } static errno_t sdap_search_user_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_search_user_state *state; bool need_paging = false; int sizelimit = 0; state = tevent_req_data(req, struct sdap_search_user_state); talloc_zfree(state->filter); state->filter = sdap_combine_filters(state, state->base_filter, state->search_bases[state->base_iter]->filter); if (state->filter == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for users with base [%s]\n", state->search_bases[state->base_iter]->basedn); switch (state->lookup_type) { case SDAP_LOOKUP_SINGLE: break; /* Only requests that can return multiple entries should require * the paging control */ case SDAP_LOOKUP_WILDCARD: sizelimit = dp_opt_get_int(state->opts->basic, SDAP_WILDCARD_LIMIT); need_paging = true; break; case SDAP_LOOKUP_ENUMERATE: need_paging = true; break; } subreq = sdap_get_and_parse_generic_send( state, state->ev, state->opts, state->sh, state->search_bases[state->base_iter]->basedn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->user_map, state->opts->user_map_cnt, 0, NULL, NULL, sizelimit, state->timeout, need_paging); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_search_user_process, req); return EOK; } static void sdap_search_user_process(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_search_user_state *state = tevent_req_data(req, struct sdap_search_user_state); int ret; size_t count; struct sysdb_attrs **users; bool next_base = false; ret = sdap_get_and_parse_generic_recv(subreq, state, &count, &users); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_FUNC, "Search for users, returned %zu results.\n", count); if (state->lookup_type == SDAP_LOOKUP_WILDCARD || \ state->lookup_type == SDAP_LOOKUP_ENUMERATE || \ count == 0) { /* No users found in this search or looking up multiple entries */ next_base = true; } /* Add this batch of users to the list */ if (count > 0) { state->users = talloc_realloc(state, state->users, struct sysdb_attrs *, state->count + count + 1); if (!state->users) { tevent_req_error(req, ENOMEM); return; } sdap_search_user_copy_batch(state, users, count); } if (next_base) { state->base_iter++; if (state->search_bases[state->base_iter]) { /* There are more search bases to try */ ret = sdap_search_user_next_base(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } } /* No more search bases * Return ENOENT if no users were found */ if (state->count == 0) { tevent_req_error(req, ENOENT); return; } DEBUG(SSSDBG_TRACE_ALL, "Retrieved total %zu users\n", state->count); tevent_req_done(req); } static void sdap_search_user_copy_batch(struct sdap_search_user_state *state, struct sysdb_attrs **users, size_t count) { size_t copied; bool filter; /* Always copy all objects for wildcard lookups. */ filter = state->lookup_type == SDAP_LOOKUP_SINGLE ? true : false; copied = sdap_steal_objects_in_dom(state->opts, state->users, state->count, state->dom, users, count, filter); state->count += copied; state->users[state->count] = NULL; } int sdap_search_user_recv(TALLOC_CTX *memctx, struct tevent_req *req, char **higher_usn, struct sysdb_attrs ***users, size_t *count) { struct sdap_search_user_state *state = tevent_req_data(req, struct sdap_search_user_state); if (higher_usn) { *higher_usn = talloc_steal(memctx, state->higher_usn); } if (users) { *users = talloc_steal(memctx, state->users); } if (count) { *count = state->count; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==Search-And-Save-Users-with-filter============================================= */ struct sdap_get_users_state { struct sysdb_ctx *sysdb; struct sdap_options *opts; struct sss_domain_info *dom; char *higher_usn; struct sysdb_attrs **users; size_t count; }; static void sdap_get_users_done(struct tevent_req *subreq); struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sysdb_ctx *sysdb, struct sdap_options *opts, struct sdap_search_base **search_bases, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout, enum sdap_entry_lookup_type lookup_type) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct sdap_get_users_state *state; req = tevent_req_create(memctx, &state, struct sdap_get_users_state); if (!req) return NULL; state->sysdb = sysdb; state->opts = opts; state->dom = dom; subreq = sdap_search_user_send(state, ev, dom, opts, search_bases, sh, attrs, filter, timeout, lookup_type); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_get_users_done, req); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void sdap_get_users_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_users_state *state = tevent_req_data(req, struct sdap_get_users_state); int ret; ret = sdap_search_user_recv(state, subreq, &state->higher_usn, &state->users, &state->count); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to retrieve users\n"); tevent_req_error(req, ret); return; } ret = sdap_save_users(state, state->sysdb, state->dom, state->opts, state->users, state->count, &state->higher_usn); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store users.\n"); tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_ALL, "Saving %zu Users - Done\n", state->count); tevent_req_done(req); } int sdap_get_users_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **usn_value) { struct sdap_get_users_state *state = tevent_req_data(req, struct sdap_get_users_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (usn_value) { *usn_value = talloc_steal(mem_ctx, state->higher_usn); } return EOK; } /* ==Fetch-Fallback-local-user============================================ */ errno_t sdap_fallback_local_user(TALLOC_CTX *memctx, struct sdap_options *opts, const char *name, uid_t uid, struct sysdb_attrs ***reply) { struct sysdb_attrs **ua; struct sysdb_attrs *user; struct passwd *pwd; int ret; if (name) { pwd = getpwnam(name); } else { pwd = getpwuid(uid); } if (!pwd) { return errno ? errno : ENOENT; } ua = talloc_array(memctx, struct sysdb_attrs *, 2); if (!ua) { ret = ENOMEM; goto done; } ua[1] = NULL; user = sysdb_new_attrs(ua); if (!user) { ret = ENOMEM; goto done; } ua[0] = user; ret = sysdb_attrs_add_string(user, SYSDB_NAME, pwd->pw_name); if (ret != EOK) { goto done; } if (pwd->pw_passwd) { ret = sysdb_attrs_add_string(user, SYSDB_PWD, pwd->pw_passwd); if (ret != EOK) { goto done; } } ret = sysdb_attrs_add_long(user, SYSDB_UIDNUM, (long)pwd->pw_uid); if (ret != EOK) { goto done; } ret = sysdb_attrs_add_long(user, SYSDB_GIDNUM, (long)pwd->pw_gid); if (ret != EOK) { goto done; } if (pwd->pw_gecos) { ret = sysdb_attrs_add_string(user, SYSDB_GECOS, pwd->pw_gecos); if (ret != EOK) { goto done; } } if (pwd->pw_dir) { ret = sysdb_attrs_add_string(user, SYSDB_HOMEDIR, pwd->pw_dir); if (ret != EOK) { goto done; } } if (pwd->pw_shell) { ret = sysdb_attrs_add_string(user, SYSDB_SHELL, pwd->pw_shell); if (ret != EOK) { goto done; } } done: if (ret != EOK) { talloc_free(ua); } else { *reply = ua; } return ret; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_access.c0000644000000000000000000000007412703456111020456 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.768794015 sssd-1.13.4/src/providers/ldap/ldap_access.c0000644002412700241270000000703712703456111022134 0ustar00jhrozekjhrozek00000000000000/* SSSD ldap_access.c Authors: Simo Sorce Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "src/util/util.h" #include "src/providers/data_provider.h" #include "src/providers/dp_backend.h" #include "src/providers/ldap/sdap_access.h" #include "providers/ldap/ldap_common.h" static void sdap_access_reply(struct be_req *be_req, int pam_status) { struct pam_data *pd; pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); pd->pam_status = pam_status; if (pam_status == PAM_SUCCESS || pam_status == PAM_PERM_DENIED || pam_status == PAM_ACCT_EXPIRED) { be_req_terminate(be_req, DP_ERR_OK, pam_status, NULL); } else { be_req_terminate(be_req, DP_ERR_FATAL, pam_status, NULL); } } static void sdap_access_done(struct tevent_req *req); void sdap_pam_access_handler(struct be_req *breq) { struct be_ctx *be_ctx = be_req_get_be_ctx(breq); struct pam_data *pd; struct tevent_req *req; struct sdap_access_ctx *access_ctx; struct sss_domain_info *dom; pd = talloc_get_type(be_req_get_data(breq), struct pam_data); access_ctx = talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data, struct sdap_access_ctx); dom = be_ctx->domain; if (strcasecmp(pd->domain, be_ctx->domain->name) != 0) { /* Subdomain request, verify subdomain */ dom = find_domain_by_name(be_ctx->domain, pd->domain, true); } req = sdap_access_send(breq, be_ctx->ev, be_ctx, dom, access_ctx, access_ctx->id_ctx->conn, pd); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to start sdap_access request\n"); sdap_access_reply(breq, PAM_SYSTEM_ERR); return; } tevent_req_set_callback(req, sdap_access_done, breq); } static void sdap_access_done(struct tevent_req *req) { errno_t ret; int pam_status; struct be_req *breq = tevent_req_callback_data(req, struct be_req); ret = sdap_access_recv(req); talloc_zfree(req); switch (ret) { case EOK: pam_status = PAM_SUCCESS; break; case ERR_ACCESS_DENIED: pam_status = PAM_PERM_DENIED; break; case ERR_ACCOUNT_EXPIRED: pam_status = PAM_ACCT_EXPIRED; break; case ERR_PASSWORD_EXPIRED: pam_status = PAM_PERM_DENIED; break; case ERR_PASSWORD_EXPIRED_REJECT: pam_status = PAM_PERM_DENIED; break; case ERR_PASSWORD_EXPIRED_WARN: pam_status = PAM_SUCCESS; break; case ERR_PASSWORD_EXPIRED_RENEW: pam_status = PAM_NEW_AUTHTOK_REQD; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Error retrieving access check result.\n"); pam_status = PAM_SYSTEM_ERR; break; } sdap_access_reply(breq, pam_status); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_common.c0000644000000000000000000000007412703456111020505 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.775794039 sssd-1.13.4/src/providers/ldap/ldap_common.c0000644002412700241270000006774512703456111022177 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Provider Common Functions Authors: Simo Sorce Copyright (C) 2008-2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ldap/ldap_common.h" #include "providers/fail_over.h" #include "providers/ldap/sdap_async_private.h" #include "providers/krb5/krb5_common.h" #include "db/sysdb_sudo.h" #include "db/sysdb_services.h" #include "db/sysdb_autofs.h" #include "util/sss_krb5.h" #include "util/crypto/sss_crypto.h" #include "providers/ldap/sdap_idmap.h" /* a fd the child process would log into */ int ldap_child_debug_fd = -1; void sdap_handler_done(struct be_req *req, int dp_err, int error, const char *errstr) { return be_req_terminate(req, dp_err, error, errstr); } int ldap_id_setup_tasks(struct sdap_id_ctx *ctx) { return sdap_id_setup_tasks(ctx->be, ctx, ctx->opts->sdom, ldap_enumeration_send, ldap_enumeration_recv, ctx); } int sdap_id_setup_tasks(struct be_ctx *be_ctx, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, be_ptask_send_t send_fn, be_ptask_recv_t recv_fn, void *pvt) { int ret; /* set up enumeration task */ if (sdom->dom->enumerate) { DEBUG(SSSDBG_TRACE_FUNC, "Setting up enumeration for %s\n", sdom->dom->name); ret = ldap_setup_enumeration(be_ctx, ctx->opts, sdom, send_fn, recv_fn, pvt); } else { /* the enumeration task, runs the cleanup process by itself, * but if enumeration is not running we need to schedule it */ DEBUG(SSSDBG_TRACE_FUNC, "Setting up cleanup task for %s\n", sdom->dom->name); ret = ldap_setup_cleanup(ctx, sdom); } return ret; } static void sdap_uri_callback(void *private_data, struct fo_server *server) { TALLOC_CTX *tmp_ctx = NULL; struct sdap_service *service; struct resolv_hostent *srvaddr; struct sockaddr_storage *sockaddr; const char *tmp; const char *srv_name; char *new_uri; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed\n"); return; } service = talloc_get_type(private_data, struct sdap_service); if (!service) { talloc_free(tmp_ctx); return; } tmp = (const char *)fo_get_server_user_data(server); srvaddr = fo_get_server_hostent(server); if (!srvaddr) { DEBUG(SSSDBG_CRIT_FAILURE, "FATAL: No hostent available for server (%s)\n", fo_get_server_str_name(server)); talloc_free(tmp_ctx); return; } sockaddr = resolv_get_sockaddr_address(tmp_ctx, srvaddr, fo_get_server_port(server)); if (sockaddr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_sockaddr_address failed.\n"); talloc_free(tmp_ctx); return; } if (fo_is_srv_lookup(server)) { if (!tmp) { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown service, using ldap\n"); tmp = SSS_LDAP_SRV_NAME; } srv_name = fo_get_server_name(server); if (srv_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get server host name\n"); talloc_free(tmp_ctx); return; } new_uri = talloc_asprintf(service, "%s://%s:%d", tmp, srv_name, fo_get_server_port(server)); } else { new_uri = talloc_strdup(service, tmp); } if (!new_uri) { DEBUG(SSSDBG_OP_FAILURE, "Failed to copy URI ...\n"); talloc_free(tmp_ctx); return; } DEBUG(SSSDBG_TRACE_FUNC, "Constructed uri '%s'\n", new_uri); /* free old one and replace with new one */ talloc_zfree(service->uri); service->uri = new_uri; talloc_zfree(service->sockaddr); service->sockaddr = talloc_steal(service, sockaddr); talloc_free(tmp_ctx); } static void sdap_finalize(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { char *realm = (char *) private_data; int ret; ret = remove_krb5_info_files(se, realm); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "remove_krb5_info_files failed.\n"); } orderly_shutdown(0); } errno_t sdap_install_sigterm_handler(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *realm) { char *sig_realm; struct tevent_signal *sige; BlockSignals(false, SIGTERM); sig_realm = talloc_strdup(mem_ctx, realm); if (sig_realm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed!\n"); return ENOMEM; } sige = tevent_add_signal(ev, mem_ctx, SIGTERM, SA_SIGINFO, sdap_finalize, sig_realm); if (sige == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_signal failed.\n"); talloc_free(sig_realm); return ENOMEM; } talloc_steal(sige, sig_realm); return EOK; } void sdap_remove_kdcinfo_files_callback(void *pvt) { int ret; TALLOC_CTX *tmp_ctx = NULL; struct remove_info_files_ctx *ctx = talloc_get_type(pvt, struct remove_info_files_ctx); ret = be_fo_run_callbacks_at_next_request(ctx->be_ctx, ctx->kdc_service_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_fo_run_callbacks_at_next_request failed, " "krb5 info files will not be removed, because " "it is unclear if they will be recreated properly.\n"); return; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed, cannot remove krb5 info files.\n"); return; } ret = remove_krb5_info_files(tmp_ctx, ctx->realm); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "remove_krb5_info_files failed.\n"); } talloc_zfree(tmp_ctx); } errno_t sdap_install_offline_callback(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, const char *realm, const char *service_name) { int ret; struct remove_info_files_ctx *ctx; ctx = talloc_zero(mem_ctx, struct remove_info_files_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zfree failed.\n"); return ENOMEM; } ctx->be_ctx = be_ctx; ctx->realm = talloc_strdup(ctx, realm); ctx->kdc_service_name = talloc_strdup(ctx, service_name); if (ctx->realm == NULL || ctx->kdc_service_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed!\n"); ret = ENOMEM; goto done; } ret = be_add_offline_cb(ctx, be_ctx, sdap_remove_kdcinfo_files_callback, ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_add_offline_cb failed.\n"); goto done; } ret = EOK; done: if (ret != EOK) { talloc_zfree(ctx); } return ret; } errno_t sdap_set_sasl_options(struct sdap_options *id_opts, char *default_primary, char *default_realm, const char *keytab_path) { errno_t ret; TALLOC_CTX *tmp_ctx; char *sasl_primary; char *desired_primary; char *primary_realm; char *sasl_realm; char *desired_realm; bool primary_requested = true; bool realm_requested = true; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; /* Configuration of SASL auth ID and realm */ desired_primary = dp_opt_get_string(id_opts->basic, SDAP_SASL_AUTHID); if (!desired_primary) { primary_requested = false; desired_primary = default_primary; } if ((primary_realm = strchr(desired_primary, '@'))) { *primary_realm = '\0'; desired_realm = primary_realm+1; DEBUG(SSSDBG_TRACE_INTERNAL, "authid contains realm [%s]\n", desired_realm); } else { desired_realm = dp_opt_get_string(id_opts->basic, SDAP_SASL_REALM); if (!desired_realm) { realm_requested = false; desired_realm = default_realm; } } DEBUG(SSSDBG_CONF_SETTINGS, "Will look for %s@%s in %s\n", desired_primary, desired_realm, keytab_path ? keytab_path : "default keytab"); ret = select_principal_from_keytab(tmp_ctx, desired_primary, desired_realm, keytab_path, NULL, &sasl_primary, &sasl_realm); if (ret != EOK) { goto done; } if (primary_requested && strcmp(desired_primary, sasl_primary) != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Configured SASL auth ID not found in keytab. " "Requested %s, found %s\n", desired_primary, sasl_primary); } if (realm_requested && strcmp(desired_realm, sasl_realm) != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Configured SASL realm not found in keytab. " "Requested %s, found %s\n", desired_realm, sasl_realm); } ret = dp_opt_set_string(id_opts->basic, SDAP_SASL_AUTHID, sasl_primary); if (ret != EOK) { goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", id_opts->basic[SDAP_SASL_AUTHID].opt_name, dp_opt_get_string(id_opts->basic, SDAP_SASL_AUTHID)); ret = dp_opt_set_string(id_opts->basic, SDAP_SASL_REALM, sasl_realm); if (ret != EOK) { goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n", id_opts->basic[SDAP_SASL_REALM].opt_name, dp_opt_get_string(id_opts->basic, SDAP_SASL_REALM)); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static const char * sdap_gssapi_get_default_realm(TALLOC_CTX *mem_ctx) { char *krb5_realm = NULL; const char *realm = NULL; krb5_error_code krberr; krb5_context context = NULL; krberr = krb5_init_context(&context); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, "Failed to init kerberos context\n"); goto done; } krberr = krb5_get_default_realm(context, &krb5_realm); if (krberr) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get default realm name: %s\n", sss_krb5_get_error_message(context, krberr)); goto done; } realm = talloc_strdup(mem_ctx, krb5_realm); krb5_free_default_realm(context, krb5_realm); if (!realm) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory\n"); goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Will use default realm %s\n", realm); done: if (context) krb5_free_context(context); return realm; } const char *sdap_gssapi_realm(struct dp_option *opts) { const char *realm; realm = dp_opt_get_cstring(opts, SDAP_SASL_REALM); if (!realm) { realm = dp_opt_get_cstring(opts, SDAP_KRB5_REALM); } return realm; } int sdap_gssapi_init(TALLOC_CTX *mem_ctx, struct dp_option *opts, struct be_ctx *bectx, struct sdap_service *sdap_service, struct krb5_service **krb5_service) { int ret; const char *krb5_servers; const char *krb5_backup_servers; const char *krb5_realm; const char *krb5_opt_realm; struct krb5_service *service = NULL; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; krb5_servers = dp_opt_get_string(opts, SDAP_KRB5_KDC); krb5_backup_servers = dp_opt_get_string(opts, SDAP_KRB5_BACKUP_KDC); krb5_opt_realm = sdap_gssapi_realm(opts); if (krb5_opt_realm == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing krb5_realm option, will use libkrb default\n"); krb5_realm = sdap_gssapi_get_default_realm(tmp_ctx); if (krb5_realm == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot determine the Kerberos realm, aborting\n"); ret = EIO; goto done; } } else { krb5_realm = talloc_strdup(tmp_ctx, krb5_opt_realm); if (krb5_realm == NULL) { ret = ENOMEM; goto done; } } ret = krb5_service_init(mem_ctx, bectx, SSS_KRB5KDC_FO_SRV, krb5_servers, krb5_backup_servers, krb5_realm, dp_opt_get_bool(opts, SDAP_KRB5_USE_KDCINFO), &service); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init KRB5 failover service!\n"); goto done; } ret = sdap_install_sigterm_handler(mem_ctx, bectx->ev, krb5_realm); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to install sigterm handler\n"); goto done; } ret = sdap_install_offline_callback(mem_ctx, bectx, krb5_realm, SSS_KRB5KDC_FO_SRV); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to install sigterm handler\n"); goto done; } sdap_service->kinit_service_name = talloc_strdup(sdap_service, service->name); if (sdap_service->kinit_service_name == NULL) { ret = ENOMEM; goto done; } ret = EOK; *krb5_service = service; done: talloc_free(tmp_ctx); if (ret != EOK) talloc_free(service); return ret; } static errno_t _sdap_urls_init(struct be_ctx *ctx, struct sdap_service *service, const char *service_name, const char *dns_service_name, const char *urls, bool primary) { TALLOC_CTX *tmp_ctx; char *srv_user_data; char **list = NULL; LDAPURLDesc *lud; errno_t ret = 0; int i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } /* split server parm into a list */ ret = split_on_separator(tmp_ctx, urls, ',', true, true, &list, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse server list!\n"); goto done; } /* now for each URI add a new server to the failover service */ for (i = 0; list[i]; i++) { if (be_fo_is_srv_identifier(list[i])) { if (!primary) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add server [%s] to failover service: " "SRV resolution only allowed for primary servers!\n", list[i]); continue; } if (!dns_service_name) { DEBUG(SSSDBG_FATAL_FAILURE, "Missing DNS service name for service [%s].\n", service_name); ret = EINVAL; goto done; } srv_user_data = talloc_strdup(service, dns_service_name); if (!srv_user_data) { ret = ENOMEM; goto done; } ret = be_fo_add_srv_server(ctx, service_name, dns_service_name, NULL, BE_FO_PROTO_TCP, false, srv_user_data); if (ret) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n"); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Added service lookup\n"); continue; } ret = ldap_url_parse(list[i], &lud); if (ret != LDAP_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse ldap URI (%s)!\n", list[i]); ret = EINVAL; goto done; } if (lud->lud_host == NULL) { DEBUG(SSSDBG_OP_FAILURE, "The LDAP URI (%s) did not contain a host name\n", list[i]); ldap_free_urldesc(lud); continue; } DEBUG(SSSDBG_TRACE_FUNC, "Added URI %s\n", list[i]); talloc_steal(service, list[i]); /* It could be ipv6 address in square brackets. Remove * the brackets if needed. */ ret = remove_ipv6_brackets(lud->lud_host); if (ret != EOK) { goto done; } ret = be_fo_add_server(ctx, service->name, lud->lud_host, lud->lud_port, list[i], primary); ldap_free_urldesc(lud); if (ret) { goto done; } } done: talloc_free(tmp_ctx); return ret; } static inline errno_t sdap_primary_urls_init(struct be_ctx *ctx, struct sdap_service *service, const char *service_name, const char *dns_service_name, const char *urls) { return _sdap_urls_init(ctx, service, service_name, dns_service_name, urls, true); } static inline errno_t sdap_backup_urls_init(struct be_ctx *ctx, struct sdap_service *service, const char *service_name, const char *dns_service_name, const char *urls) { return _sdap_urls_init(ctx, service, service_name, dns_service_name, urls, false); } static int ldap_user_data_cmp(void *ud1, void *ud2) { return strcasecmp((char*) ud1, (char*) ud2); } int sdap_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, const char *service_name, const char *dns_service_name, const char *urls, const char *backup_urls, struct sdap_service **_service) { TALLOC_CTX *tmp_ctx; struct sdap_service *service; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } service = talloc_zero(tmp_ctx, struct sdap_service); if (!service) { ret = ENOMEM; goto done; } ret = be_fo_add_service(ctx, service_name, ldap_user_data_cmp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create failover service!\n"); goto done; } service->name = talloc_strdup(service, service_name); if (!service->name) { ret = ENOMEM; goto done; } if (!urls) { DEBUG(SSSDBG_CONF_SETTINGS, "No primary servers defined, using service discovery\n"); urls = BE_SRV_IDENTIFIER; } ret = sdap_primary_urls_init(ctx, service, service_name, dns_service_name, urls); if (ret != EOK) { goto done; } if (backup_urls) { ret = sdap_backup_urls_init(ctx, service, service_name, dns_service_name, backup_urls); if (ret != EOK) { goto done; } } ret = be_fo_service_add_callback(memctx, ctx, service->name, sdap_uri_callback, service); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add failover callback!\n"); goto done; } ret = EOK; done: if (ret == EOK) { *_service = talloc_steal(memctx, service); } talloc_zfree(tmp_ctx); return ret; } errno_t string_to_shadowpw_days(const char *s, long *d) { long l; char *endptr; if (s == NULL || *s == '\0') { *d = -1; return EOK; } errno = 0; l = strtol(s, &endptr, 10); if (errno != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "strtol failed [%d][%s].\n", errno, strerror(errno)); return errno; } if (*endptr != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Input string [%s] is invalid.\n", s); return EINVAL; } if (l < -1) { DEBUG(SSSDBG_CRIT_FAILURE, "Input string contains not allowed negative value [%ld].\n", l); return EINVAL; } *d = l; return EOK; } errno_t get_sysdb_attr_name(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, size_t map_size, const char *ldap_name, char **sysdb_name) { size_t i; for (i = 0; i < map_size; i++) { /* Skip map entries with no name (may depend on * schema selected) */ if (!map[i].name) continue; /* Check if it is a mapped attribute */ if(strcasecmp(ldap_name, map[i].name) == 0) break; } if (i < map_size) { /* We found a mapped name, return that */ *sysdb_name = talloc_strdup(mem_ctx, map[i].sys_name); } else { /* Not mapped, use the same name */ *sysdb_name = talloc_strdup(mem_ctx, ldap_name); } if (!*sysdb_name) { return ENOMEM; } return EOK; } errno_t list_missing_attrs(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, size_t map_size, struct sysdb_attrs *recvd_attrs, char ***missing_attrs) { errno_t ret; size_t attr_count = 0; size_t i, j, k; char **missing = NULL; const char **expected_attrs; char *sysdb_name; TALLOC_CTX *tmp_ctx; if (!recvd_attrs || !missing_attrs) { return EINVAL; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = build_attrs_from_map(tmp_ctx, map, map_size, NULL, &expected_attrs, &attr_count); if (ret != EOK) { goto done; } /* Allocate the maximum possible values for missing_attrs, to * be on the safe side */ missing = talloc_array(tmp_ctx, char *, attr_count + 2); if (!missing) { ret = ENOMEM; goto done; } k = 0; /* Check for each expected attribute */ for (i = 0; i < attr_count; i++) { ret = get_sysdb_attr_name(tmp_ctx, map, map_size, expected_attrs[i], &sysdb_name); if (ret != EOK) { goto done; } /* objectClass is a special-case and we need to * check for it explicitly. */ if (strcasecmp(sysdb_name, "objectClass") == 0) { talloc_free(sysdb_name); continue; } /* GECOS is another special case. Its value can come * either from the 'gecos' attribute or the 'cn' * attribute. It's best if we just never remove it. */ if (strcasecmp(sysdb_name, SYSDB_GECOS) == 0) { talloc_free(sysdb_name); continue; } for (j = 0; j < recvd_attrs->num; j++) { /* Check whether this expected attribute appeared in the * received attributes and had a non-zero number of * values. */ if ((strcasecmp(recvd_attrs->a[j].name, sysdb_name) == 0) && (recvd_attrs->a[j].num_values > 0)) { break; } } if (j < recvd_attrs->num) { /* Attribute was found, therefore not missing */ talloc_free(sysdb_name); } else { /* Attribute could not be found. Add to the missing list */ missing[k] = talloc_steal(missing, sysdb_name); k++; /* Remove originalMemberOf as well if MemberOf is missing */ if (strcmp(sysdb_name, SYSDB_MEMBEROF) == 0) { missing[k] = talloc_strdup(missing, SYSDB_ORIG_MEMBEROF); k++; } } } if (k == 0) { *missing_attrs = NULL; } else { /* Terminate the list */ missing[k] = NULL; *missing_attrs = talloc_steal(mem_ctx, missing); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } bool sdap_is_secure_uri(const char *uri) { /* LDAPS URI's are secure channels */ if (strncasecmp(uri, LDAP_SSL_URI, strlen(LDAP_SSL_URI)) == 0) { return true; } return false; } char *sdap_get_access_filter(TALLOC_CTX *mem_ctx, const char *base_filter) { char *filter = NULL; if (base_filter == NULL) return NULL; if (base_filter[0] == '(') { /* This filter is wrapped in parentheses. * Pass it as-is to the openldap libraries. */ filter = talloc_strdup(mem_ctx, base_filter); } else { filter = talloc_asprintf(mem_ctx, "(%s)", base_filter); } return filter; } errno_t sdap_attrs_get_sid_str(TALLOC_CTX *mem_ctx, struct sdap_idmap_ctx *idmap_ctx, struct sysdb_attrs *sysdb_attrs, const char *sid_attr, char **_sid_str) { errno_t ret; enum idmap_error_code err; struct ldb_message_element *el; char *sid_str; ret = sysdb_attrs_get_el(sysdb_attrs, sid_attr, &el); if (ret != EOK || el->num_values != 1) { DEBUG(SSSDBG_TRACE_LIBS, "No [%s] attribute. [%d][%s]\n", sid_attr, el->num_values, strerror(ret)); return ENOENT; } if (el->values[0].length > 2 && el->values[0].data[0] == 'S' && el->values[0].data[1] == '-') { sid_str = talloc_strndup(mem_ctx, (char *) el->values[0].data, el->values[0].length); if (sid_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); return ENOMEM; } } else { err = sss_idmap_bin_sid_to_sid(idmap_ctx->map, el->values[0].data, el->values[0].length, &sid_str); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not convert SID: [%s]\n", idmap_error_string(err)); return EIO; } } *_sid_str = talloc_steal(mem_ctx, sid_str); return EOK; } struct sdap_id_conn_ctx * sdap_id_ctx_conn_add(struct sdap_id_ctx *id_ctx, struct sdap_service *sdap_service) { struct sdap_id_conn_ctx *conn; errno_t ret; conn = talloc_zero(id_ctx, struct sdap_id_conn_ctx); if (conn == NULL) { return NULL; } conn->service = talloc_steal(conn, sdap_service); conn->id_ctx = id_ctx; /* Create a connection cache */ ret = sdap_id_conn_cache_create(conn, id_ctx, conn, &conn->conn_cache); if (ret != EOK) { talloc_free(conn); return NULL; } DLIST_ADD_END(id_ctx->conn, conn, struct sdap_id_conn_ctx *); return conn; } struct sdap_id_ctx * sdap_id_ctx_new(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, struct sdap_service *sdap_service) { struct sdap_id_ctx *sdap_ctx; sdap_ctx = talloc_zero(mem_ctx, struct sdap_id_ctx); if (sdap_ctx == NULL) { return NULL; } sdap_ctx->be = bectx; /* There should be at least one connection context */ sdap_ctx->conn = sdap_id_ctx_conn_add(sdap_ctx, sdap_service); if (sdap_ctx->conn == NULL) { talloc_free(sdap_ctx); return NULL; } return sdap_ctx; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_services.c0000644000000000000000000000007312703456111022243 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.786794076 sssd-1.13.4/src/providers/ldap/sdap_async_services.c0000644002412700241270000004567412703456111023733 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "db/sysdb_services.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/ldap_common.h" struct sdap_get_services_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; struct sss_domain_info *dom; struct sysdb_ctx *sysdb; const char **attrs; const char *base_filter; char *filter; int timeout; bool enumeration; char *higher_usn; struct sysdb_attrs **services; size_t count; size_t base_iter; struct sdap_search_base **search_bases; }; static errno_t sdap_get_services_next_base(struct tevent_req *req); static void sdap_get_services_process(struct tevent_req *subreq); static errno_t sdap_save_services(TALLOC_CTX *memctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct sdap_options *opts, struct sysdb_attrs **services, size_t num_services, char **_usn_value); static errno_t sdap_save_service(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sdap_options *opts, struct sss_domain_info *dom, struct sysdb_attrs *attrs, char **_usn_value, time_t now); struct tevent_req * sdap_get_services_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sysdb_ctx *sysdb, struct sdap_options *opts, struct sdap_search_base **search_bases, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout, bool enumeration) { errno_t ret; struct tevent_req *req; struct sdap_get_services_state *state; req = tevent_req_create(memctx, &state, struct sdap_get_services_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->dom = dom; state->sh = sh; state->sysdb = sysdb; state->attrs = attrs; state->higher_usn = NULL; state->services = NULL; state->count = 0; state->timeout = timeout; state->base_filter = filter; state->base_iter = 0; state->search_bases = search_bases; state->enumeration = enumeration; if (!state->search_bases) { DEBUG(SSSDBG_CRIT_FAILURE, "Services lookup request without a search base\n"); ret = EINVAL; goto done; } ret = sdap_get_services_next_base(req); done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, state->ev); } return req; } static errno_t sdap_get_services_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_get_services_state *state; state = tevent_req_data(req, struct sdap_get_services_state); talloc_zfree(state->filter); state->filter = sdap_combine_filters(state, state->base_filter, state->search_bases[state->base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for services with base [%s]\n", state->search_bases[state->base_iter]->basedn); subreq = sdap_get_generic_send( state, state->ev, state->opts, state->sh, state->search_bases[state->base_iter]->basedn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->service_map, SDAP_OPTS_SERVICES, state->timeout, state->enumeration); /* If we're enumerating, we need paging */ if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_get_services_process, req); return EOK; } static void sdap_get_services_process(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_services_state *state = tevent_req_data(req, struct sdap_get_services_state); int ret; size_t count, i; struct sysdb_attrs **services; bool next_base = false; ret = sdap_get_generic_recv(subreq, state, &count, &services); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_FUNC, "Search for services, returned %zu results.\n", count); if (state->enumeration || count == 0) { /* No services found in this search or enumerating */ next_base = true; } /* Add this batch of sevices to the list */ if (count > 0) { state->services = talloc_realloc(state, state->services, struct sysdb_attrs *, state->count + count + 1); if (!state->services) { tevent_req_error(req, ENOMEM); return; } /* Copy the new services into the list */ for (i = 0; i < count; i++) { state->services[state->count + i] = talloc_steal(state->services, services[i]); } state->count += count; state->services[state->count] = NULL; } if (next_base) { state->base_iter++; if (state->search_bases[state->base_iter]) { /* There are more search bases to try */ ret = sdap_get_services_next_base(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } } /* No more search bases * Return ENOENT if no services were found */ if (state->count == 0) { tevent_req_error(req, ENOENT); return; } ret = sdap_save_services(state, state->sysdb, state->dom, state->opts, state->services, state->count, &state->higher_usn); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to store services.\n"); tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_INTERNAL, "Saving %zu services - Done\n", state->count); tevent_req_done(req); } static errno_t sdap_save_services(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct sdap_options *opts, struct sysdb_attrs **services, size_t num_services, char **_usn_value) { errno_t ret, sret; time_t now; size_t i; bool in_transaction = false; char *higher_usn = NULL; char *usn_value; TALLOC_CTX *tmp_ctx; if (num_services == 0) { /* Nothing to do */ return ENOENT; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; now = time(NULL); for (i = 0; i < num_services; i++) { usn_value = NULL; ret = sdap_save_service(tmp_ctx, sysdb, opts, dom, services[i], &usn_value, now); /* Do not fail completely on errors. * Just report the failure to save and go on */ if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to store service %zu. Ignoring.\n", i); } else { DEBUG(SSSDBG_TRACE_INTERNAL, "Service [%zu/%zu] processed!\n", i, num_services); } if (usn_value) { if (higher_usn) { if ((strlen(usn_value) > strlen(higher_usn)) || (strcmp(usn_value, higher_usn) > 0)) { talloc_zfree(higher_usn); higher_usn = usn_value; } else { talloc_zfree(usn_value); } } else { higher_usn = usn_value; } } } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction!\n"); goto done; } in_transaction = false; if (_usn_value) { *_usn_value = talloc_steal(mem_ctx, higher_usn); } done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction!\n"); } } talloc_free(tmp_ctx); return ret; } static errno_t sdap_save_service(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sdap_options *opts, struct sss_domain_info *dom, struct sysdb_attrs *attrs, char **_usn_value, time_t now) { errno_t ret; TALLOC_CTX *tmp_ctx = NULL; struct sysdb_attrs *svc_attrs; struct ldb_message_element *el; char *usn_value = NULL; const char *name = NULL; const char **aliases; const char **protocols; const char **cased_protocols; const char **store_protocols; char **missing; uint16_t port; uint64_t cache_timeout; DEBUG(SSSDBG_TRACE_ALL, "Saving service\n"); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } svc_attrs = sysdb_new_attrs(tmp_ctx); if (!svc_attrs) { ret = ENOMEM; goto done; } /* Identify the primary name of this services */ ret = sysdb_attrs_primary_name( sysdb, attrs, opts->service_map[SDAP_AT_SERVICE_NAME].name, &name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not determine the primary name of the service\n"); goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Primary name: [%s]\n", name); /* Handle any available aliases */ ret = sysdb_attrs_get_aliases(tmp_ctx, attrs, name, !dom->case_sensitive, &aliases); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to identify service aliases\n"); goto done; } /* Get the port number */ ret = sysdb_attrs_get_uint16_t(attrs, SYSDB_SVC_PORT, &port); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to identify service port: [%s]\n", strerror(ret)); goto done; } /* Get the protocols this service offers on that port */ ret = sysdb_attrs_get_string_array(attrs, SYSDB_SVC_PROTO, tmp_ctx, &protocols); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to identify service protocols: [%s]\n", strerror(ret)); goto done; } if (dom->case_sensitive == false) { /* Don't perform the extra mallocs if not necessary */ ret = sss_get_cased_name_list(tmp_ctx, protocols, dom->case_sensitive, &cased_protocols); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get case_sensitive protocols names: [%s]\n", strerror(ret)); goto done; } } store_protocols = dom->case_sensitive ? protocols : cased_protocols; /* Get the USN value, if available */ ret = sysdb_attrs_get_el(attrs, opts->service_map[SDAP_AT_SERVICE_USN].sys_name, &el); if (ret && ret != ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to retrieve USN value: [%s]\n", strerror(ret)); goto done; } if (ret == ENOENT || el->num_values == 0) { DEBUG(SSSDBG_TRACE_LIBS, "Original USN value is not available for [%s].\n", name); } else { ret = sysdb_attrs_add_string(svc_attrs, opts->service_map[SDAP_AT_SERVICE_USN].sys_name, (const char*)el->values[0].data); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add USN value: [%s]\n", strerror(ret)); goto done; } usn_value = talloc_strdup(tmp_ctx, (const char*)el->values[0].data); if (!usn_value) { ret = ENOMEM; goto done; } } /* Make sure to remove any extra attributes from the sysdb * that have been removed from LDAP */ ret = list_missing_attrs(svc_attrs, opts->service_map, SDAP_OPTS_SERVICES, attrs, &missing); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to identify removed attributes: [%s]\n", strerror(ret)); goto done; } cache_timeout = dom->service_timeout; ret = sysdb_store_service(dom, name, port, aliases, store_protocols, svc_attrs, missing, cache_timeout, now); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to store service in the sysdb: [%s]\n", strerror(ret)); goto done; } *_usn_value = talloc_steal(mem_ctx, usn_value); done: talloc_free(tmp_ctx); return ret; } errno_t sdap_get_services_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **usn_value) { struct sdap_get_services_state *state = tevent_req_data(req, struct sdap_get_services_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (usn_value) { *usn_value = talloc_steal(mem_ctx, state->higher_usn); } return EOK; } /* Enumeration routines */ struct enum_services_state { struct tevent_context *ev; struct sdap_id_ctx *id_ctx; struct sdap_id_op *op; struct sss_domain_info *domain; struct sysdb_ctx *sysdb; char *filter; const char **attrs; }; static void enum_services_op_done(struct tevent_req *subreq); struct tevent_req * enum_services_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *id_ctx, struct sdap_id_op *op, bool purge) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct enum_services_state *state; req = tevent_req_create(memctx, &state, struct enum_services_state); if (!req) return NULL; state->ev = ev; state->id_ctx = id_ctx; state->domain = id_ctx->be->domain; state->sysdb = id_ctx->be->domain->sysdb; state->op = op; if (id_ctx->srv_opts && id_ctx->srv_opts->max_service_value && !purge) { state->filter = talloc_asprintf( state, "(&(objectclass=%s)(%s=*)(%s=*)(%s=*)(%s>=%s)(!(%s=%s)))", id_ctx->opts->service_map[SDAP_OC_SERVICE].name, id_ctx->opts->service_map[SDAP_AT_SERVICE_NAME].name, id_ctx->opts->service_map[SDAP_AT_SERVICE_PORT].name, id_ctx->opts->service_map[SDAP_AT_SERVICE_PROTOCOL].name, id_ctx->opts->service_map[SDAP_AT_SERVICE_USN].name, id_ctx->srv_opts->max_service_value, id_ctx->opts->service_map[SDAP_AT_SERVICE_USN].name, id_ctx->srv_opts->max_service_value); } else { state->filter = talloc_asprintf( state, "(&(objectclass=%s)(%s=*)(%s=*)(%s=*))", id_ctx->opts->service_map[SDAP_OC_SERVICE].name, id_ctx->opts->service_map[SDAP_AT_SERVICE_NAME].name, id_ctx->opts->service_map[SDAP_AT_SERVICE_PORT].name, id_ctx->opts->service_map[SDAP_AT_SERVICE_PROTOCOL].name); } if (!state->filter) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to build base filter\n"); ret = ENOMEM; goto fail; } /* TODO: handle attrs_type */ ret = build_attrs_from_map(state, id_ctx->opts->service_map, SDAP_OPTS_SERVICES, NULL, &state->attrs, NULL); if (ret != EOK) goto fail; subreq = sdap_get_services_send(state, state->ev, state->domain, state->sysdb, state->id_ctx->opts, state->id_ctx->opts->sdom->service_search_bases, sdap_id_op_handle(state->op), state->attrs, state->filter, dp_opt_get_int(state->id_ctx->opts->basic, SDAP_SEARCH_TIMEOUT), true); if (!subreq) { ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, enum_services_op_done, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void enum_services_op_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct enum_services_state *state = tevent_req_data(req, struct enum_services_state); char *usn_value; char *endptr = NULL; unsigned usn_number; int ret; ret = sdap_get_services_recv(state, subreq, &usn_value); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } if (usn_value) { talloc_zfree(state->id_ctx->srv_opts->max_service_value); state->id_ctx->srv_opts->max_service_value = talloc_steal(state->id_ctx, usn_value); usn_number = strtoul(usn_value, &endptr, 10); if ((endptr == NULL || (*endptr == '\0' && endptr != usn_value)) && (usn_number > state->id_ctx->srv_opts->last_usn)) { state->id_ctx->srv_opts->last_usn = usn_number; } } DEBUG(SSSDBG_FUNC_DATA, "Services higher USN value: [%s]\n", state->id_ctx->srv_opts->max_service_value); tevent_req_done(req); } errno_t enum_services_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_autofs.c0000644000000000000000000000007312703456111020524 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.805794141 sssd-1.13.4/src/providers/ldap/sdap_autofs.c0000644002412700241270000002121012703456111022170 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP handler for autofs Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_autofs.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_async.h" #include "providers/dp_backend.h" #include "providers/data_provider.h" #include "db/sysdb_autofs.h" #include "util/util.h" static void sdap_autofs_shutdown(struct be_req *req) { sdap_handler_done(req, DP_ERR_OK, EOK, NULL); } void sdap_autofs_handler(struct be_req *be_req); /* Autofs Handler */ struct bet_ops sdap_autofs_ops = { .handler = sdap_autofs_handler, .finalize = sdap_autofs_shutdown }; int sdap_autofs_init(struct be_ctx *be_ctx, struct sdap_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data) { int ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing autofs LDAP back end\n"); *ops = &sdap_autofs_ops; *pvt_data = id_ctx; ret = ldap_get_autofs_options(id_ctx, be_ctx->cdb, be_ctx->conf_path, id_ctx->opts); if (ret != EOK) { return ret; } return ret; } static struct tevent_req * sdap_autofs_get_map_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, const char *map_name); static void sdap_autofs_handler_done(struct tevent_req *req); void sdap_autofs_handler(struct be_req *be_req) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct sdap_id_ctx *id_ctx; struct be_autofs_req *autofs_req; struct tevent_req *req; const char *master_map; int ret = EOK; DEBUG(SSSDBG_TRACE_INTERNAL, "sdap autofs handler called\n"); id_ctx = talloc_get_type(be_ctx->bet_info[BET_AUTOFS].pvt_bet_data, struct sdap_id_ctx); if (be_is_offline(id_ctx->be)) { return sdap_handler_done(be_req, DP_ERR_OFFLINE, EAGAIN, "Offline"); } autofs_req = talloc_get_type(be_req_get_data(be_req), struct be_autofs_req); DEBUG(SSSDBG_FUNC_DATA, "Requested refresh for: %s\n", autofs_req->mapname ? autofs_req->mapname : "\n"); if (autofs_req->mapname != NULL) { master_map = dp_opt_get_string(id_ctx->opts->basic, SDAP_AUTOFS_MAP_MASTER_NAME); if (strcmp(master_map, autofs_req->mapname) == 0) { autofs_req->invalidate = true; DEBUG(SSSDBG_FUNC_DATA, "Refresh of automount master map triggered: %s\n", autofs_req->mapname); } } if (autofs_req->invalidate) { ret = sysdb_invalidate_autofs_maps(id_ctx->be->domain); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not invalidate autofs maps, " "backend might return stale entries\n"); } } req = sdap_autofs_get_map_send(be_req, be_ctx->ev, id_ctx, autofs_req->mapname); if (!req) { ret = ENOMEM; goto fail; } tevent_req_set_callback(req, sdap_autofs_handler_done, be_req); return; fail: be_req_terminate(be_req, DP_ERR_FATAL, ret, NULL); } struct autofs_get_map_state { struct tevent_context *ev; struct sdap_id_ctx *ctx; struct sdap_id_op *op; const char *map_name; int dp_error; }; static errno_t sdap_autofs_get_map_retry(struct tevent_req *req); static void sdap_autofs_get_map_connect_done(struct tevent_req *subreq); static void sdap_autofs_get_map_done(struct tevent_req *req); static struct tevent_req * sdap_autofs_get_map_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, const char *map_name) { struct tevent_req *req; struct autofs_get_map_state *state; int ret; req = tevent_req_create(mem_ctx, &state, struct autofs_get_map_state); if (!req) return NULL; state->ev = ev; state->ctx = ctx; state->dp_error = DP_ERR_FATAL; state->map_name = map_name; state->op = sdap_id_op_create(state, state->ctx->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto fail; } ret = sdap_autofs_get_map_retry(req); if (ret != EOK) { goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static errno_t sdap_autofs_get_map_retry(struct tevent_req *req) { struct autofs_get_map_state *state = tevent_req_data(req, struct autofs_get_map_state); struct tevent_req *subreq; int ret = EOK; subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { return ret; } tevent_req_set_callback(subreq, sdap_autofs_get_map_connect_done, req); return EOK; } static void sdap_autofs_get_map_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct autofs_get_map_state *state = tevent_req_data(req, struct autofs_get_map_state); int dp_error = DP_ERR_FATAL; int ret; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } subreq = sdap_autofs_setautomntent_send(state, state->ev, state->ctx->be->domain, state->ctx->be->domain->sysdb, sdap_id_op_handle(state->op), state->op, state->ctx->opts, state->map_name); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_autofs_setautomntent_send failed\n"); tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_autofs_get_map_done, req); } static void sdap_autofs_get_map_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct autofs_get_map_state *state = tevent_req_data(req, struct autofs_get_map_state); int dp_error = DP_ERR_FATAL; int ret; ret = sdap_autofs_setautomntent_recv(subreq); talloc_zfree(subreq); ret = sdap_id_op_done(state->op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = sdap_autofs_get_map_retry(req); if (ret != EOK) { tevent_req_error(req, ret); return; } return; } if (ret && ret != ENOENT) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } if (ret == ENOENT) { ret = sysdb_delete_autofsmap(state->ctx->be->domain, state->map_name); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Cannot delete autofs map %s [%d]: %s\n", state->map_name, ret, strerror(ret)); tevent_req_error(req, ret); return; } } state->dp_error = DP_ERR_OK; tevent_req_done(req); } static errno_t sdap_autofs_get_map_recv(struct tevent_req *req, int *dp_error_out) { struct autofs_get_map_state *state = tevent_req_data(req, struct autofs_get_map_state); if (dp_error_out) { *dp_error_out = state->dp_error; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void sdap_autofs_handler_done(struct tevent_req *req) { struct be_req *be_req = tevent_req_callback_data(req, struct be_req); int dperr; errno_t ret; ret = sdap_autofs_get_map_recv(req, &dperr); sdap_handler_done(be_req, dperr, ret, strerror(ret)); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_refresh.c0000644000000000000000000000007412703456111020662 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.795794107 sssd-1.13.4/src/providers/ldap/sdap_refresh.c0000644002412700241270000002066612703456111022343 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "providers/ldap/sdap.h" #include "providers/ldap/ldap_common.h" struct sdap_refresh_state { struct tevent_context *ev; struct be_ctx *be_ctx; struct be_acct_req *account_req; struct sdap_id_ctx *id_ctx; struct sdap_domain *sdom; const char *type; char **names; size_t index; }; static errno_t sdap_refresh_step(struct tevent_req *req); static void sdap_refresh_done(struct tevent_req *subreq); static struct tevent_req *sdap_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, int entry_type, char **names, void *pvt) { struct sdap_refresh_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_refresh_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } if (names == NULL) { ret = EOK; goto immediately; } state->ev = ev; state->be_ctx = be_ctx; state->id_ctx = talloc_get_type(pvt, struct sdap_id_ctx); state->names = names; state->index = 0; state->sdom = sdap_domain_get(state->id_ctx->opts, domain); if (state->sdom == NULL) { ret = ERR_DOMAIN_NOT_FOUND; goto immediately; } switch (entry_type) { case BE_REQ_USER: state->type = "user"; break; case BE_REQ_GROUP: state->type = "group"; break; case BE_REQ_NETGROUP: state->type = "netgroup"; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid entry type [%d]!\n", entry_type); } state->account_req = talloc_zero(state, struct be_acct_req); if (state->account_req == NULL) { ret = ENOMEM; goto immediately; } state->account_req->entry_type = entry_type; state->account_req->attr_type = BE_ATTR_CORE; state->account_req->filter_type = BE_FILTER_NAME; state->account_req->extra_value = NULL; state->account_req->domain = domain->name; /* filter will be filled later */ ret = sdap_refresh_step(req); if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Nothing to refresh\n"); goto immediately; } else if (ret != EAGAIN) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_refresh_step() failed " "[%d]: %s\n", ret, sss_strerror(ret)); goto immediately; } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t sdap_refresh_step(struct tevent_req *req) { struct sdap_refresh_state *state = NULL; struct tevent_req *subreq = NULL; errno_t ret; state = tevent_req_data(req, struct sdap_refresh_state); if (state->names == NULL) { ret = EOK; goto done; } state->account_req->filter_value = state->names[state->index]; if (state->account_req->filter_value == NULL) { ret = EOK; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Issuing refresh of %s %s\n", state->type, state->account_req->filter_value); subreq = sdap_handle_acct_req_send(state, state->be_ctx, state->account_req, state->id_ctx, state->sdom, state->id_ctx->conn, true); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_refresh_done, req); state->index++; ret = EAGAIN; done: return ret; } static void sdap_refresh_done(struct tevent_req *subreq) { struct sdap_refresh_state *state = NULL; struct tevent_req *req = NULL; const char *err_msg = NULL; errno_t dp_error; int sdap_ret; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_refresh_state); ret = sdap_handle_acct_req_recv(subreq, &dp_error, &err_msg, &sdap_ret); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to refresh %s [dp_error: %d, " "sdap_ret: %d, errno: %d]: %s\n", state->type, dp_error, sdap_ret, ret, err_msg); goto done; } ret = sdap_refresh_step(req); if (ret == EAGAIN) { return; } done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t sdap_refresh_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static struct tevent_req * sdap_refresh_users_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, char **names, void *pvt) { return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, BE_REQ_USER, names, pvt); } static errno_t sdap_refresh_users_recv(struct tevent_req *req) { return sdap_refresh_recv(req); } static struct tevent_req * sdap_refresh_groups_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, char **names, void *pvt) { return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, BE_REQ_GROUP, names, pvt); } static errno_t sdap_refresh_groups_recv(struct tevent_req *req) { return sdap_refresh_recv(req); } static struct tevent_req * sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, char **names, void *pvt) { return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, BE_REQ_NETGROUP, names, pvt); } static errno_t sdap_refresh_netgroups_recv(struct tevent_req *req) { return sdap_refresh_recv(req); } errno_t sdap_refresh_init(struct be_refresh_ctx *refresh_ctx, struct sdap_id_ctx *id_ctx) { errno_t ret; ret = be_refresh_add_cb(refresh_ctx, BE_REFRESH_TYPE_USERS, sdap_refresh_users_send, sdap_refresh_users_recv, id_ctx); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users " "will not work [%d]: %s\n", ret, strerror(ret)); } ret = be_refresh_add_cb(refresh_ctx, BE_REFRESH_TYPE_GROUPS, sdap_refresh_groups_send, sdap_refresh_groups_recv, id_ctx); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of groups " "will not work [%d]: %s\n", ret, strerror(ret)); } ret = be_refresh_add_cb(refresh_ctx, BE_REFRESH_TYPE_NETGROUPS, sdap_refresh_netgroups_send, sdap_refresh_netgroups_recv, id_ctx); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups " "will not work [%d]: %s\n", ret, strerror(ret)); } return ret; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_id_cleanup.c0000644000000000000000000000007412703456111021320 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.772794029 sssd-1.13.4/src/providers/ldap/ldap_id_cleanup.c0000644002412700241270000003635712703456111023005 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Identity Cleanup Functions Authors: Simo Sorce Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "util/find_uid.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" /* ==Cleanup-Task========================================================= */ struct ldap_id_cleanup_ctx { struct sdap_id_ctx *ctx; struct sdap_domain *sdom; }; static errno_t ldap_cleanup_task(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct ldap_id_cleanup_ctx *cleanup_ctx = NULL; cleanup_ctx = talloc_get_type(pvt, struct ldap_id_cleanup_ctx); return ldap_id_cleanup(cleanup_ctx->ctx->opts, cleanup_ctx->sdom); } errno_t ldap_setup_cleanup(struct sdap_id_ctx *id_ctx, struct sdap_domain *sdom) { errno_t ret; time_t first_delay; time_t period; struct ldap_id_cleanup_ctx *cleanup_ctx = NULL; char *name = NULL; period = dp_opt_get_int(id_ctx->opts->basic, SDAP_PURGE_CACHE_TIMEOUT); if (period == 0) { /* Cleanup has been explicitly disabled, so we won't * create any cleanup tasks. */ ret = EOK; goto done; } /* Run the first one in a couple of seconds so that we have time to * finish initializations first. */ first_delay = 10; cleanup_ctx = talloc_zero(sdom, struct ldap_id_cleanup_ctx); if (cleanup_ctx == NULL) { ret = ENOMEM; goto done; } cleanup_ctx->ctx = id_ctx; cleanup_ctx->sdom = sdom; name = talloc_asprintf(cleanup_ctx, "Cleanup of %s", sdom->dom->name); if (name == NULL) { return ENOMEM; } ret = be_ptask_create_sync(sdom, id_ctx->be, period, first_delay, 5 /* enabled delay */, 0 /* random offset */, period /* timeout */, BE_PTASK_OFFLINE_SKIP, 0, ldap_cleanup_task, cleanup_ctx, name, &sdom->cleanup_task); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize cleanup periodic " "task for %s\n", sdom->dom->name); goto done; } talloc_steal(sdom->cleanup_task, cleanup_ctx); ret = EOK; done: talloc_free(name); if (ret != EOK) { talloc_free(cleanup_ctx); } return ret; } static int cleanup_users(struct sdap_options *opts, struct sss_domain_info *dom); static int cleanup_groups(TALLOC_CTX *memctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain); errno_t ldap_id_cleanup(struct sdap_options *opts, struct sdap_domain *sdom) { int ret, tret; bool in_transaction = false; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = sysdb_transaction_start(sdom->dom->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; ret = cleanup_users(opts, sdom->dom); if (ret && ret != ENOENT) { goto done; } ret = cleanup_groups(tmp_ctx, sdom->dom->sysdb, sdom->dom); if (ret) { goto done; } ret = sysdb_transaction_commit(sdom->dom->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; sdom->last_purge = tevent_timeval_current(); ret = EOK; done: if (in_transaction) { tret = sysdb_transaction_cancel(sdom->dom->sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } /* ==User-Cleanup-Process================================================= */ static int cleanup_users_logged_in(hash_table_t *table, const struct ldb_message *msg); static errno_t expire_memberof_target_groups(struct sss_domain_info *dom, struct ldb_message *user); static int cleanup_users(struct sdap_options *opts, struct sss_domain_info *dom) { TALLOC_CTX *tmpctx; const char *attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, SYSDB_MEMBEROF, NULL }; time_t now = time(NULL); char *subfilter = NULL; int account_cache_expiration; hash_table_t *uid_table; struct ldb_message **msgs; size_t count; const char *name; int ret; int i; tmpctx = talloc_new(NULL); if (!tmpctx) { return ENOMEM; } account_cache_expiration = dp_opt_get_int(opts->basic, SDAP_ACCOUNT_CACHE_EXPIRATION); DEBUG(SSSDBG_TRACE_ALL, "Cache expiration is set to %d days\n", account_cache_expiration); if (account_cache_expiration > 0) { subfilter = talloc_asprintf(tmpctx, "(&(!(%s=0))(%s<=%ld)(|(!(%s=*))(%s<=%ld)))", SYSDB_CACHE_EXPIRE, SYSDB_CACHE_EXPIRE, (long) now, SYSDB_LAST_LOGIN, SYSDB_LAST_LOGIN, (long) (now - (account_cache_expiration * 86400))); } else { subfilter = talloc_asprintf(tmpctx, "(&(!(%s=0))(%s<=%ld)(!(%s=*)))", SYSDB_CACHE_EXPIRE, SYSDB_CACHE_EXPIRE, (long) now, SYSDB_LAST_LOGIN); } if (!subfilter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto done; } ret = sysdb_search_users(tmpctx, dom, subfilter, attrs, &count, &msgs); if (ret == ENOENT) { count = 0; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_search_users failed: %d\n", ret); goto done; } DEBUG(SSSDBG_FUNC_DATA, "Found %zu expired user entries!\n", count); if (count == 0) { ret = EOK; goto done; } ret = get_uid_table(tmpctx, &uid_table); /* get_uid_table returns ENOSYS on non-Linux platforms. We proceed with * the cleanup in that case */ if (ret != EOK && ret != ENOSYS) { DEBUG(SSSDBG_CRIT_FAILURE, "get_uid_table failed: %d\n", ret); goto done; } for (i = 0; i < count; i++) { name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL); if (!name) { DEBUG(SSSDBG_OP_FAILURE, "Entry %s has no Name Attribute ?!?\n", ldb_dn_get_linearized(msgs[i]->dn)); ret = EFAULT; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Processing user %s\n", name); if (uid_table) { ret = cleanup_users_logged_in(uid_table, msgs[i]); if (ret == EOK) { /* If the user is logged in, proceed to the next one */ DEBUG(SSSDBG_FUNC_DATA, "User %s is still logged in or a dummy entry, " "keeping data\n", name); continue; } else if (ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot check if user is logged in: %d\n", ret); goto done; } } /* If not logged in or cannot check the table, delete him */ DEBUG(SSSDBG_TRACE_ALL, "About to delete user %s\n", name); ret = sysdb_delete_user(dom, name, 0); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_delete_user failed: %d\n", ret); goto done; } /* Mark all groups of which user was a member as expired in cache, * so that its ghost/member attributes are refreshed on next * request. */ ret = expire_memberof_target_groups(dom, msgs[i]); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "expire_memberof_target_groups failed: [%d]:%s\n", ret, sss_strerror(ret)); goto done; } } done: talloc_zfree(tmpctx); return ret; } static errno_t expire_memberof_target_groups(struct sss_domain_info *dom, struct ldb_message *user) { struct ldb_message_element *memberof_el = NULL; errno_t ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } memberof_el = ldb_msg_find_element(user, SYSDB_MEMBEROF); if (memberof_el == NULL) { /* User has no cached groups. Nothing to be marked as expired. */ ret = EOK; goto done; } for (unsigned int i = 0; i < memberof_el->num_values; i++) { ret = sysdb_mark_entry_as_expired_ldb_val(dom, &memberof_el->values[i]); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_mark_entry_as_expired_ldb_val failed: [%d]: %s\n", ret, sss_strerror(ret)); goto done; } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static int cleanup_users_logged_in(hash_table_t *table, const struct ldb_message *msg) { uid_t uid; hash_key_t key; hash_value_t value; int ret; uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0); if (!uid) { DEBUG(SSSDBG_OP_FAILURE, "Entry %s has no UID Attribute!\n", ldb_dn_get_linearized(msg->dn)); return ENOENT; } key.type = HASH_KEY_ULONG; key.ul = (unsigned long) uid; ret = hash_lookup(table, &key, &value); if (ret == HASH_SUCCESS) { return EOK; } else if (ret == HASH_ERROR_KEY_NOT_FOUND) { return ENOENT; } DEBUG(SSSDBG_OP_FAILURE, "hash_lookup failed: %d\n", ret); return EIO; } /* ==Group-Cleanup-Process================================================ */ static int cleanup_groups(TALLOC_CTX *memctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain) { TALLOC_CTX *tmpctx; const char *attrs[] = { SYSDB_NAME, SYSDB_GIDNUM, NULL }; time_t now = time(NULL); char *subfilter; const char *dn; gid_t gid; struct ldb_message **msgs; size_t count; struct ldb_message **u_msgs; size_t u_count; int ret; int i; const char *posix; struct ldb_dn *base_dn; tmpctx = talloc_new(memctx); if (!tmpctx) { return ENOMEM; } subfilter = talloc_asprintf(tmpctx, "(&(!(%s=0))(%s<=%ld))", SYSDB_CACHE_EXPIRE, SYSDB_CACHE_EXPIRE, (long)now); if (!subfilter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto done; } ret = sysdb_search_groups(tmpctx, domain, subfilter, attrs, &count, &msgs); if (ret == ENOENT) { count = 0; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_search_groups failed: %d\n", ret); goto done; } DEBUG(SSSDBG_FUNC_DATA, "Found %zu expired group entries!\n", count); if (count == 0) { ret = EOK; goto done; } for (i = 0; i < count; i++) { char *sanitized_dn; dn = ldb_dn_get_linearized(msgs[i]->dn); if (!dn) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot linearize DN!\n"); ret = EFAULT; goto done; } /* sanitize dn */ ret = sss_filter_sanitize(tmpctx, dn, &sanitized_dn); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_filter_sanitize failed: %s:[%d]\n", sss_strerror(ret), ret); goto done; } posix = ldb_msg_find_attr_as_string(msgs[i], SYSDB_POSIX, NULL); if (!posix || strcmp(posix, "TRUE") == 0) { /* Search for users that are members of this group, or * that have this group as their primary GID. * Include subdomain users as well. */ gid = (gid_t) ldb_msg_find_attr_as_uint(msgs[i], SYSDB_GIDNUM, 0); subfilter = talloc_asprintf(tmpctx, "(&(%s=%s)(|(%s=%s)(%s=%lu)))", SYSDB_OBJECTCLASS, SYSDB_USER_CLASS, SYSDB_MEMBEROF, sanitized_dn, SYSDB_GIDNUM, (long unsigned) gid); } else { subfilter = talloc_asprintf(tmpctx, "(%s=%s)", SYSDB_MEMBEROF, sanitized_dn); } talloc_zfree(sanitized_dn); if (!subfilter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto done; } base_dn = sysdb_base_dn(sysdb, tmpctx); if (base_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Searching with: %s\n", subfilter); ret = sysdb_search_entry(tmpctx, sysdb, base_dn, LDB_SCOPE_SUBTREE, subfilter, NULL, &u_count, &u_msgs); if (ret == ENOENT) { const char *name; name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL); if (!name) { DEBUG(SSSDBG_OP_FAILURE, "Entry %s has no Name Attribute ?!?\n", ldb_dn_get_linearized(msgs[i]->dn)); ret = EFAULT; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "About to delete group %s\n", name); ret = sysdb_delete_group(domain, name, 0); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Group delete returned %d (%s)\n", ret, strerror(ret)); goto done; } } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to search sysdb using %s: [%d] %s\n", subfilter, ret, sss_strerror(ret)); goto done; } talloc_zfree(u_msgs); } done: talloc_zfree(tmpctx); return ret; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_opts.h0000644000000000000000000000007212703456111020205 xustar0030 atime=1460561751.647715617 28 ctime=1460561774.5577933 sssd-1.13.4/src/providers/ldap/ldap_opts.h0000644002412700241270000000340712703456111021662 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef LDAP_OPTS_H_ #define LDAP_OPTS_H_ #include "src/providers/data_provider.h" #include "providers/ldap/ldap_common.h" extern struct dp_option default_basic_opts[]; extern struct sdap_attr_map generic_attr_map[]; extern struct sdap_attr_map gen_ipa_attr_map[]; extern struct sdap_attr_map gen_ad_attr_map[]; extern struct sdap_attr_map rfc2307_user_map[]; extern struct sdap_attr_map rfc2307_group_map[]; extern struct sdap_attr_map rfc2307bis_user_map[]; extern struct sdap_attr_map rfc2307bis_group_map[]; extern struct sdap_attr_map gen_ad2008r2_user_map[]; extern struct sdap_attr_map gen_ad2008r2_group_map[]; extern struct sdap_attr_map netgroup_map[]; extern struct sdap_attr_map native_sudorule_map[]; extern struct sdap_attr_map service_map[]; extern struct sdap_attr_map rfc2307_autofs_mobject_map[]; extern struct sdap_attr_map rfc2307_autofs_entry_map[]; extern struct sdap_attr_map rfc2307bis_autofs_mobject_map[]; extern struct sdap_attr_map rfc2307bis_autofs_entry_map[]; #endif /* LDAP_OPTS_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_nested_groups.c0000644000000000000000000000007312703456111023301 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.781794059 sssd-1.13.4/src/providers/ldap/sdap_async_nested_groups.c0000644002412700241270000025573212703456111024767 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ipa/ipa_dn.h" #define sdap_nested_group_sysdb_search_users(domain, filter) \ sdap_nested_group_sysdb_search((domain), (filter), true) #define sdap_nested_group_sysdb_search_groups(domain, filter) \ sdap_nested_group_sysdb_search((domain), (filter), false) enum sdap_nested_group_dn_type { SDAP_NESTED_GROUP_DN_USER, SDAP_NESTED_GROUP_DN_GROUP, SDAP_NESTED_GROUP_DN_UNKNOWN }; struct sdap_nested_group_member { enum sdap_nested_group_dn_type type; const char *dn; const char *user_filter; const char *group_filter; }; #ifndef EXTERNAL_MEMBERS_CHUNK #define EXTERNAL_MEMBERS_CHUNK 16 #endif /* EXTERNAL_MEMBERS_CHUNK */ struct sdap_external_missing_member { const char **parent_group_dns; size_t parent_dn_idx; }; struct sdap_nested_group_ctx { struct sss_domain_info *domain; struct sdap_options *opts; struct sdap_search_base **user_search_bases; struct sdap_search_base **group_search_bases; struct sdap_handle *sh; hash_table_t *users; hash_table_t *groups; hash_table_t *missing_external; bool try_deref; int deref_treshold; int max_nesting_level; }; static struct tevent_req * sdap_nested_group_process_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, int nesting_level, struct sysdb_attrs *group); static errno_t sdap_nested_group_process_recv(struct tevent_req *req); static struct tevent_req * sdap_nested_group_single_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct sdap_nested_group_member *members, int num_members, int num_groups_max, int nesting_level); static errno_t sdap_nested_group_single_recv(struct tevent_req *req); static struct tevent_req * sdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct sdap_nested_group_member *member); static errno_t sdap_nested_group_lookup_user_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct sysdb_attrs **_user); static struct tevent_req * sdap_nested_group_lookup_group_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct sdap_nested_group_member *member); static errno_t sdap_nested_group_lookup_group_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct sysdb_attrs **_group); static struct tevent_req * sdap_nested_group_lookup_unknown_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct sdap_nested_group_member *member); static errno_t sdap_nested_group_lookup_unknown_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct sysdb_attrs **_entry, enum sdap_nested_group_dn_type *_type); static struct tevent_req * sdap_nested_group_deref_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct ldb_message_element *members, const char *group_dn, int nesting_level); static errno_t sdap_nested_group_deref_recv(struct tevent_req *req); static errno_t sdap_nested_group_extract_hash_table(TALLOC_CTX *mem_ctx, hash_table_t *table, unsigned long *_num_entries, struct sysdb_attrs ***_entries) { struct sysdb_attrs **entries = NULL; struct sysdb_attrs *entry = NULL; hash_value_t *values; unsigned long num_entries; unsigned int i; bool hret; errno_t ret; hret = hash_values(table, &num_entries, &values); if (hret != HASH_SUCCESS) { ret = EIO; goto done; } if (num_entries > 0) { entries = talloc_array(mem_ctx, struct sysdb_attrs *, num_entries); if (entries == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < num_entries; i++) { entry = talloc_get_type(values[i].ptr, struct sysdb_attrs); entries[i] = talloc_steal(entries, entry); } } if (_num_entries != NULL) { *_num_entries = num_entries; } if (_entries != NULL) { *_entries = entries; } ret = EOK; done: talloc_free(values); if (ret != EOK) { talloc_free(entries); } return ret; } static errno_t sdap_nested_group_hash_insert(hash_table_t *table, const char *entry_key, void *entry_value, bool overwrite, const char *table_name) { hash_key_t key; hash_value_t value; int hret; DEBUG(SSSDBG_TRACE_ALL, "Inserting [%s] into hash table [%s]\n", entry_key, table_name); key.type = HASH_KEY_STRING; key.str = talloc_strdup(NULL, entry_key); if (key.str == NULL) { return ENOMEM; } if (overwrite == false && hash_has_key(table, &key)) { talloc_free(key.str); return EEXIST; } value.type = HASH_VALUE_PTR; value.ptr = entry_value; hret = hash_enter(table, &key, &value); if (hret != HASH_SUCCESS) { talloc_free(key.str); return EIO; } talloc_steal(table, key.str); talloc_steal(table, value.ptr); return EOK; } static errno_t sdap_nested_group_hash_entry(hash_table_t *table, struct sysdb_attrs *entry, const char *table_name) { const char *name = NULL; errno_t ret; ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &name); if (ret != EOK) { return ret; } return sdap_nested_group_hash_insert(table, name, entry, false, table_name); } static errno_t sdap_nested_group_hash_user(struct sdap_nested_group_ctx *group_ctx, struct sysdb_attrs *user) { return sdap_nested_group_hash_entry(group_ctx->users, user, "users"); } static errno_t sdap_nested_group_hash_group(struct sdap_nested_group_ctx *group_ctx, struct sysdb_attrs *group) { struct sdap_attr_map *map = group_ctx->opts->group_map; gid_t gid; errno_t ret; bool posix_group = true; bool use_id_mapping; bool can_find_gid; bool need_filter; ret = sdap_check_ad_group_type(group_ctx->domain, group_ctx->opts, group, "", &need_filter); if (ret != EOK) { return ret; } if (need_filter) { posix_group = false; gid = 0; } use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( group_ctx->opts->idmap_ctx, group_ctx->domain->name, group_ctx->domain->domain_id); can_find_gid = posix_group && !use_id_mapping; if (can_find_gid) { ret = sysdb_attrs_get_uint32_t(group, map[SDAP_AT_GROUP_GID].sys_name, &gid); } if (!can_find_gid || ret == ENOENT || (ret == EOK && gid == 0)) { DEBUG(SSSDBG_TRACE_ALL, "The group's gid was %s\n", ret == ENOENT ? "missing" : "zero"); DEBUG(SSSDBG_TRACE_INTERNAL, "Marking group as non-posix and setting GID=0!\n"); if (ret == ENOENT || !posix_group) { ret = sysdb_attrs_add_uint32(group, map[SDAP_AT_GROUP_GID].sys_name, 0); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add a GID to non-posix group!\n"); return ret; } } ret = sysdb_attrs_add_bool(group, SYSDB_POSIX, false); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error: Failed to mark group as non-posix!\n"); return ret; } } else if (ret != EOK) { return ret; } return sdap_nested_group_hash_entry(group_ctx->groups, group, "groups"); } static errno_t sdap_nested_group_external_add(hash_table_t *table, const char *ext_member, const char *parent_group_dn) { hash_key_t key; hash_value_t value; int hret; int ret; struct sdap_external_missing_member *ext_mem; key.type = HASH_KEY_STRING; key.str = discard_const(ext_member); DEBUG(SSSDBG_TRACE_ALL, "Inserting external member [%s] into external members hash table\n", ext_member); hret = hash_lookup(table, &key, &value); switch (hret) { case HASH_ERROR_KEY_NOT_FOUND: ext_mem = talloc_zero(table, struct sdap_external_missing_member); if (ext_mem == NULL) { return ENOMEM; } ext_mem->parent_group_dns = talloc_zero_array(ext_mem, const char *, EXTERNAL_MEMBERS_CHUNK); if (ext_mem->parent_group_dns == NULL) { talloc_free(ext_mem); return ENOMEM; } ret = sdap_nested_group_hash_insert(table, ext_member, ext_mem, true, "missing external users"); if (ret != EOK) { return ret; } break; case HASH_SUCCESS: ext_mem = talloc_get_type(value.ptr, struct sdap_external_missing_member); if (ext_mem->parent_dn_idx == \ talloc_array_length(ext_mem->parent_group_dns)) { ext_mem->parent_group_dns = talloc_realloc(ext_mem, ext_mem->parent_group_dns, const char *, ext_mem->parent_dn_idx + \ EXTERNAL_MEMBERS_CHUNK); if (ext_mem->parent_group_dns == NULL) { talloc_free(ext_mem); return ENOMEM; } } break; default: return EIO; } ext_mem->parent_group_dns[ext_mem->parent_dn_idx] = \ talloc_strdup(ext_mem->parent_group_dns, parent_group_dn); if (ext_mem->parent_group_dns[ext_mem->parent_dn_idx] == NULL) { return ENOMEM; } ext_mem->parent_dn_idx++; return EOK; } static errno_t sdap_nested_group_sysdb_search(struct sss_domain_info *domain, const char *filter, bool user) { static const char *attrs[] = {SYSDB_CACHE_EXPIRE, SYSDB_UIDNUM, NULL}; struct ldb_message **msgs = NULL; size_t count; time_t now = time(NULL); uint64_t expire; uid_t uid; errno_t ret; if (user) { ret = sysdb_search_users(NULL, domain, filter, attrs, &count, &msgs); } else { ret = sysdb_search_groups(NULL, domain, filter, attrs, &count, &msgs); } if (ret != EOK) { goto done; } if (count != 1) { DEBUG(SSSDBG_OP_FAILURE, "More than one entry found?\n"); ret = EFAULT; goto done; } /* we found an object with this origDN in the sysdb, * check if it is valid */ if (user) { uid = ldb_msg_find_attr_as_uint64(msgs[0], SYSDB_UIDNUM, 0); if (uid == 0) { DEBUG(SSSDBG_OP_FAILURE, "User with no UID?\n"); ret = EINVAL; goto done; } } expire = ldb_msg_find_attr_as_uint64(msgs[0], SYSDB_CACHE_EXPIRE, 0); if (expire != 0 && expire <= now) { /* needs refresh */ ret = EAGAIN; goto done; } /* valid object */ ret = EOK; done: talloc_zfree(msgs); return ret; } static errno_t sdap_nested_group_check_cache(struct sdap_options *opts, struct sss_domain_info *domain, const char *member_dn, enum sdap_nested_group_dn_type *_type) { TALLOC_CTX *tmp_ctx = NULL; struct sdap_domain *sdap_domain = NULL; struct sss_domain_info *member_domain = NULL; char *sanitized_dn = NULL; char *filter = NULL; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } ret = sss_filter_sanitize(tmp_ctx, member_dn, &sanitized_dn); if (ret != EOK) { goto done; } filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_ORIG_DN, sanitized_dn); if (filter == NULL) { ret = ENOMEM; goto done; } /* determine correct domain of this member */ sdap_domain = sdap_domain_get_by_dn(opts, member_dn); member_domain = sdap_domain == NULL ? domain : sdap_domain->dom; /* search in users */ ret = sdap_nested_group_sysdb_search_users(member_domain, filter); if (ret == EOK || ret == EAGAIN) { /* user found */ *_type = SDAP_NESTED_GROUP_DN_USER; goto done; } else if (ret != ENOENT) { /* error */ goto done; } /* search in groups */ ret = sdap_nested_group_sysdb_search_groups(member_domain, filter); if (ret == EOK || ret == EAGAIN) { /* group found */ *_type = SDAP_NESTED_GROUP_DN_GROUP; goto done; } else if (ret != ENOENT) { /* error */ goto done; } /* not found in the sysdb */ ret = ENOENT; done: talloc_free(tmp_ctx); return ret; } static bool sdap_nested_member_is_ent(struct sdap_nested_group_ctx *group_ctx, const char *dn, char **filter, bool is_user) { struct sdap_domain *sditer = NULL; bool ret = false; struct sdap_search_base **search_bases; DLIST_FOR_EACH(sditer, group_ctx->opts->sdom) { search_bases = is_user ? sditer->user_search_bases : \ sditer->group_search_bases; ret = sss_ldap_dn_in_search_bases(group_ctx, dn, search_bases, filter); if (ret == true) { break; } } return ret; } static inline bool sdap_nested_member_is_user(struct sdap_nested_group_ctx *group_ctx, const char *dn, char **filter) { return sdap_nested_member_is_ent(group_ctx, dn, filter, true); } static inline bool sdap_nested_member_is_group(struct sdap_nested_group_ctx *group_ctx, const char *dn, char **filter) { return sdap_nested_member_is_ent(group_ctx, dn, filter, false); } static errno_t sdap_nested_group_split_members(TALLOC_CTX *mem_ctx, struct sdap_nested_group_ctx *group_ctx, int nesting_level, struct ldb_message_element *members, struct sdap_nested_group_member **_missing, int *_num_missing, int *_num_groups) { TALLOC_CTX *tmp_ctx = NULL; struct sdap_nested_group_member *missing = NULL; enum sdap_nested_group_dn_type type; char *dn = NULL; char *user_filter = NULL; char *group_filter = NULL; int num_missing = 0; int num_groups = 0; hash_key_t key; bool bret; bool is_user; bool is_group; errno_t ret; int i; if (members == NULL) { *_missing = NULL; *_num_missing = 0; *_num_groups = 0; return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } missing = talloc_zero_array(tmp_ctx, struct sdap_nested_group_member, members->num_values); if (missing == NULL) { ret = ENOMEM; goto done; } /* create list of missing members * skip dn if: * - is present in user or group hash table * - is present in sysdb and not expired * - it is a group and we have reached the maximal nesting level * - it is not under user nor group search bases * * if dn is in sysdb but expired * - we know what object type it is * * if dn is not in hash table or sysdb * - try to determine type of object by search base that match dn */ for (i = 0; i < members->num_values; i++) { dn = (char*)members->values[i].data; type = SDAP_NESTED_GROUP_DN_UNKNOWN; /* check hash tables */ key.type = HASH_KEY_STRING; key.str = dn; bret = hash_has_key(group_ctx->users, &key); if (bret) { continue; } bret = hash_has_key(group_ctx->groups, &key); if (bret) { continue; } /* check sysdb */ ret = sdap_nested_group_check_cache(group_ctx->opts, group_ctx->domain, dn, &type); if (ret == EOK) { /* found and valid */ DEBUG(SSSDBG_TRACE_ALL, "[%s] found in cache, skipping\n", dn); continue; } else if (ret != EAGAIN && ret != ENOENT) { /* error */ goto done; } /* try to determine type by dn */ if (type == SDAP_NESTED_GROUP_DN_UNKNOWN) { /* user */ is_user = sdap_nested_member_is_user(group_ctx, dn, &user_filter); is_group = sdap_nested_member_is_group(group_ctx, dn, &group_filter); if (is_user && is_group) { /* search bases overlap */ DEBUG(SSSDBG_TRACE_ALL, "[%s] is unknown object\n", dn); type = SDAP_NESTED_GROUP_DN_UNKNOWN; } else if (is_user) { DEBUG(SSSDBG_TRACE_ALL, "[%s] is a user\n", dn); type = SDAP_NESTED_GROUP_DN_USER; } else if (is_group) { DEBUG(SSSDBG_TRACE_ALL, "[%s] is a group\n", dn); type = SDAP_NESTED_GROUP_DN_GROUP; } else { /* dn is outside search bases */ DEBUG(SSSDBG_TRACE_ALL, "[%s] is out of scope of configured " "search bases, skipping\n", dn); continue; } } /* check nesting level */ if (type == SDAP_NESTED_GROUP_DN_GROUP) { if (nesting_level >= group_ctx->max_nesting_level) { DEBUG(SSSDBG_TRACE_ALL, "[%s] is outside nesting limit " "(level %d), skipping\n", dn, nesting_level); talloc_zfree(user_filter); talloc_zfree(group_filter); continue; } } missing[num_missing].dn = talloc_strdup(missing, dn); if (missing[num_missing].dn == NULL) { ret = ENOMEM; goto done; } missing[num_missing].type = type; missing[num_missing].user_filter = talloc_steal(missing, user_filter); missing[num_missing].group_filter = talloc_steal(missing, group_filter); num_missing++; if (type != SDAP_NESTED_GROUP_DN_USER) { num_groups++; } } missing = talloc_realloc(mem_ctx, missing, struct sdap_nested_group_member, num_missing); /* talloc_realloc behaves as talloc_free if 3rd parameter (count) is 0, * so it's OK to return NULL then */ if (missing == NULL && num_missing > 0) { ret = ENOMEM; goto done; } if (_missing) { *_missing = talloc_steal(mem_ctx, missing); } if (_num_missing) { *_num_missing = num_missing; } if (_num_groups) { *_num_groups = num_groups; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t sdap_nested_group_add_ext_members(TALLOC_CTX *mem_ctx, struct sdap_nested_group_ctx *group_ctx, struct sysdb_attrs *group, struct ldb_message_element *ext_members) { errno_t ret; const char *ext_member_attr; const char *orig_dn; if (ext_members == NULL) { return EOK; } ret = sysdb_attrs_get_string(group, SYSDB_ORIG_DN, &orig_dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "A group with no originalDN!?!\n"); return ret; } for (size_t i = 0; i < ext_members->num_values; i++) { ext_member_attr = (const char *) ext_members->values[i].data; ret = sdap_nested_group_external_add(group_ctx->missing_external, ext_member_attr, orig_dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add %s into external members [%d]: %s\n", ext_member_attr, ret, sss_strerror(ret)); return ret; } } return EOK; } static struct ldb_message_element * sdap_nested_group_ext_members(struct sdap_options *opts, struct sysdb_attrs *group) { errno_t ret; struct ldb_message_element *ext_members = NULL; if (opts->ext_ctx == NULL) { return NULL; } ret = sysdb_attrs_get_el_ext(group, opts->group_map[SDAP_AT_GROUP_EXT_MEMBER].sys_name, false, &ext_members); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve external member list " "[%d]: %s\n", ret, sss_strerror(ret)); } return ext_members; } struct sdap_nested_group_state { struct sdap_nested_group_ctx *group_ctx; }; static void sdap_nested_group_done(struct tevent_req *subreq); struct tevent_req * sdap_nested_group_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_domain *sdom, struct sdap_options *opts, struct sdap_handle *sh, struct sysdb_attrs *group) { struct sdap_nested_group_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; errno_t ret; int i; req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } /* create main nested group context */ state->group_ctx = talloc_zero(state, struct sdap_nested_group_ctx); if (state->group_ctx == NULL) { ret = ENOMEM; goto immediately; } ret = sss_hash_create(state->group_ctx, 32, &state->group_ctx->users); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n", ret, strerror(ret)); goto immediately; } ret = sss_hash_create(state->group_ctx, 32, &state->group_ctx->groups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n", ret, strerror(ret)); goto immediately; } ret = sss_hash_create(state->group_ctx, 32, &state->group_ctx->missing_external); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n", ret, strerror(ret)); goto immediately; } state->group_ctx->try_deref = true; state->group_ctx->deref_treshold = dp_opt_get_int(opts->basic, SDAP_DEREF_THRESHOLD); state->group_ctx->max_nesting_level = dp_opt_get_int(opts->basic, SDAP_NESTING_LEVEL); state->group_ctx->domain = sdom->dom; state->group_ctx->opts = opts; state->group_ctx->user_search_bases = sdom->user_search_bases; state->group_ctx->group_search_bases = sdom->group_search_bases; state->group_ctx->sh = sh; state->group_ctx->try_deref = sdap_has_deref_support(sh, opts); /* disable deref if threshold <= 0 */ if (state->group_ctx->deref_treshold <= 0) { state->group_ctx->try_deref = false; } /* if any search base contains filter, disable dereference. */ if (state->group_ctx->try_deref) { for (i = 0; opts->sdom->user_search_bases[i] != NULL; i++) { if (opts->sdom->user_search_bases[i]->filter != NULL) { DEBUG(SSSDBG_TRACE_FUNC, "User search base contains filter, " "dereference will be disabled\n"); state->group_ctx->try_deref = false; break; } } } if (state->group_ctx->try_deref) { for (i = 0; opts->sdom->group_search_bases[i] != NULL; i++) { if (opts->sdom->group_search_bases[i]->filter != NULL) { DEBUG(SSSDBG_TRACE_FUNC, "Group search base contains filter, " "dereference will be disabled\n"); state->group_ctx->try_deref = false; break; } } } /* insert initial group into hash table */ ret = sdap_nested_group_hash_group(state->group_ctx, group); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to insert group into hash table " "[%d]: %s\n", ret, strerror(ret)); goto immediately; } /* resolve group */ subreq = sdap_nested_group_process_send(state, ev, state->group_ctx, 0, group); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_nested_group_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sdap_nested_group_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); ret = sdap_nested_group_process_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } errno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, unsigned long *_num_users, struct sysdb_attrs ***_users, unsigned long *_num_groups, struct sysdb_attrs ***_groups, hash_table_t **_missing_external) { struct sdap_nested_group_state *state = NULL; struct sysdb_attrs **users = NULL; struct sysdb_attrs **groups = NULL; unsigned long num_users; unsigned long num_groups; errno_t ret; state = tevent_req_data(req, struct sdap_nested_group_state); TEVENT_REQ_RETURN_ON_ERROR(req); ret = sdap_nested_group_extract_hash_table(state, state->group_ctx->users, &num_users, &users); if (ret != EOK) { return ret; } DEBUG(SSSDBG_TRACE_FUNC, "%lu users found in the hash table\n", num_users); ret = sdap_nested_group_extract_hash_table(state, state->group_ctx->groups, &num_groups, &groups); if (ret != EOK) { return ret; } DEBUG(SSSDBG_TRACE_FUNC, "%lu groups found in the hash table\n", num_groups); if (_num_users != NULL) { *_num_users = num_users; } if (_users != NULL) { *_users = talloc_steal(mem_ctx, users); } if (_num_groups!= NULL) { *_num_groups = num_groups; } if (_groups != NULL) { *_groups = talloc_steal(mem_ctx, groups); } if (_missing_external) { *_missing_external = talloc_steal(mem_ctx, state->group_ctx->missing_external); } return EOK; } struct sdap_nested_group_process_state { struct tevent_context *ev; struct sdap_nested_group_ctx *group_ctx; struct sdap_nested_group_member *missing; int num_missing_total; int num_missing_groups; struct ldb_message_element *ext_members; int nesting_level; char *group_dn; bool deref; }; static void sdap_nested_group_process_done(struct tevent_req *subreq); static struct tevent_req * sdap_nested_group_process_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, int nesting_level, struct sysdb_attrs *group) { struct sdap_nested_group_process_state *state = NULL; struct sdap_attr_map *group_map = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct ldb_message_element *members = NULL; const char *orig_dn = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_process_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->group_ctx = group_ctx; state->nesting_level = nesting_level; group_map = state->group_ctx->opts->group_map; /* get original dn */ ret = sysdb_attrs_get_string(group, SYSDB_ORIG_DN, &orig_dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve original dn " "[%d]: %s\n", ret, strerror(ret)); goto immediately; } state->group_dn = talloc_strdup(state, orig_dn); if (state->group_dn == NULL) { ret = ENOMEM; goto immediately; } DEBUG(SSSDBG_TRACE_INTERNAL, "About to process group [%s]\n", orig_dn); /* get member list, both direct and external */ state->ext_members = sdap_nested_group_ext_members(state->group_ctx->opts, group); ret = sysdb_attrs_get_el_ext(group, group_map[SDAP_AT_GROUP_MEMBER].sys_name, false, &members); if (ret == ENOENT && state->ext_members == NULL) { ret = EOK; /* no members, direct or external */ goto immediately; } else if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve member list " "[%d]: %s\n", ret, strerror(ret)); goto immediately; } /* get members that need to be refreshed */ ret = sdap_nested_group_split_members(state, state->group_ctx, state->nesting_level, members, &state->missing, &state->num_missing_total, &state->num_missing_groups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to split member list " "[%d]: %s\n", ret, sss_strerror(ret)); goto immediately; } ret = sdap_nested_group_add_ext_members(state, state->group_ctx, group, state->ext_members); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to split external member list " "[%d]: %s\n", ret, sss_strerror(ret)); goto immediately; } if (state->num_missing_total == 0 && hash_count(state->group_ctx->missing_external) == 0) { ret = EOK; /* we're done */ goto immediately; } /* If there are only indirect members of the group, it's still safe to * proceed and let the direct lookup code just fall through. */ DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up %d/%d members of group [%s]\n", state->num_missing_total, members ? members->num_values : 0, orig_dn); /* process members */ if (group_ctx->try_deref && state->num_missing_total > group_ctx->deref_treshold) { DEBUG(SSSDBG_TRACE_INTERNAL, "Dereferencing members of group [%s]\n", orig_dn); state->deref = true; subreq = sdap_nested_group_deref_send(state, ev, group_ctx, members, orig_dn, state->nesting_level); } else { DEBUG(SSSDBG_TRACE_INTERNAL, "Members of group [%s] will be " "processed individually\n", orig_dn); state->deref = false; subreq = sdap_nested_group_single_send(state, ev, group_ctx, state->missing, state->num_missing_total, state->num_missing_groups, state->nesting_level); } if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_nested_group_process_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sdap_nested_group_process_done(struct tevent_req *subreq) { struct sdap_nested_group_process_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_nested_group_process_state); if (state->deref) { ret = sdap_nested_group_deref_recv(subreq); talloc_zfree(subreq); if (ret == ENOTSUP) { /* dereference is not supported, try again without dereference */ state->group_ctx->try_deref = false; state->deref = false; DEBUG(SSSDBG_TRACE_INTERNAL, "Members of group [%s] will be " "processed individually\n", state->group_dn); subreq = sdap_nested_group_single_send(state, state->ev, state->group_ctx, state->missing, state->num_missing_total, state->num_missing_groups, state->nesting_level); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_nested_group_process_done, req); ret = EAGAIN; } } else { ret = sdap_nested_group_single_recv(subreq); talloc_zfree(subreq); } done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static errno_t sdap_nested_group_process_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct sdap_nested_group_recurse_state { struct tevent_context *ev; struct sdap_nested_group_ctx *group_ctx; struct sysdb_attrs **groups; int num_groups; int index; int nesting_level; }; static errno_t sdap_nested_group_recurse_step(struct tevent_req *req); static void sdap_nested_group_recurse_done(struct tevent_req *subreq); static struct tevent_req * sdap_nested_group_recurse_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct sysdb_attrs **nested_groups, int num_groups, int nesting_level) { struct sdap_nested_group_recurse_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_recurse_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->group_ctx = group_ctx; state->groups = nested_groups; state->num_groups = num_groups; state->index = 0; state->nesting_level = nesting_level; /* process each group individually */ ret = sdap_nested_group_recurse_step(req); if (ret != EAGAIN) { goto immediately; } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t sdap_nested_group_recurse_step(struct tevent_req *req) { struct sdap_nested_group_recurse_state *state = NULL; struct tevent_req *subreq = NULL; state = tevent_req_data(req, struct sdap_nested_group_recurse_state); if (state->index >= state->num_groups) { /* we're done */ return EOK; } subreq = sdap_nested_group_process_send(state, state->ev, state->group_ctx, state->nesting_level, state->groups[state->index]); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_nested_group_recurse_done, req); state->index++; return EAGAIN; } static void sdap_nested_group_recurse_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); ret = sdap_nested_group_process_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { goto done; } ret = sdap_nested_group_recurse_step(req); done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static errno_t sdap_nested_group_recurse_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct sdap_nested_group_single_state { struct tevent_context *ev; struct sdap_nested_group_ctx *group_ctx; struct sdap_nested_group_member *members; int nesting_level; struct sdap_nested_group_member *current_member; int num_members; int member_index; struct sysdb_attrs **nested_groups; int num_groups; }; static errno_t sdap_nested_group_single_step(struct tevent_req *req); static void sdap_nested_group_single_step_done(struct tevent_req *subreq); static void sdap_nested_group_single_done(struct tevent_req *subreq); static struct tevent_req * sdap_nested_group_single_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct sdap_nested_group_member *members, int num_members, int num_groups_max, int nesting_level) { struct sdap_nested_group_single_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_single_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->group_ctx = group_ctx; state->members = members; state->nesting_level = nesting_level; state->current_member = NULL; state->num_members = num_members; state->member_index = 0; state->nested_groups = talloc_zero_array(state, struct sysdb_attrs *, num_groups_max); if (state->nested_groups == NULL) { ret = ENOMEM; goto immediately; } state->num_groups = 0; /* we will count exact number of the groups */ /* process each member individually */ ret = sdap_nested_group_single_step(req); if (ret != EAGAIN) { goto immediately; } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t sdap_nested_group_single_step(struct tevent_req *req) { struct sdap_nested_group_single_state *state = NULL; struct tevent_req *subreq = NULL; state = tevent_req_data(req, struct sdap_nested_group_single_state); if (state->member_index >= state->num_members) { /* we're done */ return EOK; } state->current_member = &state->members[state->member_index]; state->member_index++; switch (state->current_member->type) { case SDAP_NESTED_GROUP_DN_USER: subreq = sdap_nested_group_lookup_user_send(state, state->ev, state->group_ctx, state->current_member); break; case SDAP_NESTED_GROUP_DN_GROUP: subreq = sdap_nested_group_lookup_group_send(state, state->ev, state->group_ctx, state->current_member); break; case SDAP_NESTED_GROUP_DN_UNKNOWN: subreq = sdap_nested_group_lookup_unknown_send(state, state->ev, state->group_ctx, state->current_member); break; } if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_nested_group_single_step_done, req); return EAGAIN; } static errno_t sdap_nested_group_single_step_process(struct tevent_req *subreq) { struct sdap_nested_group_single_state *state = NULL; struct tevent_req *req = NULL; struct sysdb_attrs *entry = NULL; enum sdap_nested_group_dn_type type = SDAP_NESTED_GROUP_DN_UNKNOWN; const char *orig_dn = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_nested_group_single_state); /* set correct type if possible */ if (state->current_member->type == SDAP_NESTED_GROUP_DN_UNKNOWN) { ret = sdap_nested_group_lookup_unknown_recv(state, subreq, &entry, &type); if (ret != EOK) { goto done; } if (entry != NULL) { state->current_member->type = type; } } switch (state->current_member->type) { case SDAP_NESTED_GROUP_DN_USER: if (entry == NULL) { /* type was not unknown, receive data */ ret = sdap_nested_group_lookup_user_recv(state, subreq, &entry); if (ret != EOK) { goto done; } if (entry == NULL) { /* user not found, continue */ break; } } /* save user in hash table */ ret = sdap_nested_group_hash_user(state->group_ctx, entry); if (ret == EEXIST) { /* the user is already present, skip it */ talloc_zfree(entry); ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to save user in hash table " "[%d]: %s\n", ret, strerror(ret)); goto done; } break; case SDAP_NESTED_GROUP_DN_GROUP: if (entry == NULL) { /* type was not unknown, receive data */ ret = sdap_nested_group_lookup_group_recv(state, subreq, &entry); if (ret != EOK) { goto done; } if (entry == NULL) { /* group not found, continue */ break; } } else { /* the type was unknown so we had to pull the group, * but we don't want to process it if we have reached * the nesting level */ if (state->nesting_level >= state->group_ctx->max_nesting_level) { ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &orig_dn); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "The entry has no originalDN\n"); orig_dn = "invalid"; } DEBUG(SSSDBG_TRACE_ALL, "[%s] is outside nesting limit " "(level %d), skipping\n", orig_dn, state->nesting_level); break; } } /* save group in hash table */ ret = sdap_nested_group_hash_group(state->group_ctx, entry); if (ret == EEXIST) { /* the group is already present, skip it */ talloc_zfree(entry); ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to save group in hash table " "[%d]: %s\n", ret, strerror(ret)); goto done; } /* remember the group for later processing */ state->nested_groups[state->num_groups] = entry; state->num_groups++; break; case SDAP_NESTED_GROUP_DN_UNKNOWN: /* not found in users nor nested_groups, continue */ break; } ret = EOK; done: return ret; } static void sdap_nested_group_single_step_done(struct tevent_req *subreq) { struct sdap_nested_group_single_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_nested_group_single_state); /* process direct members */ ret = sdap_nested_group_single_step_process(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error processing direct membership " "[%d]: %s\n", ret, strerror(ret)); goto done; } ret = sdap_nested_group_single_step(req); if (ret == EOK) { /* we have processed all direct members, * now recurse and process nested groups */ subreq = sdap_nested_group_recurse_send(state, state->ev, state->group_ctx, state->nested_groups, state->num_groups, state->nesting_level + 1); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_nested_group_single_done, req); } else if (ret != EAGAIN) { /* error */ goto done; } /* we're not done yet */ ret = EAGAIN; done: if (ret == EOK) { /* tevent_req_error() cannot cope with EOK */ DEBUG(SSSDBG_CRIT_FAILURE, "We should not get here with EOK\n"); tevent_req_error(req, EINVAL); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static void sdap_nested_group_single_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); /* all nested groups are completed */ ret = sdap_nested_group_recurse_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error processing nested groups " "[%d]: %s.\n", ret, strerror(ret)); tevent_req_error(req, ret); return; } tevent_req_done(req); return; } static errno_t sdap_nested_group_single_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static errno_t sdap_nested_group_get_ipa_user(TALLOC_CTX *mem_ctx, const char *user_dn, struct sysdb_ctx *sysdb, struct sysdb_attrs **_user) { TALLOC_CTX *tmp_ctx; struct sysdb_attrs *user; char *name; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = ipa_get_rdn(tmp_ctx, sysdb, user_dn, &name, "uid", "cn", "users", "cn", "accounts"); if (ret != EOK) { goto done; } user = sysdb_new_attrs(tmp_ctx); if (user == NULL) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(user, SYSDB_NAME, name); if (ret != EOK) { goto done; } ret = sysdb_attrs_add_string(user, SYSDB_ORIG_DN, user_dn); if (ret != EOK) { goto done; } ret = sysdb_attrs_add_string(user, SYSDB_OBJECTCLASS, SYSDB_USER_CLASS); if (ret != EOK) { goto done; } *_user = talloc_steal(mem_ctx, user); done: talloc_free(tmp_ctx); return ret; } struct sdap_nested_group_lookup_user_state { struct sysdb_attrs *user; }; static void sdap_nested_group_lookup_user_done(struct tevent_req *subreq); static struct tevent_req * sdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct sdap_nested_group_member *member) { struct sdap_nested_group_lookup_user_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; const char **attrs = NULL; const char *base_filter = NULL; const char *filter = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_lookup_user_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } if (group_ctx->opts->schema_type == SDAP_SCHEMA_IPA_V1) { /* if the schema is IPA, then just shortcut and guess the name */ ret = sdap_nested_group_get_ipa_user(state, member->dn, group_ctx->domain->sysdb, &state->user); if (ret == EOK) { goto immediately; } DEBUG(SSSDBG_MINOR_FAILURE, "Couldn't parse out user information " "based on DN %s, falling back to an LDAP lookup\n", member->dn); } /* only pull down username and originalDN */ attrs = talloc_array(state, const char *, 3); if (attrs == NULL) { ret = ENOMEM; goto immediately; } attrs[0] = "objectClass"; attrs[1] = group_ctx->opts->user_map[SDAP_AT_USER_NAME].name; attrs[2] = NULL; /* create filter */ base_filter = talloc_asprintf(state, "(objectclass=%s)", group_ctx->opts->user_map[SDAP_OC_USER].name); if (base_filter == NULL) { ret = ENOMEM; goto immediately; } /* use search base filter if needed */ filter = sdap_combine_filters(state, base_filter, member->user_filter); if (filter == NULL) { ret = ENOMEM; goto immediately; } /* search */ subreq = sdap_get_generic_send(state, ev, group_ctx->opts, group_ctx->sh, member->dn, LDAP_SCOPE_BASE, filter, attrs, group_ctx->opts->user_map, group_ctx->opts->user_map_cnt, dp_opt_get_int(group_ctx->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_nested_group_lookup_user_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sdap_nested_group_lookup_user_done(struct tevent_req *subreq) { struct sdap_nested_group_lookup_user_state *state = NULL; struct tevent_req *req = NULL; struct sysdb_attrs **user = NULL; size_t count = 0; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_nested_group_lookup_user_state); ret = sdap_get_generic_recv(subreq, state, &count, &user); talloc_zfree(subreq); if (ret == ENOENT) { count = 0; } else if (ret != EOK) { goto done; } if (count == 1) { state->user = user[0]; } else if (count == 0) { /* group not found */ state->user = NULL; } else { DEBUG(SSSDBG_OP_FAILURE, "BASE search returned more than one records\n"); ret = EIO; goto done; } ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t sdap_nested_group_lookup_user_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct sysdb_attrs **_user) { struct sdap_nested_group_lookup_user_state *state = NULL; state = tevent_req_data(req, struct sdap_nested_group_lookup_user_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_user != NULL) { *_user = talloc_steal(mem_ctx, state->user); } return EOK; } struct sdap_nested_group_lookup_group_state { struct sysdb_attrs *group; }; static void sdap_nested_group_lookup_group_done(struct tevent_req *subreq); static struct tevent_req * sdap_nested_group_lookup_group_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct sdap_nested_group_member *member) { struct sdap_nested_group_lookup_group_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_attr_map *map = group_ctx->opts->group_map; const char **attrs = NULL; const char *base_filter = NULL; const char *filter = NULL; char *oc_list; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_lookup_group_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } ret = build_attrs_from_map(state, group_ctx->opts->group_map, SDAP_OPTS_GROUP, NULL, &attrs, NULL); if (ret != EOK) { goto immediately; } /* create filter */ oc_list = sdap_make_oc_list(state, map); if (oc_list == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n"); ret = ENOMEM; goto immediately; } base_filter = talloc_asprintf(attrs, "(&(%s)(%s=*))", oc_list, map[SDAP_AT_GROUP_NAME].name); if (base_filter == NULL) { ret = ENOMEM; goto immediately; } /* use search base filter if needed */ filter = sdap_combine_filters(state, base_filter, member->group_filter); if (filter == NULL) { ret = ENOMEM; goto immediately; } /* search */ subreq = sdap_get_generic_send(state, ev, group_ctx->opts, group_ctx->sh, member->dn, LDAP_SCOPE_BASE, filter, attrs, map, SDAP_OPTS_GROUP, dp_opt_get_int(group_ctx->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_nested_group_lookup_group_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sdap_nested_group_lookup_group_done(struct tevent_req *subreq) { struct sdap_nested_group_lookup_group_state *state = NULL; struct tevent_req *req = NULL; struct sysdb_attrs **group = NULL; size_t count = 0; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_nested_group_lookup_group_state); ret = sdap_get_generic_recv(subreq, state, &count, &group); talloc_zfree(subreq); if (ret == ENOENT) { count = 0; } else if (ret != EOK) { goto done; } if (count == 1) { state->group = group[0]; } else if (count == 0) { /* group not found */ state->group = NULL; } else { DEBUG(SSSDBG_OP_FAILURE, "BASE search returned more than one records\n"); ret = EIO; goto done; } ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t sdap_nested_group_lookup_group_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct sysdb_attrs **_group) { struct sdap_nested_group_lookup_group_state *state = NULL; state = tevent_req_data(req, struct sdap_nested_group_lookup_group_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_group != NULL) { *_group = talloc_steal(mem_ctx, state->group); } return EOK; } struct sdap_nested_group_lookup_unknown_state { struct tevent_context *ev; struct sdap_nested_group_ctx *group_ctx; struct sdap_nested_group_member *member; enum sdap_nested_group_dn_type type; struct sysdb_attrs *entry; }; static void sdap_nested_group_lookup_unknown_user_done(struct tevent_req *subreq); static void sdap_nested_group_lookup_unknown_group_done(struct tevent_req *subreq); static struct tevent_req * sdap_nested_group_lookup_unknown_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct sdap_nested_group_member *member) { struct sdap_nested_group_lookup_unknown_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_lookup_unknown_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->group_ctx = group_ctx; state->member = member; /* try users first */ subreq = sdap_nested_group_lookup_user_send(state, state->ev, state->group_ctx, state->member); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_nested_group_lookup_unknown_user_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sdap_nested_group_lookup_unknown_user_done(struct tevent_req *subreq) { struct sdap_nested_group_lookup_unknown_state *state = NULL; struct tevent_req *req = NULL; struct sysdb_attrs *entry = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_nested_group_lookup_unknown_state); ret = sdap_nested_group_lookup_user_recv(state, subreq, &entry); talloc_zfree(subreq); if (ret != EOK) { goto done; } if (entry != NULL) { /* found in users */ state->entry = entry; state->type = SDAP_NESTED_GROUP_DN_USER; ret = EOK; goto done; } /* not found in users, try group */ subreq = sdap_nested_group_lookup_group_send(state, state->ev, state->group_ctx, state->member); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_nested_group_lookup_unknown_group_done, req); ret = EAGAIN; done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static void sdap_nested_group_lookup_unknown_group_done(struct tevent_req *subreq) { struct sdap_nested_group_lookup_unknown_state *state = NULL; struct tevent_req *req = NULL; struct sysdb_attrs *entry = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_nested_group_lookup_unknown_state); ret = sdap_nested_group_lookup_group_recv(state, subreq, &entry); talloc_zfree(subreq); if (ret != EOK) { goto done; } if (entry == NULL) { /* not found, end request */ state->entry = NULL; state->type = SDAP_NESTED_GROUP_DN_UNKNOWN; } else { /* found in groups */ state->entry = entry; state->type = SDAP_NESTED_GROUP_DN_GROUP; } ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t sdap_nested_group_lookup_unknown_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct sysdb_attrs **_entry, enum sdap_nested_group_dn_type *_type) { struct sdap_nested_group_lookup_unknown_state *state = NULL; state = tevent_req_data(req, struct sdap_nested_group_lookup_unknown_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_entry != NULL) { *_entry = talloc_steal(mem_ctx, state->entry); } if (_type != NULL) { *_type = state->type; } return EOK; } struct sdap_nested_group_deref_state { struct tevent_context *ev; struct sdap_nested_group_ctx *group_ctx; struct ldb_message_element *members; int nesting_level; struct sysdb_attrs **nested_groups; int num_groups; }; static void sdap_nested_group_deref_direct_done(struct tevent_req *subreq); static void sdap_nested_group_deref_done(struct tevent_req *subreq); static struct tevent_req * sdap_nested_group_deref_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_nested_group_ctx *group_ctx, struct ldb_message_element *members, const char *group_dn, int nesting_level) { struct sdap_nested_group_deref_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_attr_map_info *maps = NULL; static const int num_maps = 2; struct sdap_options *opts = group_ctx->opts; const char **attrs = NULL; size_t num_attrs = 0; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_deref_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->group_ctx = group_ctx; state->members = members; state->nesting_level = nesting_level; state->num_groups = 0; /* we will count exact number of the groups */ maps = talloc_array(state, struct sdap_attr_map_info, num_maps); if (maps == NULL) { ret = ENOMEM; goto immediately; } maps[0].map = opts->user_map; maps[0].num_attrs = opts->user_map_cnt; maps[1].map = opts->group_map; maps[1].num_attrs = SDAP_OPTS_GROUP; /* pull down the whole group map, * but only pull down username and originalDN for users */ ret = build_attrs_from_map(state, opts->group_map, SDAP_OPTS_GROUP, NULL, &attrs, &num_attrs); if (ret != EOK) { goto immediately; } attrs = talloc_realloc(state, attrs, const char *, num_attrs + 2); if (attrs == NULL) { ret = ENOMEM; goto immediately; } attrs[num_attrs] = group_ctx->opts->user_map[SDAP_AT_USER_NAME].name; attrs[num_attrs + 1] = NULL; /* send request */ subreq = sdap_deref_search_send(state, ev, opts, group_ctx->sh, group_dn, opts->group_map[SDAP_AT_GROUP_MEMBER].name, attrs, num_maps, maps, dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT)); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_nested_group_deref_direct_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t sdap_nested_group_deref_direct_process(struct tevent_req *subreq) { struct sdap_nested_group_deref_state *state = NULL; struct tevent_req *req = NULL; struct sdap_options *opts = NULL; struct sdap_deref_attrs **entries = NULL; struct ldb_message_element *members = NULL; const char *orig_dn = NULL; const char *member_dn = NULL; size_t num_entries = 0; size_t i, j; bool member_found; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_nested_group_deref_state); opts = state->group_ctx->opts; members = state->members; ret = sdap_deref_search_recv(subreq, state, &num_entries, &entries); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Received %zu dereference results, " "about to process them\n", num_entries); /* * We don't have any knowledge about possible number of groups when * dereferencing. We expect that every member is a group and we will * allocate enough space to hold it. We will shrink the memory later. */ state->nested_groups = talloc_zero_array(state, struct sysdb_attrs *, num_entries); if (state->nested_groups == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < num_entries; i++) { ret = sysdb_attrs_get_string(entries[i]->attrs, SYSDB_ORIG_DN, &orig_dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "The entry has no originalDN\n"); goto done; } /* Ensure that all members returned from the deref request are included * in the member processing. Sometimes we will get more results back * from deref/asq than we got from the initial lookup, as is the case * with Active Directory and its range retrieval mechanism. */ member_found = false; for (j = 0; j < members->num_values; j++) { /* FIXME: This is inefficient for very large sets of groups */ member_dn = (const char *)members->values[j].data; if (strcasecmp(orig_dn, member_dn) == 0) { member_found = true; break; } } if (!member_found) { /* Append newly found member to member list. * Changes in state->members will propagate into sysdb_attrs of * the group. */ state->members->values = talloc_realloc(members, members->values, struct ldb_val, members->num_values + 1); if (members->values == NULL) { ret = ENOMEM; goto done; } members->values[members->num_values].data = (uint8_t *)talloc_strdup(members->values, orig_dn); if (members->values[members->num_values].data == NULL) { ret = ENOMEM; goto done; } members->values[members->num_values].length = strlen(orig_dn); members->num_values++; } if (entries[i]->map == opts->user_map) { /* we found a user */ /* skip the user if it is not amongst configured search bases */ if (!sdap_nested_member_is_user(state->group_ctx, orig_dn, NULL)) { continue; } /* save user in hash table */ ret = sdap_nested_group_hash_user(state->group_ctx, entries[i]->attrs); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to save user in hash table " "[%d]: %s\n", ret, strerror(ret)); goto done; } } else if (entries[i]->map == opts->group_map) { /* we found a group */ /* skip the group if we have reached the nesting limit */ if (state->nesting_level >= state->group_ctx->max_nesting_level) { DEBUG(SSSDBG_TRACE_ALL, "[%s] is outside nesting limit " "(level %d), skipping\n", orig_dn, state->nesting_level); continue; } /* skip the group if it is not amongst configured search bases */ if (!sdap_nested_member_is_group(state->group_ctx, orig_dn, NULL)) { continue; } /* save group in hash table */ ret = sdap_nested_group_hash_group(state->group_ctx, entries[i]->attrs); if (ret == EEXIST) { continue; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to save group in hash table " "[%d]: %s\n", ret, strerror(ret)); goto done; } /* remember the group for later processing */ state->nested_groups[state->num_groups] = entries[i]->attrs; state->num_groups++; } else { /* this should never happen, but if it does, do not loop forever */ DEBUG(SSSDBG_MINOR_FAILURE, "Entry does not match any known map, skipping\n"); continue; } } /* adjust size of nested groups array */ if (state->num_groups > 0) { state->nested_groups = talloc_realloc(state, state->nested_groups, struct sysdb_attrs *, state->num_groups); if (state->nested_groups == NULL) { ret = ENOMEM; goto done; } } else { talloc_zfree(state->nested_groups); } ret = EOK; done: return ret; } static void sdap_nested_group_deref_direct_done(struct tevent_req *subreq) { struct sdap_nested_group_deref_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_nested_group_deref_state); /* process direct members */ ret = sdap_nested_group_deref_direct_process(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error processing direct membership " "[%d]: %s\n", ret, strerror(ret)); goto done; } /* we have processed all direct members, * now recurse and process nested groups */ subreq = sdap_nested_group_recurse_send(state, state->ev, state->group_ctx, state->nested_groups, state->num_groups, state->nesting_level + 1); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_nested_group_deref_done, req); ret = EAGAIN; done: if (ret == EOK) { /* tevent_req_error() cannot cope with EOK */ DEBUG(SSSDBG_CRIT_FAILURE, "We should not get here with EOK\n"); tevent_req_error(req, EINVAL); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static void sdap_nested_group_deref_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); /* process nested groups */ ret = sdap_nested_group_recurse_recv(subreq); talloc_zfree(subreq); if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } return; } static errno_t sdap_nested_group_deref_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct sdap_ext_member { struct sdap_external_missing_member *missing_mem; const char *ext_member_attr; enum sysdb_member_type member_type; struct sss_domain_info *dom; struct sysdb_attrs *attrs; }; struct sdap_nested_group_lookup_external_state { struct tevent_context *ev; struct sdap_ext_member_ctx *ext_ctx; struct sss_domain_info *group_dom; hash_table_t *missing_external; hash_entry_t *entries; unsigned long n_entries; unsigned long eniter; struct sdap_ext_member *ext_members; ext_member_send_fn_t ext_member_resolve_send; ext_member_recv_fn_t ext_member_resolve_recv; }; static errno_t sdap_nested_group_lookup_external_step(struct tevent_req *req); static void sdap_nested_group_lookup_external_done(struct tevent_req *subreq); static errno_t sdap_nested_group_lookup_external_link(struct tevent_req *req); static errno_t sdap_nested_group_lookup_external_link_member( struct sdap_nested_group_lookup_external_state *state, struct sdap_ext_member *member); static errno_t sdap_nested_group_memberof_dn_by_original_dn( TALLOC_CTX *mem_ctx, struct sss_domain_info *group_dom, const char *original_dn, const char ***_parents); struct tevent_req * sdap_nested_group_lookup_external_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sss_domain_info *group_dom, struct sdap_ext_member_ctx *ext_ctx, hash_table_t *missing_external) { struct sdap_nested_group_lookup_external_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_nested_group_lookup_external_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->ev = ev; state->group_dom = group_dom; state->ext_ctx = ext_ctx; state->missing_external = missing_external; if (state->ext_ctx->ext_member_resolve_send == NULL || state->ext_ctx->ext_member_resolve_recv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrong private context\n"); ret = EINVAL; goto immediately; } ret = hash_entries(state->missing_external, &state->n_entries, &state->entries); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_entries returned %d\n", ret); ret = EIO; goto immediately; } state->eniter = 0; state->ext_members = talloc_zero_array(state, struct sdap_ext_member, state->n_entries); if (state->ext_members == NULL) { ret = ENOMEM; goto immediately; } ret = sdap_nested_group_lookup_external_step(req); if (ret != EAGAIN) { goto immediately; } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t sdap_nested_group_lookup_external_step(struct tevent_req *req) { struct tevent_req *subreq = NULL; struct sdap_nested_group_lookup_external_state *state = NULL; state = tevent_req_data(req, struct sdap_nested_group_lookup_external_state); subreq = state->ext_ctx->ext_member_resolve_send(state, state->ev, state->entries[state->eniter].key.str, state->ext_ctx->pvt); if (subreq == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Refreshing member %lu/%lu\n", state->eniter, state->n_entries); tevent_req_set_callback(subreq, sdap_nested_group_lookup_external_done, req); return EAGAIN; } static void sdap_nested_group_lookup_external_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = NULL; struct sdap_nested_group_lookup_external_state *state = NULL; enum sysdb_member_type member_type; struct sysdb_attrs *member; struct sss_domain_info *member_dom; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_nested_group_lookup_external_state); ret = state->ext_ctx->ext_member_resolve_recv(state, subreq, &member_type, &member_dom, &member); talloc_free(subreq); if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Refreshed member %lu\n", state->eniter); state->ext_members[state->eniter].missing_mem = \ state->entries[state->eniter].value.ptr; state->ext_members[state->eniter].dom = member_dom; state->ext_members[state->eniter].ext_member_attr = \ talloc_steal(state->ext_members, state->entries[state->eniter].key.str); state->ext_members[state->eniter].member_type = member_type; state->ext_members[state->eniter].attrs = \ talloc_steal(state->ext_members, member); } state->eniter++; if (state->eniter >= state->n_entries) { DEBUG(SSSDBG_TRACE_FUNC, "All external members processed\n"); ret = sdap_nested_group_lookup_external_link(req); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); return; } ret = sdap_nested_group_lookup_external_step(req); if (ret != EOK && ret != EAGAIN) { tevent_req_error(req, ret); return; } return; } static errno_t sdap_nested_group_lookup_external_link(struct tevent_req *req) { errno_t ret, tret; bool in_transaction = false; struct sdap_nested_group_lookup_external_state *state = NULL; state = tevent_req_data(req, struct sdap_nested_group_lookup_external_state); ret = sysdb_transaction_start(state->group_dom->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto fail; } in_transaction = true; for (size_t i = 0; i < state->eniter; i++) { if (state->ext_members[i].attrs == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "The member %s could not be resolved\n", state->ext_members[i].ext_member_attr); continue; } ret = sdap_nested_group_lookup_external_link_member(state, &state->ext_members[i]); if (ret != EOK) { goto fail; } } ret = sysdb_transaction_commit(state->group_dom->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto fail; } in_transaction = false; return EOK; fail: if (in_transaction) { tret = sysdb_transaction_cancel(state->group_dom->sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } return EFAULT; } static errno_t sdap_nested_group_lookup_external_link_member( struct sdap_nested_group_lookup_external_state *state, struct sdap_ext_member *member) { const char *name; int ret; const char **parents = NULL; size_t i; TALLOC_CTX *tmp_ctx; const char *orig_dn; tmp_ctx = talloc_new(state); if (tmp_ctx == NULL) { return ENOMEM; } ret = sysdb_attrs_get_string(member->attrs, SYSDB_NAME, &name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "No name for a user\n"); goto done; } /* This only works because the groups were saved in a previous * transaction */ for (i=0; i < member->missing_mem->parent_dn_idx; i++) { orig_dn = member->missing_mem->parent_group_dns[i]; DEBUG(SSSDBG_TRACE_INTERNAL, "Linking external members %s from domain %s to parents of %s\n", name, member->dom->name, orig_dn); ret = sdap_nested_group_memberof_dn_by_original_dn(tmp_ctx, state->group_dom, orig_dn, &parents); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot find parents of %s\n", orig_dn); continue; } /* We don't have to remove the members here, since all members attributes * are always written anew */ ret = sysdb_update_members_dn(member->dom, name, member->member_type, parents, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot link %s@%s to its parents\n", name, member->dom->name); goto done; } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t sdap_nested_group_memberof_dn_by_original_dn( TALLOC_CTX *mem_ctx, struct sss_domain_info *group_dom, const char *original_dn, const char ***_parents) { errno_t ret; char *sanitized_dn; char *filter; const char *attrs[] = { SYSDB_NAME, SYSDB_MEMBEROF, NULL }; struct ldb_message **msgs = NULL; size_t count; TALLOC_CTX *tmp_ctx; struct ldb_message_element *memberof; const char **parents; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { return ENOMEM; } ret = sss_filter_sanitize(tmp_ctx, original_dn, &sanitized_dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot sanitize originalDN [%s]\n", original_dn); goto done; } filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_ORIG_DN, sanitized_dn); if (filter == NULL) { goto done; } ret = sysdb_search_groups(tmp_ctx, group_dom, filter, attrs, &count, &msgs); if (ret != EOK) { goto done; } if (count != 1) { DEBUG(SSSDBG_OP_FAILURE, "More than one entry found by originalDN?\n"); goto done; } memberof = ldb_msg_find_element(msgs[0], SYSDB_MEMBEROF); if (memberof == NULL || memberof->num_values == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "The external group is not a member of any groups\n"); ret = ENOENT; goto done; } parents = talloc_zero_array(tmp_ctx, const char *, memberof->num_values + 1); if (parents == NULL) { ret = ENOMEM; goto done; } for (size_t i = 0; i < memberof->num_values; i++) { parents[i] = talloc_strdup(parents, (const char *) memberof->values[i].data); if (parents[i] == NULL) { ret = ENOMEM; goto done; } } *_parents = talloc_steal(mem_ctx, parents); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sdap_nested_group_lookup_external_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_id_enum.c0000644000000000000000000000007412703456111020635 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.770794022 sssd-1.13.4/src/providers/ldap/ldap_id_enum.c0000644002412700241270000001366112703456111022313 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Identity Enumeration Authors: Simo Sorce Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async_enum.h" #define LDAP_ENUM_PURGE_TIMEOUT 10800 errno_t ldap_setup_enumeration(struct be_ctx *be_ctx, struct sdap_options *opts, struct sdap_domain *sdom, be_ptask_send_t send_fn, be_ptask_recv_t recv_fn, void *pvt) { errno_t ret; time_t first_delay; time_t period; time_t cleanup; bool has_enumerated; struct ldap_enum_ctx *ectx; ret = sysdb_has_enumerated(sdom->dom, &has_enumerated); if (ret == ENOENT) { /* default value */ has_enumerated = false; } else if (ret != EOK) { return ret; } if (has_enumerated) { /* At least one enumeration has previously run, * so clients will get cached data. We will delay * starting to enumerate by 10s so we don't slow * down the startup process if this is happening * during system boot. */ first_delay = 10; } else { /* This is our first startup. Schedule the * enumeration to start immediately once we * enter the mainloop. */ first_delay = 0; } cleanup = dp_opt_get_int(opts->basic, SDAP_PURGE_CACHE_TIMEOUT); if (cleanup == 0) { /* We need to cleanup the cache once in a while when enumerating, otherwise * enumeration would only download deltas since the previous lastUSN and would * not detect removed entries */ ret = dp_opt_set_int(opts->basic, SDAP_PURGE_CACHE_TIMEOUT, LDAP_ENUM_PURGE_TIMEOUT); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set cleanup timeout, enumeration wouldn't " "detect removed entries!\n"); return ret; } } period = dp_opt_get_int(opts->basic, SDAP_ENUM_REFRESH_TIMEOUT); ectx = talloc(sdom, struct ldap_enum_ctx); if (ectx == NULL) { return ENOMEM; } ectx->sdom = sdom; ectx->pvt = pvt; ret = be_ptask_create(sdom, be_ctx, period, /* period */ first_delay, /* first_delay */ 5, /* enabled delay */ 0, /* random offset */ period, /* timeout */ BE_PTASK_OFFLINE_SKIP, 0, /* max_backoff */ send_fn, recv_fn, ectx, "enumeration", &sdom->enum_task); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize enumeration periodic task\n"); talloc_free(ectx); return ret; } talloc_steal(sdom->enum_task, ectx); return EOK; } struct ldap_enumeration_state { struct ldap_enum_ctx *ectx; struct sdap_id_ctx *id_ctx; struct sss_domain_info *dom; }; static void ldap_enumeration_done(struct tevent_req *subreq); struct tevent_req * ldap_enumeration_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct ldap_enumeration_state *state; struct tevent_req *req; struct tevent_req *subreq; struct ldap_enum_ctx *ectx; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct ldap_enumeration_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } ectx = talloc_get_type(pvt, struct ldap_enum_ctx); if (ectx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot retrieve ldap_enum_ctx!\n"); ret = EFAULT; goto fail; } state->ectx = ectx; state->dom = ectx->sdom->dom; state->id_ctx = talloc_get_type_abort(ectx->pvt, struct sdap_id_ctx); subreq = sdap_dom_enum_send(state, ev, state->id_ctx, ectx->sdom, state->id_ctx->conn); if (subreq == NULL) { /* The ptask API will reschedule the enumeration on its own on * failure */ DEBUG(SSSDBG_OP_FAILURE, "Failed to schedule enumeration, retrying later!\n"); ret = EIO; goto fail; } tevent_req_set_callback(subreq, ldap_enumeration_done, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void ldap_enumeration_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); ret = sdap_dom_enum_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } errno_t ldap_enumeration_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_groups.c0000644000000000000000000000007312703456111021737 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.780794056 sssd-1.13.4/src/providers/ldap/sdap_async_groups.c0000644002412700241270000025104312703456111023414 0ustar00jhrozekjhrozek00000000000000/* SSSD Async LDAP Helper routines - retrieving groups Copyright (C) Simo Sorce - 2009 Copyright (C) 2010, Ralf Haferkamp , Novell Inc. Copyright (C) Jan Zeleny - 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ad/ad_common.h" /* ==Group-Parsing Routines=============================================== */ static int sdap_find_entry_by_origDN(TALLOC_CTX *memctx, struct sysdb_ctx *ctx, struct sss_domain_info *domain, const char *orig_dn, char **_localdn, bool *_is_group) { TALLOC_CTX *tmpctx; const char *attrs[] = {SYSDB_OBJECTCLASS, NULL}; struct ldb_dn *base_dn; char *filter; struct ldb_message **msgs; size_t num_msgs; int ret; char *sanitized_dn; const char *objectclass; tmpctx = talloc_new(NULL); if (!tmpctx) { return ENOMEM; } ret = sss_filter_sanitize(tmpctx, orig_dn, &sanitized_dn); if (ret != EOK) { ret = ENOMEM; goto done; } filter = talloc_asprintf(tmpctx, "%s=%s", SYSDB_ORIG_DN, sanitized_dn); if (!filter) { ret = ENOMEM; goto done; } base_dn = sysdb_domain_dn(tmpctx, domain); if (!base_dn) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Searching cache for [%s].\n", sanitized_dn); ret = sysdb_search_entry(tmpctx, ctx, base_dn, LDB_SCOPE_SUBTREE, filter, attrs, &num_msgs, &msgs); if (ret) { goto done; } if (num_msgs != 1) { ret = ENOENT; goto done; } *_localdn = talloc_strdup(memctx, ldb_dn_get_linearized(msgs[0]->dn)); if (!*_localdn) { ret = ENOENT; goto done; } if (_is_group != NULL) { objectclass = ldb_msg_find_attr_as_string(msgs[0], SYSDB_OBJECTCLASS, NULL); if (objectclass == NULL) { DEBUG(SSSDBG_OP_FAILURE, "An antry without a %s?\n", SYSDB_OBJECTCLASS); ret = EINVAL; goto done; } *_is_group = strcmp(SYSDB_GROUP_CLASS, objectclass) == 0; } ret = EOK; done: talloc_zfree(tmpctx); return ret; } static errno_t sdap_get_members_with_primary_gid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, gid_t gid, char ***_localdn, size_t *_ndn) { static const char *search_attrs[] = { SYSDB_NAME, NULL }; char *filter; struct ldb_message **msgs; size_t count; size_t i; errno_t ret; char **localdn; /* Don't search if the group is non-posix */ if (!gid) return EOK; filter = talloc_asprintf(mem_ctx, "(%s=%llu)", SYSDB_GIDNUM, (unsigned long long) gid); if (!filter) { return ENOMEM; } ret = sysdb_search_users(mem_ctx, domain, filter, search_attrs, &count, &msgs); talloc_free(filter); if (ret == ENOENT) { *_localdn = NULL; *_ndn = 0; return EOK; } else if (ret != EOK) { return ret; } localdn = talloc_array(mem_ctx, char *, count); if (!localdn) { talloc_free(msgs); return ENOMEM; } for (i=0; i < count; i++) { localdn[i] = talloc_strdup(localdn, ldb_dn_get_linearized(msgs[i]->dn)); if (!localdn[i]) { talloc_free(localdn); talloc_free(msgs); return ENOMEM; } } talloc_free(msgs); *_localdn = localdn; *_ndn = count; return EOK; } static errno_t sdap_dn_by_primary_gid(TALLOC_CTX *mem_ctx, struct sysdb_attrs *ldap_attrs, struct sss_domain_info *domain, struct sdap_options *opts, char ***_dn_list, size_t *_count) { gid_t gid; errno_t ret; ret = sysdb_attrs_get_uint32_t(ldap_attrs, opts->group_map[SDAP_AT_GROUP_GID].sys_name, &gid); if (ret == ENOENT) { /* Non-posix AD group. Skip. */ *_dn_list = NULL; *_count = 0; return EOK; } else if (ret && ret != ENOENT) { return ret; } ret = sdap_get_members_with_primary_gid(mem_ctx, domain, gid, _dn_list, _count); if (ret) return ret; return EOK; } static bool has_member(struct ldb_message_element *member_el, char *member) { struct ldb_val val; val.data = (uint8_t *) member; val.length = strlen(member); /* This is bad complexity, but the this loop should only be invoked in * the very rare scenario of AD POSIX group that is primary group of * some users but has user member attributes at the same time */ if (ldb_msg_find_val(member_el, &val) != NULL) { return true; } return false; } static void link_pgroup_members(struct sysdb_attrs *group_attrs, struct ldb_message_element *member_el, char **userdns, size_t nuserdns) { int i, j; j = 0; for (i=0; i < nuserdns; i++) { if (has_member(member_el, userdns[i])) { DEBUG(SSSDBG_TRACE_INTERNAL, "Member %s already included, skipping\n", userdns[i]); continue; } member_el->values[member_el->num_values + j].data = (uint8_t *) \ talloc_steal(group_attrs, userdns[i]); member_el->values[member_el->num_values + j].length = \ strlen(userdns[i]); j++; } member_el->num_values += j; } static int sdap_fill_memberships(struct sdap_options *opts, struct sysdb_attrs *group_attrs, struct sysdb_ctx *ctx, struct sss_domain_info *domain, hash_table_t *ghosts, struct ldb_val *values, int num_values, char **userdns, size_t nuserdns) { struct ldb_message_element *el; int i, j; int ret; errno_t hret; hash_key_t key; hash_value_t value; struct sdap_domain *sdom; struct sysdb_ctx *member_sysdb; struct sss_domain_info *member_dom; ret = sysdb_attrs_get_el(group_attrs, SYSDB_MEMBER, &el); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_attrs_get_el failed\n"); goto done; } /* Just allocate both big enough to contain all members for now */ el->values = talloc_realloc(group_attrs, el->values, struct ldb_val, el->num_values + num_values + nuserdns); if (!el->values) { DEBUG(SSSDBG_MINOR_FAILURE, "No memory to allocate group attrs\n"); ret = ENOMEM; goto done; } j = el->num_values; for (i = 0; i < num_values; i++) { if (ghosts == NULL) { hret = HASH_ERROR_KEY_NOT_FOUND; } else { key.type = HASH_KEY_STRING; key.str = (char *)values[i].data; hret = hash_lookup(ghosts, &key, &value); } if (hret == HASH_ERROR_KEY_NOT_FOUND) { sdom = sdap_domain_get_by_dn(opts, (char *)values[i].data); if (sdom == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Member [%s] is it out of domain " "scope?\n", (char *)values[i].data); member_sysdb = ctx; member_dom = domain; } else { member_sysdb = sdom->dom->sysdb; member_dom = sdom->dom; } /* sync search entry with this as origDN */ ret = sdap_find_entry_by_origDN(el->values, member_sysdb, member_dom, (char *)values[i].data, (char **)&el->values[j].data, NULL); if (ret == ENOENT) { /* member may be outside of the configured search bases * or out of scope of nesting limit */ DEBUG(SSSDBG_MINOR_FAILURE, "Member [%s] was not found in " "cache. Is it out of scope?\n", (char *)values[i].data); continue; } if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "'sdap_find_entry_by_origDN' failed for member [%s].\n", (char *)values[i].data); goto done; } DEBUG(SSSDBG_TRACE_LIBS, " member #%d (%s): [%s]\n", i, (char *)values[i].data, (char *)el->values[j].data); el->values[j].length = strlen((char *)el->values[j].data); j++; } else if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "hash_lookup failed: [%d]: %s\n", hret, strerror(hret)); ret = EFAULT; goto done; } /* If the member is in ghost table, it has * already been processed - just skip it */ } el->num_values = j; link_pgroup_members(group_attrs, el, userdns, nuserdns); ret = EOK; done: return ret; } /* ==Save-Group-Entry===================================================== */ /* FIXME: support non legacy */ /* FIXME: support storing additional attributes */ static errno_t sdap_store_group_with_gid(struct sss_domain_info *domain, const char *name, gid_t gid, struct sysdb_attrs *group_attrs, uint64_t cache_timeout, bool posix_group, time_t now) { errno_t ret; /* make sure that non-posix (empty or explicit gid=0) groups have the * gidNumber set to zero even if updating existing group */ if (!posix_group) { ret = sysdb_attrs_add_uint32(group_attrs, SYSDB_GIDNUM, 0); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not set explicit GID 0 for %s\n", name); return ret; } } ret = sysdb_store_group(domain, name, gid, group_attrs, cache_timeout, now); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not store group %s\n", name); return ret; } return ret; } static errno_t sdap_process_ghost_members(struct sysdb_attrs *attrs, struct sdap_options *opts, hash_table_t *ghosts, bool populate_members, bool store_original_member, struct sysdb_attrs *sysdb_attrs) { errno_t ret; struct ldb_message_element *gh; struct ldb_message_element *memberel; struct ldb_message_element *sysdb_memberel; struct ldb_message_element *ghostel; size_t cnt; int i; int hret; hash_key_t key; hash_value_t value; ret = sysdb_attrs_get_el(attrs, SYSDB_GHOST, &gh); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error reading ghost attributes: [%s]\n", strerror(ret)); return ret; } ret = sysdb_attrs_get_el_ext(attrs, opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, false, &memberel); if (ret == ENOENT) { /* Create a dummy element with no values in order for the loop to just * fall through and make sure the attrs array is not reallocated. */ memberel = talloc(attrs, struct ldb_message_element); if (memberel == NULL) { return ENOMEM; } memberel->num_values = 0; memberel->values = NULL; } else if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error reading members: [%s]\n", strerror(ret)); return ret; } if (store_original_member) { DEBUG(SSSDBG_TRACE_FUNC, "The group has %d members\n", memberel->num_values); for (i = 0; i < memberel->num_values; i++) { ret = sysdb_attrs_add_string(sysdb_attrs, SYSDB_ORIG_MEMBER, (const char *) memberel->values[i].data); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not add member [%s]\n", (const char *) memberel->values[i].data); return ret; } } } if (populate_members) { ret = sysdb_attrs_get_el(sysdb_attrs, SYSDB_MEMBER, &sysdb_memberel); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error reading group members from group_attrs: [%s]\n", strerror(ret)); return ret; } sysdb_memberel->values = memberel->values; sysdb_memberel->num_values = memberel->num_values; } ret = sysdb_attrs_get_el(sysdb_attrs, SYSDB_GHOST, &ghostel); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error getting ghost element: [%s]\n", strerror(ret)); return ret; } ghostel->values = gh->values; ghostel->num_values = gh->num_values; cnt = ghostel->num_values + memberel->num_values; DEBUG(SSSDBG_TRACE_FUNC, "Group has %zu members\n", cnt); /* Now process RFC2307bis ghost hash table */ if (ghosts && cnt > 0) { ghostel->values = talloc_realloc(sysdb_attrs, ghostel->values, struct ldb_val, cnt); if (ghostel->values == NULL) { return ENOMEM; } for (i = 0; i < memberel->num_values; i++) { key.type = HASH_KEY_STRING; key.str = (char *) memberel->values[i].data; hret = hash_lookup(ghosts, &key, &value); if (hret == HASH_ERROR_KEY_NOT_FOUND) { continue; } else if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Error checking hash table: [%s]\n", hash_error_string(hret)); return EFAULT; } DEBUG(SSSDBG_TRACE_FUNC, "Adding ghost member for group [%s]\n", (char *) value.ptr); ghostel->values[ghostel->num_values].data = \ (uint8_t *) talloc_strdup(ghostel->values, value.ptr); if (ghostel->values[ghostel->num_values].data == NULL) { return ENOMEM; } ghostel->values[ghostel->num_values].length = strlen(value.ptr); ghostel->num_values++; } } return EOK; } static int sdap_save_group(TALLOC_CTX *memctx, struct sdap_options *opts, struct sss_domain_info *dom, struct sysdb_attrs *attrs, bool populate_members, bool store_original_member, hash_table_t *ghosts, char **_usn_value, time_t now) { struct ldb_message_element *el; struct sysdb_attrs *group_attrs; const char *group_name = NULL; gid_t gid; errno_t ret; char *usn_value = NULL; TALLOC_CTX *tmpctx = NULL; bool posix_group; bool use_id_mapping; bool need_filter; char *sid_str; struct sss_domain_info *subdomain; tmpctx = talloc_new(NULL); if (!tmpctx) { ret = ENOMEM; goto done; } group_attrs = sysdb_new_attrs(tmpctx); if (group_attrs == NULL) { ret = ENOMEM; goto done; } /* Always store SID string if available */ ret = sdap_attrs_get_sid_str(tmpctx, opts->idmap_ctx, attrs, opts->group_map[SDAP_AT_GROUP_OBJECTSID].sys_name, &sid_str); if (ret == EOK) { ret = sysdb_attrs_add_string(group_attrs, SYSDB_SID_STR, sid_str); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add SID string: [%s]\n", sss_strerror(ret)); goto done; } } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "objectSID: not available for group [%s].\n", group_name); sid_str = NULL; } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not identify objectSID: [%s]\n", sss_strerror(ret)); sid_str = NULL; } /* Always store UUID if available */ ret = sysdb_handle_original_uuid( opts->group_map[SDAP_AT_GROUP_UUID].def_name, attrs, opts->group_map[SDAP_AT_GROUP_UUID].sys_name, group_attrs, SYSDB_UUID); if (ret != EOK) { DEBUG((ret == ENOENT) ? SSSDBG_TRACE_ALL : SSSDBG_MINOR_FAILURE, "Failed to retrieve UUID [%d][%s].\n", ret, sss_strerror(ret)); } /* If this object has a SID available, we will determine the correct * domain by its SID. */ if (sid_str != NULL) { subdomain = sss_get_domain_by_sid_ldap_fallback(get_domains_head(dom), sid_str); if (subdomain) { dom = subdomain; } else { DEBUG(SSSDBG_TRACE_FUNC, "SID %s does not belong to any known " "domain\n", sid_str); } } ret = sdap_get_group_primary_name(tmpctx, opts, attrs, dom, &group_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get group name\n"); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Processing group %s\n", group_name); posix_group = true; ret = sdap_check_ad_group_type(dom, opts, attrs, group_name, &need_filter); if (ret != EOK) { goto done; } if (need_filter) { posix_group = false; gid = 0; ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, false); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error: Failed to mark group as non-posix!\n"); return ret; } } if (posix_group) { use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx, dom->name, sid_str); if (use_id_mapping) { posix_group = true; if (sid_str == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "SID not available, cannot map a " \ "unix ID to group [%s].\n", group_name); ret = ENOENT; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Mapping group [%s] objectSID [%s] to unix ID\n", group_name, sid_str); /* Convert the SID into a UNIX group ID */ ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &gid); if (ret == ENOTSUP) { /* ENOTSUP is returned if built-in SID was provided * => do not store the group, but return EOK */ DEBUG(SSSDBG_TRACE_FUNC, "Skipping built-in object.\n"); ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not convert SID string: [%s]\n", sss_strerror(ret)); goto done; } /* Store the GID in the ldap_attrs so it doesn't get * treated as a missing attribute from LDAP and removed. */ ret = sdap_replace_id(attrs, SYSDB_GIDNUM, gid); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set the id-mapped GID\n"); goto done; } } else { ret = sysdb_attrs_get_bool(attrs, SYSDB_POSIX, &posix_group); if (ret == ENOENT) { posix_group = true; } else if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error reading posix attribute: [%s]\n", sss_strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "This is%s a posix group\n", (posix_group)?"":" not"); ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, posix_group); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error setting posix attribute: [%s]\n", sss_strerror(ret)); goto done; } ret = sysdb_attrs_get_uint32_t(attrs, opts->group_map[SDAP_AT_GROUP_GID].sys_name, &gid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "no gid provided for [%s] in domain [%s].\n", group_name, dom->name); ret = EINVAL; goto done; } } } /* check that the gid is valid for this domain */ if (posix_group) { if (OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) { DEBUG(SSSDBG_MINOR_FAILURE, "Group [%s] filtered out! (id out of range)\n", group_name); ret = EINVAL; goto done; } /* Group ID OK */ } ret = sdap_attrs_add_string(attrs, SYSDB_ORIG_DN, "original DN", group_name, group_attrs); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error setting original DN: [%s]\n", sss_strerror(ret)); goto done; } ret = sdap_attrs_add_string(attrs, opts->group_map[SDAP_AT_GROUP_MODSTAMP].sys_name, "original mod-Timestamp", group_name, group_attrs); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error setting mod timestamp: [%s]\n", sss_strerror(ret)); goto done; } ret = sysdb_attrs_get_el(attrs, opts->group_map[SDAP_AT_GROUP_USN].sys_name, &el); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Error looking up group USN: [%s]\n", sss_strerror(ret)); goto done; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_FUNC, "Original USN value is not available for [%s].\n", group_name); } else { ret = sysdb_attrs_add_string(group_attrs, opts->group_map[SDAP_AT_GROUP_USN].sys_name, (const char*)el->values[0].data); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Error setting group USN: [%s]\n", sss_strerror(ret)); goto done; } usn_value = talloc_strdup(tmpctx, (const char*)el->values[0].data); if (!usn_value) { ret = ENOMEM; goto done; } } ret = sdap_process_ghost_members(attrs, opts, ghosts, populate_members, store_original_member, group_attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to save ghost members\n"); goto done; } ret = sdap_save_all_names(group_name, attrs, dom, group_attrs); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save group names\n"); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Storing info for group %s\n", group_name); ret = sdap_store_group_with_gid(dom, group_name, gid, group_attrs, dom->group_timeout, posix_group, now); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not store group with GID: [%s]\n", sss_strerror(ret)); goto done; } if (_usn_value) { *_usn_value = talloc_steal(memctx, usn_value); } talloc_steal(memctx, group_attrs); ret = EOK; done: if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to save group [%s]: [%s]\n", group_name ? group_name : "Unknown", sss_strerror(ret)); } talloc_free(tmpctx); return ret; } static errno_t are_sids_from_same_dom(const char *sid1, const char *sid2, bool *_result) { size_t len_prefix_sid1; size_t len_prefix_sid2; char *rid1, *rid2; bool result; rid1 = strrchr(sid1, '-'); if (rid1 == NULL) { return EINVAL; } rid2 = strrchr(sid2, '-'); if (rid2 == NULL) { return EINVAL; } len_prefix_sid1 = rid1 - sid1; len_prefix_sid2 = rid2 - sid2; result = (len_prefix_sid1 == len_prefix_sid2) && (strncmp(sid1, sid2, len_prefix_sid1) == 0); *_result = result; return EOK; } static errno_t retain_extern_members(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *group_name, const char *group_sid, char ***_userdns, size_t *_nuserdns) { TALLOC_CTX *tmp_ctx; const char **sids, **dns; bool same_domain; errno_t ret; size_t i, n; size_t nuserdns = 0; const char **userdns = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = sysdb_get_sids_of_members(tmp_ctx, dom, group_name, &sids, &dns, &n); if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "get_sids_of_members failed: %d [%s]\n", ret, sss_strerror(ret)); } goto done; } for (i=0; i < n; i++) { ret = are_sids_from_same_dom(group_sid, sids[i], &same_domain); if (ret == EOK && !same_domain) { DEBUG(SSSDBG_TRACE_ALL, "extern member: %s\n", dns[i]); nuserdns++; userdns = talloc_realloc(tmp_ctx, userdns, const char*, nuserdns); if (userdns == NULL) { ret = ENOMEM; goto done; } userdns[nuserdns-1] = talloc_steal(userdns, dns[i]); } } *_nuserdns = nuserdns; *_userdns = discard_const(talloc_steal(mem_ctx, userdns)); ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* ==Save-Group-Memebrs=================================================== */ /* FIXME: support non legacy */ /* FIXME: support storing additional attributes */ static int sdap_save_grpmem(TALLOC_CTX *memctx, struct sysdb_ctx *ctx, struct sdap_options *opts, struct sss_domain_info *dom, struct sysdb_attrs *attrs, hash_table_t *ghosts, time_t now) { struct ldb_message_element *el; struct sysdb_attrs *group_attrs = NULL; const char *group_sid; const char *group_name; char **userdns = NULL; size_t nuserdns = 0; struct sss_domain_info *group_dom = NULL; int ret; if (dom->ignore_group_members) { DEBUG(SSSDBG_CRIT_FAILURE, "Group members are ignored, nothing to do. If you see this " \ "message it might indicate an error in the group processing " \ "logic.\n"); return EOK; } ret = sysdb_attrs_get_string(attrs, SYSDB_SID_STR, &group_sid); if (ret != EOK) { /* Try harder. */ ret = sdap_attrs_get_sid_str(memctx, opts->idmap_ctx, attrs, opts->group_map[SDAP_AT_GROUP_OBJECTSID].sys_name, discard_const(&group_sid)); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Failed to get group sid\n"); group_sid = NULL; } } if (group_sid != NULL) { group_dom = sss_get_domain_by_sid_ldap_fallback(get_domains_head(dom), group_sid); if (group_dom == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "SID [%s] does not belong to any known " "domain, using [%s].\n", group_sid, dom->name); } } if (group_dom == NULL) { group_dom = dom; } ret = sdap_get_group_primary_name(memctx, opts, attrs, group_dom, &group_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get group name\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "Processing group %s\n", group_name); /* With AD we also want to merge in parent groups of primary GID as they * are reported with tokenGroups, too */ if (opts->schema_type == SDAP_SCHEMA_AD) { ret = sdap_dn_by_primary_gid(memctx, attrs, group_dom, opts, &userdns, &nuserdns); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sdap_dn_by_primary_gid failed: [%d][%s].\n", ret, strerror(ret)); goto fail; } } /* This is a temporal solution until the IPA provider is able to * resolve external group membership. * https://fedorahosted.org/sssd/ticket/2522 */ if (opts->schema_type == SDAP_SCHEMA_IPA_V1) { if (group_sid != NULL) { ret = retain_extern_members(memctx, group_dom, group_name, group_sid, &userdns, &nuserdns); if (ret != EOK) { DEBUG(SSSDBG_TRACE_INTERNAL, "retain_extern_members failed: %d:[%s].\n", ret, sss_strerror(ret)); } } } ret = sysdb_attrs_get_el(attrs, opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, &el); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_attrs_get_el failed: [%d][%s].\n", ret, strerror(ret)); goto fail; } if (el->num_values == 0 && nuserdns == 0) { DEBUG(SSSDBG_TRACE_FUNC, "No members for group [%s]\n", group_name); } else { DEBUG(SSSDBG_TRACE_FUNC, "Adding member users to group [%s]\n", group_name); group_attrs = sysdb_new_attrs(memctx); if (!group_attrs) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_new_attrs failed\n"); ret = ENOMEM; goto fail; } ret = sdap_fill_memberships(opts, group_attrs, ctx, group_dom, ghosts, el->values, el->num_values, userdns, nuserdns); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_fill_memberships failed with [%d]: %s\n", ret, strerror(ret)); goto fail; } } ret = sysdb_store_group(group_dom, group_name, 0, group_attrs, group_dom->group_timeout, now); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_store_group failed: [%d][%s].\n", ret, strerror(ret)); goto fail; } return EOK; fail: DEBUG(SSSDBG_OP_FAILURE, "Failed to save members of group %s\n", group_name); return ret; } /* ==Generic-Function-to-save-multiple-groups============================= */ static int sdap_save_groups(TALLOC_CTX *memctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct sdap_options *opts, struct sysdb_attrs **groups, int num_groups, bool populate_members, hash_table_t *ghosts, bool save_orig_member, char **_usn_value) { TALLOC_CTX *tmpctx; char *higher_usn = NULL; char *usn_value; bool twopass; bool has_nesting = false; int ret; errno_t sret; int i; struct sysdb_attrs **saved_groups = NULL; int nsaved_groups = 0; time_t now; bool in_transaction = false; switch (opts->schema_type) { case SDAP_SCHEMA_RFC2307: twopass = false; break; case SDAP_SCHEMA_RFC2307BIS: case SDAP_SCHEMA_IPA_V1: case SDAP_SCHEMA_AD: twopass = true; has_nesting = true; break; default: return EINVAL; } tmpctx = talloc_new(memctx); if (!tmpctx) { return ENOMEM; } ret = sysdb_transaction_start(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; if (twopass && !populate_members) { saved_groups = talloc_array(tmpctx, struct sysdb_attrs *, num_groups); if (!saved_groups) { ret = ENOMEM; goto done; } } now = time(NULL); for (i = 0; i < num_groups; i++) { usn_value = NULL; /* if 2 pass savemembers = false */ ret = sdap_save_group(tmpctx, opts, dom, groups[i], populate_members, has_nesting && save_orig_member, ghosts, &usn_value, now); /* Do not fail completely on errors. * Just report the failure to save and go on */ if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store group %d. Ignoring.\n", i); } else { DEBUG(SSSDBG_TRACE_ALL, "Group %d processed!\n", i); if (twopass && !populate_members) { saved_groups[nsaved_groups] = groups[i]; nsaved_groups++; } } if (usn_value) { if (higher_usn) { if ((strlen(usn_value) > strlen(higher_usn)) || (strcmp(usn_value, higher_usn) > 0)) { talloc_zfree(higher_usn); higher_usn = usn_value; } else { talloc_zfree(usn_value); } } else { higher_usn = usn_value; } } } if (twopass && !populate_members) { for (i = 0; i < nsaved_groups; i++) { ret = sdap_save_grpmem(tmpctx, sysdb, opts, dom, saved_groups[i], ghosts, now); /* Do not fail completely on errors. * Just report the failure to save and go on */ if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store group %d members.\n", i); } else { DEBUG(SSSDBG_TRACE_ALL, "Group %d members processed!\n", i); } } } ret = sysdb_transaction_commit(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction!\n"); goto done; } in_transaction = false; if (_usn_value) { *_usn_value = talloc_steal(memctx, higher_usn); } done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_zfree(tmpctx); return ret; } /* ==Process-Groups======================================================= */ struct sdap_process_group_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; struct sss_domain_info *dom; struct sysdb_ctx *sysdb; struct sysdb_attrs *group; struct ldb_message_element* sysdb_dns; struct ldb_message_element* ghost_dns; char **queued_members; int queue_len; const char **attrs; const char *filter; size_t queue_idx; size_t count; size_t check_count; bool enumeration; }; #define GROUPMEMBER_REQ_PARALLEL 50 static void sdap_process_group_members(struct tevent_req *subreq); static int sdap_process_group_members_2307bis(struct tevent_req *req, struct sdap_process_group_state *state, struct ldb_message_element *memberel); static int sdap_process_group_members_2307(struct sdap_process_group_state *state, struct ldb_message_element *memberel, struct ldb_message_element *ghostel); static errno_t sdap_process_group_create_dns(TALLOC_CTX *mem_ctx, size_t num_values, struct ldb_message_element **_dns) { struct ldb_message_element *dns; dns = talloc(mem_ctx, struct ldb_message_element); if (dns == NULL) { return ENOMEM; } dns->num_values = 0; dns->values = talloc_array(dns, struct ldb_val, num_values); if (dns->values == NULL) { talloc_zfree(dns); return ENOMEM; } *_dns = dns; return EOK; } struct tevent_req *sdap_process_group_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sysdb_ctx *sysdb, struct sdap_options *opts, struct sdap_handle *sh, struct sysdb_attrs *group, bool enumeration) { struct ldb_message_element *el; struct ldb_message_element *ghostel; struct sdap_process_group_state *grp_state; struct tevent_req *req = NULL; const char **attrs; char* filter; int ret; req = tevent_req_create(memctx, &grp_state, struct sdap_process_group_state); if (!req) return NULL; ret = build_attrs_from_map(grp_state, opts->user_map, opts->user_map_cnt, NULL, &attrs, NULL); if (ret) { goto done; } /* FIXME: we ignore nested rfc2307bis groups for now */ filter = talloc_asprintf(grp_state, "(objectclass=%s)", opts->user_map[SDAP_OC_USER].name); if (!filter) { talloc_zfree(req); return NULL; } grp_state->ev = ev; grp_state->opts = opts; grp_state->dom = dom; grp_state->sh = sh; grp_state->sysdb = sysdb; grp_state->group = group; grp_state->check_count = 0; grp_state->queue_idx = 0; grp_state->queued_members = NULL; grp_state->queue_len = 0; grp_state->filter = filter; grp_state->attrs = attrs; grp_state->enumeration = enumeration; ret = sysdb_attrs_get_el(group, opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, &el); if (ret) { goto done; } /* Group without members */ if (el->num_values == 0) { DEBUG(SSSDBG_OP_FAILURE, "No Members. Done!\n"); ret = EOK; goto done; } ret = sysdb_attrs_get_el(group, SYSDB_GHOST, &ghostel); if (ret) { goto done; } if (ghostel->num_values == 0) { /* Element was probably newly created, look for "member" again */ ret = sysdb_attrs_get_el(group, opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, &el); if (ret != EOK) { goto done; } } ret = sdap_process_group_create_dns(grp_state, el->num_values, &grp_state->sysdb_dns); if (ret != EOK) { goto done; } ret = sdap_process_group_create_dns(grp_state, el->num_values, &grp_state->ghost_dns); if (ret != EOK) { goto done; } switch (opts->schema_type) { case SDAP_SCHEMA_RFC2307: ret = sdap_process_group_members_2307(grp_state, el, ghostel); break; case SDAP_SCHEMA_IPA_V1: case SDAP_SCHEMA_AD: case SDAP_SCHEMA_RFC2307BIS: /* Note that this code branch will be used only if * ldap_nesting_level = 0 is set in config file */ ret = sdap_process_group_members_2307bis(req, grp_state, el); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown schema type %d\n", opts->schema_type); ret = EINVAL; break; } done: /* We managed to process all the entries */ /* EBUSY means we need to wait for entries in LDAP */ if (ret == EOK) { DEBUG(SSSDBG_TRACE_LIBS, "All group members processed\n"); tevent_req_done(req); tevent_req_post(req, ev); } if (ret != EOK && ret != EBUSY) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static int sdap_process_missing_member_2307bis(struct tevent_req *req, char *user_dn, unsigned num_users) { struct sdap_process_group_state *grp_state = tevent_req_data(req, struct sdap_process_group_state); struct tevent_req *subreq; /* * Issue at most GROUPMEMBER_REQ_PARALLEL LDAP searches at once. * The rest is sent while the results are being processed. * We limit the number as of request here, as the Server might * enforce limits on the number of pending operations per * connection. */ if (grp_state->check_count > GROUPMEMBER_REQ_PARALLEL) { DEBUG(SSSDBG_TRACE_LIBS, " queueing search for: %s\n", user_dn); if (!grp_state->queued_members) { DEBUG(SSSDBG_TRACE_LIBS, "Allocating queue for %zu members\n", num_users - grp_state->check_count); grp_state->queued_members = talloc_array(grp_state, char *, num_users - grp_state->check_count + 1); if (!grp_state->queued_members) { return ENOMEM; } } grp_state->queued_members[grp_state->queue_len] = user_dn; grp_state->queue_len++; } else { subreq = sdap_get_generic_send(grp_state, grp_state->ev, grp_state->opts, grp_state->sh, user_dn, LDAP_SCOPE_BASE, grp_state->filter, grp_state->attrs, grp_state->opts->user_map, grp_state->opts->user_map_cnt, dp_opt_get_int(grp_state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_process_group_members, req); } grp_state->check_count++; return EOK; } static int sdap_process_group_members_2307bis(struct tevent_req *req, struct sdap_process_group_state *state, struct ldb_message_element *memberel) { char *member_dn; char *strdn; int ret; int i; int nesting_level; bool is_group; nesting_level = dp_opt_get_int(state->opts->basic, SDAP_NESTING_LEVEL); for (i=0; i < memberel->num_values; i++) { member_dn = (char *)memberel->values[i].data; ret = sdap_find_entry_by_origDN(state->sysdb_dns->values, state->sysdb, state->dom, member_dn, &strdn, &is_group); if (ret == EOK) { if (nesting_level == 0 && is_group) { /* Ignore group members which are groups themselves. */ continue; } /* * User already cached in sysdb. Remember the sysdb DN for later * use by sdap_save_groups() */ DEBUG(SSSDBG_TRACE_LIBS, "sysdbdn: %s\n", strdn); state->sysdb_dns->values[state->sysdb_dns->num_values].data = (uint8_t*) strdn; state->sysdb_dns->values[state->sysdb_dns->num_values].length = strlen(strdn); state->sysdb_dns->num_values++; } else if (ret == ENOENT) { if (!state->enumeration) { /* The user is not in sysdb, need to add it * We don't need to do this if we're in an enumeration, * because all real members should all be populated * already by the first pass of the enumeration. * Also, we don't want to be holding the sysdb * transaction while we're performing LDAP lookups. */ DEBUG(SSSDBG_TRACE_LIBS, "Searching LDAP for missing user entry\n"); ret = sdap_process_missing_member_2307bis(req, member_dn, memberel->num_values); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error processing missing member #%d (%s):\n", i, member_dn); return ret; } } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Error checking cache for member #%d (%s):\n", i, (char *)memberel->values[i].data); return ret; } } if (state->queue_len > 0) { state->queued_members[state->queue_len]=NULL; } if (state->check_count == 0) { /* * All group members are already cached in sysdb, we are done * with this group. To avoid redundant sysdb lookups, populate the * "member" attribute of the group entry with the sysdb DNs of * the members. */ ret = EOK; memberel->values = talloc_steal(state->group, state->sysdb_dns->values); memberel->num_values = state->sysdb_dns->num_values; } else { state->count = state->check_count; ret = EBUSY; } return ret; } static int sdap_add_group_member_2307(struct ldb_message_element *sysdb_dns, const char *username) { sysdb_dns->values[sysdb_dns->num_values].data = (uint8_t *) talloc_strdup(sysdb_dns->values, username); if (sysdb_dns->values[sysdb_dns->num_values].data == NULL) { return ENOMEM; } sysdb_dns->values[sysdb_dns->num_values].length = strlen(username); sysdb_dns->num_values++; return EOK; } static int sdap_process_missing_member_2307(struct sdap_process_group_state *state, char *member_name) { int ret; TALLOC_CTX *tmp_ctx; const char *filter; const char *username; const char *user_dn; size_t count; struct ldb_message **msgs = NULL; static const char *attrs[] = { SYSDB_NAME, NULL }; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; /* Check for the alias in the sysdb */ filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_NAME_ALIAS, member_name); if (!filter) { ret = ENOMEM; goto done; } ret = sysdb_search_users(tmp_ctx, state->dom, filter, attrs, &count, &msgs); if (ret == EOK && count > 0) { /* Entry exists but the group references it with an alias. */ if (count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "More than one entry with this alias?\n"); ret = EIO; goto done; } /* fill username with primary name */ username = ldb_msg_find_attr_as_string(msgs[0], SYSDB_NAME, NULL); if (username == NULL) { ret = EINVAL; DEBUG(SSSDBG_MINOR_FAILURE, "Inconsistent sysdb: user " "without primary name?\n"); goto done; } user_dn = sysdb_user_strdn(tmp_ctx, state->dom->name, username); if (user_dn == NULL) { return ENOMEM; } ret = sdap_add_group_member_2307(state->sysdb_dns, user_dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not add group member %s\n", username); } } else if (ret == ENOENT || count == 0) { /* The entry really does not exist, add a ghost */ DEBUG(SSSDBG_TRACE_FUNC, "Adding a ghost entry\n"); ret = sdap_add_group_member_2307(state->ghost_dns, member_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not add group member %s\n", member_name); } } else { ret = EIO; } done: talloc_free(tmp_ctx); return ret; } static int sdap_process_group_members_2307(struct sdap_process_group_state *state, struct ldb_message_element *memberel, struct ldb_message_element *ghostel) { struct ldb_message *msg; char *member_name; char *userdn; int ret; int i; for (i=0; i < memberel->num_values; i++) { member_name = (char *)memberel->values[i].data; /* We need to skip over zero-length usernames */ if (member_name[0] == '\0') continue; ret = sysdb_search_user_by_name(state, state->dom, member_name, NULL, &msg); if (ret == EOK) { /* * User already cached in sysdb. Remember the sysdb DN for later * use by sdap_save_groups() */ DEBUG(SSSDBG_TRACE_LIBS, "Member already cached in sysdb: %s\n", member_name); userdn = sysdb_user_strdn(state->sysdb_dns, state->dom->name, member_name); if (userdn == NULL) { return ENOMEM; } ret = sdap_add_group_member_2307(state->sysdb_dns, userdn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add member %s into sysdb\n", member_name); goto done; } } else if (ret == ENOENT) { /* The user is not in sysdb, need to add it */ DEBUG(SSSDBG_TRACE_LIBS, "member #%d (%s): not found in sysdb\n", i, member_name); ret = sdap_process_missing_member_2307(state, member_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error processing missing member #%d (%s):\n", i, member_name); goto done; } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Error checking cache for member #%d (%s):\n", i, (char *) memberel->values[i].data); goto done; } } ret = EOK; talloc_free(memberel->values); memberel->values = talloc_steal(state->group, state->sysdb_dns->values); memberel->num_values = state->sysdb_dns->num_values; talloc_free(ghostel->values); ghostel->values = talloc_steal(state->group, state->ghost_dns->values); ghostel->num_values = state->ghost_dns->num_values; done: return ret; } static void sdap_process_group_members(struct tevent_req *subreq) { struct sysdb_attrs **usr_attrs; size_t count; int ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_process_group_state *state = tevent_req_data(req, struct sdap_process_group_state); struct ldb_message_element *el; uint8_t* name_string; state->check_count--; DEBUG(SSSDBG_TRACE_ALL, "Members remaining: %zu\n", state->check_count); ret = sdap_get_generic_recv(subreq, state, &count, &usr_attrs); talloc_zfree(subreq); if (ret) { goto next; } if (count != 1) { ret = EINVAL; DEBUG(SSSDBG_TRACE_LIBS, "Expected one user entry and got %zu\n", count); goto next; } ret = sysdb_attrs_get_el(usr_attrs[0], state->opts->user_map[SDAP_AT_USER_NAME].sys_name, &el); if (el->num_values == 0) { ret = EINVAL; } if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get the member's name\n"); goto next; } name_string = el[0].values[0].data; state->ghost_dns->values[state->ghost_dns->num_values].data = talloc_steal(state->ghost_dns->values, name_string); state->ghost_dns->values[state->ghost_dns->num_values].length = strlen((char *)name_string); state->ghost_dns->num_values++; next: if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error reading group member[%d]: %s. Skipping\n", ret, strerror(ret)); state->count--; } /* Are there more searches for uncached users to submit ? */ if (state->queued_members && state->queued_members[state->queue_idx]) { subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, state->queued_members[state->queue_idx], LDAP_SCOPE_BASE, state->filter, state->attrs, state->opts->user_map, state->opts->user_map_cnt, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_process_group_members, req); state->queue_idx++; } if (state->check_count == 0) { /* * To avoid redundant sysdb lookups, populate the "member" attribute * of the group entry with the sysdb DNs of the members. */ ret = sysdb_attrs_get_el(state->group, state->opts->group_map[SDAP_AT_GROUP_MEMBER].sys_name, &el); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get the group member attribute [%d]: %s\n", ret, strerror(ret)); tevent_req_error(req, ret); return; } el->values = talloc_steal(state->group, state->sysdb_dns->values); el->num_values = state->sysdb_dns->num_values; ret = sysdb_attrs_get_el(state->group, SYSDB_GHOST, &el); if (ret != EOK) { tevent_req_error(req, ret); return; } el->values = talloc_steal(state->group, state->ghost_dns->values); el->num_values = state->ghost_dns->num_values; DEBUG(SSSDBG_TRACE_ALL, "Processed Group - Done\n"); tevent_req_done(req); } } static int sdap_process_group_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==Search-Groups-with-filter============================================ */ struct sdap_get_groups_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; struct sss_domain_info *dom; struct sdap_domain *sdom; struct sysdb_ctx *sysdb; const char **attrs; const char *base_filter; char *filter; int timeout; enum sdap_entry_lookup_type lookup_type; bool no_members; char *higher_usn; struct sysdb_attrs **groups; size_t count; size_t check_count; hash_table_t *missing_external; hash_table_t *user_hash; hash_table_t *group_hash; size_t base_iter; struct sdap_search_base **search_bases; struct sdap_handle *ldap_sh; struct sdap_id_op *op; }; static errno_t sdap_get_groups_next_base(struct tevent_req *req); static void sdap_get_groups_ldap_connect_done(struct tevent_req *subreq); static void sdap_get_groups_process(struct tevent_req *subreq); static void sdap_get_groups_done(struct tevent_req *subreq); struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_domain *sdom, struct sdap_options *opts, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout, enum sdap_entry_lookup_type lookup_type, bool no_members) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct sdap_get_groups_state *state; struct ad_id_ctx *subdom_id_ctx; req = tevent_req_create(memctx, &state, struct sdap_get_groups_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->sdom = sdom; state->dom = sdom->dom; state->sh = sh; state->sysdb = sdom->dom->sysdb; state->attrs = attrs; state->higher_usn = NULL; state->groups = NULL; state->count = 0; state->timeout = timeout; state->lookup_type = lookup_type; state->no_members = no_members; state->base_filter = filter; state->base_iter = 0; state->search_bases = sdom->group_search_bases; if (!state->search_bases) { DEBUG(SSSDBG_CRIT_FAILURE, "Group lookup request without a search base\n"); ret = EINVAL; goto done; } /* With AD by default the Global Catalog is used for lookup. But the GC * group object might not have full group membership data. To make sure we * connect to an LDAP server of the group's domain. */ if (state->opts->schema_type == SDAP_SCHEMA_AD && sdom->pvt != NULL) { subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx); state->op = sdap_id_op_create(state, subdom_id_ctx->ldap_ctx->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto done; } subreq = sdap_id_op_connect_send(state->op, state, &ret); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_get_groups_ldap_connect_done, req); return req; } ret = sdap_get_groups_next_base(req); done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void sdap_get_groups_ldap_connect_done(struct tevent_req *subreq) { struct tevent_req *req; struct sdap_get_groups_state *state; int ret; int dp_error; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_get_groups_state); ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } state->ldap_sh = sdap_id_op_handle(state->op); ret = sdap_get_groups_next_base(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } static errno_t sdap_get_groups_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_get_groups_state *state; bool need_paging = false; int sizelimit = 0; state = tevent_req_data(req, struct sdap_get_groups_state); talloc_zfree(state->filter); state->filter = sdap_combine_filters(state, state->base_filter, state->search_bases[state->base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for groups with base [%s]\n", state->search_bases[state->base_iter]->basedn); switch (state->lookup_type) { case SDAP_LOOKUP_SINGLE: break; /* Only requests that can return multiple entries should require * the paging control */ case SDAP_LOOKUP_WILDCARD: sizelimit = dp_opt_get_int(state->opts->basic, SDAP_WILDCARD_LIMIT); need_paging = true; break; case SDAP_LOOKUP_ENUMERATE: need_paging = true; break; } subreq = sdap_get_and_parse_generic_send( state, state->ev, state->opts, state->ldap_sh != NULL ? state->ldap_sh : state->sh, state->search_bases[state->base_iter]->basedn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->group_map, SDAP_OPTS_GROUP, 0, NULL, NULL, sizelimit, state->timeout, need_paging); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_get_groups_process, req); return EOK; } static void sdap_nested_done(struct tevent_req *req); static void sdap_search_group_copy_batch(struct sdap_get_groups_state *state, struct sysdb_attrs **groups, size_t count); static void sdap_ad_match_rule_members_process(struct tevent_req *subreq); static void sdap_get_groups_process(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_groups_state *state = tevent_req_data(req, struct sdap_get_groups_state); int ret; int i; bool next_base = false; size_t count; struct sysdb_attrs **groups; char **groupnamelist; ret = sdap_get_and_parse_generic_recv(subreq, state, &count, &groups); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_FUNC, "Search for groups, returned %zu results.\n", count); if (state->lookup_type == SDAP_LOOKUP_WILDCARD || \ state->lookup_type == SDAP_LOOKUP_ENUMERATE || \ count == 0) { /* No users found in this search or looking up multiple entries */ next_base = true; } /* Add this batch of groups to the list */ if (count > 0) { state->groups = talloc_realloc(state, state->groups, struct sysdb_attrs *, state->count + count + 1); if (!state->groups) { tevent_req_error(req, ENOMEM); return; } sdap_search_group_copy_batch(state, groups, count); } if (next_base) { state->base_iter++; if (state->search_bases[state->base_iter]) { /* There are more search bases to try */ ret = sdap_get_groups_next_base(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } } /* No more search bases * Return ENOENT if no groups were found */ if (state->count == 0) { tevent_req_error(req, ENOENT); return; } if (state->no_members) { ret = sysdb_attrs_primary_name_list(state->sysdb, state, state->groups, state->count, state->opts->group_map[SDAP_AT_GROUP_NAME].name, &groupnamelist); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_primary_name_list failed.\n"); tevent_req_error(req, ret); return; } ret = sdap_add_incomplete_groups(state->sysdb, state->dom, state->opts, groupnamelist, state->groups, state->count); if (ret == EOK) { DEBUG(SSSDBG_TRACE_LIBS, "Writing only group data without members was successful.\n"); tevent_req_done(req); } else { DEBUG(SSSDBG_OP_FAILURE, "sdap_add_incomplete_groups failed.\n"); tevent_req_error(req, ret); } return; } /* Check whether we need to do nested searches * for RFC2307bis/FreeIPA/ActiveDirectory * We don't need to do this for enumeration, * because all groups will be picked up anyway. * * We can also skip this if we're using the * LDAP_MATCHING_RULE_IN_CHAIN available in * AD 2008 and later */ if (state->lookup_type == SDAP_LOOKUP_SINGLE) { if ((state->opts->schema_type != SDAP_SCHEMA_RFC2307) && (dp_opt_get_int(state->opts->basic, SDAP_NESTING_LEVEL) != 0) && !dp_opt_get_bool(state->opts->basic, SDAP_AD_MATCHING_RULE_GROUPS)) { subreq = sdap_nested_group_send(state, state->ev, state->sdom, state->opts, state->sh, state->groups[0]); if (!subreq) { tevent_req_error(req, EIO); return; } tevent_req_set_callback(subreq, sdap_nested_done, req); return; } } /* We have all of the groups. Save them to the sysdb */ state->check_count = state->count; /* If we're using LDAP_MATCHING_RULE_IN_CHAIN, start a subreq to * retrieve the members so we can save them in a single step. */ if (state->lookup_type == SDAP_LOOKUP_SINGLE && (state->opts->schema_type != SDAP_SCHEMA_RFC2307) && state->opts->support_matching_rule && dp_opt_get_bool(state->opts->basic, SDAP_AD_MATCHING_RULE_GROUPS)) { subreq = sdap_get_ad_match_rule_members_send( state, state->ev, state->opts, state->sh, state->groups[0], state->timeout); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_ad_match_rule_members_process, req); return; } ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to start transaction\n"); tevent_req_error(req, ret); return; } if ((state->lookup_type == SDAP_LOOKUP_ENUMERATE || state->lookup_type == SDAP_LOOKUP_WILDCARD) && state->opts->schema_type != SDAP_SCHEMA_RFC2307 && dp_opt_get_int(state->opts->basic, SDAP_NESTING_LEVEL) != 0) { DEBUG(SSSDBG_TRACE_ALL, "Saving groups without members first " "to allow unrolling of nested groups.\n"); ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts, state->groups, state->count, false, NULL, true, NULL); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store groups.\n"); tevent_req_error(req, ret); return; } } for (i = 0; i < state->count; i++) { subreq = sdap_process_group_send(state, state->ev, state->dom, state->sysdb, state->opts, state->sh, state->groups[i], state->lookup_type == SDAP_LOOKUP_ENUMERATE); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_get_groups_done, req); } } static void sdap_search_group_copy_batch(struct sdap_get_groups_state *state, struct sysdb_attrs **groups, size_t count) { size_t copied; bool filter; /* Always copy all objects for wildcard lookups. */ filter = state->lookup_type == SDAP_LOOKUP_SINGLE ? true : false; copied = sdap_steal_objects_in_dom(state->opts, state->groups, state->count, state->dom, groups, count, filter); state->count += copied; state->groups[state->count] = NULL; } static void sdap_get_groups_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_groups_state *state = tevent_req_data(req, struct sdap_get_groups_state); int ret; errno_t sysret; ret = sdap_process_group_recv(subreq); talloc_zfree(subreq); if (ret) { sysret = sysdb_transaction_cancel(state->sysdb); if (sysret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not cancel sysdb transaction\n"); } tevent_req_error(req, ret); return; } state->check_count--; DEBUG(SSSDBG_TRACE_ALL, "Groups remaining: %zu\n", state->check_count); if (state->check_count == 0) { DEBUG(SSSDBG_TRACE_ALL, "All groups processed\n"); /* If ignore_group_members is set for the domain, don't update * group memberships in the cache. * * If enumeration is on, don't overwrite orig_members as they've been * saved earlier. */ ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts, state->groups, state->count, !state->dom->ignore_group_members, NULL, state->lookup_type == SDAP_LOOKUP_SINGLE, &state->higher_usn); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store groups.\n"); tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_ALL, "Saving %zu Groups - Done\n", state->count); sysret = sysdb_transaction_commit(state->sysdb); if (sysret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Couldn't commit transaction\n"); tevent_req_error(req, sysret); } else { tevent_req_done(req); } } } static errno_t sdap_nested_group_populate_users(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_options *opts, struct sysdb_attrs **users, int num_users, hash_table_t **_ghosts); static void sdap_ad_match_rule_members_process(struct tevent_req *subreq) { errno_t ret; TALLOC_CTX *tmp_ctx = NULL; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_groups_state *state = tevent_req_data(req, struct sdap_get_groups_state); struct sysdb_attrs **users; struct sysdb_attrs *group = state->groups[0]; struct ldb_message_element *member_el; struct ldb_message_element *orig_dn_el; size_t count = 0; size_t i; hash_table_t *ghosts; ret = sdap_get_ad_match_rule_members_recv(subreq, state, &count, &users); talloc_zfree(subreq); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not retrieve members using AD match rule. [%s]\n", strerror(ret)); goto done; } /* Save the group and users to the cache */ /* Truncate the member attribute of the group. * It will be repopulated below, and it may currently * be incomplete anyway, thanks to the range extension. */ ret = sysdb_attrs_get_el(group, SYSDB_MEMBER, &member_el); if (ret != EOK) { goto done; } member_el->num_values = 0; talloc_zfree(member_el->values); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } /* Figure out which users are already cached in the sysdb and * which ones need to be added as ghost users. */ ret = sdap_nested_group_populate_users(tmp_ctx, state->sysdb, state->dom, state->opts, users, count, &ghosts); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not determine which users are ghosts: [%s]\n", strerror(ret)); goto done; } /* Add any entries that aren't in the ghost hash table to the * member element of the group. This will get converted to a * native sysdb representation later in sdap_save_groups(). */ /* Add all of the users as members */ member_el->values = talloc_zero_array(tmp_ctx, struct ldb_val, count); if (!member_el->values) { ret = ENOMEM; goto done; } /* Copy the origDN values of the users into the member element */ for (i = 0; i < count; i++) { ret = sysdb_attrs_get_el(users[i], SYSDB_ORIG_DN, &orig_dn_el); if (ret != EOK) { /* This should never happen. Every entry should have * an originalDN. */ DEBUG(SSSDBG_MINOR_FAILURE, "BUG: Missing originalDN for user?\n"); goto done; } /* These values will have the same lifespan, so instead * of copying them, just point at the data. */ member_el->values[i].data = orig_dn_el->values[0].data; member_el->values[i].length = orig_dn_el->values[0].length; } member_el->num_values = count; /* Now save the group, users and ghosts to the cache */ ret = sdap_save_groups(tmp_ctx, state->sysdb, state->dom, state->opts, state->groups, 1, false, ghosts, true, NULL); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not save group to the cache: [%s]\n", strerror(ret)); goto done; } ret = EOK; done: talloc_free(tmp_ctx); if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } int sdap_get_groups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **usn_value) { struct sdap_get_groups_state *state = tevent_req_data(req, struct sdap_get_groups_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (usn_value) { *usn_value = talloc_steal(mem_ctx, state->higher_usn); } return EOK; } static void sdap_nested_ext_done(struct tevent_req *subreq); static void sdap_nested_done(struct tevent_req *subreq) { errno_t ret, tret; unsigned long user_count; unsigned long group_count; bool in_transaction = false; struct sysdb_attrs **users = NULL; struct sysdb_attrs **groups = NULL; hash_table_t *ghosts; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_groups_state *state = tevent_req_data(req, struct sdap_get_groups_state); ret = sdap_nested_group_recv(state, subreq, &user_count, &users, &group_count, &groups, &state->missing_external); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Nested group processing failed: [%d][%s]\n", ret, strerror(ret)); goto fail; } /* Save all of the users first so that they are in * place for the groups to add them. */ ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto fail; } in_transaction = true; ret = sdap_nested_group_populate_users(state, state->sysdb, state->dom, state->opts, users, user_count, &ghosts); if (ret != EOK) { goto fail; } ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts, groups, group_count, false, ghosts, true, &state->higher_usn); if (ret != EOK) { goto fail; } ret = sysdb_transaction_commit(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto fail; } in_transaction = false; if (hash_count(state->missing_external) == 0) { /* No external members. Processing complete */ DEBUG(SSSDBG_TRACE_INTERNAL, "No external members, done"); tevent_req_done(req); return; } /* At the moment, we need to save the direct groups & members in one * transaction and then query the others in a separate requests */ subreq = sdap_nested_group_lookup_external_send(state, state->ev, state->dom, state->opts->ext_ctx, state->missing_external); if (subreq == NULL) { ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, sdap_nested_ext_done, req); return; fail: if (in_transaction) { tret = sysdb_transaction_cancel(state->sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } tevent_req_error(req, ret); } static void sdap_nested_ext_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_groups_state *state = tevent_req_data(req, struct sdap_get_groups_state); ret = sdap_nested_group_lookup_external_recv(state, subreq); talloc_free(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot resolve external members [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } tevent_req_done(req); return; } static errno_t sdap_nested_group_populate_users(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_options *opts, struct sysdb_attrs **users, int num_users, hash_table_t **_ghosts) { int i; errno_t ret, sret; struct ldb_message_element *el; const char *username; char *clean_orig_dn; const char *original_dn; struct sss_domain_info *user_dom; struct sdap_domain *sdap_dom; TALLOC_CTX *tmp_ctx; struct ldb_message **msgs; char *filter; const char *sysdb_name; struct sysdb_attrs *attrs; static const char *search_attrs[] = { SYSDB_NAME, NULL }; hash_table_t *ghosts; hash_key_t key; hash_value_t value; size_t count; bool in_transaction = false; if (_ghosts == NULL) { return EINVAL; } if (num_users == 0) { /* Nothing to do if there are no users */ *_ghosts = NULL; return EOK; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; ret = sss_hash_create(tmp_ctx, num_users, &ghosts); if (ret != HASH_SUCCESS) { ret = ENOMEM; goto done; } ret = sysdb_transaction_start(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction!\n"); goto done; } in_transaction = true; for (i = 0; i < num_users; i++) { ret = sysdb_attrs_get_el(users[i], SYSDB_ORIG_DN, &el); if (el->num_values == 0) { ret = EINVAL; } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "User entry %d has no originalDN attribute\n", i); goto done; } original_dn = (const char *) el->values[0].data; ret = sss_filter_sanitize(tmp_ctx, original_dn, &clean_orig_dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot sanitize originalDN [%s]\n", original_dn); goto done; } sdap_dom = sdap_domain_get_by_dn(opts, original_dn); user_dom = sdap_dom == NULL ? domain : sdap_dom->dom; ret = sdap_get_user_primary_name(tmp_ctx, opts, users[i], user_dom, &username); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "User entry %d has no name attribute. Skipping\n", i); continue; } /* Check for the specified origDN in the sysdb */ filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_ORIG_DN, clean_orig_dn); if (!filter) { ret = ENOMEM; goto done; } ret = sysdb_search_users(tmp_ctx, user_dom, filter, search_attrs, &count, &msgs); talloc_zfree(filter); talloc_zfree(clean_orig_dn); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Error checking cache for user entry\n"); goto done; } else if (ret == EOK) { /* The entry is cached but expired. Update the username * if needed. */ if (count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "More than one entry with this origDN? Skipping\n"); continue; } sysdb_name = ldb_msg_find_attr_as_string(msgs[0], SYSDB_NAME, NULL); if (strcmp(sysdb_name, username) == 0) { /* Username is correct, continue */ continue; } attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, username); if (ret) goto done; ret = sysdb_set_entry_attr(user_dom->sysdb, msgs[0]->dn, attrs, SYSDB_MOD_REP); if (ret != EOK) goto done; } else { key.type = HASH_KEY_STRING; key.str = talloc_steal(ghosts, discard_const(original_dn)); value.type = HASH_VALUE_PTR; value.ptr = talloc_steal(ghosts, discard_const(username)); ret = hash_enter(ghosts, &key, &value); if (ret != HASH_SUCCESS) { talloc_free(key.str); talloc_free(value.ptr); ret = ENOMEM; goto done; } } } ret = sysdb_transaction_commit(sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction!\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } if (ret != EOK) { *_ghosts = NULL; } else { *_ghosts = talloc_steal(mem_ctx, ghosts); } talloc_zfree(tmp_ctx); return ret; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_enum.c0000644000000000000000000000007312703456111021364 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.771794026 sssd-1.13.4/src/providers/ldap/sdap_async_enum.c0000644002412700241270000007241212703456111023042 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Enumeration Module Authors: Simo Sorce Jakub Hrozek Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_async_enum.h" #include "providers/ldap/sdap_idmap.h" static struct tevent_req *enum_users_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_op *op, bool purge); static errno_t enum_users_recv(struct tevent_req *req); static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_op *op, bool purge); static errno_t enum_groups_recv(struct tevent_req *req); /* ==Enumeration-Request-with-connections=================================== */ struct sdap_dom_enum_ex_state { struct tevent_context *ev; struct sdap_id_ctx *ctx; struct sdap_domain *sdom; struct sdap_id_conn_ctx *user_conn; struct sdap_id_conn_ctx *group_conn; struct sdap_id_conn_ctx *svc_conn; struct sdap_id_op *user_op; struct sdap_id_op *group_op; struct sdap_id_op *svc_op; bool purge; }; static errno_t sdap_dom_enum_ex_retry(struct tevent_req *req, struct sdap_id_op *op, tevent_req_fn tcb); static bool sdap_dom_enum_ex_connected(struct tevent_req *subreq); static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq); static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq); static errno_t sdap_dom_enum_search_users(struct tevent_req *req); static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq); static void sdap_dom_enum_ex_get_groups(struct tevent_req *subreq); static void sdap_dom_enum_ex_groups_done(struct tevent_req *subreq); static void sdap_dom_enum_ex_get_svcs(struct tevent_req *subreq); static void sdap_dom_enum_ex_svcs_done(struct tevent_req *subreq); struct tevent_req * sdap_dom_enum_ex_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *user_conn, struct sdap_id_conn_ctx *group_conn, struct sdap_id_conn_ctx *svc_conn) { struct tevent_req *req; struct sdap_dom_enum_ex_state *state; int t; errno_t ret; req = tevent_req_create(memctx, &state, struct sdap_dom_enum_ex_state); if (req == NULL) return NULL; state->ev = ev; state->ctx = ctx; state->sdom = sdom; state->user_conn = user_conn; state->group_conn = group_conn; state->svc_conn = svc_conn; sdom->last_enum = tevent_timeval_current(); t = dp_opt_get_int(ctx->opts->basic, SDAP_PURGE_CACHE_TIMEOUT); if ((sdom->last_purge.tv_sec + t) < sdom->last_enum.tv_sec) { state->purge = true; } state->user_op = sdap_id_op_create(state, user_conn->conn_cache); if (state->user_op == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_id_op_create failed for users\n"); ret = EIO; goto fail; } ret = sdap_dom_enum_ex_retry(req, state->user_op, sdap_dom_enum_ex_get_users); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sdap_dom_enum_ex_retry failed\n"); goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static errno_t sdap_dom_enum_ex_retry(struct tevent_req *req, struct sdap_id_op *op, tevent_req_fn tcb) { struct sdap_dom_enum_ex_state *state = tevent_req_data(req, struct sdap_dom_enum_ex_state); struct tevent_req *subreq; errno_t ret; subreq = sdap_id_op_connect_send(op, state, &ret); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d\n", ret); return ret; } tevent_req_set_callback(subreq, tcb, req); return EOK; } static bool sdap_dom_enum_ex_connected(struct tevent_req *subreq) { errno_t ret; int dp_error; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_TRACE_FUNC, "Backend is marked offline, retry later!\n"); tevent_req_done(req); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Domain enumeration failed to connect to " \ "LDAP server: (%d)[%s]\n", ret, strerror(ret)); tevent_req_error(req, ret); } return false; } return true; } static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_dom_enum_ex_state *state = tevent_req_data(req, struct sdap_dom_enum_ex_state); bool use_id_mapping; errno_t ret; if (sdap_dom_enum_ex_connected(subreq) == false) { return; } use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( state->ctx->opts->idmap_ctx, state->sdom->dom->name, state->sdom->dom->domain_id); /* If POSIX attributes have been requested with an AD server and we * have no idea about POSIX attributes support, run a one-time check */ if (use_id_mapping == false && state->ctx->opts->schema_type == SDAP_SCHEMA_AD && state->ctx->srv_opts && state->ctx->srv_opts->posix_checked == false) { subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, sdap_id_op_handle(state->user_op), state->sdom->user_search_bases, dp_opt_get_int(state->ctx->opts->basic, SDAP_SEARCH_TIMEOUT)); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_dom_enum_ex_posix_check_done, req); return; } ret = sdap_dom_enum_search_users(req); if (ret != EOK) { tevent_req_error(req, ret); return; } /* Execution resumes in sdap_dom_enum_ex_users_done */ } static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq) { errno_t ret; bool has_posix; int dp_error; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_dom_enum_ex_state *state = tevent_req_data(req, struct sdap_dom_enum_ex_state); ret = sdap_posix_check_recv(subreq, &has_posix); talloc_zfree(subreq); if (ret != EOK && ret != ERR_NO_POSIX) { /* We can only finish the id_op on error as the connection * is re-used by the user search */ ret = sdap_id_op_done(state->user_op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = sdap_dom_enum_ex_retry(req, state->user_op, sdap_dom_enum_ex_get_users); if (ret != EOK) { tevent_req_error(req, ret); } return; } else if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_TRACE_FUNC, "Backend is offline, retrying later\n"); tevent_req_done(req); return; } else { /* Non-recoverable error */ DEBUG(SSSDBG_OP_FAILURE, "POSIX check failed: %d: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } } state->ctx->srv_opts->posix_checked = true; /* If the check ran to completion, we know for certain about the attributes */ if (has_posix == false) { tevent_req_error(req, ERR_NO_POSIX); return; } ret = sdap_dom_enum_search_users(req); if (ret != EOK) { tevent_req_error(req, ret); return; } /* Execution resumes in sdap_dom_enum_ex_users_done */ } static errno_t sdap_dom_enum_search_users(struct tevent_req *req) { struct sdap_dom_enum_ex_state *state = tevent_req_data(req, struct sdap_dom_enum_ex_state); struct tevent_req *subreq; subreq = enum_users_send(state, state->ev, state->ctx, state->sdom, state->user_op, state->purge); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_dom_enum_ex_users_done, req); return EOK; } static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_dom_enum_ex_state *state = tevent_req_data(req, struct sdap_dom_enum_ex_state); errno_t ret; int dp_error; ret = enum_users_recv(subreq); talloc_zfree(subreq); ret = sdap_id_op_done(state->user_op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = sdap_dom_enum_ex_retry(req, state->user_op, sdap_dom_enum_ex_get_users); if (ret != EOK) { tevent_req_error(req, ret); return; } return; } else if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_TRACE_FUNC, "Backend is offline, retrying later\n"); tevent_req_done(req); return; } else if (ret != EOK && ret != ENOENT) { /* Non-recoverable error */ DEBUG(SSSDBG_OP_FAILURE, "User enumeration failed: %d: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } state->group_op = sdap_id_op_create(state, state->group_conn->conn_cache); if (state->group_op == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_id_op_create failed for groups\n"); tevent_req_error(req, EIO); return; } ret = sdap_dom_enum_ex_retry(req, state->group_op, sdap_dom_enum_ex_get_groups); if (ret != EOK) { tevent_req_error(req, ret); return; } /* Continues to sdap_dom_enum_ex_get_groups */ } static void sdap_dom_enum_ex_get_groups(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_dom_enum_ex_state *state = tevent_req_data(req, struct sdap_dom_enum_ex_state); if (sdap_dom_enum_ex_connected(subreq) == false) { return; } subreq = enum_groups_send(state, state->ev, state->ctx, state->sdom, state->group_op, state->purge); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_dom_enum_ex_groups_done, req); } static void sdap_dom_enum_ex_groups_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_dom_enum_ex_state *state = tevent_req_data(req, struct sdap_dom_enum_ex_state); int ret; int dp_error; ret = enum_groups_recv(subreq); talloc_zfree(subreq); ret = sdap_id_op_done(state->group_op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = sdap_dom_enum_ex_retry(req, state->group_op, sdap_dom_enum_ex_get_groups); if (ret != EOK) { tevent_req_error(req, ret); return; } return; } else if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_TRACE_FUNC, "Backend is offline, retrying later\n"); tevent_req_done(req); return; } else if (ret != EOK && ret != ENOENT) { /* Non-recoverable error */ DEBUG(SSSDBG_OP_FAILURE, "Group enumeration failed: %d: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } state->svc_op = sdap_id_op_create(state, state->svc_conn->conn_cache); if (state->svc_op == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_id_op_create failed for svcs\n"); tevent_req_error(req, EIO); return; } ret = sdap_dom_enum_ex_retry(req, state->svc_op, sdap_dom_enum_ex_get_svcs); if (ret != EOK) { tevent_req_error(req, ret); return; } } static void sdap_dom_enum_ex_get_svcs(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_dom_enum_ex_state *state = tevent_req_data(req, struct sdap_dom_enum_ex_state); if (sdap_dom_enum_ex_connected(subreq) == false) { return; } subreq = enum_services_send(state, state->ev, state->ctx, state->svc_op, state->purge); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_dom_enum_ex_svcs_done, req); } static void sdap_dom_enum_ex_svcs_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_dom_enum_ex_state *state = tevent_req_data(req, struct sdap_dom_enum_ex_state); int ret; int dp_error; ret = enum_services_recv(subreq); talloc_zfree(subreq); ret = sdap_id_op_done(state->svc_op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = sdap_dom_enum_ex_retry(req, state->user_op, sdap_dom_enum_ex_get_svcs); if (ret != EOK) { tevent_req_error(req, ret); return; } return; } else if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_TRACE_FUNC, "Backend is offline, retrying later\n"); tevent_req_done(req); return; } else if (ret != EOK && ret != ENOENT) { /* Non-recoverable error */ DEBUG(SSSDBG_OP_FAILURE, "Service enumeration failed: %d: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } /* Ok, we've completed an enumeration. Save this to the * sysdb so we can postpone starting up the enumeration * process on the next SSSD service restart (to avoid * slowing down system boot-up */ ret = sysdb_set_enumerated(state->sdom->dom, true); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not mark domain as having enumerated.\n"); /* This error is non-fatal, so continue */ } if (state->purge) { ret = ldap_id_cleanup(state->ctx->opts, state->sdom); if (ret != EOK) { /* Not fatal, worst case we'll have stale entries that would be * removed on a subsequent online lookup */ DEBUG(SSSDBG_MINOR_FAILURE, "Cleanup failed: [%d]: %s\n", ret, sss_strerror(ret)); } } tevent_req_done(req); } errno_t sdap_dom_enum_ex_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==Enumeration-Request==================================================== */ struct tevent_req * sdap_dom_enum_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn) { return sdap_dom_enum_ex_send(memctx, ev, ctx, sdom, conn, conn, conn); } errno_t sdap_dom_enum_recv(struct tevent_req *req) { return sdap_dom_enum_ex_recv(req); } /* ==User-Enumeration===================================================== */ struct enum_users_state { struct tevent_context *ev; struct sdap_id_ctx *ctx; struct sdap_domain *sdom; struct sdap_id_op *op; char *filter; const char **attrs; }; static void enum_users_done(struct tevent_req *subreq); static struct tevent_req *enum_users_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_op *op, bool purge) { struct tevent_req *req, *subreq; struct enum_users_state *state; int ret; bool use_mapping; req = tevent_req_create(memctx, &state, struct enum_users_state); if (!req) return NULL; state->ev = ev; state->sdom = sdom; state->ctx = ctx; state->op = op; use_mapping = sdap_idmap_domain_has_algorithmic_mapping( ctx->opts->idmap_ctx, sdom->dom->name, sdom->dom->domain_id); /* We always want to filter on objectclass and an available name */ state->filter = talloc_asprintf(state, "(&(objectclass=%s)(%s=*)", ctx->opts->user_map[SDAP_OC_USER].name, ctx->opts->user_map[SDAP_AT_USER_NAME].name); if (!state->filter) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to build base filter\n"); ret = ENOMEM; goto fail; } if (use_mapping) { /* If we're ID-mapping, check for the objectSID as well */ state->filter = talloc_asprintf_append_buffer( state->filter, "(%s=*)", ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name); } else { /* We're not ID-mapping, so make sure to only get entries * that have UID and GID */ state->filter = talloc_asprintf_append_buffer( state->filter, "(%s=*)(%s=*)", ctx->opts->user_map[SDAP_AT_USER_UID].name, ctx->opts->user_map[SDAP_AT_USER_GID].name); } if (!state->filter) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to build base filter\n"); ret = ENOMEM; goto fail; } if (ctx->srv_opts && ctx->srv_opts->max_user_value && !purge) { /* If we have lastUSN available and we're not doing a full * refresh, limit to changes with a higher entryUSN value. */ state->filter = talloc_asprintf_append_buffer( state->filter, "(%s>=%s)(!(%s=%s))", ctx->opts->user_map[SDAP_AT_USER_USN].name, ctx->srv_opts->max_user_value, ctx->opts->user_map[SDAP_AT_USER_USN].name, ctx->srv_opts->max_user_value); if (!state->filter) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to build base filter\n"); ret = ENOMEM; goto fail; } } /* Terminate the search filter */ state->filter = talloc_asprintf_append_buffer(state->filter, ")"); if (!state->filter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build base filter\n"); ret = ENOMEM; goto fail; } /* TODO: handle attrs_type */ ret = build_attrs_from_map(state, ctx->opts->user_map, ctx->opts->user_map_cnt, NULL, &state->attrs, NULL); if (ret != EOK) goto fail; /* TODO: restrict the enumerations to using a single * search base at a time. */ subreq = sdap_get_users_send(state, state->ev, state->sdom->dom, state->sdom->dom->sysdb, state->ctx->opts, state->sdom->user_search_bases, sdap_id_op_handle(state->op), state->attrs, state->filter, dp_opt_get_int(state->ctx->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), SDAP_LOOKUP_ENUMERATE); if (!subreq) { ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, enum_users_done, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void enum_users_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct enum_users_state *state = tevent_req_data(req, struct enum_users_state); char *usn_value; char *endptr = NULL; unsigned usn_number; int ret; ret = sdap_get_users_recv(subreq, state, &usn_value); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } if (usn_value) { talloc_zfree(state->ctx->srv_opts->max_user_value); state->ctx->srv_opts->max_user_value = talloc_steal(state->ctx, usn_value); usn_number = strtoul(usn_value, &endptr, 10); if ((endptr == NULL || (*endptr == '\0' && endptr != usn_value)) && (usn_number > state->ctx->srv_opts->last_usn)) { state->ctx->srv_opts->last_usn = usn_number; } } DEBUG(SSSDBG_CONF_SETTINGS, "Users higher USN value: [%s]\n", state->ctx->srv_opts->max_user_value); tevent_req_done(req); } static errno_t enum_users_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* =Group-Enumeration===================================================== */ struct enum_groups_state { struct tevent_context *ev; struct sdap_id_ctx *ctx; struct sdap_domain *sdom; struct sdap_id_op *op; char *filter; const char **attrs; }; static void enum_groups_done(struct tevent_req *subreq); static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_op *op, bool purge) { struct tevent_req *req, *subreq; struct enum_groups_state *state; int ret; bool use_mapping; char *oc_list; req = tevent_req_create(memctx, &state, struct enum_groups_state); if (!req) return NULL; state->ev = ev; state->sdom = sdom; state->ctx = ctx; state->op = op; use_mapping = sdap_idmap_domain_has_algorithmic_mapping( ctx->opts->idmap_ctx, sdom->dom->name, sdom->dom->domain_id); /* We always want to filter on objectclass and an available name */ oc_list = sdap_make_oc_list(state, ctx->opts->group_map); if (oc_list == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n"); ret = ENOMEM; goto fail; } state->filter = talloc_asprintf(state, "(&(%s)(%s=*)", oc_list, ctx->opts->group_map[SDAP_AT_GROUP_NAME].name); if (!state->filter) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to build base filter\n"); ret = ENOMEM; goto fail; } if (use_mapping) { /* If we're ID-mapping, check for the objectSID as well */ state->filter = talloc_asprintf_append_buffer( state->filter, "(%s=*)", ctx->opts->group_map[SDAP_AT_GROUP_OBJECTSID].name); } else { /* We're not ID-mapping, so make sure to only get entries * that have a non-zero GID. */ state->filter = talloc_asprintf_append_buffer( state->filter, "(&(%s=*)(!(%s=0)))", ctx->opts->group_map[SDAP_AT_GROUP_GID].name, ctx->opts->group_map[SDAP_AT_GROUP_GID].name); } if (!state->filter) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to build base filter\n"); ret = ENOMEM; goto fail; } if (ctx->srv_opts && ctx->srv_opts->max_group_value && !purge) { state->filter = talloc_asprintf_append_buffer( state->filter, "(%s>=%s)(!(%s=%s))", ctx->opts->group_map[SDAP_AT_GROUP_USN].name, ctx->srv_opts->max_group_value, ctx->opts->group_map[SDAP_AT_GROUP_USN].name, ctx->srv_opts->max_group_value); if (!state->filter) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to build base filter\n"); ret = ENOMEM; goto fail; } } /* Terminate the search filter */ state->filter = talloc_asprintf_append_buffer(state->filter, ")"); if (!state->filter) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to build base filter\n"); ret = ENOMEM; goto fail; } /* TODO: handle attrs_type */ ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP, NULL, &state->attrs, NULL); if (ret != EOK) goto fail; /* TODO: restrict the enumerations to using a single * search base at a time. */ subreq = sdap_get_groups_send(state, state->ev, state->sdom, state->ctx->opts, sdap_id_op_handle(state->op), state->attrs, state->filter, dp_opt_get_int(state->ctx->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), SDAP_LOOKUP_ENUMERATE, false); if (!subreq) { ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, enum_groups_done, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void enum_groups_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct enum_groups_state *state = tevent_req_data(req, struct enum_groups_state); char *usn_value; char *endptr = NULL; unsigned usn_number; int ret; ret = sdap_get_groups_recv(subreq, state, &usn_value); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } if (usn_value) { talloc_zfree(state->ctx->srv_opts->max_group_value); state->ctx->srv_opts->max_group_value = talloc_steal(state->ctx, usn_value); usn_number = strtoul(usn_value, &endptr, 10); if ((endptr == NULL || (*endptr == '\0' && endptr != usn_value)) && (usn_number > state->ctx->srv_opts->last_usn)) { state->ctx->srv_opts->last_usn = usn_number; } } DEBUG(SSSDBG_CONF_SETTINGS, "Groups higher USN value: [%s]\n", state->ctx->srv_opts->max_group_value); tevent_req_done(req); } static errno_t enum_groups_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_child_helpers.c0000644000000000000000000000007312703456111022030 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.788794083 sssd-1.13.4/src/providers/ldap/sdap_child_helpers.c0000644002412700241270000003214712703456111023507 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Backend Module -- child helpers Authors: Jakub Hrozek Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "util/sss_krb5.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async_private.h" #include "util/child_common.h" #ifndef SSSD_LIBEXEC_PATH #error "SSSD_LIBEXEC_PATH not defined" #else #define LDAP_CHILD SSSD_LIBEXEC_PATH"/ldap_child" #endif #ifndef LDAP_CHILD_USER #define LDAP_CHILD_USER "nobody" #endif struct sdap_child { /* child info */ pid_t pid; struct child_io_fds *io; }; static void sdap_close_fd(int *fd) { int ret; if (*fd == -1) { DEBUG(SSSDBG_TRACE_FUNC, "fd already closed\n"); return; } ret = close(*fd); if (ret) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "Closing fd %d, return error %d (%s)\n", *fd, ret, strerror(ret)); } *fd = -1; } static errno_t sdap_fork_child(struct tevent_context *ev, struct sdap_child *child) { int pipefd_to_child[2]; int pipefd_from_child[2]; pid_t pid; int ret; errno_t err; ret = pipe(pipefd_from_child); if (ret == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", err, strerror(err)); return err; } ret = pipe(pipefd_to_child); if (ret == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", err, strerror(err)); return err; } pid = fork(); if (pid == 0) { /* child */ err = exec_child(child, pipefd_to_child, pipefd_from_child, LDAP_CHILD, ldap_child_debug_fd); DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec LDAP child: [%d][%s].\n", err, strerror(err)); return err; } else if (pid > 0) { /* parent */ child->pid = pid; child->io->read_from_child_fd = pipefd_from_child[0]; close(pipefd_from_child[1]); child->io->write_to_child_fd = pipefd_to_child[1]; close(pipefd_to_child[0]); sss_fd_nonblocking(child->io->read_from_child_fd); sss_fd_nonblocking(child->io->write_to_child_fd); ret = child_handler_setup(ev, pid, NULL, NULL, NULL); if (ret != EOK) { return ret; } } else { /* error */ err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n", err, strerror(err)); return err; } return EOK; } static errno_t create_tgt_req_send_buffer(TALLOC_CTX *mem_ctx, const char *realm_str, const char *princ_str, const char *keytab_name, int32_t lifetime, struct io_buffer **io_buf) { struct io_buffer *buf; size_t rp; buf = talloc(mem_ctx, struct io_buffer); if (buf == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); return ENOMEM; } buf->size = 6 * sizeof(uint32_t); if (realm_str) { buf->size += strlen(realm_str); } if (princ_str) { buf->size += strlen(princ_str); } if (keytab_name) { buf->size += strlen(keytab_name); } DEBUG(SSSDBG_TRACE_FUNC, "buffer size: %zu\n", buf->size); buf->data = talloc_size(buf, buf->size); if (buf->data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); talloc_free(buf); return ENOMEM; } rp = 0; /* realm */ if (realm_str) { SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(realm_str), &rp); safealign_memcpy(&buf->data[rp], realm_str, strlen(realm_str), &rp); } else { SAFEALIGN_SET_UINT32(&buf->data[rp], 0, &rp); } /* principal */ if (princ_str) { SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(princ_str), &rp); safealign_memcpy(&buf->data[rp], princ_str, strlen(princ_str), &rp); } else { SAFEALIGN_SET_UINT32(&buf->data[rp], 0, &rp); } /* keytab */ if (keytab_name) { SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(keytab_name), &rp); safealign_memcpy(&buf->data[rp], keytab_name, strlen(keytab_name), &rp); } else { SAFEALIGN_SET_UINT32(&buf->data[rp], 0, &rp); } /* lifetime */ SAFEALIGN_SET_UINT32(&buf->data[rp], lifetime, &rp); /* UID and GID to drop privileges to, if needed. The ldap_child process runs as * setuid if the back end runs unprivileged as it needs to access the keytab */ SAFEALIGN_SET_UINT32(&buf->data[rp], geteuid(), &rp); SAFEALIGN_SET_UINT32(&buf->data[rp], getegid(), &rp); *io_buf = buf; return EOK; } static int parse_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, ssize_t size, int *result, krb5_error_code *kerr, char **ccache, time_t *expire_time_out) { size_t p = 0; uint32_t len; uint32_t res; char *ccn; time_t expire_time; krb5_error_code krberr; /* operation result code */ SAFEALIGN_COPY_UINT32_CHECK(&res, buf + p, size, &p); /* krb5 error code */ safealign_memcpy(&krberr, buf+p, sizeof(krberr), &p); /* ccache name size */ SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); if (len > size - p) return EINVAL; ccn = talloc_size(mem_ctx, sizeof(char) * (len + 1)); if (ccn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); return ENOMEM; } safealign_memcpy(ccn, buf+p, sizeof(char) * len, &p); ccn[len] = '\0'; if (p + sizeof(time_t) > size) { talloc_free(ccn); return EINVAL; } safealign_memcpy(&expire_time, buf+p, sizeof(time_t), &p); *result = res; *ccache = ccn; *expire_time_out = expire_time; *kerr = krberr; return EOK; } /* ==The-public-async-interface============================================*/ struct sdap_get_tgt_state { struct tevent_context *ev; struct sdap_child *child; ssize_t len; uint8_t *buf; }; static errno_t set_tgt_child_timeout(struct tevent_req *req, struct tevent_context *ev, int timeout); static void sdap_get_tgt_step(struct tevent_req *subreq); static void sdap_get_tgt_done(struct tevent_req *subreq); struct tevent_req *sdap_get_tgt_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *realm_str, const char *princ_str, const char *keytab_name, int32_t lifetime, int timeout) { struct tevent_req *req, *subreq; struct sdap_get_tgt_state *state; struct io_buffer *buf; int ret; req = tevent_req_create(mem_ctx, &state, struct sdap_get_tgt_state); if (!req) { return NULL; } state->ev = ev; state->child = talloc_zero(state, struct sdap_child); if (!state->child) { ret = ENOMEM; goto fail; } state->child->io = talloc(state, struct child_io_fds); if (state->child->io == NULL) { ret = ENOMEM; goto fail; } state->child->io->read_from_child_fd = -1; state->child->io->write_to_child_fd = -1; talloc_set_destructor((TALLOC_CTX *) state->child->io, child_io_destructor); /* prepare the data to pass to child */ ret = create_tgt_req_send_buffer(state, realm_str, princ_str, keytab_name, lifetime, &buf); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "create_tgt_req_send_buffer failed.\n"); goto fail; } ret = sdap_fork_child(state->ev, state->child); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_fork_child failed.\n"); goto fail; } ret = set_tgt_child_timeout(req, ev, timeout); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "activate_child_timeout_handler failed.\n"); goto fail; } subreq = write_pipe_send(state, ev, buf->data, buf->size, state->child->io->write_to_child_fd); if (!subreq) { ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, sdap_get_tgt_step, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void sdap_get_tgt_step(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_tgt_state *state = tevent_req_data(req, struct sdap_get_tgt_state); int ret; ret = write_pipe_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } sdap_close_fd(&state->child->io->write_to_child_fd); subreq = read_pipe_send(state, state->ev, state->child->io->read_from_child_fd); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_get_tgt_done, req); } static void sdap_get_tgt_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_tgt_state *state = tevent_req_data(req, struct sdap_get_tgt_state); int ret; ret = read_pipe_recv(subreq, state, &state->buf, &state->len); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } sdap_close_fd(&state->child->io->read_from_child_fd); tevent_req_done(req); } int sdap_get_tgt_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, int *result, krb5_error_code *kerr, char **ccname, time_t *expire_time_out) { struct sdap_get_tgt_state *state = tevent_req_data(req, struct sdap_get_tgt_state); char *ccn; time_t expire_time; int res; int ret; krb5_error_code krberr; TEVENT_REQ_RETURN_ON_ERROR(req); ret = parse_child_response(mem_ctx, state->buf, state->len, &res, &krberr, &ccn, &expire_time); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse child response: [%d][%s]\n", ret, strerror(ret)); return ret; } DEBUG(SSSDBG_TRACE_FUNC, "Child responded: %d [%s], expired on [%ld]\n", res, ccn, (long)expire_time); *result = res; *kerr = krberr; *ccname = ccn; *expire_time_out = expire_time; return EOK; } static void get_tgt_timeout_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct sdap_get_tgt_state *state = tevent_req_data(req, struct sdap_get_tgt_state); int ret; DEBUG(SSSDBG_TRACE_ALL, "timeout for tgt child [%d] reached.\n", state->child->pid); ret = kill(state->child->pid, SIGKILL); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "kill failed [%d][%s].\n", errno, strerror(errno)); } tevent_req_error(req, ETIMEDOUT); } static errno_t set_tgt_child_timeout(struct tevent_req *req, struct tevent_context *ev, int timeout) { struct tevent_timer *te; struct timeval tv; DEBUG(SSSDBG_TRACE_FUNC, "Setting %d seconds timeout for tgt child\n", timeout); tv = tevent_timeval_current_ofs(timeout, 0); te = tevent_add_timer(ev, req, tv, get_tgt_timeout_handler, req); if (te == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n"); return ENOMEM; } return EOK; } /* Setup child logging */ int sdap_setup_child(void) { return child_debug_init(LDAP_CHILD_LOG_FILE, &ldap_child_debug_fd); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_auth.h0000644000000000000000000000007412703456111020163 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.558793303 sssd-1.13.4/src/providers/ldap/ldap_auth.h0000644002412700241270000000265012703456111021635 0ustar00jhrozekjhrozek00000000000000/* SSSD Copyright (C) Pavel Reichl 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _LDAP_AUTH_H_ #define _LDAP_AUTH_H_ #include "config.h" enum pwexpire { PWEXPIRE_NONE = 0, PWEXPIRE_LDAP_PASSWORD_POLICY, PWEXPIRE_KERBEROS, PWEXPIRE_SHADOW }; int get_user_dn(TALLOC_CTX *memctx, struct sss_domain_info *domain, struct sdap_options *opts, const char *username, char **user_dn, enum pwexpire *user_pw_expire_type, void **user_pw_expire_data); errno_t check_pwexpire_policy(enum pwexpire pw_expire_type, void *pw_expire_data, struct pam_data *pd, errno_t checkb); #endif /* _LDAP_AUTH_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_ops.h0000644000000000000000000000007412703456111020032 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.562793317 sssd-1.13.4/src/providers/ldap/sdap_ops.h0000644002412700241270000000333612703456111021506 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SDAP_OPS_H_ #define _SDAP_OPS_H_ #include #include #include "providers/ldap/ldap_common.h" struct tevent_req *sdap_search_bases_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, struct sdap_search_base **bases, struct sdap_attr_map *map, bool allow_paging, int timeout, const char *filter, const char **attrs); int sdap_search_bases_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sysdb_attrs ***reply); #endif /* _SDAP_OPS_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_ops.c0000644000000000000000000000007412703456111020025 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.798794117 sssd-1.13.4/src/providers/ldap/sdap_ops.c0000644002412700241270000001554312703456111021504 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/util.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/ldap_common.h" struct sdap_search_bases_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; const char *filter; const char **attrs; struct sdap_attr_map *map; int map_num_attrs; int timeout; bool allow_paging; size_t base_iter; struct sdap_search_base *cur_base; struct sdap_search_base **bases; size_t reply_count; struct sysdb_attrs **reply; }; static errno_t sdap_search_bases_next_base(struct tevent_req *req); static void sdap_search_bases_done(struct tevent_req *subreq); struct tevent_req *sdap_search_bases_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, struct sdap_search_base **bases, struct sdap_attr_map *map, bool allow_paging, int timeout, const char *filter, const char **attrs) { struct tevent_req *req; struct sdap_search_bases_state *state; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_search_bases_state); if (req == NULL) { return NULL; } if (bases == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No search base specified!\n"); ret = ERR_INTERNAL; goto immediately; } if (map == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No attribute map specified!\n"); ret = ERR_INTERNAL; goto immediately; } state->ev = ev; state->opts = opts; state->sh = sh; state->bases = bases; state->map = map; state->filter = filter; state->attrs = attrs; state->allow_paging = allow_paging; state->timeout = timeout == 0 ? dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT) : timeout; for (state->map_num_attrs = 0; state->map[state->map_num_attrs].opt_name != NULL; state->map_num_attrs++) { /* no op */; } if (state->attrs == NULL) { ret = build_attrs_from_map(state, state->map, state->map_num_attrs, NULL, &state->attrs, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to build attrs from map " "[%d]: %s\n", ret, sss_strerror(ret)); goto immediately; } } state->base_iter = 0; ret = sdap_search_bases_next_base(req); if (ret == EAGAIN) { /* asynchronous processing */ return req; } immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t sdap_search_bases_next_base(struct tevent_req *req) { struct sdap_search_bases_state *state; struct tevent_req *subreq; char *filter; state = tevent_req_data(req, struct sdap_search_bases_state); state->cur_base = state->bases[state->base_iter]; if (state->cur_base == NULL) { return EOK; } /* Combine lookup and search base filters. */ filter = sdap_combine_filters(state, state->filter, state->cur_base->filter); if (filter == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Issuing LDAP lookup with base [%s]\n", state->cur_base->basedn); subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, state->cur_base->basedn, state->cur_base->scope, filter, state->attrs, state->map, state->map_num_attrs, state->timeout, state->allow_paging); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_search_bases_done, req); state->base_iter++; return EAGAIN; } static void sdap_search_bases_done(struct tevent_req *subreq) { struct tevent_req *req; struct sdap_search_bases_state *state; struct sysdb_attrs **attrs; size_t count; size_t i; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_search_bases_state); DEBUG(SSSDBG_TRACE_FUNC, "Receiving data from base [%s]\n", state->cur_base->basedn); ret = sdap_get_generic_recv(subreq, state, &count, &attrs); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } /* Add rules to result. */ if (count > 0) { state->reply = talloc_realloc(state, state->reply, struct sysdb_attrs *, state->reply_count + count); if (state->reply == NULL) { tevent_req_error(req, ENOMEM); return; } for (i = 0; i < count; i++) { state->reply[state->reply_count + i] = talloc_steal(state->reply, attrs[i]); } state->reply_count += count; } /* Try next search base. */ ret = sdap_search_bases_next_base(req); if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } int sdap_search_bases_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sysdb_attrs ***reply) { struct sdap_search_bases_state *state = tevent_req_data(req, struct sdap_search_bases_state); TEVENT_REQ_RETURN_ON_ERROR(req); *reply_count = state->reply_count; *reply = talloc_steal(mem_ctx, state->reply); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap.h0000644000000000000000000000007412703456111017151 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.549793273 sssd-1.13.4/src/providers/ldap/sdap.h0000644002412700241270000004341512703456111020627 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Helper routines Copyright (C) Simo Sorce This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SDAP_H_ #define _SDAP_H_ #include "providers/dp_backend.h" #include #include "util/sss_ldap.h" struct sdap_msg { struct sdap_msg *next; LDAPMessage *msg; }; struct sdap_op; typedef void (sdap_op_callback_t)(struct sdap_op *op, struct sdap_msg *, int, void *); struct sdap_handle; struct sdap_op { struct sdap_op *prev, *next; struct sdap_handle *sh; int msgid; bool done; sdap_op_callback_t *callback; void *data; struct tevent_context *ev; struct sdap_msg *list; struct sdap_msg *last; }; struct fd_event_item { struct fd_event_item *prev; struct fd_event_item *next; int fd; struct tevent_fd *fde; }; struct ldap_cb_data { struct sdap_handle *sh; struct tevent_context *ev; struct fd_event_item *fd_list; }; struct sup_list { int num_vals; char **vals; }; struct sdap_handle { LDAP *ldap; bool connected; /* Authentication ticket expiration time (if any) */ time_t expire_time; ber_int_t page_size; bool disable_deref; struct sdap_fd_events *sdap_fd_events; struct sup_list supported_saslmechs; struct sup_list supported_controls; struct sup_list supported_extensions; struct sdap_op *ops; /* during release we need to lock access to the handler * from the destructor to avoid recursion */ bool destructor_lock; /* mark when it is safe to finally release the handler memory */ bool release_memory; }; struct sdap_service { char *name; char *uri; char *kinit_service_name; struct sockaddr_storage *sockaddr; }; struct sdap_ppolicy_data { int grace; int expire; }; #define SYSDB_SHADOWPW_LASTCHANGE "shadowLastChange" #define SYSDB_SHADOWPW_MIN "shadowMin" #define SYSDB_SHADOWPW_MAX "shadowMax" #define SYSDB_SHADOWPW_WARNING "shadowWarning" #define SYSDB_SHADOWPW_INACTIVE "shadowInactive" #define SYSDB_SHADOWPW_EXPIRE "shadowExpire" #define SYSDB_SHADOWPW_FLAG "shadowFlag" #define SYSDB_NS_ACCOUNT_LOCK "nsAccountLock" #define SYSDB_KRBPW_LASTCHANGE "krbLastPwdChange" #define SYSDB_KRBPW_EXPIRATION "krbPasswordExpiration" #define SYSDB_PWD_ATTRIBUTE "pwdAttribute" #define SYSDB_NDS_LOGIN_DISABLED "ndsLoginDisabled" #define SYSDB_NDS_LOGIN_EXPIRATION_TIME "ndsLoginExpirationTime" #define SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP "ndsLoginAllowedTimeMap" #define SDAP_ROOTDSE_ATTR_NAMING_CONTEXTS "namingContexts" #define SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT "defaultNamingContext" #define SDAP_ROOTDSE_ATTR_AD_VERSION "domainControllerFunctionality" #define SDAP_IPA_USN "entryUSN" #define SDAP_IPA_LAST_USN "lastUSN" #define SDAP_AD_USN "uSNChanged" #define SDAP_AD_LAST_USN "highestCommittedUSN" #define SDAP_AD_GROUP_TYPE_BUILTIN 0x00000001 #define SDAP_AD_GROUP_TYPE_GLOBAL 0x00000002 #define SDAP_AD_GROUP_TYPE_DOMAIN_LOCAL 0x00000004 #define SDAP_AD_GROUP_TYPE_UNIVERSAL 0x00000008 #define SDAP_AD_GROUP_TYPE_APP_BASIC 0x00000010 #define SDAP_AD_GROUP_TYPE_APP_QUERY 0x00000020 #define SDAP_AD_GROUP_TYPE_SECURITY 0x80000000 enum sdap_basic_opt { SDAP_URI = 0, SDAP_BACKUP_URI, SDAP_SEARCH_BASE, SDAP_DEFAULT_BIND_DN, SDAP_DEFAULT_AUTHTOK_TYPE, SDAP_DEFAULT_AUTHTOK, SDAP_SEARCH_TIMEOUT, SDAP_NETWORK_TIMEOUT, SDAP_OPT_TIMEOUT, SDAP_TLS_REQCERT, SDAP_USER_SEARCH_BASE, SDAP_USER_SEARCH_SCOPE, SDAP_USER_SEARCH_FILTER, SDAP_USER_EXTRA_ATTRS, SDAP_GROUP_SEARCH_BASE, SDAP_GROUP_SEARCH_SCOPE, SDAP_GROUP_SEARCH_FILTER, SDAP_SERVICE_SEARCH_BASE, SDAP_SUDO_SEARCH_BASE, SDAP_SUDO_FULL_REFRESH_INTERVAL, SDAP_SUDO_SMART_REFRESH_INTERVAL, SDAP_SUDO_USE_HOST_FILTER, SDAP_SUDO_HOSTNAMES, SDAP_SUDO_IP, SDAP_SUDO_INCLUDE_NETGROUPS, SDAP_SUDO_INCLUDE_REGEXP, SDAP_AUTOFS_SEARCH_BASE, SDAP_AUTOFS_MAP_MASTER_NAME, SDAP_SCHEMA, SDAP_OFFLINE_TIMEOUT, SDAP_FORCE_UPPER_CASE_REALM, SDAP_ENUM_REFRESH_TIMEOUT, SDAP_PURGE_CACHE_TIMEOUT, SDAP_TLS_CACERT, SDAP_TLS_CACERTDIR, SDAP_TLS_CERT, SDAP_TLS_KEY, SDAP_TLS_CIPHER_SUITE, SDAP_ID_TLS, SDAP_ID_MAPPING, SDAP_SASL_MECH, SDAP_SASL_AUTHID, SDAP_SASL_REALM, SDAP_SASL_MINSSF, SDAP_KRB5_KEYTAB, SDAP_KRB5_KINIT, SDAP_KRB5_KDC, SDAP_KRB5_BACKUP_KDC, SDAP_KRB5_REALM, SDAP_KRB5_CANONICALIZE, SDAP_KRB5_USE_KDCINFO, SDAP_PWD_POLICY, SDAP_REFERRALS, SDAP_ACCOUNT_CACHE_EXPIRATION, SDAP_DNS_SERVICE_NAME, SDAP_KRB5_TICKET_LIFETIME, SDAP_ACCESS_FILTER, SDAP_NETGROUP_SEARCH_BASE, SDAP_NESTING_LEVEL, SDAP_DEREF, SDAP_ACCOUNT_EXPIRE_POLICY, SDAP_ACCESS_ORDER, SDAP_CHPASS_URI, SDAP_CHPASS_BACKUP_URI, SDAP_CHPASS_DNS_SERVICE_NAME, SDAP_CHPASS_UPDATE_LAST_CHANGE, SDAP_ENUM_SEARCH_TIMEOUT, SDAP_DISABLE_AUTH_TLS, SDAP_PAGE_SIZE, SDAP_DEREF_THRESHOLD, SDAP_SASL_CANONICALIZE, SDAP_EXPIRE_TIMEOUT, SDAP_DISABLE_PAGING, SDAP_IDMAP_LOWER, SDAP_IDMAP_UPPER, SDAP_IDMAP_RANGESIZE, SDAP_IDMAP_AUTORID_COMPAT, SDAP_IDMAP_DEFAULT_DOMAIN, SDAP_IDMAP_DEFAULT_DOMAIN_SID, SDAP_IDMAP_EXTRA_SLICE_INIT, SDAP_AD_MATCHING_RULE_GROUPS, SDAP_AD_MATCHING_RULE_INITGROUPS, SDAP_AD_USE_TOKENGROUPS, SDAP_RFC2307_FALLBACK_TO_LOCAL_USERS, SDAP_DISABLE_RANGE_RETRIEVAL, SDAP_MIN_ID, SDAP_MAX_ID, SDAP_PWDLOCKOUT_DN, SDAP_WILDCARD_LIMIT, SDAP_OPTS_BASIC /* opts counter */ }; enum sdap_gen_attrs { SDAP_AT_ENTRY_USN = 0, SDAP_AT_LAST_USN, SDAP_AT_GENERAL /* attrs counter */ }; /* the objectclass must be the first attribute. * Functions depend on this */ enum sdap_user_attrs { SDAP_OC_USER = 0, SDAP_AT_USER_NAME, SDAP_AT_USER_PWD, SDAP_AT_USER_UID, SDAP_AT_USER_GID, SDAP_AT_USER_GECOS, SDAP_AT_USER_HOME, SDAP_AT_USER_SHELL, SDAP_AT_USER_PRINC, SDAP_AT_USER_FULLNAME, SDAP_AT_USER_MEMBEROF, SDAP_AT_USER_UUID, SDAP_AT_USER_OBJECTSID, SDAP_AT_USER_PRIMARY_GROUP, SDAP_AT_USER_MODSTAMP, SDAP_AT_USER_USN, SDAP_AT_SP_LSTCHG, SDAP_AT_SP_MIN, SDAP_AT_SP_MAX, SDAP_AT_SP_WARN, SDAP_AT_SP_INACT, SDAP_AT_SP_EXPIRE, SDAP_AT_SP_FLAG, SDAP_AT_KP_LASTCHANGE, SDAP_AT_KP_EXPIRATION, SDAP_AT_PWD_ATTRIBUTE, SDAP_AT_AUTH_SVC, SDAP_AT_AD_ACCOUNT_EXPIRES, SDAP_AT_AD_USER_ACCOUNT_CONTROL, SDAP_AT_NS_ACCOUNT_LOCK, SDAP_AT_AUTHORIZED_HOST, SDAP_AT_NDS_LOGIN_DISABLED, SDAP_AT_NDS_LOGIN_EXPIRATION_TIME, SDAP_AT_NDS_LOGIN_ALLOWED_TIME_MAP, SDAP_AT_USER_SSH_PUBLIC_KEY, SDAP_AT_USER_AUTH_TYPE, SDAP_AT_USER_CERT, SDAP_OPTS_USER /* attrs counter */ }; #define SDAP_FIRST_EXTRA_USER_AT SDAP_AT_SP_LSTCHG /* the objectclass must be the first attribute. * Functions depend on this */ enum sdap_group_attrs { SDAP_OC_GROUP = 0, SDAP_OC_GROUP_ALT, SDAP_AT_GROUP_NAME, SDAP_AT_GROUP_PWD, SDAP_AT_GROUP_GID, SDAP_AT_GROUP_MEMBER, SDAP_AT_GROUP_UUID, SDAP_AT_GROUP_OBJECTSID, SDAP_AT_GROUP_MODSTAMP, SDAP_AT_GROUP_USN, SDAP_AT_GROUP_TYPE, SDAP_AT_GROUP_EXT_MEMBER, SDAP_OPTS_GROUP /* attrs counter */ }; enum sdap_netgroup_attrs { SDAP_OC_NETGROUP = 0, SDAP_AT_NETGROUP_NAME, SDAP_AT_NETGROUP_MEMBER, SDAP_AT_NETGROUP_TRIPLE, SDAP_AT_NETGROUP_MODSTAMP, SDAP_OPTS_NETGROUP /* attrs counter */ }; enum sdap_sudorule_attrs { SDAP_OC_SUDORULE = 0, SDAP_AT_SUDO_NAME, SDAP_AT_SUDO_COMMAND, SDAP_AT_SUDO_HOST, SDAP_AT_SUDO_USER, SDAP_AT_SUDO_OPTION, SDAP_AT_SUDO_RUNAS, SDAP_AT_SUDO_RUNASUSER, SDAP_AT_SUDO_RUNASGROUP, SDAP_AT_SUDO_NOTBEFORE, SDAP_AT_SUDO_NOTAFTER, SDAP_AT_SUDO_ORDER, SDAP_AT_SUDO_USN, SDAP_OPTS_SUDO /* attrs counter */ }; enum sdap_service_attrs { SDAP_OC_SERVICE = 0, SDAP_AT_SERVICE_NAME, SDAP_AT_SERVICE_PORT, SDAP_AT_SERVICE_PROTOCOL, SDAP_AT_SERVICE_USN, SDAP_OPTS_SERVICES /* attrs counter */ }; enum sdap_autofs_map_attrs { SDAP_OC_AUTOFS_MAP, SDAP_AT_AUTOFS_MAP_NAME, SDAP_OPTS_AUTOFS_MAP /* attrs counter */ }; enum sdap_autofs_entry_attrs { SDAP_OC_AUTOFS_ENTRY, SDAP_AT_AUTOFS_ENTRY_KEY, SDAP_AT_AUTOFS_ENTRY_VALUE, SDAP_OPTS_AUTOFS_ENTRY /* attrs counter */ }; struct sdap_attr_map { const char *opt_name; const char *def_name; const char *sys_name; char *name; }; #define SDAP_ATTR_MAP_TERMINATOR { NULL, NULL, NULL, NULL } struct sdap_search_base { const char *basedn; int scope; const char *filter; }; errno_t sdap_create_search_base(TALLOC_CTX *mem_ctx, const char *unparsed_base, int scope, const char *filter, struct sdap_search_base **_base); /* Values from * http://msdn.microsoft.com/en-us/library/cc223272%28v=prot.13%29.aspx */ enum dc_functional_level { DS_BEHAVIOR_WIN2000 = 0, DS_BEHAVIOR_WIN2003 = 2, DS_BEHAVIOR_WIN2008 = 3, DS_BEHAVIOR_WIN2008R2 = 4, DS_BEHAVIOR_WIN2012 = 5, DS_BEHAVIOR_WIN2012R2 = 6, DS_BEHAVIOR_WIN2016 = 7, }; struct sdap_domain { struct sss_domain_info *dom; char *basedn; struct sdap_search_base **search_bases; struct sdap_search_base **user_search_bases; struct sdap_search_base **group_search_bases; struct sdap_search_base **netgroup_search_bases; struct sdap_search_base **sudo_search_bases; struct sdap_search_base **service_search_bases; struct sdap_search_base **autofs_search_bases; struct sdap_domain *next, *prev; /* Need to modify the list from a talloc destructor */ struct sdap_domain **head; /* Enumeration and cleanup periodic task */ struct be_ptask *enum_task; struct be_ptask *cleanup_task; /* enumeration loop timer */ struct timeval last_enum; /* cleanup loop timer */ struct timeval last_purge; void *pvt; }; typedef struct tevent_req * (*ext_member_send_fn_t)(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *ext_member, void *pvt); typedef errno_t (*ext_member_recv_fn_t)(TALLOC_CTX *mem_ctx, struct tevent_req *req, enum sysdb_member_type *member_type, struct sss_domain_info **_dom, struct sysdb_attrs **_member); struct sdap_ext_member_ctx { /* Typically ID context of the external ID provider */ void *pvt; ext_member_send_fn_t ext_member_resolve_send; ext_member_recv_fn_t ext_member_resolve_recv; }; struct sdap_options { struct dp_option *basic; struct sdap_attr_map *gen_map; struct sdap_attr_map *user_map; size_t user_map_cnt; struct sdap_attr_map *group_map; struct sdap_attr_map *netgroup_map; struct sdap_attr_map *service_map; /* ID-mapping support */ struct sdap_idmap_ctx *idmap_ctx; /* Resolving external members */ struct sdap_ext_member_ctx *ext_ctx; /* FIXME - should this go to a special struct to avoid mixing with name-service-switch maps? */ struct sdap_attr_map *sudorule_map; struct sdap_attr_map *autofs_mobject_map; struct sdap_attr_map *autofs_entry_map; /* supported schema types */ enum schema_type { SDAP_SCHEMA_RFC2307 = 1, /* memberUid = uid */ SDAP_SCHEMA_RFC2307BIS = 2, /* member = dn */ SDAP_SCHEMA_IPA_V1 = 3, /* member/memberof */ SDAP_SCHEMA_AD = 4 /* AD's member/memberof */ } schema_type; /* The search bases for the domain or its subdomain */ struct sdap_domain *sdom; bool support_matching_rule; enum dc_functional_level dc_functional_level; }; struct sdap_server_opts { char *server_id; bool supports_usn; unsigned long last_usn; char *max_user_value; char *max_group_value; char *max_service_value; char *max_sudo_value; bool posix_checked; }; struct sdap_id_ctx; struct sdap_attr_map_info { struct sdap_attr_map *map; int num_attrs; }; struct sdap_deref_attrs { struct sdap_attr_map *map; struct sysdb_attrs *attrs; }; errno_t sdap_copy_map_entry(const struct sdap_attr_map *src_map, struct sdap_attr_map *dst_map, int entry_index); int sdap_copy_map(TALLOC_CTX *memctx, struct sdap_attr_map *src_map, int num_entries, struct sdap_attr_map **_map); int sdap_extend_map(TALLOC_CTX *memctx, struct sdap_attr_map *src_map, size_t num_entries, char **extra_attrs, struct sdap_attr_map **_map, size_t *_new_size); int sdap_extend_map_with_list(TALLOC_CTX *mem_ctx, struct sdap_options *opts, int extra_attr_index, struct sdap_attr_map *src_map, size_t num_entries, struct sdap_attr_map **_map, size_t *_new_size); void sdap_inherit_options(char **inherit_opt_list, struct sdap_options *parent_sdap_opts, struct sdap_options *child_sdap_opts); int sdap_get_map(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, struct sdap_attr_map *def_map, int num_entries, struct sdap_attr_map **_map); int sdap_parse_entry(TALLOC_CTX *memctx, struct sdap_handle *sh, struct sdap_msg *sm, struct sdap_attr_map *map, int attrs_num, struct sysdb_attrs **_attrs, bool disable_range_retrieval); errno_t sdap_parse_deref(TALLOC_CTX *mem_ctx, struct sdap_attr_map_info *minfo, size_t num_maps, LDAPDerefRes *dref, struct sdap_deref_attrs ***_deref_res); errno_t setup_tls_config(struct dp_option *basic_opts); int sdap_set_rootdse_supported_lists(struct sysdb_attrs *rootdse, struct sdap_handle *sh); bool sdap_check_sup_list(struct sup_list *l, const char *val); #define sdap_is_sasl_mech_supported(sh, sasl_mech) \ sdap_check_sup_list(&((sh)->supported_saslmechs), sasl_mech) #define sdap_is_control_supported(sh, ctrl_oid) \ sdap_check_sup_list(&((sh)->supported_controls), ctrl_oid) #define sdap_is_extension_supported(sh, ext_oid) \ sdap_check_sup_list(&((sh)->supported_extensions), ext_oid) int build_attrs_from_map(TALLOC_CTX *memctx, struct sdap_attr_map *map, size_t size, const char **filter, const char ***_attrs, size_t *attr_count); int sdap_control_create(struct sdap_handle *sh, const char *oid, int iscritical, struct berval *value, int dupval, LDAPControl **ctrlp); int sdap_replace_id(struct sysdb_attrs *entry, const char *attr, id_t val); errno_t sdap_get_group_primary_name(TALLOC_CTX *memctx, struct sdap_options *opts, struct sysdb_attrs *attrs, struct sss_domain_info *dom, const char **_group_name); errno_t sdap_get_user_primary_name(TALLOC_CTX *memctx, struct sdap_options *opts, struct sysdb_attrs *attrs, struct sss_domain_info *dom, const char **_user_name); errno_t sdap_get_netgroup_primary_name(TALLOC_CTX *memctx, struct sdap_options *opts, struct sysdb_attrs *attrs, struct sss_domain_info *dom, const char **_netgroup_name); errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, struct sdap_options *opts, struct sdap_domain *sdom); int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx, const char *server, struct sysdb_attrs *rootdse, struct sdap_options *opts, struct sdap_server_opts **srv_opts); void sdap_steal_server_opts(struct sdap_id_ctx *id_ctx, struct sdap_server_opts **srv_opts); char *sdap_make_oc_list(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map); size_t sdap_steal_objects_in_dom(struct sdap_options *opts, struct sysdb_attrs **dom_objects, size_t offset, struct sss_domain_info *dom, struct sysdb_attrs **all_objects, size_t count, bool filter); #endif /* _SDAP_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_id_netgroup.c0000644000000000000000000000007412703456111021534 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.773794032 sssd-1.13.4/src/providers/ldap/ldap_id_netgroup.c0000644002412700241270000001630312703456111023206 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Identity Backend Module - Netgroup support Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" struct ldap_netgroup_get_state { struct tevent_context *ev; struct sdap_id_ctx *ctx; struct sdap_domain *sdom; struct sdap_id_op *op; struct sdap_id_conn_ctx *conn; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; const char *name; int timeout; char *filter; const char **attrs; size_t count; struct sysdb_attrs **netgroups; int dp_error; int sdap_ret; bool noexist_delete; }; static int ldap_netgroup_get_retry(struct tevent_req *req); static void ldap_netgroup_get_connect_done(struct tevent_req *subreq); static void ldap_netgroup_get_done(struct tevent_req *subreq); struct tevent_req *ldap_netgroup_get_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_id_ctx *ctx, struct sdap_domain *sdom, struct sdap_id_conn_ctx *conn, const char *name, bool noexist_delete) { struct tevent_req *req; struct ldap_netgroup_get_state *state; char *clean_name; int ret; req = tevent_req_create(memctx, &state, struct ldap_netgroup_get_state); if (!req) return NULL; state->ev = ev; state->ctx = ctx; state->sdom = sdom; state->conn = conn; state->dp_error = DP_ERR_FATAL; state->noexist_delete = noexist_delete; state->op = sdap_id_op_create(state, state->conn->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto fail; } state->domain = sdom->dom; state->sysdb = sdom->dom->sysdb; state->name = name; state->timeout = dp_opt_get_int(ctx->opts->basic, SDAP_SEARCH_TIMEOUT); ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { goto fail; } state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))", ctx->opts->netgroup_map[SDAP_AT_NETGROUP_NAME].name, clean_name, ctx->opts->netgroup_map[SDAP_OC_NETGROUP].name); if (!state->filter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto fail; } talloc_zfree(clean_name); ret = build_attrs_from_map(state, ctx->opts->netgroup_map, SDAP_OPTS_NETGROUP, NULL, &state->attrs, NULL); if (ret != EOK) goto fail; ret = ldap_netgroup_get_retry(req); if (ret != EOK) { goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static int ldap_netgroup_get_retry(struct tevent_req *req) { struct ldap_netgroup_get_state *state = tevent_req_data(req, struct ldap_netgroup_get_state); struct tevent_req *subreq; int ret = EOK; subreq = sdap_id_op_connect_send(state->op, state, &ret); if (!subreq) { return ret; } tevent_req_set_callback(subreq, ldap_netgroup_get_connect_done, req); return EOK; } static void ldap_netgroup_get_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ldap_netgroup_get_state *state = tevent_req_data(req, struct ldap_netgroup_get_state); int dp_error = DP_ERR_FATAL; int ret; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } subreq = sdap_get_netgroups_send(state, state->ev, state->domain, state->sysdb, state->ctx->opts, state->sdom->netgroup_search_bases, sdap_id_op_handle(state->op), state->attrs, state->filter, state->timeout); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, ldap_netgroup_get_done, req); return; } static void ldap_netgroup_get_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct ldap_netgroup_get_state *state = tevent_req_data(req, struct ldap_netgroup_get_state); int dp_error = DP_ERR_FATAL; int ret; ret = sdap_get_netgroups_recv(subreq, state, NULL, &state->count, &state->netgroups); talloc_zfree(subreq); ret = sdap_id_op_done(state->op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = ldap_netgroup_get_retry(req); if (ret != EOK) { tevent_req_error(req, ret); return; } return; } state->sdap_ret = ret; if (ret && ret != ENOENT) { state->dp_error = dp_error; tevent_req_error(req, ret); return; } if (ret == EOK && state->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Found more than one netgroup with the name [%s].\n", state->name); tevent_req_error(req, EINVAL); return; } if (ret == ENOENT && state->noexist_delete == true) { ret = sysdb_delete_netgroup(state->domain, state->name); if (ret != EOK && ret != ENOENT) { tevent_req_error(req, ret); return; } } state->dp_error = DP_ERR_OK; tevent_req_done(req); return; } int ldap_netgroup_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret) { struct ldap_netgroup_get_state *state = tevent_req_data(req, struct ldap_netgroup_get_state); if (dp_error_out) { *dp_error_out = state->dp_error; } if (sdap_ret) { *sdap_ret = state->sdap_ret; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_autofs.h0000644000000000000000000000007312703456111020531 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.555793293 sssd-1.13.4/src/providers/ldap/sdap_autofs.h0000644002412700241270000000304412703456111022202 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP handler for autofs Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SDAP_AUTOFS_H_ #define _SDAP_AUTOFS_H_ int sdap_autofs_init(struct be_ctx *be_ctx, struct sdap_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data); struct tevent_req * sdap_autofs_setautomntent_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sysdb_ctx *sysdb, struct sdap_handle *sh, struct sdap_id_op *op, struct sdap_options *opts, const char *mapname); errno_t sdap_autofs_setautomntent_recv(struct tevent_req *req); #endif /* _SDAP_AUTOFS_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_idmap.h0000644000000000000000000000007412703456111020323 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.792794097 sssd-1.13.4/src/providers/ldap/sdap_idmap.h0000644002412700241270000000412312703456111021772 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SDAP_IDMAP_H_ #define SDAP_IDMAP_H_ #include "src/providers/ldap/sdap.h" #include "src/providers/ldap/ldap_common.h" typedef errno_t (find_new_domain_fn_t)(struct sdap_idmap_ctx *idmap_ctx, const char *dom_name, const char *dom_sid_str); struct sdap_idmap_ctx { struct sss_idmap_ctx *map; struct sdap_id_ctx *id_ctx; find_new_domain_fn_t *find_new_domain; }; errno_t sdap_idmap_init(TALLOC_CTX *mem_ctx, struct sdap_id_ctx *id_ctx, struct sdap_idmap_ctx **_idmap_ctx); errno_t sdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx, const char *dom_name, const char *dom_sid, id_t slice); errno_t sdap_idmap_get_dom_sid_from_object(TALLOC_CTX *mem_ctx, const char *object_sid, char **dom_sid_str); errno_t sdap_idmap_sid_to_unix(struct sdap_idmap_ctx *idmap_ctx, const char *sid_str, id_t *id); bool sdap_idmap_domain_has_algorithmic_mapping(struct sdap_idmap_ctx *ctx, const char *name, const char *dom_sid); #endif /* SDAP_IDMAP_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_options.c0000644000000000000000000000007412703456111020710 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.776794042 sssd-1.13.4/src/providers/ldap/ldap_options.c0000644002412700241270000006310712703456111022366 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Copyright (C) 2008-2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ldap/ldap_common.h" #include "providers/ldap/ldap_opts.h" #include "providers/ldap/sdap_async_private.h" #include "util/crypto/sss_crypto.h" int ldap_get_options(TALLOC_CTX *memctx, struct sss_domain_info *dom, struct confdb_ctx *cdb, const char *conf_path, struct sdap_options **_opts) { struct sdap_attr_map *default_attr_map; struct sdap_attr_map *default_user_map; struct sdap_attr_map *default_group_map; struct sdap_attr_map *default_netgroup_map; struct sdap_attr_map *default_service_map; struct sdap_options *opts; char *schema; const char *search_base; const char *pwd_policy; int ret; int account_cache_expiration; int offline_credentials_expiration; const char *ldap_deref; int ldap_deref_val; int o; const char *authtok_type; struct dp_opt_blob authtok_blob; char *cleartext; const int search_base_options[] = { SDAP_USER_SEARCH_BASE, SDAP_GROUP_SEARCH_BASE, SDAP_NETGROUP_SEARCH_BASE, SDAP_SERVICE_SEARCH_BASE, -1 }; opts = talloc_zero(memctx, struct sdap_options); if (!opts) return ENOMEM; ret = sdap_domain_add(opts, dom, NULL); if (ret != EOK) { goto done; } ret = dp_get_options(opts, cdb, conf_path, default_basic_opts, SDAP_OPTS_BASIC, &opts->basic); if (ret != EOK) { goto done; } /* Handle search bases */ search_base = dp_opt_get_string(opts->basic, SDAP_SEARCH_BASE); if (search_base != NULL) { /* set user/group/netgroup search bases if they are not */ for (o = 0; search_base_options[o] != -1; o++) { if (NULL == dp_opt_get_string(opts->basic, search_base_options[o])) { ret = dp_opt_set_string(opts->basic, search_base_options[o], search_base); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n", opts->basic[search_base_options[o]].opt_name, dp_opt_get_string(opts->basic, search_base_options[o])); } } } else { DEBUG(SSSDBG_FUNC_DATA, "Search base not set, trying to discover it later when " "connecting to the LDAP server.\n"); } /* Default search */ ret = sdap_parse_search_base(opts, opts->basic, SDAP_SEARCH_BASE, &opts->sdom->search_bases); if (ret != EOK && ret != ENOENT) goto done; /* User search */ ret = sdap_parse_search_base(opts, opts->basic, SDAP_USER_SEARCH_BASE, &opts->sdom->user_search_bases); if (ret != EOK && ret != ENOENT) goto done; /* Group search base */ ret = sdap_parse_search_base(opts, opts->basic, SDAP_GROUP_SEARCH_BASE, &opts->sdom->group_search_bases); if (ret != EOK && ret != ENOENT) goto done; /* Netgroup search */ ret = sdap_parse_search_base(opts, opts->basic, SDAP_NETGROUP_SEARCH_BASE, &opts->sdom->netgroup_search_bases); if (ret != EOK && ret != ENOENT) goto done; /* Service search */ ret = sdap_parse_search_base(opts, opts->basic, SDAP_SERVICE_SEARCH_BASE, &opts->sdom->service_search_bases); if (ret != EOK && ret != ENOENT) goto done; pwd_policy = dp_opt_get_string(opts->basic, SDAP_PWD_POLICY); if (pwd_policy == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing password policy, this may not happen.\n"); ret = EINVAL; goto done; } if (strcasecmp(pwd_policy, PWD_POL_OPT_NONE) != 0 && strcasecmp(pwd_policy, PWD_POL_OPT_SHADOW) != 0 && strcasecmp(pwd_policy, PWD_POL_OPT_MIT) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported password policy [%s].\n", pwd_policy); ret = EINVAL; goto done; } /* account_cache_expiration must be >= than offline_credentials_expiration */ ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_CRED_TIMEOUT, 0, &offline_credentials_expiration); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get value of %s from confdb \n", CONFDB_PAM_CRED_TIMEOUT); goto done; } account_cache_expiration = dp_opt_get_int(opts->basic, SDAP_ACCOUNT_CACHE_EXPIRATION); /* account cache_expiration must not be smaller than * offline_credentials_expiration to prevent deleting entries that * still contain credentials valid for offline login. * * offline_credentials_expiration == 0 is a special case that says * that the cached credentials are valid forever. Therefore, the cached * entries must not be purged from cache. */ if (!offline_credentials_expiration && account_cache_expiration) { DEBUG(SSSDBG_CRIT_FAILURE, "Conflicting values for options %s (unlimited) " "and %s (%d)\n", opts->basic[SDAP_ACCOUNT_CACHE_EXPIRATION].opt_name, CONFDB_PAM_CRED_TIMEOUT, offline_credentials_expiration); ret = EINVAL; goto done; } if (offline_credentials_expiration && account_cache_expiration && offline_credentials_expiration > account_cache_expiration) { DEBUG(SSSDBG_CRIT_FAILURE, "Value of %s (now %d) must be larger " "than value of %s (now %d)\n", opts->basic[SDAP_ACCOUNT_CACHE_EXPIRATION].opt_name, account_cache_expiration, CONFDB_PAM_CRED_TIMEOUT, offline_credentials_expiration); ret = EINVAL; goto done; } ldap_deref = dp_opt_get_string(opts->basic, SDAP_DEREF); if (ldap_deref != NULL) { ret = deref_string_to_val(ldap_deref, &ldap_deref_val); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to verify ldap_deref option.\n"); goto done; } } #ifndef HAVE_LDAP_CONNCB bool ldap_referrals; ldap_referrals = dp_opt_get_bool(opts->basic, SDAP_REFERRALS); if (ldap_referrals) { DEBUG(SSSDBG_CRIT_FAILURE, "LDAP referrals are not supported, because the LDAP library " "is too old, see sssd-ldap(5) for details.\n"); ret = dp_opt_set_bool(opts->basic, SDAP_REFERRALS, false); } #endif /* schema type */ schema = dp_opt_get_string(opts->basic, SDAP_SCHEMA); if (strcasecmp(schema, "rfc2307") == 0) { opts->schema_type = SDAP_SCHEMA_RFC2307; default_attr_map = generic_attr_map; default_user_map = rfc2307_user_map; default_group_map = rfc2307_group_map; default_netgroup_map = netgroup_map; default_service_map = service_map; } else if (strcasecmp(schema, "rfc2307bis") == 0) { opts->schema_type = SDAP_SCHEMA_RFC2307BIS; default_attr_map = generic_attr_map; default_user_map = rfc2307bis_user_map; default_group_map = rfc2307bis_group_map; default_netgroup_map = netgroup_map; default_service_map = service_map; } else if (strcasecmp(schema, "IPA") == 0) { opts->schema_type = SDAP_SCHEMA_IPA_V1; default_attr_map = gen_ipa_attr_map; default_user_map = rfc2307bis_user_map; default_group_map = rfc2307bis_group_map; default_netgroup_map = netgroup_map; default_service_map = service_map; } else if (strcasecmp(schema, "AD") == 0) { opts->schema_type = SDAP_SCHEMA_AD; default_attr_map = gen_ad_attr_map; default_user_map = gen_ad2008r2_user_map; default_group_map = gen_ad2008r2_group_map; default_netgroup_map = netgroup_map; default_service_map = service_map; } else { DEBUG(SSSDBG_FATAL_FAILURE, "Unrecognized schema type: %s\n", schema); ret = EINVAL; goto done; } ret = sdap_get_map(opts, cdb, conf_path, default_attr_map, SDAP_AT_GENERAL, &opts->gen_map); if (ret != EOK) { goto done; } ret = sdap_get_map(opts, cdb, conf_path, default_user_map, SDAP_OPTS_USER, &opts->user_map); if (ret != EOK) { goto done; } ret = sdap_extend_map_with_list(opts, opts, SDAP_USER_EXTRA_ATTRS, opts->user_map, SDAP_OPTS_USER, &opts->user_map, &opts->user_map_cnt); if (ret != EOK) { goto done; } ret = sdap_get_map(opts, cdb, conf_path, default_group_map, SDAP_OPTS_GROUP, &opts->group_map); if (ret != EOK) { goto done; } ret = sdap_get_map(opts, cdb, conf_path, default_netgroup_map, SDAP_OPTS_NETGROUP, &opts->netgroup_map); if (ret != EOK) { goto done; } ret = sdap_get_map(opts, cdb, conf_path, default_service_map, SDAP_OPTS_SERVICES, &opts->service_map); if (ret != EOK) { goto done; } /* If there is no KDC, try the deprecated krb5_kdcip option, too */ /* FIXME - this can be removed in a future version */ ret = krb5_try_kdcip(cdb, conf_path, opts->basic, SDAP_KRB5_KDC); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_try_kdcip failed.\n"); goto done; } authtok_type = dp_opt_get_string(opts->basic, SDAP_DEFAULT_AUTHTOK_TYPE); if (authtok_type != NULL && strcasecmp(authtok_type,"obfuscated_password") == 0) { DEBUG(SSSDBG_TRACE_ALL, "Found obfuscated password, " "trying to convert to cleartext.\n"); authtok_blob = dp_opt_get_blob(opts->basic, SDAP_DEFAULT_AUTHTOK); if (authtok_blob.data == NULL || authtok_blob.length == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing obfuscated password string.\n"); return EINVAL; } ret = sss_password_decrypt(memctx, (char *) authtok_blob.data, &cleartext); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot convert the obfuscated " "password back to cleartext\n"); return ret; } authtok_blob.data = (uint8_t *) cleartext; authtok_blob.length = strlen(cleartext); ret = dp_opt_set_blob(opts->basic, SDAP_DEFAULT_AUTHTOK, authtok_blob); talloc_free(cleartext); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed.\n"); return ret; } ret = dp_opt_set_string(opts->basic, SDAP_DEFAULT_AUTHTOK_TYPE, "password"); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed.\n"); return ret; } } ret = EOK; *_opts = opts; done: if (ret != EOK) { talloc_zfree(opts); } return ret; } int ldap_get_sudo_options(struct confdb_ctx *cdb, const char *conf_path, struct sdap_options *opts, bool *use_host_filter, bool *include_regexp, bool *include_netgroups) { const char *search_base; int ret; /* search base */ search_base = dp_opt_get_string(opts->basic, SDAP_SEARCH_BASE); if (search_base != NULL) { /* set sudo search bases if they are not */ if (dp_opt_get_string(opts->basic, SDAP_SUDO_SEARCH_BASE) == NULL) { ret = dp_opt_set_string(opts->basic, SDAP_SUDO_SEARCH_BASE, search_base); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set SUDO search base" "to default value\n"); return ret; } DEBUG(SSSDBG_FUNC_DATA, "Option %s set to %s\n", opts->basic[SDAP_SUDO_SEARCH_BASE].opt_name, dp_opt_get_string(opts->basic, SDAP_SUDO_SEARCH_BASE)); } } else { DEBUG(SSSDBG_TRACE_FUNC, "Search base not set, trying to discover it later " "connecting to the LDAP server.\n"); } ret = sdap_parse_search_base(opts, opts->basic, SDAP_SUDO_SEARCH_BASE, &opts->sdom->sudo_search_bases); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Could not parse SUDO search base\n"); return ret; } /* attrs map */ ret = sdap_get_map(opts, cdb, conf_path, native_sudorule_map, SDAP_OPTS_SUDO, &opts->sudorule_map); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not get SUDO attribute map\n"); return ret; } /* host filter */ *use_host_filter = dp_opt_get_bool(opts->basic, SDAP_SUDO_USE_HOST_FILTER); *include_netgroups = dp_opt_get_bool(opts->basic, SDAP_SUDO_INCLUDE_NETGROUPS); *include_regexp = dp_opt_get_bool(opts->basic, SDAP_SUDO_INCLUDE_REGEXP); return EOK; } int ldap_get_autofs_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, struct sdap_options *opts) { const char *search_base; struct sdap_attr_map *default_entry_map; struct sdap_attr_map *default_mobject_map; int ret; /* search base */ search_base = dp_opt_get_string(opts->basic, SDAP_SEARCH_BASE); if (search_base != NULL) { /* set autofs search bases if they are not */ if (dp_opt_get_string(opts->basic, SDAP_AUTOFS_SEARCH_BASE) == NULL) { ret = dp_opt_set_string(opts->basic, SDAP_AUTOFS_SEARCH_BASE, search_base); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set autofs search base" "to default value\n"); return ret; } DEBUG(SSSDBG_FUNC_DATA, "Option %s set to %s\n", opts->basic[SDAP_AUTOFS_SEARCH_BASE].opt_name, dp_opt_get_string(opts->basic, SDAP_AUTOFS_SEARCH_BASE)); } } else { DEBUG(SSSDBG_TRACE_FUNC, "Search base not set, trying to discover it later " "connecting to the LDAP server.\n"); } ret = sdap_parse_search_base(opts, opts->basic, SDAP_AUTOFS_SEARCH_BASE, &opts->sdom->autofs_search_bases); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Could not parse autofs search base\n"); return ret; } /* attribute maps */ switch (opts->schema_type) { case SDAP_SCHEMA_RFC2307: default_mobject_map = rfc2307_autofs_mobject_map; default_entry_map = rfc2307_autofs_entry_map; break; case SDAP_SCHEMA_RFC2307BIS: case SDAP_SCHEMA_IPA_V1: case SDAP_SCHEMA_AD: default_mobject_map = rfc2307bis_autofs_mobject_map; default_entry_map = rfc2307bis_autofs_entry_map; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown LDAP schema!\n"); return EINVAL; } ret = sdap_get_map(opts, cdb, conf_path, default_mobject_map, SDAP_OPTS_AUTOFS_MAP, &opts->autofs_mobject_map); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not get autofs map object attribute map\n"); return ret; } ret = sdap_get_map(opts, cdb, conf_path, default_entry_map, SDAP_OPTS_AUTOFS_ENTRY, &opts->autofs_entry_map); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not get autofs entry object attribute map\n"); return ret; } return EOK; } errno_t sdap_parse_search_base(TALLOC_CTX *mem_ctx, struct dp_option *opts, int class, struct sdap_search_base ***_search_bases) { const char *class_name; char *unparsed_base; const char *old_filter = NULL; *_search_bases = NULL; switch (class) { case SDAP_SEARCH_BASE: class_name = "DEFAULT"; break; case SDAP_USER_SEARCH_BASE: class_name = "USER"; old_filter = dp_opt_get_string(opts, SDAP_USER_SEARCH_FILTER); break; case SDAP_GROUP_SEARCH_BASE: class_name = "GROUP"; old_filter = dp_opt_get_string(opts, SDAP_GROUP_SEARCH_FILTER); break; case SDAP_NETGROUP_SEARCH_BASE: class_name = "NETGROUP"; break; case SDAP_SUDO_SEARCH_BASE: class_name = "SUDO"; break; case SDAP_SERVICE_SEARCH_BASE: class_name = "SERVICE"; break; case SDAP_AUTOFS_SEARCH_BASE: class_name = "AUTOFS"; break; default: DEBUG(SSSDBG_CONF_SETTINGS, "Unknown search base type: [%d]\n", class); class_name = "UNKNOWN"; /* Non-fatal */ break; } unparsed_base = dp_opt_get_string(opts, class); if (!unparsed_base || unparsed_base[0] == '\0') return ENOENT; return common_parse_search_base(mem_ctx, unparsed_base, class_name, old_filter, _search_bases); } errno_t common_parse_search_base(TALLOC_CTX *mem_ctx, const char *unparsed_base, const char *class_name, const char *old_filter, struct sdap_search_base ***_search_bases) { errno_t ret; struct sdap_search_base **search_bases; TALLOC_CTX *tmp_ctx; struct ldb_context *ldb; struct ldb_dn *ldn; struct ldb_parse_tree *tree; char **split_bases; char *filter; int count; int i, c; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } /* Create a throwaway LDB context for validating the DN */ ldb = ldb_init(tmp_ctx, NULL); if (!ldb) { ret = ENOMEM; goto done; } ret = split_on_separator(tmp_ctx, unparsed_base, '?', false, false, &split_bases, &count); if (ret != EOK) goto done; /* The split must be either exactly one value or a multiple of * three in order to be valid. * One value: just a base, backwards-compatible with pre-1.7.0 versions * Multiple: search_base?scope?filter[?search_base?scope?filter]* */ if (count > 1 && (count % 3)) { DEBUG(SSSDBG_CRIT_FAILURE, "Unparseable search base: [%s][%d]\n", unparsed_base, count); ret = EINVAL; goto done; } if (count == 1) { search_bases = talloc_array(tmp_ctx, struct sdap_search_base *, 2); if (!search_bases) { ret = ENOMEM; goto done; } if (old_filter != NULL) { /* Using a deprecated ldap_{user,group}_search_filter */ DEBUG(SSSDBG_IMPORTANT_INFO, "WARNING: Using a deprecated filter " "option for %s. Please see the documentation on LDAP search " "bases to see how the obsolete option can be migrated\n", class_name); sss_log(SSS_LOG_NOTICE, "WARNING: Using a deprecated filter option" "for %s. Please see the documentation on LDAP search bases " "to see how the obsolete option can be migrated\n", class_name); } ret = sdap_create_search_base(search_bases, unparsed_base, LDAP_SCOPE_SUBTREE, old_filter, &search_bases[0]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot create new sdap search base\n"); goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Search base added: [%s][%s][%s][%s]\n", class_name, search_bases[0]->basedn, "SUBTREE", search_bases[0]->filter ? search_bases[0]->filter : ""); search_bases[1] = NULL; } else { search_bases = talloc_array(tmp_ctx, struct sdap_search_base *, (count / 3) + 1); if (!search_bases) { ret = ENOMEM; goto done; } i = 0; for (c = 0; c < count; c += 3) { search_bases[i] = talloc_zero(search_bases, struct sdap_search_base); if (!search_bases[i]) { ret = ENOMEM; goto done; } if (split_bases[c][0] == '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Zero-length search base: [%s]\n", unparsed_base); ret = EINVAL; goto done; } /* Validate the basedn */ ldn = ldb_dn_new(tmp_ctx, ldb, split_bases[c]); if (!ldn) { ret = ENOMEM; goto done; } if (!ldb_dn_validate(ldn)) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid base DN [%s]\n", split_bases[c]); ret = EINVAL; goto done; } talloc_zfree(ldn); /* Set the search base DN */ search_bases[i]->basedn = talloc_strdup(search_bases[i], split_bases[c]); if (!search_bases[i]->basedn) { ret = ENOMEM; goto done; } /* Set the search scope for this base DN */ if ((split_bases[c+1][0] == '\0') || strcasecmp(split_bases[c+1], "sub") == 0 || strcasecmp(split_bases[c+1], "subtree") == 0) { /* If unspecified, default to subtree */ search_bases[i]->scope = LDAP_SCOPE_SUBTREE; } else if (strcasecmp(split_bases[c+1], "one") == 0 || strcasecmp(split_bases[c+1], "onelevel") == 0) { search_bases[i]->scope = LDAP_SCOPE_ONELEVEL; } else if (strcasecmp(split_bases[c+1], "base") == 0) { search_bases[i]->scope = LDAP_SCOPE_BASE; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown search scope: [%s]\n", split_bases[c+1]); ret = EINVAL; goto done; } /* Get a specialized filter if provided */ if (split_bases[c+2][0] == '\0') { search_bases[i]->filter = NULL; } else { if (split_bases[c+2][0] != '(') { /* Filters need to be enclosed in parentheses * to be validated properly by ldb_parse_tree() */ filter = talloc_asprintf(tmp_ctx, "(%s)", split_bases[c+2]); } else { filter = talloc_strdup(tmp_ctx, split_bases[c+2]); } if (!filter) { ret = ENOMEM; goto done; } tree = ldb_parse_tree(tmp_ctx, filter); if(!tree) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid search filter: [%s]\n", filter); ret = EINVAL; goto done; } talloc_zfree(tree); search_bases[i]->filter = talloc_steal(search_bases[i], filter); } DEBUG(SSSDBG_CONF_SETTINGS, "Search base added: [%s][%s][%s][%s]\n", class_name, search_bases[i]->basedn, split_bases[c+1][0] ? split_bases[c+1] : "SUBTREE", search_bases[i]->filter ? search_bases[i]->filter : ""); i++; } search_bases[i] = NULL; } *_search_bases = talloc_steal(mem_ctx, search_bases); ret = EOK; done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_initgroups.c0000644000000000000000000000007312703456111022623 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.783794066 sssd-1.13.4/src/providers/ldap/sdap_async_initgroups.c0000644002412700241270000031577512703456111024315 0ustar00jhrozekjhrozek00000000000000/* SSSD Async LDAP Helper routines - initgroups operation Copyright (C) Simo Sorce - 2009 Copyright (C) 2010, Ralf Haferkamp , Novell Inc. Copyright (C) Jan Zeleny - 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ldap/sdap_users.h" /* ==Save-fake-group-list=====================================*/ errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_options *opts, char **groupnames, struct sysdb_attrs **ldap_groups, int ldap_groups_count) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; int i, mi, ai; const char *groupname; const char *original_dn; const char *uuid = NULL; char **missing; gid_t gid; int ret; errno_t sret; bool in_transaction = false; bool posix; time_t now; char *sid_str = NULL; bool use_id_mapping; bool need_filter; char *tmp_name; /* There are no groups in LDAP but we should add user to groups ?? */ if (ldap_groups_count == 0) return EOK; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; missing = talloc_array(tmp_ctx, char *, ldap_groups_count+1); if (!missing) { ret = ENOMEM; goto done; } mi = 0; for (i=0; groupnames[i]; i++) { tmp_name = sss_get_domain_name(tmp_ctx, groupnames[i], domain); if (tmp_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to format original name [%s]\n", groupnames[i]); ret = ENOMEM; goto done; } ret = sysdb_search_group_by_name(tmp_ctx, domain, tmp_name, NULL, &msg); if (ret == EOK) { continue; } else if (ret == ENOENT) { missing[mi] = talloc_steal(missing, tmp_name); DEBUG(SSSDBG_TRACE_LIBS, "Group #%d [%s][%s] is not cached, " \ "need to add a fake entry\n", i, groupnames[i], missing[mi]); mi++; continue; } else if (ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "search for group failed [%d]: %s\n", ret, strerror(ret)); goto done; } } missing[mi] = NULL; /* All groups are cached, nothing to do */ if (mi == 0) { ret = EOK; goto done; } use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx, domain->name, domain->domain_id); ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot start sysdb transaction [%d]: %s\n", ret, strerror(ret)); goto done; } in_transaction = true; now = time(NULL); for (i=0; missing[i]; i++) { /* The group is not in sysdb, need to add a fake entry */ for (ai=0; ai < ldap_groups_count; ai++) { ret = sdap_get_group_primary_name(tmp_ctx, opts, ldap_groups[ai], domain, &groupname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "The group has no name attribute\n"); goto done; } if (strcmp(groupname, missing[i]) == 0) { posix = true; ret = sdap_attrs_get_sid_str( tmp_ctx, opts->idmap_ctx, ldap_groups[ai], opts->group_map[SDAP_AT_GROUP_OBJECTSID].sys_name, &sid_str); if (ret != EOK && ret != ENOENT) goto done; if (use_id_mapping) { if (sid_str == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "No SID for group [%s] " \ "while id-mapping.\n", groupname); ret = EINVAL; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Mapping group [%s] objectSID to unix ID\n", groupname); DEBUG(SSSDBG_TRACE_INTERNAL, "Group [%s] has objectSID [%s]\n", groupname, sid_str); /* Convert the SID into a UNIX group ID */ ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &gid); if (ret == EOK) { DEBUG(SSSDBG_TRACE_INTERNAL, "Group [%s] has mapped gid [%lu]\n", groupname, (unsigned long)gid); } else { posix = false; gid = 0; DEBUG(SSSDBG_TRACE_INTERNAL, "Group [%s] cannot be mapped. " "Treating as a non-POSIX group\n", groupname); } } else { ret = sysdb_attrs_get_uint32_t(ldap_groups[ai], SYSDB_GIDNUM, &gid); if (ret == ENOENT || (ret == EOK && gid == 0)) { DEBUG(SSSDBG_TRACE_LIBS, "The group %s gid was %s\n", groupname, ret == ENOENT ? "missing" : "zero"); DEBUG(SSSDBG_TRACE_FUNC, "Marking group %s as non-posix and setting GID=0!\n", groupname); gid = 0; posix = false; } else if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "The GID attribute is malformed\n"); goto done; } } ret = sysdb_attrs_get_string(ldap_groups[ai], SYSDB_ORIG_DN, &original_dn); if (ret) { DEBUG(SSSDBG_FUNC_DATA, "The group has no original DN\n"); original_dn = NULL; } ret = sysdb_handle_original_uuid( opts->group_map[SDAP_AT_GROUP_UUID].def_name, ldap_groups[ai], opts->group_map[SDAP_AT_GROUP_UUID].sys_name, ldap_groups[ai], "uniqueIDstr"); if (ret != EOK) { DEBUG((ret == ENOENT) ? SSSDBG_TRACE_ALL : SSSDBG_MINOR_FAILURE, "Failed to retrieve UUID [%d][%s].\n", ret, sss_strerror(ret)); } ret = sysdb_attrs_get_string(ldap_groups[ai], "uniqueIDstr", &uuid); if (ret) { DEBUG(SSSDBG_FUNC_DATA, "The group has no UUID\n"); uuid = NULL; } ret = sdap_check_ad_group_type(domain, opts, ldap_groups[ai], groupname, &need_filter); if (ret != EOK) { goto done; } if (need_filter) { posix = false; gid = 0; } DEBUG(SSSDBG_TRACE_INTERNAL, "Adding fake group %s to sysdb\n", groupname); ret = sysdb_add_incomplete_group(domain, groupname, gid, original_dn, sid_str, uuid, posix, now); if (ret != EOK) { goto done; } break; } } if (ai == ldap_groups_count) { DEBUG(SSSDBG_OP_FAILURE, "Group %s not present in LDAP\n", missing[i]); ret = EINVAL; goto done; } } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_transaction_commit failed.\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } int sdap_initgr_common_store(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_options *opts, const char *name, enum sysdb_member_type type, char **sysdb_grouplist, struct sysdb_attrs **ldap_groups, int ldap_groups_count) { TALLOC_CTX *tmp_ctx; char **ldap_grouplist = NULL; char **add_groups; char **del_groups; int ret, tret; bool in_transaction = false; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; if (ldap_groups_count == 0) { /* No groups for this user in LDAP. * We need to ensure that there are no groups * in the sysdb either. */ ldap_grouplist = NULL; } else { ret = sysdb_attrs_primary_name_list( sysdb, tmp_ctx, ldap_groups, ldap_groups_count, opts->group_map[SDAP_AT_GROUP_NAME].name, &ldap_grouplist); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_primary_name_list failed [%d]: %s\n", ret, strerror(ret)); goto done; } } /* Find the differences between the sysdb and LDAP lists * Groups in the sysdb only must be removed. */ ret = diff_string_lists(tmp_ctx, ldap_grouplist, sysdb_grouplist, &add_groups, &del_groups, NULL); if (ret != EOK) goto done; ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; /* Add fake entries for any groups the user should be added as * member of but that are not cached in sysdb */ if (add_groups && add_groups[0]) { ret = sdap_add_incomplete_groups(sysdb, domain, opts, add_groups, ldap_groups, ldap_groups_count); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Adding incomplete users failed\n"); goto done; } } DEBUG(SSSDBG_TRACE_INTERNAL, "Updating memberships for %s\n", name); ret = sysdb_update_members(domain, name, type, (const char *const *) add_groups, (const char *const *) del_groups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Membership update failed [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { tret = sysdb_transaction_cancel(sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_zfree(tmp_ctx); return ret; } /* ==Initgr-call-(groups-a-user-is-member-of)-RFC2307===================== */ struct sdap_initgr_rfc2307_state { struct tevent_context *ev; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; struct sdap_options *opts; struct sdap_handle *sh; const char **attrs; const char *name; const char *base_filter; const char *orig_dn; char *filter; int timeout; struct sdap_op *op; struct sysdb_attrs **ldap_groups; size_t ldap_groups_count; size_t base_iter; struct sdap_search_base **search_bases; }; static errno_t sdap_initgr_rfc2307_next_base(struct tevent_req *req); static void sdap_initgr_rfc2307_process(struct tevent_req *subreq); struct tevent_req *sdap_initgr_rfc2307_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_handle *sh, const char *name) { struct tevent_req *req; struct sdap_initgr_rfc2307_state *state; const char **attr_filter; char *clean_name; errno_t ret; char *oc_list; req = tevent_req_create(memctx, &state, struct sdap_initgr_rfc2307_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->sysdb = sysdb; state->domain = domain; state->sh = sh; state->op = NULL; state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT); state->ldap_groups = NULL; state->ldap_groups_count = 0; state->base_iter = 0; state->search_bases = opts->sdom->group_search_bases; if (!state->search_bases) { DEBUG(SSSDBG_CRIT_FAILURE, "Initgroups lookup request without a group search base\n"); ret = EINVAL; goto done; } state->name = talloc_strdup(state, name); if (!state->name) { talloc_zfree(req); return NULL; } attr_filter = talloc_array(state, const char *, 2); if (!attr_filter) { talloc_free(req); return NULL; } attr_filter[0] = opts->group_map[SDAP_AT_GROUP_MEMBER].name; attr_filter[1] = NULL; ret = build_attrs_from_map(state, opts->group_map, SDAP_OPTS_GROUP, attr_filter, &state->attrs, NULL); if (ret != EOK) { talloc_free(req); return NULL; } ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { talloc_free(req); return NULL; } oc_list = sdap_make_oc_list(state, opts->group_map); if (oc_list == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n"); ret = ENOMEM; goto done; } state->base_filter = talloc_asprintf(state, "(&(%s=%s)(%s)(%s=*)(&(%s=*)(!(%s=0))))", opts->group_map[SDAP_AT_GROUP_MEMBER].name, clean_name, oc_list, opts->group_map[SDAP_AT_GROUP_NAME].name, opts->group_map[SDAP_AT_GROUP_GID].name, opts->group_map[SDAP_AT_GROUP_GID].name); if (!state->base_filter) { talloc_zfree(req); return NULL; } talloc_zfree(clean_name); ret = sdap_initgr_rfc2307_next_base(req); done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static errno_t sdap_initgr_rfc2307_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_initgr_rfc2307_state *state; state = tevent_req_data(req, struct sdap_initgr_rfc2307_state); talloc_zfree(state->filter); state->filter = sdap_combine_filters( state, state->base_filter, state->search_bases[state->base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for groups with base [%s]\n", state->search_bases[state->base_iter]->basedn); subreq = sdap_get_generic_send( state, state->ev, state->opts, state->sh, state->search_bases[state->base_iter]->basedn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->group_map, SDAP_OPTS_GROUP, state->timeout, true); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_initgr_rfc2307_process, req); return EOK; } static void sdap_initgr_rfc2307_process(struct tevent_req *subreq) { struct tevent_req *req; struct sdap_initgr_rfc2307_state *state; struct sysdb_attrs **ldap_groups; char **sysdb_grouplist = NULL; size_t count; int ret; int i; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_initgr_rfc2307_state); ret = sdap_get_generic_recv(subreq, state, &count, &ldap_groups); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } /* Add this batch of groups to the list */ if (count > 0) { state->ldap_groups = talloc_realloc(state, state->ldap_groups, struct sysdb_attrs *, state->ldap_groups_count + count + 1); if (!state->ldap_groups) { tevent_req_error(req, ENOMEM); return; } /* Copy the new groups into the list. */ for (i = 0; i < count; i++) { state->ldap_groups[state->ldap_groups_count + i] = talloc_steal(state->ldap_groups, ldap_groups[i]); } state->ldap_groups_count += count; state->ldap_groups[state->ldap_groups_count] = NULL; } state->base_iter++; /* Check for additional search bases, and iterate * through again. */ if (state->search_bases[state->base_iter] != NULL) { ret = sdap_initgr_rfc2307_next_base(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } /* Search for all groups for which this user is a member */ ret = get_sysdb_grouplist(state, state->sysdb, state->domain, state->name, &sysdb_grouplist); if (ret != EOK) { tevent_req_error(req, ret); return; } /* There are no nested groups here so we can just update the * memberships */ ret = sdap_initgr_common_store(state->sysdb, state->domain, state->opts, state->name, SYSDB_MEMBER_USER, sysdb_grouplist, state->ldap_groups, state->ldap_groups_count); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static int sdap_initgr_rfc2307_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==Common code for pure RFC2307bis and IPA/AD========================= */ static errno_t sdap_nested_groups_store(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_options *opts, struct sysdb_attrs **groups, unsigned long count) { errno_t ret, tret; TALLOC_CTX *tmp_ctx; char **groupnamelist = NULL; bool in_transaction = false; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; if (count > 0) { ret = sysdb_attrs_primary_name_list(sysdb, tmp_ctx, groups, count, opts->group_map[SDAP_AT_GROUP_NAME].name, &groupnamelist); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_attrs_primary_name_list failed [%d]: %s\n", ret, strerror(ret)); goto done; } } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; ret = sdap_add_incomplete_groups(sysdb, domain, opts, groupnamelist, groups, count); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Could not add incomplete groups [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { tret = sysdb_transaction_cancel(sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } struct membership_diff { struct membership_diff *prev; struct membership_diff *next; const char *name; char **add; char **del; }; static errno_t build_membership_diff(TALLOC_CTX *mem_ctx, const char *name, char **ldap_parent_names, char **sysdb_parent_names, struct membership_diff **_mdiff) { TALLOC_CTX *tmp_ctx; struct membership_diff *mdiff; errno_t ret; char **add_groups; char **del_groups; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } mdiff = talloc_zero(tmp_ctx, struct membership_diff); if (!mdiff) { ret = ENOMEM; goto done; } mdiff->name = talloc_strdup(mdiff, name); if (!mdiff->name) { ret = ENOMEM; goto done; } /* Find the differences between the sysdb and ldap lists * Groups in ldap only must be added to the sysdb; * groups in the sysdb only must be removed. */ ret = diff_string_lists(tmp_ctx, ldap_parent_names, sysdb_parent_names, &add_groups, &del_groups, NULL); if (ret != EOK) { goto done; } mdiff->add = talloc_steal(mdiff, add_groups); mdiff->del = talloc_steal(mdiff, del_groups); ret = EOK; *_mdiff = talloc_steal(mem_ctx, mdiff); done: talloc_free(tmp_ctx); return ret; } /* ==Initgr-call-(groups-a-user-is-member-of)-nested-groups=============== */ struct sdap_initgr_nested_state { struct tevent_context *ev; struct sysdb_ctx *sysdb; struct sdap_options *opts; struct sss_domain_info *dom; struct sdap_handle *sh; struct sysdb_attrs *user; const char *username; const char *orig_dn; const char **grp_attrs; struct ldb_message_element *memberof; char *filter; char **group_dns; int cur; struct sdap_op *op; struct sysdb_attrs **groups; int groups_cur; }; static errno_t sdap_initgr_nested_deref_search(struct tevent_req *req); static errno_t sdap_initgr_nested_noderef_search(struct tevent_req *req); static void sdap_initgr_nested_search(struct tevent_req *subreq); static void sdap_initgr_nested_store(struct tevent_req *req); static struct tevent_req *sdap_initgr_nested_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct sdap_handle *sh, struct sysdb_attrs *user, const char **grp_attrs) { struct tevent_req *req; struct sdap_initgr_nested_state *state; errno_t ret; int deref_threshold; req = tevent_req_create(memctx, &state, struct sdap_initgr_nested_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->sysdb = sysdb; state->dom = dom; state->sh = sh; state->grp_attrs = grp_attrs; state->user = user; state->op = NULL; ret = sdap_get_user_primary_name(memctx, opts, user, dom, &state->username); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "User entry had no username\n"); goto immediate; } ret = sysdb_attrs_get_el(state->user, SYSDB_MEMBEROF, &state->memberof); if (ret || !state->memberof || state->memberof->num_values == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "User entry lacks original memberof ?\n"); /* We can't find any groups for this user, so we'll * have to assume there aren't any. Just return * success here. */ ret = EOK; goto immediate; } state->groups = talloc_zero_array(state, struct sysdb_attrs *, state->memberof->num_values + 1);; if (!state->groups) { ret = ENOMEM; goto immediate; } state->groups_cur = 0; deref_threshold = dp_opt_get_int(state->opts->basic, SDAP_DEREF_THRESHOLD); if (sdap_has_deref_support(state->sh, state->opts) && deref_threshold < state->memberof->num_values) { ret = sysdb_attrs_get_string(user, SYSDB_ORIG_DN, &state->orig_dn); if (ret != EOK) goto immediate; ret = sdap_initgr_nested_deref_search(req); if (ret != EAGAIN) goto immediate; } else { ret = sdap_initgr_nested_noderef_search(req); if (ret != EAGAIN) goto immediate; } return req; immediate: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t sdap_initgr_nested_noderef_search(struct tevent_req *req) { int i; struct tevent_req *subreq; struct sdap_initgr_nested_state *state; char *oc_list; state = tevent_req_data(req, struct sdap_initgr_nested_state); state->group_dns = talloc_array(state, char *, state->memberof->num_values + 1); if (!state->group_dns) { return ENOMEM; } for (i = 0; i < state->memberof->num_values; i++) { state->group_dns[i] = talloc_strdup(state->group_dns, (char *)state->memberof->values[i].data); if (!state->group_dns[i]) { return ENOMEM; } } state->group_dns[i] = NULL; /* terminate */ state->cur = 0; oc_list = sdap_make_oc_list(state, state->opts->group_map); if (oc_list == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n"); return ENOMEM; } state->filter = talloc_asprintf(state, "(&(%s)(%s=*))", oc_list, state->opts->group_map[SDAP_AT_GROUP_NAME].name); if (!state->filter) { return ENOMEM; } subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, state->group_dns[state->cur], LDAP_SCOPE_BASE, state->filter, state->grp_attrs, state->opts->group_map, SDAP_OPTS_GROUP, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_initgr_nested_search, req); return EAGAIN; } static void sdap_initgr_nested_deref_done(struct tevent_req *subreq); static errno_t sdap_initgr_nested_deref_search(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_attr_map_info *maps; const int num_maps = 1; const char **sdap_attrs; errno_t ret; int timeout; struct sdap_initgr_nested_state *state; state = tevent_req_data(req, struct sdap_initgr_nested_state); maps = talloc_array(state, struct sdap_attr_map_info, num_maps+1); if (!maps) return ENOMEM; maps[0].map = state->opts->group_map; maps[0].num_attrs = SDAP_OPTS_GROUP; maps[1].map = NULL; ret = build_attrs_from_map(state, state->opts->group_map, SDAP_OPTS_GROUP, NULL, &sdap_attrs, NULL); if (ret != EOK) goto fail; timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT); subreq = sdap_deref_search_send(state, state->ev, state->opts, state->sh, state->orig_dn, state->opts->user_map[SDAP_AT_USER_MEMBEROF].name, sdap_attrs, num_maps, maps, timeout); if (!subreq) { ret = EIO; goto fail; } talloc_steal(subreq, sdap_attrs); talloc_steal(subreq, maps); tevent_req_set_callback(subreq, sdap_initgr_nested_deref_done, req); return EAGAIN; fail: talloc_free(sdap_attrs); talloc_free(maps); return ret; } static void sdap_initgr_nested_deref_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req; struct sdap_initgr_nested_state *state; size_t num_results; size_t i; struct sdap_deref_attrs **deref_result; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_initgr_nested_state); ret = sdap_deref_search_recv(subreq, state, &num_results, &deref_result); talloc_zfree(subreq); if (ret == ENOTSUP) { ret = sdap_initgr_nested_noderef_search(req); if (ret != EAGAIN) { if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } return; } else if (ret != EOK && ret != ENOENT) { tevent_req_error(req, ret); return; } else if (ret == ENOENT || deref_result == NULL) { /* Nothing could be dereferenced. Done. */ tevent_req_done(req); return; } for (i=0; i < num_results; i++) { state->groups[i] = talloc_steal(state->groups, deref_result[i]->attrs); } state->groups_cur = num_results; sdap_initgr_nested_store(req); } static void sdap_initgr_nested_search(struct tevent_req *subreq) { struct tevent_req *req; struct sdap_initgr_nested_state *state; struct sysdb_attrs **groups; size_t count; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_initgr_nested_state); ret = sdap_get_generic_recv(subreq, state, &count, &groups); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } if (count == 1) { state->groups[state->groups_cur] = talloc_steal(state->groups, groups[0]); state->groups_cur++; } else { DEBUG(SSSDBG_OP_FAILURE, "Search for group %s, returned %zu results. Skipping\n", state->group_dns[state->cur], count); } state->cur++; /* note that state->memberof->num_values is the count of original * memberOf which might not be only groups, but permissions, etc. * Use state->groups_cur for group index cap */ if (state->cur < state->memberof->num_values) { subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, state->group_dns[state->cur], LDAP_SCOPE_BASE, state->filter, state->grp_attrs, state->opts->group_map, SDAP_OPTS_GROUP, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_initgr_nested_search, req); } else { sdap_initgr_nested_store(req); } } static errno_t sdap_initgr_store_groups(struct sdap_initgr_nested_state *state); static errno_t sdap_initgr_store_group_memberships(struct sdap_initgr_nested_state *state); static errno_t sdap_initgr_store_user_memberships(struct sdap_initgr_nested_state *state); static void sdap_initgr_nested_store(struct tevent_req *req) { errno_t ret; struct sdap_initgr_nested_state *state; bool in_transaction = false; errno_t tret; state = tevent_req_data(req, struct sdap_initgr_nested_state); ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto fail; } in_transaction = true; /* save the groups if they are not already */ ret = sdap_initgr_store_groups(state); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not save groups [%d]: %s\n", ret, strerror(ret)); goto fail; } /* save the group memberships */ ret = sdap_initgr_store_group_memberships(state); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not save group memberships [%d]: %s\n", ret, strerror(ret)); goto fail; } /* save the user memberships */ ret = sdap_initgr_store_user_memberships(state); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not save user memberships [%d]: %s\n", ret, strerror(ret)); goto fail; } ret = sysdb_transaction_commit(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto fail; } in_transaction = false; tevent_req_done(req); return; fail: if (in_transaction) { tret = sysdb_transaction_cancel(state->sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } tevent_req_error(req, ret); return; } static errno_t sdap_initgr_store_groups(struct sdap_initgr_nested_state *state) { return sdap_nested_groups_store(state->sysdb, state->dom, state->opts, state->groups, state->groups_cur); } static errno_t sdap_initgr_nested_get_membership_diff(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sdap_options *opts, struct sss_domain_info *dom, struct sysdb_attrs *group, struct sysdb_attrs **all_groups, int groups_count, struct membership_diff **mdiff); static int sdap_initgr_nested_get_direct_parents(TALLOC_CTX *mem_ctx, struct sysdb_attrs *attrs, struct sysdb_attrs **groups, int ngroups, struct sysdb_attrs ***_direct_parents, int *_ndirect); static errno_t sdap_initgr_store_group_memberships(struct sdap_initgr_nested_state *state) { errno_t ret; int i, tret; TALLOC_CTX *tmp_ctx; struct membership_diff *miter = NULL; struct membership_diff *memberships = NULL; bool in_transaction = false; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; /* Compute the diffs first in order to keep the transaction as small * as possible */ for (i=0; i < state->groups_cur; i++) { ret = sdap_initgr_nested_get_membership_diff(tmp_ctx, state->sysdb, state->opts, state->dom, state->groups[i], state->groups, state->groups_cur, &miter); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not compute memberships for group %d [%d]: %s\n", i, ret, strerror(ret)); goto done; } DLIST_ADD(memberships, miter); } ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; DLIST_FOR_EACH(miter, memberships) { ret = sysdb_update_members(state->dom, miter->name, SYSDB_MEMBER_GROUP, (const char *const *) miter->add, (const char *const *) miter->del); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to update memberships\n"); goto done; } } ret = sysdb_transaction_commit(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { tret = sysdb_transaction_cancel(state->sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } static errno_t sdap_initgr_store_user_memberships(struct sdap_initgr_nested_state *state) { errno_t ret; int tret; const char *orig_dn; char **sysdb_parent_name_list = NULL; char **ldap_parent_name_list = NULL; int nparents; struct sysdb_attrs **ldap_parentlist; struct ldb_message_element *el; int i, mi; char **add_groups; char **del_groups; TALLOC_CTX *tmp_ctx; bool in_transaction = false; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } /* Get direct LDAP parents */ ret = sysdb_attrs_get_string(state->user, SYSDB_ORIG_DN, &orig_dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "The user has no original DN\n"); goto done; } ldap_parentlist = talloc_zero_array(tmp_ctx, struct sysdb_attrs *, state->groups_cur + 1); if (!ldap_parentlist) { ret = ENOMEM; goto done; } nparents = 0; for (i=0; i < state->groups_cur ; i++) { ret = sysdb_attrs_get_el(state->groups[i], SYSDB_MEMBER, &el); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "A group with no members during initgroups?\n"); goto done; } for (mi = 0; mi < el->num_values; mi++) { if (strcasecmp((const char *) el->values[mi].data, orig_dn) != 0) { continue; } ldap_parentlist[nparents] = state->groups[i]; nparents++; } } DEBUG(SSSDBG_TRACE_LIBS, "The user %s is a direct member of %d LDAP groups\n", state->username, nparents); if (nparents == 0) { ldap_parent_name_list = NULL; } else { ret = sysdb_attrs_primary_name_list(state->sysdb, tmp_ctx, ldap_parentlist, nparents, state->opts->group_map[SDAP_AT_GROUP_NAME].name, &ldap_parent_name_list); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_primary_name_list failed [%d]: %s\n", ret, strerror(ret)); goto done; } } ret = sysdb_get_direct_parents(tmp_ctx, state->dom, SYSDB_MEMBER_USER, state->username, &sysdb_parent_name_list); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get direct sysdb parents for %s: %d [%s]\n", state->username, ret, strerror(ret)); goto done; } ret = diff_string_lists(tmp_ctx, ldap_parent_name_list, sysdb_parent_name_list, &add_groups, &del_groups, NULL); if (ret != EOK) { goto done; } ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; DEBUG(SSSDBG_TRACE_INTERNAL, "Updating memberships for %s\n", state->username); ret = sysdb_update_members(state->dom, state->username, SYSDB_MEMBER_USER, (const char *const *) add_groups, (const char *const *) del_groups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not update sysdb memberships for %s: %d [%s]\n", state->username, ret, strerror(ret)); goto done; } ret = sysdb_transaction_commit(state->sysdb); if (ret != EOK) { goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { tret = sysdb_transaction_cancel(state->sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_zfree(tmp_ctx); return ret; } static errno_t sdap_initgr_nested_get_membership_diff(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sdap_options *opts, struct sss_domain_info *dom, struct sysdb_attrs *group, struct sysdb_attrs **all_groups, int groups_count, struct membership_diff **_mdiff) { errno_t ret; struct membership_diff *mdiff; const char *group_name; struct sysdb_attrs **ldap_parentlist; int parents_count; char **ldap_parent_names_list = NULL; char **sysdb_parents_names_list = NULL; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } /* Get direct sysdb parents */ ret = sdap_get_group_primary_name(tmp_ctx, opts, group, dom, &group_name); if (ret != EOK) { goto done; } ret = sysdb_get_direct_parents(tmp_ctx, dom, SYSDB_MEMBER_GROUP, group_name, &sysdb_parents_names_list); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get direct sysdb parents for %s: %d [%s]\n", group_name, ret, strerror(ret)); goto done; } /* For each group, filter only parents from full set */ ret = sdap_initgr_nested_get_direct_parents(tmp_ctx, group, all_groups, groups_count, &ldap_parentlist, &parents_count); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get parent groups for %s [%d]: %s\n", group_name, ret, strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_LIBS, "The group %s is a direct member of %d LDAP groups\n", group_name, parents_count); if (parents_count > 0) { ret = sysdb_attrs_primary_name_list(sysdb, tmp_ctx, ldap_parentlist, parents_count, opts->group_map[SDAP_AT_GROUP_NAME].name, &ldap_parent_names_list); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_primary_name_list failed [%d]: %s\n", ret, strerror(ret)); goto done; } } ret = build_membership_diff(tmp_ctx, group_name, ldap_parent_names_list, sysdb_parents_names_list, &mdiff); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not build membership diff for %s [%d]: %s\n", group_name, ret, strerror(ret)); goto done; } ret = EOK; *_mdiff = talloc_steal(mem_ctx, mdiff); done: talloc_free(tmp_ctx); return ret; } static int sdap_initgr_nested_get_direct_parents(TALLOC_CTX *mem_ctx, struct sysdb_attrs *attrs, struct sysdb_attrs **groups, int ngroups, struct sysdb_attrs ***_direct_parents, int *_ndirect) { TALLOC_CTX *tmp_ctx; struct ldb_message_element *member; int i, mi; int ret; const char *orig_dn; int ndirect; struct sysdb_attrs **direct_groups; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; direct_groups = talloc_zero_array(tmp_ctx, struct sysdb_attrs *, ngroups + 1); if (!direct_groups) { ret = ENOMEM; goto done; } ndirect = 0; ret = sysdb_attrs_get_string(attrs, SYSDB_ORIG_DN, &orig_dn); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Missing originalDN\n"); goto done; } DEBUG(SSSDBG_TRACE_ALL, "Looking up direct parents for group [%s]\n", orig_dn); /* FIXME - Filter only parents from full set to avoid searching * through all members of huge groups. That requires asking for memberOf * with the group LDAP search */ /* Filter only direct parents from the list of all groups */ for (i=0; i < ngroups; i++) { ret = sysdb_attrs_get_el(groups[i], SYSDB_MEMBER, &member); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "A group with no members during initgroups?\n"); continue; } for (mi = 0; mi < member->num_values; mi++) { if (strcasecmp((const char *) member->values[mi].data, orig_dn) != 0) { continue; } direct_groups[ndirect] = groups[i]; ndirect++; } } direct_groups[ndirect] = NULL; DEBUG(SSSDBG_TRACE_ALL, "The group [%s] has %d direct parents\n", orig_dn, ndirect); *_direct_parents = talloc_steal(mem_ctx, direct_groups); *_ndirect = ndirect; ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } static int sdap_initgr_nested_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==Initgr-call-(groups-a-user-is-member-of)-RFC2307-BIS================= */ struct sdap_initgr_rfc2307bis_state { struct tevent_context *ev; struct sysdb_ctx *sysdb; struct sdap_options *opts; struct sss_domain_info *dom; struct sdap_handle *sh; const char *name; char *base_filter; char *filter; const char **attrs; const char *orig_dn; int timeout; size_t base_iter; struct sdap_search_base **search_bases; struct sdap_op *op; hash_table_t *group_hash; size_t num_direct_parents; struct sysdb_attrs **direct_groups; }; struct sdap_nested_group { struct sysdb_attrs *group; struct sysdb_attrs **ldap_parents; size_t parents_count; }; static errno_t sdap_initgr_rfc2307bis_next_base(struct tevent_req *req); static void sdap_initgr_rfc2307bis_process(struct tevent_req *subreq); static void sdap_initgr_rfc2307bis_done(struct tevent_req *subreq); errno_t save_rfc2307bis_user_memberships( struct sdap_initgr_rfc2307bis_state *state); struct tevent_req *rfc2307bis_nested_groups_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct sdap_handle *sh, struct sdap_search_base **search_bases, struct sysdb_attrs **groups, size_t num_groups, hash_table_t *group_hash, size_t nesting); static errno_t rfc2307bis_nested_groups_recv(struct tevent_req *req); static struct tevent_req *sdap_initgr_rfc2307bis_send( TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_domain *sdom, struct sdap_handle *sh, const char *name, const char *orig_dn) { errno_t ret; struct tevent_req *req; struct sdap_initgr_rfc2307bis_state *state; const char **attr_filter; char *clean_orig_dn; bool use_id_mapping; char *oc_list; req = tevent_req_create(memctx, &state, struct sdap_initgr_rfc2307bis_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->sysdb = sdom->dom->sysdb; state->dom = sdom->dom; state->sh = sh; state->op = NULL; state->name = name; state->direct_groups = NULL; state->num_direct_parents = 0; state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT); state->base_iter = 0; state->search_bases = sdom->group_search_bases; state->orig_dn = orig_dn; if (!state->search_bases) { DEBUG(SSSDBG_CRIT_FAILURE, "Initgroups lookup request without a group search base\n"); ret = EINVAL; goto done; } ret = sss_hash_create(state, 32, &state->group_hash); if (ret != EOK) { talloc_free(req); return NULL; } attr_filter = talloc_array(state, const char *, 2); if (!attr_filter) { ret = ENOMEM; goto done; } attr_filter[0] = opts->group_map[SDAP_AT_GROUP_MEMBER].name; attr_filter[1] = NULL; ret = build_attrs_from_map(state, opts->group_map, SDAP_OPTS_GROUP, attr_filter, &state->attrs, NULL); if (ret != EOK) goto done; ret = sss_filter_sanitize(state, orig_dn, &clean_orig_dn); if (ret != EOK) goto done; use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( opts->idmap_ctx, sdom->dom->name, sdom->dom->domain_id); oc_list = sdap_make_oc_list(state, opts->group_map); if (oc_list == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n"); ret = ENOMEM; goto done; } state->base_filter = talloc_asprintf(state, "(&(%s=%s)(%s)(%s=*)", opts->group_map[SDAP_AT_GROUP_MEMBER].name, clean_orig_dn, oc_list, opts->group_map[SDAP_AT_GROUP_NAME].name); if (!state->base_filter) { ret = ENOMEM; goto done; } if (use_id_mapping) { /* When mapping IDs or looking for SIDs, we don't want to limit * ourselves to groups with a GID value. But there must be a SID to map * from. */ state->base_filter = talloc_asprintf_append(state->base_filter, "(%s=*))", opts->group_map[SDAP_AT_GROUP_OBJECTSID].name); } else { state->base_filter = talloc_asprintf_append(state->base_filter, ")"); } if (!state->base_filter) { talloc_zfree(req); return NULL; } talloc_zfree(clean_orig_dn); ret = sdap_initgr_rfc2307bis_next_base(req); done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static errno_t sdap_initgr_rfc2307bis_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_initgr_rfc2307bis_state *state; state = tevent_req_data(req, struct sdap_initgr_rfc2307bis_state); talloc_zfree(state->filter); state->filter = sdap_combine_filters(state, state->base_filter, state->search_bases[state->base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for parent groups for user [%s] with base [%s]\n", state->orig_dn, state->search_bases[state->base_iter]->basedn); subreq = sdap_get_generic_send( state, state->ev, state->opts, state->sh, state->search_bases[state->base_iter]->basedn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->group_map, SDAP_OPTS_GROUP, state->timeout, true); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_initgr_rfc2307bis_process, req); return EOK; } static void sdap_initgr_rfc2307bis_process(struct tevent_req *subreq) { struct tevent_req *req; struct sdap_initgr_rfc2307bis_state *state; struct sysdb_attrs **ldap_groups; size_t count; size_t i; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_initgr_rfc2307bis_state); ret = sdap_get_generic_recv(subreq, state, &count, &ldap_groups); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_LIBS, "Found %zu parent groups for user [%s]\n", count, state->name); /* Add this batch of groups to the list */ if (count > 0) { state->direct_groups = talloc_realloc(state, state->direct_groups, struct sysdb_attrs *, state->num_direct_parents + count + 1); if (!state->direct_groups) { tevent_req_error(req, ENOMEM); return; } /* Copy the new groups into the list. */ for (i = 0; i < count; i++) { state->direct_groups[state->num_direct_parents + i] = talloc_steal(state->direct_groups, ldap_groups[i]); } state->num_direct_parents += count; state->direct_groups[state->num_direct_parents] = NULL; } state->base_iter++; /* Check for additional search bases, and iterate * through again. */ if (state->search_bases[state->base_iter] != NULL) { ret = sdap_initgr_rfc2307bis_next_base(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } if (state->num_direct_parents == 0) { /* Start a transaction to look up the groups in the sysdb * and update them with LDAP data */ ret = save_rfc2307bis_user_memberships(state); if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } return; } subreq = rfc2307bis_nested_groups_send(state, state->ev, state->opts, state->sysdb, state->dom, state->sh, state->search_bases, state->direct_groups, state->num_direct_parents, state->group_hash, 0); if (!subreq) { tevent_req_error(req, EIO); return; } tevent_req_set_callback(subreq, sdap_initgr_rfc2307bis_done, req); } static errno_t save_rfc2307bis_groups(struct sdap_initgr_rfc2307bis_state *state); static errno_t save_rfc2307bis_group_memberships(struct sdap_initgr_rfc2307bis_state *state); static void sdap_initgr_rfc2307bis_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_initgr_rfc2307bis_state *state = tevent_req_data(req, struct sdap_initgr_rfc2307bis_state); bool in_transaction = false; errno_t tret; ret = rfc2307bis_nested_groups_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto fail; } in_transaction = true; /* save the groups if they are not cached */ ret = save_rfc2307bis_groups(state); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not save groups memberships [%d]\n", ret); goto fail; } /* save the group membership */ ret = save_rfc2307bis_group_memberships(state); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not save group memberships [%d]\n", ret); goto fail; } /* save the user memberships */ ret = save_rfc2307bis_user_memberships(state); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not save user memberships [%d]\n", ret); goto fail; } ret = sysdb_transaction_commit(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto fail; } in_transaction = false; tevent_req_done(req); return; fail: if (in_transaction) { tret = sysdb_transaction_cancel(state->sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } tevent_req_error(req, ret); return; } static int sdap_initgr_rfc2307bis_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct rfc2307bis_group_memberships_state { struct sysdb_ctx *sysdb; struct sdap_options *opts; struct sss_domain_info *dom; hash_table_t *group_hash; struct membership_diff *memberships; int ret; }; static errno_t save_rfc2307bis_groups(struct sdap_initgr_rfc2307bis_state *state) { struct sysdb_attrs **groups = NULL; unsigned long count; hash_value_t *values; int hret, i; errno_t ret; TALLOC_CTX *tmp_ctx; struct sdap_nested_group *gr; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; hret = hash_values(state->group_hash, &count, &values); if (hret != HASH_SUCCESS) { ret = EIO; goto done; } groups = talloc_array(tmp_ctx, struct sysdb_attrs *, count); if (!groups) { ret = ENOMEM; goto done; } for (i = 0; i < count; i++) { gr = talloc_get_type(values[i].ptr, struct sdap_nested_group); groups[i] = gr->group; } talloc_zfree(values); ret = sdap_nested_groups_store(state->sysdb, state->dom, state->opts, groups, count); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not save groups [%d]: %s\n", ret, strerror(ret)); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static bool rfc2307bis_group_memberships_build(hash_entry_t *item, void *user_data); static errno_t save_rfc2307bis_group_memberships(struct sdap_initgr_rfc2307bis_state *state) { errno_t ret, tret; int hret; TALLOC_CTX *tmp_ctx; struct rfc2307bis_group_memberships_state *membership_state; struct membership_diff *iter; struct membership_diff *iter_start; struct membership_diff *iter_tmp; bool in_transaction = false; int num_added; int i; int grp_count; char **add = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; membership_state = talloc_zero(tmp_ctx, struct rfc2307bis_group_memberships_state); if (!membership_state) { ret = ENOMEM; goto done; } membership_state->sysdb = state->sysdb; membership_state->dom = state->dom; membership_state->opts = state->opts; membership_state->group_hash = state->group_hash; hret = hash_iterate(state->group_hash, rfc2307bis_group_memberships_build, membership_state); if (hret != HASH_SUCCESS) { ret = membership_state->ret; goto done; } ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; iter_start = membership_state->memberships; DLIST_FOR_EACH(iter, membership_state->memberships) { /* Create a copy of iter->add array but do not include groups outside * nesting limit. This array must be NULL terminated. */ for (grp_count = 0; iter->add[grp_count]; grp_count++); add = talloc_zero_array(tmp_ctx, char *, grp_count + 1); if (add == NULL) { ret = ENOMEM; goto done; } num_added = 0; for (i = 0; i < grp_count; i++) { DLIST_FOR_EACH(iter_tmp, iter_start) { if (!strcmp(iter_tmp->name,iter->add[i])) { add[num_added] = iter->add[i]; num_added++; break; } } } if (num_added == 0) { add = NULL; } else { add[num_added] = NULL; } ret = sysdb_update_members(state->dom, iter->name, SYSDB_MEMBER_GROUP, (const char *const *) add, (const char *const *) iter->del); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to update memberships\n"); goto done; } } ret = sysdb_transaction_commit(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { tret = sysdb_transaction_cancel(state->sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } static bool rfc2307bis_group_memberships_build(hash_entry_t *item, void *user_data) { struct rfc2307bis_group_memberships_state *mstate = talloc_get_type( user_data, struct rfc2307bis_group_memberships_state); struct sdap_nested_group *group; char *group_name; TALLOC_CTX *tmp_ctx; errno_t ret; char **sysdb_parents_names_list; char **ldap_parents_names_list = NULL; struct membership_diff *mdiff; group_name = (char *) item->key.str; group = (struct sdap_nested_group *) item->value.ptr; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } ret = sysdb_get_direct_parents(tmp_ctx, mstate->dom, SYSDB_MEMBER_GROUP, group_name, &sysdb_parents_names_list); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get direct sysdb parents for %s: %d [%s]\n", group_name, ret, strerror(ret)); goto done; } if (group->parents_count > 0) { ret = sysdb_attrs_primary_name_list(mstate->sysdb, tmp_ctx, group->ldap_parents, group->parents_count, mstate->opts->group_map[SDAP_AT_GROUP_NAME].name, &ldap_parents_names_list); if (ret != EOK) { goto done; } } ret = build_membership_diff(tmp_ctx, group_name, ldap_parents_names_list, sysdb_parents_names_list, &mdiff); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not build membership diff for %s [%d]: %s\n", group_name, ret, strerror(ret)); goto done; } talloc_steal(mstate, mdiff); DLIST_ADD(mstate->memberships, mdiff); ret = EOK; done: talloc_free(tmp_ctx); mstate->ret = ret; return ret == EOK ? true : false; } errno_t save_rfc2307bis_user_memberships( struct sdap_initgr_rfc2307bis_state *state) { errno_t ret, tret; char **ldap_grouplist; char **sysdb_parent_name_list; char **add_groups; char **del_groups; bool in_transaction = false; size_t c; char *tmp_str; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if(!tmp_ctx) { return ENOMEM; } DEBUG(SSSDBG_TRACE_LIBS, "Save parent groups to sysdb\n"); ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto error; } in_transaction = true; ret = sysdb_get_direct_parents(tmp_ctx, state->dom, SYSDB_MEMBER_USER, state->name, &sysdb_parent_name_list); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get direct sysdb parents for %s: %d [%s]\n", state->name, ret, strerror(ret)); goto error; } if (state->num_direct_parents == 0) { ldap_grouplist = NULL; } else { ret = sysdb_attrs_primary_name_list( state->sysdb, tmp_ctx, state->direct_groups, state->num_direct_parents, state->opts->group_map[SDAP_AT_GROUP_NAME].name, &ldap_grouplist); if (ret != EOK) { goto error; } if (IS_SUBDOMAIN(state->dom)) { for (c = 0; ldap_grouplist[c] != NULL; c++) { tmp_str = sss_tc_fqname(ldap_grouplist, state->dom->names, state->dom, ldap_grouplist[c]); if (tmp_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_tc_fqname failed.\n"); ret = ENOMEM; goto error; } talloc_free(ldap_grouplist[c]); ldap_grouplist[c] = tmp_str; } } } /* Find the differences between the sysdb and ldap lists * Groups in ldap only must be added to the sysdb; * groups in the sysdb only must be removed. */ ret = diff_string_lists(tmp_ctx, ldap_grouplist, sysdb_parent_name_list, &add_groups, &del_groups, NULL); if (ret != EOK) { goto error; } DEBUG(SSSDBG_TRACE_INTERNAL, "Updating memberships for %s\n", state->name); ret = sysdb_update_members(state->dom, state->name, SYSDB_MEMBER_USER, (const char *const *)add_groups, (const char *const *)del_groups); if (ret != EOK) { goto error; } ret = sysdb_transaction_commit(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto error; } in_transaction = false; talloc_free(tmp_ctx); return EOK; error: if (in_transaction) { tret = sysdb_transaction_cancel(state->sysdb); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } struct sdap_rfc2307bis_nested_ctx { struct tevent_context *ev; struct sdap_options *opts; struct sysdb_ctx *sysdb; struct sss_domain_info *dom; struct sdap_handle *sh; int timeout; const char *base_filter; char *filter; const char *orig_dn; const char **attrs; struct sysdb_attrs **groups; size_t num_groups; size_t nesting_level; size_t group_iter; struct sdap_nested_group **processed_groups; hash_table_t *group_hash; const char *primary_name; struct sysdb_handle *handle; size_t base_iter; struct sdap_search_base **search_bases; }; static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req); struct tevent_req *rfc2307bis_nested_groups_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct sdap_handle *sh, struct sdap_search_base **search_bases, struct sysdb_attrs **groups, size_t num_groups, hash_table_t *group_hash, size_t nesting) { errno_t ret; struct tevent_req *req; struct sdap_rfc2307bis_nested_ctx *state; DEBUG(SSSDBG_TRACE_INTERNAL, "About to process %zu groups in nesting level %zu\n", num_groups, nesting); req = tevent_req_create(mem_ctx, &state, struct sdap_rfc2307bis_nested_ctx); if (!req) return NULL; if ((num_groups == 0) || (nesting > dp_opt_get_int(opts->basic, SDAP_NESTING_LEVEL))) { /* No parent groups to process or too deep*/ ret = EOK; goto done; } state->ev = ev; state->opts = opts; state->sysdb = sysdb; state->dom = dom; state->sh = sh; state->groups = groups; state->num_groups = num_groups; state->group_iter = 0; state->nesting_level = nesting; state->group_hash = group_hash; state->filter = NULL; state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT); state->base_iter = 0; state->search_bases = search_bases; if (!state->search_bases) { DEBUG(SSSDBG_CRIT_FAILURE, "Initgroups nested lookup request " "without a group search base\n"); ret = EINVAL; goto done; } state->processed_groups = talloc_array(state, struct sdap_nested_group *, state->num_groups); if (state->processed_groups == NULL) { ret = ENOMEM; goto done; } while (state->group_iter < state->num_groups) { ret = rfc2307bis_nested_groups_step(req); if (ret == EOK) { /* This group had already been looked up. Continue to * another group in the same level */ state->group_iter++; continue; } else { goto done; } } ret = EOK; done: if (ret == EOK) { /* All parent groups were already processed */ tevent_req_done(req); tevent_req_post(req, ev); } else if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } /* EAGAIN means a lookup is in progress */ return req; } static errno_t rfc2307bis_nested_groups_next_base(struct tevent_req *req); static void rfc2307bis_nested_groups_process(struct tevent_req *subreq); static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req) { errno_t ret; TALLOC_CTX *tmp_ctx = NULL; const char **attr_filter; char *clean_orig_dn; hash_key_t key; hash_value_t value; struct sdap_rfc2307bis_nested_ctx *state = tevent_req_data(req, struct sdap_rfc2307bis_nested_ctx); char *oc_list; tmp_ctx = talloc_new(state); if (!tmp_ctx) { ret = ENOMEM; goto done; } ret = sdap_get_group_primary_name(state, state->opts, state->groups[state->group_iter], state->dom, &state->primary_name); if (ret != EOK) { goto done; } key.type = HASH_KEY_STRING; key.str = talloc_strdup(state, state->primary_name); if (!key.str) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Processing group [%s]\n", state->primary_name); ret = hash_lookup(state->group_hash, &key, &value); if (ret == HASH_SUCCESS) { DEBUG(SSSDBG_TRACE_INTERNAL, "Group [%s] was already processed, " "taking a shortcut\n", state->primary_name); state->processed_groups[state->group_iter] = talloc_get_type(value.ptr, struct sdap_nested_group); talloc_free(key.str); ret = EOK; goto done; } /* Need to try to find parent groups for this group. */ state->processed_groups[state->group_iter] = talloc_zero(state->processed_groups, struct sdap_nested_group); if (!state->processed_groups[state->group_iter]) { ret = ENOMEM; goto done; } /* this steal doesn't change much now, but will be helpful later on * if we steal the whole processed_group on the hash table */ state->processed_groups[state->group_iter]->group = talloc_steal(state->processed_groups[state->group_iter], state->groups[state->group_iter]); /* Get any parent groups for this group */ ret = sysdb_attrs_get_string(state->groups[state->group_iter], SYSDB_ORIG_DN, &state->orig_dn); if (ret != EOK) { goto done; } attr_filter = talloc_array(state, const char *, 2); if (!attr_filter) { ret = ENOMEM; goto done; } attr_filter[0] = state->opts->group_map[SDAP_AT_GROUP_MEMBER].name; attr_filter[1] = NULL; ret = build_attrs_from_map(state, state->opts->group_map, SDAP_OPTS_GROUP, attr_filter, &state->attrs, NULL); if (ret != EOK) { goto done; } ret = sss_filter_sanitize(tmp_ctx, state->orig_dn, &clean_orig_dn); if (ret != EOK) { goto done; } oc_list = sdap_make_oc_list(state, state->opts->group_map); if (oc_list == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n"); ret = ENOMEM; goto done; } state->base_filter = talloc_asprintf( state, "(&(%s=%s)(%s)(%s=*))", state->opts->group_map[SDAP_AT_GROUP_MEMBER].name, clean_orig_dn, oc_list, state->opts->group_map[SDAP_AT_GROUP_NAME].name); if (!state->base_filter) { ret = ENOMEM; goto done; } ret = rfc2307bis_nested_groups_next_base(req); if (ret != EOK) goto done; /* Still processing parent groups */ ret = EAGAIN; done: talloc_free(tmp_ctx); return ret; } static errno_t rfc2307bis_nested_groups_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_rfc2307bis_nested_ctx *state; state = tevent_req_data(req, struct sdap_rfc2307bis_nested_ctx); talloc_zfree(state->filter); state->filter = sdap_combine_filters(state, state->base_filter, state->search_bases[state->base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for parent groups of group [%s] with base [%s]\n", state->orig_dn, state->search_bases[state->base_iter]->basedn); subreq = sdap_get_generic_send( state, state->ev, state->opts, state->sh, state->search_bases[state->base_iter]->basedn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->group_map, SDAP_OPTS_GROUP, state->timeout, true); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, rfc2307bis_nested_groups_process, req); return EOK; } static void rfc2307bis_nested_groups_iterate(struct tevent_req *req, struct sdap_rfc2307bis_nested_ctx *state) { errno_t ret; state->group_iter++; while (state->group_iter < state->num_groups) { ret = rfc2307bis_nested_groups_step(req); if (ret == EAGAIN) { /* Looking up parent groups.. */ return; } else if (ret != EOK) { tevent_req_error(req, ret); return; } /* EOK means this group has already been processed * in another nesting level */ state->group_iter++; } if (state->group_iter == state->num_groups) { /* All groups processed. Done. */ tevent_req_done(req); } } static void rfc2307bis_nested_groups_done(struct tevent_req *subreq); static void rfc2307bis_nested_groups_process(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_rfc2307bis_nested_ctx *state = tevent_req_data(req, struct sdap_rfc2307bis_nested_ctx); size_t count; size_t i; struct sysdb_attrs **ldap_groups; struct sdap_nested_group *ngr; hash_value_t value; hash_key_t key; int hret; ret = sdap_get_generic_recv(subreq, state, &count, &ldap_groups); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_LIBS, "Found %zu parent groups of [%s]\n", count, state->orig_dn); ngr = state->processed_groups[state->group_iter]; /* Add this batch of groups to the list */ if (count > 0) { ngr->ldap_parents = talloc_realloc(ngr, ngr->ldap_parents, struct sysdb_attrs *, ngr->parents_count + count + 1); if (!ngr->ldap_parents) { tevent_req_error(req, ENOMEM); return; } /* Copy the new groups into the list. * They're allocated on 'state' so we need to move them * onto ldap_parents so that the data won't disappear when * we finish this nesting level. */ for (i = 0; i < count; i++) { ngr->ldap_parents[ngr->parents_count + i] = talloc_steal(ngr->ldap_parents, ldap_groups[i]); } ngr->parents_count += count; ngr->ldap_parents[ngr->parents_count] = NULL; DEBUG(SSSDBG_TRACE_INTERNAL, "Total of %zu direct parents after this iteration\n", ngr->parents_count); } state->base_iter++; /* Check for additional search bases, and iterate * through again. */ if (state->search_bases[state->base_iter] != NULL) { ret = rfc2307bis_nested_groups_next_base(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } /* Reset the base iterator for future lookups */ state->base_iter = 0; /* Save the group into the hash table */ key.type = HASH_KEY_STRING; key.str = talloc_strdup(state, state->primary_name); if (!key.str) { tevent_req_error(req, ENOMEM); return; } /* Steal the nested group entry on the group_hash context so it can * outlive this request */ talloc_steal(state->group_hash, ngr); value.type = HASH_VALUE_PTR; value.ptr = ngr; hret = hash_enter(state->group_hash, &key, &value); if (hret != HASH_SUCCESS) { talloc_free(key.str); tevent_req_error(req, EIO); return; } talloc_free(key.str); if (ngr->parents_count == 0) { /* No parent groups for this group in LDAP * Move on to the next group */ rfc2307bis_nested_groups_iterate(req, state); return; } /* Otherwise, recurse into the groups */ subreq = rfc2307bis_nested_groups_send( state, state->ev, state->opts, state->sysdb, state->dom, state->sh, state->search_bases, ngr->ldap_parents, ngr->parents_count, state->group_hash, state->nesting_level+1); if (!subreq) { tevent_req_error(req, EIO); return; } tevent_req_set_callback(subreq, rfc2307bis_nested_groups_done, req); } static errno_t rfc2307bis_nested_groups_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void rfc2307bis_nested_groups_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_rfc2307bis_nested_ctx *state = tevent_req_data(req, struct sdap_rfc2307bis_nested_ctx); ret = rfc2307bis_nested_groups_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "rfc2307bis_nested failed [%d][%s]\n", ret, strerror(ret)); tevent_req_error(req, ret); return; } rfc2307bis_nested_groups_iterate(req, state); } /* ==Initgr-call-(groups-a-user-is-member-of)============================= */ struct sdap_get_initgr_state { struct tevent_context *ev; struct sysdb_ctx *sysdb; struct sdap_options *opts; struct sss_domain_info *dom; struct sdap_domain *sdom; struct sdap_handle *sh; struct sdap_id_ctx *id_ctx; struct sdap_id_conn_ctx *conn; const char *name; const char **grp_attrs; const char **user_attrs; char *user_base_filter; char *filter; int timeout; struct sysdb_attrs *orig_user; size_t user_base_iter; struct sdap_search_base **user_search_bases; bool use_id_mapping; }; static errno_t sdap_get_initgr_next_base(struct tevent_req *req); static void sdap_get_initgr_user(struct tevent_req *subreq); static void sdap_get_initgr_done(struct tevent_req *subreq); struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_domain *sdom, struct sdap_handle *sh, struct sdap_id_ctx *id_ctx, struct sdap_id_conn_ctx *conn, const char *name, int name_type, const char *extra_value, const char **grp_attrs) { struct tevent_req *req; struct sdap_get_initgr_state *state; int ret; char *clean_name; bool use_id_mapping; const char *search_attr; DEBUG(SSSDBG_TRACE_ALL, "Retrieving info for initgroups call\n"); req = tevent_req_create(memctx, &state, struct sdap_get_initgr_state); if (!req) return NULL; state->ev = ev; state->opts = id_ctx->opts; state->dom = sdom->dom; state->sysdb = sdom->dom->sysdb; state->sdom = sdom; state->sh = sh; state->id_ctx = id_ctx; state->conn = conn; state->name = name; state->grp_attrs = grp_attrs; state->orig_user = NULL; state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT); state->user_base_iter = 0; state->user_search_bases = sdom->user_search_bases; if (!state->user_search_bases) { DEBUG(SSSDBG_CRIT_FAILURE, "Initgroups lookup request without a user search base\n"); ret = EINVAL; goto done; } use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( id_ctx->opts->idmap_ctx, sdom->dom->name, sdom->dom->domain_id); ret = sss_filter_sanitize(state, name, &clean_name); if (ret != EOK) { talloc_zfree(req); return NULL; } if (extra_value && strcmp(extra_value, EXTRA_NAME_IS_UPN) == 0) { search_attr = state->opts->user_map[SDAP_AT_USER_PRINC].name; } else { switch (name_type) { case BE_FILTER_SECID: search_attr = state->opts->user_map[SDAP_AT_USER_OBJECTSID].name; break; case BE_FILTER_UUID: search_attr = state->opts->user_map[SDAP_AT_USER_UUID].name; break; default: search_attr = state->opts->user_map[SDAP_AT_USER_NAME].name; } } state->user_base_filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s)", search_attr, clean_name, state->opts->user_map[SDAP_OC_USER].name); if (!state->user_base_filter) { talloc_zfree(req); return NULL; } if (use_id_mapping) { /* When mapping IDs or looking for SIDs, we don't want to limit * ourselves to users with a UID value. But there must be a SID to map * from. */ state->user_base_filter = talloc_asprintf_append(state->user_base_filter, "(%s=*))", id_ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name); } else { /* When not ID-mapping, make sure there is a non-NULL UID */ state->user_base_filter = talloc_asprintf_append(state->user_base_filter, "(&(%s=*)(!(%s=0))))", id_ctx->opts->user_map[SDAP_AT_USER_UID].name, id_ctx->opts->user_map[SDAP_AT_USER_UID].name); } if (!state->user_base_filter) { talloc_zfree(req); return NULL; } ret = build_attrs_from_map(state, state->opts->user_map, state->opts->user_map_cnt, NULL, &state->user_attrs, NULL); if (ret) { talloc_zfree(req); return NULL; } state->use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( state->opts->idmap_ctx, state->dom->name, state->dom->domain_id); ret = sdap_get_initgr_next_base(req); done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static errno_t sdap_get_initgr_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_get_initgr_state *state; state = tevent_req_data(req, struct sdap_get_initgr_state); talloc_zfree(state->filter); state->filter = sdap_combine_filters(state, state->user_base_filter, state->user_search_bases[state->user_base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for users with base [%s]\n", state->user_search_bases[state->user_base_iter]->basedn); subreq = sdap_get_generic_send( state, state->ev, state->opts, state->sh, state->user_search_bases[state->user_base_iter]->basedn, state->user_search_bases[state->user_base_iter]->scope, state->filter, state->user_attrs, state->opts->user_map, state->opts->user_map_cnt, state->timeout, false); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_get_initgr_user, req); return EOK; } static void sdap_get_initgr_user(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_initgr_state *state = tevent_req_data(req, struct sdap_get_initgr_state); struct sysdb_attrs **usr_attrs; size_t count; int ret; errno_t sret; const char *orig_dn; const char *cname; bool in_transaction = false; DEBUG(SSSDBG_TRACE_ALL, "Receiving info for the user\n"); ret = sdap_get_generic_recv(subreq, state, &count, &usr_attrs); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } if (count == 0) { /* No users found in this search */ state->user_base_iter++; if (state->user_search_bases[state->user_base_iter]) { /* There are more search bases to try */ ret = sdap_get_initgr_next_base(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } /* fallback to fetch a local user if required */ if ((state->opts->schema_type == SDAP_SCHEMA_RFC2307) && (dp_opt_get_bool(state->opts->basic, SDAP_RFC2307_FALLBACK_TO_LOCAL_USERS) == true)) { ret = sdap_fallback_local_user(state, state->opts, state->name, -1, &usr_attrs); } else { ret = ENOENT; } if (ret != EOK) { tevent_req_error(req, ret); return; } } else if (count == 1) { state->orig_user = usr_attrs[0]; } else if (count != 1) { DEBUG(SSSDBG_OP_FAILURE, "Expected one user entry and got %zu\n", count); ret = sysdb_try_to_find_expected_dn(state->dom, "dc", usr_attrs, count, &state->orig_user); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "try_to_find_expected_dn failed. No matching DN found.\n"); tevent_req_error(req, EINVAL); return; } } ret = sysdb_transaction_start(state->sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto fail; } in_transaction = true; DEBUG(SSSDBG_TRACE_ALL, "Storing the user\n"); ret = sdap_save_user(state, state->opts, state->dom, state->orig_user, NULL, 0); if (ret) { goto fail; } DEBUG(SSSDBG_TRACE_ALL, "Commit change\n"); ret = sysdb_transaction_commit(state->sysdb); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto fail; } in_transaction = false; ret = sysdb_get_real_name(state, state->dom, state->name, &cname); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot canonicalize username\n"); tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_ALL, "Process user's groups\n"); switch (state->opts->schema_type) { case SDAP_SCHEMA_RFC2307: subreq = sdap_initgr_rfc2307_send(state, state->ev, state->opts, state->sysdb, state->dom, state->sh, cname); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_get_initgr_done, req); break; case SDAP_SCHEMA_RFC2307BIS: case SDAP_SCHEMA_AD: ret = sysdb_attrs_get_string(state->orig_user, SYSDB_ORIG_DN, &orig_dn); if (ret != EOK) { tevent_req_error(req, ret); return; } if (state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2003 && dp_opt_get_bool(state->opts->basic, SDAP_AD_USE_TOKENGROUPS)) { /* Take advantage of AD's tokenGroups mechanism to look up all * parent groups in a single request. */ subreq = sdap_ad_tokengroups_initgroups_send(state, state->ev, state->id_ctx, state->conn, state->opts, state->sysdb, state->dom, state->sh, cname, orig_dn, state->timeout, state->use_id_mapping); } else if (state->opts->support_matching_rule && dp_opt_get_bool(state->opts->basic, SDAP_AD_MATCHING_RULE_INITGROUPS)) { /* Take advantage of AD's extensibleMatch filter to look up * all parent groups in a single request. */ subreq = sdap_get_ad_match_rule_initgroups_send(state, state->ev, state->opts, state->sysdb, state->dom, state->sh, cname, orig_dn, state->timeout); } else { subreq = sdap_initgr_rfc2307bis_send( state, state->ev, state->opts, state->sdom, state->sh, cname, orig_dn); } if (!subreq) { tevent_req_error(req, ENOMEM); return; } talloc_steal(subreq, orig_dn); tevent_req_set_callback(subreq, sdap_get_initgr_done, req); break; case SDAP_SCHEMA_IPA_V1: subreq = sdap_initgr_nested_send(state, state->ev, state->opts, state->sysdb, state->dom, state->sh, state->orig_user, state->grp_attrs); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_get_initgr_done, req); return; default: tevent_req_error(req, EINVAL); return; } return; fail: if (in_transaction) { sret = sysdb_transaction_cancel(state->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } tevent_req_error(req, ret); } static void sdap_get_initgr_pgid(struct tevent_req *req); static void sdap_get_initgr_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_initgr_state *state = tevent_req_data(req, struct sdap_get_initgr_state); int ret; TALLOC_CTX *tmp_ctx; gid_t primary_gid; char *gid; char *sid_str; char *dom_sid_str; char *group_sid_str; struct sdap_options *opts = state->opts; struct ldb_message *msg; DEBUG(SSSDBG_TRACE_ALL, "Initgroups done\n"); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { tevent_req_error(req, ENOMEM); return; } switch (state->opts->schema_type) { case SDAP_SCHEMA_RFC2307: ret = sdap_initgr_rfc2307_recv(subreq); break; case SDAP_SCHEMA_RFC2307BIS: case SDAP_SCHEMA_AD: if (state->opts->dc_functional_level >= DS_BEHAVIOR_WIN2003 && dp_opt_get_bool(state->opts->basic, SDAP_AD_USE_TOKENGROUPS)) { ret = sdap_ad_tokengroups_initgroups_recv(subreq); } else if (state->opts->support_matching_rule && dp_opt_get_bool(state->opts->basic, SDAP_AD_MATCHING_RULE_INITGROUPS)) { ret = sdap_get_ad_match_rule_initgroups_recv(subreq); } else { ret = sdap_initgr_rfc2307bis_recv(subreq); } break; case SDAP_SCHEMA_IPA_V1: ret = sdap_initgr_nested_recv(subreq); break; default: ret = EINVAL; break; } talloc_zfree(subreq); if (ret) { DEBUG(SSSDBG_TRACE_ALL, "Error in initgroups: [%d][%s]\n", ret, strerror(ret)); goto done; } /* We also need to update the user's primary group, since * the user may not be an explicit member of that group */ if (state->use_id_mapping) { DEBUG(SSSDBG_TRACE_LIBS, "Mapping primary group to unix ID\n"); /* The primary group ID is just the RID part of the objectSID * of the group. Generate the GID by adding this to the domain * SID value. */ /* Get the user SID so we can extract the domain SID * from it. */ ret = sdap_attrs_get_sid_str( tmp_ctx, opts->idmap_ctx, state->orig_user, opts->user_map[SDAP_AT_USER_OBJECTSID].sys_name, &sid_str); if (ret != EOK) goto done; /* Get the domain SID from the user SID */ ret = sdap_idmap_get_dom_sid_from_object(tmp_ctx, sid_str, &dom_sid_str); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not parse domain SID from [%s]\n", sid_str); goto done; } ret = sysdb_attrs_get_uint32_t( state->orig_user, opts->user_map[SDAP_AT_USER_PRIMARY_GROUP].sys_name, &primary_gid); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "no primary group ID provided\n"); ret = EINVAL; goto done; } /* Add the RID to the end */ group_sid_str = talloc_asprintf(tmp_ctx, "%s-%lu", dom_sid_str, (unsigned long)primary_gid); if (!group_sid_str) { ret = ENOMEM; goto done; } /* Convert the SID into a UNIX group ID */ ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, group_sid_str, &primary_gid); if (ret != EOK) goto done; } else { ret = sysdb_attrs_get_uint32_t(state->orig_user, SYSDB_GIDNUM, &primary_gid); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Could not find user's primary GID\n"); goto done; } } ret = sysdb_search_group_by_gid(tmp_ctx, state->dom, primary_gid, NULL, &msg); if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Primary group already cached, nothing to do.\n"); ret = EOK; goto done; } else { gid = talloc_asprintf(state, "%lu", (unsigned long)primary_gid); if (gid == NULL) { ret = ENOMEM; goto done; } subreq = groups_get_send(req, state->ev, state->id_ctx, state->id_ctx->opts->sdom, state->conn, gid, BE_FILTER_IDNUM, BE_ATTR_ALL, false, false); if (!subreq) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_get_initgr_pgid, req); } talloc_free(tmp_ctx); return; done: talloc_free(tmp_ctx); if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } return; } static void sdap_get_initgr_pgid(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); errno_t ret; ret = groups_get_recv(subreq, NULL, NULL); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } int sdap_get_initgr_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static errno_t get_sysdb_grouplist_ex(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *name, char ***grouplist, bool get_dn) { errno_t ret; const char *attrs[2]; struct ldb_message *msg; TALLOC_CTX *tmp_ctx; struct ldb_message_element *groups; char **sysdb_grouplist = NULL; unsigned int i; attrs[0] = SYSDB_MEMBEROF; attrs[1] = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; ret = sysdb_search_user_by_name(tmp_ctx, domain, name, attrs, &msg); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error searching user [%s] by name: [%s]\n", name, strerror(ret)); goto done; } groups = ldb_msg_find_element(msg, SYSDB_MEMBEROF); if (!groups || groups->num_values == 0) { /* No groups for this user in sysdb currently */ sysdb_grouplist = NULL; } else { sysdb_grouplist = talloc_array(tmp_ctx, char *, groups->num_values+1); if (!sysdb_grouplist) { ret = ENOMEM; goto done; } if (get_dn) { /* Get distinguish name */ for (i=0; i < groups->num_values; i++) { sysdb_grouplist[i] = talloc_strdup(sysdb_grouplist, (const char *)groups->values[i].data); if (sysdb_grouplist[i] == NULL) { ret = ENOMEM; goto done; } } } else { /* Get a list of the groups by groupname only */ for (i=0; i < groups->num_values; i++) { ret = sysdb_group_dn_name(sysdb, sysdb_grouplist, (const char *)groups->values[i].data, &sysdb_grouplist[i]); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not determine group name from [%s]: [%s]\n", (const char *)groups->values[i].data, strerror(ret)); goto done; } } } sysdb_grouplist[groups->num_values] = NULL; } *grouplist = talloc_steal(mem_ctx, sysdb_grouplist); done: talloc_free(tmp_ctx); return ret; } errno_t get_sysdb_grouplist(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *name, char ***grouplist) { return get_sysdb_grouplist_ex(mem_ctx, sysdb, domain, name, grouplist, false); } errno_t get_sysdb_grouplist_dn(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *name, char ***grouplist) { return get_sysdb_grouplist_ex(mem_ctx, sysdb, domain, name, grouplist, true); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_private.h0000644000000000000000000000007312703456111022077 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.552793283 sssd-1.13.4/src/providers/ldap/sdap_async_private.h0000644002412700241270000001503312703456111023551 0ustar00jhrozekjhrozek00000000000000/* SSSD Async LDAP Helper routines Copyright (C) Simo Sorce This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SDAP_ASYNC_PRIVATE_H_ #define _SDAP_ASYNC_PRIVATE_H_ #include "config.h" #include "util/sss_krb5.h" #include "providers/ldap/sdap_async.h" struct dn_item { const char *dn; /* Parent netgroup containing this record */ struct sysdb_attrs *netgroup; char *cn; struct dn_item *next; struct dn_item *prev; }; bool is_dn(const char *str); errno_t update_dn_list(struct dn_item *dn_list, const size_t count, struct ldb_message **res, bool *all_resolved); struct sdap_handle *sdap_handle_create(TALLOC_CTX *memctx); void sdap_ldap_result(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *pvt); int setup_ldap_connection_callbacks(struct sdap_handle *sh, struct tevent_context *ev); int remove_ldap_connection_callbacks(struct sdap_handle *sh); int get_fd_from_ldap(LDAP *ldap, int *fd); errno_t sdap_set_connected(struct sdap_handle *sh, struct tevent_context *ev); errno_t sdap_call_conn_cb(const char *uri,int fd, struct sdap_handle *sh); int sdap_op_add(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_handle *sh, int msgid, sdap_op_callback_t *callback, void *data, int timeout, struct sdap_op **_op); struct tevent_req *sdap_get_rootdse_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh); int sdap_get_rootdse_recv(struct tevent_req *req, TALLOC_CTX *memctx, struct sysdb_attrs **rootdse); errno_t deref_string_to_val(const char *str, int *val); /* from sdap_child_helpers.c */ struct tevent_req *sdap_get_tgt_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *realm_str, const char *princ_str, const char *keytab_name, int32_t lifetime, int timeout); int sdap_get_tgt_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, int *result, krb5_error_code *kerr, char **ccname, time_t *expire_time_out); int sdap_save_users(TALLOC_CTX *memctx, struct sysdb_ctx *sysdb, struct sss_domain_info *dom, struct sdap_options *opts, struct sysdb_attrs **users, int num_users, char **_usn_value); int sdap_initgr_common_store(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_options *opts, const char *name, enum sysdb_member_type type, char **sysdb_grouplist, struct sysdb_attrs **ldap_groups, int ldap_groups_count); errno_t get_sysdb_grouplist(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *name, char ***grouplist); errno_t get_sysdb_grouplist_dn(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *name, char ***grouplist); /* from sdap_async_nested_groups.c */ struct tevent_req *sdap_nested_group_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_domain *sdom, struct sdap_options *opts, struct sdap_handle *sh, struct sysdb_attrs *group); errno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, unsigned long *_num_users, struct sysdb_attrs ***_users, unsigned long *_num_groups, struct sysdb_attrs ***_groups, hash_table_t **missing_external); struct tevent_req * sdap_nested_group_lookup_external_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sss_domain_info *group_dom, struct sdap_ext_member_ctx *ext_ctx, hash_table_t *missing_external); errno_t sdap_nested_group_lookup_external_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req); /* from sdap_async_initgroups.c */ errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct sdap_options *opts, char **groupnames, struct sysdb_attrs **ldap_groups, int ldap_groups_count); /* from sdap_ad_groups.c */ errno_t sdap_check_ad_group_type(struct sss_domain_info *dom, struct sdap_options *opts, struct sysdb_attrs *group_attrs, const char *group_name, bool *_need_filter); #endif /* _SDAP_ASYNC_PRIVATE_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_auth.c0000644000000000000000000000007412703456111020156 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.774794035 sssd-1.13.4/src/providers/ldap/ldap_auth.c0000644002412700241270000012307612703456111021636 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Backend Module Authors: Sumit Bose Copyright (C) 2008 Red Hat Copyright (C) 2010, rhafer@suse.de, Novell Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifdef WITH_MOZLDAP #define LDAP_OPT_SUCCESS LDAP_SUCCESS #define LDAP_TAG_EXOP_MODIFY_PASSWD_ID ((ber_tag_t) 0x80U) #define LDAP_TAG_EXOP_MODIFY_PASSWD_OLD ((ber_tag_t) 0x81U) #define LDAP_TAG_EXOP_MODIFY_PASSWD_NEW ((ber_tag_t) 0x82U) #endif #include "config.h" #include #include #include #include #include #include #include "util/util.h" #include "util/user_info_msg.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/ldap_auth.h" #include "providers/ldap/sdap_access.h" #define LDAP_PWEXPIRE_WARNING_TIME 0 static errno_t add_expired_warning(struct pam_data *pd, long exp_time) { int ret; uint32_t *data; if (exp_time < 0 || exp_time > UINT32_MAX) { DEBUG(SSSDBG_CRIT_FAILURE, "Time to expire out of range.\n"); return EINVAL; } data = talloc_array(pd, uint32_t, 2); if (data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); return ENOMEM; } data[0] = SSS_PAM_USER_INFO_EXPIRE_WARN; data[1] = (uint32_t) exp_time; ret = pam_add_response(pd, SSS_PAM_USER_INFO, 2 * sizeof(uint32_t), (uint8_t *) data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } return EOK; } static errno_t check_pwexpire_kerberos(const char *expire_date, time_t now, struct pam_data *pd, int pwd_exp_warning) { time_t expire_time; int expiration_warning; int ret = ERR_INTERNAL; ret = sss_utc_to_time_t(expire_date, "%Y%m%d%H%M%SZ", &expire_time); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_utc_to_time_t failed with %d:%s.\n", ret, sss_strerror(ret)); return ret; } DEBUG(SSSDBG_TRACE_ALL, "Time info: tzname[0] [%s] tzname[1] [%s] timezone [%ld] " "daylight [%d] now [%ld] expire_time [%ld].\n", tzname[0], tzname[1], timezone, daylight, now, expire_time); if (difftime(now, expire_time) > 0.0) { DEBUG(SSSDBG_CONF_SETTINGS, "Kerberos password expired.\n"); ret = ERR_PASSWORD_EXPIRED; } else { if (pwd_exp_warning >= 0) { expiration_warning = pwd_exp_warning; } else { expiration_warning = KERBEROS_PWEXPIRE_WARNING_TIME; } if (pd != NULL && (difftime(now + expiration_warning, expire_time) > 0.0 || expiration_warning == 0)) { ret = add_expired_warning(pd, (long) difftime(expire_time, now)); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "add_expired_warning failed.\n"); } } ret = EOK; } return ret; } static errno_t check_pwexpire_shadow(struct spwd *spwd, time_t now, struct pam_data *pd) { long today; long password_age; long exp; int ret; if (spwd->sp_lstchg <= 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Last change day is not set, new password needed.\n"); return ERR_PASSWORD_EXPIRED; } today = (long) (now / (60 * 60 *24)); password_age = today - spwd->sp_lstchg; if (password_age < 0) { DEBUG(SSSDBG_OP_FAILURE, "The last password change time is in the future!.\n"); return EOK; } if ((spwd->sp_expire != -1 && today > spwd->sp_expire) || (spwd->sp_max != -1 && spwd->sp_inact != -1 && password_age > spwd->sp_max + spwd->sp_inact)) { DEBUG(SSSDBG_CONF_SETTINGS, "Account expired.\n"); return ERR_ACCOUNT_EXPIRED; } if (spwd->sp_max != -1 && password_age > spwd->sp_max) { DEBUG(SSSDBG_CONF_SETTINGS, "Password expired.\n"); return ERR_PASSWORD_EXPIRED; } if (pd != NULL && spwd->sp_max != -1 && spwd->sp_warn != -1 && password_age > spwd->sp_max - spwd->sp_warn ) { /* add_expired_warning() expects time in seconds */ exp = (spwd->sp_max - password_age) * (60 * 60 * 24); if (exp == 0) { /* Seconds until next midnight */ exp = ((today + 1) * (60 * 60 * 24)) - now; } ret = add_expired_warning(pd, exp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "add_expired_warning failed.\n"); } } return EOK; } static errno_t check_pwexpire_ldap(struct pam_data *pd, struct sdap_ppolicy_data *ppolicy, int pwd_exp_warning) { int ret = EOK; if (ppolicy->grace >= 0 || ppolicy->expire > 0) { uint32_t *data; uint32_t *ptr; if (pwd_exp_warning < 0) { pwd_exp_warning = 0; } data = talloc_size(pd, 2* sizeof(uint32_t)); if (data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); return ENOMEM; } ptr = data; if (ppolicy->grace >= 0) { *ptr = SSS_PAM_USER_INFO_GRACE_LOGIN; ptr++; *ptr = ppolicy->grace; } else if (ppolicy->expire > 0) { if (pwd_exp_warning != 0 && ppolicy->expire > pwd_exp_warning) { /* do not warn */ goto done; } /* send warning */ *ptr = SSS_PAM_USER_INFO_EXPIRE_WARN; ptr++; *ptr = ppolicy->expire; } ret = pam_add_response(pd, SSS_PAM_USER_INFO, 2* sizeof(uint32_t), (uint8_t*)data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } } done: return ret; } errno_t check_pwexpire_policy(enum pwexpire pw_expire_type, void *pw_expire_data, struct pam_data *pd, int pwd_expiration_warning) { errno_t ret; switch (pw_expire_type) { case PWEXPIRE_SHADOW: ret = check_pwexpire_shadow(pw_expire_data, time(NULL), pd); break; case PWEXPIRE_KERBEROS: ret = check_pwexpire_kerberos(pw_expire_data, time(NULL), pd, pwd_expiration_warning); break; case PWEXPIRE_LDAP_PASSWORD_POLICY: ret = check_pwexpire_ldap(pd, pw_expire_data, pwd_expiration_warning); break; case PWEXPIRE_NONE: ret = EOK; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown password expiration type.\n"); ret = EINVAL; } return ret; } static errno_t find_password_expiration_attributes(TALLOC_CTX *mem_ctx, const struct ldb_message *msg, struct dp_option *opts, enum pwexpire *type, void **data) { const char *mark; const char *val; struct spwd *spwd; const char *pwd_policy; int ret; *type = PWEXPIRE_NONE; *data = NULL; pwd_policy = dp_opt_get_string(opts, SDAP_PWD_POLICY); if (pwd_policy == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing password policy.\n"); return EINVAL; } if (strcasecmp(pwd_policy, PWD_POL_OPT_NONE) == 0) { DEBUG(SSSDBG_TRACE_ALL, "No password policy requested.\n"); return EOK; } else if (strcasecmp(pwd_policy, PWD_POL_OPT_MIT) == 0) { mark = ldb_msg_find_attr_as_string(msg, SYSDB_KRBPW_LASTCHANGE, NULL); if (mark != NULL) { DEBUG(SSSDBG_TRACE_ALL, "Found Kerberos password expiration attributes.\n"); val = ldb_msg_find_attr_as_string(msg, SYSDB_KRBPW_EXPIRATION, NULL); if (val != NULL) { *data = talloc_strdup(mem_ctx, val); if (*data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); return ENOMEM; } *type = PWEXPIRE_KERBEROS; return EOK; } } else { DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos password expiration attributes found, " "but MIT Kerberos password policy was requested. " "Access will be denied.\n"); return EACCES; } } else if (strcasecmp(pwd_policy, PWD_POL_OPT_SHADOW) == 0) { mark = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL); if (mark != NULL) { DEBUG(SSSDBG_TRACE_ALL, "Found shadow password expiration attributes.\n"); spwd = talloc_zero(mem_ctx, struct spwd); if (spwd == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); return ENOMEM; } val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_LASTCHANGE, NULL); ret = string_to_shadowpw_days(val, &spwd->sp_lstchg); if (ret != EOK) goto shadow_fail; val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_MIN, NULL); ret = string_to_shadowpw_days(val, &spwd->sp_min); if (ret != EOK) goto shadow_fail; val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_MAX, NULL); ret = string_to_shadowpw_days(val, &spwd->sp_max); if (ret != EOK) goto shadow_fail; val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_WARNING, NULL); ret = string_to_shadowpw_days(val, &spwd->sp_warn); if (ret != EOK) goto shadow_fail; val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_INACTIVE, NULL); ret = string_to_shadowpw_days(val, &spwd->sp_inact); if (ret != EOK) goto shadow_fail; val = ldb_msg_find_attr_as_string(msg, SYSDB_SHADOWPW_EXPIRE, NULL); ret = string_to_shadowpw_days(val, &spwd->sp_expire); if (ret != EOK) goto shadow_fail; *data = spwd; *type = PWEXPIRE_SHADOW; return EOK; } else { DEBUG(SSSDBG_CRIT_FAILURE, "No shadow password attributes found, " "but shadow password policy was requested. " "Access will be denied.\n"); return EACCES; } } DEBUG(SSSDBG_TRACE_ALL, "No password expiration attributes found.\n"); return EOK; shadow_fail: talloc_free(spwd); return ret; } /* ==Get-User-DN========================================================== */ struct get_user_dn_state { const char *username; char *orig_dn; }; static void get_user_dn_done(struct tevent_req *subreq); static struct tevent_req *get_user_dn_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *domain, struct sdap_handle *sh, struct sdap_options *opts, const char *username) { struct tevent_req *req; struct tevent_req *subreq; struct get_user_dn_state *state; char *clean_name; char *filter; const char **attrs; errno_t ret; req = tevent_req_create(memctx, &state, struct get_user_dn_state); if (!req) return NULL; state->username = username; ret = sss_filter_sanitize(state, username, &clean_name); if (ret != EOK) { goto done; } filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))", opts->user_map[SDAP_AT_USER_NAME].name, clean_name, opts->user_map[SDAP_OC_USER].name); talloc_zfree(clean_name); if (filter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build the base filter\n"); ret = ENOMEM; goto done; } /* We're mostly interested in the DN anyway */ attrs = talloc_array(state, const char *, 3); if (attrs == NULL) { ret = ENOMEM; goto done; } attrs[0] = "objectclass"; attrs[1] = opts->user_map[SDAP_AT_USER_NAME].name; attrs[2] = NULL; subreq = sdap_search_user_send(state, ev, domain, opts, opts->sdom->user_search_bases, sh, attrs, filter, dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT), SDAP_LOOKUP_SINGLE); if (!subreq) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, get_user_dn_done, req); return req; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void get_user_dn_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct get_user_dn_state *state = tevent_req_data(req, struct get_user_dn_state); struct ldb_message_element *el; struct sysdb_attrs **users; size_t count; ret = sdap_search_user_recv(state, subreq, NULL, &users, &count); talloc_zfree(subreq); if (ret && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Failed to retrieve users\n"); tevent_req_error(req, ret); return; } if (count == 0) { DEBUG(SSSDBG_OP_FAILURE, "No such user\n"); tevent_req_error(req, ENOMEM); return; } else if (count > 1) { DEBUG(SSSDBG_OP_FAILURE, "Multiple users matched\n"); tevent_req_error(req, EIO); return; } /* exactly one user. Get the originalDN */ ret = sysdb_attrs_get_el_ext(users[0], SYSDB_ORIG_DN, false, &el); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "originalDN is not available for [%s].\n", state->username); tevent_req_error(req, ret); return; } state->orig_dn = talloc_strdup(state, (const char *) el->values[0].data); if (state->orig_dn == NULL) { tevent_req_error(req, ENOMEM); return; } DEBUG(SSSDBG_TRACE_INTERNAL, "Found originalDN [%s] for [%s]\n", state->orig_dn, state->username); tevent_req_done(req); } static int get_user_dn_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **orig_dn) { struct get_user_dn_state *state = tevent_req_data(req, struct get_user_dn_state); if (orig_dn) { *orig_dn = talloc_move(mem_ctx, &state->orig_dn); } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } int get_user_dn(TALLOC_CTX *memctx, struct sss_domain_info *domain, struct sdap_options *opts, const char *username, char **user_dn, enum pwexpire *user_pw_expire_type, void **user_pw_expire_data) { TALLOC_CTX *tmpctx; enum pwexpire pw_expire_type; void *pw_expire_data; struct ldb_result *res; const char **attrs; const char *dn; int ret; tmpctx = talloc_new(memctx); if (!tmpctx) { return ENOMEM; } attrs = talloc_array(tmpctx, const char *, 11); if (!attrs) { ret = ENOMEM; goto done; } attrs[0] = SYSDB_ORIG_DN; attrs[1] = SYSDB_SHADOWPW_LASTCHANGE; attrs[2] = SYSDB_SHADOWPW_MIN; attrs[3] = SYSDB_SHADOWPW_MAX; attrs[4] = SYSDB_SHADOWPW_WARNING; attrs[5] = SYSDB_SHADOWPW_INACTIVE; attrs[6] = SYSDB_SHADOWPW_EXPIRE; attrs[7] = SYSDB_KRBPW_LASTCHANGE; attrs[8] = SYSDB_KRBPW_EXPIRATION; attrs[9] = SYSDB_PWD_ATTRIBUTE; attrs[10] = NULL; ret = sysdb_get_user_attr(tmpctx, domain, username, attrs, &res); if (ret) { goto done; } switch (res->count) { case 0: /* No such user entry? Look it up */ ret = EAGAIN; break; case 1: dn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_ORIG_DN, NULL); if (dn == NULL) { /* The user entry has no original DN. This is the case when the ID * provider is not LDAP-based (proxy perhaps) */ ret = EAGAIN; break; } dn = talloc_strdup(tmpctx, dn); if (!dn) { ret = ENOMEM; break; } ret = find_password_expiration_attributes(tmpctx, res->msgs[0], opts->basic, &pw_expire_type, &pw_expire_data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "find_password_expiration_attributes failed.\n"); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "User search by name (%s) returned > 1 results!\n", username); ret = EFAULT; break; } done: if (ret == EOK) { *user_dn = talloc_strdup(memctx, dn); if (!*user_dn) { ret = ENOMEM; } /* pw_expire_data may be NULL */ *user_pw_expire_data = talloc_steal(memctx, pw_expire_data); *user_pw_expire_type = pw_expire_type; } talloc_zfree(tmpctx); return ret; } /* ==Authenticate-User==================================================== */ struct auth_state { struct tevent_context *ev; struct sdap_auth_ctx *ctx; const char *username; struct sss_auth_token *authtok; struct sdap_service *sdap_service; struct sdap_handle *sh; char *dn; enum pwexpire pw_expire_type; void *pw_expire_data; struct fo_server *srv; }; static struct tevent_req *auth_get_server(struct tevent_req *req); static void auth_get_dn_done(struct tevent_req *subreq); static void auth_do_bind(struct tevent_req *req); static void auth_resolve_done(struct tevent_req *subreq); static void auth_connect_done(struct tevent_req *subreq); static void auth_bind_user_done(struct tevent_req *subreq); static struct tevent_req *auth_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_auth_ctx *ctx, const char *username, struct sss_auth_token *authtok, bool try_chpass_service) { struct tevent_req *req; struct auth_state *state; req = tevent_req_create(memctx, &state, struct auth_state); if (!req) return NULL; /* The token must be a password token */ if (sss_authtok_get_type(authtok) != SSS_AUTHTOK_TYPE_PASSWORD) { tevent_req_error(req, ERR_AUTH_FAILED); return tevent_req_post(req, ev); } state->ev = ev; state->ctx = ctx; state->username = username; state->authtok = authtok; state->srv = NULL; if (try_chpass_service && ctx->chpass_service != NULL && ctx->chpass_service->name != NULL) { state->sdap_service = ctx->chpass_service; } else { state->sdap_service = ctx->service; } if (!auth_get_server(req)) goto fail; return req; fail: talloc_zfree(req); return NULL; } static struct tevent_req *auth_get_server(struct tevent_req *req) { struct tevent_req *next_req; struct auth_state *state = tevent_req_data(req, struct auth_state); /* NOTE: this call may cause service->uri to be refreshed * with a new valid server. Do not use service->uri before */ next_req = be_resolve_server_send(state, state->ev, state->ctx->be, state->sdap_service->name, state->srv == NULL ? true : false); if (!next_req) { DEBUG(SSSDBG_CRIT_FAILURE, "be_resolve_server_send failed.\n"); return NULL; } tevent_req_set_callback(next_req, auth_resolve_done, req); return next_req; } static void auth_resolve_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct auth_state *state = tevent_req_data(req, struct auth_state); int ret; bool use_tls; ret = be_resolve_server_recv(subreq, state, &state->srv); talloc_zfree(subreq); if (ret) { /* all servers have been tried and none * was found good, go offline */ tevent_req_error(req, ETIMEDOUT); return; } /* Determine whether we need to use TLS */ if (sdap_is_secure_uri(state->ctx->service->uri)) { DEBUG(SSSDBG_TRACE_INTERNAL, "[%s] is a secure channel. No need to run START_TLS\n", state->ctx->service->uri); use_tls = false; } else { /* Check for undocumented debugging feature to disable TLS * for authentication. This should never be used in production * for obvious reasons. */ use_tls = !dp_opt_get_bool(state->ctx->opts->basic, SDAP_DISABLE_AUTH_TLS); if (!use_tls) { sss_log(SSS_LOG_ALERT, "LDAP authentication being performed over " "insecure connection. This should be done " "for debugging purposes only."); } } subreq = sdap_connect_send(state, state->ev, state->ctx->opts, state->sdap_service->uri, state->sdap_service->sockaddr, use_tls); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, auth_connect_done, req); } static void auth_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct auth_state *state = tevent_req_data(req, struct auth_state); int ret; ret = sdap_connect_recv(subreq, state, &state->sh); talloc_zfree(subreq); if (ret) { if (state->srv) { /* mark this server as bad if connection failed */ be_fo_set_port_status(state->ctx->be, state->sdap_service->name, state->srv, PORT_NOT_WORKING); } if (auth_get_server(req) == NULL) { tevent_req_error(req, ENOMEM); } return; } else if (state->srv) { be_fo_set_port_status(state->ctx->be, state->sdap_service->name, state->srv, PORT_WORKING); } /* In case the ID provider is set to proxy, this might be the first * LDAP operation at all, so we need to set the connection status */ if (state->sh->connected == false) { ret = sdap_set_connected(state->sh, state->ev); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set connected status\n"); tevent_req_error(req, ret); return; } } ret = get_user_dn(state, state->ctx->be->domain, state->ctx->opts, state->username, &state->dn, &state->pw_expire_type, &state->pw_expire_data); if (ret == EOK) { /* All required user data was pre-cached during an identity lookup. * We can proceed with the bind */ auth_do_bind(req); return; } else if (ret == EAGAIN) { /* The cached user entry was missing the bind DN. Need to look * it up based on user name in order to perform the bind */ subreq = get_user_dn_send(req, state->ev, state->ctx->be->domain, state->sh, state->ctx->opts, state->username); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, auth_get_dn_done, req); return; } tevent_req_error(req, ret); return; } static void auth_get_dn_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct auth_state *state = tevent_req_data(req, struct auth_state); errno_t ret; ret = get_user_dn_recv(state, subreq, &state->dn); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ERR_ACCOUNT_UNKNOWN); return; } /* The DN was found with an LDAP lookup * We can proceed with the bind */ return auth_do_bind(req); } static void auth_do_bind(struct tevent_req *req) { struct auth_state *state = tevent_req_data(req, struct auth_state); struct tevent_req *subreq; subreq = sdap_auth_send(state, state->ev, state->sh, NULL, NULL, state->dn, state->authtok, dp_opt_get_int(state->ctx->opts->basic, SDAP_OPT_TIMEOUT)); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, auth_bind_user_done, req); } static void auth_bind_user_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct auth_state *state = tevent_req_data(req, struct auth_state); int ret; struct sdap_ppolicy_data *ppolicy = NULL; ret = sdap_auth_recv(subreq, state, &ppolicy); talloc_zfree(subreq); if (ppolicy != NULL) { DEBUG(SSSDBG_TRACE_ALL,"Found ppolicy data, " "assuming LDAP password policies are active.\n"); state->pw_expire_type = PWEXPIRE_LDAP_PASSWORD_POLICY; state->pw_expire_data = ppolicy; } switch (ret) { case EOK: break; case ETIMEDOUT: case ERR_NETWORK_IO: if (auth_get_server(req) == NULL) { tevent_req_error(req, ENOMEM); } return; default: tevent_req_error(req, ret); return; } tevent_req_done(req); } static errno_t auth_recv(struct tevent_req *req, TALLOC_CTX *memctx, struct sdap_handle **sh, char **dn, enum pwexpire *pw_expire_type, void **pw_expire_data) { struct auth_state *state = tevent_req_data(req, struct auth_state); if (sh != NULL) { *sh = talloc_steal(memctx, state->sh); if (*sh == NULL) return ENOMEM; } if (dn != NULL) { *dn = talloc_steal(memctx, state->dn); if (*dn == NULL) return ENOMEM; } if (pw_expire_data != NULL) { *pw_expire_data = talloc_steal(memctx, state->pw_expire_data); } *pw_expire_type = state->pw_expire_type; TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==Perform-Password-Change===================== */ struct sdap_pam_chpass_state { struct be_req *breq; struct pam_data *pd; const char *username; char *dn; struct sdap_handle *sh; struct sdap_auth_ctx *ctx; }; static void sdap_auth4chpass_done(struct tevent_req *req); static void sdap_pam_chpass_done(struct tevent_req *req); void sdap_pam_chpass_handler(struct be_req *breq) { struct be_ctx *be_ctx = be_req_get_be_ctx(breq); struct sdap_pam_chpass_state *state; struct sdap_auth_ctx *ctx; struct tevent_req *subreq; struct pam_data *pd; int dp_err = DP_ERR_FATAL; ctx = talloc_get_type(be_ctx->bet_info[BET_CHPASS].pvt_bet_data, struct sdap_auth_ctx); pd = talloc_get_type(be_req_get_data(breq), struct pam_data); if (be_is_offline(ctx->be)) { DEBUG(SSSDBG_CONF_SETTINGS, "Backend is marked offline, retry later!\n"); pd->pam_status = PAM_AUTHINFO_UNAVAIL; dp_err = DP_ERR_OFFLINE; goto done; } if ((pd->priv == 1) && (pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) && (sss_authtok_get_type(pd->authtok) != SSS_AUTHTOK_TYPE_PASSWORD)) { DEBUG(SSSDBG_CONF_SETTINGS, "Password reset by root is not supported.\n"); pd->pam_status = PAM_PERM_DENIED; dp_err = DP_ERR_OK; goto done; } DEBUG(SSSDBG_OP_FAILURE, "starting password change request for user [%s].\n", pd->user); pd->pam_status = PAM_SYSTEM_ERR; if (pd->cmd != SSS_PAM_CHAUTHTOK && pd->cmd != SSS_PAM_CHAUTHTOK_PRELIM) { DEBUG(SSSDBG_OP_FAILURE, "chpass target was called by wrong pam command.\n"); goto done; } state = talloc_zero(breq, struct sdap_pam_chpass_state); if (!state) goto done; state->breq = breq; state->pd = pd; state->username = pd->user; state->ctx = ctx; subreq = auth_send(breq, be_ctx->ev, ctx, state->username, pd->authtok, true); if (!subreq) goto done; tevent_req_set_callback(subreq, sdap_auth4chpass_done, state); return; done: be_req_terminate(breq, dp_err, pd->pam_status, NULL); } static void sdap_lastchange_done(struct tevent_req *req); static void sdap_auth4chpass_done(struct tevent_req *req) { struct sdap_pam_chpass_state *state = tevent_req_callback_data(req, struct sdap_pam_chpass_state); struct be_ctx *be_ctx = be_req_get_be_ctx(state->breq); struct tevent_req *subreq; enum pwexpire pw_expire_type; void *pw_expire_data; int dp_err = DP_ERR_FATAL; int ret; size_t msg_len; uint8_t *msg; ret = auth_recv(req, state, &state->sh, &state->dn, &pw_expire_type, &pw_expire_data); talloc_zfree(req); if ((ret == EOK || ret == ERR_PASSWORD_EXPIRED) && state->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) { DEBUG(SSSDBG_TRACE_ALL, "Initial authentication for change password operation " "successful.\n"); state->pd->pam_status = PAM_SUCCESS; dp_err = DP_ERR_OK; goto done; } if (ret == EOK) { switch (pw_expire_type) { case PWEXPIRE_SHADOW: ret = check_pwexpire_shadow(pw_expire_data, time(NULL), NULL); break; case PWEXPIRE_KERBEROS: ret = check_pwexpire_kerberos(pw_expire_data, time(NULL), NULL, be_ctx->domain->pwd_expiration_warning); if (ret == ERR_PASSWORD_EXPIRED) { DEBUG(SSSDBG_CRIT_FAILURE, "LDAP provider cannot change kerberos " "passwords.\n"); state->pd->pam_status = PAM_SYSTEM_ERR; goto done; } break; case PWEXPIRE_LDAP_PASSWORD_POLICY: case PWEXPIRE_NONE: break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown password expiration type.\n"); state->pd->pam_status = PAM_SYSTEM_ERR; goto done; } } switch (ret) { case EOK: case ERR_PASSWORD_EXPIRED: DEBUG(SSSDBG_TRACE_LIBS, "user [%s] successfully authenticated.\n", state->dn); if (pw_expire_type == PWEXPIRE_SHADOW) { /* TODO: implement async ldap modify request */ DEBUG(SSSDBG_CRIT_FAILURE, "Changing shadow password attributes not implemented.\n"); state->pd->pam_status = PAM_MODULE_UNKNOWN; goto done; } else { const char *password; const char *new_password; int timeout; ret = sss_authtok_get_password(state->pd->authtok, &password, NULL); if (ret) { state->pd->pam_status = PAM_SYSTEM_ERR; goto done; } ret = sss_authtok_get_password(state->pd->newauthtok, &new_password, NULL); if (ret) { state->pd->pam_status = PAM_SYSTEM_ERR; goto done; } timeout = dp_opt_get_int(state->ctx->opts->basic, SDAP_OPT_TIMEOUT); subreq = sdap_exop_modify_passwd_send(state, be_ctx->ev, state->sh, state->dn, password, new_password, timeout); if (!subreq) { DEBUG(SSSDBG_OP_FAILURE, "Failed to change password for %s\n", state->username); goto done; } tevent_req_set_callback(subreq, sdap_pam_chpass_done, state); return; } break; case ERR_AUTH_DENIED: case ERR_AUTH_FAILED: state->pd->pam_status = PAM_AUTH_ERR; ret = pack_user_info_chpass_error(state->pd, "Old password not accepted.", &msg_len, &msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_user_info_chpass_error failed.\n"); } else { ret = pam_add_response(state->pd, SSS_PAM_USER_INFO, msg_len, msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } } break; case ETIMEDOUT: case ERR_NETWORK_IO: state->pd->pam_status = PAM_AUTHINFO_UNAVAIL; be_mark_offline(be_ctx); dp_err = DP_ERR_OFFLINE; break; default: state->pd->pam_status = PAM_SYSTEM_ERR; } done: be_req_terminate(state->breq, dp_err, state->pd->pam_status, NULL); } static void sdap_pam_chpass_done(struct tevent_req *req) { struct sdap_pam_chpass_state *state = tevent_req_callback_data(req, struct sdap_pam_chpass_state); struct be_ctx *be_ctx = be_req_get_be_ctx(state->breq); int dp_err = DP_ERR_FATAL; int ret; char *user_error_message = NULL; char *lastchanged_name; struct tevent_req *subreq; size_t msg_len; uint8_t *msg; ret = sdap_exop_modify_passwd_recv(req, state, &user_error_message); talloc_zfree(req); switch (ret) { case EOK: state->pd->pam_status = PAM_SUCCESS; dp_err = DP_ERR_OK; break; case ERR_CHPASS_DENIED: state->pd->pam_status = PAM_NEW_AUTHTOK_REQD; break; case ERR_NETWORK_IO: state->pd->pam_status = PAM_AUTHTOK_ERR; break; default: state->pd->pam_status = PAM_SYSTEM_ERR; break; } if (state->pd->pam_status != PAM_SUCCESS && user_error_message != NULL) { ret = pack_user_info_chpass_error(state->pd, user_error_message, &msg_len, &msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_user_info_chpass_error failed.\n"); } else { ret = pam_add_response(state->pd, SSS_PAM_USER_INFO, msg_len, msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } } } if (state->pd->pam_status == PAM_SUCCESS && dp_opt_get_bool(state->ctx->opts->basic, SDAP_CHPASS_UPDATE_LAST_CHANGE)) { lastchanged_name = state->ctx->opts->user_map[SDAP_AT_SP_LSTCHG].name; subreq = sdap_modify_shadow_lastchange_send(state, be_ctx->ev, state->sh, state->dn, lastchanged_name); if (subreq == NULL) { state->pd->pam_status = PAM_SYSTEM_ERR; goto done; } tevent_req_set_callback(subreq, sdap_lastchange_done, state); return; } done: be_req_terminate(state->breq, dp_err, state->pd->pam_status, NULL); } static void sdap_lastchange_done(struct tevent_req *req) { struct sdap_pam_chpass_state *state = tevent_req_callback_data(req, struct sdap_pam_chpass_state); int dp_err = DP_ERR_FATAL; errno_t ret; ret = sdap_modify_shadow_lastchange_recv(req); if (ret != EOK) { state->pd->pam_status = PAM_SYSTEM_ERR; goto done; } dp_err = DP_ERR_OK; state->pd->pam_status = PAM_SUCCESS; done: be_req_terminate(state->breq, dp_err, state->pd->pam_status, NULL); } /* ==Perform-User-Authentication-and-Password-Caching===================== */ struct sdap_pam_auth_state { struct be_req *breq; struct pam_data *pd; }; static void sdap_pam_auth_done(struct tevent_req *req); void sdap_pam_auth_handler(struct be_req *breq) { struct be_ctx *be_ctx = be_req_get_be_ctx(breq); struct sdap_pam_auth_state *state; struct sdap_auth_ctx *ctx; struct tevent_req *subreq; struct pam_data *pd; int dp_err = DP_ERR_FATAL; ctx = talloc_get_type(be_ctx->bet_info[BET_AUTH].pvt_bet_data, struct sdap_auth_ctx); pd = talloc_get_type(be_req_get_data(breq), struct pam_data); if (be_is_offline(ctx->be)) { DEBUG(SSSDBG_CONF_SETTINGS, "Backend is marked offline, retry later!\n"); pd->pam_status = PAM_AUTHINFO_UNAVAIL; dp_err = DP_ERR_OFFLINE; goto done; } pd->pam_status = PAM_SYSTEM_ERR; switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: case SSS_PAM_CHAUTHTOK_PRELIM: state = talloc_zero(breq, struct sdap_pam_auth_state); if (!state) goto done; state->breq = breq; state->pd = pd; subreq = auth_send(breq, be_ctx->ev, ctx, pd->user, pd->authtok, pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM ? true : false); if (!subreq) goto done; tevent_req_set_callback(subreq, sdap_pam_auth_done, state); return; case SSS_PAM_CHAUTHTOK: break; case SSS_PAM_ACCT_MGMT: case SSS_PAM_SETCRED: case SSS_PAM_OPEN_SESSION: case SSS_PAM_CLOSE_SESSION: pd->pam_status = PAM_SUCCESS; dp_err = DP_ERR_OK; break; default: pd->pam_status = PAM_MODULE_UNKNOWN; dp_err = DP_ERR_OK; } done: be_req_terminate(breq, dp_err, pd->pam_status, NULL); } static void sdap_pam_auth_done(struct tevent_req *req) { struct sdap_pam_auth_state *state = tevent_req_callback_data(req, struct sdap_pam_auth_state); struct be_ctx *be_ctx = be_req_get_be_ctx(state->breq); enum pwexpire pw_expire_type; void *pw_expire_data; const char *password; int dp_err = DP_ERR_OK; int ret; ret = auth_recv(req, state, NULL, NULL, &pw_expire_type, &pw_expire_data); talloc_zfree(req); if (ret == EOK) { ret = check_pwexpire_policy(pw_expire_type, pw_expire_data, state->pd, be_ctx->domain->pwd_expiration_warning); if (ret == EINVAL) { /* Unknown password expiration type. */ state->pd->pam_status = PAM_SYSTEM_ERR; goto done; } } switch (ret) { case EOK: state->pd->pam_status = PAM_SUCCESS; break; case ERR_AUTH_DENIED: state->pd->pam_status = PAM_PERM_DENIED; break; case ERR_AUTH_FAILED: state->pd->pam_status = PAM_AUTH_ERR; break; case ETIMEDOUT: case ERR_NETWORK_IO: state->pd->pam_status = PAM_AUTHINFO_UNAVAIL; break; case ERR_ACCOUNT_EXPIRED: state->pd->pam_status = PAM_ACCT_EXPIRED; break; case ERR_PASSWORD_EXPIRED: state->pd->pam_status = PAM_NEW_AUTHTOK_REQD; break; case ERR_ACCOUNT_LOCKED: state->pd->account_locked = true; state->pd->pam_status = PAM_PERM_DENIED; break; default: state->pd->pam_status = PAM_SYSTEM_ERR; dp_err = DP_ERR_FATAL; } if (ret == ETIMEDOUT || ret == ERR_NETWORK_IO) { be_mark_offline(be_ctx); dp_err = DP_ERR_OFFLINE; goto done; } if (ret == EOK && be_ctx->domain->cache_credentials) { ret = sss_authtok_get_password(state->pd->authtok, &password, NULL); if (ret == EOK) { ret = sysdb_cache_password(be_ctx->domain, state->pd->user, password); } /* password caching failures are not fatal errors */ if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to cache password for %s\n", state->pd->user); } else { DEBUG(SSSDBG_CONF_SETTINGS, "Password successfully cached for %s\n", state->pd->user); } } done: be_req_terminate(state->breq, dp_err, state->pd->pam_status, NULL); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_sudo_refresh.c0000644000000000000000000000007412703456111021714 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.803794134 sssd-1.13.4/src/providers/ldap/sdap_sudo_refresh.c0000644002412700241270000003364012703456111023371 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "providers/dp_ptask.h" #include "providers/ldap/sdap_sudo.h" #include "providers/ldap/sdap_sudo_shared.h" #include "db/sysdb_sudo.h" struct sdap_sudo_full_refresh_state { struct sdap_sudo_ctx *sudo_ctx; struct sdap_id_ctx *id_ctx; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; int dp_error; }; static void sdap_sudo_full_refresh_done(struct tevent_req *subreq); struct tevent_req *sdap_sudo_full_refresh_send(TALLOC_CTX *mem_ctx, struct sdap_sudo_ctx *sudo_ctx) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx; struct sdap_sudo_full_refresh_state *state = NULL; char *search_filter = NULL; char *delete_filter = NULL; int ret; req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_full_refresh_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->sudo_ctx = sudo_ctx; state->id_ctx = id_ctx; state->sysdb = id_ctx->be->domain->sysdb; state->domain = id_ctx->be->domain; /* Download all rules from LDAP */ search_filter = talloc_asprintf(state, SDAP_SUDO_FILTER_CLASS, id_ctx->opts->sudorule_map[SDAP_OC_SUDORULE].name); if (search_filter == NULL) { ret = ENOMEM; goto immediately; } /* Remove all rules from cache */ delete_filter = talloc_asprintf(state, "(%s=%s)", SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC); if (delete_filter == NULL) { ret = ENOMEM; goto immediately; } DEBUG(SSSDBG_TRACE_FUNC, "Issuing a full refresh of sudo rules\n"); subreq = sdap_sudo_refresh_send(state, sudo_ctx, search_filter, delete_filter); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_sudo_full_refresh_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, id_ctx->be->ev); return req; } static void sdap_sudo_full_refresh_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; struct sdap_sudo_full_refresh_state *state = NULL; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_sudo_full_refresh_state); ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error, NULL); talloc_zfree(subreq); if (ret != EOK || state->dp_error != DP_ERR_OK) { goto done; } /* save the time in the sysdb */ ret = sysdb_sudo_set_last_full_refresh(state->domain, time(NULL)); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to save time of " "a successful full refresh\n"); /* this is only a minor error that does not affect the functionality, * therefore there is no need to report it with tevent_req_error() * which would cause problems in the consumers */ } DEBUG(SSSDBG_TRACE_FUNC, "Successful full refresh of sudo rules\n"); done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } int sdap_sudo_full_refresh_recv(struct tevent_req *req, int *dp_error) { struct sdap_sudo_full_refresh_state *state = NULL; state = tevent_req_data(req, struct sdap_sudo_full_refresh_state); TEVENT_REQ_RETURN_ON_ERROR(req); *dp_error = state->dp_error; return EOK; } struct sdap_sudo_smart_refresh_state { struct sdap_id_ctx *id_ctx; struct sysdb_ctx *sysdb; int dp_error; }; static void sdap_sudo_smart_refresh_done(struct tevent_req *subreq); struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx, struct sdap_sudo_ctx *sudo_ctx) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx; struct sdap_attr_map *map = id_ctx->opts->sudorule_map; struct sdap_server_opts *srv_opts = id_ctx->srv_opts; struct sdap_sudo_smart_refresh_state *state = NULL; char *search_filter = NULL; const char *usn; int ret; req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_smart_refresh_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->id_ctx = id_ctx; state->sysdb = id_ctx->be->domain->sysdb; /* Download all rules from LDAP that are newer than usn */ if (srv_opts == NULL || srv_opts->max_sudo_value == 0) { DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero.\n"); usn = "0"; search_filter = talloc_asprintf(state, "(objectclass=%s)", map[SDAP_OC_SUDORULE].name); } else { usn = srv_opts->max_sudo_value; search_filter = talloc_asprintf(state, "(&(objectclass=%s)(%s>=%s))", map[SDAP_OC_SUDORULE].name, map[SDAP_AT_SUDO_USN].name, usn); } if (search_filter == NULL) { ret = ENOMEM; goto immediately; } /* Do not remove any rules that are already in the sysdb * sysdb_filter = NULL; */ DEBUG(SSSDBG_TRACE_FUNC, "Issuing a smart refresh of sudo rules " "(USN >= %s)\n", usn); subreq = sdap_sudo_refresh_send(state, sudo_ctx, search_filter, NULL); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_sudo_smart_refresh_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, id_ctx->be->ev); return req; } static void sdap_sudo_smart_refresh_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; struct sdap_sudo_smart_refresh_state *state = NULL; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_sudo_smart_refresh_state); ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error, NULL); talloc_zfree(subreq); if (ret != EOK || state->dp_error != DP_ERR_OK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Successful smart refresh of sudo rules\n"); done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } int sdap_sudo_smart_refresh_recv(struct tevent_req *req, int *dp_error) { struct sdap_sudo_smart_refresh_state *state = NULL; state = tevent_req_data(req, struct sdap_sudo_smart_refresh_state); TEVENT_REQ_RETURN_ON_ERROR(req); *dp_error = state->dp_error; return EOK; } struct sdap_sudo_rules_refresh_state { struct sdap_id_ctx *id_ctx; size_t num_rules; int dp_error; bool deleted; }; static void sdap_sudo_rules_refresh_done(struct tevent_req *subreq); struct tevent_req *sdap_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx, struct sdap_sudo_ctx *sudo_ctx, char **rules) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_sudo_rules_refresh_state *state = NULL; struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx; struct sdap_options *opts = id_ctx->opts; TALLOC_CTX *tmp_ctx = NULL; char *search_filter = NULL; char *delete_filter = NULL; char *safe_rule = NULL; int ret; int i; if (rules == NULL) { return NULL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return NULL; } req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_rules_refresh_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } search_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */ delete_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */ /* Download only selected rules from LDAP */ /* Remove all selected rules from cache */ for (i = 0; rules[i] != NULL; i++) { ret = sss_filter_sanitize(tmp_ctx, rules[i], &safe_rule); if (ret != EOK) { ret = ENOMEM; goto immediately; } search_filter = talloc_asprintf_append_buffer(search_filter, "(%s=%s)", opts->sudorule_map[SDAP_AT_SUDO_NAME].name, safe_rule); if (search_filter == NULL) { ret = ENOMEM; goto immediately; } delete_filter = talloc_asprintf_append_buffer(delete_filter, "(%s=%s)", SYSDB_SUDO_CACHE_AT_CN, safe_rule); if (delete_filter == NULL) { ret = ENOMEM; goto immediately; } } state->id_ctx = sudo_ctx->id_ctx; state->num_rules = i; search_filter = talloc_asprintf(tmp_ctx, "(&"SDAP_SUDO_FILTER_CLASS"(|%s))", opts->sudorule_map[SDAP_OC_SUDORULE].name, search_filter); if (search_filter == NULL) { ret = ENOMEM; goto immediately; } delete_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(|%s))", SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC, delete_filter); if (delete_filter == NULL) { ret = ENOMEM; goto immediately; } subreq = sdap_sudo_refresh_send(req, sudo_ctx, search_filter, delete_filter); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_sudo_rules_refresh_done, req); ret = EOK; immediately: talloc_free(tmp_ctx); if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, id_ctx->be->ev); } return req; } static void sdap_sudo_rules_refresh_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; struct sdap_sudo_rules_refresh_state *state = NULL; size_t downloaded_rules_num; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_sudo_rules_refresh_state); ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error, &downloaded_rules_num); talloc_zfree(subreq); if (ret != EOK || state->dp_error != DP_ERR_OK) { goto done; } state->deleted = downloaded_rules_num != state->num_rules ? true : false; done: if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } int sdap_sudo_rules_refresh_recv(struct tevent_req *req, int *dp_error, bool *deleted) { struct sdap_sudo_rules_refresh_state *state = NULL; state = tevent_req_data(req, struct sdap_sudo_rules_refresh_state); TEVENT_REQ_RETURN_ON_ERROR(req); *dp_error = state->dp_error; *deleted = state->deleted; return EOK; } static struct tevent_req * sdap_sudo_ptask_full_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct sdap_sudo_ctx *sudo_ctx; sudo_ctx = talloc_get_type(pvt, struct sdap_sudo_ctx); return sdap_sudo_full_refresh_send(mem_ctx, sudo_ctx); } static errno_t sdap_sudo_ptask_full_refresh_recv(struct tevent_req *req) { int dp_error; return sdap_sudo_full_refresh_recv(req, &dp_error); } static struct tevent_req * sdap_sudo_ptask_smart_refresh_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct sdap_sudo_ctx *sudo_ctx; sudo_ctx = talloc_get_type(pvt, struct sdap_sudo_ctx); return sdap_sudo_smart_refresh_send(mem_ctx, sudo_ctx); } static errno_t sdap_sudo_ptask_smart_refresh_recv(struct tevent_req *req) { int dp_error; return sdap_sudo_smart_refresh_recv(req, &dp_error); } errno_t sdap_sudo_ptask_setup(struct be_ctx *be_ctx, struct sdap_sudo_ctx *sudo_ctx) { return sdap_sudo_ptask_setup_generic(be_ctx, sudo_ctx->id_ctx->opts->basic, sdap_sudo_ptask_full_refresh_send, sdap_sudo_ptask_full_refresh_recv, sdap_sudo_ptask_smart_refresh_send, sdap_sudo_ptask_smart_refresh_recv, sudo_ctx); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_sudo_shared.c0000644000000000000000000000007412703456111021524 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.804794137 sssd-1.13.4/src/providers/ldap/sdap_sudo_shared.c0000644002412700241270000001503512703456111023177 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "providers/dp_ptask.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_sudo_shared.h" #include "db/sysdb_sudo.h" errno_t sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx, struct dp_option *opts, be_ptask_send_t full_send_fn, be_ptask_recv_t full_recv_fn, be_ptask_send_t smart_send_fn, be_ptask_recv_t smart_recv_fn, void *pvt) { time_t smart; time_t full; time_t delay; time_t last_refresh; errno_t ret; smart = dp_opt_get_int(opts, SDAP_SUDO_SMART_REFRESH_INTERVAL); full = dp_opt_get_int(opts, SDAP_SUDO_FULL_REFRESH_INTERVAL); if (smart == 0 && full == 0) { /* We don't allow both types to be disabled. At least smart refresh * needs to be enabled. In this case smart refresh will catch up new * and modified rules and deleted rules are caught when expired. */ smart = opts[SDAP_SUDO_SMART_REFRESH_INTERVAL].def_val.number; DEBUG(SSSDBG_CONF_SETTINGS, "At least smart refresh needs to be " "enabled. Setting smart refresh interval to default value " "(%ld) seconds.\n", smart); } else if (full > 0 && full <= smart) { /* In this case it does not make any sense to run smart refresh. */ smart = 0; DEBUG(SSSDBG_CONF_SETTINGS, "Smart refresh interval has to be lower " "than full refresh interval. Periodical smart refresh will be " "disabled.\n"); } ret = sysdb_sudo_get_last_full_refresh(be_ctx->domain, &last_refresh); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to obtain time of last full " "refresh. Assuming none was performed so far.\n"); last_refresh = 0; } if (last_refresh == 0) { /* If this is the first startup, we need to kick off an refresh * immediately, to close a window where clients requesting sudo * information won't get an immediate reply with no entries */ delay = 0; } else { /* At least one update has previously run, so clients will get cached * data. We will delay the refresh so we don't slow down the startup * process if this is happening during system boot. */ delay = 10; } /* Full refresh. * * Disable when offline and run immediately when SSSD goes back online. * Since we have periodical online check we don't have to run this task * when offline. */ if (full > 0) { ret = be_ptask_create(be_ctx, be_ctx, full, delay, 0, 0, full, BE_PTASK_OFFLINE_DISABLE, 0, full_send_fn, full_recv_fn, pvt, "SUDO Full Refresh", NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup full refresh ptask " "[%d]: %s\n", ret, sss_strerror(ret)); return ret; } } /* Smart refresh. * * Disable when offline and reschedule normally when SSSD goes back online. * Since we have periodical online check we don't have to run this task * when offline. */ if (smart > 0) { ret = be_ptask_create(be_ctx, be_ctx, smart, delay + smart, smart, 0, smart, BE_PTASK_OFFLINE_DISABLE, 0, smart_send_fn, smart_recv_fn, pvt, "SUDO Smart Refresh", NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup smart refresh ptask " "[%d]: %s\n", ret, sss_strerror(ret)); return ret; } } return EOK; } static char * sdap_sudo_new_usn(TALLOC_CTX *mem_ctx, unsigned long usn, const char *leftover) { const char *str = leftover == NULL ? "" : leftover; char *newusn; /* We increment USN number so that we can later use simplify filter * (just usn >= last+1 instaed of usn >= last && usn != last). */ usn++; /* Convert back to string appending non-converted values since it * is an indicator that modifyTimestamp is used instead of entryUSN. * modifyTimestamp contains also timezone specification, usually Z. * We can't really handle any errors here so we just use what we got. */ newusn = talloc_asprintf(mem_ctx, "%lu%s", usn, str); if (newusn == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to change USN value (OOM)!\n"); return NULL; } return newusn; } void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, const char *usn) { unsigned long usn_number; char *newusn; char *endptr = NULL; errno_t ret; if (srv_opts == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "Bug: srv_opts is NULL\n"); return; } if (usn == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "Bug: usn is NULL\n"); return; } errno = 0; usn_number = strtoul(usn, &endptr, 10); if (errno != 0) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Unable to convert USN %s [%d]: %s\n", usn, ret, sss_strerror(ret)); return; } newusn = sdap_sudo_new_usn(srv_opts, usn_number, endptr); if (newusn == NULL) { return; } if (sysdb_compare_usn(newusn, srv_opts->max_sudo_value) > 0) { talloc_zfree(srv_opts->max_sudo_value); srv_opts->max_sudo_value = newusn; } else { talloc_zfree(newusn); } if (usn_number > srv_opts->last_usn) { srv_opts->last_usn = usn_number; } DEBUG(SSSDBG_FUNC_DATA, "SUDO higher USN value: [%s]\n", srv_opts->max_sudo_value); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_sudo.c0000644000000000000000000000007412703456111020176 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.805794141 sssd-1.13.4/src/providers/ldap/sdap_sudo.c0000644002412700241270000001361412703456111021652 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "providers/dp_backend.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_async.h" #include "providers/ldap/sdap_sudo.h" #include "db/sysdb_sudo.h" static void sdap_sudo_handler(struct be_req *breq); struct bet_ops sdap_sudo_ops = { .handler = sdap_sudo_handler, .finalize = NULL }; static void sdap_sudo_online_cb(void *pvt) { struct sdap_sudo_ctx *sudo_ctx; sudo_ctx = talloc_get_type(pvt, struct sdap_sudo_ctx); if (sudo_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "BUG: sudo_ctx is NULL\n"); return; } DEBUG(SSSDBG_TRACE_FUNC, "We are back online. SUDO host information will " "be renewed on next refresh.\n"); sudo_ctx->run_hostinfo = true; } int sdap_sudo_init(struct be_ctx *be_ctx, struct sdap_id_ctx *id_ctx, struct bet_ops **ops, void **pvt_data) { struct sdap_sudo_ctx *sudo_ctx = NULL; int ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing sudo LDAP back end\n"); sudo_ctx = talloc_zero(be_ctx, struct sdap_sudo_ctx); if (sudo_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc() failed\n"); return ENOMEM; } sudo_ctx->id_ctx = id_ctx; *ops = &sdap_sudo_ops; *pvt_data = sudo_ctx; ret = ldap_get_sudo_options(be_ctx->cdb, be_ctx->conf_path, id_ctx->opts, &sudo_ctx->use_host_filter, &sudo_ctx->include_regexp, &sudo_ctx->include_netgroups); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get SUDO options [%d]: %s\n", ret, strerror(ret)); goto done; } if (sudo_ctx->use_host_filter) { ret = be_add_online_cb(sudo_ctx, sudo_ctx->id_ctx->be, sdap_sudo_online_cb, sudo_ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to install online callback " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } /* Obtain hostinfo with the first refresh. */ sudo_ctx->run_hostinfo = true; } ret = sdap_sudo_ptask_setup(sudo_ctx->id_ctx->be, sudo_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to setup periodical refresh of sudo rules [%d]: %s\n", ret, strerror(ret)); /* periodical updates will not work, but specific-rule update * is no affected by this, therefore we don't have to fail here */ } ret = EOK; done: if (ret != EOK) { talloc_free(sudo_ctx); } return ret; } static void sdap_sudo_reply(struct tevent_req *req) { struct be_req *be_req = NULL; struct be_sudo_req *sudo_req = NULL; int dp_error; bool deleted; int ret; be_req = tevent_req_callback_data(req, struct be_req); sudo_req = talloc_get_type(be_req_get_data(be_req), struct be_sudo_req); switch (sudo_req->type) { case BE_REQ_SUDO_FULL: ret = sdap_sudo_full_refresh_recv(req, &dp_error); break; case BE_REQ_SUDO_RULES: ret = sdap_sudo_rules_refresh_recv(req, &dp_error, &deleted); if (ret == EOK && deleted == true) { ret = ENOENT; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n", sudo_req->type); dp_error = DP_ERR_FATAL; ret = ERR_INTERNAL; break; } talloc_zfree(req); sdap_handler_done(be_req, dp_error, ret, strerror(ret)); } static void sdap_sudo_handler(struct be_req *be_req) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct tevent_req *req = NULL; struct be_sudo_req *sudo_req = NULL; struct sdap_sudo_ctx *sudo_ctx = NULL; int ret = EOK; if (be_is_offline(be_ctx)) { sdap_handler_done(be_req, DP_ERR_OFFLINE, EAGAIN, "Offline"); return; } sudo_ctx = talloc_get_type(be_ctx->bet_info[BET_SUDO].pvt_bet_data, struct sdap_sudo_ctx); sudo_req = talloc_get_type(be_req_get_data(be_req), struct be_sudo_req); switch (sudo_req->type) { case BE_REQ_SUDO_FULL: DEBUG(SSSDBG_TRACE_FUNC, "Issuing a full refresh of sudo rules\n"); req = sdap_sudo_full_refresh_send(be_req, sudo_ctx); break; case BE_REQ_SUDO_RULES: DEBUG(SSSDBG_TRACE_FUNC, "Issuing a refresh of specific sudo rules\n"); req = sdap_sudo_rules_refresh_send(be_req, sudo_ctx, sudo_req->rules); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n", sudo_req->type); ret = EINVAL; goto fail; } if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send request: %d\n", sudo_req->type); ret = ENOMEM; goto fail; } tevent_req_set_callback(req, sdap_sudo_reply, be_req); return; fail: sdap_handler_done(be_req, DP_ERR_FATAL, ret, NULL); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_netgroups.c0000644000000000000000000000007312703456111022446 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.786794076 sssd-1.13.4/src/providers/ldap/sdap_async_netgroups.c0000644002412700241270000005772412703456111024135 0ustar00jhrozekjhrozek00000000000000/* SSSD Async LDAP Helper routines for netgroups Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/ldap_common.h" bool is_dn(const char *str) { int ret; LDAPDN dn; ret = ldap_str2dn(str, &dn, LDAP_DN_FORMAT_LDAPV3); ldap_dnfree(dn); return (ret == LDAP_SUCCESS ? true : false); } static errno_t sdap_save_netgroup(TALLOC_CTX *memctx, struct sss_domain_info *dom, struct sdap_options *opts, struct sysdb_attrs *attrs, char **_timestamp, time_t now) { struct ldb_message_element *el; struct sysdb_attrs *netgroup_attrs; const char *name = NULL; int ret; char *timestamp = NULL; char **missing = NULL; ret = sdap_get_netgroup_primary_name(memctx, opts, attrs, dom, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get netgroup name\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "Processing netgroup %s\n", name); netgroup_attrs = sysdb_new_attrs(memctx); if (!netgroup_attrs) { ret = ENOMEM; goto fail; } ret = sdap_attrs_add_string(attrs, SYSDB_ORIG_DN, "original DN", name, netgroup_attrs); if (ret != EOK) { goto fail; } ret = sysdb_attrs_get_el(attrs, opts->netgroup_map[SDAP_AT_NETGROUP_MODSTAMP].sys_name, &el); if (ret) { goto fail; } if (el->num_values == 0) { DEBUG(SSSDBG_TRACE_LIBS, "Original mod-Timestamp is not available for [%s].\n", name); } else { ret = sysdb_attrs_add_string(netgroup_attrs, opts->netgroup_map[SDAP_AT_NETGROUP_MODSTAMP].sys_name, (const char*)el->values[0].data); if (ret) { goto fail; } timestamp = talloc_strdup(memctx, (const char*)el->values[0].data); if (!timestamp) { ret = ENOMEM; goto fail; } } ret = sdap_attrs_add_list(attrs, opts->netgroup_map[SDAP_AT_NETGROUP_TRIPLE].sys_name, "netgroup triple", name, netgroup_attrs); if (ret != EOK) { goto fail; } ret = sdap_attrs_add_list(attrs, opts->netgroup_map[SDAP_AT_NETGROUP_MEMBER].sys_name, "original members", name, netgroup_attrs); if (ret != EOK) { goto fail; } ret = sdap_attrs_add_list(attrs, SYSDB_NETGROUP_MEMBER, "members", name, netgroup_attrs); if (ret != EOK) { goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "Storing info for netgroup %s\n", name); ret = sdap_save_all_names(name, attrs, dom, netgroup_attrs); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save netgroup names\n"); goto fail; } /* Make sure that any attributes we requested from LDAP that we * did not receive are also removed from the sysdb */ ret = list_missing_attrs(attrs, opts->netgroup_map, SDAP_OPTS_NETGROUP, attrs, &missing); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to list missing attributes\n"); goto fail; } ret = sysdb_add_netgroup(dom, name, NULL, netgroup_attrs, missing, dom->netgroup_timeout, now); if (ret) goto fail; if (_timestamp) { *_timestamp = timestamp; } return EOK; fail: DEBUG(SSSDBG_OP_FAILURE, "Failed to save netgroup %s\n", name); return ret; } errno_t update_dn_list(struct dn_item *dn_list, const size_t count, struct ldb_message **res, bool *all_resolved) { struct dn_item *dn_item; size_t c; const char *dn; const char *cn; bool not_resolved = false; *all_resolved = false; DLIST_FOR_EACH(dn_item, dn_list) { if (dn_item->cn != NULL) { continue; } for(c = 0; c < count; c++) { dn = ldb_msg_find_attr_as_string(res[c], SYSDB_ORIG_DN, NULL); if (dn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing original DN.\n"); return EINVAL; } if (strcmp(dn, dn_item->dn) == 0) { DEBUG(SSSDBG_TRACE_ALL, "Found matching entry for [%s].\n", dn_item->dn); cn = ldb_msg_find_attr_as_string(res[c], SYSDB_NAME, NULL); if (cn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing name.\n"); return EINVAL; } dn_item->cn = talloc_strdup(dn_item, cn); break; } } if (dn_item->cn == NULL) { not_resolved = true; } } *all_resolved = !not_resolved; return EOK; } struct netgr_translate_members_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; struct sysdb_attrs **netgroups; size_t count; struct dn_item *dn_list; struct dn_item *dn_item; struct dn_item *dn_idx; }; static errno_t netgr_translate_members_ldap_step(struct tevent_req *req); static void netgr_translate_members_ldap_done(struct tevent_req *subreq); struct tevent_req *netgr_translate_members_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, struct sss_domain_info *dom, struct sysdb_ctx *sysdb, const size_t count, struct sysdb_attrs **netgroups) { struct tevent_req *req; struct netgr_translate_members_state *state; size_t c; size_t mc; const char **member_list; size_t sysdb_count; int ret; struct ldb_message **sysdb_res; struct dn_item *dn_item; char *dn_filter; char *sysdb_filter; struct ldb_dn *netgr_basedn; bool all_resolved; const char *cn_attr[] = { SYSDB_NAME, SYSDB_ORIG_DN, NULL }; req = tevent_req_create(memctx, &state, struct netgr_translate_members_state); if (req == NULL) { return NULL; } state->ev = ev; state->opts = opts; state->sh = sh; state->netgroups = netgroups; state->count = count; state->dn_list = NULL; state->dn_item = NULL; state->dn_idx = NULL; for (c = 0; c < count; c++) { ret = sysdb_attrs_get_string_array(netgroups[c], SYSDB_ORIG_NETGROUP_MEMBER, state, &member_list); if (ret != EOK) { DEBUG(SSSDBG_TRACE_LIBS, "Missing netgroup members.\n"); continue; } for (mc = 0; member_list[mc] != NULL; mc++) { if (is_dn(member_list[mc])) { dn_item = talloc_zero(state, struct dn_item); if (dn_item == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); ret = ENOMEM; goto fail; } DEBUG(SSSDBG_TRACE_ALL, "Adding [%s] to DN list.\n", member_list[mc]); dn_item->netgroup = netgroups[c]; dn_item->dn = member_list[mc]; DLIST_ADD(state->dn_list, dn_item); } else { ret = sysdb_attrs_add_string(netgroups[c], SYSDB_NETGROUP_MEMBER, member_list[mc]); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n"); goto fail; } } } } if (state->dn_list == NULL) { DEBUG(SSSDBG_TRACE_ALL, "No DNs found among netgroup members.\n"); tevent_req_done(req); tevent_req_post(req, ev); return req; } dn_filter = talloc_strdup(state, "(|"); if (dn_filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM;; goto fail; } DLIST_FOR_EACH(dn_item, state->dn_list) { dn_filter = talloc_asprintf_append(dn_filter, "(%s=%s)", SYSDB_ORIG_DN, dn_item->dn); if (dn_filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n"); ret = ENOMEM; goto fail; } } dn_filter = talloc_asprintf_append(dn_filter, ")"); if (dn_filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n"); ret = ENOMEM; goto fail; } sysdb_filter = talloc_asprintf(state, "(&(%s)%s)", SYSDB_NC, dn_filter); if (sysdb_filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto fail; } netgr_basedn = sysdb_netgroup_base_dn(state, dom); if (netgr_basedn == NULL) { ret = ENOMEM; goto fail; } ret = sysdb_search_entry(state, sysdb, netgr_basedn, LDB_SCOPE_BASE, sysdb_filter, cn_attr, &sysdb_count, &sysdb_res); talloc_zfree(netgr_basedn); talloc_zfree(sysdb_filter); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_search_entry failed.\n"); goto fail; } if (ret == EOK) { ret = update_dn_list(state->dn_list, sysdb_count, sysdb_res, &all_resolved); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "update_dn_list failed.\n"); goto fail; } if (all_resolved) { DLIST_FOR_EACH(dn_item, state->dn_list) { ret = sysdb_attrs_add_string(dn_item->netgroup, SYSDB_NETGROUP_MEMBER, dn_item->cn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n"); goto fail; } } tevent_req_done(req); tevent_req_post(req, ev); return req; } } state->dn_idx = state->dn_list; ret = netgr_translate_members_ldap_step(req); if (ret != EOK && ret != EAGAIN) { DEBUG(SSSDBG_CRIT_FAILURE, "netgr_translate_members_ldap_step failed.\n"); goto fail; } if (ret == EOK) { tevent_req_done(req); tevent_req_post(req, ev); } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } /* netgr_translate_members_ldap_step() returns * EOK: if everthing is translated, the caller can call tevent_req_done * EAGAIN: if there are still members waiting to be translated, the caller * should return to the mainloop * Exyz: every other return code indicates an error and tevent_req_error * should be called */ static errno_t netgr_translate_members_ldap_step(struct tevent_req *req) { struct netgr_translate_members_state *state = tevent_req_data(req, struct netgr_translate_members_state); const char **cn_attr; char *filter = NULL; struct tevent_req *subreq; int ret; DLIST_FOR_EACH(state->dn_item, state->dn_idx) { if (state->dn_item->cn == NULL) { break; } } if (state->dn_item == NULL) { DLIST_FOR_EACH(state->dn_item, state->dn_list) { ret = sysdb_attrs_add_string(state->dn_item->netgroup, SYSDB_NETGROUP_MEMBER, state->dn_item->cn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n"); tevent_req_error(req, ret); return ret; } } return EOK; } if (!sss_ldap_dn_in_search_bases(state, state->dn_item->dn, state->opts->sdom->netgroup_search_bases, &filter)) { /* not in search base, skip it */ state->dn_idx = state->dn_item->next; DLIST_REMOVE(state->dn_list, state->dn_item); return netgr_translate_members_ldap_step(req); } cn_attr = talloc_array(state, const char *, 3); if (cn_attr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array failed.\n"); return ENOMEM; } cn_attr[0] = state->opts->netgroup_map[SDAP_AT_NETGROUP_NAME].name; cn_attr[1] = "objectclass"; cn_attr[2] = NULL; DEBUG(SSSDBG_TRACE_ALL, "LDAP base search for [%s].\n", state->dn_item->dn); subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, state->dn_item->dn, LDAP_SCOPE_BASE, filter, cn_attr, state->opts->netgroup_map, SDAP_OPTS_NETGROUP, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_get_generic_send failed.\n"); return ENOMEM; } talloc_steal(subreq, cn_attr); tevent_req_set_callback(subreq, netgr_translate_members_ldap_done, req); return EAGAIN; } static void netgr_translate_members_ldap_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct netgr_translate_members_state *state = tevent_req_data(req, struct netgr_translate_members_state); int ret; size_t count; struct sysdb_attrs **netgroups; const char *str; ret = sdap_get_generic_recv(subreq, state, &count, &netgroups); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_get_generic request failed.\n"); goto fail; } switch (count) { case 0: DEBUG(SSSDBG_FATAL_FAILURE, "sdap_get_generic_recv found no entry for [%s].\n", state->dn_item->dn); break; case 1: ret = sysdb_attrs_get_string(netgroups[0], SYSDB_NAME, &str); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n"); break; } state->dn_item->cn = talloc_strdup(state->dn_item, str); if (state->dn_item->cn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected number of results [%zu] for base search.\n", count); } if (state->dn_item->cn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to resolve netgroup name for DN [%s], using DN.\n", state->dn_item->dn); state->dn_item->cn = talloc_strdup(state->dn_item, state->dn_item->dn); } state->dn_idx = state->dn_item->next; ret = netgr_translate_members_ldap_step(req); if (ret != EOK && ret != EAGAIN) { DEBUG(SSSDBG_CRIT_FAILURE, "netgr_translate_members_ldap_step failed.\n"); goto fail; } if (ret == EOK) { tevent_req_done(req); } return; fail: tevent_req_error(req, ret); return; } static errno_t netgroup_translate_ldap_members_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *count, struct sysdb_attrs ***netgroups) { struct netgr_translate_members_state *state = tevent_req_data(req, struct netgr_translate_members_state); TEVENT_REQ_RETURN_ON_ERROR(req); *count = state->count; *netgroups = talloc_steal(mem_ctx, state->netgroups); return EOK; } /* ==Search-Netgroups-with-filter============================================ */ struct sdap_get_netgroups_state { struct tevent_context *ev; struct sdap_options *opts; struct sdap_handle *sh; struct sss_domain_info *dom; struct sysdb_ctx *sysdb; const char **attrs; const char *base_filter; char *filter; int timeout; char *higher_timestamp; struct sysdb_attrs **netgroups; size_t count; size_t base_iter; struct sdap_search_base **search_bases; }; static errno_t sdap_get_netgroups_next_base(struct tevent_req *req); static void sdap_get_netgroups_process(struct tevent_req *subreq); static void netgr_translate_members_done(struct tevent_req *subreq); struct tevent_req *sdap_get_netgroups_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, struct sysdb_ctx *sysdb, struct sdap_options *opts, struct sdap_search_base **search_bases, struct sdap_handle *sh, const char **attrs, const char *filter, int timeout) { errno_t ret; struct tevent_req *req; struct sdap_get_netgroups_state *state; req = tevent_req_create(memctx, &state, struct sdap_get_netgroups_state); if (!req) return NULL; state->ev = ev; state->opts = opts; state->dom = dom; state->sh = sh; state->sysdb = sysdb; state->attrs = attrs; state->higher_timestamp = NULL; state->netgroups = NULL; state->count = 0; state->timeout = timeout; state->base_filter = filter; state->base_iter = 0; state->search_bases = search_bases; if (!state->search_bases) { DEBUG(SSSDBG_CRIT_FAILURE, "Netgroup lookup request without a netgroup search base\n"); ret = EINVAL; goto done; } ret = sdap_get_netgroups_next_base(req); done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, state->ev); } return req; } static errno_t sdap_get_netgroups_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_get_netgroups_state *state; state = tevent_req_data(req, struct sdap_get_netgroups_state); talloc_zfree(state->filter); state->filter = sdap_combine_filters(state, state->base_filter, state->search_bases[state->base_iter]->filter); if (!state->filter) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Searching for netgroups with base [%s]\n", state->search_bases[state->base_iter]->basedn); subreq = sdap_get_generic_send( state, state->ev, state->opts, state->sh, state->search_bases[state->base_iter]->basedn, state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->netgroup_map, SDAP_OPTS_NETGROUP, state->timeout, false); if (!subreq) { return ENOMEM; } tevent_req_set_callback(subreq, sdap_get_netgroups_process, req); return EOK; } static void sdap_get_netgroups_process(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_netgroups_state *state = tevent_req_data(req, struct sdap_get_netgroups_state); int ret; ret = sdap_get_generic_recv(subreq, state, &state->count, &state->netgroups); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_FUNC, "Search for netgroups, returned %zu results.\n", state->count); if (state->count == 0) { /* No netgroups found in this search */ state->base_iter++; if (state->search_bases[state->base_iter]) { /* There are more search bases to try */ ret = sdap_get_netgroups_next_base(req); if (ret != EOK) { tevent_req_error(req, ENOENT); } return; } tevent_req_error(req, ENOENT); return; } subreq = netgr_translate_members_send(state, state->ev, state->opts, state->sh, state->dom, state->sysdb, state->count, state->netgroups); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, netgr_translate_members_done, req); return; } static void netgr_translate_members_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_get_netgroups_state *state = tevent_req_data(req, struct sdap_get_netgroups_state); int ret; size_t c; time_t now; ret = netgroup_translate_ldap_members_recv(subreq, state, &state->count, &state->netgroups); talloc_zfree(subreq); if (ret) { tevent_req_error(req, ret); return; } now = time(NULL); for (c = 0; c < state->count; c++) { ret = sdap_save_netgroup(state, state->dom, state->opts, state->netgroups[c], &state->higher_timestamp, now); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store netgroups.\n"); tevent_req_error(req, ret); return; } } DEBUG(SSSDBG_TRACE_ALL, "Saving %zu Netgroups - Done\n", state->count); tevent_req_done(req); } int sdap_get_netgroups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **timestamp, size_t *reply_count, struct sysdb_attrs ***reply) { struct sdap_get_netgroups_state *state = tevent_req_data(req, struct sdap_get_netgroups_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (timestamp) { *timestamp = talloc_steal(mem_ctx, state->higher_timestamp); } if (reply_count) { *reply_count = state->count; } if (reply) { *reply = talloc_steal(mem_ctx, state->netgroups); } return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_opts.c0000644000000000000000000000007412703456111020202 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.777794046 sssd-1.13.4/src/providers/ldap/ldap_opts.c0000644002412700241270000005377112703456111021666 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "src/providers/data_provider.h" #include "db/sysdb.h" #include "db/sysdb_sudo.h" #include "db/sysdb_autofs.h" #include "db/sysdb_services.h" #include "providers/ldap/ldap_common.h" struct dp_option default_basic_opts[] = { { "ldap_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_backup_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_default_bind_dn", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_default_authtok_type", DP_OPT_STRING, { "password" }, NULL_STRING}, { "ldap_default_authtok", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB }, { "ldap_search_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "ldap_network_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "ldap_tls_reqcert", DP_OPT_STRING, { "hard" }, NULL_STRING }, { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, { "ldap_user_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_user_extra_attrs", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, { "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_service_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_full_refresh_interval", DP_OPT_NUMBER, { .number = 21600 }, NULL_NUMBER }, /* 360 mins */ { "ldap_sudo_smart_refresh_interval", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER }, /* 15 mins */ { "ldap_sudo_use_host_filter", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_sudo_hostnames", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_ip", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sudo_include_netgroups", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_sudo_include_regexp", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_autofs_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_autofs_map_master_name", DP_OPT_STRING, { "auto.master" }, NULL_STRING }, { "ldap_schema", DP_OPT_STRING, { "rfc2307" }, NULL_STRING }, { "ldap_offline_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, { "ldap_force_upper_case_realm", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_enumeration_refresh_timeout", DP_OPT_NUMBER, { .number = 300 }, NULL_NUMBER }, { "ldap_purge_cache_timeout", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, { "ldap_tls_cacert", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_tls_cacertdir", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_tls_cert", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_tls_key", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_tls_cipher_suite", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_id_use_start_tls", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_id_mapping", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_sasl_mech", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sasl_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_sasl_minssf", DP_OPT_NUMBER, { .number = -1 }, NULL_NUMBER }, { "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, /* use the same parm name as the krb5 module so we set it only once */ { "krb5_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_canonicalize", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "krb5_use_kdcinfo", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "ldap_pwd_policy", DP_OPT_STRING, { "none" }, NULL_STRING }, { "ldap_referrals", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "account_cache_expiration", DP_OPT_NUMBER, { .number = 0 }, NULL_NUMBER }, { "ldap_dns_service_name", DP_OPT_STRING, { SSS_LDAP_SRV_NAME }, NULL_STRING }, { "ldap_krb5_ticket_lifetime", DP_OPT_NUMBER, { .number = (24 * 60 * 60) }, NULL_NUMBER }, { "ldap_access_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_netgroup_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_group_nesting_level", DP_OPT_NUMBER, { .number = 2 }, NULL_NUMBER }, { "ldap_deref", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_account_expire_policy", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_access_order", DP_OPT_STRING, { "filter" }, NULL_STRING }, { "ldap_chpass_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_chpass_backup_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_chpass_dns_service_name", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_chpass_update_last_change", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_enumeration_search_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, /* Do not include ldap_auth_disable_tls_never_use_in_production in the * manpages or SSSDConfig API */ { "ldap_auth_disable_tls_never_use_in_production", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_page_size", DP_OPT_NUMBER, { .number = 1000 }, NULL_NUMBER }, { "ldap_deref_threshold", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER }, { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_connection_expire_timeout", DP_OPT_NUMBER, { .number = 900 }, NULL_NUMBER }, { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER }, { "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000200000LL }, NULL_NUMBER }, { "ldap_idmap_range_size", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER }, { "ldap_idmap_autorid_compat", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_idmap_default_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_idmap_default_domain_sid", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_idmap_helper_table_size", DP_OPT_NUMBER, { .number = 10 }, NULL_NUMBER }, { "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_use_tokengroups", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE}, { "ldap_rfc2307_fallback_to_local_users", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_disable_range_retrieval", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_min_id", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER}, { "ldap_max_id", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER}, { "ldap_pwdlockout_dn", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "wildcard_limit", DP_OPT_NUMBER, { .number = 1000 }, NULL_NUMBER}, DP_OPTION_TERMINATOR }; struct sdap_attr_map generic_attr_map[] = { { "ldap_entry_usn", NULL, SYSDB_USN, NULL }, { "ldap_rootdse_last_usn", NULL, SYSDB_HIGH_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map gen_ipa_attr_map[] = { { "ldap_entry_usn", SDAP_IPA_USN, SYSDB_USN, NULL }, { "ldap_rootdse_last_usn", SDAP_IPA_LAST_USN, SYSDB_HIGH_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map gen_ad_attr_map[] = { { "ldap_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL }, { "ldap_rootdse_last_usn", SDAP_AD_LAST_USN, SYSDB_HIGH_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map rfc2307_user_map[] = { { "ldap_user_object_class", "posixAccount", SYSDB_USER_CLASS, NULL }, { "ldap_user_name", "uid", SYSDB_NAME, NULL }, { "ldap_user_pwd", "userPassword", SYSDB_PWD, NULL }, { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL }, { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL }, { "ldap_user_home_directory", "homeDirectory", SYSDB_HOMEDIR, NULL }, { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL }, { "ldap_user_principal", "krbPrincipalName", SYSDB_UPN, NULL }, { "ldap_user_fullname", "cn", SYSDB_FULLNAME, NULL }, { "ldap_user_member_of", NULL, SYSDB_MEMBEROF, NULL }, { "ldap_user_uuid", NULL, SYSDB_UUID, NULL }, { "ldap_user_objectsid", NULL, SYSDB_SID, NULL }, { "ldap_user_primary_group", NULL, SYSDB_PRIMARY_GROUP, NULL }, { "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_user_entry_usn", NULL, SYSDB_USN, NULL }, { "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL }, { "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL }, { "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL }, { "ldap_user_shadow_warning", "shadowWarning", SYSDB_SHADOWPW_WARNING, NULL }, { "ldap_user_shadow_inactive", "shadowInactive", SYSDB_SHADOWPW_INACTIVE, NULL }, { "ldap_user_shadow_expire", "shadowExpire", SYSDB_SHADOWPW_EXPIRE, NULL }, { "ldap_user_shadow_flag", "shadowFlag", SYSDB_SHADOWPW_FLAG, NULL }, { "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL }, { "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL }, { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL }, { "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL }, { "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL}, { "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL}, { "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL}, { "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL }, { "ldap_user_nds_login_disabled", "loginDisabled", SYSDB_NDS_LOGIN_DISABLED, NULL }, { "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL }, { "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL }, { "ldap_user_ssh_public_key", "sshPublicKey", SYSDB_SSH_PUBKEY, NULL }, { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL }, { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map rfc2307_group_map[] = { { "ldap_group_object_class", "posixGroup", SYSDB_GROUP_CLASS, NULL }, { "ldap_group_object_class_alt", NULL, SYSDB_GROUP_CLASS, NULL }, { "ldap_group_name", "cn", SYSDB_NAME, NULL }, { "ldap_group_pwd", "userPassword", SYSDB_PWD, NULL }, { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_group_member", "memberuid", SYSDB_MEMBER, NULL }, { "ldap_group_uuid", NULL, SYSDB_UUID, NULL }, { "ldap_group_objectsid", NULL, SYSDB_SID, NULL }, { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_group_entry_usn", NULL, SYSDB_USN, NULL }, { "ldap_group_type", NULL, SYSDB_GROUP_TYPE, NULL }, { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map rfc2307bis_user_map[] = { { "ldap_user_object_class", "posixAccount", SYSDB_USER_CLASS, NULL }, { "ldap_user_name", "uid", SYSDB_NAME, NULL }, { "ldap_user_pwd", "userPassword", SYSDB_PWD, NULL }, { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL }, { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL }, { "ldap_user_home_directory", "homeDirectory", SYSDB_HOMEDIR, NULL }, { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL }, { "ldap_user_principal", "krbPrincipalName", SYSDB_UPN, NULL }, { "ldap_user_fullname", "cn", SYSDB_FULLNAME, NULL }, { "ldap_user_member_of", "memberOf", SYSDB_MEMBEROF, NULL }, { "ldap_user_uuid", NULL, SYSDB_UUID, NULL }, { "ldap_user_objectsid", NULL, SYSDB_SID, NULL }, { "ldap_user_primary_group", NULL, SYSDB_PRIMARY_GROUP, NULL }, { "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_user_entry_usn", NULL, SYSDB_USN, NULL }, { "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL }, { "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL }, { "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL }, { "ldap_user_shadow_warning", "shadowWarning", SYSDB_SHADOWPW_WARNING, NULL }, { "ldap_user_shadow_inactive", "shadowInactive", SYSDB_SHADOWPW_INACTIVE, NULL }, { "ldap_user_shadow_expire", "shadowExpire", SYSDB_SHADOWPW_EXPIRE, NULL }, { "ldap_user_shadow_flag", "shadowFlag", SYSDB_SHADOWPW_FLAG, NULL }, { "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL }, { "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL }, { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL }, { "ldap_user_authorized_service", "authorizedService", SYSDB_AUTHORIZED_SERVICE, NULL }, { "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL}, { "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL}, { "ldap_ns_account_lock", "nsAccountLock", SYSDB_NS_ACCOUNT_LOCK, NULL}, { "ldap_user_authorized_host", "host", SYSDB_AUTHORIZED_HOST, NULL }, { "ldap_user_nds_login_disabled", "loginDisabled", SYSDB_NDS_LOGIN_DISABLED, NULL }, { "ldap_user_nds_login_expiration_time", "loginExpirationTime", SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL }, { "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL }, { "ldap_user_ssh_public_key", "sshPublicKey", SYSDB_SSH_PUBKEY, NULL }, { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL }, { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map rfc2307bis_group_map[] = { { "ldap_group_object_class", "posixGroup", SYSDB_GROUP_CLASS, NULL }, { "ldap_group_object_class_alt", NULL, SYSDB_GROUP_CLASS, NULL }, { "ldap_group_name", "cn", SYSDB_NAME, NULL }, { "ldap_group_pwd", "userPassword", SYSDB_PWD, NULL }, { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_group_member", "member", SYSDB_MEMBER, NULL }, { "ldap_group_uuid", NULL, SYSDB_UUID, NULL }, { "ldap_group_objectsid", NULL, SYSDB_SID, NULL }, { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_group_entry_usn", NULL, SYSDB_USN, NULL }, { "ldap_group_type", NULL, SYSDB_GROUP_TYPE, NULL }, { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map gen_ad2008r2_user_map[] = { { "ldap_user_object_class", "user", SYSDB_USER_CLASS, NULL }, { "ldap_user_name", "sAMAccountName", SYSDB_NAME, NULL }, { "ldap_user_pwd", "unixUserPassword", SYSDB_PWD, NULL }, { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL }, { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL }, { "ldap_user_home_directory", "unixHomeDirectory", SYSDB_HOMEDIR, NULL }, { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL }, { "ldap_user_principal", "userPrincipalName", SYSDB_UPN, NULL }, { "ldap_user_fullname", "name", SYSDB_FULLNAME, NULL }, { "ldap_user_member_of", "memberOf", SYSDB_MEMBEROF, NULL }, { "ldap_user_uuid", "objectGUID", SYSDB_UUID, NULL }, { "ldap_user_objectsid", "objectSID", SYSDB_SID, NULL }, { "ldap_user_primary_group", "primaryGroupID", SYSDB_PRIMARY_GROUP, NULL }, { "ldap_user_modify_timestamp", "whenChanged", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_user_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL }, { "ldap_user_shadow_last_change", NULL, SYSDB_SHADOWPW_LASTCHANGE, NULL }, { "ldap_user_shadow_min", NULL, SYSDB_SHADOWPW_MIN, NULL }, { "ldap_user_shadow_max", NULL, SYSDB_SHADOWPW_MAX, NULL }, { "ldap_user_shadow_warning", NULL, SYSDB_SHADOWPW_WARNING, NULL }, { "ldap_user_shadow_inactive", NULL, SYSDB_SHADOWPW_INACTIVE, NULL }, { "ldap_user_shadow_expire", NULL, SYSDB_SHADOWPW_EXPIRE, NULL }, { "ldap_user_shadow_flag", NULL, SYSDB_SHADOWPW_FLAG, NULL }, { "ldap_user_krb_last_pwd_change", NULL, SYSDB_KRBPW_LASTCHANGE, NULL }, { "ldap_user_krb_password_expiration", NULL, SYSDB_KRBPW_EXPIRATION, NULL }, { "ldap_pwd_attribute", NULL, SYSDB_PWD_ATTRIBUTE, NULL }, { "ldap_user_authorized_service", NULL, SYSDB_AUTHORIZED_SERVICE, NULL }, { "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL}, { "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL}, { "ldap_ns_account_lock", NULL, SYSDB_NS_ACCOUNT_LOCK, NULL}, { "ldap_user_authorized_host", NULL, SYSDB_AUTHORIZED_HOST, NULL }, { "ldap_user_nds_login_disabled", NULL, SYSDB_NDS_LOGIN_DISABLED, NULL }, { "ldap_user_nds_login_expiration_time", NULL, SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL }, { "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL }, { "ldap_user_ssh_public_key", NULL, SYSDB_SSH_PUBKEY, NULL }, { "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL }, { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map gen_ad2008r2_group_map[] = { { "ldap_group_object_class", "group", SYSDB_GROUP_CLASS, NULL }, { "ldap_group_object_class_alt", NULL, SYSDB_GROUP_CLASS, NULL }, { "ldap_group_name", "name", SYSDB_NAME, NULL }, { "ldap_group_pwd", NULL, SYSDB_PWD, NULL }, { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, { "ldap_group_member", "member", SYSDB_MEMBER, NULL }, { "ldap_group_uuid", "objectGUID", SYSDB_UUID, NULL }, { "ldap_group_objectsid", "objectSID", SYSDB_SID, NULL }, { "ldap_group_modify_timestamp", "whenChanged", SYSDB_ORIG_MODSTAMP, NULL }, { "ldap_group_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL }, { "ldap_group_type", "groupType", SYSDB_GROUP_TYPE, NULL }, { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map netgroup_map[] = { { "ldap_netgroup_object_class", "nisNetgroup", SYSDB_NETGROUP_CLASS, NULL }, { "ldap_netgroup_name", "cn", SYSDB_NAME, NULL }, { "ldap_netgroup_member", "memberNisNetgroup", SYSDB_ORIG_NETGROUP_MEMBER, NULL }, { "ldap_netgroup_triple", "nisNetgroupTriple", SYSDB_NETGROUP_TRIPLE, NULL }, { "ldap_netgroup_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map native_sudorule_map[] = { { "ldap_sudorule_object_class", "sudoRole", SYSDB_SUDO_CACHE_OC, NULL }, { "ldap_sudorule_name", "cn", SYSDB_SUDO_CACHE_AT_CN, NULL }, { "ldap_sudorule_command", "sudoCommand", SYSDB_SUDO_CACHE_AT_COMMAND, NULL }, { "ldap_sudorule_host", "sudoHost", SYSDB_SUDO_CACHE_AT_HOST, NULL }, { "ldap_sudorule_user", "sudoUser", SYSDB_SUDO_CACHE_AT_USER, NULL }, { "ldap_sudorule_option", "sudoOption", SYSDB_SUDO_CACHE_AT_OPTION, NULL }, { "ldap_sudorule_runas", "sudoRunAs", SYSDB_SUDO_CACHE_AT_RUNAS, NULL }, { "ldap_sudorule_runasuser", "sudoRunAsUser", SYSDB_SUDO_CACHE_AT_RUNASUSER, NULL }, { "ldap_sudorule_runasgroup", "sudoRunAsGroup", SYSDB_SUDO_CACHE_AT_RUNASGROUP, NULL }, { "ldap_sudorule_notbefore", "sudoNotBefore", SYSDB_SUDO_CACHE_AT_NOTBEFORE, NULL }, { "ldap_sudorule_notafter", "sudoNotAfter", SYSDB_SUDO_CACHE_AT_NOTAFTER, NULL }, { "ldap_sudorule_order", "sudoOrder", SYSDB_SUDO_CACHE_AT_ORDER, NULL }, { "ldap_sudorule_entry_usn", NULL, SYSDB_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map service_map[] = { { "ldap_service_object_class", "ipService", SYSDB_SVC_CLASS, NULL }, { "ldap_service_name", "cn", SYSDB_NAME, NULL }, { "ldap_service_port", "ipServicePort", SYSDB_SVC_PORT, NULL }, { "ldap_service_proto", "ipServiceProtocol", SYSDB_SVC_PROTO, NULL }, { "ldap_service_entry_usn", NULL, SYSDB_USN, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map rfc2307_autofs_mobject_map[] = { { "ldap_autofs_map_object_class", "automountMap", SYSDB_AUTOFS_MAP_OC, NULL }, { "ldap_autofs_map_name", "ou", SYSDB_AUTOFS_MAP_NAME, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map rfc2307_autofs_entry_map[] = { { "ldap_autofs_entry_object_class", "automount", SYSDB_AUTOFS_ENTRY_OC, NULL }, { "ldap_autofs_entry_key", "cn", SYSDB_AUTOFS_ENTRY_KEY, NULL }, { "ldap_autofs_entry_value", "automountInformation", SYSDB_AUTOFS_ENTRY_VALUE, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map rfc2307bis_autofs_mobject_map[] = { { "ldap_autofs_map_object_class", "automountMap", SYSDB_AUTOFS_MAP_OC, NULL }, { "ldap_autofs_map_name", "automountMapName", SYSDB_AUTOFS_MAP_NAME, NULL }, SDAP_ATTR_MAP_TERMINATOR }; struct sdap_attr_map rfc2307bis_autofs_entry_map[] = { { "ldap_autofs_entry_object_class", "automount", SYSDB_AUTOFS_ENTRY_OC, NULL }, { "ldap_autofs_entry_key", "automountKey", SYSDB_AUTOFS_ENTRY_KEY, NULL }, { "ldap_autofs_entry_value", "automountInformation", SYSDB_AUTOFS_ENTRY_VALUE, NULL }, SDAP_ATTR_MAP_TERMINATOR }; sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_sudo_shared.h0000644000000000000000000000007312703456111021530 xustar0030 atime=1460561751.649715624 29 ctime=1460561774.55479329 sssd-1.13.4/src/providers/ldap/sdap_sudo_shared.h0000644002412700241270000000257512703456111023211 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SDAP_SUDO_SHARED_H_ #define _SDAP_SUDO_SHARED_H_ #include "providers/dp_backend.h" #include "providers/dp_ptask.h" errno_t sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx, struct dp_option *opts, be_ptask_send_t full_send_fn, be_ptask_recv_t full_recv_fn, be_ptask_send_t smart_send_fn, be_ptask_recv_t smart_recv_fn, void *pvt); void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, const char *usn); #endif /* _SDAP_SUDO_SHARED_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_access.c0000644000000000000000000000007412703456111020465 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.778794049 sssd-1.13.4/src/providers/ldap/sdap_access.c0000644002412700241270000017430512703456111022146 0ustar00jhrozekjhrozek00000000000000/* SSSD sdap_access.c Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include #include #include #include "util/util.h" #include "util/strtonum.h" #include "db/sysdb.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_access.h" #include "providers/ldap/sdap_async.h" #include "providers/data_provider.h" #include "providers/dp_backend.h" #include "providers/ldap/ldap_auth.h" #define PERMANENTLY_LOCKED_ACCOUNT "000001010000Z" #define MALFORMED_FILTER "Malformed access control filter [%s]\n" enum sdap_pwpolicy_mode { PWP_LOCKOUT_ONLY, PWP_LOCKOUT_EXPIRE, PWP_SENTINEL, }; static errno_t perform_pwexpire_policy(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct pam_data *pd, struct sdap_options *opts); static errno_t sdap_save_user_cache_bool(struct sss_domain_info *domain, const char *username, const char *attr_name, bool value); static errno_t sdap_get_basedn_user_entry(struct ldb_message *user_entry, const char *username, const char **_basedn); static struct tevent_req * sdap_access_ppolicy_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, struct sdap_access_ctx *access_ctx, struct sdap_id_conn_ctx *conn, const char *username, struct ldb_message *user_entry, enum sdap_pwpolicy_mode pwpol_mod); static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, struct sdap_access_ctx *access_ctx, struct sdap_id_conn_ctx *conn, const char *username, struct ldb_message *user_entry); static errno_t sdap_access_filter_recv(struct tevent_req *req); static errno_t sdap_access_ppolicy_recv(struct tevent_req *req); static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx, struct pam_data *pd, struct ldb_message *user_entry); static errno_t sdap_access_service(struct pam_data *pd, struct ldb_message *user_entry); static errno_t sdap_access_host(struct ldb_message *user_entry); enum sdap_access_control_type { SDAP_ACCESS_CONTROL_FILTER, SDAP_ACCESS_CONTROL_PPOLICY_LOCK, }; struct sdap_access_req_ctx { struct pam_data *pd; struct tevent_context *ev; struct sdap_access_ctx *access_ctx; struct sdap_id_conn_ctx *conn; struct be_ctx *be_ctx; struct sss_domain_info *domain; struct ldb_message *user_entry; size_t current_rule; enum sdap_access_control_type ac_type; }; static errno_t sdap_access_check_next_rule(struct sdap_access_req_ctx *state, struct tevent_req *req); static void sdap_access_done(struct tevent_req *subreq); struct tevent_req * sdap_access_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, struct sdap_access_ctx *access_ctx, struct sdap_id_conn_ctx *conn, struct pam_data *pd) { errno_t ret; struct sdap_access_req_ctx *state; struct tevent_req *req; struct ldb_result *res; const char *attrs[] = { "*", NULL }; req = tevent_req_create(mem_ctx, &state, struct sdap_access_req_ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->be_ctx = be_ctx; state->domain = domain; state->pd = pd; state->ev = ev; state->access_ctx = access_ctx; state->conn = conn; state->current_rule = 0; DEBUG(SSSDBG_TRACE_FUNC, "Performing access check for user [%s]\n", pd->user); if (access_ctx->access_rule[0] == LDAP_ACCESS_EMPTY) { DEBUG(SSSDBG_MINOR_FAILURE, "No access rules defined, access denied.\n"); ret = ERR_ACCESS_DENIED; goto done; } /* Get original user DN, domain already points to the right (sub)domain */ ret = sysdb_get_user_attr(state, domain, pd->user, attrs, &res); if (ret != EOK) { if (ret == ENOENT) { /* If we can't find the user, return access denied */ ret = ERR_ACCESS_DENIED; goto done; } goto done; } else { if (res->count == 0) { /* If we can't find the user, return access denied */ ret = ERR_ACCESS_DENIED; goto done; } if (res->count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid response from sysdb_get_user_attr\n"); ret = EINVAL; goto done; } } state->user_entry = res->msgs[0]; ret = sdap_access_check_next_rule(state, req); if (ret == EAGAIN) { return req; } done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t sdap_access_check_next_rule(struct sdap_access_req_ctx *state, struct tevent_req *req) { struct tevent_req *subreq; int ret = EOK; while (ret == EOK) { switch (state->access_ctx->access_rule[state->current_rule]) { case LDAP_ACCESS_EMPTY: /* we are done with no errors */ return EOK; /* This option is deprecated by LDAP_ACCESS_PPOLICY */ case LDAP_ACCESS_LOCKOUT: DEBUG(SSSDBG_MINOR_FAILURE, "WARNING: %s option is deprecated and might be removed in " "a future release. Please migrate to %s option instead.\n", LDAP_ACCESS_LOCK_NAME, LDAP_ACCESS_PPOLICY_NAME); subreq = sdap_access_ppolicy_send(state, state->ev, state->be_ctx, state->domain, state->access_ctx, state->conn, state->pd->user, state->user_entry, PWP_LOCKOUT_ONLY); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_ppolicy_send failed.\n"); return ENOMEM; } state->ac_type = SDAP_ACCESS_CONTROL_PPOLICY_LOCK; tevent_req_set_callback(subreq, sdap_access_done, req); return EAGAIN; case LDAP_ACCESS_PPOLICY: subreq = sdap_access_ppolicy_send(state, state->ev, state->be_ctx, state->domain, state->access_ctx, state->conn, state->pd->user, state->user_entry, PWP_LOCKOUT_EXPIRE); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_ppolicy_send failed.\n"); return ENOMEM; } state->ac_type = SDAP_ACCESS_CONTROL_PPOLICY_LOCK; tevent_req_set_callback(subreq, sdap_access_done, req); return EAGAIN; case LDAP_ACCESS_FILTER: subreq = sdap_access_filter_send(state, state->ev, state->be_ctx, state->domain, state->access_ctx, state->conn, state->pd->user, state->user_entry); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_filter_send failed.\n"); return ENOMEM; } state->ac_type = SDAP_ACCESS_CONTROL_FILTER; tevent_req_set_callback(subreq, sdap_access_done, req); return EAGAIN; case LDAP_ACCESS_EXPIRE: ret = sdap_account_expired(state->access_ctx, state->pd, state->user_entry); break; case LDAP_ACCESS_EXPIRE_POLICY_REJECT: ret = perform_pwexpire_policy(state, state->domain, state->pd, state->access_ctx->id_ctx->opts); if (ret == ERR_PASSWORD_EXPIRED) { ret = ERR_PASSWORD_EXPIRED_REJECT; } break; case LDAP_ACCESS_EXPIRE_POLICY_WARN: ret = perform_pwexpire_policy(state, state->domain, state->pd, state->access_ctx->id_ctx->opts); if (ret == ERR_PASSWORD_EXPIRED) { ret = ERR_PASSWORD_EXPIRED_WARN; } break; case LDAP_ACCESS_EXPIRE_POLICY_RENEW: ret = perform_pwexpire_policy(state, state->domain, state->pd, state->access_ctx->id_ctx->opts); if (ret == ERR_PASSWORD_EXPIRED) { ret = ERR_PASSWORD_EXPIRED_RENEW; } break; case LDAP_ACCESS_SERVICE: ret = sdap_access_service( state->pd, state->user_entry); break; case LDAP_ACCESS_HOST: ret = sdap_access_host(state->user_entry); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected access rule type. Access denied.\n"); ret = ERR_ACCESS_DENIED; } state->current_rule++; } return ret; } static void sdap_access_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req; struct sdap_access_req_ctx *state; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_access_req_ctx); /* process subrequest */ switch(state->ac_type) { case SDAP_ACCESS_CONTROL_FILTER: ret = sdap_access_filter_recv(subreq); break; case SDAP_ACCESS_CONTROL_PPOLICY_LOCK: ret = sdap_access_ppolicy_recv(subreq); break; default: ret = EINVAL; DEBUG(SSSDBG_MINOR_FAILURE, "Unknown access control type: %d.\n", state->ac_type); break; } talloc_zfree(subreq); if (ret != EOK) { if (ret == ERR_ACCESS_DENIED) { DEBUG(SSSDBG_TRACE_FUNC, "Access was denied.\n"); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Error retrieving access check result.\n"); } tevent_req_error(req, ret); return; } state->current_rule++; ret = sdap_access_check_next_rule(state, req); switch (ret) { case EAGAIN: return; case EOK: tevent_req_done(req); return; default: tevent_req_error(req, ret); return; } } errno_t sdap_access_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } #define SHADOW_EXPIRE_MSG "Account expired according to shadow attributes" static errno_t sdap_account_expired_shadow(struct pam_data *pd, struct ldb_message *user_entry) { int ret; const char *val; long sp_expire; long today; DEBUG(SSSDBG_TRACE_FUNC, "Performing access shadow check for user [%s]\n", pd->user); val = ldb_msg_find_attr_as_string(user_entry, SYSDB_SHADOWPW_EXPIRE, NULL); if (val == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Shadow expire attribute not found. " "Access will be granted.\n"); return EOK; } ret = string_to_shadowpw_days(val, &sp_expire); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to retrieve shadow expire date.\n"); return ret; } today = (long) (time(NULL) / (60 * 60 * 24)); if (sp_expire > 0 && today > sp_expire) { ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, sizeof(SHADOW_EXPIRE_MSG), (const uint8_t *) SHADOW_EXPIRE_MSG); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } return ERR_ACCOUNT_EXPIRED; } return EOK; } #define UAC_ACCOUNTDISABLE 0x00000002 #define AD_NEVER_EXP 0x7fffffffffffffffLL #define AD_TO_UNIX_TIME_CONST 11644473600LL #define AD_DISABLE_MESSAGE "The user account is disabled on the AD server" #define AD_EXPIRED_MESSAGE "The user account is expired on the AD server" static bool ad_account_expired(uint64_t expiration_time) { time_t now; int err; uint64_t nt_now; if (expiration_time == 0 || expiration_time == AD_NEVER_EXP) { return false; } now = time(NULL); if (now == ((time_t) -1)) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "time failed [%d][%s].\n", err, strerror(err)); return true; } /* NT timestamps start at 1601-01-01 and use a 100ns base */ nt_now = (now + AD_TO_UNIX_TIME_CONST) * 1000 * 1000 * 10; if (nt_now > expiration_time) { return true; } return false; } static errno_t sdap_account_expired_ad(struct pam_data *pd, struct ldb_message *user_entry) { uint32_t uac; uint64_t expiration_time; int ret; DEBUG(SSSDBG_TRACE_FUNC, "Performing AD access check for user [%s]\n", pd->user); uac = ldb_msg_find_attr_as_uint(user_entry, SYSDB_AD_USER_ACCOUNT_CONTROL, 0); DEBUG(SSSDBG_TRACE_ALL, "User account control for user [%s] is [%X].\n", pd->user, uac); expiration_time = ldb_msg_find_attr_as_uint64(user_entry, SYSDB_AD_ACCOUNT_EXPIRES, 0); DEBUG(SSSDBG_TRACE_ALL, "Expiration time for user [%s] is [%"PRIu64"].\n", pd->user, expiration_time); if (uac & UAC_ACCOUNTDISABLE) { ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, sizeof(AD_DISABLE_MESSAGE), (const uint8_t *) AD_DISABLE_MESSAGE); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } return ERR_ACCESS_DENIED; } else if (ad_account_expired(expiration_time)) { ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, sizeof(AD_EXPIRED_MESSAGE), (const uint8_t *) AD_EXPIRED_MESSAGE); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } return ERR_ACCOUNT_EXPIRED; } return EOK; } #define RHDS_LOCK_MSG "The user account is locked on the server" static errno_t sdap_account_expired_rhds(struct pam_data *pd, struct ldb_message *user_entry) { bool locked; int ret; DEBUG(SSSDBG_TRACE_FUNC, "Performing RHDS access check for user [%s]\n", pd->user); locked = ldb_msg_find_attr_as_bool(user_entry, SYSDB_NS_ACCOUNT_LOCK, false); DEBUG(SSSDBG_TRACE_ALL, "Account for user [%s] is%s locked.\n", pd->user, locked ? "" : " not" ); if (locked) { ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, sizeof(RHDS_LOCK_MSG), (const uint8_t *) RHDS_LOCK_MSG); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } return ERR_ACCESS_DENIED; } return EOK; } #define NDS_DISABLE_MSG "The user account is disabled on the server" #define NDS_EXPIRED_MSG "The user account is expired" #define NDS_TIME_MAP_MSG "The user account is not allowed at this time" bool nds_check_expired(const char *exp_time_str) { time_t expire_time; time_t now; errno_t ret; if (exp_time_str == NULL) { DEBUG(SSSDBG_TRACE_ALL, "ndsLoginExpirationTime is not set, access granted.\n"); return false; } ret = sss_utc_to_time_t(exp_time_str, "%Y%m%d%H%M%SZ", &expire_time); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_utc_to_time_t failed with %d:%s.\n", ret, sss_strerror(ret)); return true; } now = time(NULL); DEBUG(SSSDBG_TRACE_ALL, "Time info: tzname[0] [%s] tzname[1] [%s] timezone [%ld] " "daylight [%d] now [%ld] expire_time [%ld].\n", tzname[0], tzname[1], timezone, daylight, now, expire_time); if (difftime(now, expire_time) > 0.0) { DEBUG(SSSDBG_CONF_SETTINGS, "NDS account expired.\n"); return true; } return false; } /* There is no real documentation of the byte string value of * loginAllowedTimeMap, but some good example code in * http://http://developer.novell.com/documentation/samplecode/extjndi_sample/CheckBind.java.html */ static bool nds_check_time_map(const struct ldb_val *time_map) { time_t now; struct tm *tm_now; size_t map_index; div_t q; uint8_t mask = 0; if (time_map == NULL) { DEBUG(SSSDBG_TRACE_ALL, "loginAllowedTimeMap is missing, access granted.\n"); return false; } if (time_map->length != 42) { DEBUG(SSSDBG_FUNC_DATA, "Allowed time map has the wrong size, " "got [%zu], expected 42.\n", time_map->length); return true; } now = time(NULL); tm_now = gmtime(&now); map_index = tm_now->tm_wday * 48 + tm_now->tm_hour * 2 + (tm_now->tm_min < 30 ? 0 : 1); if (map_index > 335) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected index value [%zu] for time map.\n", map_index); return true; } q = div(map_index, 8); if (q.quot > 41 || q.quot < 0 || q.rem > 7 || q.rem < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected result of div(), [%zu][%d][%d].\n", map_index, q.quot, q.rem); return true; } if (q.rem > 0) { mask = 1 << q.rem; } if (time_map->data[q.quot] & mask) { DEBUG(SSSDBG_CONF_SETTINGS, "Access allowed by time map.\n"); return false; } return true; } static errno_t sdap_account_expired_nds(struct pam_data *pd, struct ldb_message *user_entry) { bool locked = true; int ret; const char *exp_time_str; const struct ldb_val *time_map; DEBUG(SSSDBG_TRACE_FUNC, "Performing NDS access check for user [%s]\n", pd->user); locked = ldb_msg_find_attr_as_bool(user_entry, SYSDB_NDS_LOGIN_DISABLED, false); DEBUG(SSSDBG_TRACE_ALL, "Account for user [%s] is%s disabled.\n", pd->user, locked ? "" : " not"); if (locked) { ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, sizeof(NDS_DISABLE_MSG), (const uint8_t *) NDS_DISABLE_MSG); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } return ERR_ACCESS_DENIED; } else { exp_time_str = ldb_msg_find_attr_as_string(user_entry, SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL); locked = nds_check_expired(exp_time_str); DEBUG(SSSDBG_TRACE_ALL, "Account for user [%s] is%s expired.\n", pd->user, locked ? "" : " not"); if (locked) { ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, sizeof(NDS_EXPIRED_MSG), (const uint8_t *) NDS_EXPIRED_MSG); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } return ERR_ACCESS_DENIED; } else { time_map = ldb_msg_find_ldb_val(user_entry, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP); locked = nds_check_time_map(time_map); DEBUG(SSSDBG_TRACE_ALL, "Account for user [%s] is%s locked at this time.\n", pd->user, locked ? "" : " not"); if (locked) { ret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, sizeof(NDS_TIME_MAP_MSG), (const uint8_t *) NDS_TIME_MAP_MSG); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } return ERR_ACCESS_DENIED; } } } return EOK; } static errno_t sdap_account_expired(struct sdap_access_ctx *access_ctx, struct pam_data *pd, struct ldb_message *user_entry) { const char *expire; int ret; expire = dp_opt_get_cstring(access_ctx->id_ctx->opts->basic, SDAP_ACCOUNT_EXPIRE_POLICY); if (expire == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing account expire policy. Access denied\n"); return ERR_ACCESS_DENIED; } else { if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_SHADOW) == 0) { ret = sdap_account_expired_shadow(pd, user_entry); if (ret == ERR_ACCOUNT_EXPIRED) { DEBUG(SSSDBG_TRACE_FUNC, "sdap_account_expired_shadow: %s.\n", sss_strerror(ret)); } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_account_expired_shadow failed.\n"); } } else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_AD) == 0) { ret = sdap_account_expired_ad(pd, user_entry); if (ret == ERR_ACCOUNT_EXPIRED || ret == ERR_ACCESS_DENIED) { DEBUG(SSSDBG_TRACE_FUNC, "sdap_account_expired_ad: %s.\n", sss_strerror(ret)); } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_account_expired_ad failed.\n"); } } else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_RHDS) == 0 || strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_IPA) == 0 || strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_389DS) == 0) { ret = sdap_account_expired_rhds(pd, user_entry); if (ret == ERR_ACCESS_DENIED) { DEBUG(SSSDBG_TRACE_FUNC, "sdap_account_expired_rhds: %s.\n", sss_strerror(ret)); } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_account_expired_rhds failed.\n"); } } else if (strcasecmp(expire, LDAP_ACCOUNT_EXPIRE_NDS) == 0) { ret = sdap_account_expired_nds(pd, user_entry); if (ret == ERR_ACCESS_DENIED) { DEBUG(SSSDBG_TRACE_FUNC, "sdap_account_expired_nds: %s.\n", sss_strerror(ret)); } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_account_expired_nds failed.\n"); } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported LDAP account expire policy [%s]. " "Access denied.\n", expire); ret = ERR_ACCESS_DENIED; } } return ret; } static errno_t perform_pwexpire_policy(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct pam_data *pd, struct sdap_options *opts) { enum pwexpire pw_expire_type; void *pw_expire_data; errno_t ret; char *dn; ret = get_user_dn(mem_ctx, domain, opts, pd->user, &dn, &pw_expire_type, &pw_expire_data); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "get_user_dn returned %d:[%s].\n", ret, sss_strerror(ret)); goto done; } ret = check_pwexpire_policy(pw_expire_type, pw_expire_data, pd, domain->pwd_expiration_warning); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "check_pwexpire_policy returned %d:[%s].\n", ret, sss_strerror(ret)); goto done; } done: return ret; } struct sdap_access_filter_req_ctx { const char *username; const char *filter; struct tevent_context *ev; struct sdap_access_ctx *access_ctx; struct sdap_options *opts; struct sdap_id_conn_ctx *conn; struct sdap_id_op *sdap_op; struct sysdb_handle *handle; struct sss_domain_info *domain; /* cached result of access control checks */ bool cached_access; const char *basedn; }; static errno_t sdap_access_decide_offline(bool cached_ac); static int sdap_access_filter_retry(struct tevent_req *req); static void sdap_access_ppolicy_connect_done(struct tevent_req *subreq); static errno_t sdap_access_ppolicy_get_lockout_step(struct tevent_req *req); static void sdap_access_filter_connect_done(struct tevent_req *subreq); static void sdap_access_filter_done(struct tevent_req *req); static struct tevent_req *sdap_access_filter_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, struct sdap_access_ctx *access_ctx, struct sdap_id_conn_ctx *conn, const char *username, struct ldb_message *user_entry) { struct sdap_access_filter_req_ctx *state; struct tevent_req *req; char *clean_username; errno_t ret = ERR_INTERNAL; char *name; req = tevent_req_create(mem_ctx, &state, struct sdap_access_filter_req_ctx); if (req == NULL) { return NULL; } if (access_ctx->filter == NULL || *access_ctx->filter == '\0') { /* If no filter is set, default to restrictive */ DEBUG(SSSDBG_TRACE_FUNC, "No filter set. Access is denied.\n"); ret = ERR_ACCESS_DENIED; goto done; } state->filter = NULL; state->username = username; state->opts = access_ctx->id_ctx->opts; state->conn = conn; state->ev = ev; state->access_ctx = access_ctx; state->domain = domain; DEBUG(SSSDBG_TRACE_FUNC, "Performing access filter check for user [%s]\n", username); state->cached_access = ldb_msg_find_attr_as_bool(user_entry, SYSDB_LDAP_ACCESS_FILTER, false); /* Ok, we have one result, check if we are online or offline */ if (be_is_offline(be_ctx)) { /* Ok, we're offline. Return from the cache */ ret = sdap_access_decide_offline(state->cached_access); goto done; } ret = sdap_get_basedn_user_entry(user_entry, state->username, &state->basedn); if (ret != EOK) { goto done; } /* Construct the filter */ /* Subdomain users are identified by FQDN. We need to use just the username */ ret = sss_parse_name(state, domain->names, username, NULL, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not parse [%s] into name and " "domain components, access might fail\n", username); name = discard_const(username); } ret = sss_filter_sanitize(state, name, &clean_username); if (ret != EOK) { goto done; } state->filter = talloc_asprintf( state, "(&(%s=%s)(objectclass=%s)%s)", state->opts->user_map[SDAP_AT_USER_NAME].name, clean_username, state->opts->user_map[SDAP_OC_USER].name, state->access_ctx->filter); if (state->filter == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not construct access filter\n"); ret = ENOMEM; goto done; } talloc_zfree(clean_username); DEBUG(SSSDBG_TRACE_FUNC, "Checking filter against LDAP\n"); state->sdap_op = sdap_id_op_create(state, state->conn->conn_cache); if (!state->sdap_op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto done; } ret = sdap_access_filter_retry(req); if (ret != EOK) { goto done; } return req; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } /* Helper function, * cached_ac => access granted * !cached_ac => access denied */ static errno_t sdap_access_decide_offline(bool cached_ac) { if (cached_ac) { DEBUG(SSSDBG_TRACE_FUNC, "Access granted by cached credentials\n"); return EOK; } else { DEBUG(SSSDBG_TRACE_FUNC, "Access denied by cached credentials\n"); return ERR_ACCESS_DENIED; } } static int sdap_access_filter_retry(struct tevent_req *req) { struct sdap_access_filter_req_ctx *state = tevent_req_data(req, struct sdap_access_filter_req_ctx); struct tevent_req *subreq; int ret; subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (!subreq) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d (%s)\n", ret, strerror(ret)); return ret; } tevent_req_set_callback(subreq, sdap_access_filter_connect_done, req); return EOK; } static void sdap_access_filter_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_access_filter_req_ctx *state = tevent_req_data(req, struct sdap_access_filter_req_ctx); int ret, dp_error; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { if (dp_error == DP_ERR_OFFLINE) { ret = sdap_access_decide_offline(state->cached_access); if (ret == EOK) { tevent_req_done(req); return; } } tevent_req_error(req, ret); return; } /* Connection to LDAP succeeded * Send filter request */ subreq = sdap_get_generic_send(state, state->ev, state->opts, sdap_id_op_handle(state->sdap_op), state->basedn, LDAP_SCOPE_BASE, state->filter, NULL, NULL, 0, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not start LDAP communication\n"); tevent_req_error(req, EIO); return; } tevent_req_set_callback(subreq, sdap_access_filter_done, req); } static void sdap_access_filter_done(struct tevent_req *subreq) { int ret, tret, dp_error; size_t num_results; bool found = false; struct sysdb_attrs **results; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_access_filter_req_ctx *state = tevent_req_data(req, struct sdap_access_filter_req_ctx); ret = sdap_get_generic_recv(subreq, state, &num_results, &results); talloc_zfree(subreq); ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); if (ret != EOK) { if (dp_error == DP_ERR_OK) { /* retry */ tret = sdap_access_filter_retry(req); if (tret == EOK) { return; } } else if (dp_error == DP_ERR_OFFLINE) { ret = sdap_access_decide_offline(state->cached_access); } else if (ret == ERR_INVALID_FILTER) { sss_log(SSS_LOG_ERR, MALFORMED_FILTER, state->filter); DEBUG(SSSDBG_CRIT_FAILURE, MALFORMED_FILTER, state->filter); ret = ERR_ACCESS_DENIED; } else { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_get_generic_send() returned error [%d][%s]\n", ret, sss_strerror(ret)); } goto done; } /* Check the number of responses we got * If it's exactly 1, we passed the check * If it's < 1, we failed the check * Anything else is an error */ if (num_results < 1) { DEBUG(SSSDBG_CONF_SETTINGS, "User [%s] was not found with the specified filter. " "Denying access.\n", state->username); found = false; } else if (results == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "num_results > 0, but results is NULL\n"); ret = ERR_INTERNAL; goto done; } else if (num_results > 1) { /* It should not be possible to get more than one reply * here, since we're doing a base-scoped search */ DEBUG(SSSDBG_CRIT_FAILURE, "Received multiple replies\n"); ret = ERR_INTERNAL; goto done; } else { /* Ok, we got a single reply */ found = true; } if (found) { /* Save "allow" to the cache for future offline access checks. */ DEBUG(SSSDBG_TRACE_FUNC, "Access granted by online lookup\n"); ret = EOK; } else { /* Save "disallow" to the cache for future offline * access checks. */ DEBUG(SSSDBG_TRACE_FUNC, "Access denied by online lookup\n"); ret = ERR_ACCESS_DENIED; } tret = sdap_save_user_cache_bool(state->domain, state->username, SYSDB_LDAP_ACCESS_FILTER, found); if (tret != EOK) { /* Failing to save to the cache is non-fatal. * Just return the result. */ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set user access attribute\n"); goto done; } done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } static errno_t sdap_access_filter_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } #define AUTHR_SRV_MISSING_MSG "Authorized service attribute missing, " \ "access denied" #define AUTHR_SRV_DENY_MSG "Access denied by authorized service attribute" #define AUTHR_SRV_NO_MATCH_MSG "Authorized service attribute has " \ "no matching rule, access denied" static errno_t sdap_access_service(struct pam_data *pd, struct ldb_message *user_entry) { errno_t ret, tret; struct ldb_message_element *el; unsigned int i; char *service; el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_SERVICE); if (!el || el->num_values == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing authorized services. Access denied\n"); tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, sizeof(AUTHR_SRV_MISSING_MSG), (const uint8_t *) AUTHR_SRV_MISSING_MSG); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } return ERR_ACCESS_DENIED; } ret = ENOENT; for (i = 0; i < el->num_values; i++) { service = (char *)el->values[i].data; if (service[0] == '!' && strcasecmp(pd->service, service+1) == 0) { /* This service is explicitly denied */ DEBUG(SSSDBG_CONF_SETTINGS, "Access denied by [%s]\n", service); tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, sizeof(AUTHR_SRV_DENY_MSG), (const uint8_t *) AUTHR_SRV_DENY_MSG); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } /* A denial trumps all. Break here */ return ERR_ACCESS_DENIED; } else if (strcasecmp(pd->service, service) == 0) { /* This service is explicitly allowed */ DEBUG(SSSDBG_CONF_SETTINGS, "Access granted for [%s]\n", service); /* We still need to loop through to make sure * that it's not also explicitly denied */ ret = EOK; } else if (strcmp("*", service) == 0) { /* This user has access to all services */ DEBUG(SSSDBG_CONF_SETTINGS, "Access granted to all services\n"); /* We still need to loop through to make sure * that it's not also explicitly denied */ ret = EOK; } } if (ret == ENOENT) { DEBUG(SSSDBG_CONF_SETTINGS, "No matching service rule found\n"); tret = pam_add_response(pd, SSS_PAM_SYSTEM_INFO, sizeof(AUTHR_SRV_NO_MATCH_MSG), (const uint8_t *) AUTHR_SRV_NO_MATCH_MSG); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } ret = ERR_ACCESS_DENIED; } return ret; } static errno_t sdap_save_user_cache_bool(struct sss_domain_info *domain, const char *username, const char *attr_name, bool value) { errno_t ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(NULL); if (attrs == NULL) { ret = ENOMEM; DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up attrs\n"); goto done; } ret = sysdb_attrs_add_bool(attrs, attr_name, value); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up attrs\n"); goto done; } ret = sysdb_set_user_attr(domain, username, attrs, SYSDB_MOD_REP); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set user access attribute\n"); goto done; } done: talloc_free(attrs); return ret; } static errno_t sdap_access_host(struct ldb_message *user_entry) { errno_t ret; struct ldb_message_element *el; unsigned int i; char *host; char hostname[HOST_NAME_MAX + 1]; el = ldb_msg_find_element(user_entry, SYSDB_AUTHORIZED_HOST); if (!el || el->num_values == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing hosts. Access denied\n"); return ERR_ACCESS_DENIED; } if (gethostname(hostname, HOST_NAME_MAX) == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get system hostname. Access denied\n"); return ERR_ACCESS_DENIED; } hostname[HOST_NAME_MAX] = '\0'; /* FIXME: PADL's pam_ldap also calls gethostbyname() on the hostname * in some attempt to get aliases and/or FQDN for the machine. * Not sure this is a good idea, but we might want to add it in * order to be compatible... */ ret = ENOENT; for (i = 0; i < el->num_values; i++) { host = (char *)el->values[i].data; if (host[0] == '!' && strcasecmp(hostname, host+1) == 0) { /* This host is explicitly denied */ DEBUG(SSSDBG_CONF_SETTINGS, "Access denied by [%s]\n", host); /* A denial trumps all. Break here */ return ERR_ACCESS_DENIED; } else if (strcasecmp(hostname, host) == 0) { /* This host is explicitly allowed */ DEBUG(SSSDBG_CONF_SETTINGS, "Access granted for [%s]\n", host); /* We still need to loop through to make sure * that it's not also explicitly denied */ ret = EOK; } else if (strcmp("*", host) == 0) { /* This user has access to all hosts */ DEBUG(SSSDBG_CONF_SETTINGS, "Access granted to all hosts\n"); /* We still need to loop through to make sure * that it's not also explicitly denied */ ret = EOK; } } if (ret == ENOENT) { DEBUG(SSSDBG_CONF_SETTINGS, "No matching host rule found\n"); ret = ERR_ACCESS_DENIED; } return ret; } static void sdap_access_ppolicy_get_lockout_done(struct tevent_req *subreq); static int sdap_access_ppolicy_retry(struct tevent_req *req); static errno_t sdap_access_ppolicy_step(struct tevent_req *req); static void sdap_access_ppolicy_step_done(struct tevent_req *subreq); struct sdap_access_ppolicy_req_ctx { const char *username; const char *filter; struct tevent_context *ev; struct sdap_access_ctx *access_ctx; struct sdap_options *opts; struct sdap_id_conn_ctx *conn; struct sdap_id_op *sdap_op; struct sysdb_handle *handle; struct sss_domain_info *domain; /* cached results of access control checks */ bool cached_access; const char *basedn; /* default DNs to ppolicy */ const char **ppolicy_dns; unsigned int ppolicy_dns_index; enum sdap_pwpolicy_mode pwpol_mode; }; static struct tevent_req * sdap_access_ppolicy_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct sss_domain_info *domain, struct sdap_access_ctx *access_ctx, struct sdap_id_conn_ctx *conn, const char *username, struct ldb_message *user_entry, enum sdap_pwpolicy_mode pwpol_mode) { struct sdap_access_ppolicy_req_ctx *state; struct tevent_req *req; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_access_ppolicy_req_ctx); if (req == NULL) { return NULL; } state->filter = NULL; state->username = username; state->opts = access_ctx->id_ctx->opts; state->conn = conn; state->ev = ev; state->access_ctx = access_ctx; state->domain = domain; state->ppolicy_dns_index = 0; state->pwpol_mode = pwpol_mode; DEBUG(SSSDBG_TRACE_FUNC, "Performing access ppolicy check for user [%s]\n", username); state->cached_access = ldb_msg_find_attr_as_bool( user_entry, SYSDB_LDAP_ACCESS_CACHED_LOCKOUT, false); /* Ok, we have one result, check if we are online or offline */ if (be_is_offline(be_ctx)) { /* Ok, we're offline. Return from the cache */ ret = sdap_access_decide_offline(state->cached_access); goto done; } ret = sdap_get_basedn_user_entry(user_entry, state->username, &state->basedn); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Checking ppolicy against LDAP\n"); state->sdap_op = sdap_id_op_create(state, state->conn->conn_cache); if (!state->sdap_op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto done; } ret = sdap_access_ppolicy_retry(req); if (ret != EOK) { goto done; } return req; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static int sdap_access_ppolicy_retry(struct tevent_req *req) { struct sdap_access_ppolicy_req_ctx *state; struct tevent_req *subreq; int ret; state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (!subreq) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: %d (%s)\n", ret, sss_strerror(ret)); return ret; } tevent_req_set_callback(subreq, sdap_access_ppolicy_connect_done, req); return EOK; } static const char** get_default_ppolicy_dns(TALLOC_CTX *mem_ctx, struct sdap_domain *sdom) { const char **ppolicy_dns; int count = 0; int i; while(sdom->search_bases[count] != NULL) { count++; } /* +1 to have space for final NULL */ ppolicy_dns = talloc_array(mem_ctx, const char*, count + 1); for(i = 0; i < count; i++) { ppolicy_dns[i] = talloc_asprintf(mem_ctx, "cn=ppolicy,ou=policies,%s", sdom->search_bases[i]->basedn); } ppolicy_dns[count] = NULL; return ppolicy_dns; } static void sdap_access_ppolicy_connect_done(struct tevent_req *subreq) { struct tevent_req *req; struct sdap_access_ppolicy_req_ctx *state; int ret, dp_error; const char *ppolicy_dn; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { if (dp_error == DP_ERR_OFFLINE) { ret = sdap_access_decide_offline(state->cached_access); if (ret == EOK) { tevent_req_done(req); return; } } tevent_req_error(req, ret); return; } ppolicy_dn = dp_opt_get_string(state->opts->basic, SDAP_PWDLOCKOUT_DN); /* option was configured */ if (ppolicy_dn != NULL) { state->ppolicy_dns = talloc_array(state, const char*, 2); if (state->ppolicy_dns == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate ppolicy_dns.\n"); tevent_req_error(req, ERR_INTERNAL); return; } state->ppolicy_dns[0] = ppolicy_dn; state->ppolicy_dns[1] = NULL; } else { /* try to determine default value */ DEBUG(SSSDBG_CONF_SETTINGS, "ldap_pwdlockout_dn was not defined in configuration file.\n"); state->ppolicy_dns = get_default_ppolicy_dns(state, state->opts->sdom); if (state->ppolicy_dns == NULL) { tevent_req_error(req, ERR_INTERNAL); return; } } /* Connection to LDAP succeeded * Send 'pwdLockout' request */ ret = sdap_access_ppolicy_get_lockout_step(req); if (ret != EOK && ret != EAGAIN) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_ppolicy_get_lockout_step failed: [%d][%s]\n", ret, sss_strerror(ret)); tevent_req_error(req, ERR_INTERNAL); return; } if (ret == EOK) { tevent_req_done(req); } } static errno_t sdap_access_ppolicy_get_lockout_step(struct tevent_req *req) { const char *attrs[] = { SYSDB_LDAP_ACCESS_LOCKOUT, NULL }; struct sdap_access_ppolicy_req_ctx *state; struct tevent_req *subreq; errno_t ret; state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); /* no more DNs to try */ if (state->ppolicy_dns[state->ppolicy_dns_index] == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "No more DNs to try.\n"); ret = EOK; goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Trying to find out if ppolicy is enabled using the DN: %s\n", state->ppolicy_dns[state->ppolicy_dns_index]); subreq = sdap_get_generic_send(state, state->ev, state->opts, sdap_id_op_handle(state->sdap_op), state->ppolicy_dns[state->ppolicy_dns_index], LDAP_SCOPE_BASE, NULL, attrs, NULL, 0, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not start LDAP communication\n"); ret = EIO; goto done; } /* try next basedn */ state->ppolicy_dns_index++; tevent_req_set_callback(subreq, sdap_access_ppolicy_get_lockout_done, req); ret = EAGAIN; done: return ret; } static void sdap_access_ppolicy_get_lockout_done(struct tevent_req *subreq) { int ret, tret, dp_error; size_t num_results; bool pwdLockout = false; struct sysdb_attrs **results; struct tevent_req *req; struct sdap_access_ppolicy_req_ctx *state; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); ret = sdap_get_generic_recv(subreq, state, &num_results, &results); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot retrieve ppolicy\n"); ret = ERR_NETWORK_IO; goto done; } /* Check the number of responses we got * If it's exactly 1, we passed the check * If it's < 1, we failed the check * Anything else is an error */ /* Didn't find ppolicy attribute */ if (num_results < 1) { /* Try using next $search_base */ ret = sdap_access_ppolicy_get_lockout_step(req); if (ret == EOK) { /* No more search bases to try */ DEBUG(SSSDBG_CONF_SETTINGS, "[%s] was not found. Granting access.\n", SYSDB_LDAP_ACCESS_LOCKOUT); } else { if (ret != EAGAIN) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_ppolicy_get_lockout_step failed: " "[%d][%s]\n", ret, sss_strerror(ret)); } goto done; } } else if (results == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "num_results > 0, but results is NULL\n"); ret = ERR_INTERNAL; goto done; } else if (num_results > 1) { /* It should not be possible to get more than one reply * here, since we're doing a base-scoped search */ DEBUG(SSSDBG_CRIT_FAILURE, "Received multiple replies\n"); ret = ERR_INTERNAL; goto done; } else { /* Ok, we got a single reply */ ret = sysdb_attrs_get_bool(results[0], SYSDB_LDAP_ACCESS_LOCKOUT, &pwdLockout); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Error reading %s: [%s]\n", SYSDB_LDAP_ACCESS_LOCKOUT, sss_strerror(ret)); ret = ERR_INTERNAL; goto done; } } if (pwdLockout) { DEBUG(SSSDBG_TRACE_FUNC, "Password policy is enabled on LDAP server.\n"); /* ppolicy is enabled => find out if account is locked */ ret = sdap_access_ppolicy_step(req); if (ret != EOK && ret != EAGAIN) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_ppolicy_step failed: [%d][%s].\n", ret, sss_strerror(ret)); } goto done; } else { DEBUG(SSSDBG_TRACE_FUNC, "Password policy is disabled on LDAP server " "- storing 'access granted' in sysdb.\n"); tret = sdap_save_user_cache_bool(state->domain, state->username, SYSDB_LDAP_ACCESS_CACHED_LOCKOUT, true); if (tret != EOK) { /* Failing to save to the cache is non-fatal. * Just return the result. */ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set user locked attribute\n"); goto done; } ret = EOK; goto done; } done: if (ret != EAGAIN) { /* release connection */ tret = sdap_id_op_done(state->sdap_op, ret, &dp_error); if (tret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_get_generic_send() returned error [%d][%s]\n", ret, sss_strerror(ret)); } if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } } errno_t sdap_access_ppolicy_step(struct tevent_req *req) { errno_t ret; struct tevent_req *subreq; struct sdap_access_ppolicy_req_ctx *state; const char *attrs[] = { SYSDB_LDAP_ACCESS_LOCKED_TIME, SYSDB_LDAP_ACESS_LOCKOUT_DURATION, NULL }; state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); subreq = sdap_get_generic_send(state, state->ev, state->opts, sdap_id_op_handle(state->sdap_op), state->basedn, LDAP_SCOPE_BASE, NULL, attrs, NULL, 0, dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT), false); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_access_ppolicy_send failed.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_access_ppolicy_step_done, req); ret = EAGAIN; done: return ret; } static errno_t is_account_locked(const char *pwdAccountLockedTime, const char *pwdAccountLockedDurationTime, enum sdap_pwpolicy_mode pwpol_mode, const char *username, bool *_locked) { errno_t ret; time_t lock_time; time_t duration; time_t now; bool locked; /* Default action is to consider account to be locked. */ locked = true; /* account is permanently locked */ if (strcasecmp(pwdAccountLockedTime, PERMANENTLY_LOCKED_ACCOUNT) == 0) { ret = EOK; goto done; } switch(pwpol_mode) { case PWP_LOCKOUT_ONLY: /* We do *not* care about exact value of account locked time, we * only *do* care if the value is equal to * PERMANENTLY_LOCKED_ACCOUNT, which means that account is locked * permanently. */ DEBUG(SSSDBG_TRACE_FUNC, "Account of: %s is being blocked by password policy, " "but value: [%s] value is ignored by SSSD.\n", username, pwdAccountLockedTime); locked = false; break; case PWP_LOCKOUT_EXPIRE: /* Account may be locked out from natural reasons (too many attempts, * expired password). In this case, pwdAccountLockedTime is also set, * to the time of lock out. */ ret = sss_utc_to_time_t(pwdAccountLockedTime, "%Y%m%d%H%M%SZ", &lock_time); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "sss_utc_to_time_t failed with %d:%s.\n", ret, sss_strerror(ret)); goto done; } now = time(NULL); /* Account was NOT locked in past. */ if (difftime(lock_time, now) > 0.0) { locked = false; } else if (pwdAccountLockedDurationTime != NULL) { errno = 0; duration = strtouint32(pwdAccountLockedDurationTime, NULL, 0); if (errno) { ret = errno; goto done; } /* Lockout has expired */ if (duration != 0 && difftime(now, lock_time) > duration) { locked = false; } } break; case PWP_SENTINEL: default: DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected value of password policy mode: %d.\n", pwpol_mode); ret = EINVAL; goto done; } ret = EOK; done: if (ret == EOK) { *_locked = locked; } return ret; } static void sdap_access_ppolicy_step_done(struct tevent_req *subreq) { int ret, tret, dp_error; size_t num_results; bool locked = false; const char *pwdAccountLockedTime; const char *pwdAccountLockedDurationTime; struct sysdb_attrs **results; struct tevent_req *req; struct sdap_access_ppolicy_req_ctx *state; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_access_ppolicy_req_ctx); ret = sdap_get_generic_recv(subreq, state, &num_results, &results); talloc_zfree(subreq); ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); if (ret != EOK) { if (dp_error == DP_ERR_OK) { /* retry */ tret = sdap_access_ppolicy_retry(req); if (tret == EOK) { return; } } else if (dp_error == DP_ERR_OFFLINE) { ret = sdap_access_decide_offline(state->cached_access); } else { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_get_generic_send() returned error [%d][%s]\n", ret, sss_strerror(ret)); } goto done; } /* Check the number of responses we got * If it's exactly 1, we passed the check * If it's < 1, we failed the check * Anything else is an error */ if (num_results < 1) { DEBUG(SSSDBG_CONF_SETTINGS, "User [%s] was not found with the specified filter. " "Denying access.\n", state->username); } else if (results == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "num_results > 0, but results is NULL\n"); ret = ERR_INTERNAL; goto done; } else if (num_results > 1) { /* It should not be possible to get more than one reply * here, since we're doing a base-scoped search */ DEBUG(SSSDBG_CRIT_FAILURE, "Received multiple replies\n"); ret = ERR_INTERNAL; goto done; } else { /* Ok, we got a single reply */ ret = sysdb_attrs_get_string(results[0], SYSDB_LDAP_ACESS_LOCKOUT_DURATION, &pwdAccountLockedDurationTime); if (ret != EOK) { /* This attribute might not be set even if account is locked */ pwdAccountLockedDurationTime = NULL; } ret = sysdb_attrs_get_string(results[0], SYSDB_LDAP_ACCESS_LOCKED_TIME, &pwdAccountLockedTime); if (ret == EOK) { ret = is_account_locked(pwdAccountLockedTime, pwdAccountLockedDurationTime, state->pwpol_mode, state->username, &locked); if (ret != EOK) { if (ret == ERR_TIMESPEC_NOT_SUPPORTED) { DEBUG(SSSDBG_MINOR_FAILURE, "timezone specifier in ppolicy is not supported\n"); } else { DEBUG(SSSDBG_MINOR_FAILURE, "is_account_locked failed: %d:[%s].\n", ret, sss_strerror(ret)); } DEBUG(SSSDBG_MINOR_FAILURE, "Account will be considered to be locked.\n"); locked = true; } } else { /* Attribute SYSDB_LDAP_ACCESS_LOCKED_TIME in not be present unless * user's account is blocked by password policy. */ DEBUG(SSSDBG_TRACE_INTERNAL, "Attribute %s failed to be obtained - [%d][%s].\n", SYSDB_LDAP_ACCESS_LOCKED_TIME, ret, strerror(ret)); } } if (locked) { DEBUG(SSSDBG_TRACE_FUNC, "Access denied by online lookup - account is locked.\n"); ret = ERR_ACCESS_DENIED; } else { DEBUG(SSSDBG_TRACE_FUNC, "Access granted by online lookup - account is not locked.\n"); ret = EOK; } /* Save '!locked' to the cache for future offline access checks. * Locked == true => access denied, * Locked == false => access granted */ tret = sdap_save_user_cache_bool(state->domain, state->username, SYSDB_LDAP_ACCESS_CACHED_LOCKOUT, !locked); if (tret != EOK) { /* Failing to save to the cache is non-fatal. * Just return the result. */ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set user locked attribute\n"); goto done; } done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } static errno_t sdap_access_ppolicy_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static errno_t sdap_get_basedn_user_entry(struct ldb_message *user_entry, const char *username, const char **_basedn) { const char *basedn; errno_t ret; basedn = ldb_msg_find_attr_as_string(user_entry, SYSDB_ORIG_DN, NULL); if (basedn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE,"Could not find originalDN for user [%s]\n", username); ret = EINVAL; goto done; } *_basedn = basedn; ret = EOK; done: return ret; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_fd_events.c0000644000000000000000000000007412703456111021201 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.789794087 sssd-1.13.4/src/providers/ldap/sdap_fd_events.c0000644002412700241270000002202312703456111022647 0ustar00jhrozekjhrozek00000000000000/* SSSD Helper routines for file descriptor events Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "providers/ldap/sdap_async_private.h" struct sdap_fd_events { #ifdef HAVE_LDAP_CONNCB struct ldap_conncb *conncb; #else struct tevent_fd *fde; #endif }; int get_fd_from_ldap(LDAP *ldap, int *fd) { int ret; ret = ldap_get_option(ldap, LDAP_OPT_DESC, fd); if (ret != LDAP_OPT_SUCCESS || *fd < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get fd from ldap!!\n"); *fd = -1; return EIO; } return EOK; } int remove_ldap_connection_callbacks(struct sdap_handle *sh) { /* sdap_fd_events might be NULL here if the back end was marked offline * before a connection was established. */ if (sh->sdap_fd_events) { #ifdef HAVE_LDAP_CONNCB talloc_zfree(sh->sdap_fd_events->conncb); #else talloc_zfree(sh->sdap_fd_events->fde); #endif } return EOK; } #ifdef HAVE_LDAP_CONNCB static int remove_connection_callback(TALLOC_CTX *mem_ctx) { int lret; struct ldap_conncb *conncb = talloc_get_type(mem_ctx, struct ldap_conncb); struct ldap_cb_data *cb_data = talloc_get_type(conncb->lc_arg, struct ldap_cb_data); lret = ldap_get_option(cb_data->sh->ldap, LDAP_OPT_CONNECT_CB, conncb); if (lret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to remove connection callback.\n"); } else { DEBUG(SSSDBG_TRACE_ALL, "Successfully removed connection callback.\n"); } return EOK; } static int sdap_ldap_connect_callback_add(LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv, struct sockaddr *addr, struct ldap_conncb *ctx) { int ret; ber_socket_t ber_fd; struct fd_event_item *fd_event_item; struct ldap_cb_data *cb_data = talloc_get_type(ctx->lc_arg, struct ldap_cb_data); if (cb_data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_ldap_connect_callback_add called without " "callback data.\n"); return EINVAL; } ret = ber_sockbuf_ctrl(sb, LBER_SB_OPT_GET_FD, &ber_fd); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "ber_sockbuf_ctrl failed.\n"); return EINVAL; } if (DEBUG_IS_SET(SSSDBG_TRACE_LIBS)) { char *uri = ldap_url_desc2str(srv); DEBUG(SSSDBG_TRACE_LIBS, "New LDAP connection to [%s] with fd [%d].\n", uri, ber_fd); free(uri); } fd_event_item = talloc_zero(cb_data, struct fd_event_item); if (fd_event_item == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); return ENOMEM; } fd_event_item->fde = tevent_add_fd(cb_data->ev, fd_event_item, ber_fd, TEVENT_FD_READ, sdap_ldap_result, cb_data->sh); if (fd_event_item->fde == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_fd failed.\n"); talloc_free(fd_event_item); return ENOMEM; } fd_event_item->fd = ber_fd; DLIST_ADD(cb_data->fd_list, fd_event_item); return LDAP_SUCCESS; } static void sdap_ldap_connect_callback_del(LDAP *ld, Sockbuf *sb, struct ldap_conncb *ctx) { int ret; ber_socket_t ber_fd; struct fd_event_item *fd_event_item; struct ldap_cb_data *cb_data = talloc_get_type(ctx->lc_arg, struct ldap_cb_data); if (sb == NULL || cb_data == NULL) { return; } ret = ber_sockbuf_ctrl(sb, LBER_SB_OPT_GET_FD, &ber_fd); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "ber_sockbuf_ctrl failed.\n"); return; } DEBUG(SSSDBG_TRACE_ALL, "Closing LDAP connection with fd [%d].\n", ber_fd); DLIST_FOR_EACH(fd_event_item, cb_data->fd_list) { if (fd_event_item->fd == ber_fd) { break; } } if (fd_event_item == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No event for fd [%d] found.\n", ber_fd); return; } DLIST_REMOVE(cb_data->fd_list, fd_event_item); talloc_zfree(fd_event_item); return; } #else static int sdap_install_ldap_callbacks(struct sdap_handle *sh, struct tevent_context *ev) { int fd; int ret; if (sh->sdap_fd_events) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_install_ldap_callbacks is called with already " "initialized sdap_fd_events.\n"); return EINVAL; } sh->sdap_fd_events = talloc_zero(sh, struct sdap_fd_events); if (!sh->sdap_fd_events) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ret = get_fd_from_ldap(sh->ldap, &fd); if (ret) return ret; sh->sdap_fd_events->fde = tevent_add_fd(ev, sh->sdap_fd_events, fd, TEVENT_FD_READ, sdap_ldap_result, sh); if (!sh->sdap_fd_events->fde) { talloc_zfree(sh->sdap_fd_events); return ENOMEM; } DEBUG(SSSDBG_TRACE_INTERNAL, "Trace: sh[%p], connected[%d], ops[%p], fde[%p], ldap[%p]\n", sh, (int)sh->connected, sh->ops, sh->sdap_fd_events->fde, sh->ldap); return EOK; } #endif errno_t setup_ldap_connection_callbacks(struct sdap_handle *sh, struct tevent_context *ev) { #ifdef HAVE_LDAP_CONNCB int ret; struct ldap_cb_data *cb_data; sh->sdap_fd_events = talloc_zero(sh, struct sdap_fd_events); if (sh->sdap_fd_events == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; goto fail; } sh->sdap_fd_events->conncb = talloc_zero(sh->sdap_fd_events, struct ldap_conncb); if (sh->sdap_fd_events->conncb == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; goto fail; } cb_data = talloc_zero(sh->sdap_fd_events->conncb, struct ldap_cb_data); if (cb_data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; goto fail; } cb_data->sh = sh; cb_data->ev = ev; sh->sdap_fd_events->conncb->lc_add = sdap_ldap_connect_callback_add; sh->sdap_fd_events->conncb->lc_del = sdap_ldap_connect_callback_del; sh->sdap_fd_events->conncb->lc_arg = cb_data; ret = ldap_set_option(sh->ldap, LDAP_OPT_CONNECT_CB, sh->sdap_fd_events->conncb); if (ret != LDAP_OPT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set connection callback\n"); ret = EFAULT; goto fail; } talloc_set_destructor((TALLOC_CTX *) sh->sdap_fd_events->conncb, remove_connection_callback); return EOK; fail: talloc_zfree(sh->sdap_fd_events); return ret; #else DEBUG(SSSDBG_TRACE_ALL, "LDAP connection callbacks are not supported.\n"); return EOK; #endif } errno_t sdap_set_connected(struct sdap_handle *sh, struct tevent_context *ev) { int ret = EOK; sh->connected = true; #ifndef HAVE_LDAP_CONNCB ret = sdap_install_ldap_callbacks(sh, ev); #endif return ret; } errno_t sdap_call_conn_cb(const char *uri,int fd, struct sdap_handle *sh) { #ifdef HAVE_LDAP_CONNCB int ret; Sockbuf *sb; LDAPURLDesc *lud; sb = ber_sockbuf_alloc(); if (sb == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "ber_sockbuf_alloc failed.\n"); return ENOMEM; } ret = ber_sockbuf_ctrl(sb, LBER_SB_OPT_SET_FD, &fd); if (ret != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "ber_sockbuf_ctrl failed.\n"); return EFAULT; } ret = ldap_url_parse(uri, &lud); if (ret != 0) { ber_sockbuf_free(sb); DEBUG(SSSDBG_CRIT_FAILURE, "ldap_url_parse failed to validate [%s] on fd [%d].\n", uri, fd); return EFAULT; } ret = sdap_ldap_connect_callback_add(NULL, sb, lud, NULL, sh->sdap_fd_events->conncb); ldap_free_urldesc(lud); ber_sockbuf_free(sb); return ret; #else DEBUG(SSSDBG_TRACE_ALL, "LDAP connection callbacks are not supported.\n"); return EOK; #endif } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/ldap_init.c0000644000000000000000000000007412703456111020160 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.767794012 sssd-1.13.4/src/providers/ldap/ldap_init.c0000644002412700241270000004043112703456111021631 0ustar00jhrozekjhrozek00000000000000/* SSSD LDAP Provider Initialization functions Authors: Simo Sorce Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/child_common.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/sdap_access.h" #include "providers/ldap/sdap_sudo.h" #include "providers/ldap/sdap_autofs.h" #include "providers/ldap/sdap_idmap.h" #include "providers/fail_over_srv.h" #include "providers/dp_refresh.h" static void sdap_shutdown(struct be_req *req); /* Id Handler */ struct bet_ops sdap_id_ops = { .handler = sdap_account_info_handler, .finalize = sdap_shutdown, .check_online = sdap_check_online }; /* Auth Handler */ struct bet_ops sdap_auth_ops = { .handler = sdap_pam_auth_handler, .finalize = sdap_shutdown }; /* Chpass Handler */ struct bet_ops sdap_chpass_ops = { .handler = sdap_pam_chpass_handler, .finalize = sdap_shutdown }; /* Access Handler */ struct bet_ops sdap_access_ops = { .handler = sdap_pam_access_handler, .finalize = sdap_shutdown }; /* Please use this only for short lists */ errno_t check_order_list_for_duplicates(char **list, bool case_sensitive) { size_t c; size_t d; int cmp; for (c = 0; list[c] != NULL; c++) { for (d = c + 1; list[d] != NULL; d++) { if (case_sensitive) { cmp = strcmp(list[c], list[d]); } else { cmp = strcasecmp(list[c], list[d]); } if (cmp == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Duplicate string [%s] found.\n", list[c]); return EINVAL; } } } return EOK; } static int ldap_id_init_internal(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { struct sdap_id_ctx *ctx = NULL; const char *urls; const char *backup_urls; const char *dns_service_name; const char *sasl_mech; struct sdap_service *sdap_service; struct sdap_options *opts = NULL; int ret; /* If we're already set up, just return that */ if(bectx->bet_info[BET_ID].mod_name && strcmp("ldap", bectx->bet_info[BET_ID].mod_name) == 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "Re-using sdap_id_ctx for this provider\n"); *ops = bectx->bet_info[BET_ID].bet_ops; *pvt_data = bectx->bet_info[BET_ID].pvt_bet_data; return EOK; } ret = ldap_get_options(bectx, bectx->domain, bectx->cdb, bectx->conf_path, &opts); if (ret != EOK) { goto done; } dns_service_name = dp_opt_get_string(opts->basic, SDAP_DNS_SERVICE_NAME); DEBUG(SSSDBG_CONF_SETTINGS, "Service name for discovery set to %s\n", dns_service_name); urls = dp_opt_get_string(opts->basic, SDAP_URI); backup_urls = dp_opt_get_string(opts->basic, SDAP_BACKUP_URI); ret = sdap_service_init(bectx, bectx, "LDAP", dns_service_name, urls, backup_urls, &sdap_service); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to initialize failover service!\n"); goto done; } ctx = sdap_id_ctx_new(bectx, bectx, sdap_service); if (!ctx) { ret = ENOMEM; goto done; } ctx->opts = talloc_steal(ctx, opts); sasl_mech = dp_opt_get_string(ctx->opts->basic, SDAP_SASL_MECH); if (sasl_mech && strcasecmp(sasl_mech, "GSSAPI") == 0) { if (dp_opt_get_bool(ctx->opts->basic, SDAP_KRB5_KINIT)) { ret = sdap_gssapi_init(ctx, ctx->opts->basic, ctx->be, ctx->conn->service, &ctx->krb5_service); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_gssapi_init failed [%d][%s].\n", ret, strerror(ret)); goto done; } } } ret = setup_tls_config(ctx->opts->basic); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "setup_tls_config failed [%d][%s].\n", ret, strerror(ret)); goto done; } /* Set up the ID mapping object */ ret = sdap_idmap_init(ctx, ctx, &ctx->opts->idmap_ctx); if (ret != EOK) goto done; ret = sdap_setup_child(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "setup_child failed [%d][%s].\n", ret, strerror(ret)); goto done; } /* setup SRV lookup plugin */ ret = be_fo_set_dns_srv_lookup_plugin(bectx, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin " "[%d]: %s\n", ret, strerror(ret)); goto done; } /* setup periodical refresh of expired records */ ret = sdap_refresh_init(bectx->refresh_ctx, ctx); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh " "will not work [%d]: %s\n", ret, strerror(ret)); } *ops = &sdap_id_ops; *pvt_data = ctx; ret = EOK; done: if (ret != EOK) { talloc_free(opts); talloc_free(ctx); } return ret; } int sssm_ldap_id_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret; struct sdap_id_ctx *ctx = NULL; ret = ldap_id_init_internal(bectx, ops, (void **) &ctx); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "ldap_id_init_internal failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = ldap_id_setup_tasks(ctx); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sdap_id_setup_tasks failed [%d][%s].\n", ret, strerror(ret)); goto done; } *pvt_data = ctx; ret = EOK; done: if (ret != EOK) { talloc_free(ctx); } return ret; } int sssm_ldap_auth_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { void *data; struct sdap_id_ctx *id_ctx; struct sdap_auth_ctx *ctx; int ret; ret = ldap_id_init_internal(bectx, ops, &data); if (ret == EOK) { id_ctx = talloc_get_type(data, struct sdap_id_ctx); ctx = talloc(bectx, struct sdap_auth_ctx); if (!ctx) return ENOMEM; ctx->be = bectx; ctx->opts = id_ctx->opts; ctx->service = id_ctx->conn->service; ctx->chpass_service = NULL; *ops = &sdap_auth_ops; *pvt_data = ctx; } return ret; } int sssm_ldap_chpass_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret; void *data; struct sdap_auth_ctx *ctx = NULL; const char *urls; const char *backup_urls; const char *dns_service_name; ret = sssm_ldap_auth_init(bectx, ops, &data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssm_ldap_auth_init failed.\n"); goto done; } ctx = talloc_get_type(data, struct sdap_auth_ctx); dns_service_name = dp_opt_get_string(ctx->opts->basic, SDAP_CHPASS_DNS_SERVICE_NAME); if (dns_service_name) { DEBUG(SSSDBG_TRACE_LIBS, "Service name for chpass discovery set to %s\n", dns_service_name); } urls = dp_opt_get_string(ctx->opts->basic, SDAP_CHPASS_URI); backup_urls = dp_opt_get_string(ctx->opts->basic, SDAP_CHPASS_BACKUP_URI); if (!urls && !backup_urls && !dns_service_name) { DEBUG(SSSDBG_TRACE_ALL, "ldap_chpass_uri and ldap_chpass_dns_service_name not set, " "using ldap_uri.\n"); ctx->chpass_service = NULL; } else { ret = sdap_service_init(ctx, ctx->be, "LDAP_CHPASS", dns_service_name, urls, backup_urls, &ctx->chpass_service); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize failover service!\n"); goto done; } } *ops = &sdap_chpass_ops; *pvt_data = ctx; ret = EOK; done: if (ret != EOK) { talloc_free(ctx); } return ret; } int sssm_ldap_access_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data) { int ret; struct sdap_access_ctx *access_ctx; const char *filter; const char *order; char **order_list; int order_list_len; size_t c; const char *dummy; access_ctx = talloc_zero(bectx, struct sdap_access_ctx); if(access_ctx == NULL) { ret = ENOMEM; goto done; } ret = ldap_id_init_internal(bectx, ops, (void **)&access_ctx->id_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_id_init_internal failed.\n"); goto done; } order = dp_opt_get_cstring(access_ctx->id_ctx->opts->basic, SDAP_ACCESS_ORDER); if (order == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_access_order not given, using 'filter'.\n"); order = "filter"; } ret = split_on_separator(access_ctx, order, ',', true, true, &order_list, &order_list_len); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "split_on_separator failed.\n"); goto done; } ret = check_order_list_for_duplicates(order_list, false); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "check_order_list_for_duplicates failed.\n"); goto done; } if (order_list_len > LDAP_ACCESS_LAST) { DEBUG(SSSDBG_CRIT_FAILURE, "Currently only [%d] different access rules are supported.\n", LDAP_ACCESS_LAST); ret = EINVAL; goto done; } for (c = 0; order_list[c] != NULL; c++) { if (strcasecmp(order_list[c], LDAP_ACCESS_FILTER_NAME) == 0) { access_ctx->access_rule[c] = LDAP_ACCESS_FILTER; filter = dp_opt_get_cstring(access_ctx->id_ctx->opts->basic, SDAP_ACCESS_FILTER); if (filter == NULL) { /* It's okay if this is NULL. In that case we will simply act * like the 'deny' provider. */ DEBUG(SSSDBG_FATAL_FAILURE, "Warning: LDAP access rule 'filter' is set, " "but no ldap_access_filter configured. " "All domain users will be denied access.\n"); } else { access_ctx->filter = sdap_get_access_filter(access_ctx, filter); if (access_ctx->filter == NULL) { ret = ENOMEM; goto done; } } } else if (strcasecmp(order_list[c], LDAP_ACCESS_EXPIRE_NAME) == 0) { access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE; dummy = dp_opt_get_cstring(access_ctx->id_ctx->opts->basic, SDAP_ACCOUNT_EXPIRE_POLICY); if (dummy == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Warning: LDAP access rule 'expire' is set, " "but no ldap_account_expire_policy configured. " "All domain users will be denied access.\n"); } else { if (strcasecmp(dummy, LDAP_ACCOUNT_EXPIRE_SHADOW) != 0 && strcasecmp(dummy, LDAP_ACCOUNT_EXPIRE_AD) != 0 && strcasecmp(dummy, LDAP_ACCOUNT_EXPIRE_NDS) != 0 && strcasecmp(dummy, LDAP_ACCOUNT_EXPIRE_RHDS) != 0 && strcasecmp(dummy, LDAP_ACCOUNT_EXPIRE_IPA) != 0 && strcasecmp(dummy, LDAP_ACCOUNT_EXPIRE_389DS) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported LDAP account expire policy [%s].\n", dummy); ret = EINVAL; goto done; } } } else if (strcasecmp(order_list[c], LDAP_ACCESS_SERVICE_NAME) == 0) { access_ctx->access_rule[c] = LDAP_ACCESS_SERVICE; } else if (strcasecmp(order_list[c], LDAP_ACCESS_HOST_NAME) == 0) { access_ctx->access_rule[c] = LDAP_ACCESS_HOST; } else if (strcasecmp(order_list[c], LDAP_ACCESS_LOCK_NAME) == 0) { access_ctx->access_rule[c] = LDAP_ACCESS_LOCKOUT; } else if (strcasecmp(order_list[c], LDAP_ACCESS_EXPIRE_POLICY_REJECT_NAME) == 0) { access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE_POLICY_REJECT; } else if (strcasecmp(order_list[c], LDAP_ACCESS_EXPIRE_POLICY_WARN_NAME) == 0) { access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE_POLICY_WARN; } else if (strcasecmp(order_list[c], LDAP_ACCESS_EXPIRE_POLICY_RENEW_NAME) == 0) { access_ctx->access_rule[c] = LDAP_ACCESS_EXPIRE_POLICY_RENEW; } else if (strcasecmp(order_list[c], LDAP_ACCESS_PPOLICY_NAME) == 0) { access_ctx->access_rule[c] = LDAP_ACCESS_PPOLICY; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected access rule name [%s].\n", order_list[c]); ret = EINVAL; goto done; } } access_ctx->access_rule[c] = LDAP_ACCESS_EMPTY; if (c == 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Warning: access_provider=ldap set, " "but ldap_access_order is empty. " "All domain users will be denied access.\n"); } *ops = &sdap_access_ops; *pvt_data = access_ctx; ret = EOK; done: if (ret != EOK) { talloc_free(access_ctx); } return ret; } int sssm_ldap_sudo_init(struct be_ctx *be_ctx, struct bet_ops **ops, void **pvt_data) { #ifdef BUILD_SUDO struct sdap_id_ctx *id_ctx; void *data; int ret; ret = ldap_id_init_internal(be_ctx, ops, &data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init LDAP ID provider [%d]: %s\n", ret, strerror(ret)); return ret; } id_ctx = talloc_get_type(data, struct sdap_id_ctx); if (!id_ctx) { DEBUG(SSSDBG_CRIT_FAILURE, "No ID provider?\n"); return EIO; } return sdap_sudo_init(be_ctx, id_ctx, ops, pvt_data); #else DEBUG(SSSDBG_MINOR_FAILURE, "Sudo init handler called but SSSD is " "built without sudo support, ignoring\n"); return EOK; #endif } int sssm_ldap_autofs_init(struct be_ctx *be_ctx, struct bet_ops **ops, void **pvt_data) { #ifdef BUILD_AUTOFS struct sdap_id_ctx *id_ctx; void *data; int ret; ret = ldap_id_init_internal(be_ctx, ops, &data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init LDAP ID provider [%d]: %s\n", ret, strerror(ret)); return ret; } id_ctx = talloc_get_type(data, struct sdap_id_ctx); if (!id_ctx) { DEBUG(SSSDBG_CRIT_FAILURE, "No ID provider?\n"); return EIO; } return sdap_autofs_init(be_ctx, id_ctx, ops, pvt_data); #else DEBUG(SSSDBG_MINOR_FAILURE, "Autofs init handler called but SSSD is " "built without autofs support, ignoring\n"); return EOK; #endif } static void sdap_shutdown(struct be_req *req) { /* TODO: Clean up any internal data */ sdap_handler_done(req, DP_ERR_OK, EOK, NULL); } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_sudo.c0000644000000000000000000000007312703456111021372 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.801794127 sssd-1.13.4/src/providers/ldap/sdap_async_sudo.c0000644002412700241270000004267612703456111023061 0ustar00jhrozekjhrozek00000000000000/* SSSD Async LDAP Helper routines for sudo Authors: Pavel Březina Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "providers/dp_backend.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_ops.h" #include "providers/ldap/sdap_sudo.h" #include "providers/ldap/sdap_sudo_shared.h" #include "db/sysdb_sudo.h" struct sdap_sudo_load_sudoers_state { struct sysdb_attrs **rules; size_t num_rules; }; static void sdap_sudo_load_sudoers_done(struct tevent_req *subreq); static struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *ldap_filter) { struct tevent_req *req; struct tevent_req *subreq; struct sdap_sudo_load_sudoers_state *state; struct sdap_search_base **sb; int ret; req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_load_sudoers_state); if (!req) { return NULL; } state->rules = NULL; state->num_rules = 0; sb = opts->sdom->sudo_search_bases; if (sb == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "SUDOERS lookup request without a search base\n"); ret = EINVAL; goto immediately; } DEBUG(SSSDBG_TRACE_FUNC, "About to fetch sudo rules\n"); subreq = sdap_search_bases_send(state, ev, opts, sh, sb, opts->sudorule_map, true, 0, ldap_filter, NULL); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sdap_sudo_load_sudoers_done, req); ret = EOK; immediately: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void sdap_sudo_load_sudoers_done(struct tevent_req *subreq) { struct tevent_req *req; struct sdap_sudo_load_sudoers_state *state; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_sudo_load_sudoers_state); ret = sdap_search_bases_recv(subreq, state, &state->num_rules, &state->rules); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_IMPORTANT_INFO, "Received %zu sudo rules\n", state->num_rules); tevent_req_done(req); return; } static int sdap_sudo_load_sudoers_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *num_rules, struct sysdb_attrs ***rules) { struct sdap_sudo_load_sudoers_state *state; state = tevent_req_data(req, struct sdap_sudo_load_sudoers_state); TEVENT_REQ_RETURN_ON_ERROR(req); *num_rules = state->num_rules; *rules = talloc_steal(mem_ctx, state->rules); return EOK; } static char *sdap_sudo_build_host_filter(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, char **hostnames, char **ip_addr, bool netgroups, bool regexp) { TALLOC_CTX *tmp_ctx = NULL; char *filter = NULL; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return NULL; } filter = talloc_strdup(tmp_ctx, "(|"); if (filter == NULL) { goto done; } /* sudoHost is not specified */ filter = talloc_asprintf_append_buffer(filter, "(!(%s=*))", map[SDAP_AT_SUDO_HOST].name); if (filter == NULL) { goto done; } /* ALL */ filter = talloc_asprintf_append_buffer(filter, "(%s=ALL)", map[SDAP_AT_SUDO_HOST].name); if (filter == NULL) { goto done; } /* hostnames */ if (hostnames != NULL) { for (i = 0; hostnames[i] != NULL; i++) { filter = talloc_asprintf_append_buffer(filter, "(%s=%s)", map[SDAP_AT_SUDO_HOST].name, hostnames[i]); if (filter == NULL) { goto done; } } } /* ip addresses and networks */ if (ip_addr != NULL) { for (i = 0; ip_addr[i] != NULL; i++) { filter = talloc_asprintf_append_buffer(filter, "(%s=%s)", map[SDAP_AT_SUDO_HOST].name, ip_addr[i]); if (filter == NULL) { goto done; } } } /* sudoHost contains netgroup - will be filtered more by sudo */ if (netgroups) { filter = talloc_asprintf_append_buffer(filter, SDAP_SUDO_FILTER_NETGROUP, map[SDAP_AT_SUDO_HOST].name, "*"); if (filter == NULL) { goto done; } } /* sudoHost contains regexp - will be filtered more by sudo */ /* from sudo match.c : * #define has_meta(s) (strpbrk(s, "\\?*[]") != NULL) */ if (regexp) { filter = talloc_asprintf_append_buffer(filter, "(|(%s=*\\\\*)(%s=*?*)(%s=*\\2A*)" "(%s=*[*]*))", map[SDAP_AT_SUDO_HOST].name, map[SDAP_AT_SUDO_HOST].name, map[SDAP_AT_SUDO_HOST].name, map[SDAP_AT_SUDO_HOST].name); if (filter == NULL) { goto done; } } filter = talloc_strdup_append_buffer(filter, ")"); if (filter == NULL) { goto done; } talloc_steal(mem_ctx, filter); done: talloc_free(tmp_ctx); return filter; } static char *sdap_sudo_get_filter(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map, struct sdap_sudo_ctx *sudo_ctx, const char *rule_filter) { TALLOC_CTX *tmp_ctx = NULL; char *host_filter = NULL; char *filter = NULL; if (!sudo_ctx->use_host_filter) { return talloc_strdup(mem_ctx, rule_filter); } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return NULL; } host_filter = sdap_sudo_build_host_filter(tmp_ctx, map, sudo_ctx->hostnames, sudo_ctx->ip_addr, sudo_ctx->include_netgroups, sudo_ctx->include_regexp); if (host_filter == NULL) { goto done; } filter = sdap_combine_filters(tmp_ctx, rule_filter, host_filter); if (filter == NULL) { goto done; } talloc_steal(mem_ctx, filter); done: talloc_free(tmp_ctx); return filter; } struct sdap_sudo_refresh_state { struct sdap_sudo_ctx *sudo_ctx; struct tevent_context *ev; struct sdap_server_opts *srv_opts; struct sdap_options *opts; struct sdap_id_op *sdap_op; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; const char *search_filter; const char *delete_filter; int dp_error; size_t num_rules; }; static errno_t sdap_sudo_refresh_retry(struct tevent_req *req); static void sdap_sudo_refresh_connect_done(struct tevent_req *subreq); static void sdap_sudo_refresh_hostinfo_done(struct tevent_req *subreq); static errno_t sdap_sudo_refresh_sudoers(struct tevent_req *req); static void sdap_sudo_refresh_done(struct tevent_req *subreq); struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx, struct sdap_sudo_ctx *sudo_ctx, const char *search_filter, const char *delete_filter) { struct tevent_req *req; struct sdap_sudo_refresh_state *state; struct sdap_id_ctx *id_ctx = sudo_ctx->id_ctx; int ret; req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_refresh_state); if (!req) { return NULL; } /* if we don't have a search filter, this request is meaningless */ if (search_filter == NULL) { ret = EINVAL; goto immediately; } state->sudo_ctx = sudo_ctx; state->ev = id_ctx->be->ev; state->opts = id_ctx->opts; state->domain = id_ctx->be->domain; state->sysdb = id_ctx->be->domain->sysdb; state->dp_error = DP_ERR_FATAL; state->sdap_op = sdap_id_op_create(state, id_ctx->conn->conn_cache); if (!state->sdap_op) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create() failed\n"); ret = ENOMEM; goto immediately; } state->search_filter = talloc_strdup(state, search_filter); if (state->search_filter == NULL) { ret = ENOMEM; goto immediately; } state->delete_filter = talloc_strdup(state, delete_filter); if (delete_filter != NULL && state->delete_filter == NULL) { ret = ENOMEM; goto immediately; } ret = sdap_sudo_refresh_retry(req); if (ret == EAGAIN) { /* asynchronous processing */ return req; } immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, id_ctx->be->ev); return req; } static errno_t sdap_sudo_refresh_retry(struct tevent_req *req) { struct sdap_sudo_refresh_state *state; struct tevent_req *subreq; int ret; state = tevent_req_data(req, struct sdap_sudo_refresh_state); subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_id_op_connect_send() failed: " "%d(%s)\n", ret, strerror(ret)); return ret; } tevent_req_set_callback(subreq, sdap_sudo_refresh_connect_done, req); return EAGAIN; } static void sdap_sudo_refresh_connect_done(struct tevent_req *subreq) { struct tevent_req *req; struct sdap_sudo_refresh_state *state; int dp_error; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_sudo_refresh_state); ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "SUDO LDAP connection failed " "[%d]: %s\n", ret, strerror(ret)); state->dp_error = dp_error; tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_FUNC, "SUDO LDAP connection successful\n"); /* Obtain srv_opts here in case of first connection. */ state->srv_opts = state->sudo_ctx->id_ctx->srv_opts; /* Renew host information if needed. */ if (state->sudo_ctx->run_hostinfo) { subreq = sdap_sudo_get_hostinfo_send(state, state->opts, state->sudo_ctx->id_ctx->be); if (subreq == NULL) { state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, sdap_sudo_refresh_hostinfo_done, req); state->sudo_ctx->run_hostinfo = false; return; } ret = sdap_sudo_refresh_sudoers(req); if (ret != EAGAIN) { state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); } } static void sdap_sudo_refresh_hostinfo_done(struct tevent_req *subreq) { struct sdap_sudo_ctx *sudo_ctx; struct sdap_sudo_refresh_state *state; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_sudo_refresh_state); sudo_ctx = state->sudo_ctx; ret = sdap_sudo_get_hostinfo_recv(sudo_ctx, subreq, &sudo_ctx->hostnames, &sudo_ctx->ip_addr); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve host information, " "host filter will be disabled [%d]: %s\n", ret, sss_strerror(ret)); sudo_ctx->use_host_filter = false; } else { sudo_ctx->use_host_filter = true; } ret = sdap_sudo_refresh_sudoers(req); if (ret != EAGAIN) { state->dp_error = DP_ERR_FATAL; tevent_req_error(req, ret); } } static errno_t sdap_sudo_refresh_sudoers(struct tevent_req *req) { struct sdap_sudo_refresh_state *state; struct tevent_req *subreq; char *filter; state = tevent_req_data(req, struct sdap_sudo_refresh_state); /* We are connected. Host information may have changed during transition * from offline to online state. At this point we can combine search * and host filter. */ filter = sdap_sudo_get_filter(state, state->opts->sudorule_map, state->sudo_ctx, state->search_filter); if (filter == NULL) { return ENOMEM; } subreq = sdap_sudo_load_sudoers_send(state, state->ev, state->opts, sdap_id_op_handle(state->sdap_op), filter); if (subreq == NULL) { talloc_free(filter); return ENOMEM; } tevent_req_set_callback(subreq, sdap_sudo_refresh_done, req); return EAGAIN; } static void sdap_sudo_refresh_done(struct tevent_req *subreq) { struct tevent_req *req; struct sdap_sudo_refresh_state *state; struct sysdb_attrs **rules = NULL; size_t rules_count = 0; char *usn = NULL; int dp_error; int ret; errno_t sret; bool in_transaction = false; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_sudo_refresh_state); ret = sdap_sudo_load_sudoers_recv(subreq, state, &rules_count, &rules); talloc_zfree(subreq); ret = sdap_id_op_done(state->sdap_op, ret, &dp_error); if (dp_error == DP_ERR_OK && ret != EOK) { /* retry */ ret = sdap_sudo_refresh_retry(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } else if (ret != EOK) { tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_FUNC, "Received %zu rules\n", rules_count); /* start transaction */ ret = sysdb_transaction_start(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; /* purge cache */ ret = sysdb_sudo_purge(state->domain, state->delete_filter, rules, rules_count); if (ret != EOK) { goto done; } /* store rules */ ret = sysdb_sudo_store(state->domain, rules, rules_count); if (ret != EOK) { goto done; } /* commit transaction */ ret = sysdb_transaction_commit(state->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; DEBUG(SSSDBG_TRACE_FUNC, "Sudoers is successfuly stored in cache\n"); /* remember new usn */ ret = sysdb_get_highest_usn(state, rules, rules_count, &usn); if (ret == EOK) { sdap_sudo_set_usn(state->srv_opts, usn); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get highest USN [%d]: %s\n", ret, sss_strerror(ret)); } ret = EOK; state->num_rules = rules_count; done: if (in_transaction) { sret = sysdb_transaction_cancel(state->sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not cancel transaction\n"); } } state->dp_error = dp_error; if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } int sdap_sudo_refresh_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *dp_error, size_t *num_rules) { struct sdap_sudo_refresh_state *state; state = tevent_req_data(req, struct sdap_sudo_refresh_state); TEVENT_REQ_RETURN_ON_ERROR(req); *dp_error = state->dp_error; if (num_rules != NULL) { *num_rules = state->num_rules; } return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_async_sudo_hostinfo.c0000644000000000000000000000007312703456111023303 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.802794131 sssd-1.13.4/src/providers/ldap/sdap_async_sudo_hostinfo.c0000644002412700241270000003725312703456111024765 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_id_op.h" #include "providers/ldap/sdap_sudo.h" #include "resolv/async_resolv.h" static int sdap_sudo_get_ip_addresses(TALLOC_CTX *mem_ctx, char ***_ip_addr); struct sdap_sudo_get_hostinfo_state { char **hostnames; char **ip_addr; }; struct sdap_sudo_get_hostnames_state { struct tevent_context *ev; struct resolv_ctx *resolv_ctx; enum host_database *host_db; enum restrict_family family_order; char **hostnames; }; static void sdap_sudo_get_hostinfo_done(struct tevent_req *req); static struct tevent_req *sdap_sudo_get_hostnames_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx); static void sdap_sudo_get_hostnames_done(struct tevent_req *subreq); static int sdap_sudo_get_hostnames_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char ***hostnames); struct tevent_req * sdap_sudo_get_hostinfo_send(TALLOC_CTX *mem_ctx, struct sdap_options *opts, struct be_ctx *be_ctx) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_sudo_get_hostinfo_state *state = NULL; char *conf_hostnames = NULL; char *conf_ip_addr = NULL; int ret = EOK; /* create request */ req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_get_hostinfo_state); if (req == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->hostnames = NULL; state->ip_addr = NULL; /* load info from configuration */ conf_hostnames = dp_opt_get_string(opts->basic, SDAP_SUDO_HOSTNAMES); conf_ip_addr = dp_opt_get_string(opts->basic, SDAP_SUDO_IP); if (conf_hostnames != NULL) { ret = split_on_separator(state, conf_hostnames, ' ', true, true, &state->hostnames, NULL); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to parse hostnames [%d]: %s\n", ret, strerror(ret)); goto done; } else { DEBUG(SSSDBG_CONF_SETTINGS, "Hostnames set to: %s\n", conf_hostnames); } } if (conf_ip_addr != NULL) { ret = split_on_separator(state, conf_ip_addr, ' ', true, true, &state->ip_addr, NULL); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to parse IP addresses [%d]: %s\n", ret, strerror(ret)); goto done; } else { DEBUG(SSSDBG_CONF_SETTINGS, "IP addresses set to: %s\n", conf_ip_addr); } } /* if IP addresses are not specified, configure it automatically */ if (state->ip_addr == NULL) { ret = sdap_sudo_get_ip_addresses(state, &state->ip_addr); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to detect IP addresses [%d]: %s\n", ret, strerror(ret)); } } /* if hostnames are not specified, configure it automatically */ if (state->hostnames == NULL) { subreq = sdap_sudo_get_hostnames_send(state, be_ctx); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_sudo_get_hostinfo_done, req); ret = EAGAIN; } done: if (ret != EAGAIN) { if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, be_ctx->ev); } return req; } static void sdap_sudo_get_hostinfo_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; struct sdap_sudo_get_hostinfo_state *state = NULL; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_sudo_get_hostinfo_state); ret = sdap_sudo_get_hostnames_recv(state, subreq, &state->hostnames); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve hostnames [%d]: %s\n", ret, strerror(ret)); tevent_req_error(req, ret); return; } tevent_req_done(req); } int sdap_sudo_get_hostinfo_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char ***hostnames, char ***ip_addr) { struct sdap_sudo_get_hostinfo_state *state = NULL; state = tevent_req_data(req, struct sdap_sudo_get_hostinfo_state); TEVENT_REQ_RETURN_ON_ERROR(req); *hostnames = talloc_steal(mem_ctx, state->hostnames); *ip_addr = talloc_steal(mem_ctx, state->ip_addr); return EOK; } static int sdap_sudo_get_ip_addresses(TALLOC_CTX *mem_ctx, char ***_ip_addr_list) { TALLOC_CTX *tmp_ctx = NULL; char **ip_addr_list = NULL; struct ifaddrs *ifaces = NULL; struct ifaddrs *iface = NULL; struct sockaddr_in ip4_addr; struct sockaddr_in ip4_network; struct sockaddr_in6 ip6_addr; struct sockaddr_in6 ip6_network; char ip_addr[INET6_ADDRSTRLEN + 1]; char network_addr[INET6_ADDRSTRLEN + 1]; in_addr_t ip4_netmask = 0; uint32_t ip6_netmask = 0; unsigned int netmask = 0; void *sinx_addr = NULL; void *sinx_network = NULL; int addr_count = 0; int ret; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } errno = 0; ret = getifaddrs(&ifaces); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Could not read interfaces [%d][%s]\n", ret, strerror(ret)); goto done; } for (iface = ifaces; iface != NULL; iface = iface->ifa_next) { /* Some interfaces don't have an ifa_addr */ if (!iface->ifa_addr) continue; netmask = 0; switch (iface->ifa_addr->sa_family) { case AF_INET: memcpy(&ip4_addr, iface->ifa_addr, sizeof(struct sockaddr_in)); memcpy(&ip4_network, iface->ifa_netmask, sizeof(struct sockaddr_in)); if (!check_ipv4_addr(&ip4_addr.sin_addr, SSS_NO_LOOPBACK|SSS_NO_MULTICAST |SSS_NO_BROADCAST)) { continue; } /* get network mask length */ ip4_netmask = ntohl(ip4_network.sin_addr.s_addr); while (ip4_netmask) { netmask++; ip4_netmask <<= 1; } /* get network address */ ip4_network.sin_addr.s_addr = ip4_addr.sin_addr.s_addr & ip4_network.sin_addr.s_addr; sinx_addr = &ip4_addr.sin_addr; sinx_network = &ip4_network.sin_addr; break; case AF_INET6: memcpy(&ip6_addr, iface->ifa_addr, sizeof(struct sockaddr_in6)); memcpy(&ip6_network, iface->ifa_netmask, sizeof(struct sockaddr_in6)); if (!check_ipv6_addr(&ip6_addr.sin6_addr, SSS_NO_LOOPBACK|SSS_NO_MULTICAST)) { continue; } /* get network mask length */ for (i = 0; i < 4; i++) { ip6_netmask = ntohl(((uint32_t*)(&ip6_network.sin6_addr))[i]); while (ip6_netmask) { netmask++; ip6_netmask <<= 1; } } /* get network address */ for (i = 0; i < 4; i++) { ((uint32_t*)(&ip6_network.sin6_addr))[i] = ((uint32_t*)(&ip6_addr.sin6_addr))[i] & ((uint32_t*)(&ip6_network.sin6_addr))[i]; } sinx_addr = &ip6_addr.sin6_addr; sinx_network = &ip6_network.sin6_addr; break; default: /* skip other families */ continue; } /* ip address */ errno = 0; if (inet_ntop(iface->ifa_addr->sa_family, sinx_addr, ip_addr, INET6_ADDRSTRLEN) == NULL) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "inet_ntop() failed [%d]: %s\n", ret, strerror(ret)); goto done; } /* network */ errno = 0; if (inet_ntop(iface->ifa_addr->sa_family, sinx_network, network_addr, INET6_ADDRSTRLEN) == NULL) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "inet_ntop() failed [%d]: %s\n", ret, strerror(ret)); goto done; } addr_count += 2; ip_addr_list = talloc_realloc(tmp_ctx, ip_addr_list, char*, addr_count + 1); if (ip_addr_list == NULL) { ret = ENOMEM; goto done; } ip_addr_list[addr_count - 2] = talloc_strdup(ip_addr_list, ip_addr); if (ip_addr_list[addr_count - 2] == NULL) { ret = ENOMEM; goto done; } ip_addr_list[addr_count - 1] = talloc_asprintf(ip_addr_list, "%s/%d", network_addr, netmask); if (ip_addr_list[addr_count - 1] == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Found IP address: %s in network %s/%d\n", ip_addr, network_addr, netmask); } if (ip_addr_list) { ip_addr_list[addr_count] = NULL; } *_ip_addr_list = talloc_steal(mem_ctx, ip_addr_list); done: freeifaddrs(ifaces); talloc_free(tmp_ctx); return ret; } /* * SUDO allows only one hostname that is returned from gethostname() * (and set to "localhost" if the returned value is empty) * and then - if allowed - resolves its fqdn using gethostbyname() or * getaddrinfo() if available. */ static struct tevent_req *sdap_sudo_get_hostnames_send(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sdap_sudo_get_hostnames_state *state = NULL; char *dot = NULL; char hostname[HOST_NAME_MAX + 1]; int ret; req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_get_hostnames_state); if (req == NULL) { return NULL; } state->ev = be_ctx->ev; state->hostnames = NULL; /* hostname, fqdn and NULL */ state->hostnames = talloc_zero_array(state, char*, 3); if (state->hostnames == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); ret = ENOMEM; goto done; } /* get hostname */ errno = 0; ret = gethostname(hostname, HOST_NAME_MAX); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve machine hostname " "[%d]: %s\n", ret, strerror(ret)); goto done; } hostname[HOST_NAME_MAX] = '\0'; state->hostnames[0] = talloc_strdup(state->hostnames, hostname); if (state->hostnames[0] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); ret = ENOMEM; goto done; } dot = strchr(hostname, '.'); if (dot != NULL) { /* already a fqdn, determine hostname and finish */ DEBUG(SSSDBG_TRACE_INTERNAL, "Found fqdn: %s\n", hostname); *dot = '\0'; DEBUG(SSSDBG_TRACE_INTERNAL, "Found hostname: %s\n", hostname); state->hostnames[1] = talloc_strdup(state->hostnames, hostname); if (state->hostnames[1] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); ret = ENOMEM; goto done; } ret = EOK; goto done; } else { DEBUG(SSSDBG_TRACE_INTERNAL, "Found hostname: %s\n", hostname); } state->resolv_ctx = be_ctx->be_res->resolv; state->host_db = default_host_dbs; /* get fqdn */ subreq = resolv_gethostbyname_send(state, state->ev, state->resolv_ctx, hostname, be_ctx->be_res->family_order, state->host_db); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sdap_sudo_get_hostnames_done, req); ret = EAGAIN; done: if (ret != EAGAIN) { if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, be_ctx->ev); } return req; } static void sdap_sudo_get_hostnames_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; struct sdap_sudo_get_hostnames_state *state = NULL; struct resolv_hostent *rhostent = NULL; int resolv_status; int ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_sudo_get_hostnames_state); ret = resolv_gethostbyname_recv(subreq, state, &resolv_status, NULL, &rhostent); talloc_zfree(subreq); if (ret == ENOENT) { /* Empty result, just quit */ DEBUG(SSSDBG_TRACE_INTERNAL, "No hostent found\n"); goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not resolve fqdn for this machine, error [%d]: %s, " "resolver returned: [%d]: %s\n", ret, strerror(ret), resolv_status, resolv_strerror(resolv_status)); tevent_req_error(req, ret); return; } /* EOK */ DEBUG(SSSDBG_TRACE_INTERNAL, "Found fqdn: %s\n", rhostent->name); if (state->hostnames == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "state->hostnames is NULL\n"); ret = EINVAL; goto done; } state->hostnames[1] = talloc_strdup(state->hostnames, rhostent->name); if (state->hostnames[1] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); ret = ENOMEM; goto done; } ret = EOK; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } static int sdap_sudo_get_hostnames_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char ***hostnames) { struct sdap_sudo_get_hostnames_state *state = NULL; state = tevent_req_data(req, struct sdap_sudo_get_hostnames_state); TEVENT_REQ_RETURN_ON_ERROR(req); *hostnames = talloc_steal(mem_ctx, state->hostnames); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_range.h0000644000000000000000000000007412703456111020325 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.559793307 sssd-1.13.4/src/providers/ldap/sdap_range.h0000644002412700241270000000212212703456111021771 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SDAP_RANGE_H_ #define SDAP_RANGE_H_ #include "src/util/util.h" errno_t sdap_parse_range(TALLOC_CTX *mem_ctx, const char *attr_desc, char **base_attr, uint32_t *range_offset, bool disable_range_retrieval); #endif /* SDAP_RANGE_H_ */ sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_dyndns.c0000644000000000000000000000007312703456111020522 xustar0029 atime=1460561751.64871562 30 ctime=1460561774.794794103 sssd-1.13.4/src/providers/ldap/sdap_dyndns.c0000644002412700241270000006675112703456111022211 0ustar00jhrozekjhrozek00000000000000/* SSSD sdap_dyndns.c: LDAP specific dynamic DNS update Authors: Jakub Hrozek Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "resolv/async_resolv.h" #include "providers/dp_backend.h" #include "providers/dp_dyndns.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/sdap_dyndns.h" #include "providers/ldap/sdap_id_op.h" #include "providers/ldap/ldap_common.h" static struct tevent_req * sdap_dyndns_get_addrs_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_ctx, const char *iface); static errno_t sdap_dyndns_get_addrs_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sss_iface_addr **_addresses); struct sdap_dyndns_update_state { struct tevent_context *ev; struct be_resolv_ctx *be_res; struct dp_option *opts; const char *hostname; const char *realm; const char *servername; int ttl; struct sss_iface_addr *addresses; struct sss_iface_addr *dns_addrlist; uint8_t remove_af; bool update_ptr; bool check_diff; enum be_nsupdate_auth auth_type; bool fallback_mode; char *update_msg; struct sss_iface_addr *ptr_addr_iter; bool del_phase; }; static void sdap_dyndns_update_addrs_done(struct tevent_req *subreq); static void sdap_dyndns_dns_addrs_done(struct tevent_req *subreq); static errno_t sdap_dyndns_addrs_diff(struct sdap_dyndns_update_state *state, bool *_do_update); static errno_t sdap_dyndns_update_step(struct tevent_req *req); static errno_t sdap_dyndns_update_ptr_step(struct tevent_req *req); static void sdap_dyndns_update_done(struct tevent_req *subreq); static void sdap_dyndns_update_ptr_done(struct tevent_req *subreq); static errno_t sdap_dyndns_next_ptr_record(struct sdap_dyndns_update_state *state, struct tevent_req *req); static struct sss_iface_addr* sdap_get_address_to_delete(struct sss_iface_addr *address_it, uint8_t remove_af); struct tevent_req * sdap_dyndns_update_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct dp_option *opts, struct sdap_id_ctx *sdap_ctx, enum be_nsupdate_auth auth_type, const char *ifname, const char *hostname, const char *realm, const char *servername, const int ttl, bool check_diff) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct sdap_dyndns_update_state *state; const char *conf_servername; req = tevent_req_create(mem_ctx, &state, struct sdap_dyndns_update_state); if (req == NULL) { return NULL; } state->check_diff = check_diff; state->update_ptr = dp_opt_get_bool(opts, DP_OPT_DYNDNS_UPDATE_PTR); state->hostname = hostname; state->realm = realm; state->servername = servername; state->fallback_mode = false; state->ttl = ttl; state->be_res = be_ctx->be_res; state->ev = ev; state->opts = opts; state->auth_type = auth_type; state->ptr_addr_iter = NULL; state->del_phase = true; /* fallback servername is overriden by user option */ conf_servername = dp_opt_get_string(opts, DP_OPT_DYNDNS_SERVER); if (conf_servername != NULL) { state->servername = conf_servername; } if (ifname) { /* Unless one family is restricted, just replace all * address families during the update */ switch (state->be_res->family_order) { case IPV4_ONLY: state->remove_af |= DYNDNS_REMOVE_A; break; case IPV6_ONLY: state->remove_af |= DYNDNS_REMOVE_AAAA; break; case IPV4_FIRST: case IPV6_FIRST: state->remove_af |= (DYNDNS_REMOVE_A | DYNDNS_REMOVE_AAAA); break; } } else { /* If the interface isn't specified, we ONLY want to have the address * that's connected to the LDAP server stored, so we need to check * (and later remove) both address families. */ state->remove_af = (DYNDNS_REMOVE_A | DYNDNS_REMOVE_AAAA); } subreq = sdap_dyndns_get_addrs_send(state, state->ev, sdap_ctx, ifname); if (!subreq) { ret = EIO; DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } tevent_req_set_callback(subreq, sdap_dyndns_update_addrs_done, req); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void sdap_dyndns_update_addrs_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req; struct sdap_dyndns_update_state *state; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_dyndns_update_state); ret = sdap_dyndns_get_addrs_recv(subreq, state, &state->addresses); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Can't get addresses for DNS update\n"); tevent_req_error(req, ret); return; } if (state->check_diff || state->update_ptr) { /* Check if we need the update at all. In case we are updating the PTR * records as well, we need to know the old addresses to be able to * reliably delete the PTR records */ subreq = nsupdate_get_addrs_send(state, state->ev, state->be_res, state->hostname); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Can't initiate address check\n"); tevent_req_error(req, ret); return; } tevent_req_set_callback(subreq, sdap_dyndns_dns_addrs_done, req); return; } /* Perform update */ ret = sdap_dyndns_update_step(req); if (ret != EOK) { tevent_req_error(req, ret); return; } /* Execution will resume in sdap_dyndns_update_done */ } static void sdap_dyndns_dns_addrs_done(struct tevent_req *subreq) { struct tevent_req *req; struct sdap_dyndns_update_state *state; errno_t ret; bool do_update; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_dyndns_update_state); ret = nsupdate_get_addrs_recv(subreq, state, &state->dns_addrlist, NULL); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not receive list of current addresses [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } if (state->check_diff) { ret = sdap_dyndns_addrs_diff(state, &do_update); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not check the diff between DNS " "and current addresses [%d]: %s\n", ret, strerror(ret)); tevent_req_error(req, ret); return; } if (do_update == false) { DEBUG(SSSDBG_TRACE_FUNC, "No DNS update needed, addresses did not change\n"); tevent_req_done(req); return; } DEBUG(SSSDBG_TRACE_FUNC, "Detected IP addresses change, will perform an update\n"); } /* Either we needed the addresses for updating PTR records only or * the addresses have changed (or both) */ ret = sdap_dyndns_update_step(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not start the update [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); } return; } static errno_t sdap_dyndns_addrs_diff(struct sdap_dyndns_update_state *state, bool *_do_update) { errno_t ret; int i; char **str_dnslist = NULL, **str_local_list = NULL; char **dns_only = NULL, **local_only = NULL; bool do_update = false; ret = sss_iface_addr_list_as_str_list(state, state->dns_addrlist, &str_dnslist); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Converting DNS IP addresses to strings failed: [%d]: %s\n", ret, sss_strerror(ret)); return ret; } ret = sss_iface_addr_list_as_str_list(state, state->addresses, &str_local_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Converting local IP addresses to strings failed: [%d]: %s\n", ret, sss_strerror(ret)); return ret; } /* Compare the lists */ ret = diff_string_lists(state, str_dnslist, str_local_list, &dns_only, &local_only, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "diff_string_lists failed: [%d]: %s\n", ret, sss_strerror(ret)); return ret; } if (dns_only) { for (i=0; dns_only[i]; i++) { DEBUG(SSSDBG_TRACE_LIBS, "Address in DNS only: %s\n", dns_only[i]); do_update = true; } } if (local_only) { for (i=0; local_only[i]; i++) { DEBUG(SSSDBG_TRACE_LIBS, "Address on localhost only: %s\n", local_only[i]); do_update = true; } } *_do_update = do_update; return EOK; } static errno_t sdap_dyndns_update_step(struct tevent_req *req) { errno_t ret; struct sdap_dyndns_update_state *state; const char *servername; struct tevent_req *subreq; state = tevent_req_data(req, struct sdap_dyndns_update_state); servername = NULL; if (state->fallback_mode == true && state->servername) { servername = state->servername; } ret = be_nsupdate_create_fwd_msg(state, state->realm, servername, state->hostname, state->ttl, state->remove_af, state->addresses, &state->update_msg); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Can't get addresses for DNS update\n"); return ret; } /* Fork a child process to perform the DNS update */ subreq = be_nsupdate_send(state, state->ev, state->auth_type, state->update_msg, dp_opt_get_bool(state->opts, DP_OPT_DYNDNS_FORCE_TCP)); if (subreq == NULL) { return EIO; } tevent_req_set_callback(subreq, sdap_dyndns_update_done, req); return EOK; } static void sdap_dyndns_update_done(struct tevent_req *subreq) { errno_t ret; int child_status; struct tevent_req *req; struct sdap_dyndns_update_state *state; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_dyndns_update_state); ret = be_nsupdate_recv(subreq, &child_status); talloc_zfree(subreq); if (ret != EOK) { /* If the update didn't succeed, we can retry using the server name */ if (state->fallback_mode == false && state->servername && WIFEXITED(child_status) && WEXITSTATUS(child_status) != 0) { state->fallback_mode = true; DEBUG(SSSDBG_MINOR_FAILURE, "nsupdate failed, retrying with server name\n"); ret = sdap_dyndns_update_step(req); if (ret == EOK) { return; } } tevent_req_error(req, ret); return; } if (state->update_ptr == false) { DEBUG(SSSDBG_TRACE_FUNC, "No PTR update requested, done\n"); tevent_req_done(req); return; } talloc_free(state->update_msg); /* init iterator for addresses to be deleted */ state->ptr_addr_iter = sdap_get_address_to_delete(state->dns_addrlist, state->remove_af); if (state->ptr_addr_iter == NULL) { /* init iterator for addresses to be added */ state->del_phase = false; state->ptr_addr_iter = state->addresses; } ret = sdap_dyndns_update_ptr_step(req); if (ret != EOK) { tevent_req_error(req, ret); return; } /* Execution will resume in sdap_dyndns_update_ptr_done */ } static bool remove_addr(int address_family, uint8_t remove_af) { bool ret = false; switch(address_family) { case AF_INET: if (remove_af & DYNDNS_REMOVE_A) { ret = true; } break; case AF_INET6: if (remove_af & DYNDNS_REMOVE_AAAA) { ret = true; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown address family\n"); ret = false; } return ret; } static struct sss_iface_addr* sdap_get_address_to_delete(struct sss_iface_addr *address_it, uint8_t remove_af) { struct sockaddr_storage* address; while (address_it != NULL) { address = sss_iface_addr_get_address(address_it); /* skip addresses that are not to be deleted */ if (remove_addr(address->ss_family, remove_af)) { break; } address_it = sss_iface_addr_get_next(address_it); } return address_it; } static errno_t sdap_dyndns_update_ptr_step(struct tevent_req *req) { errno_t ret; struct sdap_dyndns_update_state *state; const char *servername; struct tevent_req *subreq; struct sockaddr_storage *address; state = tevent_req_data(req, struct sdap_dyndns_update_state); servername = NULL; if (state->fallback_mode == true && state->servername) { servername = state->servername; } address = sss_iface_addr_get_address(state->ptr_addr_iter); if (address == NULL) { return EIO; } ret = be_nsupdate_create_ptr_msg(state, state->realm, servername, state->hostname, state->ttl, address, state->del_phase, &state->update_msg); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Can't get addresses for DNS update\n"); return ret; } /* Fork a child process to perform the DNS update */ subreq = be_nsupdate_send(state, state->ev, state->auth_type, state->update_msg, dp_opt_get_bool(state->opts, DP_OPT_DYNDNS_FORCE_TCP)); if (subreq == NULL) { return EIO; } tevent_req_set_callback(subreq, sdap_dyndns_update_ptr_done, req); return EOK; } static void sdap_dyndns_update_ptr_done(struct tevent_req *subreq) { errno_t ret; int child_status; struct tevent_req *req; struct sdap_dyndns_update_state *state; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_dyndns_update_state); ret = be_nsupdate_recv(subreq, &child_status); talloc_zfree(subreq); if (ret != EOK) { /* If the update didn't succeed, we can retry using the server name */ if (state->fallback_mode == false && state->servername && WIFEXITED(child_status) && WEXITSTATUS(child_status) != 0) { state->fallback_mode = true; DEBUG(SSSDBG_MINOR_FAILURE, "nsupdate failed, retrying with server name\n"); ret = sdap_dyndns_update_ptr_step(req); if (ret == EOK) { return; } } ret = sdap_dyndns_next_ptr_record(state, req); if (ret == EAGAIN) { return; } tevent_req_error(req, ret); return; } ret = sdap_dyndns_next_ptr_record(state, req); if (ret == EAGAIN) { return; } tevent_req_done(req); } static errno_t sdap_dyndns_next_ptr_record(struct sdap_dyndns_update_state *state, struct tevent_req *req) { errno_t ret; if (state->del_phase) { /* iterate to next address to delete */ state->ptr_addr_iter = sdap_get_address_to_delete( sss_iface_addr_get_next(state->ptr_addr_iter), state->remove_af); if (state->ptr_addr_iter == NULL) { /* init iterator for addresses to be added */ state->del_phase = false; state->ptr_addr_iter = state->addresses; } } else { /* iterate to next address to add */ state->ptr_addr_iter = sss_iface_addr_get_next(state->ptr_addr_iter); } if (state->ptr_addr_iter != NULL) { state->fallback_mode = false; ret = sdap_dyndns_update_ptr_step(req); if (ret == EOK) { return EAGAIN; } } return EOK; } errno_t sdap_dyndns_update_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* A request to get addresses to update with */ struct sdap_dyndns_get_addrs_state { struct sdap_id_op* sdap_op; struct sss_iface_addr *addresses; }; static void sdap_dyndns_get_addrs_done(struct tevent_req *subreq); static errno_t sdap_dyndns_add_ldap_conn(struct sdap_dyndns_get_addrs_state *state, struct sdap_handle *sh); static errno_t get_ifaces_addrs(TALLOC_CTX *mem_ctx, const char *iface, struct sss_iface_addr **_result) { struct sss_iface_addr *result_addrs = NULL; struct sss_iface_addr *intf_addrs; TALLOC_CTX *tmp_ctx; char **list_of_intfs; int num_of_intfs; errno_t ret; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ret = split_on_separator(tmp_ctx, iface, ',', true, true, &list_of_intfs, &num_of_intfs); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Parsing names of interfaces failed - %d:[%s].\n", ret, sss_strerror(ret)); goto done; } for (i = 0; i < num_of_intfs; i++) { ret = sss_iface_addr_list_get(tmp_ctx, list_of_intfs[i], &intf_addrs); if (ret == EOK) { if (result_addrs != NULL) { /* If there is already an existing list, head of this existing * list will be considered as parent talloc context for the * new list. */ talloc_steal(result_addrs, intf_addrs); } sss_iface_addr_concatenate(&result_addrs, intf_addrs); } else if (ret == ENOENT) { /* non-critical failure */ DEBUG(SSSDBG_TRACE_FUNC, "Cannot get interface %s or there are no addresses " "bind to it.\n", list_of_intfs[i]); } else { DEBUG(SSSDBG_OP_FAILURE, "Cannot get list of addresses from interface %s - %d:[%s]\n", list_of_intfs[i], ret, sss_strerror(ret)); goto done; } } ret = EOK; *_result = talloc_steal(mem_ctx, result_addrs); done: talloc_free(tmp_ctx); return ret; } static struct tevent_req * sdap_dyndns_get_addrs_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_ctx, const char *iface) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct sdap_dyndns_get_addrs_state *state; req = tevent_req_create(mem_ctx, &state, struct sdap_dyndns_get_addrs_state); if (req == NULL) { return NULL; } if (iface) { ret = get_ifaces_addrs(state, iface, &state->addresses); if (ret != EOK || state->addresses == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "get_ifaces_addrs() failed: %d:[%s]\n", ret, sss_strerror(ret)); } /* We're done. Just fake an async request completion */ goto done; } /* Detect DYNDNS address from LDAP connection */ state->sdap_op = sdap_id_op_create(state, sdap_ctx->conn->conn_cache); if (!state->sdap_op) { ret = ENOMEM; DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); goto done; } subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (!subreq) { ret = EIO; DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: [%d](%s)\n", ret, sss_strerror(ret)); goto done; } tevent_req_set_callback(subreq, sdap_dyndns_get_addrs_done, req); ret = EAGAIN; done: if (ret == EOK) { tevent_req_done(req); tevent_req_post(req, ev); } else if (ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, ev); } /* EAGAIN - resolution in progress */ return req; } static void sdap_dyndns_get_addrs_done(struct tevent_req *subreq) { errno_t ret; int dp_error; struct tevent_req *req; struct sdap_dyndns_get_addrs_state *state; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct sdap_dyndns_get_addrs_state); ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_MINOR_FAILURE, "No LDAP server is available, " "dynamic DNS update is skipped in offline mode.\n"); ret = ERR_DYNDNS_OFFLINE; } else { DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to LDAP server: [%d](%s)\n", ret, sss_strerror(ret)); } tevent_req_error(req, ret); return; } ret = sdap_dyndns_add_ldap_conn(state, sdap_id_op_handle(state->sdap_op)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Can't get addresses from LDAP connection\n"); tevent_req_error(req, ret); return; } /* Got the address! Done! */ tevent_req_done(req); } static errno_t sdap_dyndns_add_ldap_conn(struct sdap_dyndns_get_addrs_state *state, struct sdap_handle *sh) { int ret; int fd; struct sockaddr_storage ss; socklen_t ss_len = sizeof(ss); if (sh == NULL) { return EINVAL; } /* Get the file descriptor for the primary LDAP connection */ ret = get_fd_from_ldap(sh->ldap, &fd); if (ret != EOK) { return ret; } errno = 0; ret = getsockname(fd, (struct sockaddr *) &ss, &ss_len); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get socket name\n"); return ret; } if (ss.ss_family != AF_INET && ss.ss_family != AF_INET6) { DEBUG(SSSDBG_CRIT_FAILURE, "Connection to LDAP is neither IPv4 nor IPv6\n"); return EIO; } ret = sss_get_dualstack_addresses(state, (struct sockaddr *) &ss, &state->addresses); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_get_dualstack_addresses failed: %d:[%s]\n", ret, sss_strerror(ret)); return ret; } return EOK; } static errno_t sdap_dyndns_get_addrs_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sss_iface_addr **_addresses) { struct sdap_dyndns_get_addrs_state *state; state = tevent_req_data(req, struct sdap_dyndns_get_addrs_state); TEVENT_REQ_RETURN_ON_ERROR(req); *_addresses = talloc_steal(mem_ctx, state->addresses); return EOK; } struct sdap_dyndns_timer_state { struct tevent_context *ev; struct sdap_id_ctx *sdap_ctx; struct be_nsupdate_ctx *dyndns_ctx; struct sdap_id_op *sdap_op; }; static void sdap_dyndns_timer_conn_done(struct tevent_req *req); struct tevent_req * sdap_dyndns_timer_conn_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_id_ctx *sdap_ctx, struct be_nsupdate_ctx *dyndns_ctx) { struct sdap_dyndns_timer_state *state; struct tevent_req *req; struct tevent_req *subreq; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct sdap_dyndns_timer_state); if (req == NULL) { return NULL; } state->ev = ev; state->sdap_ctx = sdap_ctx; state->dyndns_ctx = dyndns_ctx; /* In order to prevent the connection triggering an * online callback which would in turn trigger a concurrent DNS * update */ state->dyndns_ctx->timer_in_progress = true; /* Make sure to have a valid LDAP connection */ state->sdap_op = sdap_id_op_create(state, state->sdap_ctx->conn->conn_cache); if (state->sdap_op == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); ret = ENOMEM; goto fail; } subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_connect_send failed: [%d](%s)\n", ret, sss_strerror(ret)); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, sdap_dyndns_timer_conn_done, req); return req; fail: dyndns_ctx->timer_in_progress = false; be_nsupdate_timer_schedule(ev, dyndns_ctx); tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void sdap_dyndns_timer_conn_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sdap_dyndns_timer_state *state = tevent_req_data(req, struct sdap_dyndns_timer_state); errno_t ret; int dp_error; state->dyndns_ctx->timer_in_progress = false; ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); if (ret != EOK) { if (dp_error == DP_ERR_OFFLINE) { DEBUG(SSSDBG_MINOR_FAILURE, "No server is available, " "dynamic DNS update is skipped in offline mode.\n"); /* Another timer will be scheduled when provider goes online */ tevent_req_error(req, ERR_DYNDNS_OFFLINE); } else { DEBUG(SSSDBG_OP_FAILURE, "Failed to connect to LDAP server: [%d](%s)\n", ret, sss_strerror(ret)); /* Just schedule another dyndns retry */ be_nsupdate_timer_schedule(state->ev, state->dyndns_ctx); tevent_req_error(req, ERR_NETWORK_IO); } return; } /* All OK, schedule another refresh and let the user call its * provider-specific update */ be_nsupdate_timer_schedule(state->ev, state->dyndns_ctx); tevent_req_done(req); } errno_t sdap_dyndns_timer_conn_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_range.c0000644000000000000000000000007212703456111020316 xustar0030 atime=1460561751.649715624 28 ctime=1460561774.7937941 sssd-1.13.4/src/providers/ldap/sdap_range.c0000644002412700241270000001034512703456111021772 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/ldap/sdap_range.h" #include "util/util.h" #include "util/strtonum.h" #define SDAP_RANGE_STRING "range=" errno_t sdap_parse_range(TALLOC_CTX *mem_ctx, const char *attr_desc, char **base_attr, uint32_t *range_offset, bool disable_range_retrieval) { errno_t ret; TALLOC_CTX *tmp_ctx; char *endptr; char *end_range; char *base; size_t rangestringlen = sizeof(SDAP_RANGE_STRING) - 1; *range_offset = 0; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; /* The base_attr is the portion before the semicolon (if it exists) */ endptr = strchr(attr_desc, ';'); if (endptr == NULL) { /* Not a ranged attribute. Just copy the attribute desc */ *base_attr = talloc_strdup(mem_ctx, attr_desc); if (!*base_attr) { ret = ENOMEM; } else { ret = EOK; } DEBUG(SSSDBG_TRACE_INTERNAL, "No sub-attributes for [%s]\n", attr_desc); goto done; } /* This is a complex attribute. First get the base attribute name */ base = talloc_strndup(tmp_ctx, attr_desc, endptr - attr_desc); if (!base) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Base attribute of [%s] is [%s]\n", attr_desc, base); /* Next, determine if this is a ranged attribute */ if (strncmp(endptr+1, SDAP_RANGE_STRING, rangestringlen) != 0) { /* This is some other sub-attribute. We'll just return the whole * thing in case it's dealt with elsewhere. */ *base_attr = talloc_strdup(mem_ctx, attr_desc); if (!*base_attr) { ret = ENOMEM; } else { ret = EOK; } DEBUG(SSSDBG_TRACE_LIBS, "[%s] contains sub-attribute other than a range, returning whole\n", attr_desc); goto done; } else if (disable_range_retrieval) { /* This is range sub-attribute, but we want to ignore it. */ *base_attr = talloc_strdup(mem_ctx, attr_desc); if (!*base_attr) { ret = ENOMEM; } else { ret = ECANCELED; } goto done; } /* Get the end of the range */ end_range = strchr(endptr + rangestringlen +1, '-'); if (!end_range) { ret = EINVAL; DEBUG(SSSDBG_MINOR_FAILURE, "Cannot find hyphen in [%s]\n", endptr + rangestringlen +1); goto done; } end_range++; /* advance past the hyphen */ if (*end_range == '*') { /* this was the last iteration of range retrievals */ *base_attr = talloc_steal(mem_ctx, base); *range_offset = 0; DEBUG(SSSDBG_TRACE_LIBS, "[%s] contained the last set of values for this attribute\n", attr_desc); ret = EOK; goto done; } *range_offset = strtouint32(end_range, &endptr, 10); if (*endptr != '\0') { *range_offset = 0; ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "[%s] did not parse as an unsigned integer: [%s]\n", end_range, strerror(ret)); goto done; } (*range_offset)++; *base_attr = talloc_steal(mem_ctx, base); DEBUG(SSSDBG_TRACE_LIBS, "Parsed range values: [%s][%d]\n", base, *range_offset); ret = EAGAIN; done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/providers/ldap/PaxHeaders.16287/sdap_users.h0000644000000000000000000000007412703456111020372 xustar0030 atime=1460561751.649715624 30 ctime=1460561774.559793307 sssd-1.13.4/src/providers/ldap/sdap_users.h0000644002412700241270000000252312703456111022043 0ustar00jhrozekjhrozek00000000000000/* SSSD Async LDAP Helper routines Copyright (C) Simo Sorce This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SDAP_USERS_H_ #define _SDAP_USERS_H_ #include "config.h" /* shared non-async user functions */ errno_t sdap_fallback_local_user(TALLOC_CTX *memctx, struct sdap_options *opts, const char *name, uid_t uid, struct sysdb_attrs ***reply); int sdap_save_user(TALLOC_CTX *memctx, struct sdap_options *opts, struct sss_domain_info *dom, struct sysdb_attrs *attrs, char **_usn_value, time_t now); #endif /* _SDAP_USERS_H_ */ sssd-1.13.4/src/providers/PaxHeaders.16287/data_provider_callbacks.c0000644000000000000000000000007412703456111022117 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.657793639 sssd-1.13.4/src/providers/data_provider_callbacks.c0000644002412700241270000001704012703456111023570 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider Process - Callback Authors: Stephen Gallagher Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "providers/dp_backend.h" struct be_cb { struct be_cb *prev; struct be_cb *next; be_callback_t cb; void *pvt; struct be_cb **list; struct be_ctx *be; }; struct be_cb_ctx { struct be_ctx *be; struct be_cb *callback; }; static int cb_destructor(TALLOC_CTX *ptr) { struct be_cb *cb = talloc_get_type(ptr, struct be_cb); DLIST_REMOVE(*(cb->list), cb); return 0; } static int be_add_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, void *pvt, struct be_cb **cb_list, struct be_cb **return_cb) { struct be_cb *new_cb; if (!ctx || !cb) { return EINVAL; } new_cb = talloc(mem_ctx, struct be_cb); if (!new_cb) { return ENOMEM; } new_cb->cb = cb; new_cb->pvt = pvt; new_cb->list = cb_list; new_cb->be = ctx; DLIST_ADD(*cb_list, new_cb); talloc_set_destructor((TALLOC_CTX *) new_cb, cb_destructor); if (return_cb) { *return_cb = new_cb; } return EOK; } static void be_run_cb_step(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { struct be_cb_ctx *cb_ctx = talloc_get_type(pvt, struct be_cb_ctx); struct be_cb *next_cb; struct tevent_timer *tev; struct timeval soon; /* Store next callback in case this callback frees itself */ next_cb = cb_ctx->callback->next; /* Call the callback */ cb_ctx->callback->cb(cb_ctx->callback->pvt); if (next_cb) { cb_ctx->callback = next_cb; /* Delay 30ms so we don't block any other events */ soon = tevent_timeval_current_ofs(0, 30000); tev = tevent_add_timer(cb_ctx->be->ev, cb_ctx, soon, be_run_cb_step, cb_ctx); if (!tev) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory. Could not invoke callbacks\n"); goto final; } return; } final: /* Steal the timer event onto the be_ctx so it doesn't * get freed with the cb_ctx */ talloc_steal(cb_ctx->be, te); talloc_free(cb_ctx); } static errno_t be_run_cb(struct be_ctx *be, struct be_cb *cb_list) { struct timeval soon; struct tevent_timer *te; struct be_cb_ctx *cb_ctx; if (cb_list == NULL) { return EOK; } cb_ctx = talloc(be, struct be_cb_ctx); if (!cb_ctx) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory. Could not invoke callbacks\n"); return ENOMEM; } cb_ctx->be = be; cb_ctx->callback = cb_list; /* Delay 30ms so we don't block any other events */ soon = tevent_timeval_current_ofs(0, 30000); te = tevent_add_timer(be->ev, cb_ctx, soon, be_run_cb_step, cb_ctx); if (!te) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory. Could not invoke callbacks\n"); talloc_free(cb_ctx); return ENOMEM; } return EOK; } int be_add_reconnect_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, void *pvt, struct be_cb **reconnect_cb) { int ret; ret = be_add_cb(mem_ctx, ctx, cb, pvt, &ctx->reconnect_cb_list, reconnect_cb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_add_cb failed.\n"); return ret; } return EOK; } void be_run_reconnect_cb(struct be_ctx *be) { struct be_cb *callback = be->reconnect_cb_list; struct be_cb *next_cb; if (callback) { DEBUG(SSSDBG_TRACE_FUNC, "Reconnecting. Running callbacks.\n"); /** * Call the callback: we have to call this right away * so the provider doesn't go into offline even for * a little while */ do { /* Store next callback in case this callback frees itself */ next_cb = callback->next; callback->cb(callback->pvt); callback = next_cb; } while(callback != NULL); } else { DEBUG(SSSDBG_TRACE_INTERNAL, "Reconnect call back list is empty, nothing to do.\n"); } } int be_add_online_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, void *pvt, struct be_cb **online_cb) { int ret; ret = be_add_cb(mem_ctx, ctx, cb, pvt, &ctx->online_cb_list, online_cb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_add_cb failed.\n"); return ret; } /* Make sure we run the callback for the first * connection after startup. */ ctx->run_online_cb = true; return EOK; } void be_run_online_cb(struct be_ctx *be) { int ret; if (be->run_online_cb) { /* Reset the flag. We only want to run these * callbacks when transitioning to online */ be->run_online_cb = false; if (be->online_cb_list) { DEBUG(SSSDBG_MINOR_FAILURE, "Going online. Running callbacks.\n"); ret = be_run_cb(be, be->online_cb_list); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_run_cb failed.\n"); } } else { DEBUG(SSSDBG_TRACE_ALL, "Online call back list is empty, nothing to do.\n"); } } } int be_add_unconditional_online_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, void *pvt, struct be_cb **unconditional_online_cb) { return be_add_cb(mem_ctx, ctx, cb, pvt, &ctx->unconditional_online_cb_list, unconditional_online_cb); } void be_run_unconditional_online_cb(struct be_ctx *be) { int ret; if (be->unconditional_online_cb_list) { DEBUG(SSSDBG_TRACE_FUNC, "Running unconditional online callbacks.\n"); ret = be_run_cb(be, be->unconditional_online_cb_list); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "be_run_cb failed.\n"); } } else { DEBUG(SSSDBG_TRACE_ALL, "List of unconditional online callbacks is empty, " \ "nothing to do.\n"); } } int be_add_offline_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, void *pvt, struct be_cb **offline_cb) { return be_add_cb(mem_ctx, ctx, cb, pvt, &ctx->offline_cb_list, offline_cb); } void be_run_offline_cb(struct be_ctx *be) { int ret; if (be->offline_cb_list) { DEBUG(SSSDBG_MINOR_FAILURE, "Going offline. Running callbacks.\n"); ret = be_run_cb(be, be->offline_cb_list); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_run_cb failed.\n"); } } else { DEBUG(SSSDBG_TRACE_ALL, "Offline call back list is empty, nothing to do.\n"); } } sssd-1.13.4/src/providers/PaxHeaders.16287/data_provider_req.c0000644000000000000000000000007412703456111020767 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.654793629 sssd-1.13.4/src/providers/data_provider_req.c0000644002412700241270000000407712703456111022446 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider -- backend request Copyright (C) Petr Cech 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/data_provider_req.h" #define be_req_to_str(req_type, be_req_t) \ ((req_type) & BE_REQ_FAST) ? "FAST " #be_req_t : #be_req_t const char *be_req2str(dbus_uint32_t req_type) { switch (req_type & BE_REQ_TYPE_MASK) { case BE_REQ_USER: return be_req_to_str(req_type, BE_REQ_USER); case BE_REQ_GROUP: return be_req_to_str(req_type, BE_REQ_GROUP); case BE_REQ_INITGROUPS: return be_req_to_str(req_type, BE_REQ_INITGROUPS); case BE_REQ_NETGROUP: return be_req_to_str(req_type, BE_REQ_NETGROUP); case BE_REQ_SERVICES: return be_req_to_str(req_type, BE_REQ_SERVICES); case BE_REQ_SUDO_FULL: return be_req_to_str(req_type, BE_REQ_SUDO_FULL); case BE_REQ_SUDO_RULES: return be_req_to_str(req_type, BE_REQ_SUDO_RULES); case BE_REQ_AUTOFS: return be_req_to_str(req_type, BE_REQ_AUTOFS); case BE_REQ_HOST: return be_req_to_str(req_type, BE_REQ_HOST); case BE_REQ_BY_SECID: return be_req_to_str(req_type, BE_REQ_BY_SECID); case BE_REQ_USER_AND_GROUP: return be_req_to_str(req_type, BE_REQ_USER_AND_GROUP); case BE_REQ_BY_UUID: return be_req_to_str(req_type, BE_REQ_BY_UUID); case BE_REQ_BY_CERT: return be_req_to_str(req_type, BE_REQ_BY_CERT); } return "UNKNOWN_REQ"; } sssd-1.13.4/src/providers/PaxHeaders.16287/dp_ptask_private.h0000644000000000000000000000007412703456111020641 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.527793198 sssd-1.13.4/src/providers/dp_ptask_private.h0000644002412700241270000000300312703456111022304 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef DP_PTASK_PRIVATE_H_ #define DP_PTASK_PRIVATE_H_ struct be_ptask { struct tevent_context *ev; struct be_ctx *be_ctx; time_t orig_period; time_t first_delay; time_t enabled_delay; time_t random_offset; unsigned int ro_seed; time_t timeout; time_t max_backoff; enum be_ptask_offline offline; be_ptask_send_t send_fn; be_ptask_recv_t recv_fn; void *pvt; const char *name; time_t period; /* computed period */ time_t next_execution; /* next time when the task is scheduled */ time_t last_execution; /* last time when send was called */ struct tevent_req *req; /* active tevent request */ struct tevent_timer *timer; /* active tevent timer */ bool enabled; }; #endif /* DP_PTASK_PRIVATE_H_ */ sssd-1.13.4/src/providers/PaxHeaders.16287/dp_ptask.h0000644000000000000000000000007412703456111017107 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.529793205 sssd-1.13.4/src/providers/dp_ptask.h0000644002412700241270000001071112703456111020556 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _DP_PTASK_H_ #define _DP_PTASK_H_ #include #include #include /* solve circular dependency */ struct be_ctx; struct be_ptask; /** * Defines how should task behave when back end is offline. */ enum be_ptask_offline { /* current request will be skipped and rescheduled to 'now + period' */ BE_PTASK_OFFLINE_SKIP, /* An offline and online callback is registered. The task is disabled * immediately when back end goes offline and then enabled again * when back end goes back online */ BE_PTASK_OFFLINE_DISABLE, /* current request will be executed as planned */ BE_PTASK_OFFLINE_EXECUTE }; typedef struct tevent_req * (*be_ptask_send_t)(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt); /** * If EOK, task will be scheduled again to 'last_execution_time + period'. * If other error code, task will be rescheduled to 'now + period'. */ typedef errno_t (*be_ptask_recv_t)(struct tevent_req *req); /** * If EOK, task will be scheduled again to 'last_execution_time + period'. * If other error code, task will be rescheduled to 'now + period'. */ typedef errno_t (*be_ptask_sync_t)(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt); /** * The first execution is scheduled first_delay seconds after the task is * created. * * If request does not complete in timeout seconds, it will be * cancelled and rescheduled to 'now + period'. * * If the task is reenabled, it will be scheduled again to * 'now + enabled_delay'. * * The random_offset is maximum number of seconds added to the * expected delay. Set to 0 if no randomization is needed. * If max_backoff is not 0 then the period is doubled * every time the task is scheduled. The maximum value of * period is max_backoff. The value of period will be reset to * original value when the task is disabled. With max_backoff * set to zero, this feature is disabled. * * If an internal error occurred, the task is automatically disabled. */ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, time_t period, time_t first_delay, time_t enabled_delay, time_t random_offset, time_t timeout, enum be_ptask_offline offline, time_t max_backoff, be_ptask_send_t send_fn, be_ptask_recv_t recv_fn, void *pvt, const char *name, struct be_ptask **_task); errno_t be_ptask_create_sync(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, time_t period, time_t first_delay, time_t enabled_delay, time_t random_offset, time_t timeout, enum be_ptask_offline offline, time_t max_backoff, be_ptask_sync_t fn, void *pvt, const char *name, struct be_ptask **_task); void be_ptask_enable(struct be_ptask *task); void be_ptask_disable(struct be_ptask *task); void be_ptask_destroy(struct be_ptask **task); time_t be_ptask_get_period(struct be_ptask *task); time_t be_ptask_get_timeout(struct be_ptask *task); #endif /* _DP_PTASK_H_ */ sssd-1.13.4/src/providers/PaxHeaders.16287/dp_pam_data_util.c0000644000000000000000000000007312703456111020562 xustar0030 atime=1460561751.644715607 29 ctime=1460561774.84379427 sssd-1.13.4/src/providers/dp_pam_data_util.c0000644002412700241270000001234112703456111022233 0ustar00jhrozekjhrozek00000000000000/* SSSD Utilities to for tha pam_data structure Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "providers/data_provider.h" #include "util/sss_cli_cmd.h" #define PAM_SAFE_ITEM(item) item ? item : "not set" int pam_data_destructor(void *ptr) { struct pam_data *pd = talloc_get_type(ptr, struct pam_data); /* make sure to wipe any password from memory before freeing */ sss_authtok_wipe_password(pd->authtok); sss_authtok_wipe_password(pd->newauthtok); return 0; } struct pam_data *create_pam_data(TALLOC_CTX *mem_ctx) { struct pam_data *pd; pd = talloc_zero(mem_ctx, struct pam_data); if (pd == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); goto failed; } pd->authtok = sss_authtok_new(pd); if (pd->authtok == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); goto failed; } pd->newauthtok = sss_authtok_new(pd); if (pd->newauthtok == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); goto failed; } talloc_set_destructor((TALLOC_CTX *) pd, pam_data_destructor); return pd; failed: talloc_free(pd); return NULL; } errno_t copy_pam_data(TALLOC_CTX *mem_ctx, struct pam_data *src, struct pam_data **dst) { struct pam_data *pd = NULL; errno_t ret; pd = create_pam_data(mem_ctx); if (pd == NULL) { ret = ENOMEM; goto failed; } pd->cmd = src->cmd; pd->priv = src->priv; pd->domain = talloc_strdup(pd, src->domain); if (pd->domain == NULL && src->domain != NULL) { ret = ENOMEM; goto failed; } pd->user = talloc_strdup(pd, src->user); if (pd->user == NULL && src->user != NULL) { ret = ENOMEM; goto failed; } pd->service = talloc_strdup(pd, src->service); if (pd->service == NULL && src->service != NULL) { ret = ENOMEM; goto failed; } pd->tty = talloc_strdup(pd, src->tty); if (pd->tty == NULL && src->tty != NULL) { ret = ENOMEM; goto failed; } pd->ruser = talloc_strdup(pd, src->ruser); if (pd->ruser == NULL && src->ruser != NULL) { ret = ENOMEM; goto failed; } pd->rhost = talloc_strdup(pd, src->rhost); if (pd->rhost == NULL && src->rhost != NULL) { ret = ENOMEM; goto failed; } pd->cli_pid = src->cli_pid; /* if structure pam_data was allocated on stack and zero initialized, * than src->authtok and src->newauthtok are NULL, therefore * instead of copying, new empty authtok will be created. */ if (src->authtok) { ret = sss_authtok_copy(src->authtok, pd->authtok); if (ret) { goto failed; } } else { pd->authtok = sss_authtok_new(pd); if (pd->authtok == NULL) { ret = ENOMEM; goto failed; } } if (src->newauthtok) { ret = sss_authtok_copy(src->newauthtok, pd->newauthtok); if (ret) { goto failed; } } else { pd->newauthtok = sss_authtok_new(pd); if (pd->newauthtok == NULL) { ret = ENOMEM; goto failed; } } *dst = pd; return EOK; failed: talloc_free(pd); DEBUG(SSSDBG_CRIT_FAILURE, "copy_pam_data failed: (%d) %s.\n", ret, strerror(ret)); return ret; } void pam_print_data(int l, struct pam_data *pd) { DEBUG(l, "command: %s\n", sss_cmd2str(pd->cmd)); DEBUG(l, "domain: %s\n", PAM_SAFE_ITEM(pd->domain)); DEBUG(l, "user: %s\n", PAM_SAFE_ITEM(pd->user)); DEBUG(l, "service: %s\n", PAM_SAFE_ITEM(pd->service)); DEBUG(l, "tty: %s\n", PAM_SAFE_ITEM(pd->tty)); DEBUG(l, "ruser: %s\n", PAM_SAFE_ITEM(pd->ruser)); DEBUG(l, "rhost: %s\n", PAM_SAFE_ITEM(pd->rhost)); DEBUG(l, "authtok type: %d\n", sss_authtok_get_type(pd->authtok)); DEBUG(l, "newauthtok type: %d\n", sss_authtok_get_type(pd->newauthtok)); DEBUG(l, "priv: %d\n", pd->priv); DEBUG(l, "cli_pid: %d\n", pd->cli_pid); DEBUG(l, "logon name: %s\n", PAM_SAFE_ITEM(pd->logon_name)); } int pam_add_response(struct pam_data *pd, enum response_type type, int len, const uint8_t *data) { struct response_data *new; new = talloc(pd, struct response_data); if (new == NULL) return ENOMEM; new->type = type; new->len = len; new->data = talloc_memdup(pd, data, len); if (new->data == NULL) return ENOMEM; new->do_not_send_to_client = false; new->next = pd->resp_list; pd->resp_list = new; return EOK; } sssd-1.13.4/src/providers/PaxHeaders.16287/fail_over.h0000644000000000000000000000007412703456111017250 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.532793215 sssd-1.13.4/src/providers/fail_over.h0000644002412700241270000001717312703456111020730 0ustar00jhrozekjhrozek00000000000000/* SSSD Fail over helper functions. Authors: Martin Nagy Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __FAIL_OVER_H__ #define __FAIL_OVER_H__ #include #include #include "resolv/async_resolv.h" #include "providers/fail_over_srv.h" #define FO_PROTO_TCP "tcp" #define FO_PROTO_UDP "udp" /* Some forward declarations that don't have to do anything with fail over. */ struct hostent; struct tevent_context; struct tevent_req; enum port_status { PORT_NEUTRAL, /* We didn't try this port yet. */ PORT_WORKING, /* This port was reported to work. */ PORT_NOT_WORKING /* This port was reported to not work. */ }; enum server_status { SERVER_NAME_NOT_RESOLVED, /* We didn't yet resolved the host name. */ SERVER_RESOLVING_NAME, /* Name resolving is in progress. */ SERVER_NAME_RESOLVED, /* We resolved the host name but didn't try to connect. */ SERVER_WORKING, /* We successfully connected to the server. */ SERVER_NOT_WORKING /* We tried and failed to connect to the server. */ }; struct fo_ctx; struct fo_service; struct fo_server; /* * Failover settings. * * The 'retry_timeout' member specifies the * duration in seconds of how long a server or port will be considered * non-working after being marked as such. * * The 'service_resolv_timeout' member specifies how long we wait for * service resolution. When this timeout is reached, the resolve request * is cancelled with an error * * The 'srv_retry_timeout' member specifies how long a SRV lookup * is considered valid until we ask the server again. * * The 'srv_retry_neg_timeout' member specifies how long a SRV lookup * waits before previously failed lookup is tried again. * * The family_order member specifies the order of address families to * try when looking up the service. */ struct fo_options { time_t srv_retry_neg_timeout; time_t retry_timeout; int service_resolv_timeout; enum restrict_family family_order; }; /* * Create a new fail over context based on options passed in the * opts parameter */ struct fo_ctx *fo_context_init(TALLOC_CTX *mem_ctx, struct fo_options *opts); typedef int (*datacmp_fn)(void*, void*); /* * Create a new service structure for 'ctx', saving it to the location pointed * to by '_service'. The needed memory will be allocated from 'ctx'. * Service name will be set to 'name'. * * Function pointed by user_data_cmp returns 0 if user_data is equal * or nonzero value if not. Set to NULL if no user data comparison * is needed in fail over duplicate servers detection. */ int fo_new_service(struct fo_ctx *ctx, const char *name, datacmp_fn user_data_cmp, struct fo_service **_service); /* * Look up service named 'name' from the 'ctx' service list. Target of * '_service' will be set to the service if it was found. */ int fo_get_service(struct fo_ctx *ctx, const char *name, struct fo_service **_service); /* * Get number of servers registered for the 'service'. */ int fo_get_server_count(struct fo_service *service); /* * Adds a server 'name' to the 'service'. Port 'port' will be used for * connection. If 'name' is NULL, no server resolution will be done. */ int fo_add_server(struct fo_service *service, const char *name, int port, void *user_data, bool primary); int fo_add_srv_server(struct fo_service *service, const char *srv, const char *discovery_domain, const char *sssd_domain, const char *proto, void *user_data); /* * Request the first server from the service's list of servers. It is only * considered if it is not marked as not working (or the retry interval already * passed). If the server address wasn't resolved yet, it will be done. */ struct tevent_req *fo_resolve_service_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv, struct fo_ctx *ctx, struct fo_service *service); int fo_resolve_service_recv(struct tevent_req *req, TALLOC_CTX *ref_ctx, struct fo_server **server); /* To be used by async consumers of fo_resolve_service. If a server should be returned * to an outer request, it should be referenced by a memory from that outer request, * because the failover's server list might change with a subsequent call (see upstream * bug #2829) */ void fo_ref_server(TALLOC_CTX *ref_ctx, struct fo_server *server); /* * Set feedback about 'server'. Caller should use this to indicate a problem * with the server itself, not only with the service on that server. This * should be used, for example, when the IP address of the server can't be * reached. This setting can affect other services as well, since they can * share the same server. */ void fo_set_server_status(struct fo_server *server, enum server_status status); /* * Set feedback about the port status. This function should be used when * the server itself is working but the service is not. When status is set * to PORT_WORKING, 'server' is also marked as an "active server" for its * service. When the next fo_resolve_service_send() function is called, this * server will be preferred. This will hold as long as it is not marked as * not-working. */ void fo_set_port_status(struct fo_server *server, enum port_status status); /* * Instruct fail-over to try next server on the next connect attempt. * Should be used after connection to service was unexpectedly dropped * but there is no authoritative information on whether active server is down. */ void fo_try_next_server(struct fo_service *service); void *fo_get_server_user_data(struct fo_server *server); int fo_get_server_port(struct fo_server *server); const char *fo_get_server_name(struct fo_server *server); const char *fo_get_server_str_name(struct fo_server *server); struct resolv_hostent *fo_get_server_hostent(struct fo_server *server); bool fo_is_server_primary(struct fo_server *server); time_t fo_get_server_hostname_last_change(struct fo_server *server); int fo_is_srv_lookup(struct fo_server *s); time_t fo_get_service_retry_timeout(struct fo_service *svc); void fo_reset_services(struct fo_ctx *fo_ctx); void fo_reset_servers(struct fo_service *svc); struct fo_server *fo_get_active_server(struct fo_service *service); bool fo_svc_has_server(struct fo_service *service, struct fo_server *server); /* * pvt will be talloc_stealed to ctx */ bool fo_set_srv_lookup_plugin(struct fo_ctx *ctx, fo_srv_lookup_plugin_send_t send_fn, fo_srv_lookup_plugin_recv_t recv_fn, void *pvt); #endif /* !__FAIL_OVER_H__ */ sssd-1.13.4/src/providers/PaxHeaders.16287/data_provider_fo.c0000644000000000000000000000007412703456111020604 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.655793632 sssd-1.13.4/src/providers/data_provider_fo.c0000644002412700241270000006465012703456111022266 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider Helpers Copyright (C) Simo Sorce 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "providers/dp_backend.h" #include "resolv/async_resolv.h" struct be_svc_callback { struct be_svc_callback *prev; struct be_svc_callback *next; struct be_svc_data *svc; be_svc_callback_fn_t *fn; void *private_data; }; struct be_svc_data { struct be_svc_data *prev; struct be_svc_data *next; const char *name; struct fo_service *fo_service; struct fo_server *last_good_srv; time_t last_status_change; bool run_callbacks; struct be_svc_callback *callbacks; struct fo_server *first_resolved; }; struct be_failover_ctx { struct fo_ctx *fo_ctx; struct be_resolv_ctx *be_res; struct be_svc_data *svcs; struct tevent_timer *primary_server_handler; }; static const char *proto_table[] = { FO_PROTO_TCP, FO_PROTO_UDP, NULL }; int be_fo_is_srv_identifier(const char *server) { return server && strcasecmp(server, BE_SRV_IDENTIFIER) == 0; } static int be_fo_get_options(struct be_ctx *ctx, struct fo_options *opts) { opts->service_resolv_timeout = dp_opt_get_int(ctx->be_res->opts, DP_RES_OPT_RESOLVER_TIMEOUT); opts->retry_timeout = 30; opts->srv_retry_neg_timeout = 15; opts->family_order = ctx->be_res->family_order; return EOK; } int be_init_failover(struct be_ctx *ctx) { int ret; struct fo_options fopts; if (ctx->be_fo != NULL) { return EOK; } ctx->be_fo = talloc_zero(ctx, struct be_failover_ctx); if (!ctx->be_fo) { return ENOMEM; } ret = be_res_init(ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing resolver context\n"); talloc_zfree(ctx->be_fo); return ret; } ctx->be_fo->be_res = ctx->be_res; ret = be_fo_get_options(ctx, &fopts); if (ret != EOK) { talloc_zfree(ctx->be_fo); return ret; } ctx->be_fo->fo_ctx = fo_context_init(ctx->be_fo, &fopts); if (!ctx->be_fo->fo_ctx) { talloc_zfree(ctx->be_fo); return ENOMEM; } return EOK; } static int be_svc_data_destroy(void *memptr) { struct be_svc_data *svc; svc = talloc_get_type(memptr, struct be_svc_data); while (svc->callbacks) { /* callbacks removes themselves from the list, * so this while will freem them all and then terminate */ talloc_free(svc->callbacks); } return 0; } /* * Find registered be_svc_data by service name. */ static struct be_svc_data *be_fo_find_svc_data(struct be_ctx *ctx, const char *service_name) { struct be_svc_data *svc; if (!ctx || !ctx->be_fo) { return 0; } DLIST_FOR_EACH(svc, ctx->be_fo->svcs) { if (strcmp(svc->name, service_name) == 0) { return svc; } } return 0; } int be_fo_add_service(struct be_ctx *ctx, const char *service_name, datacmp_fn user_data_cmp) { struct fo_service *service; struct be_svc_data *svc; int ret; svc = be_fo_find_svc_data(ctx, service_name); if (svc) { DEBUG(SSSDBG_TRACE_FUNC, "Failover service already initialized!\n"); /* we already have a service up and configured, * can happen when using both id and auth provider */ return EOK; } /* if not in the be service list, try to create new one */ ret = fo_new_service(ctx->be_fo->fo_ctx, service_name, user_data_cmp, &service); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create failover service!\n"); return ret; } svc = talloc_zero(ctx->be_fo, struct be_svc_data); if (!svc) { return ENOMEM; } talloc_set_destructor((TALLOC_CTX *)svc, be_svc_data_destroy); svc->name = talloc_strdup(svc, service_name); if (!svc->name) { talloc_zfree(svc); return ENOMEM; } svc->fo_service = service; DLIST_ADD(ctx->be_fo->svcs, svc); return EOK; } static int be_svc_callback_destroy(void *memptr) { struct be_svc_callback *callback; callback = talloc_get_type(memptr, struct be_svc_callback); if (callback->svc) { DLIST_REMOVE(callback->svc->callbacks, callback); } return 0; } int be_fo_service_add_callback(TALLOC_CTX *memctx, struct be_ctx *ctx, const char *service_name, be_svc_callback_fn_t *fn, void *private_data) { struct be_svc_callback *callback; struct be_svc_data *svc; svc = be_fo_find_svc_data(ctx, service_name); if (NULL == svc) { return ENOENT; } callback = talloc_zero(memctx, struct be_svc_callback); if (!callback) { return ENOMEM; } talloc_set_destructor((TALLOC_CTX *)callback, be_svc_callback_destroy); callback->svc = svc; callback->fn = fn; callback->private_data = private_data; DLIST_ADD(svc->callbacks, callback); return EOK; } void be_fo_set_srv_lookup_plugin(struct be_ctx *ctx, fo_srv_lookup_plugin_send_t send_fn, fo_srv_lookup_plugin_recv_t recv_fn, void *pvt, const char *plugin_name) { bool bret; DEBUG(SSSDBG_TRACE_FUNC, "Trying to set SRV lookup plugin to %s\n", plugin_name); bret = fo_set_srv_lookup_plugin(ctx->be_fo->fo_ctx, send_fn, recv_fn, pvt); if (bret) { DEBUG(SSSDBG_TRACE_FUNC, "SRV lookup plugin is now %s\n", plugin_name); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to set SRV lookup plugin, " "another plugin may be already in place\n"); } } errno_t be_fo_set_dns_srv_lookup_plugin(struct be_ctx *be_ctx, const char *hostname) { struct fo_resolve_srv_dns_ctx *srv_ctx = NULL; char resolved_hostname[HOST_NAME_MAX + 1]; errno_t ret; if (hostname == NULL) { ret = gethostname(resolved_hostname, HOST_NAME_MAX); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "gethostname() failed: [%d]: %s\n", ret, strerror(ret)); return ret; } resolved_hostname[HOST_NAME_MAX] = '\0'; hostname = resolved_hostname; } srv_ctx = fo_resolve_srv_dns_ctx_init(be_ctx, be_ctx->be_res->resolv, be_ctx->be_res->family_order, default_host_dbs, hostname, be_ctx->domain->name); if (srv_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n"); return ENOMEM; } be_fo_set_srv_lookup_plugin(be_ctx, fo_resolve_srv_dns_send, fo_resolve_srv_dns_recv, srv_ctx, "DNS"); return EOK; } int be_fo_add_srv_server(struct be_ctx *ctx, const char *service_name, const char *query_service, const char *default_discovery_domain, enum be_fo_protocol proto, bool proto_fallback, void *user_data) { struct be_svc_data *svc; const char *domain; int ret; int i; svc = be_fo_find_svc_data(ctx, service_name); if (NULL == svc) { return ENOENT; } domain = dp_opt_get_string(ctx->be_res->opts, DP_RES_OPT_DNS_DOMAIN); if (!domain) { domain = default_discovery_domain; } /* Add the first protocol as the primary lookup */ ret = fo_add_srv_server(svc->fo_service, query_service, domain, ctx->domain->name, proto_table[proto], user_data); if (ret && ret != EEXIST) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add SRV lookup reference to failover service\n"); return ret; } if (proto_fallback) { i = (proto + 1) % BE_FO_PROTO_SENTINEL; /* All the rest as fallback */ while (i != proto) { ret = fo_add_srv_server(svc->fo_service, query_service, domain, ctx->domain->name, proto_table[i], user_data); if (ret && ret != EEXIST) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add SRV lookup reference to failover service\n"); return ret; } i = (i + 1) % BE_FO_PROTO_SENTINEL; } } return EOK; } int be_fo_get_server_count(struct be_ctx *ctx, const char *service_name) { struct be_svc_data *svc_data; svc_data = be_fo_find_svc_data(ctx, service_name); if (!svc_data) { return 0; } return fo_get_server_count(svc_data->fo_service); } int be_fo_add_server(struct be_ctx *ctx, const char *service_name, const char *server, int port, void *user_data, bool primary) { struct be_svc_data *svc; int ret; svc = be_fo_find_svc_data(ctx, service_name); if (NULL == svc) { return ENOENT; } ret = fo_add_server(svc->fo_service, server, port, user_data, primary); if (ret && ret != EEXIST) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add server to failover service\n"); return ret; } return EOK; } struct be_resolve_server_state { struct tevent_context *ev; struct be_ctx *ctx; struct be_svc_data *svc; int attempts; struct fo_server *srv; bool first_try; }; struct be_primary_server_ctx { struct be_ctx *bctx; struct tevent_context *ev; struct be_svc_data *svc; unsigned long timeout; int attempts; }; errno_t be_resolve_server_process(struct tevent_req *subreq, struct be_resolve_server_state *state, struct tevent_req **new_subreq); static void be_primary_server_done(struct tevent_req *subreq); static errno_t be_primary_server_timeout_activate(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *bctx, struct be_svc_data *svc, const unsigned long timeout_seconds); static void be_primary_server_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct be_primary_server_ctx *ctx = talloc_get_type(pvt, struct be_primary_server_ctx); struct tevent_req *subreq; ctx->bctx->be_fo->primary_server_handler = NULL; DEBUG(SSSDBG_TRACE_FUNC, "Looking for primary server!\n"); subreq = fo_resolve_service_send(ctx->bctx, ctx->ev, ctx->bctx->be_fo->be_res->resolv, ctx->bctx->be_fo->fo_ctx, ctx->svc->fo_service); if (subreq == NULL) { return; } tevent_req_set_callback(subreq, be_primary_server_done, ctx); } static void be_primary_server_done(struct tevent_req *subreq) { errno_t ret; struct be_primary_server_ctx *ctx; struct be_resolve_server_state *resolve_state; struct tevent_req *new_subreq; ctx = tevent_req_callback_data(subreq, struct be_primary_server_ctx); resolve_state = talloc_zero(ctx->bctx, struct be_resolve_server_state); if (resolve_state == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero() failed\n"); return; } resolve_state->attempts = ctx->attempts; resolve_state->ctx = ctx->bctx; resolve_state->ev = ctx->ev; resolve_state->first_try = true; resolve_state->srv = NULL; resolve_state->svc = ctx->svc; ret = be_resolve_server_process(subreq, resolve_state, &new_subreq); talloc_free(subreq); if (ret == EAGAIN) { ctx->attempts++; tevent_req_set_callback(new_subreq, be_primary_server_done, ctx); return; } else if (ret == EIO || (ret == EOK && !fo_is_server_primary(resolve_state->srv))) { /* Schedule another lookup * (either no server could be found or it was not primary) */ ret = be_primary_server_timeout_activate(ctx->bctx, ctx->ev, ctx->bctx, ctx->svc, ctx->timeout); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not schedule primary server lookup\n"); } } else if (ret == EOK) { be_run_reconnect_cb(ctx->bctx); } talloc_zfree(ctx); /* If an error occurred just end the routine */ } static errno_t be_primary_server_timeout_activate(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *bctx, struct be_svc_data *svc, const unsigned long timeout_seconds) { struct timeval tv; struct be_primary_server_ctx *ctx; struct be_failover_ctx *fo_ctx = bctx->be_fo; if (fo_ctx->primary_server_handler != NULL) { DEBUG(SSSDBG_TRACE_FUNC, "The primary server reconnection " "is already scheduled\n"); return EOK; } ctx = talloc_zero(mem_ctx, struct be_primary_server_ctx); if (ctx == NULL) { return ENOMEM; } ctx->bctx = bctx; ctx->ev = ev; ctx->svc = svc; ctx->timeout = timeout_seconds; tv = tevent_timeval_current(); tv = tevent_timeval_add(&tv, timeout_seconds, 0); fo_ctx->primary_server_handler = tevent_add_timer(ev, bctx, tv, be_primary_server_timeout, ctx); if (fo_ctx->primary_server_handler == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n"); talloc_free(ctx); return ENOMEM; } DEBUG(SSSDBG_TRACE_INTERNAL, "Primary server reactivation timeout set " "to %lu seconds\n", timeout_seconds); return EOK; } static void be_resolve_server_done(struct tevent_req *subreq); struct tevent_req *be_resolve_server_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct be_ctx *ctx, const char *service_name, bool first_try) { struct tevent_req *req, *subreq; struct be_resolve_server_state *state; struct be_svc_data *svc; req = tevent_req_create(memctx, &state, struct be_resolve_server_state); if (!req) return NULL; state->ev = ev; state->ctx = ctx; svc = be_fo_find_svc_data(ctx, service_name); if (NULL == svc) { tevent_req_error(req, EINVAL); tevent_req_post(req, ev); return req; } state->svc = svc; state->attempts = 0; state->first_try = first_try; subreq = fo_resolve_service_send(state, ev, ctx->be_fo->be_res->resolv, ctx->be_fo->fo_ctx, svc->fo_service); if (!subreq) { talloc_zfree(req); return NULL; } tevent_req_set_callback(subreq, be_resolve_server_done, req); return req; } static void be_resolve_server_done(struct tevent_req *subreq) { struct tevent_req *new_subreq; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct be_resolve_server_state *state = tevent_req_data(req, struct be_resolve_server_state); time_t timeout = fo_get_service_retry_timeout(state->svc->fo_service) + 1; int ret; ret = be_resolve_server_process(subreq, state, &new_subreq); talloc_zfree(subreq); if (ret == EAGAIN) { tevent_req_set_callback(new_subreq, be_resolve_server_done, req); return; } else if (ret != EOK) { goto fail; } if (!fo_is_server_primary(state->srv)) { /* FIXME: make the timeout configurable */ ret = be_primary_server_timeout_activate(state->ctx, state->ev, state->ctx, state->svc, timeout); if (ret != EOK) { goto fail; } } tevent_req_done(req); return; fail: DEBUG(SSSDBG_TRACE_LIBS, "Server resolution failed: %d\n", ret); state->svc->first_resolved = NULL; tevent_req_error(req, ret); } errno_t be_resolve_server_process(struct tevent_req *subreq, struct be_resolve_server_state *state, struct tevent_req **new_subreq) { errno_t ret; time_t srv_status_change; struct be_svc_callback *callback; ret = fo_resolve_service_recv(subreq, state, &state->srv); switch (ret) { case EOK: if (!state->srv) { return EFAULT; } break; case ENOENT: /* all servers have been tried and none * was found good, go offline */ return EIO; default: /* mark server as bad and retry */ if (!state->srv) { return EFAULT; } DEBUG(SSSDBG_MINOR_FAILURE, "Couldn't resolve server (%s), resolver returned (%d)\n", fo_get_server_str_name(state->srv), ret); state->attempts++; if (state->attempts >= 10) { DEBUG(SSSDBG_OP_FAILURE, "Failed to find a server after 10 attempts\n"); return EIO; } /* now try next one */ DEBUG(SSSDBG_TRACE_LIBS, "Trying with the next one!\n"); subreq = fo_resolve_service_send(state, state->ev, state->ctx->be_fo->be_res->resolv, state->ctx->be_fo->fo_ctx, state->svc->fo_service); if (!subreq) { return ENOMEM; } if (new_subreq) { *new_subreq = subreq; } return EAGAIN; } /* all fine we got the server */ if (state->svc->first_resolved == NULL || state->first_try == true) { DEBUG(SSSDBG_TRACE_LIBS, "Saving the first resolved server\n"); state->svc->first_resolved = state->srv; } else if (state->svc->first_resolved == state->srv) { DEBUG(SSSDBG_OP_FAILURE, "The fail over cycled through all available servers\n"); return ENOENT; } if (DEBUG_IS_SET(SSSDBG_FUNC_DATA) && fo_get_server_name(state->srv)) { struct resolv_hostent *srvaddr; char ipaddr[128]; srvaddr = fo_get_server_hostent(state->srv); if (!srvaddr) { DEBUG(SSSDBG_CRIT_FAILURE, "FATAL: No hostent available for server (%s)\n", fo_get_server_str_name(state->srv)); return EFAULT; } inet_ntop(srvaddr->family, srvaddr->addr_list[0]->ipaddr, ipaddr, 128); DEBUG(SSSDBG_FUNC_DATA, "Found address for server %s: [%s] TTL %d\n", fo_get_server_str_name(state->srv), ipaddr, srvaddr->addr_list[0]->ttl); } srv_status_change = fo_get_server_hostname_last_change(state->srv); /* now call all svc callbacks if server changed or if it is explicitly * requested or if the server is the same but changed status since last time*/ if (state->srv != state->svc->last_good_srv || state->svc->run_callbacks || srv_status_change > state->svc->last_status_change) { state->svc->last_good_srv = state->srv; state->svc->last_status_change = srv_status_change; state->svc->run_callbacks = false; DLIST_FOR_EACH(callback, state->svc->callbacks) { callback->fn(callback->private_data, state->srv); } } return EOK; } int be_resolve_server_recv(struct tevent_req *req, TALLOC_CTX *ref_ctx, struct fo_server **srv) { struct be_resolve_server_state *state = tevent_req_data(req, struct be_resolve_server_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (srv) { fo_ref_server(ref_ctx, state->srv); *srv = state->srv; } return EOK; } void be_fo_try_next_server(struct be_ctx *ctx, const char *service_name) { struct be_svc_data *svc; svc = be_fo_find_svc_data(ctx, service_name); if (svc) { fo_try_next_server(svc->fo_service); } } const char *be_fo_get_active_server_name(struct be_ctx *ctx, const char *service_name) { struct be_svc_data *svc; struct fo_server *server; svc = be_fo_find_svc_data(ctx, service_name); if (svc != NULL) { server = fo_get_active_server(svc->fo_service); if (server != NULL) { return fo_get_server_name(server); } } return NULL; } int be_fo_run_callbacks_at_next_request(struct be_ctx *ctx, const char *service_name) { struct be_svc_data *svc; svc = be_fo_find_svc_data(ctx, service_name); if (NULL == svc) { return ENOENT; } svc->run_callbacks = true; return EOK; } void reset_fo(struct be_ctx *be_ctx) { fo_reset_services(be_ctx->be_fo->fo_ctx); } void be_fo_reset_svc(struct be_ctx *be_ctx, const char *svc_name) { struct fo_service *service; int ret; DEBUG(SSSDBG_TRACE_LIBS, "Resetting all servers in service %s\n", svc_name); ret = fo_get_service(be_ctx->be_fo->fo_ctx, svc_name, &service); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot retrieve service [%s]\n", svc_name); return; } fo_reset_servers(service); } void _be_fo_set_port_status(struct be_ctx *ctx, const char *service_name, struct fo_server *server, enum port_status status, int line, const char *file, const char *function) { struct be_svc_data *be_svc; /* Print debug info */ switch (status) { case PORT_NEUTRAL: DEBUG(SSSDBG_BE_FO, "Setting status: PORT_NEUTRAL. Called from: %s: %s: %d\n", file, function, line); break; case PORT_WORKING: DEBUG(SSSDBG_BE_FO, "Setting status: PORT_WORKING. Called from: %s: %s: %d\n", file, function, line); break; case PORT_NOT_WORKING: DEBUG(SSSDBG_BE_FO, "Setting status: PORT_NOT_WORKING. Called from: %s: %s: %d\n", file, function, line); break; } be_svc = be_fo_find_svc_data(ctx, service_name); if (be_svc == NULL) { DEBUG(SSSDBG_OP_FAILURE, "No service associated with name %s\n", service_name); return; } if (!fo_svc_has_server(be_svc->fo_service, server)) { DEBUG(SSSDBG_OP_FAILURE, "The server %p is not valid anymore, cannot set its status\n", server); return; } /* Now we know that the server is valid */ fo_set_port_status(server, status); if (status == PORT_WORKING) { /* We were successful in connecting to the server. Cycle through all * available servers next time */ be_svc->first_resolved = NULL; } } /* Resolver back end interface */ static struct dp_option dp_res_default_opts[] = { { "lookup_family_order", DP_OPT_STRING, { "ipv4_first" }, NULL_STRING }, { "dns_resolver_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "dns_resolver_op_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "dns_discovery_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING }, DP_OPTION_TERMINATOR }; static errno_t be_res_get_opts(struct be_resolv_ctx *res_ctx, struct confdb_ctx *cdb, const char *conf_path) { errno_t ret; const char *str_family; ret = dp_get_options(res_ctx, cdb, conf_path, dp_res_default_opts, DP_RES_OPTS, &res_ctx->opts); if (ret != EOK) { return ret; } str_family = dp_opt_get_string(res_ctx->opts, DP_RES_OPT_FAMILY_ORDER); DEBUG(SSSDBG_CONF_SETTINGS, "Lookup order: %s\n", str_family); if (strcasecmp(str_family, "ipv4_first") == 0) { res_ctx->family_order = IPV4_FIRST; } else if (strcasecmp(str_family, "ipv4_only") == 0) { res_ctx->family_order = IPV4_ONLY; } else if (strcasecmp(str_family, "ipv6_first") == 0) { res_ctx->family_order = IPV6_FIRST; } else if (strcasecmp(str_family, "ipv6_only") == 0) { res_ctx->family_order = IPV6_ONLY; } else { DEBUG(SSSDBG_OP_FAILURE, "Unknown value for option %s: %s\n", dp_res_default_opts[DP_RES_OPT_FAMILY_ORDER].opt_name, str_family); return EINVAL; } return EOK; } errno_t be_res_init(struct be_ctx *ctx) { errno_t ret; if (ctx->be_res != NULL) { return EOK; } ctx->be_res = talloc_zero(ctx, struct be_resolv_ctx); if (!ctx->be_res) { return ENOMEM; } ret = be_res_get_opts(ctx->be_res, ctx->cdb, ctx->conf_path); if (ret != EOK) { talloc_zfree(ctx->be_res); return ret; } ret = resolv_init(ctx, ctx->ev, dp_opt_get_int(ctx->be_res->opts, DP_RES_OPT_RESOLVER_OP_TIMEOUT), &ctx->be_res->resolv); if (ret != EOK) { talloc_zfree(ctx->be_res); return ret; } return EOK; } sssd-1.13.4/src/providers/PaxHeaders.16287/data_provider_iface_generated.h0000644000000000000000000000007412703456111023272 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.663793659 sssd-1.13.4/src/providers/data_provider_iface_generated.h0000644002412700241270000000614712703456111024751 0ustar00jhrozekjhrozek00000000000000/* The following declarations are auto-generated from data_provider_iface.xml */ #ifndef __DATA_PROVIDER_IFACE_XML__ #define __DATA_PROVIDER_IFACE_XML__ #include "sbus/sssd_dbus.h" /* ------------------------------------------------------------------------ * DBus Constants * * Various constants of interface and method names mostly for use by clients */ /* constants for org.freedesktop.sssd.dataprovider */ #define DATA_PROVIDER_IFACE "org.freedesktop.sssd.dataprovider" #define DATA_PROVIDER_IFACE_REGISTERSERVICE "RegisterService" #define DATA_PROVIDER_IFACE_PAMHANDLER "pamHandler" #define DATA_PROVIDER_IFACE_SUDOHANDLER "sudoHandler" #define DATA_PROVIDER_IFACE_AUTOFSHANDLER "autofsHandler" #define DATA_PROVIDER_IFACE_HOSTHANDLER "hostHandler" #define DATA_PROVIDER_IFACE_GETDOMAINS "getDomains" #define DATA_PROVIDER_IFACE_GETACCOUNTINFO "getAccountInfo" /* constants for org.freedesktop.sssd.dataprovider_rev */ #define DATA_PROVIDER_REV_IFACE "org.freedesktop.sssd.dataprovider_rev" #define DATA_PROVIDER_REV_IFACE_UPDATECACHE "updateCache" #define DATA_PROVIDER_REV_IFACE_INITGRCHECK "initgrCheck" /* ------------------------------------------------------------------------ * DBus handlers * * These structures are filled in by implementors of the different * dbus interfaces to handle method calls. * * Handler functions of type sbus_msg_handler_fn accept raw messages, * other handlers are typed appropriately. If a handler that is * set to NULL is invoked it will result in a * org.freedesktop.DBus.Error.NotSupported error for the caller. * * Handlers have a matching xxx_finish() function (unless the method has * accepts raw messages). These finish functions the * sbus_request_return_and_finish() with the appropriate arguments to * construct a valid reply. Once a finish function has been called, the * @dbus_req it was called with is freed and no longer valid. */ /* vtable for org.freedesktop.sssd.dataprovider */ struct data_provider_iface { struct sbus_vtable vtable; /* derive from sbus_vtable */ sbus_msg_handler_fn RegisterService; sbus_msg_handler_fn pamHandler; sbus_msg_handler_fn sudoHandler; sbus_msg_handler_fn autofsHandler; sbus_msg_handler_fn hostHandler; sbus_msg_handler_fn getDomains; sbus_msg_handler_fn getAccountInfo; }; /* vtable for org.freedesktop.sssd.dataprovider_rev */ struct data_provider_rev_iface { struct sbus_vtable vtable; /* derive from sbus_vtable */ sbus_msg_handler_fn updateCache; sbus_msg_handler_fn initgrCheck; }; /* ------------------------------------------------------------------------ * DBus Interface Metadata * * These structure definitions are filled in with the information about * the interfaces, methods, properties and so on. * * The actual definitions are found in the accompanying C file next * to this header. */ /* interface info for org.freedesktop.sssd.dataprovider */ extern const struct sbus_interface_meta data_provider_iface_meta; /* interface info for org.freedesktop.sssd.dataprovider_rev */ extern const struct sbus_interface_meta data_provider_rev_iface_meta; #endif /* __DATA_PROVIDER_IFACE_XML__ */ sssd-1.13.4/src/providers/PaxHeaders.16287/dp_sbus.c0000644000000000000000000000007412703456111016734 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.844794273 sssd-1.13.4/src/providers/dp_sbus.c0000644002412700241270000000253012703456111020403 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider Helpers Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include "confdb/confdb.h" #include "sbus/sssd_dbus.h" #include "providers/data_provider.h" int dp_get_sbus_address(TALLOC_CTX *mem_ctx, char **address, const char *domain_name) { char *default_address; *address = NULL; default_address = talloc_asprintf(mem_ctx, "unix:path=%s/%s_%s", PIPE_PATH, DATA_PROVIDER_PIPE, domain_name); if (default_address == NULL) { return ENOMEM; } *address = default_address; return EOK; } sssd-1.13.4/src/providers/PaxHeaders.16287/krb50000644000000000000000000000013212703463556015725 xustar0030 mtime=1460561774.939794595 30 atime=1460561776.118798593 30 ctime=1460561774.939794595 sssd-1.13.4/src/providers/krb5/0000755002412700241270000000000012703463556017456 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_common.h0000644000000000000000000000007412703456111020360 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.540793242 sssd-1.13.4/src/providers/krb5/krb5_common.h0000644002412700241270000001573312703456111022040 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos Backend, common header file Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __KRB5_COMMON_H__ #define __KRB5_COMMON_H__ #include "config.h" #include #include "providers/dp_backend.h" #include "util/util.h" #include "util/sss_krb5.h" #define SSSD_KRB5_KDC "SSSD_KRB5_KDC" #define SSSD_KRB5_REALM "SSSD_KRB5_REALM" #define SSSD_KRB5_RENEWABLE_LIFETIME "SSSD_KRB5_RENEWABLE_LIFETIME" #define SSSD_KRB5_LIFETIME "SSSD_KRB5_LIFETIME" #define SSSD_KRB5_USE_FAST "SSSD_KRB5_USE_FAST" #define SSSD_KRB5_FAST_PRINCIPAL "SSSD_KRB5_FAST_PRINCIPAL" #define SSSD_KRB5_CANONICALIZE "SSSD_KRB5_CANONICALIZE" #define KDCINFO_TMPL PUBCONF_PATH"/kdcinfo.%s" #define KPASSWDINFO_TMPL PUBCONF_PATH"/kpasswdinfo.%s" #define SSS_KRB5KDC_FO_SRV "KERBEROS" #define SSS_KRB5KPASSWD_FO_SRV "KPASSWD" enum krb5_opts { KRB5_KDC = 0, KRB5_BACKUP_KDC, KRB5_REALM, KRB5_CCACHEDIR, KRB5_CCNAME_TMPL, KRB5_AUTH_TIMEOUT, KRB5_KEYTAB, KRB5_VALIDATE, KRB5_KPASSWD, KRB5_BACKUP_KPASSWD, KRB5_STORE_PASSWORD_IF_OFFLINE, KRB5_RENEWABLE_LIFETIME, KRB5_LIFETIME, KRB5_RENEW_INTERVAL, KRB5_USE_FAST, KRB5_FAST_PRINCIPAL, KRB5_CANONICALIZE, KRB5_USE_ENTERPRISE_PRINCIPAL, KRB5_USE_KDCINFO, KRB5_MAP_USER, KRB5_OPTS }; typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type; struct krb5_service { char *name; char *realm; bool write_kdcinfo; }; struct fo_service; struct deferred_auth_ctx; struct renew_tgt_ctx; enum krb5_config_type { K5C_GENERIC, K5C_IPA_CLIENT, K5C_IPA_SERVER }; struct map_id_name_to_krb_primary { const char *id_name; const char* krb_primary; }; struct krb5_ctx { /* opts taken from kinit */ /* in seconds */ krb5_deltat starttime; krb5_deltat lifetime; krb5_deltat rlife; int forwardable; int proxiable; int addresses; int not_forwardable; int not_proxiable; int no_addresses; int verbose; char* principal_name; char* service_name; char* keytab_name; char* k5_cache_name; char* k4_cache_name; action_type action; struct dp_option *opts; struct krb5_service *service; struct krb5_service *kpasswd_service; int child_debug_fd; pcre *illegal_path_re; struct deferred_auth_ctx *deferred_auth_ctx; struct renew_tgt_ctx *renew_tgt_ctx; bool use_fast; hash_table_t *wait_queue_hash; enum krb5_config_type config_type; struct map_id_name_to_krb_primary *name_to_primary; }; struct remove_info_files_ctx { char *realm; struct be_ctx *be_ctx; const char *kdc_service_name; const char *kpasswd_service_name; }; errno_t check_and_export_options(struct dp_option *opts, struct sss_domain_info *dom, struct krb5_ctx *krb5_ctx); errno_t krb5_try_kdcip(struct confdb_ctx *cdb, const char *conf_path, struct dp_option *opts, int opt_id); errno_t krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, struct dp_option **_opts); errno_t write_krb5info_file(const char *realm, const char *kdc, const char *service); int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, const char *service_name, const char *primary_servers, const char *backup_servers, const char *realm, bool use_kdcinfo, struct krb5_service **_service); void remove_krb5_info_files_callback(void *pvt); void krb5_finalize(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data); errno_t krb5_install_offline_callback(struct be_ctx *be_ctx, struct krb5_ctx *krb_ctx); errno_t krb5_install_sigterm_handler(struct tevent_context *ev, struct krb5_ctx *krb5_ctx); errno_t remove_krb5_info_files(TALLOC_CTX *mem_ctx, const char *realm); errno_t krb5_get_simple_upn(TALLOC_CTX *mem_ctx, struct krb5_ctx *krb5_ctx, struct sss_domain_info *dom, const char *username, const char *user_dom, char **_upn); errno_t compare_principal_realm(const char *upn, const char *realm, bool *different_realm); int sssm_krb5_auth_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_auth_data); /* from krb5_keytab.c */ /** * @brief Copy given keytab into a MEMORY keytab * * @param[in] mem_ctx Talloc memory context the new keytab name should be * allocated on * @param[in] kctx Kerberos context * @param[in] inp_keytab_file Existing keytab, if set to NULL the default * keytab will be used * @param[out] _mem_name Name of the new MEMORY keytab * @param[out] _mem_keytab Krb5 keytab handle for the new MEMORY keytab, NULL * may be passed here if the caller has no use for the * handle * * The memory for the MEMORY keytab is handled by libkrb5 internally and * a reference counter is used. If the reference counter of the specific * MEMORY keytab reaches 0, i.e. no open ones are left, the memory is free. * This means we cannot call krb5_kt_close() for the new MEMORY keytab in * copy_keytab_into_memory() because this would destroy it immediately. Hence * we have to return the handle so that the caller can safely remove the * MEMORY keytab if the is not needed anymore. Since libkrb5 frees the * internal memory when the library is unloaded short running processes can * safely pass NULL as the 5th argument because on exit all memory is freed. * Long running processes which need more control over the memory consumption * should close the handle for free the memory at runtime. */ krb5_error_code copy_keytab_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx, const char *inp_keytab_file, char **_mem_name, krb5_keytab *_mem_keytab); #endif /* __KRB5_COMMON_H__ */ sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_child_handler.c0000644000000000000000000000007412703456111021643 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.763793998 sssd-1.13.4/src/providers/krb5/krb5_child_handler.c0000644002412700241270000004654712703456111023332 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module - Manage krb5_child Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/child_common.h" #include "providers/krb5/krb5_common.h" #include "providers/krb5/krb5_auth.h" #include "src/providers/krb5/krb5_utils.h" #ifndef KRB5_CHILD_DIR #ifndef SSSD_LIBEXEC_PATH #error "SSSD_LIBEXEC_PATH not defined" #endif /* SSSD_LIBEXEC_PATH */ #define KRB5_CHILD_DIR SSSD_LIBEXEC_PATH #endif /* KRB5_CHILD_DIR */ #define KRB5_CHILD KRB5_CHILD_DIR"/krb5_child" #define TIME_T_MAX LONG_MAX #define int64_to_time_t(val) ((time_t)((val) < TIME_T_MAX ? val : TIME_T_MAX)) struct handle_child_state { struct tevent_context *ev; struct krb5child_req *kr; uint8_t *buf; ssize_t len; struct tevent_timer *timeout_handler; pid_t child_pid; struct child_io_fds *io; }; static errno_t pack_authtok(struct io_buffer *buf, size_t *rp, struct sss_auth_token *tok) { uint32_t auth_token_type; uint32_t auth_token_length = 0; const char *data; size_t len; errno_t ret = EOK; auth_token_type = sss_authtok_get_type(tok); switch (auth_token_type) { case SSS_AUTHTOK_TYPE_EMPTY: auth_token_length = 0; data = ""; break; case SSS_AUTHTOK_TYPE_PASSWORD: ret = sss_authtok_get_password(tok, &data, &len); auth_token_length = len + 1; break; case SSS_AUTHTOK_TYPE_CCFILE: ret = sss_authtok_get_ccfile(tok, &data, &len); auth_token_length = len + 1; break; case SSS_AUTHTOK_TYPE_2FA: data = (char *) sss_authtok_get_data(tok); auth_token_length = sss_authtok_get_size(tok); break; default: ret = EINVAL; } if (ret == EOK) { SAFEALIGN_COPY_UINT32(&buf->data[*rp], &auth_token_type, rp); SAFEALIGN_COPY_UINT32(&buf->data[*rp], &auth_token_length, rp); safealign_memcpy(&buf->data[*rp], data, auth_token_length, rp); } return ret; } static errno_t create_send_buffer(struct krb5child_req *kr, struct io_buffer **io_buf) { struct io_buffer *buf; size_t rp; const char *keytab; uint32_t validate; uint32_t send_pac; uint32_t use_enterprise_principal; size_t username_len = 0; errno_t ret; keytab = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_KEYTAB); if (keytab == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing keytab option.\n"); return EINVAL; } validate = dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_VALIDATE) ? 1 : 0; /* Always send PAC except for local IPA users and IPA server mode */ switch (kr->krb5_ctx->config_type) { case K5C_IPA_CLIENT: send_pac = kr->upn_from_different_realm ? 1 : 0; break; case K5C_IPA_SERVER: send_pac = 0; break; default: send_pac = 1; break; } if (kr->pd->cmd == SSS_CMD_RENEW || kr->is_offline) { use_enterprise_principal = false; } else { use_enterprise_principal = dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_USE_ENTERPRISE_PRINCIPAL) ? 1 : 0; } buf = talloc(kr, struct io_buffer); if (buf == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); return ENOMEM; } buf->size = 8*sizeof(uint32_t) + strlen(kr->upn); if (kr->pd->cmd == SSS_PAM_AUTHENTICATE || kr->pd->cmd == SSS_CMD_RENEW || kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM || kr->pd->cmd == SSS_PAM_CHAUTHTOK) { buf->size += 4*sizeof(uint32_t) + strlen(kr->ccname) + strlen(keytab) + sss_authtok_get_size(kr->pd->authtok); buf->size += sizeof(uint32_t); if (kr->old_ccname) { buf->size += strlen(kr->old_ccname); } } if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) { buf->size += 2*sizeof(uint32_t) + sss_authtok_get_size(kr->pd->newauthtok); } if (kr->pd->cmd == SSS_PAM_ACCT_MGMT) { username_len = strlen(kr->pd->user); buf->size += sizeof(uint32_t) + username_len; } buf->data = talloc_size(kr, buf->size); if (buf->data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); talloc_free(buf); return ENOMEM; } rp = 0; SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->pd->cmd, &rp); SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->uid, &rp); SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->gid, &rp); SAFEALIGN_COPY_UINT32(&buf->data[rp], &validate, &rp); SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->is_offline, &rp); SAFEALIGN_COPY_UINT32(&buf->data[rp], &send_pac, &rp); SAFEALIGN_COPY_UINT32(&buf->data[rp], &use_enterprise_principal, &rp); SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(kr->upn), &rp); safealign_memcpy(&buf->data[rp], kr->upn, strlen(kr->upn), &rp); if (kr->pd->cmd == SSS_PAM_AUTHENTICATE || kr->pd->cmd == SSS_CMD_RENEW || kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM || kr->pd->cmd == SSS_PAM_CHAUTHTOK) { SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(kr->ccname), &rp); safealign_memcpy(&buf->data[rp], kr->ccname, strlen(kr->ccname), &rp); if (kr->old_ccname) { SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(kr->old_ccname), &rp); safealign_memcpy(&buf->data[rp], kr->old_ccname, strlen(kr->old_ccname), &rp); } else { SAFEALIGN_SET_UINT32(&buf->data[rp], 0, &rp); } SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(keytab), &rp); safealign_memcpy(&buf->data[rp], keytab, strlen(keytab), &rp); ret = pack_authtok(buf, &rp, kr->pd->authtok); if (ret) { return ret; } } if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) { ret = pack_authtok(buf, &rp, kr->pd->newauthtok); if (ret) { return ret; } } if (kr->pd->cmd == SSS_PAM_ACCT_MGMT) { SAFEALIGN_SET_UINT32(&buf->data[rp], username_len, &rp); safealign_memcpy(&buf->data[rp], kr->pd->user, username_len, &rp); } *io_buf = buf; return EOK; } static void krb5_child_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct handle_child_state *state = tevent_req_data(req, struct handle_child_state); int ret; if (state->timeout_handler == NULL) { return; } DEBUG(SSSDBG_IMPORTANT_INFO, "Timeout for child [%d] reached. In case KDC is distant or network " "is slow you may consider increasing value of krb5_auth_timeout.\n", state->child_pid); ret = kill(state->child_pid, SIGKILL); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "kill failed [%d][%s].\n", errno, strerror(errno)); } tevent_req_error(req, ETIMEDOUT); } static errno_t activate_child_timeout_handler(struct tevent_req *req, struct tevent_context *ev, const uint32_t timeout_seconds) { struct timeval tv; struct handle_child_state *state = tevent_req_data(req, struct handle_child_state); tv = tevent_timeval_current(); tv = tevent_timeval_add(&tv, timeout_seconds, 0); state->timeout_handler = tevent_add_timer(ev, state, tv, krb5_child_timeout, req); if (state->timeout_handler == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n"); return ENOMEM; } return EOK; } static errno_t fork_child(struct tevent_req *req) { int pipefd_to_child[2]; int pipefd_from_child[2]; pid_t pid; int ret; errno_t err; struct handle_child_state *state = tevent_req_data(req, struct handle_child_state); const char *k5c_extra_args[3]; k5c_extra_args[0] = talloc_asprintf(state, "--fast-ccache-uid=%"SPRIuid, getuid()); k5c_extra_args[1] = talloc_asprintf(state, "--fast-ccache-gid=%"SPRIgid, getgid()); k5c_extra_args[2] = NULL; if (k5c_extra_args[0] == NULL || k5c_extra_args[1] == NULL) { return ENOMEM; } ret = pipe(pipefd_from_child); if (ret == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", errno, strerror(errno)); return err; } ret = pipe(pipefd_to_child); if (ret == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", errno, strerror(errno)); return err; } pid = fork(); if (pid == 0) { /* child */ err = exec_child_ex(state, pipefd_to_child, pipefd_from_child, KRB5_CHILD, state->kr->krb5_ctx->child_debug_fd, k5c_extra_args, false, STDIN_FILENO, STDOUT_FILENO); if (err != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec KRB5 child: [%d][%s].\n", err, strerror(err)); return err; } } else if (pid > 0) { /* parent */ state->child_pid = pid; state->io->read_from_child_fd = pipefd_from_child[0]; close(pipefd_from_child[1]); state->io->write_to_child_fd = pipefd_to_child[1]; close(pipefd_to_child[0]); sss_fd_nonblocking(state->io->read_from_child_fd); sss_fd_nonblocking(state->io->write_to_child_fd); ret = child_handler_setup(state->ev, pid, NULL, NULL, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up child signal handler\n"); return ret; } err = activate_child_timeout_handler(req, state->ev, dp_opt_get_int(state->kr->krb5_ctx->opts, KRB5_AUTH_TIMEOUT)); if (err != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "activate_child_timeout_handler failed.\n"); } } else { /* error */ err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n", errno, strerror(errno)); return err; } return EOK; } static void handle_child_step(struct tevent_req *subreq); static void handle_child_done(struct tevent_req *subreq); struct tevent_req *handle_child_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct krb5child_req *kr) { struct tevent_req *req, *subreq; struct handle_child_state *state; int ret; struct io_buffer *buf = NULL; req = tevent_req_create(mem_ctx, &state, struct handle_child_state); if (req == NULL) { return NULL; } state->ev = ev; state->kr = kr; state->buf = NULL; state->len = 0; state->child_pid = -1; state->timeout_handler = NULL; state->io = talloc(state, struct child_io_fds); if (state->io == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); ret = ENOMEM; goto fail; } state->io->write_to_child_fd = -1; state->io->read_from_child_fd = -1; talloc_set_destructor((void *) state->io, child_io_destructor); ret = create_send_buffer(kr, &buf); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "create_send_buffer failed.\n"); goto fail; } ret = fork_child(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "fork_child failed.\n"); goto fail; } subreq = write_pipe_send(state, ev, buf->data, buf->size, state->io->write_to_child_fd); if (!subreq) { ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, handle_child_step, req); return req; fail: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void handle_child_step(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct handle_child_state *state = tevent_req_data(req, struct handle_child_state); int ret; ret = write_pipe_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } close(state->io->write_to_child_fd); state->io->write_to_child_fd = -1; subreq = read_pipe_send(state, state->ev, state->io->read_from_child_fd); if (!subreq) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, handle_child_done, req); } static void handle_child_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct handle_child_state *state = tevent_req_data(req, struct handle_child_state); int ret; talloc_zfree(state->timeout_handler); ret = read_pipe_recv(subreq, state, &state->buf, &state->len); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } close(state->io->read_from_child_fd); state->io->read_from_child_fd = -1; tevent_req_done(req); return; } int handle_child_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **buf, ssize_t *len) { struct handle_child_state *state = tevent_req_data(req, struct handle_child_state); TEVENT_REQ_RETURN_ON_ERROR(req); *buf = talloc_move(mem_ctx, &state->buf); *len = state->len; return EOK; } errno_t parse_krb5_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, ssize_t len, struct pam_data *pd, int pwd_exp_warning, struct krb5_child_response **_res) { ssize_t pref_len; size_t p; errno_t ret; bool skip; char *ccname = NULL; size_t ccname_len = 0; int32_t msg_status; int32_t msg_type; int32_t msg_len; int64_t time_data; struct tgt_times tgtt; uint32_t expiration; uint32_t msg_subtype; struct krb5_child_response *res; const char *upn = NULL; size_t upn_len = 0; bool otp = false; if ((size_t) len < sizeof(int32_t)) { DEBUG(SSSDBG_CRIT_FAILURE, "message too short.\n"); return EINVAL; } memset(&tgtt, 0, sizeof(struct tgt_times)); if (pwd_exp_warning < 0) { pwd_exp_warning = KERBEROS_PWEXPIRE_WARNING_TIME; } /* A buffer with the following structure is expected. * int32_t status of the request (required) * message (zero or more) * * A message consists of: * int32_t type of the message * int32_t length of the following data * uint8_t[len] data */ p=0; SAFEALIGN_COPY_INT32(&msg_status, buf+p, &p); while (p < len) { skip = false; SAFEALIGN_COPY_INT32(&msg_type, buf+p, &p); SAFEALIGN_COPY_INT32(&msg_len, buf+p, &p); DEBUG(SSSDBG_TRACE_LIBS, "child response [%d][%d][%d].\n", msg_status, msg_type, msg_len); if (msg_len > len - p) { DEBUG(SSSDBG_CRIT_FAILURE, "message format error [%d] > [%zu].\n", msg_len, len - p); return EINVAL; } /* We need to save the name of the credential cache file. To find it * we check if the data part of a message starts with * CCACHE_ENV_NAME"=". pref_len also counts the trailing '=' because * sizeof() counts the trailing '\0' of a string. */ pref_len = sizeof(CCACHE_ENV_NAME); if ((msg_type == SSS_PAM_ENV_ITEM) && (msg_len > pref_len) && (strncmp((const char *) &buf[p], CCACHE_ENV_NAME"=", pref_len) == 0)) { ccname = (char *) &buf[p+pref_len]; ccname_len = msg_len-pref_len; } if (msg_type == SSS_KRB5_INFO_TGT_LIFETIME && msg_len == 4*sizeof(int64_t)) { SAFEALIGN_COPY_INT64(&time_data, buf+p, NULL); tgtt.authtime = int64_to_time_t(time_data); SAFEALIGN_COPY_INT64(&time_data, buf+p+sizeof(int64_t), NULL); tgtt.starttime = int64_to_time_t(time_data); SAFEALIGN_COPY_INT64(&time_data, buf+p+2*sizeof(int64_t), NULL); tgtt.endtime = int64_to_time_t(time_data); SAFEALIGN_COPY_INT64(&time_data, buf+p+3*sizeof(int64_t), NULL); tgtt.renew_till = int64_to_time_t(time_data); DEBUG(SSSDBG_TRACE_LIBS, "TGT times are [%ld][%ld][%ld][%ld].\n", tgtt.authtime, tgtt.starttime, tgtt.endtime, tgtt.renew_till); } if (msg_type == SSS_KRB5_INFO_UPN) { upn = (char *) buf + p; upn_len = msg_len; } if (msg_type == SSS_PAM_USER_INFO) { SAFEALIGN_COPY_UINT32(&msg_subtype, buf + p, NULL); if (msg_subtype == SSS_PAM_USER_INFO_EXPIRE_WARN) { SAFEALIGN_COPY_UINT32(&expiration, buf + p + sizeof(uint32_t), NULL); if (pwd_exp_warning > 0 && difftime(pwd_exp_warning, expiration) < 0.0) { skip = true; } } } if (msg_type == SSS_OTP) { otp = true; skip = true; } if (!skip) { ret = pam_add_response(pd, msg_type, msg_len, &buf[p]); if (ret != EOK) { /* This is not a fatal error */ DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } } p += msg_len; if ((p < len) && (p + 2*sizeof(int32_t) > len)) { DEBUG(SSSDBG_CRIT_FAILURE, "The remainder of the message is too short.\n"); return EINVAL; } } res = talloc_zero(mem_ctx, struct krb5_child_response); if (!res) return ENOMEM; res->otp = otp; res->msg_status = msg_status; memcpy(&res->tgtt, &tgtt, sizeof(tgtt)); if (ccname) { res->ccname = talloc_strndup(res, ccname, ccname_len); if (res->ccname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n"); talloc_free(res); return ENOMEM; } } if (upn != NULL) { res->correct_upn = talloc_strndup(res, upn, upn_len); if (res->correct_upn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n"); talloc_free(res); return ENOMEM; } } *_res = res; return EOK; } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_init_shared.h0000644000000000000000000000007412703456111021361 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.543793252 sssd-1.13.4/src/providers/krb5/krb5_init_shared.h0000644002412700241270000000167512703456111023041 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef KRB5_INIT_SHARED_H_ #define KRB5_INIT_SHARED_H_ errno_t krb5_child_init(struct krb5_ctx *krb5_auth_ctx, struct be_ctx *bectx); #endif /* KRB5_INIT_SHARED_H_ */ sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_delayed_online_authentication.c0000644000000000000000000000007412703456111025135 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.757793978 sssd-1.13.4/src/providers/krb5/krb5_delayed_online_authentication.c0000644002412700241270000002722212703456111026611 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module -- Request a TGT when the system gets online Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #ifdef USE_KEYRING #include #include #endif #include #include "providers/krb5/krb5_auth.h" #include "util/util.h" #include "util/find_uid.h" #define INITIAL_USER_TABLE_SIZE 10 struct deferred_auth_ctx { hash_table_t *user_table; struct be_ctx *be_ctx; struct tevent_context *ev; struct krb5_ctx *krb5_ctx; }; struct auth_data { struct be_ctx *be_ctx; struct krb5_ctx *krb5_ctx; struct pam_data *pd; }; static void *hash_talloc(const size_t size, void *pvt) { return talloc_size(pvt, size); } static void hash_talloc_free(void *ptr, void *pvt) { talloc_free(ptr); } static void authenticate_user_done(struct tevent_req *req); static void authenticate_user(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *private_data) { struct auth_data *auth_data = talloc_get_type(private_data, struct auth_data); struct pam_data *pd = auth_data->pd; struct tevent_req *req; DEBUG_PAM_DATA(SSSDBG_TRACE_ALL, pd); #ifdef USE_KEYRING char *password; long keysize; long keyrevoke; errno_t ret; keysize = keyctl_read_alloc(pd->key_serial, (void **)&password); if (keysize == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "keyctl_read failed [%d][%s].\n", ret, strerror(ret)); return; } ret = sss_authtok_set_password(pd->authtok, password, keysize); safezero(password, keysize); free(password); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "failed to set password in auth token [%d][%s].\n", ret, strerror(ret)); return; } keyrevoke = keyctl_revoke(pd->key_serial); if (keyrevoke == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "keyctl_revoke failed [%d][%s].\n", ret, strerror(ret)); } #endif req = krb5_auth_queue_send(auth_data, ev, auth_data->be_ctx, auth_data->pd, auth_data->krb5_ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_auth_send failed.\n"); talloc_free(auth_data); return; } tevent_req_set_callback(req, authenticate_user_done, auth_data); } static void authenticate_user_done(struct tevent_req *req) { struct auth_data *auth_data = tevent_req_callback_data(req, struct auth_data); int ret; int pam_status = PAM_SYSTEM_ERR; int dp_err = DP_ERR_OK; ret = krb5_auth_queue_recv(req, &pam_status, &dp_err); talloc_free(req); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_auth request failed.\n"); } else { if (pam_status == PAM_SUCCESS) { DEBUG(SSSDBG_CONF_SETTINGS, "Successfully authenticated user [%s].\n", auth_data->pd->user); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to authenticate user [%s].\n", auth_data->pd->user); } } talloc_free(auth_data); } static errno_t authenticate_stored_users( struct deferred_auth_ctx *deferred_auth_ctx) { int ret; hash_table_t *uid_table; struct hash_iter_context_t *iter; hash_entry_t *entry; hash_key_t key; hash_value_t value; struct pam_data *pd; struct auth_data *auth_data; struct tevent_timer *te; ret = get_uid_table(deferred_auth_ctx, &uid_table); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "get_uid_table failed.\n"); return ret; } iter = new_hash_iter_context(deferred_auth_ctx->user_table); if (iter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "new_hash_iter_context failed.\n"); return EINVAL; } while ((entry = iter->next(iter)) != NULL) { key.type = HASH_KEY_ULONG; key.ul = entry->key.ul; pd = talloc_get_type(entry->value.ptr, struct pam_data); ret = hash_lookup(uid_table, &key, &value); if (ret == HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "User [%s] is still logged in, " "trying online authentication.\n", pd->user); auth_data = talloc_zero(deferred_auth_ctx->be_ctx, struct auth_data); if (auth_data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); } else { auth_data->pd = talloc_steal(auth_data, pd); auth_data->krb5_ctx = deferred_auth_ctx->krb5_ctx; auth_data->be_ctx = deferred_auth_ctx->be_ctx; te = tevent_add_timer(deferred_auth_ctx->ev, auth_data, tevent_timeval_current(), authenticate_user, auth_data); if (te == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n"); } } } else { DEBUG(SSSDBG_CRIT_FAILURE, "User [%s] is not logged in anymore, " "discarding online authentication.\n", pd->user); talloc_free(pd); } ret = hash_delete(deferred_auth_ctx->user_table, &entry->key); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_delete failed [%s].\n", hash_error_string(ret)); } } talloc_free(iter); return EOK; } static void delayed_online_authentication_callback(void *private_data) { struct deferred_auth_ctx *deferred_auth_ctx = talloc_get_type(private_data, struct deferred_auth_ctx); int ret; if (deferred_auth_ctx->user_table == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Delayed online authentication activated, " "but user table does not exists.\n"); return; } DEBUG(SSSDBG_FUNC_DATA, "Backend is online, starting delayed online authentication.\n"); ret = authenticate_stored_users(deferred_auth_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "authenticate_stored_users failed.\n"); } return; } errno_t add_user_to_delayed_online_authentication(struct krb5_ctx *krb5_ctx, struct pam_data *pd, uid_t uid) { int ret; hash_key_t key; hash_value_t value; struct pam_data *new_pd; if (krb5_ctx->deferred_auth_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing context for delayed online authentication.\n"); return EINVAL; } if (krb5_ctx->deferred_auth_ctx->user_table == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "user_table not available.\n"); return EINVAL; } if (sss_authtok_get_type(pd->authtok) != SSS_AUTHTOK_TYPE_PASSWORD) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid authtok for user [%s].\n", pd->user); return EINVAL; } ret = copy_pam_data(krb5_ctx->deferred_auth_ctx, pd, &new_pd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "copy_pam_data failed\n"); return ENOMEM; } #ifdef USE_KEYRING const char *password; size_t len; ret = sss_authtok_get_password(new_pd->authtok, &password, &len); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get password [%d][%s].\n", ret, strerror(ret)); sss_authtok_set_empty(new_pd->authtok); talloc_free(new_pd); return ret; } new_pd->key_serial = add_key("user", new_pd->user, password, len, KEY_SPEC_SESSION_KEYRING); if (new_pd->key_serial == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "add_key failed [%d][%s].\n", ret, strerror(ret)); sss_authtok_set_empty(new_pd->authtok); talloc_free(new_pd); return ret; } DEBUG(SSSDBG_TRACE_ALL, "Saved authtok of user [%s] with serial [%"SPRIkey_ser"].\n", new_pd->user, new_pd->key_serial); sss_authtok_set_empty(new_pd->authtok); #endif key.type = HASH_KEY_ULONG; key.ul = uid; value.type = HASH_VALUE_PTR; value.ptr = new_pd; ret = hash_enter(krb5_ctx->deferred_auth_ctx->user_table, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add user [%s] to table [%s], " "delayed online authentication not possible.\n", pd->user, hash_error_string(ret)); talloc_free(new_pd); return ENOMEM; } DEBUG(SSSDBG_TRACE_ALL, "Added user [%s] successfully to " "delayed online authentication.\n", pd->user); return EOK; } errno_t init_delayed_online_authentication(struct krb5_ctx *krb5_ctx, struct be_ctx *be_ctx, struct tevent_context *ev) { int ret; hash_table_t *tmp_table; ret = get_uid_table(krb5_ctx, &tmp_table); if (ret != EOK) { if (ret == ENOSYS) { DEBUG(SSSDBG_FATAL_FAILURE, "Delayed online auth was requested " "on an unsupported system.\n"); } else { DEBUG(SSSDBG_FATAL_FAILURE, "Delayed online auth was requested " "but initialisation failed.\n"); } return ret; } ret = hash_destroy(tmp_table); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_destroy failed [%s].\n", hash_error_string(ret)); return EFAULT; } krb5_ctx->deferred_auth_ctx = talloc_zero(krb5_ctx, struct deferred_auth_ctx); if (krb5_ctx->deferred_auth_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ret = hash_create_ex(INITIAL_USER_TABLE_SIZE, &krb5_ctx->deferred_auth_ctx->user_table, 0, 0, 0, 0, hash_talloc, hash_talloc_free, krb5_ctx->deferred_auth_ctx, NULL, NULL); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_create_ex failed [%s]\n", hash_error_string(ret)); ret = ENOMEM; goto fail; } krb5_ctx->deferred_auth_ctx->be_ctx = be_ctx; krb5_ctx->deferred_auth_ctx->krb5_ctx = krb5_ctx; krb5_ctx->deferred_auth_ctx->ev = ev; ret = be_add_online_cb(krb5_ctx, be_ctx, delayed_online_authentication_callback, krb5_ctx->deferred_auth_ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_add_online_cb failed.\n"); goto fail; } /* TODO: add destructor */ return EOK; fail: talloc_zfree(krb5_ctx->deferred_auth_ctx); return ret; } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_renew_tgt.c0000644000000000000000000000007412703456111021061 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.758793981 sssd-1.13.4/src/providers/krb5/krb5_renew_tgt.c0000644002412700241270000005443312703456111022541 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module -- Renew a TGT automatically Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "providers/krb5/krb5_common.h" #include "providers/krb5/krb5_auth.h" #include "providers/krb5/krb5_utils.h" #include "providers/krb5/krb5_ccache.h" #define INITIAL_TGT_TABLE_SIZE 10 struct renew_tgt_ctx { hash_table_t *tgt_table; struct be_ctx *be_ctx; struct tevent_context *ev; struct krb5_ctx *krb5_ctx; time_t timer_interval; struct tevent_timer *te; }; struct renew_data { const char *ccfile; time_t start_time; time_t lifetime; time_t start_renew_at; struct pam_data *pd; }; struct auth_data { struct be_ctx *be_ctx; struct krb5_ctx *krb5_ctx; struct pam_data *pd; struct renew_data *renew_data; hash_table_t *table; hash_key_t key; }; static void renew_tgt_done(struct tevent_req *req); static void renew_tgt(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *private_data) { struct auth_data *auth_data = talloc_get_type(private_data, struct auth_data); struct tevent_req *req; req = krb5_auth_queue_send(auth_data, ev, auth_data->be_ctx, auth_data->pd, auth_data->krb5_ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_auth_send failed.\n"); /* Give back the pam data to the renewal item to be able to retry at the next * time the renewals re run. */ auth_data->renew_data->pd = talloc_steal(auth_data->renew_data, auth_data->pd); talloc_free(auth_data); return; } tevent_req_set_callback(req, renew_tgt_done, auth_data); } static void renew_tgt_done(struct tevent_req *req) { struct auth_data *auth_data = tevent_req_callback_data(req, struct auth_data); int ret; int pam_status = PAM_SYSTEM_ERR; int dp_err; hash_value_t value; ret = krb5_auth_queue_recv(req, &pam_status, &dp_err); talloc_free(req); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_auth request failed.\n"); if (auth_data->renew_data != NULL) { DEBUG(SSSDBG_FUNC_DATA, "Giving back pam data.\n"); auth_data->renew_data->pd = talloc_steal(auth_data->renew_data, auth_data->pd); } } else { switch (pam_status) { case PAM_SUCCESS: DEBUG(SSSDBG_CONF_SETTINGS, "Successfully renewed TGT for user [%s].\n", auth_data->pd->user); /* In general a successful renewal will update the renewal item and free the * old data. But if the TGT has reached the end of his renewable lifetime it * will not be put into the list of renewable tickets again. In this case the * renewal item is not updated and the value from the hash and the one we have * stored are the same. Since the TGT cannot be renewed anymore we want to * remove it from the list of renewable tickets. */ ret = hash_lookup(auth_data->table, &auth_data->key, &value); if (ret == HASH_SUCCESS) { if (value.type == HASH_VALUE_PTR && auth_data->renew_data == talloc_get_type(value.ptr, struct renew_data)) { DEBUG(SSSDBG_FUNC_DATA, "New TGT was not added for renewal, " "removing list entry for user [%s].\n", auth_data->pd->user); ret = hash_delete(auth_data->table, &auth_data->key); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_delete failed.\n"); } } } break; case PAM_AUTHINFO_UNAVAIL: case PAM_AUTHTOK_LOCK_BUSY: DEBUG(SSSDBG_CONF_SETTINGS, "Cannot renewed TGT for user [%s] while offline, " "will retry later.\n", auth_data->pd->user); if (auth_data->renew_data != NULL) { DEBUG(SSSDBG_FUNC_DATA, "Giving back pam data.\n"); auth_data->renew_data->pd = talloc_steal(auth_data->renew_data, auth_data->pd); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Failed to renew TGT for user [%s].\n", auth_data->pd->user); ret = hash_delete(auth_data->table, &auth_data->key); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_delete failed.\n"); } } } talloc_zfree(auth_data); } static errno_t renew_all_tgts(struct renew_tgt_ctx *renew_tgt_ctx) { int ret; hash_entry_t *entries; unsigned long count; size_t c; time_t now; struct auth_data *auth_data; struct renew_data *renew_data; struct tevent_timer *te = NULL; ret = hash_entries(renew_tgt_ctx->tgt_table, &count, &entries); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_entries failed.\n"); return ENOMEM; } now = time(NULL); for (c = 0; c < count; c++) { renew_data = talloc_get_type(entries[c].value.ptr, struct renew_data); DEBUG(SSSDBG_TRACE_ALL, "Checking [%s] for renewal at [%.24s].\n", renew_data->ccfile, ctime(&renew_data->start_renew_at)); /* If renew_data->pd == NULL a renewal request for this data is * currently running so we skip it. */ if (renew_data->start_renew_at < now && renew_data->pd != NULL) { auth_data = talloc_zero(renew_tgt_ctx, struct auth_data); if (auth_data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); } else { /* We need to steal the pam_data here, because a successful renewal of the * ticket might add a new renewal item to the list with the same key (upn). * This would delete renew_data and all its children. But we cannot be sure * that adding the new renewal item is the last operation of the renewal * process with access the pam_data. To be on the safe side we steal the * pam_data and make it a child of auth_data which is only freed after the * renewal process is finished. In the case of an error during renewal we * might want to steal the pam_data back to renew_data before freeing * auth_data to allow a new renewal attempt. */ auth_data->pd = talloc_move(auth_data, &renew_data->pd); auth_data->krb5_ctx = renew_tgt_ctx->krb5_ctx; auth_data->be_ctx = renew_tgt_ctx->be_ctx; auth_data->table = renew_tgt_ctx->tgt_table; auth_data->renew_data = renew_data; auth_data->key.type = entries[c].key.type; auth_data->key.str = talloc_strdup(auth_data, entries[c].key.str); if (auth_data->key.str == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); } else { te = tevent_add_timer(renew_tgt_ctx->ev, auth_data, tevent_timeval_current(), renew_tgt, auth_data); if (te == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n"); } } } if (auth_data == NULL || te == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to renew TGT in [%s].\n", renew_data->ccfile); ret = hash_delete(renew_tgt_ctx->tgt_table, &entries[c].key); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_delete failed.\n"); } } } } talloc_free(entries); return EOK; } static void renew_handler(struct renew_tgt_ctx *renew_tgt_ctx); static void renew_tgt_offline_callback(void *private_data) { struct renew_tgt_ctx *renew_tgt_ctx = talloc_get_type(private_data, struct renew_tgt_ctx); talloc_zfree(renew_tgt_ctx->te); } static void renew_tgt_online_callback(void *private_data) { struct renew_tgt_ctx *renew_tgt_ctx = talloc_get_type(private_data, struct renew_tgt_ctx); renew_handler(renew_tgt_ctx); } static void renew_tgt_timer_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *data) { struct renew_tgt_ctx *renew_tgt_ctx = talloc_get_type(data, struct renew_tgt_ctx); /* forget the timer event, it will be freed by the tevent timer loop */ renew_tgt_ctx->te = NULL; renew_handler(renew_tgt_ctx); } static void renew_handler(struct renew_tgt_ctx *renew_tgt_ctx) { struct timeval next; int ret; if (be_is_offline(renew_tgt_ctx->be_ctx)) { DEBUG(SSSDBG_CONF_SETTINGS, "Offline, disable renew timer.\n"); return; } ret = renew_all_tgts(renew_tgt_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "renew_all_tgts failed. " "Disabling automatic TGT renewal\n"); sss_log(SSS_LOG_ERR, "Disabling automatic TGT renewal."); talloc_zfree(renew_tgt_ctx); return; } if (renew_tgt_ctx->te != NULL) { DEBUG(SSSDBG_TRACE_LIBS, "There is an active renewal timer, doing nothing.\n"); return; } DEBUG(SSSDBG_TRACE_LIBS, "Adding new renew timer.\n"); next = tevent_timeval_current_ofs(renew_tgt_ctx->timer_interval, 0); renew_tgt_ctx->te = tevent_add_timer(renew_tgt_ctx->ev, renew_tgt_ctx, next, renew_tgt_timer_handler, renew_tgt_ctx); if (renew_tgt_ctx->te == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n"); sss_log(SSS_LOG_ERR, "Disabling automatic TGT renewal."); talloc_zfree(renew_tgt_ctx); } return; } static void renew_del_cb(hash_entry_t *entry, hash_destroy_enum type, void *pvt) { struct renew_data *renew_data; if (entry->value.type == HASH_VALUE_PTR) { renew_data = talloc_get_type(entry->value.ptr, struct renew_data); talloc_zfree(renew_data); return; } DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected value type [%d].\n", entry->value.type); } static errno_t check_ccache_file(struct renew_tgt_ctx *renew_tgt_ctx, const char *ccache_file, const char *upn, const char *user_name) { int ret; struct stat stat_buf; struct tgt_times tgtt; struct pam_data pd; time_t now; const char *filename; if (ccache_file == NULL || upn == NULL || user_name == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "Missing one of the needed attributes: [%s][%s][%s].\n", ccache_file == NULL ? "cache file missing" : ccache_file, upn == NULL ? "principal missing" : upn, user_name == NULL ? "user name missing" : user_name); return EINVAL; } if (strncmp(ccache_file, "FILE:", 5) == 0) { filename = ccache_file + 5; } else { filename = ccache_file; } ret = stat(filename, &stat_buf); if (ret != EOK) { if (ret == ENOENT) { return EOK; } return ret; } DEBUG(SSSDBG_TRACE_ALL, "Found ccache file [%s].\n", ccache_file); memset(&tgtt, 0, sizeof(tgtt)); ret = get_ccache_file_data(ccache_file, upn, &tgtt); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "get_ccache_file_data failed.\n"); return ret; } memset(&pd, 0, sizeof(pd)); pd.cmd = SSS_CMD_RENEW; pd.user = discard_const_p(char, user_name); now = time(NULL); if (tgtt.renew_till > tgtt.endtime && tgtt.renew_till > now && tgtt.endtime > now) { DEBUG(SSSDBG_TRACE_LIBS, "Adding [%s] for automatic renewal.\n", ccache_file); ret = add_tgt_to_renew_table(renew_tgt_ctx->krb5_ctx, ccache_file, &tgtt, &pd, upn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "add_tgt_to_renew_table failed, " "automatic renewal not possible.\n"); } } else { DEBUG(SSSDBG_TRACE_ALL, "TGT in [%s] for [%s] is too old.\n", ccache_file, upn); } return EOK; } static errno_t check_ccache_files(struct renew_tgt_ctx *renew_tgt_ctx) { TALLOC_CTX *tmp_ctx; int ret; const char *ccache_filter = "(&("SYSDB_CCACHE_FILE"=*)" \ "("SYSDB_OBJECTCLASS"="SYSDB_USER_CLASS"))"; const char *ccache_attrs[] = { SYSDB_CCACHE_FILE, SYSDB_UPN, SYSDB_NAME, SYSDB_CANONICAL_UPN, NULL }; size_t msgs_count = 0; struct ldb_message **msgs = NULL; size_t c; const char *ccache_file; char *upn; const char *user_name; struct ldb_dn *base_dn; const struct ldb_val *user_dom_val; char *user_dom; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); return ENOMEM; } base_dn = sysdb_base_dn(renew_tgt_ctx->be_ctx->domain->sysdb, tmp_ctx); if (base_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_base_dn failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_search_entry(tmp_ctx, renew_tgt_ctx->be_ctx->domain->sysdb, base_dn, LDB_SCOPE_SUBTREE, ccache_filter, ccache_attrs, &msgs_count, &msgs); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_search_entry failed.\n"); goto done; } if (msgs_count == 0) { DEBUG(SSSDBG_TRACE_ALL, "No entries with ccache file found in cache.\n"); ret = EOK; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Found [%zu] entries with ccache file in cache.\n", msgs_count); for (c = 0; c < msgs_count; c++) { user_name = ldb_msg_find_attr_as_string(msgs[c], SYSDB_NAME, NULL); if (user_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No user name found, this is a severe error, " "but we ignore it here.\n"); continue; } /* The DNs of users in sysdb looks like * name=username,cn=users,cn=domain.name,cn=sysdb * the value of the third component (index 2) is the domain name. */ user_dom_val = ldb_dn_get_component_val(msgs[c]->dn, 2); if (user_dom_val == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Invalid user DN [%s].\n", ldb_dn_get_linearized(msgs[c]->dn)); ret = EINVAL; goto done; } user_dom = talloc_strndup(tmp_ctx, (char *) user_dom_val->data, user_dom_val->length); if (user_dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed,\n"); ret = ENOMEM; goto done; } ret = find_or_guess_upn(tmp_ctx, msgs[c], renew_tgt_ctx->krb5_ctx, renew_tgt_ctx->be_ctx->domain, user_name, user_dom, &upn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "find_or_guess_upn failed.\n"); goto done; } ccache_file = ldb_msg_find_attr_as_string(msgs[c], SYSDB_CCACHE_FILE, NULL); ret = check_ccache_file(renew_tgt_ctx, ccache_file, upn, user_name); if (ret != EOK) { DEBUG(SSSDBG_FUNC_DATA, "Failed to check ccache file [%s].\n", ccache_file); } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t init_renew_tgt(struct krb5_ctx *krb5_ctx, struct be_ctx *be_ctx, struct tevent_context *ev, time_t renew_intv) { int ret; struct timeval next; krb5_ctx->renew_tgt_ctx = talloc_zero(krb5_ctx, struct renew_tgt_ctx); if (krb5_ctx->renew_tgt_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ret = sss_hash_create_ex(krb5_ctx->renew_tgt_ctx, INITIAL_TGT_TABLE_SIZE, &krb5_ctx->renew_tgt_ctx->tgt_table, 0, 0, 0, 0, renew_del_cb, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_hash_create failed.\n"); goto fail; } krb5_ctx->renew_tgt_ctx->be_ctx = be_ctx; krb5_ctx->renew_tgt_ctx->krb5_ctx = krb5_ctx; krb5_ctx->renew_tgt_ctx->ev = ev; krb5_ctx->renew_tgt_ctx->timer_interval = renew_intv; ret = check_ccache_files(krb5_ctx->renew_tgt_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read ccache files, continuing ...\n"); } next = tevent_timeval_current_ofs(krb5_ctx->renew_tgt_ctx->timer_interval, 0); krb5_ctx->renew_tgt_ctx->te = tevent_add_timer(ev, krb5_ctx->renew_tgt_ctx, next, renew_tgt_timer_handler, krb5_ctx->renew_tgt_ctx); if (krb5_ctx->renew_tgt_ctx->te == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n"); ret = ENOMEM; goto fail; } DEBUG(SSSDBG_TRACE_LIBS, "Adding offline callback to remove renewal timer.\n"); ret = be_add_offline_cb(krb5_ctx->renew_tgt_ctx, be_ctx, renew_tgt_offline_callback, krb5_ctx->renew_tgt_ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add offline callback.\n"); goto fail; } DEBUG(SSSDBG_TRACE_LIBS, "Adding renewal task to online callbacks.\n"); ret = be_add_online_cb(krb5_ctx->renew_tgt_ctx, be_ctx, renew_tgt_online_callback, krb5_ctx->renew_tgt_ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add renewal task to online callbacks.\n"); goto fail; } return EOK; fail: talloc_zfree(krb5_ctx->renew_tgt_ctx); return ret; } errno_t add_tgt_to_renew_table(struct krb5_ctx *krb5_ctx, const char *ccfile, struct tgt_times *tgtt, struct pam_data *pd, const char *upn) { int ret; hash_key_t key; hash_value_t value; struct renew_data *renew_data = NULL; if (krb5_ctx->renew_tgt_ctx == NULL) { DEBUG(SSSDBG_TRACE_LIBS ,"Renew context not initialized, " "automatic renewal not available.\n"); return EOK; } if (pd->cmd != SSS_PAM_AUTHENTICATE && pd->cmd != SSS_CMD_RENEW && pd->cmd != SSS_PAM_CHAUTHTOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected pam task [%d].\n", pd->cmd); return EINVAL; } if (upn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing user principal name.\n"); return EINVAL; } /* hash_enter copies the content of the hash string, so it is safe to use * discard_const_p here. */ key.type = HASH_KEY_STRING; key.str = discard_const_p(char, upn); renew_data = talloc_zero(krb5_ctx->renew_tgt_ctx, struct renew_data); if (renew_data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; goto done; } if (ccfile[0] == '/') { renew_data->ccfile = talloc_asprintf(renew_data, "FILE:%s", ccfile); if (renew_data->ccfile == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } } else { renew_data->ccfile = talloc_strdup(renew_data, ccfile); } renew_data->start_time = tgtt->starttime; renew_data->lifetime = tgtt->endtime; renew_data->start_renew_at = (time_t) (tgtt->starttime + 0.5 *(tgtt->endtime - tgtt->starttime)); ret = copy_pam_data(renew_data, pd, &renew_data->pd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "copy_pam_data failed.\n"); goto done; } sss_authtok_set_empty(renew_data->pd->newauthtok); ret = sss_authtok_set_ccfile(renew_data->pd->authtok, renew_data->ccfile, 0); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store ccfile in auth token.\n"); goto done; } renew_data->pd->cmd = SSS_CMD_RENEW; value.type = HASH_VALUE_PTR; value.ptr = renew_data; ret = hash_enter(krb5_ctx->renew_tgt_ctx->tgt_table, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_enter failed.\n"); ret = EFAULT; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Added [%s] for renewal at [%.24s].\n", renew_data->ccfile, ctime(&renew_data->start_renew_at)); ret = EOK; done: if (ret != EOK) { talloc_free(renew_data); } return ret; } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_init_shared.c0000644000000000000000000000007412703456111021354 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.764794002 sssd-1.13.4/src/providers/krb5/krb5_init_shared.c0000644002412700241270000000702312703456111023025 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "providers/krb5/krb5_common.h" #include "providers/krb5/krb5_auth.h" #include "providers/krb5/krb5_utils.h" #include "providers/krb5/krb5_init_shared.h" errno_t krb5_child_init(struct krb5_ctx *krb5_auth_ctx, struct be_ctx *bectx) { errno_t ret; time_t renew_intv = 0; krb5_deltat renew_interval_delta; char *renew_interval_str; if (dp_opt_get_bool(krb5_auth_ctx->opts, KRB5_STORE_PASSWORD_IF_OFFLINE)) { ret = init_delayed_online_authentication(krb5_auth_ctx, bectx, bectx->ev); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "init_delayed_online_authentication failed.\n"); goto done; } } renew_interval_str = dp_opt_get_string(krb5_auth_ctx->opts, KRB5_RENEW_INTERVAL); if (renew_interval_str != NULL) { ret = krb5_string_to_deltat(renew_interval_str, &renew_interval_delta); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Reading krb5_renew_interval failed.\n"); renew_interval_delta = 0; } renew_intv = renew_interval_delta; } if (renew_intv > 0) { ret = init_renew_tgt(krb5_auth_ctx, bectx, bectx->ev, renew_intv); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "init_renew_tgt failed.\n"); goto done; } } ret = check_and_export_options(krb5_auth_ctx->opts, bectx->domain, krb5_auth_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "check_and_export_opts failed.\n"); goto done; } ret = krb5_install_offline_callback(bectx, krb5_auth_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_install_offline_callback failed.\n"); goto done; } ret = krb5_install_sigterm_handler(bectx->ev, krb5_auth_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_install_sigterm_handler failed.\n"); goto done; } krb5_auth_ctx->child_debug_fd = -1; /* -1 means not initialized */ ret = child_debug_init(KRB5_CHILD_LOG_FILE, &krb5_auth_ctx->child_debug_fd); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set krb5_child debugging!\n"); goto done; } ret = parse_krb5_map_user(krb5_auth_ctx, dp_opt_get_cstring(krb5_auth_ctx->opts, KRB5_MAP_USER), &krb5_auth_ctx->name_to_primary); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "parse_krb5_map_user failed: %s:[%d]\n", sss_strerror(ret), ret); goto done; } ret = EOK; done: return ret; } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_child.c0000644000000000000000000000007412703456111020146 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.938794592 sssd-1.13.4/src/providers/krb5/krb5_child.c0000644002412700241270000025276212703456111021633 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module -- tgt_req and changepw child Authors: Sumit Bose Copyright (C) 2009-2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "util/sss_krb5.h" #include "util/user_info_msg.h" #include "util/child_common.h" #include "util/find_uid.h" #include "src/util/util_errors.h" #include "providers/dp_backend.h" #include "providers/krb5/krb5_auth.h" #include "providers/krb5/krb5_utils.h" #include "sss_cli.h" #define SSSD_KRB5_CHANGEPW_PRINCIPAL "kadmin/changepw" enum k5c_fast_opt { K5C_FAST_NEVER, K5C_FAST_TRY, K5C_FAST_DEMAND, }; struct krb5_req { krb5_context ctx; krb5_principal princ; char* name; krb5_creds *creds; bool otp; char *otp_vendor; char *otp_token_id; char *otp_challenge; krb5_get_init_creds_opt *options; struct pam_data *pd; char *realm; char *ccname; char *keytab; bool validate; bool send_pac; bool use_enterprise_princ; char *fast_ccname; const char *upn; uid_t uid; gid_t gid; char *old_ccname; bool old_cc_valid; bool old_cc_active; enum k5c_fast_opt fast_val; uid_t fast_uid; gid_t fast_gid; }; static krb5_context krb5_error_ctx; #define KRB5_CHILD_DEBUG(level, error) KRB5_DEBUG(level, krb5_error_ctx, error) static krb5_error_code set_lifetime_options(krb5_get_init_creds_opt *options) { char *lifetime_str; krb5_error_code kerr; krb5_deltat lifetime; lifetime_str = getenv(SSSD_KRB5_RENEWABLE_LIFETIME); if (lifetime_str == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "Cannot read [%s] from environment.\n", SSSD_KRB5_RENEWABLE_LIFETIME); /* Unset option flag to make sure defaults from krb5.conf are used. */ options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE); } else { kerr = krb5_string_to_deltat(lifetime_str, &lifetime); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_string_to_deltat failed for [%s].\n", lifetime_str); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n", SSSD_KRB5_RENEWABLE_LIFETIME, lifetime_str); krb5_get_init_creds_opt_set_renew_life(options, lifetime); } lifetime_str = getenv(SSSD_KRB5_LIFETIME); if (lifetime_str == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "Cannot read [%s] from environment.\n", SSSD_KRB5_LIFETIME); /* Unset option flag to make sure defaults from krb5.conf are used. */ options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_TKT_LIFE); } else { kerr = krb5_string_to_deltat(lifetime_str, &lifetime); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_string_to_deltat failed for [%s].\n", lifetime_str); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n", SSSD_KRB5_LIFETIME, lifetime_str); krb5_get_init_creds_opt_set_tkt_life(options, lifetime); } return 0; } static void set_canonicalize_option(krb5_get_init_creds_opt *opts) { int canonicalize = 0; char *tmp_str; tmp_str = getenv(SSSD_KRB5_CANONICALIZE); if (tmp_str != NULL && strcasecmp(tmp_str, "true") == 0) { canonicalize = 1; } DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n", SSSD_KRB5_CANONICALIZE, tmp_str ? tmp_str : "not set"); sss_krb5_get_init_creds_opt_set_canonicalize(opts, canonicalize); } static void set_changepw_options(krb5_get_init_creds_opt *options) { sss_krb5_get_init_creds_opt_set_canonicalize(options, 0); krb5_get_init_creds_opt_set_forwardable(options, 0); krb5_get_init_creds_opt_set_proxiable(options, 0); krb5_get_init_creds_opt_set_renew_life(options, 0); krb5_get_init_creds_opt_set_tkt_life(options, 5*60); } static void revert_changepw_options(krb5_get_init_creds_opt *options) { krb5_error_code kerr; set_canonicalize_option(options); /* Currently we do not set forwardable and proxiable explicitly, the flags * must be removed so that libkrb5 can take the defaults from krb5.conf */ options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_FORWARDABLE); options->flags &= ~(KRB5_GET_INIT_CREDS_OPT_PROXIABLE); kerr = set_lifetime_options(options); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, ("set_lifetime_options failed.\n")); } } static errno_t sss_send_pac(krb5_authdata **pac_authdata) { struct sss_cli_req_data sss_data; int ret; int errnop; sss_data.len = pac_authdata[0]->length; sss_data.data = pac_authdata[0]->contents; ret = sss_pac_make_request(SSS_PAC_ADD_PAC_USER, &sss_data, NULL, NULL, &errnop); if (ret != NSS_STATUS_SUCCESS || errnop != 0) { DEBUG(SSSDBG_OP_FAILURE, "sss_pac_make_request failed [%d][%d].\n", ret, errnop); return EIO; } DEBUG(SSSDBG_TRACE_FUNC, "PAC responder contacted. It might take a bit of time in case the " "cache is not up to date.\n"); return EOK; } static void sss_krb5_expire_callback_func(krb5_context context, void *data, krb5_timestamp password_expiration, krb5_timestamp account_expiration, krb5_boolean is_last_req) { int ret; uint32_t *blob; long exp_time; struct krb5_req *kr = talloc_get_type(data, struct krb5_req); if (password_expiration == 0) { return; } exp_time = password_expiration - time(NULL); if (exp_time < 0 || exp_time > UINT32_MAX) { DEBUG(SSSDBG_CRIT_FAILURE, "Time to expire out of range.\n"); return; } DEBUG(SSSDBG_TRACE_INTERNAL, "exp_time: [%ld]\n", exp_time); blob = talloc_array(kr->pd, uint32_t, 2); if (blob == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); return; } blob[0] = SSS_PAM_USER_INFO_EXPIRE_WARN; blob[1] = (uint32_t) exp_time; ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, 2 * sizeof(uint32_t), (uint8_t *) blob); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } return; } #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_RESPONDER /* * TODO: These features generally would requires a significant refactoring * of SSSD and MIT krb5 doesn't support them anyway. They are listed here * simply as a reminder of things that might become future feature potential. * * 1. tokeninfo selection * 2. challenge * 3. discreet token/pin prompting * 4. interactive otp format correction * 5. nextOTP * */ typedef int (*checker)(int c); static inline checker pick_checker(int format) { switch (format) { case KRB5_RESPONDER_OTP_FORMAT_DECIMAL: return isdigit; case KRB5_RESPONDER_OTP_FORMAT_HEXADECIMAL: return isxdigit; case KRB5_RESPONDER_OTP_FORMAT_ALPHANUMERIC: return isalnum; } return NULL; } static int token_pin_destructor(char *mem) { safezero(mem, strlen(mem)); return 0; } static krb5_error_code tokeninfo_matches_2fa(TALLOC_CTX *mem_ctx, const krb5_responder_otp_tokeninfo *ti, const char *fa1, size_t fa1_len, const char *fa2, size_t fa2_len, char **out_token, char **out_pin) { char *token = NULL, *pin = NULL; checker check = NULL; int i; if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_NEXTOTP) { return ENOTSUP; } if (ti->challenge != NULL) { return ENOTSUP; } /* This is a non-sensical value. */ if (ti->length == 0) { return EPROTO; } if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN) { if (ti->length > 0 && ti->length != fa2_len) { DEBUG(SSSDBG_CRIT_FAILURE, "Expected [%d] and given [%zu] token size " "do not match.\n", ti->length, fa2_len); return EMSGSIZE; } if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN) { if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN) { pin = talloc_strndup(mem_ctx, fa1, fa1_len); if (pin == NULL) { talloc_free(token); return ENOMEM; } talloc_set_destructor(pin, token_pin_destructor); token = talloc_strndup(mem_ctx, fa2, fa2_len); if (token == NULL) { return ENOMEM; } talloc_set_destructor(token, token_pin_destructor); check = pick_checker(ti->format); } } else { token = talloc_asprintf(mem_ctx, "%s%s", fa1, fa2); if (token == NULL) { return ENOMEM; } talloc_set_destructor(token, token_pin_destructor); check = pick_checker(ti->format); } } else { /* Assuming PIN only required */ pin = talloc_strndup(mem_ctx, fa1, fa1_len); if (pin == NULL) { return ENOMEM; } talloc_set_destructor(pin, token_pin_destructor); } /* If check is set, we need to verify the contents of the token. */ for (i = 0; check != NULL && token[i] != '\0'; i++) { if (!check(token[i])) { talloc_free(token); talloc_free(pin); return EBADMSG; } } *out_token = token; *out_pin = pin; return 0; } static krb5_error_code tokeninfo_matches_pwd(TALLOC_CTX *mem_ctx, const krb5_responder_otp_tokeninfo *ti, const char *pwd, size_t len, char **out_token, char **out_pin) { char *token = NULL, *pin = NULL; checker check = NULL; int i; if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_NEXTOTP) { return ENOTSUP; } if (ti->challenge != NULL) { return ENOTSUP; } /* This is a non-sensical value. */ if (ti->length == 0) { return EPROTO; } if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN) { /* ASSUMPTION: authtok has one of the following formats: * 1. TokenValue * 2. PIN+TokenValue */ token = talloc_strndup(mem_ctx, pwd, len); if (token == NULL) { return ENOMEM; } talloc_set_destructor(token, token_pin_destructor); if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_COLLECT_PIN) { /* If the server desires a separate pin, we will split it. * ASSUMPTION: Format of authtok is PIN+TokenValue. */ if (ti->flags & KRB5_RESPONDER_OTP_FLAGS_SEPARATE_PIN) { if (ti->length < 1) { talloc_free(token); return ENOTSUP; } if (ti->length >= len) { talloc_free(token); return EMSGSIZE; } /* Copy the PIN from the front of the value. */ pin = talloc_strndup(NULL, pwd, len - ti->length); if (pin == NULL) { talloc_free(token); return ENOMEM; } talloc_set_destructor(pin, token_pin_destructor); /* Remove the PIN from the front of the token value. */ memmove(token, token + len - ti->length, ti->length + 1); check = pick_checker(ti->format); } else { if (ti->length > 0 && ti->length > len) { talloc_free(token); return EMSGSIZE; } } } else { if (ti->length > 0 && ti->length != len) { talloc_free(token); return EMSGSIZE; } check = pick_checker(ti->format); } } else { pin = talloc_strndup(mem_ctx, pwd, len); if (pin == NULL) { return ENOMEM; } talloc_set_destructor(pin, token_pin_destructor); } /* If check is set, we need to verify the contents of the token. */ for (i = 0; check != NULL && token[i] != '\0'; i++) { if (!check(token[i])) { talloc_free(token); talloc_free(pin); return EBADMSG; } } *out_token = token; *out_pin = pin; return 0; } static krb5_error_code tokeninfo_matches(TALLOC_CTX *mem_ctx, const krb5_responder_otp_tokeninfo *ti, struct sss_auth_token *auth_tok, char **out_token, char **out_pin) { int ret; const char *pwd; size_t len; const char *fa2; size_t fa2_len; switch (sss_authtok_get_type(auth_tok)) { case SSS_AUTHTOK_TYPE_PASSWORD: ret = sss_authtok_get_password(auth_tok, &pwd, &len); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_password failed.\n"); return ret; } return tokeninfo_matches_pwd(mem_ctx, ti, pwd, len, out_token, out_pin); break; case SSS_AUTHTOK_TYPE_2FA: ret = sss_authtok_get_2fa(auth_tok, &pwd, &len, &fa2, &fa2_len); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_2fa failed.\n"); return ret; } return tokeninfo_matches_2fa(mem_ctx, ti, pwd, len, fa2, fa2_len, out_token, out_pin); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported authtok type.\n"); } return EINVAL; } static krb5_error_code answer_otp(krb5_context ctx, struct krb5_req *kr, krb5_responder_context rctx) { krb5_responder_otp_challenge *chl; char *token = NULL, *pin = NULL; krb5_error_code ret; size_t i; ret = krb5_responder_otp_get_challenge(ctx, rctx, &chl); if (ret != EOK || chl == NULL) { /* Either an error, or nothing to do. */ return ret; } if (chl->tokeninfo == NULL || chl->tokeninfo[0] == NULL) { /* No tokeninfos? Absurd! */ ret = EINVAL; goto done; } kr->otp = true; if (kr->pd->cmd == SSS_PAM_PREAUTH) { for (i = 0; chl->tokeninfo[i] != NULL; i++) { DEBUG(SSSDBG_TRACE_ALL, "[%zu] Vendor [%s].\n", i, chl->tokeninfo[i]->vendor); DEBUG(SSSDBG_TRACE_ALL, "[%zu] Token-ID [%s].\n", i, chl->tokeninfo[i]->token_id); DEBUG(SSSDBG_TRACE_ALL, "[%zu] Challenge [%s].\n", i, chl->tokeninfo[i]->challenge); DEBUG(SSSDBG_TRACE_ALL, "[%zu] Flags [%d].\n", i, chl->tokeninfo[i]->flags); } if (chl->tokeninfo[0]->vendor != NULL) { kr->otp_vendor = talloc_strdup(kr, chl->tokeninfo[0]->vendor); } if (chl->tokeninfo[0]->token_id != NULL) { kr->otp_token_id = talloc_strdup(kr, chl->tokeninfo[0]->token_id); } if (chl->tokeninfo[0]->challenge != NULL) { kr->otp_challenge = talloc_strdup(kr, chl->tokeninfo[0]->challenge); } /* Allocation errors are ignored on purpose */ DEBUG(SSSDBG_TRACE_INTERNAL, "Exit answer_otp during pre-auth.\n"); return EAGAIN; } /* Find the first supported tokeninfo which matches our authtoken. */ for (i = 0; chl->tokeninfo[i] != NULL; i++) { ret = tokeninfo_matches(kr, chl->tokeninfo[i], kr->pd->authtok, &token, &pin); if (ret == EOK) { break; } switch (ret) { case EBADMSG: case EMSGSIZE: case ENOTSUP: case EPROTO: break; default: goto done; } } if (chl->tokeninfo[i] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No tokeninfos found which match our credentials.\n"); ret = EOK; goto done; } if (chl->tokeninfo[i]->flags & KRB5_RESPONDER_OTP_FLAGS_COLLECT_TOKEN) { /* Don't let SSSD cache the OTP authtok since it is single-use. */ ret = pam_add_response(kr->pd, SSS_OTP, 0, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); goto done; } } /* Respond with the appropriate answer. */ ret = krb5_responder_otp_set_answer(ctx, rctx, i, token, pin); done: talloc_free(token); talloc_free(pin); krb5_responder_otp_challenge_free(ctx, rctx, chl); return ret; } static krb5_error_code sss_krb5_responder(krb5_context ctx, void *data, krb5_responder_context rctx) { struct krb5_req *kr = talloc_get_type(data, struct krb5_req); if (kr == NULL) { return EINVAL; } return answer_otp(ctx, kr, rctx); } #endif static krb5_error_code sss_krb5_prompter(krb5_context context, void *data, const char *name, const char *banner, int num_prompts, krb5_prompt prompts[]) { int ret; struct krb5_req *kr = talloc_get_type(data, struct krb5_req); if (num_prompts != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot handle password prompts.\n"); return KRB5_LIBOS_CANTREADPWD; } if (banner == NULL || *banner == '\0') { DEBUG(SSSDBG_FUNC_DATA, "Prompter called with empty banner, nothing to do.\n"); return EOK; } DEBUG(SSSDBG_FUNC_DATA, "Prompter called with [%s].\n", banner); ret = pam_add_response(kr->pd, SSS_PAM_TEXT_MSG, strlen(banner)+1, (const uint8_t *) banner); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } return EOK; } static krb5_error_code create_empty_cred(krb5_context ctx, krb5_principal princ, krb5_creds **_cred) { krb5_error_code kerr; krb5_creds *cred = NULL; krb5_data *krb5_realm; cred = calloc(sizeof(krb5_creds), 1); if (cred == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "calloc failed.\n"); return ENOMEM; } kerr = krb5_copy_principal(ctx, princ, &cred->client); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_copy_principal failed.\n"); goto done; } krb5_realm = krb5_princ_realm(ctx, princ); kerr = krb5_build_principal_ext(ctx, &cred->server, krb5_realm->length, krb5_realm->data, KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, krb5_realm->length, krb5_realm->data, 0); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_build_principal_ext failed.\n"); goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Created empty krb5_creds.\n"); done: if (kerr != 0) { krb5_free_cred_contents(ctx, cred); free(cred); } else { *_cred = cred; } return kerr; } static errno_t handle_randomized(char *in) { size_t ccname_len; char *ccname = NULL; int ret; /* We only treat the FILE type case in a special way due to the history * of storing FILE type ccache in /tmp and associated security issues */ if (in[0] == '/') { ccname = in; } else if (strncmp(in, "FILE:", 5) == 0) { ccname = in + 5; } else { return EOK; } ccname_len = strlen(ccname); if (ccname_len >= 6 && strcmp(ccname + (ccname_len - 6), "XXXXXX") == 0) { /* NOTE: this call is only used to create a unique name, as later * krb5_cc_initialize() will unlink and recreate the file. * This is ok because this part of the code is called with * privileges already dropped when handling user ccache, or the ccache * is stored in a private directory. So we do not have huge issues if * something races, we mostly care only about not accidentally use * an existing name and thus failing in the process of saving the * cache. Malicious races can only be avoided by libkrb5 itself. */ ret = sss_unique_filename(NULL, ccname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "mkstemp(\"%s\") failed [%d]: %s!\n", ccname, ret, strerror(ret)); return ret; } } return EOK; } /* NOTE: callers rely on 'name' being *changed* if it needs to be randomized, * as they will then send the name back to the new name via the return call * k5c_attach_ccname_msg(). Callers will send in a copy of the name if they * do not care for changes. */ static krb5_error_code create_ccache(char *ccname, krb5_creds *creds) { krb5_context kctx = NULL; krb5_ccache kcc = NULL; const char *type; krb5_error_code kerr; #ifdef HAVE_KRB5_CC_COLLECTION krb5_ccache cckcc; bool switch_to_cc = false; #endif /* Set a restrictive umask, just in case we end up creating any file */ umask(SSS_DFL_X_UMASK); /* we create a new context here as the main process one may have been * opened as root and contain possibly references (even open handles ?) * to resources we do not have or do not want to have access to */ kerr = krb5_init_context(&kctx); if (kerr) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return ERR_INTERNAL; } kerr = handle_randomized(ccname); if (kerr) { DEBUG(SSSDBG_CRIT_FAILURE, "handle_randomized failed: %d\n", kerr); goto done; } kerr = krb5_cc_resolve(kctx, ccname, &kcc); if (kerr) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; } type = krb5_cc_get_type(kctx, kcc); DEBUG(SSSDBG_TRACE_ALL, "Initializing ccache of type [%s]\n", type); #ifdef HAVE_KRB5_CC_COLLECTION if (krb5_cc_support_switch(kctx, type)) { DEBUG(SSSDBG_TRACE_ALL, "CC supports switch\n"); kerr = krb5_cc_set_default_name(kctx, ccname); if (kerr) { DEBUG(SSSDBG_TRACE_ALL, "Cannot set default name!\n"); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; } kerr = krb5_cc_cache_match(kctx, creds->client, &cckcc); if (kerr == KRB5_CC_NOTFOUND) { DEBUG(SSSDBG_TRACE_ALL, "Match not found\n"); kerr = krb5_cc_new_unique(kctx, type, NULL, &cckcc); switch_to_cc = true; } if (kerr) { DEBUG(SSSDBG_TRACE_ALL, "krb5_cc_cache_match failed\n"); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; } krb5_cc_close(kctx, kcc); kcc = cckcc; } #endif kerr = krb5_cc_initialize(kctx, kcc, creds->client); if (kerr) { DEBUG(SSSDBG_TRACE_ALL, "krb5_cc_initialize failed\n"); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; } kerr = krb5_cc_store_cred(kctx, kcc, creds); if (kerr) { DEBUG(SSSDBG_TRACE_ALL, "krb5_cc_store_cred failed\n"); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; } #ifdef HAVE_KRB5_CC_COLLECTION if (switch_to_cc) { DEBUG(SSSDBG_TRACE_ALL, "switch_to_cc\n"); kerr = krb5_cc_switch(kctx, kcc); if (kerr) { DEBUG(SSSDBG_TRACE_ALL, "krb5_cc_switch\n"); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; } } #endif DEBUG(SSSDBG_TRACE_ALL, "returning: %d\n", kerr); done: if (kcc) { /* FIXME: should we krb5_cc_destroy in case of error ? */ krb5_cc_close(kctx, kcc); } return kerr; } static errno_t pack_response_packet(TALLOC_CTX *mem_ctx, errno_t error, struct response_data *resp_list, uint8_t **_buf, size_t *_len) { uint8_t *buf; size_t size = 0; size_t p = 0; struct response_data *pdr; /* A buffer with the following structure must be created: * int32_t status of the request (required) * message (zero or more) * * A message consists of: * int32_t type of the message * int32_t length of the following data * uint8_t[len] data */ size = sizeof(int32_t); for (pdr = resp_list; pdr != NULL; pdr = pdr->next) { size += 2*sizeof(int32_t) + pdr->len; } buf = talloc_array(mem_ctx, uint8_t, size); if (!buf) { DEBUG(SSSDBG_CRIT_FAILURE, "Insufficient memory to create message.\n"); return ENOMEM; } SAFEALIGN_SET_INT32(&buf[p], error, &p); for (pdr = resp_list; pdr != NULL; pdr = pdr->next) { SAFEALIGN_SET_INT32(&buf[p], pdr->type, &p); SAFEALIGN_SET_INT32(&buf[p], pdr->len, &p); safealign_memcpy(&buf[p], pdr->data, pdr->len, &p); } DEBUG(SSSDBG_TRACE_INTERNAL, "response packet size: [%zu]\n", p); *_buf = buf; *_len = p; return EOK; } static errno_t k5c_attach_otp_info_msg(struct krb5_req *kr) { uint8_t *msg = NULL; size_t msg_len; int ret; size_t vendor_len = 0; size_t token_id_len = 0; size_t challenge_len = 0; size_t idx = 0; msg_len = 3; if (kr->otp_vendor != NULL) { vendor_len = strlen(kr->otp_vendor); msg_len += vendor_len; } if (kr->otp_token_id != NULL) { token_id_len = strlen(kr->otp_token_id); msg_len += token_id_len; } if (kr->otp_challenge != NULL) { challenge_len = strlen(kr->otp_challenge); msg_len += challenge_len; } msg = talloc_zero_size(kr, msg_len); if (msg == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); return ENOMEM; } if (kr->otp_vendor != NULL) { memcpy(msg, kr->otp_vendor, vendor_len); } idx += vendor_len +1; if (kr->otp_token_id != NULL) { memcpy(msg + idx, kr->otp_token_id, token_id_len); } idx += token_id_len +1; if (kr->otp_challenge != NULL) { memcpy(msg + idx, kr->otp_challenge, challenge_len); } ret = pam_add_response(kr->pd, SSS_PAM_OTP_INFO, msg_len, msg); talloc_zfree(msg); return ret; } static errno_t k5c_attach_ccname_msg(struct krb5_req *kr) { char *msg = NULL; int ret; if (kr->ccname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Error obtaining ccname.\n"); return ERR_INTERNAL; } msg = talloc_asprintf(kr, "%s=%s",CCACHE_ENV_NAME, kr->ccname); if (msg == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); return ENOMEM; } ret = pam_add_response(kr->pd, SSS_PAM_ENV_ITEM, strlen(msg) + 1, (uint8_t *)msg); talloc_zfree(msg); return ret; } static errno_t k5c_send_data(struct krb5_req *kr, int fd, errno_t error) { ssize_t written; uint8_t *buf; size_t len; int ret; DEBUG(SSSDBG_FUNC_DATA, "Received error code %d\n", error); ret = pack_response_packet(kr, error, kr->pd->resp_list, &buf, &len); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_response_packet failed.\n"); return ret; } errno = 0; written = sss_atomic_write_s(fd, buf, len); if (written == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret, strerror(ret)); return ret; } if (written != len) { DEBUG(SSSDBG_CRIT_FAILURE, "Write error, wrote [%zu] bytes, expected [%zu]\n", written, len); return EOK; } DEBUG(SSSDBG_TRACE_ALL, "Response sent.\n"); return EOK; } static errno_t add_ticket_times_and_upn_to_response(struct krb5_req *kr) { int ret; int64_t t[4]; krb5_error_code kerr; char *upn = NULL; unsigned int upn_len = 0; t[0] = (int64_t) kr->creds->times.authtime; t[1] = (int64_t) kr->creds->times.starttime; t[2] = (int64_t) kr->creds->times.endtime; t[3] = (int64_t) kr->creds->times.renew_till; ret = pam_add_response(kr->pd, SSS_KRB5_INFO_TGT_LIFETIME, 4*sizeof(int64_t), (uint8_t *) t); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_response_packet failed.\n"); goto done; } kerr = krb5_unparse_name_ext(kr->ctx, kr->creds->client, &upn, &upn_len); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_unparse_name failed.\n"); goto done; } ret = pam_add_response(kr->pd, SSS_KRB5_INFO_UPN, upn_len, (uint8_t *) upn); krb5_free_unparsed_name(kr->ctx, upn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_response_packet failed.\n"); goto done; } done: return ret; } static krb5_error_code validate_tgt(struct krb5_req *kr) { krb5_error_code kerr; krb5_error_code kt_err; char *principal = NULL; krb5_keytab keytab; krb5_kt_cursor cursor; krb5_keytab_entry entry; krb5_verify_init_creds_opt opt; krb5_principal validation_princ = NULL; bool realm_entry_found = false; krb5_ccache validation_ccache = NULL; krb5_authdata **pac_authdata = NULL; memset(&keytab, 0, sizeof(keytab)); kerr = krb5_kt_resolve(kr->ctx, kr->keytab, &keytab); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s], " \ "not verifying TGT.\n", kr->keytab); return kerr; } memset(&cursor, 0, sizeof(cursor)); kerr = krb5_kt_start_seq_get(kr->ctx, keytab, &cursor); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab [%s], " \ "not verifying TGT.\n", kr->keytab); return kerr; } /* We look for the first entry from our realm or take the last one */ memset(&entry, 0, sizeof(entry)); while ((kt_err = krb5_kt_next_entry(kr->ctx, keytab, &entry, &cursor)) == 0) { if (validation_princ != NULL) { krb5_free_principal(kr->ctx, validation_princ); validation_princ = NULL; } kerr = krb5_copy_principal(kr->ctx, entry.principal, &validation_princ); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_copy_principal failed.\n"); goto done; } kerr = sss_krb5_free_keytab_entry_contents(kr->ctx, &entry); if (kerr != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to free keytab entry.\n"); } memset(&entry, 0, sizeof(entry)); if (krb5_realm_compare(kr->ctx, validation_princ, kr->creds->client)) { DEBUG(SSSDBG_TRACE_INTERNAL, "Found keytab entry with the realm of the credential.\n"); realm_entry_found = true; break; } } if (!realm_entry_found) { DEBUG(SSSDBG_TRACE_INTERNAL, "Keytab entry with the realm of the credential not found " "in keytab. Using the last entry.\n"); } /* Close the keytab here. Even though we're using cursors, the file * handle is stored in the krb5_keytab structure, and it gets * overwritten when the verify_init_creds() call below creates its own * cursor, creating a leak. */ kerr = krb5_kt_end_seq_get(kr->ctx, keytab, &cursor); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_end_seq_get failed, " \ "not verifying TGT.\n"); goto done; } /* check if we got any errors from krb5_kt_next_entry */ if (kt_err != 0 && kt_err != KRB5_KT_END) { DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab [%s], " \ "not verifying TGT.\n", kr->keytab); goto done; } /* Get the principal to which the key belongs, for logging purposes. */ principal = NULL; kerr = krb5_unparse_name(kr->ctx, validation_princ, &principal); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "internal error parsing principal name, " "not verifying TGT.\n"); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; } krb5_verify_init_creds_opt_init(&opt); kerr = krb5_verify_init_creds(kr->ctx, kr->creds, validation_princ, keytab, &validation_ccache, &opt); if (kerr == 0) { DEBUG(SSSDBG_TRACE_FUNC, "TGT verified using key for [%s].\n", principal); } else { DEBUG(SSSDBG_CRIT_FAILURE ,"TGT failed verification using key " \ "for [%s].\n", principal); goto done; } /* Try to find and send the PAC to the PAC responder. * Failures are not critical. */ if (kr->send_pac) { kerr = sss_extract_pac(kr->ctx, validation_ccache, validation_princ, kr->creds->client, keytab, &pac_authdata); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "sss_extract_and_send_pac failed, group " \ "membership for user with principal [%s] " \ "might not be correct.\n", kr->name); kerr = 0; goto done; } kerr = sss_send_pac(pac_authdata); krb5_free_authdata(kr->ctx, pac_authdata); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "sss_send_pac failed, group " \ "membership for user with principal [%s] " \ "might not be correct.\n", kr->name); kerr = 0; } } done: if (validation_ccache != NULL) { krb5_cc_destroy(kr->ctx, validation_ccache); } if (krb5_kt_close(kr->ctx, keytab) != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_close failed\n"); } if (validation_princ != NULL) { krb5_free_principal(kr->ctx, validation_princ); } if (principal != NULL) { sss_krb5_free_unparsed_name(kr->ctx, principal); } return kerr; } static krb5_error_code get_and_save_tgt_with_keytab(krb5_context ctx, krb5_principal princ, krb5_keytab keytab, char *ccname) { krb5_error_code kerr = 0; krb5_creds creds; krb5_get_init_creds_opt options; memset(&creds, 0, sizeof(creds)); memset(&options, 0, sizeof(options)); krb5_get_init_creds_opt_set_address_list(&options, NULL); krb5_get_init_creds_opt_set_forwardable(&options, 0); krb5_get_init_creds_opt_set_proxiable(&options, 0); set_canonicalize_option(&options); kerr = krb5_get_init_creds_keytab(ctx, &creds, princ, keytab, 0, NULL, &options); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } /* Use the updated principal in the creds in case canonicalized */ kerr = create_ccache(ccname, &creds); if (kerr != 0) { goto done; } kerr = 0; done: krb5_free_cred_contents(ctx, &creds); return kerr; } static krb5_error_code get_and_save_tgt(struct krb5_req *kr, const char *password) { const char *realm_name; int realm_length; krb5_error_code kerr; char *cc_name; kerr = sss_krb5_get_init_creds_opt_set_expire_callback(kr->ctx, kr->options, sss_krb5_expire_callback_func, kr); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set expire callback, continue without.\n"); } sss_krb5_princ_realm(kr->ctx, kr->princ, &realm_name, &realm_length); if (realm_length == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_princ_realm failed.\n"); return KRB5KRB_ERR_GENERIC; } DEBUG(SSSDBG_TRACE_FUNC, "Attempting kinit for realm [%s]\n",realm_name); kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ, discard_const(password), sss_krb5_prompter, kr, 0, NULL, kr->options); if (kr->pd->cmd == SSS_PAM_PREAUTH) { /* Any errors are ignored during pre-auth, only data is collected to * be send back to the client.*/ DEBUG(SSSDBG_TRACE_FUNC, "krb5_get_init_creds_password returned [%d} during pre-auth.\n", kerr); return 0; } else { if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } } if (kr->validate) { kerr = validate_tgt(kr); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } } else { DEBUG(SSSDBG_CONF_SETTINGS, "TGT validation is disabled.\n"); } /* If kr->ccname is cache collection (DIR:/...), we want to work * directly with file ccache (DIR::/...), but cache collection * should be returned back to back end. */ cc_name = sss_get_ccache_name_for_principal(kr->pd, kr->ctx, kr->creds->client, kr->ccname); if (cc_name == NULL) { cc_name = kr->ccname; } /* Use the updated principal in the creds in case canonicalized */ kerr = create_ccache(cc_name, kr->creds); if (kerr != 0) { goto done; } /* Successfull authentication! Check if ccache contains the * right principal... */ kerr = sss_krb5_check_ccache_princ(kr->ctx, kr->ccname, kr->creds->client); if (kerr) { DEBUG(SSSDBG_CRIT_FAILURE, "No ccache for %s in %s?\n", kr->upn, kr->ccname); goto done; } kerr = safe_remove_old_ccache_file(kr->old_ccname, kr->ccname, kr->uid, kr->gid); if (kerr != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to remove old ccache file [%s], " "please remove it manually.\n", kr->old_ccname); } kerr = add_ticket_times_and_upn_to_response(kr); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "add_ticket_times_and_upn_to_response failed.\n"); } kerr = 0; done: krb5_free_cred_contents(kr->ctx, kr->creds); return kerr; } static errno_t map_krb5_error(krb5_error_code kerr) { if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); } switch (kerr) { case 0: return ERR_OK; case KRB5_LIBOS_CANTREADPWD: return ERR_NO_CREDS; case KRB5_KDCREP_SKEW: case KRB5KRB_AP_ERR_SKEW: case KRB5_KDC_UNREACH: case KRB5_REALM_CANT_RESOLVE: return ERR_NETWORK_IO; case KRB5KDC_ERR_CLIENT_REVOKED: return ERR_ACCOUNT_EXPIRED; case KRB5KDC_ERR_KEY_EXP: return ERR_CREDS_EXPIRED; case KRB5KRB_AP_ERR_BAD_INTEGRITY: return ERR_AUTH_FAILED; /* ERR_CREDS_INVALID is used to indicate to the IPA provider that trying * password migration would make sense. All Kerberos error codes which can * be seen while migrating LDAP users to IPA should be added here. */ case KRB5_PROG_ETYPE_NOSUPP: case KRB5_PREAUTH_FAILED: case KRB5KDC_ERR_PREAUTH_FAILED: return ERR_CREDS_INVALID; /* Please do not remove KRB5KRB_ERR_GENERIC here, it is a _generic_ error * code and we cannot make any assumptions about the reason for the error. * As a consequence we cannot return a different error code than a generic * one which unfortunately might result in a unspecific system error * message to the user. * * If there are cases where libkrb5 calls return KRB5KRB_ERR_GENERIC where * SSSD should behave differently this has to be detected by different * means, e.g. by evaluation error messages, and then the error code * should be changed to a more suitable KRB5* error code or immediately to * a SSSD ERR_* error code to avoid the default handling here. */ case KRB5KRB_ERR_GENERIC: default: return ERR_INTERNAL; } } static errno_t changepw_child(struct krb5_req *kr, bool prelim) { int ret; krb5_error_code kerr = 0; const char *password = NULL; const char *newpassword = NULL; int result_code = -1; krb5_data result_code_string; krb5_data result_string; char *user_error_message = NULL; size_t user_resp_len; uint8_t *user_resp; krb5_prompter_fct prompter = NULL; const char *realm_name; int realm_length; size_t msg_len; uint8_t *msg; uint32_t user_info_type; DEBUG(SSSDBG_TRACE_LIBS, "Password change operation\n"); ret = sss_authtok_get_password(kr->pd->authtok, &password, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to fetch current password [%d] %s.\n", ret, strerror(ret)); return ERR_NO_CREDS; } if (!prelim) { /* We do not need a password expiration warning here. */ prompter = sss_krb5_prompter; } set_changepw_options(kr->options); sss_krb5_princ_realm(kr->ctx, kr->princ, &realm_name, &realm_length); if (realm_length == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_princ_realm failed.\n"); return ERR_INTERNAL; } DEBUG(SSSDBG_TRACE_FUNC, "Attempting kinit for realm [%s]\n",realm_name); kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ, discard_const(password), prompter, kr, 0, SSSD_KRB5_CHANGEPW_PRINCIPAL, kr->options); DEBUG(SSSDBG_TRACE_INTERNAL, "chpass is%s using OTP\n", kr->otp ? "" : " not"); if (kerr != 0) { ret = pack_user_info_chpass_error(kr->pd, "Old password not accepted.", &msg_len, &msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_user_info_chpass_error failed.\n"); } else { ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, msg_len, msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } } return kerr; } sss_authtok_set_empty(kr->pd->authtok); if (prelim) { DEBUG(SSSDBG_TRACE_LIBS, "Initial authentication for change password operation " "successful.\n"); krb5_free_cred_contents(kr->ctx, kr->creds); return EOK; } ret = sss_authtok_get_password(kr->pd->newauthtok, &newpassword, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to fetch new password [%d] %s.\n", ret, strerror(ret)); return ERR_NO_CREDS; } memset(&result_code_string, 0, sizeof(krb5_data)); memset(&result_string, 0, sizeof(krb5_data)); kerr = krb5_change_password(kr->ctx, kr->creds, discard_const(newpassword), &result_code, &result_code_string, &result_string); if (kerr == KRB5_KDC_UNREACH) { return ERR_NETWORK_IO; } if (kerr != 0 || result_code != 0) { if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); } if (result_code_string.length > 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_change_password failed [%d][%.*s].\n", result_code, result_code_string.length, result_code_string.data); user_error_message = talloc_strndup(kr->pd, result_code_string.data, result_code_string.length); if (user_error_message == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n"); } } if (result_string.length > 0 && result_string.data[0] != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_change_password failed [%d][%.*s].\n", result_code, result_string.length, result_string.data); talloc_free(user_error_message); user_error_message = talloc_strndup(kr->pd, result_string.data, result_string.length); if (user_error_message == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n"); } } else if (result_code == KRB5_KPASSWD_SOFTERROR) { user_error_message = talloc_strdup(kr->pd, "Please make sure the " "password meets the complexity constraints."); if (user_error_message == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strndup failed.\n"); } } if (user_error_message != NULL) { ret = pack_user_info_chpass_error(kr->pd, user_error_message, &user_resp_len, &user_resp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_user_info_chpass_error failed.\n"); } else { ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, user_resp_len, user_resp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_response_packet failed.\n"); } } } return ERR_CHPASS_FAILED; } krb5_free_cred_contents(kr->ctx, kr->creds); if (kr->otp == true) { user_info_type = SSS_PAM_USER_INFO_OTP_CHPASS; ret = pam_add_response(kr->pd, SSS_PAM_USER_INFO, sizeof(uint32_t), (const uint8_t *) &user_info_type); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); /* Not fatal */ } sss_authtok_set_empty(kr->pd->newauthtok); return map_krb5_error(kerr); } /* We changed some of the gic options for the password change, now we have * to change them back to get a fresh TGT. */ revert_changepw_options(kr->options); kerr = get_and_save_tgt(kr, newpassword); sss_authtok_set_empty(kr->pd->newauthtok); if (kerr == 0) { kerr = k5c_attach_ccname_msg(kr); } return map_krb5_error(kerr); } static errno_t tgt_req_child(struct krb5_req *kr) { const char *password = NULL; krb5_error_code kerr; int ret; DEBUG(SSSDBG_TRACE_LIBS, "Attempting to get a TGT\n"); /* No password is needed for pre-auth, or if we have 2FA */ if (kr->pd->cmd != SSS_PAM_PREAUTH && sss_authtok_get_type(kr->pd->authtok) != SSS_AUTHTOK_TYPE_2FA) { ret = sss_authtok_get_password(kr->pd->authtok, &password, NULL); switch (ret) { case EOK: break; case EACCES: DEBUG(SSSDBG_OP_FAILURE, "Invalid authtok type\n"); return ERR_INVALID_CRED_TYPE; break; default: DEBUG(SSSDBG_OP_FAILURE, "No credentials available\n"); return ERR_NO_CREDS; break; } } kerr = get_and_save_tgt(kr, password); if (kerr != KRB5KDC_ERR_KEY_EXP) { if (kr->pd->cmd == SSS_PAM_PREAUTH) { /* add OTP tokeninfo messge if available */ if (kr->otp) { kerr = k5c_attach_otp_info_msg(kr); } } else { if (kerr == 0) { kerr = k5c_attach_ccname_msg(kr); } } ret = map_krb5_error(kerr); goto done; } /* If the password is expired the KDC will always return KRB5KDC_ERR_KEY_EXP regardless if the supplied password is correct or not. In general the password can still be used to get a changepw ticket. So we validate the password by trying to get a changepw ticket. */ DEBUG(SSSDBG_TRACE_LIBS, "Password was expired\n"); kerr = sss_krb5_get_init_creds_opt_set_expire_callback(kr->ctx, kr->options, NULL, NULL); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unset expire callback, continue ...\n"); } set_changepw_options(kr->options); kerr = krb5_get_init_creds_password(kr->ctx, kr->creds, kr->princ, discard_const(password), sss_krb5_prompter, kr, 0, SSSD_KRB5_CHANGEPW_PRINCIPAL, kr->options); krb5_free_cred_contents(kr->ctx, kr->creds); if (kerr == 0) { ret = ERR_CREDS_EXPIRED; /* If the password is expired we can safely remove the ccache from the * cache and disk if it is not actively used anymore. This will allow * to create a new random ccache if sshd with privilege separation is * used. */ if (kr->old_cc_active == false && kr->old_ccname) { ret = safe_remove_old_ccache_file(kr->old_ccname, NULL, kr->uid, kr->gid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to remove old ccache file [%s], " "please remove it manually.\n", kr->old_ccname); } ret = ERR_CREDS_EXPIRED_CCACHE; } } else { ret = map_krb5_error(kerr); } done: sss_authtok_set_empty(kr->pd->authtok); return ret; } static errno_t kuserok_child(struct krb5_req *kr) { krb5_boolean access_allowed; krb5_error_code kerr; DEBUG(SSSDBG_TRACE_LIBS, "Verifying if principal can log in as user\n"); /* krb5_kuserok tries to verify that kr->pd->user is a locally known * account, so we have to unset _SSS_LOOPS to make getpwnam() work. */ if (unsetenv("_SSS_LOOPS") != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unset _SSS_LOOPS, " "krb5_kuserok will most certainly fail.\n"); } kerr = krb5_set_default_realm(kr->ctx, kr->realm); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_set_default_realm failed, " "krb5_kuserok may fail.\n"); } access_allowed = krb5_kuserok(kr->ctx, kr->princ, kr->pd->user); DEBUG(SSSDBG_TRACE_LIBS, "Access was %s\n", access_allowed ? "allowed" : "denied"); if (access_allowed) { return EOK; } return ERR_AUTH_DENIED; } static errno_t renew_tgt_child(struct krb5_req *kr) { const char *ccname; krb5_ccache ccache = NULL; krb5_error_code kerr; int ret; DEBUG(SSSDBG_TRACE_LIBS, "Renewing a ticket\n"); ret = sss_authtok_get_ccfile(kr->pd->authtok, &ccname, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unsupported authtok type for TGT renewal [%d].\n", sss_authtok_get_type(kr->pd->authtok)); return ERR_INVALID_CRED_TYPE; } kerr = krb5_cc_resolve(kr->ctx, ccname, &ccache); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; } kerr = krb5_get_renewed_creds(kr->ctx, kr->creds, kr->princ, ccache, NULL); if (kerr != 0) { goto done; } if (kr->validate) { kerr = validate_tgt(kr); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; } } else { DEBUG(SSSDBG_CONF_SETTINGS, "TGT validation is disabled.\n"); } kerr = krb5_cc_initialize(kr->ctx, ccache, kr->princ); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; } kerr = krb5_cc_store_cred(kr->ctx, ccache, kr->creds); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); goto done; } kerr = add_ticket_times_and_upn_to_response(kr); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "add_ticket_times_and_upn_to_response failed.\n"); } kerr = k5c_attach_ccname_msg(kr); done: krb5_free_cred_contents(kr->ctx, kr->creds); if (ccache != NULL) { krb5_cc_close(kr->ctx, ccache); } return map_krb5_error(kerr); } static errno_t create_empty_ccache(struct krb5_req *kr) { krb5_creds *creds = NULL; krb5_error_code kerr; if (kr->old_cc_valid == false) { DEBUG(SSSDBG_TRACE_LIBS, "Creating empty ccache\n"); kerr = create_empty_cred(kr->ctx, kr->princ, &creds); if (kerr == 0) { kerr = create_ccache(kr->ccname, creds); } } else { DEBUG(SSSDBG_TRACE_LIBS, "Existing ccache still valid, reusing\n"); kerr = 0; } if (kerr == 0) { kerr = k5c_attach_ccname_msg(kr); } krb5_free_creds(kr->ctx, creds); return map_krb5_error(kerr); } static errno_t unpack_authtok(struct sss_auth_token *tok, uint8_t *buf, size_t size, size_t *p) { uint32_t auth_token_type; uint32_t auth_token_length; errno_t ret = EOK; SAFEALIGN_COPY_UINT32_CHECK(&auth_token_type, buf + *p, size, p); SAFEALIGN_COPY_UINT32_CHECK(&auth_token_length, buf + *p, size, p); if ((*p + auth_token_length) > size) { return EINVAL; } switch (auth_token_type) { case SSS_AUTHTOK_TYPE_EMPTY: sss_authtok_set_empty(tok); break; case SSS_AUTHTOK_TYPE_PASSWORD: ret = sss_authtok_set_password(tok, (char *)(buf + *p), 0); break; case SSS_AUTHTOK_TYPE_CCFILE: ret = sss_authtok_set_ccfile(tok, (char *)(buf + *p), 0); break; case SSS_AUTHTOK_TYPE_2FA: ret = sss_authtok_set(tok, SSS_AUTHTOK_TYPE_2FA, (buf + *p), auth_token_length); break; default: return EINVAL; } if (ret == EOK) { *p += auth_token_length; } return ret; } static errno_t unpack_buffer(uint8_t *buf, size_t size, struct krb5_req *kr, uint32_t *offline) { size_t p = 0; uint32_t len; uint32_t validate; uint32_t send_pac; uint32_t use_enterprise_princ; struct pam_data *pd; errno_t ret; DEBUG(SSSDBG_TRACE_LIBS, "total buffer size: [%zu]\n", size); if (!offline || !kr) return EINVAL; pd = create_pam_data(kr); if (pd == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } kr->pd = pd; SAFEALIGN_COPY_UINT32_CHECK(&pd->cmd, buf + p, size, &p); SAFEALIGN_COPY_UINT32_CHECK(&kr->uid, buf + p, size, &p); SAFEALIGN_COPY_UINT32_CHECK(&kr->gid, buf + p, size, &p); SAFEALIGN_COPY_UINT32_CHECK(&validate, buf + p, size, &p); kr->validate = (validate == 0) ? false : true; SAFEALIGN_COPY_UINT32_CHECK(offline, buf + p, size, &p); SAFEALIGN_COPY_UINT32_CHECK(&send_pac, buf + p, size, &p); kr->send_pac = (send_pac == 0) ? false : true; SAFEALIGN_COPY_UINT32_CHECK(&use_enterprise_princ, buf + p, size, &p); kr->use_enterprise_princ = (use_enterprise_princ == 0) ? false : true; SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); if (len > size - p) return EINVAL; kr->upn = talloc_strndup(pd, (char *)(buf + p), len); if (kr->upn == NULL) return ENOMEM; p += len; DEBUG(SSSDBG_CONF_SETTINGS, "cmd [%d] uid [%llu] gid [%llu] validate [%s] " "enterprise principal [%s] offline [%s] UPN [%s]\n", pd->cmd, (unsigned long long) kr->uid, (unsigned long long) kr->gid, kr->validate ? "true" : "false", kr->use_enterprise_princ ? "true" : "false", *offline ? "true" : "false", kr->upn ? kr->upn : "none"); if (pd->cmd == SSS_PAM_AUTHENTICATE || pd->cmd == SSS_CMD_RENEW || pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM || pd->cmd == SSS_PAM_CHAUTHTOK) { SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); if (len > size - p) return EINVAL; kr->ccname = talloc_strndup(pd, (char *)(buf + p), len); if (kr->ccname == NULL) return ENOMEM; p += len; SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); if (len > size - p) return EINVAL; if (len > 0) { kr->old_ccname = talloc_strndup(pd, (char *)(buf + p), len); if (kr->old_ccname == NULL) return ENOMEM; p += len; } else { DEBUG(SSSDBG_TRACE_INTERNAL, "No old ccache\n"); } SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); if (len > size - p) return EINVAL; kr->keytab = talloc_strndup(pd, (char *)(buf + p), len); if (kr->keytab == NULL) return ENOMEM; p += len; ret = unpack_authtok(pd->authtok, buf, size, &p); if (ret) { return ret; } DEBUG(SSSDBG_CONF_SETTINGS, "ccname: [%s] old_ccname: [%s] keytab: [%s]\n", kr->ccname, kr->old_ccname ? kr->old_ccname : "not set", kr->keytab); } else { kr->ccname = NULL; kr->old_ccname = NULL; kr->keytab = NULL; sss_authtok_set_empty(pd->authtok); } if (pd->cmd == SSS_PAM_CHAUTHTOK) { ret = unpack_authtok(pd->newauthtok, buf, size, &p); if (ret) { return ret; } } else { sss_authtok_set_empty(pd->newauthtok); } if (pd->cmd == SSS_PAM_ACCT_MGMT) { SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); if (len > size - p) return EINVAL; pd->user = talloc_strndup(pd, (char *)(buf + p), len); if (pd->user == NULL) return ENOMEM; p += len; DEBUG(SSSDBG_CONF_SETTINGS, "user: [%s]\n", pd->user); } else { pd->user = NULL; } return EOK; } static int krb5_cleanup(struct krb5_req *kr) { if (kr == NULL) return EOK; if (kr->options != NULL) { sss_krb5_get_init_creds_opt_free(kr->ctx, kr->options); } if (kr->creds != NULL) { krb5_free_cred_contents(kr->ctx, kr->creds); krb5_free_creds(kr->ctx, kr->creds); } if (kr->name != NULL) sss_krb5_free_unparsed_name(kr->ctx, kr->name); if (kr->princ != NULL) krb5_free_principal(kr->ctx, kr->princ); if (kr->ctx != NULL) krb5_free_context(kr->ctx); memset(kr, 0, sizeof(struct krb5_req)); return EOK; } static krb5_error_code get_tgt_times(krb5_context ctx, const char *ccname, krb5_principal server_principal, krb5_principal client_principal, sss_krb5_ticket_times *tgtt) { krb5_error_code krberr; krb5_ccache ccache = NULL; krb5_creds mcred; krb5_creds cred; krberr = krb5_cc_resolve(ctx, ccname, &ccache); if (krberr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_resolve failed.\n"); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, krberr); goto done; } memset(&mcred, 0, sizeof(mcred)); memset(&cred, 0, sizeof(mcred)); mcred.server = server_principal; mcred.client = client_principal; krberr = krb5_cc_retrieve_cred(ctx, ccache, 0, &mcred, &cred); if (krberr == KRB5_FCC_NOFILE) { DEBUG(SSSDBG_TRACE_LIBS, "FAST ccache must be recreated\n"); } else if (krberr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_retrieve_cred failed\n"); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, krberr); krberr = 0; goto done; } tgtt->authtime = cred.times.authtime; tgtt->starttime = cred.times.starttime; tgtt->endtime = cred.times.endtime; tgtt->renew_till = cred.times.renew_till; krb5_free_cred_contents(ctx, &cred); krberr = 0; done: if (ccache != NULL) { krb5_cc_close(ctx, ccache); } return krberr; } static krb5_error_code check_fast_ccache(TALLOC_CTX *mem_ctx, krb5_context ctx, uid_t fast_uid, gid_t fast_gid, const char *primary, const char *realm, const char *keytab_name, char **fast_ccname) { TALLOC_CTX *tmp_ctx = NULL; krb5_error_code kerr; char *ccname; char *server_name; sss_krb5_ticket_times tgtt; krb5_keytab keytab = NULL; krb5_principal client_princ = NULL; krb5_principal server_princ = NULL; pid_t fchild_pid; int status; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ccname = talloc_asprintf(tmp_ctx, "FILE:%s/fast_ccache_%s", DB_PATH, realm); if (ccname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); kerr = ENOMEM; goto done; } if (keytab_name != NULL) { kerr = krb5_kt_resolve(ctx, keytab_name, &keytab); } else { kerr = krb5_kt_default(ctx, &keytab); } if (kerr) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to read keytab file [%s]: %s\n", KEYTAB_CLEAN_NAME, sss_krb5_get_error_message(ctx, kerr)); goto done; } kerr = find_principal_in_keytab(ctx, keytab, primary, realm, &client_princ); if (kerr != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "find_principal_in_keytab failed for principal %s@%s.\n", primary, realm); goto done; } server_name = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", realm, realm); if (server_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); kerr = ENOMEM; goto done; } kerr = krb5_parse_name(ctx, server_name, &server_princ); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n"); goto done; } memset(&tgtt, 0, sizeof(tgtt)); kerr = get_tgt_times(ctx, ccname, server_princ, client_princ, &tgtt); if (kerr == 0) { if (tgtt.endtime > time(NULL)) { DEBUG(SSSDBG_FUNC_DATA, "FAST TGT is still valid.\n"); goto done; } } /* Need to recreate the FAST ccache */ fchild_pid = fork(); switch (fchild_pid) { case -1: DEBUG(SSSDBG_CRIT_FAILURE, "fork failed\n"); kerr = EIO; goto done; case 0: /* Child */ debug_prg_name = talloc_asprintf(NULL, "[sssd[krb5_child[%d]]]", getpid()); if (debug_prg_name == NULL) { debug_prg_name = "[sssd[krb5_child]]"; DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); /* Try to carry on */ } kerr = become_user(fast_uid, fast_gid); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed: %d\n", kerr); exit(1); } DEBUG(SSSDBG_TRACE_INTERNAL, "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid()); kerr = get_and_save_tgt_with_keytab(ctx, client_princ, keytab, ccname); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "get_and_save_tgt_with_keytab failed: %d\n", kerr); exit(2); } exit(0); default: /* Parent */ do { errno = 0; kerr = waitpid(fchild_pid, &status, 0); } while (kerr == -1 && errno == EINTR); if (kerr > 0) { if (WIFEXITED(status)) { kerr = WEXITSTATUS(status); /* Don't blindly fail if the child fails, but check * the ccache again */ if (kerr != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Creating FAST ccache failed, krb5_child will " "likely fail!\n"); } } else { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_child subprocess %d terminated unexpectedly\n", fchild_pid); } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to wait for child %d\n", fchild_pid); /* Let the code re-check the TGT times and fail if we * can't find the updated principal */ } } /* Check the ccache times again. Should be updated ... */ memset(&tgtt, 0, sizeof(tgtt)); kerr = get_tgt_times(ctx, ccname, server_princ, client_princ, &tgtt); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "get_tgt_times() failed\n"); goto done; } if (tgtt.endtime < time(NULL)) { DEBUG(SSSDBG_OP_FAILURE, "FAST TGT was renewed but is already expired, please check that " "time is synchronized with server.\n"); kerr = ERR_CREDS_EXPIRED; goto done; } DEBUG(SSSDBG_FUNC_DATA, "FAST TGT was successfully recreated!\n"); done: if (client_princ != NULL) { krb5_free_principal(ctx, client_princ); } if (server_princ != NULL) { krb5_free_principal(ctx, server_princ); } if (kerr == 0) { *fast_ccname = talloc_steal(mem_ctx, ccname); } talloc_free(tmp_ctx); if (keytab != NULL) { krb5_kt_close(ctx, keytab); } return kerr; } static errno_t k5c_recv_data(struct krb5_req *kr, int fd, uint32_t *offline) { uint8_t buf[IN_BUF_SIZE]; ssize_t len; errno_t ret; errno = 0; len = sss_atomic_read_s(fd, buf, IN_BUF_SIZE); if (len == -1) { ret = errno; ret = (ret == 0) ? EINVAL: ret; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret)); return ret; } ret = unpack_buffer(buf, len, kr, offline); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "unpack_buffer failed.\n"); } return ret; } static int k5c_setup_fast(struct krb5_req *kr, bool demand) { krb5_principal fast_princ_struct; krb5_data *realm_data; char *fast_principal_realm; char *fast_principal; krb5_error_code kerr; char *tmp_str; char *new_ccname; tmp_str = getenv(SSSD_KRB5_FAST_PRINCIPAL); if (tmp_str) { DEBUG(SSSDBG_CONF_SETTINGS, "%s is set to [%s]\n", SSSD_KRB5_FAST_PRINCIPAL, tmp_str); kerr = krb5_parse_name(kr->ctx, tmp_str, &fast_princ_struct); if (kerr) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n"); return kerr; } kerr = sss_krb5_unparse_name_flags(kr->ctx, fast_princ_struct, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &tmp_str); if (kerr) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_unparse_name_flags failed.\n"); return kerr; } fast_principal = talloc_strdup(kr, tmp_str); if (!fast_principal) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); return KRB5KRB_ERR_GENERIC; } free(tmp_str); realm_data = krb5_princ_realm(kr->ctx, fast_princ_struct); fast_principal_realm = talloc_asprintf(kr, "%.*s", realm_data->length, realm_data->data); if (!fast_principal_realm) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); return ENOMEM; } } else { fast_principal_realm = kr->realm; fast_principal = NULL; } kerr = check_fast_ccache(kr, kr->ctx, kr->fast_uid, kr->fast_gid, fast_principal, fast_principal_realm, kr->keytab, &kr->fast_ccname); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "check_fast_ccache failed.\n"); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } kerr = copy_ccache_into_memory(kr, kr->ctx, kr->fast_ccname, &new_ccname); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "copy_ccache_into_memory failed.\n"); return kerr; } talloc_free(kr->fast_ccname); kr->fast_ccname = new_ccname; kerr = sss_krb5_get_init_creds_opt_set_fast_ccache_name(kr->ctx, kr->options, kr->fast_ccname); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_get_init_creds_opt_set_fast_ccache_name " "failed.\n"); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } if (demand) { kerr = sss_krb5_get_init_creds_opt_set_fast_flags(kr->ctx, kr->options, SSS_KRB5_FAST_REQUIRED); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_get_init_creds_opt_set_fast_flags " "failed.\n"); KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } } return EOK; } static errno_t check_use_fast(enum k5c_fast_opt *_fast_val) { char *use_fast_str; enum k5c_fast_opt fast_val; use_fast_str = getenv(SSSD_KRB5_USE_FAST); if (use_fast_str == NULL || strcasecmp(use_fast_str, "never") == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Not using FAST.\n"); fast_val = K5C_FAST_NEVER; } else if (strcasecmp(use_fast_str, "try") == 0) { fast_val = K5C_FAST_TRY; } else if (strcasecmp(use_fast_str, "demand") == 0) { fast_val = K5C_FAST_DEMAND; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported value [%s] for krb5_use_fast.\n", use_fast_str); return EINVAL; } *_fast_val = fast_val; return EOK; } static errno_t old_ccache_valid(struct krb5_req *kr, bool *_valid) { errno_t ret; bool valid; valid = false; ret = sss_krb5_cc_verify_ccache(kr->old_ccname, kr->uid, kr->gid, kr->realm, kr->upn); switch (ret) { case ERR_NOT_FOUND: case ENOENT: DEBUG(SSSDBG_TRACE_FUNC, "Saved ccache %s doesn't exist, ignoring\n", kr->old_ccname); break; case EINVAL: /* cache found but no tgt or expired */ case EOK: valid = true; break; default: DEBUG(SSSDBG_OP_FAILURE, "Cannot check if saved ccache %s is valid\n", kr->old_ccname); return ret; } *_valid = valid; return EOK; } static int k5c_check_old_ccache(struct krb5_req *kr) { errno_t ret; if (kr->old_ccname) { ret = old_ccache_valid(kr, &kr->old_cc_valid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "old_ccache_valid failed.\n"); return ret; } ret = check_if_uid_is_active(kr->uid, &kr->old_cc_active); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "check_if_uid_is_active failed.\n"); return ret; } DEBUG(SSSDBG_TRACE_ALL, "Ccache_file is [%s] and is %s active and TGT is %s valid.\n", kr->old_ccname ? kr->old_ccname : "not set", kr->old_cc_active ? "" : "not", kr->old_cc_valid ? "" : "not"); } return EOK; } static int k5c_precreate_ccache(struct krb5_req *kr, uint32_t offline) { errno_t ret; /* The ccache file should be (re)created if one of the following conditions * is true: * - it doesn't exist (kr->old_ccname == NULL) * - the backend is online and the current ccache file is not used, i.e * the related user is currently not logged in and it is not a renewal * request * (offline && !kr->old_cc_active && kr->pd->cmd != SSS_CMD_RENEW) * - the backend is offline and the current cache file not used and * it does not contain a valid tgt * (offline && !kr->old_cc_active && !kr->valid_tgt) */ if (kr->old_ccname == NULL || (offline && !kr->old_cc_active && !kr->old_cc_valid) || (!offline && !kr->old_cc_active && kr->pd->cmd != SSS_CMD_RENEW)) { DEBUG(SSSDBG_TRACE_ALL, "Recreating ccache\n"); ret = sss_krb5_precreate_ccache(kr->ccname, kr->uid, kr->gid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "ccache creation failed.\n"); return ret; } } else { /* We can reuse the old ccache */ kr->ccname = kr->old_ccname; } return EOK; } static int k5c_ccache_setup(struct krb5_req *kr, uint32_t offline) { errno_t ret; if (kr->pd->cmd == SSS_PAM_ACCT_MGMT) { return EOK; } ret = k5c_check_old_ccache(kr); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot check old ccache [%s]: [%d][%s]. " \ "Assuming old cache is invalid " \ "and not used.\n", kr->old_ccname, ret, sss_strerror(ret)); } /* Pre-creating the ccache must be done as root, otherwise we can't mkdir * some of the DIR: cache components. One example is /run/user/$UID because * logind doesn't create the directory until the session phase, whereas * we need the directory during the auth phase already */ ret = k5c_precreate_ccache(kr, offline); if (ret != 0) { DEBUG(SSSDBG_OP_FAILURE, "Cannot precreate ccache\n"); return ret; } return EOK; } static int k5c_setup(struct krb5_req *kr, uint32_t offline) { krb5_error_code kerr; int parse_flags; if (offline || (kr->fast_val == K5C_FAST_NEVER && kr->validate == false)) { /* If krb5_child was started as setuid, but we don't need to * perform either validation or FAST, just drop privileges to * the user who is logging in. The same applies to the offline case * the user who is logging in. The same applies to the offline case. */ kerr = become_user(kr->uid, kr->gid); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n"); return kerr; } } DEBUG(SSSDBG_TRACE_INTERNAL, "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid()); /* Set the global error context */ krb5_error_ctx = kr->ctx; if (debug_level & SSSDBG_TRACE_ALL) { kerr = sss_child_set_krb5_tracing(kr->ctx); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_MINOR_FAILURE, kerr); return EIO; } } /* Enterprise principals require that a default realm is available. To * make SSSD more robust in the case that the default realm option is * missing in krb5.conf or to allow SSSD to work with multiple unconnected * realms (e.g. AD domains without trust between them) the default realm * will be set explicitly. */ if (kr->use_enterprise_princ) { kerr = krb5_set_default_realm(kr->ctx, kr->realm); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_set_default_realm failed.\n"); } } parse_flags = kr->use_enterprise_princ ? KRB5_PRINCIPAL_PARSE_ENTERPRISE : 0; kerr = sss_krb5_parse_name_flags(kr->ctx, kr->upn, parse_flags, &kr->princ); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } kerr = krb5_unparse_name(kr->ctx, kr->princ, &kr->name); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } kr->creds = calloc(1, sizeof(krb5_creds)); if (kr->creds == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_RESPONDER kerr = krb5_get_init_creds_opt_set_responder(kr->ctx, kr->options, sss_krb5_responder, kr); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } #endif #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT /* A prompter is used to catch messages about when a password will * expired. The library shall not use the prompter to ask for a new password * but shall return KRB5KDC_ERR_KEY_EXP. */ krb5_get_init_creds_opt_set_change_password_prompt(kr->options, 0); #endif kerr = set_lifetime_options(kr->options); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "set_lifetime_options failed.\n"); return kerr; } if (!offline) { set_canonicalize_option(kr->options); } /* TODO: set options, e.g. * krb5_get_init_creds_opt_set_forwardable * krb5_get_init_creds_opt_set_proxiable * krb5_get_init_creds_opt_set_etype_list * krb5_get_init_creds_opt_set_address_list * krb5_get_init_creds_opt_set_preauth_list * krb5_get_init_creds_opt_set_salt * krb5_get_init_creds_opt_set_change_password_prompt * krb5_get_init_creds_opt_set_pa */ return kerr; } static krb5_error_code privileged_krb5_setup(struct krb5_req *kr, uint32_t offline) { krb5_error_code kerr; int ret; char *mem_keytab; kr->realm = getenv(SSSD_KRB5_REALM); if (kr->realm == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot read [%s] from environment.\n", SSSD_KRB5_REALM); } kerr = krb5_init_context(&kr->ctx); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } kerr = sss_krb5_get_init_creds_opt_alloc(kr->ctx, &kr->options); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; } ret = check_use_fast(&kr->fast_val); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "check_use_fast failed.\n"); return ret;; } /* For ccache types FILE: and DIR: we might need to create some directory * components as root. Cache files are not needed during preauth. */ if (kr->pd->cmd != SSS_PAM_PREAUTH) { ret = k5c_ccache_setup(kr, offline); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "k5c_ccache_setup failed.\n"); return ret; } } if (!(offline || (kr->fast_val == K5C_FAST_NEVER && kr->validate == false))) { kerr = copy_keytab_into_memory(kr, kr->ctx, kr->keytab, &mem_keytab, NULL); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "copy_keytab_into_memory failed.\n"); return kerr; } talloc_free(kr->keytab); kr->keytab = mem_keytab; if (kr->fast_val != K5C_FAST_NEVER) { kerr = k5c_setup_fast(kr, kr->fast_val == K5C_FAST_DEMAND); if (kerr != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set up FAST\n"); return kerr; } } } if (kr->send_pac) { ret = sss_pac_check_and_open(); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot open the PAC responder socket\n"); /* Not fatal */ } } return 0; } static void try_open_krb5_conf(void) { int fd; int ret; fd = open("/etc/krb5.conf", O_RDONLY); if (fd != -1) { close(fd); } else { ret = errno; if (ret == EACCES || ret == EPERM) { DEBUG(SSSDBG_CRIT_FAILURE, "User with uid:%"SPRIuid" gid:%"SPRIgid" cannot read " "/etc/krb5.conf. It might cause problems\n", geteuid(), getegid()); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot open /etc/krb5.conf [%d]: %s\n", ret, strerror(ret)); } } } int main(int argc, const char *argv[]) { struct krb5_req *kr = NULL; uint32_t offline; int opt; poptContext pc; int debug_fd = -1; errno_t ret; krb5_error_code kerr; uid_t fast_uid; gid_t fast_gid; struct poptOption long_options[] = { POPT_AUTOHELP {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, _("Debug level"), NULL}, {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0, _("Add debug timestamps"), NULL}, {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0, _("Show timestamps with microseconds"), NULL}, {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0, _("An open file descriptor for the debug logs"), NULL}, {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, _("Send the debug output to stderr directly."), NULL }, {"fast-ccache-uid", 0, POPT_ARG_INT, &fast_uid, 0, _("The user to create FAST ccache as"), NULL}, {"fast-ccache-gid", 0, POPT_ARG_INT, &fast_gid, 0, _("The group to create FAST ccache as"), NULL}, POPT_TABLEEND }; /* Set debug level to invalid value so we can decide if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); _exit(-1); } } poptFreeContext(pc); DEBUG_INIT(debug_level); debug_prg_name = talloc_asprintf(NULL, "[sssd[krb5_child[%d]]]", getpid()); if (!debug_prg_name) { debug_prg_name = "[sssd[krb5_child]]"; DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } if (debug_fd != -1) { ret = set_debug_file_from_fd(debug_fd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n"); } } DEBUG(SSSDBG_TRACE_FUNC, "krb5_child started.\n"); kr = talloc_zero(NULL, struct krb5_req); if (kr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); ret = ENOMEM; goto done; } talloc_steal(kr, debug_prg_name); kr->fast_uid = fast_uid; kr->fast_gid = fast_gid; ret = k5c_recv_data(kr, STDIN_FILENO, &offline); if (ret != EOK) { goto done; } close(STDIN_FILENO); kerr = privileged_krb5_setup(kr, offline); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "privileged_krb5_setup failed.\n"); ret = EFAULT; goto done; } kerr = become_user(kr->uid, kr->gid); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n"); ret = EFAULT; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid()); try_open_krb5_conf(); ret = k5c_setup(kr, offline); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_child_setup failed.\n"); goto done; } switch(kr->pd->cmd) { case SSS_PAM_AUTHENTICATE: /* If we are offline, we need to create an empty ccache file */ if (offline) { DEBUG(SSSDBG_TRACE_FUNC, "Will perform offline auth\n"); ret = create_empty_ccache(kr); } else { DEBUG(SSSDBG_TRACE_FUNC, "Will perform online auth\n"); ret = tgt_req_child(kr); } break; case SSS_PAM_CHAUTHTOK: DEBUG(SSSDBG_TRACE_FUNC, "Will perform password change\n"); ret = changepw_child(kr, false); break; case SSS_PAM_CHAUTHTOK_PRELIM: DEBUG(SSSDBG_TRACE_FUNC, "Will perform password change checks\n"); ret = changepw_child(kr, true); break; case SSS_PAM_ACCT_MGMT: DEBUG(SSSDBG_TRACE_FUNC, "Will perform account management\n"); ret = kuserok_child(kr); break; case SSS_CMD_RENEW: if (offline) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot renew TGT while offline\n"); ret = KRB5_KDC_UNREACH; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Will perform ticket renewal\n"); ret = renew_tgt_child(kr); break; case SSS_PAM_PREAUTH: DEBUG(SSSDBG_TRACE_FUNC, "Will perform pre-auth\n"); ret = tgt_req_child(kr); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "PAM command [%d] not supported.\n", kr->pd->cmd); ret = EINVAL; goto done; } ret = k5c_send_data(kr, STDOUT_FILENO, ret); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to send reply\n"); } done: if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "krb5_child completed successfully\n"); ret = 0; } else { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_child failed!\n"); ret = -1; } krb5_cleanup(kr); talloc_free(kr); exit(ret); } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_ccache.c0000644000000000000000000000007412703456111020271 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.765794005 sssd-1.13.4/src/providers/krb5/krb5_ccache.c0000644002412700241270000005257412703456111021755 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module -- ccache related utilities Authors: Sumit Bose Jakub Hrozek Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifdef HAVE_KRB5_KRB5_H #include #else #include #endif #include "providers/krb5/krb5_ccache.h" #include "util/sss_krb5.h" #include "util/util.h" struct string_list { struct string_list *next; struct string_list *prev; char *s; }; static errno_t find_ccdir_parent_data(TALLOC_CTX *mem_ctx, const char *ccdirname, struct stat *parent_stat, struct string_list **missing_parents) { int ret = EFAULT; char *parent = NULL; char *end; struct string_list *li; ret = stat(ccdirname, parent_stat); if (ret == EOK) { if ( !S_ISDIR(parent_stat->st_mode) ) { DEBUG(SSSDBG_MINOR_FAILURE, "[%s] is not a directory.\n", ccdirname); return EINVAL; } return EOK; } else { if (errno != ENOENT) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "stat for [%s] failed: [%d][%s].\n", ccdirname, ret, strerror(ret)); return ret; } } li = talloc_zero(mem_ctx, struct string_list); if (li == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } li->s = talloc_strdup(li, ccdirname); if (li->s == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); return ENOMEM; } DLIST_ADD(*missing_parents, li); parent = talloc_strdup(mem_ctx, ccdirname); if (parent == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); return ENOMEM; } /* We'll remove all trailing slashes from the back so that * we only pass /some/path to find_ccdir_parent_data, not * /some/path */ do { end = strrchr(parent, '/'); if (end == NULL || end == parent) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot find parent directory of [%s], / is not allowed.\n", ccdirname); ret = EINVAL; goto done; } *end = '\0'; } while (*(end+1) == '\0'); ret = find_ccdir_parent_data(mem_ctx, parent, parent_stat, missing_parents); done: talloc_free(parent); return ret; } static errno_t check_parent_stat(struct stat *parent_stat, uid_t uid) { if (parent_stat->st_uid != 0 && parent_stat->st_uid != uid) { DEBUG(SSSDBG_CRIT_FAILURE, "Private directory can only be created below a directory " "belonging to root or to [%"SPRIuid"].\n", uid); return EINVAL; } if (parent_stat->st_uid == uid) { if (!(parent_stat->st_mode & S_IXUSR)) { DEBUG(SSSDBG_CRIT_FAILURE, "Parent directory does not have the search bit set for " "the owner.\n"); return EINVAL; } } else { if (!(parent_stat->st_mode & S_IXOTH)) { DEBUG(SSSDBG_CRIT_FAILURE, "Parent directory does not have the search bit set for " "others.\n"); return EINVAL; } } return EOK; } static errno_t create_ccache_dir(const char *ccdirname, uid_t uid, gid_t gid) { int ret = EFAULT; struct stat parent_stat; struct string_list *missing_parents = NULL; struct string_list *li = NULL; mode_t old_umask; mode_t new_dir_mode; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); return ENOMEM; } if (*ccdirname != '/') { DEBUG(SSSDBG_MINOR_FAILURE, "Only absolute paths are allowed, not [%s] .\n", ccdirname); ret = EINVAL; goto done; } ret = find_ccdir_parent_data(tmp_ctx, ccdirname, &parent_stat, &missing_parents); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "find_ccdir_parent_data failed.\n"); goto done; } ret = check_parent_stat(&parent_stat, uid); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Check the ownership and permissions of krb5_ccachedir: [%s].\n", ccdirname); goto done; } DLIST_FOR_EACH(li, missing_parents) { DEBUG(SSSDBG_TRACE_INTERNAL, "Creating directory [%s].\n", li->s); new_dir_mode = 0700; old_umask = umask(0000); ret = mkdir(li->s, new_dir_mode); umask(old_umask); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "mkdir [%s] failed: [%d][%s].\n", li->s, ret, strerror(ret)); goto done; } ret = chown(li->s, uid, gid); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "chown failed [%d][%s].\n", ret, strerror(ret)); goto done; } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sss_krb5_precreate_ccache(const char *ccname, uid_t uid, gid_t gid) { TALLOC_CTX *tmp_ctx = NULL; const char *filename; char *ccdirname; char *end; errno_t ret; if (ccname[0] == '/') { filename = ccname; } else if (strncmp(ccname, "FILE:", 5) == 0) { filename = ccname + 5; } else if (strncmp(ccname, "DIR:", 4) == 0) { filename = ccname + 4; } else { /* only FILE and DIR types need precreation so far, we ignore any * other type */ return EOK; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; ccdirname = talloc_strdup(tmp_ctx, filename); if (ccdirname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } /* We'll remove all trailing slashes from the back so that * we only pass /some/path to find_ccdir_parent_data, not * /some/path/ */ do { end = strrchr(ccdirname, '/'); if (end == NULL || end == ccdirname) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find parent directory of [%s], " "/ is not allowed.\n", ccdirname); ret = EINVAL; goto done; } *end = '\0'; } while (*(end+1) == '\0'); ret = create_ccache_dir(ccdirname, uid, gid); done: talloc_free(tmp_ctx); return ret; } struct sss_krb5_ccache { struct sss_creds *creds; krb5_context context; krb5_ccache ccache; }; static int sss_free_krb5_ccache(void *mem) { struct sss_krb5_ccache *cc = talloc_get_type(mem, struct sss_krb5_ccache); if (cc->ccache) { krb5_cc_close(cc->context, cc->ccache); } krb5_free_context(cc->context); restore_creds(cc->creds); return 0; } static errno_t sss_open_ccache_as_user(TALLOC_CTX *mem_ctx, const char *ccname, uid_t uid, gid_t gid, struct sss_krb5_ccache **ccache) { struct sss_krb5_ccache *cc; krb5_error_code kerr; errno_t ret; cc = talloc_zero(mem_ctx, struct sss_krb5_ccache); if (!cc) { return ENOMEM; } talloc_set_destructor((TALLOC_CTX *)cc, sss_free_krb5_ccache); ret = switch_creds(cc, uid, gid, 0, NULL, &cc->creds); if (ret) { goto done; } kerr = krb5_init_context(&cc->context); if (kerr) { ret = EIO; goto done; } kerr = krb5_cc_resolve(cc->context, ccname, &cc->ccache); if (kerr == KRB5_FCC_NOFILE || cc->ccache == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "ccache %s is missing or empty\n", ccname); ret = ERR_NOT_FOUND; goto done; } else if (kerr != 0) { KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr); DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_resolve failed.\n"); ret = ERR_INTERNAL; goto done; } ret = EOK; done: if (ret) { talloc_free(cc); } else { *ccache = cc; } return ret; } static errno_t sss_destroy_ccache(struct sss_krb5_ccache *cc) { krb5_error_code kerr; errno_t ret; kerr = krb5_cc_destroy(cc->context, cc->ccache); if (kerr) { KRB5_DEBUG(SSSDBG_OP_FAILURE, cc->context, kerr); DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_destroy failed.\n"); ret = EIO; } else { ret = EOK; } /* krb5_cc_destroy frees cc->ccache in all events */ cc->ccache = NULL; return ret; } errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid) { struct sss_krb5_ccache *cc = NULL; TALLOC_CTX *tmp_ctx; errno_t ret; if (ccname == NULL) { /* nothing to remove */ return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = sss_open_ccache_as_user(tmp_ctx, ccname, uid, gid, &cc); if (ret) { goto done; } ret = sss_destroy_ccache(cc); done: talloc_free(tmp_ctx); return ret; } /* This function is called only as a way to validate that we have the * right cache */ errno_t sss_krb5_check_ccache_princ(krb5_context kctx, const char *ccname, krb5_principal user_princ) { krb5_ccache kcc = NULL; krb5_principal ccprinc = NULL; krb5_error_code kerr; const char *cc_type; errno_t ret; kerr = krb5_cc_resolve(kctx, ccname, &kcc); if (kerr) { ret = ERR_INTERNAL; goto done; } cc_type = krb5_cc_get_type(kctx, kcc); kerr = krb5_cc_get_principal(kctx, kcc, &ccprinc); if (kerr != 0) { KRB5_DEBUG(SSSDBG_OP_FAILURE, kctx, kerr); DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_get_principal failed.\n"); } if (ccprinc) { if (krb5_principal_compare(kctx, user_princ, ccprinc) == TRUE) { /* found in the primary ccache */ ret = EOK; goto done; } } #ifdef HAVE_KRB5_CC_COLLECTION if (krb5_cc_support_switch(kctx, cc_type)) { krb5_cc_close(kctx, kcc); kcc = NULL; kerr = krb5_cc_set_default_name(kctx, ccname); if (kerr != 0) { KRB5_DEBUG(SSSDBG_MINOR_FAILURE, kctx, kerr); /* try to continue despite failure */ } kerr = krb5_cc_cache_match(kctx, user_princ, &kcc); if (kerr == 0) { ret = EOK; goto done; } KRB5_DEBUG(SSSDBG_TRACE_INTERNAL, kctx, kerr); } #endif /* HAVE_KRB5_CC_COLLECTION */ ret = ERR_NOT_FOUND; done: if (ccprinc) { krb5_free_principal(kctx, ccprinc); } if (kcc) { krb5_cc_close(kctx, kcc); } return ret; } static errno_t sss_low_level_path_check(const char *ccname) { const char *filename; struct stat buf; int ret; if (ccname[0] == '/') { filename = ccname; } else if (strncmp(ccname, "FILE:", 5) == 0) { filename = ccname + 5; } else if (strncmp(ccname, "DIR:", 4) == 0) { filename = ccname + 4; if (filename[0] == ':') filename += 1; } else { /* only FILE and DIR types need file checks so far, we ignore any * other type */ return EOK; } ret = stat(filename, &buf); if (ret == -1) return errno; return EOK; } errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid, const char *realm, const char *principal) { struct sss_krb5_ccache *cc = NULL; TALLOC_CTX *tmp_ctx = NULL; krb5_principal tgt_princ = NULL; krb5_principal princ = NULL; char *tgt_name; krb5_creds mcred = { 0 }; krb5_creds cred = { 0 }; krb5_error_code kerr; errno_t ret; /* first of all verify if the old ccache file/dir exists as we may be * trying to verify if an old ccache exists at all. If no file/dir * exists bail out immediately otherwise a following krb5_cc_resolve() * call may actually create paths and files we do not want to have * around */ ret = sss_low_level_path_check(ccname); if (ret) { return ret; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = sss_open_ccache_as_user(tmp_ctx, ccname, uid, gid, &cc); if (ret) { goto done; } tgt_name = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", realm, realm); if (!tgt_name) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); ret = ENOMEM; goto done; } kerr = krb5_parse_name(cc->context, tgt_name, &tgt_princ); if (kerr) { KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr); if (kerr == KRB5_PARSE_MALFORMED) ret = EINVAL; else ret = ERR_INTERNAL; goto done; } kerr = krb5_parse_name(cc->context, principal, &princ); if (kerr) { KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr); if (kerr == KRB5_PARSE_MALFORMED) ret = EINVAL; else ret = ERR_INTERNAL; goto done; } mcred.client = princ; mcred.server = tgt_princ; mcred.times.endtime = time(NULL); kerr = krb5_cc_retrieve_cred(cc->context, cc->ccache, KRB5_TC_MATCH_TIMES, &mcred, &cred); if (kerr) { if (kerr == KRB5_CC_NOTFOUND || kerr == KRB5_FCC_NOFILE) { DEBUG(SSSDBG_TRACE_INTERNAL, "TGT not found or expired.\n"); ret = EINVAL; } else { KRB5_DEBUG(SSSDBG_CRIT_FAILURE, cc->context, kerr); ret = ERR_INTERNAL; } } krb5_free_cred_contents(cc->context, &cred); done: if (tgt_princ) krb5_free_principal(cc->context, tgt_princ); if (princ) krb5_free_principal(cc->context, princ); talloc_free(tmp_ctx); return ret; } errno_t get_ccache_file_data(const char *ccache_file, const char *client_name, struct tgt_times *tgtt) { krb5_error_code kerr; krb5_context ctx = NULL; krb5_ccache cc = NULL; krb5_principal client_princ = NULL; krb5_principal server_princ = NULL; char *server_name; krb5_creds mcred; krb5_creds cred; const char *realm_name; int realm_length; kerr = krb5_init_context(&ctx); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_init_context failed.\n"); goto done; } kerr = krb5_parse_name(ctx, client_name, &client_princ); if (kerr != 0) { KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr); DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n"); goto done; } sss_krb5_princ_realm(ctx, client_princ, &realm_name, &realm_length); if (realm_length == 0) { kerr = KRB5KRB_ERR_GENERIC; DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_princ_realm failed.\n"); goto done; } server_name = talloc_asprintf(NULL, "krbtgt/%.*s@%.*s", realm_length, realm_name, realm_length, realm_name); if (server_name == NULL) { kerr = KRB5_CC_NOMEM; DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); goto done; } kerr = krb5_parse_name(ctx, server_name, &server_princ); talloc_free(server_name); if (kerr != 0) { KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr); DEBUG(SSSDBG_CRIT_FAILURE, "krb5_parse_name failed.\n"); goto done; } kerr = krb5_cc_resolve(ctx, ccache_file, &cc); if (kerr != 0) { KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr); DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_resolve failed.\n"); goto done; } memset(&mcred, 0, sizeof(mcred)); memset(&cred, 0, sizeof(mcred)); mcred.server = server_princ; mcred.client = client_princ; kerr = krb5_cc_retrieve_cred(ctx, cc, 0, &mcred, &cred); if (kerr != 0) { KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr); DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_retrieve_cred failed.\n"); goto done; } tgtt->authtime = cred.times.authtime; tgtt->starttime = cred.times.starttime; tgtt->endtime = cred.times.endtime; tgtt->renew_till = cred.times.renew_till; krb5_free_cred_contents(ctx, &cred); kerr = krb5_cc_close(ctx, cc); if (kerr != 0) { KRB5_DEBUG(SSSDBG_OP_FAILURE, ctx, kerr); DEBUG(SSSDBG_CRIT_FAILURE, "krb5_cc_close failed.\n"); goto done; } cc = NULL; kerr = 0; done: if (cc != NULL) { krb5_cc_close(ctx, cc); } if (client_princ != NULL) { krb5_free_principal(ctx, client_princ); } if (server_princ != NULL) { krb5_free_principal(ctx, server_princ); } if (ctx != NULL) { krb5_free_context(ctx); } if (kerr != 0) { return EIO; } return EOK; } errno_t safe_remove_old_ccache_file(const char *old_ccache, const char *new_ccache, uid_t uid, gid_t gid) { if ((old_ccache == new_ccache) || (old_ccache && new_ccache && (strcmp(old_ccache, new_ccache) == 0))) { DEBUG(SSSDBG_TRACE_FUNC, "New and old ccache file are the same, " "none will be deleted.\n"); return EOK; } return sss_krb5_cc_destroy(old_ccache, uid, gid); } krb5_error_code copy_ccache_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx, const char *ccache_file, char **_mem_name) { krb5_error_code kerr; krb5_ccache ccache; krb5_ccache mem_ccache = NULL; char *ccache_name = NULL; krb5_principal princ = NULL; char *mem_name = NULL; char *sep; kerr = krb5_cc_resolve(kctx, ccache_file, &ccache); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "error resolving ccache [%s].\n", ccache_file); return kerr; } kerr = krb5_cc_get_full_name(kctx, ccache, &ccache_name); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read name for ccache [%s].\n", ccache_file); goto done; } sep = strchr(ccache_name, ':'); if (sep == NULL || sep[1] == '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Ccache name [%s] does not have delimiter[:] .\n", ccache_name); kerr = KRB5KRB_ERR_GENERIC; goto done; } if (strncmp(ccache_name, "MEMORY:", sizeof("MEMORY:") -1) == 0) { DEBUG(SSSDBG_TRACE_FUNC, "Ccache [%s] is already memory ccache.\n", ccache_name); *_mem_name = talloc_strdup(mem_ctx, ccache_name); if(*_mem_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); kerr = KRB5KRB_ERR_GENERIC; goto done; } kerr = 0; goto done; } if (strncmp(ccache_name, "FILE:", sizeof("FILE:") -1) == 0) { mem_name = talloc_asprintf(mem_ctx, "MEMORY:%s", sep + 1); if (mem_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); kerr = KRB5KRB_ERR_GENERIC; goto done; } } else { DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected ccache type for ccache [%s], " \ "currently only FILE is supported.\n", ccache_name); kerr = KRB5KRB_ERR_GENERIC; goto done; } kerr = krb5_cc_resolve(kctx, mem_name, &mem_ccache); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "error resolving ccache [%s].\n", mem_name); goto done; } kerr = krb5_cc_get_principal(kctx, ccache, &princ); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "error reading principal from ccache [%s].\n", ccache_name); goto done; } kerr = krb5_cc_initialize(kctx, mem_ccache, princ); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize ccache [%s].\n", mem_name); goto done; } kerr = krb5_cc_copy_creds(kctx, ccache, mem_ccache); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy ccache [%s] to [%s].\n", ccache_name, mem_name); goto done; } *_mem_name = mem_name; kerr = 0; done: if (kerr != 0) { talloc_free(mem_name); } free(ccache_name); krb5_free_principal(kctx, princ); if (krb5_cc_close(kctx, ccache) != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_cc_close failed.\n"); } if (krb5_cc_close(kctx, mem_ccache) != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_cc_close failed.\n"); } return kerr; } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_utils.c0000644000000000000000000000007412703456111020223 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.756793975 sssd-1.13.4/src/providers/krb5/krb5_utils.c0000644002412700241270000004435412703456111021704 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module -- Utilities Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "providers/krb5/krb5_utils.h" #include "providers/krb5/krb5_ccache.h" #include "providers/krb5/krb5_auth.h" #include "src/util/find_uid.h" #include "util/util.h" errno_t find_or_guess_upn(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct krb5_ctx *krb5_ctx, struct sss_domain_info *dom, const char *user, const char *user_dom, char **_upn) { const char *upn = NULL; int ret; if (krb5_ctx == NULL || dom == NULL || user == NULL || _upn == NULL) { return EINVAL; } if (msg != NULL) { upn = ldb_msg_find_attr_as_string(msg, SYSDB_CANONICAL_UPN, NULL); if (upn != NULL) { ret = EOK; goto done; } upn = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); if (upn != NULL) { ret = EOK; goto done; } } ret = krb5_get_simple_upn(mem_ctx, krb5_ctx, dom, user, user_dom, _upn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "krb5_get_simple_upn failed.\n"); return ret; } done: if (ret == EOK && upn != NULL) { *_upn = talloc_strdup(mem_ctx, upn); if (*_upn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); return ENOMEM; } } return ret; } errno_t check_if_cached_upn_needs_update(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *user, const char *upn) { TALLOC_CTX *tmp_ctx; int ret; int sret; const char *attrs[] = {SYSDB_UPN, SYSDB_CANONICAL_UPN, NULL}; struct sysdb_attrs *new_attrs; struct ldb_result *res; bool in_transaction = false; const char *cached_upn; const char *cached_canonical_upn; if (sysdb == NULL || user == NULL || upn == NULL) { return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = sysdb_get_user_attr(tmp_ctx, domain, user, attrs, &res); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_user_attr failed.\n"); goto done; } if (res->count != 1) { DEBUG(SSSDBG_OP_FAILURE, "[%d] user objects for name [%s] found, " \ "expected 1.\n", res->count, user); ret = EINVAL; goto done; } cached_upn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_UPN, NULL); if (cached_upn != NULL && strcmp(cached_upn, upn) == 0) { DEBUG(SSSDBG_TRACE_ALL, "Cached UPN and new one match, " "nothing to do.\n"); ret = EOK; goto done; } cached_canonical_upn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_CANONICAL_UPN, NULL); if (cached_canonical_upn != NULL && strcmp(cached_canonical_upn, upn) == 0) { DEBUG(SSSDBG_TRACE_ALL, "Cached canonical UPN and new one match, " "nothing to do.\n"); ret = EOK; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Replacing canonical UPN [%s] with [%s] " \ "for user [%s].\n", cached_canonical_upn == NULL ? "empty" : cached_canonical_upn, upn, user); new_attrs = sysdb_new_attrs(tmp_ctx); if (new_attrs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(new_attrs, SYSDB_CANONICAL_UPN, upn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error %d starting transaction (%s)\n", ret, strerror(ret)); goto done; } in_transaction = true; ret = sysdb_set_entry_attr(sysdb, res->msgs[0]->dn, new_attrs, cached_canonical_upn == NULL ? SYSDB_MOD_ADD : SYSDB_MOD_REP); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_entry_attr failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to commit transaction!\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } #define S_EXP_UID "{uid}" #define L_EXP_UID (sizeof(S_EXP_UID) - 1) #define S_EXP_USERID "{USERID}" #define L_EXP_USERID (sizeof(S_EXP_USERID) - 1) #define S_EXP_EUID "{euid}" #define L_EXP_EUID (sizeof(S_EXP_EUID) - 1) #define S_EXP_USERNAME "{username}" #define L_EXP_USERNAME (sizeof(S_EXP_USERNAME) - 1) static errno_t check_ccache_re(const char *filename, pcre *illegal_re) { errno_t ret; ret = pcre_exec(illegal_re, NULL, filename, strlen(filename), 0, 0, NULL, 0); if (ret == 0) { DEBUG(SSSDBG_OP_FAILURE, "Illegal pattern in ccache directory name [%s].\n", filename); return EINVAL; } else if (ret == PCRE_ERROR_NOMATCH) { DEBUG(SSSDBG_TRACE_LIBS, "Ccache directory name [%s] does not contain " "illegal patterns.\n", filename); return EOK; } DEBUG(SSSDBG_CRIT_FAILURE, "pcre_exec failed [%d].\n", ret); return EFAULT; } char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr, const char *template, pcre *illegal_re, bool file_mode, bool case_sensitive) { char *copy; char *p; char *n; char *result = NULL; char *dummy; char *name; char *res = NULL; const char *cache_dir_tmpl; TALLOC_CTX *tmp_ctx = NULL; char action; bool rerun; int ret; if (template == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing template.\n"); return NULL; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return NULL; copy = talloc_strdup(tmp_ctx, template); if (copy == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); goto done; } result = talloc_strdup(tmp_ctx, ""); if (result == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); goto done; } p = copy; while ( (n = strchr(p, '%')) != NULL) { *n = '\0'; n++; if ( *n == '\0' ) { DEBUG(SSSDBG_CRIT_FAILURE, "format error, single %% at the end of the template.\n"); goto done; } rerun = true; action = *n; while (rerun) { rerun = false; switch (action) { case 'u': if (kr->pd->user == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand user name template " "because user name is empty.\n"); goto done; } name = sss_get_cased_name(tmp_ctx, kr->pd->user, case_sensitive); if (!name) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_get_cased_name failed\n"); goto done; } result = talloc_asprintf_append(result, "%s%s", p, name); break; case 'U': if (kr->uid <= 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand uid template " "because uid is invalid.\n"); goto done; } result = talloc_asprintf_append(result, "%s%"SPRIuid, p, kr->uid); break; case 'p': if (kr->upn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand user principal name template " "because upn is empty.\n"); goto done; } result = talloc_asprintf_append(result, "%s%s", p, kr->upn); break; case '%': result = talloc_asprintf_append(result, "%s%%", p); break; case 'r': dummy = dp_opt_get_string(kr->krb5_ctx->opts, KRB5_REALM); if (dummy == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing kerberos realm.\n"); goto done; } result = talloc_asprintf_append(result, "%s%s", p, dummy); break; case 'h': if (kr->homedir == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand home directory template " "because the path is not available.\n"); goto done; } result = talloc_asprintf_append(result, "%s%s", p, kr->homedir); break; case 'd': if (file_mode) { cache_dir_tmpl = dp_opt_get_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR); if (cache_dir_tmpl == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing credential cache directory.\n"); goto done; } dummy = expand_ccname_template(tmp_ctx, kr, cache_dir_tmpl, illegal_re, false, case_sensitive); if (dummy == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Expanding credential cache directory " "template failed.\n"); goto done; } result = talloc_asprintf_append(result, "%s%s", p, dummy); talloc_zfree(dummy); } else { DEBUG(SSSDBG_CRIT_FAILURE, "'%%d' is not allowed in this template.\n"); goto done; } break; case 'P': if (!file_mode) { DEBUG(SSSDBG_CRIT_FAILURE, "'%%P' is not allowed in this template.\n"); goto done; } if (kr->pd->cli_pid == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand PID template " "because PID is not available.\n"); goto done; } result = talloc_asprintf_append(result, "%s%d", p, kr->pd->cli_pid); break; /* Additional syntax from krb5.conf default_ccache_name */ case '{': if (strncmp(n , S_EXP_UID, L_EXP_UID) == 0) { action = 'U'; n += L_EXP_UID - 1; rerun = true; continue; } else if (strncmp(n , S_EXP_USERID, L_EXP_USERID) == 0) { action = 'U'; n += L_EXP_USERID - 1; rerun = true; continue; } else if (strncmp(n , S_EXP_EUID, L_EXP_EUID) == 0) { /* SSSD does not distinguish between uid and euid, * so we treat both the same way */ action = 'U'; n += L_EXP_EUID - 1; rerun = true; continue; } else if (strncmp(n , S_EXP_USERNAME, L_EXP_USERNAME) == 0) { action = 'u'; n += L_EXP_USERNAME - 1; rerun = true; continue; } else { /* ignore any expansion variable we do not understand and * let libkrb5 hndle it or fail */ name = n; n = strchr(name, '}'); if (!n) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid substitution sequence in cache " "template. Missing closing '}' in [%s].\n", template); goto done; } result = talloc_asprintf_append(result, "%s%%%.*s", p, (int)(n - name + 1), name); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "format error, unknown template [%%%c].\n", *n); goto done; } } if (result == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n"); goto done; } p = n + 1; } result = talloc_asprintf_append(result, "%s", p); if (result == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n"); goto done; } if (illegal_re != NULL) { ret = check_ccache_re(result, illegal_re); if (ret != EOK) { goto done; } } res = talloc_move(mem_ctx, &result); done: talloc_zfree(tmp_ctx); return res; } errno_t get_domain_or_subdomain(struct be_ctx *be_ctx, char *domain_name, struct sss_domain_info **dom) { if (domain_name != NULL && strcasecmp(domain_name, be_ctx->domain->name) != 0) { *dom = find_domain_by_name(be_ctx->domain, domain_name, true); if (*dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "find_domain_by_name failed.\n"); return ENOMEM; } } else { *dom = be_ctx->domain; } return EOK; } static errno_t split_tuple(TALLOC_CTX *mem_ctx, const char *tuple, const char **_first, const char **_second) { errno_t ret; char **list; int n; ret = split_on_separator(mem_ctx, tuple, ':', true, true, &list, &n); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "split_on_separator failed - %s:[%d]\n", sss_strerror(ret), ret); goto done; } else if (n != 2) { DEBUG(SSSDBG_MINOR_FAILURE, "split_on_separator failed - Expected format is: " "'username:primary' but got: '%s'.\n", tuple); ret = EINVAL; goto done; } *_first = list[0]; *_second = list[1]; done: return ret; } static errno_t fill_name_to_primary_map(TALLOC_CTX *mem_ctx, char **map, struct map_id_name_to_krb_primary *name_to_primary, size_t size) { int i; errno_t ret; for (i = 0; i < size; i++) { ret = split_tuple(mem_ctx, map[i], &name_to_primary[i].id_name, &name_to_primary[i].krb_primary); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "split_tuple failed - %s:[%d]\n", sss_strerror(ret), ret); goto done; } } ret = EOK; done: return ret; } errno_t parse_krb5_map_user(TALLOC_CTX *mem_ctx, const char *krb5_map_user, struct map_id_name_to_krb_primary **_name_to_primary) { int size; char **map; errno_t ret; TALLOC_CTX *tmp_ctx; struct map_id_name_to_krb_primary *name_to_primary; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } if (krb5_map_user == NULL || strlen(krb5_map_user) == 0) { DEBUG(SSSDBG_FUNC_DATA, "Warning: krb5_map_user is empty!\n"); size = 0; } else { ret = split_on_separator(tmp_ctx, krb5_map_user, ',', true, true, &map, &size); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to parse krb5_map_user!\n"); goto done; } } name_to_primary = talloc_zero_array(tmp_ctx, struct map_id_name_to_krb_primary, size + 1); if (name_to_primary == NULL) { ret = ENOMEM; goto done; } /* sentinel */ name_to_primary[size].id_name = NULL; name_to_primary[size].krb_primary = NULL; if (size > 0) { ret = fill_name_to_primary_map(name_to_primary, map, name_to_primary, size); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "fill_name_to_primary_map failed: %s:[%d]\n", sss_strerror(ret), ret); goto done; } } ret = EOK; done: if (ret == EOK) { *_name_to_primary = talloc_steal(mem_ctx, name_to_primary); } talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_ccache.h0000644000000000000000000000007412703456111020276 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.546793262 sssd-1.13.4/src/providers/krb5/krb5_ccache.h0000644002412700241270000000512412703456111021747 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module -- ccache related utilities Authors: Sumit Bose Jakub Hrozek Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __KRB5_CCACHE_H__ #define __KRB5_CCACHE_H__ #include "util/util.h" struct tgt_times { time_t authtime; time_t starttime; time_t endtime; time_t renew_till; }; errno_t sss_krb5_precreate_ccache(const char *ccname, uid_t uid, gid_t gid); errno_t sss_krb5_cc_destroy(const char *ccname, uid_t uid, gid_t gid); errno_t sss_krb5_check_ccache_princ(krb5_context kctx, const char *ccname, krb5_principal user_princ); errno_t sss_krb5_cc_verify_ccache(const char *ccname, uid_t uid, gid_t gid, const char *realm, const char *principal); errno_t get_ccache_file_data(const char *ccache_file, const char *client_name, struct tgt_times *tgtt); errno_t safe_remove_old_ccache_file(const char *old_ccache, const char *new_ccache, uid_t uid, gid_t gid); /** * @brief Copy given ccache into a MEMORY ccache * * @param[in] mem_ctx Talloc memory context the new ccache name should be * allocated on * @param[in] kctx Kerberos context * @param[in] ccache_file Name of existing ccache * @param[out] _mem_name Name of the new MEMORY ccache * * In contrast to MEMORY keytabs MEMORY ccaches can and must be removed * explicitly with krb5_cc_destroy() from the memory. Just calling * krb5_cc_close() will keep the MEMORY ccache in memory even if there are no * open handles for the given MEMORY ccache. */ krb5_error_code copy_ccache_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx, const char *ccache_file, char **_mem_name); #endif /* __KRB5_CCACHE_H__ */ sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_wait_queue.c0000644000000000000000000000007412703456111021233 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.759793985 sssd-1.13.4/src/providers/krb5/krb5_wait_queue.c0000644002412700241270000002626012703456111022710 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module - Serialize the request of a user Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "src/providers/krb5/krb5_auth.h" #define INIT_HASH_SIZE 5 struct queue_entry { struct queue_entry *prev; struct queue_entry *next; struct be_ctx *be_ctx; struct be_req *be_req; struct tevent_req *parent_req; struct pam_data *pd; struct krb5_ctx *krb5_ctx; }; static void wait_queue_auth_done(struct tevent_req *req); static void krb5_auth_queue_finish(struct tevent_req *req, errno_t ret, int pam_status, int dp_err); static void wait_queue_auth(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *private_data) { struct queue_entry *qe = talloc_get_type(private_data, struct queue_entry); struct tevent_req *req; req = krb5_auth_send(qe->parent_req, qe->be_ctx->ev, qe->be_ctx, qe->pd, qe->krb5_ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_auth_send failed.\n"); } else { tevent_req_set_callback(req, wait_queue_auth_done, qe->parent_req); } talloc_zfree(qe); } static void wait_queue_auth_done(struct tevent_req *req) { struct tevent_req *parent_req = \ tevent_req_callback_data(req, struct tevent_req); int pam_status; int dp_err; errno_t ret; ret = krb5_auth_recv(req, &pam_status, &dp_err); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "krb5_auth_recv failed: %d\n", ret); } krb5_auth_queue_finish(parent_req, ret, pam_status, dp_err); } static void wait_queue_del_cb(hash_entry_t *entry, hash_destroy_enum type, void *pvt) { struct queue_entry *head; if (entry->value.type == HASH_VALUE_PTR) { head = talloc_get_type(entry->value.ptr, struct queue_entry); talloc_zfree(head); return; } DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected value type [%d].\n", entry->value.type); } static errno_t add_to_wait_queue(struct be_ctx *be_ctx, struct tevent_req *parent_req, struct pam_data *pd, struct krb5_ctx *krb5_ctx) { int ret; hash_key_t key; hash_value_t value; struct queue_entry *head; struct queue_entry *queue_entry; if (krb5_ctx->wait_queue_hash == NULL) { ret = sss_hash_create_ex(krb5_ctx, INIT_HASH_SIZE, &krb5_ctx->wait_queue_hash, 0, 0, 0, 0, wait_queue_del_cb, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_hash_create failed\n"); return ret; } } key.type = HASH_KEY_STRING; key.str = pd->user; ret = hash_lookup(krb5_ctx->wait_queue_hash, &key, &value); switch (ret) { case HASH_SUCCESS: if (value.type != HASH_VALUE_PTR) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected hash value type.\n"); return EINVAL; } head = talloc_get_type(value.ptr, struct queue_entry); queue_entry = talloc_zero(head, struct queue_entry); if (queue_entry == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } queue_entry->be_ctx = be_ctx; queue_entry->parent_req = parent_req; queue_entry->pd = pd; queue_entry->krb5_ctx = krb5_ctx; DLIST_ADD_END(head, queue_entry, struct queue_entry *); break; case HASH_ERROR_KEY_NOT_FOUND: value.type = HASH_VALUE_PTR; head = talloc_zero(krb5_ctx->wait_queue_hash, struct queue_entry); if (head == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } value.ptr = head; ret = hash_enter(krb5_ctx->wait_queue_hash, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_enter failed.\n"); talloc_free(head); return EIO; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "hash_lookup failed.\n"); return EIO; } if (head->next == NULL) { return ENOENT; } else { return EOK; } } static void check_wait_queue(struct krb5_ctx *krb5_ctx, char *username) { int ret; hash_key_t key; hash_value_t value; struct queue_entry *head; struct queue_entry *queue_entry; struct tevent_timer *te; if (krb5_ctx->wait_queue_hash == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No wait queue available.\n"); return; } key.type = HASH_KEY_STRING; key.str = username; ret = hash_lookup(krb5_ctx->wait_queue_hash, &key, &value); switch (ret) { case HASH_SUCCESS: if (value.type != HASH_VALUE_PTR) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected hash value type.\n"); return; } head = talloc_get_type(value.ptr, struct queue_entry); if (head->next == NULL) { DEBUG(SSSDBG_TRACE_LIBS, "Wait queue for user [%s] is empty.\n", username); } else { queue_entry = head->next; DLIST_REMOVE(head, queue_entry); te = tevent_add_timer(queue_entry->be_ctx->ev, krb5_ctx, tevent_timeval_current(), wait_queue_auth, queue_entry); if (te == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n"); } else { return; } } ret = hash_delete(krb5_ctx->wait_queue_hash, &key); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to remove wait queue for user [%s].\n", username); } break; case HASH_ERROR_KEY_NOT_FOUND: DEBUG(SSSDBG_CRIT_FAILURE, "No wait queue for user [%s] found.\n", username); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "hash_lookup failed.\n"); } return; } struct krb5_auth_queue_state { struct krb5_ctx *krb5_ctx; struct pam_data *pd; int pam_status; int dp_err; }; static void krb5_auth_queue_done(struct tevent_req *subreq); struct tevent_req *krb5_auth_queue_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct pam_data *pd, struct krb5_ctx *krb5_ctx) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct krb5_auth_queue_state *state; req = tevent_req_create(mem_ctx, &state, struct krb5_auth_queue_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->krb5_ctx = krb5_ctx; state->pd = pd; ret = add_to_wait_queue(be_ctx, req, pd, krb5_ctx); if (ret == EOK) { DEBUG(SSSDBG_TRACE_LIBS, "Request [%p] successfully added to wait queue " "of user [%s].\n", req, pd->user); ret = EOK; goto immediate; } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_LIBS, "Wait queue of user [%s] is empty, " "running request [%p] immediately.\n", pd->user, req); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add request to wait queue of user [%s], " "running request [%p] immediately.\n", pd->user, req); } subreq = krb5_auth_send(req, ev, be_ctx, pd, krb5_ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_auth_send failed.\n"); ret = ENOMEM; goto immediate; } tevent_req_set_callback(subreq, krb5_auth_queue_done, req); ret = EOK; immediate: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void krb5_auth_queue_done(struct tevent_req *subreq) { struct tevent_req *req = \ tevent_req_callback_data(subreq, struct tevent_req); struct krb5_auth_queue_state *state = \ tevent_req_data(req, struct krb5_auth_queue_state); errno_t ret; ret = krb5_auth_recv(subreq, &state->pam_status, &state->dp_err); talloc_zfree(subreq); check_wait_queue(state->krb5_ctx, state->pd->user); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "krb5_auth_recv failed with: %d\n", ret); tevent_req_error(req, ret); return; } DEBUG(SSSDBG_TRACE_LIBS, "krb5_auth_queue request [%p] done.\n", req); tevent_req_done(req); } /* This is a violation of the tevent_req style. Ideally, the wait queue would * be rewritten to the tevent_req style in the future, expose per-request recv * and not hide the request underneath. But this function allows us to expose * a tevent_req API for users of this module */ static void krb5_auth_queue_finish(struct tevent_req *req, errno_t ret, int pam_status, int dp_err) { struct krb5_auth_queue_state *state = \ tevent_req_data(req, struct krb5_auth_queue_state); check_wait_queue(state->krb5_ctx, state->pd->user); state->pam_status = pam_status; state->dp_err = dp_err; if (ret != EOK) { tevent_req_error(req, ret); } else { DEBUG(SSSDBG_TRACE_LIBS, "krb5_auth_queue request [%p] done.\n", req); tevent_req_done(req); } } int krb5_auth_queue_recv(struct tevent_req *req, int *_pam_status, int *_dp_err) { struct krb5_auth_queue_state *state = \ tevent_req_data(req, struct krb5_auth_queue_state); /* Returning values even on failure is not typical, but IPA password migration * relies on receiving PAM_CRED_ERR even if the request fails.. */ if (_pam_status) { *_pam_status = state->pam_status; } if (_dp_err) { *_dp_err = state->dp_err; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_common.c0000644000000000000000000000007412703456111020353 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.760793988 sssd-1.13.4/src/providers/krb5/krb5_common.c0000644002412700241270000007675712703456111022050 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos Provider Common Functions Authors: Sumit Bose Copyright (C) 2008-2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "providers/dp_backend.h" #include "providers/krb5/krb5_common.h" #include "providers/krb5/krb5_opts.h" #include "providers/krb5/krb5_utils.h" #ifdef HAVE_KRB5_CC_COLLECTION /* krb5 profile functions */ #include #endif errno_t check_and_export_lifetime(struct dp_option *opts, const int opt_id, const char *env_name) { int ret; char *str; krb5_deltat lifetime; bool free_str = false; str = dp_opt_get_string(opts, opt_id); if (str == NULL || *str == '\0') { DEBUG(SSSDBG_FUNC_DATA, "No lifetime configured.\n"); return EOK; } if (isdigit(str[strlen(str)-1])) { str = talloc_asprintf(opts, "%ss", str); if (str == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed\n"); return ENOMEM; } free_str = true; ret = dp_opt_set_string(opts, opt_id, str); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed\n"); goto done; } } ret = krb5_string_to_deltat(str, &lifetime); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid value [%s] for a lifetime.\n", str); ret = EINVAL; goto done; } ret = setenv(env_name, str, 1); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "setenv [%s] failed.\n", env_name); goto done; } ret = EOK; done: if (free_str) { talloc_free(str); } return ret; } #ifdef HAVE_KRB5_CC_COLLECTION /* source default_ccache_name from krb5.conf */ static errno_t sss_get_system_ccname_template(TALLOC_CTX *mem_ctx, char **ccname) { krb5_context ctx; profile_t p; char *value = NULL; long ret; *ccname = NULL; ret = krb5_init_context(&ctx); if (ret) return ret; ret = krb5_get_profile(ctx, &p); if (ret) goto done; ret = profile_get_string(p, "libdefaults", "default_ccache_name", NULL, NULL, &value); if (ret) goto done; if (!value) { ret = ERR_NOT_FOUND; goto done; } *ccname = talloc_strdup(mem_ctx, value); if (*ccname == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: krb5_free_context(ctx); free(value); return ret; } #else static errno_t sss_get_system_ccname_template(TALLOC_CTX *mem_ctx, char **ccname) { DEBUG(SSSDBG_CONF_SETTINGS, "Your kerberos library does not support the default_ccache_name " "option or the profile library. Please use krb5_ccname_template " "in sssd.conf if you want to change the default\n"); *ccname = NULL; return ERR_NOT_FOUND; } #endif static void sss_check_cc_template(const char *cc_template) { size_t template_len; template_len = strlen(cc_template); if (template_len >= 6 && strcmp(cc_template + (template_len - 6), "XXXXXX") != 0) { DEBUG(SSSDBG_CONF_SETTINGS, "ccache file name template [%s] doesn't " "contain randomizing characters (XXXXXX), file might not " "be rewritable\n", cc_template); } } errno_t check_and_export_options(struct dp_option *opts, struct sss_domain_info *dom, struct krb5_ctx *krb5_ctx) { TALLOC_CTX *tmp_ctx = NULL; int ret; const char *realm; const char *dummy; char *use_fast_str; char *fast_principal; char *ccname; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } realm = dp_opt_get_cstring(opts, KRB5_REALM); if (realm == NULL) { ret = dp_opt_set_string(opts, KRB5_REALM, dom->name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed.\n"); goto done; } realm = dom->name; } ret = setenv(SSSD_KRB5_REALM, realm, 1); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "setenv %s failed, authentication might fail.\n", SSSD_KRB5_REALM); } ret = check_and_export_lifetime(opts, KRB5_RENEWABLE_LIFETIME, SSSD_KRB5_RENEWABLE_LIFETIME); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to check value of krb5_renewable_lifetime. [%d][%s]\n", ret, strerror(ret)); goto done; } ret = check_and_export_lifetime(opts, KRB5_LIFETIME, SSSD_KRB5_LIFETIME); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to check value of krb5_lifetime. [%d][%s]\n", ret, strerror(ret)); goto done; } use_fast_str = dp_opt_get_string(opts, KRB5_USE_FAST); if (use_fast_str != NULL) { ret = check_fast(use_fast_str, &krb5_ctx->use_fast); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "check_fast failed.\n"); goto done; } if (krb5_ctx->use_fast) { ret = setenv(SSSD_KRB5_USE_FAST, use_fast_str, 1); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "setenv [%s] failed.\n", SSSD_KRB5_USE_FAST); } else { fast_principal = dp_opt_get_string(opts, KRB5_FAST_PRINCIPAL); if (fast_principal != NULL) { ret = setenv(SSSD_KRB5_FAST_PRINCIPAL, fast_principal, 1); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "setenv [%s] failed.\n", SSSD_KRB5_FAST_PRINCIPAL); } } } } } /* In contrast to MIT KDCs AD does not automatically canonicalize the * enterprise principal in an AS request but requires the canonicalize * flags to be set. To be on the safe side we always enable * canonicalization if enterprise principals are used. */ if (dp_opt_get_bool(opts, KRB5_CANONICALIZE) || dp_opt_get_bool(opts, KRB5_USE_ENTERPRISE_PRINCIPAL)) { ret = setenv(SSSD_KRB5_CANONICALIZE, "true", 1); } else { ret = setenv(SSSD_KRB5_CANONICALIZE, "false", 1); } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "setenv [%s] failed.\n", SSSD_KRB5_CANONICALIZE); } dummy = dp_opt_get_cstring(opts, KRB5_KDC); if (dummy == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "No KDC explicitly configured, using defaults.\n"); } dummy = dp_opt_get_cstring(opts, KRB5_KPASSWD); if (dummy == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "No kpasswd server explicitly configured, " "using the KDC or defaults.\n"); } ccname = dp_opt_get_string(opts, KRB5_CCNAME_TMPL); if (ccname != NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "The credential ccache name template has been explicitly set " "in sssd.conf, it is recommended to set default_ccache_name " "in krb5.conf instead so that a system default is used\n"); ccname = talloc_strdup(tmp_ctx, ccname); if (!ccname) { ret = ENOMEM; goto done; } } else { ret = sss_get_system_ccname_template(tmp_ctx, &ccname); if (ret && ret != ERR_NOT_FOUND) { goto done; } if (ret == ERR_NOT_FOUND) { /* Use fallback default */ ccname = talloc_strdup(tmp_ctx, DEFAULT_CCNAME_TEMPLATE); if (!ccname) { ret = ENOMEM; goto done; } } /* set back in opts */ ret = dp_opt_set_string(opts, KRB5_CCNAME_TMPL, ccname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed.\n"); goto done; } } if ((ccname[0] == '/') || (strncmp(ccname, "FILE:", 5) == 0)) { DEBUG(SSSDBG_CONF_SETTINGS, "ccache is of type FILE\n"); /* warn if the file type (which is usally created in a sticky bit * laden directory) does not have randomizing chracters */ sss_check_cc_template(ccname); if (ccname[0] == '/') { /* /path/to/cc prepend FILE: */ DEBUG(SSSDBG_CONF_SETTINGS, "The ccname template was " "missing an explicit type, but is an absolute " "path specifier. Assuming FILE:\n"); ccname = talloc_asprintf(tmp_ctx, "FILE:%s", ccname); if (!ccname) { ret = ENOMEM; goto done; } ret = dp_opt_set_string(opts, KRB5_CCNAME_TMPL, ccname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed.\n"); goto done; } } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t krb5_try_kdcip(struct confdb_ctx *cdb, const char *conf_path, struct dp_option *opts, int opt_id) { char *krb5_servers = NULL; errno_t ret; krb5_servers = dp_opt_get_string(opts, opt_id); if (krb5_servers == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "No KDC found in configuration, trying legacy option\n"); ret = confdb_get_string(cdb, NULL, conf_path, "krb5_kdcip", NULL, &krb5_servers); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "confdb_get_string failed.\n"); return ret; } if (krb5_servers != NULL) { ret = dp_opt_set_string(opts, opt_id, krb5_servers); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "dp_opt_set_string failed.\n"); talloc_free(krb5_servers); return ret; } DEBUG(SSSDBG_CONF_SETTINGS, "Set krb5 server [%s] based on legacy krb5_kdcip option\n", krb5_servers); DEBUG(SSSDBG_FATAL_FAILURE, "Your configuration uses the deprecated option " "'krb5_kdcip' to specify the KDC. Please change the " "configuration to use the 'krb5_server' option " "instead.\n"); talloc_free(krb5_servers); } } return EOK; } errno_t krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, struct dp_option **_opts) { int ret; struct dp_option *opts; opts = talloc_zero(memctx, struct dp_option); if (opts == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ret = dp_get_options(opts, cdb, conf_path, default_krb5_opts, KRB5_OPTS, &opts); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "dp_get_options failed.\n"); goto done; } /* If there is no KDC, try the deprecated krb5_kdcip option, too */ /* FIXME - this can be removed in a future version */ ret = krb5_try_kdcip(cdb, conf_path, opts, KRB5_KDC); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_try_kdcip failed.\n"); goto done; } *_opts = opts; ret = EOK; done: if (ret != EOK) { talloc_zfree(opts); } return ret; } errno_t write_krb5info_file(const char *realm, const char *server, const char *service) { int ret; int fd = -1; char *tmp_name = NULL; char *krb5info_name = NULL; TALLOC_CTX *tmp_ctx = NULL; const char *name_tmpl = NULL; size_t server_len; ssize_t written; if (realm == NULL || *realm == '\0' || server == NULL || *server == '\0' || service == NULL || *service == '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Missing or empty realm, server or service.\n"); return EINVAL; } if (sss_krb5_realm_has_proxy(realm)) { DEBUG(SSSDBG_CONF_SETTINGS, "KDC Proxy available for realm [%s], no kdcinfo file created.\n", realm); return EOK; } if (strcmp(service, SSS_KRB5KDC_FO_SRV) == 0) { name_tmpl = KDCINFO_TMPL; } else if (strcmp(service, SSS_KRB5KPASSWD_FO_SRV) == 0) { name_tmpl = KPASSWDINFO_TMPL; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported service [%s].\n", service); return EINVAL; } server_len = strlen(server); tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); return ENOMEM; } tmp_name = talloc_asprintf(tmp_ctx, PUBCONF_PATH"/.krb5info_dummy_XXXXXX"); if (tmp_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } krb5info_name = talloc_asprintf(tmp_ctx, name_tmpl, realm); if (krb5info_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } fd = sss_unique_file(tmp_ctx, tmp_name, &ret); if (fd == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_unique_file failed [%d][%s].\n", ret, strerror(ret)); goto done; } errno = 0; written = sss_atomic_write_s(fd, discard_const(server), server_len); if (written == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret, strerror(ret)); goto done; } if (written != server_len) { DEBUG(SSSDBG_CRIT_FAILURE, "Write error, wrote [%zd] bytes, expected [%zu]\n", written, server_len); ret = EIO; goto done; } ret = fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fchmod failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = close(fd); fd = -1; if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "close failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = rename(tmp_name, krb5info_name); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "rename failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = EOK; done: if (fd != -1) { close(fd); } talloc_free(tmp_ctx); return ret; } static void krb5_resolve_callback(void *private_data, struct fo_server *server) { struct krb5_service *krb5_service; struct resolv_hostent *srvaddr; char *address; char *safe_address; int ret; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed\n"); return; } krb5_service = talloc_get_type(private_data, struct krb5_service); if (!krb5_service) { DEBUG(SSSDBG_CRIT_FAILURE, "FATAL: Bad private_data\n"); talloc_free(tmp_ctx); return; } srvaddr = fo_get_server_hostent(server); if (!srvaddr) { DEBUG(SSSDBG_CRIT_FAILURE, "FATAL: No hostent available for server (%s)\n", fo_get_server_str_name(server)); talloc_free(tmp_ctx); return; } address = resolv_get_string_address(tmp_ctx, srvaddr); if (address == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_string_address failed.\n"); talloc_free(tmp_ctx); return; } safe_address = sss_escape_ip_address(tmp_ctx, srvaddr->family, address); if (safe_address == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_escape_ip_address failed.\n"); talloc_free(tmp_ctx); return; } if (krb5_service->write_kdcinfo) { safe_address = talloc_asprintf_append(safe_address, ":%d", fo_get_server_port(server)); if (safe_address == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n"); talloc_free(tmp_ctx); return; } ret = write_krb5info_file(krb5_service->realm, safe_address, krb5_service->name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "write_krb5info_file failed, authentication might fail.\n"); } } talloc_free(tmp_ctx); return; } static errno_t _krb5_servers_init(struct be_ctx *ctx, struct krb5_service *service, const char *service_name, const char *servers, bool primary) { TALLOC_CTX *tmp_ctx; char **list = NULL; errno_t ret = 0; int i; char *port_str; long port; char *server_spec; char *endptr; struct servent *servent; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = split_on_separator(tmp_ctx, servers, ',', true, true, &list, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse server list!\n"); goto done; } for (i = 0; list[i]; i++) { talloc_steal(service, list[i]); server_spec = talloc_strdup(service, list[i]); if (!server_spec) { ret = ENOMEM; goto done; } if (be_fo_is_srv_identifier(server_spec)) { if (!primary) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add server [%s] to failover service: " "SRV resolution only allowed for primary servers!\n", list[i]); continue; } ret = be_fo_add_srv_server(ctx, service_name, service_name, NULL, BE_FO_PROTO_UDP, true, NULL); if (ret) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n"); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Added service lookup\n"); continue; } /* Do not try to get port number if last character is ']' */ if (server_spec[strlen(server_spec) - 1] != ']') { port_str = strrchr(server_spec, ':'); } else { port_str = NULL; } if (port_str == NULL) { port = 0; } else { *port_str = '\0'; ++port_str; if (isdigit(*port_str)) { errno = 0; port = strtol(port_str, &endptr, 10); if (errno != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "strtol failed on [%s]: [%d][%s].\n", port_str, ret, strerror(ret)); goto done; } if (*endptr != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Found additional characters [%s] in port number " "[%s].\n", endptr, port_str); ret = EINVAL; goto done; } if (port < 1 || port > 65535) { DEBUG(SSSDBG_CRIT_FAILURE, "Illegal port number [%ld].\n", port); ret = EINVAL; goto done; } } else if (isalpha(*port_str)) { servent = getservbyname(port_str, NULL); if (servent == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "getservbyname cannot find service [%s].\n", port_str); ret = EINVAL; goto done; } port = servent->s_port; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported port specifier in [%s].\n", list[i]); ret = EINVAL; goto done; } } /* It could be ipv6 address in square brackets. Remove * the brackets if needed. */ ret = remove_ipv6_brackets(server_spec); if (ret != EOK) { goto done; } ret = be_fo_add_server(ctx, service_name, server_spec, (int) port, list[i], primary); if (ret && ret != EEXIST) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add server\n"); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Added Server %s\n", list[i]); } done: talloc_free(tmp_ctx); return ret; } static inline errno_t krb5_primary_servers_init(struct be_ctx *ctx, struct krb5_service *service, const char *service_name, const char *servers) { return _krb5_servers_init(ctx, service, service_name, servers, true); } static inline errno_t krb5_backup_servers_init(struct be_ctx *ctx, struct krb5_service *service, const char *service_name, const char *servers) { return _krb5_servers_init(ctx, service, service_name, servers, false); } static int krb5_user_data_cmp(void *ud1, void *ud2) { return strcasecmp((char*) ud1, (char*) ud2); } int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, const char *service_name, const char *primary_servers, const char *backup_servers, const char *realm, bool use_kdcinfo, struct krb5_service **_service) { TALLOC_CTX *tmp_ctx; struct krb5_service *service; int ret; tmp_ctx = talloc_new(memctx); if (!tmp_ctx) { return ENOMEM; } service = talloc_zero(tmp_ctx, struct krb5_service); if (!service) { ret = ENOMEM; goto done; } ret = be_fo_add_service(ctx, service_name, krb5_user_data_cmp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create failover service!\n"); goto done; } service->name = talloc_strdup(service, service_name); if (!service->name) { ret = ENOMEM; goto done; } service->realm = talloc_strdup(service, realm); if (!service->realm) { ret = ENOMEM; goto done; } service->write_kdcinfo = use_kdcinfo; if (!primary_servers) { DEBUG(SSSDBG_CONF_SETTINGS, "No primary servers defined, using service discovery\n"); primary_servers = BE_SRV_IDENTIFIER; } ret = krb5_primary_servers_init(ctx, service, service_name, primary_servers); if (ret != EOK) { goto done; } if (backup_servers) { ret = krb5_backup_servers_init(ctx, service, service_name, backup_servers); if (ret != EOK) { goto done; } } ret = be_fo_service_add_callback(memctx, ctx, service_name, krb5_resolve_callback, service); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add failover callback!\n"); goto done; } ret = EOK; done: if (ret == EOK) { *_service = talloc_steal(memctx, service); } talloc_zfree(tmp_ctx); return ret; } errno_t remove_krb5_info_files(TALLOC_CTX *mem_ctx, const char *realm) { int ret; errno_t err; char *file; file = talloc_asprintf(mem_ctx, KDCINFO_TMPL, realm); if(file == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); return ENOMEM; } errno = 0; ret = unlink(file); if (ret == -1) { err = errno; DEBUG(SSSDBG_FUNC_DATA, "Could not remove [%s], [%d][%s]\n", file, err, strerror(err)); } file = talloc_asprintf(mem_ctx, KPASSWDINFO_TMPL, realm); if(file == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); return ENOMEM; } errno = 0; ret = unlink(file); if (ret == -1) { err = errno; DEBUG(SSSDBG_FUNC_DATA, "Could not remove [%s], [%d][%s]\n", file, err, strerror(err)); } return EOK; } void remove_krb5_info_files_callback(void *pvt) { int ret; TALLOC_CTX *tmp_ctx = NULL; struct remove_info_files_ctx *ctx = talloc_get_type(pvt, struct remove_info_files_ctx); ret = be_fo_run_callbacks_at_next_request(ctx->be_ctx, ctx->kdc_service_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_fo_run_callbacks_at_next_request failed, " "krb5 info files will not be removed, because " "it is unclear if they will be recreated properly.\n"); return; } if (ctx->kpasswd_service_name != NULL) { ret = be_fo_run_callbacks_at_next_request(ctx->be_ctx, ctx->kpasswd_service_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_fo_run_callbacks_at_next_request failed, " "krb5 info files will not be removed, because " "it is unclear if they will be recreated properly.\n"); return; } } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed, cannot remove krb5 info files.\n"); return; } ret = remove_krb5_info_files(tmp_ctx, ctx->realm); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "remove_krb5_info_files failed.\n"); } talloc_zfree(tmp_ctx); } void krb5_finalize(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { char *realm = (char *)private_data; int ret; ret = remove_krb5_info_files(se, realm); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "remove_krb5_info_files failed.\n"); } orderly_shutdown(0); } errno_t krb5_install_offline_callback(struct be_ctx *be_ctx, struct krb5_ctx *krb5_ctx) { int ret; struct remove_info_files_ctx *ctx; const char *krb5_realm; if (krb5_ctx->service == NULL || krb5_ctx->service->name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing KDC service name!\n"); return EINVAL; } ctx = talloc_zero(krb5_ctx, struct remove_info_files_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zfree failed.\n"); return ENOMEM; } krb5_realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM); if (krb5_realm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing krb5_realm option!\n"); ret = EINVAL; goto done; } ctx->realm = talloc_strdup(ctx, krb5_realm); if (ctx->realm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed!\n"); ret = ENOMEM; goto done; } ctx->be_ctx = be_ctx; ctx->kdc_service_name = krb5_ctx->service->name; if (krb5_ctx->kpasswd_service == NULL) { ctx->kpasswd_service_name =NULL; } else { ctx->kpasswd_service_name = krb5_ctx->kpasswd_service->name; } ret = be_add_offline_cb(ctx, be_ctx, remove_krb5_info_files_callback, ctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "be_add_offline_cb failed.\n"); goto done; } ret = EOK; done: if (ret != EOK) { talloc_zfree(ctx); } return ret; } errno_t krb5_install_sigterm_handler(struct tevent_context *ev, struct krb5_ctx *krb5_ctx) { const char *krb5_realm; char *sig_realm; struct tevent_signal *sige; BlockSignals(false, SIGTERM); krb5_realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM); if (krb5_realm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing krb5_realm option!\n"); return EINVAL; } sig_realm = talloc_strdup(krb5_ctx, krb5_realm); if (sig_realm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed!\n"); return ENOMEM; } sige = tevent_add_signal(ev, krb5_ctx, SIGTERM, SA_SIGINFO, krb5_finalize, sig_realm); if (sige == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_signal failed.\n"); talloc_free(sig_realm); return ENOMEM; } talloc_steal(sige, sig_realm); return EOK; } errno_t krb5_get_simple_upn(TALLOC_CTX *mem_ctx, struct krb5_ctx *krb5_ctx, struct sss_domain_info *dom, const char *username, const char *user_dom, char **_upn) { const char *realm = NULL; char *uc_dom = NULL; char *upn; char *name; TALLOC_CTX *tmp_ctx = NULL; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); return ENOMEM; } if (user_dom != NULL && dom->name != NULL && strcasecmp(dom->name, user_dom) != 0) { uc_dom = get_uppercase_realm(tmp_ctx, user_dom); if (uc_dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n"); ret = ENOMEM; goto done; } } else { realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM); if (realm == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing Kerberos realm.\n"); ret = ENOMEM; goto done; } } /* Subdomains already have a fully qualified name, which contains * the domain name. We need to replace it with the realm name */ ret = sss_parse_name(tmp_ctx, dom->names, username, NULL, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not parse [%s] into name and " "domain components, login might fail\n", username); name = discard_const(username); } /* NOTE: this is a hack, works only in some environments */ upn = talloc_asprintf(tmp_ctx, "%s@%s", name, realm != NULL ? realm : uc_dom); if (upn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Using simple UPN [%s].\n", upn); *_upn = talloc_steal(mem_ctx, upn); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t compare_principal_realm(const char *upn, const char *realm, bool *different_realm) { char *at_sign; if (upn == NULL || realm == NULL || different_realm == NULL || *upn == '\0' || *realm == '\0') { return EINVAL; } at_sign = strchr(upn, '@'); if (at_sign == NULL) { return EINVAL; } if (strcmp(realm, at_sign + 1) == 0) { *different_realm = false; } else { *different_realm = true; } return EOK; } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_auth.c0000644000000000000000000000007412703456111020024 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.761793992 sssd-1.13.4/src/providers/krb5/krb5_auth.c0000644002412700241270000012156212703456111021502 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module Authors: Sumit Bose Copyright (C) 2009-2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "util/util.h" #include "util/find_uid.h" #include "util/auth_utils.h" #include "db/sysdb.h" #include "util/sss_utf8.h" #include "util/child_common.h" #include "providers/krb5/krb5_auth.h" #include "providers/krb5/krb5_utils.h" #include "providers/krb5/krb5_ccache.h" static int krb5_mod_ccname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *name, const char *ccname, int mod_op) { TALLOC_CTX *tmpctx; struct sysdb_attrs *attrs; int ret; errno_t sret; bool in_transaction = false; if (name == NULL || ccname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing user or ccache name.\n"); return EINVAL; } if (mod_op != SYSDB_MOD_REP && mod_op != SYSDB_MOD_DEL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported operation [%d].\n", mod_op); return EINVAL; } DEBUG(SSSDBG_TRACE_ALL, "%s ccname [%s] for user [%s].\n", mod_op == SYSDB_MOD_REP ? "Save" : "Delete", ccname, name); tmpctx = talloc_new(mem_ctx); if (!tmpctx) { return ENOMEM; } attrs = sysdb_new_attrs(tmpctx); if (!attrs) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_CCACHE_FILE, ccname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error %d starting transaction (%s)\n", ret, strerror(ret)); goto done; } in_transaction = true; ret = sysdb_set_user_attr(domain, name, attrs, mod_op); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); goto done; } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction!\n"); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } talloc_zfree(tmpctx); return ret; } static int krb5_save_ccname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *name, const char *ccname) { return krb5_mod_ccname(mem_ctx, sysdb, domain, name, ccname, SYSDB_MOD_REP); } static int krb5_delete_ccname(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *name, const char *ccname) { return krb5_mod_ccname(mem_ctx, sysdb, domain, name, ccname, SYSDB_MOD_DEL); } static struct krb5_ctx *get_krb5_ctx(struct be_req *be_req) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct pam_data *pd; pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: case SSS_CMD_RENEW: return talloc_get_type(be_ctx->bet_info[BET_AUTH].pvt_bet_data, struct krb5_ctx); break; case SSS_PAM_ACCT_MGMT: return talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data, struct krb5_ctx); break; case SSS_PAM_CHAUTHTOK: case SSS_PAM_CHAUTHTOK_PRELIM: return talloc_get_type(be_ctx->bet_info[BET_CHPASS].pvt_bet_data, struct krb5_ctx); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported PAM task.\n"); return NULL; } } static int krb5_cleanup(void *ptr) { struct krb5child_req *kr = talloc_get_type(ptr, struct krb5child_req); if (kr == NULL) return EOK; memset(kr, 0, sizeof(struct krb5child_req)); return EOK; } static errno_t get_krb_primary(struct map_id_name_to_krb_primary *name_to_primary, char *id_prov_name, bool cs, const char **_krb_primary) { errno_t ret; int i = 0; while(name_to_primary != NULL && name_to_primary[i].id_name != NULL && name_to_primary[i].krb_primary != NULL) { if (sss_string_equal(cs, name_to_primary[i].id_name, id_prov_name)) { *_krb_primary = name_to_primary[i].krb_primary; ret = EOK; goto done; } i++; } /* Handle also the case of name_to_primary being NULL */ ret = ENOENT; done: return ret; } errno_t krb5_setup(TALLOC_CTX *mem_ctx, struct pam_data *pd, struct krb5_ctx *krb5_ctx, bool cs, struct krb5child_req **_krb5_req) { struct krb5child_req *kr; const char *mapped_name; TALLOC_CTX *tmp_ctx; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } kr = talloc_zero(tmp_ctx, struct krb5child_req); if (kr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); ret = ENOMEM; goto done; } kr->is_offline = false; talloc_set_destructor((TALLOC_CTX *) kr, krb5_cleanup); kr->pd = pd; kr->krb5_ctx = krb5_ctx; ret = get_krb_primary(krb5_ctx->name_to_primary, pd->user, cs, &mapped_name); if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Setting mapped name to: %s\n", mapped_name); kr->user = mapped_name; } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "No mapping for: %s\n", pd->user); kr->user = pd->user; } else { DEBUG(SSSDBG_CRIT_FAILURE, "get_krb_primary failed - %s:[%d]\n", sss_strerror(ret), ret); goto done; } ret = EOK; done: if (ret == EOK) { *_krb5_req = talloc_steal(mem_ctx, kr); } talloc_free(tmp_ctx); return ret; } static void krb5_auth_cache_creds(struct krb5_ctx *krb5_ctx, struct sss_domain_info *domain, struct confdb_ctx *cdb, struct pam_data *pd, uid_t uid, int *pam_status, int *dp_err) { const char *password = NULL; errno_t ret; if (sss_authtok_get_type(pd->authtok) != SSS_AUTHTOK_TYPE_PASSWORD) { DEBUG(SSSDBG_MINOR_FAILURE, "Delayed authentication is only available for password " "authentication (single factor).\n"); return; } ret = sss_authtok_get_password(pd->authtok, &password, NULL); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get password [%d] %s\n", ret, strerror(ret)); *pam_status = PAM_SYSTEM_ERR; *dp_err = DP_ERR_OK; return; } ret = sysdb_cache_auth(domain, pd->user, password, cdb, true, NULL, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Offline authentication failed\n"); *pam_status = cached_login_pam_status(ret); *dp_err = DP_ERR_OK; return; } ret = add_user_to_delayed_online_authentication(krb5_ctx, pd, uid); if (ret != EOK) { /* This error is not fatal */ DEBUG(SSSDBG_CRIT_FAILURE, "add_user_to_delayed_online_authentication failed.\n"); } *pam_status = PAM_AUTHINFO_UNAVAIL; *dp_err = DP_ERR_OFFLINE; } static errno_t krb5_auth_prepare_ccache_name(struct krb5child_req *kr, struct ldb_message *user_msg, struct be_ctx *be_ctx) { const char *ccname_template; ccname_template = dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_CCNAME_TMPL); kr->ccname = expand_ccname_template(kr, kr, ccname_template, kr->krb5_ctx->illegal_path_re, true, be_ctx->domain->case_sensitive); if (kr->ccname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "expand_ccname_template failed.\n"); return ENOMEM; } kr->old_ccname = ldb_msg_find_attr_as_string(user_msg, SYSDB_CCACHE_FILE, NULL); if (kr->old_ccname == NULL) { DEBUG(SSSDBG_TRACE_LIBS, "No ccache file for user [%s] found.\n", kr->pd->user); } return EOK; } static void krb5_auth_store_creds(struct sss_domain_info *domain, struct pam_data *pd) { const char *password = NULL; const char *fa2; size_t password_len; size_t fa2_len = 0; int ret = EOK; switch(pd->cmd) { case SSS_CMD_RENEW: /* The authtok is set to the credential cache * during renewal. We don't want to save this * as the cached password. */ break; case SSS_PAM_AUTHENTICATE: case SSS_PAM_CHAUTHTOK_PRELIM: if (sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_2FA) { ret = sss_authtok_get_2fa(pd->authtok, &password, &password_len, &fa2, &fa2_len); if (ret == EOK && password_len < domain->cache_credentials_min_ff_length) { DEBUG(SSSDBG_FATAL_FAILURE, "First factor is too short to be cache, " "minimum length is [%u].\n", domain->cache_credentials_min_ff_length); ret = EINVAL; } } else { ret = sss_authtok_get_password(pd->authtok, &password, NULL); } break; case SSS_PAM_CHAUTHTOK: ret = sss_authtok_get_password(pd->newauthtok, &password, NULL); break; default: DEBUG(SSSDBG_FATAL_FAILURE, "unsupported PAM command [%d].\n", pd->cmd); } if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get password [%d] %s\n", ret, strerror(ret)); /* password caching failures are not fatal errors */ return; } if (password == NULL) { if (pd->cmd != SSS_CMD_RENEW) { DEBUG(SSSDBG_FATAL_FAILURE, "password not available, offline auth may not work.\n"); /* password caching failures are not fatal errors */ } return; } ret = sysdb_cache_password_ex(domain, pd->user, password, sss_authtok_get_type(pd->authtok), fa2_len); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to cache password, offline auth may not work." " (%d)[%s]!?\n", ret, strerror(ret)); /* password caching failures are not fatal errors */ } } static bool is_otp_enabled(struct ldb_message *user_msg) { struct ldb_message_element *el; size_t i; el = ldb_msg_find_element(user_msg, SYSDB_AUTH_TYPE); if (el == NULL) { return false; } for (i = 0; i < el->num_values; i++) { if (strcmp((const char * )el->values[i].data, "otp") == 0) { return true; } } return false; } /* krb5_auth request */ struct krb5_auth_state { struct tevent_context *ev; struct be_ctx *be_ctx; struct pam_data *pd; struct sysdb_ctx *sysdb; struct sss_domain_info *domain; struct krb5_ctx *krb5_ctx; struct krb5child_req *kr; bool search_kpasswd; int pam_status; int dp_err; }; static void krb5_auth_resolve_done(struct tevent_req *subreq); static void krb5_auth_done(struct tevent_req *subreq); struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct pam_data *pd, struct krb5_ctx *krb5_ctx) { const char **attrs; struct krb5_auth_state *state; struct ldb_result *res; struct krb5child_req *kr = NULL; const char *realm; struct tevent_req *req; struct tevent_req *subreq; enum sss_authtok_type authtok_type; int ret; bool otp; req = tevent_req_create(mem_ctx, &state, struct krb5_auth_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->be_ctx = be_ctx; state->pd = pd; state->krb5_ctx = krb5_ctx; state->kr = NULL; state->pam_status = PAM_SYSTEM_ERR; state->dp_err = DP_ERR_FATAL; ret = get_domain_or_subdomain(be_ctx, pd->domain, &state->domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_domain_or_subdomain failed.\n"); goto done; } state->sysdb = state->domain->sysdb; authtok_type = sss_authtok_get_type(pd->authtok); switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: case SSS_PAM_CHAUTHTOK: if (authtok_type != SSS_AUTHTOK_TYPE_PASSWORD && authtok_type != SSS_AUTHTOK_TYPE_2FA) { /* handle empty password gracefully */ if (authtok_type == SSS_AUTHTOK_TYPE_EMPTY) { DEBUG(SSSDBG_CRIT_FAILURE, "Illegal zero-length authtok for user [%s]\n", pd->user); state->pam_status = PAM_AUTH_ERR; state->dp_err = DP_ERR_OK; ret = EOK; goto done; } DEBUG(SSSDBG_CRIT_FAILURE, "Wrong authtok type for user [%s]. " \ "Expected [%d], got [%d]\n", pd->user, SSS_AUTHTOK_TYPE_PASSWORD, authtok_type); state->pam_status = PAM_SYSTEM_ERR; state->dp_err = DP_ERR_FATAL; ret = EINVAL; goto done; } break; case SSS_PAM_CHAUTHTOK_PRELIM: if (pd->priv == 1 && authtok_type != SSS_AUTHTOK_TYPE_PASSWORD) { DEBUG(SSSDBG_MINOR_FAILURE, "Password reset by root is not supported.\n"); state->pam_status = PAM_PERM_DENIED; state->dp_err = DP_ERR_OK; ret = EOK; goto done; } break; case SSS_CMD_RENEW: if (authtok_type != SSS_AUTHTOK_TYPE_CCFILE) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrong authtok type for user [%s]. " \ "Expected [%d], got [%d]\n", pd->user, SSS_AUTHTOK_TYPE_CCFILE, authtok_type); state->pam_status = PAM_SYSTEM_ERR; state->dp_err = DP_ERR_FATAL; ret = EINVAL; goto done; } break; case SSS_PAM_PREAUTH: break; default: DEBUG(SSSDBG_CONF_SETTINGS, "Unexpected pam task %d.\n", pd->cmd); state->pam_status = PAM_SYSTEM_ERR; state->dp_err = DP_ERR_FATAL; ret = EINVAL; goto done; } if (be_is_offline(be_ctx) && (pd->cmd == SSS_PAM_CHAUTHTOK || pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM || pd->cmd == SSS_CMD_RENEW)) { DEBUG(SSSDBG_TRACE_ALL, "Password changes and ticket renewal are not possible " "while offline.\n"); state->pam_status = PAM_AUTHINFO_UNAVAIL; state->dp_err = DP_ERR_OFFLINE; ret = EOK; goto done; } attrs = talloc_array(state, const char *, 8); if (attrs == NULL) { ret = ENOMEM; goto done; } attrs[0] = SYSDB_UPN; attrs[1] = SYSDB_HOMEDIR; attrs[2] = SYSDB_CCACHE_FILE; attrs[3] = SYSDB_UIDNUM; attrs[4] = SYSDB_GIDNUM; attrs[5] = SYSDB_CANONICAL_UPN; attrs[6] = SYSDB_AUTH_TYPE; attrs[7] = NULL; ret = krb5_setup(state, pd, krb5_ctx, state->domain->case_sensitive, &state->kr); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_setup failed.\n"); goto done; } kr = state->kr; ret = sysdb_get_user_attr_with_views(state, state->domain, state->pd->user, attrs, &res); if (ret) { DEBUG(SSSDBG_FUNC_DATA, "sysdb search for upn of user [%s] failed.\n", pd->user); state->pam_status = PAM_SYSTEM_ERR; state->dp_err = DP_ERR_OK; goto done; } realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM); if (realm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing Kerberos realm.\n"); ret = ENOENT; goto done; } switch (res->count) { case 0: DEBUG(SSSDBG_FUNC_DATA, "No attributes for user [%s] found.\n", pd->user); ret = ENOENT; goto done; break; case 1: ret = find_or_guess_upn(state, res->msgs[0], krb5_ctx, be_ctx->domain, kr->user, pd->domain, &kr->upn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "find_or_guess_upn failed.\n"); goto done; } ret = compare_principal_realm(kr->upn, realm, &kr->upn_from_different_realm); if (ret != 0) { DEBUG(SSSDBG_OP_FAILURE, "compare_principal_realm failed.\n"); goto done; } kr->homedir = sss_view_ldb_msg_find_attr_as_string(state->domain, res->msgs[0], SYSDB_HOMEDIR, NULL); if (kr->homedir == NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "Home directory for user [%s] not known.\n", pd->user); } kr->uid = sss_view_ldb_msg_find_attr_as_uint64(state->domain, res->msgs[0], SYSDB_UIDNUM, 0); if (kr->uid == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "UID for user [%s] not known.\n", pd->user); ret = ENOENT; goto done; } kr->gid = sss_view_ldb_msg_find_attr_as_uint64(state->domain, res->msgs[0], SYSDB_GIDNUM, 0); if (kr->gid == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "GID for user [%s] not known.\n", pd->user); ret = ENOENT; goto done; } ret = krb5_auth_prepare_ccache_name(kr, res->msgs[0], state->be_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot prepare ccache names!\n"); goto done; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "User search for (%s) returned > 1 results!\n", pd->user); ret = EINVAL; goto done; break; } otp = is_otp_enabled(res->msgs[0]); if (pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM && otp == true) { /* To avoid consuming the OTP */ DEBUG(SSSDBG_TRACE_FUNC, "Skipping password checks for OTP-enabled user\n"); state->pam_status = PAM_SUCCESS; state->dp_err = DP_ERR_OK; ret = EOK; goto done; } kr->srv = NULL; kr->kpasswd_srv = NULL; state->search_kpasswd = false; subreq = be_resolve_server_send(state, state->ev, state->be_ctx, state->krb5_ctx->service->name, state->kr->srv == NULL ? true : false); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed resolver request.\n"); ret = EIO; goto done; } tevent_req_set_callback(subreq, krb5_auth_resolve_done, req); return req; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, state->ev); return req; } static void krb5_auth_resolve_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state); struct krb5child_req *kr = state->kr; int ret; if (!state->search_kpasswd) { ret = be_resolve_server_recv(subreq, kr, &kr->srv); } else { ret = be_resolve_server_recv(subreq, kr, &kr->kpasswd_srv); } talloc_zfree(subreq); if (state->search_kpasswd) { if ((ret != EOK) && (kr->pd->cmd == SSS_PAM_CHAUTHTOK || kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM)) { /* all kpasswd servers have been tried and none was found good, * but the kdc seems ok. Password changes are not possible but * authentication is. We return an PAM error here, but do not * mark the backend offline. */ state->pam_status = PAM_AUTHTOK_LOCK_BUSY; state->dp_err = DP_ERR_OK; ret = EOK; goto done; } } else { if (ret != EOK) { /* all servers have been tried and none * was found good, setting offline, * but we still have to call the child to setup * the ccache file if we are performing auth */ be_mark_dom_offline(state->domain, state->be_ctx); kr->is_offline = true; if (kr->pd->cmd == SSS_PAM_CHAUTHTOK || kr->pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) { DEBUG(SSSDBG_TRACE_FUNC, "No KDC suitable for password change is available\n"); state->pam_status = PAM_AUTHTOK_LOCK_BUSY; state->dp_err = DP_ERR_OK; ret = EOK; goto done; } } else { if (kr->krb5_ctx->kpasswd_service != NULL) { state->search_kpasswd = true; subreq = be_resolve_server_send(state, state->ev, state->be_ctx, state->krb5_ctx->kpasswd_service->name, kr->kpasswd_srv == NULL ? true : false); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Resolver request failed.\n"); ret = EIO; goto done; } tevent_req_set_callback(subreq, krb5_auth_resolve_done, req); return; } } } if (!kr->is_offline) { kr->is_offline = be_is_offline(state->be_ctx); } if (!kr->is_offline && sss_domain_get_state(state->domain) == DOM_INACTIVE) { DEBUG(SSSDBG_TRACE_INTERNAL, "Subdomain %s is inactive, will proceed offline\n", state->domain->name); kr->is_offline = true; } if (kr->is_offline && sss_krb5_realm_has_proxy(dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_REALM))) { DEBUG(SSSDBG_TRACE_FUNC, "Resetting offline status, KDC proxy is in use\n"); kr->is_offline = false; } subreq = handle_child_send(state, state->ev, kr); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "handle_child_send failed.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, krb5_auth_done, req); return; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } static void krb5_auth_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state); struct krb5child_req *kr = state->kr; struct pam_data *pd = state->pd; int ret; uint8_t *buf = NULL; ssize_t len = -1; struct krb5_child_response *res; struct fo_server *search_srv; krb5_deltat renew_interval_delta; char *renew_interval_str; time_t renew_interval_time = 0; bool use_enterprise_principal; ret = handle_child_recv(subreq, pd, &buf, &len); talloc_zfree(subreq); if (ret == ETIMEDOUT) { DEBUG(SSSDBG_CRIT_FAILURE, "child timed out!\n"); switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: case SSS_CMD_RENEW: state->search_kpasswd = false; search_srv = kr->srv; break; case SSS_PAM_CHAUTHTOK: case SSS_PAM_CHAUTHTOK_PRELIM: if (state->kr->kpasswd_srv) { state->search_kpasswd = true; search_srv = kr->kpasswd_srv; break; } else { state->search_kpasswd = false; search_srv = kr->srv; break; } default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected PAM task\n"); ret = EINVAL; goto done; } be_fo_set_port_status(state->be_ctx, state->krb5_ctx->service->name, search_srv, PORT_NOT_WORKING); subreq = be_resolve_server_send(state, state->ev, state->be_ctx, state->krb5_ctx->service->name, search_srv == NULL ? true : false); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed resolved request.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, krb5_auth_resolve_done, req); return; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "child failed (%d [%s])\n", ret, strerror(ret)); goto done; } /* EOK */ ret = parse_krb5_child_response(state, buf, len, pd, state->be_ctx->domain->pwd_expiration_warning, &res); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not parse child response [%d]: %s\n", ret, strerror(ret)); goto done; } if (res->ccname) { kr->ccname = talloc_strdup(kr, res->ccname); if (!kr->ccname) { ret = ENOMEM; goto done; } } use_enterprise_principal = dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_USE_ENTERPRISE_PRINCIPAL); /* Check if the cases of our upn are correct and update it if needed. * Fail if the upn differs by more than just the case for non-enterprise * principals. */ if (res->correct_upn != NULL && strcmp(kr->upn, res->correct_upn) != 0) { if (strcasecmp(kr->upn, res->correct_upn) == 0 || use_enterprise_principal == true) { talloc_free(kr->upn); kr->upn = talloc_strdup(kr, res->correct_upn); if (kr->upn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } ret = check_if_cached_upn_needs_update(state->sysdb, state->domain, pd->user, res->correct_upn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "check_if_cached_upn_needs_update failed.\n"); goto done; } } else { DEBUG(SSSDBG_CRIT_FAILURE, "UPN used in the request [%s] and " \ "returned UPN [%s] differ by more " \ "than just the case.\n", kr->upn, res->correct_upn); ret = EINVAL; goto done; } } /* If the child request failed, but did not return an offline error code, * return with the status */ switch (res->msg_status) { case ERR_OK: /* If the child request was successful and we run the first pass of the * change password request just return success. */ if (pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) { state->pam_status = PAM_SUCCESS; state->dp_err = DP_ERR_OK; ret = EOK; goto done; } break; case ERR_NETWORK_IO: if (kr->kpasswd_srv != NULL && (pd->cmd == SSS_PAM_CHAUTHTOK || pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM)) { /* if using a dedicated kpasswd server for a chpass operation... */ be_fo_set_port_status(state->be_ctx, state->krb5_ctx->kpasswd_service->name, kr->kpasswd_srv, PORT_NOT_WORKING); /* ..try to resolve next kpasswd server */ state->search_kpasswd = true; subreq = be_resolve_server_send(state, state->ev, state->be_ctx, state->krb5_ctx->kpasswd_service->name, state->kr->kpasswd_srv == NULL ? true : false); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Resolver request failed.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, krb5_auth_resolve_done, req); return; } else if (kr->srv != NULL) { /* failed to use the KDC... */ be_fo_set_port_status(state->be_ctx, state->krb5_ctx->service->name, kr->srv, PORT_NOT_WORKING); /* ..try to resolve next KDC */ state->search_kpasswd = false; subreq = be_resolve_server_send(state, state->ev, state->be_ctx, state->krb5_ctx->service->name, kr->srv == NULL ? true : false); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Resolver request failed.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, krb5_auth_resolve_done, req); return; } break; case ERR_CREDS_EXPIRED_CCACHE: ret = krb5_delete_ccname(state, state->sysdb, state->domain, pd->user, kr->old_ccname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_delete_ccname failed.\n"); } /* FALLTHROUGH */ case ERR_CREDS_EXPIRED: /* If the password is expired we can safely remove the ccache from the * cache and disk if it is not actively used anymore. This will allow * to create a new random ccache if sshd with privilege separation is * used. */ if (pd->cmd == SSS_PAM_AUTHENTICATE && !kr->active_ccache) { if (kr->old_ccname != NULL) { ret = krb5_delete_ccname(state, state->sysdb, state->domain, pd->user, kr->old_ccname); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_delete_ccname failed.\n"); } } } state->pam_status = PAM_NEW_AUTHTOK_REQD; state->dp_err = DP_ERR_OK; ret = EOK; goto done; case ERR_CREDS_INVALID: state->pam_status = PAM_CRED_ERR; state->dp_err = DP_ERR_OK; ret = EOK; goto done; case ERR_ACCOUNT_EXPIRED: state->pam_status = PAM_ACCT_EXPIRED; state->dp_err = DP_ERR_OK; ret = EOK; goto done; case ERR_NO_CREDS: state->pam_status = PAM_CRED_UNAVAIL; state->dp_err = DP_ERR_OK; ret = EOK; goto done; case ERR_AUTH_FAILED: state->pam_status = PAM_AUTH_ERR; state->dp_err = DP_ERR_OK; ret = EOK; goto done; case ERR_CHPASS_FAILED: state->pam_status = PAM_AUTHTOK_ERR; state->dp_err = DP_ERR_OK; ret = EOK; goto done; default: state->pam_status = PAM_SYSTEM_ERR; state->dp_err = DP_ERR_OK; ret = EOK; goto done; } if (kr->kpasswd_srv != NULL && (pd->cmd == SSS_PAM_CHAUTHTOK || pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM)) { /* found a dedicated kpasswd server for a chpass operation */ be_fo_set_port_status(state->be_ctx, state->krb5_ctx->service->name, kr->kpasswd_srv, PORT_WORKING); } else if (kr->srv != NULL) { /* found a KDC */ be_fo_set_port_status(state->be_ctx, state->krb5_ctx->service->name, kr->srv, PORT_WORKING); } /* Now only a successful authentication or password change is left. * * We expect that one of the messages in the received buffer contains * the name of the credential cache file. */ if (kr->ccname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing ccache name in child response.\n"); ret = EINVAL; goto done; } ret = krb5_save_ccname(state, state->sysdb, state->domain, pd->user, kr->ccname); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_save_ccname failed.\n"); goto done; } renew_interval_str = dp_opt_get_string(kr->krb5_ctx->opts, KRB5_RENEW_INTERVAL); if (renew_interval_str != NULL) { ret = krb5_string_to_deltat(renew_interval_str, &renew_interval_delta); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Reading krb5_renew_interval failed.\n"); renew_interval_delta = 0; } renew_interval_time = renew_interval_delta; } if (res->msg_status == ERR_OK && renew_interval_time > 0 && (pd->cmd == SSS_PAM_AUTHENTICATE || pd->cmd == SSS_CMD_RENEW || pd->cmd == SSS_PAM_CHAUTHTOK) && (res->tgtt.renew_till > res->tgtt.endtime) && (kr->ccname != NULL)) { DEBUG(SSSDBG_TRACE_LIBS, "Adding [%s] for automatic renewal.\n", kr->ccname); ret = add_tgt_to_renew_table(kr->krb5_ctx, kr->ccname, &(res->tgtt), pd, kr->upn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "add_tgt_to_renew_table failed, " "automatic renewal not possible.\n"); } } if (kr->is_offline) { if (dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_STORE_PASSWORD_IF_OFFLINE)) { krb5_auth_cache_creds(state->kr->krb5_ctx, state->domain, state->be_ctx->cdb, state->pd, state->kr->uid, &state->pam_status, &state->dp_err); } else { DEBUG(SSSDBG_CONF_SETTINGS, "Backend is marked offline, retry later!\n"); state->pam_status = PAM_AUTHINFO_UNAVAIL; state->dp_err = DP_ERR_OFFLINE; } ret = EOK; goto done; } if (state->be_ctx->domain->cache_credentials == TRUE && (!res->otp || (res->otp && sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_2FA))) { krb5_auth_store_creds(state->domain, pd); } /* The SSS_OTP message will prevent pam_sss from putting the entered * password on the PAM stack for other modules to use. This is not needed * when both factors were entered separately because here the first factor * (long term password) can be passed to the other modules. */ if (res->otp == true && pd->cmd == SSS_PAM_AUTHENTICATE && sss_authtok_get_type(pd->authtok) != SSS_AUTHTOK_TYPE_2FA) { uint32_t otp_flag = 1; ret = pam_add_response(pd, SSS_OTP, sizeof(uint32_t), (const uint8_t *) &otp_flag); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed: %d (%s).\n", ret, sss_strerror(ret)); state->pam_status = PAM_SYSTEM_ERR; state->dp_err = DP_ERR_OK; goto done; } } state->pam_status = PAM_SUCCESS; state->dp_err = DP_ERR_OK; ret = EOK; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } int krb5_auth_recv(struct tevent_req *req, int *pam_status, int *dp_err) { struct krb5_auth_state *state = tevent_req_data(req, struct krb5_auth_state); *pam_status = state->pam_status; *dp_err = state->dp_err; TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } void krb5_pam_handler_auth_done(struct tevent_req *req); static void krb5_pam_handler_access_done(struct tevent_req *req); void krb5_pam_handler(struct be_req *be_req) { struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); struct tevent_req *req; struct pam_data *pd; struct krb5_ctx *krb5_ctx; int dp_err = DP_ERR_FATAL; pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); pd->pam_status = PAM_SYSTEM_ERR; krb5_ctx = get_krb5_ctx(be_req); if (krb5_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Kerberos context not available.\n"); goto done; } switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: case SSS_CMD_RENEW: case SSS_PAM_CHAUTHTOK_PRELIM: case SSS_PAM_CHAUTHTOK: req = krb5_auth_queue_send(be_req, be_ctx->ev, be_ctx, pd, krb5_ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_auth_send failed.\n"); goto done; } tevent_req_set_callback(req, krb5_pam_handler_auth_done, be_req); break; case SSS_PAM_ACCT_MGMT: req = krb5_access_send(be_req, be_ctx->ev, be_ctx, pd, krb5_ctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_access_send failed.\n"); goto done; } tevent_req_set_callback(req, krb5_pam_handler_access_done, be_req); break; case SSS_PAM_SETCRED: case SSS_PAM_OPEN_SESSION: case SSS_PAM_CLOSE_SESSION: pd->pam_status = PAM_SUCCESS; dp_err = DP_ERR_OK; goto done; break; default: DEBUG(SSSDBG_CONF_SETTINGS, "krb5 does not handles pam task %d.\n", pd->cmd); pd->pam_status = PAM_MODULE_UNKNOWN; dp_err = DP_ERR_OK; goto done; } return; done: be_req_terminate(be_req, dp_err, pd->pam_status, NULL); } void krb5_pam_handler_auth_done(struct tevent_req *req) { int ret; struct be_req *be_req = tevent_req_callback_data(req, struct be_req); int pam_status; int dp_err; struct pam_data *pd; pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); ret = krb5_auth_queue_recv(req, &pam_status, &dp_err); talloc_zfree(req); if (ret) { pd->pam_status = PAM_SYSTEM_ERR; dp_err = DP_ERR_OK; } else { pd->pam_status = pam_status; } be_req_terminate(be_req, dp_err, pd->pam_status, NULL); } static void krb5_pam_handler_access_done(struct tevent_req *req) { int ret; struct be_req *be_req = tevent_req_callback_data(req, struct be_req); bool access_allowed; struct pam_data *pd; int dp_err = DP_ERR_OK; pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); pd->pam_status = PAM_SYSTEM_ERR; ret = krb5_access_recv(req, &access_allowed); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_access request failed [%d][%s]\n", ret, strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Access %s for user [%s].\n", access_allowed ? "allowed" : "denied", pd->user); pd->pam_status = access_allowed ? PAM_SUCCESS : PAM_PERM_DENIED; dp_err = DP_ERR_OK; done: be_req_terminate(be_req, dp_err, pd->pam_status, NULL); } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_utils.h0000644000000000000000000000007412703456111020230 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.541793246 sssd-1.13.4/src/providers/krb5/krb5_utils.h0000644002412700241270000000400712703456111021700 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos Backend, header file for utilities Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __KRB5_UTILS_H__ #define __KRB5_UTILS_H__ #include #include "config.h" #include "providers/krb5/krb5_auth.h" #include "providers/data_provider.h" errno_t find_or_guess_upn(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct krb5_ctx *krb5_ctx, struct sss_domain_info *dom, const char *user, const char *user_dom, char **_upn); errno_t check_if_cached_upn_needs_update(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *user, const char *upn); char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr, const char *template, pcre *illegal_re, bool file_mode, bool case_sensitive); errno_t get_domain_or_subdomain(struct be_ctx *be_ctx, char *domain_name, struct sss_domain_info **dom); errno_t parse_krb5_map_user(TALLOC_CTX *mem_ctx, const char *krb5_map_user, struct map_id_name_to_krb_primary **_name_to_primary); #endif /* __KRB5_UTILS_H__ */ sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_keytab.c0000644000000000000000000000007412703456111020342 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.939794595 sssd-1.13.4/src/providers/krb5/krb5_keytab.c0000644002412700241270000001641712703456111022022 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module -- keytab related utilities Authors: Sumit Bose Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/sss_krb5.h" #include "providers/krb5/krb5_common.h" static krb5_error_code do_keytab_copy(krb5_context kctx, krb5_keytab s_keytab, krb5_keytab d_keytab) { krb5_error_code kerr; krb5_error_code kt_err; krb5_kt_cursor cursor; krb5_keytab_entry entry; memset(&cursor, 0, sizeof(cursor)); kerr = krb5_kt_start_seq_get(kctx, s_keytab, &cursor); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab.\n"); return kerr; } memset(&entry, 0, sizeof(entry)); while ((kt_err = krb5_kt_next_entry(kctx, s_keytab, &entry, &cursor)) == 0) { kerr = krb5_kt_add_entry(kctx, d_keytab, &entry); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_kt_add_entry failed.\n"); kt_err = krb5_kt_end_seq_get(kctx, s_keytab, &cursor); if (kt_err != 0) { DEBUG(SSSDBG_TRACE_ALL, "krb5_kt_end_seq_get failed with [%d], ignored.\n", kt_err); } return kerr; } kerr = sss_krb5_free_keytab_entry_contents(kctx, &entry); if (kerr != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to free keytab entry.\n"); kt_err = krb5_kt_end_seq_get(kctx, s_keytab, &cursor); if (kt_err != 0) { DEBUG(SSSDBG_TRACE_ALL, "krb5_kt_end_seq_get failed with [%d], ignored.\n", kt_err); } return kerr; } memset(&entry, 0, sizeof(entry)); } kerr = krb5_kt_end_seq_get(kctx, s_keytab, &cursor); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_end_seq_get failed.\n"); return kerr; } /* check if we got any errors from krb5_kt_next_entry */ if (kt_err != 0 && kt_err != KRB5_KT_END) { DEBUG(SSSDBG_CRIT_FAILURE, "error reading keytab.\n"); return kt_err; } return 0; } krb5_error_code copy_keytab_into_memory(TALLOC_CTX *mem_ctx, krb5_context kctx, const char *inp_keytab_file, char **_mem_name, krb5_keytab *_mem_keytab) { krb5_error_code kerr; krb5_keytab keytab = NULL; krb5_keytab mem_keytab = NULL; krb5_keytab tmp_mem_keytab = NULL; char keytab_name[MAX_KEYTAB_NAME_LEN]; char *sep; char *mem_name = NULL; char *tmp_mem_name = NULL; const char *keytab_file; char default_keytab_name[MAX_KEYTAB_NAME_LEN]; keytab_file = inp_keytab_file; if (keytab_file == NULL) { kerr = krb5_kt_default_name(kctx, default_keytab_name, sizeof(default_keytab_name)); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_default_name failed.\n"); return kerr; } keytab_file = default_keytab_name; } kerr = krb5_kt_resolve(kctx, keytab_file, &keytab); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s].\n", keytab_file); return kerr; } kerr = sss_krb5_kt_have_content(kctx, keytab); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "keytab [%s] has not entries.\n", keytab_file); goto done; } kerr = krb5_kt_get_name(kctx, keytab, keytab_name, sizeof(keytab_name)); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read name for keytab [%s].\n", keytab_file); goto done; } sep = strchr(keytab_name, ':'); if (sep == NULL || sep[1] == '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Keytab name [%s] does not have delimiter[:] .\n", keytab_name); kerr = KRB5KRB_ERR_GENERIC; goto done; } if (strncmp(keytab_name, "MEMORY:", sizeof("MEMORY:") -1) == 0) { DEBUG(SSSDBG_TRACE_FUNC, "Keytab [%s] is already memory keytab.\n", keytab_name); *_mem_name = talloc_strdup(mem_ctx, keytab_name); if(*_mem_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); kerr = KRB5KRB_ERR_GENERIC; goto done; } kerr = 0; goto done; } mem_name = talloc_asprintf(mem_ctx, "MEMORY:%s", sep + 1); if (mem_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); kerr = KRB5KRB_ERR_GENERIC; goto done; } tmp_mem_name = talloc_asprintf(mem_ctx, "MEMORY:%s.tmp", sep + 1); if (tmp_mem_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); kerr = KRB5KRB_ERR_GENERIC; goto done; } kerr = krb5_kt_resolve(kctx, mem_name, &mem_keytab); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s].\n", mem_name); goto done; } kerr = krb5_kt_resolve(kctx, tmp_mem_name, &tmp_mem_keytab); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "error resolving keytab [%s].\n", tmp_mem_name); goto done; } kerr = do_keytab_copy(kctx, keytab, tmp_mem_keytab); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy keytab [%s] into [%s].\n", keytab_file, tmp_mem_name); goto done; } /* krb5_kt_add_entry() adds new entries into MEMORY keytabs at the * beginning and not at the end as for FILE keytabs. Since we want to keep * the processing order we have to copy the MEMORY keytab again to retain * the order from the FILE keytab. */ kerr = do_keytab_copy(kctx, tmp_mem_keytab, mem_keytab); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy keytab [%s] into [%s].\n", tmp_mem_name, mem_name); goto done; } *_mem_name = mem_name; if (_mem_keytab != NULL) { *_mem_keytab = mem_keytab; } kerr = 0; done: talloc_free(tmp_mem_name); if (kerr != 0) { talloc_free(mem_name); } if (tmp_mem_keytab != NULL && krb5_kt_close(kctx, tmp_mem_keytab) != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_close failed.\n"); } if (keytab != NULL && krb5_kt_close(kctx, keytab) != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "krb5_kt_close failed.\n"); } return kerr; } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_auth.h0000644000000000000000000000007412703456111020031 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.538793235 sssd-1.13.4/src/providers/krb5/krb5_auth.h0000644002412700241270000001123112703456111021476 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos Backend, private header file Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __KRB5_AUTH_H__ #define __KRB5_AUTH_H__ #include #include "util/sss_krb5.h" #include "providers/dp_backend.h" #include "util/child_common.h" #include "providers/krb5/krb5_common.h" #include "providers/krb5/krb5_ccache.h" #define CCACHE_ENV_NAME "KRB5CCNAME" #define ILLEGAL_PATH_PATTERN "//|/\\./|/\\.\\./" struct krb5child_req { struct pam_data *pd; struct krb5_ctx *krb5_ctx; const char *ccname; const char *old_ccname; const char *homedir; char *upn; uid_t uid; gid_t gid; bool is_offline; struct fo_server *srv; struct fo_server *kpasswd_srv; bool active_ccache; bool valid_tgt; bool upn_from_different_realm; bool send_pac; const char *user; }; errno_t krb5_setup(TALLOC_CTX *mem_ctx, struct pam_data *pd, struct krb5_ctx *krb5_ctx, bool case_sensitive, struct krb5child_req **krb5_req); void krb5_pam_handler(struct be_req *be_req); void krb5_pam_handler_auth_done(struct tevent_req *req); /* Please use krb5_auth_send/recv *only* if you're certain there can't * be concurrent logins happening. With some ccache back ends, the ccache * files might clobber one another. Please use krb5_auth_queue_send() * instead that queues the requests */ struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct pam_data *pd, struct krb5_ctx *krb5_ctx); int krb5_auth_recv(struct tevent_req *req, int *pam_status, int *dp_err); struct tevent_req *handle_child_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct krb5child_req *kr); int handle_child_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **buf, ssize_t *len); struct krb5_child_response { int32_t msg_status; struct tgt_times tgtt; char *ccname; char *correct_upn; bool otp; }; errno_t parse_krb5_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, ssize_t len, struct pam_data *pd, int pwd_exp_warning, struct krb5_child_response **_res); errno_t add_user_to_delayed_online_authentication(struct krb5_ctx *krb5_ctx, struct pam_data *pd, uid_t uid); errno_t init_delayed_online_authentication(struct krb5_ctx *krb5_ctx, struct be_ctx *be_ctx, struct tevent_context *ev); errno_t init_renew_tgt(struct krb5_ctx *krb5_ctx, struct be_ctx *be_ctx, struct tevent_context *ev, time_t renew_intv); errno_t add_tgt_to_renew_table(struct krb5_ctx *krb5_ctx, const char *ccfile, struct tgt_times *tgtt, struct pam_data *pd, const char *upn); /* krb5_access.c */ struct tevent_req *krb5_access_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct pam_data *pd, struct krb5_ctx *krb5_ctx); int krb5_access_recv(struct tevent_req *req, bool *access_allowed); /* krb5_wait_queue.c */ struct tevent_req *krb5_auth_queue_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct pam_data *pd, struct krb5_ctx *krb5_ctx); int krb5_auth_queue_recv(struct tevent_req *req, int *_pam_status, int *_dp_err); #endif /* __KRB5_AUTH_H__ */ sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_opts.c0000644000000000000000000000007412703456111020050 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.761793992 sssd-1.13.4/src/providers/krb5/krb5_opts.c0000644002412700241270000000434212703456111021522 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "src/providers/data_provider.h" struct dp_option default_krb5_opts[] = { { "krb5_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_ccachedir", DP_OPT_STRING, { DEFAULT_CCACHE_DIR }, NULL_STRING }, { "krb5_ccname_template", DP_OPT_STRING, NULL_STRING, NULL_STRING}, { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, { "krb5_keytab", DP_OPT_STRING, { "/etc/krb5.keytab" }, NULL_STRING }, { "krb5_validate", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "krb5_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_backup_kpasswd", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_store_password_if_offline", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "krb5_renewable_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_lifetime", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_renew_interval", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_use_fast", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_fast_principal", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "krb5_use_enterprise_principal", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "krb5_use_kdcinfo", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "krb5_map_user", DP_OPT_STRING, NULL_STRING, NULL_STRING }, DP_OPTION_TERMINATOR }; sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_access.c0000644000000000000000000000007412703456111020324 xustar0030 atime=1460561751.646715613 30 ctime=1460561774.762793995 sssd-1.13.4/src/providers/krb5/krb5_access.c0000644002412700241270000001370412703456111022000 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module - access control Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "providers/krb5/krb5_auth.h" #include "providers/krb5/krb5_common.h" #include "providers/krb5/krb5_utils.h" struct krb5_access_state { struct tevent_context *ev; struct be_ctx *be_ctx; struct pam_data *pd; struct krb5_ctx *krb5_ctx; struct krb5child_req *kr; bool access_allowed; }; static void krb5_access_done(struct tevent_req *subreq); struct tevent_req *krb5_access_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct pam_data *pd, struct krb5_ctx *krb5_ctx) { struct krb5_access_state *state; struct tevent_req *req; struct tevent_req *subreq; int ret; const char **attrs; struct ldb_result *res; req = tevent_req_create(mem_ctx, &state, struct krb5_access_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->ev = ev; state->be_ctx = be_ctx; state->pd = pd; state->krb5_ctx = krb5_ctx; state->access_allowed = false; ret = krb5_setup(state, pd, krb5_ctx, be_ctx->domain->case_sensitive, &state->kr); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_setup failed.\n"); goto done; } if (pd->cmd != SSS_PAM_ACCT_MGMT) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected pam task.\n"); ret = EINVAL; goto done; } attrs = talloc_array(state, const char *, 5); if (attrs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } attrs[0] = SYSDB_UPN; attrs[1] = SYSDB_UIDNUM; attrs[2] = SYSDB_GIDNUM; attrs[3] = SYSDB_CANONICAL_UPN; attrs[4] = NULL; ret = sysdb_get_user_attr(state, be_ctx->domain, state->pd->user, attrs, &res); if (ret) { DEBUG(SSSDBG_FUNC_DATA, "sysdb search for upn of user [%s] failed.\n", pd->user); goto done; } switch (res->count) { case 0: DEBUG(SSSDBG_FUNC_DATA, "No attributes for user [%s] found.\n", pd->user); ret = ENOENT; goto done; break; case 1: ret = find_or_guess_upn(state, res->msgs[0], krb5_ctx, be_ctx->domain, state->kr->user, pd->domain, &state->kr->upn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "find_or_guess_upn failed.\n"); goto done; } state->kr->uid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM, 0); if (state->kr->uid == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "UID for user [%s] not known.\n", pd->user); ret = ENOENT; goto done; } state->kr->gid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GIDNUM, 0); if (state->kr->gid == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "GID for user [%s] not known.\n", pd->user); ret = ENOENT; goto done; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "User search for [%s] returned > 1 results!\n", pd->user); ret = EINVAL; goto done; break; } subreq = handle_child_send(state, state->ev, state->kr); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "handle_child_send failed.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, krb5_access_done, req); return req; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, state->ev); return req; } static void krb5_access_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct krb5_access_state *state = tevent_req_data(req, struct krb5_access_state); int ret; uint8_t *buf = NULL; ssize_t len = -1; int32_t msg_status; ret = handle_child_recv(subreq, state, &buf, &len); talloc_free(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "child failed [%d][%s].\n", ret, strerror(ret)); goto fail; } if ((size_t) len != sizeof(int32_t)) { DEBUG(SSSDBG_CRIT_FAILURE, "message has the wrong size.\n"); ret = EINVAL; goto fail; } SAFEALIGN_COPY_INT32(&msg_status, buf, NULL); if (msg_status == EOK) { state->access_allowed = true; } else { state->access_allowed = false; } tevent_req_done(req); return; fail: tevent_req_error(req, ret); return; } int krb5_access_recv(struct tevent_req *req, bool *access_allowed) { struct krb5_access_state *state = tevent_req_data(req, struct krb5_access_state); TEVENT_REQ_RETURN_ON_ERROR(req); *access_allowed = state->access_allowed; return EOK; } sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_opts.h0000644000000000000000000000007412703456111020055 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.544793256 sssd-1.13.4/src/providers/krb5/krb5_opts.h0000644002412700241270000000163012703456111021524 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef KRB5_OPTS_H_ #define KRB5_OPTS_H_ #include "src/providers/data_provider.h" extern struct dp_option default_krb5_opts[]; #endif /* KRB5_OPTS_H_ */ sssd-1.13.4/src/providers/krb5/PaxHeaders.16287/krb5_init.c0000644000000000000000000000007412703456111020026 xustar0030 atime=1460561751.647715617 30 ctime=1460561774.756793975 sssd-1.13.4/src/providers/krb5/krb5_init.c0000644002412700241270000001464412703456111021506 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/child_common.h" #include "providers/krb5/krb5_auth.h" #include "providers/krb5/krb5_common.h" #include "providers/krb5/krb5_init_shared.h" struct krb5_options { struct dp_option *opts; struct krb5_ctx *auth_ctx; }; struct krb5_options *krb5_options = NULL; struct bet_ops krb5_auth_ops = { .handler = krb5_pam_handler, .finalize = NULL, }; int krb5_ctx_re_destructor(void *memctx) { struct krb5_ctx *ctx = (struct krb5_ctx *) memctx; if (ctx->illegal_path_re) { pcre_free(ctx->illegal_path_re); ctx->illegal_path_re = NULL; } return 0; } int sssm_krb5_auth_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_auth_data) { struct krb5_ctx *ctx = NULL; int ret; const char *krb5_servers; const char *krb5_backup_servers; const char *krb5_kpasswd_servers; const char *krb5_backup_kpasswd_servers; const char *krb5_realm; const char *errstr; int errval; int errpos; if (krb5_options == NULL) { krb5_options = talloc_zero(bectx, struct krb5_options); if (krb5_options == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ret = krb5_get_options(krb5_options, bectx->cdb, bectx->conf_path, &krb5_options->opts); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_get_options failed.\n"); return ret; } } if (krb5_options->auth_ctx != NULL) { *ops = &krb5_auth_ops; *pvt_auth_data = krb5_options->auth_ctx; return EOK; } ctx = talloc_zero(bectx, struct krb5_ctx); if (!ctx) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); return ENOMEM; } krb5_options->auth_ctx = ctx; ctx->action = INIT_PW; ctx->opts = krb5_options->opts; ctx->config_type = K5C_GENERIC; krb5_servers = dp_opt_get_string(ctx->opts, KRB5_KDC); krb5_backup_servers = dp_opt_get_string(ctx->opts, KRB5_BACKUP_KDC); krb5_realm = dp_opt_get_string(ctx->opts, KRB5_REALM); if (krb5_realm == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Missing krb5_realm option!\n"); return EINVAL; } ret = krb5_service_init(ctx, bectx, SSS_KRB5KDC_FO_SRV, krb5_servers, krb5_backup_servers, krb5_realm, dp_opt_get_bool(krb5_options->opts, KRB5_USE_KDCINFO), &ctx->service); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init KRB5 failover service!\n"); return ret; } krb5_kpasswd_servers = dp_opt_get_string(ctx->opts, KRB5_KPASSWD); krb5_backup_kpasswd_servers = dp_opt_get_string(ctx->opts, KRB5_BACKUP_KPASSWD); if (krb5_kpasswd_servers == NULL && krb5_backup_kpasswd_servers != NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "kpasswd server wasn't specified but " "backup kpasswd given. Using it as primary\n"); krb5_kpasswd_servers = krb5_backup_kpasswd_servers; krb5_backup_kpasswd_servers = NULL; } if (krb5_kpasswd_servers == NULL && krb5_servers != NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Missing krb5_kpasswd option and KDC set explicitly, " "will use KDC for pasword change operations!\n"); ctx->kpasswd_service = NULL; } else { ret = krb5_service_init(ctx, bectx, SSS_KRB5KPASSWD_FO_SRV, krb5_kpasswd_servers, krb5_backup_kpasswd_servers, krb5_realm, dp_opt_get_bool(krb5_options->opts, KRB5_USE_KDCINFO), &ctx->kpasswd_service); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init KRB5KPASSWD failover service!\n"); return ret; } } /* Initialize features needed by the krb5_child */ ret = krb5_child_init(ctx, bectx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize krb5_child settings: [%s]\n", strerror(ret)); goto fail; } ctx->illegal_path_re = pcre_compile2(ILLEGAL_PATH_PATTERN, 0, &errval, &errstr, &errpos, NULL); if (ctx->illegal_path_re == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid Regular Expression pattern at position %d. " "(Error: %d [%s])\n", errpos, errval, errstr); ret = EFAULT; goto fail; } talloc_set_destructor((TALLOC_CTX *) ctx, krb5_ctx_re_destructor); ret = be_fo_set_dns_srv_lookup_plugin(bectx, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin " "[%d]: %s\n", ret, sss_strerror(ret)); goto fail; } *ops = &krb5_auth_ops; *pvt_auth_data = ctx; return EOK; fail: talloc_zfree(krb5_options->auth_ctx); return ret; } int sssm_krb5_chpass_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_auth_data) { return sssm_krb5_auth_init(bectx, ops, pvt_auth_data); } int sssm_krb5_access_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_auth_data) { return sssm_krb5_auth_init(bectx, ops, pvt_auth_data); } sssd-1.13.4/src/providers/PaxHeaders.16287/dp_auth_util.c0000644000000000000000000000007412703456111017756 xustar0030 atime=1460561751.644715607 30 ctime=1460561774.842794266 sssd-1.13.4/src/providers/dp_auth_util.c0000644002412700241270000003426312703456111021435 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider, auth utils Copyright (C) Sumit Bose 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "data_provider.h" bool dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd) { dbus_bool_t db_ret; const char *service; const char *tty; const char *ruser; const char *rhost; uint32_t authtok_type; int authtok_length; uint8_t *authtok_data; uint32_t new_authtok_type; int new_authtok_length; uint8_t *new_authtok_data; int32_t pd_priv; int32_t pd_cmd; if (pd->user == NULL) return false; service = pd->service ? pd->service : ""; tty = pd->tty ? pd->tty : ""; ruser = pd->ruser ? pd->ruser : ""; rhost = pd->rhost ? pd->rhost : ""; authtok_type = (uint32_t)sss_authtok_get_type(pd->authtok); authtok_data = sss_authtok_get_data(pd->authtok); authtok_length = sss_authtok_get_size(pd->authtok); new_authtok_type = (uint32_t)sss_authtok_get_type(pd->newauthtok); new_authtok_data = sss_authtok_get_data(pd->newauthtok); new_authtok_length = sss_authtok_get_size(pd->newauthtok); pd_priv = pd->priv; pd_cmd = pd->cmd; db_ret = dbus_message_append_args(msg, DBUS_TYPE_INT32, &pd_cmd, DBUS_TYPE_STRING, &(pd->user), DBUS_TYPE_STRING, &(pd->domain), DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &tty, DBUS_TYPE_STRING, &ruser, DBUS_TYPE_STRING, &rhost, DBUS_TYPE_UINT32, &authtok_type, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &authtok_data, authtok_length, DBUS_TYPE_UINT32, &new_authtok_type, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &new_authtok_data, new_authtok_length, DBUS_TYPE_INT32, &pd_priv, DBUS_TYPE_UINT32, &(pd->cli_pid), DBUS_TYPE_INVALID); return db_ret; } bool dp_unpack_pam_request(DBusMessage *msg, TALLOC_CTX *mem_ctx, struct pam_data **new_pd, DBusError *dbus_error) { dbus_bool_t db_ret; int ret; struct pam_data pd; uint32_t authtok_type; int authtok_length; uint8_t *authtok_data; uint32_t new_authtok_type; int new_authtok_length; uint8_t *new_authtok_data; int32_t pd_cmd; int32_t pd_priv; memset(&pd, 0, sizeof(pd)); db_ret = dbus_message_get_args(msg, dbus_error, DBUS_TYPE_INT32, &pd_cmd, DBUS_TYPE_STRING, &(pd.user), DBUS_TYPE_STRING, &(pd.domain), DBUS_TYPE_STRING, &(pd.service), DBUS_TYPE_STRING, &(pd.tty), DBUS_TYPE_STRING, &(pd.ruser), DBUS_TYPE_STRING, &(pd.rhost), DBUS_TYPE_UINT32, &authtok_type, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &authtok_data, &authtok_length, DBUS_TYPE_UINT32, &new_authtok_type, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &new_authtok_data, &new_authtok_length, DBUS_TYPE_INT32, &pd_priv, DBUS_TYPE_UINT32, &(pd.cli_pid), DBUS_TYPE_INVALID); if (!db_ret) { DEBUG(SSSDBG_CRIT_FAILURE, "dbus_message_get_args failed.\n"); return false; } pd.cmd = pd_cmd; pd.priv = pd_priv; ret = copy_pam_data(mem_ctx, &pd, new_pd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "copy_pam_data failed.\n"); return false; } ret = sss_authtok_set((*new_pd)->authtok, authtok_type, authtok_data, authtok_length); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set auth token: %d [%s]\n", ret, strerror(ret)); return false; } ret = sss_authtok_set((*new_pd)->newauthtok, new_authtok_type, new_authtok_data, new_authtok_length); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set auth token: %d [%s]\n", ret, strerror(ret)); return false; } return true; } bool dp_pack_pam_response(DBusMessage *msg, struct pam_data *pd) { dbus_bool_t dbret; struct response_data *resp; DBusMessageIter iter; DBusMessageIter array_iter; DBusMessageIter struct_iter; DBusMessageIter data_iter; uint32_t pam_status; uint32_t resp_type; dbus_message_iter_init_append(msg, &iter); /* Append the PAM status */ pam_status = pd->pam_status; dbret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &pam_status); if (!dbret) { return false; } /* Append the lockout of account */ dbret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &pd->account_locked); if (!dbret) { return false; } /* Create an array of response structures */ dbret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(uay)", &array_iter); if (!dbret) { return false; } resp = pd->resp_list; while (resp != NULL) { /* Create a DBUS struct */ dbret = dbus_message_iter_open_container(&array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter); if (!dbret) { return false; } /* Add the response type */ resp_type = resp->type; dbret = dbus_message_iter_append_basic(&struct_iter, DBUS_TYPE_UINT32, &resp_type); if (!dbret) { return false; } /* Add the response message */ dbret = dbus_message_iter_open_container(&struct_iter, DBUS_TYPE_ARRAY, "y", &data_iter); if (!dbret) { return false; } dbret = dbus_message_iter_append_fixed_array(&data_iter, DBUS_TYPE_BYTE, &(resp->data), resp->len); if (!dbret) { return false; } dbret = dbus_message_iter_close_container(&struct_iter, &data_iter); if (!dbret) { return false; } resp = resp->next; dbret = dbus_message_iter_close_container(&array_iter, &struct_iter); if (!dbret) { return false; } } /* Close the struct array */ dbret = dbus_message_iter_close_container(&iter, &array_iter); if (!dbret) { return false; } return true; } bool dp_unpack_pam_response(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error) { DBusMessageIter iter; DBusMessageIter array_iter; DBusMessageIter struct_iter; DBusMessageIter sub_iter; int type; int len; const uint8_t *data; if (!dbus_message_iter_init(msg, &iter)) { DEBUG(SSSDBG_CRIT_FAILURE, "pam response has no arguments.\n"); return false; } if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) { DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n"); return false; } dbus_message_iter_get_basic(&iter, &(pd->pam_status)); if (!dbus_message_iter_next(&iter)) { DEBUG(SSSDBG_CRIT_FAILURE, "pam response has too few arguments.\n"); return false; } if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) { DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n"); return false; } dbus_message_iter_get_basic(&iter, &(pd->account_locked)); if (!dbus_message_iter_next(&iter)) { DEBUG(SSSDBG_CRIT_FAILURE, "pam response has too few arguments.\n"); return false; } /* After this point will be an array of pam data */ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n"); DEBUG(SSSDBG_CRIT_FAILURE, "Type was %c\n", (char)dbus_message_iter_get_arg_type(&iter)); return false; } if (dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) { DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n"); return false; } dbus_message_iter_recurse(&iter, &array_iter); while (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID) { /* Read in a pam data struct */ if (dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_STRUCT) { DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n"); return false; } dbus_message_iter_recurse(&array_iter, &struct_iter); /* PAM data struct contains a type and a byte-array of data */ /* Get the pam data type */ if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_UINT32) { DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n"); return false; } dbus_message_iter_get_basic(&struct_iter, &type); if (!dbus_message_iter_next(&struct_iter)) { DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n"); return false; } /* Get the byte array */ if (dbus_message_iter_get_arg_type(&struct_iter) != DBUS_TYPE_ARRAY || dbus_message_iter_get_element_type(&struct_iter) != DBUS_TYPE_BYTE) { DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n"); return false; } dbus_message_iter_recurse(&struct_iter, &sub_iter); dbus_message_iter_get_fixed_array(&sub_iter, &data, &len); if (pam_add_response(pd, type, len, data) != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); return false; } dbus_message_iter_next(&array_iter); } return true; } void dp_id_callback(DBusPendingCall *pending, void *ptr) { DBusMessage *reply; DBusError dbus_error; dbus_bool_t ret; dbus_uint16_t dp_ver; int type; dbus_error_init(&dbus_error); reply = dbus_pending_call_steal_reply(pending); if (!reply) { /* reply should never be null. This function shouldn't be called * until reply is valid or timeout has occurred. If reply is NULL * here, something is seriously wrong and we should bail out. */ DEBUG(SSSDBG_FATAL_FAILURE, "Severe error. A reply callback was called but no" " reply was received and no timeout occurred\n"); /* FIXME: Destroy this connection ? */ goto done; } type = dbus_message_get_type(reply); switch (type) { case DBUS_MESSAGE_TYPE_METHOD_RETURN: ret = dbus_message_get_args(reply, &dbus_error, DBUS_TYPE_UINT16, &dp_ver, DBUS_TYPE_INVALID); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse message\n"); if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); /* FIXME: Destroy this connection ? */ goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Got id ack and version (%d) from DP\n", dp_ver); break; case DBUS_MESSAGE_TYPE_ERROR: DEBUG(SSSDBG_FATAL_FAILURE,"The Monitor returned an error [%s]\n", dbus_message_get_error_name(reply)); /* Falling through to default intentionally*/ default: /* * Timeout or other error occurred or something * unexpected happened. * It doesn't matter which, because either way we * know that this connection isn't trustworthy. * We'll destroy it now. */ /* FIXME: Destroy this connection ? */ break; } done: dbus_pending_call_unref(pending); dbus_message_unref(reply); } int dp_common_send_id(struct sbus_connection *conn, uint16_t version, const char *name) { DBusMessage *msg; dbus_bool_t ret; int retval; /* create the message */ msg = dbus_message_new_method_call(NULL, DP_PATH, DATA_PROVIDER_IFACE, DATA_PROVIDER_IFACE_REGISTERSERVICE); if (msg == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?!\n"); return ENOMEM; } DEBUG(SSSDBG_CONF_SETTINGS, "Sending ID to DP: (%d,%s)\n", version, name); ret = dbus_message_append_args(msg, DBUS_TYPE_UINT16, &version, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n"); return EIO; } retval = sbus_conn_send(conn, msg, 30000, dp_id_callback, NULL, NULL); dbus_message_unref(msg); return retval; } sssd-1.13.4/src/PaxHeaders.16287/resolv0000644000000000000000000000013212703463556014357 xustar0030 mtime=1460561774.667793673 30 atime=1460561776.118798593 30 ctime=1460561774.667793673 sssd-1.13.4/src/resolv/0000755002412700241270000000000012703463556016110 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/resolv/PaxHeaders.16287/async_resolv_utils.c0000644000000000000000000000007412703456111020521 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.667793673 sssd-1.13.4/src/resolv/async_resolv_utils.c0000644002412700241270000002312512703456111022173 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "resolv/async_resolv.h" struct resolv_get_domain_state { char *fqdn; char *hostname; }; static void resolv_get_domain_done(struct tevent_req *subreq); struct tevent_req * resolv_get_domain_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv_ctx, const char *hostname, enum host_database *host_dbs, enum restrict_family family_order) { struct resolv_get_domain_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; char system_hostname[HOST_NAME_MAX + 1]; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct resolv_get_domain_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } if (hostname == NULL) { /* use system hostname */ ret = gethostname(system_hostname, HOST_NAME_MAX); if (ret) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "gethostname() failed: [%d]: %s\n", ret, strerror(ret)); goto immediately; } system_hostname[HOST_NAME_MAX] = '\0'; hostname = system_hostname; } state->fqdn = NULL; state->hostname = talloc_strdup(state, hostname); if (state->hostname == NULL) { ret = ENOMEM; goto immediately; } DEBUG(SSSDBG_TRACE_LIBS, "Host name is: %s\n", state->hostname); subreq = resolv_gethostbyname_send(state, ev, resolv_ctx, state->hostname, family_order, host_dbs); if (subreq == NULL) { talloc_zfree(req); return NULL; } tevent_req_set_callback(subreq, resolv_get_domain_done, req); return req; immediately: tevent_req_error(req, ret); tevent_req_post(req, ev); return req; } static void resolv_get_domain_done(struct tevent_req *subreq) { struct resolv_get_domain_state *state = NULL; struct tevent_req *req = NULL; struct resolv_hostent *rhostent; int resolv_status; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct resolv_get_domain_state); ret = resolv_gethostbyname_recv(subreq, req, &resolv_status, NULL, &rhostent); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not get fully qualified name for host name %s " "error [%d]: %s, resolver returned: [%d]: %s\n", state->hostname, ret, strerror(ret), resolv_status, resolv_strerror(resolv_status)); state->fqdn = state->hostname; } else { DEBUG(SSSDBG_TRACE_LIBS, "The FQDN is: %s\n", rhostent->name); state->fqdn = talloc_steal(state, rhostent->name); talloc_zfree(rhostent); } tevent_req_done(req); } errno_t resolv_get_domain_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain) { struct resolv_get_domain_state *state = NULL; char *dns_domain = NULL; char *domptr = NULL; state = tevent_req_data(req, struct resolv_get_domain_state); TEVENT_REQ_RETURN_ON_ERROR(req); domptr = strchr(state->fqdn, '.'); if (domptr == NULL || (*(domptr+1) == '\0')) { /* If the FQDN did not contain a dot or the dot was the last character * (broken DNS server perhaps) */ dns_domain = state->fqdn; } else { dns_domain = domptr + 1; } *_dns_domain = talloc_strdup(mem_ctx, dns_domain); if (*_dns_domain == NULL) { return ENOMEM; } return EOK; } struct resolv_discover_srv_state { struct tevent_context *ev; struct resolv_ctx *resolv_ctx; const char *service; const char *protocol; const char **discovery_domains; int domain_index; struct ares_srv_reply *reply_list; uint32_t ttl; }; static errno_t resolv_discover_srv_next_domain(struct tevent_req *req); static void resolv_discover_srv_done(struct tevent_req *subreq); struct tevent_req *resolv_discover_srv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv_ctx, const char *service, const char *protocol, const char **discovery_domains) { struct resolv_discover_srv_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct resolv_discover_srv_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); return NULL; } if (resolv_ctx == NULL || service == NULL || protocol == NULL || discovery_domains == NULL) { ret = EINVAL; goto immediately; } state->ev = ev; state->resolv_ctx = resolv_ctx; state->discovery_domains = discovery_domains; state->service = service; state->protocol = protocol; state->domain_index = 0; ret = resolv_discover_srv_next_domain(req); if (ret != EAGAIN) { goto immediately; } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t resolv_discover_srv_next_domain(struct tevent_req *req) { struct resolv_discover_srv_state *state = NULL; struct tevent_req *subreq = NULL; const char *domain = NULL; char *query = NULL; errno_t ret; state = tevent_req_data(req, struct resolv_discover_srv_state); domain = state->discovery_domains[state->domain_index]; if (domain == NULL) { ret = EOK; goto done; } query = talloc_asprintf(state, "_%s._%s.%s", state->service, state->protocol, domain); if (query == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "SRV resolution of service '%s'. Will use DNS " "discovery domain '%s'\n", state->service, domain); subreq = resolv_getsrv_send(state, state->ev, state->resolv_ctx, query); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, resolv_discover_srv_done, req); state->domain_index++; ret = EAGAIN; done: if (ret != EAGAIN) { talloc_free(query); } return ret; } static void resolv_discover_srv_done(struct tevent_req *subreq) { struct resolv_discover_srv_state *state = NULL; struct tevent_req *req = NULL; int status; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct resolv_discover_srv_state); ret = resolv_getsrv_recv(state, subreq, &status, NULL, &state->reply_list, &state->ttl); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "SRV query failed [%d]: %s\n", status, resolv_strerror(status)); if (status == ARES_ENOTFOUND) { /* continue with next discovery domain */ ret = resolv_discover_srv_next_domain(req); if (ret == EOK) { /* there are no more domains to try */ ret = ENOENT; } goto done; } /* critical error when fetching SRV record */ ret = EIO; goto done; } done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } errno_t resolv_discover_srv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ares_srv_reply **_reply_list, uint32_t *_ttl, char **_dns_domain) { struct resolv_discover_srv_state *state = NULL; char *domain = NULL; state = tevent_req_data(req, struct resolv_discover_srv_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_dns_domain != NULL) { /* domain_index now points to selected domain + 1 */ domain = talloc_strdup(mem_ctx, state->discovery_domains[state->domain_index - 1]); if (domain == NULL) { return ENOMEM; } *_dns_domain = domain; } if (_reply_list != NULL) { *_reply_list = talloc_steal(mem_ctx, state->reply_list); } if (_ttl != NULL) { *_ttl = state->ttl; } return EOK; } sssd-1.13.4/src/resolv/PaxHeaders.16287/async_resolv.h0000644000000000000000000000007412703456111017306 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.582793385 sssd-1.13.4/src/resolv/async_resolv.h0000644002412700241270000001433212703456111020760 0ustar00jhrozekjhrozek00000000000000/* SSSD Async resolver header Authors: Martin Nagy Jakub Hrozek Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __ASYNC_RESOLV_H__ #define __ASYNC_RESOLV_H__ #include #include #include "config.h" #include "confdb/confdb.h" #ifndef RESOLV_DEFAULT_TTL #define RESOLV_DEFAULT_TTL 7200 #endif /* RESOLV_DEFAULT_TTL */ #ifndef RESOLV_DEFAULT_SRV_TTL #define RESOLV_DEFAULT_SRV_TTL 14400 #endif /* RESOLV_DEFAULT_SRV_TTL */ #include "util/util.h" /* * An opaque structure which holds context for a module using the async * resolver. Is should be used as a "local-global" variable - in sssd, * every backend should have its own. * Do NOT free the context until there are any pending resolv_ calls */ struct resolv_ctx; int resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, int timeout, struct resolv_ctx **ctxp); void resolv_reread_configuration(struct resolv_ctx *ctx); const char *resolv_strerror(int ares_code); struct resolv_hostent * resolv_copy_hostent(TALLOC_CTX *mem_ctx, struct hostent *src); struct resolv_hostent * resolv_copy_hostent_ares(TALLOC_CTX *mem_ctx, struct hostent *src, int family, void *ares_ttl_data, int num_ares_ttl_data); /** Get host by name **/ enum host_database { DB_FILES, DB_DNS, DB_SENTINEL }; enum restrict_family { IPV4_ONLY, IPV4_FIRST, IPV6_ONLY, IPV6_FIRST }; /* If resolv_hostent->family is AF_INET, then ipaddr points to * struct in_addr, else if family is AF_INET6, ipaddr points to * struct in6_addr */ struct resolv_addr { uint8_t *ipaddr; int ttl; }; struct resolv_hostent { char *name; /* official name of host */ char **aliases; /* alias list */ int family; /* host address type */ struct resolv_addr **addr_list; /* list of addresses */ }; /* The default database order */ extern enum host_database default_host_dbs[]; struct tevent_req *resolv_gethostbyname_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *ctx, const char *name, enum restrict_family family_order, enum host_database *db); int resolv_gethostbyname_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, int *status, int *timeouts, struct resolv_hostent **rhostent); char * resolv_get_string_address_index(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent, unsigned int addrindex); char * resolv_get_string_ptr_address(TALLOC_CTX *mem_ctx, int family, uint8_t *address); #define resolv_get_string_address(mem_ctx, hostent) \ resolv_get_string_address_index(mem_ctx, hostent, 0) struct sockaddr_storage * resolv_get_sockaddr_address_index(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent, int port, int addrindex); #define resolv_get_sockaddr_address(mem_ctx, rhostent, port) \ resolv_get_sockaddr_address_index(mem_ctx, rhostent, port, 0) /** Get SRV record **/ struct tevent_req *resolv_getsrv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *ctx, const char *query); int resolv_getsrv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status, int *timeouts, struct ares_srv_reply **reply_list, uint32_t *ttl); /* This is an implementation of section "Usage rules" of RFC 2782 */ int resolv_sort_srv_reply(struct ares_srv_reply **reply); /** Get TXT record **/ struct tevent_req *resolv_gettxt_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *ctx, const char *query); int resolv_gettxt_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status, int *timeouts, struct ares_txt_reply **reply_list); /** Utils **/ struct tevent_req * resolv_get_domain_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv_ctx, const char *hostname, enum host_database *host_dbs, enum restrict_family family_order); errno_t resolv_get_domain_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain); struct tevent_req * resolv_discover_srv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv_ctx, const char *service, const char *protocol, const char **discovery_domains); errno_t resolv_discover_srv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ares_srv_reply **_reply_list, uint32_t *_ttl, char **_dns_domain); #endif /* __ASYNC_RESOLV_H__ */ sssd-1.13.4/src/resolv/PaxHeaders.16287/async_resolv.c0000644000000000000000000000007412703456111017301 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.666793669 sssd-1.13.4/src/resolv/async_resolv.c0000644002412700241270000017675612703456111020776 0ustar00jhrozekjhrozek00000000000000/* SSSD Async resolver Authors: Martin Nagy Jakub Hrozek Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "resolv/async_resolv.h" #include "util/dlinklist.h" #include "util/util.h" #define DNS__16BIT(p) (((p)[0] << 8) | (p)[1]) /* * Macro DNS__32BIT reads a network long (32 bit) given in network * byte order, and returns its value as an unsigned int. Copied * from c-ares source code. */ #define DNS__32BIT(p) ((unsigned int) \ (((unsigned int)((unsigned char)(p)[0]) << 24U) | \ ((unsigned int)((unsigned char)(p)[1]) << 16U) | \ ((unsigned int)((unsigned char)(p)[2]) << 8U) | \ ((unsigned int)((unsigned char)(p)[3])))) #define DNS_HEADER_ANCOUNT(h) DNS__16BIT((h) + 6) #define DNS_RR_LEN(r) DNS__16BIT((r) + 8) #define DNS_RR_TTL(r) DNS__32BIT((r) + 4) #define RESOLV_TIMEOUTMS 2000 enum host_database default_host_dbs[] = { DB_FILES, DB_DNS, DB_SENTINEL }; struct fd_watch { struct fd_watch *prev; struct fd_watch *next; int fd; struct resolv_ctx *ctx; struct tevent_fd *fde; }; struct resolv_ctx { struct tevent_context *ev_ctx; ares_channel channel; /* List of file descriptors that are watched by tevent. */ struct fd_watch *fds; /* Time in milliseconds before canceling a DNS request */ int timeout; /* The timeout watcher periodically calls ares_process_fd() to check * if our pending requests didn't timeout. */ int pending_requests; struct tevent_timer *timeout_watcher; }; struct request_watch { struct tevent_req *req; struct resolv_request *rr; }; struct resolv_request { struct resolv_ctx *ctx; struct request_watch *rwatch; struct tevent_timer *request_timeout; }; static int return_code(int ares_code) { switch (ares_code) { case ARES_SUCCESS: return EOK; case ARES_ENOMEM: return ENOMEM; case ARES_EFILE: default: return EIO; } } const char * resolv_strerror(int ares_code) { return ares_strerror(ares_code); } static int fd_watch_destructor(struct fd_watch *f) { DLIST_REMOVE(f->ctx->fds, f); f->fd = -1; return 0; } static void fd_input_available(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *data) { struct fd_watch *watch = talloc_get_type(data, struct fd_watch); if (watch->ctx->channel == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ares channel - this is likely a bug\n"); return; } if (flags & TEVENT_FD_READ) { ares_process_fd(watch->ctx->channel, watch->fd, ARES_SOCKET_BAD); } if (flags & TEVENT_FD_WRITE) { ares_process_fd(watch->ctx->channel, ARES_SOCKET_BAD, watch->fd); } } static void check_fd_timeouts(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *private_data); static void add_timeout_timer(struct tevent_context *ev, struct resolv_ctx *ctx) { struct timeval tv = { 0, 0 }; struct timeval *tvp; if (ctx->timeout_watcher) { return; } tvp = ares_timeout(ctx->channel, NULL, &tv); if (tvp == NULL) { tvp = &tv; } /* Enforce a minimum of 1 second. */ if (tvp->tv_sec < 1) { tv = tevent_timeval_current_ofs(1, 0); } else { tv = tevent_timeval_current_ofs(tvp->tv_sec, tvp->tv_usec); } ctx->timeout_watcher = tevent_add_timer(ev, ctx, tv, check_fd_timeouts, ctx); if (ctx->timeout_watcher == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); } } static void check_fd_timeouts(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *private_data) { struct resolv_ctx *ctx = talloc_get_type(private_data, struct resolv_ctx); DEBUG(SSSDBG_TRACE_ALL, "Checking for DNS timeouts\n"); /* NULLify the timeout_watcher so we don't * free it in the _done() function if it * gets called. Now that we're already in * the handler, tevent will take care of * freeing it when it returns. */ ctx->timeout_watcher = NULL; ares_process_fd(ctx->channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); if (ctx->pending_requests > 0) { add_timeout_timer(ev, ctx); } } static void resolv_request_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct resolv_request *rreq; DEBUG(SSSDBG_MINOR_FAILURE, "The resolve request timed out\n"); rreq = talloc_get_type(pvt, struct resolv_request); if (rreq->rwatch == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "The request already completed\n"); return; } tevent_req_error(rreq->rwatch->req, ETIMEDOUT); rreq->rwatch = NULL; } static int request_watch_destructor(struct request_watch *rwatch) { DEBUG(SSSDBG_TRACE_FUNC, "Deleting request watch\n"); if (rwatch->rr) rwatch->rr->rwatch = NULL; return 0; } static struct resolv_request * schedule_request_timeout(struct tevent_context *ev, struct resolv_ctx *ctx, struct tevent_req *req) { struct resolv_request *rreq; struct timeval tv; DEBUG(SSSDBG_TRACE_INTERNAL, "Scheduling a timeout of %d seconds\n", ctx->timeout); tv = tevent_timeval_current_ofs(ctx->timeout, 0); /* Intentionally allocating on ctx, because the request might go away * before c-ares returns */ rreq = talloc(ctx, struct resolv_request); if (!rreq) { talloc_zfree(req); return NULL; } rreq->ctx = ctx; rreq->request_timeout = tevent_add_timer(ev, rreq, tv, resolv_request_timeout, rreq); if (rreq->request_timeout == NULL) { talloc_free(rreq); return NULL; } /* The watch will go away when the request finishes */ rreq->rwatch = talloc(req, struct request_watch); if (!rreq->rwatch) { talloc_zfree(req); return NULL; } rreq->rwatch->req = req; rreq->rwatch->rr = rreq; talloc_set_destructor(rreq->rwatch, request_watch_destructor); return rreq; } static struct resolv_request * schedule_timeout_watcher(struct tevent_context *ev, struct resolv_ctx *ctx, struct tevent_req *req) { struct resolv_request *rreq; rreq = schedule_request_timeout(ev, ctx, req); if (!rreq) return NULL; ctx->pending_requests++; DEBUG(SSSDBG_TRACE_INTERNAL, "Scheduling DNS timeout watcher\n"); add_timeout_timer(ev, ctx); return rreq; } static void unschedule_timeout_watcher(struct resolv_ctx *ctx, struct resolv_request *rreq) { /* Unlink the watch if the request is still active */ if (rreq->rwatch) { rreq->rwatch->rr = NULL; } talloc_free(rreq); /* Cancels the tevent timeout as well */ if (ctx->pending_requests <= 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Pending DNS requests mismatch\n"); return; } ctx->pending_requests--; if (ctx->pending_requests == 0) { DEBUG(SSSDBG_TRACE_ALL, "Unscheduling DNS timeout watcher\n"); talloc_zfree(ctx->timeout_watcher); } } static void fd_event_add(struct resolv_ctx *ctx, int s, int flags); static void fd_event_close(struct resolv_ctx *ctx, int s); /* * When ares is ready to read or write to a file descriptor, it will * call this callback. If both read and write are 0, it means that ares * will soon close the socket. We are mainly using this function to register * new file descriptors with tevent. */ static void fd_event(void *data, int s, int fd_read, int fd_write) { struct resolv_ctx *ctx = talloc_get_type(data, struct resolv_ctx); struct fd_watch *watch; int flags; /* The socket is about to get closed. */ if (fd_read == 0 && fd_write == 0) { fd_event_close(ctx, s); return; } flags = fd_read ? TEVENT_FD_READ : 0; flags |= fd_write ? TEVENT_FD_WRITE : 0; /* Are we already watching this file descriptor? */ watch = ctx->fds; while (watch) { if (watch->fd == s) { tevent_fd_set_flags(watch->fde, flags); return; } watch = watch->next; } fd_event_add(ctx, s, flags); } static void fd_event_add(struct resolv_ctx *ctx, int s, int flags) { struct fd_watch *watch; /* The file descriptor is new, register it with tevent. */ watch = talloc(ctx, struct fd_watch); if (watch == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory allocating fd_watch structure\n"); return; } talloc_set_destructor(watch, fd_watch_destructor); watch->fd = s; watch->ctx = ctx; watch->fde = tevent_add_fd(ctx->ev_ctx, watch, s, flags, fd_input_available, watch); if (watch->fde == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_fd() failed\n"); talloc_free(watch); return; } DLIST_ADD(ctx->fds, watch); } static void fd_event_close(struct resolv_ctx *ctx, int s) { struct fd_watch *watch; /* Remove the socket from list */ watch = ctx->fds; while (watch) { if (watch->fd == s) { talloc_free(watch); return; } watch = watch->next; } } static int resolv_ctx_destructor(struct resolv_ctx *ctx) { ares_channel channel; if (ctx->channel == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Ares channel already destroyed?\n"); return -1; } /* Set ctx->channel to NULL first, so that callbacks that get * ARES_EDESTRUCTION won't retry. */ channel = ctx->channel; ctx->channel = NULL; ares_destroy(channel); return 0; } static int recreate_ares_channel(struct resolv_ctx *ctx) { int ret; ares_channel new_channel; ares_channel old_channel; struct ares_options options; DEBUG(SSSDBG_CONF_SETTINGS, "Initializing new c-ares channel\n"); /* FIXME: the options would contain * the nameservers to contact, the domains * to search... => get from confdb */ options.sock_state_cb = fd_event; options.sock_state_cb_data = ctx; options.timeout = RESOLV_TIMEOUTMS; /* Only affects ares_gethostbyname */ options.lookups = discard_const("f"); options.tries = 1; ret = ares_init_options(&new_channel, &options, ARES_OPT_SOCK_STATE_CB | ARES_OPT_TIMEOUTMS | ARES_OPT_LOOKUPS | ARES_OPT_TRIES); if (ret != ARES_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize ares channel: %s\n", resolv_strerror(ret)); return return_code(ret); } old_channel = ctx->channel; ctx->channel = new_channel; if (old_channel != NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "Destroying the old c-ares channel\n"); ares_destroy(old_channel); } return EOK; } int resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, int timeout, struct resolv_ctx **ctxp) { int ret; struct resolv_ctx *ctx; if (timeout < 1) { DEBUG(SSSDBG_MINOR_FAILURE, "The timeout is too short, DNS operations are going to fail. " "This is a bug outside unit tests\n"); } ctx = talloc_zero(mem_ctx, struct resolv_ctx); if (ctx == NULL) return ENOMEM; ctx->ev_ctx = ev_ctx; ctx->timeout = timeout; ret = recreate_ares_channel(ctx); if (ret != EOK) { goto done; } talloc_set_destructor(ctx, resolv_ctx_destructor); *ctxp = ctx; return EOK; done: talloc_free(ctx); return ret; } void resolv_reread_configuration(struct resolv_ctx *ctx) { recreate_ares_channel(ctx); } static errno_t resolv_copy_in_addr(TALLOC_CTX *mem_ctx, struct resolv_addr *ret, struct ares_addrttl *attl) { ret->ipaddr = talloc_array(mem_ctx, uint8_t, sizeof(struct in_addr)); if (!ret->ipaddr) return ENOMEM; memcpy(ret->ipaddr, &attl->ipaddr, sizeof(struct in_addr)); ret->ttl = attl->ttl; return EOK; } static errno_t resolv_copy_in6_addr(TALLOC_CTX *mem_ctx, struct resolv_addr *ret, struct ares_addr6ttl *a6ttl) { ret->ipaddr = talloc_array(mem_ctx, uint8_t, sizeof(struct in6_addr)); if (!ret->ipaddr) return ENOMEM; memcpy(ret->ipaddr, &a6ttl->ip6addr, sizeof(struct in6_addr)); ret->ttl = a6ttl->ttl; return EOK; } static struct resolv_hostent * resolv_copy_hostent_common(TALLOC_CTX *mem_ctx, struct hostent *src) { struct resolv_hostent *ret; int len; int i; ret = talloc_zero(mem_ctx, struct resolv_hostent); if (ret == NULL) { return NULL; } if (src->h_name != NULL) { ret->name = talloc_strdup(ret, src->h_name); if (ret->name == NULL) { goto fail; } } if (src->h_aliases != NULL) { for (len = 0; src->h_aliases[len] != NULL; len++); ret->aliases = talloc_array(ret, char *, len + 1); if (ret->aliases == NULL) { goto fail; } for (i = 0; i < len; i++) { ret->aliases[i] = talloc_strdup(ret->aliases, src->h_aliases[i]); if (ret->aliases[i] == NULL) { goto fail; } } ret->aliases[len] = NULL; } ret->family = src->h_addrtype; return ret; fail: talloc_free(ret); return NULL; } struct resolv_hostent * resolv_copy_hostent(TALLOC_CTX *mem_ctx, struct hostent *src) { struct resolv_hostent *ret; int len; int i; ret = resolv_copy_hostent_common(mem_ctx, src); if (ret == NULL) { return NULL; } if (src->h_addr_list != NULL) { for (len = 0; src->h_addr_list[len] != NULL; len++); ret->addr_list = talloc_array(ret, struct resolv_addr *, len + 1); if (ret->addr_list == NULL) { goto fail; } for (i = 0; i < len; i++) { ret->addr_list[i] = talloc_zero(ret->addr_list, struct resolv_addr); if (ret->addr_list[i] == NULL) { goto fail; } ret->addr_list[i]->ipaddr = talloc_memdup(ret->addr_list[i], src->h_addr_list[i], src->h_length); if (ret->addr_list[i]->ipaddr == NULL) { goto fail; } ret->addr_list[i]->ttl = RESOLV_DEFAULT_TTL; } ret->addr_list[len] = NULL; } return ret; fail: talloc_free(ret); return NULL; } struct resolv_hostent * resolv_copy_hostent_ares(TALLOC_CTX *mem_ctx, struct hostent *src, int family, void *ares_ttl_data, int num_ares_ttl_data) { struct resolv_hostent *ret; errno_t cret; int i; ret = resolv_copy_hostent_common(mem_ctx, src); if (ret == NULL) { return NULL; } if (num_ares_ttl_data > 0) { ret->addr_list = talloc_array(ret, struct resolv_addr *, num_ares_ttl_data + 1); if (ret->addr_list == NULL) { goto fail; } for (i = 0; i < num_ares_ttl_data; i++) { ret->addr_list[i] = talloc_zero(ret->addr_list, struct resolv_addr); if (ret->addr_list[i] == NULL) { goto fail; } switch (family) { case AF_INET: cret = resolv_copy_in_addr(ret->addr_list, ret->addr_list[i], &((struct ares_addrttl *) ares_ttl_data)[i]); break; case AF_INET6: cret = resolv_copy_in6_addr(ret->addr_list, ret->addr_list[i], &((struct ares_addr6ttl *) ares_ttl_data)[i]); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown address family %d\n", family); goto fail; } if (cret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not copy address\n"); goto fail; } } ret->addr_list[num_ares_ttl_data] = NULL; } ret->family = family; return ret; fail: talloc_free(ret); return NULL; } /* =================== Resolve host name in files =========================*/ struct gethostbyname_files_state { struct resolv_ctx *resolv_ctx; /* Part of the query. */ const char *name; int family; /* query result */ struct resolv_hostent *rhostent; /* returned by ares. */ int status; }; /* Fake up an async interface even though files would * always be blocking */ static struct tevent_req * resolv_gethostbyname_files_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *ctx, const char *name, int family) { struct tevent_req *req; struct gethostbyname_files_state *state; struct hostent *hostent = NULL; req = tevent_req_create(mem_ctx, &state, struct gethostbyname_files_state); if (req == NULL) { tevent_req_error(req, ENOMEM); goto done; } state->resolv_ctx = ctx; state->name = name; state->rhostent = NULL; state->family = family; DEBUG(SSSDBG_CONF_SETTINGS, "Trying to resolve %s record of '%s' in files\n", state->family == AF_INET ? "A" : "AAAA", state->name); state->status = ares_gethostbyname_file(state->resolv_ctx->channel, state->name, state->family, &hostent); if (state->status == ARES_SUCCESS) { state->rhostent = resolv_copy_hostent(state, hostent); if (state->rhostent == NULL) { tevent_req_error(req, ENOMEM); goto done; } } else if (state->status == ARES_ENOTFOUND || state->status == ARES_ENODATA) { /* Just say we didn't find anything and let the caller decide * about retrying */ tevent_req_error(req, ENOENT); goto done; } else { tevent_req_error(req, return_code(state->status)); goto done; } tevent_req_done(req); done: if (hostent) ares_free_hostent(hostent); tevent_req_post(req, ev); return req; } static errno_t resolv_gethostbyname_files_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, int *status, struct resolv_hostent **rhostent) { struct gethostbyname_files_state *state = tevent_req_data(req, struct gethostbyname_files_state); /* Fill in even in case of error as status contains the * c-ares return code */ if (status) { *status = state->status; } if (rhostent) { *rhostent = talloc_steal(mem_ctx, state->rhostent); } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } /* ==================== Resolve host name in DNS =========================*/ struct gethostbyname_dns_state { struct resolv_ctx *resolv_ctx; struct tevent_context *ev; /* Part of the query. */ const char *name; int family; /* query result */ struct resolv_hostent *rhostent; /* These are returned by ares. */ int status; int timeouts; int retrying; }; static void resolv_gethostbyname_dns_wakeup(struct tevent_req *subreq); static void resolv_gethostbyname_dns_query(struct tevent_req *req, struct gethostbyname_dns_state *state); static void resolv_gethostbyname_dns_query_done(void *arg, int status, int timeouts, unsigned char *abuf, int alen); static int resolv_gethostbyname_dns_parse(struct gethostbyname_dns_state *state, int status, unsigned char *abuf, int alen); static struct tevent_req * resolv_gethostbyname_dns_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *ctx, const char *name, int family) { struct tevent_req *req, *subreq; struct gethostbyname_dns_state *state; struct timeval tv = { 0, 0 }; if (ctx->channel == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ares channel - this is likely a bug\n"); return NULL; } req = tevent_req_create(mem_ctx, &state, struct gethostbyname_dns_state); if (req == NULL) { return NULL; } state->resolv_ctx = ctx; state->ev = ev; state->name = name; state->rhostent = NULL; state->status = 0; state->timeouts = 0; state->retrying = 0; state->family = family; /* We need to have a wrapper around ares async calls, because * they can in some cases call it's callback immediately. * This would not let our caller to set a callback for req. */ subreq = tevent_wakeup_send(req, ev, tv); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add critical timer to run next operation!\n"); talloc_zfree(req); return NULL; } tevent_req_set_callback(subreq, resolv_gethostbyname_dns_wakeup, req); return req; } static void resolv_gethostbyname_dns_wakeup(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct gethostbyname_dns_state *state = tevent_req_data(req, struct gethostbyname_dns_state); if (!tevent_wakeup_recv(subreq)) { tevent_req_error(req, EIO); return; } talloc_zfree(subreq); if (state->resolv_ctx->channel == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ares channel - this is likely a bug\n"); tevent_req_error(req, EIO); return; } resolv_gethostbyname_dns_query(req, state); } static void resolv_gethostbyname_dns_query(struct tevent_req *req, struct gethostbyname_dns_state *state) { struct resolv_request *rreq; DEBUG(SSSDBG_CONF_SETTINGS, "Trying to resolve %s record of '%s' in DNS\n", state->family == AF_INET ? "A" : "AAAA", state->name); rreq = schedule_timeout_watcher(state->ev, state->resolv_ctx, req); if (!rreq) { tevent_req_error(req, ENOMEM); return; } ares_search(state->resolv_ctx->channel, state->name, ns_c_in, (state->family == AF_INET) ? ns_t_a : ns_t_aaaa, resolv_gethostbyname_dns_query_done, rreq); } static void resolv_gethostbyname_dns_query_done(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { errno_t ret; struct gethostbyname_dns_state *state; struct resolv_request *rreq = talloc_get_type(arg, struct resolv_request); struct tevent_req *req; if (rreq->rwatch == NULL) { /* The tevent request was cancelled while the ares call was still in * progress so nobody cares about the result now. Quit. */ unschedule_timeout_watcher(rreq->ctx, rreq); return; } req = rreq->rwatch->req; unschedule_timeout_watcher(rreq->ctx, rreq); state = tevent_req_data(req, struct gethostbyname_dns_state); state->status = status; state->timeouts = timeouts; /* If resolv.conf changed during processing of a request we might * destroy the old channel before the request has a chance to finish. * We must resend the request in this case */ if (state->retrying == 0 && status == ARES_EDESTRUCTION && state->resolv_ctx->channel != NULL) { state->retrying = 1; resolv_gethostbyname_dns_query(req, state); return; } if (status == ARES_ENOTFOUND || status == ARES_ENODATA) { /* Just say we didn't find anything and let the caller decide * about retrying */ tevent_req_error(req, ENOENT); return; } if (status != ARES_SUCCESS) { /* Any other error indicates a server error, * so don't bother trying again */ tevent_req_error(req, return_code(status)); return; } ret = resolv_gethostbyname_dns_parse(state, status, abuf, alen); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } static int resolv_gethostbyname_dns_parse(struct gethostbyname_dns_state *state, int status, unsigned char *abuf, int alen) { struct hostent *hostent; int naddrttls; errno_t ret; void *addr = NULL; naddrttls = DNS_HEADER_ANCOUNT(abuf); switch (state->family) { case AF_INET: DEBUG(SSSDBG_TRACE_LIBS, "Parsing an A reply\n"); addr = talloc_array(state, struct ares_addrttl, naddrttls); if (!addr) { ret = ENOMEM; goto fail; } status = ares_parse_a_reply(abuf, alen, &hostent, (struct ares_addrttl *) addr, &naddrttls); break; case AF_INET6: DEBUG(SSSDBG_TRACE_LIBS, "Parsing an AAAA reply\n"); addr = talloc_array(state, struct ares_addr6ttl, naddrttls); if (!addr) { ret = ENOMEM; goto fail; } status = ares_parse_aaaa_reply(abuf, alen, &hostent, (struct ares_addr6ttl *) addr, &naddrttls); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown family %d\n", state->family); ret = EAFNOSUPPORT; goto fail; } if (hostent != NULL) { state->rhostent = resolv_copy_hostent_ares(state, hostent, state->family, addr, naddrttls); ares_free_hostent(hostent); if (state->rhostent == NULL) { ret = ENOMEM; goto fail; } /* The address list is NULL. This is probably a bug in * c-ares, but we need to handle it gracefully. */ if (state->rhostent->addr_list == NULL) { talloc_zfree(state->rhostent); return ENOENT; } } talloc_free(addr); return return_code(status); fail: talloc_free(addr); return ret; } static int resolv_gethostbyname_dns_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, int *status, int *timeouts, struct resolv_hostent **rhostent) { struct gethostbyname_dns_state *state = tevent_req_data(req, struct gethostbyname_dns_state); /* Fill in even in case of error as status contains the * c-ares return code */ if (status) { *status = state->status; } if (timeouts) { *timeouts = state->timeouts; } TEVENT_REQ_RETURN_ON_ERROR(req); if (rhostent) { *rhostent = talloc_steal(mem_ctx, state->rhostent); } return EOK; } /******************************************************************* * Get host by name. * *******************************************************************/ struct gethostbyname_state { struct resolv_ctx *resolv_ctx; struct tevent_context *ev; /* Part of the query. */ const char *name; int family; /* In which order to use IPv4, or v6 */ enum restrict_family family_order; /* Known hosts databases and index to the current one */ enum host_database *db; int dbi; /* These are returned by ares. The hostent struct will be freed * when the user callback returns. */ struct resolv_hostent *rhostent; int status; int timeouts; int retrying; }; static errno_t resolv_gethostbyname_address(TALLOC_CTX *mem_ctx, const char *address, struct resolv_hostent **_rhostent); static inline int resolv_gethostbyname_family_init(enum restrict_family family_order); static bool resolv_is_address(const char *name); static errno_t resolv_gethostbyname_step(struct tevent_req *req); struct tevent_req * resolv_gethostbyname_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *ctx, const char *name, enum restrict_family family_order, enum host_database *db) { struct tevent_req *req; struct gethostbyname_state *state; errno_t ret; if (ctx->channel == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ares channel - this is likely a bug\n"); return NULL; } req = tevent_req_create(mem_ctx, &state, struct gethostbyname_state); if (req == NULL) { return NULL; } state->resolv_ctx = ctx; state->ev = ev; state->name = talloc_strdup(state, name); if (state->name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); goto fail; } state->rhostent = NULL; state->status = 0; state->timeouts = 0; state->retrying = 0; state->family_order = family_order; state->family = resolv_gethostbyname_family_init(state->family_order); state->db = db; state->dbi = 0; /* Do not attempt to resolve IP addresses */ if (resolv_is_address(state->name)) { ret = resolv_gethostbyname_address(state, state->name, &state->rhostent); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Canot create a fake hostent structure\n"); goto fail; } tevent_req_done(req); tevent_req_post(req, ev); return req; } ret = resolv_gethostbyname_step(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot start the resolving\n"); goto fail; } return req; fail: talloc_zfree(req); return NULL; } static bool resolv_is_address(const char *name) { struct addrinfo hints; struct addrinfo *res = NULL; int ret; memset((void *) &hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_NUMERICHOST; /* No network lookups */ ret = getaddrinfo(name, NULL, &hints, &res); if (ret != 0) { if (ret == -2) { DEBUG(SSSDBG_TRACE_ALL, "[%s] does not look like an IP address\n", name); } else { DEBUG(SSSDBG_OP_FAILURE, "getaddrinfo failed [%d]: %s\n", ret, gai_strerror(ret)); } } else { /* ret == 0 */ freeaddrinfo(res); } return ret == 0; } static errno_t resolv_gethostbyname_address(TALLOC_CTX *mem_ctx, const char *address, struct resolv_hostent **_rhostent) { struct resolv_hostent *rhostent; TALLOC_CTX *tmp_ctx; errno_t ret; int family; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; rhostent = talloc_zero(tmp_ctx, struct resolv_hostent); if (!rhostent) { ret = ENOMEM; goto done; } rhostent->name = talloc_strdup(rhostent, address); rhostent->addr_list = talloc_array(rhostent, struct resolv_addr *, 2); if (!rhostent->name || !rhostent->addr_list) { ret = ENOMEM; goto done; } rhostent->addr_list[0] = talloc_zero(rhostent->addr_list, struct resolv_addr); if (!rhostent->addr_list[0]) { ret = ENOMEM; goto done; } rhostent->addr_list[0]->ipaddr = talloc_array(rhostent->addr_list[0], uint8_t, sizeof(struct in6_addr)); if (!rhostent->addr_list[0]->ipaddr) { ret = ENOMEM; goto done; } family = AF_INET; ret = inet_pton(family, address, rhostent->addr_list[0]->ipaddr); if (ret != 1) { family = AF_INET6; ret = inet_pton(family, address, rhostent->addr_list[0]->ipaddr); if (ret != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not parse address as neither v4 nor v6\n"); ret = EINVAL; goto done; } } rhostent->addr_list[0]->ttl = RESOLV_DEFAULT_TTL; rhostent->addr_list[1] = NULL; rhostent->family = family; rhostent->aliases = NULL; *_rhostent = talloc_move(mem_ctx, &rhostent); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static inline int resolv_gethostbyname_family_init(enum restrict_family family_order) { switch(family_order) { case IPV4_ONLY: case IPV4_FIRST: return AF_INET; case IPV6_ONLY: case IPV6_FIRST: return AF_INET6; } DEBUG(SSSDBG_CRIT_FAILURE, "Unknown address family order %d\n", family_order); return -1; } static int resolv_gethostbyname_next(struct gethostbyname_state *state) { if (state->family_order == IPV4_FIRST && state->family == AF_INET) { state->family = AF_INET6; return EOK; } else if (state->family_order == IPV6_FIRST && state->family == AF_INET6) { state->family = AF_INET; return EOK; } else { /* No more address families for this DB, check if * there is another DB to try */ DEBUG(SSSDBG_FUNC_DATA, "No more address families to retry\n"); state->dbi++; if (state->db[state->dbi] != DB_SENTINEL) { state->family = resolv_gethostbyname_family_init( state->family_order); return EOK; } } DEBUG(SSSDBG_CONF_SETTINGS, "No more hosts databases to retry\n"); return ENOENT; } static void resolv_gethostbyname_done(struct tevent_req *subreq); static errno_t resolv_gethostbyname_step(struct tevent_req *req) { struct gethostbyname_state *state = tevent_req_data(req, struct gethostbyname_state); struct tevent_req *subreq; switch(state->db[state->dbi]) { case DB_FILES: DEBUG(SSSDBG_TRACE_INTERNAL, "Querying files\n"); subreq = resolv_gethostbyname_files_send(state, state->ev, state->resolv_ctx, state->name, state->family); break; case DB_DNS: DEBUG(SSSDBG_TRACE_INTERNAL, "Querying DNS\n"); subreq = resolv_gethostbyname_dns_send(state, state->ev, state->resolv_ctx, state->name, state->family); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid hosts database\n"); return EINVAL; } if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, resolv_gethostbyname_done, req); return EOK; } static void resolv_gethostbyname_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct gethostbyname_state *state = tevent_req_data(req, struct gethostbyname_state); errno_t ret; switch(state->db[state->dbi]) { case DB_FILES: ret = resolv_gethostbyname_files_recv(subreq, state, &state->status, &state->rhostent); /* files is synchronous, there can be no timeouts */ state->timeouts = 0; break; case DB_DNS: ret = resolv_gethostbyname_dns_recv(subreq, state, &state->status, &state->timeouts, &state->rhostent); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid hosts database\n"); tevent_req_error(req, EINVAL); return; } talloc_zfree(subreq); if (ret == ENOENT) { ret = resolv_gethostbyname_next(state); if (ret == EOK) { ret = resolv_gethostbyname_step(req); if (ret != EOK) { tevent_req_error(req, ret); } return; } /* No more databases and/or address families */ tevent_req_error(req, ENOENT); return; } else if (ret == ETIMEDOUT) { /* In case we killed the request before c-ares answered */ state->status = ARES_ETIMEOUT; } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "querying hosts database failed [%d]: %s\n", ret, strerror(ret)); tevent_req_error(req, ret); return; } tevent_req_done(req); } int resolv_gethostbyname_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, int *status, int *timeouts, struct resolv_hostent **rhostent) { struct gethostbyname_state *state = tevent_req_data(req, struct gethostbyname_state); /* Fill in even in case of error as status contains the * c-ares return code */ if (status) { *status = state->status; } if (timeouts) { *timeouts = state->timeouts; } if (rhostent) { *rhostent = talloc_steal(mem_ctx, state->rhostent); } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } char * resolv_get_string_address_index(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent, unsigned int addrindex) { char *address; if (!hostent) return NULL; address = talloc_zero_size(mem_ctx, 128); if (address == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return NULL; } errno = 0; if (inet_ntop(hostent->family, hostent->addr_list[addrindex]->ipaddr, address, 128) == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "inet_ntop failed [%d][%s].\n", errno, strerror(errno)); talloc_free(address); return NULL; } return address; } char * resolv_get_string_ptr_address(TALLOC_CTX *mem_ctx, int family, uint8_t *address) { char *straddr; if (family == AF_INET6) { int i; char hexbyte[3]; straddr = talloc_strdup(mem_ctx, "\0"); if (!straddr) { return NULL; } for (i = 15; i >= 0; i--) { snprintf(hexbyte, 3, "%02x", address[i]); straddr = talloc_asprintf_append(straddr, "%c.%c.", hexbyte[1], hexbyte[0]); } straddr = talloc_asprintf_append(straddr, "ip6.arpa."); } else if (family == AF_INET) { straddr = talloc_asprintf(mem_ctx, "%u.%u.%u.%u.in-addr.arpa.", (address[3]), (address[2]), (address[1]), (address[0])); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown address family\n"); return NULL; } return straddr; } struct sockaddr_storage * resolv_get_sockaddr_address_index(TALLOC_CTX *mem_ctx, struct resolv_hostent *hostent, int port, int addrindex) { struct sockaddr_storage *sockaddr; if (!hostent) return NULL; sockaddr = talloc_zero(mem_ctx, struct sockaddr_storage); if (sockaddr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); return NULL; } switch(hostent->family) { case AF_INET: sockaddr->ss_family = AF_INET; memcpy(&((struct sockaddr_in *) sockaddr)->sin_addr, hostent->addr_list[addrindex]->ipaddr, sizeof(struct in_addr)); ((struct sockaddr_in *) sockaddr)->sin_port = (in_port_t) htons(port); break; case AF_INET6: sockaddr->ss_family = AF_INET6; memcpy(&((struct sockaddr_in6 *) sockaddr)->sin6_addr, hostent->addr_list[addrindex]->ipaddr, sizeof(struct in6_addr)); ((struct sockaddr_in6 *) sockaddr)->sin6_port = (in_port_t) htons(port); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown address family %d\n", hostent->family); return NULL; } return sockaddr; } /* * A simple helper function that will take an array of struct ares_srv_reply that * was allocated by malloc() in c-ares and copies it using talloc. The old one * is freed and the talloc one is put into 'reply_list' instead. */ static int rewrite_talloc_srv_reply(TALLOC_CTX *mem_ctx, struct ares_srv_reply **reply_list) { struct ares_srv_reply *ptr = NULL; struct ares_srv_reply *new_list = NULL; struct ares_srv_reply *old_list = *reply_list; /* Nothing to do, but not an error */ if (!old_list) { return EOK; } /* Copy the linked list */ while (old_list) { /* Special case for the first node */ if (!new_list) { new_list = talloc_zero(mem_ctx, struct ares_srv_reply); if (new_list == NULL) { ares_free_data(*reply_list); return ENOMEM; } ptr = new_list; } else { ptr->next = talloc_zero(new_list, struct ares_srv_reply); if (ptr->next == NULL) { ares_free_data(*reply_list); talloc_free(new_list); return ENOMEM; } ptr = ptr->next; } ptr->weight = old_list->weight; ptr->priority = old_list->priority; ptr->port = old_list->port; ptr->host = talloc_strdup(ptr, old_list->host); if (ptr->host == NULL) { ares_free_data(*reply_list); talloc_free(new_list); return ENOMEM; } old_list = old_list->next; } /* Free the old one (uses malloc). */ ares_free_data(*reply_list); /* And now put our own new_list in place. */ *reply_list = new_list; return EOK; } /******************************************************************* * Get SRV record * *******************************************************************/ struct getsrv_state { struct tevent_context *ev; struct resolv_ctx *resolv_ctx; /* the SRV query - for example _ldap._tcp.example.com */ const char *query; /* parsed data returned by ares */ struct ares_srv_reply *reply_list; uint32_t ttl; int status; int timeouts; int retrying; }; static void ares_getsrv_wakeup(struct tevent_req *subreq); static void resolv_getsrv_query(struct tevent_req *req, struct getsrv_state *state); struct tevent_req * resolv_getsrv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *ctx, const char *query) { struct tevent_req *req, *subreq; struct getsrv_state *state; struct timeval tv = { 0, 0 }; DEBUG(SSSDBG_CONF_SETTINGS, "Trying to resolve SRV record of '%s'\n", query); if (ctx->channel == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ares channel - this is likely a bug\n"); return NULL; } req = tevent_req_create(mem_ctx, &state, struct getsrv_state); if (req == NULL) return NULL; state->resolv_ctx = ctx; state->query = query; state->reply_list = NULL; state->ttl = 0; state->status = 0; state->timeouts = 0; state->retrying = 0; state->ev = ev; subreq = tevent_wakeup_send(req, ev, tv); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add critical timer to run next operation!\n"); talloc_zfree(req); return NULL; } tevent_req_set_callback(subreq, ares_getsrv_wakeup, req); return req; } /* * Implemented based on http://tools.ietf.org/html/rfc2181#section-5 * * Especially: * 5.2. TTLs of RRs in an RRSet * Consequently the use of differing TTLs in an RRSet is hereby * deprecated, the TTLs of all RRs in an RRSet must be the same. * ... * Should an authoritative source send such a malformed RRSet, the * client should treat the RRs for all purposes as if all TTLs in the * RRSet had been set to the value of the lowest TTL in the RRSet. * * On success, returns true and sets the TTL in the _ttl parameter. On * failure, returns false and _ttl is undefined. */ static bool resolv_get_ttl(const unsigned char *abuf, const int alen, uint32_t *_ttl) { const unsigned char *aptr; int ret; char *name = NULL; long len; uint32_t ttl = 0; uint32_t rr_ttl; unsigned int rr_len; unsigned int ancount; unsigned int i; /* Read the number of RRs and then skip past the header */ if (alen < NS_HFIXEDSZ) { return false; } ancount = DNS_HEADER_ANCOUNT(abuf); if (ancount == 0) { return false; } aptr = abuf + NS_HFIXEDSZ; /* We only care about len from the question data, * so that we can move past hostname */ ret = ares_expand_name(aptr, abuf, alen, &name, &len); ares_free_string(name); if (ret != ARES_SUCCESS) { return false; } /* Skip past the question */ aptr += len + NS_QFIXEDSZ; if (aptr > abuf + alen) { return false; } /* Examine each RR in turn and read the lowest TTL */ for (i = 0; i < ancount; i++) { /* Decode the RR up to the data field. */ ret = ares_expand_name(aptr, abuf, alen, &name, &len); ares_free_string(name); if (ret != ARES_SUCCESS) { return false; } aptr += len; if (aptr + NS_RRFIXEDSZ > abuf + alen) { return false; } rr_len = DNS_RR_LEN(aptr); rr_ttl = DNS_RR_TTL(aptr); if (aptr + rr_len > abuf + alen) { return false; } aptr += NS_RRFIXEDSZ + rr_len; if (ttl > 0) { ttl = MIN(ttl, rr_ttl); } else { ttl = rr_ttl; /* special-case for first TTL */ } } *_ttl = ttl; return true; } static void resolv_getsrv_done(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { struct resolv_request *rreq = talloc_get_type(arg, struct resolv_request); struct tevent_req *req; struct getsrv_state *state; int ret; bool ok; struct ares_srv_reply *reply_list; if (rreq->rwatch == NULL) { /* The tevent request was cancelled while the ares call was still in * progress so nobody cares about the result now. Quit. */ unschedule_timeout_watcher(rreq->ctx, rreq); return; } req = rreq->rwatch->req; unschedule_timeout_watcher(rreq->ctx, rreq); state = tevent_req_data(req, struct getsrv_state); if (state->retrying == 0 && status == ARES_EDESTRUCTION && state->resolv_ctx->channel != NULL) { state->retrying = 1; resolv_getsrv_query(req, state); return; } state->status = status; state->timeouts = timeouts; if (status != ARES_SUCCESS) { ret = return_code(status); goto fail; } ret = ares_parse_srv_reply(abuf, alen, &reply_list); if (ret != ARES_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "SRV record parsing failed: %d: %s\n", ret, ares_strerror(ret)); ret = return_code(ret); goto fail; } ret = rewrite_talloc_srv_reply(req, &reply_list); if (ret != EOK) { goto fail; } state->reply_list = reply_list; ok = resolv_get_ttl(abuf, alen, &state->ttl); if (ok == false) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not read TTL, using the default..\n"); state->ttl = RESOLV_DEFAULT_SRV_TTL; } DEBUG(SSSDBG_TRACE_LIBS, "Using TTL [%"PRIu32"]\n", state->ttl); tevent_req_done(req); return; fail: state->reply_list = NULL; tevent_req_error(req, ret); } int resolv_getsrv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status, int *timeouts, struct ares_srv_reply **reply_list, uint32_t *ttl) { struct getsrv_state *state = tevent_req_data(req, struct getsrv_state); if (status) *status = state->status; if (timeouts) *timeouts = state->timeouts; if (reply_list) *reply_list = talloc_steal(mem_ctx, state->reply_list); if (ttl) { *ttl = state->ttl; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void ares_getsrv_wakeup(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct getsrv_state *state = tevent_req_data(req, struct getsrv_state); if (!tevent_wakeup_recv(subreq)) { return; } talloc_zfree(subreq); if (state->resolv_ctx->channel == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ares channel - this is likely a bug\n"); tevent_req_error(req, EIO); return; } return resolv_getsrv_query(req, state); } static void resolv_getsrv_query(struct tevent_req *req, struct getsrv_state *state) { struct resolv_request *rreq; rreq = schedule_timeout_watcher(state->ev, state->resolv_ctx, req); if (!rreq) { tevent_req_error(req, ENOMEM); return; } ares_query(state->resolv_ctx->channel, state->query, ns_c_in, ns_t_srv, resolv_getsrv_done, rreq); } /* TXT parsing is not used anywhere in the code yet, so we disable it * for now */ #ifdef BUILD_TXT /* * A simple helper function that will take an array of struct txt_reply that * was allocated by malloc() in c-ares and copies it using talloc. The old one * is freed and the talloc one is put into 'reply_list' instead. */ static int rewrite_talloc_txt_reply(TALLOC_CTX *mem_ctx, struct ares_txt_reply **reply_list) { struct ares_txt_reply *ptr = NULL; struct ares_txt_reply *new_list = NULL; struct ares_txt_reply *old_list = *reply_list; /* Nothing to do, but not an error */ if (!old_list) { return EOK; } /* Copy the linked list */ while (old_list) { /* Special case for the first node */ if (!new_list) { new_list = talloc_zero(mem_ctx, struct ares_txt_reply); if (new_list == NULL) { ares_free_data(*reply_list); talloc_free(new_list); return ENOMEM; } ptr = new_list; } else { ptr->next = talloc_zero(new_list, struct ares_txt_reply); if (ptr->next == NULL) { ares_free_data(*reply_list); talloc_free(new_list); return ENOMEM; } ptr = ptr->next; } ptr->length = old_list->length; ptr->txt = talloc_memdup(ptr, old_list->txt, old_list->length); if (ptr->txt == NULL) { ares_free_data(*reply_list); talloc_free(new_list); return ENOMEM; } old_list = old_list->next; } ares_free_data(*reply_list); /* And now put our own new_list in place. */ *reply_list = new_list; return EOK; } /******************************************************************* * Get TXT record * *******************************************************************/ struct gettxt_state { struct tevent_context *ev; struct resolv_ctx *resolv_ctx; /* the TXT query */ const char *query; /* parsed data returned by ares */ struct ares_txt_reply *reply_list; int status; int timeouts; int retrying; }; static void ares_gettxt_wakeup(struct tevent_req *subreq); static void resolv_gettxt_query(struct tevent_req *req, struct gettxt_state *state); struct tevent_req * resolv_gettxt_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *ctx, const char *query) { struct tevent_req *req, *subreq; struct gettxt_state *state; struct timeval tv = { 0, 0 }; DEBUG(SSSDBG_CONF_SETTINGS, "Trying to resolve TXT record of '%s'\n", query); if (ctx->channel == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ares channel - this is likely a bug\n"); return NULL; } req = tevent_req_create(mem_ctx, &state, struct gettxt_state); if (req == NULL) return NULL; state->resolv_ctx = ctx; state->query = query; state->reply_list = NULL; state->status = 0; state->timeouts = 0; state->retrying = 0; state->ev = ev; subreq = tevent_wakeup_send(req, ev, tv); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add critical timer to run next operation!\n"); talloc_zfree(req); return NULL; } tevent_req_set_callback(subreq, ares_gettxt_wakeup, req); return req; } static void resolv_gettxt_done(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { struct resolv_request *rreq = talloc_get_type(arg, struct resolv_request); struct tevent_req *req; struct gettxt_state *state; int ret; struct ares_txt_reply *reply_list; if (rreq->rwatch == NULL) { /* The tevent request was cancelled while the ares call was still in * progress so nobody cares about the result now. Quit. */ unschedule_timeout_watcher(rreq->ctx, rreq); return; } req = rreq->rwatch->req; unschedule_timeout_watcher(rreq->ctx, rreq); state = tevent_req_data(req, struct gettxt_state); if (state->retrying == 0 && status == ARES_EDESTRUCTION && state->resolv_ctx->channel != NULL) { state->retrying = 1; ares_query(state->resolv_ctx->channel, state->query, ns_c_in, ns_t_txt, resolv_gettxt_done, req); return; } state->status = status; state->timeouts = timeouts; if (status != ARES_SUCCESS) { ret = return_code(status); goto fail; } ret = ares_parse_txt_reply(abuf, alen, &reply_list); if (status != ARES_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "TXT record parsing failed: %d: %s\n", ret, ares_strerror(ret)); ret = return_code(ret); goto fail; } ret = rewrite_talloc_txt_reply(req, &reply_list); if (ret != EOK) { goto fail; } state->reply_list = reply_list; tevent_req_done(req); return; fail: state->reply_list = NULL; tevent_req_error(req, ret); } int resolv_gettxt_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, int *status, int *timeouts, struct ares_txt_reply **reply_list) { struct gettxt_state *state = tevent_req_data(req, struct gettxt_state); if (status) *status = state->status; if (timeouts) *timeouts = state->timeouts; if (reply_list) *reply_list = talloc_steal(mem_ctx, state->reply_list); TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void ares_gettxt_wakeup(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct gettxt_state *state = tevent_req_data(req, struct gettxt_state); if (!tevent_wakeup_recv(subreq)) { return; } talloc_zfree(subreq); if (state->resolv_ctx->channel == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ares channel - this is likely a bug\n"); tevent_req_error(req, EIO); return; } return resolv_gettxt_query(req, state); } static void resolv_gettxt_query(struct tevent_req *req, struct gettxt_state *state) { struct resolv_request *rreq; rreq = schedule_timeout_watcher(state->ev, state->resolv_ctx, req); if (!rreq) { tevent_req_error(req, ENOMEM); return; } ares_query(state->resolv_ctx->channel, state->query, ns_c_in, ns_t_txt, resolv_gettxt_done, rreq); } #endif static struct ares_srv_reply *split_reply_list(struct ares_srv_reply *list) { struct ares_srv_reply *single_step, *double_step, *prev; if (!list) { return NULL; } prev = list; single_step = list->next; double_step = single_step->next; while (double_step && double_step->next) { prev = single_step; single_step = single_step->next; double_step = double_step->next->next; } prev->next = NULL; return single_step; } static struct ares_srv_reply *merge_reply_list(struct ares_srv_reply *left, struct ares_srv_reply *right) { struct ares_srv_reply *l, *r; struct ares_srv_reply *res, *res_start; if (!left) return right; if (!right) return left; if (left->priority < right->priority) { res_start = left; l = left->next; r = right; } else { res_start = right; l = left; r = right->next; } res = res_start; while(l && r) { if (l->priority < r->priority) { res->next = l; res = l; l = l->next; } else { res->next = r; res = r; r = r->next; } } res->next = l ? l : r; return res_start; } /** * sort linked list of struct ares_srv_reply by priority using merge sort. * * Merge sort is ideal for sorting linked lists as there is no problem * with absence of random access into the list. The complexity is O(n log n) * * For reference, see Robert Sedgewick's "Algorithms in C", Addison-Wesley, * ISBN 0-201-51425 */ static struct ares_srv_reply *reply_priority_sort(struct ares_srv_reply *list) { struct ares_srv_reply *half; if (!list || !list->next) return list; half = split_reply_list(list); list = merge_reply_list(reply_priority_sort(list), reply_priority_sort(half)); return list; } static int reply_weight_rearrange(int len, struct ares_srv_reply **start, struct ares_srv_reply **end) { int i; int total, selected; int *totals; struct ares_srv_reply *r, *prev, *tmp; struct ares_srv_reply *new_start = NULL; struct ares_srv_reply *new_end = NULL; int ret; if (len <= 1) { return EOK; } totals = talloc_array(NULL, int, len); if (!totals) { return ENOMEM; } srand(time(NULL) * getpid()); /* promote all servers with weight==0 to the top */ r = *(start); prev = NULL; while (r != NULL) { if (r->weight == 0 && r != *start) { /* remove from the old list */ prev->next = r->next; /* add to the head of the new list */ tmp = r; r = r->next; tmp->next = *start; *start = tmp; } else { prev = r; r = r->next; } } *end = prev ? prev : *start; while (*start != NULL) { /* Commpute the sum of the weights of those RRs, and with each RR * associate the running sum in the selected order. */ total = 0; memset(totals, -1, sizeof(int) * len); for (i = 0, r = *start; r != NULL; r=r->next, ++i) { totals[i] = r->weight + total; total = totals[i]; } /* choose a uniform random number between 0 and the sum computed * (inclusive), and select the RR whose running sum value is the * first in the selected order which is greater than or equal to * the random number selected. */ selected = (int)((total + 1) * (rand()/(RAND_MAX + 1.0))); for (i = 0, r = *start, prev = NULL; r != NULL; r=r->next, ++i) { if (totals[i] >= selected) break; prev = r; } if (r == NULL || totals[i] == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: did not select any server!\n"); ret = EIO; goto done; } /* remove r from the old list */ if (prev) { prev->next = r->next; } else { *start = r->next; } /* add r to the end of the new list */ if (!new_start) { new_start = r; new_end = r; } else { new_end->next = r; new_end = r; } } new_end->next = NULL; /* return the rearranged list */ *start = new_start; *end = new_end; ret = EOK; done: talloc_free(totals); return ret; } int resolv_sort_srv_reply(struct ares_srv_reply **reply) { int ret; struct ares_srv_reply *pri_start, *pri_end, *next, *prev_end; int len; /* RFC 2782 says: If there is precisely one SRV RR, and its Target is "." * (the root domain), abort. */ if (*reply && !(*reply)->next && strcmp((*reply)->host, ".") == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "DNS returned only the root domain, aborting\n"); return EIO; } /* sort the list by priority */ *reply = reply_priority_sort(*reply); pri_start = *reply; prev_end = NULL; while (pri_start) { pri_end = pri_start; /* Find nodes with the same priority */ len = 1; while (pri_end->next && pri_end->priority == pri_end->next->priority) { pri_end = pri_end->next; len++; } /* rearrange each priority level according to the weight field */ next = pri_end->next; pri_end->next = NULL; ret = reply_weight_rearrange(len, &pri_start, &pri_end); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Error rearranging priority level [%d]: %s\n", ret, strerror(ret)); return ret; } /* Hook the level back into the list */ if (prev_end) { prev_end->next = pri_start; } else { *reply = pri_start; } pri_end->next = next; /* Move on to the next level */ prev_end = pri_end; pri_start = next; } return EOK; } sssd-1.13.4/src/PaxHeaders.16287/ldb_modules0000644000000000000000000000013212703463556015336 xustar0030 mtime=1460561774.895794446 30 atime=1460561776.118798593 30 ctime=1460561774.895794446 sssd-1.13.4/src/ldb_modules/0000755002412700241270000000000012703463556017067 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/ldb_modules/PaxHeaders.16287/memberof.c0000644000000000000000000000007412703456111017345 xustar0030 atime=1460561751.634715573 30 ctime=1460561774.895794446 sssd-1.13.4/src/ldb_modules/memberof.c0000644002412700241270000042705312703456111021027 0ustar00jhrozekjhrozek00000000000000/* SSSD memberof module Copyright (C) Simo Sorce 2008-2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "ldb_module.h" #include "util/util.h" #define DB_MEMBER "member" #define DB_GHOST "ghost" #define DB_MEMBEROF "memberof" #define DB_MEMBERUID "memberuid" #define DB_NAME "name" #define DB_USER_CLASS "user" #define DB_GROUP_CLASS "group" #define DB_CACHE_EXPIRE "dataExpireTimestamp" #define DB_OC "objectClass" #ifndef MAX #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #endif struct mbof_val_array { struct ldb_val *vals; int num; }; struct mbof_dn_array { struct ldb_dn **dns; int num; }; struct mbof_dn { struct mbof_dn *next; struct ldb_dn *dn; }; struct mbof_ctx { struct ldb_module *module; struct ldb_request *req; struct ldb_control **ret_ctrls; struct ldb_extended *ret_resp; }; struct mbof_add_operation { struct mbof_add_ctx *add_ctx; struct mbof_add_operation *next; struct mbof_dn_array *parents; struct ldb_dn *entry_dn; struct ldb_message *entry; }; struct mbof_memberuid_op { struct ldb_dn *dn; struct ldb_message_element *el; }; struct mbof_add_ctx { struct mbof_ctx *ctx; struct mbof_add_operation *add_list; struct mbof_add_operation *current_op; struct ldb_message *msg; struct ldb_dn *msg_dn; bool terminate; struct mbof_dn *missing; struct mbof_memberuid_op *muops; int num_muops; int cur_muop; }; struct mbof_del_ancestors_ctx { struct mbof_dn_array *new_list; int num_direct; int cur; struct ldb_message *entry; }; struct mbof_del_operation { struct mbof_del_ctx *del_ctx; struct mbof_del_operation *parent; struct mbof_del_operation **children; int num_children; int next_child; struct ldb_dn *entry_dn; struct ldb_message *entry; struct ldb_message **parents; int num_parents; int cur_parent; struct mbof_del_ancestors_ctx *anc_ctx; }; struct mbof_mod_ctx; struct mbof_del_ctx { struct mbof_ctx *ctx; struct mbof_del_operation *first; struct mbof_dn *history; struct ldb_message **mus; int num_mus; struct mbof_memberuid_op *muops; int num_muops; int cur_muop; struct mbof_memberuid_op *ghops; int num_ghops; int cur_ghop; struct mbof_mod_ctx *follow_mod; bool is_mod; }; struct mbof_mod_del_op { struct mbof_mod_ctx *mod_ctx; struct ldb_message *mod_msg; struct ldb_message_element *el; hash_table_t *inherited_gh; }; struct mbof_mod_ctx { struct mbof_ctx *ctx; const struct ldb_message_element *membel; const struct ldb_message_element *ghel; struct ldb_message *entry; struct mbof_dn_array *mb_add; struct mbof_dn_array *mb_remove; struct mbof_val_array *gh_add; struct mbof_val_array *gh_remove; struct mbof_mod_del_op *igh; struct ldb_message *msg; bool terminate; }; static struct mbof_ctx *mbof_init(struct ldb_module *module, struct ldb_request *req) { struct mbof_ctx *ctx; ctx = talloc_zero(req, struct mbof_ctx); if (!ctx) { return NULL; } ctx->module = module; ctx->req = req; return ctx; } static void *hash_alloc(const size_t size, void *pvt) { return talloc_size(pvt, size); } static void hash_free(void *ptr, void *pvt) { talloc_free(ptr); } static int entry_has_objectclass(struct ldb_message *entry, const char *objectclass) { struct ldb_message_element *el; struct ldb_val *val; int i; el = ldb_msg_find_element(entry, DB_OC); if (!el) { return LDB_ERR_OPERATIONS_ERROR; } /* see if this is a user */ for (i = 0; i < el->num_values; i++) { val = &(el->values[i]); if (strncasecmp(objectclass, (char *)val->data, val->length) == 0) { return LDB_SUCCESS; } } return LDB_ERR_NO_SUCH_ATTRIBUTE; } static int entry_is_user_object(struct ldb_message *entry) { return entry_has_objectclass(entry, DB_USER_CLASS); } static int entry_is_group_object(struct ldb_message *entry) { return entry_has_objectclass(entry, DB_GROUP_CLASS); } static int mbof_append_muop(TALLOC_CTX *memctx, struct mbof_memberuid_op **_muops, int *_num_muops, int flags, struct ldb_dn *parent, const char *name, const char *element_name) { struct mbof_memberuid_op *muops = *_muops; int num_muops = *_num_muops; struct mbof_memberuid_op *op; struct ldb_val *val; int i; op = NULL; if (muops) { for (i = 0; i < num_muops; i++) { if (ldb_dn_compare(parent, muops[i].dn) == 0) { op = &muops[i]; break; } } } if (!op) { muops = talloc_realloc(memctx, muops, struct mbof_memberuid_op, num_muops + 1); if (!muops) { return LDB_ERR_OPERATIONS_ERROR; } op = &muops[num_muops]; num_muops++; *_muops = muops; *_num_muops = num_muops; op->dn = parent; op->el = NULL; } if (!op->el) { op->el = talloc_zero(muops, struct ldb_message_element); if (!op->el) { return LDB_ERR_OPERATIONS_ERROR; } op->el->name = talloc_strdup(op->el, element_name); if (!op->el->name) { return LDB_ERR_OPERATIONS_ERROR; } op->el->flags = flags; } for (i = 0; i < op->el->num_values; i++) { if (strcmp((char *)op->el->values[i].data, name) == 0) { /* we already have this value, get out*/ return LDB_SUCCESS; } } val = talloc_realloc(op->el, op->el->values, struct ldb_val, op->el->num_values + 1); if (!val) { return LDB_ERR_OPERATIONS_ERROR; } val[op->el->num_values].data = (uint8_t *)talloc_strdup(val, name); if (!val[op->el->num_values].data) { return LDB_ERR_OPERATIONS_ERROR; } val[op->el->num_values].length = strlen(name); op->el->values = val; op->el->num_values++; return LDB_SUCCESS; } /* add operation */ /* An add operation is quite simple. * First of all a new object cannot yet have parents, so the only memberof * attribute that can be added to any member contains just one object DN. * * The real add operation is done first, to assure nothing else fails. * Then we list all members of the object just created, and for each member * we create an "add operation" and we pass it a parent list of one member * (the object we just added again). * * For each add operation we lookup the object we want to operate on. * We take the list of memberof attributes and sort out which parents are * still missing from the parent list we have provided. * We modify the object memberof attributes to reflect the new memberships. * Then we list all members of this object, and for each once again we create * an "add operation" as we did in the initial object. * * Processing stops when the target object does not have members or when it * already has all the parents (can happen if nested groups create loops). * * Group cache unrolling: * Every time we add a memberof attribute to an actual user object, * we proceed to store the user name. * * At the end we will add a memberuid attribute to our new object that * includes all direct and indirect user members names. * * Group objects can also contain a "ghost" attribute. A ghost attribute * represents a user that is a member of the group but has not yet been * looked up so there is no real user entry with member/memberof links. * * If an object being added contains a "ghost" attribute, the ghost attribute * is in turn copied to all parents of that object so that retrieving a * group returns both its direct and indirect members. The ghost attribute is * similar to the memberuid attribute in many respects. One difference is that * the memberuid attribute is completely generated and managed by the memberof * plugin - in contrast, the ghost attribute is added to the entry that "owns" * it and only propagated to parent groups. */ static int mbof_append_addop(struct mbof_add_ctx *add_ctx, struct mbof_dn_array *parents, struct ldb_dn *entry_dn) { struct mbof_add_operation *lastop = NULL; struct mbof_add_operation *addop; /* test if this is a duplicate */ /* FIXME: this is not efficient */ if (add_ctx->add_list) { do { if (lastop) { lastop = lastop->next; } else { lastop = add_ctx->add_list; } /* FIXME: check if this is right, might have to compare parents */ if (ldb_dn_compare(lastop->entry_dn, entry_dn) == 0) { /* duplicate found */ return LDB_SUCCESS; } } while (lastop->next); } addop = talloc_zero(add_ctx, struct mbof_add_operation); if (!addop) { return LDB_ERR_OPERATIONS_ERROR; } addop->add_ctx = add_ctx; addop->parents = parents; addop->entry_dn = entry_dn; if (add_ctx->add_list) { lastop->next = addop; } else { add_ctx->add_list = addop; } return LDB_SUCCESS; } static int mbof_add_fill_ghop_ex(struct mbof_add_ctx *add_ctx, struct ldb_message *entry, struct mbof_dn_array *parents, struct ldb_val *ghvals, unsigned int num_gh_vals) { int ret; int i, j; if (!parents || parents->num == 0) { /* no parents attributes ... */ return LDB_SUCCESS; } ret = entry_is_group_object(entry); switch (ret) { case LDB_SUCCESS: /* it's a group object, continue */ break; case LDB_ERR_NO_SUCH_ATTRIBUTE: /* it is not a group object, just return */ return LDB_SUCCESS; default: /* an error occurred, return */ return ret; } ldb_debug(ldb_module_get_ctx(add_ctx->ctx->module), LDB_DEBUG_TRACE, "will add %d ghost users to %d parents\n", num_gh_vals, parents->num); for (i = 0; i < parents->num; i++) { for (j = 0; j < num_gh_vals; j++) { ret = mbof_append_muop(add_ctx, &add_ctx->muops, &add_ctx->num_muops, LDB_FLAG_MOD_ADD, parents->dns[i], (const char *) ghvals[j].data, DB_GHOST); if (ret != LDB_SUCCESS) { return ret; } } } return LDB_SUCCESS; } static int memberof_recompute_task(struct ldb_module *module, struct ldb_request *req); static int mbof_add_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_next_add(struct mbof_add_operation *addop); static int mbof_next_add_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_add_operation(struct mbof_add_operation *addop); static int mbof_add_fill_ghop(struct mbof_add_ctx *add_ctx, struct ldb_message *entry, struct mbof_dn_array *parents); static int mbof_add_missing(struct mbof_add_ctx *add_ctx, struct ldb_dn *dn); static int mbof_add_cleanup(struct mbof_add_ctx *add_ctx); static int mbof_add_cleanup_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_add_muop(struct mbof_add_ctx *add_ctx); static int mbof_add_muop_callback(struct ldb_request *req, struct ldb_reply *ares); static int memberof_add(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb = ldb_module_get_ctx(module); struct mbof_add_ctx *add_ctx; struct mbof_ctx *ctx; struct ldb_request *add_req; struct ldb_message_element *el; struct mbof_dn_array *parents; struct ldb_dn *valdn; int i, ret; if (ldb_dn_is_special(req->op.add.message->dn)) { if (strcmp("@MEMBEROF-REBUILD", ldb_dn_get_linearized(req->op.add.message->dn)) == 0) { return memberof_recompute_task(module, req); } /* do not manipulate other control entries */ return ldb_next_request(module, req); } /* check if memberof is specified */ el = ldb_msg_find_element(req->op.add.message, DB_MEMBEROF); if (el) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: the memberof attribute is readonly."); return LDB_ERR_UNWILLING_TO_PERFORM; } /* check if memberuid is specified */ el = ldb_msg_find_element(req->op.add.message, DB_MEMBERUID); if (el) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: the memberuid attribute is readonly."); return LDB_ERR_UNWILLING_TO_PERFORM; } ctx = mbof_init(module, req); if (!ctx) { return LDB_ERR_OPERATIONS_ERROR; } add_ctx = talloc_zero(ctx, struct mbof_add_ctx); if (!add_ctx) { return LDB_ERR_OPERATIONS_ERROR; } add_ctx->ctx = ctx; add_ctx->msg = ldb_msg_copy(add_ctx, req->op.add.message); if (!add_ctx->msg) { return LDB_ERR_OPERATIONS_ERROR; } add_ctx->msg_dn = add_ctx->msg->dn; /* continue with normal ops if there are no members */ el = ldb_msg_find_element(add_ctx->msg, DB_MEMBER); if (!el) { add_ctx->terminate = true; goto done; } parents = talloc_zero(add_ctx, struct mbof_dn_array); if (!parents) { return LDB_ERR_OPERATIONS_ERROR; } parents->dns = talloc_array(parents, struct ldb_dn *, 1); if (!parents->dns) { return LDB_ERR_OPERATIONS_ERROR; } parents->dns[0] = add_ctx->msg_dn; parents->num = 1; /* process new members */ /* check we are not adding ourselves as member as well */ for (i = 0; i < el->num_values; i++) { valdn = ldb_dn_from_ldb_val(add_ctx, ldb, &el->values[i]); if (!valdn || !ldb_dn_validate(valdn)) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Invalid dn value: [%s]", (const char *)el->values[i].data); return LDB_ERR_INVALID_DN_SYNTAX; } if (ldb_dn_compare(valdn, req->op.add.message->dn) == 0) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Adding self as member is not permitted! Skipping"); continue; } ret = mbof_append_addop(add_ctx, parents, valdn); if (ret != LDB_SUCCESS) { return ret; } } done: /* add original object */ ret = ldb_build_add_req(&add_req, ldb, add_ctx, add_ctx->msg, req->controls, add_ctx, mbof_add_callback, req); if (ret != LDB_SUCCESS) { return ret; } return ldb_next_request(module, add_req); } static int mbof_add_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_add_ctx *add_ctx; struct mbof_ctx *ctx; int ret; add_ctx = talloc_get_type(req->context, struct mbof_add_ctx); ctx = add_ctx->ctx; if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: /* shouldn't happen */ talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: if (add_ctx->terminate) { return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } if (add_ctx->current_op == NULL) { /* first operation */ ctx->ret_ctrls = talloc_steal(ctx, ares->controls); ctx->ret_resp = talloc_steal(ctx, ares->response); ret = mbof_next_add(add_ctx->add_list); } else if (add_ctx->current_op->next) { /* next operation */ ret = mbof_next_add(add_ctx->current_op->next); } else { /* no more operations */ if (add_ctx->missing) { ret = mbof_add_cleanup(add_ctx); } else if (add_ctx->muops) { ret = mbof_add_muop(add_ctx); } else { return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } } if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_next_add(struct mbof_add_operation *addop) { static const char *attrs[] = { DB_OC, DB_NAME, DB_MEMBER, DB_GHOST, DB_MEMBEROF, NULL }; struct ldb_context *ldb; struct ldb_request *req; struct mbof_add_ctx *add_ctx; struct mbof_ctx *ctx; int ret; add_ctx = addop->add_ctx; ctx = add_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); /* mark the operation as being handled */ add_ctx->current_op = addop; ret = ldb_build_search_req(&req, ldb, ctx, addop->entry_dn, LDB_SCOPE_BASE, NULL, attrs, NULL, addop, mbof_next_add_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_request(ldb, req); } static int mbof_next_add_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_add_operation *addop; struct mbof_add_ctx *add_ctx; struct ldb_context *ldb; struct mbof_ctx *ctx; int ret; addop = talloc_get_type(req->context, struct mbof_add_operation); add_ctx = addop->add_ctx; ctx = add_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: if (addop->entry != NULL) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Found multiple entries for (%s)", ldb_dn_get_linearized(addop->entry_dn)); /* more than one entry per dn ?? db corrupted ? */ return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } addop->entry = talloc_steal(addop, ares->message); if (addop->entry == NULL) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } break; case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: talloc_zfree(ares); if (addop->entry == NULL) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Entry not found (%s)", ldb_dn_get_linearized(addop->entry_dn)); /* this target does not exists, save as missing */ ret = mbof_add_missing(add_ctx, addop->entry_dn); if (ret != LDB_SUCCESS) { return ldb_module_done(ctx->req, NULL, NULL, ret); } /* now try the next operation */ if (add_ctx->current_op->next) { ret = mbof_next_add(add_ctx->current_op->next); } else { /* no more operations */ if (add_ctx->missing) { ret = mbof_add_cleanup(add_ctx); } else if (add_ctx->muops) { ret = mbof_add_muop(add_ctx); } else { return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } } if (ret != LDB_SUCCESS) { return ldb_module_done(ctx->req, NULL, NULL, ret); } } else { ret = mbof_add_operation(addop); if (ret != LDB_SUCCESS) { return ldb_module_done(ctx->req, NULL, NULL, ret); } } return LDB_SUCCESS; } talloc_zfree(ares); return LDB_SUCCESS; } /* if it is a group, add all members for cascade effect * add memberof attribute to this entry */ static int mbof_add_operation(struct mbof_add_operation *addop) { TALLOC_CTX *tmp_ctx; struct mbof_ctx *ctx; struct mbof_add_ctx *add_ctx; struct ldb_context *ldb; struct ldb_message_element *el; struct ldb_request *mod_req; struct ldb_message *msg; struct ldb_dn *elval_dn; struct ldb_dn *valdn; struct mbof_dn_array *parents; int i, j, ret; const char *val; const char *name; add_ctx = addop->add_ctx; ctx = add_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); parents = talloc_zero(add_ctx, struct mbof_dn_array); if (!parents) { return LDB_ERR_OPERATIONS_ERROR; } /* can't be more than the immediate parent */ parents->dns = talloc_array(parents, struct ldb_dn *, addop->parents->num); if (!parents->dns) { return LDB_ERR_OPERATIONS_ERROR; } /* create new parent set for this entry */ for (i = 0; i < addop->parents->num; i++) { /* never add yourself as memberof */ if (ldb_dn_compare(addop->parents->dns[i], addop->entry_dn) == 0) { continue; } parents->dns[parents->num] = addop->parents->dns[i]; parents->num++; } /* remove entries that are already there */ el = ldb_msg_find_element(addop->entry, DB_MEMBEROF); if (el) { tmp_ctx = talloc_new(addop); if (!tmp_ctx) return LDB_ERR_OPERATIONS_ERROR; for (i = 0; i < el->num_values; i++) { elval_dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &el->values[i]); if (!elval_dn) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Invalid DN in memberof [%s]", (const char *)el->values[i].data); talloc_free(tmp_ctx); return LDB_ERR_OPERATIONS_ERROR; } for (j = 0; j < parents->num; j++) { if (ldb_dn_compare(parents->dns[j], elval_dn) == 0) { /* duplicate found */ break; } } if (j < parents->num) { /* remove duplicate */ for (;j+1 < parents->num; j++) { parents->dns[j] = parents->dns[j+1]; } parents->num--; } } if (parents->num == 0) { /* already contains all parents as memberof, skip to next */ talloc_free(tmp_ctx); talloc_free(addop->entry); addop->entry = NULL; if (addop->next) { return mbof_next_add(addop->next); } else if (add_ctx->muops) { return mbof_add_muop(add_ctx); } else { /* that was the last entry, get out */ return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } } talloc_free(tmp_ctx); } /* if it is a group add all members */ el = ldb_msg_find_element(addop->entry, DB_MEMBER); if (el) { for (i = 0; i < el->num_values; i++) { valdn = ldb_dn_from_ldb_val(add_ctx, ldb, &el->values[i]); if (!valdn) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Invalid DN in member [%s]", (const char *)el->values[i].data); return LDB_ERR_OPERATIONS_ERROR; } if (!ldb_dn_validate(valdn)) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Invalid DN syntax for member [%s]", (const char *)el->values[i].data); return LDB_ERR_INVALID_DN_SYNTAX; } ret = mbof_append_addop(add_ctx, parents, valdn); if (ret != LDB_SUCCESS) { return ret; } } } /* check if we need to store memberuid ops for this entry */ ret = entry_is_user_object(addop->entry); switch (ret) { case LDB_SUCCESS: /* it's a user object */ name = ldb_msg_find_attr_as_string(addop->entry, DB_NAME, NULL); if (!name) { return LDB_ERR_OPERATIONS_ERROR; } for (i = 0; i < parents->num; i++) { ret = mbof_append_muop(add_ctx, &add_ctx->muops, &add_ctx->num_muops, LDB_FLAG_MOD_ADD, parents->dns[i], name, DB_MEMBERUID); if (ret != LDB_SUCCESS) { return ret; } } break; case LDB_ERR_NO_SUCH_ATTRIBUTE: /* it is not a user object, continue */ break; default: /* an error occurred, return */ return ret; } ret = mbof_add_fill_ghop(add_ctx, addop->entry, parents); if (ret != LDB_SUCCESS) { return ret; } /* we are done with the entry now */ talloc_free(addop->entry); addop->entry = NULL; /* add memberof to entry */ msg = ldb_msg_new(addop); if (!msg) return LDB_ERR_OPERATIONS_ERROR; msg->dn = addop->entry_dn; ret = ldb_msg_add_empty(msg, DB_MEMBEROF, LDB_FLAG_MOD_ADD, &el); if (ret != LDB_SUCCESS) { return ret; } el->values = talloc_array(msg, struct ldb_val, parents->num); if (!el->values) { return LDB_ERR_OPERATIONS_ERROR; } for (i = 0, j = 0; i < parents->num; i++) { if (ldb_dn_compare(parents->dns[i], msg->dn) == 0) continue; val = ldb_dn_get_linearized(parents->dns[i]); el->values[j].length = strlen(val); el->values[j].data = (uint8_t *)talloc_strdup(el->values, val); if (!el->values[j].data) { return LDB_ERR_OPERATIONS_ERROR; } j++; } el->num_values = j; ret = ldb_build_mod_req(&mod_req, ldb, add_ctx, msg, NULL, add_ctx, mbof_add_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } talloc_steal(mod_req, msg); return ldb_next_request(ctx->module, mod_req); } static int mbof_add_fill_ghop(struct mbof_add_ctx *add_ctx, struct ldb_message *entry, struct mbof_dn_array *parents) { struct ldb_message_element *ghel; ghel = ldb_msg_find_element(entry, DB_GHOST); if (ghel == NULL || ghel->num_values == 0) { /* No ghel attribute, just return success */ return LDB_SUCCESS; } return mbof_add_fill_ghop_ex(add_ctx, entry, parents, ghel->values, ghel->num_values); } static int mbof_add_missing(struct mbof_add_ctx *add_ctx, struct ldb_dn *dn) { struct mbof_dn *mdn; mdn = talloc(add_ctx, struct mbof_dn); if (!mdn) { return LDB_ERR_OPERATIONS_ERROR; } mdn->dn = talloc_steal(mdn, dn); /* add to the list */ mdn->next = add_ctx->missing; add_ctx->missing = mdn; return LDB_SUCCESS; } /* remove unexisting members and add memberuid attribute */ static int mbof_add_cleanup(struct mbof_add_ctx *add_ctx) { struct ldb_context *ldb; struct ldb_message *msg; struct ldb_request *mod_req; struct ldb_message_element *el; struct mbof_ctx *ctx; struct mbof_dn *iter; const char *val; int ret, i, num; ctx = add_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); num = 0; for (iter = add_ctx->missing; iter; iter = iter->next) { num++; } if (num == 0) { return LDB_ERR_OPERATIONS_ERROR; } msg = ldb_msg_new(add_ctx); if (!msg) return LDB_ERR_OPERATIONS_ERROR; msg->dn = add_ctx->msg_dn; ret = ldb_msg_add_empty(msg, DB_MEMBER, LDB_FLAG_MOD_DELETE, &el); if (ret != LDB_SUCCESS) { return ret; } el->values = talloc_array(msg, struct ldb_val, num); if (!el->values) { return LDB_ERR_OPERATIONS_ERROR; } el->num_values = num; for (i = 0, iter = add_ctx->missing; iter; iter = iter->next, i++) { val = ldb_dn_get_linearized(iter->dn); el->values[i].length = strlen(val); el->values[i].data = (uint8_t *)talloc_strdup(el->values, val); if (!el->values[i].data) { return LDB_ERR_OPERATIONS_ERROR; } } ret = ldb_build_mod_req(&mod_req, ldb, add_ctx, msg, NULL, add_ctx, mbof_add_cleanup_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_next_request(ctx->module, mod_req); } static int mbof_add_cleanup_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_add_ctx *add_ctx; struct mbof_ctx *ctx; int ret; add_ctx = talloc_get_type(req->context, struct mbof_add_ctx); ctx = add_ctx->ctx; if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: /* shouldn't happen */ talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: if (add_ctx->muops) { ret = mbof_add_muop(add_ctx); } else { return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } } talloc_zfree(ares); return LDB_SUCCESS; } /* add memberuid attributes to parent groups */ static int mbof_add_muop(struct mbof_add_ctx *add_ctx) { struct ldb_context *ldb; struct ldb_message *msg; struct ldb_request *mod_req; struct mbof_ctx *ctx; int ret; ctx = add_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); msg = ldb_msg_new(add_ctx); if (!msg) return LDB_ERR_OPERATIONS_ERROR; msg->dn = add_ctx->muops[add_ctx->cur_muop].dn; msg->elements = add_ctx->muops[add_ctx->cur_muop].el; msg->num_elements = 1; ret = ldb_build_mod_req(&mod_req, ldb, add_ctx, msg, NULL, add_ctx, mbof_add_muop_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_request_add_control(mod_req, LDB_CONTROL_PERMISSIVE_MODIFY_OID, false, NULL); if (ret != LDB_SUCCESS) { talloc_free(mod_req); return ret; } return ldb_next_request(ctx->module, mod_req); } static int mbof_add_muop_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_add_ctx *add_ctx; struct mbof_ctx *ctx; int ret; add_ctx = talloc_get_type(req->context, struct mbof_add_ctx); ctx = add_ctx->ctx; if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: /* shouldn't happen */ talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: add_ctx->cur_muop++; if (add_ctx->cur_muop < add_ctx->num_muops) { ret = mbof_add_muop(add_ctx); } else { return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } } talloc_zfree(ares); return LDB_SUCCESS; } /* delete operations */ /* The implementation of delete operations is a bit more complex than an add * operation. This is because we need to recompute memberships of potentially * quite far descendants and we also have to account for loops and how to * break them without ending in an endless loop ourselves. * The difficulty is in the fact that while the member -> memberof link is * direct, memberof -> member is not as membership is transitive. * * Ok, first of all, contrary to the add operation, a delete operation * involves an existing object that may have existing parents. So, first, we * search the object itself to get the original membership lists (member and * memberof) for this object, and we also search for any object that has it as * one of its members. * Once we have the results, we store object and parents and proceed with the * original operation to make sure it is valid. * * Once the original op returns we proceed fixing parents (parents being each * object that has the delete operation target object as member), if any. * * For each parent we retrieved we proceed to delete the member attribute that * points to the object we just deleted. Once done for all parents (or if no * parents exists), we proceed with the children and descendants. * * To handle the children we create a first ancestor operation that reflects * the delete we just made. We set as parents of this object the parents just * retrieved with the first search. Then we create a remove list. * * The remove list contains all objects in the original memberof list and the * object dn itself of the original delete operation target object (the first * ancestor). * * An operation is identified by an object that contains a tree of * descendants: * The remove list for the children, the immediate parent, and the dn and * entry of the object this operation is about. * * We now proceed with adding a new operation for each original member of the * first ancestor. * * In each operation we must first lookup the target object and each immediate * parent (all the objects in the tree that have target as a "member"). * * Then we proceed to calculate the new memberof list that we are going to set * on the target object. * The new memberof list starts with including all the objects that have the * target as their direct member. * Finally for each entry in this provisional new memberof list we add all its * memberof elements to the new memberof list (taking care of excluding * duplicates). This way we are certain all direct and indirect membership are * accounted for. * * At this point we have the final new memberof list for this operation and we * can proceed to modify the entry. * * Once the entry has been modified we proceed again to check if there are any * children of this entry (the entry has "member"s). * We create a new remove list that is the difference between the original * entry memberof list and the new memberof list we just stored back in the * object. * Then for each member we create a new operation. * * We continue to process operations until no new operations need to be * performed. * * Ordering is important here, se the mbof_del_get_next() function to * understand how we proceed to select which new operation to process. * * As a final operation remove any memberuid corresponding to a removal of * a memberof field from a user entry. Also if the original entry had a ghost * attribute, we need to remove that attribute from all its parents as well. * * There is one catch though - at the memberof level, we can't know if the * attribute being removed from a parent group is just inherited from the group * being removed or also a direct member of the parent group. To make sure * that the attribute is displayed next time the group is requested, we also * set expire the parent group at the same time. */ static int mbof_del_search_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_orig_del(struct mbof_del_ctx *ctx); static int mbof_orig_del_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_del_cleanup_parents(struct mbof_del_ctx *del_ctx); static int mbof_del_clean_par_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_del_cleanup_children(struct mbof_del_ctx *del_ctx); static int mbof_append_delop(struct mbof_del_operation *parent, struct ldb_dn *entry_dn); static int mbof_del_execute_op(struct mbof_del_operation *delop); static int mbof_del_exop_search_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_del_execute_cont(struct mbof_del_operation *delop); static int mbof_del_ancestors(struct mbof_del_operation *delop); static int mbof_del_anc_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_del_mod_entry(struct mbof_del_operation *delop); static int mbof_del_mod_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_del_progeny(struct mbof_del_operation *delop); static int mbof_del_get_next(struct mbof_del_operation *delop, struct mbof_del_operation **nextop); static int mbof_del_fill_muop(struct mbof_del_ctx *del_ctx, struct ldb_message *entry); static int mbof_del_fill_ghop(struct mbof_del_ctx *del_ctx, struct ldb_message *entry); static int mbof_del_muop(struct mbof_del_ctx *ctx); static int mbof_del_muop_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_del_ghop(struct mbof_del_ctx *del_ctx); static int mbof_del_ghop_callback(struct ldb_request *req, struct ldb_reply *ares); static void free_delop_contents(struct mbof_del_operation *delop); static int memberof_del(struct ldb_module *module, struct ldb_request *req) { static const char *attrs[] = { DB_OC, DB_NAME, DB_MEMBER, DB_MEMBEROF, DB_GHOST, NULL }; struct ldb_context *ldb = ldb_module_get_ctx(module); struct mbof_del_operation *first; struct ldb_request *search; char *expression; const char *dn; char *clean_dn; struct mbof_del_ctx *del_ctx; struct mbof_ctx *ctx; int ret; errno_t sret; if (ldb_dn_is_special(req->op.del.dn)) { /* do not manipulate our control entries */ return ldb_next_request(module, req); } ctx = mbof_init(module, req); if (!ctx) { return LDB_ERR_OPERATIONS_ERROR; } del_ctx = talloc_zero(ctx, struct mbof_del_ctx); if (!del_ctx) { talloc_free(ctx); return LDB_ERR_OPERATIONS_ERROR; } del_ctx->ctx = ctx; /* create first entry */ /* the first entry is the parent of all entries and the one where we remove * member from, it does not get the same treatment as others */ first = talloc_zero(del_ctx, struct mbof_del_operation); if (!first) { talloc_free(ctx); return LDB_ERR_OPERATIONS_ERROR; } del_ctx->first = first; first->del_ctx = del_ctx; first->entry_dn = req->op.del.dn; dn = ldb_dn_get_linearized(req->op.del.dn); if (!dn) { talloc_free(ctx); return LDB_ERR_OPERATIONS_ERROR; } sret = sss_filter_sanitize(del_ctx, dn, &clean_dn); if (sret != 0) { talloc_free(ctx); return LDB_ERR_OPERATIONS_ERROR; } expression = talloc_asprintf(del_ctx, "(|(distinguishedName=%s)(%s=%s))", clean_dn, DB_MEMBER, clean_dn); if (!expression) { talloc_free(ctx); return LDB_ERR_OPERATIONS_ERROR; } talloc_zfree(clean_dn); ret = ldb_build_search_req(&search, ldb, del_ctx, NULL, LDB_SCOPE_SUBTREE, expression, attrs, NULL, first, mbof_del_search_callback, req); if (ret != LDB_SUCCESS) { talloc_free(ctx); return ret; } return ldb_request(ldb, search); } static int mbof_del_search_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_del_operation *first; struct ldb_context *ldb; struct ldb_message *msg; struct mbof_del_ctx *del_ctx; struct mbof_ctx *ctx; int ret; first = talloc_get_type(req->context, struct mbof_del_operation); del_ctx = first->del_ctx; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: msg = ares->message; if (ldb_dn_compare(msg->dn, ctx->req->op.del.dn) == 0) { if (first->entry != NULL) { /* more than one entry per dn ?? db corrupted ? */ return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } first->entry = talloc_steal(first, msg); if (first->entry == NULL) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } } else { first->parents = talloc_realloc(first, first->parents, struct ldb_message *, first->num_parents + 1); if (!first->parents) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } msg = talloc_steal(first->parents, ares->message); if (!msg) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } first->parents[first->num_parents] = msg; first->num_parents++; } break; case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: if (first->entry == NULL) { /* this target does not exists, too bad! */ ldb_debug(ldb, LDB_DEBUG_TRACE, "Target entry (%s) not found", ldb_dn_get_linearized(first->entry_dn)); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_NO_SUCH_OBJECT); } /* now perform the requested delete, before proceeding further */ ret = mbof_orig_del(del_ctx); if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_orig_del(struct mbof_del_ctx *del_ctx) { struct ldb_request *del_req; struct mbof_ctx *ctx; int ret; ctx = del_ctx->ctx; ret = ldb_build_del_req(&del_req, ldb_module_get_ctx(ctx->module), ctx->req, ctx->req->op.del.dn, NULL, del_ctx, mbof_orig_del_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_next_request(ctx->module, del_req); } static int mbof_orig_del_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct mbof_del_ctx *del_ctx; struct mbof_ctx *ctx; int ret; del_ctx = talloc_get_type(req->context, struct mbof_del_ctx); ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } if (ares->type != LDB_REPLY_DONE) { talloc_zfree(ares); ldb_set_errstring(ldb, "Invalid reply type!"); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* save real call stuff */ ctx->ret_ctrls = talloc_steal(ctx, ares->controls); ctx->ret_resp = talloc_steal(ctx, ares->response); /* prep following clean ops */ if (del_ctx->first->num_parents) { /* if there are parents there may be memberuids to remove */ ret = mbof_del_fill_muop(del_ctx, del_ctx->first->entry); if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } /* ..or ghost attributes to remove */ ret = mbof_del_fill_ghop(del_ctx, del_ctx->first->entry); if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } /* if there are any parents, fire a removal sequence */ ret = mbof_del_cleanup_parents(del_ctx); } else if (ldb_msg_find_element(del_ctx->first->entry, DB_MEMBER)) { /* if there are any children, fire a removal sequence */ ret = mbof_del_cleanup_children(del_ctx); } /* see if there are memberuid operations to perform */ else if (del_ctx->muops) { return mbof_del_muop(del_ctx); } /* see if we need to remove some ghost users */ else if (del_ctx->ghops) { return mbof_del_ghop(del_ctx); } else { /* no parents nor children, end ops */ return ldb_module_done(ctx->req, ares->controls, ares->response, LDB_SUCCESS); } if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_del_cleanup_parents(struct mbof_del_ctx *del_ctx) { struct mbof_del_operation *first; struct mbof_ctx *ctx; struct ldb_context *ldb; struct ldb_request *mod_req; struct ldb_message *msg; struct ldb_message_element *el; const char *val; int ret; first = del_ctx->first; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); msg = ldb_msg_new(first->parents); if (!msg) return LDB_ERR_OPERATIONS_ERROR; msg->dn = first->parents[first->cur_parent]->dn; first->cur_parent++; ret = ldb_msg_add_empty(msg, DB_MEMBER, LDB_FLAG_MOD_DELETE, &el); if (ret != LDB_SUCCESS) { return ret; } el->values = talloc_array(msg, struct ldb_val, 1); if (!el->values) { return LDB_ERR_OPERATIONS_ERROR; } val = ldb_dn_get_linearized(first->entry_dn); el->values[0].length = strlen(val); el->values[0].data = (uint8_t *)talloc_strdup(el->values, val); if (!el->values[0].data) { return LDB_ERR_OPERATIONS_ERROR; } el->num_values = 1; ret = ldb_build_mod_req(&mod_req, ldb, first->parents, msg, NULL, del_ctx, mbof_del_clean_par_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_next_request(ctx->module, mod_req); } static int mbof_del_clean_par_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_del_operation *first; struct ldb_context *ldb; struct mbof_del_ctx *del_ctx; struct mbof_ctx *ctx; int ret; del_ctx = talloc_get_type(req->context, struct mbof_del_ctx); first = del_ctx->first; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } if (ares->type != LDB_REPLY_DONE) { talloc_zfree(ares); ldb_set_errstring(ldb, "Invalid reply type!"); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (first->num_parents > first->cur_parent) { /* still parents to cleanup, go on */ ret = mbof_del_cleanup_parents(del_ctx); } else { /* continue */ if (ldb_msg_find_element(first->entry, DB_MEMBER)) { /* if there are any children, fire a removal sequence */ ret = mbof_del_cleanup_children(del_ctx); } /* see if there are memberuid operations to perform */ else if (del_ctx->muops) { return mbof_del_muop(del_ctx); } /* see if we need to remove some ghost users */ else if (del_ctx->ghops) { return mbof_del_ghop(del_ctx); } else { /* no children, end ops */ return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } } if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_del_cleanup_children(struct mbof_del_ctx *del_ctx) { struct mbof_del_operation *first; struct mbof_ctx *ctx; struct ldb_context *ldb; const struct ldb_message_element *el; struct ldb_dn *valdn; int i, ret; first = del_ctx->first; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); el = ldb_msg_find_element(first->entry, DB_MEMBER); /* prepare del sets */ for (i = 0; i < el->num_values; i++) { valdn = ldb_dn_from_ldb_val(first, ldb, &el->values[i]); if (!valdn || !ldb_dn_validate(valdn)) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Invalid dn syntax for member [%s]", (const char *)el->values[i].data); return LDB_ERR_INVALID_DN_SYNTAX; } ret = mbof_append_delop(first, valdn); if (ret != LDB_SUCCESS) { return ret; } } /* now that sets are built, start processing */ return mbof_del_execute_op(first->children[0]); } static int mbof_append_delop(struct mbof_del_operation *parent, struct ldb_dn *entry_dn) { struct mbof_del_operation *delop; delop = talloc_zero(parent, struct mbof_del_operation); if (!delop) { return LDB_ERR_OPERATIONS_ERROR; } delop->del_ctx = parent->del_ctx; delop->parent = parent; delop->entry_dn = entry_dn; parent->children = talloc_realloc(parent, parent->children, struct mbof_del_operation *, parent->num_children +1); if (!parent->children) { talloc_free(delop); return LDB_ERR_OPERATIONS_ERROR; } parent->children[parent->num_children] = delop; parent->num_children++; return LDB_SUCCESS; } static int mbof_del_execute_op(struct mbof_del_operation *delop) { struct mbof_del_ctx *del_ctx; struct mbof_ctx *ctx; struct ldb_context *ldb; struct ldb_request *search; char *expression; const char *dn; char *clean_dn; static const char *attrs[] = { DB_OC, DB_NAME, DB_MEMBER, DB_MEMBEROF, NULL }; int ret; del_ctx = delop->del_ctx; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); /* load entry */ dn = ldb_dn_get_linearized(delop->entry_dn); if (!dn) { return LDB_ERR_OPERATIONS_ERROR; } ret = sss_filter_sanitize(del_ctx, dn, &clean_dn); if (ret != 0) { return LDB_ERR_OPERATIONS_ERROR; } expression = talloc_asprintf(del_ctx, "(|(distinguishedName=%s)(%s=%s))", clean_dn, DB_MEMBER, clean_dn); if (!expression) { return LDB_ERR_OPERATIONS_ERROR; } talloc_zfree(clean_dn); ret = ldb_build_search_req(&search, ldb, delop, NULL, LDB_SCOPE_SUBTREE, expression, attrs, NULL, delop, mbof_del_exop_search_callback, ctx->req); if (ret != LDB_SUCCESS) { talloc_free(ctx); return ret; } return ldb_request(ldb, search); } static int mbof_del_exop_search_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_del_operation *delop; struct mbof_del_ctx *del_ctx; struct ldb_context *ldb; struct mbof_ctx *ctx; struct ldb_message *msg; int ret; delop = talloc_get_type(req->context, struct mbof_del_operation); del_ctx = delop->del_ctx; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: msg = ares->message; if (ldb_dn_compare(msg->dn, delop->entry_dn) == 0) { if (delop->entry != NULL) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Found multiple entries for (%s)", ldb_dn_get_linearized(delop->entry_dn)); /* more than one entry per dn ?? db corrupted ? */ return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } delop->entry = talloc_steal(delop, msg); if (delop->entry == NULL) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } } else { delop->parents = talloc_realloc(delop, delop->parents, struct ldb_message *, delop->num_parents + 1); if (!delop->parents) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } msg = talloc_steal(delop->parents, msg); if (!msg) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } delop->parents[delop->num_parents] = msg; delop->num_parents++; } break; case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: if (delop->entry == NULL) { /* no target, no party! */ return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* ok process the entry */ ret = mbof_del_execute_cont(delop); if (ret != LDB_SUCCESS) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_del_execute_cont(struct mbof_del_operation *delop) { struct mbof_del_ancestors_ctx *anc_ctx; struct mbof_dn_array *new_list; int i; anc_ctx = talloc_zero(delop, struct mbof_del_ancestors_ctx); if (!anc_ctx) { return LDB_ERR_OPERATIONS_ERROR; } delop->anc_ctx = anc_ctx; new_list = talloc_zero(anc_ctx, struct mbof_dn_array); if (!new_list) { return LDB_ERR_OPERATIONS_ERROR; } /* at the very least we have a number of memberof elements * equal to the number of objects that have this entry as * direct member */ new_list->num = delop->num_parents; /* attach the list to the operation */ delop->anc_ctx->new_list = new_list; delop->anc_ctx->num_direct = new_list->num; /* do we have any direct parent at all ? */ if (new_list->num == 0) { /* no entries at all, entry ended up being orphaned */ /* skip to directly set the new memberof list for this entry */ return mbof_del_mod_entry(delop); } /* fill in the list if we have parents */ new_list->dns = talloc_zero_array(new_list, struct ldb_dn *, new_list->num); if (!new_list->dns) { return LDB_ERR_OPERATIONS_ERROR; } for (i = 0; i < delop->num_parents; i++) { new_list->dns[i] = delop->parents[i]->dn; } /* before proceeding we also need to fetch the ancestors (anew as some may * have changed by preceeding operations) */ return mbof_del_ancestors(delop); } static int mbof_del_ancestors(struct mbof_del_operation *delop) { struct mbof_del_ancestors_ctx *anc_ctx; struct mbof_del_ctx *del_ctx; struct mbof_ctx *ctx; struct ldb_context *ldb; struct mbof_dn_array *new_list; static const char *attrs[] = { DB_MEMBEROF, NULL }; struct ldb_request *search; int ret; del_ctx = delop->del_ctx; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); anc_ctx = delop->anc_ctx; new_list = anc_ctx->new_list; ret = ldb_build_search_req(&search, ldb, anc_ctx, new_list->dns[anc_ctx->cur], LDB_SCOPE_BASE, NULL, attrs, NULL, delop, mbof_del_anc_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_request(ldb, search); } static int mbof_del_anc_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_del_ancestors_ctx *anc_ctx; struct mbof_del_operation *delop; struct mbof_del_ctx *del_ctx; struct mbof_ctx *ctx; struct ldb_context *ldb; struct ldb_message *msg; const struct ldb_message_element *el; struct mbof_dn_array *new_list; struct ldb_dn *valdn; int i, j, ret; delop = talloc_get_type(req->context, struct mbof_del_operation); del_ctx = delop->del_ctx; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); anc_ctx = delop->anc_ctx; new_list = anc_ctx->new_list; if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: msg = ares->message; if (anc_ctx->entry != NULL) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Found multiple entries for (%s)", ldb_dn_get_linearized(anc_ctx->entry->dn)); /* more than one entry per dn ?? db corrupted ? */ return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } anc_ctx->entry = talloc_steal(anc_ctx, msg); if (anc_ctx->entry == NULL) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } break; case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: if (anc_ctx->entry == NULL) { /* no target, no party! */ return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* check entry */ el = ldb_msg_find_element(anc_ctx->entry, DB_MEMBEROF); if (el) { for (i = 0; i < el->num_values; i++) { valdn = ldb_dn_from_ldb_val(new_list, ldb, &el->values[i]); if (!valdn) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Invalid dn for memberof: (%s)", (const char *)el->values[i].data); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } for (j = 0; j < new_list->num; j++) { if (ldb_dn_compare(valdn, new_list->dns[j]) == 0) break; } if (j < new_list->num) { talloc_free(valdn); continue; } /* do not re-add the original deleted entry by mistake */ if (ldb_dn_compare(valdn, del_ctx->first->entry_dn) == 0) { talloc_free(valdn); continue; } new_list->dns = talloc_realloc(new_list, new_list->dns, struct ldb_dn *, new_list->num + 1); if (!new_list->dns) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } new_list->dns[new_list->num] = valdn; new_list->num++; } } /* done with this one */ talloc_free(anc_ctx->entry); anc_ctx->entry = NULL; anc_ctx->cur++; /* check if we need to process any more */ if (anc_ctx->cur < anc_ctx->num_direct) { /* ok process the next one */ ret = mbof_del_ancestors(delop); } else { /* ok, end of the story, proceed to modify the entry */ ret = mbof_del_mod_entry(delop); } if (ret != LDB_SUCCESS) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_del_mod_entry(struct mbof_del_operation *delop) { struct mbof_del_ctx *del_ctx; struct mbof_ctx *ctx; struct ldb_context *ldb; struct mbof_dn_array *new_list; struct ldb_request *mod_req; struct ldb_message *msg; struct ldb_message_element *el; struct ldb_dn **diff = NULL; const char *name; const char *val; int i, j, k; bool is_user; int ret; del_ctx = delop->del_ctx; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); new_list = delop->anc_ctx->new_list; /* if this is a user we need to find out which entries have been * removed so that we can later schedule removal of memberuid * attributes from these entries */ ret = entry_is_user_object(delop->entry); switch (ret) { case LDB_SUCCESS: /* it's a user object */ is_user = true; break; case LDB_ERR_NO_SUCH_ATTRIBUTE: /* it is not a user object, continue */ is_user = false; break; default: /* an error occurred, return */ return ret; } if (is_user) { /* prepare memberuid delete list */ /* copy all original memberof entries, and then later remove * the ones that will survive in the entry */ el = ldb_msg_find_element(delop->entry, DB_MEMBEROF); if (!el || !el->num_values) { return LDB_ERR_OPERATIONS_ERROR; } diff = talloc_array(del_ctx, struct ldb_dn *, el->num_values + 1); if (!diff) { return LDB_ERR_OPERATIONS_ERROR; } for (i = 0, j = 0; i < el->num_values; i++) { diff[j] = ldb_dn_from_ldb_val(diff, ldb, &el->values[i]); if (!diff[j]) { return LDB_ERR_OPERATIONS_ERROR; } /* skip the deleted entry if this is a delete op */ if (!del_ctx->is_mod) { if (ldb_dn_compare(del_ctx->first->entry_dn, diff[j]) == 0) { continue; } } j++; } /* zero terminate array */ diff[j] = NULL; } /* change memberof on entry */ msg = ldb_msg_new(delop); if (!msg) return LDB_ERR_OPERATIONS_ERROR; msg->dn = delop->entry_dn; if (new_list->num) { ret = ldb_msg_add_empty(msg, DB_MEMBEROF, LDB_FLAG_MOD_REPLACE, &el); if (ret != LDB_SUCCESS) { return ret; } el->values = talloc_array(el, struct ldb_val, new_list->num); if (!el->values) { return LDB_ERR_OPERATIONS_ERROR; } for (i = 0, j = 0; i < new_list->num; i++) { if (ldb_dn_compare(new_list->dns[i], msg->dn) == 0) continue; val = ldb_dn_get_linearized(new_list->dns[i]); if (!val) { return LDB_ERR_OPERATIONS_ERROR; } el->values[j].length = strlen(val); el->values[j].data = (uint8_t *)talloc_strdup(el->values, val); if (!el->values[j].data) { return LDB_ERR_OPERATIONS_ERROR; } j++; if (is_user) { /* compare the entry's original memberof list with the new * one and for each missing entry add a memberuid removal * operation */ for (k = 0; diff[k]; k++) { if (ldb_dn_compare(new_list->dns[i], diff[k]) == 0) { break; } } if (diff[k]) { talloc_zfree(diff[k]); for (; diff[k + 1]; k++) { diff[k] = diff[k + 1]; } diff[k] = NULL; } } } el->num_values = j; } else { ret = ldb_msg_add_empty(msg, DB_MEMBEROF, LDB_FLAG_MOD_DELETE, &el); if (ret != LDB_SUCCESS) { return ret; } } if (is_user && diff[0]) { /* file memberuid removal operations */ name = ldb_msg_find_attr_as_string(delop->entry, DB_NAME, NULL); if (!name) { return LDB_ERR_OPERATIONS_ERROR; } for (i = 0; diff[i]; i++) { ret = mbof_append_muop(del_ctx, &del_ctx->muops, &del_ctx->num_muops, LDB_FLAG_MOD_DELETE, diff[i], name, DB_MEMBERUID); if (ret != LDB_SUCCESS) { return ret; } talloc_steal(del_ctx->muops, diff[i]); } } ret = ldb_build_mod_req(&mod_req, ldb, delop, msg, NULL, delop, mbof_del_mod_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } talloc_steal(mod_req, msg); return ldb_next_request(ctx->module, mod_req); } static int mbof_del_mod_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_del_operation *delop; struct mbof_del_ctx *del_ctx; struct ldb_context *ldb; struct mbof_ctx *ctx; int ret; delop = talloc_get_type(req->context, struct mbof_del_operation); del_ctx = delop->del_ctx; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: ldb_debug(ldb, LDB_DEBUG_TRACE, "Got an entry on a non search op ?!"); /* shouldn't happen */ talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); case LDB_REPLY_REFERRAL: /* ignore */ talloc_zfree(ares); break; case LDB_REPLY_DONE: ret = mbof_del_progeny(delop); if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } } return LDB_SUCCESS; } static int mbof_mod_add(struct mbof_mod_ctx *mod_ctx, struct mbof_dn_array *ael, struct mbof_val_array *addgh); static int mbof_del_progeny(struct mbof_del_operation *delop) { struct mbof_ctx *ctx; struct mbof_del_ctx *del_ctx; struct mbof_del_operation *nextop; const struct ldb_message_element *el; struct ldb_context *ldb; struct ldb_dn *valdn; int i, ret; del_ctx = delop->del_ctx; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); /* now verify if this entry is a group and members need to be processed as * well */ el = ldb_msg_find_element(delop->entry, DB_MEMBER); if (el) { for (i = 0; i < el->num_values; i++) { valdn = ldb_dn_from_ldb_val(delop, ldb, &el->values[i]); if (!valdn || !ldb_dn_validate(valdn)) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Invalid DN for member: (%s)", (const char *)el->values[i].data); return LDB_ERR_INVALID_DN_SYNTAX; } ret = mbof_append_delop(delop, valdn); if (ret != LDB_SUCCESS) { return ret; } } } /* finally find the next entry to handle */ ret = mbof_del_get_next(delop, &nextop); if (ret != LDB_SUCCESS) { return ret; } free_delop_contents(delop); if (nextop) { return mbof_del_execute_op(nextop); } /* see if there are memberuid operations to perform */ if (del_ctx->muops) { return mbof_del_muop(del_ctx); } /* see if we need to remove some ghost users */ else if (del_ctx->ghops) { return mbof_del_ghop(del_ctx); } /* see if there are follow functions to run */ if (del_ctx->follow_mod) { return mbof_mod_add(del_ctx->follow_mod, del_ctx->follow_mod->mb_add, del_ctx->follow_mod->gh_add); } /* ok, no more ops, this means our job is done */ return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } static int mbof_del_get_next(struct mbof_del_operation *delop, struct mbof_del_operation **nextop) { struct mbof_del_operation *top, *cop; struct mbof_del_ctx *del_ctx; struct mbof_dn *save, *tmp; del_ctx = delop->del_ctx; /* first of all, save the current delop in the history */ save = talloc_zero(del_ctx, struct mbof_dn); if (!save) { return LDB_ERR_OPERATIONS_ERROR; } save->dn = delop->entry_dn; if (del_ctx->history) { tmp = del_ctx->history; while (tmp->next) tmp = tmp->next; tmp->next = save; } else { del_ctx->history = save; } /* Find next one */ for (top = delop; top; top = top->parent) { if (top->num_children == 0 || top->next_child >= top->num_children) { /* no children, go for next one */ continue; } while (top->next_child < top->num_children) { cop = top->children[top->next_child]; top->next_child++; /* verify this operation has not already been performed */ for (tmp = del_ctx->history; tmp; tmp = tmp->next) { if (ldb_dn_compare(tmp->dn, cop->entry_dn) == 0) { break; } } if (tmp == NULL) { /* and return the current one */ *nextop = cop; return LDB_SUCCESS; } } } /* we have no more ops */ *nextop = NULL; return LDB_SUCCESS; } static int mbof_del_fill_muop(struct mbof_del_ctx *del_ctx, struct ldb_message *entry) { struct ldb_message_element *el; char *name; int ret; int i; el = ldb_msg_find_element(entry, DB_MEMBEROF); if (!el || el->num_values == 0) { /* no memberof attributes ... */ return LDB_SUCCESS; } ret = entry_is_user_object(entry); switch (ret) { case LDB_SUCCESS: /* it's a user object, continue */ break; case LDB_ERR_NO_SUCH_ATTRIBUTE: /* it is not a user object, just return */ return LDB_SUCCESS; default: /* an error occurred, return */ return ret; } name = talloc_strdup(del_ctx, ldb_msg_find_attr_as_string(entry, DB_NAME, NULL)); if (!name) { return LDB_ERR_OPERATIONS_ERROR; } for (i = 0; i < el->num_values; i++) { struct ldb_dn *valdn; valdn = ldb_dn_from_ldb_val(del_ctx, ldb_module_get_ctx(del_ctx->ctx->module), &el->values[i]); if (!valdn || !ldb_dn_validate(valdn)) { ldb_debug(ldb_module_get_ctx(del_ctx->ctx->module), LDB_DEBUG_ERROR, "Invalid dn value: [%s]", (const char *)el->values[i].data); } ret = mbof_append_muop(del_ctx, &del_ctx->muops, &del_ctx->num_muops, LDB_FLAG_MOD_DELETE, valdn, name, DB_MEMBERUID); if (ret != LDB_SUCCESS) { return ret; } talloc_steal(del_ctx->muops, valdn); } return LDB_SUCCESS; } static int mbof_del_fill_ghop_ex(struct mbof_del_ctx *del_ctx, struct ldb_message *entry, struct ldb_val *ghvals, unsigned int num_gh_vals) { struct ldb_message_element *mbof; struct ldb_dn *valdn; int ret; int i, j; mbof = ldb_msg_find_element(entry, DB_MEMBEROF); if (!mbof || mbof->num_values == 0) { /* no memberof attributes ... */ return LDB_SUCCESS; } ret = entry_is_group_object(entry); switch (ret) { case LDB_SUCCESS: /* it's a group object, continue */ break; case LDB_ERR_NO_SUCH_ATTRIBUTE: /* it is not a group object, just return */ return LDB_SUCCESS; default: /* an error occurred, return */ return ret; } ldb_debug(ldb_module_get_ctx(del_ctx->ctx->module), LDB_DEBUG_TRACE, "will delete %d ghost users from %d parents\n", num_gh_vals, mbof->num_values); for (i = 0; i < mbof->num_values; i++) { valdn = ldb_dn_from_ldb_val(del_ctx, ldb_module_get_ctx(del_ctx->ctx->module), &mbof->values[i]); if (!valdn || !ldb_dn_validate(valdn)) { ldb_debug(ldb_module_get_ctx(del_ctx->ctx->module), LDB_DEBUG_ERROR, "Invalid dn value: [%s]", (const char *)mbof->values[i].data); } ldb_debug(ldb_module_get_ctx(del_ctx->ctx->module), LDB_DEBUG_TRACE, "processing ghosts in parent [%s]\n", (const char *) mbof->values[i].data); for (j = 0; j < num_gh_vals; j++) { ret = mbof_append_muop(del_ctx, &del_ctx->ghops, &del_ctx->num_ghops, LDB_FLAG_MOD_DELETE, valdn, (const char *) ghvals[j].data, DB_GHOST); if (ret != LDB_SUCCESS) { return ret; } talloc_steal(del_ctx->ghops, valdn); } } return LDB_SUCCESS; } static int mbof_del_fill_ghop(struct mbof_del_ctx *del_ctx, struct ldb_message *entry) { struct ldb_message_element *ghel; ghel = ldb_msg_find_element(entry, DB_GHOST); if (ghel == NULL || ghel->num_values == 0) { /* No ghel attribute, just return success */ return LDB_SUCCESS; } return mbof_del_fill_ghop_ex(del_ctx, entry, ghel->values, ghel->num_values); } /* del memberuid attributes from parent groups */ static int mbof_del_muop(struct mbof_del_ctx *del_ctx) { struct ldb_context *ldb; struct ldb_message *msg; struct ldb_request *mod_req; struct mbof_ctx *ctx; int ret; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); msg = ldb_msg_new(del_ctx); if (!msg) return LDB_ERR_OPERATIONS_ERROR; msg->dn = del_ctx->muops[del_ctx->cur_muop].dn; msg->elements = del_ctx->muops[del_ctx->cur_muop].el; msg->num_elements = 1; ret = ldb_build_mod_req(&mod_req, ldb, del_ctx, msg, NULL, del_ctx, mbof_del_muop_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_next_request(ctx->module, mod_req); } static int mbof_del_muop_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_del_ctx *del_ctx; struct mbof_ctx *ctx; int ret; del_ctx = talloc_get_type(req->context, struct mbof_del_ctx); ctx = del_ctx->ctx; if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* if the attribute was not present it means the db is not * perfectly consistent but failing here is not useful * anyway and missing entries cause no harm if we are trying * to remove them anyway */ if (ares->error != LDB_SUCCESS && ares->error != LDB_ERR_NO_SUCH_ATTRIBUTE) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: /* shouldn't happen */ talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: del_ctx->cur_muop++; if (del_ctx->cur_muop < del_ctx->num_muops) { ret = mbof_del_muop(del_ctx); } /* see if we need to remove some ghost users */ else if (del_ctx->ghops) { return mbof_del_ghop(del_ctx); } /* see if there are follow functions to run */ else if (del_ctx->follow_mod) { return mbof_mod_add(del_ctx->follow_mod, del_ctx->follow_mod->mb_add, del_ctx->follow_mod->gh_add); } else { return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } } talloc_zfree(ares); return LDB_SUCCESS; } /* del ghost attributes from parent groups */ static int mbof_del_ghop(struct mbof_del_ctx *del_ctx) { struct ldb_context *ldb; struct ldb_message *msg; struct ldb_request *mod_req; struct mbof_ctx *ctx; int ret; ctx = del_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); msg = ldb_msg_new(del_ctx); if (!msg) return LDB_ERR_OPERATIONS_ERROR; msg->dn = del_ctx->ghops[del_ctx->cur_ghop].dn; ret = ldb_msg_add(msg, del_ctx->ghops[del_ctx->cur_ghop].el, LDB_FLAG_MOD_DELETE); if (ret != LDB_SUCCESS) { return ret; } /* Also expire any parent groups to force reloading direct members in * case the ghost users we remove now were actually *also* direct members * of the parent groups */ ret = ldb_msg_add_empty(msg, DB_CACHE_EXPIRE, LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_msg_add_string(msg, DB_CACHE_EXPIRE, "1"); if (ret != LDB_SUCCESS) { return ret; } ret = ldb_build_mod_req(&mod_req, ldb, del_ctx, msg, NULL, del_ctx, mbof_del_ghop_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_next_request(ctx->module, mod_req); } static int mbof_del_ghop_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_del_ctx *del_ctx; struct mbof_ctx *ctx; int ret; del_ctx = talloc_get_type(req->context, struct mbof_del_ctx); ctx = del_ctx->ctx; if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* We must treat no such attribute as non-fatal b/c the entry * might have been directly nested in the parent as well and * updated with another replace operation. */ if (ares->error != LDB_SUCCESS && ares->error != LDB_ERR_NO_SUCH_ATTRIBUTE) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: /* shouldn't happen */ talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: del_ctx->cur_ghop++; if (del_ctx->cur_ghop < del_ctx->num_ghops) { ret = mbof_del_ghop(del_ctx); } /* see if there are follow functions to run */ else if (del_ctx->follow_mod) { return mbof_mod_add(del_ctx->follow_mod, del_ctx->follow_mod->mb_add, del_ctx->follow_mod->gh_add); } else { return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } } talloc_zfree(ares); return LDB_SUCCESS; } /* delop may carry on a lot of memory, so we need a function to clean up * the payload without breaking the delop chain */ static void free_delop_contents(struct mbof_del_operation *delop) { talloc_zfree(delop->entry); talloc_zfree(delop->parents); talloc_zfree(delop->anc_ctx); delop->num_parents = 0; delop->cur_parent = 0; } /* mod operation */ /* A modify operation just implements either an add operation, or a delete * operation or both (replace) in turn. * One difference between a modify and a pure add or a pure delete is that * the object is not created a new or not completely removed, but the setup just * treats it in the same way children objects are treated in a pure add or delete * operation. A list of appropriate parents and objects to modify is built, then * we jump directly in the add or delete code. * If both add and delete are necessary, delete operations are performed first * and then a followup add operation is concatenated * * Another difference is the ghost users. Because of its semi-managed nature, * the ghost attribute requires some special care. During a modify operation, the * ghost attribute can be set to a new list. That list coming, from an * application, would typically only include the direct ghost * members. However, we want to keep both direct and indirect ghost members * in the cache to be able to return them all in a single call. To solve * that problem, we also iterate over members of the group being modified, * collect all ghost entries and add them back in case the original modify * operation wiped them out. */ static int mbof_mod_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_collect_child_ghosts(struct mbof_mod_ctx *mod_ctx); static int mbof_get_ghost_from_parent(struct mbof_mod_del_op *igh); static int mbof_get_ghost_from_parent_cb(struct ldb_request *req, struct ldb_reply *ares); static int mbof_orig_mod(struct mbof_mod_ctx *mod_ctx); static int mbof_orig_mod_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_inherited_mod(struct mbof_mod_ctx *mod_ctx); static int mbof_inherited_mod_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_mod_process(struct mbof_mod_ctx *mod_ctx, bool *done); static int mbof_mod_process_membel(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldb_message *entry, const struct ldb_message_element *membel, struct mbof_dn_array **_added, struct mbof_dn_array **_removed); static int mbof_mod_process_ghel(TALLOC_CTX *mem_ctx, struct ldb_message *entry, const struct ldb_message_element *ghel, const struct ldb_message_element *inherited, struct mbof_val_array **_added, struct mbof_val_array **_removed); static int mbof_mod_delete(struct mbof_mod_ctx *mod_ctx, struct mbof_dn_array *del, struct mbof_val_array *delgh); static int mbof_fill_dn_array(TALLOC_CTX *memctx, struct ldb_context *ldb, const struct ldb_message_element *el, struct mbof_dn_array **dn_array); static int mbof_fill_vals_array(TALLOC_CTX *memctx, unsigned int num_values, struct ldb_val *values, struct mbof_val_array **val_array); static int mbof_fill_vals_array_el(TALLOC_CTX *memctx, const struct ldb_message_element *el, struct mbof_val_array **val_array); static int memberof_mod(struct ldb_module *module, struct ldb_request *req) { struct ldb_message_element *el; struct mbof_mod_ctx *mod_ctx; struct mbof_ctx *ctx; static const char *attrs[] = { DB_OC, DB_GHOST, DB_MEMBER, DB_MEMBEROF, NULL}; struct ldb_context *ldb = ldb_module_get_ctx(module); struct ldb_request *search; int ret; if (ldb_dn_is_special(req->op.mod.message->dn)) { /* do not manipulate our control entries */ return ldb_next_request(module, req); } /* check if memberof is specified */ el = ldb_msg_find_element(req->op.mod.message, DB_MEMBEROF); if (el) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: the memberof attribute is readonly."); return LDB_ERR_UNWILLING_TO_PERFORM; } /* check if memberuid is specified */ el = ldb_msg_find_element(req->op.mod.message, DB_MEMBERUID); if (el) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: the memberuid attribute is readonly."); return LDB_ERR_UNWILLING_TO_PERFORM; } ctx = mbof_init(module, req); if (!ctx) { return LDB_ERR_OPERATIONS_ERROR; } mod_ctx = talloc_zero(ctx, struct mbof_mod_ctx); if (!mod_ctx) { talloc_free(ctx); return LDB_ERR_OPERATIONS_ERROR; } mod_ctx->ctx = ctx; mod_ctx->msg = ldb_msg_copy(mod_ctx, req->op.mod.message); if (!mod_ctx->msg) { return LDB_ERR_OPERATIONS_ERROR; } mod_ctx->membel = ldb_msg_find_element(mod_ctx->msg, DB_MEMBER); mod_ctx->ghel = ldb_msg_find_element(mod_ctx->msg, DB_GHOST); /* continue with normal ops if there are no members and no ghosts */ if (mod_ctx->membel == NULL && mod_ctx->ghel == NULL) { mod_ctx->terminate = true; return mbof_orig_mod(mod_ctx); } /* can't do anything, * must check first what's on the entry */ ret = ldb_build_search_req(&search, ldb, mod_ctx, mod_ctx->msg->dn, LDB_SCOPE_BASE, NULL, attrs, NULL, mod_ctx, mbof_mod_callback, req); if (ret != LDB_SUCCESS) { talloc_free(ctx); return ret; } return ldb_request(ldb, search); } static int mbof_mod_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_mod_ctx *mod_ctx; struct ldb_context *ldb; struct mbof_ctx *ctx; int ret; mod_ctx = talloc_get_type(req->context, struct mbof_mod_ctx); ctx = mod_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: if (mod_ctx->entry != NULL) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Found multiple entries for (%s)", ldb_dn_get_linearized(mod_ctx->msg->dn)); /* more than one entry per dn ?? db corrupted ? */ return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } mod_ctx->entry = talloc_steal(mod_ctx, ares->message); if (mod_ctx->entry == NULL) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } break; case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: if (mod_ctx->entry == NULL) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Entry not found (%s)", ldb_dn_get_linearized(mod_ctx->msg->dn)); /* this target does not exists, too bad! */ return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_NO_SUCH_OBJECT); } ret = mbof_collect_child_ghosts(mod_ctx); if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_collect_child_ghosts(struct mbof_mod_ctx *mod_ctx) { int ret; const struct ldb_message_element *member; member = ldb_msg_find_element(mod_ctx->entry, DB_MEMBER); if (member == NULL || member->num_values == 0 || mod_ctx->ghel == NULL || mod_ctx->ghel->flags != LDB_FLAG_MOD_REPLACE) { ret = mbof_orig_mod(mod_ctx); if (ret != LDB_SUCCESS) { return ret; } return LDB_SUCCESS; } mod_ctx->igh = talloc_zero(mod_ctx, struct mbof_mod_del_op); if (mod_ctx->igh == NULL) { return LDB_ERR_OPERATIONS_ERROR; } mod_ctx->igh->mod_ctx = mod_ctx; ret = hash_create_ex(1024, &mod_ctx->igh->inherited_gh, 0, 0, 0, 0, hash_alloc, hash_free, mod_ctx, NULL, NULL); if (ret != HASH_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } return mbof_get_ghost_from_parent(mod_ctx->igh); } static int mbof_get_ghost_from_parent(struct mbof_mod_del_op *igh) { struct ldb_request *search; struct ldb_context *ldb; struct mbof_ctx *ctx; int ret; static const char *attrs[] = { DB_GHOST, NULL }; char *expression; char *clean_dn; const char *dn; ctx = igh->mod_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); dn = ldb_dn_get_linearized(igh->mod_ctx->entry->dn); if (!dn) { talloc_free(ctx); return LDB_ERR_OPERATIONS_ERROR; } ret = sss_filter_sanitize(igh, dn, &clean_dn); if (ret != 0) { return LDB_ERR_OPERATIONS_ERROR; } expression = talloc_asprintf(igh, "(&(%s=%s)(%s=%s))", DB_OC, DB_GROUP_CLASS, DB_MEMBEROF, clean_dn); if (!expression) { return LDB_ERR_OPERATIONS_ERROR; } talloc_zfree(clean_dn); ret = ldb_build_search_req(&search, ldb, igh, NULL, LDB_SCOPE_SUBTREE, expression, attrs, NULL, igh, mbof_get_ghost_from_parent_cb, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_request(ldb, search); } static int mbof_get_ghost_from_parent_cb(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_mod_del_op *igh; struct mbof_ctx *ctx; struct ldb_message_element *el; struct ldb_val *dupval; int ret; hash_value_t value; hash_key_t key; int i; igh = talloc_get_type(req->context, struct mbof_mod_del_op); ctx = igh->mod_ctx->ctx; if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: el = ldb_msg_find_element(ares->message, DB_GHOST); if (!el) { break; } for (i=0; i < el->num_values; i++) { key.type = HASH_KEY_STRING; key.str = (char *) el->values[i].data; if (hash_has_key(igh->inherited_gh, &key)) { /* We already have this user. Don't re-add him */ continue; } dupval = talloc_zero(igh->inherited_gh, struct ldb_val); if (dupval == NULL) { return LDB_ERR_OPERATIONS_ERROR; } *dupval = ldb_val_dup(igh->inherited_gh, &el->values[i]); if (dupval->data == NULL) { return LDB_ERR_OPERATIONS_ERROR; } value.type = HASH_VALUE_PTR; value.ptr = dupval; ret = hash_enter(igh->inherited_gh, &key, &value); if (ret != HASH_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } } break; case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: /* All the children are gathered, let's do the real * modify operation */ ret = mbof_orig_mod(igh->mod_ctx); if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } break; } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_orig_mod(struct mbof_mod_ctx *mod_ctx) { struct ldb_request *mod_req; struct ldb_context *ldb; struct mbof_ctx *ctx; int ret; ctx = mod_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); ret = ldb_build_mod_req(&mod_req, ldb, ctx->req, mod_ctx->msg, ctx->req->controls, mod_ctx, mbof_orig_mod_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_next_request(ctx->module, mod_req); } static int mbof_orig_mod_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct mbof_mod_ctx *mod_ctx; struct mbof_ctx *ctx; int ret; mod_ctx = talloc_get_type(req->context, struct mbof_mod_ctx); ctx = mod_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } if (ares->type != LDB_REPLY_DONE) { talloc_zfree(ares); ldb_debug(ldb, LDB_DEBUG_TRACE, "Invalid reply type!"); ldb_set_errstring(ldb, "Invalid reply type!"); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } /* save real call stuff */ ctx->ret_ctrls = talloc_steal(ctx, ares->controls); ctx->ret_resp = talloc_steal(ctx, ares->response); if (!mod_ctx->terminate) { /* next step */ if (mod_ctx->igh && mod_ctx->igh->inherited_gh && hash_count(mod_ctx->igh->inherited_gh) > 0) { ret = mbof_inherited_mod(mod_ctx); } else { ret = mbof_mod_process(mod_ctx, &mod_ctx->terminate); } if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } } if (mod_ctx->terminate) { talloc_zfree(ares); return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_inherited_mod(struct mbof_mod_ctx *mod_ctx) { struct ldb_request *mod_req; struct ldb_context *ldb; struct mbof_ctx *ctx; int ret; struct ldb_message_element *el; struct ldb_message *msg; struct ldb_val *val; struct ldb_val *dupval; hash_value_t *values; unsigned long num_values; int i, j; ctx = mod_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); /* add back the inherited children to entry */ msg = ldb_msg_new(mod_ctx); if (!msg) return LDB_ERR_OPERATIONS_ERROR; msg->dn = mod_ctx->entry->dn; /* We only inherit during replaces, so it's safe to only look * at the replaced set */ ret = ldb_msg_add_empty(msg, DB_GHOST, LDB_FLAG_MOD_ADD, &el); if (ret != LDB_SUCCESS) { return ret; } ret = hash_values(mod_ctx->igh->inherited_gh, &num_values, &values); if (ret != HASH_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } el->values = talloc_array(msg, struct ldb_val, num_values); if (!el->values) { return LDB_ERR_OPERATIONS_ERROR; } for (i = 0, j = 0; i < num_values; i++) { val = talloc_get_type(values[i].ptr, struct ldb_val); dupval = ldb_msg_find_val(mod_ctx->ghel, val); if (dupval) { continue; } el->values[j].length = strlen((const char *) val->data); el->values[j].data = (uint8_t *) talloc_strdup(el->values, (const char *) val->data); if (!el->values[j].data) { return LDB_ERR_OPERATIONS_ERROR; } j++; } el->num_values = j; if (el->num_values == 0) { /* nothing to do */ /* We cannot modify element which has 0 values */ msg->num_elements = 0; } mod_ctx->igh->mod_msg = msg; mod_ctx->igh->el = el; ret = ldb_build_mod_req(&mod_req, ldb, ctx->req, msg, ctx->req->controls, mod_ctx, mbof_inherited_mod_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_next_request(ctx->module, mod_req); } static int mbof_inherited_mod_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct mbof_mod_ctx *mod_ctx; struct mbof_ctx *ctx; int ret; mod_ctx = talloc_get_type(req->context, struct mbof_mod_ctx); ctx = mod_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } if (ares->type != LDB_REPLY_DONE) { talloc_zfree(ares); ldb_debug(ldb, LDB_DEBUG_TRACE, "Invalid reply type!"); ldb_set_errstring(ldb, "Invalid reply type!"); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } ret = mbof_mod_process(mod_ctx, &mod_ctx->terminate); if (ret != LDB_SUCCESS) { talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, ret); } if (mod_ctx->terminate) { talloc_zfree(ares); return ldb_module_done(ctx->req, ctx->ret_ctrls, ctx->ret_resp, LDB_SUCCESS); } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_mod_process(struct mbof_mod_ctx *mod_ctx, bool *done) { struct ldb_context *ldb; struct mbof_ctx *ctx; int ret; ctx = mod_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); ret = mbof_mod_process_membel(mod_ctx, ldb, mod_ctx->entry, mod_ctx->membel, &mod_ctx->mb_add, &mod_ctx->mb_remove); if (ret != LDB_SUCCESS) { return ret; } ret = mbof_mod_process_ghel(mod_ctx, mod_ctx->entry, mod_ctx->ghel, mod_ctx->igh ? mod_ctx->igh->el : NULL, &mod_ctx->gh_add, &mod_ctx->gh_remove); if (ret != LDB_SUCCESS) { return ret; } /* Process the operations */ /* if we have something to remove do it first */ if ((mod_ctx->mb_remove && mod_ctx->mb_remove->num) || (mod_ctx->gh_remove && mod_ctx->gh_remove->num)) { return mbof_mod_delete(mod_ctx, mod_ctx->mb_remove, mod_ctx->gh_remove); } /* if there is nothing to remove and we have stuff to add * do it right away */ if ((mod_ctx->mb_add && mod_ctx->mb_add->num) || (mod_ctx->gh_add && mod_ctx->gh_add->num)) { return mbof_mod_add(mod_ctx, mod_ctx->mb_add, mod_ctx->gh_add); } /* the replacement function resulted in a null op, * nothing to do, return happily */ *done = true; return LDB_SUCCESS; } static int mbof_mod_process_membel(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldb_message *entry, const struct ldb_message_element *membel, struct mbof_dn_array **_added, struct mbof_dn_array **_removed) { const struct ldb_message_element *el; struct mbof_dn_array *removed = NULL; struct mbof_dn_array *added = NULL; int i, j, ret; if (!membel) { /* Nothing to do.. */ return LDB_SUCCESS; } switch (membel->flags) { case LDB_FLAG_MOD_ADD: ret = mbof_fill_dn_array(mem_ctx, ldb, membel, &added); if (ret != LDB_SUCCESS) { return ret; } break; case LDB_FLAG_MOD_DELETE: if (membel->num_values == 0) { el = ldb_msg_find_element(entry, DB_MEMBER); } else { el = membel; } if (!el) { /* nothing to do really */ break; } ret = mbof_fill_dn_array(mem_ctx, ldb, el, &removed); if (ret != LDB_SUCCESS) { return ret; } break; case LDB_FLAG_MOD_REPLACE: removed = NULL; el = ldb_msg_find_element(entry, DB_MEMBER); if (el) { ret = mbof_fill_dn_array(mem_ctx, ldb, el, &removed); if (ret != LDB_SUCCESS) { return ret; } } added = NULL; el = membel; if (el) { ret = mbof_fill_dn_array(mem_ctx, ldb, el, &added); if (ret != LDB_SUCCESS) { talloc_free(removed); return ret; } } /* remove from arrays values that ended up unchanged */ if (removed && removed->num && added && added->num) { for (i = 0; i < added->num; i++) { for (j = 0; j < removed->num; j++) { if (ldb_dn_compare(added->dns[i], removed->dns[j]) == 0) { break; } } if (j < removed->num) { /* preexisting one, not removed, nor added */ for (; j+1 < removed->num; j++) { removed->dns[j] = removed->dns[j+1]; } removed->num--; for (j = i; j+1 < added->num; j++) { added->dns[j] = added->dns[j+1]; } added->num--; i--; } } } break; default: return LDB_ERR_OPERATIONS_ERROR; } *_added = added; *_removed = removed; return LDB_SUCCESS; } static int mbof_mod_process_ghel(TALLOC_CTX *mem_ctx, struct ldb_message *entry, const struct ldb_message_element *ghel, const struct ldb_message_element *inherited, struct mbof_val_array **_added, struct mbof_val_array **_removed) { const struct ldb_message_element *el; struct mbof_val_array *removed = NULL; struct mbof_val_array *added = NULL; int i, j, ret; if (!ghel) { /* Nothing to do.. */ return LDB_SUCCESS; } el = ldb_msg_find_element(entry, DB_MEMBEROF); if (!el || el->num_values == 0) { /* no memberof attributes ... */ return LDB_SUCCESS; } switch (ghel->flags) { case LDB_FLAG_MOD_ADD: ret = mbof_fill_vals_array_el(mem_ctx, ghel, &added); if (ret != LDB_SUCCESS) { return ret; } break; case LDB_FLAG_MOD_DELETE: if (ghel->num_values == 0) { el = ldb_msg_find_element(entry, DB_GHOST); } else { el = ghel; } if (!el) { /* nothing to do really */ break; } ret = mbof_fill_vals_array_el(mem_ctx, ghel, &removed); if (ret != LDB_SUCCESS) { return ret; } break; case LDB_FLAG_MOD_REPLACE: el = ldb_msg_find_element(entry, DB_GHOST); if (el) { ret = mbof_fill_vals_array_el(mem_ctx, el, &removed); if (ret != LDB_SUCCESS) { return ret; } } el = ghel; if (el) { ret = mbof_fill_vals_array_el(mem_ctx, el, &added); if (ret != LDB_SUCCESS) { talloc_free(removed); return ret; } } if (inherited) { ret = mbof_fill_vals_array_el(mem_ctx, inherited, &added); if (ret != LDB_SUCCESS) { talloc_free(added); talloc_free(removed); return ret; } } /* remove from arrays values that ended up unchanged */ if (removed && removed->num && added && added->num) { for (i = 0; i < added->num; i++) { for (j = 0; j < removed->num; j++) { if (strcmp((const char *) added->vals[i].data, (const char *) removed->vals[j].data) == 0) { break; } } if (j < removed->num) { /* preexisting one, not removed, nor added */ for (; j+1 < removed->num; j++) { removed->vals[j] = removed->vals[j+1]; } removed->num--; for (j = i; j+1 < added->num; j++) { added->vals[j] = added->vals[j+1]; } added->num--; i--; } } } break; default: return LDB_ERR_OPERATIONS_ERROR; } *_added = added; *_removed = removed; return LDB_SUCCESS; } static int mbof_mod_add(struct mbof_mod_ctx *mod_ctx, struct mbof_dn_array *ael, struct mbof_val_array *addgh) { const struct ldb_message_element *el; struct mbof_dn_array *parents; struct mbof_add_ctx *add_ctx; struct ldb_context *ldb; struct mbof_ctx *ctx; int i, ret; ctx = mod_ctx->ctx; ldb = ldb_module_get_ctx(ctx->module); el = ldb_msg_find_element(mod_ctx->entry, DB_MEMBEROF); /* all the parents + itself */ ret = mbof_fill_dn_array(mod_ctx, ldb, el, &parents); if (ret != LDB_SUCCESS) { return ret; } add_ctx = talloc_zero(mod_ctx, struct mbof_add_ctx); if (!add_ctx) { return LDB_ERR_OPERATIONS_ERROR; } add_ctx->ctx = ctx; add_ctx->msg_dn = mod_ctx->msg->dn; if (addgh != NULL) { /* Build the memberuid add op */ ret = mbof_add_fill_ghop_ex(add_ctx, mod_ctx->entry, parents, addgh->vals, addgh->num); if (ret != LDB_SUCCESS) { return ret; } } if (ael != NULL && ael->num > 0) { /* Add itself to the list of the parents to also get the memberuid */ parents->dns = talloc_realloc(parents, parents->dns, struct ldb_dn *, parents->num + 1); if (!parents->dns) { return LDB_ERR_OPERATIONS_ERROR; } parents->dns[parents->num] = mod_ctx->entry->dn; parents->num++; /* Build the member-add array */ for (i = 0; i < ael->num; i++) { ret = mbof_append_addop(add_ctx, parents, ael->dns[i]); if (ret != LDB_SUCCESS) { return ret; } } return mbof_next_add(add_ctx->add_list); } return mbof_add_muop(add_ctx); } static int mbof_mod_delete(struct mbof_mod_ctx *mod_ctx, struct mbof_dn_array *del, struct mbof_val_array *delgh) { struct mbof_del_operation *first; struct mbof_del_ctx *del_ctx; struct mbof_ctx *ctx; int i, ret; ctx = mod_ctx->ctx; del_ctx = talloc_zero(mod_ctx, struct mbof_del_ctx); if (!del_ctx) { return LDB_ERR_OPERATIONS_ERROR; } del_ctx->ctx = ctx; del_ctx->is_mod = true; /* create first entry */ /* the first entry is the parent of all entries and the one where we * remove member from, it does not get the same treatment as others */ first = talloc_zero(del_ctx, struct mbof_del_operation); if (!first) { return LDB_ERR_OPERATIONS_ERROR; } del_ctx->first = first; /* add followup function if we also have stuff to add */ if ((mod_ctx->mb_add && mod_ctx->mb_add->num > 0) || (mod_ctx->gh_add && mod_ctx->gh_add->num > 0)) { del_ctx->follow_mod = mod_ctx; } first->del_ctx = del_ctx; first->entry = mod_ctx->entry; first->entry_dn = mod_ctx->entry->dn; if (delgh != NULL) { ret = mbof_del_fill_ghop_ex(del_ctx, del_ctx->first->entry, delgh->vals, delgh->num); if (ret != LDB_SUCCESS) { return ret; } } /* prepare del sets */ if (del != NULL && del->num > 0) { for (i = 0; i < del->num; i++) { ret = mbof_append_delop(first, del->dns[i]); if (ret != LDB_SUCCESS) { return ret; } } /* now that sets are built, start processing */ return mbof_del_execute_op(first->children[0]); } /* No member processing, just delete ghosts */ return mbof_del_ghop(del_ctx); } static int mbof_fill_dn_array(TALLOC_CTX *memctx, struct ldb_context *ldb, const struct ldb_message_element *el, struct mbof_dn_array **dn_array) { struct mbof_dn_array *ar; struct ldb_dn *valdn; int i; ar = talloc_zero(memctx, struct mbof_dn_array); if (!ar) { return LDB_ERR_OPERATIONS_ERROR; } *dn_array = ar; if (!el || el->num_values == 0) { return LDB_SUCCESS; } ar->dns = talloc_array(ar, struct ldb_dn *, el->num_values); if (!ar->dns) { return LDB_ERR_OPERATIONS_ERROR; } ar->num = el->num_values; for (i = 0; i < ar->num; i++) { valdn = ldb_dn_from_ldb_val(ar, ldb, &el->values[i]); if (!valdn || !ldb_dn_validate(valdn)) { ldb_debug(ldb, LDB_DEBUG_TRACE, "Invalid dn value: [%s]", (const char *)el->values[i].data); return LDB_ERR_INVALID_DN_SYNTAX; } ar->dns[i] = valdn; } return LDB_SUCCESS; } static int mbof_fill_vals_array(TALLOC_CTX *memctx, unsigned int num_values, struct ldb_val *values, struct mbof_val_array **val_array) { struct mbof_val_array *var = *val_array; int i, vi; if (var == NULL) { var = talloc_zero(memctx, struct mbof_val_array); if (!var) { return LDB_ERR_OPERATIONS_ERROR; } *val_array = var; } if (values == NULL || num_values == 0) { return LDB_SUCCESS; } /* We do not care about duplicate values now. * They will be filtered later */ vi = var->num; var->num += num_values; var->vals = talloc_realloc(memctx, var->vals, struct ldb_val, var->num); if (!var->vals) { return LDB_ERR_OPERATIONS_ERROR; } /* FIXME - use ldb_val_dup() */ for (i = 0; i < num_values; i++) { var->vals[vi].length = strlen((const char *) values[i].data); var->vals[vi].data = (uint8_t *) talloc_strdup(var, (const char *) values[i].data); if (var->vals[vi].data == NULL) { return LDB_ERR_OPERATIONS_ERROR; } vi++; } return LDB_SUCCESS; } static int mbof_fill_vals_array_el(TALLOC_CTX *memctx, const struct ldb_message_element *el, struct mbof_val_array **val_array) { if (el == NULL) { return LDB_SUCCESS; } return mbof_fill_vals_array(memctx, el->num_values, el->values, val_array); } /************************* * Cleanup task routines * *************************/ struct mbof_member { struct mbof_member *prev; struct mbof_member *next; struct ldb_dn *dn; const char *name; bool orig_has_memberof; bool orig_has_memberuid; struct ldb_message_element *orig_members; struct mbof_member **members; hash_table_t *memberofs; struct ldb_message_element *memuids; enum { MBOF_GROUP_TO_DO = 0, MBOF_GROUP_DONE, MBOF_USER, MBOF_ITER_ERROR } status; }; struct mbof_rcmp_context { struct ldb_module *module; struct ldb_request *req; struct mbof_member *user_list; hash_table_t *user_table; struct mbof_member *group_list; hash_table_t *group_table; }; static int mbof_steal_msg_el(TALLOC_CTX *memctx, const char *name, struct ldb_message *msg, struct ldb_message_element **_dest) { struct ldb_message_element *src; struct ldb_message_element *dest; src = ldb_msg_find_element(msg, name); if (!src) { return LDB_ERR_NO_SUCH_ATTRIBUTE; } dest = talloc_zero(memctx, struct ldb_message_element); if (!dest) { return LDB_ERR_OPERATIONS_ERROR; } *dest = *src; talloc_steal(dest, dest->name); talloc_steal(dest, dest->values); *_dest = dest; return LDB_SUCCESS; } static int mbof_rcmp_usr_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_rcmp_search_groups(struct mbof_rcmp_context *ctx); static int mbof_rcmp_grp_callback(struct ldb_request *req, struct ldb_reply *ares); static int mbof_member_update(struct mbof_rcmp_context *ctx, struct mbof_member *parent, struct mbof_member *mem); static bool mbof_member_iter(hash_entry_t *item, void *user_data); static int mbof_add_memuid(struct mbof_member *grp, const char *user); static int mbof_rcmp_update(struct mbof_rcmp_context *ctx); static int mbof_rcmp_mod_callback(struct ldb_request *req, struct ldb_reply *ares); static int memberof_recompute_task(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb = ldb_module_get_ctx(module); static const char *attrs[] = { DB_NAME, DB_MEMBEROF, NULL }; static const char *filter = "(objectclass=user)"; struct mbof_rcmp_context *ctx; struct ldb_request *src_req; int ret; ctx = talloc_zero(req, struct mbof_rcmp_context); if (!ctx) { return LDB_ERR_OPERATIONS_ERROR; } ctx->module = module; ctx->req = req; ret = hash_create_ex(1024, &ctx->user_table, 0, 0, 0, 0, hash_alloc, hash_free, ctx, NULL, NULL); if (ret != HASH_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } ret = ldb_build_search_req(&src_req, ldb, ctx, NULL, LDB_SCOPE_SUBTREE, filter, attrs, NULL, ctx, mbof_rcmp_usr_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_request(ldb, src_req); } static int mbof_rcmp_usr_callback(struct ldb_request *req, struct ldb_reply *ares) { struct mbof_rcmp_context *ctx; struct mbof_member *usr; hash_value_t value; hash_key_t key; const char *name; int ret; ctx = talloc_get_type(req->context, struct mbof_rcmp_context); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: usr = talloc_zero(ctx, struct mbof_member); if (!usr) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } usr->status = MBOF_USER; usr->dn = talloc_steal(usr, ares->message->dn); name = ldb_msg_find_attr_as_string(ares->message, DB_NAME, NULL); if (name) { usr->name = talloc_steal(usr, name); } if (ldb_msg_find_element(ares->message, DB_MEMBEROF)) { usr->orig_has_memberof = true; } DLIST_ADD(ctx->user_list, usr); key.type = HASH_KEY_STRING; key.str = discard_const(ldb_dn_get_linearized(usr->dn)); value.type = HASH_VALUE_PTR; value.ptr = usr; ret = hash_enter(ctx->user_table, &key, &value); if (ret != HASH_SUCCESS) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } break; case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: talloc_zfree(ares); /* and now search groups */ return mbof_rcmp_search_groups(ctx); } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_rcmp_search_groups(struct mbof_rcmp_context *ctx) { struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); static const char *attrs[] = { DB_MEMBEROF, DB_MEMBERUID, DB_NAME, DB_MEMBER, NULL }; static const char *filter = "(objectclass=group)"; struct ldb_request *req; int ret; ret = hash_create_ex(1024, &ctx->group_table, 0, 0, 0, 0, hash_alloc, hash_free, ctx, NULL, NULL); if (ret != HASH_SUCCESS) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } ret = ldb_build_search_req(&req, ldb, ctx, NULL, LDB_SCOPE_SUBTREE, filter, attrs, NULL, ctx, mbof_rcmp_grp_callback, ctx->req); if (ret != LDB_SUCCESS) { return ret; } return ldb_request(ldb, req); } static int mbof_rcmp_grp_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct mbof_rcmp_context *ctx; struct ldb_message_element *el; struct mbof_member *iter; struct mbof_member *grp; hash_value_t value; hash_key_t key; const char *name; int i, j; int ret; ctx = talloc_get_type(req->context, struct mbof_rcmp_context); ldb = ldb_module_get_ctx(ctx->module); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: grp = talloc_zero(ctx, struct mbof_member); if (!grp) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } grp->status = MBOF_GROUP_TO_DO; grp->dn = talloc_steal(grp, ares->message->dn); grp->name = ldb_msg_find_attr_as_string(ares->message, DB_NAME, NULL); name = ldb_msg_find_attr_as_string(ares->message, DB_NAME, NULL); if (name) { grp->name = talloc_steal(grp, name); } if (ldb_msg_find_element(ares->message, DB_MEMBEROF)) { grp->orig_has_memberof = true; } if (ldb_msg_find_element(ares->message, DB_MEMBERUID)) { grp->orig_has_memberuid = true; } ret = mbof_steal_msg_el(grp, DB_MEMBER, ares->message, &grp->orig_members); if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } DLIST_ADD(ctx->group_list, grp); key.type = HASH_KEY_STRING; key.str = discard_const(ldb_dn_get_linearized(grp->dn)); value.type = HASH_VALUE_PTR; value.ptr = grp; ret = hash_enter(ctx->group_table, &key, &value); if (ret != HASH_SUCCESS) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } break; case LDB_REPLY_REFERRAL: /* ignore */ break; case LDB_REPLY_DONE: talloc_zfree(ares); if (!ctx->group_list) { /* no groups ? */ return ldb_module_done(ctx->req, NULL, NULL, LDB_SUCCESS); } /* for each group compute the members list */ for (iter = ctx->group_list; iter; iter = iter->next) { el = iter->orig_members; if (!el || el->num_values == 0) { /* no members */ continue; } /* we have at most num_values group members */ iter->members = talloc_array(iter, struct mbof_member *, el->num_values +1); if (!iter->members) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } for (i = 0, j = 0; i < el->num_values; i++) { key.type = HASH_KEY_STRING; key.str = (char *)el->values[i].data; ret = hash_lookup(ctx->user_table, &key, &value); switch (ret) { case HASH_SUCCESS: iter->members[j] = (struct mbof_member *)value.ptr; j++; break; case HASH_ERROR_KEY_NOT_FOUND: /* not a user, see if it is a group */ ret = hash_lookup(ctx->group_table, &key, &value); if (ret != HASH_SUCCESS) { if (ret != HASH_ERROR_KEY_NOT_FOUND) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } } if (ret == HASH_ERROR_KEY_NOT_FOUND) { /* not a known user, nor a known group ? give a warning an continue */ ldb_debug(ldb, LDB_DEBUG_ERROR, "member attribute [%s] has no corresponding" " entry!", key.str); break; } iter->members[j] = (struct mbof_member *)value.ptr; j++; break; default: return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } } /* terminate */ iter->members[j] = NULL; talloc_zfree(iter->orig_members); } /* now generate correct memberof tables */ while (ctx->group_list->status == MBOF_GROUP_TO_DO) { grp = ctx->group_list; /* move to end of list and mark as done. * NOTE: this is not efficient, but will do for now */ DLIST_DEMOTE(ctx->group_list, grp, struct mbof_member *); grp->status = MBOF_GROUP_DONE; /* verify if members need updating */ if (!grp->members) { continue; } for (i = 0; grp->members[i]; i++) { ret = mbof_member_update(ctx, grp, grp->members[i]); if (ret != LDB_SUCCESS) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } } } /* ok all done, now go on and modify the tree */ return mbof_rcmp_update(ctx); } talloc_zfree(ares); return LDB_SUCCESS; } static int mbof_member_update(struct mbof_rcmp_context *ctx, struct mbof_member *parent, struct mbof_member *mem) { hash_value_t value; hash_key_t key; int ret; /* ignore loops */ if (parent == mem) return LDB_SUCCESS; key.type = HASH_KEY_STRING; key.str = discard_const(ldb_dn_get_linearized(parent->dn)); if (!mem->memberofs) { ret = hash_create_ex(32, &mem->memberofs, 0, 0, 0, 0, hash_alloc, hash_free, mem, NULL, NULL); if (ret != HASH_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } ret = HASH_ERROR_KEY_NOT_FOUND; } else { ret = hash_lookup(mem->memberofs, &key, &value); if (ret != HASH_SUCCESS) { if (ret != HASH_ERROR_KEY_NOT_FOUND) { /* fatal error */ return LDB_ERR_OPERATIONS_ERROR; } } } if (ret == HASH_ERROR_KEY_NOT_FOUND) { /* it's missing, update member */ value.type = HASH_VALUE_PTR; value.ptr = parent; ret = hash_enter(mem->memberofs, &key, &value); if (ret != HASH_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } if (mem->status == MBOF_USER) { /* add corresponding memuid to the group */ ret = mbof_add_memuid(parent, mem->name); if (ret != LDB_SUCCESS) { return ret; } } /* if we updated a group, mark it as TO DO again */ if (mem->status == MBOF_GROUP_DONE) { mem->status = MBOF_GROUP_TO_DO; } } /* now see if the parent has memberofs to pass down */ if (parent->memberofs) { ret = hash_iterate(parent->memberofs, mbof_member_iter, mem); if (ret != HASH_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } if (mem->status == MBOF_ITER_ERROR) { return LDB_ERR_OPERATIONS_ERROR; } } /* finally, if it was made TO DO move it to the head */ if (mem->status == MBOF_GROUP_TO_DO) { DLIST_PROMOTE(ctx->group_list, mem); } return LDB_SUCCESS; } static bool mbof_member_iter(hash_entry_t *item, void *user_data) { struct mbof_member *parent; struct mbof_member *mem; hash_value_t value; int ret; mem = talloc_get_type(user_data, struct mbof_member); /* exclude self */ if (strcmp(item->key.str, ldb_dn_get_linearized(mem->dn)) == 0) { return true; } /* check if we already have it */ ret = hash_lookup(mem->memberofs, &item->key, &value); if (ret != HASH_SUCCESS) { if (ret != HASH_ERROR_KEY_NOT_FOUND) { /* fatal error */ mem->status = MBOF_ITER_ERROR; return false; } /* was not already here, add it and mark group as TO DO */ ret = hash_enter(mem->memberofs, &item->key, &item->value); if (ret != HASH_SUCCESS) { return LDB_ERR_OPERATIONS_ERROR; } if (mem->status == MBOF_GROUP_DONE) { mem->status = MBOF_GROUP_TO_DO; } if (mem->status == MBOF_USER) { /* add corresponding memuid to the group */ parent = (struct mbof_member *)item->value.ptr; ret = mbof_add_memuid(parent, mem->name); if (ret != LDB_SUCCESS) { mem->status = MBOF_ITER_ERROR; return false; } } } return true; } static int mbof_add_memuid(struct mbof_member *grp, const char *user) { struct ldb_val *vals; int n; if (!grp->memuids) { grp->memuids = talloc_zero(grp, struct ldb_message_element); if (!grp->memuids) { return LDB_ERR_OPERATIONS_ERROR; } grp->memuids->name = talloc_strdup(grp->memuids, DB_MEMBERUID); if (!grp->memuids->name) { return LDB_ERR_OPERATIONS_ERROR; } } n = grp->memuids->num_values; vals = talloc_realloc(grp->memuids, grp->memuids->values, struct ldb_val, n + 1); if (!vals) { return LDB_ERR_OPERATIONS_ERROR; } vals[n].data = (uint8_t *)talloc_strdup(vals, user); vals[n].length = strlen(user); grp->memuids->values = vals; grp->memuids->num_values = n + 1; return LDB_SUCCESS; } static int mbof_rcmp_update(struct mbof_rcmp_context *ctx) { struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); struct ldb_message_element *el; struct ldb_message *msg = NULL; struct ldb_request *req; struct mbof_member *x = NULL; hash_key_t *keys; unsigned long count; int flags; int ret, i; /* we process all users first and then all groups */ if (ctx->user_list) { /* take the next entry and remove it from the list */ x = ctx->user_list; DLIST_REMOVE(ctx->user_list, x); } else if (ctx->group_list) { /* take the next entry and remove it from the list */ x = ctx->group_list; DLIST_REMOVE(ctx->group_list, x); } else { /* processing terminated, return */ ret = LDB_SUCCESS; goto done; } msg = ldb_msg_new(ctx); if (!msg) { ret = LDB_ERR_OPERATIONS_ERROR; goto done; } msg->dn = x->dn; /* process memberof */ if (x->memberofs) { ret = hash_keys(x->memberofs, &count, &keys); if (ret != HASH_SUCCESS) { ret = LDB_ERR_OPERATIONS_ERROR; goto done; } if (x->orig_has_memberof) { flags = LDB_FLAG_MOD_REPLACE; } else { flags = LDB_FLAG_MOD_ADD; } ret = ldb_msg_add_empty(msg, DB_MEMBEROF, flags, &el); if (ret != LDB_SUCCESS) { goto done; } el->values = talloc_array(el, struct ldb_val, count); if (!el->values) { ret = LDB_ERR_OPERATIONS_ERROR; goto done; } el->num_values = count; for (i = 0; i < count; i++) { el->values[i].data = (uint8_t *)keys[i].str; el->values[i].length = strlen(keys[i].str); } } else if (x->orig_has_memberof) { ret = ldb_msg_add_empty(msg, DB_MEMBEROF, LDB_FLAG_MOD_DELETE, NULL); if (ret != LDB_SUCCESS) { goto done; } } /* process memberuid */ if (x->memuids) { if (x->orig_has_memberuid) { flags = LDB_FLAG_MOD_REPLACE; } else { flags = LDB_FLAG_MOD_ADD; } ret = ldb_msg_add(msg, x->memuids, flags); if (ret != LDB_SUCCESS) { goto done; } } else if (x->orig_has_memberuid) { ret = ldb_msg_add_empty(msg, DB_MEMBERUID, LDB_FLAG_MOD_DELETE, NULL); if (ret != LDB_SUCCESS) { goto done; } } ret = ldb_build_mod_req(&req, ldb, ctx, msg, NULL, ctx, mbof_rcmp_mod_callback, ctx->req); if (ret != LDB_SUCCESS) { goto done; } talloc_steal(req, msg); /* fire next call */ return ldb_next_request(ctx->module, req); done: /* all users and groups have been processed */ return ldb_module_done(ctx->req, NULL, NULL, ret); } static int mbof_rcmp_mod_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ldb_context *ldb; struct mbof_rcmp_context *ctx; ctx = talloc_get_type(req->context, struct mbof_rcmp_context); ldb = ldb_module_get_ctx(ctx->module); if (!ares) { return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } if (ares->error != LDB_SUCCESS) { return ldb_module_done(ctx->req, ares->controls, ares->response, ares->error); } switch (ares->type) { case LDB_REPLY_ENTRY: ldb_debug(ldb, LDB_DEBUG_TRACE, "Got an entry on a non search op ?!"); /* shouldn't happen */ talloc_zfree(ares); return ldb_module_done(ctx->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); case LDB_REPLY_REFERRAL: /* ignore */ talloc_zfree(ares); break; case LDB_REPLY_DONE: talloc_zfree(ares); /* update the next one */ return mbof_rcmp_update(ctx); } return LDB_SUCCESS; } /* module init code */ static int memberof_init(struct ldb_module *module) { struct ldb_context *ldb = ldb_module_get_ctx(module); int ret; /* set syntaxes for member and memberof so that comparisons in filters and * such are done right */ ret = ldb_schema_attribute_add(ldb, DB_MEMBER, 0, LDB_SYNTAX_DN); if (ret != 0) return LDB_ERR_OPERATIONS_ERROR; ret = ldb_schema_attribute_add(ldb, DB_MEMBEROF, 0, LDB_SYNTAX_DN); if (ret != 0) return LDB_ERR_OPERATIONS_ERROR; return ldb_next_init(module); } const struct ldb_module_ops ldb_memberof_module_ops = { .name = "memberof", .init_context = memberof_init, .add = memberof_add, .modify = memberof_mod, .del = memberof_del, }; int ldb_init_module(const char *version) { #if defined(SSS_LDB_VERSION_CHECK) && defined(LDB_MODULE_CHECK_VERSION) LDB_MODULE_CHECK_VERSION(version); #endif /* SSS_LDB_VERSION_CHECK && LDB_MODULE_CHECK_VERSION */ return ldb_register_module(&ldb_memberof_module_ops); } sssd-1.13.4/src/PaxHeaders.16287/confdb0000644000000000000000000000013212703463556014300 xustar0030 mtime=1460561774.994794782 30 atime=1460561776.118798593 30 ctime=1460561774.994794782 sssd-1.13.4/src/confdb/0000755002412700241270000000000012703463556016031 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/confdb/PaxHeaders.16287/confdb.h0000644000000000000000000000007412703456111015753 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.517793164 sssd-1.13.4/src/confdb/confdb.h0000644002412700241270000005527112703456111017434 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Configuratoin DB Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _CONF_DB_H #define _CONF_DB_H #include #include #include #include #include #include "config.h" /** * @defgroup sss_confdb The ConfDB API * The ConfDB is an interface for data providers to * access the configuration information provided in * the sssd.conf * @{ */ #define CONFDB_DEFAULT_CFG_FILE_VER 2 #define CONFDB_FILE "config.ldb" #define CONFDB_DEFAULT_CONFIG_FILE SSSD_CONF_DIR"/sssd.conf" #define SSSD_MIN_ID 1 #define SSSD_LOCAL_MINID 1000 #define CONFDB_DEFAULT_SHELL_FALLBACK "/bin/sh" /* Configuration options */ /* Services */ #define CONFDB_SERVICE_PATH_TMPL "config/%s" #define CONFDB_SERVICE_COMMAND "command" #define CONFDB_SERVICE_DEBUG_LEVEL "debug_level" #define CONFDB_SERVICE_DEBUG_TIMESTAMPS "debug_timestamps" #define CONFDB_SERVICE_DEBUG_MICROSECONDS "debug_microseconds" #define CONFDB_SERVICE_DEBUG_TO_FILES "debug_to_files" #define CONFDB_SERVICE_TIMEOUT "timeout" #define CONFDB_SERVICE_FORCE_TIMEOUT "force_timeout" #define CONFDB_SERVICE_RECON_RETRIES "reconnection_retries" #define CONFDB_SERVICE_FD_LIMIT "fd_limit" #define CONFDB_SERVICE_ALLOWED_UIDS "allowed_uids" /* Monitor */ #define CONFDB_MONITOR_CONF_ENTRY "config/sssd" #define CONFDB_MONITOR_SBUS_TIMEOUT "sbus_timeout" #define CONFDB_MONITOR_ACTIVE_SERVICES "services" #define CONFDB_MONITOR_ACTIVE_DOMAINS "domains" #define CONFDB_MONITOR_TRY_INOTIFY "try_inotify" #define CONFDB_MONITOR_KRB5_RCACHEDIR "krb5_rcache_dir" #define CONFDB_MONITOR_DEFAULT_DOMAIN "default_domain_suffix" #define CONFDB_MONITOR_OVERRIDE_SPACE "override_space" #define CONFDB_MONITOR_USER_RUNAS "user" #define CONFDB_MONITOR_CERT_VERIFICATION "certificate_verification" /* Both monitor and domains */ #define CONFDB_NAME_REGEX "re_expression" #define CONFDB_FULL_NAME_FORMAT "full_name_format" #define CONFDB_DEFAULT_FULL_NAME_FORMAT_INTERNAL "%1$s@%2$s%3$s" #define CONFDB_DEFAULT_FULL_NAME_FORMAT "%1$s@%2$s" /* Responders */ #define CONFDB_RESPONDER_GET_DOMAINS_TIMEOUT "get_domains_timeout" #define CONFDB_RESPONDER_CLI_IDLE_TIMEOUT "client_idle_timeout" #define CONFDB_RESPONDER_CLI_IDLE_DEFAULT_TIMEOUT 60 /* NSS */ #define CONFDB_NSS_CONF_ENTRY "config/nss" #define CONFDB_NSS_ENUM_CACHE_TIMEOUT "enum_cache_timeout" #define CONFDB_NSS_ENTRY_CACHE_NOWAIT_PERCENTAGE "entry_cache_nowait_percentage" #define CONFDB_NSS_ENTRY_NEG_TIMEOUT "entry_negative_timeout" #define CONFDB_NSS_FILTER_USERS_IN_GROUPS "filter_users_in_groups" #define CONFDB_NSS_FILTER_USERS "filter_users" #define CONFDB_NSS_FILTER_GROUPS "filter_groups" #define CONFDB_NSS_PWFIELD "pwfield" #define CONFDB_NSS_OVERRIDE_HOMEDIR "override_homedir" #define CONFDB_NSS_FALLBACK_HOMEDIR "fallback_homedir" #define CONFDB_NSS_OVERRIDE_SHELL "override_shell" #define CONFDB_NSS_VETOED_SHELL "vetoed_shells" #define CONFDB_NSS_ALLOWED_SHELL "allowed_shells" #define CONFDB_NSS_SHELL_FALLBACK "shell_fallback" #define CONFDB_NSS_DEFAULT_SHELL "default_shell" #define CONFDB_MEMCACHE_TIMEOUT "memcache_timeout" #define CONFDB_NSS_HOMEDIR_SUBSTRING "homedir_substring" #define CONFDB_DEFAULT_HOMEDIR_SUBSTRING "/home" /* PAM */ #define CONFDB_PAM_CONF_ENTRY "config/pam" #define CONFDB_PAM_CRED_TIMEOUT "offline_credentials_expiration" #define CONFDB_PAM_FAILED_LOGIN_ATTEMPTS "offline_failed_login_attempts" #define CONFDB_DEFAULT_PAM_FAILED_LOGIN_ATTEMPTS 0 #define CONFDB_PAM_FAILED_LOGIN_DELAY "offline_failed_login_delay" #define CONFDB_DEFAULT_PAM_FAILED_LOGIN_DELAY 5 #define CONFDB_PAM_VERBOSITY "pam_verbosity" #define CONFDB_PAM_ID_TIMEOUT "pam_id_timeout" #define CONFDB_PAM_PWD_EXPIRATION_WARNING "pam_pwd_expiration_warning" #define CONFDB_PAM_TRUSTED_USERS "pam_trusted_users" #define CONFDB_PAM_PUBLIC_DOMAINS "pam_public_domains" #define CONFDB_PAM_ACCOUNT_EXPIRED_MESSAGE "pam_account_expired_message" #define CONFDB_PAM_ACCOUNT_LOCKED_MESSAGE "pam_account_locked_message" #define CONFDB_PAM_CERT_AUTH "pam_cert_auth" #define CONFDB_PAM_CERT_DB_PATH "pam_cert_db_path" #define CONFDB_PAM_P11_CHILD_TIMEOUT "p11_child_timeout" /* SUDO */ #define CONFDB_SUDO_CONF_ENTRY "config/sudo" #define CONFDB_SUDO_CACHE_TIMEOUT "sudo_cache_timeout" #define CONFDB_DEFAULT_SUDO_CACHE_TIMEOUT 180 #define CONFDB_SUDO_TIMED "sudo_timed" #define CONFDB_DEFAULT_SUDO_TIMED false #define CONFDB_SUDO_INVERSE_ORDER "sudo_inverse_order" #define CONFDB_DEFAULT_SUDO_INVERSE_ORDER false /* autofs */ #define CONFDB_AUTOFS_CONF_ENTRY "config/autofs" #define CONFDB_AUTOFS_MAP_NEG_TIMEOUT "autofs_negative_timeout" /* SSH */ #define CONFDB_SSH_CONF_ENTRY "config/ssh" #define CONFDB_SSH_HASH_KNOWN_HOSTS "ssh_hash_known_hosts" #define CONFDB_DEFAULT_SSH_HASH_KNOWN_HOSTS true #define CONFDB_SSH_KNOWN_HOSTS_TIMEOUT "ssh_known_hosts_timeout" #define CONFDB_DEFAULT_SSH_KNOWN_HOSTS_TIMEOUT 180 #define CONFDB_SSH_CA_DB "ca_db" #define CONFDB_DEFAULT_SSH_CA_DB SYSCONFDIR"/pki/nssdb" /* PAC */ #define CONFDB_PAC_CONF_ENTRY "config/pac" /* InfoPipe */ #define CONFDB_IFP_CONF_ENTRY "config/ifp" #define CONFDB_IFP_USER_ATTR_LIST "user_attributes" #define CONFDB_IFP_WILDCARD_LIMIT "wildcard_limit" /* Domains */ #define CONFDB_DOMAIN_PATH_TMPL "config/domain/%s" #define CONFDB_DOMAIN_BASEDN "cn=domain,cn=config" #define CONFDB_DOMAIN_ID_PROVIDER "id_provider" #define CONFDB_DOMAIN_AUTH_PROVIDER "auth_provider" #define CONFDB_DOMAIN_ACCESS_PROVIDER "access_provider" #define CONFDB_DOMAIN_CHPASS_PROVIDER "chpass_provider" #define CONFDB_DOMAIN_SUDO_PROVIDER "sudo_provider" #define CONFDB_DOMAIN_AUTOFS_PROVIDER "autofs_provider" #define CONFDB_DOMAIN_SELINUX_PROVIDER "selinux_provider" #define CONFDB_DOMAIN_HOSTID_PROVIDER "hostid_provider" #define CONFDB_DOMAIN_SUBDOMAINS_PROVIDER "subdomains_provider" #define CONFDB_DOMAIN_COMMAND "command" #define CONFDB_DOMAIN_TIMEOUT "timeout" #define CONFDB_DOMAIN_ATTR "cn" #define CONFDB_DOMAIN_ENUMERATE "enumerate" #define CONFDB_SUBDOMAIN_ENUMERATE "subdomain_enumerate" #define CONFDB_DEFAULT_SUBDOMAIN_ENUMERATE "none" #define CONFDB_DOMAIN_MINID "min_id" #define CONFDB_DOMAIN_MAXID "max_id" #define CONFDB_DOMAIN_CACHE_CREDS "cache_credentials" #define CONFDB_DOMAIN_CACHE_CREDS_MIN_FF_LENGTH \ "cache_credentials_minimal_first_factor_length" #define CONFDB_DEFAULT_CACHE_CREDS_MIN_FF_LENGTH 8 #define CONFDB_DOMAIN_LEGACY_PASS "store_legacy_passwords" #define CONFDB_DOMAIN_MPG "magic_private_groups" #define CONFDB_DOMAIN_FQ "use_fully_qualified_names" #define CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT "entry_cache_timeout" #define CONFDB_DOMAIN_ACCOUNT_CACHE_EXPIRATION "account_cache_expiration" #define CONFDB_DOMAIN_OVERRIDE_GID "override_gid" #define CONFDB_DOMAIN_CASE_SENSITIVE "case_sensitive" #define CONFDB_DOMAIN_SUBDOMAIN_HOMEDIR "subdomain_homedir" #define CONFDB_DOMAIN_DEFAULT_SUBDOMAIN_HOMEDIR "/home/%d/%u" #define CONFDB_DOMAIN_IGNORE_GROUP_MEMBERS "ignore_group_members" #define CONFDB_DOMAIN_SUBDOMAIN_REFRESH "subdomain_refresh_interval" #define CONFDB_DOMAIN_USER_CACHE_TIMEOUT "entry_cache_user_timeout" #define CONFDB_DOMAIN_GROUP_CACHE_TIMEOUT "entry_cache_group_timeout" #define CONFDB_DOMAIN_NETGROUP_CACHE_TIMEOUT "entry_cache_netgroup_timeout" #define CONFDB_DOMAIN_SERVICE_CACHE_TIMEOUT "entry_cache_service_timeout" #define CONFDB_DOMAIN_AUTOFS_CACHE_TIMEOUT "entry_cache_autofs_timeout" #define CONFDB_DOMAIN_SUDO_CACHE_TIMEOUT "entry_cache_sudo_timeout" #define CONFDB_DOMAIN_SSH_HOST_CACHE_TIMEOUT "entry_cache_ssh_host_timeout" #define CONFDB_DOMAIN_PWD_EXPIRATION_WARNING "pwd_expiration_warning" #define CONFDB_DOMAIN_REFRESH_EXPIRED_INTERVAL "refresh_expired_interval" #define CONFDB_DOMAIN_OFFLINE_TIMEOUT "offline_timeout" #define CONFDB_DOMAIN_SUBDOMAIN_INHERIT "subdomain_inherit" #define CONFDB_DOMAIN_CACHED_AUTH_TIMEOUT "cached_auth_timeout" /* Local Provider */ #define CONFDB_LOCAL_DEFAULT_SHELL "default_shell" #define CONFDB_LOCAL_DEFAULT_BASEDIR "base_directory" #define CONFDB_LOCAL_CREATE_HOMEDIR "create_homedir" #define CONFDB_LOCAL_REMOVE_HOMEDIR "remove_homedir" #define CONFDB_LOCAL_UMASK "homedir_umask" #define CONFDB_LOCAL_SKEL_DIR "skel_dir" #define CONFDB_LOCAL_MAIL_DIR "mail_dir" #define CONFDB_LOCAL_USERDEL_CMD "userdel_cmd" /* Proxy Provider */ #define CONFDB_PROXY_LIBNAME "proxy_lib_name" #define CONFDB_PROXY_PAM_TARGET "proxy_pam_target" #define CONFDB_PROXY_FAST_ALIAS "proxy_fast_alias" struct confdb_ctx; struct config_file_ctx; /** sssd domain state */ enum sss_domain_state { /** Domain is usable by both responders and providers. This * is the default state after creating a new domain */ DOM_ACTIVE, /** Domain was removed, should not be used be neither responders * not providers. */ DOM_DISABLED, /** Domain cannot be contacted. Providers return an offline error code * when receiving request for inactive domain, but responders should * return cached data */ DOM_INACTIVE, }; /** * Data structure storing all of the basic features * of a domain. */ struct sss_domain_info { char *name; char *conn_name; char *provider; int timeout; bool enumerate; char **sd_enumerate; bool fqnames; bool mpg; bool ignore_group_members; uint32_t id_min; uint32_t id_max; bool cache_credentials; uint32_t cache_credentials_min_ff_length; bool legacy_passwords; bool case_sensitive; bool case_preserve; gid_t override_gid; const char *override_homedir; const char *fallback_homedir; const char *subdomain_homedir; const char *homedir_substr; const char *override_shell; const char *default_shell; uint32_t user_timeout; uint32_t group_timeout; uint32_t netgroup_timeout; uint32_t service_timeout; uint32_t autofsmap_timeout; uint32_t sudo_timeout; uint32_t ssh_host_timeout; uint32_t refresh_expired_interval; uint32_t subdomain_refresh_interval; uint32_t cached_auth_timeout; int pwd_expiration_warning; struct sysdb_ctx *sysdb; struct sss_names_ctx *names; struct sss_domain_info *parent; struct sss_domain_info *subdomains; char *realm; char *flat_name; char *domain_id; uint32_t trust_direction; struct timeval subdomains_last_checked; bool has_views; const char *view_name; struct sss_domain_info *prev; struct sss_domain_info *next; enum sss_domain_state state; char **sd_inherit; /* Do not use the forest pointer directly in new code, but rather the * forest_root pointer. sss_domain_info will be more opaque in the future */ char *forest; struct sss_domain_info *forest_root; }; /** * Initialize the connection to the ConfDB * * @param[in] mem_ctx The parent memory context for the confdb_ctx * @param[out] cdb_ctx The newly-created connection object * @param[in] confdb_location The absolute path to the ConfDB file on the * filesystem * * @return 0 - Connection succeeded and cdb_ctx was populated * @return ENOMEM - There was not enough memory to create the cdb_ctx * @return EIO - There was an I/O error communicating with the ConfDB file */ int confdb_init(TALLOC_CTX *mem_ctx, struct confdb_ctx **cdb_ctx, const char *confdb_location); /** * Get a domain object for the named domain * * @param[in] cdb The connection object to the confdb * @param[in] name The name of the domain to retrieve * @param[out] domain A pointer to a domain object for the domain given by * name * * @return 0 - Lookup succeeded and domain was populated * @return ENOMEM - There was insufficient memory to complete the operation * @return ENOENT - The named domain does not exist or is not set active */ int confdb_get_domain(struct confdb_ctx *cdb, const char *name, struct sss_domain_info **domain); /** * Get a null-terminated linked-list of active domain objects * @param[in] cdb The connection object to the confdb * @param[out] domains A pointer to the first entry of a linked-list of domain * objects * * @return 0 - Lookup succeeded and all active domains are in the list * @return ENOMEM - There was insufficient memory to complete the operation * @return ENOENT - No active domains are configured */ int confdb_get_domains(struct confdb_ctx *cdb, struct sss_domain_info **domains); /** * Get a null-terminated linked-list of all domain names * @param[in] mem_ctx The parent memory context for the value list * @param[in] cdb The connection object to the confdb * @param[out] _names Output list * * @return 0 - Lookup succeeded and all domain names are in the list * @return ENOMEM - There was insufficient memory to complete the operation * @return ENOENT - No active domains are configured * @return EIO - There was an I/O error communicating with the ConfDB file * @return EINVAL - Corrupted confdb object */ int confdb_list_all_domain_names(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, char ***_names); /** * @brief Add an arbitrary parameter to the confdb. * * This is mostly useful * for testing, as they will not persist between SSSD restarts. For * persistence, make changes to the sssd.conf file. * * @param[in] cdb The connection object to the confdb * @param[in] replace If replace is set to true, pre-existing values will be * overwritten. * If it is false, the provided values will be added to the * attribute. * @param[in] section The ConfDB section to update. This is constructed from * the format of the sssd.conf file. All sections start * with 'config/'. Subsections are separated by slashes. * e.g. [domain/LDAP] in sssd.conf would translate to * config/domain/LDAP * @param[in] attribute The name of the attribute to update * @param[in] values A null-terminated array of values to add to the attribute * * @return 0 - Successfully added the provided value(s) * @return ENOMEM - There was insufficient memory to complete the operation * @return EINVAL - The section could not be parsed * @return EIO - An I/O error occurred communicating with the ConfDB */ int confdb_add_param(struct confdb_ctx *cdb, bool replace, const char *section, const char *attribute, const char **values); /** * @brief Retrieve all values for an attribute * * @param[in] cdb The connection object to the confdb * @param[in] mem_ctx The parent memory context for the value list * @param[in] section The ConfDB section to update. This is constructed from * the format of the sssd.conf file. All sections start * with 'config/'. Subsections are separated by slashes. * e.g. [domain/LDAP] in sssd.conf would translate to * config/domain/LDAP * @param[in] attribute The name of the attribute to update * @param[out] values A null-terminated array of cstrings containing all * values for this attribute * * @return 0 - Successfully retrieved the value(s) * @return ENOMEM - There was insufficient memory to complete the operation * @return EINVAL - The section could not be parsed * @return EIO - An I/O error occurred while communicating with the ConfDB */ int confdb_get_param(struct confdb_ctx *cdb, TALLOC_CTX *mem_ctx, const char *section, const char *attribute, char ***values); /** * @brief Convenience function to retrieve a single-valued attribute as a * string * * @param[in] cdb The connection object to the confdb * @param[in] ctx The parent memory context for the returned string * @param[in] section The ConfDB section to update. This is constructed from * the format of the sssd.conf file. All sections start * with 'config/'. Subsections are separated by slashes. * e.g. [domain/LDAP] in sssd.conf would translate to * config/domain/LDAP * @param[in] attribute The name of the attribute to update * @param[in] defstr If not NULL, the string to use if the attribute does not * exist in the ConfDB * @param[out] result A pointer to the retrieved (or default) string * * @return 0 - Successfully retrieved the entry (or used the default) * @return ENOMEM - There was insufficient memory to complete the operation * @return EINVAL - The section could not be parsed, or the attribute was not * single-valued. * @return EIO - An I/O error occurred while communicating with the ConfDB */ int confdb_get_string(struct confdb_ctx *cdb, TALLOC_CTX *ctx, const char *section, const char *attribute, const char *defstr, char **result); /** * @brief Convenience function to retrieve a single-valued attribute as an * integer * * @param[in] cdb The connection object to the confdb * @param[in] section The ConfDB section to update. This is constructed from * the format of the sssd.conf file. All sections start * with 'config/'. Subsections are separated by slashes. * e.g. [domain/LDAP] in sssd.conf would translate to * config/domain/LDAP * @param[in] attribute The name of the attribute to update * @param[in] defval If not NULL, the integer to use if the attribute does not * exist in the ConfDB * @param[out] result A pointer to the retrieved (or default) integer * * @return 0 - Successfully retrieved the entry (or used the default) * @return ENOMEM - There was insufficient memory to complete the operation * @return EINVAL - The section could not be parsed, or the attribute was not * single-valued. * @return EIO - An I/O error occurred while communicating with the ConfDB * @return ERANGE - The value stored in the ConfDB was outside the range * [INT_MIN..INT_MAX] */ int confdb_get_int(struct confdb_ctx *cdb, const char *section, const char *attribute, int defval, int *result); /** * @brief Convenience function to retrieve a single-valued attribute as a * boolean * * This function will read (in a case-insensitive manner) a "true" or "false" * value from the ConfDB and convert it to an integral bool value. * * @param[in] cdb The connection object to the confdb * @param[in] section The ConfDB section to update. This is constructed from * the format of the sssd.conf file. All sections start * with 'config/'. Subsections are separated by slashes. * e.g. [domain/LDAP] in sssd.conf would translate to * config/domain/LDAP * @param[in] attribute The name of the attribute to update * @param[in] defval If not NULL, the boolean state to use if the attribute * does not exist in the ConfDB * @param[out] result A pointer to the retrieved (or default) bool * * @return 0 - Successfully retrieved the entry (or used the default) * @return ENOMEM - There was insufficient memory to complete the operation * @return EINVAL - The section could not be parsed, the attribute was not * single-valued, or the value was not a boolean. * @return EIO - An I/O error occurred while communicating with the ConfDB */ int confdb_get_bool(struct confdb_ctx *cdb, const char *section, const char *attribute, bool defval, bool *result); /** * @brief Convenience function to set a single-valued attribute as a string * * @param[in] cdb The connection object to the confdb * @param[in] section The ConfDB section to update. This is constructed from * the format of the sssd.conf file. All sections start * with 'config/'. Subsections are separated by slashes. * e.g. [domain/LDAP] in sssd.conf would translate to * config/domain/LDAP * @param[in] attribute The name of the attribute to update * @param[in] val New value of the attribute. * * @return 0 - Successfully retrieved the entry (or used the default) * @return ENOMEM - There was insufficient memory to complete the operation * @return EINVAL - The section could not be parsed * @return EIO - An I/O error occurred while communicating with the ConfDB */ int confdb_set_string(struct confdb_ctx *cdb, const char *section, const char *attribute, const char *val); /** * @brief Convenience function to retrieve a single-valued attribute as a * null-terminated array of strings * * This function will automatically split a comma-separated string in an * attribute into a null-terminated array of strings. This is useful for * storing and retrieving ordered lists, as ConfDB multivalued attributes do * not guarantee retrieval order. * * @param[in] cdb The connection object to the confdb * @param[in] ctx The parent memory context for the returned string * @param[in] section The ConfDB section to update. This is constructed from * the format of the sssd.conf file. All sections start * with 'config/'. Subsections are separated by slashes. * e.g. [domain/LDAP] in sssd.conf would translate to * config/domain/LDAP * @param[in] attribute The name of the attribute to update * @param[out] result A pointer to the retrieved array of strings * * @return 0 - Successfully retrieved the entry (or used the default) * @return ENOMEM - There was insufficient memory to complete the operation * @return EINVAL - The section could not be parsed, or the attribute was not * single-valued. * @return ENOENT - The attribute was not found. * @return EIO - An I/O error occurred while communicating with the ConfDB */ int confdb_get_string_as_list(struct confdb_ctx *cdb, TALLOC_CTX *ctx, const char *section, const char *attribute, char ***result); /** * @} */ #endif sssd-1.13.4/src/confdb/PaxHeaders.16287/confdb_setup.h0000644000000000000000000000007412703456111017173 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.520793174 sssd-1.13.4/src/confdb/confdb_setup.h0000644002412700241270000000274612703456111020653 0ustar00jhrozekjhrozek00000000000000/* SSSD Configuration Database Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef CONFDB_SETUP_H_ #define CONFDB_SETUP_H_ #define CONFDB_VERSION "2" #define CONFDB_VERSION_INT 2 #define CONFDB_BASE_LDIF \ "dn: @ATTRIBUTES\n" \ "cn: CASE_INSENSITIVE\n" \ "dc: CASE_INSENSITIVE\n" \ "dn: CASE_INSENSITIVE\n" \ "name: CASE_INSENSITIVE\n" \ "objectclass: CASE_INSENSITIVE\n" \ "\n" \ "dn: @INDEXLIST\n" \ "@IDXATTR: cn\n" \ "\n" \ "dn: @MODULES\n" \ "@LIST: server_sort\n" \ "\n" #define CONFDB_INTERNAL_LDIF \ "dn: cn=config\n" \ "version: "CONFDB_VERSION"\n" \ "\n" int confdb_create_base(struct confdb_ctx *cdb); int confdb_test(struct confdb_ctx *cdb); int confdb_init_db(const char *config_file, struct confdb_ctx *cdb); #endif /* CONFDB_SETUP_H_ */ sssd-1.13.4/src/confdb/PaxHeaders.16287/confdb_setup.c0000644000000000000000000000007412703456111017166 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.994794782 sssd-1.13.4/src/confdb/confdb_setup.c0000644002412700241270000002220612703456111020637 0ustar00jhrozekjhrozek00000000000000/* SSSD Configuration Database Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include "util/util.h" #include "db/sysdb.h" #include "confdb.h" #include "confdb_private.h" #include "confdb_setup.h" #include "util/sss_ini.h" int confdb_test(struct confdb_ctx *cdb) { char **values; int ret; ret = confdb_get_param(cdb, cdb, "config", "version", &values); if (ret != EOK) { return ret; } if (values[0] == NULL) { /* empty database, will need to init */ talloc_free(values); return ENOENT; } if (values[1] != NULL) { /* more than 1 value ?? */ talloc_free(values); return EIO; } if (strcmp(values[0], CONFDB_VERSION) != 0) { /* Existing version does not match executable version */ DEBUG(SSSDBG_CRIT_FAILURE, "Upgrading confdb version from %s to %s\n", values[0], CONFDB_VERSION); /* This is recoverable, since we purge the confdb file * when we re-initialize it. */ talloc_free(values); return ENOENT; } talloc_free(values); return EOK; } static int confdb_purge(struct confdb_ctx *cdb) { int ret, i; TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_dn *dn; const char *attrs[] = { "dn", NULL }; tmp_ctx = talloc_new(NULL); dn = ldb_dn_new(tmp_ctx, cdb->ldb, "cn=config"); /* Get the list of all DNs */ ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_SUBTREE, attrs, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } for(i=0; icount; i++) { /* Delete this DN */ ret = ldb_delete(cdb->ldb, res->msgs[i]->dn); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } done: talloc_free(tmp_ctx); return ret; } int confdb_create_base(struct confdb_ctx *cdb) { int ret; struct ldb_ldif *ldif; const char *base_ldif = CONFDB_BASE_LDIF; while ((ldif = ldb_ldif_read_string(cdb->ldb, &base_ldif))) { ret = ldb_add(cdb->ldb, ldif->msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to initialize DB (%d,[%s]), aborting!\n", ret, ldb_errstring(cdb->ldb)); return EIO; } ldb_ldif_read_free(cdb->ldb, ldif); } return EOK; } int confdb_init_db(const char *config_file, struct confdb_ctx *cdb) { TALLOC_CTX *tmp_ctx; int ret; int sret = EOK; int version; char timestr[21]; char *lasttimestr; bool in_transaction = false; const char *config_ldif; const char *vals[2] = { timestr, NULL }; struct ldb_ldif *ldif; struct sss_ini_initdata *init_data; tmp_ctx = talloc_new(cdb); if (tmp_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory.\n"); return ENOMEM; } init_data = sss_ini_initdata_init(tmp_ctx); if (!init_data) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory.\n"); ret = ENOMEM; goto done; } /* Open config file */ ret = sss_ini_config_file_open(init_data, config_file); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "sss_ini_config_file_open failed: %s [%d]\n", strerror(ret), ret); if (ret == ENOENT) { /* sss specific error denoting missing configuration file */ ret = ERR_MISSING_CONF; } goto done; } ret = sss_ini_config_access_check(init_data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Permission check on config file failed.\n"); ret = EPERM; goto done; } /* Determine if the conf file has changed since we last updated * the confdb */ ret = sss_ini_get_stat(init_data); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Status check on config file failed.\n"); ret = errno; goto done; } errno = 0; ret = sss_ini_get_mtime(init_data, sizeof(timestr), timestr); if (ret <= 0 || ret >= sizeof(timestr)) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to convert time_t to string ??\n"); ret = errno ? errno : EFAULT; } ret = confdb_get_string(cdb, tmp_ctx, "config", "lastUpdate", NULL, &lasttimestr); if (ret == EOK) { /* check if we lastUpdate and last file modification change differ*/ if ((lasttimestr != NULL) && (strcmp(lasttimestr, timestr) == 0)) { /* not changed, get out, nothing more to do */ ret = EOK; goto done; } } else { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get lastUpdate attribute.\n"); goto done; } ret = sss_ini_get_config(init_data, config_file); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load configuration\n"); goto done; } /* Make sure that the config file version matches the confdb version */ ret = sss_ini_get_cfgobj(init_data, "sssd", "config_file_version"); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Internal error determining config_file_version\n"); goto done; } ret = sss_ini_check_config_obj(init_data); if (ret != EOK) { /* No known version. Use default. */ DEBUG(SSSDBG_CONF_SETTINGS, "Value of config_file_version option not found. " "Assumed to be version %d.\n", CONFDB_DEFAULT_CFG_FILE_VER); } else { version = sss_ini_get_int_config_value(init_data, CONFDB_DEFAULT_CFG_FILE_VER, -1, &ret); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Config file version could not be determined\n"); goto done; } else if (version < CONFDB_VERSION_INT) { DEBUG(SSSDBG_FATAL_FAILURE, "Config file is an old version. " "Please run configuration upgrade script.\n"); ret = EINVAL; goto done; } else if (version > CONFDB_VERSION_INT) { DEBUG(SSSDBG_FATAL_FAILURE, "Config file version is newer than confdb\n"); ret = EINVAL; goto done; } } /* Set up a transaction to replace the configuration */ ret = ldb_transaction_start(cdb->ldb); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to start a transaction for " "updating the configuration\n"); ret = sysdb_error_to_errno(ret); goto done; } in_transaction = true; /* Purge existing database */ ret = confdb_purge(cdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not purge existing configuration\n"); goto done; } ret = sss_confdb_create_ldif(tmp_ctx, init_data, &config_ldif); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not create LDIF for confdb\n"); goto done; } DEBUG(SSSDBG_TRACE_LIBS, "LDIF file to import: \n%s\n", config_ldif); while ((ldif = ldb_ldif_read_string(cdb->ldb, &config_ldif))) { ret = ldb_add(cdb->ldb, ldif->msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to initialize DB (%d,[%s]), aborting!\n", ret, ldb_errstring(cdb->ldb)); ret = EIO; goto done; } ldb_ldif_read_free(cdb->ldb, ldif); } /* now store the lastUpdate time so that we do not re-init if nothing * changed on restart */ ret = confdb_add_param(cdb, true, "config", "lastUpdate", vals); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set last update time on db!\n"); goto done; } ret = ldb_transaction_commit(cdb->ldb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = ldb_transaction_cancel(cdb->ldb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } sss_ini_config_destroy(init_data); sss_ini_close_file(init_data); talloc_zfree(tmp_ctx); return ret; } sssd-1.13.4/src/confdb/PaxHeaders.16287/confdb.c0000644000000000000000000000007412703456111015746 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.828794219 sssd-1.13.4/src/confdb/confdb.c0000644002412700241270000012651512703456111017427 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Configuratoin DB Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include "util/util.h" #include "confdb/confdb.h" #include "confdb/confdb_private.h" #include "util/strtonum.h" #include "db/sysdb.h" #define CONFDB_ZERO_CHECK_OR_JUMP(var, ret, err, label) do { \ if (!var) { \ ret = err; \ goto label; \ } \ } while(0) /* Warning messages */ #define SAME_DOMAINS_ERROR_MSG "Domain '%s' is the same as or differs only "\ "in case from domain '%s'.\n" static char *prepend_cn(char *str, int *slen, const char *comp, int clen) { char *ret; ret = talloc_realloc(NULL, str, char, *slen + 4 + clen + 1); if (!ret) return NULL; /* move current string to the end */ memmove(&ret[clen +4], ret, *slen+1); /* includes termination */ memcpy(ret, "cn=", 3); memcpy(&ret[3], comp, clen); ret[clen+3] = ','; *slen = *slen + 4 + clen; return ret; } int parse_section(TALLOC_CTX *mem_ctx, const char *section, char **sec_dn, const char **rdn_name) { TALLOC_CTX *tmp_ctx; char *dn = NULL; char *p; const char *s; int l, ret; /* section must be a non null string and must not start with '/' */ if (!section || !*section || *section == '/') return EINVAL; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) return ENOMEM; s = section; l = 0; while ((p = strchrnul(s, '/'))) { if (l == 0) { dn = talloc_asprintf(tmp_ctx, "cn=%s", s); l = 3 + (p-s); dn[l] = '\0'; } else { dn = prepend_cn(dn, &l, s, p-s); } if (!dn) { ret = ENOMEM; goto done; } if (*p == '\0') { if (rdn_name) *rdn_name = s; break; /* reached end */ } s = p+1; if (*s == '\0') { /* a section cannot end in '.' */ ret = EINVAL; goto done; } } *sec_dn = talloc_steal(mem_ctx, dn); ret = EOK; done: talloc_free(tmp_ctx); return ret; } int confdb_add_param(struct confdb_ctx *cdb, bool replace, const char *section, const char *attribute, const char **values) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_message *msg; struct ldb_result *res; struct ldb_dn *dn; char *secdn; const char *rdn_name; int ret, i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } ret = parse_section(tmp_ctx, section, &secdn, &rdn_name); if (ret != EOK) { goto done; } dn = ldb_dn_new(tmp_ctx, cdb->ldb, secdn); CONFDB_ZERO_CHECK_OR_JUMP(dn, ret, EIO, done); ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } msg = ldb_msg_new(tmp_ctx); CONFDB_ZERO_CHECK_OR_JUMP(msg, ret, ENOMEM, done); msg->dn = talloc_steal(msg, dn); CONFDB_ZERO_CHECK_OR_JUMP(msg->dn, ret, ENOMEM, done); if (res->count == 0) { /* add a new message */ errno = 0; /* cn first */ ret = ldb_msg_add_string(msg, "cn", rdn_name); if (ret != LDB_SUCCESS) { if (errno) ret = errno; else ret = EIO; goto done; } /* now the requested attribute */ for (i = 0; values[i]; i++) { ret = ldb_msg_add_string(msg, attribute, values[i]); if (ret != LDB_SUCCESS) { if (errno) ret = errno; else ret = EIO; goto done; } } ret = ldb_add(cdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } } else { int optype; errno = 0; /* mark this as a replacement */ if (replace) optype = LDB_FLAG_MOD_REPLACE; else optype = LDB_FLAG_MOD_ADD; ret = ldb_msg_add_empty(msg, attribute, optype, NULL); if (ret != LDB_SUCCESS) { if (errno) ret = errno; else ret = EIO; goto done; } /* now the requested attribute */ for (i = 0; values[i]; i++) { ret = ldb_msg_add_string(msg, attribute, values[i]); if (ret != LDB_SUCCESS) { if (errno) ret = errno; else ret = EIO; goto done; } } ret = ldb_modify(cdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(ret), ret, ldb_errstring(cdb->ldb)); ret = EIO; goto done; } } ret = EOK; done: talloc_free(tmp_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add [%s] to [%s], error [%d] (%s)\n", attribute, section, ret, strerror(ret)); } return ret; } int confdb_get_param(struct confdb_ctx *cdb, TALLOC_CTX *mem_ctx, const char *section, const char *attribute, char ***values) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_dn *dn; char *secdn; const char *attrs[] = { attribute, NULL }; char **vals; struct ldb_message_element *el; int ret, i; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) return ENOMEM; ret = parse_section(tmp_ctx, section, &secdn, NULL); if (ret != EOK) { goto done; } dn = ldb_dn_new(tmp_ctx, cdb->ldb, secdn); if (!dn) { ret = EIO; goto done; } ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } if (res->count > 1) { ret = EIO; goto done; } vals = talloc_zero(mem_ctx, char *); ret = EOK; if (res->count > 0) { el = ldb_msg_find_element(res->msgs[0], attribute); if (el && el->num_values > 0) { vals = talloc_realloc(mem_ctx, vals, char *, el->num_values +1); if (!vals) { ret = ENOMEM; goto done; } /* should always be strings so this should be safe */ for (i = 0; i < el->num_values; i++) { struct ldb_val v = el->values[i]; vals[i] = talloc_strndup(vals, (char *)v.data, v.length); if (!vals[i]) { ret = ENOMEM; goto done; } } vals[i] = NULL; } } *values = vals; done: talloc_free(tmp_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get [%s] from [%s], error [%d] (%s)\n", attribute, section, ret, strerror(ret)); } return ret; } int confdb_set_string(struct confdb_ctx *cdb, const char *section, const char *attribute, const char *val) { TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; char *secdn; struct ldb_message *msg; int ret, lret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = parse_section(tmp_ctx, section, &secdn, NULL); if (ret != EOK) { goto done; } dn = ldb_dn_new(tmp_ctx, cdb->ldb, secdn); if (!dn) { ret = EIO; goto done; } msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = dn; lret = ldb_msg_add_empty(msg, attribute, LDB_FLAG_MOD_REPLACE, NULL); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_msg_add_empty failed: [%s]\n", ldb_strerror(lret)); ret = EIO; goto done; } lret = ldb_msg_add_string(msg, attribute, val); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_msg_add_string failed: [%s]\n", ldb_strerror(lret)); ret = EIO; goto done; } lret = ldb_modify(cdb->ldb, msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(lret), lret, ldb_errstring(cdb->ldb)); ret = EIO; goto done; } ret = EOK; done: talloc_free(tmp_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set [%s] from [%s], error [%d] (%s)\n", attribute, section, ret, strerror(ret)); } return ret; } int confdb_get_string(struct confdb_ctx *cdb, TALLOC_CTX *ctx, const char *section, const char *attribute, const char *defstr, char **result) { char **values = NULL; char *restr; int ret; ret = confdb_get_param(cdb, ctx, section, attribute, &values); if (ret != EOK) { goto failed; } if (values[0]) { if (values[1] != NULL) { /* too many values */ ret = EINVAL; goto failed; } restr = talloc_steal(ctx, values[0]); } else { /* Did not return a value, so use the default */ if (defstr == NULL) { /* No default given */ *result = NULL; talloc_free(values); return EOK; } /* Copy the default string */ restr = talloc_strdup(ctx, defstr); } if (!restr) { ret = ENOMEM; goto failed; } talloc_free(values); *result = restr; return EOK; failed: talloc_free(values); DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get [%s] from [%s], error [%d] (%s)\n", attribute, section, ret, strerror(ret)); return ret; } int confdb_get_int(struct confdb_ctx *cdb, const char *section, const char *attribute, int defval, int *result) { char **values = NULL; long val; int ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto failed; } ret = confdb_get_param(cdb, tmp_ctx, section, attribute, &values); if (ret != EOK) { goto failed; } if (values[0]) { if (values[1] != NULL) { /* too many values */ ret = EINVAL; goto failed; } errno = 0; val = strtol(values[0], NULL, 0); if (errno) { ret = errno; goto failed; } if (val < INT_MIN || val > INT_MAX) { ret = ERANGE; goto failed; } } else { val = defval; } talloc_free(tmp_ctx); *result = (int)val; return EOK; failed: talloc_free(tmp_ctx); DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read [%s] from [%s], error [%d] (%s)\n", attribute, section, ret, strerror(ret)); return ret; } long confdb_get_long(struct confdb_ctx *cdb, const char *section, const char *attribute, long defval, long *result) { char **values = NULL; long val; int ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto failed; } ret = confdb_get_param(cdb, tmp_ctx, section, attribute, &values); if (ret != EOK) { goto failed; } if (values[0]) { if (values[1] != NULL) { /* too many values */ ret = EINVAL; goto failed; } errno = 0; val = strtol(values[0], NULL, 0); if (errno) { ret = errno; goto failed; } } else { val = defval; } talloc_free(tmp_ctx); *result = val; return EOK; failed: talloc_free(tmp_ctx); DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read [%s] from [%s], error [%d] (%s)\n", attribute, section, ret, strerror(ret)); return ret; } int confdb_get_bool(struct confdb_ctx *cdb, const char *section, const char *attribute, bool defval, bool *result) { char **values = NULL; bool val; int ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto failed; } ret = confdb_get_param(cdb, tmp_ctx, section, attribute, &values); if (ret != EOK) { goto failed; } if (values[0]) { if (values[1] != NULL) { /* too many values */ ret = EINVAL; goto failed; } if (strcasecmp(values[0], "FALSE") == 0) { val = false; } else if (strcasecmp(values[0], "TRUE") == 0) { val = true; } else { DEBUG(SSSDBG_OP_FAILURE, "Value is not a boolean!\n"); ret = EINVAL; goto failed; } } else { val = defval; } talloc_free(tmp_ctx); *result = val; return EOK; failed: talloc_free(tmp_ctx); DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read [%s] from [%s], error [%d] (%s)\n", attribute, section, ret, strerror(ret)); return ret; } /* WARNING: Unlike other similar functions, this one does NOT take a default, * and returns ENOENT if the attribute was not found ! */ int confdb_get_string_as_list(struct confdb_ctx *cdb, TALLOC_CTX *ctx, const char *section, const char *attribute, char ***result) { char **values = NULL; int ret; ret = confdb_get_param(cdb, ctx, section, attribute, &values); if (ret != EOK) { goto done; } if (values && values[0]) { if (values[1] != NULL) { /* too many values */ ret = EINVAL; goto done; } } else { /* Did not return a value */ ret = ENOENT; goto done; } ret = split_on_separator(ctx, values[0], ',', true, true, result, NULL); done: talloc_free(values); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get [%s] from [%s], error [%d] (%s)\n", attribute, section, ret, strerror(ret)); } return ret; } int confdb_init(TALLOC_CTX *mem_ctx, struct confdb_ctx **cdb_ctx, const char *confdb_location) { struct confdb_ctx *cdb; int ret = EOK; mode_t old_umask; cdb = talloc_zero(mem_ctx, struct confdb_ctx); if (!cdb) return ENOMEM; /* Because confdb calls use sync ldb calls, we create a separate event * context here. This will prevent the ldb sync calls to start nested * events. * NOTE: this means that we *cannot* do async calls and return in confdb * unless we convert all calls and hook back to the main event context. */ cdb->pev = tevent_context_init(cdb); if (!cdb->pev) { talloc_free(cdb); return EIO; } cdb->ldb = ldb_init(cdb, cdb->pev); if (!cdb->ldb) { talloc_free(cdb); return EIO; } ret = ldb_set_debug(cdb->ldb, ldb_debug_messages, NULL); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE,"Could not set up debug fn.\n"); talloc_free(cdb); return EIO; } old_umask = umask(SSS_DFL_UMASK); ret = ldb_connect(cdb->ldb, confdb_location, 0, NULL); umask(old_umask); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to open config database [%s]\n", confdb_location); talloc_free(cdb); return EIO; } *cdb_ctx = cdb; return EOK; } static errno_t get_entry_as_uint32(struct ldb_message *msg, uint32_t *return_value, const char *entry, uint32_t default_value) { const char *tmp = NULL; char *endptr; uint32_t u32ret = 0; *return_value = 0; if (!msg || !entry) { return EFAULT; } tmp = ldb_msg_find_attr_as_string(msg, entry, NULL); if (tmp == NULL) { *return_value = default_value; return EOK; } if ((*tmp == '-') || (*tmp == '\0')) { return EINVAL; } u32ret = strtouint32 (tmp, &endptr, 10); if (errno) { return errno; } if (*endptr != '\0') { /* Not all of the string was a valid number */ return EINVAL; } *return_value = u32ret; return EOK; } static errno_t get_entry_as_bool(struct ldb_message *msg, bool *return_value, const char *entry, bool default_value) { const char *tmp = NULL; *return_value = 0; if (!msg || !entry) { return EFAULT; } tmp = ldb_msg_find_attr_as_string(msg, entry, NULL); if (tmp == NULL || *tmp == '\0') { *return_value = default_value; return EOK; } if (strcasecmp(tmp, "FALSE") == 0) { *return_value = 0; } else if (strcasecmp(tmp, "TRUE") == 0) { *return_value = 1; } else { return EINVAL; } return EOK; } /* The default UID/GID for domains is 1. This wouldn't work well with * the local provider */ static uint32_t confdb_get_min_id(struct sss_domain_info *domain) { uint32_t defval = SSSD_MIN_ID; if (domain && strcasecmp(domain->provider, "local") == 0) { defval = SSSD_LOCAL_MINID; } return defval; } static errno_t init_cached_auth_timeout(struct confdb_ctx *cdb, struct ldb_message *msg, uint32_t *_cached_auth_timeout) { int cred_expiration; int id_timeout; errno_t ret; uint32_t cached_auth_timeout; ret = get_entry_as_uint32(msg, &cached_auth_timeout, CONFDB_DOMAIN_CACHED_AUTH_TIMEOUT, 0); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_CACHED_AUTH_TIMEOUT); goto done; } ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_CRED_TIMEOUT, 0, &cred_expiration); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read expiration time of offline credentials.\n"); goto done; } /* convert from days to seconds */ cred_expiration *= 3600 * 24; if (cred_expiration != 0 && cred_expiration < cached_auth_timeout) { cached_auth_timeout = cred_expiration; } /* Set up the PAM identity timeout */ ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_ID_TIMEOUT, 5, &id_timeout); if (ret != EOK) goto done; if (cached_auth_timeout > id_timeout) { DEBUG(SSSDBG_MINOR_FAILURE, "cached_auth_timeout is greater than pam_id_timeout so be aware " "that back end could be called to handle initgroups.\n"); } ret = EOK; done: if (ret == EOK) { *_cached_auth_timeout = cached_auth_timeout; } return ret; } static int confdb_get_domain_internal(struct confdb_ctx *cdb, TALLOC_CTX *mem_ctx, const char *name, struct sss_domain_info **_domain) { struct sss_domain_info *domain; struct ldb_result *res; TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; const char *tmp; int ret, val; uint32_t entry_cache_timeout; char *default_domain; bool fqnames_default = false; int memcache_timeout; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) return ENOMEM; dn = ldb_dn_new_fmt(tmp_ctx, cdb->ldb, "cn=%s,%s", name, CONFDB_DOMAIN_BASEDN); if (!dn) { ret = ENOMEM; goto done; } ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } if (res->count != 1) { DEBUG(SSSDBG_FATAL_FAILURE, "Unknown domain [%s]\n", name); ret = ENOENT; goto done; } ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_MEMCACHE_TIMEOUT, 300, &memcache_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to get memory cache entry timeout.\n"); goto done; } domain = talloc_zero(mem_ctx, struct sss_domain_info); if (!domain) { ret = ENOMEM; goto done; } tmp = ldb_msg_find_attr_as_string(res->msgs[0], "cn", NULL); if (!tmp) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid configuration entry, fatal error!\n"); ret = EINVAL; goto done; } domain->name = talloc_strdup(domain, tmp); if (!domain->name) { ret = ENOMEM; goto done; } domain->conn_name = domain->name; tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_DOMAIN_ID_PROVIDER, NULL); if (tmp) { domain->provider = talloc_strdup(domain, tmp); if (!domain->provider) { ret = ENOMEM; goto done; } } else { DEBUG(SSSDBG_FATAL_FAILURE, "Domain [%s] does not specify an ID provider, disabling!\n", domain->name); ret = EINVAL; goto done; } if (strcasecmp(domain->provider, "files") == 0) { /* The files provider is not valid anymore */ DEBUG(SSSDBG_FATAL_FAILURE, "The \"files\" provider is invalid\n"); ret = EINVAL; goto done; } if (strcasecmp(domain->provider, "local") == 0) { /* If this is the local provider, we need to ensure that * no other provider was specified for other types, since * the local provider cannot load them. */ tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_DOMAIN_AUTH_PROVIDER, NULL); if (tmp && strcasecmp(tmp, "local") != 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Local ID provider does not support [%s] as an AUTH provider.\n", tmp); ret = EINVAL; goto done; } tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_DOMAIN_ACCESS_PROVIDER, NULL); if (tmp && strcasecmp(tmp, "permit") != 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Local ID provider does not support [%s] as an ACCESS provider.\n", tmp); ret = EINVAL; goto done; } tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_DOMAIN_CHPASS_PROVIDER, NULL); if (tmp && strcasecmp(tmp, "local") != 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Local ID provider does not support [%s] as a CHPASS provider.\n", tmp); ret = EINVAL; goto done; } /* The LOCAL provider use always Magic Private Groups */ domain->mpg = true; } domain->timeout = ldb_msg_find_attr_as_int(res->msgs[0], CONFDB_DOMAIN_TIMEOUT, 0); /* Determine if this domain can be enumerated */ /* TEMP: test if the old bitfield conf value is used and warn it has been * superceeded. */ val = ldb_msg_find_attr_as_int(res->msgs[0], CONFDB_DOMAIN_ENUMERATE, 0); if (val > 0) { /* ok there was a number in here */ DEBUG(SSSDBG_FATAL_FAILURE, "Warning: enumeration parameter in %s still uses integers! " "Enumeration is now a boolean and takes true/false values. " "Interpreting as true\n", domain->name); domain->enumerate = true; } else { /* assume the new format */ ret = get_entry_as_bool(res->msgs[0], &domain->enumerate, CONFDB_DOMAIN_ENUMERATE, 0); if(ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for %s\n", CONFDB_DOMAIN_ENUMERATE); goto done; } } if (!domain->enumerate) { DEBUG(SSSDBG_TRACE_FUNC, "No enumeration for [%s]!\n", domain->name); } ret = confdb_get_string(cdb, tmp_ctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_DEFAULT_DOMAIN, NULL, &default_domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannnot get the default domain [%d]: %s\n", ret, strerror(ret)); goto done; } /* Determine if user/group names will be Fully Qualified * in NSS interfaces */ if (default_domain != NULL) { DEBUG(SSSDBG_CONF_SETTINGS, "Default domain suffix set. Changing default for " "use_fully_qualified_names to True.\n"); fqnames_default = true; } ret = get_entry_as_bool(res->msgs[0], &domain->fqnames, CONFDB_DOMAIN_FQ, fqnames_default); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for %s\n", CONFDB_DOMAIN_FQ); goto done; } if (default_domain != NULL && domain->fqnames == false) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid configuration detected (default_domain_suffix is used " "while use_fully_qualified_names was set to false).\n"); ret = ERR_INVALID_CONFIG; goto done; } ret = get_entry_as_bool(res->msgs[0], &domain->ignore_group_members, CONFDB_DOMAIN_IGNORE_GROUP_MEMBERS, 0); if(ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for %s\n", CONFDB_DOMAIN_IGNORE_GROUP_MEMBERS); goto done; } ret = get_entry_as_uint32(res->msgs[0], &domain->id_min, CONFDB_DOMAIN_MINID, confdb_get_min_id(domain)); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for minId\n"); ret = EINVAL; goto done; } ret = get_entry_as_uint32(res->msgs[0], &domain->id_max, CONFDB_DOMAIN_MAXID, 0); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for maxId\n"); ret = EINVAL; goto done; } if (domain->id_max && (domain->id_max < domain->id_min)) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid domain range\n"); ret = EINVAL; goto done; } /* Do we allow to cache credentials */ ret = get_entry_as_bool(res->msgs[0], &domain->cache_credentials, CONFDB_DOMAIN_CACHE_CREDS, 0); if(ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for %s\n", CONFDB_DOMAIN_CACHE_CREDS); goto done; } ret = get_entry_as_uint32(res->msgs[0], &domain->cache_credentials_min_ff_length, CONFDB_DOMAIN_CACHE_CREDS_MIN_FF_LENGTH, CONFDB_DEFAULT_CACHE_CREDS_MIN_FF_LENGTH); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for %s\n", CONFDB_DOMAIN_CACHE_CREDS_MIN_FF_LENGTH); goto done; } ret = get_entry_as_bool(res->msgs[0], &domain->legacy_passwords, CONFDB_DOMAIN_LEGACY_PASS, 0); if(ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for %s\n", CONFDB_DOMAIN_LEGACY_PASS); goto done; } /* Get the global entry cache timeout setting */ ret = get_entry_as_uint32(res->msgs[0], &entry_cache_timeout, CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT, 5400); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT); goto done; } /* Override the user cache timeout, if specified */ ret = get_entry_as_uint32(res->msgs[0], &domain->user_timeout, CONFDB_DOMAIN_USER_CACHE_TIMEOUT, entry_cache_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_USER_CACHE_TIMEOUT); goto done; } if (domain->user_timeout < memcache_timeout) { DEBUG(SSSDBG_CONF_SETTINGS, "%s is less than %s. User records will not be updated before " "memory cache entry expires.\n", CONFDB_DOMAIN_USER_CACHE_TIMEOUT, CONFDB_MEMCACHE_TIMEOUT); } /* Override the group cache timeout, if specified */ ret = get_entry_as_uint32(res->msgs[0], &domain->group_timeout, CONFDB_DOMAIN_GROUP_CACHE_TIMEOUT, entry_cache_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_GROUP_CACHE_TIMEOUT); goto done; } if (domain->group_timeout < memcache_timeout) { DEBUG(SSSDBG_CONF_SETTINGS, "%s is less than %s. Group records will not be updated before " "memory cache entry expires.\n", CONFDB_DOMAIN_GROUP_CACHE_TIMEOUT, CONFDB_MEMCACHE_TIMEOUT); } /* Override the netgroup cache timeout, if specified */ ret = get_entry_as_uint32(res->msgs[0], &domain->netgroup_timeout, CONFDB_DOMAIN_NETGROUP_CACHE_TIMEOUT, entry_cache_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_NETGROUP_CACHE_TIMEOUT); goto done; } /* Override the service cache timeout, if specified */ ret = get_entry_as_uint32(res->msgs[0], &domain->service_timeout, CONFDB_DOMAIN_SERVICE_CACHE_TIMEOUT, entry_cache_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_SERVICE_CACHE_TIMEOUT); goto done; } /* Override the autofs cache timeout, if specified */ ret = get_entry_as_uint32(res->msgs[0], &domain->autofsmap_timeout, CONFDB_DOMAIN_AUTOFS_CACHE_TIMEOUT, entry_cache_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_AUTOFS_CACHE_TIMEOUT); goto done; } /* Override the sudo cache timeout, if specified */ ret = get_entry_as_uint32(res->msgs[0], &domain->sudo_timeout, CONFDB_DOMAIN_SUDO_CACHE_TIMEOUT, entry_cache_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_SUDO_CACHE_TIMEOUT); goto done; } /* Override the ssh known hosts timeout, if specified */ ret = get_entry_as_uint32(res->msgs[0], &domain->ssh_host_timeout, CONFDB_DOMAIN_SSH_HOST_CACHE_TIMEOUT, entry_cache_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_SSH_HOST_CACHE_TIMEOUT); goto done; } /* Set refresh_expired_interval, if specified */ ret = get_entry_as_uint32(res->msgs[0], &domain->refresh_expired_interval, CONFDB_DOMAIN_REFRESH_EXPIRED_INTERVAL, 0); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_REFRESH_EXPIRED_INTERVAL); goto done; } /* detect and fix misconfiguration */ if (domain->refresh_expired_interval > entry_cache_timeout) { DEBUG(SSSDBG_CONF_SETTINGS, "refresh_expired_interval (%d) cannot be greater than " "entry_cache_timeout (%u)\n", domain->refresh_expired_interval, entry_cache_timeout); domain->refresh_expired_interval = 0.75 * entry_cache_timeout; DEBUG(SSSDBG_CONF_SETTINGS, "refresh_expired_interval is being set to recommended value " "entry_cache_timeout * 0.75 (%u).\n", domain->refresh_expired_interval); } /* Set the PAM warning time, if specified. If not specified, pass on * the "not set" value of "-1" which means "use provider default". The * value 0 means "always display the warning if server sends one" */ domain->pwd_expiration_warning = -1; val = ldb_msg_find_attr_as_int(res->msgs[0], CONFDB_DOMAIN_PWD_EXPIRATION_WARNING, -1); if (val == -1) { ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_PWD_EXPIRATION_WARNING, -1, &val); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read PAM expiration warning, not fatal.\n"); val = -1; } } DEBUG(SSSDBG_TRACE_LIBS, "pwd_expiration_warning is %d\n", val); if (val >= 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Setting domain password expiration warning to %d days\n", val); /* The value is in days, transform it to seconds */ domain->pwd_expiration_warning = val * 24 * 3600; } ret = get_entry_as_uint32(res->msgs[0], &domain->override_gid, CONFDB_DOMAIN_OVERRIDE_GID, 0); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_OVERRIDE_GID); goto done; } tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_NSS_OVERRIDE_HOMEDIR, NULL); if (tmp != NULL) { domain->override_homedir = talloc_strdup(domain, tmp); if (!domain->override_homedir) { ret = ENOMEM; goto done; } } tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_NSS_FALLBACK_HOMEDIR, NULL); if (tmp != NULL) { domain->fallback_homedir = talloc_strdup(domain, tmp); if (!domain->fallback_homedir) { ret = ENOMEM; goto done; } } tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_DOMAIN_SUBDOMAIN_HOMEDIR, CONFDB_DOMAIN_DEFAULT_SUBDOMAIN_HOMEDIR); if (tmp != NULL) { domain->subdomain_homedir = talloc_strdup(domain, tmp); if (!domain->subdomain_homedir) { ret = ENOMEM; goto done; } } tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_NSS_HOMEDIR_SUBSTRING, NULL); if (tmp != NULL) { domain->homedir_substr = talloc_strdup(domain, tmp); if (domain->homedir_substr == NULL) { ret = ENOMEM; goto done; } } tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_NSS_OVERRIDE_SHELL, NULL); if (tmp != NULL) { domain->override_shell = talloc_strdup(domain, tmp); if (!domain->override_shell) { ret = ENOMEM; goto done; } } tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_NSS_DEFAULT_SHELL, NULL); if (tmp != NULL) { domain->default_shell = talloc_strdup(domain, tmp); if (!domain->default_shell) { ret = ENOMEM; goto done; } } tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_DOMAIN_CASE_SENSITIVE, "true"); if (tmp != NULL) { if (strcasecmp(tmp, "true") == 0) { domain->case_sensitive = true; domain->case_preserve = true; } else if (strcasecmp(tmp, "false") == 0) { domain->case_sensitive = false; domain->case_preserve = false; } else if (strcasecmp(tmp, "preserving") == 0) { domain->case_sensitive = false; domain->case_preserve = true; } else { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for %s\n", CONFDB_DOMAIN_CASE_SENSITIVE); goto done; } } else { /* default */ domain->case_sensitive = true; domain->case_preserve = true; } if (domain->case_sensitive == false && strcasecmp(domain->provider, "local") == 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Local ID provider does not support the case insensitive flag\n"); ret = EINVAL; goto done; } tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_SUBDOMAIN_ENUMERATE, CONFDB_DEFAULT_SUBDOMAIN_ENUMERATE); if (tmp != NULL) { ret = split_on_separator(domain, tmp, ',', true, true, &domain->sd_enumerate, NULL); if (ret != 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot parse %s\n", CONFDB_SUBDOMAIN_ENUMERATE); goto done; } } tmp = ldb_msg_find_attr_as_string(res->msgs[0], CONFDB_DOMAIN_SUBDOMAIN_INHERIT, NULL); if (tmp != NULL) { ret = split_on_separator(domain, tmp, ',', true, true, &domain->sd_inherit, NULL); if (ret != 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot parse %s\n", CONFDB_SUBDOMAIN_ENUMERATE); goto done; } } ret = get_entry_as_uint32(res->msgs[0], &domain->subdomain_refresh_interval, CONFDB_DOMAIN_SUBDOMAIN_REFRESH, 14400); if (ret != EOK || domain->subdomain_refresh_interval == 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for [%s]\n", CONFDB_DOMAIN_SUBDOMAIN_REFRESH); goto done; } ret = init_cached_auth_timeout(cdb, res->msgs[0], &domain->cached_auth_timeout); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "init_cached_auth_timeout failed: %s:[%d].\n", sss_strerror(ret), ret); goto done; } domain->has_views = false; domain->view_name = NULL; domain->state = DOM_ACTIVE; *_domain = domain; ret = EOK; done: talloc_free(tmp_ctx); return ret; } int confdb_get_domains(struct confdb_ctx *cdb, struct sss_domain_info **domains) { TALLOC_CTX *tmp_ctx; struct sss_domain_info *domain = NULL; char **domlist; int ret, i; if (cdb->doms) { *domains = cdb->doms; return EOK; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; ret = confdb_get_string_as_list(cdb, tmp_ctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_ACTIVE_DOMAINS, &domlist); if (ret == ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "No domains configured, fatal error!\n"); goto done; } if (ret != EOK ) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal error retrieving domains list!\n"); goto done; } for (i = 0; domlist[i]; i++) { /* check if domain name is really unique */ DLIST_FOR_EACH(domain, cdb->doms) { if (strcasecmp(domain->name, domlist[i]) == 0) { DEBUG(SSSDBG_FATAL_FAILURE, SAME_DOMAINS_ERROR_MSG, domlist[i], domain->name); sss_log(SSS_LOG_CRIT, SAME_DOMAINS_ERROR_MSG, domlist[i], domain->name); ret = EINVAL; goto done; } } domain = NULL; ret = confdb_get_domain_internal(cdb, cdb, domlist[i], &domain); if (ret) { DEBUG(SSSDBG_FATAL_FAILURE, "Error (%d [%s]) retrieving domain [%s], skipping!\n", ret, sss_strerror(ret), domlist[i]); continue; } DLIST_ADD_END(cdb->doms, domain, struct sss_domain_info *); } if (cdb->doms == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "No properly configured domains, fatal error!\n"); ret = ENOENT; goto done; } *domains = cdb->doms; ret = EOK; done: talloc_free(tmp_ctx); return ret; } int confdb_get_domain(struct confdb_ctx *cdb, const char *name, struct sss_domain_info **_domain) { struct sss_domain_info *dom, *doms; int ret; ret = confdb_get_domains(cdb, &doms); if (ret != EOK) { return ret; } for (dom = doms; dom; dom = get_next_domain(dom, 0)) { if (strcasecmp(dom->name, name) == 0) { *_domain = dom; return EOK; } } return ENOENT; } int confdb_list_all_domain_names(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, char ***_names) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_dn *dn = NULL; struct ldb_result *res = NULL; static const char *attrs[] = {CONFDB_DOMAIN_ATTR, NULL}; const char *name = NULL; char **names = NULL; int i; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } dn = ldb_dn_new(tmp_ctx, cdb->ldb, CONFDB_DOMAIN_BASEDN); if (dn == NULL) { ret = ENOMEM; goto done; } ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_ONELEVEL, attrs, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } names = talloc_zero_array(tmp_ctx, char*, res->count + 1); if (names == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < res->count; i++) { name = ldb_msg_find_attr_as_string(res->msgs[i], CONFDB_DOMAIN_ATTR, NULL); if (name == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "The object [%s] doesn't have a name\n", ldb_dn_get_linearized(res->msgs[i]->dn)); ret = EINVAL; goto done; } names[i] = talloc_strdup(names, name); if (names[i] == NULL) { ret = ENOMEM; goto done; } } *_names = talloc_steal(mem_ctx, names); ret = EOK; done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/confdb/PaxHeaders.16287/confdb_private.h0000644000000000000000000000007412703456111017505 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.518793167 sssd-1.13.4/src/confdb/confdb_private.h0000644002412700241270000000206112703456111021153 0ustar00jhrozekjhrozek00000000000000/* SSSD Configuration Database Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef CONFDB_PRIVATE_H_ #define CONFDB_PRIVATE_H_ struct confdb_ctx { struct tevent_context *pev; struct ldb_context *ldb; struct sss_domain_info *doms; }; int parse_section(TALLOC_CTX *mem_ctx, const char *section, char **sec_dn, const char **rdn_name); #endif /* CONFDB_PRIVATE_H_ */ sssd-1.13.4/src/PaxHeaders.16287/sysv0000644000000000000000000000013212703463556014051 xustar0030 mtime=1460561774.639793578 30 atime=1460561776.118798593 30 ctime=1460561774.639793578 sssd-1.13.4/src/sysv/0000755002412700241270000000000012703463556015602 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sysv/PaxHeaders.16287/systemd0000644000000000000000000000013212703463557015542 xustar0030 mtime=1460561775.062795012 30 atime=1460561776.118798593 30 ctime=1460561775.062795012 sssd-1.13.4/src/sysv/systemd/0000755002412700241270000000000012703463557017273 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sysv/systemd/PaxHeaders.16287/journal.conf.in0000644000000000000000000000007412703456111020536 xustar0030 atime=1460561751.655715644 30 ctime=1460561775.062795012 sssd-1.13.4/src/sysv/systemd/journal.conf.in0000644002412700241270000000042012703456111022201 0ustar00jhrozekjhrozek00000000000000[Service] # Uncomment *both* of the following lines to enable debug logging # to go to journald instead of /var/log/sssd. You will need to # run 'systemctl daemon-reload' and then restart the SSSD service # for this to take effect #ExecStart= #ExecStart=@sbindir@/sssd -D sssd-1.13.4/src/sysv/systemd/PaxHeaders.16287/sssd.service.in0000644000000000000000000000007412703456111020553 xustar0030 atime=1460561751.655715644 30 ctime=1460561775.061795009 sssd-1.13.4/src/sysv/systemd/sssd.service.in0000644002412700241270000000072712703456111022230 0ustar00jhrozekjhrozek00000000000000[Unit] Description=System Security Services Daemon # SSSD must be running before we permit user sessions Before=systemd-user-sessions.service nss-user-lookup.target Wants=nss-user-lookup.target [Service] EnvironmentFile=-@environment_file@ ExecStart=@sbindir@/sssd -D -f # These two should be used with traditional UNIX forking daemons # consult systemd.service(5) for more details Type=forking PIDFile=@localstatedir@/run/sssd.pid [Install] WantedBy=multi-user.target sssd-1.13.4/src/sysv/PaxHeaders.16287/gentoo0000644000000000000000000000013212703463556015344 xustar0030 mtime=1460561774.638793575 30 atime=1460561776.118798593 30 ctime=1460561774.638793575 sssd-1.13.4/src/sysv/gentoo/0000755002412700241270000000000012703463556017075 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sysv/gentoo/PaxHeaders.16287/sssd.in0000644000000000000000000000007412703456111016717 xustar0030 atime=1460561772.625786749 30 ctime=1460561774.638793575 sssd-1.13.4/src/sysv/gentoo/sssd.in0000644002412700241270000000051512703456111020367 0ustar00jhrozekjhrozek00000000000000#!/sbin/runscript depend(){ need localmount netmount clock use syslog xdm } start(){ ebegin "Starting sssd" start-stop-daemon --start --exec @sbindir@/sssd -- -Df ${SSSD_OPTIONS} eend ${?} } stop(){ ebegin "Stopping sssd" start-stop-daemon --stop --pidfile @localstatedir@/run/sssd.pid eend ${?} } sssd-1.13.4/src/sysv/PaxHeaders.16287/SUSE0000644000000000000000000000013212703463556014630 xustar0030 mtime=1460561774.637793571 30 atime=1460561776.118798593 30 ctime=1460561774.637793571 sssd-1.13.4/src/sysv/SUSE/0000755002412700241270000000000012703463556016361 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sysv/SUSE/PaxHeaders.16287/sssd.in0000644000000000000000000000007412703456111016203 xustar0030 atime=1460561772.636786786 30 ctime=1460561774.637793571 sssd-1.13.4/src/sysv/SUSE/sssd.in0000644002412700241270000000340312703456111017652 0ustar00jhrozekjhrozek00000000000000#!/bin/sh ### BEGIN INIT INFO # Provides: sssd # Required-Start: $remote_fs $time # Should-Start: $syslog # Should-Stop: $syslog # Required-Stop: $remote_fs # Default-Start: 3 5 # Default-Stop: 0 1 2 4 6 # Short-Description: System Security Services Daemon # Description: Provides a set of daemons to manage access to remote directories # and authentication mechanisms. It provides an NSS and PAM # interface toward the system and a pluggable backend system to # connect to multiple different account sources. It is also the # basis to provide client auditing and policy services for projects # like FreeIPA. ### END INIT INFO RETVAL=0 prog="sssd" # Source function library. . /etc/rc.status rc_reset SSSD=@sbindir@/sssd PID_FILE=@localstatedir@/run/sssd.pid case "$1" in start) echo -n "Starting $prog " /sbin/startproc $SSSD -f -D 2>/dev/null rc_status -v ;; stop) echo -n "Shutting down $prog " /sbin/killproc -p $PID_FILE $SSSD -TERM rc_status -v ;; restart) $0 stop $0 start rc_status ;; reload) echo -n "Reload service $prog " killproc $SSSD -HUP rc_status -v ;; force-reload) $0 reload ;; status) echo -n "Checking for service $prog" /sbin/checkproc $SSSD rc_status -v ;; condrestart|try-restart) $0 status if test $? = 0; then $0 restart else rc_reset # Not running is not a failure. fi rc_status ;; *) echo "Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" exit 1 esac rc_exit sssd-1.13.4/src/sysv/PaxHeaders.16287/sssd.in0000644000000000000000000000007412703456111015424 xustar0030 atime=1460561772.612786705 30 ctime=1460561774.639793578 sssd-1.13.4/src/sysv/sssd.in0000644002412700241270000000522612703456111017100 0ustar00jhrozekjhrozek00000000000000#!/bin/sh # # # chkconfig: - 12 88 # description: Provides a set of daemons to manage access to remote directories # and authentication mechanisms. It provides an NSS and PAM # interface toward the system and a pluggable backend system to # connect to multiple different account sources. It is also the # basis to provide client auditing and policy services for projects # like FreeIPA. # ### BEGIN INIT INFO # Provides: sssd # Required-Start: $remote_fs $time # Should-Start: $syslog # Should-Stop: $null # Required-Stop: $null # Default-Stop: 0 1 6 # Short-Description: System Security Services Daemon # Description: Provides a set of daemons to manage access to remote directories # and authentication mechanisms. It provides an NSS and PAM # interface toward the system and a pluggable backend system to # connect to multiple different account sources. It is also the # basis to provide client auditing and policy services for projects # like FreeIPA. ### END INIT INFO RETVAL=0 prog="sssd" # Source function library. . /etc/init.d/functions if [ -f @environment_file@ ]; then . @environment_file@ fi SSSD=@sbindir@/sssd LOCK_FILE=@localstatedir@/lock/subsys/sssd PID_FILE=@localstatedir@/run/sssd.pid start() { [ -x $SSSD ] || exit 5 echo -n $"Starting $prog: " daemon $SSSD -f -D RETVAL=$? echo [ "$RETVAL" = 0 ] && touch $LOCK_FILE return $RETVAL } stop() { echo -n $"Stopping $prog: " pid=`cat $PID_FILE` killproc -p $PID_FILE $SSSD -TERM RETVAL=$? # Wait until the monitor exits while (checkpid $pid) do usleep 100000 done echo [ "$RETVAL" = 0 ] && rm -f $LOCK_FILE return $RETVAL } reload() { echo -n $"Reloading $prog: " killproc $SSSD -HUP RETVAL=$? echo return $RETVAL } restart() { stop start } force_reload() { restart } rh_status() { # run checks to determine if the service is running or use generic status status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 restart ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" exit 2 esac exit $? sssd-1.13.4/src/PaxHeaders.16287/util0000644000000000000000000000013212703463556014022 xustar0030 mtime=1460561774.884794409 30 atime=1460561776.118798593 30 ctime=1460561774.884794409 sssd-1.13.4/src/util/0000755002412700241270000000000012703463556015553 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/util/PaxHeaders.16287/sss_semanage.c0000644000000000000000000000007412703456111016705 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.813794168 sssd-1.13.4/src/util/sss_semanage.c0000644002412700241270000002762512703456111020370 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_semanage.c Copyright (C) Jakub Hrozek 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #ifdef HAVE_SEMANAGE #include #endif #include "util/util.h" #ifndef DEFAULT_SERANGE #define DEFAULT_SERANGE "s0" #endif #ifdef HAVE_SEMANAGE /* turn libselinux messages into SSSD DEBUG() calls */ static void sss_semanage_error_callback(void *varg, semanage_handle_t *handle, const char *fmt, ...) { int level = SSSDBG_INVALID; va_list ap; switch (semanage_msg_get_level(handle)) { case SEMANAGE_MSG_ERR: level = SSSDBG_CRIT_FAILURE; break; case SEMANAGE_MSG_WARN: level = SSSDBG_MINOR_FAILURE; break; case SEMANAGE_MSG_INFO: level = SSSDBG_TRACE_FUNC; break; } va_start(ap, fmt); if (DEBUG_IS_SET(level)) { sss_vdebug_fn(__FILE__, __LINE__, "libsemanage", level, 0, fmt, ap); } va_end(ap); } static void sss_semanage_close(semanage_handle_t *handle) { if (handle == NULL) { return; /* semanage uses asserts */ } if (semanage_is_connected(handle)) { semanage_disconnect(handle); } semanage_handle_destroy(handle); } static semanage_handle_t *sss_semanage_init(void) { int ret; semanage_handle_t *handle = NULL; handle = semanage_handle_create(); if (!handle) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n"); return NULL; } semanage_msg_set_callback(handle, sss_semanage_error_callback, NULL); ret = semanage_is_managed(handle); if (ret != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "SELinux policy not managed\n"); goto fail; } ret = semanage_access_check(handle); if (ret < SEMANAGE_CAN_READ) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot read SELinux policy store\n"); goto fail; } ret = semanage_connect(handle); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot estabilish SELinux management connection\n"); goto fail; } return handle; fail: sss_semanage_close(handle); return NULL; } static int sss_semanage_user_add(semanage_handle_t *handle, semanage_seuser_key_t *key, const char *login_name, const char *seuser_name, const char *mls) { int ret; semanage_seuser_t *seuser = NULL; ret = semanage_seuser_create(handle, &seuser); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux login mapping for %s\n", login_name); ret = EIO; goto done; } ret = semanage_seuser_set_name(handle, seuser, login_name); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set name for %s\n", login_name); ret = EIO; goto done; } ret = semanage_seuser_set_mlsrange(handle, seuser, mls ? mls : DEFAULT_SERANGE); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set serange for %s\n", login_name); ret = EIO; goto done; } ret = semanage_seuser_set_sename(handle, seuser, seuser_name); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set SELinux user for %s\n", login_name); ret = EIO; goto done; } ret = semanage_seuser_modify_local(handle, key, seuser); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add login mapping for %s\n", login_name); ret = EIO; goto done; } ret = EOK; done: semanage_seuser_free(seuser); return ret; } static int sss_semanage_user_mod(semanage_handle_t *handle, semanage_seuser_key_t *key, const char *login_name, const char *seuser_name, const char *mls) { int ret; semanage_seuser_t *seuser = NULL; semanage_seuser_query(handle, key, &seuser); if (seuser == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not query seuser for %s\n", login_name); ret = EIO; goto done; } ret = semanage_seuser_set_mlsrange(handle, seuser, mls ? mls : DEFAULT_SERANGE); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set serange for %s\n", login_name); ret = EIO; goto done; } ret = semanage_seuser_set_sename(handle, seuser, seuser_name); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set sename for %s\n", login_name); ret = EIO; goto done; } ret = semanage_seuser_modify_local(handle, key, seuser); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, ("Could not modify login mapping for %s\n"), login_name); ret = EIO; goto done; } ret = EOK; done: semanage_seuser_free(seuser); return ret; } int set_seuser(const char *login_name, const char *seuser_name, const char *mls) { semanage_handle_t *handle = NULL; semanage_seuser_key_t *key = NULL; int ret; int seuser_exists = 0; if (seuser_name == NULL) { /* don't care, just let system pick the defaults */ return EOK; } handle = sss_semanage_init(); if (!handle) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init SELinux management\n"); ret = EIO; goto done; } ret = semanage_begin_transaction(handle); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot begin SELinux transaction\n"); ret = EIO; goto done; } ret = semanage_seuser_key_create(handle, login_name, &key); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux user key\n"); ret = EIO; goto done; } ret = semanage_seuser_exists(handle, key, &seuser_exists); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot verify the SELinux user\n"); ret = EIO; goto done; } if (seuser_exists) { ret = sss_semanage_user_mod(handle, key, login_name, seuser_name, mls); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot modify SELinux user mapping\n"); ret = EIO; goto done; } } else { ret = sss_semanage_user_add(handle, key, login_name, seuser_name, mls); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add SELinux user mapping\n"); ret = EIO; goto done; } } ret = semanage_commit(handle); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot commit SELinux transaction\n"); ret = EIO; goto done; } ret = EOK; done: semanage_seuser_key_free(key); sss_semanage_close(handle); return ret; } int del_seuser(const char *login_name) { semanage_handle_t *handle = NULL; semanage_seuser_key_t *key = NULL; int ret; int exists = 0; handle = sss_semanage_init(); if (!handle) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot init SELinux management\n"); ret = EIO; goto done; } ret = semanage_begin_transaction(handle); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot begin SELinux transaction\n"); ret = EIO; goto done; } ret = semanage_seuser_key_create(handle, login_name, &key); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux user key\n"); ret = EIO; goto done; } ret = semanage_seuser_exists(handle, key, &exists); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot verify the SELinux user\n"); ret = EIO; goto done; } if (!exists) { DEBUG(SSSDBG_FUNC_DATA, "Login mapping for %s is not defined, OK if default mapping " "was used\n", login_name); ret = EOK; /* probably default mapping */ goto done; } ret = semanage_seuser_exists_local(handle, key, &exists); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot verify the SELinux user\n"); ret = EIO; goto done; } if (!exists) { DEBUG(SSSDBG_CRIT_FAILURE, "Login mapping for %s is defined in policy, cannot be deleted\n", login_name); ret = ENOENT; goto done; } ret = semanage_seuser_del_local(handle, key); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete login mapping for %s\n", login_name); ret = EIO; goto done; } ret = semanage_commit(handle); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot commit SELinux transaction\n"); ret = EIO; goto done; } ret = EOK; done: sss_semanage_close(handle); return ret; } int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name, char **_seuser, char **_mls_range) { errno_t ret; const char *seuser; const char *mls_range; semanage_handle_t *sm_handle = NULL; semanage_seuser_t *sm_user = NULL; semanage_seuser_key_t *sm_key = NULL; sm_handle = sss_semanage_init(); if (sm_handle == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux handle\n"); ret = EIO; goto done; } ret = semanage_seuser_key_create(sm_handle, login_name, &sm_key); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create key for %s\n", login_name); ret = EIO; goto done; } ret = semanage_seuser_query(sm_handle, sm_key, &sm_user); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot query for %s\n", login_name); ret = EIO; goto done; } seuser = semanage_seuser_get_sename(sm_user); if (seuser != NULL) { *_seuser = talloc_strdup(mem_ctx, seuser); if (*_seuser == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_OP_FAILURE, "SELinux user for %s: %s\n", login_name, *_seuser); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get sename for %s\n", login_name); } mls_range = semanage_seuser_get_mlsrange(sm_user); if (mls_range != NULL) { *_mls_range = talloc_strdup(mem_ctx, mls_range); if (*_mls_range == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_OP_FAILURE, "SELinux range for %s: %s\n", login_name, *_mls_range); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get mlsrange for %s\n", login_name); } ret = EOK; done: semanage_seuser_key_free(sm_key); semanage_seuser_free(sm_user); sss_semanage_close(sm_handle); return ret; } #else /* HAVE_SEMANAGE */ int set_seuser(const char *login_name, const char *seuser_name, const char *mls) { return EOK; } int del_seuser(const char *login_name) { return EOK; } int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name, char **_seuser, char **_mls_range) { return EOK; } #endif /* HAVE_SEMANAGE */ sssd-1.13.4/src/util/PaxHeaders.16287/util.c0000644000000000000000000000007412703456111015212 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.856794314 sssd-1.13.4/src/util/util.c0000644002412700241270000007051312703456111016667 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "util/sss_utf8.h" int split_on_separator(TALLOC_CTX *mem_ctx, const char *str, const char sep, bool trim, bool skip_empty, char ***_list, int *size) { int ret; const char *substr_end = str; const char *substr_begin = str; const char *sep_pos = NULL; size_t substr_len; char **list = NULL; int num_strings = 0; TALLOC_CTX *tmp_ctx = NULL; if (str == NULL || *str == '\0' || _list == NULL) { return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } do { substr_len = 0; /* If this is not the first substring, then move from the separator. */ if (sep_pos != NULL) { substr_end = sep_pos + 1; substr_begin = sep_pos + 1; } /* Find end of the first substring */ while (*substr_end != sep && *substr_end != '\0') { substr_end++; substr_len++; } sep_pos = substr_end; if (trim) { /* Trim leading whitespace */ while (isspace(*substr_begin) && substr_begin < substr_end) { substr_begin++; substr_len--; } /* Trim trailing whitespace */ while (substr_end - 1 > substr_begin && isspace(*(substr_end-1))) { substr_end--; substr_len--; } } /* Copy the substring to the output list of strings */ if (skip_empty == false || substr_len > 0) { list = talloc_realloc(tmp_ctx, list, char*, num_strings + 2); if (list == NULL) { ret = ENOMEM; goto done; } /* empty string is stored for substr_len == 0 */ list[num_strings] = talloc_strndup(list, substr_begin, substr_len); if (list[num_strings] == NULL) { ret = ENOMEM; goto done; } num_strings++; } } while (*sep_pos != '\0'); if (list == NULL) { /* No allocations were done, make space for the NULL */ list = talloc(tmp_ctx, char *); if (list == NULL) { ret = ENOMEM; goto done; } } list[num_strings] = NULL; if (size) { *size = num_strings; } *_list = talloc_steal(mem_ctx, list); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static void free_args(char **args) { int i; if (args) { for (i = 0; args[i]; i++) free(args[i]); free(args); } } /* parse a string into arguments. * arguments are separated by a space * '\' is an escape character and can be used only to escape * itself or the white space. */ char **parse_args(const char *str) { const char *p; char **ret, **r; char *tmp; int num; int i; bool e, w; tmp = malloc(strlen(str) + 1); if (!tmp) return NULL; ret = NULL; num = 0; i = 0; e = false; /* skip leading whitespaces */ w = true; p = str; while (*p) { if (*p == '\\') { w = false; if (e) { /* if we were already escaping, add a '\' literal */ tmp[i] = '\\'; i++; e = false; } else { /* otherwise just start escaping */ e = true; } } else if (isspace(*p)) { if (e) { /* Add escaped whitespace literally */ tmp[i] = *p; i++; e = false; } else if (w == false) { /* If previous character was non-whitespace, arg break */ tmp[i] = '\0'; i++; w = true; } /* previous char was whitespace as well, skip it */ } else { w = false; if (e) { /* Prepend escaped chars with a literal \ */ tmp[i] = '\\'; i++; e = false; } /* Copy character from the source string */ tmp[i] = *p; i++; } p++; /* check if this was the last char */ if (*p == '\0') { if (e) { tmp[i] = '\\'; i++; e = false; } tmp[i] = '\0'; i++; } /* save token to result array */ if (i > 1 && tmp[i-1] == '\0') { r = realloc(ret, (num + 2) * sizeof(char *)); if (!r) goto fail; ret = r; ret[num+1] = NULL; ret[num] = strdup(tmp); if (!ret[num]) goto fail; num++; i = 0; } } free(tmp); return ret; fail: free(tmp); free_args(ret); return NULL; } char **dup_string_list(TALLOC_CTX *memctx, const char **str_list) { int i = 0; int j = 0; char **dup_list; if (!str_list) { return NULL; } /* Find the size of the list */ while (str_list[i]) i++; dup_list = talloc_array(memctx, char *, i+1); if (!dup_list) { return NULL; } /* Copy the elements */ for (j = 0; j < i; j++) { dup_list[j] = talloc_strdup(dup_list, str_list[j]); if (!dup_list[j]) { talloc_free(dup_list); return NULL; } } /* NULL-terminate the list */ dup_list[i] = NULL; return dup_list; } /* Take two string lists (terminated on a NULL char*) * and return up to three arrays of strings based on * shared ownership. * * Pass NULL to any return type you don't care about */ errno_t diff_string_lists(TALLOC_CTX *memctx, char **_list1, char **_list2, char ***_list1_only, char ***_list2_only, char ***_both_lists) { int error; errno_t ret; int i; int i2 = 0; int i12 = 0; hash_table_t *table; hash_key_t key; hash_value_t value; char **list1 = NULL; char **list2 = NULL; char **list1_only = NULL; char **list2_only = NULL; char **both_lists = NULL; unsigned long count; hash_key_t *keys; TALLOC_CTX *tmp_ctx = talloc_new(memctx); if (!tmp_ctx) { return ENOMEM; } if (!_list1) { list1 = talloc_array(tmp_ctx, char *, 1); if (!list1) { talloc_free(tmp_ctx); return ENOMEM; } list1[0] = NULL; } else { list1 = _list1; } if (!_list2) { list2 = talloc_array(tmp_ctx, char *, 1); if (!list2) { talloc_free(tmp_ctx); return ENOMEM; } list2[0] = NULL; } else { list2 = _list2; } error = hash_create(10, &table, NULL, NULL); if (error != HASH_SUCCESS) { talloc_free(tmp_ctx); return EIO; } key.type = HASH_KEY_STRING; value.type = HASH_VALUE_UNDEF; /* Add all entries from list 1 into a hash table */ i = 0; while (list1[i]) { key.str = talloc_strdup(tmp_ctx, list1[i]); error = hash_enter(table, &key, &value); if (error != HASH_SUCCESS) { ret = EIO; goto done; } i++; } /* Iterate through list 2 and remove matching items */ i = 0; while (list2[i]) { key.str = talloc_strdup(tmp_ctx, list2[i]); error = hash_delete(table, &key); if (error == HASH_SUCCESS) { if (_both_lists) { /* String was present in both lists */ i12++; both_lists = talloc_realloc(tmp_ctx, both_lists, char *, i12+1); if (!both_lists) { ret = ENOMEM; goto done; } both_lists[i12-1] = talloc_strdup(both_lists, list2[i]); if (!both_lists[i12-1]) { ret = ENOMEM; goto done; } both_lists[i12] = NULL; } } else if (error == HASH_ERROR_KEY_NOT_FOUND) { if (_list2_only) { /* String was present only in list2 */ i2++; list2_only = talloc_realloc(tmp_ctx, list2_only, char *, i2+1); if (!list2_only) { ret = ENOMEM; goto done; } list2_only[i2-1] = talloc_strdup(list2_only, list2[i]); if (!list2_only[i2-1]) { ret = ENOMEM; goto done; } list2_only[i2] = NULL; } } else { /* An error occurred */ ret = EIO; goto done; } i++; } /* Get the leftover entries in the hash table */ if (_list1_only) { error = hash_keys(table, &count, &keys); if (error != HASH_SUCCESS) { ret = EIO; goto done; } list1_only = talloc_array(tmp_ctx, char *, count+1); if (!list1_only) { ret = ENOMEM; goto done; } for (i = 0; i < count; i++) { list1_only[i] = talloc_strdup(list1_only, keys[i].str); if (!list1_only[i]) { ret = ENOMEM; goto done; } } list1_only[count] = NULL; free(keys); *_list1_only = talloc_steal(memctx, list1_only); } if (_list2_only) { if (list2_only) { *_list2_only = talloc_steal(memctx, list2_only); } else { *_list2_only = talloc_array(memctx, char *, 1); if (!(*_list2_only)) { ret = ENOMEM; goto done; } *_list2_only[0] = NULL; } } if (_both_lists) { if (both_lists) { *_both_lists = talloc_steal(memctx, both_lists); } else { *_both_lists = talloc_array(memctx, char *, 1); if (!(*_both_lists)) { ret = ENOMEM; goto done; } *_both_lists[0] = NULL; } } ret = EOK; done: hash_destroy(table); talloc_free(tmp_ctx); return ret; } static void *hash_talloc(const size_t size, void *pvt) { return talloc_size(pvt, size); } static void hash_talloc_free(void *ptr, void *pvt) { talloc_free(ptr); } errno_t sss_hash_create_ex(TALLOC_CTX *mem_ctx, unsigned long count, hash_table_t **tbl, unsigned int directory_bits, unsigned int segment_bits, unsigned long min_load_factor, unsigned long max_load_factor, hash_delete_callback *delete_callback, void *delete_private_data) { errno_t ret; hash_table_t *table; int hret; TALLOC_CTX *internal_ctx; internal_ctx = talloc_new(NULL); if (!internal_ctx) { return ENOMEM; } hret = hash_create_ex(count, &table, directory_bits, segment_bits, min_load_factor, max_load_factor, hash_talloc, hash_talloc_free, internal_ctx, delete_callback, delete_private_data); switch (hret) { case HASH_SUCCESS: /* Steal the table pointer onto the mem_ctx, * then make the internal_ctx a child of * table. * * This way, we can clean up the values when * we talloc_free() the table */ *tbl = talloc_steal(mem_ctx, table); talloc_steal(table, internal_ctx); return EOK; case HASH_ERROR_NO_MEMORY: ret = ENOMEM; break; default: ret = EIO; } DEBUG(SSSDBG_FATAL_FAILURE, "Could not create hash table: [%d][%s]\n", hret, hash_error_string(hret)); talloc_free(internal_ctx); return ret; } errno_t sss_hash_create(TALLOC_CTX *mem_ctx, unsigned long count, hash_table_t **tbl) { return sss_hash_create_ex(mem_ctx, count, tbl, 0, 0, 0, 0, NULL, NULL); } errno_t sss_filter_sanitize_ex(TALLOC_CTX *mem_ctx, const char *input, char **sanitized, const char *ignore) { char *output; size_t i = 0; size_t j = 0; char *allowed; /* Assume the worst-case. We'll resize it later, once */ output = talloc_array(mem_ctx, char, strlen(input) * 3 + 1); if (!output) { return ENOMEM; } while (input[i]) { /* Even though this character might have a special meaning, if it's * expliticly allowed, just copy it and move on */ if (ignore == NULL) { allowed = NULL; } else { allowed = strchr(ignore, input[i]); } if (allowed) { output[j++] = input[i++]; continue; } switch(input[i]) { case '\t': output[j++] = '\\'; output[j++] = '0'; output[j++] = '9'; break; case ' ': output[j++] = '\\'; output[j++] = '2'; output[j++] = '0'; break; case '*': output[j++] = '\\'; output[j++] = '2'; output[j++] = 'a'; break; case '(': output[j++] = '\\'; output[j++] = '2'; output[j++] = '8'; break; case ')': output[j++] = '\\'; output[j++] = '2'; output[j++] = '9'; break; case '\\': output[j++] = '\\'; output[j++] = '5'; output[j++] = 'c'; break; default: output[j++] = input[i]; } i++; } output[j] = '\0'; *sanitized = talloc_realloc(mem_ctx, output, char, j+1); if (!*sanitized) { talloc_free(output); return ENOMEM; } return EOK; } errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx, const char *input, char **sanitized) { return sss_filter_sanitize_ex(mem_ctx, input, sanitized, NULL); } char * sss_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr) { return family == AF_INET6 ? talloc_asprintf(mem_ctx, "[%s]", addr) : talloc_strdup(mem_ctx, addr); } /* out->len includes terminating '\0' */ void to_sized_string(struct sized_string *out, const char *in) { out->str = in; if (out->str) { out->len = strlen(out->str) + 1; } else { out->len = 0; } } /* This function only removes first and last * character if the first character was '['. * * NOTE: This means, that ipv6addr must NOT be followed * by port number. */ errno_t remove_ipv6_brackets(char *ipv6addr) { size_t len; if (ipv6addr && ipv6addr[0] == '[') { len = strlen(ipv6addr); if (len < 3) { return EINVAL; } memmove(ipv6addr, &ipv6addr[1], len - 2); ipv6addr[len -2] = '\0'; } return EOK; } errno_t add_string_to_list(TALLOC_CTX *mem_ctx, const char *string, char ***list_p) { size_t c; char **old_list = NULL; char **new_list = NULL; if (string == NULL || list_p == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing string or list.\n"); return EINVAL; } old_list = *list_p; if (old_list == NULL) { /* If the input is a NULL list a new one is created with the new * string and the terminating NULL element. */ c = 0; new_list = talloc_array(mem_ctx, char *, 2); } else { for (c = 0; old_list[c] != NULL; c++); /* Allocate one extra space for the new service and one for * the terminating NULL */ new_list = talloc_realloc(mem_ctx, old_list, char *, c + 2); } if (new_list == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array/talloc_realloc failed.\n"); return ENOMEM; } new_list[c] = talloc_strdup(new_list, string); if (new_list[c] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); talloc_free(new_list); return ENOMEM; } new_list[c + 1] = NULL; *list_p = new_list; return EOK; } bool string_in_list(const char *string, char **list, bool case_sensitive) { size_t c; int(*compare)(const char *s1, const char *s2); if (string == NULL || list == NULL || *list == NULL) { return false; } compare = case_sensitive ? strcmp : strcasecmp; for (c = 0; list[c] != NULL; c++) { if (compare(string, list[c]) == 0) { return true; } } return false; } void safezero(void *data, size_t size) { volatile uint8_t *p = data; while (size--) { *p++ = 0; } } int domain_to_basedn(TALLOC_CTX *memctx, const char *domain, char **basedn) { const char *s; char *dn; char *p; int l; if (!domain || !basedn) { return EINVAL; } s = domain; dn = talloc_strdup(memctx, "dc="); while ((p = strchr(s, '.'))) { l = p - s; dn = talloc_asprintf_append_buffer(dn, "%.*s,dc=", l, s); if (!dn) { return ENOMEM; } s = p + 1; } dn = talloc_strdup_append_buffer(dn, s); if (!dn) { return ENOMEM; } for (p=dn; *p; ++p) { *p = tolower(*p); } *basedn = dn; return EOK; } bool is_host_in_domain(const char *host, const char *domain) { int diff = strlen(host) - strlen(domain); if (diff == 0 && strcmp(host, domain) == 0) { return true; } if (diff > 0 && strcmp(host + diff, domain) == 0 && host[diff - 1] == '.') { return true; } return false; } /* addr is in network order for both IPv4 and IPv6 versions */ bool check_ipv4_addr(struct in_addr *addr, uint8_t flags) { char straddr[INET_ADDRSTRLEN]; if (inet_ntop(AF_INET, addr, straddr, INET_ADDRSTRLEN) == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "inet_ntop failed, won't log IP addresses\n"); snprintf(straddr, INET_ADDRSTRLEN, "unknown"); } if ((flags & SSS_NO_MULTICAST) && IN_MULTICAST(ntohl(addr->s_addr))) { DEBUG(SSSDBG_FUNC_DATA, "Multicast IPv4 address %s\n", straddr); return false; } else if ((flags & SSS_NO_LOOPBACK) && inet_netof(*addr) == IN_LOOPBACKNET) { DEBUG(SSSDBG_FUNC_DATA, "Loopback IPv4 address %s\n", straddr); return false; } else if ((flags & SSS_NO_LINKLOCAL) && (addr->s_addr & htonl(0xffff0000)) == htonl(0xa9fe0000)) { /* 169.254.0.0/16 */ DEBUG(SSSDBG_FUNC_DATA, "Link-local IPv4 address %s\n", straddr); return false; } else if ((flags & SSS_NO_BROADCAST) && addr->s_addr == htonl(INADDR_BROADCAST)) { DEBUG(SSSDBG_FUNC_DATA, "Broadcast IPv4 address %s\n", straddr); return false; } return true; } bool check_ipv6_addr(struct in6_addr *addr, uint8_t flags) { char straddr[INET6_ADDRSTRLEN]; if (inet_ntop(AF_INET6, addr, straddr, INET6_ADDRSTRLEN) == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "inet_ntop failed, won't log IP addresses\n"); snprintf(straddr, INET6_ADDRSTRLEN, "unknown"); } if ((flags & SSS_NO_LINKLOCAL) && IN6_IS_ADDR_LINKLOCAL(addr)) { DEBUG(SSSDBG_FUNC_DATA, "Link local IPv6 address %s\n", straddr); return false; } else if ((flags & SSS_NO_LOOPBACK) && IN6_IS_ADDR_LOOPBACK(addr)) { DEBUG(SSSDBG_FUNC_DATA, "Loopback IPv6 address %s\n", straddr); return false; } else if ((flags & SSS_NO_MULTICAST) && IN6_IS_ADDR_MULTICAST(addr)) { DEBUG(SSSDBG_FUNC_DATA, "Multicast IPv6 address %s\n", straddr); return false; } return true; } const char * const * get_known_services(void) { static const char *svc[] = {"nss", "pam", "sudo", "autofs", "ssh", "pac", "ifp", NULL }; return svc; } errno_t add_strings_lists(TALLOC_CTX *mem_ctx, const char **l1, const char **l2, bool copy_strings, char ***_new_list) { size_t c; size_t l1_count = 0; size_t l2_count = 0; size_t new_count = 0; char **new; int ret; if (l1 != NULL) { for (l1_count = 0; l1[l1_count] != NULL; l1_count++); } if (l2 != NULL) { for (l2_count = 0; l2[l2_count] != NULL; l2_count++); } new_count = l1_count + l2_count; new = talloc_array(mem_ctx, char *, new_count + 1); if (new == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); return ENOMEM; } new [new_count] = NULL; if (copy_strings) { for(c = 0; c < l1_count; c++) { new[c] = talloc_strdup(new, l1[c]); if (new[c] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } for(c = 0; c < l2_count; c++) { new[l1_count + c] = talloc_strdup(new, l2[c]); if (new[l1_count + c] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } } else { if (l1 != NULL) { memcpy(new, l1, sizeof(char *) * l1_count); } if (l2 != NULL) { memcpy(&new[l1_count], l2, sizeof(char *) * l2_count); } } *_new_list = new; ret = EOK; done: if (ret != EOK) { talloc_free(new); } return ret; } /* Set the nonblocking flag to the fd */ errno_t sss_fd_nonblocking(int fd) { int flags; int ret; flags = fcntl(fd, F_GETFL, 0); if (flags == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "F_GETFL failed [%d][%s].\n", ret, strerror(ret)); return ret; } if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "F_SETFL failed [%d][%s].\n", ret, strerror(ret)); return ret; } return EOK; } /* Convert GeneralizedTime (http://en.wikipedia.org/wiki/GeneralizedTime) * to unix time (seconds since epoch). Use UTC time zone. */ errno_t sss_utc_to_time_t(const char *str, const char *format, time_t *_unix_time) { char *end; struct tm tm; size_t len; time_t ut; if (str == NULL) { return EINVAL; } len = strlen(str); if (str[len-1] != 'Z') { DEBUG(SSSDBG_TRACE_INTERNAL, "%s does not seem to be in UTZ time zone.\n", str); return ERR_TIMESPEC_NOT_SUPPORTED; } memset(&tm, 0, sizeof(tm)); end = strptime(str, format, &tm); /* not all characters from format were matched */ if (end == NULL) { DEBUG(SSSDBG_TRACE_INTERNAL, "String [%s] failed to match format [%s].\n", str, format); return EINVAL; } /* str is 'longer' than format */ if (*end != '\0') { DEBUG(SSSDBG_TRACE_INTERNAL, "String [%s] is longer than format [%s].\n", str, format); return EINVAL; } ut = mktime(&tm); if (ut == -1) { DEBUG(SSSDBG_TRACE_INTERNAL, "mktime failed to convert [%s].\n", str); return EINVAL; } tzset(); ut -= timezone; *_unix_time = ut; return EOK; } struct tmpfile_watch { const char *filename; }; static int unlink_dbg(const char *filename) { errno_t ret; ret = unlink(filename); if (ret != 0) { if (errno == 2) { DEBUG(SSSDBG_TRACE_INTERNAL, "File already removed: [%s]\n", filename); return 0; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot remove temporary file [%s]\n", filename); return -1; } } return 0; } static int unique_filename_destructor(void *memptr) { struct tmpfile_watch *tw = talloc_get_type(memptr, struct tmpfile_watch); if (tw == NULL || tw->filename == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Wrong private pointer\n"); return -1; } DEBUG(SSSDBG_TRACE_INTERNAL, "Unlinking [%s]\n", tw->filename); return unlink_dbg(tw->filename); } static struct tmpfile_watch *tmpfile_watch_set(TALLOC_CTX *owner, const char *filename) { struct tmpfile_watch *tw = NULL; tw = talloc_zero(owner, struct tmpfile_watch); if (tw == NULL) { return NULL; } tw->filename = talloc_strdup(tw, filename); if (tw->filename == NULL) { talloc_free(tw); return NULL; } talloc_set_destructor((TALLOC_CTX *) tw, unique_filename_destructor); return tw; } int sss_unique_file_ex(TALLOC_CTX *owner, char *path_tmpl, mode_t file_umask, errno_t *_err) { size_t tmpl_len; errno_t ret; int fd = -1; mode_t old_umask; struct tmpfile_watch *tw = NULL; tmpl_len = strlen(path_tmpl); if (tmpl_len < 6 || strcmp(path_tmpl + (tmpl_len - 6), "XXXXXX") != 0) { DEBUG(SSSDBG_OP_FAILURE, "Template too short or doesn't end with XXXXXX!\n"); ret = EINVAL; goto done; } old_umask = umask(file_umask); fd = mkstemp(path_tmpl); umask(old_umask); if (fd == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "mkstemp(\"%s\") failed [%d]: %s!\n", path_tmpl, ret, strerror(ret)); goto done; } if (owner != NULL) { tw = tmpfile_watch_set(owner, path_tmpl); if (tw == NULL) { unlink_dbg(path_tmpl); ret = ENOMEM; goto done; } } ret = EOK; done: if (_err) { *_err = ret; } return fd; } int sss_unique_file(TALLOC_CTX *owner, char *path_tmpl, errno_t *_err) { return sss_unique_file_ex(owner, path_tmpl, 077, _err); } errno_t sss_unique_filename(TALLOC_CTX *owner, char *path_tmpl) { int fd; errno_t ret; fd = sss_unique_file(owner, path_tmpl, &ret); /* We only care about a unique file name */ if (fd >= 0) { close(fd); } return ret; } errno_t parse_cert_verify_opts(const char *verify_opts, bool *do_ocsp) { int ret; TALLOC_CTX *tmp_ctx; char **opts; size_t c; if (verify_opts == NULL) { *do_ocsp = true; return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = split_on_separator(tmp_ctx, verify_opts, ',', true, true, &opts, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "split_on_separator failed.\n"); goto done; } for (c = 0; opts[c] != NULL; c++) { if (strcasecmp(opts[c], "no_ocsp") == 0) { DEBUG(SSSDBG_TRACE_ALL, "Found 'no_ocsp' option, disabling OCSP.\n"); *do_ocsp = false; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported certificate verification option [%s], " \ "skipping.\n", opts[c]); } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/util/PaxHeaders.16287/user_info_msg.c0000644000000000000000000000007412703456111017074 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.800794124 sssd-1.13.4/src/util/user_info_msg.c0000644002412700241270000000334612703456111020551 0ustar00jhrozekjhrozek00000000000000/* SSSD Pack user info messages Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/user_info_msg.h" #include "sss_client/sss_cli.h" errno_t pack_user_info_chpass_error(TALLOC_CTX *mem_ctx, const char *user_error_message, size_t *resp_len, uint8_t **_resp) { uint32_t resp_type = SSS_PAM_USER_INFO_CHPASS_ERROR; size_t err_len; uint8_t *resp; size_t p; err_len = strlen(user_error_message); *resp_len = 2 * sizeof(uint32_t) + err_len; resp = talloc_size(mem_ctx, *resp_len); if (resp == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); return ENOMEM; } p = 0; SAFEALIGN_SET_UINT32(&resp[p], resp_type, &p); SAFEALIGN_SET_UINT32(&resp[p], err_len, &p); safealign_memcpy(&resp[p], user_error_message, err_len, &p); if (p != *resp_len) { DEBUG(SSSDBG_FATAL_FAILURE, "Size mismatch\n"); } *_resp = resp; return EOK; } sssd-1.13.4/src/util/PaxHeaders.16287/safe-format-string.h0000644000000000000000000000007412703456111017752 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.410792801 sssd-1.13.4/src/util/safe-format-string.h0000644002412700241270000000602112703456111021420 0ustar00jhrozekjhrozek00000000000000/* * This file originated in the realmd project * * Copyright 2013 Red Hat Inc * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2 of the licence or (at * your option) any later version. * * See the included COPYING file for more information. * * Author: Stef Walter */ #include "config.h" #ifndef __SAFE_FORMAT_STRING_H__ #define __SAFE_FORMAT_STRING_H__ #include /* * This is a neutered printf variant that can be used with user-provided * format strings. * * Not only are the normal printf functions not safe to use on user-provided * input (ie: can crash, be abused, etc), they're also very brittle with * regards to positional arguments: one must consume them all or printf will * just abort(). This is because arguments of different sizes are accepted * in the varargs. So obviously the positional code cannot know the offset * of the relevant varargs if some are not consumed (ie: tagged with a * field type). * * Thus the only accepted field type here is 's'. It's all we need. * * In general new code should use a better syntax than printf format strings * for configuration options. This code is here to facilitate robust processing * of the full_name_format syntax we already have, which has been documented as * "printf(3) compatible". * * Features: * - Only string 's' fields are supported * - All the varargs should be strings, followed by a NULL argument * - Both positional '%$1s' and non-positional '%s' are supported * - Field widths '%8s' work as expected * - Precision '%.8s' works, but precision cannot be read from a field * - Left alignment flag is supported '%-8s'. * - The space flag '% 8s' has no effect (it's the default for string fields). * - No more than six digits are supported for widths, precisions, etc. * - Percent signs are to be escaped as usual '%%' * * Use of other flags or field types will cause the relevant printf call to * return -1. Using too many arguments or incorrect positional arguments * will also cause the call to fail. * * Functions return -1 on failure and set errno. Otherwise they return * the full length of the string that would be formatted, with the same * semantics as snprintf(). */ #ifndef GNUC_NULL_TERMINATED #if __GNUC__ >= 4 #define GNUC_NULL_TERMINATED __attribute__((__sentinel__)) #else #define GNUC_NULL_TERMINATED #endif #endif int safe_format_string (char *str, size_t len, const char *format, ...) GNUC_NULL_TERMINATED; int safe_format_string_cb (void (* callback) (void *data, const char *piece, size_t len), void *data, const char *format, const char * const args[], int num_args); #endif /* __SAFE_FORMAT_STRING_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/authtok.h0000644000000000000000000000007412703456111015721 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.440792903 sssd-1.13.4/src/util/authtok.h0000644002412700241270000002335612703456111017401 0ustar00jhrozekjhrozek00000000000000/* SSSD - auth utils Copyright (C) Simo Sorce 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __AUTHTOK_H__ #define __AUTHTOK_H__ #include "util/util.h" #include "util/authtok-utils.h" #include "sss_client/sss_cli.h" /* Use sss_authtok_* accesor functions instead of struct sss_auth_token */ struct sss_auth_token; /** * @brief Returns the token type * * @param tok A pointer to an sss_auth_token * * @return A sss_authtok_type (empty, password, ...) */ enum sss_authtok_type sss_authtok_get_type(struct sss_auth_token *tok); /** * @brief Returns the token size * * @param tok A pointer to an sss_auth_token * * @return The current size of the token payload */ size_t sss_authtok_get_size(struct sss_auth_token *tok); /** * @brief Get the data buffer * * @param tok A pointer to an sss_auth_token * * @return A pointer to the token payload */ uint8_t *sss_authtok_get_data(struct sss_auth_token *tok); /** * @brief Returns a const string if the auth token is of type SSS_AUTHTOK_TYPE_PASSWORD, otherwise it returns an error * * @param tok A pointer to an sss_auth_token * @param pwd A pointer to a const char *, that will point to a null * terminated string * @param len The length of the password string * * @return EOK on success * ENOENT if the token is empty * EACCESS if the token is not a password token */ errno_t sss_authtok_get_password(struct sss_auth_token *tok, const char **pwd, size_t *len); /** * @brief Set a password into a an auth token, replacing any previous data * * @param tok A pointer to a sss_auth_token structure to change, also * used as a memory context to allocate the internal data. * @param password A string * @param len The length of the string or, if 0 is passed, * then strlen(password) will be used internally. * * @return EOK on success * ENOMEM on error */ errno_t sss_authtok_set_password(struct sss_auth_token *tok, const char *password, size_t len); /** * @brief Returns a const string if the auth token is of type SSS_AUTHTOK_TYPE_CCFILE, otherwise it returns an error * * @param tok A pointer to an sss_auth_token * @param ccfile A pointer to a const char *, that will point to a null * terminated string, also used as a memory context use to allocate the internal data * @param len The length of the string * * @return EOK on success * ENOENT if the token is empty * EACCESS if the token is not a password token */ errno_t sss_authtok_get_ccfile(struct sss_auth_token *tok, const char **ccfile, size_t *len); /** * @brief Set a cc file name into a an auth token, replacing any previous data * * @param tok A pointer to a sss_auth_token structure to change, also * used as a memory context to allocate the internal data. * @param ccfile A null terminated string * @param len The length of the string * * @return EOK on success * ENOMEM on error */ errno_t sss_authtok_set_ccfile(struct sss_auth_token *tok, const char *ccfile, size_t len); /** * @brief Resets an auth token to the empty status * * @param tok A pointer to a sss_auth_token structure to reset * * NOTE: This function uses safezero() on the payload if the type * is SSS_AUTHTOK_TYPE_PASSWORD */ void sss_authtok_set_empty(struct sss_auth_token *tok); /** * @brief Set an auth token by type, replacing any previous data * * @param tok A pointer to a sss_auth_token structure to change, also * used as a memory context to allocate the internal data. * @param type A valid authtok type * @param data A data pointer * @param len The length of the data * * @return EOK on success * ENOMEM or EINVAL on error */ errno_t sss_authtok_set(struct sss_auth_token *tok, enum sss_authtok_type type, const uint8_t *data, size_t len); /** * @brief Copy an auth token from source to destination * * @param src The source auth token * @param dst The destination auth token, also used as a memory context * to allocate dst internal data. * * @return EOK on success * ENOMEM on error */ errno_t sss_authtok_copy(struct sss_auth_token *src, struct sss_auth_token *dst); /** * @brief Uses safezero to wipe the password from memory if the * authtoken contains a password, otherwise does nothing. * * @param tok A pointer to a sss_auth_token structure to change * * NOTE: This function should only be used in destructors or similar * functions where freing the actual string is unsafe and where it can * be guaranteed that the auth token will not be used anymore. * Use sss_authtok_set_empty() in normal circumstances. */ void sss_authtok_wipe_password(struct sss_auth_token *tok); /** * @brief Create new empty struct sss_auth_token. * * @param mem_ctx A memory context use to allocate the internal data * @return A pointer to new empty struct sss_auth_token * NULL in case of failure * * NOTE: This function is the only way, how to create new empty * struct sss_auth_token. */ struct sss_auth_token *sss_authtok_new(TALLOC_CTX *mem_ctx); /** * @brief Set authtoken with 2FA data * * @param tok A pointer to a sss_auth_token structure to change, also * used as a memory context to allocate the internal data. * @param[in] fa1 First authentication factor, null terminated * @param[in] fa1_len Length of the first authentication factor, if 0 * strlen() will be called internally * @param[in] fa2 Second authentication factor, null terminated * @param[in] fa2_len Length of the second authentication factor, if 0 * strlen() will be called internally * * @return EOK on success * ENOMEM if memory allocation failed * EINVAL if input data is not consistent */ errno_t sss_authtok_set_2fa(struct sss_auth_token *tok, const char *fa1, size_t fa1_len, const char *fa2, size_t fa2_len); /** * @brief Get 2FA factors from authtoken * * @param tok A pointer to a sss_auth_token structure to change, also * used as a memory context to allocate the internal data. * @param[out] fa1 A pointer to a const char *, that will point to a * null terminated string holding the first * authentication factor, may not be modified or freed * @param[out] fa1_len Length of the first authentication factor * @param[out] fa2 A pointer to a const char *, that will point to a * null terminated string holding the second * authentication factor, may not be modified or freed * @param[out] fa2_len Length of the second authentication factor * * @return EOK on success * ENOMEM if memory allocation failed * EINVAL if input data is not consistent * ENOENT if the token is empty * EACCESS if the token is not a 2FA token */ errno_t sss_authtok_get_2fa(struct sss_auth_token *tok, const char **fa1, size_t *fa1_len, const char **fa2, size_t *fa2_len); /** * @brief Set a Smart Card pin into a an auth token, replacing any previous data * * @param tok A pointer to a sss_auth_token structure to change, also * used as a memory context to allocate the internal data. * @param pin A string * @param len The length of the string or, if 0 is passed, * then strlen(password) will be used internally. * * @return EOK on success * ENOMEM on error */ errno_t sss_authtok_set_sc_pin(struct sss_auth_token *tok, const char *pin, size_t len); /** * @brief Returns a Smart Card pin as const string if the auth token is of * type SSS_AUTHTOK_TYPE_SC_PIN, otherwise it returns an error * * @param tok A pointer to an sss_auth_token * @param pin A pointer to a const char *, that will point to a null * terminated string * @param len The length of the pin string * * @return EOK on success * ENOENT if the token is empty * EACCESS if the token is not a Smart Card pin token */ errno_t sss_authtok_get_sc_pin(struct sss_auth_token *tok, const char **pin, size_t *len); /** * @brief Sets an auth token to type SSS_AUTHTOK_TYPE_SC_KEYPAD, replacing any * previous data * * @param tok A pointer to a sss_auth_token structure to change, also * used as a memory context to allocate the internal data. */ void sss_authtok_set_sc_keypad(struct sss_auth_token *tok); #endif /* __AUTHTOK_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/strtonum.h0000644000000000000000000000007412703456111016135 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.411792805 sssd-1.13.4/src/util/strtonum.h0000644002412700241270000000204212703456111017602 0ustar00jhrozekjhrozek00000000000000/* SSSD SSSD Utility functions Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _STRTONUM_H_ #define _STRTONUM_H_ #include #include #include int32_t strtoint32(const char *nptr, char **endptr, int base); uint32_t strtouint32(const char *nptr, char **endptr, int base); uint16_t strtouint16(const char *nptr, char **endptr, int base); #endif /* _STRTONUM_H_ */ sssd-1.13.4/src/util/PaxHeaders.16287/check_and_open.c0000644000000000000000000000007412703456111017155 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.863794337 sssd-1.13.4/src/util/check_and_open.c0000644002412700241270000001017412703456111020627 0ustar00jhrozekjhrozek00000000000000/* SSSD Check file permissions and open file Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" static errno_t perform_checks(struct stat *stat_buf, uid_t uid, gid_t gid, mode_t mode, mode_t mask); errno_t check_file(const char *filename, uid_t uid, uid_t gid, mode_t mode, mode_t mask, struct stat *caller_stat_buf, bool follow_symlink) { int ret; struct stat local_stat_buf; struct stat *stat_buf; if (caller_stat_buf == NULL) { stat_buf = &local_stat_buf; } else { stat_buf = caller_stat_buf; } if (follow_symlink) { ret = stat(filename, stat_buf); } else { ret = lstat(filename, stat_buf); } if (ret == -1) { DEBUG(SSSDBG_TRACE_FUNC, "lstat for [%s] failed: [%d][%s].\n", filename, errno, strerror(errno)); return errno; } return perform_checks(stat_buf, uid, gid, mode, mask); } errno_t check_fd(int fd, uid_t uid, gid_t gid, mode_t mode, mode_t mask, struct stat *caller_stat_buf) { int ret; struct stat local_stat_buf; struct stat *stat_buf; if (caller_stat_buf == NULL) { stat_buf = &local_stat_buf; } else { stat_buf = caller_stat_buf; } ret = fstat(fd, stat_buf); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "fstat for [%d] failed: [%d][%s].\n", fd, errno, strerror(errno)); return errno; } return perform_checks(stat_buf, uid, gid, mode, mask); } static errno_t perform_checks(struct stat *stat_buf, uid_t uid, gid_t gid, mode_t mode, mode_t mask) { mode_t st_mode; if (mask) { st_mode = stat_buf->st_mode & mask; } else { st_mode = stat_buf->st_mode & (S_IFMT|ALLPERMS); } if ((mode & S_IFMT) != (st_mode & S_IFMT)) { DEBUG(SSSDBG_TRACE_LIBS, "File is not the right type.\n"); return EINVAL; } if ((st_mode & ALLPERMS) != (mode & ALLPERMS)) { DEBUG(SSSDBG_TRACE_LIBS, "File has the wrong (bit masked) mode [%.7o], " "expected [%.7o].\n", (st_mode & ALLPERMS), (mode & ALLPERMS)); return EINVAL; } if (uid != (uid_t)(-1) && stat_buf->st_uid != uid) { DEBUG(SSSDBG_TRACE_LIBS, "File must be owned by uid [%d].\n", uid); return EINVAL; } if (gid != (gid_t)(-1) && stat_buf->st_gid != gid) { DEBUG(SSSDBG_TRACE_LIBS, "File must be owned by gid [%d].\n", gid); return EINVAL; } return EOK; } errno_t check_and_open_readonly(const char *filename, int *fd, uid_t uid, gid_t gid, mode_t mode, mode_t mask) { int ret; struct stat stat_buf; *fd = open(filename, O_RDONLY); if (*fd == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "open [%s] failed: [%d][%s].\n", filename, errno, strerror(errno)); return errno; } ret = check_fd(*fd, uid, gid, mode, mask, &stat_buf); if (ret != EOK) { close(*fd); *fd = -1; DEBUG(SSSDBG_CRIT_FAILURE, "check_fd failed.\n"); return ret; } return EOK; } sssd-1.13.4/src/util/PaxHeaders.16287/util_errors.h0000644000000000000000000000007412703456111016613 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.410792801 sssd-1.13.4/src/util/util_errors.h0000644002412700241270000000750212703456111020266 0ustar00jhrozekjhrozek00000000000000/* Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Authors: Simo Sorce */ #ifndef __SSSD_UTIL_ERRORS_H__ #define __SSSD_UTIL_ERRORS_H__ #ifndef HAVE_ERRNO_T #define HAVE_ERRNO_T typedef int errno_t; #endif /* * We define a specific number space so that we do not overlap with other * generic errors returned by various libraries. This will make it easy * to have functions that double check that what was returned was a SSSD * specific error where it matters. For example we may want to ensure some * particularly sensitive paths only return SSSD sepcific errors as that * will insure all error conditions have been explicitly dealt with, * and are not the result of assigning the wrong return result. * * Basic system errno errors can still be used, but when an error condition * does not properly map to a system error we should use a SSSD specific one */ #define ERR_BASE 0x555D0000 #define ERR_MASK 0x0000FFFF /* never use ERR_INVALID, it is used for catching and returning * information on invalid error numbers */ /* never use ERR_LAST, this represent the maximum error value available * and is used to validate error codes */ enum sssd_errors { ERR_INVALID = ERR_BASE + 0, ERR_INTERNAL, ERR_ACCOUNT_UNKNOWN, ERR_INVALID_CRED_TYPE, ERR_NO_CREDS, ERR_CREDS_EXPIRED, ERR_CREDS_EXPIRED_CCACHE, ERR_CREDS_INVALID, ERR_NO_CACHED_CREDS, ERR_CACHED_CREDS_EXPIRED, ERR_AUTH_DENIED, ERR_AUTH_FAILED, ERR_CHPASS_DENIED, ERR_CHPASS_FAILED, ERR_NETWORK_IO, ERR_ACCOUNT_EXPIRED, ERR_PASSWORD_EXPIRED, ERR_PASSWORD_EXPIRED_REJECT, ERR_PASSWORD_EXPIRED_WARN, ERR_PASSWORD_EXPIRED_RENEW, ERR_ACCESS_DENIED, ERR_SRV_NOT_FOUND, ERR_SRV_LOOKUP_ERROR, ERR_SRV_DUPLICATES, ERR_DYNDNS_FAILED, ERR_DYNDNS_TIMEOUT, ERR_DYNDNS_OFFLINE, ERR_INPUT_PARSE, ERR_NOT_FOUND, ERR_DOMAIN_NOT_FOUND, ERR_MISSING_CONF, ERR_INVALID_FILTER, ERR_NO_POSIX, ERR_DUP_EXTRA_ATTR, ERR_INVALID_EXTRA_ATTR, ERR_SBUS_GET_SENDER_ERROR, ERR_SBUS_NO_SENDER, ERR_SBUS_INVALID_PATH, ERR_NO_SIDS, ERR_SBUS_NOSUP, ERR_NO_SYSBUS, ERR_REFERRAL, ERR_SELINUX_CONTEXT, ERR_REGEX_NOMATCH, ERR_TIMESPEC_NOT_SUPPORTED, ERR_INVALID_CONFIG, ERR_MALFORMED_ENTRY, ERR_UNEXPECTED_ENTRY_TYPE, ERR_SIMPLE_GROUPS_MISSING, ERR_HOMEDIR_IS_NULL, ERR_TRUST_NOT_SUPPORTED, ERR_IPA_GETKEYTAB_FAILED, ERR_TRUST_FOREST_UNKNOWN, ERR_P11_CHILD, ERR_ADDR_FAMILY_NOT_SUPPORTED, ERR_SBUS_SENDER_BUS, ERR_SUBDOM_INACTIVE, ERR_ACCOUNT_LOCKED, ERR_RENEWAL_CHILD, ERR_LAST /* ALWAYS LAST */ }; #define SSSD_ERR_BASE(err) ((err) & ~ERR_MASK) #define SSSD_ERR_IDX(err) ((err) & ERR_MASK) #define IS_SSSD_ERROR(err) \ ((SSSD_ERR_BASE(err) == ERR_BASE) && ((err) <= ERR_LAST)) #define ERR_OK 0 /* Backwards compat */ #ifndef EOK #define EOK ERR_OK #endif /** * @brief return a string descriing the error number like strerror() * * @param error An errno_t number, can be a SSSD error or a system error * * @return A statically allocated string. */ const char *sss_strerror(errno_t error); #endif /* __SSSD_UTIL_ERRORS_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/find_uid.h0000644000000000000000000000007412703456111016023 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.424792849 sssd-1.13.4/src/util/find_uid.h0000644002412700241270000000204412703456111017472 0ustar00jhrozekjhrozek00000000000000/* SSSD Create uid table Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __FIND_UID_H__ #define __FIND_UID_H__ #include #include #include #include "util/util.h" errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_t **table); errno_t check_if_uid_is_active(uid_t uid, bool *result); #endif /* __FIND_UID_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/util.h0000644000000000000000000000007412703456111015217 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.408792794 sssd-1.13.4/src/util/util.h0000644002412700241270000005002212703456111016665 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSSD_UTIL_H__ #define __SSSD_UTIL_H__ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "confdb/confdb.h" #include "util/atomic_io.h" #include "util/util_errors.h" #include "util/util_safealign.h" #include "util/sss_format.h" #include "util/debug.h" #define _(STRING) gettext (STRING) #define ENUM_INDICATOR "*" #define CLEAR_MC_FLAG "clear_mc_flag" /** Default secure umask */ #define SSS_DFL_UMASK 0177 /** Secure mask with executable bit */ #define SSS_DFL_X_UMASK 0077 #ifndef NULL #define NULL 0 #endif #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) #define SSSD_MAIN_OPTS SSSD_DEBUG_OPTS #define SSSD_SERVER_OPTS(uid, gid) \ {"uid", 0, POPT_ARG_INT, &uid, 0, \ _("The user ID to run the server as"), NULL}, \ {"gid", 0, POPT_ARG_INT, &gid, 0, \ _("The group ID to run the server as"), NULL}, #define FLAGS_NONE 0x0000 #define FLAGS_DAEMON 0x0001 #define FLAGS_INTERACTIVE 0x0002 #define FLAGS_PID_FILE 0x0004 #ifndef talloc_zfree #define talloc_zfree(ptr) do { talloc_free(discard_const(ptr)); ptr = NULL; } while(0) #endif #ifndef discard_const_p #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr))) #else # define discard_const_p(type, ptr) ((type *)(ptr)) #endif #endif #define TEVENT_REQ_RETURN_ON_ERROR(req) do { \ enum tevent_req_state TRROEstate; \ uint64_t TRROEerr; \ \ if (tevent_req_is_error(req, &TRROEstate, &TRROEerr)) { \ if (TRROEstate == TEVENT_REQ_USER_ERROR) { \ return TRROEerr; \ } \ return ERR_INTERNAL; \ } \ } while (0) #define OUT_OF_ID_RANGE(id, min, max) \ (id == 0 || (min && (id < min)) || (max && (id > max))) #include "util/dlinklist.h" /* From debug.c */ void ldb_debug_messages(void *context, enum ldb_debug_level level, const char *fmt, va_list ap); int chown_debug_file(const char *filename, uid_t uid, gid_t gid); int open_debug_file_ex(const char *filename, FILE **filep, bool want_cloexec); int open_debug_file(void); int rotate_debug_files(void); void talloc_log_fn(const char *msg); /* From sss_log.c */ #define SSS_LOG_EMERG 0 /* system is unusable */ #define SSS_LOG_ALERT 1 /* action must be taken immediately */ #define SSS_LOG_CRIT 2 /* critical conditions */ #define SSS_LOG_ERR 3 /* error conditions */ #define SSS_LOG_WARNING 4 /* warning conditions */ #define SSS_LOG_NOTICE 5 /* normal but significant condition */ #define SSS_LOG_INFO 6 /* informational */ #define SSS_LOG_DEBUG 7 /* debug-level messages */ void sss_log(int priority, const char *format, ...) SSS_ATTRIBUTE_PRINTF(2, 3); void sss_log_ext(int priority, int facility, const char *format, ...) SSS_ATTRIBUTE_PRINTF(3, 4); /* from server.c */ struct main_context { struct tevent_context *event_ctx; struct confdb_ctx *confdb_ctx; pid_t parent_pid; }; errno_t server_common_rotate_logs(struct confdb_ctx *confdb, const char *conf_entry); int die_if_parent_died(void); int pidfile(const char *path, const char *name); int server_setup(const char *name, int flags, uid_t uid, gid_t gid, const char *conf_entry, struct main_context **main_ctx); void server_loop(struct main_context *main_ctx); void orderly_shutdown(int status); /* from signal.c */ #include void BlockSignals(bool block, int signum); void (*CatchSignal(int signum,void (*handler)(int )))(int); /* from memory.c */ typedef int (void_destructor_fn_t)(void *); struct mem_holder { void *mem; void_destructor_fn_t *fn; }; void *sss_mem_attach(TALLOC_CTX *mem_ctx, void *ptr, void_destructor_fn_t *fn); int password_destructor(void *memctx); /* from usertools.c */ char *get_uppercase_realm(TALLOC_CTX *memctx, const char *name); struct sss_names_ctx { char *re_pattern; char *fq_fmt; pcre *re; }; /* initialize sss_names_ctx directly from arguments */ int sss_names_init_from_args(TALLOC_CTX *mem_ctx, const char *re_pattern, const char *fq_fmt, struct sss_names_ctx **out); /* initialize sss_names_ctx from domain configuration */ int sss_names_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, const char *domain, struct sss_names_ctx **out); int sss_ad_default_names_ctx(TALLOC_CTX *mem_ctx, struct sss_names_ctx **_out); int sss_parse_name(TALLOC_CTX *memctx, struct sss_names_ctx *snctx, const char *orig, char **_domain, char **_name); int sss_parse_name_const(TALLOC_CTX *memctx, struct sss_names_ctx *snctx, const char *orig, const char **_domain, const char **_name); int sss_parse_name_for_domains(TALLOC_CTX *memctx, struct sss_domain_info *domains, const char *default_domain, const char *orig, char **domain, char **name); char * sss_get_cased_name(TALLOC_CTX *mem_ctx, const char *orig_name, bool case_sensitive); errno_t sss_get_cased_name_list(TALLOC_CTX *mem_ctx, const char * const *orig, bool case_sensitive, const char ***_cased); /* Return fully-qualified name according to the fq_fmt. The name is allocated using * talloc on top of mem_ctx */ char * sss_tc_fqname(TALLOC_CTX *mem_ctx, struct sss_names_ctx *nctx, struct sss_domain_info *domain, const char *name); /* Return fully-qualified name according to the fq_fmt. The name is allocated using * talloc on top of mem_ctx. In contrast to sss_tc_fqname() sss_tc_fqname2() * expects the domain and flat domain name as separate arguments. */ char * sss_tc_fqname2(TALLOC_CTX *mem_ctx, struct sss_names_ctx *nctx, const char *dom_name, const char *flat_dom_name, const char *name); /* Return fully-qualified name formatted according to the fq_fmt. The buffer in "str" is * "size" bytes long. Returns the number of bytes written on success or a negative * value of failure. * * Pass a zero size to calculate the length that would be needed by the fully-qualified * name. */ int sss_fqname(char *str, size_t size, struct sss_names_ctx *nctx, struct sss_domain_info *domain, const char *name); /* Subdomains use fully qualified names in the cache while primary domains use * just the name. Return either of these for a specified domain or subdomain */ char * sss_get_domain_name(TALLOC_CTX *mem_ctx, const char *orig_name, struct sss_domain_info *dom); /* from backup-file.c */ int backup_file(const char *src, int dbglvl); /* check_file() * Verify that a file has certain permissions and/or is of a certain * file type. This function can be used to determine if a file is a * symlink. * Warning: use of this function implies a potential race condition * Opening a file before or after checking it does NOT guarantee that * it is still the same file. Additional checks should be performed * on the caller_stat_buf to ensure that it has the same device and * inode to minimize impact. Permission changes may have occurred, * however. */ errno_t check_file(const char *filename, uid_t uid, gid_t gid, mode_t mode, mode_t mask, struct stat *caller_stat_buf, bool follow_symlink); /* check_fd() * Verify that an open file descriptor has certain permissions and/or * is of a certain file type. This function CANNOT detect symlinks, * as the file is already open and symlinks have been traversed. This * is the safer way to perform file checks and should be preferred * over check_file for nearly all situations. */ errno_t check_fd(int fd, uid_t uid, gid_t gid, mode_t mode, mode_t mask, struct stat *caller_stat_buf); /* check_and_open_readonly() * Utility function to open a file and verify that it has certain * permissions and is of a certain file type. This function wraps * check_fd(), and is considered race-condition safe. */ errno_t check_and_open_readonly(const char *filename, int *fd, uid_t uid, gid_t gid, mode_t mode, mode_t mask); /* from util.c */ #define SSS_NO_LINKLOCAL 0x01 #define SSS_NO_LOOPBACK 0x02 #define SSS_NO_MULTICAST 0x04 #define SSS_NO_BROADCAST 0x08 #define SSS_NO_SPECIAL \ (SSS_NO_LINKLOCAL|SSS_NO_LOOPBACK|SSS_NO_MULTICAST|SSS_NO_BROADCAST) /* These two functions accept addr in network order */ bool check_ipv4_addr(struct in_addr *addr, uint8_t check); bool check_ipv6_addr(struct in6_addr *addr, uint8_t check); const char * const * get_known_services(void); errno_t sss_user_by_name_or_uid(const char *input, uid_t *_uid, gid_t *_gid); int split_on_separator(TALLOC_CTX *mem_ctx, const char *str, const char sep, bool trim, bool skip_empty, char ***_list, int *size); char **parse_args(const char *str); errno_t parse_cert_verify_opts(const char *verify_opts, bool *do_ocsp); errno_t sss_hash_create(TALLOC_CTX *mem_ctx, unsigned long count, hash_table_t **tbl); errno_t sss_hash_create_ex(TALLOC_CTX *mem_ctx, unsigned long count, hash_table_t **tbl, unsigned int directory_bits, unsigned int segment_bits, unsigned long min_load_factor, unsigned long max_load_factor, hash_delete_callback *delete_callback, void *delete_private_data); /** * @brief Add two list of strings * * Create a new NULL-termintated list of strings by adding two lists together. * * @param[in] mem_ctx Talloc memory context for the new list. * @param[in] l1 First NULL-termintated list of strings. * @param[in] l2 Second NULL-termintated list of strings. * @param[in] copy_strings If set to 'true' the list items will be copied * otherwise only the pointers to the items are * copied. * @param[out] new_list New NULL-terminated list of strings. Must be freed * with talloc_free() by the caller. If copy_strings * is 'true' the new elements will be freed as well. */ errno_t add_strings_lists(TALLOC_CTX *mem_ctx, const char **l1, const char **l2, bool copy_strings, char ***_new_list); /** * @brief set file descriptor as nonblocking * * Set the O_NONBLOCK flag for the input fd * * @param[in] fd The file descriptor to set as nonblocking * * @return EOK on success, errno code otherwise */ errno_t sss_fd_nonblocking(int fd); /* Copy a NULL-terminated string list * Returns NULL on out of memory error or invalid input */ char **dup_string_list(TALLOC_CTX *memctx, const char **str_list); /* Take two string lists (terminated on a NULL char*) * and return up to three arrays of strings based on * shared ownership. * * Pass NULL to any return type you don't care about */ errno_t diff_string_lists(TALLOC_CTX *memctx, char **string1, char **string2, char ***string1_only, char ***string2_only, char ***both_strings); /* Sanitize an input string (e.g. a username) for use in * an LDAP/LDB filter * Returns a newly-constructed string attached to mem_ctx * It will fail only on an out of memory condition, where it * will return ENOMEM. */ errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx, const char *input, char **sanitized); errno_t sss_filter_sanitize_ex(TALLOC_CTX *mem_ctx, const char *input, char **sanitized, const char *ignore); errno_t sss_filter_sanitize_for_dom(TALLOC_CTX *mem_ctx, const char *input, struct sss_domain_info *dom, char **sanitized, char **lc_sanitized); char * sss_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr); /* This function only removes first and last * character if the first character was '['. * * NOTE: This means, that ipv6addr must NOT be followed * by port number. */ errno_t remove_ipv6_brackets(char *ipv6addr); errno_t add_string_to_list(TALLOC_CTX *mem_ctx, const char *string, char ***list_p); bool string_in_list(const char *string, char **list, bool case_sensitive); /** * @brief Safely zero a segment of memory, * prevents the compiler from optimizing out * * @param data The address of buffer to wipe * @param size Size of the buffer */ void safezero(void *data, size_t size); int domain_to_basedn(TALLOC_CTX *memctx, const char *domain, char **basedn); bool is_host_in_domain(const char *host, const char *domain); /* from nscd.c */ enum nscd_db { NSCD_DB_PASSWD, NSCD_DB_GROUP }; int flush_nscd_cache(enum nscd_db flush_db); errno_t sss_nscd_parse_conf(const char *conf_path); /* from sss_tc_utf8.c */ char * sss_tc_utf8_str_tolower(TALLOC_CTX *mem_ctx, const char *s); uint8_t * sss_tc_utf8_tolower(TALLOC_CTX *mem_ctx, const uint8_t *s, size_t len, size_t *_nlen); bool sss_string_equal(bool cs, const char *s1, const char *s2); /* len includes terminating '\0' */ struct sized_string { const char *str; size_t len; }; void to_sized_string(struct sized_string *out, const char *in); /* from domain_info.c */ struct sss_domain_info *get_domains_head(struct sss_domain_info *domain); #define SSS_GND_DESCEND 0x01 #define SSS_GND_INCLUDE_DISABLED 0x02 #define SSS_GND_ALL_DOMAINS (SSS_GND_DESCEND | SSS_GND_INCLUDE_DISABLED) struct sss_domain_info *get_next_domain(struct sss_domain_info *domain, uint32_t gnd_flags); struct sss_domain_info *find_domain_by_name(struct sss_domain_info *domain, const char *name, bool match_any); struct sss_domain_info *find_domain_by_sid(struct sss_domain_info *domain, const char *sid); enum sss_domain_state sss_domain_get_state(struct sss_domain_info *dom); void sss_domain_set_state(struct sss_domain_info *dom, enum sss_domain_state state); struct sss_domain_info* sss_get_domain_by_sid_ldap_fallback(struct sss_domain_info *domain, const char* sid); struct sss_domain_info * find_domain_by_object_name(struct sss_domain_info *domain, const char *object_name); bool subdomain_enumerates(struct sss_domain_info *parent, const char *sd_name); errno_t sssd_domain_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, const char *domain_name, const char *db_path, struct sss_domain_info **_domain); #define IS_SUBDOMAIN(dom) ((dom)->parent != NULL) #define DOM_HAS_VIEWS(dom) ((dom)->has_views) /* the directory domain - realm mappings and other krb5 config snippers are * written to */ #define KRB5_MAPPING_DIR PUBCONF_PATH"/krb5.include.d" errno_t sss_write_domain_mappings(struct sss_domain_info *domain); errno_t sss_write_krb5_conf_snippet(const char *path); errno_t get_dom_names(TALLOC_CTX *mem_ctx, struct sss_domain_info *start_dom, char ***_dom_names, int *_dom_names_count); errno_t fix_domain_in_name_list(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, char **in, char ***_out); /* from util_lock.c */ errno_t sss_br_lock_file(int fd, size_t start, size_t len, int num_tries, useconds_t wait); #include "io.h" #ifdef HAVE_PAC_RESPONDER #define BUILD_WITH_PAC_RESPONDER true #else #define BUILD_WITH_PAC_RESPONDER false #endif /* from well_known_sids.c */ errno_t well_known_sid_to_name(const char *sid, const char **dom, const char **name); errno_t name_to_well_known_sid(const char *dom, const char *name, const char **sid); /* from string_utils.c */ char * sss_replace_space(TALLOC_CTX *mem_ctx, const char *orig_name, const char replace_char); char * sss_reverse_replace_space(TALLOC_CTX *mem_ctx, const char *orig_name, const char replace_char); #define GUID_BIN_LENGTH 16 /* 16 2-digit hex values + 4 dashes + terminating 0 */ #define GUID_STR_BUF_SIZE (2 * GUID_BIN_LENGTH + 4 + 1) errno_t guid_blob_to_string_buf(const uint8_t *blob, char *str_buf, size_t buf_size); const char *get_last_x_chars(const char *str, size_t x); /* from become_user.c */ errno_t become_user(uid_t uid, gid_t gid); struct sss_creds; errno_t switch_creds(TALLOC_CTX *mem_ctx, uid_t uid, gid_t gid, int num_gids, gid_t *gids, struct sss_creds **saved_creds); errno_t restore_creds(struct sss_creds *saved_creds); /* from sss_semanage.c */ /* Please note that libsemange relies on files and directories created with * certain permissions. Therefore the caller should make sure the umask is * not too restricted (especially when called from the daemon code). */ int set_seuser(const char *login_name, const char *seuser_name, const char *mlsrange); int del_seuser(const char *login_name); int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name, char **_seuser, char **_mls_range); /* convert time from generalized form to unix time */ errno_t sss_utc_to_time_t(const char *str, const char *format, time_t *unix_time); /* Creates a unique file using mkstemp with provided umask. The template * must end with XXXXXX. Returns the fd, sets _err to an errno value on error. * * Prefer using sss_unique_file() as it uses a secure umask internally. */ int sss_unique_file_ex(TALLOC_CTX *mem_ctx, char *path_tmpl, mode_t file_umask, errno_t *_err); int sss_unique_file(TALLOC_CTX *owner, char *path_tmpl, errno_t *_err); /* Creates a unique filename using mkstemp with secure umask. The template * must end with XXXXXX * * path_tmpl must be a talloc context. Destructor would be set on the filename * so that it's guaranteed the file is removed. */ int sss_unique_filename(TALLOC_CTX *owner, char *path_tmpl); #endif /* __SSSD_UTIL_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/murmurhash3.c0000644000000000000000000000007412703456111016513 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.650793615 sssd-1.13.4/src/util/murmurhash3.c0000644002412700241270000000413012703456111020160 0ustar00jhrozekjhrozek00000000000000/* This file is based on the public domain MurmurHash3 from Austin Appleby: * http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp * * We use only the 32 bit variant because the 2 produce different result while * we need to produce the same result regardless of the architecture as * clients can be both 64 or 32 bit at the same time. */ #include #include #include #include "config.h" #include "util/murmurhash3.h" #include "util/sss_endian.h" static uint32_t rotl(uint32_t x, int8_t r) { return (x << r) | (x >> (32 - r)); } /* slower than original but is endian neutral and handles platforms that * do only aligned reads */ __attribute__((always_inline)) static inline uint32_t getblock(const uint8_t *p, int i) { uint32_t r; size_t size = sizeof(uint32_t); memcpy(&r, &p[i * size], size); return le32toh(r); } /* * Finalization mix - force all bits of a hash block to avalanche */ __attribute__((always_inline)) static inline uint32_t fmix(uint32_t h) { h ^= h >> 16; h *= 0x85ebca6b; h ^= h >> 13; h *= 0xc2b2ae35; h ^= h >> 16; return h; } uint32_t murmurhash3(const char *key, int len, uint32_t seed) { const uint8_t *blocks; const uint8_t *tail; int nblocks; uint32_t h1; uint32_t k1; uint32_t c1; uint32_t c2; int i; blocks = (const uint8_t *)key; nblocks = len / 4; h1 = seed; c1 = 0xcc9e2d51; c2 = 0x1b873593; /* body */ for (i = 0; i < nblocks; i++) { k1 = getblock(blocks, i); k1 *= c1; k1 = rotl(k1, 15); k1 *= c2; h1 ^= k1; h1 = rotl(h1, 13); h1 = h1 * 5 + 0xe6546b64; } /* tail */ tail = (const uint8_t *)key + nblocks * 4; k1 = 0; switch (len & 3) { case 3: k1 ^= tail[2] << 16; case 2: k1 ^= tail[1] << 8; case 1: k1 ^= tail[0]; k1 *= c1; k1 = rotl(k1, 15); k1 *= c2; h1 ^= k1; default: break; } /* finalization */ h1 ^= len; h1 = fmix(h1); return h1; } sssd-1.13.4/src/util/PaxHeaders.16287/sss_ini.c0000644000000000000000000000007412703456111015704 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.879794392 sssd-1.13.4/src/util/sss_ini.c0000644002412700241270000003072512703456111017362 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_ini.c Authors: Ondrej Kos Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "config.h" #include "util/util.h" #include "util/sss_ini.h" #include "confdb/confdb_setup.h" #include "confdb/confdb_private.h" #ifdef HAVE_LIBINI_CONFIG_V1 #include "ini_configobj.h" #else #include "collection.h" #include "collection_tools.h" #endif #include "ini_config.h" #ifdef HAVE_LIBINI_CONFIG_V1 struct sss_ini_initdata { char **error_list; struct ini_cfgobj *sssd_config; struct value_obj *obj; const struct stat *cstat; struct ini_cfgfile *file; }; #define sss_ini_get_sec_list ini_get_section_list #define sss_ini_get_attr_list ini_get_attribute_list #define sss_ini_get_const_string_config_value ini_get_const_string_config_value #define sss_ini_get_config_obj ini_get_config_valueobj #else struct sss_ini_initdata { struct collection_item *error_list; struct collection_item *sssd_config; struct collection_item *obj; struct stat cstat; int file; }; #define sss_ini_get_sec_list get_section_list #define sss_ini_get_attr_list get_attribute_list #define sss_ini_get_const_string_config_value get_const_string_config_value #define sss_ini_get_config_obj(secs,attrs,cfg,flag,attr) \ get_config_item(secs,attrs,cfg,attr) #endif /* Initialize data structure */ struct sss_ini_initdata* sss_ini_initdata_init(TALLOC_CTX *mem_ctx) { return talloc_zero(mem_ctx, struct sss_ini_initdata); } /* Close file descriptor */ void sss_ini_close_file(struct sss_ini_initdata *init_data) { if (init_data == NULL) return; #ifdef HAVE_LIBINI_CONFIG_V1 if (init_data->file != NULL) { ini_config_file_destroy(init_data->file); init_data->file = NULL; } #else if (init_data->file != -1) { close(init_data->file); init_data->file = -1; } #endif } /* Open configuration file */ int sss_ini_config_file_open(struct sss_ini_initdata *init_data, const char *config_file) { #ifdef HAVE_LIBINI_CONFIG_V1 return ini_config_file_open(config_file, INI_META_STATS, &init_data->file); #else return check_and_open_readonly(config_file, &init_data->file, 0, 0, S_IFREG|S_IRUSR, /* f r**------ */ S_IFMT|(ALLPERMS & ~(S_IWUSR|S_IXUSR))); #endif } /* Check configuration file permissions */ int sss_ini_config_access_check(struct sss_ini_initdata *init_data) { #ifdef HAVE_LIBINI_CONFIG_V1 return ini_config_access_check(init_data->file, INI_ACCESS_CHECK_MODE | INI_ACCESS_CHECK_UID | INI_ACCESS_CHECK_GID, 0, /* owned by root */ 0, /* owned by root */ S_IRUSR, /* r**------ */ ALLPERMS & ~(S_IWUSR|S_IXUSR)); #else return EOK; #endif } /* Get cstat */ int sss_ini_get_stat(struct sss_ini_initdata *init_data) { #ifdef HAVE_LIBINI_CONFIG_V1 init_data->cstat = ini_config_get_stat(init_data->file); if (!init_data->cstat) return EIO; return EOK; #else return fstat(init_data->file, &init_data->cstat); #endif } /* Get mtime */ int sss_ini_get_mtime(struct sss_ini_initdata *init_data, size_t timestr_len, char *timestr) { #ifdef HAVE_LIBINI_CONFIG_V1 return snprintf(timestr, timestr_len, "%llu", (long long unsigned)init_data->cstat->st_mtime); #else return snprintf(timestr, timestr_len, "%llu", (long long unsigned)init_data->cstat.st_mtime); #endif } /* Print ini_config errors */ void sss_ini_config_print_errors(char **error_list) { #ifdef HAVE_LIBINI_CONFIG_V1 unsigned count = 0; if (!error_list) { return; } while (error_list[count]) { DEBUG(SSSDBG_CRIT_FAILURE, "%s\n", error_list[count]); count++; } #endif return; } /* Load configuration */ int sss_ini_get_config(struct sss_ini_initdata *init_data, const char *config_file) { int ret; #ifdef HAVE_LIBINI_CONFIG_V1 /* Create config object */ ret = ini_config_create(&(init_data->sssd_config)); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to create config object. Error %d.\n", ret); return ret; } /* Parse file */ ret = ini_config_parse(init_data->file, INI_STOP_ON_ANY, INI_MV1S_OVERWRITE, INI_PARSE_NOWRAP, init_data->sssd_config); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse configuration. Error %d.\n", ret); if (ini_config_error_count(init_data->sssd_config)) { DEBUG(SSSDBG_FATAL_FAILURE, "Errors detected while parsing: %s\n", ini_config_get_filename(init_data->file)); ini_config_get_errors(init_data->sssd_config, &init_data->error_list); sss_ini_config_print_errors(init_data->error_list); ini_config_free_errors(init_data->error_list); } ini_config_destroy(init_data->sssd_config); init_data->sssd_config = NULL; return ret; } return ret; #else /* Read the configuration into a collection */ ret = config_from_fd("sssd", init_data->file, config_file, &init_data->sssd_config, INI_STOP_ON_ANY, &init_data->error_list); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Parse error reading configuration file [%s]\n", config_file); print_file_parsing_errors(stderr, init_data->error_list); free_ini_config_errors(init_data->error_list); free_ini_config(init_data->sssd_config); return ret; } return EOK; #endif } /* Get configuration object */ int sss_ini_get_cfgobj(struct sss_ini_initdata *init_data, const char *section, const char *name) { return sss_ini_get_config_obj(section,name, init_data->sssd_config, INI_GET_FIRST_VALUE, &init_data->obj); } /* Check configuration object */ int sss_ini_check_config_obj(struct sss_ini_initdata *init_data) { if (init_data->obj == NULL) { return ENOENT; } return EOK; } /* Get integer value */ int sss_ini_get_int_config_value(struct sss_ini_initdata *init_data, int strict, int def, int *error) { #ifdef HAVE_LIBINI_CONFIG_V1 return ini_get_int_config_value(init_data->obj, strict, def, error); #else return get_int_config_value(init_data->obj, strict, def, error); #endif } /* Destroy ini config (v1) */ void sss_ini_config_destroy(struct sss_ini_initdata *init_data) { if (init_data == NULL) return; #ifdef HAVE_LIBINI_CONFIG_V1 if (init_data->sssd_config != NULL) { ini_config_destroy(init_data->sssd_config); init_data->sssd_config = NULL; } #else free_ini_config(init_data->sssd_config); #endif } /* Create LDIF */ int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx, struct sss_ini_initdata *init_data, const char **config_ldif) { int ret, i, j; char *ldif; char *tmp_ldif; char **sections; int section_count; char *dn; char *tmp_dn; char *sec_dn; char **attrs; int attr_count; char *ldif_attr; TALLOC_CTX *tmp_ctx; size_t dn_size; size_t ldif_len; size_t attr_len; #ifdef HAVE_LIBINI_CONFIG_V1 struct value_obj *obj = NULL; #else struct collection_item *obj = NULL; #endif ldif_len = strlen(CONFDB_INTERNAL_LDIF); ldif = talloc_array(mem_ctx, char, ldif_len+1); if (!ldif) return ENOMEM; tmp_ctx = talloc_new(ldif); if (!tmp_ctx) { ret = ENOMEM; goto error; } memcpy(ldif, CONFDB_INTERNAL_LDIF, ldif_len); /* Read in the collection and convert it to an LDIF */ /* Get the list of sections */ sections = sss_ini_get_sec_list(init_data->sssd_config, §ion_count, &ret); if (ret != EOK) { goto error; } for (i = 0; i < section_count; i++) { const char *rdn = NULL; DEBUG(SSSDBG_TRACE_FUNC, "Processing config section [%s]\n", sections[i]); ret = parse_section(tmp_ctx, sections[i], &sec_dn, &rdn); if (ret != EOK) { goto error; } dn = talloc_asprintf(tmp_ctx, "dn: %s,cn=config\n" "cn: %s\n", sec_dn, rdn); if (!dn) { ret = ENOMEM; free_section_list(sections); goto error; } dn_size = strlen(dn); /* Get all of the attributes and their values as LDIF */ attrs = sss_ini_get_attr_list(init_data->sssd_config, sections[i], &attr_count, &ret); if (ret != EOK) { free_section_list(sections); goto error; } for (j = 0; j < attr_count; j++) { DEBUG(SSSDBG_TRACE_FUNC, "Processing attribute [%s]\n", attrs[j]); ret = sss_ini_get_config_obj(sections[i], attrs[j], init_data->sssd_config, INI_GET_FIRST_VALUE, &obj); if (ret != EOK) goto error; const char *value = sss_ini_get_const_string_config_value(obj, &ret); if (ret != EOK) goto error; if (value && value[0] == '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Attribute '%s' has empty value, ignoring\n", attrs[j]); continue; } ldif_attr = talloc_asprintf(tmp_ctx, "%s: %s\n", attrs[j], value); DEBUG(SSSDBG_TRACE_ALL, "%s\n", ldif_attr); attr_len = strlen(ldif_attr); tmp_dn = talloc_realloc(tmp_ctx, dn, char, dn_size+attr_len+1); if (!tmp_dn) { ret = ENOMEM; free_attribute_list(attrs); free_section_list(sections); goto error; } dn = tmp_dn; memcpy(dn+dn_size, ldif_attr, attr_len+1); dn_size += attr_len; } dn_size ++; tmp_dn = talloc_realloc(tmp_ctx, dn, char, dn_size+1); if (!tmp_dn) { ret = ENOMEM; free_attribute_list(attrs); free_section_list(sections); goto error; } dn = tmp_dn; dn[dn_size-1] = '\n'; dn[dn_size] = '\0'; DEBUG(SSSDBG_TRACE_ALL, "Section dn\n%s\n", dn); tmp_ldif = talloc_realloc(mem_ctx, ldif, char, ldif_len+dn_size+1); if (!tmp_ldif) { ret = ENOMEM; free_attribute_list(attrs); free_section_list(sections); goto error; } ldif = tmp_ldif; memcpy(ldif+ldif_len, dn, dn_size); ldif_len += dn_size; free_attribute_list(attrs); talloc_free(dn); } ldif[ldif_len] = '\0'; free_section_list(sections); *config_ldif = (const char *)ldif; talloc_free(tmp_ctx); return EOK; error: talloc_free(ldif); return ret; } sssd-1.13.4/src/util/PaxHeaders.16287/sss_nss.h0000644000000000000000000000007412703456111015735 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.414792815 sssd-1.13.4/src/util/sss_nss.h0000644002412700241270000000227712703456111017414 0ustar00jhrozekjhrozek00000000000000/* SSSD Utility functions related to ID information Copyright (C) Jan Zeleny 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSS_NSS_H__ #define __SSS_NSS_H__ #include #include struct sss_nss_homedir_ctx { const char *username; uint32_t uid; const char *original; const char *domain; const char *flatname; const char *config_homedir_substr; const char *upn; }; char *expand_homedir_template(TALLOC_CTX *mem_ctx, const char *template, struct sss_nss_homedir_ctx *homedir_ctx); #endif sssd-1.13.4/src/util/PaxHeaders.16287/strtonum.c0000644000000000000000000000007412703456111016130 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.808794151 sssd-1.13.4/src/util/strtonum.c0000644002412700241270000000372512703456111017606 0ustar00jhrozekjhrozek00000000000000/* SSSD SSSD Utility functions Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "config.h" #include "util/util.h" #include "util/strtonum.h" /* strtoint32 */ int32_t strtoint32(const char *nptr, char **endptr, int base) { long long ret = 0; errno = 0; ret = strtoll(nptr, endptr, base); if (ret > INT32_MAX) { errno = ERANGE; return INT32_MAX; } else if (ret < INT32_MIN) { errno = ERANGE; return INT32_MIN; } /* If errno was set by strtoll, we'll pass it back as-is */ return (int32_t)ret; } /* strtouint32 */ uint32_t strtouint32(const char *nptr, char **endptr, int base) { unsigned long long ret = 0; errno = 0; ret = strtoull(nptr, endptr, base); if (ret > UINT32_MAX) { errno = ERANGE; return UINT32_MAX; } /* If errno was set by strtoll, we'll pass it back as-is */ return (uint32_t)ret; } /* strtouint16 */ uint16_t strtouint16(const char *nptr, char **endptr, int base) { unsigned long long ret = 0; errno = 0; ret = strtoull(nptr, endptr, base); if (ret > UINT16_MAX) { errno = ERANGE; return UINT16_MAX; } /* If errno was set by strtoll, we'll pass it back as-is */ return (uint16_t)ret; } sssd-1.13.4/src/util/PaxHeaders.16287/debug.h0000644000000000000000000000007412703456111015330 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.407792791 sssd-1.13.4/src/util/debug.h0000644002412700241270000001211412703456111016776 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSSD_DEBUG_H__ #define __SSSD_DEBUG_H__ #include "config.h" #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT #define SSS_ATTRIBUTE_PRINTF(a1, a2) __attribute__((format (printf, a1, a2))) #else #define SSS_ATTRIBUTE_PRINTF(a1, a2) #endif #define APPEND_LINE_FEED 0x1 extern const char *debug_prg_name; extern int debug_level; extern int debug_timestamps; extern int debug_microseconds; extern int debug_to_file; extern int debug_to_stderr; extern const char *debug_log_file; void sss_vdebug_fn(const char *file, long line, const char *function, int level, int flags, const char *format, va_list ap); void sss_debug_fn(const char *file, long line, const char *function, int level, const char *format, ...) SSS_ATTRIBUTE_PRINTF(5, 6); int debug_convert_old_level(int old_level); errno_t set_debug_file_from_fd(const int fd); int get_fd_from_debug_file(void); #define SSS_DOM_ENV "_SSS_DOM" #define SSSDBG_FATAL_FAILURE 0x0010 /* level 0 */ #define SSSDBG_CRIT_FAILURE 0x0020 /* level 1 */ #define SSSDBG_OP_FAILURE 0x0040 /* level 2 */ #define SSSDBG_MINOR_FAILURE 0x0080 /* level 3 */ #define SSSDBG_CONF_SETTINGS 0x0100 /* level 4 */ #define SSSDBG_FUNC_DATA 0x0200 /* level 5 */ #define SSSDBG_TRACE_FUNC 0x0400 /* level 6 */ #define SSSDBG_TRACE_LIBS 0x1000 /* level 7 */ #define SSSDBG_TRACE_INTERNAL 0x2000 /* level 8 */ #define SSSDBG_TRACE_ALL 0x4000 /* level 9 */ #define SSSDBG_BE_FO 0x8000 /* level 9 */ #define SSSDBG_IMPORTANT_INFO SSSDBG_OP_FAILURE #define SSSDBG_INVALID -1 #define SSSDBG_UNRESOLVED 0 #define SSSDBG_MASK_ALL 0xFFF0 /* enable all debug levels */ #define SSSDBG_DEFAULT SSSDBG_FATAL_FAILURE #define SSSDBG_TIMESTAMP_UNRESOLVED -1 #define SSSDBG_TIMESTAMP_DEFAULT 1 #define SSSDBG_MICROSECONDS_UNRESOLVED -1 #define SSSDBG_MICROSECONDS_DEFAULT 0 #define SSSD_DEBUG_OPTS \ {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, \ _("Debug level"), NULL}, \ {"debug-to-files", 'f', POPT_ARG_NONE, &debug_to_file, 0, \ _("Send the debug output to files instead of stderr"), NULL }, \ {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, \ _("Send the debug output to stderr directly."), NULL }, \ {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0, \ _("Add debug timestamps"), NULL}, \ {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0, \ _("Show timestamps with microseconds"), NULL}, /** \def DEBUG(level, format, ...) \brief macro to generate debug messages \param level the debug level, please use one of the SSSDBG_* macros \param format the debug message format string, should result in a newline-terminated message \param ... the debug message format arguments */ #define DEBUG(level, format, ...) do { \ int __debug_macro_level = level; \ if (DEBUG_IS_SET(__debug_macro_level)) { \ sss_debug_fn(__FILE__, __LINE__, __FUNCTION__, \ __debug_macro_level, \ format, ##__VA_ARGS__); \ } \ } while (0) /** \def DEBUG_IS_SET(level) \brief checks whether level is set in debug_level \param level the debug level, please use one of the SSSDBG*_ macros */ #define DEBUG_IS_SET(level) (debug_level & (level) || \ (debug_level == SSSDBG_UNRESOLVED && \ (level & (SSSDBG_FATAL_FAILURE | \ SSSDBG_CRIT_FAILURE)))) #define DEBUG_INIT(dbg_lvl) do { \ if (dbg_lvl != SSSDBG_INVALID) { \ debug_level = debug_convert_old_level(dbg_lvl); \ } else { \ debug_level = SSSDBG_UNRESOLVED; \ } \ \ talloc_set_log_fn(talloc_log_fn); \ } while (0) /* CLI tools shall debug to stderr even when SSSD was compiled with journald * support */ #define DEBUG_CLI_INIT(dbg_lvl) do { \ DEBUG_INIT(dbg_lvl); \ debug_to_stderr = 1; \ } while (0) #define PRINT(fmt, ...) fprintf(stdout, gettext(fmt), ##__VA_ARGS__) #define ERROR(fmt, ...) fprintf(stderr, gettext(fmt), ##__VA_ARGS__) #endif /* __SSSD_DEBUG_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/murmurhash3.h0000644000000000000000000000007412703456111016520 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.428792862 sssd-1.13.4/src/util/murmurhash3.h0000644002412700241270000000127512703456111020174 0ustar00jhrozekjhrozek00000000000000/* This file is based on the public domain MurmurHash3 from Austin Appleby: * http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp * * We use only the 32 bit variant because the 2 produce different result while * we need to produce the same result regardless of the architecture as * clients can be both 64 or 32 bit at the same time. */ #ifndef _UTIL_MURMURHASH3_H_ #define _UTIL_MURMURHASH3_H_ #include /* CAUTION: * This file is also used in sss_client (pam, nss). Therefore it have to be * minimalist and cannot include DEBUG macros or header file util.h. */ uint32_t murmurhash3(const char *key, int len, uint32_t seed); #endif /* _UTIL_MURMURHASH3_H_ */ sssd-1.13.4/src/util/PaxHeaders.16287/authtok.c0000644000000000000000000000007412703456111015714 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.868794354 sssd-1.13.4/src/util/authtok.c0000644002412700241270000003015712703456111017371 0ustar00jhrozekjhrozek00000000000000/* SSSD - auth utils Copyright (C) Simo Sorce 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "authtok.h" struct sss_auth_token { enum sss_authtok_type type; uint8_t *data; size_t length; }; enum sss_authtok_type sss_authtok_get_type(struct sss_auth_token *tok) { return tok->type; } size_t sss_authtok_get_size(struct sss_auth_token *tok) { if (!tok) { return 0; } switch (tok->type) { case SSS_AUTHTOK_TYPE_PASSWORD: case SSS_AUTHTOK_TYPE_CCFILE: case SSS_AUTHTOK_TYPE_2FA: case SSS_AUTHTOK_TYPE_SC_PIN: case SSS_AUTHTOK_TYPE_SC_KEYPAD: return tok->length; case SSS_AUTHTOK_TYPE_EMPTY: return 0; } return EINVAL; } uint8_t *sss_authtok_get_data(struct sss_auth_token *tok) { if (!tok) { return NULL; } return tok->data; } errno_t sss_authtok_get_password(struct sss_auth_token *tok, const char **pwd, size_t *len) { if (!tok) { return EFAULT; } switch (tok->type) { case SSS_AUTHTOK_TYPE_EMPTY: return ENOENT; case SSS_AUTHTOK_TYPE_PASSWORD: *pwd = (const char *)tok->data; if (len) { *len = tok->length - 1; } return EOK; case SSS_AUTHTOK_TYPE_CCFILE: case SSS_AUTHTOK_TYPE_2FA: case SSS_AUTHTOK_TYPE_SC_PIN: case SSS_AUTHTOK_TYPE_SC_KEYPAD: return EACCES; } return EINVAL; } errno_t sss_authtok_get_ccfile(struct sss_auth_token *tok, const char **ccfile, size_t *len) { if (!tok) { return EINVAL; } switch (tok->type) { case SSS_AUTHTOK_TYPE_EMPTY: return ENOENT; case SSS_AUTHTOK_TYPE_CCFILE: *ccfile = (const char *)tok->data; if (len) { *len = tok->length - 1; } return EOK; case SSS_AUTHTOK_TYPE_PASSWORD: case SSS_AUTHTOK_TYPE_2FA: case SSS_AUTHTOK_TYPE_SC_PIN: case SSS_AUTHTOK_TYPE_SC_KEYPAD: return EACCES; } return EINVAL; } static errno_t sss_authtok_set_string(struct sss_auth_token *tok, enum sss_authtok_type type, const char *context_name, const char *str, size_t len) { size_t size; if (len == 0) { len = strlen(str); } else { while (len > 0 && str[len - 1] == '\0') len--; } if (len == 0) { /* we do not allow zero length typed tokens */ return EINVAL; } size = len + 1; tok->data = talloc_named(tok, size, "%s", context_name); if (!tok->data) { return ENOMEM; } memcpy(tok->data, str, len); tok->data[len] = '\0'; tok->type = type; tok->length = size; return EOK; } void sss_authtok_set_empty(struct sss_auth_token *tok) { if (!tok) { return; } switch (tok->type) { case SSS_AUTHTOK_TYPE_EMPTY: return; case SSS_AUTHTOK_TYPE_PASSWORD: case SSS_AUTHTOK_TYPE_2FA: case SSS_AUTHTOK_TYPE_SC_PIN: safezero(tok->data, tok->length); break; case SSS_AUTHTOK_TYPE_CCFILE: case SSS_AUTHTOK_TYPE_SC_KEYPAD: break; } tok->type = SSS_AUTHTOK_TYPE_EMPTY; talloc_zfree(tok->data); tok->length = 0; } errno_t sss_authtok_set_password(struct sss_auth_token *tok, const char *password, size_t len) { sss_authtok_set_empty(tok); return sss_authtok_set_string(tok, SSS_AUTHTOK_TYPE_PASSWORD, "password", password, len); } errno_t sss_authtok_set_ccfile(struct sss_auth_token *tok, const char *ccfile, size_t len) { sss_authtok_set_empty(tok); return sss_authtok_set_string(tok, SSS_AUTHTOK_TYPE_CCFILE, "ccfile", ccfile, len); } static errno_t sss_authtok_set_2fa_from_blob(struct sss_auth_token *tok, const uint8_t *data, size_t len); errno_t sss_authtok_set(struct sss_auth_token *tok, enum sss_authtok_type type, const uint8_t *data, size_t len) { switch (type) { case SSS_AUTHTOK_TYPE_PASSWORD: return sss_authtok_set_password(tok, (const char *)data, len); case SSS_AUTHTOK_TYPE_CCFILE: return sss_authtok_set_ccfile(tok, (const char *)data, len); case SSS_AUTHTOK_TYPE_2FA: return sss_authtok_set_2fa_from_blob(tok, data, len); case SSS_AUTHTOK_TYPE_SC_PIN: return sss_authtok_set_sc_pin(tok, (const char*)data, len); case SSS_AUTHTOK_TYPE_SC_KEYPAD: sss_authtok_set_sc_keypad(tok); return EOK; case SSS_AUTHTOK_TYPE_EMPTY: sss_authtok_set_empty(tok); return EOK; } return EINVAL; } errno_t sss_authtok_copy(struct sss_auth_token *src, struct sss_auth_token *dst) { if (!src || !dst) { return EINVAL; } sss_authtok_set_empty(dst); if (src->type == SSS_AUTHTOK_TYPE_EMPTY) { return EOK; } dst->data = talloc_memdup(dst, src->data, src->length); if (!dst->data) { return ENOMEM; } dst->length = src->length; dst->type = src->type; return EOK; } struct sss_auth_token *sss_authtok_new(TALLOC_CTX *mem_ctx) { struct sss_auth_token *token; token = talloc_zero(mem_ctx, struct sss_auth_token); if (token == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); } return token; } void sss_authtok_wipe_password(struct sss_auth_token *tok) { if (!tok || tok->type != SSS_AUTHTOK_TYPE_PASSWORD) { return; } safezero(tok->data, tok->length); } errno_t sss_auth_unpack_2fa_blob(TALLOC_CTX *mem_ctx, const uint8_t *blob, size_t blob_len, char **fa1, size_t *_fa1_len, char **fa2, size_t *_fa2_len) { size_t c; uint32_t fa1_len; uint32_t fa2_len; if (blob_len < 2 * sizeof(uint32_t)) { DEBUG(SSSDBG_CRIT_FAILURE, "Blob too small.\n"); return EINVAL; } c = 0; SAFEALIGN_COPY_UINT32(&fa1_len, blob, &c); SAFEALIGN_COPY_UINT32(&fa2_len, blob + c, &c); if (blob_len != 2 * sizeof(uint32_t) + fa1_len + fa2_len) { DEBUG(SSSDBG_CRIT_FAILURE, "Blob size mismatch.\n"); return EINVAL; } if (fa1_len != 0) { *fa1 = talloc_strndup(mem_ctx, (const char *) blob + c, fa1_len); if (*fa1 == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); return ENOMEM; } } else { *fa1 = NULL; } if (fa2_len != 0) { *fa2 = talloc_strndup(mem_ctx, (const char *) blob + c + fa1_len, fa2_len); if (*fa2 == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); talloc_free(*fa1); return ENOMEM; } } else { *fa2 = NULL; } /* Re-calculate length for the case where \0 was missing in the blob */ *_fa1_len = (*fa1 == NULL) ? 0 : strlen(*fa1); *_fa2_len = (*fa2 == NULL) ? 0 : strlen(*fa2); return EOK; } static errno_t sss_authtok_set_2fa_from_blob(struct sss_auth_token *tok, const uint8_t *data, size_t len) { TALLOC_CTX *tmp_ctx; int ret; char *fa1; size_t fa1_len; char *fa2; size_t fa2_len; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); ret = ENOMEM; goto done; } ret = sss_auth_unpack_2fa_blob(tmp_ctx, data, len, &fa1, &fa1_len, &fa2, &fa2_len); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_auth_unpack_2fa_blob failed.\n"); goto done; } ret = sss_authtok_set_2fa(tok, fa1, fa1_len, fa2, fa2_len); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_set_2fa failed.\n"); goto done; } ret = EOK; done: talloc_free(tmp_ctx); if (ret != EOK) { sss_authtok_set_empty(tok); } return ret; } errno_t sss_authtok_get_2fa(struct sss_auth_token *tok, const char **fa1, size_t *fa1_len, const char **fa2, size_t *fa2_len) { size_t c; uint32_t tmp_uint32_t; if (tok->type != SSS_AUTHTOK_TYPE_2FA) { return (tok->type == SSS_AUTHTOK_TYPE_EMPTY) ? ENOENT : EACCES; } if (tok->length < 2 * sizeof(uint32_t)) { DEBUG(SSSDBG_CRIT_FAILURE, "Blob too small.\n"); return EINVAL; } c = 0; SAFEALIGN_COPY_UINT32(&tmp_uint32_t, tok->data, &c); *fa1_len = tmp_uint32_t - 1; SAFEALIGN_COPY_UINT32(&tmp_uint32_t, tok->data + c, &c); *fa2_len = tmp_uint32_t - 1; if (*fa1_len == 0 || *fa2_len == 0 || tok->length != 2 * sizeof(uint32_t) + *fa1_len + *fa2_len + 2) { DEBUG(SSSDBG_CRIT_FAILURE, "Blob size mismatch.\n"); return EINVAL; } if (tok->data[c + *fa1_len] != '\0' || tok->data[c + *fa1_len + 1 + *fa2_len] != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Missing terminating null character.\n"); return EINVAL; } *fa1 = (const char *) tok->data + c; *fa2 = (const char *) tok->data + c + *fa1_len + 1; return EOK; } errno_t sss_authtok_set_2fa(struct sss_auth_token *tok, const char *fa1, size_t fa1_len, const char *fa2, size_t fa2_len) { int ret; size_t needed_size; if (tok == NULL) { return EINVAL; } sss_authtok_set_empty(tok); ret = sss_auth_pack_2fa_blob(fa1, fa1_len, fa2, fa2_len, NULL, 0, &needed_size); if (ret != EAGAIN) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_auth_pack_2fa_blob unexpectedly returned [%d].\n", ret); return EINVAL; } tok->data = talloc_size(tok, needed_size); if (tok->data == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); return ENOMEM; } ret = sss_auth_pack_2fa_blob(fa1, fa1_len, fa2, fa2_len, tok->data, needed_size, &needed_size); if (ret != EOK) { talloc_free(tok->data); DEBUG(SSSDBG_OP_FAILURE, "sss_auth_pack_2fa_blob failed.\n"); return ret; } tok->length = needed_size; tok->type = SSS_AUTHTOK_TYPE_2FA; return EOK; } errno_t sss_authtok_set_sc_pin(struct sss_auth_token *tok, const char *pin, size_t len) { if (tok == NULL) { return EFAULT; } if (pin == NULL) { return EINVAL; } sss_authtok_set_empty(tok); return sss_authtok_set_string(tok, SSS_AUTHTOK_TYPE_SC_PIN, "sc_pin", pin, len); } errno_t sss_authtok_get_sc_pin(struct sss_auth_token *tok, const char **pin, size_t *len) { if (!tok) { return EFAULT; } switch (tok->type) { case SSS_AUTHTOK_TYPE_EMPTY: return ENOENT; case SSS_AUTHTOK_TYPE_SC_PIN: *pin = (const char *)tok->data; if (len) { *len = tok->length - 1; } return EOK; case SSS_AUTHTOK_TYPE_PASSWORD: case SSS_AUTHTOK_TYPE_CCFILE: case SSS_AUTHTOK_TYPE_2FA: case SSS_AUTHTOK_TYPE_SC_KEYPAD: return EACCES; } return EINVAL; } void sss_authtok_set_sc_keypad(struct sss_auth_token *tok) { if (!tok) { return; } sss_authtok_set_empty(tok); tok->type = SSS_AUTHTOK_TYPE_SC_KEYPAD; } sssd-1.13.4/src/util/PaxHeaders.16287/sss_python.h0000644000000000000000000000007412703456111016453 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.416792822 sssd-1.13.4/src/util/sss_python.h0000644002412700241270000000315412703456111020125 0ustar00jhrozekjhrozek00000000000000#ifndef __SSS_PYTHON_H__ #define __SSS_PYTHON_H__ #include #include #include "util/util.h" #if PY_VERSION_HEX < 0x02050000 #define sss_py_const_p(type, value) discard_const_p(type, (value)) #else #define sss_py_const_p(type, value) (value) #endif #if PY_MAJOR_VERSION >= 3 #define IS_PY3K #define MODINITERROR return NULL #define PYNUMBER_CHECK(what) PyLong_Check(what) #define PYNUMBER_FROMLONG(what) PyLong_FromLong(what) #define PYNUMBER_ASLONG(what) PyLong_AsLong(what) #else #include #define MODINITERROR return #define PYNUMBER_CHECK(what) PyInt_Check(what) #define PYNUMBER_FROMLONG(what) PyInt_FromLong(what) #define PYNUMBER_ASLONG(what) PyInt_AsLong(what) #endif /* Exceptions compatibility */ PyObject * sss_exception_with_doc(char *name, char *doc, PyObject *base, PyObject *dict); /* Convenience macros */ #define TYPE_READY(module, type, name) do { \ if (PyType_Ready(&type) < 0) { \ MODINITERROR; \ } \ Py_INCREF(&type); \ PyModule_AddObject(module, \ discard_const_p(char, name), \ (PyObject *) &type); \ } while(0) \ #define SAFE_SET(old, new) do { \ PyObject *__simple_set_tmp = NULL; \ __simple_set_tmp = old; \ Py_INCREF(new); \ old = new; \ Py_XDECREF(__simple_set_tmp); \ } while(0) #endif /* __SSS_PYTHON_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/util_sss_idmap.c0000644000000000000000000000007412703456111017254 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.879794392 sssd-1.13.4/src/util/util_sss_idmap.c0000644002412700241270000000170612703456111020727 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util_sss_idmap.h" void *sss_idmap_talloc(size_t size, void *pvt) { return talloc_size(pvt, size); } void sss_idmap_talloc_free(void *ptr, void *pvt) { talloc_free(ptr); } sssd-1.13.4/src/util/PaxHeaders.16287/signal.c0000644000000000000000000000007412703456111015512 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.861794331 sssd-1.13.4/src/util/signal.c0000644002412700241270000000414212703456111017162 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. signal handling functions Copyright (C) Andrew Tridgell 1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include #include /** * @file * @brief Signal handling */ /** Block sigs. **/ void BlockSignals(bool block, int signum) { #ifdef HAVE_SIGPROCMASK sigset_t set; sigemptyset(&set); sigaddset(&set,signum); sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL); #elif defined(HAVE_SIGBLOCK) if (block) { sigblock(sigmask(signum)); } else { sigsetmask(siggetmask() & ~sigmask(signum)); } #else /* yikes! This platform can't block signals? */ static int done; if (!done) { DEBUG(SSSDBG_FATAL_FAILURE,"WARNING: No signal blocking available\n"); done=1; } #endif } /** Catch a signal. This should implement the following semantics: 1) The handler remains installed after being called. 2) The signal should be blocked during handler execution. **/ void (*CatchSignal(int signum,void (*handler)(int )))(int) { #ifdef HAVE_SIGACTION struct sigaction act; struct sigaction oldact; ZERO_STRUCT(act); act.sa_handler = handler; #ifdef SA_RESTART /* * We *want* SIGALRM to interrupt a system call. */ if(signum != SIGALRM) act.sa_flags = SA_RESTART; #endif sigemptyset(&act.sa_mask); sigaddset(&act.sa_mask,signum); sigaction(signum,&act,&oldact); return oldact.sa_handler; #else /* !HAVE_SIGACTION */ /* FIXME: need to handle sigvec and systems with broken signal() */ return signal(signum, handler); #endif } sssd-1.13.4/src/util/PaxHeaders.16287/sss_krb5.c0000644000000000000000000000007412703456111015770 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.766794008 sssd-1.13.4/src/util/sss_krb5.c0000644002412700241270000010245212703456111017443 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2009-2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "config.h" #include "util/util.h" #include "util/sss_krb5.h" static char * sss_krb5_get_primary(TALLOC_CTX *mem_ctx, const char *pattern, const char *hostname) { char *primary; char *dot; char *c; char *shortname; if (strcmp(pattern, "%S$") == 0) { shortname = talloc_strdup(mem_ctx, hostname); if (!shortname) return NULL; dot = strchr(shortname, '.'); if (dot) { *dot = '\0'; } for (c=shortname; *c != '\0'; ++c) { *c = toupper(*c); } primary = talloc_asprintf(mem_ctx, "%s$", shortname); talloc_free(shortname); return primary; } return talloc_asprintf(mem_ctx, pattern, hostname); } errno_t select_principal_from_keytab(TALLOC_CTX *mem_ctx, const char *hostname, const char *desired_realm, const char *keytab_name, char **_principal, char **_primary, char **_realm) { krb5_error_code kerr = 0; krb5_context krb_ctx = NULL; krb5_keytab keytab = NULL; krb5_principal client_princ = NULL; TALLOC_CTX *tmp_ctx; char *primary = NULL; char *realm = NULL; int i = 0; errno_t ret; char *principal_string; const char *realm_name; int realm_len; /** * The %s conversion is passed as-is, the %S conversion is translated to * "short host name" * * Priority of lookup: * - our.hostname@REALM or host/our.hostname@REALM depending on the input * - SHORT.HOSTNAME$@REALM (AD domain) * - host/our.hostname@REALM * - foobar$@REALM (AD domain) * - host/foobar@REALM * - host/foo@BAR * - pick the first principal in the keytab */ const char *primary_patterns[] = {"%s", "%S$", "host/%s", "*$", "host/*", "host/*", NULL}; const char *realm_patterns[] = {"%s", "%s", "%s", "%s", "%s", NULL, NULL}; DEBUG(SSSDBG_FUNC_DATA, "trying to select the most appropriate principal from keytab\n"); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed\n"); return ENOMEM; } kerr = krb5_init_context(&krb_ctx); if (kerr) { DEBUG(SSSDBG_OP_FAILURE, "Failed to init kerberos context\n"); ret = EFAULT; goto done; } if (keytab_name != NULL) { kerr = krb5_kt_resolve(krb_ctx, keytab_name, &keytab); } else { kerr = krb5_kt_default(krb_ctx, &keytab); } if (kerr) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to read keytab [%s]: %s\n", KEYTAB_CLEAN_NAME, sss_krb5_get_error_message(krb_ctx, kerr)); ret = EFAULT; goto done; } if (!desired_realm) { desired_realm = "*"; } if (!hostname) { hostname = "*"; } do { if (primary_patterns[i]) { primary = sss_krb5_get_primary(tmp_ctx, primary_patterns[i], hostname); if (primary == NULL) { ret = ENOMEM; goto done; } } else { primary = NULL; } if (realm_patterns[i]) { realm = talloc_asprintf(tmp_ctx, realm_patterns[i], desired_realm); if (realm == NULL) { ret = ENOMEM; goto done; } } else { realm = NULL; } kerr = find_principal_in_keytab(krb_ctx, keytab, primary, realm, &client_princ); talloc_zfree(primary); talloc_zfree(realm); if (kerr == 0) { break; } if (client_princ != NULL) { krb5_free_principal(krb_ctx, client_princ); client_princ = NULL; } i++; } while(primary_patterns[i-1] != NULL || realm_patterns[i-1] != NULL); if (kerr == 0) { if (_principal) { kerr = krb5_unparse_name(krb_ctx, client_princ, &principal_string); if (kerr) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_unparse_name failed\n"); ret = EFAULT; goto done; } *_principal = talloc_strdup(mem_ctx, principal_string); free(principal_string); if (!*_principal) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_FUNC_DATA, "Selected principal: %s\n", *_principal); } if (_primary) { kerr = sss_krb5_unparse_name_flags(krb_ctx, client_princ, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &principal_string); if (kerr) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_unparse_name failed\n"); ret = EFAULT; goto done; } *_primary = talloc_strdup(mem_ctx, principal_string); free(principal_string); if (!*_primary) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed\n"); if (_principal) talloc_zfree(*_principal); ret = ENOMEM; goto done; } DEBUG(SSSDBG_FUNC_DATA, "Selected primary: %s\n", *_primary); } if (_realm) { sss_krb5_princ_realm(krb_ctx, client_princ, &realm_name, &realm_len); if (realm_len == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_krb5_princ_realm failed.\n"); if (_principal) talloc_zfree(*_principal); if (_primary) talloc_zfree(*_primary); ret = EINVAL; goto done; } *_realm = talloc_asprintf(mem_ctx, "%.*s", realm_len, realm_name); if (!*_realm) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed\n"); if (_principal) talloc_zfree(*_principal); if (_primary) talloc_zfree(*_primary); ret = ENOMEM; goto done; } DEBUG(SSSDBG_FUNC_DATA, "Selected realm: %s\n", *_realm); } ret = EOK; } else { DEBUG(SSSDBG_MINOR_FAILURE, "No suitable principal found in keytab\n"); ret = ENOENT; } done: if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to read keytab [%s]: %s\n", KEYTAB_CLEAN_NAME, strerror(ret)); sss_log(SSS_LOG_ERR, "Failed to read keytab [%s]: %s\n", KEYTAB_CLEAN_NAME, strerror(ret)); } if (keytab) krb5_kt_close(krb_ctx, keytab); if (krb_ctx) krb5_free_context(krb_ctx); if (client_princ != NULL) { krb5_free_principal(krb_ctx, client_princ); client_princ = NULL; } talloc_free(tmp_ctx); return ret; } enum matching_mode {MODE_NORMAL, MODE_PREFIX, MODE_POSTFIX}; /** * We only have primary and instances stored separately, we need to * join them to one string and compare that string. * * @param ctx kerberos context * @param principal principal we want to match * @param pattern_primary primary part of the principal we want to * perform matching against. It is possible to use * wildcard * at the beginning or at the end of the string. If NULL, it * will act as "*" * @param pattern_realm realm part of the principal we want to perform * the matching against. If NULL, it will act as "*" */ static bool match_principal(krb5_context ctx, krb5_principal principal, const char *pattern_primary, const char *pattern_realm) { char *primary = NULL; char *primary_str = NULL; int primary_str_len = 0; int tmp_len; int len_diff; const char *realm_name; int realm_len; enum matching_mode mode = MODE_NORMAL; TALLOC_CTX *tmp_ctx; bool ret = false; sss_krb5_princ_realm(ctx, principal, &realm_name, &realm_len); if (realm_len == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_krb5_princ_realm failed.\n"); return false; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed\n"); return false; } if (pattern_primary) { tmp_len = strlen(pattern_primary); if (pattern_primary[tmp_len-1] == '*') { mode = MODE_PREFIX; primary_str = talloc_strdup(tmp_ctx, pattern_primary); primary_str[tmp_len-1] = '\0'; primary_str_len = tmp_len-1; } else if (pattern_primary[0] == '*') { mode = MODE_POSTFIX; primary_str = talloc_strdup(tmp_ctx, pattern_primary+1); primary_str_len = tmp_len-1; } sss_krb5_unparse_name_flags(ctx, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &primary); len_diff = strlen(primary)-primary_str_len; if ((mode == MODE_NORMAL && strcmp(primary, pattern_primary) != 0) || (mode == MODE_PREFIX && strncmp(primary, primary_str, primary_str_len) != 0) || (mode == MODE_POSTFIX && strcmp(primary+len_diff, primary_str) != 0)) { goto done; } } if (!pattern_realm || (realm_len == strlen(pattern_realm) && strncmp(realm_name, pattern_realm, realm_len) == 0)) { DEBUG(SSSDBG_TRACE_LIBS, "Principal matched to the sample (%s@%s).\n", pattern_primary, pattern_realm); ret = true; } done: free(primary); talloc_free(tmp_ctx); return ret; } krb5_error_code find_principal_in_keytab(krb5_context ctx, krb5_keytab keytab, const char *pattern_primary, const char *pattern_realm, krb5_principal *princ) { krb5_error_code kerr; krb5_error_code kt_err; krb5_error_code kerr_d; krb5_kt_cursor cursor; krb5_keytab_entry entry; bool principal_found = false; memset(&cursor, 0, sizeof(cursor)); kerr = krb5_kt_start_seq_get(ctx, keytab, &cursor); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_start_seq_get failed.\n"); return kerr; } DEBUG(SSSDBG_TRACE_ALL, "Trying to find principal %s@%s in keytab.\n", pattern_primary, pattern_realm); memset(&entry, 0, sizeof(entry)); while ((kt_err = krb5_kt_next_entry(ctx, keytab, &entry, &cursor)) == 0) { principal_found = match_principal(ctx, entry.principal, pattern_primary, pattern_realm); if (principal_found) { break; } kerr = sss_krb5_free_keytab_entry_contents(ctx, &entry); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to free keytab entry.\n"); } memset(&entry, 0, sizeof(entry)); } /* Close the keytab here. Even though we're using cursors, the file * handle is stored in the krb5_keytab structure, and it gets * overwritten by other keytab calls, creating a leak. */ kerr = krb5_kt_end_seq_get(ctx, keytab, &cursor); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_kt_end_seq_get failed.\n"); goto done; } if (!principal_found) { kerr = KRB5_KT_NOTFOUND; DEBUG(SSSDBG_TRACE_FUNC, "No principal matching %s@%s found in keytab.\n", pattern_primary, pattern_realm); goto done; } /* check if we got any errors from krb5_kt_next_entry */ if (kt_err != 0 && kt_err != KRB5_KT_END) { DEBUG(SSSDBG_CRIT_FAILURE, "Error while reading keytab.\n"); goto done; } kerr = krb5_copy_principal(ctx, entry.principal, princ); if (kerr != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "krb5_copy_principal failed.\n"); goto done; } kerr = 0; done: kerr_d = sss_krb5_free_keytab_entry_contents(ctx, &entry); if (kerr_d != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to free keytab entry.\n"); } return kerr; } const char *KRB5_CALLCONV sss_krb5_get_error_message(krb5_context ctx, krb5_error_code ec) { #ifdef HAVE_KRB5_GET_ERROR_MESSAGE return krb5_get_error_message(ctx, ec); #else int ret; char *s = NULL; int size = sizeof("Kerberos error [XXXXXXXXXXXX]"); s = malloc(sizeof(char) * (size)); if (s == NULL) { return NULL; } ret = snprintf(s, size, "Kerberos error [%12d]", ec); if (ret < 0 || ret >= size) { free(s); return NULL; } return s; #endif } void KRB5_CALLCONV sss_krb5_free_error_message(krb5_context ctx, const char *s) { #ifdef HAVE_KRB5_GET_ERROR_MESSAGE krb5_free_error_message(ctx, s); #else free(s); #endif return; } krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_alloc( krb5_context context, krb5_get_init_creds_opt **opt) { #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC return krb5_get_init_creds_opt_alloc(context, opt); #else *opt = calloc(1, sizeof(krb5_get_init_creds_opt)); if (*opt == NULL) { return ENOMEM; } krb5_get_init_creds_opt_init(*opt); return 0; #endif } void KRB5_CALLCONV sss_krb5_get_init_creds_opt_free (krb5_context context, krb5_get_init_creds_opt *opt) { #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC krb5_get_init_creds_opt_free(context, opt); #else free(opt); #endif return; } void KRB5_CALLCONV sss_krb5_free_unparsed_name(krb5_context context, char *name) { #ifdef HAVE_KRB5_FREE_UNPARSED_NAME krb5_free_unparsed_name(context, name); #else if (name != NULL) { memset(name, 0, strlen(name)); free(name); } #endif } krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_set_expire_callback( krb5_context context, krb5_get_init_creds_opt *opt, krb5_expire_callback_func cb, void *data) { #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_EXPIRE_CALLBACK return krb5_get_init_creds_opt_set_expire_callback(context, opt, cb, data); #else DEBUG(SSSDBG_FUNC_DATA, "krb5_get_init_creds_opt_set_expire_callback not available.\n"); return 0; #endif } errno_t check_fast(const char *str, bool *use_fast) { #if HAVE_KRB5_GET_INIT_CREDS_OPT_SET_FAST_FLAGS if (strcasecmp(str, "never") == 0 ) { *use_fast = false; } else if (strcasecmp(str, "try") == 0 || strcasecmp(str, "demand") == 0) { *use_fast = true; } else { sss_log(SSS_LOG_ALERT, "Unsupported value [%s] for option krb5_use_fast," "please use never, try, or demand.\n", str); return EINVAL; } return EOK; #else sss_log(SSS_LOG_ALERT, "This build of sssd does not support FAST. " "Please remove option krb5_use_fast.\n"); return EINVAL; #endif } krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_set_fast_ccache_name( krb5_context context, krb5_get_init_creds_opt *opt, const char *fast_ccache_name) { #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_FAST_CCACHE_NAME return krb5_get_init_creds_opt_set_fast_ccache_name(context, opt, fast_ccache_name); #else DEBUG(SSSDBG_FUNC_DATA, "krb5_get_init_creds_opt_set_fast_ccache_name not available.\n"); return 0; #endif } krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_set_fast_flags( krb5_context context, krb5_get_init_creds_opt *opt, krb5_flags flags) { #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_FAST_FLAGS return krb5_get_init_creds_opt_set_fast_flags(context, opt, flags); #else DEBUG(SSSDBG_FUNC_DATA, "krb5_get_init_creds_opt_set_fast_flags not available.\n"); return 0; #endif } #ifndef HAVE_KRB5_UNPARSE_NAME_FLAGS #ifndef REALM_SEP #define REALM_SEP '@' #endif #ifndef COMPONENT_SEP #define COMPONENT_SEP '/' #endif static int sss_krb5_copy_component_quoting(char *dest, const krb5_data *src, int flags) { int j; const char *cp = src->data; char *q = dest; int length = src->length; if (flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) { memcpy(dest, src->data, src->length); return src->length; } for (j=0; j < length; j++,cp++) { int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) && !(flags & KRB5_PRINCIPAL_UNPARSE_SHORT); switch (*cp) { case REALM_SEP: if (no_realm) { *q++ = *cp; break; } case COMPONENT_SEP: case '\\': *q++ = '\\'; *q++ = *cp; break; case '\t': *q++ = '\\'; *q++ = 't'; break; case '\n': *q++ = '\\'; *q++ = 'n'; break; case '\b': *q++ = '\\'; *q++ = 'b'; break; case '\0': *q++ = '\\'; *q++ = '0'; break; default: *q++ = *cp; } } return q - dest; } static int sss_krb5_component_length_quoted(const krb5_data *src, int flags) { const char *cp = src->data; int length = src->length; int j; int size = length; if ((flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) == 0) { int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) && !(flags & KRB5_PRINCIPAL_UNPARSE_SHORT); for (j = 0; j < length; j++,cp++) if ((!no_realm && *cp == REALM_SEP) || *cp == COMPONENT_SEP || *cp == '\0' || *cp == '\\' || *cp == '\t' || *cp == '\n' || *cp == '\b') size++; } return size; } #endif /* HAVE_KRB5_UNPARSE_NAME_FLAGS */ krb5_error_code sss_krb5_parse_name_flags(krb5_context context, const char *name, int flags, krb5_principal *principal) { #ifdef HAVE_KRB5_PARSE_NAME_FLAGS return krb5_parse_name_flags(context, name, flags, principal); #else if (flags != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "krb5_parse_name_flags not available on " \ "this plattform, names are parsed " \ "without flags. Some features like " \ "enterprise principals might not work " \ "as expected.\n"); } return krb5_parse_name(context, name, principal); #endif } krb5_error_code sss_krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal, int flags, char **name) { #ifdef HAVE_KRB5_UNPARSE_NAME_FLAGS return krb5_unparse_name_flags(context, principal, flags, name); #else char *cp, *q; int i; int length; krb5_int32 nelem; unsigned int totalsize = 0; char *default_realm = NULL; krb5_error_code ret = 0; if (name != NULL) *name = NULL; if (!principal || !name) return KRB5_PARSE_MALFORMED; if (flags & KRB5_PRINCIPAL_UNPARSE_SHORT) { /* omit realm if local realm */ krb5_principal_data p; ret = krb5_get_default_realm(context, &default_realm); if (ret != 0) goto cleanup; krb5_princ_realm(context, &p)->length = strlen(default_realm); krb5_princ_realm(context, &p)->data = default_realm; if (krb5_realm_compare(context, &p, principal)) flags |= KRB5_PRINCIPAL_UNPARSE_NO_REALM; } if ((flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) == 0) { totalsize += sss_krb5_component_length_quoted(krb5_princ_realm(context, principal), flags); totalsize++; } nelem = krb5_princ_size(context, principal); for (i = 0; i < (int) nelem; i++) { cp = krb5_princ_component(context, principal, i)->data; totalsize += sss_krb5_component_length_quoted(krb5_princ_component(context, principal, i), flags); totalsize++; } if (nelem == 0) totalsize++; *name = malloc(totalsize); if (!*name) { ret = ENOMEM; goto cleanup; } q = *name; for (i = 0; i < (int) nelem; i++) { cp = krb5_princ_component(context, principal, i)->data; length = krb5_princ_component(context, principal, i)->length; q += sss_krb5_copy_component_quoting(q, krb5_princ_component(context, principal, i), flags); *q++ = COMPONENT_SEP; } if (i > 0) q--; if ((flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) == 0) { *q++ = REALM_SEP; q += sss_krb5_copy_component_quoting(q, krb5_princ_realm(context, principal), flags); } *q++ = '\0'; cleanup: free(default_realm); return ret; #endif /* HAVE_KRB5_UNPARSE_NAME_FLAGS */ } void sss_krb5_get_init_creds_opt_set_canonicalize(krb5_get_init_creds_opt *opts, int canonicalize) { /* FIXME: The extra check for HAVE_KRB5_TICKET_TIMES is a workaround due to Heimdal * defining krb5_get_init_creds_opt_set_canonicalize() with a different set of * arguments. We should use a better configure check in the future. */ #if defined(HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CANONICALIZE) && defined(HAVE_KRB5_TICKET_TIMES) krb5_get_init_creds_opt_set_canonicalize(opts, canonicalize); #else DEBUG(SSSDBG_OP_FAILURE, "Kerberos principal canonicalization is not available!\n"); #endif } #ifdef HAVE_KRB5_PRINCIPAL_GET_REALM void sss_krb5_princ_realm(krb5_context context, krb5_const_principal princ, const char **realm, int *len) { const char *realm_str = krb5_principal_get_realm(context, princ); if (realm_str != NULL) { *realm = realm_str; *len = strlen(realm_str); } else { *realm = NULL; *len = 0; } } #else void sss_krb5_princ_realm(krb5_context context, krb5_const_principal princ, const char **realm, int *len) { const krb5_data *data; data = krb5_princ_realm(context, princ); if (data) { *realm = data->data; *len = data->length; } else { *realm = NULL; *len = 0; } } #endif #ifdef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS krb5_error_code sss_krb5_free_keytab_entry_contents(krb5_context context, krb5_keytab_entry *entry) { return krb5_free_keytab_entry_contents(context, entry); } #else krb5_error_code sss_krb5_free_keytab_entry_contents(krb5_context context, krb5_keytab_entry *entry) { return krb5_kt_free_entry(context, entry); } #endif #ifdef HAVE_KRB5_SET_TRACE_CALLBACK #ifndef HAVE_KRB5_TRACE_INFO /* krb5-1.10 had struct krb5_trace_info, 1.11 has type named krb5_trace_info */ typedef struct krb5_trace_info krb5_trace_info; #endif /* HAVE_KRB5_TRACE_INFO */ static void sss_child_krb5_trace_cb(krb5_context context, const krb5_trace_info *info, void *data) { if (info == NULL) { /* Null info means destroy the callback data. */ return; } DEBUG(SSSDBG_TRACE_ALL, "%s\n", info->message); } errno_t sss_child_set_krb5_tracing(krb5_context ctx) { return krb5_set_trace_callback(ctx, sss_child_krb5_trace_cb, NULL); } #else /* HAVE_KRB5_SET_TRACE_CALLBACK */ errno_t sss_child_set_krb5_tracing(krb5_context ctx) { DEBUG(SSSDBG_CONF_SETTINGS, "krb5 tracing is not available\n"); return 0; } #endif /* HAVE_KRB5_SET_TRACE_CALLBACK */ krb5_error_code sss_krb5_find_authdata(krb5_context context, krb5_authdata *const *ticket_authdata, krb5_authdata *const *ap_req_authdata, krb5_authdatatype ad_type, krb5_authdata ***results) { #ifdef HAVE_KRB5_FIND_AUTHDATA return krb5_find_authdata(context, ticket_authdata, ap_req_authdata, ad_type, results); #else return ENOTSUP; #endif } krb5_error_code sss_extract_pac(krb5_context ctx, krb5_ccache ccache, krb5_principal server_principal, krb5_principal client_principal, krb5_keytab keytab, krb5_authdata ***_pac_authdata) { #ifdef HAVE_PAC_RESPONDER krb5_error_code kerr; krb5_creds mcred; krb5_creds cred; krb5_authdata **pac_authdata = NULL; krb5_pac pac = NULL; int ret; krb5_ticket *ticket = NULL; krb5_keytab_entry entry; memset(&entry, 0, sizeof(entry)); memset(&mcred, 0, sizeof(mcred)); memset(&cred, 0, sizeof(mcred)); mcred.server = server_principal; mcred.client = client_principal; kerr = krb5_cc_retrieve_cred(ctx, ccache, 0, &mcred, &cred); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_cc_retrieve_cred failed.\n"); goto done; } kerr = krb5_decode_ticket(&cred.ticket, &ticket); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_decode_ticket failed.\n"); goto done; } kerr = krb5_server_decrypt_ticket_keytab(ctx, keytab, ticket); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_server_decrypt_ticket_keytab failed.\n"); goto done; } kerr = sss_krb5_find_authdata(ctx, ticket->enc_part2->authorization_data, NULL, KRB5_AUTHDATA_WIN2K_PAC, &pac_authdata); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_find_authdata failed.\n"); goto done; } if (pac_authdata == NULL || pac_authdata[0] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "No PAC authdata available.\n"); kerr = ENOENT; goto done; } if (pac_authdata[1] != NULL) { DEBUG(SSSDBG_OP_FAILURE, "More than one PAC autdata found.\n"); kerr = EINVAL; goto done; } kerr = krb5_pac_parse(ctx, pac_authdata[0]->contents, pac_authdata[0]->length, &pac); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_pac_parse failed.\n"); goto done; } kerr = krb5_kt_get_entry(ctx, keytab, ticket->server, ticket->enc_part.kvno, ticket->enc_part.enctype, &entry); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_kt_get_entry failed.\n"); goto done; } kerr = krb5_pac_verify(ctx, pac, 0, NULL, &entry.key, NULL); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_pac_verify failed.\n"); goto done; } ret = unsetenv("_SSS_LOOPS"); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unset _SSS_LOOPS, " "sss_pac_make_request will most certainly fail.\n"); } *_pac_authdata = pac_authdata; kerr = 0; done: if (kerr != 0) { krb5_free_authdata(ctx, pac_authdata); } if (entry.magic != 0) { krb5_free_keytab_entry_contents(ctx, &entry); } krb5_pac_free(ctx, pac); if (ticket != NULL) { krb5_free_ticket(ctx, ticket); } krb5_free_cred_contents(ctx, &cred); return kerr; #else return ENOTSUP; #endif } char * sss_get_ccache_name_for_principal(TALLOC_CTX *mem_ctx, krb5_context ctx, krb5_principal principal, const char *location) { #ifdef HAVE_KRB5_CC_COLLECTION krb5_error_code kerr; krb5_ccache tmp_cc = NULL; char *tmp_ccname = NULL; char *ret_ccname = NULL; DEBUG(SSSDBG_TRACE_ALL, "Location: [%s]\n", location); kerr = krb5_cc_set_default_name(ctx, location); if (kerr != 0) { KRB5_DEBUG(SSSDBG_MINOR_FAILURE, ctx, kerr); return NULL; } kerr = krb5_cc_cache_match(ctx, principal, &tmp_cc); if (kerr != 0) { const char *err_msg = sss_krb5_get_error_message(ctx, kerr); DEBUG(SSSDBG_TRACE_INTERNAL, "krb5_cc_cache_match failed: [%d][%s]\n", kerr, err_msg); sss_krb5_free_error_message(ctx, err_msg); return NULL; } kerr = krb5_cc_get_full_name(ctx, tmp_cc, &tmp_ccname); if (kerr != 0) { KRB5_DEBUG(SSSDBG_MINOR_FAILURE, ctx, kerr); goto done; } DEBUG(SSSDBG_TRACE_ALL, "tmp_ccname: [%s]\n", tmp_ccname); ret_ccname = talloc_strdup(mem_ctx, tmp_ccname); if (ret_ccname == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed (ENOMEM).\n"); } done: if (tmp_cc != NULL) { kerr = krb5_cc_close(ctx, tmp_cc); if (kerr != 0) { KRB5_DEBUG(SSSDBG_MINOR_FAILURE, ctx, kerr); } } krb5_free_string(ctx, tmp_ccname); return ret_ccname; #else return NULL; #endif /* HAVE_KRB5_CC_COLLECTION */ } krb5_error_code sss_krb5_kt_have_content(krb5_context context, krb5_keytab keytab) { #ifdef HAVE_KRB5_KT_HAVE_CONTENT return krb5_kt_have_content(context, keytab); #else krb5_keytab_entry entry; krb5_kt_cursor cursor; krb5_error_code kerr; krb5_error_code kerr_end; kerr = krb5_kt_start_seq_get(context, keytab, &cursor); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_kt_start_seq_get failed, assuming no entries.\n"); return KRB5_KT_NOTFOUND; } kerr = krb5_kt_next_entry(context, keytab, &entry, &cursor); kerr_end = krb5_kt_end_seq_get(context, keytab, &cursor); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_kt_next_entry failed, assuming no entries.\n"); return KRB5_KT_NOTFOUND; } kerr = krb5_free_keytab_entry_contents(context, &entry); if (kerr_end != 0) { DEBUG(SSSDBG_TRACE_FUNC, "krb5_kt_end_seq_get failed, ignored.\n"); } if (kerr != 0) { DEBUG(SSSDBG_TRACE_FUNC, "krb5_free_keytab_entry_contents failed, ignored.\n"); } return 0; #endif } #define KDC_PROXY_INDICATOR "https://" #define KDC_PROXY_INDICATOR_LEN (sizeof(KDC_PROXY_INDICATOR) - 1) bool sss_krb5_realm_has_proxy(const char *realm) { krb5_context context = NULL; krb5_error_code kerr; struct _profile_t *profile = NULL; const char *profile_path[4] = {"realms", NULL, "kdc", NULL}; char **list = NULL; bool res = false; size_t c; if (realm == NULL) { return false; } kerr = krb5_init_context(&context); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_init_context failed.\n"); return false; } kerr = krb5_get_profile(context, &profile); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_get_profile failed.\n"); goto done; } profile_path[1] = realm; kerr = profile_get_values(profile, profile_path, &list); if (kerr == PROF_NO_RELATION || kerr == PROF_NO_SECTION) { kerr = 0; goto done; } else if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "profile_get_values failed.\n"); goto done; } for (c = 0; list[c] != NULL; c++) { if (strncasecmp(KDC_PROXY_INDICATOR, list[c], KDC_PROXY_INDICATOR_LEN) == 0) { DEBUG(SSSDBG_TRACE_ALL, "Found KDC Proxy indicator [%s] in [%s].\n", KDC_PROXY_INDICATOR, list[c]); res = true; break; } } done: profile_free_list(list); profile_release(profile); krb5_free_context(context); return res; } sssd-1.13.4/src/util/PaxHeaders.16287/user_info_msg.h0000644000000000000000000000007412703456111017101 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.426792856 sssd-1.13.4/src/util/user_info_msg.h0000644002412700241270000000211512703456111020547 0ustar00jhrozekjhrozek00000000000000/* SSSD Pack user info messages Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __USER_INFO_MSG_H__ #define __USER_INFO_MSG_H__ errno_t pack_user_info_chpass_error(TALLOC_CTX *mem_ctx, const char *user_error_message, size_t *len, uint8_t **_resp); #endif /* __USER_INFO_MSG_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/sss_ini.h0000644000000000000000000000007412703456111015711 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.420792835 sssd-1.13.4/src/util/sss_ini.h0000644002412700241270000000460012703456111017360 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_ini.c Authors: Ondrej Kos Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSS_INI_H__ #define __SSS_INI_H__ /* Structure declarations */ /* INI data structure */ struct sss_ini_initdata; /* Function declarations */ /* Initialize data structure */ struct sss_ini_initdata* sss_ini_initdata_init(TALLOC_CTX *tmp_ctx); /* Close file descriptor */ void sss_ini_close_file(struct sss_ini_initdata *init_data); /* Open config file */ int sss_ini_config_file_open(struct sss_ini_initdata *init_data, const char *config_file); /* Check file permissions */ int sss_ini_config_access_check(struct sss_ini_initdata *init_data); /* Cstat */ int sss_ini_get_stat(struct sss_ini_initdata *init_data); /* Get mtime */ int sss_ini_get_mtime(struct sss_ini_initdata *init_data, size_t timestr_len, char *timestr); /* Load configuration */ int sss_ini_get_config(struct sss_ini_initdata *init_data, const char *config_file); /* Get configuration object */ int sss_ini_get_cfgobj(struct sss_ini_initdata *init_data, const char *section, const char *name); /* Check configuration object */ int sss_ini_check_config_obj(struct sss_ini_initdata *init_data); /* Get int value */ int sss_ini_get_int_config_value(struct sss_ini_initdata *init_data, int strict, int def, int *error); /* Destroy ini config */ void sss_ini_config_destroy(struct sss_ini_initdata *init_data); /* Create LDIF */ int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx, struct sss_ini_initdata *init_data, const char **config_ldif); #endif /* __SSS_INI_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/sss_tc_utf8.c0000644000000000000000000000007412703456111016501 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.866794348 sssd-1.13.4/src/util/sss_tc_utf8.c0000644002412700241270000000472512703456111020160 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/sss_utf8.h" char * sss_tc_utf8_str_tolower(TALLOC_CTX *mem_ctx, const char *s) { size_t nlen; uint8_t *ret; ret = sss_tc_utf8_tolower(mem_ctx, (const uint8_t *) s, strlen(s), &nlen); if (!ret) return NULL; ret = talloc_realloc(mem_ctx, ret, uint8_t, nlen+1); if (!ret) return NULL; ret[nlen] = '\0'; return (char *) ret; } uint8_t * sss_tc_utf8_tolower(TALLOC_CTX *mem_ctx, const uint8_t *s, size_t len, size_t *_nlen) { uint8_t *lower; uint8_t *ret; size_t nlen; lower = sss_utf8_tolower(s, len, &nlen); if (!lower) return NULL; ret = talloc_memdup(mem_ctx, lower, nlen); sss_utf8_free(lower); if (!ret) return NULL; *_nlen = nlen; return ret; } errno_t sss_filter_sanitize_for_dom(TALLOC_CTX *mem_ctx, const char *input, struct sss_domain_info *dom, char **sanitized, char **lc_sanitized) { int ret; ret = sss_filter_sanitize(mem_ctx, input, sanitized); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize failed.\n"); return ret; } if (dom->case_sensitive) { *lc_sanitized = talloc_strdup(mem_ctx, *sanitized); } else { *lc_sanitized = sss_tc_utf8_str_tolower(mem_ctx, *sanitized); } if (*lc_sanitized == NULL) { DEBUG(SSSDBG_OP_FAILURE, "%s failed.\n", dom->case_sensitive ? "talloc_strdup" : "sss_tc_utf8_str_tolower"); return ENOMEM; } return EOK; } sssd-1.13.4/src/util/PaxHeaders.16287/find_uid.c0000644000000000000000000000007412703456111016016 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.878794388 sssd-1.13.4/src/util/find_uid.c0000644002412700241270000002017512703456111017472 0ustar00jhrozekjhrozek00000000000000/* SSSD Create uid table Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "util/find_uid.h" #include "util/util.h" #include "util/strtonum.h" #ifdef HAVE_SYSTEMD_LOGIN #include #endif #define INITIAL_TABLE_SIZE 64 #define PATHLEN (NAME_MAX + 14) #define BUFSIZE 4096 static void *hash_talloc(const size_t size, void *pvt) { return talloc_size(pvt, size); } static void hash_talloc_free(void *ptr, void *pvt) { talloc_free(ptr); } static errno_t get_uid_from_pid(const pid_t pid, uid_t *uid) { int ret; char path[PATHLEN]; struct stat stat_buf; int fd; char buf[BUFSIZE]; char *p; char *e; char *endptr; uint32_t num=0; errno_t error; ret = snprintf(path, PATHLEN, "/proc/%d/status", pid); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "snprintf failed\n"); return EINVAL; } else if (ret >= PATHLEN) { DEBUG(SSSDBG_CRIT_FAILURE, "path too long?!?!\n"); return EINVAL; } fd = open(path, O_RDONLY); if (fd == -1) { error = errno; if (error == ENOENT) { DEBUG(SSSDBG_TRACE_LIBS, "Proc file [%s] is not available anymore, continuing.\n", path); return EOK; } DEBUG(SSSDBG_CRIT_FAILURE, "open failed [%d][%s].\n", error, strerror(error)); return error; } ret = fstat(fd, &stat_buf); if (ret == -1) { error = errno; if (error == ENOENT) { DEBUG(SSSDBG_TRACE_LIBS, "Proc file [%s] is not available anymore, continuing.\n", path); error = EOK; goto fail_fd; } DEBUG(SSSDBG_CRIT_FAILURE, "fstat failed [%d][%s].\n", error, strerror(error)); goto fail_fd; } if (!S_ISREG(stat_buf.st_mode)) { DEBUG(SSSDBG_CRIT_FAILURE, "not a regular file\n"); error = EINVAL; goto fail_fd; } errno = 0; ret = sss_atomic_read_s(fd, buf, BUFSIZE); if (ret == -1) { error = errno; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", error, strerror(error)); goto fail_fd; } /* Guarantee NULL-termination in case we read the full BUFSIZE somehow */ buf[BUFSIZE-1] = '\0'; ret = close(fd); if (ret == -1) { error = errno; DEBUG(SSSDBG_CRIT_FAILURE, "close failed [%d][%s].\n", error, strerror(error)); } p = strstr(buf, "\nUid:\t"); if (p != NULL) { p += 6; e = strchr(p,'\t'); if (e == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "missing delimiter.\n"); return EINVAL; } else { *e = '\0'; } num = (uint32_t) strtoint32(p, &endptr, 10); error = errno; if (error != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "strtol failed [%s].\n", strerror(error)); return error; } if (*endptr != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "uid contains extra characters\n"); return EINVAL; } } else { DEBUG(SSSDBG_CRIT_FAILURE, "format error\n"); return EINVAL; } *uid = num; return EOK; fail_fd: close(fd); return error; } static errno_t name_to_pid(const char *name, pid_t *pid) { long num; char *endptr; errno_t error; errno = 0; num = strtol(name, &endptr, 10); error = errno; if (error == ERANGE) { perror("strtol"); return error; } if (*endptr != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "pid string contains extra characters.\n"); return EINVAL; } if (num <= 0 || num >= INT_MAX) { DEBUG(SSSDBG_CRIT_FAILURE, "pid out of range.\n"); return ERANGE; } *pid = num; return EOK; } static int only_numbers(char *p) { while(*p!='\0' && isdigit(*p)) ++p; return *p; } static errno_t get_active_uid_linux(hash_table_t *table, uid_t search_uid) { DIR *proc_dir = NULL; struct dirent *dirent; int ret, err; pid_t pid = -1; uid_t uid; hash_key_t key; hash_value_t value; proc_dir = opendir("/proc"); if (proc_dir == NULL) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot open proc dir.\n"); goto done; }; errno = 0; while ((dirent = readdir(proc_dir)) != NULL) { if (only_numbers(dirent->d_name) != 0) continue; ret = name_to_pid(dirent->d_name, &pid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "name_to_pid failed.\n"); goto done; } ret = get_uid_from_pid(pid, &uid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "get_uid_from_pid failed.\n"); goto done; } if (table != NULL) { key.type = HASH_KEY_ULONG; key.ul = (unsigned long) uid; value.type = HASH_VALUE_ULONG; value.ul = (unsigned long) uid; ret = hash_enter(table, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "cannot add to table [%s]\n", hash_error_string(ret)); ret = ENOMEM; goto done; } } else { if (uid == search_uid) { ret = EOK; goto done; } } errno = 0; } if (errno != 0 && dirent == NULL) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "readdir failed.\n"); goto done; } ret = closedir(proc_dir); proc_dir = NULL; if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "closedir failed, watch out.\n"); } if (table != NULL) { ret = EOK; } else { ret = ENOENT; } done: if (proc_dir != NULL) { err = closedir(proc_dir); if (err) { DEBUG(SSSDBG_CRIT_FAILURE, "closedir failed, bad dirp?\n"); } } return ret; } errno_t get_uid_table(TALLOC_CTX *mem_ctx, hash_table_t **table) { #ifdef __linux__ int ret; ret = hash_create_ex(INITIAL_TABLE_SIZE, table, 0, 0, 0, 0, hash_talloc, hash_talloc_free, mem_ctx, NULL, NULL); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_create_ex failed [%s]\n", hash_error_string(ret)); return ENOMEM; } return get_active_uid_linux(*table, 0); #else return ENOSYS; #endif } errno_t check_if_uid_is_active(uid_t uid, bool *result) { int ret; #ifdef HAVE_SYSTEMD_LOGIN ret = sd_uid_get_sessions(uid, 0, NULL); if (ret > 0) { *result = true; return EOK; } if (ret == 0) { *result = false; } if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "systemd-login gave error %d: %s\n", -ret, strerror(-ret)); } /* fall back to the old method */ #endif ret = get_active_uid_linux(NULL, uid); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "get_uid_table failed.\n"); return ret; } if (ret == EOK) { *result = true; } else { *result = false; } return EOK; } sssd-1.13.4/src/util/PaxHeaders.16287/child_common.h0000644000000000000000000000007412703456111016675 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.536793229 sssd-1.13.4/src/util/child_common.h0000644002412700241270000000772512703456111020357 0ustar00jhrozekjhrozek00000000000000/* SSSD Common helper functions to be used in child processes Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __CHILD_COMMON_H__ #define __CHILD_COMMON_H__ #include #include #include #include #include "util/util.h" #define IN_BUF_SIZE 512 #define CHILD_MSG_CHUNK 256 struct response { uint8_t *buf; size_t size; }; struct io_buffer { uint8_t *data; size_t size; }; struct child_io_fds { int read_from_child_fd; int write_to_child_fd; }; /* COMMON SIGCHLD HANDLING */ typedef void (*sss_child_fn_t)(int pid, int wait_status, void *pvt); struct sss_sigchild_ctx; struct sss_child_ctx; /* Create a new child context to manage callbacks */ errno_t sss_sigchld_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sss_sigchild_ctx **child_ctx); errno_t sss_child_register(TALLOC_CTX *mem_ctx, struct sss_sigchild_ctx *sigchld_ctx, pid_t pid, sss_child_fn_t cb, void *pvt, struct sss_child_ctx **child_ctx); /* Callback to be invoked when a sigchld handler is called. * The tevent_signal * associated with the handler will be * freed automatically when this function returns. */ typedef void (*sss_child_callback_t)(int child_status, struct tevent_signal *sige, void *pvt); struct sss_child_ctx_old; /* Set up child termination signal handler */ int child_handler_setup(struct tevent_context *ev, int pid, sss_child_callback_t cb, void *pvt, struct sss_child_ctx_old **_child_ctx); /* Destroy child termination signal handler */ void child_handler_destroy(struct sss_child_ctx_old *ctx); /* Async communication with the child process via a pipe */ struct tevent_req *write_pipe_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, uint8_t *buf, size_t len, int fd); int write_pipe_recv(struct tevent_req *req); struct tevent_req *read_pipe_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd); int read_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **buf, ssize_t *len); /* The pipes to communicate with the child must be nonblocking */ void fd_nonblocking(int fd); /* Never returns EOK, ether returns an error, or doesn't return on success */ errno_t exec_child_ex(TALLOC_CTX *mem_ctx, int *pipefd_to_child, int *pipefd_from_child, const char *binary, int debug_fd, const char *extra_argv[], bool extra_args_only, int child_in_fd, int child_out_fd); /* Same as exec_child_ex() except child_in_fd is set to STDIN_FILENO and * child_out_fd is set to STDOUT_FILENO and extra_argv is always NULL. */ errno_t exec_child(TALLOC_CTX *mem_ctx, int *pipefd_to_child, int *pipefd_from_child, const char *binary, int debug_fd); int child_io_destructor(void *ptr); errno_t child_debug_init(const char *logfile, int *debug_fd); #endif /* __CHILD_COMMON_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/sss_ldap.h0000644000000000000000000000007412703456111016052 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.415792818 sssd-1.13.4/src/util/sss_ldap.h0000644002412700241270000000635112703456111017526 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSS_LDAP_H__ #define __SSS_LDAP_H__ #include #include #include #include #include #ifndef LDAP_CONTROL_PWEXPIRED #define LDAP_CONTROL_PWEXPIRED "2.16.840.1.113730.3.4.4" #endif #ifndef LDAP_CONTROL_PWEXPIRING #define LDAP_CONTROL_PWEXPIRING "2.16.840.1.113730.3.4.5" #endif #ifdef LDAP_OPT_DIAGNOSTIC_MESSAGE #define SDAP_DIAGNOSTIC_MESSAGE LDAP_OPT_DIAGNOSTIC_MESSAGE #else #ifdef LDAP_OPT_ERROR_STRING #define SDAP_DIAGNOSTIC_MESSAGE LDAP_OPT_ERROR_STRING #else #error No extended diagnostic message available #endif #endif const char* sss_ldap_err2string(int err); int sss_ldap_get_diagnostic_msg(TALLOC_CTX *mem_ctx, LDAP *ld, char **_errmsg); #ifndef LDAP_SERVER_ASQ_OID #define LDAP_SERVER_ASQ_OID "1.2.840.113556.1.4.1504" #endif /* LDAP_SERVER_ASQ_OID */ #ifndef LDAP_SERVER_SD_OID #define LDAP_SERVER_SD_OID "1.2.840.113556.1.4.801" #endif /* LDAP_SERVER_SD_OID */ /* * The following four flags specify which security descriptor parts to retrieve * during sd_search (see http://msdn.microsoft.com/en-us/library/aa366987.aspx) */ #define SECINFO_OWNER ( 0x00000001 ) #define SECINFO_GROUP ( 0x00000002 ) #define SECINFO_DACL ( 0x00000004 ) #define SECINFO_SACL ( 0x00000008 ) int sss_ldap_control_create(const char *oid, int iscritical, struct berval *value, int dupval, LDAPControl **ctrlp); struct tevent_req *sss_ldap_init_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *uri, struct sockaddr_storage *addr, int addr_len, int timeout); int sss_ldap_init_recv(struct tevent_req *req, LDAP **ldap, int *sd); struct sdap_options; struct sdap_search_base; bool sss_ldap_dn_in_search_bases(TALLOC_CTX *mem_ctx, const char *dn, struct sdap_search_base **search_bases, char **_filter); bool sss_ldap_dn_in_search_bases_len(TALLOC_CTX *mem_ctx, const char *dn, struct sdap_search_base **search_bases, char **_filter, int *_match_len); char *sss_ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t flags); #endif /* __SSS_LDAP_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/sss_utf8.h0000644000000000000000000000007412703456111016020 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.418792829 sssd-1.13.4/src/util/sss_utf8.h0000644002412700241270000000222212703456111017465 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_UTF8_H_ #define SSS_UTF8_H_ #include "util/util.h" #ifndef ENOMATCH #define ENOMATCH -1 #endif void sss_utf8_free(void *ptr); /* The result must be freed with sss_utf8_free() */ uint8_t *sss_utf8_tolower(const uint8_t *s, size_t len, size_t *nlen); bool sss_utf8_check(const uint8_t *s, size_t n); errno_t sss_utf8_case_eq(const uint8_t *s1, const uint8_t *s2); #endif /* SSS_UTF8_H_ */ sssd-1.13.4/src/util/PaxHeaders.16287/sss_format.h0000644000000000000000000000007412703456111016422 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.420792835 sssd-1.13.4/src/util/sss_format.h0000644002412700241270000000320512703456111020071 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_format.h Authors: Lukas Slebodnik Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSS_FORMAT_H__ #define __SSS_FORMAT_H__ #include /* key_serial_t is defined in keyutils.h as typedef int32_t */ #define SPRIkey_ser PRId32 /* rlim_t is defined with conditional build as unsigned type. * It seems that sizeof(rlim_t) is 8. It may be platform dependent, therefore * the same format will be used like with uint64_t. */ #define SPRIrlim PRIu64 #if SIZEOF_ID_T == 8 # define SPRIid PRIu64 #elif SIZEOF_ID_T == 4 # define SPRIid PRIu32 #else # error Unexpected sizeof id_t #endif /* SIZEOF_ID_T */ #if SIZEOF_UID_T == 8 # define SPRIuid PRIu64 #elif SIZEOF_UID_T == 4 # define SPRIuid PRIu32 #else # error Unexpected sizeof uid_t #endif /* SIZEOF_UID_T */ #if SIZEOF_GID_T == 8 # define SPRIgid PRIu64 #elif SIZEOF_GID_T == 4 # define SPRIgid PRIu32 #else # error Unexpected sizeof gid_t #endif /* SIZEOF_GID_T */ #endif /* __SSS_FORMAT_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/become_user.c0000644000000000000000000000007412703456111016525 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.767794012 sssd-1.13.4/src/util/become_user.c0000644002412700241270000001416312703456111020201 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module -- Utilities Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include errno_t become_user(uid_t uid, gid_t gid) { uid_t cuid; int ret; DEBUG(SSSDBG_FUNC_DATA, "Trying to become user [%"SPRIuid"][%"SPRIgid"].\n", uid, gid); /* skip call if we already are the requested user */ cuid = geteuid(); if (uid == cuid) { DEBUG(SSSDBG_FUNC_DATA, "Already user [%"SPRIuid"].\n", uid); return EOK; } /* drop supplmentary groups first */ ret = setgroups(0, NULL); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setgroups failed [%d][%s].\n", ret, strerror(ret)); return ret; } /* change gid so that root cannot be regained (changes saved gid too) */ ret = setresgid(gid, gid, gid); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setresgid failed [%d][%s].\n", ret, strerror(ret)); return ret; } /* change uid so that root cannot be regained (changes saved uid too) */ /* this call also takes care of dropping CAP_SETUID, so this is a PNR */ ret = setresuid(uid, uid, uid); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setresuid failed [%d][%s].\n", ret, strerror(ret)); return ret; } return EOK; } struct sss_creds { uid_t uid; gid_t gid; int num_gids; gid_t gids[]; }; errno_t restore_creds(struct sss_creds *saved_creds); /* This is a reversible version of become_user, and returns the saved * credentials so that creds can be switched back calling restore_creds */ errno_t switch_creds(TALLOC_CTX *mem_ctx, uid_t uid, gid_t gid, int num_gids, gid_t *gids, struct sss_creds **saved_creds) { struct sss_creds *ssc = NULL; int size; int ret; uid_t myuid; uid_t mygid; DEBUG(SSSDBG_FUNC_DATA, "Switch user to [%d][%d].\n", uid, gid); myuid = geteuid(); mygid = getegid(); if (saved_creds) { /* save current user credentials */ size = getgroups(0, NULL); if (size == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Getgroups failed! (%d, %s)\n", ret, strerror(ret)); goto done; } ssc = talloc_size(mem_ctx, (sizeof(struct sss_creds) + size * sizeof(gid_t))); if (!ssc) { DEBUG(SSSDBG_CRIT_FAILURE, "Allocation failed!\n"); ret = ENOMEM; goto done; } ssc->num_gids = size; size = getgroups(ssc->num_gids, ssc->gids); if (size == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Getgroups failed! (%d, %s)\n", ret, strerror(ret)); /* free ssc immediately otherwise the code will try to restore * wrong creds */ talloc_zfree(ssc); goto done; } /* we care only about effective ids */ ssc->uid = myuid; ssc->gid = mygid; } /* if we are regaining root set euid first so that we have CAP_SETUID back, * ane the other calls work too, otherwise call it last so that we can * change groups before we loose CAP_SETUID */ if (uid == 0) { ret = setresuid(0, 0, 0); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setresuid failed [%d][%s].\n", ret, strerror(ret)); goto done; } } /* TODO: use libcap-ng if we need to get/set capabilities too ? */ if (myuid == uid && mygid == gid) { DEBUG(SSSDBG_FUNC_DATA, "Already user [%"SPRIuid"].\n", uid); talloc_zfree(ssc); return EOK; } /* try to setgroups first should always work if CAP_SETUID is set, * otherwise it will always fail, failure is not critical though as * generally we only really care about uid and at mot primary gid */ ret = setgroups(num_gids, gids); if (ret == -1) { ret = errno; DEBUG(SSSDBG_TRACE_FUNC, "setgroups failed [%d][%s].\n", ret, strerror(ret)); } /* change gid now, (leaves saved gid to current, so we can restore) */ ret = setresgid(-1, gid, -1); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setresgid failed [%d][%s].\n", ret, strerror(ret)); goto done; } if (uid != 0) { /* change uid, (leaves saved uid to current, so we can restore) */ ret = setresuid(-1, uid, -1); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setresuid failed [%d][%s].\n", ret, strerror(ret)); goto done; } } ret = 0; done: if (ret) { /* attempt to restore creds first */ restore_creds(ssc); talloc_free(ssc); } else if (saved_creds) { *saved_creds = ssc; } return ret; } errno_t restore_creds(struct sss_creds *saved_creds) { if (saved_creds == NULL) { /* In case save_creds was saved with the UID already dropped */ return EOK; } return switch_creds(saved_creds, saved_creds->uid, saved_creds->gid, saved_creds->num_gids, saved_creds->gids, NULL); } sssd-1.13.4/src/util/PaxHeaders.16287/cert0000644000000000000000000000013212703463556014757 xustar0030 mtime=1460561774.704793798 30 atime=1460561776.118798593 30 ctime=1460561774.704793798 sssd-1.13.4/src/util/cert/0000755002412700241270000000000012703463556016510 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/util/cert/PaxHeaders.16287/cert_common.c0000644000000000000000000000007412703456111017477 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.704793798 sssd-1.13.4/src/util/cert/cert_common.c0000644002412700241270000000766212703456111021161 0ustar00jhrozekjhrozek00000000000000/* SSSD - certificate handling utils Copyright (C) Sumit Bose 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/cert.h" #include "util/crypto/sss_crypto.h" errno_t sss_cert_derb64_to_pem(TALLOC_CTX *mem_ctx, const char *derb64, char **pem, size_t *pem_size) { int ret; unsigned char *der; size_t der_size; if (derb64 == NULL) { return EINVAL; } der = sss_base64_decode(mem_ctx, derb64, &der_size); if (der == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n"); return EINVAL; } ret = sss_cert_der_to_pem(mem_ctx, der, der_size, pem, pem_size); talloc_free(der); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_cert_der_to_pem failed.\n"); } return ret; } errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem, char **derb64) { int ret; uint8_t *der; size_t der_size; ret = sss_cert_pem_to_der(mem_ctx, pem, &der, &der_size); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_cert_pem_to_der failed.\n"); return ret; } *derb64 = sss_base64_encode(mem_ctx, der, der_size); talloc_free(der); if (*derb64 == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_base64_encode failed.\n"); return EINVAL; } return EOK; } errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64, const char *attr_name, char **ldap_filter) { int ret; unsigned char *der; size_t der_size; char *val; if (derb64 == NULL || attr_name == NULL) { return EINVAL; } der = sss_base64_decode(mem_ctx, derb64, &der_size); if (der == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n"); return EINVAL; } ret = bin_to_ldap_filter_value(mem_ctx, der, der_size, &val); talloc_free(der); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "bin_to_ldap_filter_value failed.\n"); return ret; } *ldap_filter = talloc_asprintf(mem_ctx, "(%s=%s)", attr_name, val); talloc_free(val); if (*ldap_filter == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); return ENOMEM; } return EOK; } errno_t bin_to_ldap_filter_value(TALLOC_CTX *mem_ctx, const uint8_t *blob, size_t blob_size, char **_str) { int ret; size_t c; size_t len; char *str = NULL; char *p; if (blob == NULL || blob_size == 0 || _str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing input parameter.\n"); return EINVAL; } len = (blob_size * 3) + 1; str = talloc_size(mem_ctx, len); if (str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); return ENOMEM; } str[len - 1] = '\0'; p = str; for (c = 0; c < blob_size; c++) { ret = snprintf(p, 4, "\\%02x", blob[c]); if (ret != 3) { DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); ret = EIO; goto done; } p += 3; } ret = EOK; done: if (ret == EOK) { *_str = str; } else { talloc_free(str); } return ret; } sssd-1.13.4/src/util/cert/PaxHeaders.16287/nss0000644000000000000000000000013212703463556015562 xustar0030 mtime=1460561774.706793805 30 atime=1460561776.118798593 30 ctime=1460561774.706793805 sssd-1.13.4/src/util/cert/nss/0000755002412700241270000000000012703463556017313 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/util/cert/nss/PaxHeaders.16287/cert.c0000644000000000000000000000007412703456111016732 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.706793805 sssd-1.13.4/src/util/cert/nss/cert.c0000644002412700241270000002447412703456111020414 0ustar00jhrozekjhrozek00000000000000 /* SSSD - certificate handling utils - NSS version Copyright (C) Sumit Bose 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include "util/crypto/sss_crypto.h" #include "util/crypto/nss/nss_util.h" #include "util/cert.h" #define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----" #define NS_CERT_TRAILER "-----END CERTIFICATE-----" #define NS_CERT_HEADER_LEN ((sizeof NS_CERT_HEADER) - 1) #define NS_CERT_TRAILER_LEN ((sizeof NS_CERT_TRAILER) - 1) errno_t sss_cert_der_to_pem(TALLOC_CTX *mem_ctx, const uint8_t *der_blob, size_t der_size, char **pem, size_t *pem_size) { CERTCertDBHandle *handle; CERTCertificate *cert = NULL; SECItem der_item; char *ascii_crlf = NULL; size_t ascii_crlf_len; char *ascii_lf = NULL; char *pem_cert_str = NULL; int ret; size_t c; size_t d; /* initialize NSS if needed */ ret = nspr_nss_init(); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "nspr_nss_init failed.\n"); return ret; } handle = CERT_GetDefaultCertDB(); der_item.len = der_size; der_item.data = discard_const(der_blob); cert = CERT_NewTempCertificate(handle, &der_item, NULL, PR_FALSE, PR_TRUE); if (cert == NULL) { DEBUG(SSSDBG_OP_FAILURE, "CERT_NewTempCertificate failed.\n"); return EINVAL; } ascii_crlf = BTOA_DataToAscii(cert->derCert.data, cert->derCert.len); if (ascii_crlf == NULL) { DEBUG(SSSDBG_OP_FAILURE, "BTOA_DataToAscii failed.\n"); ret = EIO; goto done; } ascii_crlf_len = strlen(ascii_crlf) + 1; ascii_lf = talloc_size(mem_ctx, ascii_crlf_len * sizeof(char)); if (ascii_lf == NULL) { DEBUG(SSSDBG_OP_FAILURE, "malloc failed.\n"); ret = ENOMEM; goto done; } d = 0; for (c = 0; c < ascii_crlf_len; c++) { if (ascii_crlf[c] != '\r') { ascii_lf[d++] = ascii_crlf[c]; } } pem_cert_str = talloc_asprintf(mem_ctx, "%s\n%s\n%s\n", NS_CERT_HEADER, ascii_lf, NS_CERT_TRAILER); if (pem_cert_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } if (pem_size != NULL) { *pem_size = strlen(pem_cert_str); } if (pem != NULL) { *pem = pem_cert_str; pem_cert_str = NULL; } ret = EOK; done: talloc_free(pem_cert_str); talloc_free(ascii_lf); PORT_Free(ascii_crlf); CERT_DestroyCertificate(cert); return ret; } errno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem, uint8_t **_der_blob, size_t *_der_size) { const char *ps; const char *pe; size_t pem_len; uint8_t *der_blob = NULL; unsigned int der_size; /* unsigned int to match 2nd parameter of ATOB_AsciiToData */ CERTCertDBHandle *handle; CERTCertificate *cert = NULL; SECItem der_item; int ret; char *b64 = NULL; /* initialize NSS if needed */ ret = nspr_nss_init(); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "nspr_nss_init failed.\n"); return ret; } if (pem == NULL || *pem == '\0') { return EINVAL; } pem_len = strlen(pem); if (pem_len <= NS_CERT_HEADER_LEN + NS_CERT_TRAILER_LEN) { DEBUG(SSSDBG_CRIT_FAILURE, "PEM data too short.\n"); return EINVAL; } if (strncmp(pem, NS_CERT_HEADER, NS_CERT_HEADER_LEN) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrong PEM header.\n"); return EINVAL; } if (pem[NS_CERT_HEADER_LEN] != '\n') { DEBUG(SSSDBG_CRIT_FAILURE, "Missing newline in PEM data.\n"); return EINVAL; } pe = pem + pem_len - NS_CERT_TRAILER_LEN; if (pem[pem_len - 1] == '\n') { pe--; } if (strncmp(pe, NS_CERT_TRAILER, NS_CERT_TRAILER_LEN) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrong PEM trailer.\n"); return EINVAL; } ps = pem + NS_CERT_HEADER_LEN + 1; b64 = talloc_strndup(mem_ctx, ps, pe - ps); if(b64 == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); ret = ENOMEM; goto done; } der_blob = ATOB_AsciiToData(b64, &der_size); if (der_blob == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ATOB_AsciiToData failed.\n"); return EIO; } handle = CERT_GetDefaultCertDB(); der_item.len = der_size; der_item.data = der_blob; cert = CERT_NewTempCertificate(handle, &der_item, NULL, PR_FALSE, PR_TRUE); if (cert == NULL) { DEBUG(SSSDBG_OP_FAILURE, "CERT_NewTempCertificate failed.\n"); ret = EINVAL; goto done; } if (_der_blob != NULL) { *_der_blob = talloc_memdup(mem_ctx, cert->derCert.data, cert->derCert.len); if (*_der_blob == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_memdup failed.\n"); ret = ENOMEM; goto done; } } if (_der_size != NULL) { *_der_size = cert->derCert.len; } done: PORT_Free(der_blob); talloc_free(b64); CERT_DestroyCertificate(cert); return ret; } #define SSH_RSA_HEADER "ssh-rsa" #define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1) errno_t cert_to_ssh_key(TALLOC_CTX *mem_ctx, const char *ca_db, const uint8_t *der_blob, size_t der_size, bool do_ocsp, uint8_t **key, size_t *key_size) { CERTCertDBHandle *handle; CERTCertificate *cert = NULL; SECItem der_item; SECKEYPublicKey *cert_pub_key = NULL; int ret; size_t size; uint8_t *buf = NULL; size_t c; NSSInitContext *nss_ctx; NSSInitParameters parameters = { 0 }; parameters.length = sizeof (parameters); SECStatus rv; if (der_blob == NULL || der_size == 0) { return EINVAL; } /* initialize NSS with context, we might have already called * NSS_NoDB_Init() but for validation we need to have access to a DB with * the trusted issuer cert. Only NSS_InitContext will really open the DB * in this case. I'm not sure about how long validation might need e.g. if * CRLs or OSCP is enabled, maybe it would be better to run validation in * p11_child ? */ nss_ctx = NSS_InitContext(ca_db, "", "", SECMOD_DB, ¶meters, NSS_INIT_READONLY); if (nss_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "NSS_InitContext failed [%d].\n", PR_GetError()); return EIO; } handle = CERT_GetDefaultCertDB(); if (do_ocsp) { rv = CERT_EnableOCSPChecking(handle); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "CERT_EnableOCSPChecking failed: [%d].\n", PR_GetError()); return EIO; } } der_item.len = der_size; der_item.data = discard_const(der_blob); cert = CERT_NewTempCertificate(handle, &der_item, NULL, PR_FALSE, PR_TRUE); if (cert == NULL) { DEBUG(SSSDBG_OP_FAILURE, "CERT_NewTempCertificate failed.\n"); ret = EINVAL; goto done; } rv = CERT_VerifyCertificateNow(handle, cert, PR_TRUE, certificateUsageSSLClient, NULL, NULL); if (rv != SECSuccess) { DEBUG(SSSDBG_CRIT_FAILURE, "CERT_VerifyCertificateNow failed [%d].\n", PR_GetError()); ret = EACCES; goto done; } cert_pub_key = CERT_ExtractPublicKey(cert); if (cert_pub_key == NULL) { DEBUG(SSSDBG_OP_FAILURE, "CERT_ExtractPublicKey failed.\n"); ret = EIO; goto done; } if (cert_pub_key->keyType != rsaKey) { DEBUG(SSSDBG_CRIT_FAILURE, "Expected RSA public key, found unsupported [%d].\n", cert_pub_key->keyType); ret = EINVAL; goto done; } size = SSH_RSA_HEADER_LEN + 3 * sizeof(uint32_t) + cert_pub_key->u.rsa.modulus.len + cert_pub_key->u.rsa.publicExponent.len + 1; /* see comment about missing 00 below */ buf = talloc_size(mem_ctx, size); if (buf == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); ret = ENOMEM; goto done; } c = 0; SAFEALIGN_SET_UINT32(buf, htobe32(SSH_RSA_HEADER_LEN), &c); safealign_memcpy(&buf[c], SSH_RSA_HEADER, SSH_RSA_HEADER_LEN, &c); SAFEALIGN_SET_UINT32(&buf[c], htobe32(cert_pub_key->u.rsa.publicExponent.len), &c); safealign_memcpy(&buf[c], cert_pub_key->u.rsa.publicExponent.data, cert_pub_key->u.rsa.publicExponent.len, &c); /* Looks like nss drops the leading 00 which afaik is added to make sure * the bigint is handled as positive number */ /* TODO: make a better check if 00 must be added or not, e.g. ... & 0x80) */ SAFEALIGN_SET_UINT32(&buf[c], htobe32(cert_pub_key->u.rsa.modulus.len + 1 ), &c); SAFEALIGN_SETMEM_VALUE(&buf[c], '\0', unsigned char, &c); safealign_memcpy(&buf[c], cert_pub_key->u.rsa.modulus.data, cert_pub_key->u.rsa.modulus.len, &c); *key = buf; *key_size = size; ret = EOK; done: if (ret != EOK) { talloc_free(buf); } SECKEY_DestroyPublicKey(cert_pub_key); CERT_DestroyCertificate(cert); rv = NSS_ShutdownContext(nss_ctx); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d].\n", PR_GetError()); } return ret; } sssd-1.13.4/src/util/cert/PaxHeaders.16287/libcrypto0000644000000000000000000000013212703463556016766 xustar0030 mtime=1460561774.705793802 30 atime=1460561776.118798593 30 ctime=1460561774.705793802 sssd-1.13.4/src/util/cert/libcrypto/0000755002412700241270000000000012703463556020517 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/util/cert/libcrypto/PaxHeaders.16287/cert.c0000644000000000000000000000007412703456111020136 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.705793802 sssd-1.13.4/src/util/cert/libcrypto/cert.c0000644002412700241270000001512012703456111021604 0ustar00jhrozekjhrozek00000000000000/* SSSD - certificate handling utils - openssl version Copyright (C) Sumit Bose 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" errno_t sss_cert_der_to_pem(TALLOC_CTX *mem_ctx, const uint8_t *der_blob, size_t der_size, char **pem, size_t *pem_size) { X509 *x509 = NULL; BIO *bio_mem = NULL; const unsigned char *d; int ret; long p_size; char *p; if (der_blob == NULL || der_size == 0) { return EINVAL; } d = (const unsigned char *) der_blob; x509 = d2i_X509(NULL, &d, (int) der_size); if (x509 == NULL) { DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n"); return EINVAL; } bio_mem = BIO_new(BIO_s_mem()); if (bio_mem == NULL) { DEBUG(SSSDBG_OP_FAILURE, "BIO_new failed.\n"); ret = ENOMEM; goto done; } ret = PEM_write_bio_X509(bio_mem, x509); if (ret != 1) { DEBUG(SSSDBG_OP_FAILURE, "PEM_write_bio_X509 failed.\n"); ret = EIO; goto done; } p_size = BIO_get_mem_data(bio_mem, &p); if (p_size == 0) { DEBUG(SSSDBG_OP_FAILURE, "Unexpected PEM size [%ld].\n", p_size); ret = EINVAL; goto done; } if (pem != NULL) { *pem = talloc_strndup(mem_ctx, p, p_size); if (*pem == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_memdup failed.\n"); ret = ENOMEM; goto done; } } if (pem_size != NULL) { *pem_size = p_size; } ret = EOK; done: X509_free(x509); BIO_free_all(bio_mem); return ret; } errno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem, uint8_t **_der_blob, size_t *_der_size) { X509 *x509 = NULL; BIO *bio_mem = NULL; int ret; unsigned char *buf; int buf_size; uint8_t *der_blob; size_t der_size; if (pem == NULL) { return EINVAL; } bio_mem = BIO_new(BIO_s_mem()); if (bio_mem == NULL) { DEBUG(SSSDBG_OP_FAILURE, "BIO_new failed.\n"); ret = ENOMEM; goto done; } ret = BIO_puts(bio_mem, pem); if (ret <= 0) { DEBUG(SSSDBG_OP_FAILURE, "BIO_puts failed.\n"); ret = EIO; goto done; } x509 = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL); if (x509 == NULL) { DEBUG(SSSDBG_OP_FAILURE, "PEM_read_bio_X509 failed.\n"); ret = EIO; goto done; } buf_size = i2d_X509(x509, NULL); if (buf_size <= 0) { DEBUG(SSSDBG_OP_FAILURE, "i2d_X509 failed.\n"); ret = EIO; goto done; } if (_der_blob != NULL) { buf = talloc_size(mem_ctx, buf_size); if (buf == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); ret = ENOMEM; goto done; } der_blob = buf; der_size = i2d_X509(x509, &buf); if (der_size != buf_size) { talloc_free(der_blob); DEBUG(SSSDBG_CRIT_FAILURE, "i2d_X509 size mismatch between two calls.\n"); ret = EIO; goto done; } *_der_blob = der_blob; } if (_der_size != NULL) { *_der_size = buf_size; } ret = EOK; done: X509_free(x509); BIO_free_all(bio_mem); return ret; } #define SSH_RSA_HEADER "ssh-rsa" #define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1) errno_t cert_to_ssh_key(TALLOC_CTX *mem_ctx, const char *ca_db, const uint8_t *der_blob, size_t der_size, bool do_ocsp, uint8_t **key, size_t *key_size) { int ret; size_t size; const unsigned char *d; uint8_t *buf = NULL; size_t c; X509 *cert = NULL; EVP_PKEY *cert_pub_key = NULL; int modulus_len; unsigned char modulus[OPENSSL_RSA_MAX_MODULUS_BITS/8]; int exponent_len; unsigned char exponent[OPENSSL_RSA_MAX_PUBEXP_BITS/8]; if (der_blob == NULL || der_size == 0) { return EINVAL; } d = (const unsigned char *) der_blob; cert = d2i_X509(NULL, &d, (int) der_size); if (cert == NULL) { DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n"); return EINVAL; } /* TODO: verify certificate !!!!! */ cert_pub_key = X509_get_pubkey(cert); if (cert_pub_key == NULL) { DEBUG(SSSDBG_OP_FAILURE, "X509_get_pubkey failed.\n"); ret = EIO; goto done; } if (cert_pub_key->type != EVP_PKEY_RSA) { DEBUG(SSSDBG_CRIT_FAILURE, "Expected RSA public key, found unsupported [%d].\n", cert_pub_key->type); ret = EINVAL; goto done; } modulus_len = BN_bn2bin(cert_pub_key->pkey.rsa->n, modulus); exponent_len = BN_bn2bin(cert_pub_key->pkey.rsa->e, exponent); size = SSH_RSA_HEADER_LEN + 3 * sizeof(uint32_t) + modulus_len + exponent_len + 1; /* see comment about missing 00 below */ buf = talloc_size(mem_ctx, size); if (buf == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); ret = ENOMEM; goto done; } c = 0; SAFEALIGN_SET_UINT32(buf, htobe32(SSH_RSA_HEADER_LEN), &c); safealign_memcpy(&buf[c], SSH_RSA_HEADER, SSH_RSA_HEADER_LEN, &c); SAFEALIGN_SET_UINT32(&buf[c], htobe32(exponent_len), &c); safealign_memcpy(&buf[c], exponent, exponent_len, &c); /* Adding missing 00 which afaik is added to make sure * the bigint is handled as positive number */ /* TODO: make a better check if 00 must be added or not, e.g. ... & 0x80) */ SAFEALIGN_SET_UINT32(&buf[c], htobe32(modulus_len + 1), &c); SAFEALIGN_SETMEM_VALUE(&buf[c], '\0', unsigned char, &c); safealign_memcpy(&buf[c], modulus, modulus_len, &c); *key = buf; *key_size = size; ret = EOK; done: if (ret != EOK) { talloc_free(buf); } EVP_PKEY_free(cert_pub_key); X509_free(cert); return ret; } sssd-1.13.4/src/util/PaxHeaders.16287/io.c0000644000000000000000000000007412703456111014644 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.680793717 sssd-1.13.4/src/util/io.c0000644002412700241270000000406412703456111016317 0ustar00jhrozekjhrozek00000000000000/* SSSD io.c Authors: Lukas Slebodnik Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include "util/io.h" /* CAUTION: * This file have to be minimalist and cannot include DEBUG macros * or header file util.h. */ int sss_open_cloexec(const char *pathname, int flags, int *ret) { int fd; int oflags; oflags = flags; #ifdef O_CLOEXEC oflags |= O_CLOEXEC; #endif errno = 0; fd = open(pathname, oflags); if (fd == -1) { if (ret) { *ret = errno; } return -1; } #ifndef O_CLOEXEC int v; v = fcntl(fd, F_GETFD, 0); /* we ignore an error, it's not fatal and there is nothing we * can do about it anyways */ (void)fcntl(fd, F_SETFD, v | FD_CLOEXEC); #endif return fd; } int sss_openat_cloexec(int dir_fd, const char *pathname, int flags, int *ret) { int fd; int oflags; oflags = flags; #ifdef O_CLOEXEC oflags |= O_CLOEXEC; #endif errno = 0; fd = openat(dir_fd, pathname, oflags); if (fd == -1) { if (ret) { *ret = errno; } return -1; } #ifndef O_CLOEXEC int v; v = fcntl(fd, F_GETFD, 0); /* we ignore an error, it's not fatal and there is nothing we * can do about it anyways */ (void)fcntl(fd, F_SETFD, v | FD_CLOEXEC); #endif return fd; } sssd-1.13.4/src/util/PaxHeaders.16287/debug.c0000644000000000000000000000007412703456111015323 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.717793842 sssd-1.13.4/src/util/debug.c0000644002412700241270000002606412703456111017002 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Stephen Gallagher Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #ifdef WITH_JOURNALD #include #endif #include "util/util.h" const char *debug_prg_name = "sssd"; int debug_level = SSSDBG_UNRESOLVED; int debug_timestamps = SSSDBG_TIMESTAMP_UNRESOLVED; int debug_microseconds = SSSDBG_MICROSECONDS_UNRESOLVED; int debug_to_file = 0; int debug_to_stderr = 0; const char *debug_log_file = "sssd"; FILE *debug_file = NULL; errno_t set_debug_file_from_fd(const int fd) { FILE *dummy; errno_t ret; errno = 0; dummy = fdopen(fd, "a"); if (dummy == NULL) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fdopen failed [%d][%s].\n", ret, strerror(ret)); sss_log(SSS_LOG_ERR, "Could not open debug file descriptor [%d]. " "Debug messages will not be written to the file " "for this child process [%s][%s]\n", fd, debug_prg_name, strerror(ret)); return ret; } debug_file = dummy; return EOK; } int get_fd_from_debug_file(void) { if (debug_file == NULL) { return STDERR_FILENO; } return fileno(debug_file); } int debug_convert_old_level(int old_level) { if ((old_level != 0) && !(old_level & 0x000F)) return old_level; int new_level = SSSDBG_FATAL_FAILURE; if (old_level <= 0) return new_level; if (old_level >= 1) new_level |= SSSDBG_CRIT_FAILURE; if (old_level >= 2) new_level |= SSSDBG_OP_FAILURE; if (old_level >= 3) new_level |= SSSDBG_MINOR_FAILURE; if (old_level >= 4) new_level |= SSSDBG_CONF_SETTINGS; if (old_level >= 5) new_level |= SSSDBG_FUNC_DATA; if (old_level >= 6) new_level |= SSSDBG_TRACE_FUNC; if (old_level >= 7) new_level |= SSSDBG_TRACE_LIBS; if (old_level >= 8) new_level |= SSSDBG_TRACE_INTERNAL; if (old_level >= 9) new_level |= SSSDBG_TRACE_ALL | SSSDBG_BE_FO; return new_level; } static void debug_fflush(void) { fflush(debug_file ? debug_file : stderr); } static void debug_vprintf(const char *format, va_list ap) { vfprintf(debug_file ? debug_file : stderr, format, ap); } static void debug_printf(const char *format, ...) SSS_ATTRIBUTE_PRINTF(1, 2); static void debug_printf(const char *format, ...) { va_list ap; va_start(ap, format); debug_vprintf(format, ap); va_end(ap); } #ifdef WITH_JOURNALD errno_t journal_send(const char *file, long line, const char *function, int level, const char *format, va_list ap) { errno_t ret; int res; char *message = NULL; char *code_file = NULL; char *code_line = NULL; const char *domain; /* First, evaluate the message to be sent */ ret = vasprintf(&message, format, ap); if (ret == -1) { /* ENOMEM, just return */ return ENOMEM; } res = asprintf(&code_file, "CODE_FILE=%s", file); if (res == -1) { ret = ENOMEM; goto journal_done; } res = asprintf(&code_line, "CODE_LINE=%ld", line); if (res == -1) { ret = ENOMEM; goto journal_done; } /* If this log message was sent from a provider, * track the domain. */ domain = getenv(SSS_DOM_ENV); if (domain == NULL) { domain = ""; } /* Send the log message to journald, specifying the * source code location and other tracking data. */ res = sd_journal_send_with_location( code_file, code_line, function, "MESSAGE=%s", message, "PRIORITY=%i", LOG_DEBUG, "SSSD_DOMAIN=%s", domain, "SSSD_PRG_NAME=%s", debug_prg_name, "SSSD_DEBUG_LEVEL=%x", level, NULL); ret = -res; journal_done: free(code_line); free(code_file); free(message); return ret; } #endif /* WiTH_JOURNALD */ void sss_vdebug_fn(const char *file, long line, const char *function, int level, int flags, const char *format, va_list ap) { struct timeval tv; struct tm *tm; char datetime[20]; int year; #ifdef WITH_JOURNALD errno_t ret; va_list ap_fallback; if (!debug_file && !debug_to_stderr) { /* If we are not outputting logs to files, we should be sending them * to journald. * NOTE: on modern systems, this is where stdout/stderr will end up * from system services anyway. The only difference here is that we * can also provide extra structuring data to make it more easily * searchable. */ va_copy(ap_fallback, ap); ret = journal_send(file, line, function, level, format, ap); if (ret != EOK) { /* Emergency fallback, send to STDERR */ debug_vprintf(format, ap_fallback); debug_fflush(); } va_end(ap_fallback); return; } #endif if (debug_timestamps) { gettimeofday(&tv, NULL); tm = localtime(&tv.tv_sec); year = tm->tm_year + 1900; /* get date time without year */ memcpy(datetime, ctime(&tv.tv_sec), 19); datetime[19] = '\0'; if (debug_microseconds) { debug_printf("(%s:%.6ld %d) [%s] [%s] (%#.4x): ", datetime, tv.tv_usec, year, debug_prg_name, function, level); } else { debug_printf("(%s %d) [%s] [%s] (%#.4x): ", datetime, year, debug_prg_name, function, level); } } else { debug_printf("[%s] [%s] (%#.4x): ", debug_prg_name, function, level); } debug_vprintf(format, ap); if (flags & APPEND_LINE_FEED) { debug_printf("\n"); } debug_fflush(); } void sss_debug_fn(const char *file, long line, const char *function, int level, const char *format, ...) { va_list ap; va_start(ap, format); sss_vdebug_fn(file, line, function, level, 0, format, ap); va_end(ap); } void ldb_debug_messages(void *context, enum ldb_debug_level level, const char *fmt, va_list ap) { int loglevel = SSSDBG_UNRESOLVED; switch(level) { case LDB_DEBUG_FATAL: loglevel = SSSDBG_FATAL_FAILURE; break; case LDB_DEBUG_ERROR: loglevel = SSSDBG_CRIT_FAILURE; break; case LDB_DEBUG_WARNING: loglevel = SSSDBG_TRACE_FUNC; break; case LDB_DEBUG_TRACE: loglevel = SSSDBG_TRACE_ALL; break; } if (DEBUG_IS_SET(loglevel)) { sss_vdebug_fn(__FILE__, __LINE__, "ldb", loglevel, APPEND_LINE_FEED, fmt, ap); } } /* In cases SSSD used to run as the root user, but runs as the SSSD user now, * we need to chown the log files */ int chown_debug_file(const char *filename, uid_t uid, gid_t gid) { char *logpath; const char *log_file; errno_t ret; if (filename == NULL) { log_file = debug_log_file; } else { log_file = filename; } ret = asprintf(&logpath, "%s/%s.log", LOG_PATH, log_file); if (ret == -1) { return ENOMEM; } ret = chown(logpath, uid, gid); free(logpath); if (ret != 0) { ret = errno; if (ret == ENOENT) { /* Log does not exist. We might log to journald * or starting for first time. * It's not a failure. */ return EOK; } DEBUG(SSSDBG_FATAL_FAILURE, "chown failed for [%s]: [%d]\n", log_file, ret); return ret; } return EOK; } int open_debug_file_ex(const char *filename, FILE **filep, bool want_cloexec) { FILE *f = NULL; char *logpath; const char *log_file; mode_t old_umask; int ret; int debug_fd; int flags; if (filename == NULL) { log_file = debug_log_file; } else { log_file = filename; } ret = asprintf(&logpath, "%s/%s.log", LOG_PATH, log_file); if (ret == -1) { return ENOMEM; } if (debug_file && !filep) fclose(debug_file); old_umask = umask(SSS_DFL_UMASK); errno = 0; f = fopen(logpath, "a"); if (f == NULL) { sss_log(SSS_LOG_EMERG, "Could not open file [%s]. Error: [%d][%s]\n", logpath, errno, strerror(errno)); free(logpath); return EIO; } umask(old_umask); debug_fd = fileno(f); if (debug_fd == -1) { fclose(f); free(logpath); return EIO; } if(want_cloexec) { flags = fcntl(debug_fd, F_GETFD, 0); (void) fcntl(debug_fd, F_SETFD, flags | FD_CLOEXEC); } if (filep == NULL) { debug_file = f; } else { *filep = f; } free(logpath); return EOK; } int open_debug_file(void) { return open_debug_file_ex(NULL, NULL, true); } int rotate_debug_files(void) { int ret; errno_t error; if (!debug_to_file) return EOK; do { error = 0; ret = fclose(debug_file); if (ret != 0) { error = errno; } /* Check for EINTR, which means we should retry * because the system call was interrupted by a * signal */ } while (error == EINTR); if (error != 0) { /* Even if we were unable to close the debug log, we need to make * sure that we open up a new one. Log rotation will remove the * current file, so all debug messages will be disappearing. * * We should write an error to the syslog warning of the resource * leak and then proceed with opening the new file. */ sss_log(SSS_LOG_ALERT, "Could not close debug file [%s]. [%d][%s]\n", debug_log_file, error, strerror(error)); sss_log(SSS_LOG_ALERT, "Attempting to open new file anyway. " "Be aware that this is a resource leak\n"); } debug_file = NULL; return open_debug_file(); } void talloc_log_fn(const char *message) { DEBUG(SSSDBG_FATAL_FAILURE, "%s\n", message); } sssd-1.13.4/src/util/PaxHeaders.16287/mmap_cache.h0000644000000000000000000000007412703456111016317 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.434792883 sssd-1.13.4/src/util/mmap_cache.h0000644002412700241270000001430112703456111017765 0ustar00jhrozekjhrozek00000000000000/* SSSD Mmap Cache Common header Copyright (C) Simo Sorce 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _MMAP_CACHE_H_ #define _MMAP_CACHE_H_ #include "util/murmurhash3.h" /* NOTE: all the code here assumes that writing a uint32_t nto mmapped * memory is an atomic operation and can't be split in multiple * non-atomic operations */ typedef uint32_t rel_ptr_t; /* align macros */ #define MC_8 sizeof(uint8_t) #define MC_32 sizeof(uint32_t) #define MC_64 sizeof(uint64_t) #define MC_ALIGN32(size) ( ((size) + MC_32 -1) & (~(MC_32 -1)) ) #define MC_ALIGN64(size) ( ((size) + MC_64 -1) & (~(MC_64 -1)) ) #define MC_HEADER_SIZE MC_ALIGN64(sizeof(struct sss_mc_header)) #define MC_HT_SIZE(elems) ( (elems) * MC_32 ) #define MC_HT_ELEMS(size) ( (size) / MC_32 ) #define MC_DT_SIZE(elems, payload) ( (elems) * (payload) ) #define MC_FT_SIZE(elems) ( (elems) / 8 ) /* ^^ 8 bits per byte so we need just elems/8 bytes to represent all blocks */ #define MC_PTR_ADD(ptr, bytes) (void *)((uint8_t *)(ptr) + (bytes)) #define MC_PTR_DIFF(ptr, base) ((uint8_t *)(ptr) - (uint8_t *)(base)) #define MC_INVALID_VAL64 ((uint64_t)-1) #define MC_INVALID_VAL32 ((uint32_t)-1) #define MC_INVALID_VAL8 ((uint8_t)-1) #define MC_INVALID_VAL MC_INVALID_VAL32 /* * 40 seem a good compromise for slot size * 4 blocks are enough for the average passwd entry of 42 bytes * passwd records have 84 bytes of overhead, 160 - 82 = 78 bytes * 3 blocks can contain a very minimal entry, 120 - 82 = 38 bytes * * 3 blocks are enough for groups w/o users (private user groups) * group records have 68 bytes of overhead, 120 - 66 = 54 bytes */ #define MC_SLOT_SIZE 40 #define MC_SIZE_TO_SLOTS(len) (((len) + (MC_SLOT_SIZE - 1)) / MC_SLOT_SIZE) #define MC_PTR_TO_SLOT(base, ptr) (MC_PTR_DIFF(ptr, base) / MC_SLOT_SIZE) #define MC_SLOT_TO_PTR(base, slot, type) \ (type *)((base) + ((slot) * MC_SLOT_SIZE)) #define MC_SLOT_WITHIN_BOUNDS(slot, dt_size) \ ((slot) < ((dt_size) / MC_SLOT_SIZE)) #define MC_VALID_BARRIER(val) (((val) & 0xff000000) == 0xf0000000) #define MC_CHECK_RECORD_LENGTH(mc_ctx, rec) \ ((rec)->len >= MC_HEADER_SIZE && (rec)->len != MC_INVALID_VAL32 \ && ((rec)->len <= ((mc_ctx)->dt_size \ - MC_PTR_DIFF(rec, (mc_ctx)->data_table)))) #define SSS_MC_MAJOR_VNO 1 #define SSS_MC_MINOR_VNO 1 #define SSS_MC_HEADER_UNINIT 0 /* after ftruncate or before reset */ #define SSS_MC_HEADER_ALIVE 1 /* current and in use */ #define SSS_MC_HEADER_RECYCLED 2 /* file was recycled, reopen asap */ #pragma pack(1) struct sss_mc_header { uint32_t b1; /* barrier 1 */ uint32_t major_vno; /* major version number */ uint32_t minor_vno; /* minor version number */ uint32_t status; /* database status */ uint32_t seed; /* random seed used to avoid collision attacks */ uint32_t dt_size; /* data table size */ uint32_t ft_size; /* free table size */ uint32_t ht_size; /* hash table size */ rel_ptr_t data_table; /* data table pointer relative to mmap base */ rel_ptr_t free_table; /* free table pointer relative to mmap base */ rel_ptr_t hash_table; /* hash table pointer relative to mmap base */ rel_ptr_t reserved; /* reserved for future changes */ uint32_t b2; /* barrier 2 */ }; struct sss_mc_rec { uint32_t b1; /* barrier 1 */ uint32_t len; /* total record length including record data */ uint64_t expire; /* record expiration time (cast to time_t) */ rel_ptr_t next1; /* ptr of next record rel to data_table */ /* next1 is related to hash1 */ rel_ptr_t next2; /* ptr of next record rel to data_table */ /* next2 is related to hash2 */ uint32_t hash1; /* val of first hash (usually name of record) */ uint32_t hash2; /* val of second hash (usually id of record) */ uint32_t padding; /* padding & reserved for future changes */ uint32_t b2; /* barrier 2 - 32 bytes mark, fits a slot */ char data[0]; }; struct sss_mc_pwd_data { rel_ptr_t name; /* ptr to name string, rel. to struct base addr */ uint32_t uid; uint32_t gid; uint32_t strs_len; /* length of strs */ char strs[0]; /* concatenation of all passwd strings, each * string is zero terminated ordered as follows: * name, passwd, gecos, dir, shell */ }; struct sss_mc_grp_data { rel_ptr_t name; /* ptr to name string, rel. to struct base addr */ uint32_t gid; uint32_t members; /* number of members in strs */ uint32_t strs_len; /* length of strs */ char strs[0]; /* concatenation of all group strings, each * string is zero terminated ordered as follows: * name, passwd, member1, member2, ... */ }; struct sss_mc_initgr_data { rel_ptr_t unique_name; /* ptr to unique name string, rel. to struct base addr */ rel_ptr_t name; /* ptr to raw name string, rel. to struct base addr */ rel_ptr_t strs; /* ptr to concatenation of all strings */ uint32_t strs_len; /* length of strs */ uint32_t data_len; /* all initgroups data len */ uint32_t num_groups; /* number of groups */ uint32_t gids[0]; /* array of all groups * string with name and unique_name is stored * after gids */ }; #pragma pack() #endif /* _MMAP_CACHE_H_ */ sssd-1.13.4/src/util/PaxHeaders.16287/util_errors.c0000644000000000000000000000007412703456111016606 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.877794385 sssd-1.13.4/src/util/util_errors.c0000644002412700241270000001127612703456111020264 0ustar00jhrozekjhrozek00000000000000/* Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Authors: Simo Sorce */ #include "util/util.h" struct err_string { const char *msg; }; struct err_string error_to_str[] = { { "Invalid Error" }, /* ERR_INVALID */ { "Internal Error" }, /* ERR_INTERNAL */ { "Account Unknown" }, /* ERR_ACCOUNT_UNKNOWN */ { "Invalid credential type" }, /* ERR_INVALID_CRED_TYPE */ { "No credentials available" }, /* ERR_NO_CREDS */ { "Credentials are expired" }, /* ERR_CREDS_EXPIRED */ { "Credentials are expired, old ccache was removed" }, /* ERR_CREDS_EXPIRED_CCACHE */ { "Failure setting user credentials"}, /* ERR_CREDS_INVALID */ { "No cached credentials available" }, /* ERR_NO_CACHED_CREDS */ { "Cached credentials are expired" }, /* ERR_CACHED_CREDS_EXPIRED */ { "Authentication Denied" }, /* ERR_AUTH_DENIED */ { "Authentication Failed" }, /* ERR_AUTH_FAILED */ { "Password Change Denied" }, /* ERR_CHPASS_DENIED */ { "Password Change Failed" }, /* ERR_CHPASS_FAILED */ { "Network I/O Error" }, /* ERR_NETWORK_IO */ { "Account Expired" }, /* ERR_ACCOUNT_EXPIRED */ { "Password Expired" }, /* ERR_PASSWORD_EXPIRED */ { "Password Expired (reject access)" }, /* ERR_PASSWORD_EXPIRED_REJECT */ { "Password Expired (warn user)" }, /* ERR_PASSWORD_EXPIRED_WARN */ { "Password Expired (ask for new password)" }, /* ERR_PASSWORD_EXPIRED_RENEW */ { "Host Access Denied" }, /* ERR_ACCESS_DENIED */ { "SRV record not found" }, /* ERR_SRV_NOT_FOUND */ { "SRV lookup error" }, /* ERR_SRV_LOOKUP_ERROR */ { "SRV lookup did not return any new server" }, /* ERR_SRV_DUPLICATES */ { "Dynamic DNS update failed" }, /* ERR_DYNDNS_FAILED */ { "Dynamic DNS update timed out" }, /* ERR_DYNDNS_TIMEOUT */ { "Dynamic DNS update not possible while offline" }, /* ERR_DYNDNS_OFFLINE */ { "Cannot parse input" }, /* ERR_INPUT_PARSE */ { "Entry not found" }, /* ERR_NOT_FOUND */ { "Domain not found" }, /* ERR_DOMAIN_NOT_FOUND */ { "Missing configuration file" }, /* ERR_MISSING_CONF */ { "Malformed search filter" }, /* ERR_INVALID_FILTER, */ { "No POSIX attributes detected" }, /* ERR_NO_POSIX */ { "Extra attribute is a duplicate" }, /* ERR_DUP_EXTRA_ATTR */ { "Malformed extra attribute" }, /* ERR_INVALID_EXTRA_ATTR */ { "Cannot get bus message sender" }, /* ERR_SBUS_GET_SENDER_ERROR */ { "Bus message has no sender" }, /* ERR_SBUS_NO_SENDER */ { "Invalid SBUS path provided" }, /* ERR_SBUS_INVALID_PATH */ { "User/Group SIDs not found" }, /* ERR_NO_SIDS */ { "Bus method not supported" }, /* ERR_SBUS_NOSUP */ { "Cannot connect to system bus" }, /* ERR_NO_SYSBUS */ { "LDAP search returned a referral" }, /* ERR_REFERRAL */ { "Error setting SELinux user context" }, /* ERR_SELINUX_CONTEXT */ { "Username format not allowed by re_expression" }, /* ERR_REGEX_NOMATCH */ { "Time specification not supported" }, /* ERR_TIMESPEC_NOT_SUPPORTED */ { "Invalid SSSD configuration detected" }, /* ERR_INVALID_CONFIG */ { "Malformed cache entry" }, /* ERR_MALFORMED_ENTRY */ { "Unexpected cache entry type" }, /* ERR_UNEXPECTED_ENTRY_TYPE */ { "Failed to resolve one of user groups" }, /* ERR_SIMPLE_GROUPS_MISSING */ { "Home directory is NULL" }, /* ERR_HOMEDIR_IS_NULL */ { "Unsupported trust direction" }, /* ERR_TRUST_NOT_SUPPORTED */ { "Retrieving keytab failed" }, /* ERR_IPA_GETKEYTAB_FAILED */ { "Trusted forest root unknown" }, /* ERR_TRUST_FOREST_UNKNOWN */ { "p11_child failed" }, /* ERR_P11_CHILD */ { "Address family not supported" }, /* ERR_ADDR_FAMILY_NOT_SUPPORTED */ { "Message sender is the bus" }, /* ERR_SBUS_SENDER_BUS */ { "Subdomain is inactive" }, /* ERR_SUBDOM_INACTIVE */ { "Account is locked" }, /* ERR_ACCOUNT_LOCKED */ { "AD renewal child failed" }, /* ERR_RENEWAL_CHILD */ { "ERR_LAST" } /* ERR_LAST */ }; const char *sss_strerror(errno_t error) { if (IS_SSSD_ERROR(error)) { return error_to_str[SSSD_ERR_IDX(error)].msg; } return strerror(error); } sssd-1.13.4/src/util/PaxHeaders.16287/crypto0000644000000000000000000000013212703463556015342 xustar0030 mtime=1460561774.404792781 30 atime=1460561776.118798593 30 ctime=1460561774.404792781 sssd-1.13.4/src/util/crypto/0000755002412700241270000000000012703463556017073 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/util/crypto/PaxHeaders.16287/nss0000644000000000000000000000013212703463556016145 xustar0030 mtime=1460561774.717793842 30 atime=1460561776.118798593 30 ctime=1460561774.717793842 sssd-1.13.4/src/util/crypto/nss/0000755002412700241270000000000012703463556017676 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/util/crypto/nss/PaxHeaders.16287/nss_sha512crypt.c0000644000000000000000000000007412703456111021330 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.715793836 sssd-1.13.4/src/util/crypto/nss/nss_sha512crypt.c0000644002412700241270000002526612703456111023012 0ustar00jhrozekjhrozek00000000000000/* This file is based on the work of Ulrich Drepper * (http://people.redhat.com/drepper/SHA-crypt.txt). I have replaced the * included SHA512 implementation by calls to NSS * (http://www.mozilla.org/projects/security/pki/nss/). * * Sumit Bose */ /* SHA512-based Unix crypt implementation. Released into the Public Domain by Ulrich Drepper . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "util/sss_endian.h" #include "util/crypto/nss/nss_util.h" #include #include #include #include /* Define our magic string to mark salt for SHA512 "encryption" replacement. */ const char sha512_salt_prefix[] = "$6$"; #define SALT_PREF_SIZE (sizeof(sha512_salt_prefix) - 1) /* Prefix for optional rounds specification. */ const char sha512_rounds_prefix[] = "rounds="; #define ROUNDS_SIZE (sizeof(sha512_rounds_prefix) - 1) #define SALT_LEN_MAX 16 #define ROUNDS_DEFAULT 5000 #define ROUNDS_MIN 1000 #define ROUNDS_MAX 999999999 /* Table with characters for base64 transformation. */ const char b64t[64] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; /* base64 conversion function */ static inline void b64_from_24bit(char **dest, size_t *len, size_t n, uint8_t b2, uint8_t b1, uint8_t b0) { uint32_t w; size_t i; if (*len < n) n = *len; w = (b2 << 16) | (b1 << 8) | b0; for (i = 0; i < n; i++) { (*dest)[i] = b64t[w & 0x3f]; w >>= 6; } *len -= i; *dest += i; } #define PTR_2_INT(x) ((x) - ((__typeof__ (x)) NULL)) #define ALIGN64 __alignof__(uint64_t) static int sha512_crypt_r(const char *key, const char *salt, char *buffer, size_t buflen) { unsigned char temp_result[64] __attribute__((__aligned__(ALIGN64))); unsigned char alt_result[64] __attribute__((__aligned__(ALIGN64))); size_t rounds = ROUNDS_DEFAULT; bool rounds_custom = false; HASHContext *alt_ctx = NULL; HASHContext *ctx = NULL; size_t salt_len; size_t key_len; size_t cnt; char *copied_salt = NULL; char *copied_key = NULL; char *p_bytes = NULL; char *s_bytes = NULL; int p1, p2, p3, pt, n; unsigned int part; char *cp, *tmp; int ret; /* Find beginning of salt string. The prefix should normally always be * present. Just in case it is not. */ if (strncmp(salt, sha512_salt_prefix, SALT_PREF_SIZE) == 0) { /* Skip salt prefix. */ salt += SALT_PREF_SIZE; } if (strncmp(salt, sha512_rounds_prefix, ROUNDS_SIZE) == 0) { unsigned long int srounds; const char *num; char *endp; num = salt + ROUNDS_SIZE; srounds = strtoul(num, &endp, 10); if (*endp == '$') { salt = endp + 1; if (srounds < ROUNDS_MIN) srounds = ROUNDS_MIN; if (srounds > ROUNDS_MAX) srounds = ROUNDS_MAX; rounds = srounds; rounds_custom = true; } } salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX); key_len = strlen(key); if ((PTR_2_INT(key) % ALIGN64) != 0) { tmp = (char *)alloca(key_len + ALIGN64); key = copied_key = memcpy(tmp + ALIGN64 - PTR_2_INT(tmp) % ALIGN64, key, key_len); } if (PTR_2_INT(salt) % ALIGN64 != 0) { tmp = (char *)alloca(salt_len + ALIGN64); salt = copied_salt = memcpy(tmp + ALIGN64 - PTR_2_INT(tmp) % ALIGN64, salt, salt_len); } ret = nspr_nss_init(); if (ret != EOK) { ret = EIO; goto done; } ctx = HASH_Create(HASH_AlgSHA512); if (!ctx) { ret = EIO; goto done; } alt_ctx = HASH_Create(HASH_AlgSHA512); if (!alt_ctx) { ret = EIO; goto done; } /* Prepare for the real work. */ HASH_Begin(ctx); /* Add the key string. */ HASH_Update(ctx, (const unsigned char *)key, key_len); /* The last part is the salt string. This must be at most 16 * characters and it ends at the first `$' character (for * compatibility with existing implementations). */ HASH_Update(ctx, (const unsigned char *)salt, salt_len); /* Compute alternate SHA512 sum with input KEY, SALT, and KEY. * The final result will be added to the first context. */ HASH_Begin(alt_ctx); /* Add key. */ HASH_Update(alt_ctx, (const unsigned char *)key, key_len); /* Add salt. */ HASH_Update(alt_ctx, (const unsigned char *)salt, salt_len); /* Add key again. */ HASH_Update(alt_ctx, (const unsigned char *)key, key_len); /* Now get result of this (64 bytes) and add it to the other context. */ HASH_End(alt_ctx, alt_result, &part, HASH_ResultLenContext(alt_ctx)); /* Add for any character in the key one byte of the alternate sum. */ for (cnt = key_len; cnt > 64; cnt -= 64) { HASH_Update(ctx, alt_result, 64); } HASH_Update(ctx, alt_result, cnt); /* Take the binary representation of the length of the key and for every * 1 add the alternate sum, for every 0 the key. */ for (cnt = key_len; cnt > 0; cnt >>= 1) { if ((cnt & 1) != 0) { HASH_Update(ctx, alt_result, 64); } else { HASH_Update(ctx, (const unsigned char *)key, key_len); } } /* Create intermediate result. */ HASH_End(ctx, alt_result, &part, HASH_ResultLenContext(ctx)); /* Start computation of P byte sequence. */ HASH_Begin(alt_ctx); /* For every character in the password add the entire password. */ for (cnt = 0; cnt < key_len; cnt++) { HASH_Update(alt_ctx, (const unsigned char *)key, key_len); } /* Finish the digest. */ HASH_End(alt_ctx, temp_result, &part, HASH_ResultLenContext(alt_ctx)); /* Create byte sequence P. */ cp = p_bytes = alloca(key_len); for (cnt = key_len; cnt >= 64; cnt -= 64) { cp = mempcpy(cp, temp_result, 64); } memcpy(cp, temp_result, cnt); /* Start computation of S byte sequence. */ HASH_Begin(alt_ctx); /* For every character in the password add the entire salt. */ for (cnt = 0; cnt < 16 + alt_result[0]; cnt++) { HASH_Update(alt_ctx, (const unsigned char *)salt, salt_len); } /* Finish the digest. */ HASH_End(alt_ctx, temp_result, &part, HASH_ResultLenContext(alt_ctx)); /* Create byte sequence S. */ cp = s_bytes = alloca(salt_len); for (cnt = salt_len; cnt >= 64; cnt -= 64) { cp = mempcpy(cp, temp_result, 64); } memcpy(cp, temp_result, cnt); /* Repeatedly run the collected hash value through SHA512 to burn CPU cycles. */ for (cnt = 0; cnt < rounds; cnt++) { HASH_Begin(ctx); /* Add key or last result. */ if ((cnt & 1) != 0) { HASH_Update(ctx, (const unsigned char *)p_bytes, key_len); } else { HASH_Update(ctx, alt_result, 64); } /* Add salt for numbers not divisible by 3. */ if (cnt % 3 != 0) { HASH_Update(ctx, (const unsigned char *)s_bytes, salt_len); } /* Add key for numbers not divisible by 7. */ if (cnt % 7 != 0) { HASH_Update(ctx, (const unsigned char *)p_bytes, key_len); } /* Add key or last result. */ if ((cnt & 1) != 0) { HASH_Update(ctx, alt_result, 64); } else { HASH_Update(ctx, (const unsigned char *)p_bytes, key_len); } /* Create intermediate result. */ HASH_End(ctx, alt_result, &part, HASH_ResultLenContext(ctx)); } /* Now we can construct the result string. * It consists of three parts. */ if (buflen <= SALT_PREF_SIZE) { ret = ERANGE; goto done; } cp = stpncpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); buflen -= SALT_PREF_SIZE; if (rounds_custom) { n = snprintf(cp, buflen, "%s%zu$", sha512_rounds_prefix, rounds); if (n < 0 || n >= buflen) { ret = ERANGE; goto done; } cp += n; buflen -= n; } if (buflen <= salt_len + 1) { ret = ERANGE; goto done; } cp = stpncpy(cp, salt, salt_len); *cp++ = '$'; buflen -= salt_len + 1; /* fuzzyfill the base 64 string */ p1 = 0; p2 = 21; p3 = 42; for (n = 0; n < 21; n++) { b64_from_24bit(&cp, &buflen, 4, alt_result[p1], alt_result[p2], alt_result[p3]); if (buflen == 0) { ret = ERANGE; goto done; } pt = p1; p1 = p2 + 1; p2 = p3 + 1; p3 = pt + 1; } /* 64th and last byte */ b64_from_24bit(&cp, &buflen, 2, 0, 0, alt_result[p3]); if (buflen == 0) { ret = ERANGE; goto done; } *cp = '\0'; ret = EOK; done: /* Clear the buffer for the intermediate result so that people attaching * to processes or reading core dumps cannot get any information. We do it * in this way to clear correct_words[] inside the SHA512 implementation * as well. */ if (ctx) HASH_Destroy(ctx); if (alt_ctx) HASH_Destroy(alt_ctx); if (p_bytes) memset(p_bytes, '\0', key_len); if (s_bytes) memset(s_bytes, '\0', salt_len); if (copied_key) memset(copied_key, '\0', key_len); if (copied_salt) memset(copied_salt, '\0', salt_len); memset(temp_result, '\0', sizeof(temp_result)); return ret; } int s3crypt_sha512(TALLOC_CTX *memctx, const char *key, const char *salt, char **_hash) { char *hash; int hlen = (sizeof (sha512_salt_prefix) - 1 + sizeof (sha512_rounds_prefix) + 9 + 1 + strlen (salt) + 1 + 86 + 1); int ret; hash = talloc_size(memctx, hlen); if (!hash) return ENOMEM; ret = sha512_crypt_r(key, salt, hash, hlen); if (ret) return ret; *_hash = hash; return ret; } #define SALT_RAND_LEN 12 int s3crypt_gen_salt(TALLOC_CTX *memctx, char **_salt) { uint8_t rb[SALT_RAND_LEN]; char *salt, *cp; size_t slen; int ret; ret = nspr_nss_init(); if (ret != EOK) { return EIO; } salt = talloc_size(memctx, SALT_LEN_MAX + 1); if (!salt) { return ENOMEM; } ret = PK11_GenerateRandom(rb, SALT_RAND_LEN); if (ret != SECSuccess) { return EIO; } slen = SALT_LEN_MAX; cp = salt; b64_from_24bit(&cp, &slen, 4, rb[0], rb[1], rb[2]); b64_from_24bit(&cp, &slen, 4, rb[3], rb[4], rb[5]); b64_from_24bit(&cp, &slen, 4, rb[6], rb[7], rb[8]); b64_from_24bit(&cp, &slen, 4, rb[9], rb[10], rb[11]); *cp = '\0'; *_salt = salt; return EOK; } sssd-1.13.4/src/util/crypto/nss/PaxHeaders.16287/nss_base64.c0000644000000000000000000000007412703456111020327 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.713793829 sssd-1.13.4/src/util/crypto/nss/nss_base64.c0000644002412700241270000000476012703456111022005 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "util/crypto/nss/nss_util.h" #include "util/crypto/sss_crypto.h" #include /* NSS wraps b64 encoded buffers with CRLF automatically after 64 chars. This * function strips the CRLF double-chars. The buffer can be decoded with plain * NSS calls */ char *sss_base64_encode(TALLOC_CTX *mem_ctx, const unsigned char *inbuf, size_t inbufsize) { int ret; char *b64encoded = NULL; int i, j, b64size; char *outbuf; /* initialize NSS if needed */ ret = nspr_nss_init(); if (ret != EOK) { return NULL; } b64encoded = BTOA_DataToAscii(inbuf, inbufsize); if (!b64encoded) return NULL; b64size = strlen(b64encoded) + 1; outbuf = talloc_array(mem_ctx, char, b64size); if (outbuf == NULL) { PORT_Free(b64encoded); return NULL; } for (i=0, j=0; i < b64size; i++) { if (b64encoded[i] == '\n' || b64encoded[i] == '\r') { continue; } outbuf[j++] = b64encoded[i]; /* will also copy the trailing \0 char */ } PORT_Free(b64encoded); return outbuf; } unsigned char *sss_base64_decode(TALLOC_CTX *mem_ctx, const char *inbuf, size_t *outbufsize) { int ret; unsigned char *b64decoded = NULL; unsigned int size; unsigned char *outbuf; /* initialize NSS if needed */ ret = nspr_nss_init(); if (ret != EOK) { return NULL; } b64decoded = ATOB_AsciiToData(inbuf, &size); if (!b64decoded) return NULL; outbuf = talloc_memdup(mem_ctx, b64decoded, size); PORT_Free(b64decoded); if (!outbuf) return NULL; *outbufsize = size; return outbuf; } sssd-1.13.4/src/util/crypto/nss/PaxHeaders.16287/nss_hmac_sha1.c0000644000000000000000000000007412703456111021067 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.714793832 sssd-1.13.4/src/util/crypto/nss/nss_hmac_sha1.c0000644002412700241270000000516512703456111022545 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* NSS does not provide public API for HMAC, so we implement it ourselves. See RFC 2104 for details on the algorithm. */ #include "util/util.h" #include "util/crypto/sss_crypto.h" #include "util/crypto/nss/nss_util.h" #include #define HMAC_SHA1_BLOCKSIZE 64 int sss_hmac_sha1(const unsigned char *key, size_t key_len, const unsigned char *in, size_t in_len, unsigned char *out) { int ret; unsigned char ikey[HMAC_SHA1_BLOCKSIZE], okey[HMAC_SHA1_BLOCKSIZE]; size_t i; HASHContext *sha1; unsigned char hash[SSS_SHA1_LENGTH]; unsigned int res_len; ret = nspr_nss_init(); if (ret != EOK) { return ret; } sha1 = HASH_Create(HASH_AlgSHA1); if (!sha1) { return ENOMEM; } if (key_len > HMAC_SHA1_BLOCKSIZE) { /* keys longer than blocksize are shortened */ HASH_Begin(sha1); HASH_Update(sha1, key, key_len); HASH_End(sha1, ikey, &res_len, SSS_SHA1_LENGTH); memset(ikey + SSS_SHA1_LENGTH, 0, HMAC_SHA1_BLOCKSIZE - SSS_SHA1_LENGTH); } else { /* keys shorter than blocksize are zero-padded */ memcpy(ikey, key, key_len); if (key_len != HMAC_SHA1_BLOCKSIZE) { memset(ikey + key_len, 0, HMAC_SHA1_BLOCKSIZE - key_len); } } /* HMAC(key, msg) = HASH(key XOR opad, HASH(key XOR ipad, msg)) */ for (i = 0; i < HMAC_SHA1_BLOCKSIZE; i++) { okey[i] = ikey[i] ^ 0x5c; ikey[i] ^= 0x36; } HASH_Begin(sha1); HASH_Update(sha1, ikey, HMAC_SHA1_BLOCKSIZE); HASH_Update(sha1, in, in_len); HASH_End(sha1, hash, &res_len, SSS_SHA1_LENGTH); HASH_Begin(sha1); HASH_Update(sha1, okey, HMAC_SHA1_BLOCKSIZE); HASH_Update(sha1, hash, SSS_SHA1_LENGTH); HASH_End(sha1, out, &res_len, SSS_SHA1_LENGTH); HASH_Destroy(sha1); return EOK; } sssd-1.13.4/src/util/crypto/nss/PaxHeaders.16287/nss_util.h0000644000000000000000000000007412703456111020225 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.602793452 sssd-1.13.4/src/util/crypto/nss/nss_util.h0000644002412700241270000000147312703456111021701 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS crypto wrappers Authors: Jakub Hrozek Copyright (C) Red Hat, Inc 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ int nspr_nss_init(void); int nspr_nss_cleanup(void); sssd-1.13.4/src/util/crypto/nss/PaxHeaders.16287/nss_util.c0000644000000000000000000000007412703456111020220 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.717793842 sssd-1.13.4/src/util/crypto/nss/nss_util.c0000644002412700241270000000350412703456111021671 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS crypto wrappers Authors: Sumit Bose Jakub Hrozek Copyright (C) Red Hat, Inc 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include #include "util/util.h" #include "util/crypto/nss/nss_util.h" static int nspr_nss_init_done = 0; int nspr_nss_init(void) { SECStatus sret; /* nothing to do */ if (nspr_nss_init_done == 1) return SECSuccess; PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); sret = NSS_NoDB_Init(NULL); if (sret != SECSuccess) { DEBUG(SSSDBG_CRIT_FAILURE, "Error initializing connection to NSS [%d]\n", PR_GetError()); return EIO; } nspr_nss_init_done = 1; return EOK; } int nspr_nss_cleanup(void) { SECStatus sret; /* nothing to do */ if (nspr_nss_init_done == 0) return SECSuccess; sret = NSS_Shutdown(); if (sret != SECSuccess) { DEBUG(SSSDBG_CRIT_FAILURE, "Error shutting down connection to NSS [%d]\n", PR_GetError()); return EIO; } PR_Cleanup(); nspr_nss_init_done = 0; return EOK; } sssd-1.13.4/src/util/crypto/nss/PaxHeaders.16287/nss_obfuscate.c0000644000000000000000000000007412703456111021216 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.716793839 sssd-1.13.4/src/util/crypto/nss/nss_obfuscate.c0000644002412700241270000003445112703456111022674 0ustar00jhrozekjhrozek00000000000000/* SSSD Password obfuscation logic Author: Jakub Hrozek Copyright (C) Red Hat, Inc 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* * READ ME: * * Please note that password obfuscation does not improve security in any * way. It is just a mechanism to make the password human-unreadable. If you * need to secure passwords in your application, you should probably take a * look at storing passwords in NSS-backed database. */ #include "config.h" #include #include #include #include #include #include "util/util.h" #include "util/crypto/sss_crypto.h" #include "util/crypto/nss/nss_util.h" #define OBF_BUFFER_SENTINEL "\0\1\2\3" #define OBF_BUFFER_SENTINEL_SIZE 4 #define MAKE_SECITEM(sdata, slen, sitem) do { \ (sitem)->type = (siBuffer); \ (sitem)->data = (sdata); \ (sitem)->len = (slen); \ } while(0) struct sss_nss_crypto_ctx { PK11SlotInfo *slot; PK11Context *ectx; PK11SymKey *keyobj; SECItem *sparam; SECItem *iv; SECItem *key; }; struct crypto_mech_data { CK_MECHANISM_TYPE cipher; uint16_t keylen; uint16_t bsize; }; static struct crypto_mech_data cmdata[] = { /* AES with automatic padding, 256b key, 128b block */ { CKM_AES_CBC_PAD, 32, 16 }, /* sentinel */ { 0, 0, 0 } }; static struct crypto_mech_data *get_crypto_mech_data(enum obfmethod meth) { if (meth >= NUM_OBFMETHODS) { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported cipher type\n"); return NULL; } return &cmdata[meth]; } static int generate_random_key(TALLOC_CTX *mem_ctx, PK11SlotInfo *slot, struct crypto_mech_data *mech_props, SECItem **_key) { SECStatus sret; SECItem *randkeydata; SECItem *key = NULL; PK11SymKey *randkey; int ret; randkey = PK11_KeyGen(slot, mech_props->cipher, NULL, mech_props->keylen, NULL); if (randkey == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failure to generate key (err %d)\n", PR_GetError()); ret = EIO; goto done; } sret = PK11_ExtractKeyValue(randkey); if (sret != SECSuccess) { DEBUG(SSSDBG_CRIT_FAILURE, "Failure to extract key value (err %d)\n", PR_GetError()); ret = EIO; goto done; } randkeydata = PK11_GetKeyData(randkey); if (randkeydata == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failure to get key data (err %d)\n", PR_GetError()); ret = EIO; goto done; } /* randkeydata is valid until randkey is. Copy with talloc to * get a nice memory hierarchy symmetrical in encrypt * and decrypt case */ key = talloc_zero(mem_ctx, SECItem); if (!key) { ret = ENOMEM; goto done; } key->data = talloc_memdup(key, randkeydata->data, randkeydata->len); if (!key->data) { ret = ENOMEM; goto done; } key->len = randkeydata->len; *_key = key; ret = EOK; done: if (ret != EOK) talloc_zfree(key); PK11_FreeSymKey(randkey); return ret; } static int sss_nss_crypto_ctx_destructor(struct sss_nss_crypto_ctx *cctx) { if (cctx->ectx) PK11_DestroyContext(cctx->ectx, PR_TRUE); if (cctx->sparam) SECITEM_FreeItem(cctx->sparam, PR_TRUE); if (cctx->slot) PK11_FreeSlot(cctx->slot); if (cctx->keyobj) PK11_FreeSymKey(cctx->keyobj); return EOK; } static int nss_ctx_init(TALLOC_CTX *mem_ctx, struct crypto_mech_data *mech_props, struct sss_nss_crypto_ctx **_cctx) { struct sss_nss_crypto_ctx *cctx; int ret; cctx = talloc_zero(mem_ctx, struct sss_nss_crypto_ctx); if (!cctx) { return ENOMEM; } talloc_set_destructor(cctx, sss_nss_crypto_ctx_destructor); cctx->slot = PK11_GetBestSlot(mech_props->cipher, NULL); if (cctx->slot == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to find security device (err %d)\n", PR_GetError()); ret = EIO; goto done; } ret = EOK; *_cctx = cctx; done: if (ret) talloc_zfree(cctx); return ret; } static int nss_encrypt_decrypt_init(struct crypto_mech_data *mech_props, bool do_encrypt, struct sss_nss_crypto_ctx *cctx) { CK_ATTRIBUTE_TYPE op; int ret; op = do_encrypt ? CKA_ENCRYPT : CKA_DECRYPT; /* turn the raw key into a key object */ cctx->keyobj = PK11_ImportSymKey(cctx->slot, mech_props->cipher, PK11_OriginUnwrap, op, cctx->key, NULL); if (cctx->keyobj == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failure to import key into NSS (err %d)\n", PR_GetError()); ret = EIO; goto done; } /* turn the raw IV into a initialization vector object */ cctx->sparam = PK11_ParamFromIV(mech_props->cipher, cctx->iv); if (cctx->sparam == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failure to set up PKCS11 param (err %d)\n", PR_GetError()); ret = EIO; goto done; } /* Create cipher context */ cctx->ectx = PK11_CreateContextBySymKey(mech_props->cipher, op, cctx->keyobj, cctx->sparam); if (cctx->ectx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create cipher context (err %d)\n", PORT_GetError()); ret = EIO; goto done; } ret = EOK; done: return ret; } int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen, enum obfmethod meth, char **obfpwd) { SECStatus sret; int ret; TALLOC_CTX *tmp_ctx = NULL; struct crypto_mech_data *mech_props; struct sss_nss_crypto_ctx *cctx; unsigned char *plaintext; unsigned char *cryptotext; int ct_maxsize; int ctlen; unsigned int digestlen; int result_len; unsigned char *obfbuf; size_t obufsize = 0; size_t p = 0; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { return ENOMEM; } /* initialize NSS if needed */ ret = nspr_nss_init(); if (ret != EOK) { ret = EIO; goto done; } mech_props = get_crypto_mech_data(meth); if (mech_props == NULL) { ret = EINVAL; goto done; } ret = nss_ctx_init(tmp_ctx, mech_props, &cctx); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot initialize NSS context\n"); goto done; } /* generate random encryption and IV key */ ret = generate_random_key(cctx, cctx->slot, mech_props, &cctx->key); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not generate encryption key\n"); goto done; } ret = generate_random_key(cctx, cctx->slot, mech_props, &cctx->iv); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not generate initialization vector\n"); goto done; } ret = nss_encrypt_decrypt_init(mech_props, true, cctx); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot initialize NSS context properties\n"); goto done; } plaintext = (unsigned char *) talloc_strndup(tmp_ctx, password, plen); if (!plaintext) { ret = ENOMEM; goto done; } /* cryptotext buffer must be at least len(plaintext)+blocksize */ ct_maxsize = plen + (mech_props->bsize); cryptotext = talloc_array(tmp_ctx, unsigned char, ct_maxsize); if (!cryptotext) { ret = ENOMEM; goto done; } /* sample data we'll encrypt and decrypt */ sret = PK11_CipherOp(cctx->ectx, cryptotext, &ctlen, ct_maxsize, plaintext, plen); if (sret != SECSuccess) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot execute the encryption operation (err %d)\n", PR_GetError()); ret = EIO; goto done; } sret = PK11_DigestFinal(cctx->ectx, cryptotext+ctlen, &digestlen, ct_maxsize-ctlen); if (sret != SECSuccess) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot execute the digest operation (err %d)\n", PR_GetError()); ret = EIO; goto done; } result_len = ctlen + digestlen; if (result_len < 0 || result_len > UINT16_MAX) { ret = ERANGE; goto done; } /* Pack the obfuscation buffer */ /* The buffer consists of: * uint16_t the type of the cipher * uint16_t length of the cryptotext in bytes (clen) * uint8_t[klen] key * uint8_t[blen] IV * uint8_t[clen] cryptotext * 4 bytes of "sentinel" denoting end of the buffer */ obufsize = sizeof(uint16_t) + sizeof(uint16_t) + mech_props->keylen + mech_props->bsize + result_len + OBF_BUFFER_SENTINEL_SIZE; obfbuf = talloc_array(tmp_ctx, unsigned char, obufsize); if (!obfbuf) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Writing method: %d\n", meth); SAFEALIGN_SET_UINT16(&obfbuf[p], meth, &p); DEBUG(SSSDBG_TRACE_INTERNAL, "Writing bufsize: %d\n", result_len); SAFEALIGN_SET_UINT16(&obfbuf[p], result_len, &p); safealign_memcpy(&obfbuf[p], cctx->key->data, mech_props->keylen, &p); safealign_memcpy(&obfbuf[p], cctx->iv->data, mech_props->bsize, &p); safealign_memcpy(&obfbuf[p], cryptotext, result_len, &p); safealign_memcpy(&obfbuf[p], OBF_BUFFER_SENTINEL, OBF_BUFFER_SENTINEL_SIZE, &p); /* Base64 encode the resulting buffer */ *obfpwd = sss_base64_encode(mem_ctx, obfbuf, obufsize); if (*obfpwd == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: talloc_free(tmp_ctx); nspr_nss_cleanup(); return ret; } int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded, char **password) { SECStatus sret; int ret; TALLOC_CTX *tmp_ctx = NULL; struct crypto_mech_data *mech_props; struct sss_nss_crypto_ctx *cctx; int plainlen; unsigned int digestlen; unsigned char *obfbuf = NULL; size_t obflen; char *pwdbuf; /* for unmarshaling data */ uint16_t meth; uint16_t ctsize; size_t p = 0; unsigned char *cryptotext; unsigned char *keybuf; unsigned char *ivbuf; unsigned char sentinel_check[OBF_BUFFER_SENTINEL_SIZE]; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { return ENOMEM; } /* initialize NSS if needed */ ret = nspr_nss_init(); if (ret != EOK) { ret = EIO; goto done; } /* Base64 decode the incoming buffer */ obfbuf = sss_base64_decode(tmp_ctx, b64encoded, &obflen); if (!obfbuf) { ret = ENOMEM; goto done; } /* unpack obfuscation buffer */ SAFEALIGN_COPY_UINT16_CHECK(&meth, obfbuf+p, obflen, &p); DEBUG(SSSDBG_TRACE_INTERNAL, "Read method: %d\n", meth); SAFEALIGN_COPY_UINT16_CHECK(&ctsize, obfbuf+p, obflen, &p); DEBUG(SSSDBG_TRACE_INTERNAL, "Read bufsize: %d\n", ctsize); mech_props = get_crypto_mech_data(meth); if (mech_props == NULL) { ret = EINVAL; goto done; } /* check that we got sane mechanism properties and cryptotext size */ memcpy(sentinel_check, obfbuf + p + mech_props->keylen + mech_props->bsize + ctsize, OBF_BUFFER_SENTINEL_SIZE); if (memcmp(sentinel_check, OBF_BUFFER_SENTINEL, OBF_BUFFER_SENTINEL_SIZE) != 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Obfuscation buffer seems corrupt, aborting\n"); ret = EFAULT; goto done; } /* copy out key, ivbuf and cryptotext */ keybuf = talloc_array(tmp_ctx, unsigned char, mech_props->keylen); if (keybuf == NULL) { ret = ENOMEM; goto done; } safealign_memcpy(keybuf, obfbuf+p, mech_props->keylen, &p); ivbuf = talloc_array(tmp_ctx, unsigned char, mech_props->bsize); if (ivbuf == NULL) { ret = ENOMEM; goto done; } safealign_memcpy(ivbuf, obfbuf+p, mech_props->bsize, &p); cryptotext = talloc_array(tmp_ctx, unsigned char, ctsize); if (cryptotext == NULL) { ret = ENOMEM; goto done; } safealign_memcpy(cryptotext, obfbuf+p, ctsize, &p); ret = nss_ctx_init(tmp_ctx, mech_props, &cctx); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot initialize NSS context\n"); goto done; } cctx->iv = talloc_zero(cctx, SECItem); cctx->key = talloc_zero(cctx, SECItem); if (!cctx->iv || !cctx->key) { ret = ENOMEM; goto done; } MAKE_SECITEM(ivbuf, mech_props->bsize, cctx->iv); MAKE_SECITEM(keybuf, mech_props->keylen, cctx->key); ret = nss_encrypt_decrypt_init(mech_props, false, cctx); if (ret) { goto done; } pwdbuf = talloc_array(tmp_ctx, char, ctsize); if (!pwdbuf) { ret = ENOMEM; goto done; } sret = PK11_CipherOp(cctx->ectx, (unsigned char *) pwdbuf, &plainlen, ctsize, cryptotext, ctsize); if (sret != SECSuccess) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot execute the encryption operation (err %d)\n", PR_GetError()); ret = EIO; goto done; } sret = PK11_DigestFinal(cctx->ectx, (unsigned char *) pwdbuf+plainlen, &digestlen, ctsize - plainlen); if (sret != SECSuccess) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot execute the encryption operation (err %d)\n", PR_GetError()); ret = EIO; goto done; } *password = talloc_move(mem_ctx, &pwdbuf); ret = EOK; done: talloc_free(tmp_ctx); nspr_nss_cleanup(); return ret; } sssd-1.13.4/src/util/crypto/PaxHeaders.16287/libcrypto0000644000000000000000000000013212703463556017351 xustar0030 mtime=1460561774.712793825 30 atime=1460561776.118798593 30 ctime=1460561774.712793825 sssd-1.13.4/src/util/crypto/libcrypto/0000755002412700241270000000000012703463556021102 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/util/crypto/libcrypto/PaxHeaders.16287/crypto_sha512crypt.c0000644000000000000000000000007412703456111023251 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.711793822 sssd-1.13.4/src/util/crypto/libcrypto/crypto_sha512crypt.c0000644002412700241270000002537112703456111024730 0ustar00jhrozekjhrozek00000000000000/* This file is based on nss_sha512crypt.c which is based on the work of * Ulrich Drepper (http://people.redhat.com/drepper/SHA-crypt.txt). * * libcrypto is used to provide SHA512 and random number generation. * (http://www.openssl.org/docs/crypto/crypto.html). * * Sumit Bose * George McCollister */ /* SHA512-based Unix crypt implementation. Released into the Public Domain by Ulrich Drepper . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "util/sss_endian.h" #include #include /* Define our magic string to mark salt for SHA512 "encryption" replacement. */ const char sha512_salt_prefix[] = "$6$"; #define SALT_PREF_SIZE (sizeof(sha512_salt_prefix) - 1) /* Prefix for optional rounds specification. */ const char sha512_rounds_prefix[] = "rounds="; #define ROUNDS_SIZE (sizeof(sha512_rounds_prefix) - 1) #define SALT_LEN_MAX 16 #define ROUNDS_DEFAULT 5000 #define ROUNDS_MIN 1000 #define ROUNDS_MAX 999999999 /* Table with characters for base64 transformation. */ const char b64t[64] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; /* base64 conversion function */ static inline void b64_from_24bit(char **dest, size_t *len, size_t n, uint8_t b2, uint8_t b1, uint8_t b0) { uint32_t w; size_t i; if (*len < n) n = *len; w = (b2 << 16) | (b1 << 8) | b0; for (i = 0; i < n; i++) { (*dest)[i] = b64t[w & 0x3f]; w >>= 6; } *len -= i; *dest += i; } #define PTR_2_INT(x) ((x) - ((__typeof__ (x)) NULL)) #define ALIGN64 __alignof__(uint64_t) static int sha512_crypt_r(const char *key, const char *salt, char *buffer, size_t buflen) { unsigned char temp_result[64] __attribute__((__aligned__(ALIGN64))); unsigned char alt_result[64] __attribute__((__aligned__(ALIGN64))); size_t rounds = ROUNDS_DEFAULT; bool rounds_custom = false; EVP_MD_CTX alt_ctx; EVP_MD_CTX ctx; size_t salt_len; size_t key_len; size_t cnt; char *copied_salt = NULL; char *copied_key = NULL; char *p_bytes = NULL; char *s_bytes = NULL; int p1, p2, p3, pt, n; unsigned int part; char *cp, *tmp; int ret; /* Find beginning of salt string. The prefix should normally always be * present. Just in case it is not. */ if (strncmp(salt, sha512_salt_prefix, SALT_PREF_SIZE) == 0) { /* Skip salt prefix. */ salt += SALT_PREF_SIZE; } if (strncmp(salt, sha512_rounds_prefix, ROUNDS_SIZE) == 0) { unsigned long int srounds; const char *num; char *endp; num = salt + ROUNDS_SIZE; srounds = strtoul(num, &endp, 10); if (*endp == '$') { salt = endp + 1; if (srounds < ROUNDS_MIN) srounds = ROUNDS_MIN; if (srounds > ROUNDS_MAX) srounds = ROUNDS_MAX; rounds = srounds; rounds_custom = true; } } salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX); key_len = strlen(key); if ((PTR_2_INT(key) % ALIGN64) != 0) { tmp = (char *)alloca(key_len + ALIGN64); key = copied_key = memcpy(tmp + ALIGN64 - PTR_2_INT(tmp) % ALIGN64, key, key_len); } if (PTR_2_INT(salt) % ALIGN64 != 0) { tmp = (char *)alloca(salt_len + ALIGN64); salt = copied_salt = memcpy(tmp + ALIGN64 - PTR_2_INT(tmp) % ALIGN64, salt, salt_len); } EVP_MD_CTX_init(&ctx); EVP_MD_CTX_init(&alt_ctx); /* Prepare for the real work. */ if (!EVP_DigestInit_ex(&ctx, EVP_sha512(), NULL)) { ret = EIO; goto done; } /* Add the key string. */ EVP_DigestUpdate(&ctx, (const unsigned char *)key, key_len); /* The last part is the salt string. This must be at most 16 * characters and it ends at the first `$' character (for * compatibility with existing implementations). */ EVP_DigestUpdate(&ctx, (const unsigned char *)salt, salt_len); /* Compute alternate SHA512 sum with input KEY, SALT, and KEY. * The final result will be added to the first context. */ if (!EVP_DigestInit_ex(&alt_ctx, EVP_sha512(), NULL)) { ret = EIO; goto done; } /* Add key. */ EVP_DigestUpdate(&alt_ctx, (const unsigned char *)key, key_len); /* Add salt. */ EVP_DigestUpdate(&alt_ctx, (const unsigned char *)salt, salt_len); /* Add key again. */ EVP_DigestUpdate(&alt_ctx, (const unsigned char *)key, key_len); /* Now get result of this (64 bytes) and add it to the other context. */ EVP_DigestFinal_ex(&alt_ctx, alt_result, &part); /* Add for any character in the key one byte of the alternate sum. */ for (cnt = key_len; cnt > 64; cnt -= 64) { EVP_DigestUpdate(&ctx, alt_result, 64); } EVP_DigestUpdate(&ctx, alt_result, cnt); /* Take the binary representation of the length of the key and for every * 1 add the alternate sum, for every 0 the key. */ for (cnt = key_len; cnt > 0; cnt >>= 1) { if ((cnt & 1) != 0) { EVP_DigestUpdate(&ctx, alt_result, 64); } else { EVP_DigestUpdate(&ctx, (const unsigned char *)key, key_len); } } /* Create intermediate result. */ EVP_DigestFinal_ex(&ctx, alt_result, &part); /* Start computation of P byte sequence. */ if (!EVP_DigestInit_ex(&alt_ctx, EVP_sha512(), NULL)) { ret = EIO; goto done; } /* For every character in the password add the entire password. */ for (cnt = 0; cnt < key_len; cnt++) { EVP_DigestUpdate(&alt_ctx, (const unsigned char *)key, key_len); } /* Finish the digest. */ EVP_DigestFinal_ex(&alt_ctx, temp_result, &part); /* Create byte sequence P. */ cp = p_bytes = alloca(key_len); for (cnt = key_len; cnt >= 64; cnt -= 64) { cp = mempcpy(cp, temp_result, 64); } memcpy(cp, temp_result, cnt); /* Start computation of S byte sequence. */ if (!EVP_DigestInit_ex(&alt_ctx, EVP_sha512(), NULL)) { ret = EIO; goto done; } /* For every character in the password add the entire salt. */ for (cnt = 0; cnt < 16 + alt_result[0]; cnt++) { EVP_DigestUpdate(&alt_ctx, (const unsigned char *)salt, salt_len); } /* Finish the digest. */ EVP_DigestFinal_ex(&alt_ctx, temp_result, &part); /* Create byte sequence S. */ cp = s_bytes = alloca(salt_len); for (cnt = salt_len; cnt >= 64; cnt -= 64) { cp = mempcpy(cp, temp_result, 64); } memcpy(cp, temp_result, cnt); /* Repeatedly run the collected hash value through SHA512 to burn CPU cycles. */ for (cnt = 0; cnt < rounds; cnt++) { if (!EVP_DigestInit_ex(&ctx, EVP_sha512(), NULL)) { ret = EIO; goto done; } /* Add key or last result. */ if ((cnt & 1) != 0) { EVP_DigestUpdate(&ctx, (const unsigned char *)p_bytes, key_len); } else { EVP_DigestUpdate(&ctx, alt_result, 64); } /* Add salt for numbers not divisible by 3. */ if (cnt % 3 != 0) { EVP_DigestUpdate(&ctx, (const unsigned char *)s_bytes, salt_len); } /* Add key for numbers not divisible by 7. */ if (cnt % 7 != 0) { EVP_DigestUpdate(&ctx, (const unsigned char *)p_bytes, key_len); } /* Add key or last result. */ if ((cnt & 1) != 0) { EVP_DigestUpdate(&ctx, alt_result, 64); } else { EVP_DigestUpdate(&ctx, (const unsigned char *)p_bytes, key_len); } /* Create intermediate result. */ EVP_DigestFinal_ex(&ctx, alt_result, &part); } /* Now we can construct the result string. * It consists of three parts. */ if (buflen <= SALT_PREF_SIZE) { ret = ERANGE; goto done; } cp = stpncpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); buflen -= SALT_PREF_SIZE; if (rounds_custom) { n = snprintf(cp, buflen, "%s%zu$", sha512_rounds_prefix, rounds); if (n < 0 || n >= buflen) { ret = ERANGE; goto done; } cp += n; buflen -= n; } if (buflen <= salt_len + 1) { ret = ERANGE; goto done; } cp = stpncpy(cp, salt, salt_len); *cp++ = '$'; buflen -= salt_len + 1; /* fuzzyfill the base 64 string */ p1 = 0; p2 = 21; p3 = 42; for (n = 0; n < 21; n++) { b64_from_24bit(&cp, &buflen, 4, alt_result[p1], alt_result[p2], alt_result[p3]); if (buflen == 0) { ret = ERANGE; goto done; } pt = p1; p1 = p2 + 1; p2 = p3 + 1; p3 = pt + 1; } /* 64th and last byte */ b64_from_24bit(&cp, &buflen, 2, 0, 0, alt_result[p3]); if (buflen == 0) { ret = ERANGE; goto done; } *cp = '\0'; ret = EOK; done: /* Clear the buffer for the intermediate result so that people attaching * to processes or reading core dumps cannot get any information. We do it * in this way to clear correct_words[] inside the SHA512 implementation * as well. */ EVP_MD_CTX_cleanup(&ctx); EVP_MD_CTX_cleanup(&alt_ctx); if (p_bytes) memset(p_bytes, '\0', key_len); if (s_bytes) memset(s_bytes, '\0', salt_len); if (copied_key) memset(copied_key, '\0', key_len); if (copied_salt) memset(copied_salt, '\0', salt_len); memset(temp_result, '\0', sizeof(temp_result)); return ret; } int s3crypt_sha512(TALLOC_CTX *memctx, const char *key, const char *salt, char **_hash) { char *hash; int hlen = (sizeof (sha512_salt_prefix) - 1 + sizeof (sha512_rounds_prefix) + 9 + 1 + strlen (salt) + 1 + 86 + 1); int ret; hash = talloc_size(memctx, hlen); if (!hash) return ENOMEM; ret = sha512_crypt_r(key, salt, hash, hlen); if (ret) return ret; *_hash = hash; return ret; } #define SALT_RAND_LEN 12 int s3crypt_gen_salt(TALLOC_CTX *memctx, char **_salt) { uint8_t rb[SALT_RAND_LEN]; char *salt, *cp; size_t slen; int ret; salt = talloc_size(memctx, SALT_LEN_MAX + 1); if (!salt) { return ENOMEM; } ret = RAND_bytes(rb, SALT_RAND_LEN); if (ret == 0) { return EIO; } slen = SALT_LEN_MAX; cp = salt; b64_from_24bit(&cp, &slen, 4, rb[0], rb[1], rb[2]); b64_from_24bit(&cp, &slen, 4, rb[3], rb[4], rb[5]); b64_from_24bit(&cp, &slen, 4, rb[6], rb[7], rb[8]); b64_from_24bit(&cp, &slen, 4, rb[9], rb[10], rb[11]); *cp = '\0'; *_salt = salt; return EOK; } sssd-1.13.4/src/util/crypto/libcrypto/PaxHeaders.16287/crypto_base64.c0000644000000000000000000000007412703456111022250 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.709793815 sssd-1.13.4/src/util/crypto/libcrypto/crypto_base64.c0000644002412700241270000000645612703456111023732 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta George McCollister Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/crypto/sss_crypto.h" #include #include char *sss_base64_encode(TALLOC_CTX *mem_ctx, const unsigned char *in, size_t insize) { char *b64encoded = NULL, *outbuf = NULL; int i, j, b64size; BIO *bmem, *b64; b64 = BIO_new(BIO_f_base64()); if (!b64) return NULL; BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bmem = BIO_new(BIO_s_mem()); if (!bmem) goto done; b64 = BIO_push(b64, bmem); BIO_write(b64, in, insize); (void) BIO_flush(b64); b64size = BIO_get_mem_data(bmem, &b64encoded); if (b64encoded) { outbuf = talloc_array(mem_ctx, char, b64size+1); if (outbuf == NULL) goto done; for (i=0, j=0; i < b64size; i++) { if (b64encoded[i] == '\n' || b64encoded[i] == '\r') { continue; } outbuf[j++] = b64encoded[i]; } outbuf[j++] = '\0'; } done: BIO_free_all(b64); return outbuf; } unsigned char *sss_base64_decode(TALLOC_CTX *mem_ctx, const char *in, size_t *outsize) { unsigned char *outbuf = NULL; unsigned char *b64decoded = NULL; unsigned char inbuf[512]; char * in_dup; int size, inlen = strlen(in); BIO *bmem, *b64, *bmem_out; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return NULL; } in_dup = talloc_size(tmp_ctx, inlen+1); if (!in_dup) goto done; memcpy(in_dup, in, inlen+1); b64 = BIO_new(BIO_f_base64()); if (!b64) goto done; BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); bmem = BIO_new_mem_buf(in_dup, -1); if (!bmem) { BIO_free(b64); goto done; } b64 = BIO_push(b64, bmem); bmem_out = BIO_new(BIO_s_mem()); if (!bmem_out) { BIO_free_all(b64); goto done; } while((inlen = BIO_read(b64, inbuf, 512)) > 0) BIO_write(bmem_out, inbuf, inlen); (void) BIO_flush(bmem_out); size = BIO_get_mem_data(bmem_out, &b64decoded); if (b64decoded) { outbuf = talloc_memdup(mem_ctx, b64decoded, size); if (!outbuf) { BIO_free_all(b64); BIO_free(bmem_out); goto done; } *outsize = size; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get decoded data\n"); } BIO_free_all(b64); BIO_free(bmem_out); done: talloc_free(tmp_ctx); return outbuf; } sssd-1.13.4/src/util/crypto/libcrypto/PaxHeaders.16287/crypto_hmac_sha1.c0000644000000000000000000000007412703456111023010 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.710793819 sssd-1.13.4/src/util/crypto/libcrypto/crypto_hmac_sha1.c0000644002412700241270000000531212703456111024460 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta George McCollister Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/crypto/sss_crypto.h" #include #define HMAC_SHA1_BLOCKSIZE 64 int sss_hmac_sha1(const unsigned char *key, size_t key_len, const unsigned char *in, size_t in_len, unsigned char *out) { int ret; EVP_MD_CTX ctx; unsigned char ikey[HMAC_SHA1_BLOCKSIZE], okey[HMAC_SHA1_BLOCKSIZE]; size_t i; unsigned char hash[SSS_SHA1_LENGTH]; unsigned int res_len; EVP_MD_CTX_init(&ctx); if (key_len > HMAC_SHA1_BLOCKSIZE) { /* keys longer than blocksize are shortened */ if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) { ret = EIO; goto done; } EVP_DigestUpdate(&ctx, (const unsigned char *)key, key_len); EVP_DigestFinal_ex(&ctx, ikey, &res_len); memset(ikey + SSS_SHA1_LENGTH, 0, HMAC_SHA1_BLOCKSIZE - SSS_SHA1_LENGTH); } else { /* keys shorter than blocksize are zero-padded */ memcpy(ikey, key, key_len); memset(ikey + key_len, 0, HMAC_SHA1_BLOCKSIZE - key_len); } /* HMAC(key, msg) = HASH(key XOR opad, HASH(key XOR ipad, msg)) */ for (i = 0; i < HMAC_SHA1_BLOCKSIZE; i++) { okey[i] = ikey[i] ^ 0x5c; ikey[i] ^= 0x36; } if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) { ret = EIO; goto done; } EVP_DigestUpdate(&ctx, (const unsigned char *)ikey, HMAC_SHA1_BLOCKSIZE); EVP_DigestUpdate(&ctx, (const unsigned char *)in, in_len); EVP_DigestFinal_ex(&ctx, hash, &res_len); if (!EVP_DigestInit_ex(&ctx, EVP_sha1(), NULL)) { ret = EIO; goto done; } EVP_DigestUpdate(&ctx, (const unsigned char *)okey, HMAC_SHA1_BLOCKSIZE); EVP_DigestUpdate(&ctx, (const unsigned char *)hash, SSS_SHA1_LENGTH); EVP_DigestFinal_ex(&ctx, out, &res_len); ret = EOK; done: EVP_MD_CTX_cleanup(&ctx); return ret; } sssd-1.13.4/src/util/crypto/libcrypto/PaxHeaders.16287/crypto_obfuscate.c0000644000000000000000000000007412703456111023137 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.712793825 sssd-1.13.4/src/util/crypto/libcrypto/crypto_obfuscate.c0000644002412700241270000002043512703456111024612 0ustar00jhrozekjhrozek00000000000000/* SSSD Password obfuscation logic Authors: George McCollister Copyright (C) George McCollister 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* * READ ME: * * Please note that password obfuscation does not improve security in any * way. It is just a mechanism to make the password human-unreadable. If you * need to secure passwords in your application, you should probably take a * look at storing passwords in NSS-backed database. */ #include "config.h" #include #include #include "util/util.h" #include "util/crypto/sss_crypto.h" #include #include #define OBF_BUFFER_SENTINEL "\0\1\2\3" #define OBF_BUFFER_SENTINEL_SIZE 4 struct crypto_mech_data { const EVP_CIPHER * (*cipher)(void); uint16_t keylen; uint16_t bsize; }; static struct crypto_mech_data cmdata[] = { /* AES with automatic padding, 256b key, 128b block */ { EVP_aes_256_cbc, 32, 16 }, /* sentinel */ { 0, 0, 0 } }; static struct crypto_mech_data *get_crypto_mech_data(enum obfmethod meth) { if (meth >= NUM_OBFMETHODS) { DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported cipher type\n"); return NULL; } return &cmdata[meth]; } int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen, enum obfmethod meth, char **obfpwd) { int ret; EVP_CIPHER_CTX ctx; struct crypto_mech_data *mech_props; TALLOC_CTX *tmp_ctx = NULL; unsigned char *keybuf; unsigned char *ivbuf; unsigned char *cryptotext; int ct_maxsize; int ctlen = 0; int digestlen = 0; int result_len; unsigned char *obfbuf; size_t obufsize = 0; size_t p = 0; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } EVP_CIPHER_CTX_init(&ctx); mech_props = get_crypto_mech_data(meth); if (mech_props == NULL) { ret = EINVAL; goto done; } keybuf = talloc_array(tmp_ctx, unsigned char, mech_props->keylen); if (keybuf == NULL) { ret = ENOMEM; goto done; } ivbuf = talloc_array(tmp_ctx, unsigned char, mech_props->bsize); if (ivbuf == NULL) { ret = ENOMEM; goto done; } RAND_bytes(keybuf, mech_props->keylen); RAND_bytes(ivbuf, mech_props->bsize); /* cryptotext buffer must be at least len(plaintext)+blocksize */ ct_maxsize = plen + (mech_props->bsize); cryptotext = talloc_array(tmp_ctx, unsigned char, ct_maxsize); if (!cryptotext) { ret = ENOMEM; goto done; } if (!EVP_EncryptInit_ex(&ctx, mech_props->cipher(), 0, keybuf, ivbuf)) { DEBUG(SSSDBG_CRIT_FAILURE, "Failure to initialize cipher contex\n"); ret = EIO; goto done; } /* sample data we'll encrypt and decrypt */ if (!EVP_EncryptUpdate(&ctx, cryptotext, &ctlen, (const unsigned char*)password, plen)) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot execute the encryption operation\n"); ret = EIO; goto done; } if(!EVP_EncryptFinal_ex(&ctx, cryptotext+ctlen, &digestlen)) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot finialize the encryption operation\n"); ret = EIO; goto done; } result_len = ctlen + digestlen; if (result_len < 0 || result_len > UINT16_MAX) { ret = ERANGE; goto done; } /* Pack the obfuscation buffer */ /* The buffer consists of: * uint16_t the type of the cipher * uint16_t length of the cryptotext in bytes (clen) * uint8_t[klen] key * uint8_t[blen] IV * uint8_t[clen] cryptotext * 4 bytes of "sentinel" denoting end of the buffer */ obufsize = sizeof(uint16_t) + sizeof(uint16_t) + mech_props->keylen + mech_props->bsize + result_len + OBF_BUFFER_SENTINEL_SIZE; obfbuf = talloc_array(tmp_ctx, unsigned char, obufsize); if (!obfbuf) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Writing method: %d\n", meth); SAFEALIGN_SET_UINT16(&obfbuf[p], meth, &p); DEBUG(SSSDBG_TRACE_FUNC, "Writing bufsize: %d\n", result_len); SAFEALIGN_SET_UINT16(&obfbuf[p], result_len, &p); safealign_memcpy(&obfbuf[p], keybuf, mech_props->keylen, &p); safealign_memcpy(&obfbuf[p], ivbuf, mech_props->bsize, &p); safealign_memcpy(&obfbuf[p], cryptotext, result_len, &p); safealign_memcpy(&obfbuf[p], OBF_BUFFER_SENTINEL, OBF_BUFFER_SENTINEL_SIZE, &p); /* Base64 encode the resulting buffer */ *obfpwd = sss_base64_encode(mem_ctx, obfbuf, obufsize); if (*obfpwd == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: talloc_free(tmp_ctx); EVP_CIPHER_CTX_cleanup(&ctx); return ret; } int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded, char **password) { int ret; EVP_CIPHER_CTX ctx; TALLOC_CTX *tmp_ctx = NULL; struct crypto_mech_data *mech_props; int plainlen; int digestlen; unsigned char *obfbuf = NULL; size_t obflen; char *pwdbuf; /* for unmarshaling data */ uint16_t meth; uint16_t ctsize; size_t p = 0; unsigned char *cryptotext; unsigned char *keybuf; unsigned char *ivbuf; unsigned char sentinel_check[OBF_BUFFER_SENTINEL_SIZE]; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } EVP_CIPHER_CTX_init(&ctx); /* Base64 decode the incoming buffer */ obfbuf = sss_base64_decode(tmp_ctx, b64encoded, &obflen); if (!obfbuf) { ret = ENOMEM; goto done; } /* unpack obfuscation buffer */ SAFEALIGN_COPY_UINT16_CHECK(&meth, obfbuf+p, obflen, &p); DEBUG(SSSDBG_TRACE_FUNC, "Read method: %d\n", meth); SAFEALIGN_COPY_UINT16_CHECK(&ctsize, obfbuf+p, obflen, &p); DEBUG(SSSDBG_TRACE_FUNC, "Read bufsize: %d\n", ctsize); mech_props = get_crypto_mech_data(meth); if (mech_props == NULL) { ret = EINVAL; goto done; } /* check that we got sane mechanism properties and cryptotext size */ memcpy(sentinel_check, obfbuf + p + mech_props->keylen + mech_props->bsize + ctsize, OBF_BUFFER_SENTINEL_SIZE); if (memcmp(sentinel_check, OBF_BUFFER_SENTINEL, OBF_BUFFER_SENTINEL_SIZE) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Obfuscation buffer seems corrupt, aborting\n"); ret = EFAULT; goto done; } /* copy out key, ivbuf and cryptotext */ keybuf = talloc_array(tmp_ctx, unsigned char, mech_props->keylen); if (keybuf == NULL) { ret = ENOMEM; goto done; } safealign_memcpy(keybuf, obfbuf+p, mech_props->keylen, &p); ivbuf = talloc_array(tmp_ctx, unsigned char, mech_props->bsize); if (ivbuf == NULL) { ret = ENOMEM; goto done; } safealign_memcpy(ivbuf, obfbuf+p, mech_props->bsize, &p); cryptotext = talloc_array(tmp_ctx, unsigned char, ctsize); if (cryptotext == NULL) { ret = ENOMEM; goto done; } safealign_memcpy(cryptotext, obfbuf+p, ctsize, &p); pwdbuf = talloc_array(tmp_ctx, char, ctsize); if (!pwdbuf) { ret = ENOMEM; goto done; } if (!EVP_DecryptInit_ex(&ctx, mech_props->cipher(), 0, keybuf, ivbuf)) { ret = EIO; goto done; } /* sample data we'll encrypt and decrypt */ if (!EVP_DecryptUpdate(&ctx, (unsigned char*)pwdbuf, &plainlen, cryptotext, ctsize)) { ret = EIO; goto done; } if(!EVP_DecryptFinal_ex(&ctx, (unsigned char*)pwdbuf+plainlen, &digestlen)) { ret = EIO; goto done; } *password = talloc_move(mem_ctx, &pwdbuf); ret = EOK; done: talloc_free(tmp_ctx); EVP_CIPHER_CTX_cleanup(&ctx); return ret; } sssd-1.13.4/src/util/crypto/PaxHeaders.16287/sss_crypto.h0000644000000000000000000000007412703456111017772 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.404792781 sssd-1.13.4/src/util/crypto/sss_crypto.h0000644002412700241270000000200312703456111021434 0ustar00jhrozekjhrozek00000000000000 int s3crypt_sha512(TALLOC_CTX *mmectx, const char *key, const char *salt, char **_hash); int s3crypt_gen_salt(TALLOC_CTX *memctx, char **_salt); /* Methods of obfuscation. */ enum obfmethod { AES_256, NUM_OBFMETHODS }; int test2(void); char *sss_base64_encode(TALLOC_CTX *mem_ctx, const unsigned char *in, size_t insize); unsigned char *sss_base64_decode(TALLOC_CTX *mem_ctx, const char *in, size_t *outsize); #define SSS_SHA1_LENGTH 20 int sss_hmac_sha1(const unsigned char *key, size_t key_len, const unsigned char *in, size_t in_len, unsigned char *out); int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen, enum obfmethod meth, char **obfpwd); int sss_password_decrypt(TALLOC_CTX *mem_ctx, char *b64encoded, char **password); sssd-1.13.4/src/util/PaxHeaders.16287/sss_nss.c0000644000000000000000000000007412703456111015730 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.865794344 sssd-1.13.4/src/util/sss_nss.c0000644002412700241270000001516112703456111017403 0ustar00jhrozekjhrozek00000000000000/* SSSD Utility functions related to ID information Copyright (C) Jan Zeleny 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/sss_nss.h" char *expand_homedir_template(TALLOC_CTX *mem_ctx, const char *template, struct sss_nss_homedir_ctx *homedir_ctx) { char *copy; char *p; char *n; char *result = NULL; char *res = NULL; TALLOC_CTX *tmp_ctx = NULL; const char *orig = NULL; if (template == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing template.\n"); return NULL; } if (homedir_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing home directory data.\n"); return NULL; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return NULL; copy = talloc_strdup(tmp_ctx, template); if (copy == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); goto done; } result = talloc_strdup(tmp_ctx, ""); if (result == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); goto done; } p = copy; while ( (n = strchr(p, '%')) != NULL) { *n = '\0'; n++; if ( *n == '\0' ) { DEBUG(SSSDBG_CRIT_FAILURE, "format error, single %% at the end of " "the template.\n"); goto done; } switch( *n ) { case 'u': if (homedir_ctx->username == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand user name template because user name " "is empty.\n"); goto done; } result = talloc_asprintf_append(result, "%s%s", p, homedir_ctx->username); break; case 'U': if (homedir_ctx->uid == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand uid template " "because uid is invalid.\n"); goto done; } result = talloc_asprintf_append(result, "%s%d", p, homedir_ctx->uid); break; case 'd': if (homedir_ctx->domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand domain name " "template because domain name " "is empty.\n"); goto done; } result = talloc_asprintf_append(result, "%s%s", p, homedir_ctx->domain); break; case 'f': if (homedir_ctx->domain == NULL || homedir_ctx->username == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand fully qualified " "name template because domain " "or user name is empty.\n"); goto done; } result = talloc_asprintf_append(result, "%s%s@%s", p, homedir_ctx->username, homedir_ctx->domain); break; case 'o': if (homedir_ctx->original == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Original home directory for %s is not available, " "using empty string\n", homedir_ctx->username); orig = ""; } else { orig = homedir_ctx->original; } result = talloc_asprintf_append(result, "%s%s", p, orig); break; case 'F': if (homedir_ctx->flatname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand domain name " "template because domain flat " "name is empty.\n"); goto done; } result = talloc_asprintf_append(result, "%s%s", p, homedir_ctx->flatname); break; case 'H': if (homedir_ctx->config_homedir_substr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand home directory substring template " "substring is empty.\n"); goto done; } result = talloc_asprintf_append(result, "%s%s", p, homedir_ctx->config_homedir_substr); break; case 'P': if (homedir_ctx->upn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot expand user principal name template " "string is empty.\n"); goto done; } result = talloc_asprintf_append(result, "%s%s", p, homedir_ctx->upn); break; case '%': result = talloc_asprintf_append(result, "%s%%", p); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "format error, unknown template " "[%%%c].\n", *n); goto done; } if (result == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n"); goto done; } p = n + 1; } result = talloc_asprintf_append(result, "%s", p); if (result == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n"); goto done; } res = talloc_move(mem_ctx, &result); done: talloc_zfree(tmp_ctx); return res; } sssd-1.13.4/src/util/PaxHeaders.16287/sss_selinux.c0000644000000000000000000000007412703456111016614 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.870794361 sssd-1.13.4/src/util/sss_selinux.c0000644002412700241270000002001412703456111020260 0ustar00jhrozekjhrozek00000000000000/* SSSD SELinux-related utility functions Authors: Jan Zeleny Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/sss_selinux.h" #include "util/sss_utf8.h" #include "db/sysdb_selinux.h" static bool match_entity(struct ldb_message_element *values, struct ldb_message_element *sought_values) { int i, j; for (i = 0; i < values->num_values; i++) { for (j = 0; j < sought_values->num_values; j++) { if (values->values[i].length != sought_values->values[j].length) { continue; } if (strncasecmp((char *)values->values[i].data, (char *)sought_values->values[j].data, values->values[i].length) == 0) return true; } } return false; } bool sss_selinux_match(struct sysdb_attrs *usermap, struct sysdb_attrs *user, struct sysdb_attrs *host, uint32_t *_priority) { struct ldb_message_element *users_el = NULL; struct ldb_message_element *usercat = NULL; struct ldb_message_element *hosts_el = NULL; struct ldb_message_element *hostcat = NULL; struct ldb_message_element *dn; struct ldb_message_element *memberof; int i; uint32_t priority = 0; bool matched_name; bool matched_group; bool matched_category; errno_t ret; if (usermap == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "NULL given as usermap! Skipping ...\n"); return false; } /* Search for user and host related elements */ for (i = 0; i < usermap->num; i++) { if (!strcasecmp(usermap->a[i].name, SYSDB_ORIG_MEMBER_USER)) { users_el = &usermap->a[i]; } else if (!strcasecmp(usermap->a[i].name, SYSDB_ORIG_MEMBER_HOST)) { hosts_el = &usermap->a[i]; } else if (!strcasecmp(usermap->a[i].name, SYSDB_USER_CATEGORY)) { usercat = &usermap->a[i]; } else if (!strcasecmp(usermap->a[i].name, SYSDB_HOST_CATEGORY)) { hostcat = &usermap->a[i]; } } if (user) { ret = sysdb_attrs_get_el(user, SYSDB_ORIG_DN, &dn); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "User does not have origDN\n"); return false; } ret = sysdb_attrs_get_el(user, SYSDB_ORIG_MEMBEROF, &memberof); if (ret != EOK) { DEBUG(SSSDBG_TRACE_ALL, "User does not have orig memberof, " "therefore it can't match to any rule\n"); return false; } /** * The rule won't match if user category != "all" and user map doesn't * contain neither user nor any of his groups in memberUser attribute */ matched_category = false; if (usercat != NULL) { for (i = 0; i < usercat->num_values; i++) { if (strcasecmp((char *)usercat->values[i].data, "all") == 0) { matched_category = true; break; } } } if (!matched_category) { if (users_el == NULL) { DEBUG(SSSDBG_TRACE_ALL, "No users specified in the rule!\n"); return false; } else { matched_name = match_entity(users_el, dn); matched_group = match_entity(users_el, memberof); if (matched_name) { priority |= SELINUX_PRIORITY_USER_NAME; } else if (matched_group) { priority |= SELINUX_PRIORITY_USER_GROUP; } else { DEBUG(SSSDBG_TRACE_ALL, "User did not match\n"); return false; } } } else { priority |= SELINUX_PRIORITY_USER_CAT; } } if (host) { ret = sysdb_attrs_get_el(host, SYSDB_ORIG_DN, &dn); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Host does not have origDN\n"); return false; } ret = sysdb_attrs_get_el(host, SYSDB_ORIG_MEMBEROF, &memberof); if (ret != EOK) { DEBUG(SSSDBG_TRACE_ALL, "Host does not have orig memberof, " "therefore it can't match to any rule\n"); return false; } /** * The rule won't match if host category != "all" and user map doesn't * contain neither host nor any of its groups in memberHost attribute */ matched_category = false; if (hostcat != NULL) { for (i = 0; i < hostcat->num_values; i++) { if (strcasecmp((char *)hostcat->values[i].data, "all") == 0) { matched_category = true; break; } } } if (!matched_category) { if (hosts_el == NULL) { DEBUG(SSSDBG_TRACE_ALL, "No users specified in the rule!\n"); return false; } else { matched_name = match_entity(hosts_el, dn); matched_group = match_entity(hosts_el, memberof); if (matched_name) { priority |= SELINUX_PRIORITY_HOST_NAME; } else if (matched_group) { priority |= SELINUX_PRIORITY_HOST_GROUP; } else { DEBUG(SSSDBG_TRACE_ALL, "Host did not match\n"); return false; } } } else { priority |= SELINUX_PRIORITY_HOST_CAT; } } if (_priority != NULL) { *_priority = priority; } return true; } errno_t sss_selinux_extract_user(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *username, struct sysdb_attrs **_user_attrs) { TALLOC_CTX *tmp_ctx; const char **attrs; struct sysdb_attrs *user_attrs; struct ldb_message *user_msg; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } attrs = talloc_array(tmp_ctx, const char *, 3); if (attrs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } attrs[0] = SYSDB_ORIG_DN; attrs[1] = SYSDB_ORIG_MEMBEROF; attrs[2] = NULL; ret = sysdb_search_user_by_name(tmp_ctx, domain, username, attrs, &user_msg); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_name failed.\n"); goto done; } user_attrs = talloc_zero(tmp_ctx, struct sysdb_attrs); if (user_attrs == NULL) { ret = ENOMEM; goto done; } user_attrs->a = talloc_steal(user_attrs, user_msg->elements); user_attrs->num = user_msg->num_elements; *_user_attrs = talloc_steal(mem_ctx, user_attrs); ret = EOK; done: talloc_free(tmp_ctx); return ret; } const char *sss_selinux_map_get_seuser(struct sysdb_attrs *usermap) { int i; const uint8_t *name; const uint8_t *template = (const uint8_t *)SYSDB_SELINUX_USER; for (i = 0; i < usermap->num; i++) { name = (const uint8_t *)usermap->a[i].name; if (sss_utf8_case_eq(name, template) == 0) { return (const char *)usermap->a[i].values[0].data; } } return NULL; } sssd-1.13.4/src/util/PaxHeaders.16287/sss_ldap.c0000644000000000000000000000007412703456111016045 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.801794127 sssd-1.13.4/src/util/sss_ldap.c0000644002412700241270000004423012703456111017517 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "config.h" #include "providers/ldap/sdap.h" #include "util/sss_ldap.h" #include "util/util.h" const char* sss_ldap_err2string(int err) { if (IS_SSSD_ERROR(err)) { return sss_strerror(err); } else { return ldap_err2string(err); } } int sss_ldap_get_diagnostic_msg(TALLOC_CTX *mem_ctx, LDAP *ld, char **_errmsg) { char *errmsg = NULL; int optret; optret = ldap_get_option(ld, SDAP_DIAGNOSTIC_MESSAGE, (void*)&errmsg); if (optret != LDAP_SUCCESS) { return EINVAL; } *_errmsg = talloc_strdup(mem_ctx, errmsg ? errmsg : "unknown error"); ldap_memfree(errmsg); if (*_errmsg == NULL) { return ENOMEM; } return EOK; } int sss_ldap_control_create(const char *oid, int iscritical, struct berval *value, int dupval, LDAPControl **ctrlp) { #ifdef HAVE_LDAP_CONTROL_CREATE return ldap_control_create(oid, iscritical, value, dupval, ctrlp); #else LDAPControl *lc = NULL; if (oid == NULL || ctrlp == NULL) { return LDAP_PARAM_ERROR; } lc = calloc(sizeof(LDAPControl), 1); if (lc == NULL) { return LDAP_NO_MEMORY; } lc->ldctl_oid = strdup(oid); if (lc->ldctl_oid == NULL) { free(lc); return LDAP_NO_MEMORY; } if (value != NULL && value->bv_val != NULL) { if (dupval == 0) { lc->ldctl_value = *value; } else { ber_dupbv(&lc->ldctl_value, value); if (lc->ldctl_value.bv_val == NULL) { free(lc->ldctl_oid); free(lc); return LDAP_NO_MEMORY; } } } lc->ldctl_iscritical = iscritical; *ctrlp = lc; return LDAP_SUCCESS; #endif } #ifdef HAVE_LDAP_INIT_FD struct sdap_async_sys_connect_state { long old_flags; struct tevent_fd *fde; int fd; socklen_t addr_len; struct sockaddr_storage addr; }; static void sdap_async_sys_connect_done(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *priv); static struct tevent_req *sdap_async_sys_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd, const struct sockaddr *addr, socklen_t addr_len) { struct tevent_req *req; struct sdap_async_sys_connect_state *state; long flags; int ret; int fret; flags = fcntl(fd, F_GETFL, 0); if (flags == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "fcntl F_GETFL failed.\n"); return NULL; } req = tevent_req_create(mem_ctx, &state, struct sdap_async_sys_connect_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->old_flags = flags; state->fd = fd; state->addr_len = addr_len; memcpy(&state->addr, addr, addr_len); ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "fcntl F_SETFL failed.\n"); goto done; } ret = connect(fd, addr, addr_len); if (ret == EOK) { goto done; } ret = errno; switch(ret) { case EINPROGRESS: case EINTR: state->fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ | TEVENT_FD_WRITE, sdap_async_sys_connect_done, req); if (state->fde == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_fd failed.\n"); ret = ENOMEM; goto done; } return req; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "connect failed [%d][%s].\n", ret, strerror(ret)); } done: fret = fcntl(fd, F_SETFL, flags); if (fret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "fcntl F_SETFL failed.\n"); } if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sdap_async_sys_connect_done(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *priv) { struct tevent_req *req = talloc_get_type(priv, struct tevent_req); struct sdap_async_sys_connect_state *state = tevent_req_data(req, struct sdap_async_sys_connect_state); int ret; int fret; errno = 0; ret = connect(state->fd, (struct sockaddr *) &state->addr, state->addr_len); if (ret != EOK) { ret = errno; if (ret == EINPROGRESS || ret == EINTR) { return; /* Try again later */ } DEBUG(SSSDBG_CRIT_FAILURE, "connect failed [%d][%s].\n", ret, strerror(ret)); } talloc_zfree(fde); fret = fcntl(state->fd, F_SETFL, state->old_flags); if (fret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "fcntl F_SETFL failed.\n"); } if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } return; } static int sdap_async_sys_connect_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static errno_t set_fd_flags_and_opts(int fd) { int ret; long flags; int dummy = 1; flags = fcntl(fd, F_GETFD, 0); if (flags == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fcntl F_GETFD failed [%d][%s].\n", ret, strerror(ret)); return ret; } flags = fcntl(fd, F_SETFD, flags| FD_CLOEXEC); if (flags == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fcntl F_SETFD failed [%d][%s].\n", ret, strerror(ret)); return ret; } /* SO_KEEPALIVE and TCP_NODELAY are set by OpenLDAP client libraries but * failures are ignored.*/ ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &dummy, sizeof(dummy)); if (ret != 0) { ret = errno; DEBUG(SSSDBG_FUNC_DATA, "setsockopt SO_KEEPALIVE failed.[%d][%s].\n", ret, strerror(ret)); } ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &dummy, sizeof(dummy)); if (ret != 0) { ret = errno; DEBUG(SSSDBG_FUNC_DATA, "setsockopt TCP_NODELAY failed.[%d][%s].\n", ret, strerror(ret)); } return EOK; } #define LDAP_PROTO_TCP 1 /* ldap:// */ #define LDAP_PROTO_UDP 2 /* reserved */ #define LDAP_PROTO_IPC 3 /* ldapi:// */ #define LDAP_PROTO_EXT 4 /* user-defined socket/sockbuf */ extern int ldap_init_fd(ber_socket_t fd, int proto, const char *url, LDAP **ld); static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq); static void sdap_async_sys_connect_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt); #endif struct sss_ldap_init_state { LDAP *ldap; int sd; const char *uri; #ifdef HAVE_LDAP_INIT_FD struct tevent_timer *connect_timeout; #endif }; static int sss_ldap_init_state_destructor(void *data) { struct sss_ldap_init_state *state = (struct sss_ldap_init_state *)data; if (state->ldap) { DEBUG(SSSDBG_TRACE_FUNC, "calling ldap_unbind_ext for ldap:[%p] sd:[%d]\n", state->ldap, state->sd); ldap_unbind_ext(state->ldap, NULL, NULL); } else if (state->sd != -1) { DEBUG(SSSDBG_TRACE_FUNC, "closing socket [%d]\n", state->sd); close(state->sd); } return 0; } struct tevent_req *sss_ldap_init_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *uri, struct sockaddr_storage *addr, int addr_len, int timeout) { int ret = EOK; struct tevent_req *req; struct sss_ldap_init_state *state; req = tevent_req_create(mem_ctx, &state, struct sss_ldap_init_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n"); return NULL; } talloc_set_destructor((TALLOC_CTX *)state, sss_ldap_init_state_destructor); state->ldap = NULL; state->uri = uri; #ifdef HAVE_LDAP_INIT_FD struct tevent_req *subreq; struct timeval tv; state->sd = socket(addr->ss_family, SOCK_STREAM, 0); if (state->sd == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "socket failed [%d][%s].\n", ret, strerror(ret)); goto fail; } ret = set_fd_flags_and_opts(state->sd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_fd_flags_and_opts failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_ALL, "Using file descriptor [%d] for LDAP connection.\n", state->sd); subreq = sdap_async_sys_connect_send(state, ev, state->sd, (struct sockaddr *) addr, addr_len); if (subreq == NULL) { ret = ENOMEM; DEBUG(SSSDBG_CRIT_FAILURE, "sdap_async_sys_connect_send failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "Setting %d seconds timeout for connecting\n", timeout); tv = tevent_timeval_current_ofs(timeout, 0); state->connect_timeout = tevent_add_timer(ev, subreq, tv, sdap_async_sys_connect_timeout, subreq); if (state->connect_timeout == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_timer failed.\n"); ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, sss_ldap_init_sys_connect_done, req); return req; fail: tevent_req_error(req, ret); #else DEBUG(SSSDBG_MINOR_FAILURE, "ldap_init_fd not available, " "will use ldap_initialize with uri [%s].\n", uri); state->sd = -1; ret = ldap_initialize(&state->ldap, uri); if (ret == LDAP_SUCCESS) { tevent_req_done(req); } else { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_initialize failed [%s].\n", sss_ldap_err2string(ret)); if (ret == LDAP_SERVER_DOWN) { tevent_req_error(req, ETIMEDOUT); } else { tevent_req_error(req, EIO); } } #endif tevent_req_post(req, ev); return req; } #ifdef HAVE_LDAP_INIT_FD static void sdap_async_sys_connect_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct tevent_req *connection_request; DEBUG(SSSDBG_CONF_SETTINGS, "The LDAP connection timed out\n"); connection_request = talloc_get_type(pvt, struct tevent_req); tevent_req_error(connection_request, ETIMEDOUT); } static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sss_ldap_init_state *state = tevent_req_data(req, struct sss_ldap_init_state); int ret; int lret; talloc_zfree(state->connect_timeout); ret = sdap_async_sys_connect_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sdap_async_sys_connect request failed: [%d]: %s.\n", ret, sss_strerror(ret)); goto fail; } /* Initialize LDAP handler */ lret = ldap_init_fd(state->sd, LDAP_PROTO_TCP, state->uri, &state->ldap); if (lret != LDAP_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_init_fd failed: %s. [%d][%s]\n", sss_ldap_err2string(lret), state->sd, state->uri); ret = lret == LDAP_SERVER_DOWN ? ETIMEDOUT : EIO; goto fail; } if (ldap_is_ldaps_url(state->uri)) { lret = ldap_install_tls(state->ldap); if (lret != LDAP_SUCCESS) { if (lret == LDAP_LOCAL_ERROR) { DEBUG(SSSDBG_FUNC_DATA, "TLS/SSL already in place.\n"); } else { DEBUG(SSSDBG_CRIT_FAILURE, "ldap_install_tls failed: %s\n", sss_ldap_err2string(lret)); ret = EIO; goto fail; } } } tevent_req_done(req); return; fail: tevent_req_error(req, ret); } #endif int sss_ldap_init_recv(struct tevent_req *req, LDAP **ldap, int *sd) { struct sss_ldap_init_state *state = tevent_req_data(req, struct sss_ldap_init_state); TEVENT_REQ_RETURN_ON_ERROR(req); /* Everything went well therefore we do not want to release resources */ talloc_set_destructor(state, NULL); *ldap = state->ldap; *sd = state->sd; return EOK; } /* * _filter will contain combined filters from all possible search bases * or NULL if it should be empty */ bool sss_ldap_dn_in_search_bases_len(TALLOC_CTX *mem_ctx, const char *dn, struct sdap_search_base **search_bases, char **_filter, int *_match_len) { struct sdap_search_base *base; int basedn_len, dn_len; int len_diff; int i, j; bool base_confirmed = false; bool comma_found = false; bool backslash_found = false; char *filter = NULL; bool ret = false; int match_len; if (dn == NULL) { DEBUG(SSSDBG_FUNC_DATA, "dn is NULL\n"); ret = false; goto done; } if (search_bases == NULL) { DEBUG(SSSDBG_FUNC_DATA, "search_bases is NULL\n"); ret = false; goto done; } dn_len = strlen(dn); for (i = 0; search_bases[i] != NULL; i++) { base = search_bases[i]; basedn_len = strlen(base->basedn); if (basedn_len > dn_len) { continue; } len_diff = dn_len - basedn_len; base_confirmed = (strncasecmp(&dn[len_diff], base->basedn, basedn_len) == 0); if (!base_confirmed) { continue; } match_len = basedn_len; switch (base->scope) { case LDAP_SCOPE_BASE: /* dn > base? */ if (len_diff != 0) { continue; } break; case LDAP_SCOPE_ONELEVEL: if (len_diff == 0) { /* Base object doesn't belong to scope=one * search */ continue; } comma_found = false; for (j = 0; j < len_diff - 1; j++) { /* ignore comma before base */ if (dn[j] == '\\') { backslash_found = true; } else if (dn[j] == ',' && !backslash_found) { comma_found = true; break; } else { backslash_found = false; } } /* it has at least one more level */ if (comma_found) { continue; } break; case LDAP_SCOPE_SUBTREE: /* dn length >= base dn length && base_confirmed == true */ break; default: DEBUG(SSSDBG_FUNC_DATA, "Unsupported scope: %d\n", base->scope); continue; } /* * If we get here, the dn is valid. * If no filter is set, than return true immediately. * Append filter otherwise. */ ret = true; if (_match_len) { *_match_len = match_len; } if (base->filter == NULL || _filter == NULL) { goto done; } else { filter = talloc_strdup_append(filter, base->filter); if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup_append() failed\n"); ret = false; goto done; } } } if (_filter != NULL) { if (filter != NULL) { *_filter = talloc_asprintf(mem_ctx, "(|%s)", filter); if (*_filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append() failed\n"); ret = false; goto done; } } else { *_filter = NULL; } } done: talloc_free(filter); return ret; } bool sss_ldap_dn_in_search_bases(TALLOC_CTX *mem_ctx, const char *dn, struct sdap_search_base **search_bases, char **_filter) { return sss_ldap_dn_in_search_bases_len(mem_ctx, dn, search_bases, _filter, NULL); } char *sss_ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t flags) { char hex[9]; /* 4 bytes in hex + terminating zero */ errno_t ret; ret = snprintf(hex, 9, "%08x", flags); if (ret != 8) { return NULL; } return talloc_asprintf(mem_ctx, "\\%c%c\\%c%c\\%c%c\\%c%c", hex[6], hex[7], hex[4], hex[5], hex[2], hex[3], hex[0], hex[1]); } sssd-1.13.4/src/util/PaxHeaders.16287/well_known_sids.c0000644000000000000000000000007412703456111017436 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.880794395 sssd-1.13.4/src/util/well_known_sids.c0000644002412700241270000002414412703456111021112 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2013 Red Hat Translate well-known SIDs to domains and names This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/strtonum.h" /* Well-Known SIDs are documented in section 2.4.2.4 "Well-Known SID * Structures" of the "[MS-DTYP]: Windows Data Types" document. */ #define DOM_SID_PREFIX "S-1-5-21-" #define DOM_SID_PREFIX_LEN (sizeof(DOM_SID_PREFIX) - 1) #define BUILTIN_SID_PREFIX "S-1-5-32-" #define BUILTIN_SID_PREFIX_LEN (sizeof(BUILTIN_SID_PREFIX) - 1) #define BUILTIN_DOM_NAME "BUILTIN" #define NT_SID_PREFIX "S-1-5-" #define NT_SID_PREFIX_LEN (sizeof(NT_SID_PREFIX) - 1) #define NT_DOM_NAME "NT AUTHORITY" #define SPECIAL_SID_PREFIX "S-1-" #define SPECIAL_SID_PREFIX_LEN (sizeof(SPECIAL_SID_PREFIX) - 1) #define NULL_DOM_NAME "NULL AUTHORITY" #define WORLD_DOM_NAME "WORLD AUTHORITY" #define LOCAL_DOM_NAME "LOCAL AUTHORITY" #define CREATOR_DOM_NAME "CREATOR AUTHORITY" #define NT_MAP_ENTRY(rid, name) {rid, NT_SID_PREFIX #rid, name} #define BUILTIN_MAP_ENTRY(rid, name) {rid, BUILTIN_SID_PREFIX #rid, name} #define SPECIAL_MAP_ENTRY(id_auth, rid, dom, name) \ {(48 + id_auth), (48 + rid), SPECIAL_SID_PREFIX #id_auth "-" #rid, dom, name} struct rid_sid_name { uint32_t rid; const char *sid; const char *name; }; struct special_map { const char id_auth; char rid; const char *sid; const char *dom; const char *name; }; struct rid_sid_name builtin_map[] = { BUILTIN_MAP_ENTRY(544, "Administrators"), BUILTIN_MAP_ENTRY(545, "Users"), BUILTIN_MAP_ENTRY(546, "Guests"), BUILTIN_MAP_ENTRY(547, "Power Users"), BUILTIN_MAP_ENTRY(548, "Account Operators"), BUILTIN_MAP_ENTRY(549, "Server Operators"), BUILTIN_MAP_ENTRY(550, "Print Operators"), BUILTIN_MAP_ENTRY(551, "Backup Operators"), BUILTIN_MAP_ENTRY(552, "Replicator"), BUILTIN_MAP_ENTRY(554, "Pre-Windows 2000 Compatible Access"), BUILTIN_MAP_ENTRY(555, "Remote Desktop Users"), BUILTIN_MAP_ENTRY(556, "Network Configuration Operators"), BUILTIN_MAP_ENTRY(557, "Incoming Forest Trust Builders"), BUILTIN_MAP_ENTRY(558, "Performance Monitor Users"), BUILTIN_MAP_ENTRY(559, "Performance Log Users"), BUILTIN_MAP_ENTRY(560, "Windows Authorization Access Group"), BUILTIN_MAP_ENTRY(561, "Terminal Server License Servers"), BUILTIN_MAP_ENTRY(562, "Distributed COM Users"), BUILTIN_MAP_ENTRY(568, "IIS_IUSRS"), BUILTIN_MAP_ENTRY(569, "Cryptographic Operators"), BUILTIN_MAP_ENTRY(573, "Event Log Readers"), BUILTIN_MAP_ENTRY(574, "Certificate Service DCOM Access"), BUILTIN_MAP_ENTRY(575, "RDS Remote Access Servers"), BUILTIN_MAP_ENTRY(576, "RDS Endpoint Servers"), BUILTIN_MAP_ENTRY(577, "RDS Management Servers"), BUILTIN_MAP_ENTRY(578, "Hyper-V Admins"), BUILTIN_MAP_ENTRY(579, "Access Control Assistance OPS"), BUILTIN_MAP_ENTRY(580, "Remote Management Users"), {UINT32_MAX, NULL, NULL} }; struct rid_sid_name nt_map[] = { NT_MAP_ENTRY(1, "DIALUP"), NT_MAP_ENTRY(2, "NETWORK"), NT_MAP_ENTRY(3, "BATCH"), NT_MAP_ENTRY(4, "INTERACTIVE"), NT_MAP_ENTRY(6, "SERVICE"), NT_MAP_ENTRY(7, "ANONYMOUS LOGON"), NT_MAP_ENTRY(8, "PROXY"), NT_MAP_ENTRY(9, "ENTERPRISE DOMAIN CONTROLLERS"), NT_MAP_ENTRY(10, "SELF"), NT_MAP_ENTRY(11, "Authenticated Users"), NT_MAP_ENTRY(12, "RESTRICTED"), NT_MAP_ENTRY(13, "TERMINAL SERVER USER"), NT_MAP_ENTRY(14, "REMOTE INTERACTIVE LOGON"), NT_MAP_ENTRY(15, "This Organization"), NT_MAP_ENTRY(17, "IUSR"), NT_MAP_ENTRY(18, "SYSTEM"), NT_MAP_ENTRY(19, "LOCAL SERVICE"), NT_MAP_ENTRY(20, "NETWORK SERVICE"), {UINT32_MAX, NULL, NULL} }; /* The code to handle the SIDs of the Null, World, Local and Creator * Authorities (id_auth=0,1,2,3 respectively) is optimized to handle only * single digit id_auth and rid. */ struct special_map sp_map[] = { SPECIAL_MAP_ENTRY(0, 0, NULL_DOM_NAME, "NULL SID"), SPECIAL_MAP_ENTRY(1, 0, WORLD_DOM_NAME, "Everyone"), SPECIAL_MAP_ENTRY(2, 0, LOCAL_DOM_NAME, "LOCAL"), SPECIAL_MAP_ENTRY(2, 1, LOCAL_DOM_NAME, "CONSOLE LOGON"), SPECIAL_MAP_ENTRY(3, 0, CREATOR_DOM_NAME, "CREATOR OWNER"), SPECIAL_MAP_ENTRY(3, 1, CREATOR_DOM_NAME, "CREATOR GROUP"), SPECIAL_MAP_ENTRY(3, 2, CREATOR_DOM_NAME, "CREATOR OWNER SERVER"), SPECIAL_MAP_ENTRY(3, 3, CREATOR_DOM_NAME, "CREATOR GROUP SERVER"), SPECIAL_MAP_ENTRY(3, 4, CREATOR_DOM_NAME, "OWNER RIGHTS"), SPECIAL_MAP_ENTRY(18,1, "ASSERTED IDENTITY", "AUTHENTICATION ASSERTION"), SPECIAL_MAP_ENTRY(18,2, "ASSERTED IDENTITY", "SERVICE ASSERTION"), {'\0', '\0', NULL, NULL, NULL} }; static errno_t handle_special_sids(const char *sid, const char **dom, const char **name) { size_t c; if (!isdigit(sid[SPECIAL_SID_PREFIX_LEN]) || sid[SPECIAL_SID_PREFIX_LEN + 1] != '-' || !isdigit(sid[SPECIAL_SID_PREFIX_LEN + 2]) || sid[SPECIAL_SID_PREFIX_LEN + 3] != '\0' ) { return EINVAL; } for (c = 0; sp_map[c].name != NULL; c++) { if (sid[SPECIAL_SID_PREFIX_LEN] == sp_map[c].id_auth && sid[SPECIAL_SID_PREFIX_LEN + 2] == sp_map[c].rid) { *name = sp_map[c].name; *dom = sp_map[c].dom; return EOK; } } return EINVAL; } static errno_t handle_special_names(const char *dom, const char *name, const char **sid) { size_t c; for (c = 0; sp_map[c].name != NULL; c++) { if (strcmp(name, sp_map[c].name) == 0 && strcmp(dom, sp_map[c].dom) == 0) { *sid = sp_map[c].sid; return EOK; } } return EINVAL; } static errno_t handle_rid_to_name_map(const char *sid, size_t prefix_len, struct rid_sid_name *map, const char* dom_name, const char **dom, const char **name) { uint32_t rid; char *endptr; size_t c; errno = 0; rid = (uint32_t) strtouint32(sid + prefix_len, &endptr, 10); if (errno != 0 || *endptr != '\0') { return EINVAL; } for (c = 0; map[c].name != NULL; c++) { if (rid == map[c].rid) { *name = map[c].name; *dom = dom_name; return EOK; } } return EINVAL; } static errno_t handle_name_to_sid_map(const char *name, struct rid_sid_name *map, const char **sid) { size_t c; for (c = 0; map[c].name != NULL; c++) { if (strcmp(name, map[c].name) == 0) { *sid = map[c].sid; return EOK; } } return EINVAL; } static errno_t handle_nt_sids(const char *sid, const char **dom, const char **name) { return handle_rid_to_name_map(sid, NT_SID_PREFIX_LEN, nt_map, NT_DOM_NAME, dom, name); } static errno_t handle_nt_names(const char *name, const char **sid) { return handle_name_to_sid_map(name, nt_map, sid); } static errno_t handle_builtin_sids(const char *sid, const char **dom, const char **name) { return handle_rid_to_name_map(sid, BUILTIN_SID_PREFIX_LEN, builtin_map, BUILTIN_DOM_NAME, dom, name); } static errno_t handle_builtin_names(const char *name, const char **sid) { return handle_name_to_sid_map(name, builtin_map, sid); } errno_t well_known_sid_to_name(const char *sid, const char **dom, const char **name) { int ret; if (sid == NULL || dom == NULL || name == NULL) { return EINVAL; } if (strncmp(sid, DOM_SID_PREFIX, DOM_SID_PREFIX_LEN) == 0) { ret = ENOENT; } else if (strncmp(sid, BUILTIN_SID_PREFIX, BUILTIN_SID_PREFIX_LEN) == 0) { ret = handle_builtin_sids(sid, dom, name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "handle_builtin_sids failed.\n"); } } else if (strncmp(sid, NT_SID_PREFIX, NT_SID_PREFIX_LEN) == 0) { ret = handle_nt_sids(sid, dom, name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "handle_nt_sids failed.\n"); } } else if (strncmp(sid, SPECIAL_SID_PREFIX, SPECIAL_SID_PREFIX_LEN) == 0) { ret = handle_special_sids(sid, dom, name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "handle_special_sids failed.\n"); } } else { ret = EINVAL; } return ret; } errno_t name_to_well_known_sid(const char *dom, const char *name, const char **sid) { int ret; if (sid == NULL || dom == NULL || name == NULL) { return EINVAL; } if (strcmp(dom, NT_DOM_NAME) == 0) { ret = handle_nt_names(name, sid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "handle_nt_name failed.\n"); } } else if (strcmp(dom, BUILTIN_DOM_NAME) == 0) { ret = handle_builtin_names(name, sid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "handle_builtin_name failed.\n"); } } else if (strcmp(dom, NULL_DOM_NAME) == 0 || strcmp(dom, WORLD_DOM_NAME) == 0 || strcmp(dom, LOCAL_DOM_NAME) == 0 || strcmp(dom, CREATOR_DOM_NAME) == 0) { ret = handle_special_names(dom, name, sid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "handle_special_name failed.\n"); } } else { ret = ENOENT; } return ret; } sssd-1.13.4/src/util/PaxHeaders.16287/usertools.c0000644000000000000000000000007412703456111016274 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.861794331 sssd-1.13.4/src/util/usertools.c0000644002412700241270000005112012703456111017742 0ustar00jhrozekjhrozek00000000000000/* SSSD User tools Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "confdb/confdb.h" #include "util/strtonum.h" #include "util/util.h" #include "util/safe-format-string.h" #include "responder/common/responder.h" #ifdef HAVE_LIBPCRE_LESSER_THAN_7 #define NAME_DOMAIN_PATTERN_OPTIONS (PCRE_EXTENDED) #else #define NAME_DOMAIN_PATTERN_OPTIONS (PCRE_DUPNAMES | PCRE_EXTENDED) #endif /* Function returns given realm name as new uppercase string */ char *get_uppercase_realm(TALLOC_CTX *memctx, const char *name) { char *realm; char *c; realm = talloc_strdup(memctx, name); if (!realm) { return NULL; } c = realm; while(*c != '\0') { *c = toupper(*c); c++; } return realm; } static int sss_names_ctx_destructor(struct sss_names_ctx *snctx) { if (snctx->re) { pcre_free(snctx->re); snctx->re = NULL; } return 0; } #define IPA_AD_DEFAULT_RE "(((?P[^\\\\]+)\\\\(?P.+$))|" \ "((?P[^@]+)@(?P.+$))|" \ "(^(?P[^@\\\\]+)$))" static errno_t get_id_provider_default_re(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, const char *conf_path, char **re_pattern) { #ifdef HAVE_LIBPCRE_LESSER_THAN_7 DEBUG(SSSDBG_MINOR_FAILURE, "The libpcre version on this system is too old. Only " "the user@DOMAIN name fully qualified name format will " "be supported\n"); *re_pattern = NULL; return EOK; #else int ret; size_t c; char *id_provider = NULL; struct provider_default_re { const char *name; const char *re; } provider_default_re[] = {{"ipa", IPA_AD_DEFAULT_RE}, {"ad", IPA_AD_DEFAULT_RE}, {NULL, NULL}}; ret = confdb_get_string(cdb, mem_ctx, conf_path, CONFDB_DOMAIN_ID_PROVIDER, NULL, &id_provider); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to read ID provider " \ "from conf db.\n"); goto done; } if (id_provider == NULL) { *re_pattern = NULL; } else { for (c = 0; provider_default_re[c].name != NULL; c++) { if (strcmp(id_provider, provider_default_re[c].name) == 0) { *re_pattern = talloc_strdup(mem_ctx, provider_default_re[c].re); if (*re_pattern == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } break; } } } ret = EOK; done: talloc_free(id_provider); return ret; #endif } static errno_t sss_fqnames_init(struct sss_names_ctx *nctx, const char *fq_fmt) { char *fq; nctx->fq_fmt = talloc_strdup(nctx, fq_fmt); if (nctx->fq_fmt == NULL) { return ENOMEM; } DEBUG(SSSDBG_CONF_SETTINGS, "Using fq format [%s].\n", nctx->fq_fmt); /* Fail if the name specifier is missing, or if the format is * invalid */ fq = sss_tc_fqname2 (nctx, nctx, "unused.example.com", "unused", "the-test-user"); if (fq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "The fq format is invalid [%s]\n", nctx->fq_fmt); return EINVAL; } else if (strstr (fq, "the-test-user") == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Username pattern not found in [%s]\n", nctx->fq_fmt); return ENOENT; } talloc_free (fq); return EOK; } int sss_names_init_from_args(TALLOC_CTX *mem_ctx, const char *re_pattern, const char *fq_fmt, struct sss_names_ctx **out) { struct sss_names_ctx *ctx; const char *errstr; int errval; int errpos; int ret; ctx = talloc_zero(mem_ctx, struct sss_names_ctx); if (!ctx) return ENOMEM; talloc_set_destructor(ctx, sss_names_ctx_destructor); ctx->re_pattern = talloc_strdup(ctx, re_pattern); if (ctx->re_pattern == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Using re [%s].\n", ctx->re_pattern); ret = sss_fqnames_init(ctx, fq_fmt); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not check the FQ names format" "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } ctx->re = pcre_compile2(ctx->re_pattern, NAME_DOMAIN_PATTERN_OPTIONS, &errval, &errstr, &errpos, NULL); if (!ctx->re) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid Regular Expression pattern at position %d." " (Error: %d [%s])\n", errpos, errval, errstr); ret = EFAULT; goto done; } *out = ctx; ret = EOK; done: if (ret != EOK) { talloc_free(ctx); } return ret; } int sss_names_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, const char *domain, struct sss_names_ctx **out) { TALLOC_CTX *tmpctx = NULL; char *conf_path = NULL; char *re_pattern = NULL;; char *fq_fmt = NULL; int ret; tmpctx = talloc_new(NULL); if (tmpctx == NULL) { ret = ENOMEM; goto done; } if (domain != NULL) { conf_path = talloc_asprintf(tmpctx, CONFDB_DOMAIN_PATH_TMPL, domain); if (conf_path == NULL) { ret = ENOMEM; goto done; } ret = confdb_get_string(cdb, tmpctx, conf_path, CONFDB_NAME_REGEX, NULL, &re_pattern); if (ret != EOK) goto done; } /* If not found in the domain, look in globals */ if (re_pattern == NULL) { ret = confdb_get_string(cdb, tmpctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_NAME_REGEX, NULL, &re_pattern); if (ret != EOK) goto done; } if (re_pattern == NULL && conf_path != NULL) { ret = get_id_provider_default_re(tmpctx, cdb, conf_path, &re_pattern); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get provider default regular " \ "expression for domain [%s].\n", domain); goto done; } } if (!re_pattern) { re_pattern = talloc_strdup(tmpctx, "(?P[^@]+)@?(?P[^@]*$)"); if (!re_pattern) { ret = ENOMEM; goto done; } #ifdef HAVE_LIBPCRE_LESSER_THAN_7 } else { DEBUG(SSSDBG_OP_FAILURE, "This binary was build with a version of libpcre that does " "not support non-unique named subpatterns.\n"); DEBUG(SSSDBG_OP_FAILURE, "Please make sure that your pattern [%s] only contains " "subpatterns with a unique name and uses " "the Python syntax (?P).\n", re_pattern); #endif } if (conf_path != NULL) { ret = confdb_get_string(cdb, tmpctx, conf_path, CONFDB_FULL_NAME_FORMAT, NULL, &fq_fmt); if (ret != EOK) goto done; } /* If not found in the domain, look in globals */ if (fq_fmt == NULL) { ret = confdb_get_string(cdb, tmpctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_FULL_NAME_FORMAT, NULL, &fq_fmt); if (ret != EOK) goto done; } if (!fq_fmt) { fq_fmt = talloc_strdup(tmpctx, CONFDB_DEFAULT_FULL_NAME_FORMAT); if (!fq_fmt) { ret = ENOMEM; goto done; } } ret = sss_names_init_from_args(mem_ctx, re_pattern, fq_fmt, out); done: talloc_free(tmpctx); return ret; } int sss_ad_default_names_ctx(TALLOC_CTX *mem_ctx, struct sss_names_ctx **_out) { return sss_names_init_from_args(mem_ctx, IPA_AD_DEFAULT_RE, CONFDB_DEFAULT_FULL_NAME_FORMAT, _out); } int sss_parse_name(TALLOC_CTX *memctx, struct sss_names_ctx *snctx, const char *orig, char **_domain, char **_name) { pcre *re = snctx->re; const char *result; int ovec[30]; int origlen; int ret, strnum; origlen = strlen(orig); ret = pcre_exec(re, NULL, orig, origlen, 0, PCRE_NOTEMPTY, ovec, 30); if (ret == PCRE_ERROR_NOMATCH) { return ERR_REGEX_NOMATCH; } else if (ret < 0) { DEBUG(SSSDBG_MINOR_FAILURE, "PCRE Matching error, %d\n", ret); return EINVAL; } if (ret == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Too many matches, the pattern is invalid.\n"); } strnum = ret; if (_name != NULL) { result = NULL; ret = pcre_get_named_substring(re, orig, ovec, strnum, "name", &result); if (ret < 0 || !result) { DEBUG(SSSDBG_OP_FAILURE, "Name not found!\n"); return EINVAL; } *_name = talloc_strdup(memctx, result); pcre_free_substring(result); if (!*_name) return ENOMEM; } if (_domain != NULL) { result = NULL; ret = pcre_get_named_substring(re, orig, ovec, strnum, "domain", &result); if (ret < 0 || !result) { DEBUG(SSSDBG_CONF_SETTINGS, "Domain not provided!\n"); *_domain = NULL; } else { /* ignore "" string */ if (*result) { *_domain = talloc_strdup(memctx, result); pcre_free_substring(result); if (!*_domain) return ENOMEM; } else { pcre_free_substring(result); *_domain = NULL; } } } return EOK; } int sss_parse_name_const(TALLOC_CTX *memctx, struct sss_names_ctx *snctx, const char *orig, const char **_domain, const char **_name) { char *domain; char *name; int ret; ret = sss_parse_name(memctx, snctx, orig, (_domain == NULL) ? NULL : &domain, (_name == NULL) ? NULL : &name); if (ret == EOK) { if (_domain != NULL) { *_domain = domain; } if (_name != NULL) { *_name = name; } } return ret; } static struct sss_domain_info * match_any_domain_or_subdomain_name( struct sss_domain_info *dom, const char *dmatch) { if (strcasecmp(dom->name, dmatch) == 0 || (dom->flat_name != NULL && strcasecmp(dom->flat_name, dmatch) == 0)) { return dom; } return find_domain_by_name(dom, dmatch, true); } int sss_parse_name_for_domains(TALLOC_CTX *memctx, struct sss_domain_info *domains, const char *default_domain, const char *orig, char **domain, char **name) { struct sss_domain_info *dom, *match = NULL; char *rdomain, *rname; char *dmatch, *nmatch; char *candidate_name = NULL; char *candidate_domain = NULL; bool name_mismatch = false; TALLOC_CTX *tmp_ctx; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } rname = NULL; rdomain = NULL; for (dom = domains; dom != NULL; dom = get_next_domain(dom, 0)) { ret = sss_parse_name(tmp_ctx, dom->names, orig, &dmatch, &nmatch); if (ret == EOK) { /* * If the name matched without the domain part, make note of it. * All the other domain expressions must agree on the domain-less * name. */ if (dmatch == NULL) { if (candidate_name == NULL) { candidate_name = nmatch; } else if (strcasecmp(candidate_name, nmatch) != 0) { name_mismatch = true; } /* * If a domain was returned, then it must match the name of the * domain that this expression was found on, or one of the * subdomains. */ } else { match = match_any_domain_or_subdomain_name (dom, dmatch); if (match != NULL) { DEBUG(SSSDBG_FUNC_DATA, "name '%s' matched expression for " "domain '%s', user is %s\n", orig, match->name, nmatch); rdomain = talloc_strdup(tmp_ctx, match->name); if (rdomain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } rname = nmatch; break; } else if (candidate_domain == NULL) { candidate_domain = dmatch; } } /* EINVAL is returned when name doesn't match */ } else if (ret != EINVAL) { goto done; } } if (rdomain == NULL && rname == NULL) { if (candidate_name && !name_mismatch) { DEBUG(SSSDBG_FUNC_DATA, "name '%s' matched without domain, " \ "user is %s\n", orig, nmatch); rdomain = NULL; if (default_domain != NULL) { rdomain = talloc_strdup(tmp_ctx, default_domain); if (rdomain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } for (dom = domains; dom != NULL; dom = get_next_domain(dom, 0)) { match = match_any_domain_or_subdomain_name(dom, rdomain); if (match != NULL) { break; } } if (match == NULL) { DEBUG(SSSDBG_FUNC_DATA, "default domain [%s] is currently " \ "not known\n", rdomain); *domain = talloc_steal(memctx, rdomain); ret = EAGAIN; goto done; } DEBUG(SSSDBG_FUNC_DATA, "using default domain [%s]\n", rdomain); } rname = candidate_name; } else if (candidate_domain) { /* This branch is taken when the input matches the configured * regular expression, but the domain is now known. Normally, this * is the case with a FQDN of a user from subdomain that was not * yet discovered */ *domain = talloc_steal(memctx, candidate_domain); ret = EAGAIN; goto done; } } if (rdomain == NULL && rname == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "name '%s' did not match any domain's expression\n", orig); ret = EINVAL; goto done; } if (domain != NULL) { *domain = talloc_steal(memctx, rdomain); } if (name != NULL) { *name = talloc_steal(memctx, rname); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } char * sss_get_cased_name(TALLOC_CTX *mem_ctx, const char *orig_name, bool case_sensitive) { return case_sensitive ? talloc_strdup(mem_ctx, orig_name) : sss_tc_utf8_str_tolower(mem_ctx, orig_name); } errno_t sss_get_cased_name_list(TALLOC_CTX *mem_ctx, const char * const *orig, bool case_sensitive, const char ***_cased) { const char **out; size_t num, i; if (orig == NULL) { *_cased = NULL; return EOK; } for (num=0; orig[num]; num++); /* count the num of strings */ if (num == 0) { *_cased = NULL; return EOK; } out = talloc_array(mem_ctx, const char *, num + 1); if (out == NULL) { return ENOMEM; } for (i = 0; i < num; i++) { out[i] = sss_get_cased_name(out, orig[i], case_sensitive); if (out[i] == NULL) { talloc_free(out); return ENOMEM; } } out[num] = NULL; *_cased = out; return EOK; } static inline const char * calc_flat_name(struct sss_domain_info *domain) { const char *s; s = domain->flat_name; if (s == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Flat name requested but domain has no" "flat name set, falling back to domain name\n"); s = domain->name; } return s; } char * sss_tc_fqname(TALLOC_CTX *mem_ctx, struct sss_names_ctx *nctx, struct sss_domain_info *domain, const char *name) { if (domain == NULL || nctx == NULL) return NULL; return sss_tc_fqname2 (mem_ctx, nctx, domain->name, calc_flat_name (domain), name); } static void safe_talloc_callback (void *data, const char *piece, size_t len) { char **output = data; if (*output != NULL) *output = talloc_strndup_append(*output, piece, len); } char * sss_tc_fqname2(TALLOC_CTX *mem_ctx, struct sss_names_ctx *nctx, const char *domain_name, const char *flat_dom_name, const char *name) { const char *args[] = { name, domain_name, flat_dom_name, NULL }; char *output; if (nctx == NULL) return NULL; output = talloc_strdup(mem_ctx, ""); if (safe_format_string_cb(safe_talloc_callback, &output, nctx->fq_fmt, args, 3) < 0) output = NULL; else if (output == NULL) errno = ENOMEM; return output; } int sss_fqname(char *str, size_t size, struct sss_names_ctx *nctx, struct sss_domain_info *domain, const char *name) { if (domain == NULL || nctx == NULL) return -EINVAL; return safe_format_string(str, size, nctx->fq_fmt, name, domain->name, calc_flat_name (domain), NULL); } char * sss_get_domain_name(TALLOC_CTX *mem_ctx, const char *orig_name, struct sss_domain_info *dom) { char *user_name; char *domain = NULL; int ret; /* check if the name already contains domain part */ if (dom->names != NULL) { ret = sss_parse_name(mem_ctx, dom->names, orig_name, &domain, NULL); if (ret == ERR_REGEX_NOMATCH) { DEBUG(SSSDBG_TRACE_FUNC, "sss_parse_name could not parse domain from [%s]. " "Assuming it is not FQDN.\n", orig_name); } else if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "sss_parse_name failed [%d]: %s\n", ret, sss_strerror(ret)); return NULL; } } if (IS_SUBDOMAIN(dom) && dom->fqnames && domain == NULL) { /* we always use the fully qualified name for subdomain users */ user_name = sss_tc_fqname(mem_ctx, dom->names, dom, orig_name); } else { user_name = talloc_strdup(mem_ctx, orig_name); } talloc_free(domain); return user_name; } errno_t sss_user_by_name_or_uid(const char *input, uid_t *_uid, gid_t *_gid) { uid_t uid; errno_t ret; char *endptr; struct passwd *pwd; /* Try if it's an ID first */ errno = 0; uid = strtouint32(input, &endptr, 10); if (errno != 0 || *endptr != '\0') { ret = errno; if (ret == ERANGE) { DEBUG(SSSDBG_OP_FAILURE, "UID [%s] is out of range.\n", input); return ret; } /* Nope, maybe a username? */ pwd = getpwnam(input); } else { pwd = getpwuid(uid); } if (pwd == NULL) { DEBUG(SSSDBG_OP_FAILURE, "[%s] is neither a valid UID nor a user name which could be " "resolved by getpwnam().\n", input); return EINVAL; } if (_uid) { *_uid = pwd->pw_uid; } if (_gid) { *_gid = pwd->pw_gid; } return EOK; } sssd-1.13.4/src/util/PaxHeaders.16287/util_sss_idmap.h0000644000000000000000000000007312703456111017260 xustar0030 atime=1460561751.661715665 29 ctime=1460561774.44579292 sssd-1.13.4/src/util/util_sss_idmap.h0000644002412700241270000000165712703456111020741 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __UTIL_SSS_IDMAP_H__ #define __UTIL_SSS_IDMAP_H__ void *sss_idmap_talloc(size_t size, void *pvt); void sss_idmap_talloc_free(void *ptr, void *pvt); #endif /* __UTIL_SSS_IDMAP_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/server.c0000644000000000000000000000007412703456111015543 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.860794327 sssd-1.13.4/src/util/server.c0000644002412700241270000004530412703456111017220 0ustar00jhrozekjhrozek00000000000000/* SSSD Servers setup routines Copyright (C) Andrew Tridgell 1992-2005 Copyright (C) Martin Pool 2002 Copyright (C) Jelmer Vernooij 2002 Copyright (C) James J Myers 2003 Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "util/util.h" #include "confdb/confdb.h" #include "monitor/monitor_interfaces.h" #ifdef HAVE_PRCTL #include #endif /******************************************************************* Close the low 3 fd's and open dev/null in their place. ********************************************************************/ static void close_low_fds(void) { #ifndef VALGRIND int fd; int i; close(0); close(1); close(2); /* try and use up these file descriptors, so silly library routines writing to stdout etc won't cause havoc */ for (i = 0; i < 3; i++) { fd = open("/dev/null", O_RDWR, 0); if (fd < 0) fd = open("/dev/null", O_WRONLY, 0); if (fd < 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Can't open /dev/null\n"); return; } if (fd != i) { DEBUG(SSSDBG_FATAL_FAILURE, "Didn't get file descriptor %d\n",i); return; } } #endif } static void deamon_parent_sigterm(int sig) { _exit(0); } /** Become a daemon, discarding the controlling terminal. **/ void become_daemon(bool Fork) { pid_t pid, cpid; int status; int ret, error; if (Fork) { pid = fork(); if (pid != 0) { /* Terminate parent process on demand so we can hold systemd * or initd from starting next service until sssd in initialized. * We use signals directly here because we don't have a tevent * context yet. */ CatchSignal(SIGTERM, deamon_parent_sigterm); /* or exit when sssd monitor is terminated */ do { errno = 0; cpid = waitpid(pid, &status, 0); if (cpid == 1) { /* An error occurred while waiting */ error = errno; if (error != EINTR) { DEBUG(SSSDBG_CRIT_FAILURE, "Error [%d][%s] while waiting for child\n", error, strerror(error)); /* Forcibly kill this child */ kill(pid, SIGKILL); ret = 1; } } error = 0; /* return error if we didn't exited normally */ ret = 1; if (WIFEXITED(status)) { /* but return our exit code otherwise */ ret = WEXITSTATUS(status); } } while (error == EINTR); _exit(ret); } } /* detach from the terminal */ setsid(); /* chdir to / to be sure we're not on a remote filesystem */ errno = 0; if(chdir("/") == -1) { ret = errno; DEBUG(SSSDBG_FATAL_FAILURE, "Cannot change directory (%d [%s])\n", ret, strerror(ret)); return; } /* Close fd's 0,1,2. Needed if started by rsh */ close_low_fds(); } int pidfile(const char *path, const char *name) { char pid_str[32]; pid_t pid; char *file; int fd; int ret, err; ssize_t len; size_t size; ssize_t written; ssize_t pidlen = sizeof(pid_str) - 1; file = talloc_asprintf(NULL, "%s/%s.pid", path, name); if (!file) { return ENOMEM; } fd = open(file, O_RDONLY, 0644); err = errno; if (fd != -1) { errno = 0; len = sss_atomic_read_s(fd, pid_str, pidlen); ret = errno; if (len == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret)); close(fd); talloc_free(file); return EINVAL; } /* Ensure NULL-termination */ pid_str[len] = '\0'; /* let's check the pid */ pid = (pid_t)atoi(pid_str); if (pid != 0) { errno = 0; ret = kill(pid, 0); /* succeeded in signaling the process -> another sssd process */ if (ret == 0) { close(fd); talloc_free(file); return EEXIST; } if (ret != 0 && errno != ESRCH) { err = errno; close(fd); talloc_free(file); return err; } } /* nothing in the file or no process */ close(fd); ret = unlink(file); /* non-fatal failure */ if (ret != EOK) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Failed to remove file: %s - %d [%s]!\n", file, ret, sss_strerror(ret)); } } else { if (err != ENOENT) { talloc_free(file); return err; } } fd = open(file, O_CREAT | O_WRONLY | O_EXCL, 0644); err = errno; if (fd == -1) { talloc_free(file); return err; } talloc_free(file); memset(pid_str, 0, sizeof(pid_str)); snprintf(pid_str, sizeof(pid_str) -1, "%u\n", (unsigned int) getpid()); size = strlen(pid_str); errno = 0; written = sss_atomic_write_s(fd, pid_str, size); if (written == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s]\n", err, strerror(err)); close(fd); return err; } if (written != size) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrote %zd bytes expected %zu\n", written, size); close(fd); return EIO; } close(fd); return 0; } void orderly_shutdown(int status) { #if HAVE_GETPGRP static int sent_sigterm; if (sent_sigterm == 0 && getpgrp() == getpid()) { DEBUG(SSSDBG_FATAL_FAILURE, "SIGTERM: killing children\n"); sent_sigterm = 1; kill(-getpgrp(), SIGTERM); } #endif if (status == 0) sss_log(SSS_LOG_INFO, "Shutting down"); exit(status); } static void default_quit(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { orderly_shutdown(0); } #ifndef HAVE_PRCTL static void sig_segv_abrt(int sig) { DEBUG(SSSDBG_FATAL_FAILURE, "Received signal %s, shutting down\n", strsignal(sig)); orderly_shutdown(1); } #endif /* HAVE_PRCTL */ /* setup signal masks */ static void setup_signals(void) { /* we are never interested in SIGPIPE */ BlockSignals(true, SIGPIPE); #if defined(SIGFPE) /* we are never interested in SIGFPE */ BlockSignals(true, SIGFPE); #endif /* We are no longer interested in USR1 */ BlockSignals(true, SIGUSR1); /* We are no longer interested in SIGINT except for monitor */ BlockSignals(true, SIGINT); #if defined(SIGUSR2) /* We are no longer interested in USR2 */ BlockSignals(true, SIGUSR2); #endif /* POSIX demands that signals are inherited. If the invoking process has * these signals masked, we will have problems, as we won't receive them. */ BlockSignals(false, SIGHUP); BlockSignals(false, SIGTERM); #ifndef HAVE_PRCTL /* If prctl is not defined on the system, try to handle * some common termination signals gracefully */ CatchSignal(SIGSEGV, sig_segv_abrt); CatchSignal(SIGABRT, sig_segv_abrt); #endif } /* handle io on stdin */ static void server_stdin_handler(struct tevent_context *event_ctx, struct tevent_fd *fde, uint16_t flags, void *private) { const char *binary_name = (const char *)private; uint8_t c; errno = 0; if (sss_atomic_read_s(0, &c, 1) == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "%s: EOF on stdin - terminating\n", binary_name); #if HAVE_GETPGRP if (getpgrp() == getpid()) { kill(-getpgrp(), SIGTERM); } #endif exit(0); } } /* main server helpers. */ int die_if_parent_died(void) { #ifdef HAVE_PRCTL int ret; errno = 0; ret = prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0); if (ret != 0) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "prctl failed [%d]: %s\n", ret, strerror(ret)); return ret; } #endif return EOK; } struct logrotate_ctx { struct confdb_ctx *confdb; const char *confdb_path; }; static void te_server_hup(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { errno_t ret; struct logrotate_ctx *lctx = talloc_get_type(private_data, struct logrotate_ctx); DEBUG(SSSDBG_CRIT_FAILURE, "Received SIGHUP. Rotating logfiles.\n"); ret = server_common_rotate_logs(lctx->confdb, lctx->confdb_path); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not reopen log file [%s]\n", strerror(ret)); } } errno_t server_common_rotate_logs(struct confdb_ctx *confdb, const char *conf_path) { errno_t ret; int old_debug_level = debug_level; ret = rotate_debug_files(); if (ret) { sss_log(SSS_LOG_ALERT, "Could not rotate debug files! [%d][%s]\n", ret, strerror(ret)); return ret; } /* Get new debug level from the confdb */ ret = confdb_get_int(confdb, conf_path, CONFDB_SERVICE_DEBUG_LEVEL, old_debug_level, &debug_level); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n", ret, strerror(ret)); /* Try to proceed with the old value */ debug_level = old_debug_level; } if (debug_level != old_debug_level) { DEBUG(SSSDBG_FATAL_FAILURE, "Debug level changed to %#.4x\n", debug_level); debug_level = debug_convert_old_level(debug_level); } return EOK; } static const char *get_db_path(void) { #ifdef UNIT_TESTING #ifdef TEST_DB_PATH return TEST_DB_PATH; #else #error "TEST_DB_PATH must be defined when unit testing server.c!" #endif /* TEST_DB_PATH */ #else return DB_PATH; #endif /* UNIT_TESTING */ } static const char *get_pid_path(void) { #ifdef UNIT_TESTING #ifdef TEST_PID_PATH return TEST_PID_PATH; #else #error "TEST_PID_PATH must be defined when unit testing server.c!" #endif /* TEST_PID_PATH */ #else return PID_PATH; #endif } int server_setup(const char *name, int flags, uid_t uid, gid_t gid, const char *conf_entry, struct main_context **main_ctx) { struct tevent_context *event_ctx; struct main_context *ctx; uint16_t stdin_event_flags; char *conf_db; int ret = EOK; bool dt; bool dl; bool dm; struct tevent_signal *tes; struct logrotate_ctx *lctx; char *locale; ret = chown_debug_file(NULL, uid, gid); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot chown the debug files, debugging might not work!\n"); } ret = become_user(uid, gid); if (ret != EOK) { DEBUG(SSSDBG_FUNC_DATA, "Cannot become user [%"SPRIuid"][%"SPRIgid"].\n", uid, gid); return ret; } debug_prg_name = strdup(name); if (!debug_prg_name) { return ENOMEM; } setenv("_SSS_LOOPS", "NO", 0); /* To make sure the domain cannot be set from the environment, unset the * variable explicitly when setting up any server. Backends later set the * value after reading domain from the configuration */ ret = unsetenv(SSS_DOM_ENV); if (ret != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Unsetting "SSS_DOM_ENV" failed, journald " "logging mightnot work as expected\n"); } setup_signals(); /* we want default permissions on created files to be very strict */ umask(SSS_DFL_UMASK); if (flags & FLAGS_DAEMON) { DEBUG(SSSDBG_IMPORTANT_INFO, "Becoming a daemon.\n"); become_daemon(true); } if (flags & FLAGS_PID_FILE) { ret = pidfile(get_pid_path(), name); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error creating pidfile: %s/%s.pid! " "(%d [%s])\n", get_pid_path(), name, ret, strerror(ret)); return ret; } } /* Set up locale */ locale = setlocale(LC_ALL, ""); if (locale == NULL) { /* Just print debug message and continue */ DEBUG(SSSDBG_TRACE_FUNC, "Unable to set locale\n"); } bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); /* the event context is the top level structure. * Everything else should hang off that */ event_ctx = tevent_context_init(talloc_autofree_context()); if (event_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "The event context initialiaziton failed\n"); return 1; } /* Set up an event handler for a SIGINT */ tes = tevent_add_signal(event_ctx, event_ctx, SIGINT, 0, default_quit, NULL); if (tes == NULL) { return EIO; } /* Set up an event handler for a SIGTERM */ tes = tevent_add_signal(event_ctx, event_ctx, SIGTERM, 0, default_quit, NULL); if (tes == NULL) { return EIO; } ctx = talloc(event_ctx, struct main_context); if (ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory, aborting!\n"); return ENOMEM; } ctx->parent_pid = getppid(); ctx->event_ctx = event_ctx; conf_db = talloc_asprintf(ctx, "%s/%s", get_db_path(), CONFDB_FILE); if (conf_db == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory, aborting!\n"); return ENOMEM; } ret = confdb_init(ctx, &ctx->confdb_ctx, conf_db); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "The confdb initialization failed\n"); return ret; } if (debug_level == SSSDBG_UNRESOLVED) { /* set debug level if any in conf_entry */ ret = confdb_get_int(ctx->confdb_ctx, conf_entry, CONFDB_SERVICE_DEBUG_LEVEL, SSSDBG_DEFAULT, &debug_level); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) " "[%s]\n", ret, strerror(ret)); return ret; } debug_level = debug_convert_old_level(debug_level); } /* same for debug timestamps */ if (debug_timestamps == SSSDBG_TIMESTAMP_UNRESOLVED) { ret = confdb_get_bool(ctx->confdb_ctx, conf_entry, CONFDB_SERVICE_DEBUG_TIMESTAMPS, SSSDBG_TIMESTAMP_DEFAULT, &dt); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) " "[%s]\n", ret, strerror(ret)); return ret; } if (dt) debug_timestamps = 1; else debug_timestamps = 0; } /* same for debug microseconds */ if (debug_microseconds == SSSDBG_MICROSECONDS_UNRESOLVED) { ret = confdb_get_bool(ctx->confdb_ctx, conf_entry, CONFDB_SERVICE_DEBUG_MICROSECONDS, SSSDBG_MICROSECONDS_DEFAULT, &dm); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) " "[%s]\n", ret, strerror(ret)); return ret; } if (dm) debug_microseconds = 1; else debug_microseconds = 0; } /* same for debug to file */ dl = (debug_to_file != 0); ret = confdb_get_bool(ctx->confdb_ctx, conf_entry, CONFDB_SERVICE_DEBUG_TO_FILES, dl, &dl); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n", ret, strerror(ret)); return ret; } if (dl) debug_to_file = 1; /* before opening the log file set up log rotation */ lctx = talloc_zero(ctx, struct logrotate_ctx); if (!lctx) return ENOMEM; lctx->confdb = ctx->confdb_ctx; lctx->confdb_path = conf_entry; tes = tevent_add_signal(ctx->event_ctx, ctx, SIGHUP, 0, te_server_hup, lctx); if (tes == NULL) { return EIO; } /* open log file if told so */ if (debug_to_file) { ret = open_debug_file(); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error setting up logging (%d) " "[%s]\n", ret, strerror(ret)); return ret; } } sss_log(SSS_LOG_INFO, "Starting up"); DEBUG(SSSDBG_TRACE_FUNC, "CONFDB: %s\n", conf_db); if (flags & FLAGS_INTERACTIVE) { /* terminate when stdin goes away */ stdin_event_flags = TEVENT_FD_READ; } else { /* stay alive forever */ stdin_event_flags = 0; } /* catch EOF on stdin */ #ifdef SIGTTIN signal(SIGTTIN, SIG_IGN); #endif tevent_add_fd(event_ctx, event_ctx, STDIN_FILENO, stdin_event_flags, server_stdin_handler, discard_const(name)); *main_ctx = ctx; return EOK; } void server_loop(struct main_context *main_ctx) { /* wait for events - this is where the server sits for most of its life */ tevent_loop_wait(main_ctx->event_ctx); /* as everything hangs off this event context, freeing it should initiate a clean shutdown of all services */ talloc_free(main_ctx->event_ctx); } sssd-1.13.4/src/util/PaxHeaders.16287/sss_cli_cmd.h0000644000000000000000000000007412703456111016524 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.412792808 sssd-1.13.4/src/util/sss_cli_cmd.h0000644002412700241270000000166612703456111020204 0ustar00jhrozekjhrozek00000000000000/* SSSD - cmd2str util Copyright (C) Petr Cech 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSS_CLI_CMD_H__ #define __SSS_CLI_CMD_H__ #include "sss_client/sss_cli.h" /* Translate sss_cli_command to human readable form. */ const char *sss_cmd2str(enum sss_cli_command cmd); #endif /* __SSS_CLI_CMD_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/atomic_io.c0000644000000000000000000000007412703456111016200 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.867794351 sssd-1.13.4/src/util/atomic_io.c0000644002412700241270000000324612703456111017654 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/atomic_io.h" /* based on code from libssh */ ssize_t sss_atomic_io_s(int fd, void *buf, size_t n, bool do_read) { char *b = buf; size_t pos = 0; ssize_t res; struct pollfd pfd; pfd.fd = fd; pfd.events = do_read ? POLLIN : POLLOUT; while (n > pos) { if (do_read) { res = read(fd, b + pos, n - pos); } else { res = write(fd, b + pos, n - pos); } switch (res) { case -1: if (errno == EINTR) { continue; } if (errno == EAGAIN || errno == EWOULDBLOCK) { (void) poll(&pfd, 1, -1); continue; } return -1; case 0: /* read returns 0 on end-of-file */ errno = do_read ? 0 : EPIPE; return pos; default: pos += (size_t) res; } } return pos; } sssd-1.13.4/src/util/PaxHeaders.16287/util_safealign.h0000644000000000000000000000007412703456111017230 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.443792913 sssd-1.13.4/src/util/util_safealign.h0000644002412700241270000001147612703456111020710 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Simo Sorce Copyright (C) Red Hat, Inc 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ /* CAUTION: * This file is also used in sss_client (pam, nss). Therefore it has to be * minimalist and cannot include DEBUG macros or header file util.h. */ #ifndef _UTIL_SAFEALIGN_H #define _UTIL_SAFEALIGN_H #include #include /* Use this macro to suppress alignment warnings (use it * only to suppress false-positives) */ #define DISCARD_ALIGN(ptr, type) ((type)(void *)(ptr)) #define IS_ALIGNED(ptr, type) \ ((uintptr_t)(ptr) % sizeof(type) == 0) #define PADDING_SIZE(base, type) \ ((sizeof(type) - ((base) % sizeof(type))) % sizeof(type)) #define SIZE_T_OVERFLOW(current, add) \ (((size_t)(add)) > (SIZE_MAX - ((size_t)(current)))) static inline void safealign_memcpy(void *dest, const void *src, size_t n, size_t *counter) { memcpy(dest, src, n); if (counter) { *counter += n; } } #define SAFEALIGN_SETMEM_VALUE(dest, value, type, pctr) do { \ type CV_MACRO_val = (type)(value); \ safealign_memcpy(dest, &CV_MACRO_val, sizeof(type), pctr); \ } while(0) /* SAFEALIGN_COPY_INT64(void *dest, void *src, size_t *pctr) * This macro will safely copy sizeof(int64_t) bytes from memory * location pointed by 'src' to memory location pointed by 'dest'. * If the 'pctr' pointer is not NULL, the value it points to will * be incremented by sizeof(int64_t). */ #define SAFEALIGN_COPY_INT64(dest, src, pctr) \ safealign_memcpy(dest, src, sizeof(int64_t), pctr) /* SAFEALIGN_SETMEM_INT64(void *dest, int64_t value, size_t *pctr) * This macro will safely assign an int64_t value to the memory * location pointed by 'dest'. If the 'pctr' pointer is not NULL, * the value it points to will be incremented by sizeof(int64_t). */ #define SAFEALIGN_SETMEM_INT64(dest, value, pctr) \ SAFEALIGN_SETMEM_VALUE(dest, value, int64_t, pctr) /* SAFEALIGN_COPY_UINT32(void *dest, void *src, size_t *pctr) */ #define SAFEALIGN_COPY_UINT32(dest, src, pctr) \ safealign_memcpy(dest, src, sizeof(uint32_t), pctr) /* SAFEALIGN_SETMEM_UINT32(void *dest, uint32_t value, size_t *pctr) */ #define SAFEALIGN_SETMEM_UINT32(dest, value, pctr) \ SAFEALIGN_SETMEM_VALUE(dest, value, uint32_t, pctr) /* SAFEALIGN_COPY_INT32(void *dest, void *src, size_t *pctr) */ #define SAFEALIGN_COPY_INT32(dest, src, pctr) \ safealign_memcpy(dest, src, sizeof(int32_t), pctr) /* SAFEALIGN_SETMEM_INT32(void *dest, int32_t value, size_t *pctr) */ #define SAFEALIGN_SETMEM_INT32(dest, value, pctr) \ SAFEALIGN_SETMEM_VALUE(dest, value, int32_t, pctr) /* SAFEALIGN_COPY_UINT16(void *dest, void *src, size_t *pctr) */ #define SAFEALIGN_COPY_UINT16(dest, src, pctr) \ safealign_memcpy(dest, src, sizeof(uint16_t), pctr) /* SAFEALIGN_SETMEM_UINT16(void *dest, uint16_t value, size_t *pctr) */ #define SAFEALIGN_SETMEM_UINT16(dest, value, pctr) \ SAFEALIGN_SETMEM_VALUE(dest, value, uint16_t, pctr) /* These macros are the same as their equivalents without _CHECK suffix, * but additionally make the caller return EINVAL immediatelly if *pctr * would excceed len. */ #define SAFEALIGN_COPY_UINT32_CHECK(dest, src, len, pctr) do { \ if ((*(pctr) + sizeof(uint32_t)) > (len) || \ SIZE_T_OVERFLOW(*(pctr), sizeof(uint32_t))) { return EINVAL; } \ safealign_memcpy(dest, src, sizeof(uint32_t), pctr); \ } while(0) #define SAFEALIGN_COPY_INT32_CHECK(dest, src, len, pctr) do { \ if ((*(pctr) + sizeof(int32_t)) > (len) || \ SIZE_T_OVERFLOW(*(pctr), sizeof(int32_t))) { return EINVAL; } \ safealign_memcpy(dest, src, sizeof(int32_t), pctr); \ } while(0) #define SAFEALIGN_COPY_UINT16_CHECK(dest, src, len, pctr) do { \ if ((*(pctr) + sizeof(uint16_t)) > (len) || \ SIZE_T_OVERFLOW(*(pctr), sizeof(uint16_t))) { return EINVAL; } \ safealign_memcpy(dest, src, sizeof(uint16_t), pctr); \ } while(0) /* Aliases for backward compatibility. */ #define SAFEALIGN_SET_VALUE SAFEALIGN_SETMEM_VALUE #define SAFEALIGN_SET_INT64 SAFEALIGN_SETMEM_INT64 #define SAFEALIGN_SET_UINT32 SAFEALIGN_SETMEM_UINT32 #define SAFEALIGN_SET_INT32 SAFEALIGN_SETMEM_INT32 #define SAFEALIGN_SET_UINT16 SAFEALIGN_SETMEM_UINT16 #endif /* _UTIL_SAFEALIGN_H */ sssd-1.13.4/src/util/PaxHeaders.16287/backup_file.c0000644000000000000000000000007412703456111016501 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.862794334 sssd-1.13.4/src/util/backup_file.c0000644002412700241270000000627212703456111020157 0ustar00jhrozekjhrozek00000000000000/* SSSD Backup files Copyright (C) Simo Sorce 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include #include #include #define BUFFER_SIZE 65536 int backup_file(const char *src_file, int dbglvl) { TALLOC_CTX *tmp_ctx = NULL; char buf[BUFFER_SIZE]; int src_fd = -1; int dst_fd = -1; char *dst_file; ssize_t numread; ssize_t written; int ret, i; src_fd = open(src_file, O_RDONLY); if (src_fd < 0) { ret = errno; DEBUG(dbglvl, "Error (%d [%s]) opening source file %s\n", ret, strerror(ret), src_file); goto done; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } /* try a few times to come up with a new backup file, then give up */ for (i = 0; i < 10; i++) { if (i == 0) { dst_file = talloc_asprintf(tmp_ctx, "%s.bak", src_file); } else { dst_file = talloc_asprintf(tmp_ctx, "%s.bak%d", src_file, i); } if (!dst_file) { ret = ENOMEM; goto done; } errno = 0; dst_fd = open(dst_file, O_CREAT|O_EXCL|O_WRONLY, 0600); ret = errno; if (dst_fd >= 0) break; if (ret != EEXIST) { DEBUG(dbglvl, "Error (%d [%s]) opening destination file %s\n", ret, strerror(ret), dst_file); goto done; } } if (ret != 0) { DEBUG(dbglvl, "Error (%d [%s]) opening destination file %s\n", ret, strerror(ret), dst_file); goto done; } /* copy file contents */ while (1) { errno = 0; numread = sss_atomic_read_s(src_fd, buf, BUFFER_SIZE); if (numread < 0) { ret = errno; DEBUG(dbglvl, "Error (%d [%s]) reading from source %s\n", ret, strerror(ret), src_file); goto done; } if (numread == 0) break; errno = 0; written = sss_atomic_write_s(dst_fd, buf, numread); if (written == -1) { ret = errno; DEBUG(dbglvl, "Error (%d [%s]) writing to destination %s\n", ret, strerror(ret), dst_file); goto done; } if (written != numread) { DEBUG(dbglvl, "Wrote %zd bytes expected %zd bytes\n", written, numread); ret = EIO; goto done; } } ret = EOK; done: if (src_fd != -1) close(src_fd); if (dst_fd != -1) close(dst_fd); talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/util/PaxHeaders.16287/sss_config.c0000644000000000000000000000007412703456111016372 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.708793812 sssd-1.13.4/src/util/sss_config.c0000644002412700241270000002665312703456111020055 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/sss_config.h" #define PATH_SECTION "/files/%s/target[. = \"%s\"]" #define PATH_OPTION PATH_SECTION "/%s" #define build_section_path(mem_ctx, config_ctx, section) \ talloc_asprintf(mem_ctx, PATH_SECTION, config_ctx->file, section) #define build_option_path(mem_ctx, config_ctx, section, option) \ talloc_asprintf(mem_ctx, PATH_OPTION, config_ctx->file, section, option) struct sss_config_ctx { augeas *auges_ctx; const char *file; }; static errno_t sss_config_set_option(struct sss_config_ctx *ctx, const char *section, const char *option, const char *value) { TALLOC_CTX *tmp_ctx = NULL; char *target_path = NULL; char *option_path = NULL; errno_t ret; int aug_ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } target_path = build_section_path(tmp_ctx, ctx, section); if (target_path == NULL) { ret = ENOMEM; goto done; } option_path = build_option_path(tmp_ctx, ctx, section, option); if (option_path == NULL) { ret = ENOMEM; goto done; } /* Set configuration option: * * # make sure the section exists * set /files/$file/target[. = "$section"] $section * * # set value * set /files/$file/target[. = "$section"]/$option $value */ aug_ret = aug_set(ctx->auges_ctx, target_path, section); if (aug_ret != 0) { ret = EIO; goto done; } aug_ret = aug_set(ctx->auges_ctx, option_path, value); if (aug_ret != 0) { ret = EIO; goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t sss_config_rm_option(struct sss_config_ctx *ctx, const char *section, const char *option) { TALLOC_CTX *tmp_ctx = NULL; char *option_path = NULL; errno_t ret; int aug_ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } option_path = build_option_path(tmp_ctx, ctx, section, option); if (option_path == NULL) { ret = ENOMEM; goto done; } /* Remove configuration option: * * rm /files/$file/target[. = "$section"]/$option */ aug_ret = aug_rm(ctx->auges_ctx, option_path); if (aug_ret != 1) { ret = EIO; goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t sss_config_set_list(struct sss_config_ctx *ctx, const char *section, const char *option, char **list) { TALLOC_CTX *tmp_ctx = NULL; char *value = NULL; errno_t ret; int i; if (list == NULL) { return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } if (list[0] == NULL) { ret = sss_config_rm_option(ctx, section, option); goto done; } value = talloc_strdup(tmp_ctx, list[0]); if (value == NULL) { ret = ENOMEM; goto done; } for (i = 1; list[i] != NULL; i++) { value = talloc_asprintf_append(value, ", %s", list[i]); if (value == NULL) { ret = ENOMEM; goto done; } } ret = sss_config_set_option(ctx, section, option, value); done: talloc_free(tmp_ctx); return ret; } static errno_t sss_config_get_list(TALLOC_CTX *mem_ctx, struct sss_config_ctx *ctx, const char *section, const char *option, char ***_list) { TALLOC_CTX *tmp_ctx = NULL; char *option_path = NULL; const char *value = NULL; char **list = NULL; errno_t ret; int aug_ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } option_path = build_option_path(tmp_ctx, ctx, section, option); if (option_path == NULL) { ret = ENOMEM; goto done; } aug_ret = aug_get(ctx->auges_ctx, option_path, &value); if (aug_ret == 0 || (aug_ret == 1 && (value == NULL || *value == '\0'))) { /* option is not present, return empty list */ list = talloc_zero_array(tmp_ctx, char*, 1); if (list == NULL) { ret = ENOMEM; goto done; } ret = EOK; goto done; } else if (aug_ret != 1) { /* error: more than one value found */ ret = EINVAL; goto done; } ret = split_on_separator(tmp_ctx, value, ',', true, true, &list, NULL); if (ret != EOK) { goto done; } *_list = talloc_steal(mem_ctx, list); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t sss_config_is_in_list(struct sss_config_ctx *ctx, const char *section, const char *option, const char *value, bool *_result) { char **list = NULL; errno_t ret; ret = sss_config_get_list(ctx, ctx, section, option, &list); if (ret != EOK) { goto done; } *_result = string_in_list(value, list, true); done: talloc_free(list); return ret; } static errno_t sss_config_add_to_list(struct sss_config_ctx *ctx, const char *section, const char *option, const char *value) { TALLOC_CTX *tmp_ctx = NULL; char **list = NULL; errno_t ret; bool result = false; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = sss_config_get_list(tmp_ctx, ctx, section, option, &list); if (ret != EOK) { goto done; } result = string_in_list(value, list, true); if (result == true) { ret = EOK; goto done; } ret = add_string_to_list(tmp_ctx, value, &list); if (ret != EOK) { goto done; } ret = sss_config_set_list(ctx, section, option, list); done: talloc_free(tmp_ctx); return ret; } static errno_t sss_config_del_from_list(struct sss_config_ctx *ctx, const char *section, const char *option, const char *value) { TALLOC_CTX *tmp_ctx = NULL; char **list = NULL; errno_t ret; bool found; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = sss_config_get_list(tmp_ctx, ctx, section, option, &list); if (ret != EOK) { goto done; } if (list == NULL) { goto done; } found = false; for (i = 0; list[i] != NULL; i++) { if (strcmp(list[i], value) == 0) { found = true; } if (found) { list[i] = list[i + 1]; } } ret = sss_config_set_list(ctx, section, option, list); done: talloc_free(tmp_ctx); return ret; } static int sss_config_ctx_destructor(struct sss_config_ctx *ctx) { if (ctx->auges_ctx != NULL) { aug_close(ctx->auges_ctx); ctx->auges_ctx = NULL; } return 0; } struct sss_config_ctx * sss_config_open(TALLOC_CTX *mem_ctx, const char *root, const char *file) { struct sss_config_ctx *ctx = NULL; errno_t ret; int aug_ret; ctx = talloc_zero(mem_ctx, struct sss_config_ctx); if (ctx == NULL) { return NULL; } talloc_set_destructor(ctx, sss_config_ctx_destructor); ctx->auges_ctx = aug_init(root, NULL, AUG_NO_LOAD | AUG_NO_MODL_AUTOLOAD | AUG_SAVE_BACKUP); if (ctx->auges_ctx == NULL) { ret = ENOMEM; goto done; } ctx->file = talloc_strdup(ctx, file); if (ctx->file == NULL) { ret = ENOMEM; goto done; } /* Load configuration file * * set /augeas/load/sssd/lens sssd.lns * set /augeas/load/sssd/incl $file * load */ aug_ret = aug_set(ctx->auges_ctx, "/augeas/load/sssd/lens", "sssd.lns"); if (aug_ret != 0) { ret = EIO; goto done; } aug_ret = aug_set(ctx->auges_ctx, "/augeas/load/sssd/incl", ctx->file); if (aug_ret != 0) { ret = EIO; goto done; } aug_ret = aug_load(ctx->auges_ctx); if (aug_ret != 0) { ret = EIO; goto done; } ret = EOK; done: if (ret != EOK) { talloc_free(ctx); } return ctx; } errno_t sss_config_save(struct sss_config_ctx *ctx) { int aug_ret; aug_ret = aug_save(ctx->auges_ctx); if (aug_ret != 0) { return EIO; } return EOK; } void sss_config_close(struct sss_config_ctx **_ctx) { if (_ctx == NULL || *_ctx == NULL) { return; } talloc_free(*_ctx); *_ctx = NULL; } errno_t sss_config_set_debug_level(struct sss_config_ctx *ctx, const char *section, uint32_t level) { char *level_str = NULL; errno_t ret; level_str = talloc_asprintf(ctx, "%#.4x", level); if (level_str == NULL) { return ENOMEM; } ret = sss_config_set_option(ctx, section, CONFDB_SERVICE_DEBUG_LEVEL, level_str); talloc_free(level_str); return ret; } errno_t sss_config_service_is_enabled(struct sss_config_ctx *ctx, const char *service, bool *_result) { return sss_config_is_in_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_SERVICES, service, _result); } errno_t sss_config_service_enable(struct sss_config_ctx *ctx, const char *service) { return sss_config_add_to_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_SERVICES, service); } errno_t sss_config_service_disable(struct sss_config_ctx *ctx, const char *service) { return sss_config_del_from_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_SERVICES, service); } errno_t sss_config_domain_is_enabled(struct sss_config_ctx *ctx, const char *domain, bool *_result) { return sss_config_is_in_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_DOMAINS, domain, _result); } errno_t sss_config_domain_enable(struct sss_config_ctx *ctx, const char *domain) { return sss_config_add_to_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_DOMAINS, domain); } errno_t sss_config_domain_disable(struct sss_config_ctx *ctx, const char *domain) { return sss_config_del_from_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_DOMAINS, domain); } sssd-1.13.4/src/util/PaxHeaders.16287/sss_ssh.h0000644000000000000000000000007412703456111015727 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.419792832 sssd-1.13.4/src/util/sss_ssh.h0000644002412700241270000000260012703456111017374 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SSS_SSH_H_ #define _SSS_SSH_H_ #define SSS_SSH_REQ_ALIAS 0x01 #define SSS_SSH_REQ_DOMAIN 0x02 #define SSS_SSH_REQ_MASK 0x03 struct sss_ssh_pubkey { uint8_t *data; size_t data_len; }; struct sss_ssh_ent { char *name; struct sss_ssh_pubkey *pubkeys; size_t num_pubkeys; char **aliases; size_t num_aliases; }; errno_t sss_ssh_make_ent(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct sss_ssh_ent **result); errno_t sss_ssh_format_pubkey(TALLOC_CTX *mem_ctx, struct sss_ssh_pubkey *pubkey, char **result); #endif /* _SSS_SSH_H_ */ sssd-1.13.4/src/util/PaxHeaders.16287/refcount.c0000644000000000000000000000007412703456111016062 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.864794341 sssd-1.13.4/src/util/refcount.c0000644002412700241270000000431312703456111017532 0ustar00jhrozekjhrozek00000000000000/* SSSD Simple reference counting wrappers for talloc. Authors: Martin Nagy Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "refcount.h" #include "util/util.h" struct wrapper { int *refcount; void *ptr; }; static int refcount_destructor(struct wrapper *wrapper) { (*wrapper->refcount)--; if (*wrapper->refcount == 0) { talloc_free(wrapper->ptr); }; return 0; } void * _rc_alloc(const void *context, size_t size, size_t refcount_offset, const char *type_name) { struct wrapper *wrapper; char *refcount_pos; wrapper = talloc(context, struct wrapper); if (wrapper == NULL) { return NULL; } wrapper->ptr = talloc_named_const(NULL, size, type_name); if (wrapper->ptr == NULL) { talloc_free(wrapper); return NULL; }; refcount_pos = (char *)wrapper->ptr + refcount_offset; wrapper->refcount = DISCARD_ALIGN(refcount_pos, int *); *wrapper->refcount = 1; talloc_set_destructor(wrapper, refcount_destructor); return wrapper->ptr; } void * _rc_reference(const void *context, size_t refcount_offset, void *source) { struct wrapper *wrapper; char *refcount_pos; wrapper = talloc(context, struct wrapper); if (wrapper == NULL) { return NULL; } wrapper->ptr = source; refcount_pos = (char *)wrapper->ptr + refcount_offset; wrapper->refcount = DISCARD_ALIGN(refcount_pos, int *); (*wrapper->refcount)++; talloc_set_destructor(wrapper, refcount_destructor); return wrapper->ptr; } sssd-1.13.4/src/util/PaxHeaders.16287/auth_utils.h0000644000000000000000000000007212703456111016421 xustar0030 atime=1460561751.659715658 28 ctime=1460561774.4397929 sssd-1.13.4/src/util/auth_utils.h0000644002412700241270000000236312703456111020076 0ustar00jhrozekjhrozek00000000000000/* SSSD Authentication utility functions Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include static inline int cached_login_pam_status(int auth_res) { switch (auth_res) { case EOK: return PAM_SUCCESS; case ERR_ACCOUNT_UNKNOWN: return PAM_AUTHINFO_UNAVAIL; case ERR_NO_CACHED_CREDS: case ERR_CACHED_CREDS_EXPIRED: case ERR_AUTH_DENIED: return PAM_PERM_DENIED; case ERR_AUTH_FAILED: return PAM_AUTH_ERR; default: return PAM_SYSTEM_ERR; } } sssd-1.13.4/src/util/PaxHeaders.16287/atomic_io.h0000644000000000000000000000007412703456111016205 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.438792896 sssd-1.13.4/src/util/atomic_io.h0000644002412700241270000000251712703456111017661 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSSD_ATOMIC_IO_H__ #define __SSSD_ATOMIC_IO_H__ #include #include #include #include /* Performs a read or write operation in an manner that is seemingly atomic * to the caller. * * Please note that the function does not perform any asynchronous operation * so the operation might potentially block */ ssize_t sss_atomic_io_s(int fd, void *buf, size_t n, bool do_read); #define sss_atomic_read_s(fd, buf, n) sss_atomic_io_s(fd, buf, n, true) #define sss_atomic_write_s(fd, buf, n) sss_atomic_io_s(fd, buf, n, false) #endif /* __SSSD_ATOMIC_IO_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/refcount.h0000644000000000000000000000007412703456111016067 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.422792842 sssd-1.13.4/src/util/refcount.h0000644002412700241270000000411412703456111017536 0ustar00jhrozekjhrozek00000000000000/* SSSD Simple reference counting wrappers for talloc. Authors: Martin Nagy Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __REFCOUNT_H__ #define __REFCOUNT_H__ #include #define REFCOUNT_MEMBER_NAME DO_NOT_TOUCH_THIS_MEMBER_refcount /* * Include this member in your structure in order to be able to use it with * the refcount_* functions. */ #define REFCOUNT_COMMON int REFCOUNT_MEMBER_NAME /* * Allocate a new structure that uses reference counting. The resulting pointer * returned. You must not free the returned pointer manually. It will be freed * when 'ctx' is freed with talloc_free() and no other references are left. */ #define rc_alloc(ctx, type) \ (type *)_rc_alloc(ctx, sizeof(type), offsetof(type, REFCOUNT_MEMBER_NAME), \ #type) /* * Increment the reference count of 'src' and return it back if we are * successful. The reference count will be decremented after 'ctx' has been * released by talloc_free(). The function will return NULL in case of failure. */ #define rc_reference(ctx, type, src) \ (type *)_rc_reference(ctx, offsetof(type, REFCOUNT_MEMBER_NAME), src) /* * These functions should not be used directly. Use the above macros instead. */ void *_rc_alloc(const void *context, size_t size, size_t refcount_offset, const char *type_name); void *_rc_reference(const void *context, size_t refcount_offset, void *source); #endif /* !__REFCOUNT_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/cert.h0000644000000000000000000000007412703456111015177 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.405792784 sssd-1.13.4/src/util/cert.h0000644002412700241270000000375212703456111016655 0ustar00jhrozekjhrozek00000000000000/* SSSD - certificate handling utils - openssl version Copyright (C) Sumit Bose 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/util.h" #ifndef __CERT_H__ #define __CERT_H__ errno_t sss_cert_der_to_pem(TALLOC_CTX *mem_ctx, const uint8_t *der_blob, size_t der_size, char **pem, size_t *pem_size); errno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem, uint8_t **der_blob, size_t *der_size); errno_t sss_cert_derb64_to_pem(TALLOC_CTX *mem_ctx, const char *derb64, char **pem, size_t *pem_size); errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem, char **derb64); errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64, const char *attr_name, char **ldap_filter); errno_t bin_to_ldap_filter_value(TALLOC_CTX *mem_ctx, const uint8_t *blob, size_t blob_size, char **_str); errno_t cert_to_ssh_key(TALLOC_CTX *mem_ctx, const char *ca_db, const uint8_t *der_blob, size_t der_size, bool do_ocsp, uint8_t **key, size_t *key_size); #endif /* __CERT_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/sss_krb5.h0000644000000000000000000000007412703456111015775 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.416792822 sssd-1.13.4/src/util/sss_krb5.h0000644002412700241270000001676312703456111017461 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2009-2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSS_KRB5_H__ #define __SSS_KRB5_H__ #include "config.h" #include #include #ifdef HAVE_KRB5_KRB5_H #include #else #include #endif #include "util/util.h" #define KRB5_CHILD_LOG_FILE "krb5_child" #define LDAP_CHILD_LOG_FILE "ldap_child" /* MIT Kerberos has the same hardcoded warning interval of 7 days. Due to the * fact that using the expiration time of a Kerberos password with LDAP * authentication is presumably a rare case a separate config option is not * necessary. */ #define KERBEROS_PWEXPIRE_WARNING_TIME (7 * 24 * 60 * 60) #define KEYTAB_CLEAN_NAME keytab_name ? keytab_name : "default" #if defined HAVE_KRB5_CC_CACHE_MATCH && defined HAVE_KRB5_CC_GET_FULL_NAME #define HAVE_KRB5_CC_COLLECTION 1 #endif const char * KRB5_CALLCONV sss_krb5_get_error_message (krb5_context, krb5_error_code); void KRB5_CALLCONV sss_krb5_free_error_message(krb5_context, const char *); #define KRB5_DEBUG(level, errctx, krb5_error) do { \ const char *__krb5_error_msg; \ __krb5_error_msg = sss_krb5_get_error_message(errctx, krb5_error); \ DEBUG(level, "%d: [%d][%s]\n", __LINE__, krb5_error, __krb5_error_msg); \ sss_log(SSS_LOG_ERR, "%s", __krb5_error_msg); \ sss_krb5_free_error_message(errctx, __krb5_error_msg); \ } while(0) krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_alloc( krb5_context context, krb5_get_init_creds_opt **opt); void KRB5_CALLCONV sss_krb5_get_init_creds_opt_free (krb5_context context, krb5_get_init_creds_opt *opt); void KRB5_CALLCONV sss_krb5_free_unparsed_name(krb5_context context, char *name); krb5_error_code find_principal_in_keytab(krb5_context ctx, krb5_keytab keytab, const char *pattern_primary, const char *pattern_realm, krb5_principal *princ); errno_t select_principal_from_keytab(TALLOC_CTX *mem_ctx, const char *hostname, const char *desired_realm, const char *keytab_name, char **_principal, char **_primary, char **_realm); #ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_EXPIRE_CALLBACK typedef void krb5_expire_callback_func(krb5_context context, void *data, krb5_timestamp password_expiration, krb5_timestamp account_expiration, krb5_boolean is_last_req); #endif krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_set_expire_callback( krb5_context context, krb5_get_init_creds_opt *opt, krb5_expire_callback_func cb, void *data); errno_t check_fast(const char *str, bool *use_fast); krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_set_fast_ccache_name( krb5_context context, krb5_get_init_creds_opt *opt, const char *fast_ccache_name); krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_set_fast_flags( krb5_context context, krb5_get_init_creds_opt *opt, krb5_flags flags); #if HAVE_KRB5_GET_INIT_CREDS_OPT_SET_FAST_FLAGS #define SSS_KRB5_FAST_REQUIRED KRB5_FAST_REQUIRED #else #define SSS_KRB5_FAST_REQUIRED 0 #endif #ifndef HAVE_KRB5_PARSE_NAME_FLAGS #define KRB5_PRINCIPAL_PARSE_NO_REALM 0x1 #define KRB5_PRINCIPAL_PARSE_REQUIRE_REALM 0x2 #define KRB5_PRINCIPAL_PARSE_ENTERPRISE 0x4 #endif krb5_error_code sss_krb5_parse_name_flags(krb5_context context, const char *name, int flags, krb5_principal *principal); #ifndef HAVE_KRB5_UNPARSE_NAME_FLAGS #define KRB5_PRINCIPAL_UNPARSE_SHORT 0x1 #define KRB5_PRINCIPAL_UNPARSE_NO_REALM 0x2 #define KRB5_PRINCIPAL_UNPARSE_DISPLAY 0x4 #endif krb5_error_code sss_krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal, int flags, char **name); void sss_krb5_get_init_creds_opt_set_canonicalize(krb5_get_init_creds_opt *opts, int canonicalize); enum sss_krb5_cc_type { SSS_KRB5_TYPE_FILE, #ifdef HAVE_KRB5_CC_COLLECTION SSS_KRB5_TYPE_DIR, SSS_KRB5_TYPE_KEYRING, #endif /* HAVE_KRB5_CC_COLLECTION */ SSS_KRB5_TYPE_UNKNOWN }; /* === Compatibility routines for the Heimdal Kerberos implementation === */ void sss_krb5_princ_realm(krb5_context context, krb5_const_principal princ, const char **realm, int *len); krb5_error_code sss_krb5_free_keytab_entry_contents(krb5_context context, krb5_keytab_entry *entry); #ifdef HAVE_KRB5_TICKET_TIMES typedef krb5_ticket_times sss_krb5_ticket_times; #elif defined(HAVE_KRB5_TIMES) typedef krb5_times sss_krb5_ticket_times; #endif /* Redirect libkrb5 tracing towards our DEBUG statements */ errno_t sss_child_set_krb5_tracing(krb5_context ctx); krb5_error_code sss_krb5_find_authdata(krb5_context context, krb5_authdata *const *ticket_authdata, krb5_authdata *const *ap_req_authdata, krb5_authdatatype ad_type, krb5_authdata ***results); krb5_error_code sss_extract_pac(krb5_context ctx, krb5_ccache ccache, krb5_principal server_principal, krb5_principal client_principal, krb5_keytab keytab, krb5_authdata ***_pac_authdata); char * sss_get_ccache_name_for_principal(TALLOC_CTX *mem_ctx, krb5_context ctx, krb5_principal principal, const char *location); krb5_error_code sss_krb5_kt_have_content(krb5_context context, krb5_keytab keytab); bool sss_krb5_realm_has_proxy(const char *realm); #endif /* __SSS_KRB5_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/sss_ssh.c0000644000000000000000000000007412703456111015722 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.884794409 sssd-1.13.4/src/util/sss_ssh.c0000644002412700241270000001262212703456111017374 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "db/sysdb.h" #include "util/util.h" #include "util/crypto/sss_crypto.h" #include "util/sss_ssh.h" errno_t sss_ssh_make_ent(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct sss_ssh_ent **result) { TALLOC_CTX *tmp_ctx; struct sss_ssh_ent *res = NULL; errno_t ret; const char *name; struct ldb_message_element *el; unsigned int i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); if (!name) { ret = EINVAL; DEBUG(SSSDBG_CRIT_FAILURE, "Host is missing name attribute\n"); goto done; } res = talloc_zero(tmp_ctx, struct sss_ssh_ent); if (!res) { ret = ENOMEM; goto done; } res->name = talloc_strdup(res, name); if (!res->name) { ret = ENOMEM; goto done; } el = ldb_msg_find_element(msg, SYSDB_SSH_PUBKEY); if (el) { res->num_pubkeys = el->num_values; res->pubkeys = talloc_array(res, struct sss_ssh_pubkey, res->num_pubkeys); if (!res->pubkeys) { ret = ENOMEM; goto done; } for (i = 0; i < el->num_values; i++) { res->pubkeys[i].data = sss_base64_decode(res->pubkeys, (char *)el->values[i].data, &res->pubkeys[i].data_len); if (!res->pubkeys[i].data) { ret = ENOMEM; goto done; } } } el = ldb_msg_find_element(msg, SYSDB_NAME_ALIAS); if (el) { res->num_aliases = el->num_values; res->aliases = talloc_array(res, char *, res->num_aliases); if (!res->aliases) { ret = ENOMEM; goto done; } for (i = 0; i < el->num_values; i++) { res->aliases[i] = talloc_strdup(res->aliases, (char *)el->values[i].data); if (!res->aliases[i]) { ret = ENOMEM; goto done; } } } *result = talloc_steal(mem_ctx, res); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t sss_ssh_get_pubkey_algorithm(TALLOC_CTX *mem_ctx, struct sss_ssh_pubkey *pubkey, char **result) { size_t c = 0; uint32_t algo_len; char *algo; if (pubkey->data_len < 5) { return EINVAL; } SAFEALIGN_COPY_UINT32(&algo_len, pubkey->data, &c); algo_len = ntohl(algo_len); if (algo_len < 1 || algo_len > 64 || algo_len > pubkey->data_len - 4) { /* the maximum length of 64 is defined in RFC 4250 */ return EINVAL; } algo = talloc_zero_array(mem_ctx, char, algo_len+1); if (!algo) { return ENOMEM; } memcpy(algo, pubkey->data+c, algo_len); *result = algo; return EOK; } errno_t sss_ssh_format_pubkey(TALLOC_CTX *mem_ctx, struct sss_ssh_pubkey *pubkey, char **result) { TALLOC_CTX *tmp_ctx; errno_t ret; char *blob; char *algo; char *out = NULL; size_t i, len; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (pubkey->data_len > 4 && memcmp(pubkey->data, "\0\0\0", 3) == 0) { /* All valid public key blobs start with 3 null bytes (see RFC 4253 * section 6.6, RFC 4251 section 5 and RFC 4250 section 4.6) */ blob = sss_base64_encode(tmp_ctx, pubkey->data, pubkey->data_len); if (!blob) { ret = ENOMEM; goto done; } ret = sss_ssh_get_pubkey_algorithm(tmp_ctx, pubkey, &algo); if (ret != EOK) { goto done; } out = talloc_asprintf(mem_ctx, "%s %s", algo, blob); if (!out) { ret = ENOMEM; goto done; } } else { /* Not a valid public key blob, so this must be a textual public key */ for (i = 0; i < pubkey->data_len; i++) { if (pubkey->data[i] == '\0' || (pubkey->data[i] == '\n' && i != pubkey->data_len - 1) || pubkey->data[i] == '\r') { ret = EINVAL; goto done; } } len = pubkey->data_len; if (pubkey->data[len - 1] == '\n') { len--; } out = talloc_array(mem_ctx, char, len + 1); if (out == NULL) { ret = ENOMEM; goto done; } memcpy(out, pubkey->data, len); out[len] = '\0'; } *result = out; ret = EOK; done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/util/PaxHeaders.16287/memory.c0000644000000000000000000000007412703456111015545 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.857794317 sssd-1.13.4/src/util/memory.c0000644002412700241270000000337012703456111017217 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" /* * sssd_mem_attach * This function will take a non-talloc pointer and "attach" it to a talloc * memory context. It will accept a destructor for the original pointer * so that when the parent memory context is freed, the non-talloc * pointer will also be freed properly. */ int password_destructor(void *memctx) { char *password = (char *)memctx; int i; /* zero out password */ for (i = 0; password[i]; i++) password[i] = '\0'; return 0; } static int mem_holder_destructor(void *ptr) { struct mem_holder *h; h = talloc_get_type(ptr, struct mem_holder); return h->fn(h->mem); } void *sss_mem_attach(TALLOC_CTX *mem_ctx, void *ptr, void_destructor_fn_t *fn) { struct mem_holder *h; if (!ptr || !fn) return NULL; h = talloc(mem_ctx, struct mem_holder); if (!h) return NULL; h->mem = ptr; h->fn = fn; talloc_set_destructor((TALLOC_CTX *)h, mem_holder_destructor); return h; } sssd-1.13.4/src/util/PaxHeaders.16287/sss_utf8.c0000644000000000000000000000007412703456111016013 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.670793683 sssd-1.13.4/src/util/sss_utf8.c0000644002412700241270000000772612703456111017476 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #ifdef HAVE_LIBUNISTRING #include #include #elif defined(HAVE_GLIB2) #include #endif #include "sss_utf8.h" #ifdef HAVE_LIBUNISTRING void sss_utf8_free(void *ptr) { return free(ptr); } #elif defined(HAVE_GLIB2) void sss_utf8_free(void *ptr) { return g_free(ptr); } #else #error No unicode library #endif #ifdef HAVE_LIBUNISTRING uint8_t *sss_utf8_tolower(const uint8_t *s, size_t len, size_t *_nlen) { size_t llen; uint8_t *lower; lower = u8_tolower(s, len, NULL, NULL, NULL, &llen); if (!lower) return NULL; if (_nlen) *_nlen = llen; return lower; } #elif defined(HAVE_GLIB2) uint8_t *sss_utf8_tolower(const uint8_t *s, size_t len, size_t *_nlen) { gchar *glower; size_t nlen; uint8_t *lower; glower = g_utf8_strdown((const gchar *) s, len); if (!glower) return NULL; /* strlen() is safe here because g_utf8_strdown() always null-terminates */ nlen = strlen(glower); lower = g_malloc(nlen); if (!lower) { g_free(glower); return NULL; } memcpy(lower, glower, nlen); g_free(glower); if (_nlen) *_nlen = nlen; return (uint8_t *) lower; } #else #error No unicode library #endif #ifdef HAVE_LIBUNISTRING bool sss_utf8_check(const uint8_t *s, size_t n) { if (u8_check(s, n) == NULL) { return true; } return false; } #elif defined(HAVE_GLIB2) bool sss_utf8_check(const uint8_t *s, size_t n) { return g_utf8_validate((const gchar *)s, n, NULL); } #else #error No unicode library #endif /* Returns EOK on match, ENOTUNIQ if comparison succeeds but * does not match. * May return other errno error codes on failure */ #ifdef HAVE_LIBUNISTRING errno_t sss_utf8_case_eq(const uint8_t *s1, const uint8_t *s2) { /* Do a case-insensitive comparison. * The input must be encoded in UTF8. * We have no way of knowing the language, * so we'll pass NULL for the language and * hope for the best. */ int ret; int resultp; size_t n1, n2; errno = 0; n1 = u8_strlen(s1); n2 = u8_strlen(s2); ret = u8_casecmp(s1, n1, s2, n2, NULL, NULL, &resultp); if (ret < 0) { /* An error occurred */ return errno; } if (resultp == 0) { return EOK; } return ENOMATCH; } #elif defined(HAVE_GLIB2) errno_t sss_utf8_case_eq(const uint8_t *s1, const uint8_t *s2) { gchar *gs1; gchar *gs2; gssize n1, n2; gint gret; errno_t ret; n1 = g_utf8_strlen((const gchar *)s1, -1); n2 = g_utf8_strlen((const gchar *)s2, -1); gs1 = g_utf8_casefold((const gchar *)s1, n1); if (gs1 == NULL) { return ENOMEM; } gs2 = g_utf8_casefold((const gchar *)s2, n2); if (gs2 == NULL) { return ENOMEM; } gret = g_utf8_collate(gs1, gs2); if (gret == 0) { ret = EOK; } else { ret = ENOMATCH; } g_free(gs1); g_free(gs2); return ret; } #else #error No unicode library #endif bool sss_string_equal(bool cs, const char *s1, const char *s2) { if (cs) { return strcmp(s1, s2) == 0; } return sss_utf8_case_eq((const uint8_t *)s1, (const uint8_t *)s2) == EOK; } sssd-1.13.4/src/util/PaxHeaders.16287/io.h0000644000000000000000000000007412703456111014651 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.409792798 sssd-1.13.4/src/util/io.h0000644002412700241270000000212312703456111016316 0ustar00jhrozekjhrozek00000000000000/* SSSD SSSD Utility functions Copyright (C) Lukas Slebodnik 2013 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _UTIL_IO_H_ #define _UTIL_IO_H_ /* CAUTION: * This file is also used in sss_client (pam, nss). Therefore it have to be * minimalist and cannot include DEBUG macros or header file util.h. */ int sss_open_cloexec(const char *pathname, int flags, int *ret); int sss_openat_cloexec(int dir_fd, const char *pathname, int flags, int *ret); #endif /* _UTIL_IO_H_ */ sssd-1.13.4/src/util/PaxHeaders.16287/nscd.c0000644000000000000000000000007412703456111015164 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.648793608 sssd-1.13.4/src/util/nscd.c0000644002412700241270000001225512703456111016640 0ustar00jhrozekjhrozek00000000000000/* SSSD nscd.c Copyright (C) Jakub Hrozek 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include #include #include "util/util.h" #include "tools/tools_util.h" #ifndef NSCD_RELOAD_ARG #define NSCD_RELOAD_ARG "-i" #endif #if defined(NSCD_PATH) && defined(HAVE_NSCD) int flush_nscd_cache(enum nscd_db flush_db) { const char *service; pid_t nscd_pid; int ret, status; switch(flush_db) { case NSCD_DB_PASSWD: service = "passwd"; break; case NSCD_DB_GROUP: service = "group"; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown nscd database\n"); ret = EINVAL; goto done; } nscd_pid = fork(); switch (nscd_pid) { case 0: execl(NSCD_PATH, NSCD_PATH, NSCD_RELOAD_ARG, service, NULL); /* if this returns it is an error */ DEBUG(SSSDBG_CRIT_FAILURE, "execl(3) failed: %d(%s)\n", errno, strerror(errno)); exit(errno); case -1: DEBUG(SSSDBG_CRIT_FAILURE, "fork failed\n"); ret = EFAULT; break; default: do { errno = 0; ret = waitpid(nscd_pid, &status, 0); } while (ret == -1 && errno == EINTR); if (ret > 0) { if (WIFEXITED(status)) { ret = WEXITSTATUS(status); if (ret > 0) { /* The flush fails if nscd is not running, so do not care * about the return code */ DEBUG(SSSDBG_TRACE_INTERNAL, "Error flushing cache, is nscd running?\n"); } } } else { DEBUG(SSSDBG_FUNC_DATA, "Failed to wait for children %d\n", nscd_pid); ret = EIO; } } done: return ret; } #else /* defined(NSCD_PATH) && defined(HAVE_NSCD) */ int flush_nscd_cache(enum nscd_db flush_db) { return EOK; } #endif /* NSCD config file parse and check */ static unsigned int sss_nscd_check_service(char* svc_name) { struct sss_nscd_db { const char *svc_type_name; unsigned int nscd_service_flag; }; int i; unsigned int ret = 0; struct sss_nscd_db db[] = { { "passwd", 0x0001 }, { "group", 0x0010 }, { "netgroup", 0x0100 }, { "services", 0x1000 }, { NULL, 0 } }; if (svc_name == NULL) { return ret; } for (i = 0; db[i].svc_type_name != NULL; i++) { if (!strcmp(db[i].svc_type_name, svc_name)) { ret = db[i].nscd_service_flag; break; } } return ret; } errno_t sss_nscd_parse_conf(const char *conf_path) { FILE *fp; int ret = EOK; unsigned int occurred = 0; char *line, *entry, *service, *enabled, *pad; size_t linelen = 0; fp = fopen(conf_path, "r"); if (fp == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Couldn't open NSCD configuration " "file [%s]\n", NSCD_CONF_PATH); return ENOENT; } while (getline(&line, &linelen, fp) != -1) { pad = strchr(line, '#'); if (pad != NULL) { *pad = '\0'; } if (line[0] == '\n' || line[0] == '\0') continue; entry = line; while (isspace(*entry) && *entry != '\0') { entry++; } pad = entry; while (!isspace(*pad) && *pad != '\0') { pad++; } service = pad; while (isspace(*service) && *service != '\0') { service++; } *pad = '\0'; pad = service; while (!isspace(*pad) && *pad != '\0') { pad++; } enabled = pad; while (isspace(*enabled) && *enabled != '\0') { enabled++; } *pad = '\0'; pad = enabled; while (!isspace(*pad) && *pad != '\0') { pad++; } *pad = '\0'; if (!strcmp(entry, "enable-cache") && !strcmp(enabled, "yes")) { occurred |= sss_nscd_check_service(service); } }; ret = ferror(fp); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Reading NSCD configuration file [%s] " "ended with failure [%d]: %s.\n", NSCD_CONF_PATH, ret, strerror(ret)); ret = ENOENT; goto done; } ret = EOK; if (occurred != 0) { ret = EEXIST; goto done; } done: free(line); fclose(fp); return ret; } sssd-1.13.4/src/util/PaxHeaders.16287/sss_endian.h0000644000000000000000000000007412703456111016370 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.413792812 sssd-1.13.4/src/util/sss_endian.h0000644002412700241270000000304712703456111020043 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Lukas Slebodnik Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_ENDIAN_H_ #define SSS_ENDIAN_H_ #ifdef HAVE_ENDIAN_H # include #elif defined(HAVE_SYS_ENDIAN_H) # include #endif /* !HAVE_ENDIAN_H && !HAVE_SYS_ENDIAN_H */ /* Endianness-compatibility for systems running older versions of glibc */ #ifndef le32toh #ifndef HAVE_BYTESWAP_H #error missing le32toh and byteswap.h #else /* defined HAVE_BYTESWAP_H */ #include /* support RHEL5 lack of definitions */ /* Copied from endian.h on glibc 2.15 */ #ifdef __USE_BSD /* Conversion interfaces. */ # if __BYTE_ORDER == __LITTLE_ENDIAN # define le32toh(x) (x) # define htole32(x) (x) # else # define le32toh(x) __bswap_32 (x) # define htole32(x) __bswap_32 (x) # endif #endif /* __USE_BSD */ #endif /* HAVE_BYTESWAP_H */ #endif /* le32toh */ #endif /* SSS_ENDIAN_H_ */ sssd-1.13.4/src/util/PaxHeaders.16287/authtok-utils.h0000644000000000000000000000007312703456111017056 xustar0030 atime=1460561751.659715658 29 ctime=1460561774.44279291 sssd-1.13.4/src/util/authtok-utils.h0000644002412700241270000000553312703456111020534 0ustar00jhrozekjhrozek00000000000000/* SSSD - auth utils helpers Copyright (C) Sumit Bose 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __AUTHTOK_UTILS_H__ #define __AUTHTOK_UTILS_H__ #include #include "sss_client/sss_cli.h" /** * @brief Fill memory buffer with 2FA blob * * @param[in] fa1 First authentication factor, null terminated * @param[in] fa1_len Length of the first authentication factor, if 0 * strlen() will be called internally * @param[in] fa2 Second authentication factor, null terminated * @param[in] fa2_len Length of the second authentication factor, if 0 * strlen() will be called internally * @param[in] buf memory buffer of size buf_len * @param[in] buf_len size of memory buffer buf * * @param[out] _2fa_blob_len size of the 2FA blob * * @return EOK on success * EINVAL if input data is not consistent * EAGAIN if provided buffer is too small, _2fa_blob_len * contains the size needed to store the 2FA blob */ errno_t sss_auth_pack_2fa_blob(const char *fa1, size_t fa1_len, const char *fa2, size_t fa2_len, uint8_t *buf, size_t buf_len, size_t *_2fa_blob_len); /** * @brief Extract 2FA data from memory buffer * * @param[in] mem_ctx Talloc memory context to allocate the 2FA data on * @param[in] blob Memory buffer containing the 2FA data * @param[in] blob_len Size of the memory buffer * @param[out] _fa1 First authentication factor, null terminated * @param[out] _fa1_len Length of the first authentication factor * @param[out] _fa2 Second authentication factor, null terminated * @param[out] _fa2_len Length of the second authentication factor * * @return EOK on success * EINVAL if input data is not consistent * EINVAL if no memory can be allocated */ errno_t sss_auth_unpack_2fa_blob(TALLOC_CTX *mem_ctx, const uint8_t *blob, size_t blob_len, char **fa1, size_t *_fa1_len, char **fa2, size_t *_fa2_len); #endif /* __AUTHTOK_UTILS_H__ */ sssd-1.13.4/src/util/PaxHeaders.16287/util_lock.c0000644000000000000000000000007412703456111016222 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.872794368 sssd-1.13.4/src/util/util_lock.c0000644002412700241270000000477712703456111017710 0ustar00jhrozekjhrozek00000000000000/* SSSD util_lock.c Authors: Michal Zidek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" errno_t sss_br_lock_file(int fd, size_t start, size_t len, int num_tries, useconds_t wait) { int ret; struct flock lock; int retries_left; if (num_tries <= 0) { return EINVAL; } lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; lock.l_start = start; lock.l_len = len; lock.l_pid = 0; for (retries_left = num_tries; retries_left > 0; retries_left--) { ret = fcntl(fd, F_SETLK, &lock); if (ret == -1) { ret = errno; if (ret == EACCES || ret == EAGAIN || ret == EINTR) { DEBUG(SSSDBG_TRACE_FUNC, "Failed to lock file. Retries left: %d\n", retries_left - 1); if ((ret == EACCES || ret == EAGAIN) && (retries_left <= 1)) { /* File is locked by someone else. Return EACCESS * if this is the last try. */ return EACCES; } if (retries_left - 1 > 0) { ret = usleep(wait); if (ret == -1) { DEBUG(SSSDBG_MINOR_FAILURE, "usleep() failed -> ignoring\n"); } } } else { /* Error occurred */ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lock file.\n"); return ret; } } else if (ret == 0) { /* File successfuly locked */ break; } } if (retries_left == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lock file.\n"); return ret; } return EOK; } sssd-1.13.4/src/util/PaxHeaders.16287/safe-format-string.c0000644000000000000000000000007412703456111017745 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.859794324 sssd-1.13.4/src/util/safe-format-string.c0000644002412700241270000001634112703456111021421 0ustar00jhrozekjhrozek00000000000000/* * This file originated in the realmd project * * Copyright 2013 Red Hat Inc * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2 of the licence or (at * your option) any later version. * * See the included COPYING file for more information. * * Author: Stef Walter */ /* * Some snippets of code from gnulib, but have since been refactored * to within an inch of their life... * * vsprintf with automatic memory allocation. * Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Library General Public License as published * by the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. */ #include "config.h" #include "safe-format-string.h" #include #include #include #ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif #ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif static void safe_padding (int count, int *total, void (* copy_fn) (void *, const char *, size_t), void *data) { char eight[] = " "; int num; while (count > 0) { num = MIN (count, 8); copy_fn (data, eight, num); count -= num; *total += num; } } static void dummy_copy_fn (void *data, const char *piece, size_t len) { } int safe_format_string_cb (void (* copy_fn) (void *, const char *, size_t), void *data, const char *format, const char * const args[], int num_args) { int at_arg = 0; const char *cp; int precision; int width; int len; const char *value; int total; int left; int i; if (!copy_fn) copy_fn = dummy_copy_fn; total = 0; cp = format; while (*cp) { /* Piece of raw string */ if (*cp != '%') { len = strcspn (cp, "%"); copy_fn (data, cp, len); total += len; cp += len; continue; } cp++; /* An literal percent sign? */ if (*cp == '%') { copy_fn (data, "%", 1); total++; cp++; continue; } value = NULL; left = 0; precision = -1; width = -1; /* Test for positional argument. */ if (*cp >= '0' && *cp <= '9') { /* Look-ahead parsing, otherwise skipped */ if (cp[strspn (cp, "0123456789")] == '$') { unsigned int n = 0; for (i = 0; i < 6 && *cp >= '0' && *cp <= '9'; i++, cp++) { n = 10 * n + (*cp - '0'); } /* Positional argument 0 is invalid. */ if (n == 0) { errno = EINVAL; return -1; } /* Positional argument N too high */ if (n > num_args) { errno = EINVAL; return -1; } value = args[n - 1]; cp++; /* $ */ } } /* Read the supported flags. */ for (; ; cp++) { if (*cp == '-') left = 1; /* Supported but ignored */ else if (*cp != ' ') break; } /* Parse the width. */ if (*cp >= '0' && *cp <= '9') { width = 0; for (i = 0; i < 6 && *cp >= '0' && *cp <= '9'; i++, cp++) { width = 10 * width + (*cp - '0'); } } /* Parse the precision. */ if (*cp == '.') { precision = 0; for (i = 0, cp++; i < 6 && *cp >= '0' && *cp <= '9'; cp++, i++) { precision = 10 * precision + (*cp - '0'); } } /* Read the conversion character. */ switch (*cp++) { case 's': /* Non-positional argument */ if (value == NULL) { /* Too many arguments used */ if (at_arg == num_args) { errno = EINVAL; return -1; } value = args[at_arg++]; } break; /* No other conversion characters are supported */ default: errno = EINVAL; return -1; } /* How many characters are we printing? */ len = strlen (value); if (precision >= 0) len = MIN (precision, len); /* Do we need padding? */ safe_padding (left ? 0 : width - len, &total, copy_fn, data); /* The actual data */; copy_fn (data, value, len); total += len; /* Do we need padding? */ safe_padding (left ? width - len : 0, &total, copy_fn, data); } return total; } static const char ** valist_to_args (va_list va, int *num_args) { int alo_args; const char **args; const char *arg; void *mem; *num_args = alo_args = 0; args = NULL; for (;;) { arg = va_arg (va, const char *); if (arg == NULL) break; if (*num_args == alo_args) { alo_args += 8; mem = realloc (args, sizeof (const char *) * alo_args); if (!mem) { free (args); return NULL; } args = mem; } args[(*num_args)++] = arg; } return args; } struct sprintf_ctx { char *data; size_t length; size_t alloc; }; static void snprintf_copy_fn (void *data, const char *piece, size_t length) { struct sprintf_ctx *cx = data; /* Don't copy if too much data */ if (cx->length > cx->alloc) length = 0; else if (cx->length + length > cx->alloc) length = cx->alloc - cx->length; if (length > 0) memcpy (cx->data + cx->length, piece, length); /* Null termination happens later */ cx->length += length; } int safe_format_string (char *str, size_t len, const char *format, ...) { struct sprintf_ctx cx; int num_args; va_list va; const char **args; int error = 0; int ret; cx.data = str; cx.length = 0; cx.alloc = len; va_start (va, format); args = valist_to_args (va, &num_args); va_end (va); if (args == NULL) { errno = ENOMEM; return -1; } if (len) cx.data[0] = '\0'; ret = safe_format_string_cb (snprintf_copy_fn, &cx, format, args, num_args); if (ret < 0) { error = errno; } else if (len > 0) { cx.data[MIN (cx.length, len - 1)] = '\0'; } free (args); if (error) errno = error; return ret; } sssd-1.13.4/src/util/PaxHeaders.16287/child_common.c0000644000000000000000000000007412703456111016670 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.707793808 sssd-1.13.4/src/util/child_common.c0000644002412700241270000005770012703456111020350 0ustar00jhrozekjhrozek00000000000000/* SSSD Common helper functions to be used in child processes Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "util/find_uid.h" #include "db/sysdb.h" #include "util/child_common.h" struct sss_sigchild_ctx { struct tevent_context *ev; hash_table_t *children; int options; }; struct sss_child_ctx { pid_t pid; sss_child_fn_t cb; void *pvt; struct sss_sigchild_ctx *sigchld_ctx; }; static void sss_child_handler(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data); errno_t sss_sigchld_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sss_sigchild_ctx **child_ctx) { errno_t ret; struct sss_sigchild_ctx *sigchld_ctx; struct tevent_signal *tes; sigchld_ctx = talloc_zero(mem_ctx, struct sss_sigchild_ctx); if (!sigchld_ctx) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing sss_sigchild_ctx\n"); return ENOMEM; } sigchld_ctx->ev = ev; ret = sss_hash_create(sigchld_ctx, 10, &sigchld_ctx->children); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing children hash table: [%s]\n", strerror(ret)); talloc_free(sigchld_ctx); return ret; } BlockSignals(false, SIGCHLD); tes = tevent_add_signal(ev, sigchld_ctx, SIGCHLD, SA_SIGINFO, sss_child_handler, sigchld_ctx); if (tes == NULL) { talloc_free(sigchld_ctx); return EIO; } *child_ctx = sigchld_ctx; return EOK; } static int sss_child_destructor(void *ptr) { struct sss_child_ctx *child_ctx; hash_key_t key; int error; child_ctx = talloc_get_type(ptr, struct sss_child_ctx); key.type = HASH_KEY_ULONG; key.ul = child_ctx->pid; error = hash_delete(child_ctx->sigchld_ctx->children, &key); if (error != HASH_SUCCESS && error != HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_TRACE_INTERNAL, "failed to delete child_ctx from hash table [%d]: %s\n", error, hash_error_string(error)); } return 0; } errno_t sss_child_register(TALLOC_CTX *mem_ctx, struct sss_sigchild_ctx *sigchld_ctx, pid_t pid, sss_child_fn_t cb, void *pvt, struct sss_child_ctx **child_ctx) { struct sss_child_ctx *child; hash_key_t key; hash_value_t value; int error; child = talloc_zero(mem_ctx, struct sss_child_ctx); if (child == NULL) { return ENOMEM; } child->pid = pid; child->cb = cb; child->pvt = pvt; child->sigchld_ctx = sigchld_ctx; key.type = HASH_KEY_ULONG; key.ul = pid; value.type = HASH_VALUE_PTR; value.ptr = child; error = hash_enter(sigchld_ctx->children, &key, &value); if (error != HASH_SUCCESS) { talloc_free(child); return ENOMEM; } talloc_set_destructor((TALLOC_CTX *) child, sss_child_destructor); *child_ctx = child; return EOK; } struct sss_child_cb_pvt { struct sss_child_ctx *child_ctx; int wait_status; }; static void sss_child_invoke_cb(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt) { struct sss_child_cb_pvt *cb_pvt; struct sss_child_ctx *child_ctx; hash_key_t key; int error; cb_pvt = talloc_get_type(pvt, struct sss_child_cb_pvt); child_ctx = cb_pvt->child_ctx; key.type = HASH_KEY_ULONG; key.ul = child_ctx->pid; error = hash_delete(child_ctx->sigchld_ctx->children, &key); if (error != HASH_SUCCESS && error != HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_OP_FAILURE, "failed to delete child_ctx from hash table [%d]: %s\n", error, hash_error_string(error)); } if (child_ctx->cb) { child_ctx->cb(child_ctx->pid, cb_pvt->wait_status, child_ctx->pvt); } talloc_free(imm); } static void sss_child_handler(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { struct sss_sigchild_ctx *sigchld_ctx; struct tevent_immediate *imm; struct sss_child_cb_pvt *invoke_pvt; struct sss_child_ctx *child_ctx; hash_key_t key; hash_value_t value; int error; int wait_status; pid_t pid; sigchld_ctx = talloc_get_type(private_data, struct sss_sigchild_ctx); key.type = HASH_KEY_ULONG; do { do { errno = 0; pid = waitpid(-1, &wait_status, WNOHANG | sigchld_ctx->options); } while (pid == -1 && errno == EINTR); if (pid == -1) { DEBUG(SSSDBG_TRACE_INTERNAL, "waitpid failed [%d]: %s\n", errno, strerror(errno)); return; } else if (pid == 0) continue; key.ul = pid; error = hash_lookup(sigchld_ctx->children, &key, &value); if (error == HASH_SUCCESS) { child_ctx = talloc_get_type(value.ptr, struct sss_child_ctx); imm = tevent_create_immediate(child_ctx); if (imm == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory invoking SIGCHLD callback\n"); return; } invoke_pvt = talloc_zero(child_ctx, struct sss_child_cb_pvt); if (invoke_pvt == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "out of memory invoking SIGCHLD callback\n"); return; } invoke_pvt->child_ctx = child_ctx; invoke_pvt->wait_status = wait_status; tevent_schedule_immediate(imm, sigchld_ctx->ev, sss_child_invoke_cb, invoke_pvt); } else if (error == HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_TRACE_LIBS, "BUG: waitpid() returned [%d] but it was not in the table. " "This could be due to a linked library creating processes " "without registering them with the sigchld handler\n", pid); /* We will simply ignore this and return to the loop * This will prevent a zombie, but may cause unexpected * behavior in the code that was trying to handle this * pid. */ } else { DEBUG(SSSDBG_OP_FAILURE, "SIGCHLD hash table error [%d]: %s\n", error, hash_error_string(error)); /* This is bad, but we should try to check for other * children anyway, to avoid potential zombies. */ } } while (pid != 0); } struct sss_child_ctx_old { struct tevent_signal *sige; pid_t pid; int child_status; sss_child_callback_t cb; void *pvt; }; static void child_sig_handler(struct tevent_context *ev, struct tevent_signal *sige, int signum, int count, void *__siginfo, void *pvt); int child_handler_setup(struct tevent_context *ev, int pid, sss_child_callback_t cb, void *pvt, struct sss_child_ctx_old **_child_ctx) { struct sss_child_ctx_old *child_ctx; DEBUG(SSSDBG_TRACE_INTERNAL, "Setting up signal handler up for pid [%d]\n", pid); child_ctx = talloc_zero(ev, struct sss_child_ctx_old); if (child_ctx == NULL) { return ENOMEM; } child_ctx->sige = tevent_add_signal(ev, child_ctx, SIGCHLD, SA_SIGINFO, child_sig_handler, child_ctx); if(!child_ctx->sige) { /* Error setting up signal handler */ talloc_free(child_ctx); return ENOMEM; } child_ctx->pid = pid; child_ctx->cb = cb; child_ctx->pvt = pvt; DEBUG(SSSDBG_TRACE_INTERNAL, "Signal handler set up for pid [%d]\n", pid); if (_child_ctx != NULL) { *_child_ctx = child_ctx; } return EOK; } void child_handler_destroy(struct sss_child_ctx_old *ctx) { errno_t ret; /* We still want to wait for the child to finish, but the caller is not * interested in the result anymore (e.g. timeout was reached). */ ctx->cb = NULL; ctx->pvt = NULL; ret = kill(ctx->pid, SIGKILL); if (ret == -1) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "kill failed [%d][%s].\n", ret, strerror(ret)); } } /* Async communication with the child process via a pipe */ struct write_pipe_state { int fd; uint8_t *buf; size_t len; ssize_t written; }; static void write_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *pvt); struct tevent_req *write_pipe_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, uint8_t *buf, size_t len, int fd) { struct tevent_req *req; struct write_pipe_state *state; struct tevent_fd *fde; req = tevent_req_create(mem_ctx, &state, struct write_pipe_state); if (req == NULL) return NULL; state->fd = fd; state->buf = buf; state->len = len; state->written = 0; fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, write_pipe_handler, req); if (fde == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_fd failed.\n"); goto fail; } return req; fail: talloc_zfree(req); return NULL; } static void write_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct write_pipe_state *state = tevent_req_data(req, struct write_pipe_state); errno_t ret; if (flags & TEVENT_FD_READ) { DEBUG(SSSDBG_CRIT_FAILURE, "write_pipe_done called with TEVENT_FD_READ," " this should not happen.\n"); tevent_req_error(req, EINVAL); return; } errno = 0; state->written = sss_atomic_write_s(state->fd, state->buf, state->len); if (state->written == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret, strerror(ret)); tevent_req_error(req, ret); return; } if (state->len != state->written) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrote %zd bytes, expected %zu\n", state->written, state->len); tevent_req_error(req, EIO); return; } DEBUG(SSSDBG_TRACE_FUNC, "All data has been sent!\n"); tevent_req_done(req); return; } int write_pipe_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct read_pipe_state { int fd; uint8_t *buf; size_t len; }; static void read_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *pvt); struct tevent_req *read_pipe_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int fd) { struct tevent_req *req; struct read_pipe_state *state; struct tevent_fd *fde; req = tevent_req_create(mem_ctx, &state, struct read_pipe_state); if (req == NULL) return NULL; state->fd = fd; state->buf = NULL; state->len = 0; fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, read_pipe_handler, req); if (fde == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_fd failed.\n"); goto fail; } return req; fail: talloc_zfree(req); return NULL; } static void read_pipe_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct read_pipe_state *state = tevent_req_data(req, struct read_pipe_state); ssize_t size; errno_t err; uint8_t buf[CHILD_MSG_CHUNK]; if (flags & TEVENT_FD_WRITE) { DEBUG(SSSDBG_CRIT_FAILURE, "read_pipe_done called with TEVENT_FD_WRITE," " this should not happen.\n"); tevent_req_error(req, EINVAL); return; } size = sss_atomic_read_s(state->fd, buf, CHILD_MSG_CHUNK); if (size == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", err, strerror(err)); tevent_req_error(req, err); return; } else if (size > 0) { state->buf = talloc_realloc(state, state->buf, uint8_t, state->len + size); if(!state->buf) { tevent_req_error(req, ENOMEM); return; } safealign_memcpy(&state->buf[state->len], buf, size, &state->len); return; } else if (size == 0) { DEBUG(SSSDBG_TRACE_FUNC, "EOF received, client finished\n"); tevent_req_done(req); return; } else { DEBUG(SSSDBG_CRIT_FAILURE, "unexpected return value of read [%zd].\n", size); tevent_req_error(req, EINVAL); return; } } int read_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **buf, ssize_t *len) { struct read_pipe_state *state; state = tevent_req_data(req, struct read_pipe_state); TEVENT_REQ_RETURN_ON_ERROR(req); *buf = talloc_steal(mem_ctx, state->buf); *len = state->len; return EOK; } static void child_invoke_callback(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt); static void child_sig_handler(struct tevent_context *ev, struct tevent_signal *sige, int signum, int count, void *__siginfo, void *pvt) { int ret, err; struct sss_child_ctx_old *child_ctx; struct tevent_immediate *imm; if (count <= 0) { DEBUG(SSSDBG_FATAL_FAILURE, "SIGCHLD handler called with invalid child count\n"); return; } child_ctx = talloc_get_type(pvt, struct sss_child_ctx_old); DEBUG(SSSDBG_TRACE_LIBS, "Waiting for child [%d].\n", child_ctx->pid); errno = 0; ret = waitpid(child_ctx->pid, &child_ctx->child_status, WNOHANG); if (ret == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "waitpid failed [%d][%s].\n", err, strerror(err)); } else if (ret == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "waitpid did not found a child with changed status.\n"); } else { if (WIFEXITED(child_ctx->child_status)) { if (WEXITSTATUS(child_ctx->child_status) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "child [%d] failed with status [%d].\n", ret, WEXITSTATUS(child_ctx->child_status)); } else { DEBUG(SSSDBG_CONF_SETTINGS, "child [%d] finished successfully.\n", ret); } } else if (WIFSIGNALED(child_ctx->child_status)) { DEBUG(SSSDBG_CRIT_FAILURE, "child [%d] was terminated by signal [%d].\n", ret, WTERMSIG(child_ctx->child_status)); } else { if (WIFSTOPPED(child_ctx->child_status)) { DEBUG(SSSDBG_TRACE_LIBS, "child [%d] was stopped by signal [%d].\n", ret, WSTOPSIG(child_ctx->child_status)); } if (WIFCONTINUED(child_ctx->child_status) == true) { DEBUG(SSSDBG_TRACE_LIBS, "child [%d] was resumed by delivery of SIGCONT.\n", ret); } return; } /* Invoke the callback in a tevent_immediate handler * so that it is safe to free the tevent_signal * */ imm = tevent_create_immediate(child_ctx); if (imm == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory invoking sig handler callback\n"); return; } tevent_schedule_immediate(imm, ev, child_invoke_callback, child_ctx); } return; } static void child_invoke_callback(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt) { struct sss_child_ctx_old *child_ctx = talloc_get_type(pvt, struct sss_child_ctx_old); if (child_ctx->cb) { child_ctx->cb(child_ctx->child_status, child_ctx->sige, child_ctx->pvt); } /* Stop monitoring for this child */ talloc_free(child_ctx); } static errno_t prepare_child_argv(TALLOC_CTX *mem_ctx, int child_debug_fd, const char *binary, const char *extra_argv[], bool extra_args_only, char ***_argv) { /* * program name, debug_level, debug_timestamps, * debug_microseconds and NULL */ uint_t argc = 5; char ** argv = NULL; errno_t ret = EINVAL; size_t i; if (extra_args_only) { argc = 2; /* program name and NULL */ } /* Save the current state in case an interrupt changes it */ bool child_debug_to_file = debug_to_file; bool child_debug_timestamps = debug_timestamps; bool child_debug_microseconds = debug_microseconds; bool child_debug_stderr = debug_to_stderr; if (!extra_args_only) { if (child_debug_to_file) argc++; if (child_debug_stderr) argc++; } if (extra_argv) { for (i = 0; extra_argv[i]; i++) argc++; } /* * program name, debug_level, debug_to_file, debug_timestamps, * debug_microseconds and NULL */ argv = talloc_array(mem_ctx, char *, argc); if (argv == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array failed.\n"); return ENOMEM; } argv[--argc] = NULL; /* Add extra_attrs first */ if (extra_argv) { for (i = 0; extra_argv[i]; i++) { argv[--argc] = talloc_strdup(argv, extra_argv[i]); if (argv[argc] == NULL) { ret = ENOMEM; goto fail; } } } if (!extra_args_only) { argv[--argc] = talloc_asprintf(argv, "--debug-level=%#.4x", debug_level); if (argv[argc] == NULL) { ret = ENOMEM; goto fail; } if (child_debug_stderr) { argv[--argc] = talloc_strdup(argv, "--debug-to-stderr"); if (argv[argc] == NULL) { ret = ENOMEM; goto fail; } } if (child_debug_to_file) { argv[--argc] = talloc_asprintf(argv, "--debug-fd=%d", child_debug_fd); if (argv[argc] == NULL) { ret = ENOMEM; goto fail; } } argv[--argc] = talloc_asprintf(argv, "--debug-timestamps=%d", child_debug_timestamps); if (argv[argc] == NULL) { ret = ENOMEM; goto fail; } argv[--argc] = talloc_asprintf(argv, "--debug-microseconds=%d", child_debug_microseconds); if (argv[argc] == NULL) { ret = ENOMEM; goto fail; } } argv[--argc] = talloc_strdup(argv, binary); if (argv[argc] == NULL) { ret = ENOMEM; goto fail; } if (argc != 0) { ret = EINVAL; goto fail; } *_argv = argv; return EOK; fail: talloc_free(argv); return ret; } errno_t exec_child_ex(TALLOC_CTX *mem_ctx, int *pipefd_to_child, int *pipefd_from_child, const char *binary, int debug_fd, const char *extra_argv[], bool extra_args_only, int child_in_fd, int child_out_fd) { int ret; errno_t err; char **argv; close(pipefd_to_child[1]); ret = dup2(pipefd_to_child[0], child_in_fd); if (ret == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "dup2 failed [%d][%s].\n", err, strerror(err)); return err; } close(pipefd_from_child[0]); ret = dup2(pipefd_from_child[1], child_out_fd); if (ret == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "dup2 failed [%d][%s].\n", err, strerror(err)); return err; } ret = prepare_child_argv(mem_ctx, debug_fd, binary, extra_argv, extra_args_only, &argv); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "prepare_child_argv.\n"); return ret; } execv(binary, argv); err = errno; DEBUG(SSSDBG_OP_FAILURE, "execv failed [%d][%s].\n", err, strerror(err)); return err; } errno_t exec_child(TALLOC_CTX *mem_ctx, int *pipefd_to_child, int *pipefd_from_child, const char *binary, int debug_fd) { return exec_child_ex(mem_ctx, pipefd_to_child, pipefd_from_child, binary, debug_fd, NULL, false, STDIN_FILENO, STDOUT_FILENO); } int child_io_destructor(void *ptr) { int ret; struct child_io_fds *io = talloc_get_type(ptr, struct child_io_fds); if (io == NULL) return EOK; if (io->write_to_child_fd != -1) { ret = close(io->write_to_child_fd); io->write_to_child_fd = -1; if (ret != EOK) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "close failed [%d][%s].\n", ret, strerror(ret)); } } if (io->read_from_child_fd != -1) { ret = close(io->read_from_child_fd); io->read_from_child_fd = -1; if (ret != EOK) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "close failed [%d][%s].\n", ret, strerror(ret)); } } return EOK; } errno_t child_debug_init(const char *logfile, int *debug_fd) { int ret; FILE *debug_filep; if (debug_fd == NULL) { return EOK; } if (debug_to_file != 0 && *debug_fd == -1) { ret = open_debug_file_ex(logfile, &debug_filep, false); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error setting up logging (%d) [%s]\n", ret, sss_strerror(ret)); return ret; } *debug_fd = fileno(debug_filep); if (*debug_fd == -1) { DEBUG(SSSDBG_FATAL_FAILURE, "fileno failed [%d][%s]\n", errno, strerror(errno)); ret = errno; return ret; } } return EOK; } sssd-1.13.4/src/util/PaxHeaders.16287/sss_selinux.h0000644000000000000000000000007412703456111016621 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.417792825 sssd-1.13.4/src/util/sss_selinux.h0000644002412700241270000000324512703456111020274 0ustar00jhrozekjhrozek00000000000000/* SSSD SELinux-related utility functions Authors: Jan Zeleny Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_SELINUX_H_ #define SSS_SELINUX_H_ #include #include #include #define SELINUX_PRIORITY_USER_CAT 1 #define SELINUX_PRIORITY_USER_GROUP 2 #define SELINUX_PRIORITY_USER_NAME 4 /* According to specification, host has higher priority */ #define SELINUX_PRIORITY_HOST_CAT 8 #define SELINUX_PRIORITY_HOST_GROUP 16 #define SELINUX_PRIORITY_HOST_NAME 32 errno_t sss_selinux_extract_user(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *username, struct sysdb_attrs **_user_attrs); bool sss_selinux_match(struct sysdb_attrs *usermap, struct sysdb_attrs *user, struct sysdb_attrs *host, uint32_t *_priority); const char *sss_selinux_map_get_seuser(struct sysdb_attrs *usermap); #endif /* SSS_SELINUX_H_ */ sssd-1.13.4/src/util/PaxHeaders.16287/sss_log.c0000644000000000000000000000007412703456111015706 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.718793846 sssd-1.13.4/src/util/sss_log.c0000644002412700241270000000614112703456111017357 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_log.c Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #ifdef WITH_JOURNALD #include #else /* WITH_JOURNALD */ #include #endif /* WITH_JOURNALD */ static int sss_to_syslog(int priority) { switch(priority) { case SSS_LOG_EMERG: return LOG_EMERG; case SSS_LOG_ALERT: return LOG_ALERT; case SSS_LOG_CRIT: return LOG_CRIT; case SSS_LOG_ERR: return LOG_ERR; case SSS_LOG_WARNING: return LOG_WARNING; case SSS_LOG_NOTICE: return LOG_NOTICE; case SSS_LOG_INFO: return LOG_INFO; case SSS_LOG_DEBUG: return LOG_DEBUG; default: /* If we've been passed an invalid priority, it's * best to assume it's an emergency. */ return LOG_EMERG; } } static void sss_log_internal(int priority, int facility, const char *format, va_list ap); void sss_log(int priority, const char *format, ...) { va_list ap; va_start(ap, format); sss_log_internal(priority, LOG_DAEMON, format, ap); va_end(ap); } void sss_log_ext(int priority, int facility, const char *format, ...) { va_list ap; va_start(ap, format); sss_log_internal(priority, facility, format, ap); va_end(ap); } #ifdef WITH_JOURNALD static void sss_log_internal(int priority, int facility, const char *format, va_list ap) { int syslog_priority; int ret; char *message; const char *domain; ret = vasprintf(&message, format, ap); if (ret == -1) { /* ENOMEM */ return; } domain = getenv(SSS_DOM_ENV); if (domain == NULL) { domain = ""; } syslog_priority = sss_to_syslog(priority); sd_journal_send("MESSAGE=%s", message, "SSSD_DOMAIN=%s", domain, "PRIORITY=%i", syslog_priority, "SYSLOG_FACILITY=%i", LOG_FAC(facility), "SYSLOG_IDENTIFIER=%s", debug_prg_name, NULL); free(message); } #else /* WITH_JOURNALD */ static void sss_log_internal(int priority, int facility, const char *format, va_list ap) { int syslog_priority; syslog_priority = sss_to_syslog(priority); openlog(debug_prg_name, 0, facility); vsyslog(syslog_priority, format, ap); closelog(); } #endif /* WITH_JOURNALD */ sssd-1.13.4/src/util/PaxHeaders.16287/sss_config.h0000644000000000000000000000007412703456111016377 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.421792839 sssd-1.13.4/src/util/sss_config.h0000644002412700241270000000400312703456111020043 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_CONFIG_H_ #define SSS_CONFIG_H_ #include #include "util/util.h" struct sss_config_ctx; struct sss_config_ctx * sss_config_open(TALLOC_CTX *mem_ctx, const char *root, const char *file); errno_t sss_config_save(struct sss_config_ctx *ctx); void sss_config_close(struct sss_config_ctx **_ctx); errno_t sss_config_set_debug_level(struct sss_config_ctx *ctx, const char *section, uint32_t level); errno_t sss_config_service_is_enabled(struct sss_config_ctx *ctx, const char *service, bool *_result); errno_t sss_config_service_enable(struct sss_config_ctx *ctx, const char *service); errno_t sss_config_service_disable(struct sss_config_ctx *ctx, const char *service); errno_t sss_config_domain_is_enabled(struct sss_config_ctx *ctx, const char *domain, bool *_result); errno_t sss_config_domain_enable(struct sss_config_ctx *ctx, const char *domain); errno_t sss_config_domain_disable(struct sss_config_ctx *ctx, const char *domain); #endif /* SSS_CONFIG_H_ */ sssd-1.13.4/src/util/PaxHeaders.16287/dlinklist.h0000644000000000000000000000007412703456111016237 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.406792788 sssd-1.13.4/src/util/dlinklist.h0000644002412700241270000000771412703456111017717 0ustar00jhrozekjhrozek00000000000000/* Unix SMB/CIFS implementation. some simple double linked list macros Copyright (C) Andrew Tridgell 1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* To use these macros you must have a structure containing a next and prev pointer */ #ifndef _DLINKLIST_H #define _DLINKLIST_H /* hook into the front of the list */ #define DLIST_ADD(list, p) \ do { \ if (!(list)) { \ (list) = (p); \ (p)->next = (p)->prev = NULL; \ } else { \ (list)->prev = (p); \ (p)->next = (list); \ (p)->prev = NULL; \ (list) = (p); \ } \ } while (0) /* remove an element from a list - element doesn't have to be in list. */ #define DLIST_REMOVE(list, p) \ do { \ if ((p) == (list)) { \ (list) = (p)->next; \ if (list) { \ (list)->prev = NULL; \ } \ } else { \ if ((p)->prev) { \ (p)->prev->next = (p)->next; \ } \ if ((p)->next) { \ (p)->next->prev = (p)->prev; \ } \ } \ if ((p) != (list)) { \ (p)->next = (p)->prev = NULL; \ } \ } while (0) /* promote an element to the top of the list */ #define DLIST_PROMOTE(list, p) \ do { \ DLIST_REMOVE(list, p); \ DLIST_ADD(list, p); \ } while (0) /* hook into the end of the list - needs a tmp pointer */ #define DLIST_ADD_END(list, p, type) \ do { \ if (!(list)) { \ (list) = (p); \ (p)->next = (p)->prev = NULL; \ } else { \ type tmp; \ for (tmp = (list); tmp->next; tmp = tmp->next) { \ /* no op */ \ } \ tmp->next = (p); \ (p)->next = NULL; \ (p)->prev = tmp; \ } \ } while (0) /* insert 'p' after the given element 'el' in a list. If el is NULL then this is the same as a DLIST_ADD() */ #define DLIST_ADD_AFTER(list, p, el) \ do { \ if (!(list) || !(el)) { \ DLIST_ADD(list, p); \ } else { \ p->prev = el; \ p->next = el->next; \ el->next = p; \ if (p->next) { \ p->next->prev = p; \ } \ } \ } while (0) /* demote an element to the end of the list, needs a tmp pointer */ #define DLIST_DEMOTE(list, p, type) \ do { \ DLIST_REMOVE(list, p); \ DLIST_ADD_END(list, p, type); \ } while (0) /* concatenate two lists - putting all elements of the 2nd list at the end of the first list */ #define DLIST_CONCATENATE(list1, list2, type) \ do { \ if (!(list1)) { \ (list1) = (list2); \ } else { \ type tmp; \ for (tmp = (list1); tmp->next; tmp = tmp->next) { \ /* no op */ \ } \ tmp->next = (list2); \ if (list2) { \ (list2)->prev = tmp; \ } \ } \ } while (0) /* insert all elements from list2 after the given element 'el' in the * first list */ #define DLIST_ADD_LIST_AFTER(list1, el, list2, type) \ do { \ if (!(list1) || !(el) || !(list2)) { \ DLIST_CONCATENATE(list1, list2, type); \ } else { \ type tmp; \ for (tmp = (list2); tmp->next; tmp = tmp->next) { \ /* no op */ \ } \ (list2)->prev = (el); \ tmp->next = (el)->next; \ (el)->next = (list2); \ if (tmp->next != NULL) { \ tmp->next->prev = tmp; \ } \ } \ } while (0); #define DLIST_FOR_EACH(p, list) \ for ((p) = (list); (p) != NULL; (p) = (p)->next) #endif /* _DLINKLIST_H */ sssd-1.13.4/src/util/PaxHeaders.16287/authtok-utils.c0000644000000000000000000000007412703456111017052 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.869794358 sssd-1.13.4/src/util/authtok-utils.c0000644002412700241270000000417212703456111020525 0ustar00jhrozekjhrozek00000000000000/* SSSD - auth utils helpers Copyright (C) Sumit Bose 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* This file is use by SSSD clients and the main daemons. Please do not add * code which is specific to only one of them. */ #include #include "sss_client/sss_cli.h" errno_t sss_auth_pack_2fa_blob(const char *fa1, size_t fa1_len, const char *fa2, size_t fa2_len, uint8_t *buf, size_t buf_len, size_t *_2fa_blob_len) { size_t c; uint32_t tmp_uint32_t; if (fa1 == NULL || *fa1 == '\0' || fa1_len > UINT32_MAX || fa2 == NULL || *fa2 == '\0' || fa2_len > UINT32_MAX || (buf == NULL && buf_len != 0)) { return EINVAL; } if (fa1_len == 0) { fa1_len = strlen(fa1); } else { if (fa1[fa1_len] != '\0') { return EINVAL; } } if (fa2_len == 0) { fa2_len = strlen(fa2); } else { if (fa2[fa2_len] != '\0') { return EINVAL; } } *_2fa_blob_len = fa1_len + fa2_len + 2 + 2 * sizeof(uint32_t); if (buf == NULL || buf_len < *_2fa_blob_len) { return EAGAIN; } c = 0; tmp_uint32_t = (uint32_t) fa1_len + 1; SAFEALIGN_COPY_UINT32(buf, &tmp_uint32_t, &c); tmp_uint32_t = (uint32_t) fa2_len + 1; SAFEALIGN_COPY_UINT32(buf + c, &tmp_uint32_t, &c); memcpy(buf + c, fa1, fa1_len + 1); c += fa1_len + 1; memcpy(buf + c, fa2, fa2_len + 1); return 0; } sssd-1.13.4/src/util/PaxHeaders.16287/string_utils.c0000644000000000000000000000007412703456111016763 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.881794398 sssd-1.13.4/src/util/string_utils.c0000644002412700241270000000667512703456111020450 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Lukas Slebodnik Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" static char *replace_char(TALLOC_CTX *mem_ctx, const char *in, const char match, const char sub) { char *p; char *out; out = talloc_strdup(mem_ctx, in); if (out == NULL) { return NULL; } for (p = out; *p != '\0'; ++p) { if (*p == match) { *p = sub; } } return out; } char * sss_replace_space(TALLOC_CTX *mem_ctx, const char *orig_name, const char subst) { if (subst == '\0' || subst == ' ') { return talloc_strdup(mem_ctx, orig_name); } if (strchr(orig_name, subst) != NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Input [%s] already contains replacement character [%c].\n", orig_name, subst); sss_log(SSS_LOG_CRIT, "Name [%s] already contains replacement character [%c]. " \ "No replacement will be done.\n", orig_name, subst); return talloc_strdup(mem_ctx, orig_name); } return replace_char(mem_ctx, orig_name, ' ', subst); } char * sss_reverse_replace_space(TALLOC_CTX *mem_ctx, const char *orig_name, const char subst) { if (subst == '\0' || subst == ' ') { return talloc_strdup(mem_ctx, orig_name); } if (strchr(orig_name, subst) != NULL && strchr(orig_name, ' ') != NULL) { DEBUG(SSSDBG_TRACE_FUNC, "Input [%s] contains replacement character [%c] and space.\n", orig_name, subst); return talloc_strdup(mem_ctx, orig_name); } return replace_char(mem_ctx, orig_name, subst, ' '); } errno_t guid_blob_to_string_buf(const uint8_t *blob, char *str_buf, size_t buf_size) { int ret; if (blob == NULL || str_buf == NULL || buf_size < GUID_STR_BUF_SIZE) { DEBUG(SSSDBG_CRIT_FAILURE, "Buffer too small.\n"); return EINVAL; } ret = snprintf(str_buf, buf_size, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", blob[3], blob[2], blob[1], blob[0], blob[5], blob[4], blob[7], blob[6], blob[8], blob[9], blob[10], blob[11],blob[12], blob[13],blob[14], blob[15]);; if (ret != (GUID_STR_BUF_SIZE -1)) { DEBUG(SSSDBG_CRIT_FAILURE, "snprintf failed.\n"); return EIO; } return EOK; } const char *get_last_x_chars(const char *str, size_t x) { size_t len; if (str == NULL) { return NULL; } len = strlen(str); if (len < x) { return str; } return (str + len - x); } sssd-1.13.4/src/util/PaxHeaders.16287/domain_info_utils.c0000644000000000000000000000007412703456111017737 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.871794365 sssd-1.13.4/src/util/domain_info_utils.c0000644002412700241270000004742012703456111021415 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "confdb/confdb.h" #include "db/sysdb.h" #include "util/util.h" struct sss_domain_info *get_domains_head(struct sss_domain_info *domain) { struct sss_domain_info *dom = NULL; /* get to the top level domain */ for (dom = domain; dom->parent != NULL; dom = dom->parent); return dom; } struct sss_domain_info *get_next_domain(struct sss_domain_info *domain, uint32_t gnd_flags) { struct sss_domain_info *dom; bool descend = gnd_flags & SSS_GND_DESCEND; bool include_disabled = gnd_flags & SSS_GND_INCLUDE_DISABLED; dom = domain; while (dom) { if (descend && dom->subdomains) { dom = dom->subdomains; } else if (dom->next) { dom = dom->next; } else if (descend && IS_SUBDOMAIN(dom) && dom->parent->next) { dom = dom->parent->next; } else { dom = NULL; } if (dom) { if (sss_domain_get_state(dom) == DOM_DISABLED && !include_disabled) { continue; } else { /* Next domain found. */ break; } } } return dom; } bool subdomain_enumerates(struct sss_domain_info *parent, const char *sd_name) { if (parent->sd_enumerate == NULL || parent->sd_enumerate[0] == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Subdomain_enumerate not set\n"); return false; } if (strcasecmp(parent->sd_enumerate[0], "all") == 0) { return true; } else if (strcasecmp(parent->sd_enumerate[0], "none") == 0) { return false; } else { for (int i=0; parent->sd_enumerate[i]; i++) { if (strcasecmp(parent->sd_enumerate[i], sd_name) == 0) { return true; } } } return false; } struct sss_domain_info *find_domain_by_name(struct sss_domain_info *domain, const char *name, bool match_any) { struct sss_domain_info *dom = domain; if (name == NULL) { return NULL; } while (dom && sss_domain_get_state(dom) == DOM_DISABLED) { dom = get_next_domain(dom, SSS_GND_DESCEND); } while (dom) { if (strcasecmp(dom->name, name) == 0 || ((match_any == true) && (dom->flat_name != NULL) && (strcasecmp(dom->flat_name, name) == 0))) { return dom; } dom = get_next_domain(dom, SSS_GND_DESCEND); } return NULL; } struct sss_domain_info *find_domain_by_sid(struct sss_domain_info *domain, const char *sid) { struct sss_domain_info *dom = domain; size_t sid_len; size_t dom_sid_len; if (sid == NULL) { return NULL; } sid_len = strlen(sid); while (dom && sss_domain_get_state(dom) == DOM_DISABLED) { dom = get_next_domain(dom, SSS_GND_DESCEND); } while (dom) { if (dom->domain_id != NULL) { dom_sid_len = strlen(dom->domain_id); if (strncasecmp(dom->domain_id, sid, dom_sid_len) == 0) { if (dom_sid_len == sid_len) { /* sid is domain sid */ return dom; } /* sid is object sid, check if domain sid is align with * sid first subauthority component */ if (sid[dom_sid_len] == '-') { return dom; } } } dom = get_next_domain(dom, SSS_GND_DESCEND); } return NULL; } struct sss_domain_info* sss_get_domain_by_sid_ldap_fallback(struct sss_domain_info *domain, const char* sid) { /* LDAP provider doesn't know about sub-domains and hence can only * have one configured domain */ if (strcmp(domain->provider, "ldap") == 0) { return domain; } else { return find_domain_by_sid(get_domains_head(domain), sid); } } struct sss_domain_info * find_domain_by_object_name(struct sss_domain_info *domain, const char *object_name) { TALLOC_CTX *tmp_ctx; struct sss_domain_info *dom = NULL; char *domainname = NULL; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return NULL; } ret = sss_parse_name(tmp_ctx, domain->names, object_name, &domainname, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name '%s' [%d]: %s\n", object_name, ret, sss_strerror(ret)); goto done; } if (domainname == NULL) { dom = domain; } else { dom = find_domain_by_name(domain, domainname, true); } done: talloc_free(tmp_ctx); return dom; } errno_t sssd_domain_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, const char *domain_name, const char *db_path, struct sss_domain_info **_domain) { int ret; struct sss_domain_info *dom; struct sysdb_ctx *sysdb; ret = confdb_get_domain(cdb, domain_name, &dom); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error retrieving domain configuration.\n"); return ret; } if (dom->sysdb != NULL) { DEBUG(SSSDBG_OP_FAILURE, "Sysdb context already initialized.\n"); return EEXIST; } ret = sysdb_domain_init(mem_ctx, dom, db_path, &sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error opening cache database.\n"); return ret; } dom->sysdb = talloc_steal(dom, sysdb); *_domain = dom; return EOK; } static errno_t sss_krb5_touch_config(void) { const char *config = NULL; errno_t ret; config = getenv("KRB5_CONFIG"); if (config == NULL) { config = KRB5_CONF_PATH; } ret = utime(config, NULL); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Unable to change mtime of \"%s\" " "[%d]: %s\n", config, ret, strerror(ret)); return ret; } return EOK; } errno_t sss_write_domain_mappings(struct sss_domain_info *domain) { struct sss_domain_info *dom; struct sss_domain_info *parent_dom; errno_t ret; errno_t err; TALLOC_CTX *tmp_ctx; const char *mapping_file; char *sanitized_domain; char *tmp_file = NULL; int fd = -1; mode_t old_mode; FILE *fstream = NULL; int i; bool capaths_started = false; char *uc_forest; char *uc_parent; if (domain == NULL || domain->name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No domain name provided\n"); return EINVAL; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; sanitized_domain = talloc_strdup(tmp_ctx, domain->name); if (sanitized_domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); return ENOMEM; } /* only alpha-numeric chars, dashes and underscores are allowed in * krb5 include directory */ for (i = 0; sanitized_domain[i] != '\0'; i++) { if (!isalnum(sanitized_domain[i]) && sanitized_domain[i] != '-' && sanitized_domain[i] != '_') { sanitized_domain[i] = '_'; } } mapping_file = talloc_asprintf(tmp_ctx, "%s/domain_realm_%s", KRB5_MAPPING_DIR, sanitized_domain); if (!mapping_file) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_FUNC_DATA, "Mapping file for domain [%s] is [%s]\n", domain->name, mapping_file); tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", mapping_file); if (tmp_file == NULL) { ret = ENOMEM; goto done; } old_mode = umask(SSS_DFL_X_UMASK); fd = mkstemp(tmp_file); umask(old_mode); if (fd < 0) { DEBUG(SSSDBG_OP_FAILURE, "creating the temp file [%s] for domain-realm mappings " "failed.\n", tmp_file); ret = EIO; talloc_zfree(tmp_ctx); goto done; } fstream = fdopen(fd, "a"); if (!fstream) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "fdopen failed [%d]: %s\n", ret, strerror(ret)); ret = close(fd); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fclose failed [%d][%s].\n", ret, strerror(ret)); /* Nothing to do here, just report the failure */ } ret = EIO; goto done; } ret = fprintf(fstream, "[domain_realm]\n"); if (ret < 0) { DEBUG(SSSDBG_OP_FAILURE, "fprintf failed\n"); ret = EIO; goto done; } for (dom = get_next_domain(domain, SSS_GND_DESCEND); dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */ dom = get_next_domain(dom, 0)) { ret = fprintf(fstream, ".%s = %s\n%s = %s\n", dom->name, dom->realm, dom->name, dom->realm); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "fprintf failed\n"); goto done; } } parent_dom = domain; uc_parent = get_uppercase_realm(tmp_ctx, parent_dom->name); if (uc_parent == NULL) { DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n"); ret = ENOMEM; goto done; } for (dom = get_next_domain(domain, SSS_GND_DESCEND); dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */ dom = get_next_domain(dom, 0)) { if (dom->forest == NULL) { continue; } uc_forest = get_uppercase_realm(tmp_ctx, dom->forest); if (uc_forest == NULL) { DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n"); ret = ENOMEM; goto done; } if (!capaths_started) { ret = fprintf(fstream, "[capaths]\n"); if (ret < 0) { DEBUG(SSSDBG_OP_FAILURE, "fprintf failed\n"); ret = EIO; goto done; } capaths_started = true; } ret = fprintf(fstream, "%s = {\n %s = %s\n}\n%s = {\n %s = %s\n}\n", dom->realm, uc_parent, uc_forest, uc_parent, dom->realm, uc_forest); if (ret < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "fprintf failed\n"); goto done; } } ret = fclose(fstream); fstream = NULL; if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fclose failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = rename(tmp_file, mapping_file); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "rename failed [%d][%s].\n", ret, strerror(ret)); goto done; } talloc_zfree(tmp_file); ret = chmod(mapping_file, 0644); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fchmod failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = EOK; done: err = sss_krb5_touch_config(); if (err != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to change last modification time " "of krb5.conf. Created mappings may not be loaded.\n"); /* Ignore */ } if (fstream) { err = fclose(fstream); if (err != 0) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fclose failed [%d][%s].\n", err, strerror(err)); /* Nothing to do here, just report the failure */ } } if (tmp_file) { err = unlink(tmp_file); if (err < 0) { err = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Could not remove file [%s]: [%d]: %s\n", tmp_file, err, strerror(err)); } } talloc_free(tmp_ctx); return ret; } /* Save domain names, do not descend. */ errno_t get_dom_names(TALLOC_CTX *mem_ctx, struct sss_domain_info *start_dom, char ***_dom_names, int *_dom_names_count) { struct sss_domain_info *dom; TALLOC_CTX *tmp_ctx; char **dom_names; size_t count, i; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } /* get count of domains*/ count = 0; dom = start_dom; while (dom) { count++; dom = get_next_domain(dom, 0); } dom_names = talloc_array(tmp_ctx, char*, count); if (dom_names == NULL) { ret = ENOMEM; goto done; } /* copy names */ i = 0; dom = start_dom; while (dom) { dom_names[i] = talloc_strdup(dom_names, dom->name); if (dom_names[i] == NULL) { ret = ENOMEM; goto done; } dom = get_next_domain(dom, 0); i++; } if (_dom_names != NULL ) { *_dom_names = talloc_steal(mem_ctx, dom_names); } if (_dom_names_count != NULL ) { *_dom_names_count = count; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } #define LOCALAUTH_PLUGIN_CONFIG \ "[plugins]\n" \ " localauth = {\n" \ " module = sssd:"APP_MODULES_PATH"/sssd_krb5_localauth_plugin.so\n" \ " enable_only = sssd\n" \ " }" static errno_t sss_write_krb5_localauth_snippet(const char *path) { #ifdef HAVE_KRB5_LOCALAUTH_PLUGIN int ret; errno_t err; TALLOC_CTX *tmp_ctx = NULL; char *tmp_file = NULL; const char *file_name; int fd = -1; mode_t old_mode; ssize_t written; size_t size; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } file_name = talloc_asprintf(tmp_ctx, "%s/localauth_plugin", path); if (file_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_FUNC_DATA, "File for localauth plugin configuration is [%s]\n", file_name); tmp_file = talloc_asprintf(tmp_ctx, "%sXXXXXX", file_name); if (tmp_file == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } old_mode = umask(SSS_DFL_X_UMASK); fd = mkstemp(tmp_file); umask(old_mode); if (fd < 0) { DEBUG(SSSDBG_OP_FAILURE, "creating the temp file [%s] for " "domain-realm mappings failed.\n", tmp_file); ret = EIO; talloc_zfree(tmp_ctx); goto done; } size = sizeof(LOCALAUTH_PLUGIN_CONFIG) -1; written = sss_atomic_write_s(fd, discard_const(LOCALAUTH_PLUGIN_CONFIG), size); close(fd); if (written == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s]\n", ret, sss_strerror(ret)); goto done; } if (written != size) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrote %zd bytes expected %zu\n", written, size); ret = EIO; goto done; } ret = rename(tmp_file, file_name); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "rename failed [%d][%s].\n", ret, sss_strerror(ret)); goto done; } tmp_file = NULL; ret = chmod(file_name, 0644); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "chmod failed [%d][%s].\n", ret, sss_strerror(ret)); goto done; } done: if (tmp_file != NULL) { err = unlink(tmp_file); if (err == -1) { err = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Could not remove file [%s]: [%d]: %s\n", tmp_file, err, sss_strerror(err)); } } talloc_free(tmp_ctx); return ret; #else DEBUG(SSSDBG_TRACE_ALL, "Kerberos localauth plugin not available.\n"); return EOK; #endif } errno_t sss_write_krb5_conf_snippet(const char *path) { errno_t ret; errno_t err; if (path != NULL && (*path == '\0' || strcasecmp(path, "none") == 0)) { DEBUG(SSSDBG_TRACE_FUNC, "Empty path, nothing to do.\n"); return EOK; } if (path == NULL || *path != '/') { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid or missing path [%s]-\n", path == NULL ? "missing" : path); return EINVAL; } ret = sss_write_krb5_localauth_snippet(path); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_write_krb5_localauth_snippet failed.\n"); goto done; } ret = EOK; done: err = sss_krb5_touch_config(); if (err != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to change last modification time " "of krb5.conf. Created mappings may not be loaded.\n"); /* Ignore */ } return ret; } errno_t fix_domain_in_name_list(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, char **in, char ***_out) { int ret; size_t c; TALLOC_CTX *tmp_ctx; char **out; struct sss_domain_info *head; struct sss_domain_info *out_domain; char *in_name; char *in_domain; head = get_domains_head(dom); tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } /* count elements */ for (c = 0; in[c] != NULL; c++); out = talloc_zero_array(tmp_ctx, char *, c + 1); if (out == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } for (c = 0; in[c] != NULL; c++) { ret = sss_parse_name(tmp_ctx, head->names, in[c], &in_domain, &in_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_parse_name failed for [%s].\n", in[c]); goto done; } if (in_domain == NULL) { out[c] = talloc_strdup(out, in_name); } else { out_domain = find_domain_by_name(head, in_domain, true); if (out_domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find domain with name [%s].\n", in_domain); ret = EINVAL; goto done; } out[c] = sss_get_domain_name(out, in_name, out_domain); } if (out[c] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "%s failed.\n", in_domain == NULL ? "talloc_strdup" : "sss_tc_fqname"); ret = ENOMEM; goto done; } } *_out = talloc_steal(mem_ctx, out); ret = EOK; done: talloc_free(tmp_ctx); return ret; } enum sss_domain_state sss_domain_get_state(struct sss_domain_info *dom) { return dom->state; } void sss_domain_set_state(struct sss_domain_info *dom, enum sss_domain_state state) { dom->state = state; } sssd-1.13.4/src/util/PaxHeaders.16287/sss_cli_cmd.c0000644000000000000000000000007412703456111016517 xustar0030 atime=1460561751.660715661 30 ctime=1460561774.719793849 sssd-1.13.4/src/util/sss_cli_cmd.c0000644002412700241270000001542612703456111020176 0ustar00jhrozekjhrozek00000000000000/* SSSD - cmd2str util Copyright (C) Petr Cech 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "sss_client/sss_cli.h" #include "util/sss_cli_cmd.h" #include "util/util.h" const char *sss_cmd2str(enum sss_cli_command cmd) { switch (cmd) { /* null */ case SSS_CLI_NULL: return "SSS_CLI_NULL"; /* version */ case SSS_GET_VERSION: return "SSS_GET_VERSION"; /* passwd */ case SSS_NSS_GETPWNAM: return "SSS_NSS_GETPWNAM"; case SSS_NSS_GETPWUID: return "SSS_NSS_GETPWUID"; case SSS_NSS_SETPWENT: return "SSS_NSS_SETPWENT"; case SSS_NSS_GETPWENT: return "SSS_NSS_GETPWENT"; case SSS_NSS_ENDPWENT: return "SSS_NSS_ENDPWENT"; /* group */ case SSS_NSS_GETGRNAM: return "SSS_NSS_GETGRNAM"; case SSS_NSS_GETGRGID: return "SSS_NSS_GETGRGID"; case SSS_NSS_SETGRENT: return "SSS_NSS_SETGRENT"; case SSS_NSS_GETGRENT: return "SSS_NSS_GETGRENT"; case SSS_NSS_ENDGRENT: return "SSS_NSS_ENDGRENT"; case SSS_NSS_INITGR: return "SSS_NSS_INITGR"; #if 0 /* aliases */ case SSS_NSS_GETALIASBYNAME: return "SSS_NSS_GETALIASBYNAME"; case SSS_NSS_GETALIASBYPORT: return "SSS_NSS_GETALIASBYPORT"; case SSS_NSS_SETALIASENT: return "SSS_NSS_SETALIASENT"; case SSS_NSS_GETALIASENT: return "SSS_NSS_GETALIASENT"; case SSS_NSS_ENDALIASENT: return "SSS_NSS_ENDALIASENT"; /* ethers */ case SSS_NSS_GETHOSTTON: return "SSS_NSS_GETHOSTTON"; case SSS_NSS_GETNTOHOST: return "SSS_NSS_GETNTOHOST"; case SSS_NSS_SETETHERENT: return "SSS_NSS_SETETHERENT"; case SSS_NSS_GETETHERENT: return "SSS_NSS_GETETHERENT"; case SSS_NSS_ENDETHERENT: return "SSS_NSS_ENDETHERENT"; /* hosts */ case SSS_NSS_GETHOSTBYNAME: return "SSS_NSS_GETHOSTBYNAME"; case SSS_NSS_GETHOSTBYNAME2: return "SSS_NSS_GETHOSTBYNAME2"; case SSS_NSS_GETHOSTBYADDR: return "SSS_NSS_GETHOSTBYADDR"; case SSS_NSS_SETHOSTENT: return "SSS_NSS_SETHOSTENT"; case SSS_NSS_GETHOSTENT: return "SSS_NSS_GETHOSTENT"; case SSS_NSS_ENDHOSTENT: return "SSS_NSS_ENDHOSTENT"; #endif /* netgroup */ case SSS_NSS_SETNETGRENT: return "SSS_NSS_SETNETGRENT"; case SSS_NSS_GETNETGRENT: return "SSS_NSS_GETNETGRENT"; case SSS_NSS_ENDNETGRENT: return "SSS_NSS_ENDNETGRENT"; /* SSS_NSS_INNETGR: return "SSS_NSS_INNETGR"; break; */ #if 0 /* networks */ case SSS_NSS_GETNETBYNAME: return "SSS_NSS_GETNETBYNAME"; case SSS_NSS_GETNETBYADDR: return "SSS_NSS_GETNETBYADDR"; case SSS_NSS_SETNETENT: return "SSS_NSS_SETNETENT"; case SSS_NSS_GETNETENT: return "SSS_NSS_GETNETENT"; case SSS_NSS_ENDNETENT: return "SSS_NSS_ENDNETENT"; /* protocols */ case SSS_NSS_GETPROTOBYNAME: return "SSS_NSS_GETPROTOBYNAME"; case SSS_NSS_GETPROTOBYNUM: return "SSS_NSS_GETPROTOBYNUM"; case SSS_NSS_SETPROTOENT: return "SSS_NSS_SETPROTOENT"; case SSS_NSS_GETPROTOENT: return "SSS_NSS_GETPROTOENT"; case SSS_NSS_ENDPROTOENT: return "SSS_NSS_ENDPROTOENT"; /* rpc */ case SSS_NSS_GETRPCBYNAME: return "SSS_NSS_GETRPCBYNAME"; case SSS_NSS_GETRPCBYNUM: return "SSS_NSS_GETRPCBYNUM"; case SSS_NSS_SETRPCENT: return "SSS_NSS_SETRPCENT"; case SSS_NSS_GETRPCENT: return "SSS_NSS_GETRPCENT"; case SSS_NSS_ENDRPCENT: return "SSS_NSS_ENDRPCENT"; #endif /* services */ case SSS_NSS_GETSERVBYNAME: return "SSS_NSS_GETSERVBYNAME"; case SSS_NSS_GETSERVBYPORT: return "SSS_NSS_GETSERVBYPORT"; case SSS_NSS_SETSERVENT: return "SSS_NSS_SETSERVENT"; case SSS_NSS_GETSERVENT: return "SSS_NSS_GETSERVENT"; case SSS_NSS_ENDSERVENT: return "SSS_NSS_ENDSERVENT"; #if 0 /* shadow */ case SSS_NSS_GETSPNAM: return "SSS_NSS_GETSPNAM"; case SSS_NSS_GETSPUID: return "SSS_NSS_GETSPUID"; case SSS_NSS_SETSPENT: return "SSS_NSS_SETSPENT"; case SSS_NSS_GETSPENT: return "SSS_NSS_GETSPENT"; case SSS_NSS_ENDSPENT: return "SSS_NSS_ENDSPENT"; #endif /* SUDO */ case SSS_SUDO_GET_SUDORULES: return "SSS_SUDO_GET_SUDORULES"; case SSS_SUDO_GET_DEFAULTS: return "SSS_SUDO_GET_DEFAULTS"; /* autofs */ case SSS_AUTOFS_SETAUTOMNTENT: return "SSS_AUTOFS_SETAUTOMNTENT"; case SSS_AUTOFS_GETAUTOMNTENT: return "SSS_AUTOFS_GETAUTOMNTENT"; case SSS_AUTOFS_GETAUTOMNTBYNAME: return "SSS_AUTOFS_GETAUTOMNTBYNAME"; case SSS_AUTOFS_ENDAUTOMNTENT: return "SSS_AUTOFS_ENDAUTOMNTENT"; /* SSH */ case SSS_SSH_GET_USER_PUBKEYS: return "SSS_SSH_GET_USER_PUBKEYS"; case SSS_SSH_GET_HOST_PUBKEYS: return "SSS_SSH_GET_HOST_PUBKEYS"; /* PAM related calls */ case SSS_PAM_AUTHENTICATE: return "SSS_PAM_AUTHENTICATE"; case SSS_PAM_SETCRED: return "SSS_PAM_SETCRED"; case SSS_PAM_ACCT_MGMT: return "SSS_PAM_ACCT_MGMT"; case SSS_PAM_OPEN_SESSION: return "SSS_PAM_OPEN_SESSION"; case SSS_PAM_CLOSE_SESSION: return "SSS_PAM_CLOSE_SESSION"; case SSS_PAM_CHAUTHTOK: return "SSS_PAM_CHAUTHTOK"; case SSS_PAM_CHAUTHTOK_PRELIM: return "SSS_PAM_CHAUTHTOK_PRELIM"; case SSS_CMD_RENEW: return "SSS_CMD_RENEW"; case SSS_PAM_PREAUTH: return "SSS_PAM_PREAUTH"; /* PAC responder calls */ case SSS_PAC_ADD_PAC_USER: return "SSS_PAC_ADD_PAC_USER"; /* ID-SID mapping calls */ case SSS_NSS_GETSIDBYNAME: return "SSS_NSS_GETSIDBYNAME"; case SSS_NSS_GETSIDBYID: return "SSS_NSS_GETSIDBYID"; case SSS_NSS_GETNAMEBYSID: return "SSS_NSS_GETNAMEBYSID"; case SSS_NSS_GETIDBYSID: return "SSS_NSS_GETIDBYSID"; case SSS_NSS_GETORIGBYNAME: return "SSS_NSS_GETORIGBYNAME"; default: DEBUG(SSSDBG_MINOR_FAILURE, "Translation's string is missing for command [%#x].\n", cmd); return "UNKNOWN COMMAND"; } } sssd-1.13.4/src/util/PaxHeaders.16287/sss_python.c0000644000000000000000000000007412703456111016446 xustar0030 atime=1460561751.661715665 30 ctime=1460561774.642793588 sssd-1.13.4/src/util/sss_python.c0000644002412700241270000000315512703456111020121 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "src/util/sss_python.h" #include "config.h" PyObject * sss_exception_with_doc(char *name, char *doc, PyObject *base, PyObject *dict) { #ifdef HAVE_PYERR_NEWEXCEPTIONWITHDOC return PyErr_NewExceptionWithDoc(name, doc, base, dict); #else int result; PyObject *ret = NULL; PyObject *mydict = NULL; /* points to the dict only if we create it */ PyObject *docobj; if (dict == NULL) { dict = mydict = PyDict_New(); if (dict == NULL) { return NULL; } } if (doc != NULL) { docobj = PyString_FromString(doc); if (docobj == NULL) goto failure; result = PyDict_SetItemString(dict, "__doc__", docobj); Py_DECREF(docobj); if (result < 0) goto failure; } ret = PyErr_NewException(name, base, dict); failure: Py_XDECREF(mydict); return ret; #endif } sssd-1.13.4/src/PaxHeaders.16287/external0000644000000000000000000000013212703463556014667 xustar0030 mtime=1460561774.331792534 30 atime=1460561776.118798593 30 ctime=1460561774.331792534 sssd-1.13.4/src/external/0000755002412700241270000000000012703463556016420 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/external/PaxHeaders.16287/sasl.m40000644000000000000000000000007312703456111016141 xustar0030 atime=1460561754.188724233 29 ctime=1460561774.32479251 sssd-1.13.4/src/external/sasl.m40000644002412700241270000000104612703456111017612 0ustar00jhrozekjhrozek00000000000000AC_SUBST(SASL_LIBS) AC_SUBST(SASL_CFLAGS) PKG_CHECK_MODULES([SASL], [libsasl2], [found_sasl=yes], [found_sasl=no]) SSS_AC_EXPAND_LIB_DIR() AS_IF([test x"$found_sasl" != xyes], [AC_CHECK_HEADERS([sasl/sasl.h], [AC_CHECK_LIB([sasl2], [sasl_client_init], [SASL_LIBS="-L$sss_extra_libdir -lsasl2"], [AC_MSG_ERROR([SASL library must support sasl_client_init])], [-L$sss_extra_libdir])], [AC_MSG_ERROR([SASL header files are not installed])])] ) sssd-1.13.4/src/external/PaxHeaders.16287/pkg.m40000644000000000000000000000007412703456111015761 xustar0030 atime=1460561754.183724216 30 ctime=1460561774.297792418 sssd-1.13.4/src/external/pkg.m40000644002412700241270000001205012703456111017426 0ustar00jhrozekjhrozek00000000000000# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # # Copyright © 2004 Scott James Remnant . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # # Similar to PKG_CHECK_MODULES, make sure that the first instance of # this or PKG_CHECK_MODULES is called, or make sure to call # PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_ifval([$2], [$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$PKG_CONFIG"; then if test -n "$$1"; then pkg_cv_[]$1="$$1" else PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], [pkg_failed=yes]) fi else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` else $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD ifelse([$4], , [AC_MSG_ERROR(dnl [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT ])], [AC_MSG_RESULT([no]) $4]) elif test $pkg_failed = untried; then ifelse([$4], , [AC_MSG_FAILURE(dnl [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])], [$4]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) ifelse([$3], , :, [$3]) fi[]dnl ])# PKG_CHECK_MODULES sssd-1.13.4/src/external/PaxHeaders.16287/systemd.m40000644000000000000000000000007312703456111016667 xustar0029 atime=1460561754.18772423 30 ctime=1460561774.319792493 sssd-1.13.4/src/external/systemd.m40000644002412700241270000000304612703456111020342 0ustar00jhrozekjhrozek00000000000000dnl There are no module libsystemd-journal and libsystem-login dnl up systemd version 209 PKG_CHECK_EXISTS([libsystemd], [HAVE_LIBSYSTEMD=yes], [HAVE_LIBSYSTEMD=no]) dnl A macro to check presence of systemd on the system AC_DEFUN([AM_CHECK_SYSTEMD], [ PKG_CHECK_EXISTS(systemd, [ HAVE_SYSTEMD=1, AC_SUBST(HAVE_SYSTEMD) ], [AC_MSG_ERROR([Could not detect systemd presence])]) ]) AS_IF([test x$HAVE_LIBSYSTEMD = xyes], [login_lib_name=libsystemd], [login_lib_name=libsystemd-login]) AM_COND_IF([HAVE_SYSTEMD], [PKG_CHECK_MODULES([SYSTEMD_LOGIN], [$login_lib_name], [AC_DEFINE_UNQUOTED([HAVE_SYSTEMD_LOGIN], 1, [Build with libsystemdlogin support]) ], [AC_MSG_NOTICE([Build without libsystemd-login support])])]) dnl A macro to check presence of journald on the system AC_DEFUN([AM_CHECK_JOURNALD], [ AS_IF([test x$HAVE_LIBSYSTEMD = xyes], [journal_lib_name=libsystemd], [journal_lib_name=libsystemd-journal]) PKG_CHECK_MODULES(JOURNALD, [$journal_lib_name], [AC_DEFINE_UNQUOTED([WITH_JOURNALD], 1, [journald is available])]) dnl Some older versions of pkg-config might not set these automatically dnl while setting CFLAGS and LIBS manually twice doesn't hurt. AC_SUBST([JOURNALD_CFLAGS]) AC_SUBST([JOURNALD_LIBS]) ]) sssd-1.13.4/src/external/PaxHeaders.16287/libkeyutils.m40000644000000000000000000000007312703456111017537 xustar0029 atime=1460561754.18772423 30 ctime=1460561774.317792486 sssd-1.13.4/src/external/libkeyutils.m40000644002412700241270000000075412703456111021215 0ustar00jhrozekjhrozek00000000000000AC_SUBST(KEYUTILS_LIBS) AC_CHECK_HEADERS([keyutils.h], [AC_CHECK_LIB([keyutils], [add_key], [AC_DEFINE(USE_KEYRING, 1, [Define if the keyring should be used]) KEYUTILS_LIBS="-lkeyutils" ], [AC_MSG_WARN([No usable keyutils library found])] )], [AC_MSG_WARN([keyutils header files are not available])] ) sssd-1.13.4/src/external/PaxHeaders.16287/pac_responder.m40000644000000000000000000000007312703456111020023 xustar0029 atime=1460561754.18772423 30 ctime=1460561774.320792496 sssd-1.13.4/src/external/pac_responder.m40000644002412700241270000000264312703456111021500 0ustar00jhrozekjhrozek00000000000000AC_SUBST(NDR_KRB5PAC_CFLAGS) AC_SUBST(NDR_KRB5PAC_LIBS) AC_ARG_ENABLE([pac-responder], [AS_HELP_STRING([--enable-pac-responder], [build pac responder])], [build_pac_responder=$enableval], [build_pac_responder=yes]) ndr_krb5pac_ok=no krb5_version_ok=no if test x$build_pac_responder = xyes then PKG_CHECK_MODULES(NDR_KRB5PAC, ndr_krb5pac, ndr_krb5pac_ok=yes, AC_MSG_WARN([Cannot build pac responder without libndr_krb5pac])) AC_PATH_PROG(KRB5_CONFIG, krb5-config) AC_MSG_CHECKING(for supported MIT krb5 version) KRB5_VERSION="`$KRB5_CONFIG --version`" case $KRB5_VERSION in Kerberos\ 5\ release\ 1.9* | \ Kerberos\ 5\ release\ 1.10* | \ Kerberos\ 5\ release\ 1.11* | \ Kerberos\ 5\ release\ 1.12* | \ Kerberos\ 5\ release\ 1.13* | \ Kerberos\ 5\ release\ 1.14*) krb5_version_ok=yes AC_MSG_RESULT([yes]) ;; *) AC_MSG_RESULT([no]) AC_MSG_WARN([Cannot build authdata plugin with this version of MIT Kerberos, please use 1.9.x or later]) esac fi AM_CONDITIONAL([BUILD_PAC_RESPONDER], [test x$build_pac_responder = xyes -a x$ndr_krb5pac_ok = xyes -a x$krb5_version_ok = xyes ]) AM_COND_IF([BUILD_PAC_RESPONDER], [AC_DEFINE_UNQUOTED(HAVE_PAC_RESPONDER, 1, [Build with the PAC responder])]) sssd-1.13.4/src/external/PaxHeaders.16287/ldap.m40000644000000000000000000000007412703456111016120 xustar0030 atime=1460561754.185724223 30 ctime=1460561774.307792452 sssd-1.13.4/src/external/ldap.m40000644002412700241270000000734612703456111017601 0ustar00jhrozekjhrozek00000000000000dnl AC_SUBST(LDAP_LIBS) dnl dnl AC_CHECK_HEADERS(lber.h ldap.h, , AC_MSG_ERROR("could not locate ldap header files please install devel package")) dnl dnl AC_CHECK_LIB(lber, main, LDAP_LIBS="-llber $LDAP_LIBS") dnl AC_CHECK_LIB(ldap, main, LDAP_LIBS="-lldap $LDAP_LIBS") dnl dnl --------------------------------------------------------------------------- dnl - Check for Mozilla LDAP or OpenLDAP SDK dnl --------------------------------------------------------------------------- for p in /usr/include/openldap24 /usr/local/include; do if test -f "${p}/ldap.h"; then OPENLDAP_CFLAGS="${OPENLDAP_CFLAGS} -I${p}" break; fi done for p in /usr/lib64/openldap24 /usr/lib/openldap24 /usr/local/lib ; do if test -f "${p}/libldap.so"; then OPENLDAP_LIBS="${OPENLDAP_LIBS} -L${p}" break; fi done SAVE_CFLAGS=$CFLAGS SAVE_LIBS=$LIBS CFLAGS="$CFLAGS $OPENLDAP_CFLAGS" LIBS="$LIBS $OPENLDAP_LIBS" AC_CHECK_LIB(ldap, ldap_search, with_ldap=yes) dnl Check for other libraries we need to link with to get the main routines. test "$with_ldap" != "yes" && { AC_CHECK_LIB(ldap, ldap_open, [with_ldap=yes with_ldap_lber=yes], , -llber) } test "$with_ldap" != "yes" && { AC_CHECK_LIB(ldap, ldap_open, [with_ldap=yes with_ldap_lber=yes with_ldap_krb=yes], , -llber -lkrb) } test "$with_ldap" != "yes" && { AC_CHECK_LIB(ldap, ldap_open, [with_ldap=yes with_ldap_lber=yes with_ldap_krb=yes with_ldap_des=yes], , -llber -lkrb -ldes) } CFLAGS=$SAVE_CFLAGS LIBS=$SAVE_LIBS dnl Recently, we need -lber even though the main routines are elsewhere, dnl because otherwise be get link errors w.r.t. ber_pvt_opt_on. So just dnl check for that (it's a variable not a fun but that doesn't seem to dnl matter in these checks) and stick in -lber if so. Can't hurt (even to dnl stick it in always shouldn't hurt, I don't think) ... #### Someone who dnl #### understands LDAP needs to fix this properly. test "$with_ldap_lber" != "yes" && { AC_CHECK_LIB(lber, ber_pvt_opt_on, with_ldap_lber=yes) } if test "$with_ldap" = "yes"; then if test "$with_ldap_des" = "yes" ; then OPENLDAP_LIBS="${OPENLDAP_LIBS} -ldes" fi if test "$with_ldap_krb" = "yes" ; then OPENLDAP_LIBS="${OPENLDAP_LIBS} -lkrb" fi if test "$with_ldap_lber" = "yes" ; then OPENLDAP_LIBS="${OPENLDAP_LIBS} -llber" fi OPENLDAP_LIBS="${OPENLDAP_LIBS} -lldap" else AC_MSG_ERROR([OpenLDAP not found]) fi AC_SUBST(OPENLDAP_LIBS) AC_SUBST(OPENLDAP_CFLAGS) SAVE_CFLAGS=$CFLAGS SAVE_LIBS=$LIBS CFLAGS="$CFLAGS $OPENLDAP_CFLAGS" LIBS="$LIBS $OPENLDAP_LIBS" AC_CHECK_FUNCS([ldap_control_create ldap_init_fd \ ldap_create_deref_control_value \ ldap_parse_derefresponse_control \ ldap_derefresponse_free]) AC_CHECK_MEMBERS([struct ldap_conncb.lc_arg], [AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[ #include ]], [[ struct ldap_conncb cb; return ldap_set_option(NULL, LDAP_OPT_CONNECT_CB, &cb); ]] )], [AC_DEFINE([HAVE_LDAP_CONNCB], [1], [Define if LDAP connection callbacks are available])], [AC_MSG_WARN([Found broken callback implementation])], [])], [], [[#include ]]) AC_CHECK_TYPE([LDAPDerefRes], [], [AC_MSG_ERROR([The OpenLDAP version found does not contain the required type LDAPDerefRes])], [[#include ]]) CFLAGS=$SAVE_CFLAGS LIBS=$SAVE_LIBS AC_PATH_PROG([SLAPD], [slapd], , [$PATH$PATH_SEPARATOR/usr/sbin$PATH_SEPARATOR]) AS_IF([test -n "$SLAPD"], [HAVE_SLAPD=yes], [HAVE_SLAPD=no]) AC_CHECK_PROG([HAVE_LDAPMODIFY], [ldapmodify], [yes], [no]) sssd-1.13.4/src/external/PaxHeaders.16287/libdhash.m40000644000000000000000000000007412703456111016756 xustar0030 atime=1460561754.184724219 30 ctime=1460561774.303792439 sssd-1.13.4/src/external/libdhash.m40000644002412700241270000000023112703456111020421 0ustar00jhrozekjhrozek00000000000000AC_SUBST(DHASH_CFLAGS) AC_SUBST(DHASH_LIBS) PKG_CHECK_MODULES(DHASH, dhash >= 0.4.2, , AC_MSG_ERROR("Please install libdhash-devel") ) sssd-1.13.4/src/external/PaxHeaders.16287/libpopt.m40000644000000000000000000000007412703456111016651 xustar0030 atime=1460561754.184724219 30 ctime=1460561774.298792421 sssd-1.13.4/src/external/libpopt.m40000644002412700241270000000102712703456111020320 0ustar00jhrozekjhrozek00000000000000AC_SUBST(POPT_LIBS) AC_SUBST(POPT_CFLAGS) PKG_CHECK_MODULES([POPT], [popt], [found_popt=yes], [found_popt=no]) SSS_AC_EXPAND_LIB_DIR() AS_IF([test x"$found_popt" != xyes], [AC_CHECK_HEADERS([popt.h], [AC_CHECK_LIB([popt], [poptGetContext], [POPT_LIBS="-L$sss_extra_libdir -lpopt"], [AC_MSG_ERROR([POPT library must support poptGetContext])], [-L$sss_extra_libdir])], [AC_MSG_ERROR([POPT header files are not installed])])] ) sssd-1.13.4/src/external/PaxHeaders.16287/libldb.m40000644000000000000000000000007412703456111016430 xustar0030 atime=1460561754.184724219 30 ctime=1460561774.302792435 sssd-1.13.4/src/external/libldb.m40000644002412700241270000000241612703456111020102 0ustar00jhrozekjhrozek00000000000000AC_SUBST(LDB_CFLAGS) AC_SUBST(LDB_LIBS) PKG_CHECK_MODULES(LDB, ldb >= 0.9.2) AC_CHECK_HEADERS(ldb.h ldb_module.h, [AC_CHECK_LIB(ldb, ldb_init, [LDB_LIBS="-lldb"], , -ltevent -ltdb -ldl -lldap) ], [AC_MSG_ERROR([LDB header files are not installed])] ) AC_ARG_WITH([ldb-lib-dir], [AC_HELP_STRING([--with-ldb-lib-dir=PATH], [Path to store ldb modules [${libdir}/ldb]] ) ] ) if test x"$with_ldb_lib_dir" != x; then ldblibdir=$with_ldb_lib_dir else ldblibdir="`$PKG_CONFIG --variable=modulesdir ldb`" if ! test -d $ldblibdir; then ldblibdir="${libdir}/ldb" fi fi AC_MSG_CHECKING([feature ldb runtime version check]) AC_ARG_ENABLE(ldb-version-check, [AS_HELP_STRING([--enable-ldb-version-check], [compile with ldb runtime version check [default=no]])], enable_ldb_version_check="$enableval", enable_ldb_version_check="no") if test x"$enable_ldb_version_check" = xyes ; then AC_MSG_RESULT([yes]) AC_DEFINE([SSS_LDB_VERSION_CHECK], [1], [Define to 1 if you want ldb version check.]) else AC_MSG_RESULT([no]) fi AC_MSG_NOTICE([ldb lib directory: $ldblibdir]) AC_SUBST(ldblibdir) sssd-1.13.4/src/external/PaxHeaders.16287/python.m40000644000000000000000000000007412703456111016521 xustar0030 atime=1460561754.186724226 30 ctime=1460561774.313792472 sssd-1.13.4/src/external/python.m40000644002412700241270000000766212703456111020203 0ustar00jhrozekjhrozek00000000000000dnl Check for python-config and substitute needed CFLAGS and LDFLAGS dnl Usage: dnl AM_PYTHON_CONFIG(python_with_major_version) dnl argument python_with_major_version should be either python2 or python3 dnl This function sets the PYTHON_CFLAGS, PYTHON_LIBS and PYTHON_INCLUDES dnl variables AC_DEFUN([AM_PYTHON_CONFIG], [ AC_PATH_PROG([PYTHON_CONFIG], [python$PYTHON_VERSION-config]) AS_IF([test x"$PYTHON_CONFIG" = x], AC_MSG_ERROR([ The program python$PYTHON_VERSION-config was not found in search path. Please ensure that it is installed and its directory is included in the search path. If you want to build sssd without $1 bindings then specify --without-$1-bindings when running configure.])) PYTHON_CFLAGS="` $PYTHON_CONFIG --cflags`" PYTHON_LIBS="` $PYTHON_CONFIG --libs`" PYTHON_INCLUDES="` $PYTHON_CONFIG --includes`" ]) dnl Taken from GNOME sources dnl a macro to check for ability to create python extensions dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE]) AC_DEFUN([AM_CHECK_PYTHON_HEADERS], [ AC_REQUIRE([AM_PATH_PYTHON]) AC_MSG_CHECKING(for headers required to compile python extensions) dnl check if the headers exist: save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" AC_TRY_CPP([#include ],dnl [AC_MSG_RESULT([found]) $1],dnl [AC_MSG_RESULT([not found]) $2]) CPPFLAGS="$save_CPPFLAGS" ]) dnl Checks for a couple of functions we use that may not be defined dnl in some older python (< 2.6) versions used e.g. on RHEL6 AC_DEFUN([AM_CHECK_PYTHON_COMPAT], [ AC_REQUIRE([AM_CHECK_PYTHON_HEADERS]) save_CPPFLAGS="$CPPFLAGS" save_LIBS="$LIBS" CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" LIBS="$LIBS $PYTHON_LIBS" AC_CHECK_FUNCS([PyErr_NewExceptionWithDoc]) CPPFLAGS="$save_CPPFLAGS" LIBS="$save_LIBS" ]) dnl Clean variables after detection of python AC_DEFUN([SSS_CLEAN_PYTHON_VARIABLES], [ unset pyexecdir pkgpyexecdir pythondir pgkpythondir unset PYTHON PYTHON_CFLAGS PYTHON_LIBS PYTHON_INCLUDES unset PYTHON_PREFIX PYTHON_EXEC_PREFIX PYTHON_VERSION PYTHON_CONFIG dnl removed cached variables, required for reusing of AM_PATH_PYTHON unset am_cv_pathless_PYTHON ac_cv_path_PYTHON am_cv_python_version unset am_cv_python_platform am_cv_python_pythondir am_cv_python_pyexecdir unset ac_cv_path_PYTHON_CONFIG ]) dnl =========================================================================== dnl http://www.gnu.org/software/autoconf-archive/ax_python_module.html dnl =========================================================================== dnl dnl SYNOPSIS dnl dnl AM_PYTHON2_MODULE(modname[, fatal]) dnl dnl DESCRIPTION dnl dnl Checks for Python 2 module. dnl dnl If fatal is non-empty then absence of a module will trigger an error. dnl dnl LICENSE dnl dnl Copyright (c) 2008 Andrew Collier dnl dnl Copying and distribution of this file, with or without modification, are dnl permitted in any medium without royalty provided the copyright notice dnl and this notice are preserved. This file is offered as-is, without any dnl warranty. AC_DEFUN([AM_PYTHON2_MODULE],[ if test x"$PYTHON2" = x; then if test -n "$2"; then AC_MSG_ERROR([cannot look for $1 module: Python 2 not found]) else AC_MSG_NOTICE([cannot look for $1 module: Python 2 not found]) eval AS_TR_CPP(HAVE_PY2MOD_$1)=no fi else AC_MSG_CHECKING($(basename $PYTHON2) module: $1) $PYTHON2 -c "import $1" 2>/dev/null if test $? -eq 0; then AC_MSG_RESULT(yes) eval AS_TR_CPP(HAVE_PY2MOD_$1)=yes else AC_MSG_RESULT(no) eval AS_TR_CPP(HAVE_PY2MOD_$1)=no # if test -n "$2" then AC_MSG_ERROR(failed to find required module $1) exit 1 fi fi fi ]) sssd-1.13.4/src/external/PaxHeaders.16287/inotify.m40000644000000000000000000000007312703456111016660 xustar0029 atime=1460561754.18772423 30 ctime=1460561774.322792503 sssd-1.13.4/src/external/inotify.m40000644002412700241270000000162412703456111020333 0ustar00jhrozekjhrozek00000000000000dnl A macro to check if inotify works AC_DEFUN([AM_CHECK_INOTIFY], [ AC_CHECK_HEADERS([sys/inotify.h]) AC_MSG_CHECKING([whether sys/inotify.h actually works]) AC_LINK_IFELSE( [AC_LANG_SOURCE([ #ifdef HAVE_SYS_INOTITY_H #include , #endif int main () { return (-1 == inotify_init()); }])], [AC_MSG_RESULT([yes]); inotify_works=yes], [AC_MSG_RESULT([no])] ) SSS_AC_EXPAND_LIB_DIR() AS_IF([test x"$inotify_works" != xyes], [AC_CHECK_LIB([inotify], [inotify_init], [INOTIFY_LIBS="$sss_extra_libdir -linotify" inotify_works=yes], [inotify_works=no], [$sss_extra_libdir])] ) AS_IF([test x"$inotify_works" = xyes], [AC_DEFINE_UNQUOTED([HAVE_INOTIFY], [1], [Inotify works])]) AC_SUBST(INOTIFY_LIBS) ]) sssd-1.13.4/src/external/PaxHeaders.16287/sizes.m40000644000000000000000000000007412703456111016335 xustar0030 atime=1460561754.186724226 30 ctime=1460561774.312792469 sssd-1.13.4/src/external/sizes.m40000644002412700241270000000247012703456111020007 0ustar00jhrozekjhrozek00000000000000# Solaris needs HAVE_LONG_LONG defined AC_CHECK_TYPES(long long) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(char) AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(long long) AC_CHECK_SIZEOF(uid_t) AC_CHECK_SIZEOF(gid_t) AC_CHECK_SIZEOF(id_t) if test $ac_cv_sizeof_long_long -lt 8 ; then AC_MSG_ERROR([SSSD requires long long of 64-bits]) fi AC_CHECK_TYPE(uint_t, unsigned int) AC_CHECK_TYPE(int8_t, char) AC_CHECK_TYPE(uint8_t, unsigned char) AC_CHECK_TYPE(int16_t, short) AC_CHECK_TYPE(uint16_t, unsigned short) if test $ac_cv_sizeof_int -eq 4 ; then AC_CHECK_TYPE(int32_t, int) AC_CHECK_TYPE(uint32_t, unsigned int) elif test $ac_cv_size_long -eq 4 ; then AC_CHECK_TYPE(int32_t, long) AC_CHECK_TYPE(uint32_t, unsigned long) else AC_MSG_ERROR([LIBREPLACE no 32-bit type found]) fi AC_CHECK_TYPE(int64_t, long long) AC_CHECK_TYPE(uint64_t, unsigned long long) AC_CHECK_TYPE(size_t, unsigned int) AC_CHECK_TYPE(ssize_t, int) AC_CHECK_SIZEOF(off_t) AC_CHECK_SIZEOF(size_t) AC_CHECK_SIZEOF(ssize_t) AC_CHECK_TYPES([intptr_t], [], [AC_DEFINE_UNQUOTED([intptr_t], [long long], [Define to `long long' if does not define.])]) AC_CHECK_TYPE(uintptr_t, unsigned long long) AC_CHECK_TYPE(ptrdiff_t, unsigned long long) sssd-1.13.4/src/external/PaxHeaders.16287/signal.m40000644000000000000000000000007112703456111016452 xustar0029 atime=1460561754.18772423 28 ctime=1460561774.3217925 sssd-1.13.4/src/external/signal.m40000644002412700241270000000007512703456111020126 0ustar00jhrozekjhrozek00000000000000AC_CHECK_FUNCS(sigprocmask sigblock sigaction getpgrp prctl) sssd-1.13.4/src/external/PaxHeaders.16287/intgcheck.m40000644000000000000000000000007412703456111017137 xustar0030 atime=1460561754.188724233 30 ctime=1460561774.328792523 sssd-1.13.4/src/external/intgcheck.m40000644002412700241270000000242112703456111020605 0ustar00jhrozekjhrozek00000000000000AC_CHECK_PROG([HAVE_FAKEROOT], [fakeroot], [yes], [no]) AC_PATH_PROG([PYTEST], [py.test]) AS_IF([test -n "$PYTEST"], [HAVE_PYTEST=yes], [HAVE_PYTEST=no]) dnl Check for variable and fail unless value is "yes" dnl The second argument will be printed in error message in case of error dnl Usage: dnl SSS_INTGCHECK_REQ(variable, message) AC_DEFUN([SSS_INTGCHECK_REQ], [ AS_IF([test x$$1 = xyes], , [ AC_MSG_ERROR([cannot enable integration tests: $2 not found])]) ]) AC_DEFUN([SSS_ENABLE_INTGCHECK_REQS], [ AC_ARG_ENABLE(intgcheck-reqs, [AS_HELP_STRING([--enable-intgcheck-reqs], [enable checking for integration test requirements [default=no]])], [enable_intgcheck_reqs="$enableval"], [enable_intgcheck_reqs="no"]) if test x"$enable_intgcheck_reqs" = xyes; then SSS_INTGCHECK_REQ([HAVE_UID_WRAPPER], [uid_wrapper]) SSS_INTGCHECK_REQ([HAVE_NSS_WRAPPER], [nss_wrapper]) SSS_INTGCHECK_REQ([HAVE_SLAPD], [slapd]) SSS_INTGCHECK_REQ([HAVE_LDAPMODIFY], [ldapmodify]) SSS_INTGCHECK_REQ([HAVE_FAKEROOT], [fakeroot]) SSS_INTGCHECK_REQ([HAVE_PYTHON2], [python2]) SSS_INTGCHECK_REQ([HAVE_PYTEST], [pytest]) SSS_INTGCHECK_REQ([HAVE_PY2MOD_LDAP], [python-ldap]) fi ]) sssd-1.13.4/src/external/PaxHeaders.16287/pam.m40000644000000000000000000000007412703456111015755 xustar0030 atime=1460561754.184724219 30 ctime=1460561774.306792449 sssd-1.13.4/src/external/pam.m40000644002412700241270000000142412703456111017425 0ustar00jhrozekjhrozek00000000000000AC_SUBST(PAM_LIBS) AC_SUBST(PAM_MISC_LIBS) AC_CHECK_HEADERS([security/pam_appl.h security/pam_modules.h], [AC_CHECK_LIB([pam], [pam_get_item], [PAM_LIBS="-lpam"], [AC_MSG_ERROR([PAM must support pam_get_item])])], [AC_MSG_ERROR([PAM development libraries not installed])] ) AC_CHECK_HEADERS([security/pam_ext.h security/pam_modutil.h]) AC_CHECK_HEADERS([security/pam_misc.h security/_pam_macros.h]) AC_CHECK_HEADERS([security/openpam.h],,,[ #ifdef HAVE_SECURITY_PAM_APPL_H #include #endif ]) AC_CHECK_LIB([pam_misc], [misc_conv], [PAM_MISC_LIBS="-lpam_misc"]) dnl save LIBS to restore later save_LIBS="$LIBS" LIBS="$PAM_LIBS" AC_CHECK_FUNCS(pam_modutil_getlogin pam_vsyslog) dnl restore LIBS LIBS="$save_LIBS" sssd-1.13.4/src/external/PaxHeaders.16287/nscd.m40000644000000000000000000000007312703456111016126 xustar0029 atime=1460561754.18772423 30 ctime=1460561774.316792483 sssd-1.13.4/src/external/nscd.m40000644002412700241270000000037612703456111017604 0ustar00jhrozekjhrozek00000000000000AC_PATH_PROG(NSCD, nscd, $NSCD_PATH) AC_MSG_CHECKING(for nscd) AC_DEFINE_UNQUOTED([NSCD_PATH], "$NSCD", [The path to nscd, if available]) if test -x "$NSCD"; then AC_MSG_RESULT(yes) else AC_MSG_RESULT([not installed, assuming standard location]) fi sssd-1.13.4/src/external/PaxHeaders.16287/configlib.m40000644000000000000000000000007412703456111017134 xustar0030 atime=1460561754.188724233 30 ctime=1460561774.325792513 sssd-1.13.4/src/external/configlib.m40000644002412700241270000000071012703456111020601 0ustar00jhrozekjhrozek00000000000000AC_ARG_ENABLE([config-lib], [AS_HELP_STRING([--disable-config-lib], [do not build internal config library])], [build_config_lib=$enableval], [build_config_lib=yes]) AM_CONDITIONAL([BUILD_CONFIG_LIB], [test x$build_config_lib = xyes]) AM_COND_IF([BUILD_CONFIG_LIB], [AC_DEFINE_UNQUOTED(HAVE_CONFIG_LIB, 1, [Build with internal config library])])sssd-1.13.4/src/external/PaxHeaders.16287/libcmocka.m40000644000000000000000000000007412703456111017124 xustar0030 atime=1460561754.185724223 30 ctime=1460561774.310792462 sssd-1.13.4/src/external/libcmocka.m40000644002412700241270000000137612703456111020602 0ustar00jhrozekjhrozek00000000000000dnl A macro to check presence of cmocka on the system AC_DEFUN([AM_CHECK_CMOCKA], [ PKG_CHECK_EXISTS(cmocka >= 1.0.0, [AC_CHECK_HEADERS([stdarg.h stddef.h setjmp.h], [], dnl We are only intrested in action-if-not-found [AC_MSG_WARN([Header files stdarg.h stddef.h setjmp.h are required by cmocka]) cmocka_required_headers="no" ] ) AS_IF([test x"$cmocka_required_headers" != x"no"], [PKG_CHECK_MODULES([CMOCKA], [cmocka], [have_cmocka="yes"])] )], dnl PKG_CHECK_EXISTS ACTION-IF-NOT-FOUND [AC_MSG_WARN([No libcmocka-1.0.0 or newer library found, cmocka tests will not be built])] ) AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes]) ]) sssd-1.13.4/src/external/PaxHeaders.16287/libini_config.m40000644000000000000000000000007412703456111017773 xustar0030 atime=1460561754.184724219 30 ctime=1460561774.305792445 sssd-1.13.4/src/external/libini_config.m40000644002412700241270000000265212703456111021447 0ustar00jhrozekjhrozek00000000000000PKG_CHECK_MODULES(INI_CONFIG_V0, [ ini_config >= 0.6.1], [ INI_CONFIG_CFLAGS="$INI_CONFIG_V0_CFLAGS" INI_CONFIG_LIBS="$INI_CONFIG_V0_LIBS" HAVE_LIBINI_CONFIG_V0=1 AC_DEFINE_UNQUOTED(HAVE_LIBINI_CONFIG_V0, 1, [libini_config version 0.6.1 or greater]) PKG_CHECK_MODULES(INI_CONFIG_V1, [ ini_config >= 1.0.0], [ INI_CONFIG_CFLAGS="$INI_CONFIG_V1_CFLAGS" INI_CONFIG_LIBS="$INI_CONFIG_V1_LIBS" HAVE_LIBINI_CONFIG_V1=1 AC_DEFINE_UNQUOTED(HAVE_LIBINI_CONFIG_V1, 1, [libini_config version 1.0.0 or greater]) PKG_CHECK_MODULES(INI_CONFIG_V1_1, [ ini_config >= 1.1.0], [ INI_CONFIG_CFLAGS="$INI_CONFIG_V1_1_CFLAGS" INI_CONFIG_LIBS="$INI_CONFIG_V1_1_LIBS" HAVE_LIBINI_CONFIG_V1_1=1 AC_DEFINE_UNQUOTED(HAVE_LIBINI_CONFIG_V1_1, 1, [libini_config version 1.1.0 or greater]) ], [ AC_MSG_WARN([libini_config-devel >= 1.1.0 not available, using older version]) ] ) ], [ AC_MSG_WARN([libini_config-devel >= 1.0.0 not available, using older version]) ] ) ], [ AC_MSG_ERROR([Please install libini_config-devel]) ] ) AC_SUBST(INI_CONFIG_CFLAGS) AC_SUBST(INI_CONFIG_LIBS) sssd-1.13.4/src/external/PaxHeaders.16287/libnl.m40000644000000000000000000000007312703456111016277 xustar0029 atime=1460561754.18772423 30 ctime=1460561774.318792489 sssd-1.13.4/src/external/libnl.m40000644002412700241270000000464712703456111017762 0ustar00jhrozekjhrozek00000000000000dnl A macro to check if this particular version of libnl supports particular common libnl functions AC_DEFUN([AM_CHECK_LIBNL_FCS], [ AC_CHECK_LIB($1, [nl_socket_add_membership], [AC_DEFINE([HAVE_NL_SOCKET_ADD_MEMBERSHIP], 1, [Does libnl have nl_socket_add_membership?]) ], ) AC_CHECK_LIB($1, [nl_socket_modify_cb], [AC_DEFINE([HAVE_NL_SOCKET_MODIFY_CB], 1, [Does libnl have nl_socket_modify_cb?]) ], ) AC_CHECK_LIB($1, [rtnl_route_get_oif], [AC_DEFINE([HAVE_RTNL_ROUTE_GET_OIF], 1, [Does libnl have rtnl_route_get_oif?]) ], ) AC_CHECK_LIB($1, [nl_set_passcred], [AC_DEFINE([HAVE_NL_SET_PASSCRED], 1, [Does libnl have nl_set_passcred?]) ], ) AC_CHECK_LIB($1, [nl_socket_set_passcred], [AC_DEFINE([HAVE_NL_SOCKET_SET_PASSCRED], 1, [Does libnl have nl_socket_set_passcred?]) ], ) ]) dnl A macro to check the availability and version of libnetlink AC_DEFUN([AM_CHECK_LIBNL1], [ PKG_CHECK_MODULES(LIBNL1, libnl-1 >= 1.1,[ HAVE_LIBNL=1 HAVE_LIBNL1=1 LIBNL_CFLAGS="$LIBNL1_CFLAGS" LIBNL_LIBS="$LIBNL1_LIBS" AC_DEFINE_UNQUOTED(HAVE_LIBNL, 1, [Build with libnetlink support]) AC_DEFINE_UNQUOTED(HAVE_LIBNL1, 1, [Libnetlink version = 1]) AC_MSG_NOTICE([Building with libnl]) AC_CHECK_HEADERS(netlink.h) AC_CHECK_LIB(nl, nl_connect, [ LIBNL_LIBS="-lnl" ], [AC_MSG_ERROR([libnl is required])]) AM_CHECK_LIBNL_FCS(nl) ],[AC_MSG_WARN([Netlink v1 support unavailable or too old])]) AC_SUBST(LIBNL_CFLAGS) AC_SUBST(LIBNL_LIBS) ]) dnl A macro to check the availability of libnetlink version 3 AC_DEFUN([AM_CHECK_LIBNL3], [ PKG_CHECK_MODULES(LIBNL3, [ libnl-3.0 >= 3.0 libnl-route-3.0 >= 3.0], [ HAVE_LIBNL=1 HAVE_LIBNL3=1 LIBNL_CFLAGS="$LIBNL3_CFLAGS" LIBNL_LIBS="$LIBNL3_LIBS" AC_DEFINE_UNQUOTED(HAVE_LIBNL, 1, [Build with libnetlink support]) AC_DEFINE_UNQUOTED(HAVE_LIBNL3, 1, [Libnetlink version = 3]) AC_MSG_NOTICE([Building with libnl3]) AM_CHECK_LIBNL_FCS(nl-3) ],[AC_MSG_WARN([Netlink v3 support unavailable or too old])]) AC_SUBST(LIBNL_CFLAGS) AC_SUBST(LIBNL_LIBS) ]) sssd-1.13.4/src/external/PaxHeaders.16287/cwrap.m40000644000000000000000000000007412703456111016314 xustar0030 atime=1460561754.188724233 30 ctime=1460561774.326792516 sssd-1.13.4/src/external/cwrap.m40000644002412700241270000000154412703456111017767 0ustar00jhrozekjhrozek00000000000000dnl A macro to check presence of a cwrap wrapper on the system dnl Usage: dnl AM_CHECK_WRAPPER(name, conditional) dnl If the cwrap library is found, sets the HAVE_$name conditional AC_DEFUN([AM_CHECK_WRAPPER], [ AC_MSG_CHECKING([for $1]) PKG_CHECK_EXISTS([$1], [ AC_MSG_RESULT([yes]) AC_SUBST([$2], [yes]) ], [ AC_MSG_RESULT([no]) AC_SUBST([$2], [no]) AC_MSG_WARN([cwrap library $1 not found, some tests will not run]) ]) AM_CONDITIONAL($2, [ test x$$2 = xyes]) ]) AC_DEFUN([AM_CHECK_UID_WRAPPER], [ AM_CHECK_WRAPPER(uid_wrapper, HAVE_UID_WRAPPER) ]) AC_DEFUN([AM_CHECK_NSS_WRAPPER], [ AM_CHECK_WRAPPER(nss_wrapper, HAVE_NSS_WRAPPER) ]) sssd-1.13.4/src/external/PaxHeaders.16287/selinux.m40000644000000000000000000000007412703456111016667 xustar0030 atime=1460561754.186724226 30 ctime=1460561774.314792476 sssd-1.13.4/src/external/selinux.m40000644002412700241270000000255412703456111020344 0ustar00jhrozekjhrozek00000000000000dnl A macro to check the availability of SELinux AC_DEFUN([AM_CHECK_SELINUX], [ AC_CHECK_HEADERS(selinux/selinux.h, [AC_CHECK_LIB(selinux, is_selinux_enabled, [SELINUX_LIBS="-lselinux"], [AC_MSG_ERROR([SELinux library is missing])] ) ], [AC_MSG_ERROR([SELinux headers are missing])]) AC_SUBST(SELINUX_LIBS) ]) dnl A macro to check the availability of SELinux management library AC_DEFUN([AM_CHECK_SEMANAGE], [ AC_CHECK_HEADERS(semanage/semanage.h, [AC_CHECK_LIB(semanage, semanage_handle_create, [SEMANAGE_LIBS="-lsemanage"], [AC_MSG_ERROR([libsemanage is missing])] ) ], [AC_MSG_ERROR([libsemanage is missing])]) AC_SUBST(SEMANAGE_LIBS) ]) dnl Check if the SELinux login directory exists AC_DEFUN([AM_CHECK_SELINUX_LOGIN_DIR], [ AC_CHECK_FILE(/etc/selinux/targeted/logins/, [AC_DEFINE([HAVE_SELINUX_LOGIN_DIR], [1], [The directory to store SELinux user login is available])], [AC_MSG_WARN([SELinux login directory is not available])]) ]) sssd-1.13.4/src/external/PaxHeaders.16287/libtdb.m40000644000000000000000000000007412703456111016440 xustar0030 atime=1460561754.184724219 30 ctime=1460561774.300792428 sssd-1.13.4/src/external/libtdb.m40000644002412700241270000000101312703456111020102 0ustar00jhrozekjhrozek00000000000000AC_SUBST(TDB_CFLAGS) AC_SUBST(TDB_LIBS) PKG_CHECK_MODULES([TDB], [tdb >= 1.1.3], [found_tdb=yes], [found_tdb=no]) SSS_AC_EXPAND_LIB_DIR() AS_IF([test x"$found_tdb" != xyes], [AC_CHECK_HEADERS([tdb.h], [AC_CHECK_LIB([tdb], [tdb_repack], [TDB_LIBS="-L$sss_extra_libdir -ltdb"], [AC_MSG_ERROR([library TDB must support tdb_repack])], [-L$sss_extra_libdir])], [AC_MSG_ERROR([tdb header files are not installed])])] ) sssd-1.13.4/src/external/PaxHeaders.16287/libaugeas.m40000644000000000000000000000007412703456111017134 xustar0030 atime=1460561754.188724233 30 ctime=1460561774.329792527 sssd-1.13.4/src/external/libaugeas.m40000644002412700241270000000036112703456111020603 0ustar00jhrozekjhrozek00000000000000AC_SUBST(AUGEAS_CFLAGS) AC_SUBST(AUGEAS_LIBS) PKG_CHECK_MODULES(AUGEAS, augeas >= 1.0.0, , AC_MSG_ERROR([ Please install augeas-devel or disable this dependency by specifying --disable-config-lib when running configure.]) ) sssd-1.13.4/src/external/PaxHeaders.16287/libtevent.m40000644000000000000000000000007412703456111017174 xustar0030 atime=1460561754.184724219 30 ctime=1460561774.301792432 sssd-1.13.4/src/external/libtevent.m40000644002412700241270000000110212703456111020635 0ustar00jhrozekjhrozek00000000000000AC_SUBST(TEVENT_CFLAGS) AC_SUBST(TEVENT_LIBS) PKG_CHECK_MODULES([TEVENT], [tevent], [found_tevent=yes], [found_tevent=no]) SSS_AC_EXPAND_LIB_DIR() AS_IF([test x"$found_tevent" != xyes], [AC_CHECK_HEADER([tevent.h], [AC_CHECK_LIB([tevent], [tevent_context_init], [TEVENT_LIBS="-L$sss_extra_libdir -ltevent -ltalloc"], [AC_MSG_ERROR([libtevent missing tevent_context_init])], [-L$sss_extra_libdir -ltalloc])], [AC_MSG_ERROR([tevent header files are not installed])])] ) sssd-1.13.4/src/external/PaxHeaders.16287/docbook.m40000644000000000000000000000007412703456111016620 xustar0030 atime=1460561754.185724223 30 ctime=1460561774.311792466 sssd-1.13.4/src/external/docbook.m40000644002412700241270000000160612703456111020272 0ustar00jhrozekjhrozek00000000000000dnl Checks for tools needed to generate manual pages AC_DEFUN([CHECK_XML_TOOLS], [ AC_PATH_PROG([XSLTPROC], [xsltproc]) if test ! -x "$XSLTPROC"; then AC_MSG_ERROR([Could not find xsltproc]) fi AC_PATH_PROG([XMLLINT], [xmllint]) if test ! -x "$XMLLINT"; then AC_MSG_ERROR([Could not find xmllint]) fi ]) dnl Usage: dnl CHECK_STYLESHEET_URI(FILE, URI, [FRIENDLY-NAME], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl Checks if the XML catalog given by FILE exists and dnl if a particular URI appears in the XML catalog AC_DEFUN([CHECK_STYLESHEET], [ AC_CHECK_FILE($1, [], [AC_MSG_ERROR([could not find XML catalog])]) AC_MSG_CHECKING([for ifelse([$3],,[$2],[$3]) in XML catalog]) if AC_RUN_LOG([$XSLTPROC --catalogs --nonet --noout "$2" >&2]); then AC_MSG_RESULT([yes]) m4_ifval([$4], [$4], [:]) else AC_MSG_RESULT([no]) m4_ifval([$5], [$5], [:]) fi ]) sssd-1.13.4/src/external/PaxHeaders.16287/samba.m40000644000000000000000000000007412703456111016263 xustar0030 atime=1460561754.188724233 30 ctime=1460561774.323792506 sssd-1.13.4/src/external/samba.m40000644002412700241270000000247412703456111017741 0ustar00jhrozekjhrozek00000000000000AC_SUBST(NDR_NBT_CFLAGS) AC_SUBST(NDR_NBT_LIBS) AC_SUBST(SMBCLIENT_CFLAGS) AC_SUBST(SMBCLIENT_LIBS) if test x"$with_samba" = xyes; then PKG_CHECK_MODULES(NDR_NBT, ndr_nbt, , AC_MSG_ERROR([[Please install Samba 4 development libraries. Samba 4 libraries are necessary for building ad and ipa provider. If you do not want to build these providers it is possible to build SSSD without them. In this case, you will need to execute configure script with argument --without-samba ]])) PKG_CHECK_MODULES(SMBCLIENT, smbclient, , AC_MSG_ERROR([[Please install libsmbclient development libraries. libsmbclient libraries are necessary for building ad and ipa provider. If you do not want to build these providers it is possible to build SSSD without them. In this case, you will need to execute configure script with argument --without-samba ]])) if test x"$HAVE_LIBINI_CONFIG_V1_1" != x1; then AC_MSG_ERROR([[Please install libini_config development libraries v1.1.0, or newer. libini_config libraries are necessary for building ipa provider, as well as for building gpo-based access control in ad provider. If you do not want to build these providers it is possible to build SSSD without them. In this case, you will need to execute configure script with argument --without-samba ]]) fi fi sssd-1.13.4/src/external/PaxHeaders.16287/libcares.m40000644000000000000000000000007412703456111016764 xustar0030 atime=1460561754.185724223 30 ctime=1460561774.309792459 sssd-1.13.4/src/external/libcares.m40000644002412700241270000000104012703456111020426 0ustar00jhrozekjhrozek00000000000000AC_SUBST(CARES_LIBS) AC_SUBST(CARES_CFLAGS) PKG_CHECK_MODULES([CARES], [libcares], [found_libcares=yes], [found_libcares=no]) SSS_AC_EXPAND_LIB_DIR() AS_IF([test x"$found_libcares" != xyes], [AC_CHECK_HEADERS([ares.h], [AC_CHECK_LIB([cares], [ares_init], [CARES_LIBS="-L$sss_extra_libdir -lcares"], [AC_MSG_ERROR([No usable c-ares library found])], [-L$sss_extra_libdir])], [AC_MSG_ERROR([c-ares header files are not installed])])] ) sssd-1.13.4/src/external/PaxHeaders.16287/libcollection.m40000644000000000000000000000007412703456111020022 xustar0030 atime=1460561754.184724219 30 ctime=1460561774.304792442 sssd-1.13.4/src/external/libcollection.m40000644002412700241270000000026212703456111021471 0ustar00jhrozekjhrozek00000000000000AC_SUBST(COLLECTION_CFLAGS) AC_SUBST(COLLECTION_LIBS) PKG_CHECK_MODULES(COLLECTION, collection >= 0.5.1, , AC_MSG_ERROR("Please install libcollection-devel") ) sssd-1.13.4/src/external/PaxHeaders.16287/crypto.m40000644000000000000000000000007412703456111016520 xustar0030 atime=1460561754.186724226 30 ctime=1460561774.315792479 sssd-1.13.4/src/external/crypto.m40000644002412700241270000000047512703456111020175 0ustar00jhrozekjhrozek00000000000000AC_DEFUN([AM_CHECK_NSS], [PKG_CHECK_MODULES([NSS],[nss]) AC_DEFINE_UNQUOTED(HAVE_NSS, 1, [Build with NSS crypto back end]) ]) AC_DEFUN([AM_CHECK_LIBCRYPTO], [PKG_CHECK_MODULES([CRYPTO],[libcrypto]) AC_DEFINE_UNQUOTED(HAVE_LIBCRYPTO, 1, [Build with libcrypt crypto back end]) ]) sssd-1.13.4/src/external/PaxHeaders.16287/libresolv.m40000644000000000000000000000007312703456111017200 xustar0030 atime=1460561754.188724233 29 ctime=1460561774.32779252 sssd-1.13.4/src/external/libresolv.m40000644002412700241270000000064512703456111020655 0ustar00jhrozekjhrozek00000000000000AC_SUBST(RESOLV_CFLAGS) AC_SUBST(RESOLV_LIBS) # Some unit tests require libresolv to fake DNS packets SSS_AC_EXPAND_LIB_DIR() AC_CHECK_LIB([resolv], [ns_name_compress], [RESOLV_LIBS="-L$sss_extra_libdir -lresolv"], [AC_MSG_WARN([No libresolv detected, some tests will not run])], [-L$sss_extra_libdir]) AM_CONDITIONAL([HAVE_LIBRESOLV], [test x"$RESOLV_LIBS" != "x"]) sssd-1.13.4/src/external/PaxHeaders.16287/nsupdate.m40000644000000000000000000000007312703456111017022 xustar0029 atime=1460561754.18772423 30 ctime=1460561774.316792483 sssd-1.13.4/src/external/nsupdate.m40000644002412700241270000000113112703456111020466 0ustar00jhrozekjhrozek00000000000000AC_PATH_PROG(NSUPDATE, nsupdate) AC_MSG_CHECKING(for executable nsupdate) if test -x "$NSUPDATE"; then AC_DEFINE_UNQUOTED([NSUPDATE_PATH], ["$NSUPDATE"], [The path to nsupdate]) AC_MSG_RESULT(yes) AC_MSG_CHECKING(for nsupdate 'realm' support') if AC_RUN_LOG([echo realm |$NSUPDATE >&2]); then AC_MSG_RESULT([yes]) AC_DEFINE_UNQUOTED([HAVE_NSUPDATE_REALM], 1, [Whether to use the 'realm' directive with nsupdate]) else AC_MSG_RESULT([no]) AC_MSG_WARN([Will build without the 'realm' directive]) fi else AC_MSG_RESULT([no]) AC_MSG_ERROR([nsupdate is not available]) fi sssd-1.13.4/src/external/PaxHeaders.16287/libpcre.m40000644000000000000000000000007412703456111016620 xustar0030 atime=1460561754.185724223 30 ctime=1460561774.308792456 sssd-1.13.4/src/external/libpcre.m40000644002412700241270000000152312703456111020270 0ustar00jhrozekjhrozek00000000000000AC_SUBST(PCRE_LIBS) AC_SUBST(PCRE_CFLAGS) PKG_CHECK_MODULES([PCRE], [libpcre], [found_libpcre=yes], [found_libpcre=no]) PKG_CHECK_EXISTS(libpcre >= 7, [AC_MSG_NOTICE([PCRE version is 7 or higher])], [AC_MSG_NOTICE([PCRE version is below 7]) AC_DEFINE([HAVE_LIBPCRE_LESSER_THAN_7], 1, [Define if libpcre version is less than 7])]) SSS_AC_EXPAND_LIB_DIR() AS_IF([test x"$found_libpcre" != xyes], [AC_CHECK_HEADERS([pcre.h], [AC_CHECK_LIB([pcre], [pcre_compile], [PCRE_LIBS="-L$sss_extra_libdir -lpcre"], [AC_MSG_ERROR([No usable PCRE library found])], [-L$sss_extra_libdir])], [AC_MSG_ERROR([pcre header files are not installed])])] ) sssd-1.13.4/src/external/PaxHeaders.16287/cifsidmap.m40000644000000000000000000000007112703456111017134 xustar0029 atime=1460561754.18772423 28 ctime=1460561774.3217925 sssd-1.13.4/src/external/cifsidmap.m40000644002412700241270000000146312703456111020612 0ustar00jhrozekjhrozek00000000000000AC_ARG_ENABLE([cifs-idmap-plugin], [AS_HELP_STRING([--disable-cifs-idmap-plugin], [do not build CIFS idmap plugin])], [build_cifs_idmap_plugin=$enableval], [build_cifs_idmap_plugin=yes]) AS_IF([test x$build_cifs_idmap_plugin = xyes], [AC_CHECK_HEADER([cifsidmap.h], [], [AC_MSG_ERROR([ You must have the cifsidmap header installed to build the idmap plugin. If you want to build sssd withoud cifsidmap plugin then specify --disable-cifs-idmap-plugin when running configure.])]) ]) AM_CONDITIONAL([BUILD_CIFS_IDMAP_PLUGIN], [test x$build_cifs_idmap_plugin = xyes]) AM_COND_IF([BUILD_CIFS_IDMAP_PLUGIN], [AC_DEFINE_UNQUOTED(HAVE_CIFS_IDMAP_PLUGIN, 1, [Build with cifs idmap plugin])]) sssd-1.13.4/src/external/PaxHeaders.16287/platform.m40000644000000000000000000000007412703456111017024 xustar0030 atime=1460561754.181724209 30 ctime=1460561774.295792411 sssd-1.13.4/src/external/platform.m40000644002412700241270000000314712703456111020500 0ustar00jhrozekjhrozek00000000000000AC_ARG_WITH([os], [AC_HELP_STRING([--with-os=OS_TYPE], [Type of your operation system (fedora|redhat|suse|gentoo)])] ) osname="" if test x"$with_os" != x ; then if test x"$with_os" = xfedora || \ test x"$with_os" = xredhat || \ test x"$with_os" = xsuse || \ test x"$with_os" = xgentoo || \ test x"$with_os" = xdebian ; then osname=$with_os else AC_MSG_ERROR([Illegal value -$with_os- for option --with-os]) fi fi if test x"$osname" = x ; then if test -f /etc/fedora-release ; then osname="fedora" elif test -f /etc/redhat-release ; then osname="redhat" elif test -f /etc/SuSE-release ; then osname="suse" elif test -f /etc/debian_version ; then osname="debian" elif test -f /etc/gentoo-release ; then osname="gentoo" fi AC_MSG_NOTICE([Detected operating system type: $osname]) fi AM_CONDITIONAL([HAVE_FEDORA], [test x"$osname" = xfedora]) AM_CONDITIONAL([HAVE_REDHAT], [test x"$osname" = xredhat]) AM_CONDITIONAL([HAVE_SUSE], [test x"$osname" = xsuse]) AM_CONDITIONAL([HAVE_DEBIAN], [test x"$osname" = xdebian]) AM_CONDITIONAL([HAVE_GENTOO], [test x"$osname" = xgentoo]) AC_CHECK_MEMBERS([struct ucred.pid, struct ucred.uid, struct ucred.gid], , , [[#include ]]) if test x"$ac_cv_member_struct_ucred_pid" = xyes -a \ x"$ac_cv_member_struct_ucred_uid" = xyes -a \ x"$ac_cv_member_struct_ucred_gid" = xyes ; then AC_DEFINE([HAVE_UCRED], [1], [Define if struct ucred is available]) else AC_MSG_WARN([struct ucred is not available]) fi sssd-1.13.4/src/external/PaxHeaders.16287/libunistring.m40000644000000000000000000000007312703456111017710 xustar0030 atime=1460561754.188724233 29 ctime=1460561774.33079253 sssd-1.13.4/src/external/libunistring.m40000644002412700241270000000204612703456111021362 0ustar00jhrozekjhrozek00000000000000SSS_AC_EXPAND_LIB_DIR() AC_CHECK_HEADERS([unistr.h], [AC_CHECK_LIB([unistring], [u8_strlen], [UNISTRING_LIBS="-lunistring"], [AC_MSG_ERROR([No usable libunistring library found])], [-L$sss_extra_libdir])], [AC_MSG_ERROR([libunistring header files are not installed])] ) AC_CHECK_HEADERS([unicase.h], [AC_CHECK_LIB([unistring], [u8_casecmp], [UNISTRING_LIBS="-lunistring"], [AC_MSG_ERROR([No usable libunistring library found])], [-L$sss_extra_libdir])], [AC_MSG_ERROR([libunistring header files are not installed])] ) AC_CHECK_HEADERS([unistr.h], [AC_CHECK_LIB([unistring], [u8_check], [UNISTRING_LIBS="-lunistring"], [AC_MSG_ERROR([No usable libunistring library found])], [-L$sss_extra_libdir])], [AC_MSG_ERROR([libunistring header files are not installed])] ) UNISTRING_LIBS="-L$sss_extra_libdir $UNISTRING_LIBS " sssd-1.13.4/src/external/PaxHeaders.16287/glib.m40000644000000000000000000000007412703456111016115 xustar0030 atime=1460561754.189724236 30 ctime=1460561774.331792534 sssd-1.13.4/src/external/glib.m40000644002412700241270000000045612703456111017571 0ustar00jhrozekjhrozek00000000000000PKG_CHECK_MODULES([GLIB2],[glib-2.0]) if test x$has_glib2 != xno; then SAFE_LIBS="$LIBS" LIBS="$GLIB2_LIBS" AC_CHECK_FUNC([g_utf8_validate], AC_DEFINE([HAVE_G_UTF8_VALIDATE], [1], [Define if g_utf8_validate exists])) LIBS="$SAFE_LIBS" fi sssd-1.13.4/src/external/PaxHeaders.16287/krb5.m40000644000000000000000000000007412703456111016043 xustar0030 atime=1460561754.185724223 30 ctime=1460561774.309792459 sssd-1.13.4/src/external/krb5.m40000644002412700241270000000773612703456111017527 0ustar00jhrozekjhrozek00000000000000AC_SUBST(KRB5_CFLAGS) AC_SUBST(KRB5_LIBS) if test x$KRB5_LIBS != x; then KRB5_PASSED_LIBS=$KRB5_LIBS fi if test x$KRB5_CFLAGS != x; then KRB5_PASSED_CFLAGS=$KRB5_CFLAGS fi AC_PATH_PROG(KRB5_CONFIG, krb5-config) AC_MSG_CHECKING(for working krb5-config) if test -x "$KRB5_CONFIG"; then KRB5_CFLAGS="`$KRB5_CONFIG --cflags`" KRB5_LIBS="`$KRB5_CONFIG --libs`" AC_MSG_RESULT(yes) else AC_MSG_RESULT([no]) if test x$KRB5_PASSED_LIBS = x; then AC_MSG_ERROR([Please install MIT kerberos devel package]) fi fi if test x$KRB5_PASSED_LIBS != x; then KRB5_LIBS=$KRB5_PASSED_LIBS fi if test x$KRB5_PASSED_CFLAGS != x; then KRB5_CFLAGS=$KRB5_PASSED_CFLAGS fi AC_ARG_VAR([KRB5_CFLAGS], [C compiler flags for kerberos, overriding krb5-config])dnl AC_ARG_VAR([KRB5_LIBS], [linker flags for kerberos, overriding krb5-config])dnl SAVE_CFLAGS=$CFLAGS SAVE_LIBS=$LIBS CFLAGS="$CFLAGS $KRB5_CFLAGS" LIBS="$LIBS $KRB5_LIBS" AC_CHECK_HEADERS([krb5.h krb5/krb5.h]) AC_CHECK_TYPES([krb5_ticket_times, krb5_times, krb5_trace_info], [], [], [ #ifdef HAVE_KRB5_KRB5_H #include #else #include #endif ]) AC_CHECK_FUNCS([krb5_get_init_creds_opt_alloc krb5_get_error_message \ krb5_free_unparsed_name \ krb5_get_init_creds_opt_set_expire_callback \ krb5_get_init_creds_opt_set_fast_ccache_name \ krb5_get_init_creds_opt_set_fast_flags \ krb5_get_init_creds_opt_set_canonicalize \ krb5_get_init_creds_opt_set_responder \ krb5_parse_name_flags \ krb5_unparse_name_flags \ krb5_get_init_creds_opt_set_change_password_prompt \ krb5_free_keytab_entry_contents \ krb5_kt_free_entry \ krb5_princ_realm \ krb5_get_time_offsets \ krb5_principal_get_realm \ krb5_cc_cache_match \ krb5_timestamp_to_sfstring \ krb5_set_trace_callback \ krb5_find_authdata \ krb5_kt_have_content \ krb5_cc_get_full_name]) CFLAGS=$SAVE_CFLAGS LIBS=$SAVE_LIBS CFLAGS="$CFLAGS $KRB5_CFLAGS" LIBS="$LIBS $KRB5_LIBS" if test x$ac_cv_header_krb5_h != xyes -a x$ac_cv_header_krb5_krb5_h != xyes then AC_MSG_ERROR(you must have Kerberos 5 header files to build sssd) fi AC_ARG_ENABLE([krb5-locator-plugin], [AS_HELP_STRING([--disable-krb5-locator-plugin], [do not build Kerberos locator plugin])], [build_locator=$enableval], [build_locator=yes]) AC_CHECK_HEADER([krb5/locate_plugin.h], [have_locate_plugin=yes], [have_locate_plugin=no] [AC_MSG_NOTICE([Kerberos locator plugin cannot be built])], [ #ifdef HAVE_KRB5_KRB5_H #include #else #include #endif ]) AM_CONDITIONAL([BUILD_KRB5_LOCATOR_PLUGIN], [test x$have_locate_plugin = xyes -a x$build_locator = xyes]) AM_COND_IF([BUILD_KRB5_LOCATOR_PLUGIN], [AC_DEFINE_UNQUOTED(HAVE_KRB5_LOCATOR_PLUGIN, 1, [Build with krb5 locator plugin])]) AC_CHECK_HEADER([krb5/localauth_plugin.h], [have_localauth_plugin=yes], [have_localauth_plugin=no] [AC_MSG_NOTICE([Kerberos localauth plugin cannot be built])], [ #ifdef HAVE_KRB5_KRB5_H #include #else #include #endif ]) AM_CONDITIONAL([BUILD_KRB5_LOCALAUTH_PLUGIN], [test x$have_localauth_plugin = xyes]) AM_COND_IF([BUILD_KRB5_LOCALAUTH_PLUGIN], [AC_DEFINE_UNQUOTED(HAVE_KRB5_LOCALAUTH_PLUGIN, 1, [Build with krb5 localauth plugin])]) CFLAGS=$SAVE_CFLAGS LIBS=$SAVE_LIBS sssd-1.13.4/src/external/PaxHeaders.16287/libtalloc.m40000644000000000000000000000007412703456111017145 xustar0030 atime=1460561754.184724219 30 ctime=1460561774.299792425 sssd-1.13.4/src/external/libtalloc.m40000644002412700241270000000104312703456111020612 0ustar00jhrozekjhrozek00000000000000AC_SUBST(TALLOC_CFLAGS) AC_SUBST(TALLOC_LIBS) PKG_CHECK_MODULES([TALLOC], [talloc], [found_talloc=yes], [found_talloc=no]) SSS_AC_EXPAND_LIB_DIR() AS_IF([test x"$found_talloc" != xyes], [AC_CHECK_HEADER([talloc.h], [AC_CHECK_LIB([talloc], [talloc_init], [TALLOC_LIBS="-L$sss_extra_libdir -ltalloc"], [AC_MSG_ERROR([libtalloc missing talloc_init])], [-L$sss_extra_libdir])], [AC_MSG_ERROR([libtalloc header files are not installed])])] ) sssd-1.13.4/src/external/PaxHeaders.16287/libnfsidmap.m40000644000000000000000000000007412703456111017470 xustar0030 atime=1460561754.188724233 30 ctime=1460561774.325792513 sssd-1.13.4/src/external/libnfsidmap.m40000644002412700241270000000150212703456111021135 0ustar00jhrozekjhrozek00000000000000AC_SUBST(NFSIDMAP_OBJ) AC_SUBST(NFSIDMAP_CFLAGS) AC_SUBST(NFSIDMAP_LIBS) AS_IF([test x"$with_nfsv4_idmap" = xyes], [ PKG_CHECK_MODULES([NFSIDMAP], [libnfsidmap], [found_nfsidmap=yes], [found_nfsidmap=no]) SSS_AC_EXPAND_LIB_DIR() AS_IF([test x"$found_nfsidmap" != xyes], [AC_CHECK_HEADER([nfsidmap.h], [AC_CHECK_LIB([nfsidmap], [nfs4_init_name_mapping], [NFSIDMAP_LIBS="-L$sss_extra_libdir -lnfsidmap"], [AC_MSG_ERROR([libnfsidmap missing nfs4_init_name_mapping])], [-L$sss_extra_libdir])], [AC_MSG_ERROR([libnfsidmap header files are not installed] If you want to build sssd without nfs idmap pluging then specify --without-nfsv4-idmapd-plugin when running configure.)])]) ]) sssd-1.13.4/src/PaxHeaders.16287/monitor0000644000000000000000000000013212703463557014535 xustar0030 mtime=1460561775.058794998 30 atime=1460561776.118798593 30 ctime=1460561775.058794998 sssd-1.13.4/src/monitor/0000755002412700241270000000000012703463557016266 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/monitor/PaxHeaders.16287/monitor.h0000644000000000000000000000007412703456111016443 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.403792778 sssd-1.13.4/src/monitor/monitor.h0000644002412700241270000000263012703456111020113 0ustar00jhrozekjhrozek00000000000000/* SSSD Service monitor Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _MONITOR_H_ #define _MONITOR_H_ #define RESOLV_CONF_PATH "/etc/resolv.conf" #define CONFIG_FILE_POLL_INTERVAL 5 /* seconds */ /* for detecting if NSCD is running */ #ifndef NSCD_SOCKET_PATH #define NSCD_SOCKET_PATH "/var/run/nscd/socket" #endif struct config_file_ctx; typedef int (*monitor_reconf_fn) (struct config_file_ctx *file_ctx, const char *filename); struct mt_ctx; /* from monitor_netlink.c */ struct netlink_ctx; typedef void (*network_change_cb)(void *); int setup_netlink(TALLOC_CTX *mem_ctx, struct tevent_context *ev, network_change_cb change_cb, void *cb_data, struct netlink_ctx **_nlctx); #endif /* _MONITOR_H */ sssd-1.13.4/src/monitor/PaxHeaders.16287/monitor_interfaces.h0000644000000000000000000000007412703456111020646 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.446792923 sssd-1.13.4/src/monitor/monitor_interfaces.h0000644002412700241270000000331212703456111022314 0ustar00jhrozekjhrozek00000000000000/* SSSD Sbus Interfaces Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "sbus/sssd_dbus.h" #include "monitor/monitor_iface_generated.h" /*** Monitor ***/ #define MONITOR_VERSION 0x0001 /*** Monitor SRV Interface ***/ #define MON_SRV_PATH "/org/freedesktop/sssd/monitor" /*** Monitor CLI Interface ***/ #define MONITOR_PATH "/org/freedesktop/sssd/service" #define SSSD_SERVICE_PIPE "private/sbus-monitor" int monitor_get_sbus_address(TALLOC_CTX *mem_ctx, char **address); int monitor_common_send_id(struct sbus_connection *conn, const char *name, uint16_t version); int monitor_common_pong(struct sbus_request *dbus_req, void *data); int monitor_common_res_init(struct sbus_request *dbus_req, void *data); errno_t sss_monitor_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct mon_cli_iface *mon_iface, const char *svc_name, uint16_t svc_version, void *pvt, struct sbus_connection **mon_conn); sssd-1.13.4/src/monitor/PaxHeaders.16287/monitor_sbus.c0000644000000000000000000000007412703456111017472 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.841794263 sssd-1.13.4/src/monitor/monitor_sbus.c0000644002412700241270000001431312703456111021143 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider Helpers Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* Needed for res_init() */ #include #include #include #include "util/util.h" #include "confdb/confdb.h" #include "sbus/sssd_dbus.h" #include "sbus/sbus_client.h" #include "monitor/monitor_interfaces.h" int monitor_get_sbus_address(TALLOC_CTX *mem_ctx, char **address) { char *default_address; *address = NULL; default_address = talloc_asprintf(mem_ctx, "unix:path=%s/%s", PIPE_PATH, SSSD_SERVICE_PIPE); if (default_address == NULL) { return ENOMEM; } *address = default_address; return EOK; } static void id_callback(DBusPendingCall *pending, void *ptr) { DBusMessage *reply; DBusError dbus_error; dbus_bool_t ret; dbus_uint16_t mon_ver; int type; dbus_error_init(&dbus_error); reply = dbus_pending_call_steal_reply(pending); if (!reply) { /* reply should never be null. This function shouldn't be called * until reply is valid or timeout has occurred. If reply is NULL * here, something is seriously wrong and we should bail out. */ DEBUG(SSSDBG_FATAL_FAILURE, "Severe error. A reply callback was called but no" " reply was received and no timeout occurred\n"); /* FIXME: Destroy this connection ? */ goto done; } type = dbus_message_get_type(reply); switch (type) { case DBUS_MESSAGE_TYPE_METHOD_RETURN: ret = dbus_message_get_args(reply, &dbus_error, DBUS_TYPE_UINT16, &mon_ver, DBUS_TYPE_INVALID); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse message\n"); if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); /* FIXME: Destroy this connection ? */ goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Got id ack and version (%d) from Monitor\n", mon_ver); break; case DBUS_MESSAGE_TYPE_ERROR: DEBUG(SSSDBG_FATAL_FAILURE,"The Monitor returned an error [%s]\n", dbus_message_get_error_name(reply)); /* Falling through to default intentionally*/ default: /* * Timeout or other error occurred or something * unexpected happened. * It doesn't matter which, because either way we * know that this connection isn't trustworthy. * We'll destroy it now. */ /* FIXME: Destroy this connection ? */ break; } done: dbus_pending_call_unref(pending); dbus_message_unref(reply); } int monitor_common_send_id(struct sbus_connection *conn, const char *name, uint16_t version) { DBusMessage *msg; dbus_bool_t ret; int retval; /* create the message */ msg = dbus_message_new_method_call(NULL, MON_SRV_PATH, MON_SRV_IFACE, MON_SRV_IFACE_REGISTERSERVICE); if (msg == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?!\n"); return ENOMEM; } DEBUG(SSSDBG_CONF_SETTINGS, "Sending ID: (%s,%d)\n", name, version); ret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &name, DBUS_TYPE_UINT16, &version, DBUS_TYPE_INVALID); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n"); return EIO; } retval = sbus_conn_send(conn, msg, 3000, id_callback, NULL, NULL); dbus_message_unref(msg); return retval; } int monitor_common_pong(struct sbus_request *dbus_req, void *data) { return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } int monitor_common_res_init(struct sbus_request *dbus_req, void *data) { int ret; ret = res_init(); if(ret != 0) { return EIO; } /* Send an empty reply to acknowledge receipt */ return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } errno_t sss_monitor_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct mon_cli_iface *mon_iface, const char *svc_name, uint16_t svc_version, void *pvt, struct sbus_connection **mon_conn) { errno_t ret; char *sbus_address; struct sbus_connection *conn; /* Set up SBUS connection to the monitor */ ret = monitor_get_sbus_address(NULL, &sbus_address); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not locate monitor address.\n"); return ret; } ret = sbus_client_init(mem_ctx, ev, sbus_address, &conn); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to connect to monitor services.\n"); talloc_free(sbus_address); return ret; } talloc_free(sbus_address); ret = sbus_conn_register_iface(conn, &mon_iface->vtable, MONITOR_PATH, pvt); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to export monitor client.\n"); return ret; } /* Identify ourselves to the monitor */ ret = monitor_common_send_id(conn, svc_name, svc_version); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to identify to the monitor!\n"); return ret; } *mon_conn = conn; return EOK; } sssd-1.13.4/src/monitor/PaxHeaders.16287/monitor_iface_generated.h0000644000000000000000000000007412703456111021610 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.661793653 sssd-1.13.4/src/monitor/monitor_iface_generated.h0000644002412700241270000000606212703456111023263 0ustar00jhrozekjhrozek00000000000000/* The following declarations are auto-generated from monitor_iface.xml */ #ifndef __MONITOR_IFACE_XML__ #define __MONITOR_IFACE_XML__ #include "sbus/sssd_dbus.h" /* ------------------------------------------------------------------------ * DBus Constants * * Various constants of interface and method names mostly for use by clients */ /* constants for org.freedesktop.sssd.monitor */ #define MON_SRV_IFACE "org.freedesktop.sssd.monitor" #define MON_SRV_IFACE_GETVERSION "getVersion" #define MON_SRV_IFACE_REGISTERSERVICE "RegisterService" /* constants for org.freedesktop.sssd.service */ #define MON_CLI_IFACE "org.freedesktop.sssd.service" #define MON_CLI_IFACE_PING "ping" #define MON_CLI_IFACE_RESINIT "resInit" #define MON_CLI_IFACE_SHUTDOWN "shutDown" #define MON_CLI_IFACE_GOOFFLINE "goOffline" #define MON_CLI_IFACE_RESETOFFLINE "resetOffline" #define MON_CLI_IFACE_ROTATELOGS "rotateLogs" #define MON_CLI_IFACE_CLEARMEMCACHE "clearMemcache" #define MON_CLI_IFACE_CLEARENUMCACHE "clearEnumCache" #define MON_CLI_IFACE_SYSBUSRECONNECT "sysbusReconnect" /* ------------------------------------------------------------------------ * DBus handlers * * These structures are filled in by implementors of the different * dbus interfaces to handle method calls. * * Handler functions of type sbus_msg_handler_fn accept raw messages, * other handlers are typed appropriately. If a handler that is * set to NULL is invoked it will result in a * org.freedesktop.DBus.Error.NotSupported error for the caller. * * Handlers have a matching xxx_finish() function (unless the method has * accepts raw messages). These finish functions the * sbus_request_return_and_finish() with the appropriate arguments to * construct a valid reply. Once a finish function has been called, the * @dbus_req it was called with is freed and no longer valid. */ /* vtable for org.freedesktop.sssd.monitor */ struct mon_srv_iface { struct sbus_vtable vtable; /* derive from sbus_vtable */ sbus_msg_handler_fn getVersion; sbus_msg_handler_fn RegisterService; }; /* vtable for org.freedesktop.sssd.service */ struct mon_cli_iface { struct sbus_vtable vtable; /* derive from sbus_vtable */ sbus_msg_handler_fn ping; sbus_msg_handler_fn resInit; sbus_msg_handler_fn shutDown; sbus_msg_handler_fn goOffline; sbus_msg_handler_fn resetOffline; sbus_msg_handler_fn rotateLogs; sbus_msg_handler_fn clearMemcache; sbus_msg_handler_fn clearEnumCache; sbus_msg_handler_fn sysbusReconnect; }; /* ------------------------------------------------------------------------ * DBus Interface Metadata * * These structure definitions are filled in with the information about * the interfaces, methods, properties and so on. * * The actual definitions are found in the accompanying C file next * to this header. */ /* interface info for org.freedesktop.sssd.monitor */ extern const struct sbus_interface_meta mon_srv_iface_meta; /* interface info for org.freedesktop.sssd.service */ extern const struct sbus_interface_meta mon_cli_iface_meta; #endif /* __MONITOR_IFACE_XML__ */ sssd-1.13.4/src/monitor/PaxHeaders.16287/monitor_netlink.c0000644000000000000000000000007412703456111020162 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.993794778 sssd-1.13.4/src/monitor/monitor_netlink.c0000644002412700241270000005431712703456111021643 0ustar00jhrozekjhrozek00000000000000/* SSSD - Service monitor - netlink support Authors: Jakub Hrozek Parts of this code were borrowed from NetworkManager Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #define __USE_GNU /* needed for struct ucred */ #include #include #include #include #include #include "monitor/monitor.h" #include "util/util.h" #ifdef HAVE_LIBNL #include #include #include #include #include #include #include #include #include #include #include #include #endif /* Linux header file confusion causes this to be undefined. */ #ifndef SOL_NETLINK #define SOL_NETLINK 270 #endif #define SYSFS_IFACE_TEMPLATE "/sys/class/net/%s" #define SYSFS_IFACE_PATH_MAX (16+IFNAMSIZ) #define PHY_80211_SUBDIR "phy80211" /* 9 = strlen(PHY_80211_SUBDIR)+1, 1 = path delimeter */ #define SYSFS_SUBDIR_PATH_MAX (SYSFS_IFACE_PATH_MAX+9+1) #define TYPE_FILE "type" /* 5 = strlen(TYPE_FILE)+1, 1 = path delimeter */ #define SYSFS_TYPE_PATH_MAX (SYSFS_IFACE_PATH_MAX+5+1) #define BUFSIZE 8 #ifdef HAVE_LIBNL /* Wrappers determining use of libnl version 1 or 3 */ #ifdef HAVE_LIBNL3 #define nlw_destroy_handle nl_socket_free #define nlw_alloc nl_socket_alloc #define nlw_disable_seq_check nl_socket_disable_seq_check #define nlw_geterror(error) nl_geterror(error) #define nlw_handle nl_sock #elif defined(HAVE_LIBNL1) #define nlw_destroy_handle nl_handle_destroy #define nlw_alloc nl_handle_alloc #define nlw_disable_seq_check nl_disable_sequence_check #define nlw_geterror(error) nl_geterror() #define nlw_handle nl_handle #endif /* HAVE_LIBNL3 */ #endif /* HAVE_LIBNL */ enum nlw_msg_type { NLW_LINK, NLW_ROUTE, NLW_ADDR, NLW_OTHER }; struct netlink_ctx { #ifdef HAVE_LIBNL struct nlw_handle *nlp; #endif struct tevent_fd *tefd; network_change_cb change_cb; void *cb_data; }; #ifdef HAVE_LIBNL static int netlink_ctx_destructor(void *ptr) { struct netlink_ctx *nlctx; nlctx = talloc_get_type(ptr, struct netlink_ctx); nlw_destroy_handle(nlctx->nlp); return 0; } /******************************************************************* * Utility functions *******************************************************************/ /* rtnl_route_get_oif removed from libnl3 */ int rtnlw_route_get_oif(struct rtnl_route * route) { #ifndef HAVE_RTNL_ROUTE_GET_OIF struct rtnl_nexthop * nh; int hops; hops = rtnl_route_get_nnexthops(route); if (hops <= 0) { return 0; } nh = rtnl_route_nexthop_n(route, 0); return rtnl_route_nh_get_ifindex(nh); #else return rtnl_route_get_oif(route); #endif } static bool has_wireless_extension(const char *ifname) { int s; errno_t ret; struct iwreq iwr; s = socket(PF_INET, SOCK_DGRAM, 0); if (s == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "Could not open socket: [%d] %s\n", ret, strerror(ret)); return false; } strncpy(iwr.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ-1); iwr.ifr_ifrn.ifrn_name[IFNAMSIZ-1] = '\0'; /* Does the interface support a wireless extension? */ ret = ioctl(s, SIOCGIWNAME, &iwr); close(s); return ret == 0; } static bool has_ethernet_encapsulation(const char *sysfs_path) { char type_path[SYSFS_TYPE_PATH_MAX]; errno_t ret; int fd = -1; char buf[BUFSIZE]; ret = snprintf(type_path, SYSFS_TYPE_PATH_MAX, "%s/%s", sysfs_path, TYPE_FILE); if (ret < 0) { DEBUG(SSSDBG_OP_FAILURE, "snprintf failed\n"); return false; } else if (ret >= SYSFS_TYPE_PATH_MAX) { DEBUG(SSSDBG_OP_FAILURE, "path too long?!?!\n"); return false; } errno = 0; fd = open(type_path, O_RDONLY); if (fd == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "Could not open sysfs file %s: [%d] %s\n", type_path, ret, strerror(ret)); return false; } memset(buf, 0, BUFSIZE); errno = 0; ret = sss_atomic_read_s(fd, buf, BUFSIZE); if (ret == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret)); close(fd); return false; } close(fd); buf[BUFSIZE-1] = '\0'; return strncmp(buf, "1\n", BUFSIZE) == 0; } static bool has_phy_80211_subdir(const char *sysfs_path) { char phy80211_path[SYSFS_SUBDIR_PATH_MAX]; struct stat statbuf; errno_t ret; ret = snprintf(phy80211_path, SYSFS_SUBDIR_PATH_MAX, "%s/%s", sysfs_path, PHY_80211_SUBDIR); if (ret < 0) { DEBUG(SSSDBG_OP_FAILURE, "snprintf failed\n"); return false; } else if (ret >= SYSFS_SUBDIR_PATH_MAX) { DEBUG(SSSDBG_OP_FAILURE, "path too long?!?!\n"); return false; } errno = 0; ret = stat(phy80211_path, &statbuf); if (ret == -1) { ret = errno; if (ret == ENOENT || ret == ENOTDIR) { DEBUG(SSSDBG_TRACE_LIBS, "No %s directory in sysfs, probably " "not a wireless interface\n", PHY_80211_SUBDIR); } else { DEBUG(SSSDBG_OP_FAILURE, "stat failed: [%d] %s\n", ret, strerror(ret)); } return false; } if (statbuf.st_mode & S_IFDIR) { DEBUG(SSSDBG_TRACE_LIBS, "Directory %s found in sysfs, looks like " "a wireless iface\n", PHY_80211_SUBDIR); return true; } return false; } static bool discard_iff_up(const char *ifname) { char path[SYSFS_IFACE_PATH_MAX]; errno_t ret; /* This catches most of the new 80211 drivers */ if (has_wireless_extension(ifname)) { DEBUG(SSSDBG_TRACE_FUNC, "%s has a wireless extension\n", ifname); return true; } ret = snprintf(path, SYSFS_IFACE_PATH_MAX, SYSFS_IFACE_TEMPLATE, ifname); if (ret < 0) { DEBUG(SSSDBG_OP_FAILURE, "snprintf failed\n"); return false; } else if (ret >= SYSFS_IFACE_PATH_MAX) { DEBUG(SSSDBG_OP_FAILURE, "path too long?!?!\n"); return false; } /* This will filter PPP and such. Both wired and wireless * interfaces have the encapsulation. */ if (!has_ethernet_encapsulation(path)) { DEBUG(SSSDBG_TRACE_FUNC, "%s does not have ethernet encapsulation, " "filtering out\n", ifname); return true; } /* This captures old WEXT drivers, the new mac8011 would * be caught by the ioctl check */ if (has_phy_80211_subdir(path)) { DEBUG(SSSDBG_TRACE_FUNC, "%s has a 802_11 subdir, filtering out\n", ifname); return true; } return false; } static void nladdr_to_string(struct nl_addr *nl, char *buf, size_t bufsize) { int addr_family; void *addr; addr_family = nl_addr_get_family(nl); if (addr_family != AF_INET && addr_family != AF_INET6) { strncpy(buf, "unknown", bufsize); return; } addr = nl_addr_get_binary_addr(nl); if (!addr) return; if (inet_ntop(addr_family, addr, buf, bufsize) == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "inet_ntop failed\n"); snprintf(buf, bufsize, "unknown"); } } /******************************************************************* * Wrappers for different capabilities of different libnl versions *******************************************************************/ static bool nlw_accept_message(struct nlw_handle *nlp, const struct sockaddr_nl *snl, struct nlmsghdr *hdr) { bool accept_msg = false; uint32_t local_port; if (snl == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Malformed message, skipping\n"); return false; } /* Accept any messages from the kernel */ if (hdr->nlmsg_pid == 0 || snl->nl_pid == 0) { accept_msg = true; } /* And any multicast message directed to our netlink PID, since multicast * currently requires CAP_ADMIN to use. */ local_port = nl_socket_get_local_port(nlp); if ((hdr->nlmsg_pid == local_port) && snl->nl_groups) { accept_msg = true; } if (accept_msg == false) { DEBUG(SSSDBG_TRACE_ALL, "ignoring netlink message from PID %d\n", hdr->nlmsg_pid); } return accept_msg; } static bool nlw_is_addr_object(struct nl_object *obj) { bool is_addr_object = true; struct rtnl_addr *filter; filter = rtnl_addr_alloc(); if (!filter) { DEBUG(SSSDBG_CRIT_FAILURE, "Allocation error!\n"); is_addr_object = false; } /* Ensure it's an addr object */ if (!nl_object_match_filter(obj, OBJ_CAST(filter))) { DEBUG(SSSDBG_MINOR_FAILURE, "Not an addr object\n"); is_addr_object = false; } rtnl_addr_put(filter); return is_addr_object; } static bool nlw_is_route_object(struct nl_object *obj) { bool is_route_object = true; struct rtnl_route *filter; filter = rtnl_route_alloc(); if (!filter) { DEBUG(SSSDBG_CRIT_FAILURE, "Allocation error!\n"); is_route_object = false; } /* Ensure it's a route object */ if (!nl_object_match_filter(obj, OBJ_CAST(filter))) { DEBUG(SSSDBG_MINOR_FAILURE, "Not a route object\n"); is_route_object = false; } rtnl_route_put(filter); return is_route_object; } static bool nlw_is_link_object(struct nl_object *obj) { bool is_link_object = true; struct rtnl_link *filter; filter = rtnl_link_alloc(); if (!filter) { DEBUG(SSSDBG_FATAL_FAILURE, "Allocation error!\n"); is_link_object = false; } /* Ensure it's a link object */ if (!nl_object_match_filter(obj, OBJ_CAST(filter))) { DEBUG(SSSDBG_OP_FAILURE, "Not a link object\n"); is_link_object = false; } rtnl_link_put(filter); return is_link_object; } static int nlw_enable_passcred(struct nlw_handle *nlp) { #ifdef HAVE_NL_SET_PASSCRED return nl_set_passcred(nlp, 1); /* 1 = enabled */ #elif defined(HAVE_NL_SOCKET_SET_PASSCRED) return nl_socket_set_passcred(nlp, 1); #else return EOK; /* not available in this version */ #endif } static int nlw_group_subscribe(struct nlw_handle *nlp, int group) { int ret; #ifdef HAVE_NL_SOCKET_ADD_MEMBERSHIP ret = nl_socket_add_membership(nlp, group); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add membership: %s\n", nlw_geterror(ret)); return ret; } #else int nlfd = nl_socket_get_fd(nlp); errno = 0; ret = setsockopt(nlfd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof(group)); if (ret < 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "setsockopt failed (%d): %s\n", ret, strerror(ret)); return ret; } #endif return 0; } static int nlw_groups_subscribe(struct nlw_handle *nlp, int *groups) { int ret; int i; for (i=0; groups[i]; i++) { ret = nlw_group_subscribe(nlp, groups[i]); if (ret != EOK) return ret; } return EOK; } /******************************************************************* * Callbacks for validating and receiving messages *******************************************************************/ static int event_msg_recv(struct nl_msg *msg, void *arg) { struct netlink_ctx *ctx = (struct netlink_ctx *) arg; struct nlmsghdr *hdr; const struct sockaddr_nl *snl; struct ucred *creds; creds = nlmsg_get_creds(msg); if (!creds || creds->uid != 0) { DEBUG(SSSDBG_TRACE_ALL, "Ignoring netlink message from UID %"SPRIuid"\n", creds ? creds->uid : (uid_t)-1); return NL_SKIP; } hdr = nlmsg_hdr(msg); snl = nlmsg_get_src(msg); if (!nlw_accept_message(ctx->nlp, snl, hdr)) { return NL_SKIP; } return NL_OK; } static void link_msg_handler(struct nl_object *obj, void *arg); static void route_msg_handler(struct nl_object *obj, void *arg); static void addr_msg_handler(struct nl_object *obj, void *arg); static enum nlw_msg_type message_type(struct nlmsghdr *hdr) { DEBUG(SSSDBG_FUNC_DATA, "netlink Message type: %d\n", hdr->nlmsg_type); switch (hdr->nlmsg_type) { /* network interface added */ case RTM_NEWLINK: return NLW_LINK; /* routing table changed */ case RTM_NEWROUTE: case RTM_DELROUTE: return NLW_ROUTE; /* IP address added or deleted */ case RTM_NEWADDR: case RTM_DELADDR: return NLW_ADDR; /* Something else happened, but we don't care (typically RTM_GET* ) */ default: return NLW_OTHER; } return NLW_OTHER; } static int event_msg_ready(struct nl_msg *msg, void *arg) { struct nlmsghdr *hdr = nlmsg_hdr(msg); switch (message_type(hdr)) { case NLW_LINK: nl_msg_parse(msg, &link_msg_handler, arg); break; case NLW_ROUTE: nl_msg_parse(msg, &route_msg_handler, arg); break; case NLW_ADDR: nl_msg_parse(msg, &addr_msg_handler, arg); break; default: return EOK; /* Don't care */ } return NL_OK; } static int nlw_set_callbacks(struct nlw_handle *nlp, void *data) { int ret = EIO; #ifdef HAVE_NL_SOCKET_MODIFY_CB ret = nl_socket_modify_cb(nlp, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, data); #else struct nl_cb *cb = nl_handle_get_cb(nlp); ret = nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, data); #endif if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set validation callback\n"); return ret; } #ifdef HAVE_NL_SOCKET_MODIFY_CB ret = nl_socket_modify_cb(nlp, NL_CB_VALID, NL_CB_CUSTOM, event_msg_ready, data); #else ret = nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, event_msg_ready, data); #endif if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set receive callback\n"); return ret; } return ret; } static void route_msg_debug_print(struct rtnl_route *route_obj) { int prefixlen; char buf[INET6_ADDRSTRLEN]; struct nl_addr *nl; nl = rtnl_route_get_dst(route_obj); if (nl) { nladdr_to_string(nl, buf, INET6_ADDRSTRLEN); prefixlen = nl_addr_get_prefixlen(nl); } else { strncpy(buf, "unknown", INET6_ADDRSTRLEN); prefixlen = 0; } DEBUG(SSSDBG_TRACE_LIBS, "route idx %d flags %#X family %d addr %s/%d\n", rtnlw_route_get_oif(route_obj), rtnl_route_get_flags(route_obj), rtnl_route_get_family(route_obj), buf, prefixlen); } /* * If a bridge interface is configured it sets up a timer to requery for * multicast group memberships periodically. We need to discard such * messages. */ static bool route_is_multicast(struct rtnl_route *route_obj) { struct nl_addr *nl; struct in6_addr *addr6 = NULL; struct in_addr *addr4 = NULL; nl = rtnl_route_get_dst(route_obj); if (!nl) { DEBUG(SSSDBG_MINOR_FAILURE, "A route with no destination?\n"); return false; } if (nl_addr_get_family(nl) == AF_INET) { addr4 = nl_addr_get_binary_addr(nl); if (!addr4) { return false; } return IN_MULTICAST(ntohl(addr4->s_addr)); } else if (nl_addr_get_family(nl) == AF_INET6) { addr6 = nl_addr_get_binary_addr(nl); if (!addr6) { return false; } return IN6_IS_ADDR_MULTICAST(addr6); } DEBUG(SSSDBG_MINOR_FAILURE, "Unknown route address family\n"); return false; } static void route_msg_handler(struct nl_object *obj, void *arg) { struct rtnl_route *route_obj; struct netlink_ctx *ctx = (struct netlink_ctx *) arg; if (!nlw_is_route_object(obj)) return; route_obj = (struct rtnl_route *) obj; if (route_is_multicast(route_obj)) { DEBUG(SSSDBG_TRACE_INTERNAL, "Discarding multicast route message\n"); return; } if (debug_level & SSSDBG_TRACE_LIBS) { route_msg_debug_print(route_obj); } ctx->change_cb(ctx->cb_data); } static void addr_msg_debug_print(struct rtnl_addr *addr_obj) { unsigned int flags; char str_flags[512]; int ifidx; struct nl_addr *local_addr; char buf[INET6_ADDRSTRLEN]; flags = rtnl_addr_get_flags(addr_obj); ifidx = rtnl_addr_get_ifindex(addr_obj); local_addr = rtnl_addr_get_local(addr_obj); rtnl_addr_flags2str(flags, str_flags, 512); nladdr_to_string(local_addr, buf, INET6_ADDRSTRLEN); DEBUG(SSSDBG_TRACE_LIBS, "netlink addr message: iface idx %u " "addr %s flags 0x%X (%s)\n", ifidx, buf, flags, str_flags); } static void addr_msg_handler(struct nl_object *obj, void *arg) { struct netlink_ctx *ctx = (struct netlink_ctx *) arg; struct rtnl_addr *addr_obj; if (!nlw_is_addr_object(obj)) return; addr_obj = (struct rtnl_addr *) obj; if (debug_level & SSSDBG_TRACE_LIBS) { addr_msg_debug_print(addr_obj); } ctx->change_cb(ctx->cb_data); } static void link_msg_handler(struct nl_object *obj, void *arg) { struct netlink_ctx *ctx = (struct netlink_ctx *) arg; struct rtnl_link *link_obj; unsigned int flags; char str_flags[512]; int ifidx; const char *ifname; if (!nlw_is_link_object(obj)) return; link_obj = (struct rtnl_link *) obj; flags = rtnl_link_get_flags(link_obj); ifidx = rtnl_link_get_ifindex(link_obj); rtnl_link_flags2str(flags, str_flags, 512); ifname = rtnl_link_get_name(link_obj); DEBUG(SSSDBG_TRACE_LIBS, "netlink link message: iface idx %u (%s) " "flags 0x%X (%s)\n", ifidx, ifname, flags, str_flags); /* IFF_LOWER_UP is the indicator of carrier status */ if ((flags & IFF_RUNNING) && (flags & IFF_LOWER_UP) && !discard_iff_up(ifname)) { ctx->change_cb(ctx->cb_data); } } static void netlink_fd_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *data) { struct netlink_ctx *nlctx = talloc_get_type(data, struct netlink_ctx); int ret; if (!nlctx || !nlctx->nlp) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid netlink handle, this is most likely a bug!\n"); return; } ret = nl_recvmsgs_default(nlctx->nlp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error while reading from netlink fd\n"); return; } } /******************************************************************* * Set up the netlink library *******************************************************************/ int setup_netlink(TALLOC_CTX *mem_ctx, struct tevent_context *ev, network_change_cb change_cb, void *cb_data, struct netlink_ctx **_nlctx) { struct netlink_ctx *nlctx; int ret; int nlfd; unsigned flags; int groups[] = { RTNLGRP_LINK, RTNLGRP_IPV4_ROUTE, RTNLGRP_IPV6_ROUTE, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, 0 }; nlctx = talloc_zero(mem_ctx, struct netlink_ctx); if (!nlctx) return ENOMEM; talloc_set_destructor((TALLOC_CTX *) nlctx, netlink_ctx_destructor); nlctx->change_cb = change_cb; nlctx->cb_data = cb_data; /* allocate the libnl handle/socket and register the default filter set */ nlctx->nlp = nlw_alloc(); if (!nlctx->nlp) { DEBUG(SSSDBG_CRIT_FAILURE, "unable to allocate netlink handle: %s\n", nlw_geterror(ENOMEM)); ret = ENOMEM; goto fail; } /* Register our custom message validation filter */ ret = nlw_set_callbacks(nlctx->nlp, nlctx); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set callbacks\n"); ret = EIO; goto fail; } /* Try to start talking to netlink */ ret = nl_connect(nlctx->nlp, NETLINK_ROUTE); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to connect to netlink: %s\n", nlw_geterror(ret)); ret = EIO; goto fail; } ret = nlw_enable_passcred(nlctx->nlp); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot enable credential passing: %s\n", nlw_geterror(ret)); ret = EIO; goto fail; } /* Subscribe to the LINK group for internal carrier signals */ ret = nlw_groups_subscribe(nlctx->nlp, groups); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to subscribe to netlink monitor\n"); ret = EIO; goto fail; } nlw_disable_seq_check(nlctx->nlp); nlfd = nl_socket_get_fd(nlctx->nlp); flags = fcntl(nlfd, F_GETFL, 0); errno = 0; ret = fcntl(nlfd, F_SETFL, flags | O_NONBLOCK); if (ret < 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set the netlink fd to nonblocking\n"); goto fail; } nlctx->tefd = tevent_add_fd(ev, nlctx, nlfd, TEVENT_FD_READ, netlink_fd_handler, nlctx); if (nlctx->tefd == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_add_fd() failed\n"); ret = EIO; goto fail; } *_nlctx = nlctx; return EOK; fail: talloc_free(nlctx); return ret; } #else /* HAVE_LIBNL not defined */ int setup_netlink(TALLOC_CTX *mem_ctx, struct tevent_context *ev, network_change_cb change_cb, void *cb_data, struct netlink_ctx **_nlctx) { if (_nlctx) *_nlctx = NULL; return EOK; } #endif sssd-1.13.4/src/monitor/PaxHeaders.16287/monitor_iface.xml0000644000000000000000000000007412703456111020143 xustar0030 atime=1460561751.643715604 30 ctime=1460561775.058794998 sssd-1.13.4/src/monitor/monitor_iface.xml0000644002412700241270000000462712703456111021623 0ustar00jhrozekjhrozek00000000000000 sssd-1.13.4/src/monitor/PaxHeaders.16287/monitor_iface_generated.c0000644000000000000000000000007412703456111021603 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.660793649 sssd-1.13.4/src/monitor/monitor_iface_generated.c0000644002412700241270000000616712703456111023264 0ustar00jhrozekjhrozek00000000000000/* The following definitions are auto-generated from monitor_iface.xml */ #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_meta.h" #include "sbus/sssd_dbus_invokers.h" #include "monitor_iface_generated.h" /* methods for org.freedesktop.sssd.monitor */ const struct sbus_method_meta mon_srv_iface__methods[] = { { "getVersion", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct mon_srv_iface, getVersion), NULL, /* no invoker */ }, { "RegisterService", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct mon_srv_iface, RegisterService), NULL, /* no invoker */ }, { NULL, } }; /* interface info for org.freedesktop.sssd.monitor */ const struct sbus_interface_meta mon_srv_iface_meta = { "org.freedesktop.sssd.monitor", /* name */ mon_srv_iface__methods, NULL, /* no signals */ NULL, /* no properties */ sbus_invoke_get_all, /* GetAll invoker */ }; /* methods for org.freedesktop.sssd.service */ const struct sbus_method_meta mon_cli_iface__methods[] = { { "ping", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct mon_cli_iface, ping), NULL, /* no invoker */ }, { "resInit", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct mon_cli_iface, resInit), NULL, /* no invoker */ }, { "shutDown", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct mon_cli_iface, shutDown), NULL, /* no invoker */ }, { "goOffline", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct mon_cli_iface, goOffline), NULL, /* no invoker */ }, { "resetOffline", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct mon_cli_iface, resetOffline), NULL, /* no invoker */ }, { "rotateLogs", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct mon_cli_iface, rotateLogs), NULL, /* no invoker */ }, { "clearMemcache", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct mon_cli_iface, clearMemcache), NULL, /* no invoker */ }, { "clearEnumCache", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct mon_cli_iface, clearEnumCache), NULL, /* no invoker */ }, { "sysbusReconnect", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct mon_cli_iface, sysbusReconnect), NULL, /* no invoker */ }, { NULL, } }; /* interface info for org.freedesktop.sssd.service */ const struct sbus_interface_meta mon_cli_iface_meta = { "org.freedesktop.sssd.service", /* name */ mon_cli_iface__methods, NULL, /* no signals */ NULL, /* no properties */ sbus_invoke_get_all, /* GetAll invoker */ }; sssd-1.13.4/src/monitor/PaxHeaders.16287/monitor.c0000644000000000000000000000007412703456111016436 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.992794775 sssd-1.13.4/src/monitor/monitor.c0000644002412700241270000026244112703456111020116 0ustar00jhrozekjhrozek00000000000000/* SSSD Service monitor Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/child_common.h" #include #include #include #include #include #include #ifdef HAVE_SYS_INOTIFY_H #include #endif #include #include #include #include #include #include #include /* Needed for res_init() */ #include #include #include #include "confdb/confdb.h" #include "confdb/confdb_setup.h" #include "db/sysdb.h" #include "monitor/monitor.h" #include "sbus/sssd_dbus.h" #include "monitor/monitor_interfaces.h" #include "responder/common/responder_sbus.h" #ifdef USE_KEYRING #include #endif /* ping time cannot be less then once every few seconds or the * monitor will get crazy hammering children with messages */ #define MONITOR_DEF_PING_TIME 10 /* terminate the child after this interval by default if it * doesn't shutdown on receiving SIGTERM */ #define MONITOR_DEF_FORCE_TIME 60 /* TODO: get the restart related values from config */ #define MONITOR_RESTART_CNT_INTERVAL_RESET 30 /* maximum allowed number of service restarts if the restarts * were less than MONITOR_RESTART_CNT_INTERVAL_RESET apart, which would * indicate a crash after startup or after every request */ #define MONITOR_MAX_SVC_RESTARTS 2 /* The services are restarted with a delay in case the restart was * hitting a race condition where the DP is not ready yet either. * The MONITOR_MAX_RESTART_DELAY defines the maximum delay between * restarts. */ #define MONITOR_MAX_RESTART_DELAY 4 /* name of the monitor server instance */ #define MONITOR_NAME "sssd" #define SSSD_PIDFILE_PATH PID_PATH"/"MONITOR_NAME".pid" /* Special value to leave the Kerberos Replay Cache set to use * the libkrb5 defaults */ #define KRB5_RCACHE_DIR_DISABLE "__LIBKRB5_DEFAULTS__" /* Warning messages */ #define CONF_FILE_PERM_ERROR_MSG "Cannot read config file %s. Please check "\ "that the file is accessible only by the "\ "owner and owned by root.root.\n" int cmdline_debug_level; int cmdline_debug_timestamps; int cmdline_debug_microseconds; struct svc_spy; enum mt_svc_type { MT_SVC_SERVICE, MT_SVC_PROVIDER }; struct mt_svc { struct mt_svc *prev; struct mt_svc *next; enum mt_svc_type type; struct sbus_connection *conn; struct svc_spy *conn_spy; struct mt_ctx *mt_ctx; char *provider; char *command; char *name; char *identity; pid_t pid; int ping_time; int kill_time; struct tevent_timer *kill_timer; bool svc_started; int restarts; time_t last_restart; int failed_pongs; DBusPendingCall *pending; int debug_level; struct tevent_timer *ping_ev; struct sss_child_ctx *child_ctx; }; struct config_file_callback { int wd; int retries; monitor_reconf_fn fn; char *filename; time_t modified; struct config_file_callback *next; struct config_file_callback *prev; }; struct config_file_ctx { TALLOC_CTX *parent_ctx; struct tevent_timer *timer; bool needs_update; struct mt_ctx *mt_ctx; struct config_file_callback *callbacks; }; struct mt_ctx { struct tevent_context *ev; struct confdb_ctx *cdb; struct sss_domain_info *domains; char **services; int num_services; int started_services; struct mt_svc *svc_list; struct sbus_connection *sbus_srv; struct config_file_ctx *file_ctx; int inotify_fd; int service_id_timeout; bool check_children; bool services_started; struct netlink_ctx *nlctx; const char *conf_path; struct sss_sigchild_ctx *sigchld_ctx; bool is_daemon; pid_t parent_pid; /* For running unprivileged services */ uid_t uid; gid_t gid; }; static int start_service(struct mt_svc *mt_svc); static int monitor_service_init(struct sbus_connection *conn, void *data); static int service_send_ping(struct mt_svc *svc); static int service_signal_reset_offline(struct mt_svc *svc); static void ping_check(DBusPendingCall *pending, void *data); static void set_tasks_checker(struct mt_svc *srv); static int monitor_kill_service (struct mt_svc *svc); static int get_service_config(struct mt_ctx *ctx, const char *name, struct mt_svc **svc_cfg); static int get_provider_config(struct mt_ctx *ctx, const char *name, struct mt_svc **svc_cfg); static int add_new_service(struct mt_ctx *ctx, const char *name, int restarts); static int add_new_provider(struct mt_ctx *ctx, const char *name, int restarts); static int mark_service_as_started(struct mt_svc *svc); static int monitor_cleanup(void); static void network_status_change_cb(void *cb_data) { struct mt_svc *iter; struct mt_ctx *ctx = (struct mt_ctx *) cb_data; DEBUG(SSSDBG_TRACE_INTERNAL, "A networking status change detected " "signaling providers to reset offline status\n"); for (iter = ctx->svc_list; iter; iter = iter->next) { /* Don't signal services, only providers */ if (iter->provider) { service_signal_reset_offline(iter); } } } /* dbus_get_monitor_version * Return the monitor version over D-BUS */ static int get_monitor_version(struct sbus_request *dbus_req, void *data) { dbus_uint16_t version = MONITOR_VERSION; return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &version, DBUS_TYPE_INVALID); } struct mon_init_conn { struct mt_ctx *ctx; struct sbus_connection *conn; struct tevent_timer *timeout; }; static int add_svc_conn_spy(struct mt_svc *svc); /* registers a new client. * if operation is successful also sends back the Monitor version */ static int client_registration(struct sbus_request *dbus_req, void *data) { dbus_uint16_t version = MONITOR_VERSION; struct mon_init_conn *mini; struct mt_svc *svc; DBusError dbus_error; dbus_uint16_t svc_ver; char *svc_name; dbus_bool_t dbret; int ret; mini = talloc_get_type(data, struct mon_init_conn); if (!mini) { DEBUG(SSSDBG_FATAL_FAILURE, "Connection holds no valid init data\n"); return EINVAL; } /* First thing, cancel the timeout */ talloc_zfree(mini->timeout); dbus_error_init(&dbus_error); dbret = dbus_message_get_args(dbus_req->message, &dbus_error, DBUS_TYPE_STRING, &svc_name, DBUS_TYPE_UINT16, &svc_ver, DBUS_TYPE_INVALID); if (!dbret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse message, killing connection\n"); if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); sbus_disconnect(dbus_req->conn); sbus_request_finish(dbus_req, NULL); /* FIXME: should we just talloc_zfree(conn) ? */ goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Received ID registration: (%s,%d)\n", svc_name, svc_ver); /* search this service in the list */ svc = mini->ctx->svc_list; while (svc) { ret = strcasecmp(svc->identity, svc_name); if (ret == 0) { break; } svc = svc->next; } if (!svc) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to find peer [%s] in list of services," " killing connection!\n", svc_name); sbus_disconnect(dbus_req->conn); sbus_request_finish(dbus_req, NULL); /* FIXME: should we just talloc_zfree(conn) ? */ goto done; } /* Fill in svc structure with connection data */ svc->conn = mini->conn; ret = mark_service_as_started(svc); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to mark service [%s]!\n", svc_name); goto done; } /* reply that all is ok */ sbus_request_return_and_finish(dbus_req, DBUS_TYPE_UINT16, &version, DBUS_TYPE_INVALID); done: /* init complete, get rid of temp init context */ talloc_zfree(mini); return EOK; } struct svc_spy { struct mt_svc *svc; }; static int svc_destructor(void *mem) { struct mt_svc *svc = talloc_get_type(mem, struct mt_svc); if (!svc) { /* ?!?!? */ return 0; } /* try to delist service */ if (svc->mt_ctx) { DLIST_REMOVE(svc->mt_ctx->svc_list, svc); } /* Cancel any pending pings */ if (svc->pending) { dbus_pending_call_cancel(svc->pending); } /* svc is being freed, neutralize the spy */ if (svc->conn_spy) { talloc_set_destructor((TALLOC_CTX *)svc->conn_spy, NULL); talloc_zfree(svc->conn_spy); } if (svc->type == MT_SVC_SERVICE && svc->svc_started && svc->mt_ctx != NULL && svc->mt_ctx->started_services > 0) { svc->mt_ctx->started_services--; } return 0; } static int svc_spy_destructor(void *mem) { struct svc_spy *spy = talloc_get_type(mem, struct svc_spy); if (!spy) { /* ?!?!? */ return 0; } /* svc->conn has been freed, NULL the pointer in svc */ spy->svc->conn_spy = NULL; spy->svc->conn = NULL; return 0; } static int add_svc_conn_spy(struct mt_svc *svc) { struct svc_spy *spy; spy = talloc(svc->conn, struct svc_spy); if (!spy) return ENOMEM; spy->svc = svc; talloc_set_destructor((TALLOC_CTX *)spy, svc_spy_destructor); svc->conn_spy = spy; return EOK; } static int mark_service_as_started(struct mt_svc *svc) { struct mt_ctx *ctx = svc->mt_ctx; struct mt_svc *iter; int ret; int i; DEBUG(SSSDBG_FUNC_DATA, "Marking %s as started.\n", svc->name); svc->svc_started = true; /* we need to attach a spy to the connection structure so that if some code * frees it we can zero it out in the service structure. Otherwise we may * try to access or even free, freed memory. */ ret = add_svc_conn_spy(svc); if (ret) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to attch spy\n"); goto done; } if (!ctx->services_started) { /* check if all providers are up */ for (iter = ctx->svc_list; iter; iter = iter->next) { if (iter->provider && !iter->svc_started) { DEBUG(SSSDBG_FUNC_DATA, "Still waiting on %s provider.\n", iter->name); break; } } if (iter) { /* there are still unstarted providers */ goto done; } ctx->services_started = true; DEBUG(SSSDBG_CONF_SETTINGS, "Now starting services!\n"); /* then start all services */ for (i = 0; ctx->services[i]; i++) { add_new_service(ctx, ctx->services[i], 0); } } if (svc->type == MT_SVC_SERVICE) { ctx->started_services++; } if (ctx->started_services == ctx->num_services) { /* Initialization is complete, terminate parent process if in daemon * mode. Make sure we send the signal to the right process */ if (ctx->is_daemon) { if (ctx->parent_pid <= 1 || ctx->parent_pid != getppid()) { /* the parent process was already terminated */ DEBUG(SSSDBG_MINOR_FAILURE, "Invalid parent pid: %d\n", ctx->parent_pid); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "SSSD is initialized, " "terminating parent process\n"); errno = 0; ret = kill(ctx->parent_pid, SIGTERM); if (ret != 0) { ret = errno; DEBUG(SSSDBG_FATAL_FAILURE, "Unable to terminate parent " "process [%d]: %s\n", ret, strerror(ret)); } } } done: return ret; } static void services_startup_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { struct mt_ctx *ctx = talloc_get_type(ptr, struct mt_ctx); int i; DEBUG(SSSDBG_TRACE_FUNC, "Handling timeout\n"); if (!ctx->services_started) { DEBUG(SSSDBG_CRIT_FAILURE, "Providers did not start in time, " "forcing services startup!\n"); ctx->services_started = true; DEBUG(SSSDBG_CONF_SETTINGS, "Now starting services!\n"); /* then start all services */ for (i = 0; ctx->services[i]; i++) { add_new_service(ctx, ctx->services[i], 0); } } } static int add_services_startup_timeout(struct mt_ctx *ctx) { struct tevent_timer *to; struct timeval tv; /* 5 seconds should be plenty */ tv = tevent_timeval_current_ofs(5, 0); to = tevent_add_timer(ctx->ev, ctx, tv, services_startup_timeout, ctx); if (!to) { DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n"); return ENOMEM; } return EOK; } struct mon_srv_iface monitor_methods = { { &mon_srv_iface_meta, 0 }, .getVersion = get_monitor_version, .RegisterService = client_registration, }; /* monitor_dbus_init * Set up the monitor service as a D-BUS Server */ static int monitor_dbus_init(struct mt_ctx *ctx) { char *monitor_address; int ret; ret = monitor_get_sbus_address(ctx, &monitor_address); if (ret != EOK) { return ret; } /* If a service is running as unprivileged user, we need to make sure this * user can access the monitor sbus server. root is still king, so we don't * lose any access. */ ret = sbus_new_server(ctx, ctx->ev, monitor_address, ctx->uid, ctx->gid, false, &ctx->sbus_srv, monitor_service_init, ctx); talloc_free(monitor_address); return ret; } static void tasks_check_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { struct mt_svc *svc = talloc_get_type(ptr, struct mt_svc); int ret; ret = service_send_ping(svc); switch (ret) { case EOK: /* all fine */ break; case ENXIO: DEBUG(SSSDBG_CRIT_FAILURE, "Child (%s) not responding! (yet)\n", svc->name); break; default: /* TODO: should we tear it down ? */ DEBUG(SSSDBG_CRIT_FAILURE, "Sending a message to service (%s) failed!!\n", svc->name); break; } if (svc->failed_pongs >= 3) { /* too long since we last heard of this process */ DEBUG(SSSDBG_CRIT_FAILURE, "Killing service [%s], not responding to pings!\n", svc->name); sss_log(SSS_LOG_ERR, "Killing service [%s], not responding to pings!\n", svc->name); /* Kill the service. The SIGCHLD handler will restart it */ monitor_kill_service(svc); return; } /* all fine, set up the task checker again */ set_tasks_checker(svc); } static void set_tasks_checker(struct mt_svc *svc) { struct tevent_timer *te = NULL; struct timeval tv; gettimeofday(&tv, NULL); tv.tv_sec += svc->ping_time; tv.tv_usec = 0; te = tevent_add_timer(svc->mt_ctx->ev, svc, tv, tasks_check_handler, svc); if (te == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "failed to add event, monitor offline for [%s]!\n", svc->name); /* FIXME: shutdown ? */ } svc->ping_ev = te; } static void monitor_restart_service(struct mt_svc *svc); static void mt_svc_sigkill(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr); static int monitor_kill_service (struct mt_svc *svc) { int ret; struct timeval tv; ret = kill(svc->pid, SIGTERM); if (ret == -1) { ret = errno; DEBUG(SSSDBG_FATAL_FAILURE, "Sending signal to child (%s:%d) failed: [%d]: %s! " "Ignore and pretend child is dead.\n", svc->name, svc->pid, ret, strerror(ret)); /* The only thing we can try here is to launch a new process * and hope that it works. */ monitor_restart_service(svc); return EOK; } /* Set up a timer to send SIGKILL if this process * doesn't exit within sixty seconds */ tv = tevent_timeval_current_ofs(svc->kill_time, 0); svc->kill_timer = tevent_add_timer(svc->mt_ctx->ev, svc, tv, mt_svc_sigkill, svc); if (svc->kill_timer == NULL) { /* Nothing much we can do */ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to allocate timed event: mt_svc_sigkill.\n"); /* We'll just have to hope that the SIGTERM succeeds */ } return EOK; } static void mt_svc_sigkill(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { int ret; struct mt_svc *svc = talloc_get_type(ptr, struct mt_svc); DEBUG(SSSDBG_FATAL_FAILURE, "[%s][%d] is not responding to SIGTERM. Sending SIGKILL.\n", svc->name, svc->pid); sss_log(SSS_LOG_ERR, "[%s][%d] is not responding to SIGTERM. Sending SIGKILL.\n", svc->name, svc->pid); /* timer was succesfully executed and it will be released by tevent */ svc->kill_timer = NULL; ret = kill(svc->pid, SIGKILL); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_FATAL_FAILURE, "Sending signal to child (%s:%d) failed! " "Ignore and pretend child is dead.\n", svc->name, svc->pid); if (ret == ESRCH) { /* The process doesn't exist * This most likely means we hit a race where * the SIGTERM concluded just after the timer * fired but before we called kill() here. * We'll just do nothing, since the * mt_svc_exit_handler() should be doing the * necessary work. */ return; } /* Something went really wrong. * The only thing we can try here is to launch a new process * and hope that it works. */ monitor_restart_service(svc); } /* The process should terminate immediately and then be * restarted by the mt_svc_exit_handler() */ return; } static void reload_reply(DBusPendingCall *pending, void *data) { DBusMessage *reply; struct mt_svc *svc = talloc_get_type(data, struct mt_svc); reply = dbus_pending_call_steal_reply(pending); if (!reply) { /* reply should never be null. This function shouldn't be called * until reply is valid or timeout has occurred. If reply is NULL * here, something is seriously wrong and we should bail out. */ DEBUG(SSSDBG_FATAL_FAILURE, "A reply callback was called but no reply was received" " and no timeout occurred\n"); /* Destroy this connection */ sbus_disconnect(svc->conn); dbus_pending_call_unref(pending); return; } /* TODO: Handle cases where the call has timed out or returned * with an error. */ dbus_pending_call_unref(pending); dbus_message_unref(reply); } static int service_signal_dns_reload(struct mt_svc *svc); static int monitor_update_resolv(struct config_file_ctx *file_ctx, const char *filename) { int ret; struct mt_svc *cur_svc; DEBUG(SSSDBG_OP_FAILURE, "Resolv.conf has been updated. Reloading.\n"); ret = res_init(); if(ret != 0) { return EIO; } /* Signal all services to reload their DNS configuration */ for(cur_svc = file_ctx->mt_ctx->svc_list; cur_svc; cur_svc = cur_svc->next) { service_signal_dns_reload(cur_svc); } return EOK; } static int service_signal(struct mt_svc *svc, const char *svc_signal) { DBusMessage *msg; int ret; if (svc->provider && strcasecmp(svc->provider, "local") == 0) { /* The local provider requires no signaling */ return EOK; } if (!svc->conn) { /* Avoid a race condition where we are trying to * order a service to reload that hasn't started * yet. */ DEBUG(SSSDBG_CRIT_FAILURE, "Could not signal service [%s].\n", svc->name); return EIO; } msg = dbus_message_new_method_call(NULL, MONITOR_PATH, MON_CLI_IFACE, svc_signal); if (msg == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory trying to allocate memory to invoke: %s\n", svc_signal); monitor_kill_service(svc); return ENOMEM; } ret = sbus_conn_send(svc->conn, msg, svc->mt_ctx->service_id_timeout, reload_reply, svc, NULL); dbus_message_unref(msg); return ret; } static int service_signal_dns_reload(struct mt_svc *svc) { return service_signal(svc, MON_CLI_IFACE_RESINIT); } static int service_signal_offline(struct mt_svc *svc) { return service_signal(svc, MON_CLI_IFACE_GOOFFLINE); } static int service_signal_reset_offline(struct mt_svc *svc) { return service_signal(svc, MON_CLI_IFACE_RESETOFFLINE); } static int service_signal_rotate(struct mt_svc *svc) { return service_signal(svc, MON_CLI_IFACE_ROTATELOGS); } static int service_signal_clear_memcache(struct mt_svc *svc) { return service_signal(svc, MON_CLI_IFACE_CLEARMEMCACHE); } static int service_signal_clear_enum_cache(struct mt_svc *svc) { return service_signal(svc, MON_CLI_IFACE_CLEARENUMCACHE); } static int service_signal_sysbus_reconnect(struct mt_svc *svc) { return service_signal(svc, MON_CLI_IFACE_SYSBUSRECONNECT); } static int check_domain_ranges(struct sss_domain_info *domains) { struct sss_domain_info *dom = domains, *other = NULL; uint32_t id_min, id_max; while (dom) { other = get_next_domain(dom, 0); if (dom->id_max && dom->id_min > dom->id_max) { DEBUG(SSSDBG_CRIT_FAILURE, "Domain '%s' does not have a valid ID range\n", dom->name); return EINVAL; } while (other) { id_min = MAX(dom->id_min, other->id_min); id_max = MIN((dom->id_max ? dom->id_max : UINT32_MAX), (other->id_max ? other->id_max : UINT32_MAX)); if (id_min <= id_max) { DEBUG(SSSDBG_MINOR_FAILURE, "Domains '%s' and '%s' overlap in range %u - %u\n", dom->name, other->name, id_min, id_max); } other = get_next_domain(other, 0); } dom = get_next_domain(dom, 0); } return EOK; } static int check_local_domain_unique(struct sss_domain_info *domains) { uint8_t count = 0; struct sss_domain_info *dom = domains; while (dom) { if (strcasecmp(dom->provider, "local") == 0) { count++; } if (count > 1) { break; } dom = get_next_domain(dom, 0); } if (count > 1) { return EINVAL; } return EOK; } static errno_t add_implicit_services(struct confdb_ctx *cdb, TALLOC_CTX *mem_ctx, char ***_services) { int ret; char **domain_names; TALLOC_CTX *tmp_ctx; size_t c; char *conf_path; char *id_provider; bool add_pac = false; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = confdb_get_string_as_list(cdb, tmp_ctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_ACTIVE_DOMAINS, &domain_names); if (ret == ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "No domains configured!\n"); goto done; } for (c = 0; domain_names[c] != NULL; c++) { conf_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, domain_names[c]); if (conf_path == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } ret = confdb_get_string(cdb, tmp_ctx, conf_path, CONFDB_DOMAIN_ID_PROVIDER, NULL, &id_provider); if (ret == EOK) { if (id_provider == NULL) { DEBUG(SSSDBG_OP_FAILURE, "id_provider is not set for " "domain [%s], trying next domain.\n", domain_names[c]); continue; } if (strcasecmp(id_provider, "IPA") == 0) { add_pac = true; } } else { DEBUG(SSSDBG_OP_FAILURE, "Failed to get id_provider for " \ "domain [%s], trying next domain.\n", domain_names[c]); } } if (BUILD_WITH_PAC_RESPONDER && add_pac && !string_in_list("pac", *_services, false)) { ret = add_string_to_list(mem_ctx, "pac", _services); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_string_to_list failed.\n"); goto done; } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static char *check_services(char **services) { const char * const *known_services = get_known_services(); int i; int ii; /* Check if services we are about to start are in the list if known */ for (i = 0; services[i]; i++) { for (ii=0; known_services[ii]; ii++) { if (strcasecmp(services[i], known_services[ii]) == 0) { break; } } if (known_services[ii] == NULL) { return services[i]; } } return NULL; } static int get_service_user(struct mt_ctx *ctx) { errno_t ret; char *user_str; ret = confdb_get_string(ctx->cdb, ctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_USER_RUNAS, SSSD_USER, &user_str); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get the user to run as\n"); return ret; } ret = sss_user_by_name_or_uid(user_str, &ctx->uid, &ctx->gid); talloc_free(user_str); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set allowed UIDs.\n"); return ret; } return EOK; } static int get_monitor_config(struct mt_ctx *ctx) { int ret; int timeout_seconds; char *badsrv = NULL; int i; ret = confdb_get_int(ctx->cdb, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_SBUS_TIMEOUT, 10, &timeout_seconds); if (ret != EOK) { return ret; } ctx->service_id_timeout = timeout_seconds * 1000; /* service_id_timeout is in ms */ ret = confdb_get_string_as_list(ctx->cdb, ctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_ACTIVE_SERVICES, &ctx->services); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "No services configured!\n"); return EINVAL; } ret = add_implicit_services(ctx->cdb, ctx, &ctx->services); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to add implicit configured " "services. Some functionality might " "be missing\n"); } badsrv = check_services(ctx->services); if (badsrv != NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid service %s\n", badsrv); return EINVAL; } ctx->started_services = 0; ctx->num_services = 0; for (i = 0; ctx->services[i] != NULL; i++) { ctx->num_services++; } ret = get_service_user(ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get the unprivileged user\n"); return ret; } ret = confdb_get_domains(ctx->cdb, &ctx->domains); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "No domains configured.\n"); return ret; } ret = check_local_domain_unique(ctx->domains); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "More than one local domain configured.\n"); return ret; } /* Check UID/GID overlaps */ ret = check_domain_ranges(ctx->domains); if (ret != EOK) { return ret; } return EOK; } static errno_t get_ping_config(struct mt_ctx *ctx, const char *path, struct mt_svc *svc) { errno_t ret; ret = confdb_get_int(ctx->cdb, path, CONFDB_DOMAIN_TIMEOUT, MONITOR_DEF_PING_TIME, &svc->ping_time); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get ping timeout for '%s'\n", svc->name); return ret; } /* 'timeout = 0' should be translated to the default */ if (svc->ping_time == 0) { svc->ping_time = MONITOR_DEF_PING_TIME; } DEBUG(SSSDBG_CONF_SETTINGS, "Time between service pings for [%s]: [%d]\n", svc->name, svc->ping_time); ret = confdb_get_int(ctx->cdb, path, CONFDB_SERVICE_FORCE_TIMEOUT, MONITOR_DEF_FORCE_TIME, &svc->kill_time); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get kill timeout for %s\n", svc->name); return ret; } /* 'force_timeout = 0' should be translated to the default */ if (svc->kill_time == 0) { svc->kill_time = MONITOR_DEF_FORCE_TIME; } DEBUG(SSSDBG_CONF_SETTINGS, "Time between SIGTERM and SIGKILL for [%s]: [%d]\n", svc->name, svc->kill_time); return EOK; } /* This is a temporary function that returns false if the service * being started was only tested when running as root. */ static bool svc_supported_as_nonroot(const char *svc_name) { if ((strcmp(svc_name, "nss") == 0) || (strcmp(svc_name, "pam") == 0) || (strcmp(svc_name, "autofs") == 0) || (strcmp(svc_name, "pac") == 0) || (strcmp(svc_name, "sudo") == 0) || (strcmp(svc_name, "ssh") == 0)) { return true; } return false; } static int get_service_config(struct mt_ctx *ctx, const char *name, struct mt_svc **svc_cfg) { int ret; char *path; struct mt_svc *svc; time_t now = time(NULL); uid_t uid = 0; gid_t gid = 0; *svc_cfg = NULL; svc = talloc_zero(ctx, struct mt_svc); if (!svc) { return ENOMEM; } svc->mt_ctx = ctx; svc->type = MT_SVC_SERVICE; talloc_set_destructor((TALLOC_CTX *)svc, svc_destructor); svc->name = talloc_strdup(svc, name); if (!svc->name) { talloc_free(svc); return ENOMEM; } svc->identity = talloc_strdup(svc, name); if (!svc->identity) { talloc_free(svc); return ENOMEM; } path = talloc_asprintf(svc, CONFDB_SERVICE_PATH_TMPL, svc->name); if (!path) { talloc_free(svc); return ENOMEM; } ret = confdb_get_string(ctx->cdb, svc, path, CONFDB_SERVICE_COMMAND, NULL, &svc->command); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE,"Failed to start service '%s'\n", svc->name); talloc_free(svc); return ret; } if (svc_supported_as_nonroot(svc->name)) { uid = ctx->uid; gid = ctx->gid; } if (!svc->command) { svc->command = talloc_asprintf( svc, "%s/sssd_%s", SSSD_LIBEXEC_PATH, svc->name ); if (!svc->command) { talloc_free(svc); return ENOMEM; } svc->command = talloc_asprintf_append(svc->command, " --uid %"SPRIuid" --gid %"SPRIgid, uid, gid); if (!svc->command) { talloc_free(svc); return ENOMEM; } if (cmdline_debug_level != SSSDBG_UNRESOLVED) { svc->command = talloc_asprintf_append( svc->command, " -d %#.4x", cmdline_debug_level ); if (!svc->command) { talloc_free(svc); return ENOMEM; } } if (cmdline_debug_timestamps != SSSDBG_TIMESTAMP_UNRESOLVED) { svc->command = talloc_asprintf_append( svc->command, " --debug-timestamps=%d", cmdline_debug_timestamps ); if (!svc->command) { talloc_free(svc); return ENOMEM; } } if (cmdline_debug_microseconds != SSSDBG_MICROSECONDS_UNRESOLVED) { svc->command = talloc_asprintf_append( svc->command, " --debug-microseconds=%d", cmdline_debug_microseconds ); if (!svc->command) { talloc_free(svc); return ENOMEM; } } if (debug_to_file) { svc->command = talloc_strdup_append( svc->command, " --debug-to-files" ); if (!svc->command) { talloc_free(svc); return ENOMEM; } } else if (ctx->is_daemon == false) { svc->command = talloc_strdup_append( svc->command, " --debug-to-stderr" ); if (!svc->command) { talloc_free(svc); return ENOMEM; } } } ret = get_ping_config(ctx, path, svc); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get ping timeouts for %s\n", svc->name); talloc_free(svc); return ret; } svc->last_restart = now; *svc_cfg = svc; talloc_free(path); return EOK; } static int add_new_service(struct mt_ctx *ctx, const char *name, int restarts) { int ret; struct mt_svc *svc; ret = get_service_config(ctx, name, &svc); if (ret != EOK) { return ret; } svc->restarts = restarts; ret = start_service(svc); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE,"Failed to start service '%s'\n", svc->name); talloc_free(svc); } return ret; } static int get_provider_config(struct mt_ctx *ctx, const char *name, struct mt_svc **svc_cfg) { int ret; char *path; struct mt_svc *svc; time_t now = time(NULL); *svc_cfg = NULL; svc = talloc_zero(ctx, struct mt_svc); if (!svc) { return ENOMEM; } svc->mt_ctx = ctx; svc->type = MT_SVC_PROVIDER; talloc_set_destructor((TALLOC_CTX *)svc, svc_destructor); svc->name = talloc_strdup(svc, name); if (!svc->name) { talloc_free(svc); return ENOMEM; } svc->identity = talloc_asprintf(svc, "%%BE_%s", svc->name); if (!svc->identity) { talloc_free(svc); return ENOMEM; } path = talloc_asprintf(svc, CONFDB_DOMAIN_PATH_TMPL, name); if (!path) { talloc_free(svc); return ENOMEM; } ret = confdb_get_string(ctx->cdb, svc, path, CONFDB_DOMAIN_ID_PROVIDER, NULL, &svc->provider); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to find ID provider from [%s] configuration\n", name); talloc_free(svc); return ret; } ret = confdb_get_string(ctx->cdb, svc, path, CONFDB_DOMAIN_COMMAND, NULL, &svc->command); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to find command from [%s] configuration\n", name); talloc_free(svc); return ret; } ret = get_ping_config(ctx, path, svc); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get ping timeouts for %s\n", svc->name); talloc_free(svc); return ret; } talloc_free(path); /* if no provider is present do not run the domain */ if (!svc->provider) { talloc_free(svc); return EIO; } /* if there are no custom commands, build a default one */ if (!svc->command) { svc->command = talloc_asprintf( svc, "%s/sssd_be --domain %s", SSSD_LIBEXEC_PATH, svc->name ); if (!svc->command) { talloc_free(svc); return ENOMEM; } svc->command = talloc_asprintf_append(svc->command, " --uid %"SPRIuid" --gid %"SPRIgid, ctx->uid, ctx->gid); if (!svc->command) { talloc_free(svc); return ENOMEM; } if (cmdline_debug_level != SSSDBG_UNRESOLVED) { svc->command = talloc_asprintf_append( svc->command, " -d %#.4x", cmdline_debug_level ); if (!svc->command) { talloc_free(svc); return ENOMEM; } } if (cmdline_debug_timestamps != SSSDBG_TIMESTAMP_UNRESOLVED) { svc->command = talloc_asprintf_append( svc->command, " --debug-timestamps=%d", cmdline_debug_timestamps ); if (!svc->command) { talloc_free(svc); return ENOMEM; } } if (cmdline_debug_microseconds != SSSDBG_MICROSECONDS_UNRESOLVED) { svc->command = talloc_asprintf_append( svc->command, " --debug-microseconds=%d", cmdline_debug_microseconds ); if (!svc->command) { talloc_free(svc); return ENOMEM; } } if (debug_to_file) { svc->command = talloc_strdup_append( svc->command, " --debug-to-files" ); if (!svc->command) { talloc_free(svc); return ENOMEM; } } else if (ctx->is_daemon == false) { svc->command = talloc_strdup_append( svc->command, " --debug-to-stderr" ); if (!svc->command) { talloc_free(svc); return ENOMEM; } } } svc->last_restart = now; *svc_cfg = svc; return EOK; } static int add_new_provider(struct mt_ctx *ctx, const char *name, int restarts) { int ret; struct mt_svc *svc; ret = get_provider_config(ctx, name, &svc); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not get provider configuration for [%s]\n", name); return ret; } svc->restarts = restarts; if (strcasecmp(svc->provider, "local") == 0) { /* The LOCAL provider requires no back-end currently * We'll add it to the service list, but we don't need * to poll it. */ svc->svc_started = true; DLIST_ADD(ctx->svc_list, svc); return ENOENT; } ret = start_service(svc); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE,"Failed to start service '%s'\n", svc->name); talloc_free(svc); } return ret; } static void monitor_hup(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { struct mt_ctx *ctx = talloc_get_type(private_data, struct mt_ctx); struct mt_svc *cur_svc; DEBUG(SSSDBG_CRIT_FAILURE, "Received SIGHUP.\n"); /* Send D-Bus message to other services to rotate their logs. * NSS service receives also message to clear memory caches. */ for(cur_svc = ctx->svc_list; cur_svc; cur_svc = cur_svc->next) { service_signal_rotate(cur_svc); if (!strcmp(NSS_SBUS_SERVICE_NAME, cur_svc->name)) { service_signal_clear_memcache(cur_svc); service_signal_clear_enum_cache(cur_svc); } if (!strcmp(SSS_AUTOFS_SBUS_SERVICE_NAME, cur_svc->name)) { service_signal_clear_enum_cache(cur_svc); } } } static int monitor_cleanup(void) { int ret; errno = 0; ret = unlink(SSSD_PIDFILE_PATH); if (ret == -1) { ret = errno; DEBUG(SSSDBG_FATAL_FAILURE, "Error removing pidfile! (%d [%s])\n", ret, strerror(ret)); return ret; } return EOK; } static void monitor_quit(struct mt_ctx *mt_ctx, int ret) { struct mt_svc *svc; pid_t pid; int status; errno_t error; int kret; bool killed; DEBUG(SSSDBG_IMPORTANT_INFO, "Returned with: %d\n", ret); /* Kill all of our known children manually */ DLIST_FOR_EACH(svc, mt_ctx->svc_list) { if (svc->pid == 0) { /* The local provider has no PID */ continue; } killed = false; DEBUG(SSSDBG_CRIT_FAILURE, "Terminating [%s][%d]\n", svc->name, svc->pid); do { errno = 0; kret = kill(svc->pid, SIGTERM); if (kret < 0) { error = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't kill [%s][%d]: [%s]\n", svc->name, svc->pid, strerror(error)); } error = 0; do { errno = 0; pid = waitpid(svc->pid, &status, WNOHANG); if (pid == -1) { /* An error occurred while waiting */ error = errno; if (error == ECHILD) { killed = true; } else if (error != EINTR) { DEBUG(SSSDBG_FATAL_FAILURE, "[%d][%s] while waiting for [%s]\n", error, strerror(error), svc->name); /* Forcibly kill this child */ kill(svc->pid, SIGKILL); break; } } else if (pid != 0) { error = 0; if (WIFEXITED(status)) { DEBUG(SSSDBG_CRIT_FAILURE, "Child [%s] exited gracefully\n", svc->name); } else if (WIFSIGNALED(status)) { DEBUG(SSSDBG_CRIT_FAILURE, "Child [%s] terminated with a signal\n", svc->name); } else { DEBUG(SSSDBG_FATAL_FAILURE, "Child [%s] did not exit cleanly\n", svc->name); /* Forcibly kill this child */ kill(svc->pid, SIGKILL); } killed = true; } } while (error == EINTR); if (!killed) { /* Sleep 10ms and try again */ usleep(10000); } } while (!killed); } #if HAVE_GETPGRP /* Kill any remaining children in our process group, just in case * we have any leftover children we don't expect. For example, if * a krb5_child or ldap_child is running at the same moment. */ error = 0; if (getpgrp() == getpid()) { kill(-getpgrp(), SIGTERM); do { errno = 0; pid = waitpid(0, &status, 0); if (pid == -1) { error = errno; } } while (error == EINTR || pid > 0); } #endif monitor_cleanup(); exit(ret); } static void monitor_quit_signal(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { struct mt_ctx *mt_ctx = talloc_get_type(private_data, struct mt_ctx); DEBUG(SSSDBG_TRACE_INTERNAL, "Received shutdown command\n"); DEBUG(SSSDBG_IMPORTANT_INFO, "Monitor received %s: terminating " "children\n", strsignal(signum)); monitor_quit(mt_ctx, 0); } static void signal_res_init(struct mt_ctx *monitor) { struct mt_svc *cur_svc; int ret; DEBUG(SSSDBG_OP_FAILURE, "Reloading Resolv.conf.\n"); ret = res_init(); if (ret == 0) { for(cur_svc = monitor->svc_list; cur_svc; cur_svc = cur_svc->next) { service_signal_dns_reload(cur_svc); } } } static void signal_offline(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { struct mt_ctx *monitor; struct mt_svc *cur_svc; monitor = talloc_get_type(private_data, struct mt_ctx); DEBUG(SSSDBG_TRACE_INTERNAL, "Signaling providers to go offline immediately.\n"); /* Signal all providers to immediately go offline */ for(cur_svc = monitor->svc_list; cur_svc; cur_svc = cur_svc->next) { /* Don't signal services, only providers */ if (cur_svc->provider) { service_signal_offline(cur_svc); } } } static void signal_offline_reset(struct tevent_context *ev, struct tevent_signal *se, int signum, int count, void *siginfo, void *private_data) { struct mt_ctx *monitor; struct mt_svc *cur_svc; monitor = talloc_get_type(private_data, struct mt_ctx); DEBUG(SSSDBG_TRACE_INTERNAL, "Signaling providers to reset offline immediately.\n"); for(cur_svc = monitor->svc_list; cur_svc; cur_svc = cur_svc->next) { if (cur_svc->provider) { service_signal_reset_offline(cur_svc); } if (strcmp(SSS_IFP_SBUS_SERVICE_NAME, cur_svc->name) == 0) { service_signal_sysbus_reconnect(cur_svc); } } signal_res_init(monitor); } static int monitor_ctx_destructor(void *mem) { struct mt_ctx *mon = talloc_get_type(mem, struct mt_ctx); struct mt_svc *svc; /* zero out references in svcs so that they don't try * to access the monitor context on process shutdown */ for (svc = mon->svc_list; svc; svc = svc->next) { svc->mt_ctx = NULL; } return 0; } /* * This function should not be static otherwise gcc does some special kind of * optimisations which should not happen according to code: chown (unlink) * failed (return -1) but errno was zero. * As a result of this * warning is printed ‘monitor’ may be used * uninitialized in this function. Instead of checking errno for 0 * it's better to disable optimisation(in-lining) of this function. */ errno_t load_configuration(TALLOC_CTX *mem_ctx, const char *config_file, struct mt_ctx **monitor) { errno_t ret; struct mt_ctx *ctx; char *cdb_file = NULL; ctx = talloc_zero(mem_ctx, struct mt_ctx); if(!ctx) { return ENOMEM; } talloc_set_destructor((TALLOC_CTX *)ctx, monitor_ctx_destructor); cdb_file = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE); if (cdb_file == NULL) { DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory, aborting!\n"); ret = ENOMEM; goto done; } ret = confdb_init(ctx, &ctx->cdb, cdb_file); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE,"The confdb initialization failed\n"); goto done; } /* Initialize the CDB from the configuration file */ ret = confdb_test(ctx->cdb); if (ret == ENOENT) { /* First-time setup */ /* Purge any existing confdb in case an old * misconfiguration gets in the way */ talloc_zfree(ctx->cdb); ret = unlink(cdb_file); if (ret != EOK && errno != ENOENT) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Purging existing confdb failed: %d [%s].\n", ret, sss_strerror(ret)); goto done; } ret = confdb_init(ctx, &ctx->cdb, cdb_file); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE,"The confdb initialization failed\n"); goto done; } /* Load special entries */ ret = confdb_create_base(ctx->cdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to load special entries into confdb\n"); goto done; } } else if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal error initializing confdb\n"); goto done; } ret = confdb_init_db(config_file, ctx->cdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "ConfDB initialization has failed [%s]\n", sss_strerror(ret)); goto done; } /* Validate the configuration in the database */ /* Read in the monitor's configuration */ ret = get_monitor_config(ctx); if (ret != EOK) { goto done; } /* Allow configuration database to be accessible * when SSSD runs as nonroot */ ret = chown(cdb_file, ctx->uid, ctx->gid); if (ret != 0) { ret = errno; DEBUG(SSSDBG_FATAL_FAILURE, "chown failed for [%s]: [%d][%s].\n", cdb_file, ret, sss_strerror(ret)); goto done; } *monitor = ctx; ret = EOK; done: talloc_free(cdb_file); if (ret != EOK) { talloc_free(ctx); } return ret; } static errno_t monitor_config_file_fallback(TALLOC_CTX *mem_ctx, struct mt_ctx *ctx, const char *file, monitor_reconf_fn fn, bool ignore_missing); #ifdef HAVE_INOTIFY static void process_config_file(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr); static void config_file_changed(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *data) { struct tevent_timer *te = NULL; struct timeval tv; struct config_file_ctx *file_ctx; file_ctx = talloc_get_type(data, struct config_file_ctx); if (file_ctx->needs_update) { /* Skip updating. It's already queued for update. */ return; } /* We will queue the file for update in one second. * This way, if there is a script writing to the file * repeatedly, we won't be attempting to update multiple * times. */ gettimeofday(&tv, NULL); tv.tv_sec += 1; te = tevent_add_timer(ev, ev, tv, process_config_file, file_ctx); if (!te) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to queue config file update! Exiting.\n"); kill(getpid(), SIGTERM); return; } file_ctx->needs_update = 1; } struct rewatch_ctx { struct config_file_callback *cb; struct config_file_ctx *file_ctx; }; static void rewatch_config_file(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr); static void process_config_file(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { TALLOC_CTX *tmp_ctx; struct inotify_event *in_event; char *name; ssize_t len; struct config_file_ctx *file_ctx; struct config_file_callback *cb; struct rewatch_ctx *rw_ctx; errno_t ret; file_ctx = talloc_get_type(ptr, struct config_file_ctx); DEBUG(SSSDBG_CRIT_FAILURE, "Processing config file changes\n"); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return; in_event = talloc(tmp_ctx, struct inotify_event); if (!in_event) { goto done; } errno = 0; len = sss_atomic_read_s(file_ctx->mt_ctx->inotify_fd, in_event, sizeof(struct inotify_event)); if (len == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Critical error reading inotify file descriptor [%d]: %s\n", ret, strerror(ret)); goto done; } if (in_event->len > 0) { /* Read in the name, even though we don't use it, * so that read ptr is in the right place */ name = talloc_size(tmp_ctx, in_event->len); if (!name) { goto done; } errno = 0; len = sss_atomic_read_s(file_ctx->mt_ctx->inotify_fd, name, in_event->len); if (len == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Critical error reading inotify file descriptor [%d]: %s\n", ret, strerror(ret)); goto done; } } for (cb = file_ctx->callbacks; cb; cb = cb->next) { if (cb->wd == in_event->wd) { break; } } if (!cb) { DEBUG(SSSDBG_FATAL_FAILURE, "Unknown watch descriptor\n"); goto done; } if (in_event->mask & IN_IGNORED) { /* Some text editors will move a new file on top of the * existing one instead of modifying it. In this case, * the kernel will send us an IN_IGNORE signal. * We will try to open a new watch descriptor on the * new file. */ struct timeval tv; struct tevent_timer *tev; tv.tv_sec = t.tv_sec+5; tv.tv_usec = t.tv_usec; DEBUG(SSSDBG_FUNC_DATA, "Restoring inotify watch.\n"); cb->retries = 0; rw_ctx = talloc(file_ctx, struct rewatch_ctx); if(!rw_ctx) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not restore inotify watch. Quitting!\n"); close(file_ctx->mt_ctx->inotify_fd); kill(getpid(), SIGTERM); goto done; } rw_ctx->cb = cb; rw_ctx->file_ctx = file_ctx; tev = tevent_add_timer(ev, rw_ctx, tv, rewatch_config_file, rw_ctx); if (tev == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not restore inotify watch. Quitting!\n"); close(file_ctx->mt_ctx->inotify_fd); kill(getpid(), SIGTERM); } goto done; } /* Tell the monitor to signal the children */ cb->fn(file_ctx, cb->filename); file_ctx->needs_update = 0; done: talloc_free(tmp_ctx); } static void rewatch_config_file(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { int err; struct tevent_timer *tev = NULL; struct timeval tv; struct config_file_callback *cb; struct rewatch_ctx *rw_ctx; struct config_file_ctx *file_ctx; rw_ctx = talloc_get_type(ptr, struct rewatch_ctx); cb = rw_ctx->cb; file_ctx = rw_ctx->file_ctx; /* Retry six times at five-second intervals before giving up */ cb->retries++; if (cb->retries > 6) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not restore inotify watch. Switching to polling!\n"); close(file_ctx->mt_ctx->inotify_fd); err = monitor_config_file_fallback(file_ctx->parent_ctx, file_ctx->mt_ctx, cb->filename, cb->fn,true); if (err != EOK) kill(getpid(), SIGTERM); cb->fn(file_ctx, cb->filename); talloc_free(rw_ctx); /* A new callback was created in monitor_config_file_fallback()*/ DLIST_REMOVE(file_ctx->callbacks, cb); talloc_free(cb); return; } cb->wd = inotify_add_watch(file_ctx->mt_ctx->inotify_fd, cb->filename, IN_MODIFY); if (cb->wd < 0) { err = errno; tv.tv_sec = t.tv_sec+5; tv.tv_usec = t.tv_usec; DEBUG(SSSDBG_CRIT_FAILURE, "Could not add inotify watch for file [%s]. Error [%d:%s]\n", cb->filename, err, strerror(err)); tev = tevent_add_timer(ev, ev, tv, rewatch_config_file, rw_ctx); if (tev == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not restore inotify watch. Quitting!\n"); close(file_ctx->mt_ctx->inotify_fd); kill(getpid(), SIGTERM); } return; } cb->retries = 0; /* Tell the monitor to signal the children */ cb->fn(file_ctx, cb->filename); talloc_free(rw_ctx); file_ctx->needs_update = 0; } #endif /* HAVE_INOTIFY */ static void poll_config_file(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { int ret, err; struct stat file_stat; struct timeval tv; struct config_file_ctx *file_ctx; struct config_file_callback *cb; file_ctx = talloc_get_type(ptr,struct config_file_ctx); for (cb = file_ctx->callbacks; cb; cb = cb->next) { ret = stat(cb->filename, &file_stat); if (ret < 0) { err = errno; DEBUG(SSSDBG_FATAL_FAILURE, "Could not stat file [%s]. Error [%d:%s]\n", cb->filename, err, strerror(err)); /* TODO: If the config file is missing, should we shut down? */ return; } if (file_stat.st_mtime != cb->modified) { /* Parse the configuration file and signal the children */ /* Note: this will fire if the modification time changes into the past * as well as the future. */ DEBUG(SSSDBG_CRIT_FAILURE, "Config file changed\n"); cb->modified = file_stat.st_mtime; /* Tell the monitor to signal the children */ cb->fn(file_ctx, cb->filename); } } gettimeofday(&tv, NULL); tv.tv_sec += CONFIG_FILE_POLL_INTERVAL; tv.tv_usec = 0; file_ctx->timer = tevent_add_timer(ev, file_ctx->parent_ctx, tv, poll_config_file, file_ctx); if (!file_ctx->timer) { DEBUG(SSSDBG_FATAL_FAILURE, "Error: Config file no longer monitored for changes!\n"); } } static int try_inotify(struct config_file_ctx *file_ctx, const char *filename, monitor_reconf_fn fn) { #ifdef HAVE_INOTIFY int err, fd_args, ret; struct tevent_fd *tfd; struct config_file_callback *cb; /* Monitoring the file descriptor should be global */ if (!file_ctx->mt_ctx->inotify_fd) { /* Set up inotify to monitor the config file for changes */ file_ctx->mt_ctx->inotify_fd = inotify_init(); if (file_ctx->mt_ctx->inotify_fd < 0) { err = errno; DEBUG(SSSDBG_FATAL_FAILURE, "Could not initialize inotify, error [%d:%s]\n", err, strerror(err)); return err; } fd_args = fcntl(file_ctx->mt_ctx->inotify_fd, F_GETFL, NULL); if (fd_args < 0) { /* Could not set nonblocking */ close(file_ctx->mt_ctx->inotify_fd); return EINVAL; } fd_args |= O_NONBLOCK; ret = fcntl(file_ctx->mt_ctx->inotify_fd, F_SETFL, fd_args); if (ret < 0) { /* Could not set nonblocking */ close(file_ctx->mt_ctx->inotify_fd); return EINVAL; } /* Add the inotify file descriptor to the TEvent context */ tfd = tevent_add_fd(file_ctx->mt_ctx->ev, file_ctx, file_ctx->mt_ctx->inotify_fd, TEVENT_FD_READ, config_file_changed, file_ctx); if (!tfd) { close(file_ctx->mt_ctx->inotify_fd); return EIO; } } cb = talloc_zero(file_ctx, struct config_file_callback); if(!cb) { close(file_ctx->mt_ctx->inotify_fd); return ENOMEM; } cb->filename = talloc_strdup(cb, filename); if (!cb->filename) { close(file_ctx->mt_ctx->inotify_fd); return ENOMEM; } cb->wd = inotify_add_watch(file_ctx->mt_ctx->inotify_fd, cb->filename, IN_MODIFY); if (cb->wd < 0) { err = errno; DEBUG(SSSDBG_FATAL_FAILURE, "Could not add inotify watch for file [%s]. Error [%d:%s]\n", cb->filename, err, strerror(err)); close(file_ctx->mt_ctx->inotify_fd); return err; } cb->fn = fn; DLIST_ADD(file_ctx->callbacks, cb); return EOK; #else return EINVAL; #endif /* HAVE_INOTIFY */ } static int monitor_config_file(TALLOC_CTX *mem_ctx, struct mt_ctx *ctx, const char *file, monitor_reconf_fn fn, bool ignore_missing) { int ret, err; bool use_inotify; struct stat file_stat; ret = stat(file, &file_stat); if (ret < 0) { err = errno; if (err == ENOENT && ignore_missing) { DEBUG(SSSDBG_MINOR_FAILURE, "file [%s] is missing. Will not update online status " "based on watching the file\n", file); return EOK; } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not stat file [%s]. Error [%d:%s]\n", file, err, strerror(err)); return err; } } if (!ctx->file_ctx) { ctx->file_ctx = talloc_zero(mem_ctx, struct config_file_ctx); if (!ctx->file_ctx) return ENOMEM; ctx->file_ctx->parent_ctx = mem_ctx; ctx->file_ctx->mt_ctx = ctx; } ret = confdb_get_bool(ctx->cdb, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_TRY_INOTIFY, true, &use_inotify); if (ret != EOK) { talloc_free(ctx->file_ctx); return ret; } if (use_inotify) { ret = try_inotify(ctx->file_ctx, file, fn); if (ret != EOK) { use_inotify = false; } } if (!use_inotify) { /* Could not monitor file with inotify, fall back to polling */ ret = monitor_config_file_fallback(mem_ctx, ctx, file, fn, true); } return ret; } static errno_t monitor_config_file_fallback(TALLOC_CTX *mem_ctx, struct mt_ctx *ctx, const char *file, monitor_reconf_fn fn, bool ignore_missing) { struct config_file_callback *cb = NULL; struct stat file_stat; int ret, err; struct timeval tv; ret = stat(file, &file_stat); if (ret < 0) { err = errno; if (err == ENOENT && ignore_missing) { DEBUG(SSSDBG_MINOR_FAILURE, "file [%s] is missing. Will not update online status " "based on watching the file\n", file); return EOK; } else { DEBUG(SSSDBG_FATAL_FAILURE, "Could not stat file [%s]. Error [%d:%s]\n", file, err, strerror(err)); return err; } } cb = talloc_zero(ctx->file_ctx, struct config_file_callback); if (!cb) { talloc_free(ctx->file_ctx); return ENOMEM; } cb->filename = talloc_strdup(cb, file); if (!cb->filename) { talloc_free(ctx->file_ctx); return ENOMEM; } cb->fn = fn; cb->modified = file_stat.st_mtime; DLIST_ADD(ctx->file_ctx->callbacks, cb); if(!ctx->file_ctx->timer) { gettimeofday(&tv, NULL); tv.tv_sec += CONFIG_FILE_POLL_INTERVAL; tv.tv_usec = 0; ctx->file_ctx->timer = tevent_add_timer(ctx->ev, mem_ctx, tv, poll_config_file, ctx->file_ctx); if (!ctx->file_ctx->timer) { talloc_free(ctx->file_ctx); return EIO; } } return EOK; } #define MISSING_RESOLV_CONF_POLL_TIME 10 static void missing_resolv_conf(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *data) { int ret; struct mt_ctx *ctx = talloc_get_type(data, struct mt_ctx); ret = monitor_config_file(ctx, ctx, RESOLV_CONF_PATH, monitor_update_resolv, false); if (ret == EOK) { signal_res_init(ctx); } else if (ret == ENOENT) { tv = tevent_timeval_current_ofs(MISSING_RESOLV_CONF_POLL_TIME, 0); te = tevent_add_timer(ctx->ev, ctx, tv, missing_resolv_conf, ctx); if (te == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "tevent_add_timer failed. resolv.conf will be ignored.\n"); } } else { DEBUG(SSSDBG_FATAL_FAILURE, "Monitor_config_file failed. resolv.conf will be ignored.\n"); } } static int monitor_process_init(struct mt_ctx *ctx, const char *config_file) { TALLOC_CTX *tmp_ctx; struct tevent_signal *tes; struct timeval tv; struct tevent_timer *te; struct sss_domain_info *dom; char *rcachedir; int num_providers; int ret; int error; /* Set up the environment variable for the Kerberos Replay Cache */ ret = confdb_get_string(ctx->cdb, ctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_KRB5_RCACHEDIR, KRB5_RCACHE_DIR, &rcachedir); if (ret != EOK) { return ret; } if (strcmp(rcachedir, KRB5_RCACHE_DIR_DISABLE) != 0) { errno = 0; ret = setenv("KRB5RCACHEDIR", rcachedir, 1); if (ret < 0) { error = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set KRB5RCACHEDIR: %s." "Will attempt to use libkrb5 defaults\n", strerror(error)); } talloc_zfree(rcachedir); } /* Set up an event handler for a SIGHUP */ tes = tevent_add_signal(ctx->ev, ctx, SIGHUP, 0, monitor_hup, ctx); if (tes == NULL) { return EIO; } /* Set up an event handler for a SIGINT */ BlockSignals(false, SIGINT); tes = tevent_add_signal(ctx->ev, ctx, SIGINT, 0, monitor_quit_signal, ctx); if (tes == NULL) { return EIO; } /* Set up an event handler for a SIGTERM */ tes = tevent_add_signal(ctx->ev, ctx, SIGTERM, 0, monitor_quit_signal, ctx); if (tes == NULL) { return EIO; } /* Handle SIGUSR1 (tell all providers to go offline) */ BlockSignals(false, SIGUSR1); tes = tevent_add_signal(ctx->ev, ctx, SIGUSR1, 0, signal_offline, ctx); if (tes == NULL) { return EIO; } /* Handle SIGUSR2 (tell all providers to go reset offline) */ BlockSignals(false, SIGUSR2); tes = tevent_add_signal(ctx->ev, ctx, SIGUSR2, 0, signal_offline_reset, ctx); if (tes == NULL) { return EIO; } /* Set up the SIGCHLD handler */ ret = sss_sigchld_init(ctx, ctx->ev, &ctx->sigchld_ctx); if (ret != EOK) return ret; #if 0 This feature is incomplete and can leave the SSSD in a bad state if the config file is changed while the SSSD is running. Uncomment this once the backends are honoring reloadConfig() /* Watch for changes to the confdb config file */ ret = monitor_config_file(ctx, ctx, config_file, monitor_signal_reconf, true); if (ret != EOK) { return ret; } #endif /* Watch for changes to the DNS resolv.conf */ ret = monitor_config_file(ctx, ctx, RESOLV_CONF_PATH, monitor_update_resolv, false); if (ret == ENOENT) { tv = tevent_timeval_current_ofs(MISSING_RESOLV_CONF_POLL_TIME, 0); te = tevent_add_timer(ctx->ev, ctx, tv, missing_resolv_conf, ctx); if (te == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "resolv.conf will be ignored\n"); } } else if (ret != EOK) { return ret; } /* Avoid a startup race condition between process. * We need to handle DB upgrades or DB creation only * in one process before all other start. */ tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_init_ext(tmp_ctx, ctx->domains, true, true, ctx->uid, ctx->gid); if (ret != EOK) { SYSDB_VERSION_ERROR_DAEMON(ret); return ret; } talloc_zfree(tmp_ctx); /* Initialize D-BUS Server * The monitor will act as a D-BUS server for all * SSSD processes */ ret = monitor_dbus_init(ctx); if (ret != EOK) { return ret; } ret = setup_netlink(ctx, ctx->ev, network_status_change_cb, ctx, &ctx->nlctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot set up listening for network notifications\n"); return ret; } /* start providers */ num_providers = 0; for (dom = ctx->domains; dom; dom = get_next_domain(dom, 0)) { ret = add_new_provider(ctx, dom->name, 0); if (ret != EOK && ret != ENOENT) { return ret; } if (ret != ENOENT) { num_providers++; } } if (num_providers > 0) { /* now set the services stratup timeout * * (responders will be started automatically when all * providers are up and running or when the tomeout * expires) */ ret = add_services_startup_timeout(ctx); if (ret != EOK) { return ret; } } else { int i; ctx->services_started = true; /* No providers start services immediately * Normally this means only LOCAL is configured */ for (i = 0; ctx->services[i]; i++) { add_new_service(ctx, ctx->services[i], 0); } } return EOK; } static void init_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { struct mon_init_conn *mini; DEBUG(SSSDBG_OP_FAILURE, "Client timed out before Identification!\n"); mini = talloc_get_type(ptr, struct mon_init_conn); sbus_disconnect(mini->conn); talloc_zfree(mini); } /* * monitor_service_init * Set up a timeout function and temporary connection structure. * If the client does not identify before the timeout kicks in, * the client is forcibly disconnected. */ static int monitor_service_init(struct sbus_connection *conn, void *data) { struct mt_ctx *ctx; struct mon_init_conn *mini; struct timeval tv; DEBUG(SSSDBG_TRACE_FUNC, "Initializing D-BUS Service\n"); ctx = talloc_get_type(data, struct mt_ctx); mini = talloc(conn, struct mon_init_conn); if (!mini) { DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n"); talloc_zfree(conn); return ENOMEM; } mini->ctx = ctx; mini->conn = conn; /* Allow access from the SSSD user */ sbus_allow_uid(conn, &ctx->uid); /* 10 seconds should be plenty */ tv = tevent_timeval_current_ofs(10, 0); mini->timeout = tevent_add_timer(ctx->ev, mini, tv, init_timeout, mini); if (!mini->timeout) { DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n"); talloc_zfree(conn); return ENOMEM; } return sbus_conn_register_iface(conn, &monitor_methods.vtable, MON_SRV_PATH, mini); } /* service_send_ping * this function send a dbus ping to a service. * It returns EOK if all is fine or ENXIO if the connection is * not available (either not yet set up or teared down). * Returns e generic error in other cases. */ static int service_send_ping(struct mt_svc *svc) { DBusMessage *msg; int ret; if (!svc->conn) { DEBUG(SSSDBG_TRACE_INTERNAL, "Service not yet initialized\n"); return ENXIO; } DEBUG(SSSDBG_TRACE_INTERNAL, "Pinging %s\n", svc->name); /* * Set up identity request * This should be a well-known path and method * for all services */ msg = dbus_message_new_method_call(NULL, MONITOR_PATH, MON_CLI_IFACE, MON_CLI_IFACE_PING); if (!msg) { DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n"); talloc_zfree(svc->conn); return ENOMEM; } ret = sbus_conn_send(svc->conn, msg, svc->ping_time * 1000, /* milliseconds */ ping_check, svc, &svc->pending); dbus_message_unref(msg); return ret; } static void ping_check(DBusPendingCall *pending, void *data) { struct mt_svc *svc; DBusMessage *reply; const char *dbus_error_name; size_t len; int type; svc = talloc_get_type(data, struct mt_svc); if (!svc) { /* The connection probably went down before the callback fired. * Not much we can do. */ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid service pointer.\n"); return; } svc->pending = NULL; reply = dbus_pending_call_steal_reply(pending); if (!reply) { /* reply should never be null. This function shouldn't be called * until reply is valid or timeout has occurred. If reply is NULL * here, something is seriously wrong and we should bail out. */ DEBUG(SSSDBG_FATAL_FAILURE, "A reply callback was called but no reply was received" " and no timeout occurred\n"); /* Destroy this connection */ sbus_disconnect(svc->conn); goto done; } type = dbus_message_get_type(reply); switch (type) { case DBUS_MESSAGE_TYPE_METHOD_RETURN: /* ok peer replied, * make sure we reset the failure counter in the service structure */ DEBUG(SSSDBG_TRACE_INTERNAL, "Service %s replied to ping\n", svc->name); svc->failed_pongs = 0; break; case DBUS_MESSAGE_TYPE_ERROR: dbus_error_name = dbus_message_get_error_name(reply); if (!dbus_error_name) { dbus_error_name = ""; } len = strlen(DBUS_ERROR_NO_REPLY); /* Increase failed pong count */ if (strnlen(dbus_error_name, len + 1) == len && strncmp(dbus_error_name, DBUS_ERROR_NO_REPLY, len) == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "A service PING timed out on [%s]. " "Attempt [%d]\n", svc->name, svc->failed_pongs); svc->failed_pongs++; break; } DEBUG(SSSDBG_FATAL_FAILURE, "A service PING returned an error [%s], closing connection.\n", dbus_error_name); /* Falling through to default intentionally*/ default: /* * Timeout or other error occurred or something * unexpected happened. * It doesn't matter which, because either way we * know that this connection isn't trustworthy. * We'll destroy it now. */ sbus_disconnect(svc->conn); } done: dbus_pending_call_unref(pending); dbus_message_unref(reply); } static void service_startup_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr); static int start_service(struct mt_svc *svc) { struct tevent_timer *te; struct timeval tv; DEBUG(SSSDBG_CONF_SETTINGS,"Queueing service %s for startup\n", svc->name); tv = tevent_timeval_current(); /* Add a timed event to start up the service. * We have to do this in order to avoid a race * condition where the service being started forks * and attempts to connect to the SBUS before * the monitor is serving it. */ te = tevent_add_timer(svc->mt_ctx->ev, svc, tv, service_startup_handler, svc); if (te == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to queue service %s for startup\n", svc->name); return ENOMEM; } return EOK; } static void mt_svc_exit_handler(int pid, int wait_status, void *pvt); static void service_startup_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { errno_t ret; struct mt_svc *mt_svc; char **args; mt_svc = talloc_get_type(ptr, struct mt_svc); if (mt_svc == NULL) { return; } mt_svc->pid = fork(); if (mt_svc->pid != 0) { if (mt_svc->pid == -1) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not fork child to start service [%s]. " "Continuing.\n", mt_svc->name); return; } /* Parent */ mt_svc->mt_ctx->check_children = true; mt_svc->failed_pongs = 0; /* Handle process exit */ ret = sss_child_register(mt_svc, mt_svc->mt_ctx->sigchld_ctx, mt_svc->pid, mt_svc_exit_handler, mt_svc, &mt_svc->child_ctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not register sigchld handler.\n"); /* Should we exit here? For now, we'll hope this * child never dies, because we can't restart it. */ } DLIST_ADD(mt_svc->mt_ctx->svc_list, mt_svc); set_tasks_checker(mt_svc); return; } /* child */ args = parse_args(mt_svc->command); execvp(args[0], args); /* If we are here, exec() has failed * Print errno and abort quickly */ DEBUG(SSSDBG_FATAL_FAILURE, "Could not exec %s, reason: %s\n", mt_svc->command, strerror(errno)); /* We have to call _exit() instead of exit() here * because a bug in D-BUS will cause the server to * close its socket at exit() */ _exit(1); } static void mt_svc_restart(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { struct mt_svc *svc; svc = talloc_get_type(ptr, struct mt_svc); if (svc == NULL) { return; } DEBUG(SSSDBG_TRACE_FUNC, "Scheduling service %s for restart %d\n", svc->name, svc->restarts+1); if (svc->type == MT_SVC_SERVICE) { add_new_service(svc->mt_ctx, svc->name, svc->restarts + 1); } else if (svc->type == MT_SVC_PROVIDER) { add_new_provider(svc->mt_ctx, svc->name, svc->restarts + 1); } else { /* Invalid type? */ DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Invalid child process type [%d]\n", svc->type); } /* Free the old service (which will also remove it * from the child list) */ talloc_free(svc); } static void mt_svc_exit_handler(int pid, int wait_status, void *pvt) { struct mt_svc *svc = talloc_get_type(pvt, struct mt_svc); if (WIFEXITED(wait_status)) { DEBUG(SSSDBG_OP_FAILURE, "Child [%s] exited with code [%d]\n", svc->name, WEXITSTATUS(wait_status)); } else if (WIFSIGNALED(wait_status)) { DEBUG(SSSDBG_OP_FAILURE, "Child [%s] terminated with signal [%d]\n", svc->name, WTERMSIG(wait_status)); } else { DEBUG(SSSDBG_FATAL_FAILURE, "Child [%s] did not exit cleanly\n", svc->name); /* Forcibly kill this child, just in case */ kill(svc->pid, SIGKILL); /* Return and let us get caught by another * call to the SIGCHLD handler */ return; } /* Clear the kill_timer so we don't try to SIGKILL it after it's * already gone. */ talloc_zfree(svc->kill_timer); /* Check the number of restart tries and relaunch the service */ monitor_restart_service(svc); return; } static void monitor_restart_service(struct mt_svc *svc) { struct mt_ctx *mt_ctx = svc->mt_ctx; int restart_delay; time_t now = time(NULL); struct tevent_timer *te; struct timeval tv; /* Handle the actual checks for how many times to restart this * service before giving up. */ if ((now - svc->last_restart) > MONITOR_RESTART_CNT_INTERVAL_RESET) { svc->restarts = 0; } /* Restart the service */ if (svc->restarts > MONITOR_MAX_SVC_RESTARTS) { DEBUG(SSSDBG_FATAL_FAILURE, "Process [%s], definitely stopped!\n", svc->name); sss_log(SSS_LOG_ERR, "Exiting the SSSD. Could not restart critical service [%s].", svc->name); talloc_free(svc); /* exit the SSSD with an error, shutting down all * services and domains. * We do this because if one of the responders is down * and can't come back up, this is the only way to * guarantee admin intervention. */ monitor_quit(mt_ctx, 1); return; } /* restarts are schedule after 0, 2, 4 seconds */ restart_delay = svc->restarts << 1; if (restart_delay > MONITOR_MAX_RESTART_DELAY) { restart_delay = MONITOR_MAX_RESTART_DELAY; } tv = tevent_timeval_current_ofs(restart_delay, 0); te = tevent_add_timer(svc->mt_ctx->ev, svc, tv, mt_svc_restart, svc); if (te == NULL) { /* Nothing much we can do */ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to allocate timed event: mt_svc_restart.\n"); talloc_free(svc); return; } } int main(int argc, const char *argv[]) { int opt; poptContext pc; int opt_daemon = 0; int opt_interactive = 0; int opt_version = 0; char *opt_config_file = NULL; char *config_file = NULL; int flags = 0; struct main_context *main_ctx; TALLOC_CTX *tmp_ctx; struct mt_ctx *monitor; int ret; uid_t uid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS {"daemon", 'D', POPT_ARG_NONE, &opt_daemon, 0, \ _("Become a daemon (default)"), NULL }, \ {"interactive", 'i', POPT_ARG_NONE, &opt_interactive, 0, \ _("Run interactive (not a daemon)"), NULL}, \ {"config", 'c', POPT_ARG_STRING, &opt_config_file, 0, \ _("Specify a non-default config file"), NULL}, \ {"version", '\0', POPT_ARG_NONE, &opt_version, 0, \ _("Print version number and exit"), NULL }, \ POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } DEBUG_INIT(debug_level); if (opt_version) { puts(VERSION""PRERELEASE_VERSION); return EXIT_SUCCESS; } /* If the level or timestamps was passed at the command-line, we want * to save it and pass it to the children later. */ cmdline_debug_level = debug_level; cmdline_debug_timestamps = debug_timestamps; cmdline_debug_microseconds = debug_microseconds; if (opt_daemon && opt_interactive) { fprintf(stderr, "Option -i|--interactive is not allowed together with -D|--daemon\n"); poptPrintUsage(pc, stderr, 0); return 1; } if (!opt_daemon && !opt_interactive) { opt_daemon = 1; } poptFreeContext(pc); uid = getuid(); if (uid != 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Running under %"SPRIuid", must be root\n", uid); sss_log(SSS_LOG_ALERT, "sssd must be run as root"); return 8; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return 7; } if (opt_daemon) flags |= FLAGS_DAEMON; if (opt_interactive) { flags |= FLAGS_INTERACTIVE; debug_to_stderr = 1; } if (opt_config_file) { config_file = talloc_strdup(tmp_ctx, opt_config_file); } else { config_file = talloc_strdup(tmp_ctx, CONFDB_DEFAULT_CONFIG_FILE); } if (!config_file) { return 6; } /* we want a pid file check */ flags |= FLAGS_PID_FILE; /* Open before server_setup() does to have logging * during configuration checking */ if (debug_to_file) { ret = open_debug_file(); if (ret) { return 7; } } #ifdef USE_KEYRING /* Do this before all the forks, it sets the session key ring so all * keys are private to the daemon and cannot be read by any other process * tree */ /* make a new session */ ret = keyctl_join_session_keyring(NULL); if (ret == -1) { sss_log(SSS_LOG_ALERT, "Could not create private keyring session. " "If you store password there they may be easily accessible " "to the root user. (%d, %s)", errno, strerror(errno)); } ret = keyctl_setperm(KEY_SPEC_SESSION_KEYRING, KEY_POS_ALL); if (ret == -1) { sss_log(SSS_LOG_ALERT, "Could not set permissions on private keyring. " "If you store password there they may be easily accessible " "to the root user. (%d, %s)", errno, strerror(errno)); } #endif /* Warn if nscd seems to be running */ ret = check_file(NSCD_SOCKET_PATH, -1, -1, S_IFSOCK, S_IFMT, NULL, false); if (ret == EOK) { ret = sss_nscd_parse_conf(NSCD_CONF_PATH); switch (ret) { case ENOENT: sss_log(SSS_LOG_NOTICE, "NSCD socket was detected. NSCD caching capabilities " "may conflict with SSSD for users and groups. It is " "recommended not to run NSCD in parallel with SSSD, " "unless NSCD is configured not to cache the passwd, " "group, netgroup and services nsswitch maps."); break; case EEXIST: sss_log(SSS_LOG_NOTICE, "NSCD socket was detected and seems to be configured " "to cache some of the databases controlled by " "SSSD [passwd,group,netgroup,services]. It is " "recommended not to run NSCD in parallel with SSSD, " "unless NSCD is configured not to cache these."); break; case EOK: DEBUG(SSSDBG_TRACE_FUNC, "NSCD socket was detected and it " "seems to be configured not to interfere with " "SSSD's caching capabilities\n"); } } /* Parse config file, fail if cannot be done */ ret = load_configuration(tmp_ctx, config_file, &monitor); if (ret != EOK) { switch (ret) { case ERR_MISSING_CONF: DEBUG(SSSDBG_CRIT_FAILURE, "Configuration file: %s does not exist.\n", config_file); sss_log(SSS_LOG_ALERT, "Configuration file: %s does not exist.\n", config_file); break; case EPERM: case EACCES: DEBUG(SSSDBG_CRIT_FAILURE, CONF_FILE_PERM_ERROR_MSG, config_file); sss_log(SSS_LOG_ALERT, CONF_FILE_PERM_ERROR_MSG, config_file); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "SSSD couldn't load the configuration database.\n"); sss_log(SSS_LOG_ALERT, "SSSD couldn't load the configuration database [%d]: %s.\n", ret, strerror(ret)); break; } return 4; } /* set up things like debug , signals, daemonization, etc... */ monitor->conf_path = CONFDB_MONITOR_CONF_ENTRY; ret = close(STDIN_FILENO); if (ret != EOK) return 6; ret = server_setup(MONITOR_NAME, flags, 0, 0, monitor->conf_path, &main_ctx); if (ret != EOK) return 2; monitor->is_daemon = !opt_interactive; monitor->parent_pid = main_ctx->parent_pid; monitor->ev = main_ctx->event_ctx; talloc_steal(main_ctx, monitor); ret = monitor_process_init(monitor, config_file); if (ret != EOK) return 3; talloc_free(tmp_ctx); /* loop on main */ server_loop(main_ctx); ret = monitor_cleanup(); if (ret != EOK) return 5; return 0; } sssd-1.13.4/src/PaxHeaders.16287/sbus0000644000000000000000000000013212703463557014022 xustar0030 mtime=1460561775.056794992 30 atime=1460561776.118798593 30 ctime=1460561775.056794992 sssd-1.13.4/src/sbus/0000755002412700241270000000000012703463557015553 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_meta.c0000644000000000000000000000007412703456111017233 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.848794286 sssd-1.13.4/src/sbus/sssd_dbus_meta.c0000644002412700241270000000365012703456111020706 0ustar00jhrozekjhrozek00000000000000/* Authors: Stef Walter Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "sbus/sssd_dbus_meta.h" const struct sbus_method_meta * sbus_meta_find_method(const struct sbus_interface_meta *interface, const char *method_name) { const struct sbus_method_meta *method; for (method = interface->methods; method && method->name; method++) { if (strcmp(method_name, method->name) == 0) { return method; } } return NULL; } const struct sbus_signal_meta * sbus_meta_find_signal(const struct sbus_interface_meta *interface, const char *signal_name) { const struct sbus_signal_meta *sig; for (sig = interface->signals; sig && sig->name; sig++) { if (strcmp(signal_name, sig->name) == 0) { return sig; } } return NULL; } const struct sbus_property_meta * sbus_meta_find_property(const struct sbus_interface_meta *interface, const char *property_name) { const struct sbus_property_meta *property; for (property = interface->properties; property && property->name; property++) { if (strcmp(property_name, property->name) == 0) { return property; } } return NULL; } sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_invokers.h0000644000000000000000000000007412703456111020152 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.500793107 sssd-1.13.4/src/sbus/sssd_dbus_invokers.h0000644002412700241270000001036412703456111021625 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat SBUS: Interface introspection This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSSD_DBUS_INVOKER_H_ #define SSSD_DBUS_INVOKER_H_ #include "sbus/sssd_dbus.h" int sbus_invoke_get_y(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_b(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_n(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_q(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_i(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_u(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_x(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_t(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_d(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_s(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_o(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_ay(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_an(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_aq(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_ai(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_au(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_ax(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_at(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_ad(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_as(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_ao(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); int sbus_invoke_get_aDOsasDE(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr); void sbus_invoke_get(struct sbus_request *sbus_req, const char *type, sbus_get_invoker_fn invoker_fn, sbus_msg_handler_fn handler_fn); void sbus_invoke_get_all(struct sbus_request *sbus_req); #endif /* SSSD_DBUS_INVOKER_H_ */ sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_meta.h0000644000000000000000000000007412703456111017240 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.496793093 sssd-1.13.4/src/sbus/sssd_dbus_meta.h0000644002412700241270000000605512703456111020715 0ustar00jhrozekjhrozek00000000000000/* Authors: Stef Walter Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SSSD_DBUS_META_H_ #define _SSSD_DBUS_META_H_ #include /* * Interface metadata * * For arrays, the last item in each array will have a * NULL .name field * * Typically these structs will be generated by sbus_codegen * from canonical XML interface data: * * http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format */ /* Looks up a vtable func, in a struct derived from struct sbus_vtable */ #define VTABLE_FUNC(vtable, offset) \ (*(DISCARD_ALIGN((char *)(vtable) + (offset), void **))) struct sbus_arg_meta { const char *name; const char *type; }; struct sbus_request; struct sbus_interface; typedef int (* sbus_get_invoker_fn)(DBusMessageIter *iter, struct sbus_request *sbus_req, void *handler_fn); typedef void (* sbus_get_all_invoker_fn)(struct sbus_request *sbus_req); typedef int (* sbus_method_invoker_fn)(struct sbus_request *sbus_req, void *handler_fn); struct sbus_method_meta { const char *name; const struct sbus_arg_meta *in_args; const struct sbus_arg_meta *out_args; size_t vtable_offset; sbus_method_invoker_fn invoker; }; enum { SBUS_PROPERTY_READABLE = 1 << 0, SBUS_PROPERTY_WRITABLE = 1 << 1 }; struct sbus_property_meta { const char *name; const char *type; int flags; size_t vtable_offset_get; sbus_get_invoker_fn invoker_get; size_t vtable_offset_set; sbus_method_invoker_fn invoker_set; }; struct sbus_signal_meta { const char *name; const struct sbus_arg_meta *args; }; struct sbus_interface_meta { const char *name; const struct sbus_method_meta *methods; const struct sbus_signal_meta *signals; const struct sbus_property_meta *properties; sbus_get_all_invoker_fn invoker_get_all; }; const struct sbus_method_meta * sbus_meta_find_method (const struct sbus_interface_meta *interface, const char *method_name); const struct sbus_signal_meta * sbus_meta_find_signal (const struct sbus_interface_meta *interface, const char *signal_name); const struct sbus_property_meta * sbus_meta_find_property (const struct sbus_interface_meta *interface, const char *property_name); #endif /* _SSSD_DBUS_META_H_ */ sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_server.c0000644000000000000000000000007412703456111017613 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.854794307 sssd-1.13.4/src/sbus/sssd_dbus_server.c0000644002412700241270000002647412703456111021277 0ustar00jhrozekjhrozek00000000000000/* SSSD Service monitor - D-BUS features Copyright (C) Stephen Gallagher 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_private.h" static int sbus_server_destructor(void *ctx); /* * new_connection_callback * Actions to be run upon each new client connection * Must either perform dbus_connection_ref() on the * new connection or else close the connection with * dbus_connection_close() */ static void sbus_server_init_new_connection(DBusServer *dbus_server, DBusConnection *dbus_conn, void *data) { struct sbus_connection *server; struct sbus_connection *conn; int ret; DEBUG(SSSDBG_FUNC_DATA,"Entering.\n"); server = talloc_get_type(data, struct sbus_connection); if (!server) { return; } DEBUG(SSSDBG_FUNC_DATA,"Adding connection %p.\n", dbus_conn); ret = sbus_init_connection(server, server->ev, dbus_conn, SBUS_CONN_TYPE_PRIVATE, &conn); if (ret != 0) { dbus_connection_close(dbus_conn); DEBUG(SSSDBG_FUNC_DATA, "Closing connection (failed setup)\n"); return; } dbus_connection_ref(dbus_conn); DEBUG(SSSDBG_FUNC_DATA,"Got a connection\n"); /* * Initialize connection-specific features * This function (or its callbacks) should also * set up connection-specific methods. */ ret = server->srv_init_fn(conn, server->srv_init_data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE,"Initialization failed!\n"); dbus_connection_close(dbus_conn); talloc_zfree(conn); } } const char * get_socket_address(TALLOC_CTX *mem_ctx, const char *address, bool use_symlink) { if (!use_symlink) { return talloc_strdup(mem_ctx, address); } return talloc_asprintf(mem_ctx, "%s.%lu", address, (unsigned long) getpid()); } static errno_t create_socket_symlink(const char *filename, const char *symlink_filename) { errno_t ret; DEBUG(SSSDBG_TRACE_LIBS, "Symlinking the dbus path %s to a link %s\n", filename, symlink_filename); errno = 0; ret = symlink(filename, symlink_filename); if (ret != 0 && errno == EEXIST) { /* Perhaps cruft after a previous server? */ errno = 0; ret = unlink(symlink_filename); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot remove old symlink: [%d][%s].\n", ret, strerror(ret)); return EIO; } errno = 0; ret = symlink(filename, symlink_filename); } if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "symlink() failed on file '%s': [%d][%s].\n", filename, ret, strerror(ret)); return EIO; } return EOK; } static errno_t remove_socket_symlink(const char *symlink_name) { errno_t ret; char target[PATH_MAX]; char pidpath[PATH_MAX]; ssize_t numread = 0; errno = 0; numread = readlink(symlink_name, target, PATH_MAX-1); if (numread < 0) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "readlink failed [%d]: %s\n", ret, strerror(ret)); return ret; } target[numread] = '\0'; DEBUG(SSSDBG_TRACE_ALL, "The symlink points to [%s]\n", target); /* We can only remove the symlink if it points to a socket with * the same PID */ ret = snprintf(pidpath, PATH_MAX, "%s.%lu", symlink_name, (unsigned long) getpid()); if (ret < 0) { DEBUG(SSSDBG_OP_FAILURE, "snprintf failed\n"); return EIO; } else if (ret >= PATH_MAX) { DEBUG(SSSDBG_OP_FAILURE, "path too long?!?!\n"); return EIO; } DEBUG(SSSDBG_TRACE_ALL, "The path including our pid is [%s]\n", pidpath); if (strcmp(pidpath, target) != 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Will not remove symlink, seems to be owned by " "another process\n"); return EOK; } ret = unlink(symlink_name); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "unlink failed to remove [%s] [%d]: %s\n", symlink_name, ret, strerror(ret)); return ret; } DEBUG(SSSDBG_TRACE_ALL, "Removed the symlink\n"); return EOK; } /* * dbus_new_server * Set up a D-BUS server, integrate with the event loop * for handling file descriptor and timed events */ int sbus_new_server(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *address, uid_t uid, gid_t gid, bool use_symlink, struct sbus_connection **_server, sbus_server_conn_init_fn init_fn, void *init_pvt_data) { struct sbus_connection *server; DBusServer *dbus_server; DBusError dbus_error; dbus_bool_t dbret; char *tmp; int ret, tmp_ret; char *filename; char *symlink_filename = NULL; const char *socket_address; struct stat stat_buf; TALLOC_CTX *tmp_ctx; *_server = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; socket_address = get_socket_address(tmp_ctx, address, use_symlink); if (!socket_address) { ret = ENOMEM; goto done; } /* Set up D-BUS server */ dbus_error_init(&dbus_error); dbus_server = dbus_server_listen(socket_address, &dbus_error); if (!dbus_server) { DEBUG(SSSDBG_CRIT_FAILURE, "dbus_server_listen failed! (name=%s, message=%s)\n", dbus_error.name, dbus_error.message); if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); ret = EIO; goto done; } filename = strchr(socket_address, '/'); if (filename == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected dbus address [%s].\n", socket_address); ret = EIO; goto done; } if (use_symlink) { symlink_filename = strchr(address, '/'); if (symlink_filename == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected dbus address [%s].\n", address); ret = EIO; goto done; } ret = create_socket_symlink(filename, symlink_filename); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not create symlink [%d]: %s\n", ret, strerror(ret)); ret = EIO; goto done; } } /* Both check_file and chmod can handle both the symlink and * the socket */ ret = check_file(filename, getuid(), getgid(), S_IFSOCK, S_IFMT, &stat_buf, true); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "check_file failed for [%s].\n", filename); ret = EIO; goto done; } if ((stat_buf.st_mode & ~S_IFMT) != (S_IRUSR|S_IWUSR)) { ret = chmod(filename, (S_IRUSR|S_IWUSR)); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "chmod failed for [%s]: [%d][%s].\n", filename, ret, sss_strerror(ret)); ret = EIO; goto done; } } if (stat_buf.st_uid != uid || stat_buf.st_gid != gid) { ret = chown(filename, uid, gid); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "chown failed for [%s]: [%d][%s].\n", filename, ret, sss_strerror(ret)); ret = EIO; goto done; } } tmp = dbus_server_get_address(dbus_server); DEBUG(SSSDBG_TRACE_FUNC, "D-BUS Server listening on %s\n", tmp); free(tmp); server = talloc_zero(tmp_ctx, struct sbus_connection); if (!server) { ret = ENOMEM; goto done; } server->ev = ev; server->type = SBUS_SERVER; server->dbus.server = dbus_server; server->srv_init_fn = init_fn; server->srv_init_data = init_pvt_data; talloc_set_destructor((TALLOC_CTX *)server, sbus_server_destructor); if (use_symlink) { server->symlink = talloc_strdup(server, symlink_filename); if (!server->symlink) { ret = ENOMEM; goto done; } } /* Set up D-BUS new connection handler */ dbus_server_set_new_connection_function(server->dbus.server, sbus_server_init_new_connection, server, NULL); /* Set up DBusWatch functions */ dbret = dbus_server_set_watch_functions(server->dbus.server, sbus_add_watch, sbus_remove_watch, sbus_toggle_watch, server, NULL); if (!dbret) { DEBUG(SSSDBG_CONF_SETTINGS, "Error setting up D-BUS server watch functions\n"); ret = EIO; goto done; } /* Set up DBusTimeout functions */ dbret = dbus_server_set_timeout_functions(server->dbus.server, sbus_add_timeout, sbus_remove_timeout, sbus_toggle_timeout, server, NULL); if (!dbret) { DEBUG(SSSDBG_CONF_SETTINGS, "Error setting up D-BUS server timeout functions\n"); dbus_server_set_watch_functions(server->dbus.server, NULL, NULL, NULL, NULL, NULL); ret = EIO; goto done; } *_server = talloc_steal(mem_ctx, server); ret = EOK; done: if (ret != EOK && symlink_filename) { tmp_ret = unlink(symlink_filename); /* non-fatal failure */ if (tmp_ret != EOK) { tmp_ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Failed to remove symbolic link: %d [%s]!\n", tmp_ret, sss_strerror(tmp_ret)); } } talloc_free(tmp_ctx); return ret; } static int sbus_server_destructor(void *ctx) { struct sbus_connection *server; errno_t ret; server = talloc_get_type(ctx, struct sbus_connection); dbus_server_disconnect(server->dbus.server); if (server->symlink) { ret = remove_socket_symlink(server->symlink); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not remove the server symlink\n"); } } return 0; } sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_errors.h0000644000000000000000000000007312703456111017625 xustar0030 atime=1460561751.652715634 29 ctime=1460561774.50479312 sssd-1.13.4/src/sbus/sssd_dbus_errors.h0000644002412700241270000000176112703456111021302 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat SBUS: Interface introspection This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSSD_DBUS_ERRORS_H_ #define SSSD_DBUS_ERRORS_H_ #define SBUS_ERROR_INTERNAL "org.freedesktop.sssd.Error.Internal" #define SBUS_ERROR_NOT_FOUND "org.freedesktop.sssd.Error.NotFound" #endif /* SSSD_DBUS_ERRORS_H_ */ sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_request.c0000644000000000000000000000007412703456111017775 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.853794304 sssd-1.13.4/src/sbus/sssd_dbus_request.c0000644002412700241270000003647412703456111021462 0ustar00jhrozekjhrozek00000000000000/* Authors: Stef Walter Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/sss_utf8.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_private.h" #include #include #define INTERNAL_ERROR "Internal Error" static int sbus_request_destructor(struct sbus_request *dbus_req) { dbus_message_unref(dbus_req->message); return 0; } struct sbus_request * sbus_new_request(struct sbus_connection *conn, struct sbus_interface *intf, DBusMessage *message) { struct sbus_request *dbus_req; dbus_req = talloc_zero(conn, struct sbus_request); if (!dbus_req) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory allocating DBus request\n"); return NULL; } dbus_req->intf = intf; dbus_req->conn = conn; dbus_req->message = dbus_message_ref(message); dbus_req->path = dbus_message_get_path(message); talloc_set_destructor(dbus_req, sbus_request_destructor); return dbus_req; } void sbus_request_invoke_or_finish(struct sbus_request *dbus_req, sbus_msg_handler_fn handler_fn, void *handler_data, sbus_method_invoker_fn invoker_fn) { DBusError error; int ret; if (invoker_fn != NULL) { ret = invoker_fn(dbus_req, handler_fn); } else if (handler_fn != NULL) { ret = handler_fn(dbus_req, handler_data); } else { ret = EINVAL; } switch(ret) { case EOK: return; case ENOMEM: DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory handling DBus message\n"); sbus_request_finish(dbus_req, NULL); break; default: dbus_error_init(&error); dbus_set_error_const(&error, DBUS_ERROR_FAILED, INTERNAL_ERROR); sbus_request_fail_and_finish(dbus_req, &error); break; } } int sbus_request_finish(struct sbus_request *dbus_req, DBusMessage *reply) { if (reply) { sbus_conn_send_reply(dbus_req->conn, reply); } return talloc_free(dbus_req); } static int sbus_request_valist_check(va_list va, int first_arg_type) { int ret = EOK; #ifdef HAVE_DBUSBASICVALUE int type; va_list va_check; const DBusBasicValue *value; bool ok; va_copy(va_check, va); type = first_arg_type; while (type != DBUS_TYPE_INVALID) { value = va_arg(va_check, const DBusBasicValue*); if (type == DBUS_TYPE_STRING) { ok = sss_utf8_check((const uint8_t *) value->str, strlen(value->str)); if (!ok) { DEBUG(SSSDBG_MINOR_FAILURE, "sbus message argument [%s] contains invalid " "non-UTF8 characters\n", value->str); ret = EINVAL; break; } } type = va_arg(va_check, int); } va_end(va_check); #endif /* HAVE_DBUSBASICVALUE */ return ret; } int sbus_request_return_and_finish(struct sbus_request *dbus_req, int first_arg_type, ...) { DBusMessage *reply; DBusError error = DBUS_ERROR_INIT; dbus_bool_t dbret; va_list va; int ret; va_start(va, first_arg_type); ret = sbus_request_valist_check(va, first_arg_type); if (ret != EOK) { va_end(va); dbus_set_error_const(&error, DBUS_ERROR_INVALID_ARGS, INTERNAL_ERROR); return sbus_request_fail_and_finish(dbus_req, &error); } reply = dbus_message_new_method_return(dbus_req->message); if (!reply) { va_end(va); DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory allocating DBus message\n"); sbus_request_finish(dbus_req, NULL); return ENOMEM; } dbret = dbus_message_append_args_valist(reply, first_arg_type, va); va_end(va); if (dbret) { ret = sbus_request_finish(dbus_req, reply); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't build DBus message\n"); sbus_request_finish(dbus_req, NULL); ret = EINVAL; } dbus_message_unref(reply); return ret; } int sbus_request_fail_and_finish(struct sbus_request *dbus_req, const DBusError *error) { DBusMessage *reply; int ret; if (error == NULL) { sbus_request_finish(dbus_req, NULL); return ENOMEM; } reply = dbus_message_new_error(dbus_req->message, error->name, error->message); if (!reply) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory allocating DBus message\n"); sbus_request_finish(dbus_req, NULL); return ENOMEM; } ret = sbus_request_finish(dbus_req, reply); dbus_message_unref(reply); return ret; } DBusError *sbus_error_new(TALLOC_CTX *mem_ctx, const char *dbus_err_name, const char *fmt, ...) { DBusError *dberr; const char *err_msg_dup = NULL; va_list ap; dberr = talloc(mem_ctx, DBusError); if (dberr == NULL) return NULL; if (fmt) { va_start(ap, fmt); err_msg_dup = talloc_vasprintf(dberr, fmt, ap); va_end(ap); if (err_msg_dup == NULL) { talloc_free(dberr); return NULL; } } dbus_error_init(dberr); dbus_set_error_const(dberr, dbus_err_name, err_msg_dup); return dberr; } struct array_arg { char **dbus_array; }; static int array_arg_destructor(struct array_arg *arg) { dbus_free_string_array(arg->dbus_array); return 0; } static bool parent_dbus_string_arrays(struct sbus_request *request, int first_arg_type, va_list va) { struct array_arg *array_arg; int arg_type; void **arg_ptr; /* * Here we iterate through the entire thing again and look for * things we need to fix allocation for. Normally certain types * returned from dbus_message_get_args() and friends require * later freeing. We tie those to the talloc context here. * * The list of argument has already been validated by the previous * dbus_message_get_args() call, so we can be cheap. */ arg_type = first_arg_type; while (arg_type != DBUS_TYPE_INVALID) { if (arg_type == DBUS_TYPE_ARRAY) { arg_type = va_arg(va, int); /* the array element type */ arg_ptr = va_arg(va, void **); /* the array elements */ va_arg(va, int *); /* the array length */ /* Arrays of these things need to be freed */ if (arg_type == DBUS_TYPE_STRING || arg_type == DBUS_TYPE_OBJECT_PATH || arg_type == DBUS_TYPE_SIGNATURE) { array_arg = talloc_zero(request, struct array_arg); if (array_arg == NULL) { /* no kidding ... */ DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory while trying not to leak memory\n"); return false; } array_arg->dbus_array = *arg_ptr; talloc_set_destructor(array_arg, array_arg_destructor); } /* A non array argument */ } else { arg_ptr = va_arg(va, void**); } /* The next type */ arg_type = va_arg(va, int); } return true; } bool sbus_request_parse_or_finish(struct sbus_request *request, int first_arg_type, ...) { DBusError error = DBUS_ERROR_INIT; bool ret = true; va_list va2; va_list va; va_start(va, first_arg_type); va_copy(va2, va); if (dbus_message_get_args_valist(request->message, &error, first_arg_type, va)) { ret = parent_dbus_string_arrays(request, first_arg_type, va2); } else { /* Trying to send the error back to the caller in this case is a joke */ if (!dbus_error_is_set(&error) && dbus_error_has_name(&error, DBUS_ERROR_NO_MEMORY)) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory parsing DBus message\n"); sbus_request_finish(request, NULL); /* Log other errors and send them back, this include o.f.d.InvalidArgs */ } else { DEBUG(SSSDBG_OP_FAILURE, "Couldn't parse DBus message %s.%s: %s\n", dbus_message_get_interface(request->message), dbus_message_get_member(request->message), error.message); sbus_request_fail_and_finish(request, &error); } dbus_error_free(&error); ret = false; } va_end(va2); va_end(va); return ret; } struct sbus_get_sender_id_state { struct sbus_connection *conn; DBusConnection *sysbus_conn; char *sender; int64_t uid; }; static void sbus_get_sender_id_done(DBusPendingCall *pending, void *ptr); struct tevent_req *sbus_get_sender_id_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_connection *conn, const char *sender) { struct tevent_req *req; struct sbus_get_sender_id_state *state; DBusError dbus_error; DBusMessage *msg = NULL; dbus_bool_t dbret; errno_t ret; hash_key_t key; hash_value_t value; req = tevent_req_create(mem_ctx, &state, struct sbus_get_sender_id_state); if (req == NULL) { return NULL; } state->conn = conn; state->uid = -1; if (conn->connection_type != SBUS_CONN_TYPE_SYSBUS) { DEBUG(SSSDBG_TRACE_INTERNAL, "Not a sysbus message, quit\n"); ret = EOK; goto immediate; } if (sender == NULL) { ret = ERR_SBUS_NO_SENDER; goto immediate; } if (strcmp(sender, "org.freedesktop.DBus") == 0) { ret = ERR_SBUS_SENDER_BUS; goto immediate; } state->sender = talloc_strdup(state, sender); if (state->sender == NULL) { ret = ENOMEM; goto immediate; } DEBUG(SSSDBG_TRACE_INTERNAL, "Looking for identity of sender [%s]\n", sender); key.type = HASH_KEY_STRING; key.str = discard_const(sender); ret = hash_lookup(conn->clients, &key, &value); if (ret == HASH_SUCCESS) { DEBUG(SSSDBG_TRACE_INTERNAL, "%s already present in the clients table\n", sender); state->uid = (int64_t) value.ul; ret = EOK; goto immediate; } else if (ret != HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to look up %s in the clients table\n", sender); ret = ERR_SBUS_GET_SENDER_ERROR; goto immediate; } /* We don't know this sender yet, let's ask the system bus */ /* Connect to the well-known system bus */ dbus_error_init(&dbus_error); state->sysbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error); if (state->sysbus_conn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to connect to D-BUS system bus.\n"); ret = ERR_SBUS_GET_SENDER_ERROR; goto immediate; } dbus_connection_set_exit_on_disconnect(state->sysbus_conn, FALSE); /* If we ever need to get the SELinux context or the PID here, we need * to call GetConnectionCredentials instead */ msg = dbus_message_new_method_call("org.freedesktop.DBus", /* bus name */ "/org/freedesktop/DBus", /* path */ "org.freedesktop.DBus", /* interface */ "GetConnectionUnixUser"); if (msg == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); ret = ENOMEM; goto immediate; } dbret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &sender, DBUS_TYPE_INVALID); if (!dbret) { ret = ERR_INTERNAL; goto immediate; } ret = sss_dbus_conn_send(state->sysbus_conn, msg, 3000, sbus_get_sender_id_done, req, NULL); dbus_message_unref(msg); msg = NULL; if (ret != EOK) { goto immediate; } return req; immediate: if (ret == EOK) { tevent_req_done(req); } else { if (msg != NULL) { dbus_message_unref(msg); } if (state->sysbus_conn != NULL) { dbus_connection_unref(state->sysbus_conn); } tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void sbus_get_sender_id_done(DBusPendingCall *pending, void *ptr) { struct tevent_req *req; struct sbus_get_sender_id_state *state; DBusMessage *reply; DBusError dbus_error; hash_key_t key; hash_value_t value; dbus_bool_t dbret; int ret; uid_t uid; dbus_error_init(&dbus_error); req = talloc_get_type(ptr, struct tevent_req); state = tevent_req_data(req, struct sbus_get_sender_id_state); reply = dbus_pending_call_steal_reply(pending); if (!reply) { /* reply should never be null. This function shouldn't be called * until reply is valid or timeout has occurred. If reply is NULL * here, something is seriously wrong and we should bail out. */ DEBUG(SSSDBG_CRIT_FAILURE, "Severe error. A reply callback was called but no reply " "was received and no timeout occurred\n"); ret = EIO; goto done; } dbret = dbus_message_get_args(reply, &dbus_error, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID); if (!dbret) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not parse reply!\n"); ret = EIO; goto done; } state->uid = uid; key.type = HASH_KEY_STRING; key.str = talloc_steal(state->conn->clients, state->sender); value.type = HASH_VALUE_UINT; value.ul = state->uid; ret = hash_enter(state->conn->clients, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add key to hash table!\n"); ret = EIO; goto done; } ret = EOK; done: dbus_pending_call_unref(pending); dbus_message_unref(reply); dbus_connection_unref(state->sysbus_conn); if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } } int sbus_get_sender_id_recv(struct tevent_req *req, int64_t *_uid) { struct sbus_get_sender_id_state *state = \ tevent_req_data(req, struct sbus_get_sender_id_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_uid) { *_uid = state->uid; } return EOK; } sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_common_signals.c0000644000000000000000000000007312703456111021314 xustar0030 atime=1460561751.652715634 29 ctime=1460561774.85579431 sssd-1.13.4/src/sbus/sssd_dbus_common_signals.c0000644002412700241270000000511512703456111022766 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_private.h" static void sbus_signal_name_owner_changed(struct sbus_incoming_signal *a_signal, void *handler_data) { hash_table_t *table = a_signal->conn->clients; hash_key_t *keys; unsigned long count; unsigned long i; int hret; DEBUG(SSSDBG_TRACE_FUNC, "Clearing UIDs cache\n"); hret = hash_keys(table, &count, &keys); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get hash keys\n"); return; } for (i = 0; i < count; i++) { hret = hash_delete(table, &keys[i]); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not delete key from hash\n"); return; } } return; } struct signals_map { const char *iface; const char *signal; sbus_incoming_signal_fn handler_fn; int conn_type; }; static struct signals_map signals_map[] = { { "org.freedesktop.DBus", "NameOwnerChanged", sbus_signal_name_owner_changed, SBUS_CONN_TYPE_SYSBUS }, { NULL, NULL, NULL, 0 }, }; void sbus_register_common_signals(struct sbus_connection *conn, void *pvt) { errno_t ret; int i; for (i = 0; signals_map[i].iface != NULL; i++) { if (signals_map[i].conn_type != conn->connection_type) { /* Skip this signal. */ continue; } ret = sbus_signal_listen(conn, signals_map[i].iface, signals_map[i].signal, signals_map[i].handler_fn, conn); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to register signal %s.%s\n", signals_map[i].iface, signals_map[i].signal); continue; } } } sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_signals.c0000644000000000000000000000007412703456111017745 xustar0030 atime=1460561751.653715637 30 ctime=1460561774.854794307 sssd-1.13.4/src/sbus/sssd_dbus_signals.c0000644002412700241270000001775212703456111021430 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_private.h" static int sbus_incoming_signal_destructor(struct sbus_incoming_signal *a_signal) { dbus_message_unref(a_signal->message); return 0; } static struct sbus_incoming_signal * sbus_new_incoming_signal(struct sbus_connection *conn, DBusMessage *message) { struct sbus_incoming_signal *a_signal; a_signal = talloc_zero(conn, struct sbus_incoming_signal); if (a_signal == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory allocating D-Bus signal\n"); return NULL; } a_signal->conn = conn; a_signal->message = dbus_message_ref(message); a_signal->interface = dbus_message_get_interface(message); a_signal->signal = dbus_message_get_member(message); a_signal->path = dbus_message_get_path(message); talloc_set_destructor(a_signal, sbus_incoming_signal_destructor); return a_signal; } struct sbus_incoming_signal_data { sbus_incoming_signal_fn handler_fn; void *handler_data; }; errno_t sbus_incoming_signal_hash_init(TALLOC_CTX *mem_ctx, hash_table_t **_table) { return sss_hash_create(mem_ctx, 10, _table); } static errno_t sbus_incoming_signal_hash_add(hash_table_t *table, const char *iface, const char *a_signal, sbus_incoming_signal_fn handler_fn, void *handler_data) { TALLOC_CTX *tmp_ctx; struct sbus_incoming_signal_data *data; hash_key_t key; hash_value_t value; errno_t ret; bool has_key; int hret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } key.type = HASH_KEY_STRING; key.str = talloc_asprintf(tmp_ctx, "%s.%s", iface, a_signal); if (key.str == NULL) { ret = ENOMEM; goto done; } has_key = hash_has_key(table, &key); if (has_key) { ret = EEXIST; goto done; } data = talloc_zero(tmp_ctx, struct sbus_incoming_signal_data); if (data == NULL) { ret = ENOMEM; goto done; } data->handler_data = handler_data; data->handler_fn = handler_fn; value.type = HASH_VALUE_PTR; value.ptr = data; hret = hash_enter(table, &key, &value); if (hret != HASH_SUCCESS) { ret = EIO; goto done; } talloc_steal(table, key.str); talloc_steal(table, data); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static struct sbus_incoming_signal_data * sbus_incoming_signal_hash_lookup(hash_table_t *table, const char *iface, const char *a_signal) { struct sbus_incoming_signal_data *data; hash_key_t key; hash_value_t value; int hret; key.type = HASH_KEY_STRING; key.str = talloc_asprintf(NULL, "%s.%s", iface, a_signal); if (key.str == NULL) { return NULL; } hret = hash_lookup(table, &key, &value); if (hret == HASH_ERROR_KEY_NOT_FOUND) { data = NULL; goto done; } else if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Unable to search hash table: hret=%d\n", hret); data = NULL; goto done; } data = talloc_get_type(value.ptr, struct sbus_incoming_signal_data); done: talloc_free(key.str); return data; } errno_t sbus_signal_listen(struct sbus_connection *conn, const char *iface, const char *a_signal, sbus_incoming_signal_fn handler_fn, void *handler_data) { TALLOC_CTX *tmp_ctx; const char *rule; DBusError error; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } dbus_error_init(&error); ret = sbus_incoming_signal_hash_add(conn->incoming_signals, iface, a_signal, handler_fn, handler_data); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to register signal handler " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } rule = talloc_asprintf(tmp_ctx, "type='signal',interface='%s',member='%s'", iface, a_signal); if (rule == NULL) { ret = ENOMEM; goto done; } dbus_bus_add_match(conn->dbus.conn, rule, &error); if (dbus_error_is_set(&error)) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add D-Bus match rule, cause: %s\n", error.message); ret = EIO; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Listening to signal %s.%s\n", iface, a_signal); done: dbus_error_free(&error); talloc_free(tmp_ctx); return ret; } static void sbus_signal_handler_got_caller_id(struct tevent_req *req); DBusHandlerResult sbus_signal_handler(DBusConnection *dbus_conn, DBusMessage *message, void *handler_data) { struct tevent_req *req; struct sbus_connection *conn; struct sbus_incoming_signal *a_signal; const char *sender; int type; type = dbus_message_get_type(message); if (type != DBUS_MESSAGE_TYPE_SIGNAL) { /* We ignore other types here. */ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } conn = talloc_get_type(handler_data, struct sbus_connection); sender = dbus_message_get_sender(message); /* we have a valid handler, create D-Bus request */ a_signal = sbus_new_incoming_signal(conn, message); if (a_signal == NULL) { return DBUS_HANDLER_RESULT_NEED_MEMORY; } DEBUG(SSSDBG_TRACE_INTERNAL, "Received D-Bus signal %s.%s\n", a_signal->interface, a_signal->signal); /* now get the sender ID */ req = sbus_get_sender_id_send(a_signal, conn->ev, conn, sender); if (req == NULL) { talloc_free(a_signal); return DBUS_HANDLER_RESULT_NEED_MEMORY; } tevent_req_set_callback(req, sbus_signal_handler_got_caller_id, a_signal); return DBUS_HANDLER_RESULT_HANDLED; } static void sbus_signal_handler_got_caller_id(struct tevent_req *req) { struct sbus_incoming_signal_data *signal_data; struct sbus_incoming_signal *a_signal; errno_t ret; a_signal = tevent_req_callback_data(req, struct sbus_incoming_signal); ret = sbus_get_sender_id_recv(req, &a_signal->client); if (ret == ERR_SBUS_SENDER_BUS) { DEBUG(SSSDBG_TRACE_FUNC, "Got a signal from the bus..\n"); } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to resolve caller's ID: %s\n", sss_strerror(ret)); goto done; } signal_data = sbus_incoming_signal_hash_lookup( a_signal->conn->incoming_signals, a_signal->interface, a_signal->signal); if (signal_data == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Received signal %s.%s that we are " "not listening to.\n", a_signal->interface, a_signal->signal); goto done; } signal_data->handler_fn(a_signal, signal_data->handler_data); done: talloc_free(a_signal); } sssd-1.13.4/src/sbus/PaxHeaders.16287/sbus_codegen0000644000000000000000000000007412703456111016453 xustar0030 atime=1460561751.652715634 30 ctime=1460561775.057794995 sssd-1.13.4/src/sbus/sbus_codegen0000755002412700241270000007077112703456111020141 0ustar00jhrozekjhrozek00000000000000#!/usr/bin/env python # # Authors: # Stef Walter # # Copyright (C) 2014 Red Hat # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # # Some parser code from GLib # # Copyright (C) 2008-2011 Red Hat, Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General # Public License along with this library; if not, write to the # Free Software Foundation, Inc., 59 Temple Place, Suite 330, # Boston, MA 02111-1307, USA. # # Portions by: David Zeuthen # # # DBus interfaces are defined here: # # http://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format # # The introspection data format has become the standard way to represent a # DBus interface. For many examples see /usr/share/dbus-1/interfaces/ on a # typical linux machine. # # A word about annotations. These are extra flags or values that can be # assigned to anything. So far, the codegen supports this annotation: # # org.freedesktop.DBus.GLib.CSymbol # - An annotation specified in the specification that tells us what C symbol # to generate for a given interface or method. By default the codegen will # build up a symbol name from the DBus name. # from __future__ import print_function import optparse import os import re import sys import xml.parsers.expat if sys.version_info[0] > 2: import io as StringIO else: import StringIO # ----------------------------------------------------------------------------- # Objects class DBusXmlException(Exception): line = 0 file = None # Lets us print problems like a compiler would def __str__(self): message = Exception.__str__(self) if self.file and self.line: return "%s:%d: %s" % (self.file, self.line, message) elif self.file: return "%s: %s" % (self.file, message) else: return message class Base: def __init__(self, name): if not name: raise DBusXmlException('No name on element') self.name = name self.annotations = { } def validate(self): pass def c_name(self): return self.annotations.get("org.freedesktop.DBus.GLib.CSymbol", self.name) # The basic types that we support marshalling right now. These # are the ones we can pass as basic arguments to libdbus directly. # If the dbus and sssd types are identical we pass things directly. # otherwise some copying is necessary. BASIC_TYPES = { 'y': ( "DBUS_TYPE_BYTE", "uint8_t", "uint8_t" ), 'b': ( "DBUS_TYPE_BOOLEAN", "dbus_bool_t", "bool" ), 'n': ( "DBUS_TYPE_INT16", "int16_t", "int16_t" ), 'q': ( "DBUS_TYPE_UINT16", "uint16_t", "uint16_t" ), 'i': ( "DBUS_TYPE_INT32", "int32_t", "int32_t" ), 'u': ( "DBUS_TYPE_UINT32", "uint32_t", "uint32_t" ), 'x': ( "DBUS_TYPE_INT64", "int64_t", "int64_t" ), 't': ( "DBUS_TYPE_UINT64", "uint64_t", "uint64_t" ), 'd': ( "DBUS_TYPE_DOUBLE", "double", "double" ), 's': ( "DBUS_TYPE_STRING", "const char *", "const char *" ), 'o': ( "DBUS_TYPE_OBJECT_PATH", "const char *", "const char *" ), } class Typed(Base): def __init__(self, name, type): Base.__init__(self, name) self.type = type self.is_basic = False self.is_array = False self.is_dictionary = False self.dbus_constant = None self.dbus_type = None self.sssd_type = None if type[0] == 'a': type = type[1:] self.is_array = True if "{" in type: self.is_dictionary = True if type in BASIC_TYPES: (self.dbus_constant, self.dbus_type, self.sssd_type) = BASIC_TYPES[type] # If types are not identical, we can't do array (yet) if self.is_array: self.is_basic = (self.dbus_type == self.sssd_type) else: self.is_basic = True class Arg(Typed): def __init__(self, method, name, type): Typed.__init__(self, name, type) self.method = method class Method(Base): def __init__(self, iface, name): Base.__init__(self, name) self.iface = iface self.in_args = [] self.out_args = [] def validate(self): if not self.only_basic_args() and not self.use_raw_handler(): raise DBusXmlException("Method has complex arguments and requires " + "the 'org.freedesktop.sssd.RawHandler' annotation") def fq_c_name(self): return "%s_%s" % (self.iface.c_name(), self.c_name()) def use_raw_handler(self): anno = 'org.freedesktop.sssd.RawHandler' return self.annotations.get(anno, self.iface.annotations.get(anno)) == 'true' def in_signature(self): return "".join([arg.type for arg in self.in_args]) def only_basic_args(self): for arg in self.in_args + self.out_args: if not arg.is_basic: return False return True class Signal(Base): def __init__(self, iface, name): Base.__init__(self, name) self.iface = iface self.args = [] def fq_c_name(self): return "%s_%s" % (self.iface.c_name(), self.c_name()) class Property(Typed): def __init__(self, iface, name, type, access): Typed.__init__(self, name, type) self.iface = iface self.readable = False self.writable = False if access == 'readwrite': self.readable = True self.writable = True elif access == 'read': self.readable = True elif access == 'write': self.writable = True else: raise DBusXmlException('Invalid access type %s'%self.access) def fq_c_name(self): return "%s_%s" % (self.iface.c_name(), self.c_name()) def get_invoker_name(self): type = self.type type = type.replace("{", "DO") type = type.replace("}", "DE") return type def get_invoker_signature(self, name): sig = "void (*%s)(struct sbus_request *, void *data, " % (name) if self.is_dictionary: sig += "hash_table_t **" elif self.is_array: sig += "%s**, int *" % (self.sssd_type) else: sig += "%s*" % (self.sssd_type) sig += ")" return sig def getter_name(self): return "get_%s" % self.c_name() def getter_invoker_name(self): return "sbus_invoke_get_%s" % self.get_invoker_name() def getter_signature(self): return self.get_invoker_signature(self.getter_name()) class Interface(Base): def __init__(self, name): Base.__init__(self, name) self.methods = [] self.signals = [] self.properties = [] def c_name(self): return self.annotations.get("org.freedesktop.DBus.GLib.CSymbol", self.name.replace(".", "_")) # ----------------------------------------------------------------------------- # Code Generation def out(format, *args, **kwargs): str = format % args sys.stdout.write(str) # NOTE: Would like to use the following syntax for this function # but need to wait until python3 until it is supported: # def out(format, *args, new_line=True) if kwargs.pop("new_line", True): sys.stdout.write("\n") assert not kwargs, "unknown keyword argument(s): %s" % str(kwargs) def method_arg_types(args, with_names=False): str = "" for arg in args: str += ", " str += arg.sssd_type if with_names: if str[-1] != '*': str += " " str += "arg_" str += arg.c_name() if arg.is_array: str += "[], int" if with_names: str += " len_" str += arg.c_name() return str def method_function_pointer(meth, name, with_names=False): if meth.use_raw_handler(): return "sbus_msg_handler_fn " + name else: return "int (*%s)(struct sbus_request *%s, void *%s%s)" % \ (name, with_names and "req" or "", with_names and "data" or "", method_arg_types(meth.in_args, with_names)) def property_handlers(prop): return prop.getter_signature() def forward_method_invoker(signature, args): out("") out("/* invokes a handler with a '%s' DBus signature */", signature) out("static int invoke_%s_method(struct sbus_request *dbus_req, void *function_ptr);", signature) def source_method_invoker(signature, args): out("") out("/* invokes a handler with a '%s' DBus signature */", signature) out("static int invoke_%s_method(struct sbus_request *dbus_req, void *function_ptr)", signature) out("{") for i in range(0, len(args)): arg = args[i] if arg.is_array: out(" %s *arg_%d;", arg.dbus_type, i) out(" int len_%d;", i) else: out(" %s arg_%d;", arg.dbus_type, i) out(" int (*handler)(struct sbus_request *, void *%s) = function_ptr;", method_arg_types(args)) out("") out(" if (!sbus_request_parse_or_finish(dbus_req,") for i in range(0, len(args)): arg = args[i] if arg.is_array: out(" DBUS_TYPE_ARRAY, %s, &arg_%d, &len_%d,", arg.dbus_constant, i, i) else: out(" %s, &arg_%d,", arg.dbus_constant, i) out(" DBUS_TYPE_INVALID)) {") out(" return EOK; /* request handled */") out(" }") out("") out(" return (handler)(dbus_req, dbus_req->intf->handler_data", new_line=False) for i in range(0, len(args)): arg = args[i] out(",\n arg_%d", i, new_line=False) if arg.is_array: out(",\n len_%d", i, new_line=False) out(");") out("}") def source_prop_types(prop, type_prefix=False): prefix = "%s_" % prop.type if type_prefix else "" if prop.is_array: out(" %s *%sprop_val;", prop.sssd_type, prefix) out(" int %sprop_len;", prefix) out(" %s *%sout_val;", prop.dbus_type, prefix) else: out(" %s %sprop_val;", prop.sssd_type, prefix) out(" %s %sout_val;", prop.dbus_type, prefix) def source_prop_handler(prop, type_prefix=False): prefix = "%s_" % prop.type if type_prefix else "" out(" %s", prop.getter_signature("%shandler" % prefix), new_line=False) out(";") def forward_method_invokers(ifaces): invokers = { } for iface in ifaces: for meth in iface.methods: if meth.use_raw_handler() or not meth.in_args: continue signature = meth.in_signature() if signature in invokers: continue forward_method_invoker(signature, meth.in_args) invokers[signature] = meth return invokers def source_method_invokers(invokers): for (signature, meth) in invokers.items(): source_method_invoker(signature, meth.in_args) def source_finisher(meth): out("") out("int %s_finish(struct sbus_request *req%s)", meth.fq_c_name(), method_arg_types(meth.out_args, with_names=True)) out("{") for arg in meth.out_args: if arg.dbus_type != arg.sssd_type: out(" %s cast_%s = arg_%s;", arg.dbus_type, arg.c_name(), arg.c_name()) out(" return sbus_request_return_and_finish(req,") for arg in meth.out_args: out(" ", new_line=False) if arg.is_array: out("DBUS_TYPE_ARRAY, %s, &arg_%s, len_%s,", arg.dbus_constant, arg.c_name(), arg.c_name()) elif arg.dbus_type != arg.sssd_type: out("%s, &cast_%s,", arg.dbus_constant, arg.c_name()) else: out("%s, &arg_%s,", arg.dbus_constant, arg.c_name()) out(" DBUS_TYPE_INVALID);") out("}") def header_reply(meth): for arg in meth.out_args: if arg.is_array: out(" %s *%s", arg.dbus_type, arg.c_name()) out(" int %s__len", arg.c_name()) else: out(" %s %s;", arg.dbus_type, arg.c_name()) types = [arg.sssd_type for arg in meth.in_args] def source_args(parent, args, suffix): out("") out("/* arguments for %s.%s */", parent.iface.name, parent.name) out("const struct sbus_arg_meta %s%s[] = {", parent.fq_c_name(), suffix) for arg in args: out(" { \"%s\", \"%s\" },", arg.name, arg.type) out(" { NULL, }") out("};") def source_methods(iface, methods): for meth in methods: if meth.in_args: source_args(meth, meth.in_args, "__in") if meth.out_args: source_args(meth, meth.out_args, "__out") if not meth.use_raw_handler(): source_finisher(meth) out("") out("/* methods for %s */", iface.name) out("const struct sbus_method_meta %s__methods[] = {", iface.c_name()) for meth in methods: out(" {") out(" \"%s\", /* name */", meth.name) if meth.in_args: out(" %s__in,", meth.fq_c_name()) else: out(" NULL, /* no in_args */") if meth.out_args: out(" %s__out,", meth.fq_c_name()) else: out(" NULL, /* no out_args */") out(" offsetof(struct %s, %s),", iface.c_name(), meth.c_name()) if meth.use_raw_handler() or not meth.in_args: out(" NULL, /* no invoker */") else: out(" invoke_%s_method,", meth.in_signature()) out(" },") out(" { NULL, }") out("};") def source_signals(iface, signals): for sig in iface.signals: if sig.args: source_args(sig, sig.args, "__args") out("") out("/* signals for %s */", iface.name) out("const struct sbus_signal_meta %s__signals[] = {", iface.c_name()) for sig in signals: out(" {") out(" \"%s\", /* name */", sig.name) if sig.args: out(" %s__args", sig.fq_c_name()) else: out(" NULL, /* no args */") out(" },") out(" { NULL, }") out("};") def source_properties(iface, properties): out("") out("/* property info for %s */", iface.name) out("const struct sbus_property_meta %s__properties[] = {", iface.c_name()) for prop in properties: out(" {") out(" \"%s\", /* name */", prop.name) out(" \"%s\", /* type */", prop.type) if prop.readable and prop.writable: out(" SBUS_PROPERTY_READABLE | SBUS_PROPERTY_WRITABLE,") elif prop.readable: out(" SBUS_PROPERTY_READABLE,") elif prop.writable: out(" SBUS_PROPERTY_WRITABLE,") else: assert False, "should not be reached" if prop.readable: out(" offsetof(struct %s, %s),", iface.c_name(), prop.getter_name()) out(" %s,", prop.getter_invoker_name()) else: out(" 0, /* not readable */") out(" NULL, /* no invoker */") out(" 0, /* not writable */") out(" NULL, /* no invoker */") out(" },") out(" { NULL, }") out("};") def header_interface(iface): out("") out("/* interface info for %s */", iface.name) out("extern const struct sbus_interface_meta %s_meta;", iface.c_name()) def source_interface(iface): out("") out("/* interface info for %s */", iface.name) out("const struct sbus_interface_meta %s_meta = {", iface.c_name()) out(" \"%s\", /* name */", iface.name) if iface.methods: out(" %s__methods,", iface.c_name()) else: out(" NULL, /* no methods */") if iface.signals: out(" %s__signals,", iface.c_name()) else: out(" NULL, /* no signals */") if iface.properties: out(" %s__properties,", iface.c_name()) else: out(" NULL, /* no properties */") out(" sbus_invoke_get_all, /* GetAll invoker */") out("};") def generate_source(ifaces, filename, include_header=None): basename = os.path.basename(filename) out("/* The following definitions are auto-generated from %s */", basename) out("") out("#include \"util/util.h\"") out("#include \"sbus/sssd_dbus.h\"") out("#include \"sbus/sssd_dbus_meta.h\"") out("#include \"sbus/sssd_dbus_invokers.h\"") if include_header: out("#include \"%s\"", os.path.basename(include_header)) meth_invokers = forward_method_invokers(ifaces) for iface in ifaces: # The methods if iface.methods: source_methods(iface, iface.methods) # The signals array if iface.signals: source_signals(iface, iface.signals) # The properties array if iface.properties: source_properties(iface, iface.properties) # The sbus_interface structure source_interface(iface) source_method_invokers(meth_invokers) def header_finisher(iface, meth): if meth.use_raw_handler(): return out("") out("/* finish function for %s */", meth.name) out("int %s_finish(struct sbus_request *req%s);", meth.fq_c_name(), method_arg_types(meth.out_args, with_names=True)) def header_vtable(iface, methods): out("") out("/* vtable for %s */", iface.name) out("struct %s {", iface.c_name()) out(" struct sbus_vtable vtable; /* derive from sbus_vtable */") # All methods for meth in iface.methods: out(" %s;", method_function_pointer(meth, meth.c_name(), with_names=True)) for prop in iface.properties: out(" %s;", property_handlers(prop)) out("};") def header_constants(iface): out("") out("/* constants for %s */", iface.name) out("#define %s \"%s\"", iface.c_name().upper(), iface.name) for meth in iface.methods: out("#define %s \"%s\"", meth.fq_c_name().upper(), meth.name) for sig in iface.signals: out("#define %s \"%s\"", sig.fq_c_name().upper(), sig.name) for prop in iface.properties: out("#define %s \"%s\"", prop.fq_c_name().upper(), prop.name) def generate_header(ifaces, filename): basename = os.path.basename(filename) guard = "__%s__" % re.sub(r'([^_A-Z0-9])', "_", basename.upper()) out("/* The following declarations are auto-generated from %s */", basename) out("") out("#ifndef %s", guard) out("#define %s", guard) out("") out("#include \"sbus/sssd_dbus.h\"") out("") out("/* ------------------------------------------------------------------------") out(" * DBus Constants") out(" *") out(" * Various constants of interface and method names mostly for use by clients") out(" */") for iface in ifaces: header_constants(iface) out("") out("/* ------------------------------------------------------------------------") out(" * DBus handlers") out(" *") out(" * These structures are filled in by implementors of the different") out(" * dbus interfaces to handle method calls.") out(" *") out(" * Handler functions of type sbus_msg_handler_fn accept raw messages,") out(" * other handlers are typed appropriately. If a handler that is") out(" * set to NULL is invoked it will result in a") out(" * org.freedesktop.DBus.Error.NotSupported error for the caller.") out(" *") out(" * Handlers have a matching xxx_finish() function (unless the method has") out(" * accepts raw messages). These finish functions the") out(" * sbus_request_return_and_finish() with the appropriate arguments to") out(" * construct a valid reply. Once a finish function has been called, the") out(" * @dbus_req it was called with is freed and no longer valid.") out(" */") for iface in ifaces: if iface.methods or iface.properties: header_vtable(iface, iface.methods) for meth in iface.methods: header_finisher(iface, meth) out("") out("/* ------------------------------------------------------------------------") out(" * DBus Interface Metadata") out(" *") out(" * These structure definitions are filled in with the information about") out(" * the interfaces, methods, properties and so on.") out(" *") out(" * The actual definitions are found in the accompanying C file next") out(" * to this header.") out(" */") for iface in ifaces: header_interface(iface) out("") out("#endif /* %s */", guard) # ----------------------------------------------------------------------------- # XML Interface Parsing STATE_TOP = 'top' STATE_NODE = 'node' STATE_INTERFACE = 'interface' STATE_METHOD = 'method' STATE_SIGNAL = 'signal' STATE_PROPERTY = 'property' STATE_ARG = 'arg' STATE_ANNOTATION = 'annotation' STATE_IGNORED = 'ignored' def expect_attr(attrs, name): if name not in attrs: raise DBusXmlException("Missing attribute '%s'" % name) if attrs[name] == "": raise DBusXmlException("Empty attribute '%s'" % name) return attrs[name] class DBusXMLParser: def __init__(self, filename): parser = xml.parsers.expat.ParserCreate() parser.CommentHandler = self.handle_comment parser.CharacterDataHandler = self.handle_char_data parser.StartElementHandler = self.handle_start_element parser.EndElementHandler = self.handle_end_element self.parsed_interfaces = [] self.cur_object = None self.state = STATE_TOP self.state_stack = [] self.cur_object = None self.cur_object_stack = [] self.arg_count = 0 try: with open(filename, "rb") as f: parser.ParseFile(f) except DBusXmlException as ex: ex.line = parser.CurrentLineNumber ex.file = filename raise except xml.parsers.expat.ExpatError as ex: exc = DBusXmlException(str(ex)) exc.line = ex.lineno exc.file = filename raise exc def handle_comment(self, data): pass def handle_char_data(self, data): pass def handle_start_element(self, name, attrs): old_state = self.state old_cur_object = self.cur_object if self.state == STATE_IGNORED: self.state = STATE_IGNORED elif self.cur_object and name == STATE_ANNOTATION: val = attrs.get('value', '') self.cur_object.annotations[expect_attr(attrs, 'name')] = val self.state = STATE_IGNORED elif self.state == STATE_TOP: if name == STATE_NODE: self.state = STATE_NODE else: self.state = STATE_IGNORED elif self.state == STATE_NODE: if name == STATE_INTERFACE: self.state = STATE_INTERFACE iface = Interface(expect_attr(attrs, 'name')) self.cur_object = iface self.parsed_interfaces.append(iface) else: self.state = STATE_IGNORED elif self.state == STATE_INTERFACE: if name == STATE_METHOD: self.state = STATE_METHOD method = Method(self.cur_object, expect_attr(attrs, 'name')) self.cur_object.methods.append(method) self.cur_object = method self.arg_count = 0 elif name == STATE_SIGNAL: self.state = STATE_SIGNAL signal = Signal(self.cur_object, expect_attr(attrs, 'name')) self.cur_object.signals.append(signal) self.cur_object = signal self.arg_count = 0 elif name == STATE_PROPERTY: self.state = STATE_PROPERTY prop = Property(self.cur_object, expect_attr(attrs, 'name'), expect_attr(attrs, 'type'), expect_attr(attrs, 'access')) self.cur_object.properties.append(prop) self.cur_object = prop else: self.state = STATE_IGNORED elif self.state == STATE_METHOD: if name == STATE_ARG: self.state = STATE_ARG arg = Arg(self.cur_object, expect_attr(attrs, 'name'), expect_attr(attrs, 'type')) direction = attrs.get('direction', 'in') if direction == 'in': self.cur_object.in_args.append(arg) elif direction == 'out': self.cur_object.out_args.append(arg) else: raise DBusXmlException('Invalid direction "%s"' % direction) self.cur_object = arg else: self.state = STATE_IGNORED elif self.state == STATE_SIGNAL: if name == STATE_ARG: self.state = STATE_ARG arg = Arg(self.cur_object, expect_attr(attrs, 'name'), expect_attr(attrs, 'type')) self.cur_object.args.append(arg) self.cur_object = arg else: self.state = STATE_IGNORED elif self.state == STATE_PROPERTY: self.state = STATE_IGNORED elif self.state == STATE_ARG: self.state = STATE_IGNORED else: assert False, 'Unhandled state "%s" while entering element with name "%s"' % (self.state, name) self.state_stack.append(old_state) self.cur_object_stack.append(old_cur_object) def handle_end_element(self, name): if self.cur_object: self.cur_object.validate() self.state = self.state_stack.pop() self.cur_object = self.cur_object_stack.pop() def parse_options(): parser = optparse.OptionParser("usage: %prog [options] introspect.xml ...") parser.set_description("sbus_codegen generates sbus interface structures \ from standard XML Introspect data.") parser.add_option("--mode", dest="mode", default="header", help="'header' or 'source' (default: header)", metavar="MODE") parser.add_option("--output", dest="output", default=None, help="Set output file name (default: stdout)", metavar="FILE") parser.add_option("--include", dest="include", default=None, help="name of a header to #include", metavar="HEADER") (options, args) = parser.parse_args() if not args: print("sbus_codegen: no input file specified", file=sys.stderr) sys.exit(2) if options.mode not in ["header", "source"]: print("sbus_codegen: specify --mode=header or --mode=source", file=sys.stderr) return options, args def main(): options, args = parse_options() if options.output: sys.stdout = buf = StringIO.StringIO() for filename in args: parser = DBusXMLParser(filename) if options.mode == "header": generate_header(parser.parsed_interfaces, filename) elif options.mode == "source": generate_source(parser.parsed_interfaces, filename, options.include) else: assert False, "should not be reached" # Write output at end to be nice to 'make' if options.output: output = open(options.output, "w") output.write(buf.getvalue()) output.close() if __name__ == "__main__": try: main() except DBusXmlException as ex: print(str(ex), file=sys.stderr) sys.exit(1) sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus.h0000644000000000000000000000007312703456111016231 xustar0030 atime=1460561751.652715634 29 ctime=1460561774.49579309 sssd-1.13.4/src/sbus/sssd_dbus.h0000644002412700241270000003536412703456111017714 0ustar00jhrozekjhrozek00000000000000/* SSSD SSSD - D-BUS interface Copyright (C) Stephen Gallagher 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SSSD_DBUS_H_ #define _SSSD_DBUS_H_ struct sbus_connection; struct sbus_interface; struct sbus_request; #include #include #include "util/util.h" /* Older platforms (such as RHEL-6) might not have these error constants * defined */ #ifndef DBUS_ERROR_UNKNOWN_INTERFACE /** Interface you invoked a method on isn't known by the object. */ #define DBUS_ERROR_UNKNOWN_INTERFACE \ "org.freedesktop.DBus.Error.UnknownInterface" #endif /* DBUS_ERROR_UNKNOWN_INTERFACE */ #ifndef DBUS_ERROR_UNKNOWN_PROPERTY /** Property you tried to access isn't known by the object. */ #define DBUS_ERROR_UNKNOWN_PROPERTY \ "org.freedesktop.DBus.Error.UnknownProperty" #endif /* DBUS_ERROR_UNKNOWN_PROPERTY */ #ifndef DBUS_ERROR_PROPERTY_READ_ONLY /** Property you tried to set is read-only. */ #define DBUS_ERROR_PROPERTY_READ_ONLY \ "org.freedesktop.DBus.Error.PropertyReadOnly" #endif /* DBUS_ERROR_PROPERTY_READ_ONLY */ #ifndef DBUS_ERROR_INIT #define DBUS_ERROR_INIT { NULL, NULL, TRUE, 0, 0, 0, 0, NULL } #endif /* DBUS_ERROR_INIT */ /** * Note: internal functions do not rely on the value of this constant to * simplify implementation. If this connstant change, some functions in * sssd_dbus_interface.c needs to be amended. */ #define SBUS_SUBTREE_SUFFIX "/*" typedef int (*sbus_msg_handler_fn)(struct sbus_request *dbus_req, void *handler_data); /* * sbus_conn_destructor_fn * Function to be called when a connection is finalized */ typedef int (*sbus_conn_destructor_fn)(void *); typedef void (*sbus_conn_reconn_callback_fn)(struct sbus_connection *, int, void *); /* * sbus_server_conn_init_fn * Set up function for connection-specific activities * This function should define the sbus_conn_destructor_fn * for this connection at a minimum */ typedef int (*sbus_server_conn_init_fn)(struct sbus_connection *, void *); typedef const char ** (* sbus_nodes_fn)(TALLOC_CTX *mem_ctx, const char *path, void *data); enum { SBUS_CONN_TYPE_PRIVATE = 1, SBUS_CONN_TYPE_SHARED, SBUS_CONN_TYPE_SYSBUS }; enum { SBUS_RECONNECT_SUCCESS = 1, SBUS_RECONNECT_EXCEEDED_RETRIES, SBUS_RECONNECT_ERROR }; /* * This represents vtable of interface handlers for methods and * properties and so on. The actual vtable structs derive from this struct * (ie: have this struct as their first member). * * The offsets for matching vtable function pointers are in sbus_method_meta * These are used to dynamically dispatch the method invocations. */ struct sbus_vtable { const struct sbus_interface_meta *meta; int flags; /* unused for now */ /* derived structs place function pointers here. */ }; /* Special interface and method for D-BUS introspection */ #define DBUS_INTROSPECT_INTERFACE "org.freedesktop.DBus.Introspectable" #define DBUS_INTROSPECT_METHOD "Introspect" /* Special interface and method for D-BUS properties */ #define DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" struct sbus_interface { const char *path; struct sbus_vtable *vtable; void *handler_data; }; /* Server Functions */ int sbus_new_server(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *address, uid_t uid, gid_t gid, bool use_symlink, struct sbus_connection **server, sbus_server_conn_init_fn init_fn, void *init_pvt_data); /* Connection Functions */ /* sbus_new_connection * Use this function when connecting a new process to * the standard SSSD interface. * This will connect to the address specified and then * call sbus_add_connection to integrate with the main * loop. */ int sbus_new_connection(TALLOC_CTX *ctx, struct tevent_context *ev, const char *address, struct sbus_connection **conn); /* sbus_add_connection * Integrates a D-BUS connection with the TEvent main * loop. Use this function when you already have a * DBusConnection object (for example from dbus_bus_get) * Connection type can be either: * SBUS_CONN_TYPE_PRIVATE: Used only from within a D-BUS * server such as the Monitor in the * new_connection_callback * SBUS_CONN_TYPE_SHARED: Used for all D-BUS client * connections, including those retrieved from * dbus_bus_get */ int sbus_init_connection(TALLOC_CTX *ctx, struct tevent_context *ev, DBusConnection *dbus_conn, int connection_type, struct sbus_connection **_conn); DBusConnection *sbus_get_connection(struct sbus_connection *conn); void sbus_disconnect(struct sbus_connection *conn); /* * Register a new interface to be available at given object path. * * The interface will be exported at @object_path. The method handlers are * represented by @iface_vtable. @pvt contains additional caller specific data * which is made available to handlers. */ int sbus_conn_register_iface(struct sbus_connection *conn, struct sbus_vtable *iface_vtable, const char *object_path, void *handler_data); void sbus_conn_register_nodes(struct sbus_connection *conn, const char *path, sbus_nodes_fn nodes_fn, void *data); errno_t sbus_conn_reregister_paths(struct sbus_connection *conn); char * sbus_opath_escape_part(TALLOC_CTX *mem_ctx, const char *object_path_part); char * sbus_opath_unescape_part(TALLOC_CTX *mem_ctx, const char *object_path_part); char * _sbus_opath_compose(TALLOC_CTX *mem_ctx, const char *base, const char *part, ...); #define sbus_opath_compose(mem_ctx, base, ...) \ _sbus_opath_compose(mem_ctx, base, ##__VA_ARGS__, NULL) errno_t sbus_opath_decompose(TALLOC_CTX *mem_ctx, const char *object_path, const char *prefix, char ***_components, size_t *_len); errno_t sbus_opath_decompose_exact(TALLOC_CTX *mem_ctx, const char *object_path, const char *prefix, size_t expected, char ***_components); const char * sbus_opath_strip_prefix(const char *object_path, const char *prefix); char * sbus_opath_get_object_name(TALLOC_CTX *mem_ctx, const char *object_path, const char *base_path); bool sbus_conn_disconnecting(struct sbus_connection *conn); /* max_retries < 0: retry forever * max_retries = 0: never retry (why are you calling this function?) * max_retries > 0: obvious */ void sbus_reconnect_init(struct sbus_connection *conn, int max_retries, sbus_conn_reconn_callback_fn callback, void *pvt); /* * Send a message across the SBUS * If requested, the DBusPendingCall object will * be returned to the caller. * * This function will return EAGAIN in the event * that the connection is not open for * communication. */ int sbus_conn_send(struct sbus_connection *conn, DBusMessage *msg, int timeout_ms, DBusPendingCallNotifyFunction reply_handler, void *pvt, DBusPendingCall **pending); void sbus_conn_send_reply(struct sbus_connection *conn, DBusMessage *reply); /* Set up D-BUS access control. If there is a SSSD user, we must allow * him to connect. root is always allowed */ void sbus_allow_uid(struct sbus_connection *conn, uid_t *uid); /* * This structure is passed to all dbus method and property * handlers. It is a talloc context which will be valid until * the request is completed with either the sbus_request_complete() * or sbus_request_fail() functions. */ struct sbus_request { int64_t client; struct sbus_connection *conn; DBusMessage *message; struct sbus_interface *intf; const struct sbus_method_meta *method; const char *path; }; /* * Complete a DBus request, and free the @dbus_req context. The @dbus_req * and associated talloc context are no longer valid after this function * returns. * * If @reply is non-NULL then the reply is sent to the caller. Not sending * a reply when the caller is expecting one is fairly rude behavior. * * The return value is useful for logging, but not much else. In particular * even if this function return !EOK, @dbus_req is still unusable after this * function returns. */ int sbus_request_finish(struct sbus_request *dbus_req, DBusMessage *reply); /* * Return a reply for a DBus method call request. The variable * arguments are (unfortunately) formatted exactly the same as those of the * dbus_message_append_args() function. Documented here: * * http://dbus.freedesktop.org/doc/api/html/group__DBusMessage.html * * Important: don't pass int or bool or such types as * values to this function. That's not portable. Use actual dbus types. * You must also pass pointers as the values: * * dbus_bool_t val1 = TRUE; * dbus_int32_t val2 = 5; * ret = sbus_request_finish(dbus_req, * DBUS_TYPE_BOOLEAN, &val1, * DBUS_TYPE_INT32, &val2, * DBUS_TYPE_INVALID); * * To pass arrays to this function, use the following syntax. Never * pass actual C arrays with [] syntax to this function. The C standard is * rather vague with C arrays and varargs, and it just plain doesn't work. * * const char *array[] = { "one", "two", "three" }; * int count = 3; // yes, a plain int * const char **ptr = array; * ret = sbus_request_finish(dbus_req, * DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &ptr, 3, * DBUS_TYPE_INVALID); * * The @dbus_req and associated talloc context are no longer valid after this * function returns, even if this function returns an error code. */ int sbus_request_return_and_finish(struct sbus_request *dbus_req, int first_arg_type, ...); /* * Return an error for a DBus method call request. The @error is a normal * DBusError. * * The @dbus_req and associated talloc context are no longer valid after this * function returns, even if this function returns an error code. */ int sbus_request_fail_and_finish(struct sbus_request *dbus_req, const DBusError *error); /* * Construct a new DBusError instance which can be consumed by functions such * as @sbus_request_fail_and_finish(). * * The @error is a string constant representing a DBus error as documented at * http://dbus.freedesktop.org/doc/api/html/group__DBusProtocol.html. * The parameter @err_msg is a human-readable error representation (or * NULL for none). The returned DBusError is a talloc context and the err_msg * is duplicated using the returned DBusError instance as a talloc parent. */ DBusError *sbus_error_new(TALLOC_CTX *mem_ctx, const char *dbus_err_name, const char *fmt, ...) SSS_ATTRIBUTE_PRINTF(3,4); /* * Parse a DBus method call request. * * If parsing the method call message does not succeed, then an error is * sent to the DBus caller and the request is finished. If this function * returns false then @request is no longer valid. * * This also means if this method returns false within a handler, you should * return EOK from the handler. The message has been handled, appropriate * logs have been written, and everything should just move on. * * If the method call does not match the expected arguments, then a * org.freedesktop.DBus.Error.InvalidArgs is returned to the caller as * expected. * * The variable arguments are (unfortunately) formatted exactly the same * as those of the dbus_message_get_args() function. Documented here: * * http://dbus.freedesktop.org/doc/api/html/group__DBusMessage.html * * Exception: You don't need to free string arrays returned by this * function. They are automatically talloc parented to the request memory * context and can be used until the request has been finished. * * Important: don't pass int or bool or such types as values to this * function. That's not portable. Use actual dbus types. You must also pass * pointers as the values: * * dbus_bool_t val1; * dbus_int32_t val2; * ret = sbus_request_parse_or_finish(request, * DBUS_TYPE_BOOLEAN, &val1, * DBUS_TYPE_INT32, &val2, * DBUS_TYPE_INVALID); * * To pass arrays to this function, use the following syntax. Never * pass actual C arrays with [] syntax to this function. The C standard is * rather vague with C arrays and varargs, and it just plain doesn't work. * * int count; // yes, a plain int * const char **array; * ret = sbus_request_parse_or_finish(request, * DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &array, &count, * DBUS_TYPE_INVALID); */ bool sbus_request_parse_or_finish(struct sbus_request *request, int first_arg_type, ...); struct sbus_incoming_signal { struct sbus_connection *conn; DBusMessage *message; int64_t client; const char *interface; const char *signal; const char *path; }; typedef void (*sbus_incoming_signal_fn)(struct sbus_incoming_signal *sbus_signal, void *handler_data); errno_t sbus_signal_listen(struct sbus_connection *conn, const char *iface, const char *signal, sbus_incoming_signal_fn handler_fn, void *handler_data); #endif /* _SSSD_DBUS_H_*/ sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_interface.c0000644000000000000000000000007312703456111020244 xustar0030 atime=1460561751.652715634 29 ctime=1460561774.84979429 sssd-1.13.4/src/sbus/sssd_dbus_interface.c0000644002412700241270000007031512703456111021722 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_meta.h" #include "sbus/sssd_dbus_private.h" static struct sbus_interface * sbus_iface_list_lookup(struct sbus_interface_list *list, const char *iface) { struct sbus_interface_list *item; DLIST_FOR_EACH(item, list) { if (strcmp(item->interface->vtable->meta->name, iface) == 0) { return item->interface; } } return NULL; } static errno_t sbus_iface_list_copy(TALLOC_CTX *mem_ctx, struct sbus_interface_list *list, struct sbus_interface_list **_copy) { TALLOC_CTX *list_ctx; struct sbus_interface_list *new_list = NULL; struct sbus_interface_list *new_item; struct sbus_interface_list *item; errno_t ret; if (list == NULL) { *_copy = NULL; return EOK; } list_ctx = talloc_new(mem_ctx); if (list_ctx == NULL) { return ENOMEM; } DLIST_FOR_EACH(item, list) { if (sbus_iface_list_lookup(new_list, item->interface->vtable->meta->name) != NULL) { /* already in list */ continue; } new_item = talloc_zero(list_ctx, struct sbus_interface_list); if (new_item == NULL) { ret = ENOMEM; goto done; } new_item->interface = item->interface; DLIST_ADD(new_list, new_item); } *_copy = new_list; ret = EOK; done: if (ret != EOK) { talloc_free(list_ctx); } return ret; } /** * Object paths that represent all objects under the path: * /org/object/path/~* (without tilda) */ static bool sbus_opath_is_subtree(const char *path) { size_t len; len = strlen(path); if (len < 2) { return false; } return path[len - 2] == '/' && path[len - 1] == '*'; } /** * If the path represents a subtree object path, this function will * remove /~* from the end. */ static char *sbus_opath_get_base_path(TALLOC_CTX *mem_ctx, const char *object_path) { char *tree_path; size_t len; tree_path = talloc_strdup(mem_ctx, object_path); if (tree_path == NULL) { return NULL; } if (!sbus_opath_is_subtree(tree_path)) { return tree_path; } /* replace / only if it is not a root path (only slash) */ len = strlen(tree_path); tree_path[len - 1] = '\0'; tree_path[len - 2] = (len - 2 != 0) ? '\0' : '/'; return tree_path; } static char *sbus_opath_parent_subtree(TALLOC_CTX *mem_ctx, const char *path) { char *subtree; char *slash; /* first remove /~* from the end, stop when we have reached the root i.e. * subtree == "/" */ subtree = sbus_opath_get_base_path(mem_ctx, path); if (subtree == NULL || subtree[1] == '\0') { return NULL; } /* Find the first separator and replace the part with asterisk. */ slash = strrchr(subtree, '/'); if (slash == NULL) { /* we cannot continue up */ talloc_free(subtree); return NULL; } if (*(slash + 1) == '\0') { /* this object path is invalid since it cannot end with slash */ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid object path '%s'?\n", path); talloc_free(subtree); return NULL; } /* because object path cannot end with / there is enough space for * asterisk and terminating zero */ *(slash + 1) = '*'; *(slash + 2) = '\0'; return subtree; } /** * The following path related functions are based on similar code in * storaged, just tailored to use talloc instead of glib */ char * sbus_opath_escape_part(TALLOC_CTX *mem_ctx, const char *object_path_part) { size_t n; char *safe_path = NULL; TALLOC_CTX *tmp_ctx = NULL; /* The path must be valid */ if (object_path_part == NULL) { return NULL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NULL; } safe_path = talloc_strdup(tmp_ctx, ""); if (safe_path == NULL) { goto done; } /* Special case for an empty string */ if (strcmp(object_path_part, "") == 0) { /* the for loop would just fall through */ safe_path = talloc_asprintf_append_buffer(safe_path, "_"); if (safe_path == NULL) { goto done; } } for (n = 0; object_path_part[n]; n++) { int c = object_path_part[n]; /* D-Bus spec says: * * * * Each element must only contain the ASCII characters * "[A-Z][a-z][0-9]_" * */ if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) { safe_path = talloc_asprintf_append_buffer(safe_path, "%c", c); if (safe_path == NULL) { goto done; } } else { safe_path = talloc_asprintf_append_buffer(safe_path, "_%02x", c); if (safe_path == NULL) { goto done; } } } safe_path = talloc_steal(mem_ctx, safe_path); done: talloc_free(tmp_ctx); return safe_path; } static inline int unhexchar(char c) { if (c >= '0' && c <= '9') { return c - '0'; } if (c >= 'a' && c <= 'f') { return c - 'a' + 10; } if (c >= 'A' && c <= 'F') { return c - 'A' + 10; } return -1; } char * sbus_opath_unescape_part(TALLOC_CTX *mem_ctx, const char *object_path_part) { char *safe_path; const char *p; int a, b, c; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NULL; } safe_path = talloc_strdup(tmp_ctx, ""); if (safe_path == NULL) { goto done; } /* Special case for the empty string */ if (strcmp(object_path_part, "_") == 0) { safe_path = talloc_steal(mem_ctx, safe_path); goto done; } for (p = object_path_part; *p; p++) { if (*p == '_') { /* There must be at least two more chars after underscore */ if (p[1] == '\0' || p[2] == '\0') { safe_path = NULL; goto done; } if ((a = unhexchar(p[1])) < 0 || (b = unhexchar(p[2])) < 0) { /* Invalid escape code, let's take it literal then */ c = '_'; } else { c = ((a << 4) | b); p += 2; } } else { c = *p; } safe_path = talloc_asprintf_append_buffer(safe_path, "%c", c); if (safe_path == NULL) { goto done; } } safe_path = talloc_steal(mem_ctx, safe_path); done: talloc_free(tmp_ctx); return safe_path; } char * _sbus_opath_compose(TALLOC_CTX *mem_ctx, const char *base, const char *part, ...) { char *safe_part; char *path = NULL; va_list va; if (base == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Wrong object path base!\n"); return NULL; } path = talloc_strdup(mem_ctx, base); if (path == NULL) return NULL; va_start(va, part); while (part != NULL) { safe_part = sbus_opath_escape_part(mem_ctx, part); if (safe_part == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Could not add [%s] to objpath\n", part); goto fail; } path = talloc_asprintf_append(path, "/%s", safe_part); talloc_free(safe_part); if (path == NULL) { goto fail; } part = va_arg(va, const char *); } va_end(va); return path; fail: va_end(va); talloc_free(path); return NULL; } errno_t sbus_opath_decompose(TALLOC_CTX *mem_ctx, const char *object_path, const char *prefix, char ***_components, size_t *_len) { TALLOC_CTX *tmp_ctx; const char *path; char **decomposed; char **unescaped; errno_t ret; int len; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } /* Strip prefix from the path. */ if (prefix != NULL) { path = sbus_opath_strip_prefix(object_path, prefix); if (path == NULL) { ret = ERR_SBUS_INVALID_PATH; goto done; } } else { path = object_path; } /* Split the string using / as delimiter. */ split_on_separator(tmp_ctx, path, '/', true, true, &decomposed, &len); /* Unescape parts. */ unescaped = talloc_zero_array(tmp_ctx, char *, len + 1); if (unescaped == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < len; i++) { unescaped[i] = sbus_opath_unescape_part(unescaped, decomposed[i]); if (unescaped[i] == NULL) { ret = ENOMEM; goto done; } } if (_components != NULL) { *_components = talloc_steal(mem_ctx, unescaped); } if (_len != NULL) { *_len = len; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sbus_opath_decompose_exact(TALLOC_CTX *mem_ctx, const char *object_path, const char *prefix, size_t expected, char ***_components) { char **components; size_t len; errno_t ret; ret = sbus_opath_decompose(mem_ctx, object_path, prefix, &components, &len); if (ret != EOK) { return ret; } if (len != expected) { talloc_free(components); return ERR_SBUS_INVALID_PATH; } if (_components != NULL) { *_components = components; } return EOK; } const char * sbus_opath_strip_prefix(const char *object_path, const char *prefix) { if (strncmp(object_path, prefix, strlen(prefix)) == 0) { return object_path + strlen(prefix); } return NULL; } char * sbus_opath_get_object_name(TALLOC_CTX *mem_ctx, const char *object_path, const char *base_path) { const char *name; name = sbus_opath_strip_prefix(object_path, base_path); if (name == NULL || name[0] == '\0') { return NULL; } /* if base_path did not end with / */ if (name[0] == '/') { name = name + 1; } return sbus_opath_unescape_part(mem_ctx, name); } static void sbus_opath_hash_delete_cb(hash_entry_t *item, hash_destroy_enum deltype, void *pvt) { struct sbus_connection *conn; char *path; conn = talloc_get_type(pvt, struct sbus_connection); path = sbus_opath_get_base_path(NULL, item->key.str); dbus_connection_unregister_object_path(conn->dbus.conn, path); } errno_t sbus_opath_hash_init(TALLOC_CTX *mem_ctx, struct sbus_connection *conn, hash_table_t **_table) { return sss_hash_create_ex(mem_ctx, 10, _table, 0, 0, 0, 0, sbus_opath_hash_delete_cb, conn); } static errno_t sbus_opath_hash_add_iface(hash_table_t *table, const char *object_path, struct sbus_interface *iface, bool *_path_known) { TALLOC_CTX *tmp_ctx = NULL; struct sbus_interface_list *list = NULL; struct sbus_interface_list *item = NULL; const char *iface_name = iface->vtable->meta->name; hash_key_t key; hash_value_t value; bool path_known; errno_t ret; int hret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "Registering interface %s with path %s\n", iface_name, object_path); /* create new list item */ item = talloc_zero(tmp_ctx, struct sbus_interface_list); if (item == NULL) { return ENOMEM; } item->interface = iface; /* first lookup existing list in hash table */ key.type = HASH_KEY_STRING; key.str = talloc_strdup(tmp_ctx, object_path); if (key.str == NULL) { ret = ENOMEM; goto done; } hret = hash_lookup(table, &key, &value); if (hret == HASH_SUCCESS) { /* This object path has already some interface registered. We will * check for existence of the interface currently being added and * add it if missing. */ path_known = true; list = talloc_get_type(value.ptr, struct sbus_interface_list); if (sbus_iface_list_lookup(list, iface_name) != NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Trying to register the same interface" " twice: iface=%s, opath=%s\n", iface_name, object_path); ret = EEXIST; goto done; } DLIST_ADD_END(list, item, struct sbus_interface_list *); ret = EOK; goto done; } else if (hret != HASH_ERROR_KEY_NOT_FOUND) { ret = EIO; goto done; } /* otherwise create new hash entry and new list */ path_known = false; list = item; value.type = HASH_VALUE_PTR; value.ptr = list; hret = hash_enter(table, &key, &value); if (hret != HASH_SUCCESS) { ret = EIO; goto done; } talloc_steal(table, key.str); ret = EOK; done: if (ret == EOK) { talloc_steal(item, iface); talloc_steal(table, item); *_path_known = path_known; } talloc_free(tmp_ctx); return ret; } static bool sbus_opath_hash_has_path(hash_table_t *table, const char *object_path) { hash_key_t key; key.type = HASH_KEY_STRING; key.str = discard_const(object_path); return hash_has_key(table, &key); } /** * First @object_path is looked up in @table, if it is not found it steps up * in the path hierarchy and try to lookup the parent node. This continues * until the root is reached. */ struct sbus_interface * sbus_opath_hash_lookup_iface(hash_table_t *table, const char *object_path, const char *iface_name) { TALLOC_CTX *tmp_ctx = NULL; struct sbus_interface_list *list = NULL; struct sbus_interface *iface = NULL; char *lookup_path = NULL; hash_key_t key; hash_value_t value; int hret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NULL; } lookup_path = talloc_strdup(tmp_ctx, object_path); if (lookup_path == NULL) { goto done; } while (lookup_path != NULL) { key.type = HASH_KEY_STRING; key.str = lookup_path; hret = hash_lookup(table, &key, &value); if (hret == HASH_SUCCESS) { list = talloc_get_type(value.ptr, struct sbus_interface_list); iface = sbus_iface_list_lookup(list, iface_name); if (iface != NULL) { goto done; } } else if (hret != HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_OP_FAILURE, "Unable to search hash table: hret=%d\n", hret); iface = NULL; goto done; } /* we will not free lookup path since it is freed with tmp_ctx * and the object paths are supposed to be small */ lookup_path = sbus_opath_parent_subtree(tmp_ctx, lookup_path); } done: talloc_free(tmp_ctx); return iface; } /** * Acquire list of all interfaces that are supported on given object path. */ errno_t sbus_opath_hash_lookup_supported(TALLOC_CTX *mem_ctx, hash_table_t *table, const char *object_path, struct sbus_interface_list **_list) { TALLOC_CTX *tmp_ctx = NULL; TALLOC_CTX *list_ctx = NULL; struct sbus_interface_list *copy = NULL; struct sbus_interface_list *list = NULL; char *lookup_path = NULL; hash_key_t key; hash_value_t value; errno_t ret; int hret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } list_ctx = talloc_new(tmp_ctx); if (list_ctx == NULL) { ret = ENOMEM; goto done; } lookup_path = talloc_strdup(tmp_ctx, object_path); if (lookup_path == NULL) { ret = ENOMEM; goto done; } while (lookup_path != NULL) { key.type = HASH_KEY_STRING; key.str = lookup_path; hret = hash_lookup(table, &key, &value); if (hret == HASH_SUCCESS) { ret = sbus_iface_list_copy(list_ctx, value.ptr, ©); if (ret != EOK) { goto done; } DLIST_CONCATENATE(list, copy, struct sbus_interface_list *); } else if (hret != HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_OP_FAILURE, "Unable to search hash table: hret=%d\n", hret); ret = EIO; goto done; } /* we will not free lookup path since it is freed with tmp_ctx * and the object paths are supposed to be small */ lookup_path = sbus_opath_parent_subtree(tmp_ctx, lookup_path); } talloc_steal(mem_ctx, list_ctx); *_list = list; ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sbus_nodes_hash_init(TALLOC_CTX *mem_ctx, struct sbus_connection *conn, hash_table_t **_table) { return sss_hash_create_ex(mem_ctx, 10, _table, 0, 0, 0, 0, NULL, conn); } struct sbus_nodes_data { sbus_nodes_fn nodes_fn; void *handler_data; }; static errno_t sbus_nodes_hash_add(hash_table_t *table, const char *object_path, sbus_nodes_fn nodes_fn, void *handler_data) { TALLOC_CTX *tmp_ctx; struct sbus_nodes_data *data; hash_key_t key; hash_value_t value; errno_t ret; bool has_key; int hret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } key.type = HASH_KEY_STRING; key.str = talloc_strdup(tmp_ctx, object_path); if (key.str == NULL) { return ENOMEM; } has_key = hash_has_key(table, &key); if (has_key) { ret = EEXIST; goto done; } data = talloc_zero(tmp_ctx, struct sbus_nodes_data); if (data == NULL) { ret = ENOMEM; goto done; } data->handler_data = handler_data; data->nodes_fn = nodes_fn; value.type = HASH_VALUE_PTR; value.ptr = data; hret = hash_enter(table, &key, &value); if (hret != HASH_SUCCESS) { ret = EIO; goto done; } talloc_steal(table, key.str); talloc_steal(table, data); ret = EOK; done: talloc_free(tmp_ctx); return ret; } const char ** sbus_nodes_hash_lookup(TALLOC_CTX *mem_ctx, hash_table_t *table, const char *object_path) { struct sbus_nodes_data *data; hash_key_t key; hash_value_t value; int hret; key.type = HASH_KEY_STRING; key.str = discard_const(object_path); hret = hash_lookup(table, &key, &value); if (hret == HASH_ERROR_KEY_NOT_FOUND) { return NULL; } else if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Unable to search hash table: hret=%d\n", hret); return NULL; } data = talloc_get_type(value.ptr, struct sbus_nodes_data); return data->nodes_fn(mem_ctx, object_path, data->handler_data); } static struct sbus_interface * sbus_new_interface(TALLOC_CTX *mem_ctx, const char *object_path, struct sbus_vtable *iface_vtable, void *handler_data) { struct sbus_interface *intf; intf = talloc_zero(mem_ctx, struct sbus_interface); if (intf == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot allocate a new sbus_interface.\n"); return NULL; } intf->path = talloc_strdup(intf, object_path); if (intf->path == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot duplicate object path.\n"); talloc_free(intf); return NULL; } intf->vtable = iface_vtable; intf->handler_data = handler_data; return intf; } static DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, DBusMessage *message, void *user_data); static errno_t sbus_conn_register_path(struct sbus_connection *conn, const char *path) { static DBusObjectPathVTable vtable = {NULL, sbus_message_handler, NULL, NULL, NULL, NULL}; DBusError error; char *reg_path = NULL; dbus_bool_t dbret; DEBUG(SSSDBG_TRACE_FUNC, "Registering object path %s with D-Bus " "connection\n", path); if (sbus_opath_is_subtree(path)) { reg_path = sbus_opath_get_base_path(conn, path); if (reg_path == NULL) { return ENOMEM; } /* D-Bus does not allow to have both object path and fallback * registered. Since we handle the real message handlers ourselves * we will register fallback only in this case. */ if (sbus_opath_hash_has_path(conn->managed_paths, reg_path)) { dbus_connection_unregister_object_path(conn->dbus.conn, reg_path); } dbret = dbus_connection_register_fallback(conn->dbus.conn, reg_path, &vtable, conn); talloc_free(reg_path); } else { dbus_error_init(&error); dbret = dbus_connection_try_register_object_path(conn->dbus.conn, path, &vtable, conn, &error); if (dbus_error_is_set(&error) && strcmp(error.name, DBUS_ERROR_OBJECT_PATH_IN_USE) == 0) { /* A fallback is probably already registered. Just return. */ dbus_error_free(&error); return EOK; } } if (!dbret) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to register object path " "%s with D-Bus connection.\n", path); return ENOMEM; } return EOK; } errno_t sbus_conn_register_iface(struct sbus_connection *conn, struct sbus_vtable *iface_vtable, const char *object_path, void *handler_data) { struct sbus_interface *iface = NULL; bool path_known; errno_t ret; if (conn == NULL || iface_vtable == NULL || object_path == NULL) { return EINVAL; } iface = sbus_new_interface(conn, object_path, iface_vtable, handler_data); if (iface == NULL) { return ENOMEM; } ret = sbus_opath_hash_add_iface(conn->managed_paths, object_path, iface, &path_known); if (ret != EOK) { talloc_free(iface); return ret; } if (path_known) { /* this object path is already registered */ return EOK; } /* if ret != EOK we will still leave iface in the table, since * we probably don't have enough memory to remove it correctly anyway */ ret = sbus_conn_register_path(conn, object_path); if (ret != EOK) { return ret; } /* register standard interfaces with this object path as well */ ret = sbus_conn_register_iface(conn, sbus_properties_vtable(), object_path, conn); if (ret != EOK) { return ret; } ret = sbus_conn_register_iface(conn, sbus_introspect_vtable(), object_path, conn); if (ret != EOK) { return ret; } return ret; } void sbus_conn_register_nodes(struct sbus_connection *conn, const char *path, sbus_nodes_fn nodes_fn, void *data) { errno_t ret; ret = sbus_nodes_hash_add(conn->nodes_fns, path, nodes_fn, data); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to register node function with " "%s. Introspection may not work correctly.\n", path); } } errno_t sbus_conn_reregister_paths(struct sbus_connection *conn) { hash_key_t *keys = NULL; unsigned long count; unsigned long i; errno_t ret; int hret; hret = hash_keys(conn->managed_paths, &count, &keys); if (hret != HASH_SUCCESS) { ret = ENOMEM; goto done; } for (i = 0; i < count; i++) { ret = sbus_conn_register_path(conn, keys[i].str); if (ret != EOK) { goto done; } } ret = EOK; done: talloc_free(keys); return ret; } static void sbus_message_handler_got_caller_id(struct tevent_req *req); static DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn, DBusMessage *message, void *handler_data) { struct tevent_req *req; struct sbus_connection *conn; struct sbus_interface *iface; struct sbus_request *sbus_req; const struct sbus_method_meta *method; const char *iface_name; const char *method_name; const char *path; const char *sender; conn = talloc_get_type(handler_data, struct sbus_connection); /* header information */ iface_name = dbus_message_get_interface(message); method_name = dbus_message_get_member(message); path = dbus_message_get_path(message); sender = dbus_message_get_sender(message); DEBUG(SSSDBG_TRACE_INTERNAL, "Received SBUS method %s.%s on path %s\n", iface_name, method_name, path); /* try to find the interface */ iface = sbus_opath_hash_lookup_iface(conn->managed_paths, path, iface_name); if (iface == NULL) { goto fail; } method = sbus_meta_find_method(iface->vtable->meta, method_name); if (method == NULL || method->vtable_offset == 0) { goto fail; } /* we have a valid handler, create D-Bus request */ sbus_req = sbus_new_request(conn, iface, message); if (sbus_req == NULL) { return DBUS_HANDLER_RESULT_NEED_MEMORY; } sbus_req->method = method; /* now get the sender ID */ req = sbus_get_sender_id_send(sbus_req, conn->ev, conn, sender); if (req == NULL) { talloc_free(sbus_req); return DBUS_HANDLER_RESULT_NEED_MEMORY; } tevent_req_set_callback(req, sbus_message_handler_got_caller_id, sbus_req); return DBUS_HANDLER_RESULT_HANDLED; fail: ; DBusMessage *reply; DEBUG(SSSDBG_CRIT_FAILURE, "No matching handler found for method %s.%s " "on path %s\n", iface_name, method_name, path); reply = dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_METHOD, NULL); sbus_conn_send_reply(conn, reply); return DBUS_HANDLER_RESULT_HANDLED; } static void sbus_message_handler_got_caller_id(struct tevent_req *req) { struct sbus_request *sbus_req; const struct sbus_method_meta *method; sbus_msg_handler_fn handler; sbus_method_invoker_fn invoker; void *pvt; DBusError *error; errno_t ret; sbus_req = tevent_req_callback_data(req, struct sbus_request); method = sbus_req->method; ret = sbus_get_sender_id_recv(req, &sbus_req->client); if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to " "resolve caller's ID: %s\n", sss_strerror(ret)); sbus_request_fail_and_finish(sbus_req, error); return; } handler = VTABLE_FUNC(sbus_req->intf->vtable, method->vtable_offset); invoker = method->invoker; pvt = sbus_req->intf->handler_data; sbus_request_invoke_or_finish(sbus_req, handler, pvt, invoker); return; } sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_private.h0000644000000000000000000000007212703456111017762 xustar0030 atime=1460561751.652715634 28 ctime=1460561774.4987931 sssd-1.13.4/src/sbus/sssd_dbus_private.h0000644002412700241270000001324012703456111021433 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Stephen Gallagher Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SSSD_DBUS_PRIVATE_H_ #define _SSSD_DBUS_PRIVATE_H_ #include #include "sssd_dbus_meta.h" union dbus_conn_pointer { DBusServer *server; DBusConnection *conn; }; enum dbus_conn_type { SBUS_SERVER, SBUS_CONNECTION }; struct sbus_watch_ctx; struct sbus_connection { struct tevent_context *ev; enum dbus_conn_type type; union dbus_conn_pointer dbus; char *address; int connection_type; int disconnect; hash_table_t *managed_paths; hash_table_t *nodes_fns; hash_table_t *incoming_signals; /* reconnect settings */ int retries; int max_retries; sbus_conn_reconn_callback_fn reconnect_callback; /* Private data needed to reinit after reconnection */ void *reconnect_pvt; /* server related stuff */ char *symlink; sbus_server_conn_init_fn srv_init_fn; void *srv_init_data; hash_table_t *clients; /* watches list */ struct sbus_watch_ctx *watch_list; }; /* =Standard=interfaces=================================================== */ struct sbus_vtable *sbus_introspect_vtable(void); struct sbus_vtable *sbus_properties_vtable(void); /* =Watches=============================================================== */ struct sbus_watch_ctx { struct sbus_watch_ctx *prev, *next; struct sbus_connection *conn; struct tevent_fd *fde; int fd; DBusWatch *dbus_read_watch; DBusWatch *dbus_write_watch; }; dbus_bool_t sbus_add_watch(DBusWatch *watch, void *data); void sbus_toggle_watch(DBusWatch *watch, void *data); void sbus_remove_watch(DBusWatch *watch, void *data); /* =Timeouts============================================================== */ struct sbus_timeout_ctx { DBusTimeout *dbus_timeout; struct tevent_timer *te; }; dbus_bool_t sbus_add_timeout(DBusTimeout *dbus_timeout, void *data); void sbus_toggle_timeout(DBusTimeout *dbus_timeout, void *data); void sbus_remove_timeout(DBusTimeout *dbus_timeout, void *data); /* =Requests============================================================== */ struct sbus_request * sbus_new_request(struct sbus_connection *conn, struct sbus_interface *intf, DBusMessage *message); /* =Interface=and=object=paths============================================ */ struct sbus_interface_list { struct sbus_interface_list *prev, *next; struct sbus_interface *interface; }; errno_t sbus_opath_hash_init(TALLOC_CTX *mem_ctx, struct sbus_connection *conn, hash_table_t **_table); struct sbus_interface * sbus_opath_hash_lookup_iface(hash_table_t *table, const char *object_path, const char *iface_name); errno_t sbus_opath_hash_lookup_supported(TALLOC_CTX *mem_ctx, hash_table_t *table, const char *object_path, struct sbus_interface_list **_list); errno_t sbus_nodes_hash_init(TALLOC_CTX *mem_ctx, struct sbus_connection *conn, hash_table_t **_table); const char ** sbus_nodes_hash_lookup(TALLOC_CTX *mem_ctx, hash_table_t *table, const char *object_path); void sbus_request_invoke_or_finish(struct sbus_request *dbus_req, sbus_msg_handler_fn handler_fn, void *handler_data, sbus_method_invoker_fn invoker_fn); /* A low-level, private variant of sbus_conn_send that accepts just * DBusConnection. It should never be used outside sbus code, responders * and back ends should use sbus_conn_send! */ int sss_dbus_conn_send(DBusConnection *dbus_conn, DBusMessage *msg, int timeout_ms, DBusPendingCallNotifyFunction reply_handler, void *pvt, DBusPendingCall **pending); /* =Retrieve-conn-credentials=============================================== */ struct tevent_req *sbus_get_sender_id_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_connection *conn, const char *sender); int sbus_get_sender_id_recv(struct tevent_req *req, int64_t *_uid); /* =Properties============================================================ */ int sbus_properties_dispatch(struct sbus_request *dbus_req); /* =Signals=============================================================== */ DBusHandlerResult sbus_signal_handler(DBusConnection *conn, DBusMessage *message, void *handler_data); errno_t sbus_incoming_signal_hash_init(TALLOC_CTX *mem_ctx, hash_table_t **_table); void sbus_register_common_signals(struct sbus_connection *conn, void *pvt); #endif /* _SSSD_DBUS_PRIVATE_H_ */ sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_invokers.c0000644000000000000000000000007412703456111020145 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.851794297 sssd-1.13.4/src/sbus/sssd_dbus_invokers.c0000644002412700241270000004170512703456111021623 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat SBUS: Interface introspection This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_meta.h" #include "sbus/sssd_dbus_private.h" #include "sbus/sssd_dbus_invokers.h" static int sbus_invoke_get_basic(struct sbus_request *sbus_req, void *function_ptr, void *value_ptr, int dbus_type, DBusMessageIter *iter) { void (*handler_fn)(struct sbus_request *, void *, void *); dbus_bool_t value_bool; dbus_bool_t dbret; handler_fn = function_ptr; handler_fn(sbus_req, sbus_req->intf->handler_data, value_ptr); if (dbus_type == DBUS_TYPE_BOOLEAN) { /* Special case to convert bool into dbus_bool_t. */ value_bool = *((bool *) value_ptr); value_ptr = &value_bool; } dbret = dbus_message_iter_append_basic(iter, dbus_type, value_ptr); return dbret ? EOK : EIO; } static int sbus_invoke_get_string(struct sbus_request *sbus_req, void *function_ptr, const char *default_value, int dbus_type, DBusMessageIter *iter) { void (*handler_fn)(struct sbus_request *, void *, const char **); const char *value = NULL; dbus_bool_t dbret; handler_fn = function_ptr; handler_fn(sbus_req, sbus_req->intf->handler_data, &value); value = value == NULL ? default_value : value; dbret = dbus_message_iter_append_basic(iter, dbus_type, &value); return dbret ? EOK : EIO; } static int sbus_invoke_get_array(struct sbus_request *sbus_req, void *function_ptr, unsigned int item_size, int dbus_type, DBusMessageIter *iter) { void (*handler_fn)(struct sbus_request *, void *, void *, int *); const char array_type[2] = {dbus_type, '\0'}; DBusMessageIter array; dbus_bool_t dbret; uint8_t *values; void *addr; int num_values; int i; handler_fn = function_ptr; handler_fn(sbus_req, sbus_req->intf->handler_data, &values, &num_values); dbret = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, array_type, &array); if (!dbret) { return EIO; } for (i = 0; i < num_values; i++) { addr = values + i * item_size; dbret = dbus_message_iter_append_basic(&array, dbus_type, addr); if (!dbret) { return ENOMEM; } } dbret = dbus_message_iter_close_container(iter, &array); if (!dbret) { return EIO; } return EOK; } int sbus_invoke_get_y(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { uint8_t value; return sbus_invoke_get_basic(sbus_req, function_ptr, &value, DBUS_TYPE_BYTE, iter); } int sbus_invoke_get_b(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { bool value; return sbus_invoke_get_basic(sbus_req, function_ptr, &value, DBUS_TYPE_BOOLEAN, iter); } int sbus_invoke_get_n(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { int16_t value; return sbus_invoke_get_basic(sbus_req, function_ptr, &value, DBUS_TYPE_INT16, iter); } int sbus_invoke_get_q(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { uint16_t value; return sbus_invoke_get_basic(sbus_req, function_ptr, &value, DBUS_TYPE_UINT16, iter); } int sbus_invoke_get_i(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { int32_t value; return sbus_invoke_get_basic(sbus_req, function_ptr, &value, DBUS_TYPE_INT32, iter); } int sbus_invoke_get_u(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { uint32_t value; return sbus_invoke_get_basic(sbus_req, function_ptr, &value, DBUS_TYPE_UINT32, iter); } int sbus_invoke_get_x(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { int64_t value; return sbus_invoke_get_basic(sbus_req, function_ptr, &value, DBUS_TYPE_INT64, iter); } int sbus_invoke_get_t(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { uint64_t value; return sbus_invoke_get_basic(sbus_req, function_ptr, &value, DBUS_TYPE_UINT64, iter); } int sbus_invoke_get_d(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { double value; return sbus_invoke_get_basic(sbus_req, function_ptr, &value, DBUS_TYPE_DOUBLE, iter); } int sbus_invoke_get_s(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_string(sbus_req, function_ptr, "", DBUS_TYPE_STRING, iter); } int sbus_invoke_get_o(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_string(sbus_req, function_ptr, "/", DBUS_TYPE_OBJECT_PATH, iter); } int sbus_invoke_get_ay(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(uint8_t), DBUS_TYPE_BYTE, iter); } int sbus_invoke_get_an(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(int16_t), DBUS_TYPE_INT16, iter); } int sbus_invoke_get_aq(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(uint16_t), DBUS_TYPE_UINT16, iter); } int sbus_invoke_get_ai(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(int32_t), DBUS_TYPE_INT32, iter); } int sbus_invoke_get_au(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(uint32_t), DBUS_TYPE_UINT32, iter); } int sbus_invoke_get_ax(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(int64_t), DBUS_TYPE_INT64, iter); } int sbus_invoke_get_at(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(uint64_t), DBUS_TYPE_UINT64, iter); } int sbus_invoke_get_ad(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(double), DBUS_TYPE_DOUBLE, iter); } int sbus_invoke_get_as(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(const char *), DBUS_TYPE_STRING, iter); } int sbus_invoke_get_ao(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { return sbus_invoke_get_array(sbus_req, function_ptr, sizeof(const char *), DBUS_TYPE_OBJECT_PATH, iter); } int sbus_invoke_get_aDOsasDE(DBusMessageIter *iter, struct sbus_request *sbus_req, void *function_ptr) { void (*handler_fn)(struct sbus_request *, void *, hash_table_t **); DBusMessageIter it_array; DBusMessageIter it_dict; DBusMessageIter it_values; hash_table_t *table; struct hash_iter_context_t *table_iter = NULL; hash_entry_t *entry; const char **values; dbus_bool_t dbret; errno_t ret; int i; handler_fn = function_ptr; handler_fn(sbus_req, sbus_req->intf->handler_data, &table); dbret = dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &it_array); if (!dbret) { ret = EIO; goto done; } /* iterate over keys */ if (table == NULL) { dbret = dbus_message_iter_close_container(iter, &it_array); if (!dbret) { ret = EIO; goto done; } ret = EOK; goto done; } table_iter = new_hash_iter_context(table); while ((entry = table_iter->next(table_iter)) != NULL) { if (entry->key.type != HASH_KEY_STRING || entry->key.str == NULL || entry->value.type != HASH_VALUE_PTR || entry->value.ptr == NULL) { continue; } dbret = dbus_message_iter_open_container(&it_array, DBUS_TYPE_DICT_ENTRY, NULL, &it_dict); if (!dbret) { ret = EIO; goto done; } /* append key as dict entry key */ dbret = dbus_message_iter_append_basic(&it_dict, DBUS_TYPE_STRING, &entry->key.str); if (!dbret) { ret = EIO; goto done; } /* iterate over values */ dbret = dbus_message_iter_open_container(&it_dict, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &it_values); if (!dbret) { ret = EIO; goto done; } values = entry->value.ptr; for (i = 0; values[i] != NULL; i++) { /* append value into array */ dbret = dbus_message_iter_append_basic(&it_values, DBUS_TYPE_STRING, &values[i]); if (!dbret) { ret = EIO; goto done; } } dbret = dbus_message_iter_close_container(&it_dict, &it_values); if (!dbret) { ret = EIO; goto done; } dbret = dbus_message_iter_close_container(&it_array, &it_dict); if (!dbret) { ret = EIO; goto done; } } dbret = dbus_message_iter_close_container(iter, &it_array); if (!dbret) { ret = EIO; goto done; } ret = EOK; done: talloc_free(table_iter); return ret; } void sbus_invoke_get(struct sbus_request *sbus_req, const char *type, sbus_get_invoker_fn invoker_fn, sbus_msg_handler_fn handler_fn) { DBusMessage *reply = NULL; DBusMessageIter iter; DBusMessageIter variant; dbus_bool_t dbret; errno_t ret; reply = dbus_message_new_method_return(sbus_req->message); if (reply == NULL) { ret = ENOMEM; goto fail; } dbus_message_iter_init_append(reply, &iter); dbret = dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, type, &variant); if (!dbret) { ret = ENOMEM; goto fail; } ret = invoker_fn(&variant, sbus_req, handler_fn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Invoker error [%d]: %s\n", ret, sss_strerror(ret)); goto fail; } dbret = dbus_message_iter_close_container(&iter, &variant); if (!dbret) { ret = EIO; goto fail; } sbus_request_finish(sbus_req, reply); return; fail: DEBUG(SSSDBG_CRIT_FAILURE, "Unable to reply [%d]: %s\n", ret, sss_strerror(ret)); if (reply != NULL) { dbus_message_unref(reply); } sbus_request_finish(sbus_req, NULL); return; } void sbus_invoke_get_all(struct sbus_request *sbus_req) { const struct sbus_property_meta *props; sbus_msg_handler_fn *handler_fn; DBusMessage *reply = NULL; DBusMessageIter iter; DBusMessageIter array; DBusMessageIter dict; DBusMessageIter variant; dbus_bool_t dbret; errno_t ret; int i; reply = dbus_message_new_method_return(sbus_req->message); if (reply == NULL) { ret = ENOMEM; goto fail; } dbus_message_iter_init_append(reply, &iter); dbret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array); if (!dbret) { ret = ENOMEM; goto fail; } props = sbus_req->intf->vtable->meta->properties; if (props != NULL) { for (i = 0; props[i].name != NULL; i++) { dbret = dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict); if (!dbret) { ret = ENOMEM; goto fail; } /* key */ dbret = dbus_message_iter_append_basic(&dict, DBUS_TYPE_STRING, &props[i].name); if (!dbret) { ret = ENOMEM; goto fail; } /* value */ dbret = dbus_message_iter_open_container(&dict, DBUS_TYPE_VARIANT, props[i].type, &variant); if (!dbret) { ret = ENOMEM; goto fail; } handler_fn = VTABLE_FUNC(sbus_req->intf->vtable, props[i].vtable_offset_get); if (handler_fn == NULL) { ret = ERR_INTERNAL; goto fail; } ret = props[i].invoker_get(&variant, sbus_req, handler_fn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Invoker error [%d]: %s\n", ret, sss_strerror(ret)); goto fail; } dbret = dbus_message_iter_close_container(&dict, &variant); if (!dbret) { ret = EIO; goto fail; } dbret = dbus_message_iter_close_container(&array, &dict); if (!dbret) { ret = EIO; goto fail; } } } dbret = dbus_message_iter_close_container(&iter, &array); if (!dbret) { ret = EIO; goto fail; } sbus_request_finish(sbus_req, reply); return; fail: DEBUG(SSSDBG_CRIT_FAILURE, "Unable to reply [%d]: %s\n", ret, sss_strerror(ret)); dbus_message_unref(reply); sbus_request_finish(sbus_req, NULL); return; } sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_properties.c0000644000000000000000000000007212703456111020477 xustar0030 atime=1460561751.652715634 28 ctime=1460561774.8527943 sssd-1.13.4/src/sbus/sssd_dbus_properties.c0000644002412700241270000002465312703456111022162 0ustar00jhrozekjhrozek00000000000000/* Authors: Stef Walter Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_meta.h" #include "sbus/sssd_dbus_private.h" #include "sbus/sssd_dbus_invokers.h" #define CHECK_SIGNATURE_OR_FAIL(req, error, label, exp) do { \ const char *__sig; \ __sig = dbus_message_get_signature(req->message); \ if (strcmp(__sig, exp) != 0) { \ error = sbus_error_new(req, DBUS_ERROR_INVALID_ARGS, \ "Invalid arguments: expected \"%s\", got \"%s\"", exp, __sig); \ goto label; \ } \ } while (0) struct iface_properties { struct sbus_vtable vtable; /* derive from sbus_vtable */ sbus_msg_handler_fn Get; sbus_msg_handler_fn Set; sbus_msg_handler_fn GetAll; }; static int sbus_properties_get(struct sbus_request *sbus_req, void *pvt); static int sbus_properties_set(struct sbus_request *sbus_req, void *pvt); static int sbus_properties_get_all(struct sbus_request *sbus_req, void *pvt); struct sbus_vtable * sbus_properties_vtable(void) { /* Properties.Get */ static const struct sbus_arg_meta get_args_in[] = { { "interface_name", "s" }, { "property_name", "s" }, { NULL, } }; static const struct sbus_arg_meta get_args_out[] = { { "value", "v" }, { NULL, } }; /* Properties.Set */ static const struct sbus_arg_meta set_args_in[] = { { "interface_name", "s" }, { "property_name", "s" }, { "value", "v" }, { NULL, } }; /* Properties.GetAll */ static const struct sbus_arg_meta getall_args_in[] = { { "interface_name", "s" }, { NULL, } }; static const struct sbus_arg_meta getall_args_out[] = { { "props", "a{sv}" }, { NULL, } }; static const struct sbus_method_meta iface_methods[] = { { "Get", /* name */ get_args_in, get_args_out, offsetof(struct iface_properties, Get), NULL, /* no invoker */ }, { "Set", /* name */ set_args_in, NULL, /* no out_args */ offsetof(struct iface_properties, Set), NULL, /* no invoker */ }, { "GetAll", /* name */ getall_args_in, getall_args_out, offsetof(struct iface_properties, GetAll), NULL, /* no invoker */ }, { NULL, } }; static const struct sbus_interface_meta iface_meta = { "org.freedesktop.DBus.Properties", /* name */ iface_methods, NULL, /* no signals */ NULL, /* no properties */ NULL, /* no GetAll invoker */ }; static struct iface_properties iface = { { &iface_meta, 0 }, .Get = sbus_properties_get, .Set = sbus_properties_set, .GetAll = sbus_properties_get_all, }; return &iface.vtable; } static struct sbus_request * sbus_properties_subreq(struct sbus_request *sbus_req, struct sbus_interface *iface) { struct sbus_request *sbus_subreq; /* Create new sbus_request to so it contain given interface. The * old sbus_request talloc context will be attached to this new one * so it is freed together. */ sbus_subreq = sbus_new_request(sbus_req->conn, iface, sbus_req->message); if (sbus_subreq == NULL) { return NULL; } talloc_steal(sbus_subreq, sbus_req); return sbus_subreq; } static int sbus_properties_get(struct sbus_request *sbus_req, void *pvt) { DBusError *error; struct sbus_request *sbus_subreq; struct sbus_connection *conn; struct sbus_interface *iface; const struct sbus_property_meta *prop; sbus_msg_handler_fn handler_fn; const char *interface_name; const char *property_name; bool bret; conn = talloc_get_type(pvt, struct sbus_connection); CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "ss"); bret = sbus_request_parse_or_finish(sbus_req, DBUS_TYPE_STRING, &interface_name, DBUS_TYPE_STRING, &property_name, DBUS_TYPE_INVALID); if (!bret) { /* request was handled */ return EOK; } /* find interface */ iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path, interface_name); if (iface == NULL) { error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); goto fail; } /* find property handler */ prop = sbus_meta_find_property(iface->vtable->meta, property_name); if (prop == NULL) { error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property"); goto fail; } if (!(prop->flags & SBUS_PROPERTY_READABLE)) { error = sbus_error_new(sbus_req, DBUS_ERROR_ACCESS_DENIED, "Property is not readable"); goto fail; } handler_fn = VTABLE_FUNC(iface->vtable, prop->vtable_offset_get); if (handler_fn == NULL) { error = sbus_error_new(sbus_req, DBUS_ERROR_NOT_SUPPORTED, "Getter is not implemented"); goto fail; } sbus_subreq = sbus_properties_subreq(sbus_req, iface); if (sbus_subreq == NULL) { error = NULL; goto fail; } sbus_invoke_get(sbus_subreq, prop->type, prop->invoker_get, handler_fn); return EOK; fail: return sbus_request_fail_and_finish(sbus_req, error); } /* * We don't implement any handlers for setters yet. This code is for future * use and it is likely it will need some changes. */ static int sbus_properties_set(struct sbus_request *sbus_req, void *pvt) { DBusError *error; DBusMessageIter iter; DBusMessageIter iter_variant; struct sbus_request *sbus_subreq; struct sbus_connection *conn; struct sbus_interface *iface; const struct sbus_property_meta *prop; const char *interface_name; const char *property_name; const char *variant_sig; sbus_msg_handler_fn handler_fn; conn = talloc_get_type(pvt, struct sbus_connection); CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "ssv"); /* get interface and property */ dbus_message_iter_init(sbus_req->message, &iter); dbus_message_iter_get_basic(&iter, &interface_name); dbus_message_iter_next(&iter); dbus_message_iter_get_basic(&iter, &property_name); dbus_message_iter_next(&iter); /* find interface */ iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path, interface_name); if (iface == NULL) { error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); goto fail; } /* find property handler */ prop = sbus_meta_find_property(iface->vtable->meta, property_name); if (prop == NULL) { error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_PROPERTY, "Unknown property"); goto fail; } if (!(prop->flags & SBUS_PROPERTY_WRITABLE)) { error = sbus_error_new(sbus_req, DBUS_ERROR_ACCESS_DENIED, "Property is not writable"); goto fail; } handler_fn = VTABLE_FUNC(iface->vtable, prop->vtable_offset_set); if (handler_fn == NULL) { error = sbus_error_new(sbus_req, DBUS_ERROR_NOT_SUPPORTED, "Setter is not implemented"); goto fail; } /* check variant type */ dbus_message_iter_recurse(&iter, &iter_variant); variant_sig = dbus_message_iter_get_signature(&iter_variant); if (strcmp(prop->type, variant_sig) != 0) { error = sbus_error_new(sbus_req, DBUS_ERROR_INVALID_ARGS, "Invalid data type for property"); goto fail; } sbus_subreq = sbus_properties_subreq(sbus_req, iface); if (sbus_subreq == NULL) { error = NULL; goto fail; } sbus_request_invoke_or_finish(sbus_subreq, handler_fn, iface->handler_data, prop->invoker_set); return EOK; fail: return sbus_request_fail_and_finish(sbus_req, error); } static int sbus_properties_get_all(struct sbus_request *sbus_req, void *pvt) { DBusError *error; struct sbus_request *sbus_subreq; struct sbus_connection *conn; struct sbus_interface *iface; const char *interface_name; bool bret; conn = talloc_get_type(pvt, struct sbus_connection); CHECK_SIGNATURE_OR_FAIL(sbus_req, error, fail, "s"); bret = sbus_request_parse_or_finish(sbus_req, DBUS_TYPE_STRING, &interface_name, DBUS_TYPE_INVALID); if (!bret) { /* request was handled */ return EOK; } /* find interface */ iface = sbus_opath_hash_lookup_iface(conn->managed_paths, sbus_req->path, interface_name); if (iface == NULL) { error = sbus_error_new(sbus_req, DBUS_ERROR_UNKNOWN_INTERFACE, "Unknown interface"); goto fail; } sbus_subreq = sbus_properties_subreq(sbus_req, iface); if (sbus_subreq == NULL) { error = NULL; goto fail; } if (iface->vtable->meta->invoker_get_all == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "No get all invoker set," "using the default one\n"); sbus_invoke_get_all(sbus_req); } else { iface->vtable->meta->invoker_get_all(sbus_subreq); } return EOK; fail: return sbus_request_fail_and_finish(sbus_req, error); } sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_connection.c0000644000000000000000000000007412703456111020444 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.847794283 sssd-1.13.4/src/sbus/sssd_dbus_connection.c0000644002412700241270000004502312703456111022117 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Stephen Gallagher Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_private.h" #include "sbus/sssd_dbus_meta.h" /* Types */ struct dbus_ctx_list; static int sbus_auto_reconnect(struct sbus_connection *conn); static void sbus_dispatch(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *data) { struct tevent_timer *new_event; struct sbus_connection *conn; DBusConnection *dbus_conn; int ret; if (data == NULL) return; conn = talloc_get_type(data, struct sbus_connection); dbus_conn = conn->dbus.conn; DEBUG(SSSDBG_TRACE_ALL, "dbus conn: %p\n", dbus_conn); if (conn->retries > 0) { DEBUG(SSSDBG_TRACE_FUNC, "SBUS is reconnecting. Deferring.\n"); /* Currently trying to reconnect, defer dispatch for 30ms */ tv = tevent_timeval_current_ofs(0, 30); new_event = tevent_add_timer(ev, conn, tv, sbus_dispatch, conn); if (new_event == NULL) { DEBUG(SSSDBG_FATAL_FAILURE,"Could not defer dispatch!\n"); } return; } if ((!dbus_connection_get_is_connected(dbus_conn)) && (conn->max_retries != 0)) { /* Attempt to reconnect automatically */ ret = sbus_auto_reconnect(conn); if (ret == EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Performing auto-reconnect\n"); return; } DEBUG(SSSDBG_FATAL_FAILURE, "Cannot start auto-reconnection.\n"); conn->reconnect_callback(conn, SBUS_RECONNECT_ERROR, conn->reconnect_pvt); return; } if ((conn->disconnect) || (!dbus_connection_get_is_connected(dbus_conn))) { DEBUG(SSSDBG_MINOR_FAILURE,"Connection is not open for dispatching.\n"); /* * Free the connection object. * This will invoke the destructor for the connection */ talloc_free(conn); conn = NULL; return; } /* Dispatch only once each time through the mainloop to avoid * starving other features */ ret = dbus_connection_get_dispatch_status(dbus_conn); if (ret != DBUS_DISPATCH_COMPLETE) { DEBUG(SSSDBG_TRACE_ALL,"Dispatching.\n"); dbus_connection_dispatch(dbus_conn); } /* If other dispatches are waiting, queue up the dispatch function * for the next loop. */ ret = dbus_connection_get_dispatch_status(dbus_conn); if (ret != DBUS_DISPATCH_COMPLETE) { new_event = tevent_add_timer(ev, conn, tv, sbus_dispatch, conn); if (new_event == NULL) { DEBUG(SSSDBG_OP_FAILURE,"Could not add dispatch event!\n"); /* TODO: Calling exit here is bad */ exit(1); } } } /* dbus_connection_wakeup_main * D-BUS makes a callback to the wakeup_main function when * it has data available for dispatching. * In order to avoid blocking, this function will create a now() * timed event to perform the dispatch during the next iteration * through the mainloop */ static void sbus_conn_wakeup_main(void *data) { struct sbus_connection *conn; struct timeval tv; struct tevent_timer *te; conn = talloc_get_type(data, struct sbus_connection); tv = tevent_timeval_current(); /* D-BUS calls this function when it is time to do a dispatch */ te = tevent_add_timer(conn->ev, conn, tv, sbus_dispatch, conn); if (te == NULL) { DEBUG(SSSDBG_OP_FAILURE,"Could not add dispatch event!\n"); /* TODO: Calling exit here is bad */ exit(1); } } static int sbus_conn_set_fns(struct sbus_connection *conn); /* * integrate_connection_with_event_loop * Set up a D-BUS connection to use the libevents mainloop * for handling file descriptor and timed events */ int sbus_init_connection(TALLOC_CTX *ctx, struct tevent_context *ev, DBusConnection *dbus_conn, int connection_type, struct sbus_connection **_conn) { struct sbus_connection *conn; dbus_bool_t dbret; int ret; DEBUG(SSSDBG_TRACE_FUNC,"Adding connection %p\n", dbus_conn); conn = talloc_zero(ctx, struct sbus_connection); conn->ev = ev; conn->type = SBUS_CONNECTION; conn->dbus.conn = dbus_conn; conn->connection_type = connection_type; ret = sbus_opath_hash_init(conn, conn, &conn->managed_paths); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create object paths hash table\n"); talloc_free(conn); return EIO; } ret = sbus_nodes_hash_init(conn, conn, &conn->nodes_fns); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create node functions hash table\n"); talloc_free(conn); return EIO; } ret = sbus_incoming_signal_hash_init(conn, &conn->incoming_signals); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create incoming singals " "hash table\n"); talloc_free(conn); return EIO; } ret = sss_hash_create(conn, 32, &conn->clients); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create clients hash table\n"); talloc_free(conn); return EIO; } ret = sbus_conn_set_fns(conn); if (ret != EOK) { talloc_free(conn); return ret; } /* Set up signal handler. */ dbret = dbus_connection_add_filter(dbus_conn, sbus_signal_handler, conn, NULL); if (dbret == false) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot register signal handler\n"); talloc_free(conn); return EIO; } sbus_register_common_signals(conn, conn); *_conn = conn; return ret; } static int sbus_conn_set_fns(struct sbus_connection *conn) { dbus_bool_t dbret; /* Set up DBusWatch functions */ dbret = dbus_connection_set_watch_functions(conn->dbus.conn, sbus_add_watch, sbus_remove_watch, sbus_toggle_watch, conn, NULL); if (!dbret) { DEBUG(SSSDBG_OP_FAILURE, "Error setting up D-BUS connection watch functions\n"); return EIO; } /* Set up DBusTimeout functions */ dbret = dbus_connection_set_timeout_functions(conn->dbus.conn, sbus_add_timeout, sbus_remove_timeout, sbus_toggle_timeout, conn, NULL); if (!dbret) { DEBUG(SSSDBG_OP_FAILURE, "Error setting up D-BUS server timeout functions\n"); /* FIXME: free resources ? */ return EIO; } /* Set up dispatch handler */ dbus_connection_set_wakeup_main_function(conn->dbus.conn, sbus_conn_wakeup_main, conn, NULL); /* Set up any method_contexts passed in */ /* Attempt to dispatch immediately in case of opportunistic * services connecting before the handlers were all up. * If there are no messages to be dispatched, this will do * nothing. */ sbus_conn_wakeup_main(conn); return EOK; } int sbus_new_connection(TALLOC_CTX *ctx, struct tevent_context *ev, const char *address, struct sbus_connection **_conn) { struct sbus_connection *conn; DBusConnection *dbus_conn; DBusError dbus_error; int ret; dbus_error_init(&dbus_error); /* Open a shared D-BUS connection to the address */ dbus_conn = dbus_connection_open(address, &dbus_error); if (!dbus_conn) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to open connection: name=%s, message=%s\n", dbus_error.name, dbus_error.message); if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); return EIO; } ret = sbus_init_connection(ctx, ev, dbus_conn, SBUS_CONN_TYPE_SHARED, &conn); if (ret != EOK) { /* FIXME: release resources */ } /* Store the address for later reconnection */ conn->address = talloc_strdup(conn, address); dbus_connection_set_exit_on_disconnect(conn->dbus.conn, FALSE); *_conn = conn; return ret; } static int connection_destructor(void *ctx) { struct sbus_connection *conn; conn = talloc_get_type(ctx, struct sbus_connection); DEBUG(SSSDBG_TRACE_FUNC, "Invoking default destructor on connection %p\n", conn->dbus.conn); if (conn->connection_type == SBUS_CONN_TYPE_PRIVATE) { /* Private connections must be closed explicitly */ dbus_connection_close(conn->dbus.conn); } else if (conn->connection_type == SBUS_CONN_TYPE_SHARED || conn->connection_type == SBUS_CONN_TYPE_SYSBUS) { /* Shared and system bus connections are destroyed when their last reference is removed */ } else { /* Critical Error! */ DEBUG(SSSDBG_CRIT_FAILURE, "Critical Error, connection_type is neither shared nor private!\n"); return -1; } /* Remove object path */ /* TODO: Remove object paths */ dbus_connection_unref(conn->dbus.conn); return 0; } /* * sbus_get_connection * Utility function to retreive the DBusConnection object * from a sbus_connection */ DBusConnection *sbus_get_connection(struct sbus_connection *conn) { return conn->dbus.conn; } void sbus_disconnect(struct sbus_connection *conn) { if (conn == NULL) { return; } DEBUG(SSSDBG_TRACE_FUNC, "Disconnecting %p\n", conn->dbus.conn); /******************************* * Referencing conn->dbus.conn */ dbus_connection_ref(conn->dbus.conn); conn->disconnect = 1; /* Unregister object paths */ talloc_zfree(conn->managed_paths); /* Disable watch functions */ dbus_connection_set_watch_functions(conn->dbus.conn, NULL, NULL, NULL, NULL, NULL); /* Disable timeout functions */ dbus_connection_set_timeout_functions(conn->dbus.conn, NULL, NULL, NULL, NULL, NULL); /* Disable dispatch status function */ dbus_connection_set_dispatch_status_function(conn->dbus.conn, NULL, NULL, NULL); /* Disable wakeup main function */ dbus_connection_set_wakeup_main_function(conn->dbus.conn, NULL, NULL, NULL); /* Finalize the connection */ connection_destructor(conn); dbus_connection_unref(conn->dbus.conn); /* Unreferenced conn->dbus_conn * ******************************/ DEBUG(SSSDBG_TRACE_FUNC ,"Disconnected %p\n", conn->dbus.conn); } static void sbus_reconnect(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *data) { struct sbus_connection *conn; DBusError dbus_error; int ret; conn = talloc_get_type(data, struct sbus_connection); dbus_error_init(&dbus_error); DEBUG(SSSDBG_MINOR_FAILURE, "Making reconnection attempt %d to [%s]\n", conn->retries, conn->address); conn->dbus.conn = dbus_connection_open(conn->address, &dbus_error); if (conn->dbus.conn) { /* We successfully reconnected. Set up mainloop integration. */ DEBUG(SSSDBG_MINOR_FAILURE, "Reconnected to [%s]\n", conn->address); ret = sbus_conn_set_fns(conn); if (ret != EOK) { dbus_connection_unref(conn->dbus.conn); goto failed; } /* Re-register object paths */ sbus_conn_reregister_paths(conn); /* Reset retries to 0 to resume dispatch processing */ conn->retries = 0; /* Notify the owner of this connection that the * reconnection was successful */ conn->reconnect_callback(conn, SBUS_RECONNECT_SUCCESS, conn->reconnect_pvt); return; } failed: /* Reconnection failed, try again in a few seconds */ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to open connection: name=%s, message=%s\n", dbus_error.name, dbus_error.message); if (dbus_error_is_set(&dbus_error)) dbus_error_free(&dbus_error); conn->retries++; /* Check if we've passed our last chance or if we've lost track of * our retry count somehow */ if ((conn->retries > conn->max_retries) || (conn->retries <= 0)) { conn->reconnect_callback(conn, SBUS_RECONNECT_EXCEEDED_RETRIES, conn->reconnect_pvt); } if (conn->retries == 2) { /* Wait 3 seconds before the second reconnect attempt */ tv.tv_sec += 3; } else if (conn->retries == 3) { /* Wait 10 seconds before the third reconnect attempt */ tv.tv_sec += 10; } else { /* Wait 30 seconds before all subsequent reconnect attempts */ tv.tv_sec += 30; } te = tevent_add_timer(conn->ev, conn, tv, sbus_reconnect, conn); if (!te) { conn->reconnect_callback(conn, SBUS_RECONNECT_ERROR, conn->reconnect_pvt); } } /* This function will free and recreate the sbus_connection, * calling functions need to be aware of this (and whether * they have attached a talloc destructor to the * sbus_connection. */ static int sbus_auto_reconnect(struct sbus_connection *conn) { struct tevent_timer *te = NULL; struct timeval tv; conn->retries++; if (conn->retries >= conn->max_retries) { /* Return EIO (to tell the calling process it * needs to create a new connection from scratch */ return EIO; } gettimeofday(&tv, NULL); tv.tv_sec += 1; /* Wait 1 second before the first reconnect attempt */ te = tevent_add_timer(conn->ev, conn, tv, sbus_reconnect, conn); if (!te) { return EIO; } return EOK; } /* Max retries */ void sbus_reconnect_init(struct sbus_connection *conn, int max_retries, sbus_conn_reconn_callback_fn callback, void *pvt) { if (max_retries < 0 || callback == NULL) return; conn->retries = 0; conn->max_retries = max_retries; conn->reconnect_callback = callback; conn->reconnect_pvt = pvt; } bool sbus_conn_disconnecting(struct sbus_connection *conn) { if (conn->disconnect == 1) return true; return false; } int sss_dbus_conn_send(DBusConnection *dbus_conn, DBusMessage *msg, int timeout_ms, DBusPendingCallNotifyFunction reply_handler, void *pvt, DBusPendingCall **pending) { DBusPendingCall *pending_reply; dbus_bool_t dbret; dbret = dbus_connection_send_with_reply(dbus_conn, msg, &pending_reply, timeout_ms); if (!dbret) { /* * Critical Failure * Insufficient memory to send message */ DEBUG(SSSDBG_FATAL_FAILURE, "D-BUS send failed.\n"); return ENOMEM; } if (pending_reply) { /* Set up the reply handler */ dbret = dbus_pending_call_set_notify(pending_reply, reply_handler, pvt, NULL); if (!dbret) { /* * Critical Failure * Insufficient memory to create pending call notify */ DEBUG(SSSDBG_FATAL_FAILURE, "D-BUS send failed.\n"); dbus_pending_call_cancel(pending_reply); dbus_pending_call_unref(pending_reply); return ENOMEM; } if(pending) { *pending = pending_reply; } return EOK; } /* If pending_reply is NULL, the connection was not * open for sending. */ /* TODO: Create a callback into the reconnection logic so this * request is invoked when the connection is re-established */ return EAGAIN; } /* * Send a message across the SBUS * If requested, the DBusPendingCall object will * be returned to the caller. * * This function will return EAGAIN in the event * that the connection is not open for * communication. */ int sbus_conn_send(struct sbus_connection *conn, DBusMessage *msg, int timeout_ms, DBusPendingCallNotifyFunction reply_handler, void *pvt, DBusPendingCall **pending) { DBusConnection *dbus_conn; dbus_conn = sbus_get_connection(conn); if (!dbus_conn) { DEBUG(SSSDBG_CRIT_FAILURE, "D-BUS not connected\n"); return ENOTCONN; } return sss_dbus_conn_send(dbus_conn, msg, timeout_ms, reply_handler, pvt, pending); } void sbus_conn_send_reply(struct sbus_connection *conn, DBusMessage *reply) { dbus_connection_send(conn->dbus.conn, reply, NULL); } dbus_bool_t is_uid_sssd_user(DBusConnection *connection, unsigned long uid, void *data) { uid_t sssd_user = * (uid_t *) data; if (uid == 0 || uid == sssd_user) { return TRUE; } return FALSE; } void sbus_allow_uid(struct sbus_connection *conn, uid_t *uid) { dbus_connection_set_unix_user_function(sbus_get_connection(conn), is_uid_sssd_user, uid, NULL); } sssd-1.13.4/src/sbus/PaxHeaders.16287/sbus_client.h0000644000000000000000000000007412703456111016553 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.494793086 sssd-1.13.4/src/sbus/sbus_client.h0000644002412700241270000000205112703456111020220 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider Helpers Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SBUS_CLIENT_H_ #define SBUS_CLIENT_H_ #include #include "sbus/sssd_dbus.h" int sbus_client_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *server_address, struct sbus_connection **_conn); #endif /* SBUS_CLIENT_H_ */ sssd-1.13.4/src/sbus/PaxHeaders.16287/sbus_client.c0000644000000000000000000000007412703456111016546 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.845794276 sssd-1.13.4/src/sbus/sbus_client.c0000644002412700241270000000416412703456111020222 0ustar00jhrozekjhrozek00000000000000/* SSSD Data Provider Helpers Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "sbus_client.h" int sbus_client_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *server_address, struct sbus_connection **_conn) { struct sbus_connection *conn = NULL; int ret; char *filename; uid_t check_uid; gid_t check_gid; /* Validate input */ if (server_address == NULL) { return EINVAL; } filename = strchr(server_address, '/'); if (filename == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected dbus address [%s].\n", server_address); return EIO; } check_uid = geteuid(); check_gid = getegid(); /* Ignore ownership checks when the server runs as root. This is the * case when privileged monitor is setting up sockets for unprivileged * responders */ if (check_uid == 0) check_uid = -1; if (check_gid == 0) check_gid = -1; ret = check_file(filename, check_uid, check_gid, S_IFSOCK|S_IRUSR|S_IWUSR, 0, NULL, true); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "check_file failed for [%s].\n", filename); return EIO; } ret = sbus_new_connection(mem_ctx, ev, server_address, &conn); if (ret != EOK) { goto fail; } *_conn = conn; return EOK; fail: talloc_free(conn); return ret; } sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_introspect.c0000644000000000000000000000007412703456111020477 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.850794293 sssd-1.13.4/src/sbus/sssd_dbus_introspect.c0000644002412700241270000002450312703456111022152 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Pavel Březina Copyright (C) 2014 Red Hat SBUS: Interface introspection This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_meta.h" #include "sbus/sssd_dbus_private.h" #define FMT_DOCTYPE \ "\n" #define FMT_NODE "\n" #define FMT_IFACE " \n" #define FMT_METHOD " \n" #define FMT_METHOD_NOARG " \n" #define FMT_METHOD_ARG " \n" #define FMT_METHOD_CLOSE " \n" #define FMT_SIGNAL " \n" #define FMT_SIGNAL_NOARG " \n" #define FMT_SIGNAL_ARG " \n" #define FMT_SIGNAL_CLOSE " \n" #define FMT_PROPERTY " \n" #define FMT_IFACE_CLOSE " \n" #define FMT_CHILD_NODE " \n" #define FMT_NODE_CLOSE "\n" #define WRITE_OR_FAIL(file, ret, label, fmt, ...) do { \ ret = fprintf(file, fmt, ##__VA_ARGS__); \ if (ret < 0) { \ ret = EIO; \ goto label; \ } \ } while (0) #define METHOD_HAS_ARGS(m) ((m)->in_args != NULL || (m)->out_args != NULL) #define SIGNAL_HAS_ARGS(s) ((s)->args != NULL) enum sbus_arg_type { SBUS_ARG_IN, SBUS_ARG_OUT, SBUS_ARG_SIGNAL }; static int iface_Introspect_finish(struct sbus_request *req, const char *arg_data) { return sbus_request_return_and_finish(req, DBUS_TYPE_STRING, &arg_data, DBUS_TYPE_INVALID); } struct iface_introspectable { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*Introspect)(struct sbus_request *req, void *data); }; static int sbus_introspect(struct sbus_request *sbus_req, void *pvt); struct sbus_vtable * sbus_introspect_vtable(void) { static const struct sbus_arg_meta iface_out[] = { {"data", "s"}, {NULL, NULL} }; static const struct sbus_method_meta iface_methods[] = { {"Introspect", NULL, iface_out, offsetof(struct iface_introspectable, Introspect), NULL}, {NULL, } }; static const struct sbus_interface_meta iface_meta = { "org.freedesktop.DBus.Introspectable", /* name */ iface_methods, NULL, /* no signals */ NULL, /* no properties */ NULL, /* no GetAll invoker */ }; static struct iface_introspectable iface = { { &iface_meta, 0 }, .Introspect = sbus_introspect }; return &iface.vtable; } static int sbus_introspect_generate_args(FILE *file, const struct sbus_arg_meta *args, enum sbus_arg_type type) { const struct sbus_arg_meta *arg; int ret; int i; if (args == NULL) { return EOK; } for (i = 0; args[i].name != NULL; i++) { arg = &args[i]; switch (type) { case SBUS_ARG_SIGNAL: WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_ARG, arg->type, arg->name); break; case SBUS_ARG_IN: WRITE_OR_FAIL(file, ret, done, FMT_METHOD_ARG, arg->type, arg->name, "in"); break; case SBUS_ARG_OUT: WRITE_OR_FAIL(file, ret, done, FMT_METHOD_ARG, arg->type, arg->name, "out"); break; } } ret = EOK; done: return ret; } #define sbus_introspect_generate_in_args(file, args) \ sbus_introspect_generate_args(file, args, SBUS_ARG_IN) #define sbus_introspect_generate_out_args(file, args) \ sbus_introspect_generate_args(file, args, SBUS_ARG_OUT) #define sbus_introspect_generate_signal_args(file, args) \ sbus_introspect_generate_args(file, args, SBUS_ARG_SIGNAL) static int sbus_introspect_generate_methods(FILE *file, const struct sbus_method_meta *methods) { const struct sbus_method_meta *method; int ret; int i; if (methods == NULL) { return EOK; } for (i = 0; methods[i].name != NULL; i++) { method = &methods[i]; if (!METHOD_HAS_ARGS(method)) { WRITE_OR_FAIL(file, ret, done, FMT_METHOD_NOARG, method->name); continue; } WRITE_OR_FAIL(file, ret, done, FMT_METHOD, method->name); ret = sbus_introspect_generate_in_args(file, method->in_args); if (ret != EOK) { goto done; } ret = sbus_introspect_generate_out_args(file, method->out_args); if (ret != EOK) { goto done; } WRITE_OR_FAIL(file, ret, done, FMT_METHOD_CLOSE); } ret = EOK; done: return ret; } static int sbus_introspect_generate_signals(FILE *file, const struct sbus_signal_meta *signals) { const struct sbus_signal_meta *a_signal; int ret; int i; if (signals == NULL) { return EOK; } for (i = 0; signals[i].name != NULL; i++) { a_signal = &signals[i]; if (!SIGNAL_HAS_ARGS(a_signal)) { WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_NOARG, a_signal->name); continue; } WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL, a_signal->name); ret = sbus_introspect_generate_signal_args(file, a_signal->args); if (ret != EOK) { goto done; } WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_CLOSE); } ret = EOK; done: return ret; } static int sbus_introspect_generate_properties(FILE *file, const struct sbus_property_meta *props) { const struct sbus_property_meta *prop; const char *access_mode; int ret; int i; if (props == NULL) { return EOK; } for (i = 0; props[i].name != NULL; i++) { prop = &props[i]; access_mode = prop->flags & SBUS_PROPERTY_WRITABLE ? "readwrite" : "read"; WRITE_OR_FAIL(file, ret, done, FMT_PROPERTY, prop->name, prop->type, access_mode); } ret = EOK; done: return ret; } static int sbus_introspect_generate_iface(FILE *file, struct sbus_interface *iface) { const struct sbus_interface_meta *meta; int ret; meta = iface->vtable->meta; WRITE_OR_FAIL(file, ret, done, FMT_IFACE, meta->name); ret = sbus_introspect_generate_methods(file, meta->methods); if (ret != EOK) { goto done; } ret = sbus_introspect_generate_signals(file, meta->signals); if (ret != EOK) { goto done; } ret = sbus_introspect_generate_properties(file, meta->properties); if (ret != EOK) { goto done; } WRITE_OR_FAIL(file, ret, done, FMT_IFACE_CLOSE); ret = EOK; done: return ret; } static int sbus_introspect_generate_nodes(FILE *file, const char **nodes) { int ret; int i; if (nodes == NULL) { return EOK; } for (i = 0; nodes[i] != NULL; i++) { WRITE_OR_FAIL(file, ret, done, FMT_CHILD_NODE, nodes[i]); } ret = EOK; done: return ret; } static char * sbus_introspect_generate(TALLOC_CTX *mem_ctx, const char *node, const char **nodes, struct sbus_interface_list *list) { struct sbus_interface_list *item; char *introspect = NULL; FILE *memstream; char *buffer; size_t size; int ret; memstream = open_memstream(&buffer, &size); if (memstream == NULL) { goto done; } WRITE_OR_FAIL(memstream, ret, done, FMT_DOCTYPE); WRITE_OR_FAIL(memstream, ret, done, FMT_NODE, node); DLIST_FOR_EACH(item, list) { ret = sbus_introspect_generate_iface(memstream, item->interface); if (ret != EOK) { goto done; } } ret = sbus_introspect_generate_nodes(memstream, nodes); if (ret != EOK) { goto done; } WRITE_OR_FAIL(memstream, ret, done, FMT_NODE_CLOSE); fflush(memstream); introspect = talloc_memdup(mem_ctx, buffer, size + 1); DEBUG(SSSDBG_TRACE_ALL, "Introspection: \n%s\n", introspect); done: if (memstream != NULL) { fclose(memstream); free(buffer); } return introspect; } static int sbus_introspect(struct sbus_request *sbus_req, void *pvt) { DBusError *error; struct sbus_interface_list *list; struct sbus_connection *conn; const char **nodes; char *introspect; errno_t ret; conn = talloc_get_type(pvt, struct sbus_connection); ret = sbus_opath_hash_lookup_supported(sbus_req, conn->managed_paths, sbus_req->path, &list); if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "%s", sss_strerror(ret)); return sbus_request_fail_and_finish(sbus_req, error); } nodes = sbus_nodes_hash_lookup(sbus_req, conn->nodes_fns, sbus_req->path); introspect = sbus_introspect_generate(sbus_req, sbus_req->path, nodes, list); if (introspect == NULL) { ret = ENOMEM; goto done; } ret = EOK; done: if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "%s", sss_strerror(ret)); return sbus_request_fail_and_finish(sbus_req, error); } return iface_Introspect_finish(sbus_req, introspect); } sssd-1.13.4/src/sbus/PaxHeaders.16287/sssd_dbus_common.c0000644000000000000000000000007312703456111017574 xustar0030 atime=1460561751.652715634 29 ctime=1460561774.84679428 sssd-1.13.4/src/sbus/sssd_dbus_common.c0000644002412700241270000002467412703456111021261 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Stephen Gallagher Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_private.h" /* =Watches=============================================================== */ /* DBUS may ask us to add a watch to a file descriptor that already had a watch * associated. Need to check if that's the case */ static struct sbus_watch_ctx *fd_to_watch(struct sbus_watch_ctx *list, int fd) { struct sbus_watch_ctx *watch_iter; watch_iter = list; while (watch_iter != NULL) { if (watch_iter->fd == fd) { return watch_iter; } watch_iter = watch_iter->next; } return NULL; } static int watch_destructor(void *mem) { struct sbus_watch_ctx *watch; watch = talloc_get_type(mem, struct sbus_watch_ctx); DLIST_REMOVE(watch->conn->watch_list, watch); return 0; } /* * watch_handler * Callback for D-BUS to handle messages on a file-descriptor */ static void sbus_watch_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *data) { struct sbus_watch_ctx *watch = talloc_get_type(data, struct sbus_watch_ctx); enum dbus_conn_type type; union dbus_conn_pointer dbus_p; /* conn may get freed inside a handle, save the data we need for later */ type = watch->conn->type; dbus_p = watch->conn->dbus; /* Take a reference while handling watch */ if (type == SBUS_SERVER) { dbus_server_ref(dbus_p.server); } else { dbus_connection_ref(dbus_p.conn); } /* Fire if readable */ if (flags & TEVENT_FD_READ) { if (watch->dbus_read_watch) { dbus_watch_handle(watch->dbus_read_watch, DBUS_WATCH_READABLE); } } /* Fire if writeable */ if (flags & TEVENT_FD_WRITE) { if (watch->dbus_write_watch) { dbus_watch_handle(watch->dbus_write_watch, DBUS_WATCH_WRITABLE); } } /* Release reference once done */ if (type == SBUS_SERVER) { dbus_server_unref(dbus_p.server); } else { dbus_connection_unref(dbus_p.conn); } } /* * add_watch * Set up hooks into the libevents mainloop for * D-BUS to add file descriptor-based events */ dbus_bool_t sbus_add_watch(DBusWatch *dbus_watch, void *data) { unsigned int flags; uint16_t event_flags; struct sbus_connection *conn; struct sbus_watch_ctx *watch; dbus_bool_t enabled; int fd; conn = talloc_get_type(data, struct sbus_connection); #ifdef HAVE_DBUS_WATCH_GET_UNIX_FD fd = dbus_watch_get_unix_fd(dbus_watch); #else fd = dbus_watch_get_fd(dbus_watch); #endif watch = fd_to_watch(conn->watch_list, fd); if (!watch) { /* does not exist, allocate new one */ watch = talloc_zero(conn, struct sbus_watch_ctx); if (!watch) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of Memory!\n"); return FALSE; } watch->conn = conn; watch->fd = fd; } enabled = dbus_watch_get_enabled(dbus_watch); flags = dbus_watch_get_flags(dbus_watch); /* Save the event to the watch object so it can be found later */ if (flags & DBUS_WATCH_READABLE) { watch->dbus_read_watch = dbus_watch; } if (flags & DBUS_WATCH_WRITABLE) { watch->dbus_write_watch = dbus_watch; } dbus_watch_set_data(dbus_watch, watch, NULL); if (watch->fde) { /* pre-existing event, just toggle flags */ sbus_toggle_watch(dbus_watch, data); return TRUE; } event_flags = 0; if (enabled) { if (flags & DBUS_WATCH_READABLE) { event_flags |= TEVENT_FD_READ; } if (flags & DBUS_WATCH_WRITABLE) { event_flags |= TEVENT_FD_WRITE; } } /* Add the file descriptor to the event loop */ watch->fde = tevent_add_fd(conn->ev, watch, fd, event_flags, sbus_watch_handler, watch); if (!watch->fde) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up fd event!\n"); talloc_zfree(watch); return FALSE; } DLIST_ADD(conn->watch_list, watch); talloc_set_destructor((TALLOC_CTX *)watch, watch_destructor); DEBUG(SSSDBG_TRACE_INTERNAL, "%p/%p (%d), %s/%s (%s)\n", watch, dbus_watch, fd, ((flags & DBUS_WATCH_READABLE)?"R":"-"), ((flags & DBUS_WATCH_WRITABLE)?"W":"-"), enabled?"enabled":"disabled"); return TRUE; } /* * toggle_watch * Hook for D-BUS to toggle the enabled/disabled state of * an event in the mainloop */ void sbus_toggle_watch(DBusWatch *dbus_watch, void *data) { struct sbus_watch_ctx *watch; unsigned int flags; dbus_bool_t enabled; void *watch_data; int fd = -1; enabled = dbus_watch_get_enabled(dbus_watch); flags = dbus_watch_get_flags(dbus_watch); watch_data = dbus_watch_get_data(dbus_watch); watch = talloc_get_type(watch_data, struct sbus_watch_ctx); if (!watch) { DEBUG(SSSDBG_OP_FAILURE, "[%p] does not carry watch context?!\n", dbus_watch); /* abort ? */ return; } if (enabled) { if (flags & DBUS_WATCH_READABLE) { TEVENT_FD_READABLE(watch->fde); } if (flags & DBUS_WATCH_WRITABLE) { TEVENT_FD_WRITEABLE(watch->fde); } } else { if (flags & DBUS_WATCH_READABLE) { TEVENT_FD_NOT_READABLE(watch->fde); } if (flags & DBUS_WATCH_WRITABLE) { TEVENT_FD_NOT_WRITEABLE(watch->fde); } } if (DEBUG_IS_SET(SSSDBG_TRACE_ALL)) { #ifdef HAVE_DBUS_WATCH_GET_UNIX_FD fd = dbus_watch_get_unix_fd(dbus_watch); #else fd = dbus_watch_get_fd(dbus_watch); #endif } DEBUG(SSSDBG_TRACE_ALL, "%p/%p (%d), %s/%s (%s)\n", watch, dbus_watch, fd, ((flags & DBUS_WATCH_READABLE)?"R":"-"), ((flags & DBUS_WATCH_WRITABLE)?"W":"-"), enabled?"enabled":"disabled"); } /* * sbus_remove_watch * Hook for D-BUS to remove file descriptor-based events * from the libevents mainloop */ void sbus_remove_watch(DBusWatch *dbus_watch, void *data) { struct sbus_watch_ctx *watch; void *watch_data; watch_data = dbus_watch_get_data(dbus_watch); watch = talloc_get_type(watch_data, struct sbus_watch_ctx); DEBUG(SSSDBG_TRACE_INTERNAL, "%p/%p\n", watch, dbus_watch); if (!watch) { DEBUG(SSSDBG_OP_FAILURE, "DBUS trying to remove unknown watch!\n"); return; } /* remove dbus watch data */ dbus_watch_set_data(dbus_watch, NULL, NULL); /* check which watch to remove, or free if none left */ if (watch->dbus_read_watch == dbus_watch) { watch->dbus_read_watch = NULL; } if (watch->dbus_write_watch == dbus_watch) { watch->dbus_write_watch = NULL; } if (!watch->dbus_read_watch && !watch->dbus_write_watch) { talloc_free(watch); } } /* =Timeouts============================================================== */ static struct timeval _get_interval_tv(int interval) { struct timeval tv; struct timeval rightnow; gettimeofday(&rightnow,NULL); tv.tv_sec = interval / 1000 + rightnow.tv_sec; tv.tv_usec = (interval % 1000) * 1000 + rightnow.tv_usec; return tv; } /* * timeout_handler * Callback for D-BUS to handle timed events */ static void sbus_timeout_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *data) { struct sbus_timeout_ctx *timeout; timeout = talloc_get_type(data, struct sbus_timeout_ctx); dbus_timeout_handle(timeout->dbus_timeout); } /* * add_timeout * Hook for D-BUS to add time-based events to the mainloop */ dbus_bool_t sbus_add_timeout(DBusTimeout *dbus_timeout, void *data) { struct sbus_connection *conn; struct sbus_timeout_ctx *timeout; struct timeval tv; DEBUG(SSSDBG_TRACE_INTERNAL, "%p\n", dbus_timeout); if (!dbus_timeout_get_enabled(dbus_timeout)) { return TRUE; } conn = talloc_get_type(data, struct sbus_connection); timeout = talloc_zero(conn, struct sbus_timeout_ctx); if (!timeout) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of Memory!\n"); return FALSE; } timeout->dbus_timeout = dbus_timeout; tv = _get_interval_tv(dbus_timeout_get_interval(dbus_timeout)); timeout->te = tevent_add_timer(conn->ev, timeout, tv, sbus_timeout_handler, timeout); if (!timeout->te) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up timeout event!\n"); return FALSE; } /* Save the event to the watch object so it can be removed later */ dbus_timeout_set_data(timeout->dbus_timeout, timeout, NULL); return TRUE; } /* * sbus_toggle_timeout * Hook for D-BUS to toggle the enabled/disabled state of a mainloop * event */ void sbus_toggle_timeout(DBusTimeout *dbus_timeout, void *data) { DEBUG(SSSDBG_TRACE_INTERNAL, "%p\n", dbus_timeout); if (dbus_timeout_get_enabled(dbus_timeout)) { sbus_add_timeout(dbus_timeout, data); } else { sbus_remove_timeout(dbus_timeout, data); } } /* * sbus_remove_timeout * Hook for D-BUS to remove time-based events from the mainloop */ void sbus_remove_timeout(DBusTimeout *dbus_timeout, void *data) { void *timeout; DEBUG(SSSDBG_TRACE_INTERNAL, "%p\n", dbus_timeout); timeout = dbus_timeout_get_data(dbus_timeout); /* remove dbus timeout data */ dbus_timeout_set_data(dbus_timeout, NULL, NULL); /* Freeing the event object will remove it from the event loop */ talloc_free(timeout); } sssd-1.13.4/src/PaxHeaders.16287/db0000644000000000000000000000013212703463556013432 xustar0030 mtime=1460561774.883794405 30 atime=1460561776.118798593 30 ctime=1460561774.883794405 sssd-1.13.4/src/db/0000755002412700241270000000000012703463556015163 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_selinux.c0000644000000000000000000000007312703456111016537 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.832794232 sssd-1.13.4/src/db/sysdb_selinux.c0000644002412700241270000002123312703456111020210 0ustar00jhrozekjhrozek00000000000000/* SSSD System Database - SELinux support Copyright (C) Jan Zeleny 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/sss_selinux.h" #include "db/sysdb_selinux.h" #include "db/sysdb_private.h" /* Some generic routines */ enum selinux_entity_type { SELINUX_CONFIG, SELINUX_USER_MAP }; static errno_t sysdb_add_selinux_entity(struct sysdb_ctx *sysdb, struct ldb_dn *dn, const char *objectclass, struct sysdb_attrs *attrs, time_t now) { struct ldb_message *msg; TALLOC_CTX *tmp_ctx; errno_t ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, objectclass); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set map object class [%d]: %s\n", ret, strerror(ret)); return ret; } if (!now) { now = time(NULL); } ret = sysdb_attrs_add_time_t(attrs, SYSDB_CREATE_TIME, now); if (ret) goto done; msg->dn = dn; msg->elements = attrs->a; msg->num_elements = attrs->num; ret = ldb_add(sysdb->ldb, msg); ret = sysdb_error_to_errno(ret); done: if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } static errno_t sysdb_store_selinux_entity(struct sss_domain_info *domain, struct sysdb_attrs *attrs, enum selinux_entity_type type) { TALLOC_CTX *tmp_ctx; bool in_transaction = false; const char *objectclass = NULL; const char *name; char *clean_name; struct ldb_dn *dn = NULL; errno_t sret = EOK; errno_t ret; time_t now; struct sysdb_ctx *sysdb = domain->sysdb; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } switch (type) { case SELINUX_USER_MAP: objectclass = SYSDB_SELINUX_USERMAP_CLASS; ret = sysdb_attrs_get_string(attrs, SYSDB_NAME, &name); if (ret != EOK) { goto done; } ret = sysdb_dn_sanitize(tmp_ctx, name, &clean_name); if (ret != EOK) { goto done; } dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_SEUSERMAP, clean_name, domain->name); break; case SELINUX_CONFIG: objectclass = SYSDB_SELINUX_CLASS; dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_SELINUX_BASE, domain->name); break; } if (type != SELINUX_CONFIG && type != SELINUX_USER_MAP) { DEBUG(SSSDBG_CRIT_FAILURE, "Bad SELinux entity type: [%d]\n", type); ret = EINVAL; goto done; } if (!dn) { ret = ENOMEM; goto done; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; now = time(NULL); ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); if (ret) goto done; ret = sysdb_add_selinux_entity(sysdb, dn, objectclass, attrs, now); if (ret != EOK) { goto done; } ret = sysdb_set_entry_attr(sysdb, dn, attrs, SYSDB_MOD_REP); if (ret != EOK) { goto done; } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } errno_t sysdb_store_selinux_usermap(struct sss_domain_info *domain, struct sysdb_attrs *attrs) { return sysdb_store_selinux_entity(domain, attrs, SELINUX_USER_MAP); } errno_t sysdb_store_selinux_config(struct sss_domain_info *domain, const char *default_user, const char *order) { errno_t ret; struct sysdb_attrs *attrs; attrs = talloc_zero(NULL, struct sysdb_attrs); if (attrs == NULL) { return ENOMEM; } if (!order) { DEBUG(SSSDBG_CRIT_FAILURE, "The SELinux order is missing\n"); return EINVAL; } if (default_user) { ret = sysdb_attrs_add_string(attrs, SYSDB_SELINUX_DEFAULT_USER, default_user); if (ret != EOK) { goto done; } } ret = sysdb_attrs_add_string(attrs, SYSDB_SELINUX_DEFAULT_ORDER, order); if (ret != EOK) { goto done; } ret = sysdb_store_selinux_entity(domain, attrs, SELINUX_CONFIG); done: talloc_free(attrs); return ret; } errno_t sysdb_delete_usermaps(struct sss_domain_info *domain) { struct ldb_dn *dn = NULL; errno_t ret; struct sysdb_ctx *sysdb = domain->sysdb; dn = ldb_dn_new_fmt(sysdb, sysdb->ldb, SYSDB_TMPL_SELINUX_BASE, domain->name); if (!dn) return ENOMEM; ret = sysdb_delete_recursive(sysdb, dn, true); talloc_free(dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_delete_recursive failed.\n"); return ret; } return EOK; } /* --- SYSDB SELinux search routines --- */ errno_t sysdb_get_selinux_usermaps(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char **attrs, size_t *count, struct ldb_message ***messages) { errno_t ret; char *filter; struct ldb_dn *basedn; struct sysdb_ctx *sysdb = domain->sysdb; basedn = ldb_dn_new_fmt(mem_ctx, sysdb_ctx_get_ldb(sysdb), SYSDB_TMPL_SELINUX_BASE, domain->name); if (!basedn) { return ENOMEM; } filter = talloc_asprintf(mem_ctx, "(%s=%s)", SYSDB_OBJECTCLASS, SYSDB_SELINUX_USERMAP_CLASS); if (filter == NULL) { talloc_free(basedn); return ENOMEM; } ret = sysdb_search_entry(mem_ctx, sysdb, basedn, LDB_SCOPE_SUBTREE, filter, attrs, count, messages); talloc_free(basedn); talloc_free(filter); if (ret == ENOENT) { *count = 0; *messages = NULL; } else if (ret) { return ret; } return EOK; } errno_t sysdb_search_selinux_config(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char **attrs, struct ldb_message **_config) { TALLOC_CTX *tmp_ctx; const char *def_attrs[] = { SYSDB_SELINUX_DEFAULT_USER, SYSDB_SELINUX_DEFAULT_ORDER, NULL }; struct ldb_message **msgs; size_t msgs_count; struct ldb_dn *basedn; errno_t ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_SELINUX_BASE, domain->name); if (!basedn) { ret = ENOMEM; goto done; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, basedn, LDB_SCOPE_BASE, NULL, attrs?attrs:def_attrs, &msgs_count, &msgs); if (ret) { goto done; } *_config = talloc_steal(mem_ctx, msgs[0]); done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No SELinux root entry found\n"); } else if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb.c0000644000000000000000000000007312703456111014770 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.829794222 sssd-1.13.4/src/db/sysdb.c0000644002412700241270000015372612703456111016456 0ustar00jhrozekjhrozek00000000000000/* SSSD System Database Copyright (C) 2008-2011 Simo Sorce Copyright (C) 2008-2011 Stephen Gallagher This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/strtonum.h" #include "util/sss_utf8.h" #include "db/sysdb_private.h" #include "confdb/confdb.h" #include #define LDB_MODULES_PATH "LDB_MODULES_PATH" errno_t sysdb_ldb_connect(TALLOC_CTX *mem_ctx, const char *filename, struct ldb_context **_ldb) { int ret; struct ldb_context *ldb; const char *mod_path; if (_ldb == NULL) { return EINVAL; } ldb = ldb_init(mem_ctx, NULL); if (!ldb) { return EIO; } ret = ldb_set_debug(ldb, ldb_debug_messages, NULL); if (ret != LDB_SUCCESS) { return EIO; } mod_path = getenv(LDB_MODULES_PATH); if (mod_path != NULL) { DEBUG(SSSDBG_TRACE_ALL, "Setting ldb module path to [%s].\n", mod_path); ldb_set_modules_dir(ldb, mod_path); } ret = ldb_connect(ldb, filename, 0, NULL); if (ret != LDB_SUCCESS) { return EIO; } *_ldb = ldb; return EOK; } errno_t sysdb_dn_sanitize(TALLOC_CTX *mem_ctx, const char *input, char **sanitized) { struct ldb_val val; errno_t ret = EOK; val.data = (uint8_t *)talloc_strdup(mem_ctx, input); if (!val.data) { return ENOMEM; } /* We can't include the trailing NULL because it would * be escaped and result in an unterminated string */ val.length = strlen(input); *sanitized = ldb_dn_escape_value(mem_ctx, val); if (!*sanitized) { ret = ENOMEM; } talloc_free(val.data); return ret; } struct ldb_dn *sysdb_custom_subtree_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *subtree_name) { errno_t ret; char *clean_subtree; struct ldb_dn *dn = NULL; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return NULL; ret = sysdb_dn_sanitize(tmp_ctx, subtree_name, &clean_subtree); if (ret != EOK) { talloc_free(tmp_ctx); return NULL; } dn = ldb_dn_new_fmt(tmp_ctx, dom->sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE, clean_subtree, dom->name); if (dn) { talloc_steal(mem_ctx, dn); } talloc_free(tmp_ctx); return dn; } struct ldb_dn *sysdb_custom_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *object_name, const char *subtree_name) { errno_t ret; TALLOC_CTX *tmp_ctx; char *clean_name; char *clean_subtree; struct ldb_dn *dn = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return NULL; } ret = sysdb_dn_sanitize(tmp_ctx, object_name, &clean_name); if (ret != EOK) { goto done; } ret = sysdb_dn_sanitize(tmp_ctx, subtree_name, &clean_subtree); if (ret != EOK) { goto done; } dn = ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, SYSDB_TMPL_CUSTOM, clean_name, clean_subtree, dom->name); done: talloc_free(tmp_ctx); return dn; } struct ldb_dn *sysdb_user_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *name) { errno_t ret; char *clean_name; struct ldb_dn *dn; ret = sysdb_dn_sanitize(NULL, name, &clean_name); if (ret != EOK) { return NULL; } dn = ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, SYSDB_TMPL_USER, clean_name, dom->name); talloc_free(clean_name); return dn; } struct ldb_dn *sysdb_user_base_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom) { return ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, SYSDB_TMPL_USER_BASE, dom->name); } struct ldb_dn *sysdb_group_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *name) { errno_t ret; char *clean_name; struct ldb_dn *dn; ret = sysdb_dn_sanitize(NULL, name, &clean_name); if (ret != EOK) { return NULL; } dn = ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, SYSDB_TMPL_GROUP, clean_name, dom->name); talloc_free(clean_name); return dn; } struct ldb_dn *sysdb_group_base_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom) { return ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, SYSDB_TMPL_GROUP_BASE, dom->name); } struct ldb_dn *sysdb_netgroup_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *name) { errno_t ret; char *clean_name; struct ldb_dn *dn; ret = sysdb_dn_sanitize(NULL, name, &clean_name); if (ret != EOK) { return NULL; } dn = ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, SYSDB_TMPL_NETGROUP, clean_name, dom->name); talloc_free(clean_name); return dn; } struct ldb_dn *sysdb_netgroup_base_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom) { return ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, SYSDB_TMPL_NETGROUP_BASE, dom->name); } errno_t sysdb_get_rdn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx, const char *dn, char **_name, char **_val) { errno_t ret; struct ldb_dn *ldb_dn; const char *attr_name = NULL; const struct ldb_val *val; TALLOC_CTX *tmp_ctx; /* We have to create a tmp_ctx here because * ldb_dn_new_fmt() fails if mem_ctx is NULL */ tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ldb_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, "%s", dn); if (ldb_dn == NULL) { ret = ENOMEM; goto done; } if (_name) { attr_name = ldb_dn_get_rdn_name(ldb_dn); if (attr_name == NULL) { ret = EINVAL; goto done; } *_name = talloc_strdup(mem_ctx, attr_name); if (!*_name) { ret = ENOMEM; goto done; } } val = ldb_dn_get_rdn_val(ldb_dn); if (val == NULL) { ret = EINVAL; if (_name) talloc_free(*_name); goto done; } *_val = talloc_strndup(mem_ctx, (char *) val->data, val->length); if (!*_val) { ret = ENOMEM; if (_name) talloc_free(*_name); goto done; } ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } errno_t sysdb_group_dn_name(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx, const char *dn, char **_name) { return sysdb_get_rdn(sysdb, mem_ctx, dn, NULL, _name); } struct ldb_dn *sysdb_domain_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom) { return ldb_dn_new_fmt(mem_ctx, dom->sysdb->ldb, SYSDB_DOM_BASE, dom->name); } struct ldb_dn *sysdb_base_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx) { return ldb_dn_new(mem_ctx, sysdb->ldb, SYSDB_BASE); } struct ldb_context *sysdb_ctx_get_ldb(struct sysdb_ctx *sysdb) { return sysdb->ldb; } struct sysdb_attrs *sysdb_new_attrs(TALLOC_CTX *mem_ctx) { return talloc_zero(mem_ctx, struct sysdb_attrs); } int sysdb_attrs_get_el_ext(struct sysdb_attrs *attrs, const char *name, bool alloc, struct ldb_message_element **el) { struct ldb_message_element *e = NULL; int i; for (i = 0; i < attrs->num; i++) { if (strcasecmp(name, attrs->a[i].name) == 0) e = &(attrs->a[i]); } if (!e && alloc) { e = talloc_realloc(attrs, attrs->a, struct ldb_message_element, attrs->num+1); if (!e) return ENOMEM; attrs->a = e; e[attrs->num].name = talloc_strdup(e, name); if (!e[attrs->num].name) return ENOMEM; e[attrs->num].num_values = 0; e[attrs->num].values = NULL; e[attrs->num].flags = 0; e = &(attrs->a[attrs->num]); attrs->num++; } if (!e) { return ENOENT; } *el = e; return EOK; } int sysdb_attrs_get_el(struct sysdb_attrs *attrs, const char *name, struct ldb_message_element **el) { return sysdb_attrs_get_el_ext(attrs, name, true, el); } int sysdb_attrs_get_string(struct sysdb_attrs *attrs, const char *name, const char **string) { struct ldb_message_element *el; int ret; ret = sysdb_attrs_get_el_ext(attrs, name, false, &el); if (ret) { return ret; } if (el->num_values != 1) { return ERANGE; } *string = (const char *)el->values[0].data; return EOK; } int sysdb_attrs_get_int32_t(struct sysdb_attrs *attrs, const char *name, int32_t *value) { struct ldb_message_element *el; int ret; char *endptr; int32_t val; ret = sysdb_attrs_get_el_ext(attrs, name, false, &el); if (ret) { return ret; } if (el->num_values != 1) { return ERANGE; } errno = 0; val = strtoint32((const char *) el->values[0].data, &endptr, 10); if (errno != 0) return errno; if (*endptr) return EINVAL; *value = val; return EOK; } int sysdb_attrs_get_uint32_t(struct sysdb_attrs *attrs, const char *name, uint32_t *value) { struct ldb_message_element *el; int ret; char *endptr; uint32_t val; ret = sysdb_attrs_get_el_ext(attrs, name, false, &el); if (ret) { return ret; } if (el->num_values != 1) { return ERANGE; } errno = 0; val = strtouint32((const char *) el->values[0].data, &endptr, 10); if (errno != 0) return errno; if (*endptr) return EINVAL; *value = val; return EOK; } int sysdb_attrs_get_uint16_t(struct sysdb_attrs *attrs, const char *name, uint16_t *value) { struct ldb_message_element *el; int ret; char *endptr; uint16_t val; ret = sysdb_attrs_get_el_ext(attrs, name, false, &el); if (ret) { return ret; } if (el->num_values != 1) { return ERANGE; } errno = 0; val = strtouint16((const char *) el->values[0].data, &endptr, 10); if (errno != 0) return errno; if (*endptr) return EINVAL; *value = val; return EOK; } errno_t sysdb_attrs_get_bool(struct sysdb_attrs *attrs, const char *name, bool *value) { struct ldb_message_element *el; int ret; ret = sysdb_attrs_get_el_ext(attrs, name, false, &el); if (ret) { return ret; } if (el->num_values != 1) { return ERANGE; } if (strcmp((const char *)el->values[0].data, "TRUE") == 0) *value = true; else *value = false; return EOK; } const char **sss_ldb_el_to_string_list(TALLOC_CTX *mem_ctx, struct ldb_message_element *el) { unsigned int u; const char **a; a = talloc_zero_array(mem_ctx, const char *, el->num_values + 1); if (a == NULL) { return NULL; } for (u = 0; u < el->num_values; u++) { a[u] = talloc_strndup(a, (const char *)el->values[u].data, el->values[u].length); if (a[u] == NULL) { talloc_free(a); return NULL; } } return a; } int sysdb_attrs_get_string_array(struct sysdb_attrs *attrs, const char *name, TALLOC_CTX *mem_ctx, const char ***string) { struct ldb_message_element *el; int ret; const char **a; ret = sysdb_attrs_get_el_ext(attrs, name, false, &el); if (ret) { return ret; } a = sss_ldb_el_to_string_list(mem_ctx, el); if (a == NULL) { return ENOMEM; } *string = a; return EOK; } static int sysdb_attrs_add_val_int(struct sysdb_attrs *attrs, const char *name, bool check_values, const struct ldb_val *val) { struct ldb_message_element *el = NULL; struct ldb_val *vals; int ret; size_t c; ret = sysdb_attrs_get_el(attrs, name, &el); if (ret != EOK) { return ret; } if (check_values) { for (c = 0; c < el->num_values; c++) { if (val->length == el->values[c].length && memcmp(val->data, el->values[c].data, val->length) == 0) { return EOK; } } } vals = talloc_realloc(attrs->a, el->values, struct ldb_val, el->num_values+1); if (!vals) return ENOMEM; vals[el->num_values] = ldb_val_dup(vals, val); if (vals[el->num_values].data == NULL && vals[el->num_values].length != 0) { return ENOMEM; } el->values = vals; el->num_values++; return EOK; } int sysdb_attrs_add_val(struct sysdb_attrs *attrs, const char *name, const struct ldb_val *val) { return sysdb_attrs_add_val_int(attrs, name, false, val); } /* Check if the same value already exists. */ int sysdb_attrs_add_val_safe(struct sysdb_attrs *attrs, const char *name, const struct ldb_val *val) { return sysdb_attrs_add_val_int(attrs, name, true, val); } int sysdb_attrs_add_string_safe(struct sysdb_attrs *attrs, const char *name, const char *str) { struct ldb_val v; v.data = (uint8_t *)discard_const(str); v.length = strlen(str); return sysdb_attrs_add_val_safe(attrs, name, &v); } int sysdb_attrs_add_string(struct sysdb_attrs *attrs, const char *name, const char *str) { struct ldb_val v; v.data = (uint8_t *)discard_const(str); v.length = strlen(str); return sysdb_attrs_add_val(attrs, name, &v); } int sysdb_attrs_add_lower_case_string(struct sysdb_attrs *attrs, bool safe, const char *name, const char *str) { char *lc_str; int ret; if (attrs == NULL || str == NULL) { return EINVAL; } lc_str = sss_tc_utf8_str_tolower(attrs, str); if (lc_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot convert name to lowercase.\n"); return ENOMEM; } if (safe) { ret = sysdb_attrs_add_string_safe(attrs, name, lc_str); } else { ret = sysdb_attrs_add_string(attrs, name, lc_str); } talloc_free(lc_str); return ret; } int sysdb_attrs_add_mem(struct sysdb_attrs *attrs, const char *name, const void *mem, size_t size) { struct ldb_val v; v.data = discard_const(mem); v.length = size; return sysdb_attrs_add_val(attrs, name, &v); } int sysdb_attrs_add_bool(struct sysdb_attrs *attrs, const char *name, bool value) { if(value) { return sysdb_attrs_add_string(attrs, name, "TRUE"); } return sysdb_attrs_add_string(attrs, name, "FALSE"); } int sysdb_attrs_steal_string(struct sysdb_attrs *attrs, const char *name, char *str) { struct ldb_message_element *el = NULL; struct ldb_val *vals; int ret; ret = sysdb_attrs_get_el(attrs, name, &el); if (ret != EOK) { return ret; } vals = talloc_realloc(attrs->a, el->values, struct ldb_val, el->num_values+1); if (!vals) return ENOMEM; el->values = vals; /* now steal and assign the string */ talloc_steal(el->values, str); el->values[el->num_values].data = (uint8_t *)str; el->values[el->num_values].length = strlen(str); el->num_values++; return EOK; } int sysdb_attrs_add_long(struct sysdb_attrs *attrs, const char *name, long value) { struct ldb_val v; char *str; int ret; str = talloc_asprintf(attrs, "%ld", value); if (!str) return ENOMEM; v.data = (uint8_t *)str; v.length = strlen(str); ret = sysdb_attrs_add_val(attrs, name, &v); talloc_free(str); return ret; } int sysdb_attrs_add_uint32(struct sysdb_attrs *attrs, const char *name, uint32_t value) { unsigned long val = value; struct ldb_val v; char *str; int ret; str = talloc_asprintf(attrs, "%lu", val); if (!str) return ENOMEM; v.data = (uint8_t *)str; v.length = strlen(str); ret = sysdb_attrs_add_val(attrs, name, &v); talloc_free(str); return ret; } int sysdb_attrs_add_time_t(struct sysdb_attrs *attrs, const char *name, time_t value) { long long val = value; struct ldb_val v; char *str; int ret; str = talloc_asprintf(attrs, "%lld", val); if (!str) return ENOMEM; v.data = (uint8_t *)str; v.length = strlen(str); ret = sysdb_attrs_add_val(attrs, name, &v); talloc_free(str); return ret; } int sysdb_attrs_add_lc_name_alias(struct sysdb_attrs *attrs, const char *value) { return sysdb_attrs_add_lower_case_string(attrs, false, SYSDB_NAME_ALIAS, value); } int sysdb_attrs_add_lc_name_alias_safe(struct sysdb_attrs *attrs, const char *value) { return sysdb_attrs_add_lower_case_string(attrs, true, SYSDB_NAME_ALIAS, value); } int sysdb_attrs_copy_values(struct sysdb_attrs *src, struct sysdb_attrs *dst, const char *name) { int ret = EOK; int i; struct ldb_message_element *src_el; ret = sysdb_attrs_get_el(src, name, &src_el); if (ret != EOK) { goto done; } for (i = 0; i < src_el->num_values; i++) { ret = sysdb_attrs_add_val(dst, name, &src_el->values[i]); if (ret != EOK) { goto done; } } done: return ret; } int sysdb_attrs_users_from_str_list(struct sysdb_attrs *attrs, const char *attr_name, const char *domain, const char *const *list) { struct ldb_message_element *el = NULL; struct ldb_val *vals; int i, j, num; char *member; int ret; ret = sysdb_attrs_get_el(attrs, attr_name, &el); if (ret) { return ret; } for (num = 0; list[num]; num++) /* count */ ; vals = talloc_realloc(attrs->a, el->values, struct ldb_val, el->num_values + num); if (!vals) { return ENOMEM; } el->values = vals; DEBUG(SSSDBG_TRACE_ALL, "Adding %d members to existing %d ones\n", num, el->num_values); for (i = 0, j = el->num_values; i < num; i++) { member = sysdb_user_strdn(el->values, domain, list[i]); if (!member) { DEBUG(SSSDBG_CONF_SETTINGS, "Failed to get user dn for [%s]\n", list[i]); continue; } el->values[j].data = (uint8_t *)member; el->values[j].length = strlen(member); j++; DEBUG(SSSDBG_TRACE_LIBS, " member #%d: [%s]\n", i, member); } el->num_values = j; return EOK; } static char *build_dom_dn_str_escape(TALLOC_CTX *mem_ctx, const char *template, const char *domain, const char *name) { char *ret; int l; l = strcspn(name, ",=\n+<>#;\\\""); if (name[l] != '\0') { struct ldb_val v; char *tmp; v.data = discard_const_p(uint8_t, name); v.length = strlen(name); tmp = ldb_dn_escape_value(mem_ctx, v); if (!tmp) { return NULL; } ret = talloc_asprintf(mem_ctx, template, tmp, domain); talloc_zfree(tmp); if (!ret) { return NULL; } return ret; } ret = talloc_asprintf(mem_ctx, template, name, domain); if (!ret) { return NULL; } return ret; } char *sysdb_user_strdn(TALLOC_CTX *mem_ctx, const char *domain, const char *name) { return build_dom_dn_str_escape(mem_ctx, SYSDB_TMPL_USER, domain, name); } char *sysdb_group_strdn(TALLOC_CTX *mem_ctx, const char *domain, const char *name) { return build_dom_dn_str_escape(mem_ctx, SYSDB_TMPL_GROUP, domain, name); } /* TODO: make a more complete and precise mapping */ int sysdb_error_to_errno(int ldberr) { switch (ldberr) { case LDB_SUCCESS: return EOK; case LDB_ERR_OPERATIONS_ERROR: return EIO; case LDB_ERR_NO_SUCH_OBJECT: return ENOENT; case LDB_ERR_BUSY: return EBUSY; case LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS: case LDB_ERR_ENTRY_ALREADY_EXISTS: return EEXIST; case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX: return EINVAL; default: DEBUG(SSSDBG_CRIT_FAILURE, "LDB returned unexpected error: [%s]\n", ldb_strerror(ldberr)); return EFAULT; } } /* =Transactions========================================================== */ int sysdb_transaction_start(struct sysdb_ctx *sysdb) { int ret; ret = ldb_transaction_start(sysdb->ldb); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start ldb transaction! (%d)\n", ret); } return sysdb_error_to_errno(ret); } int sysdb_transaction_commit(struct sysdb_ctx *sysdb) { int ret; ret = ldb_transaction_commit(sysdb->ldb); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit ldb transaction! (%d)\n", ret); } return sysdb_error_to_errno(ret); } int sysdb_transaction_cancel(struct sysdb_ctx *sysdb) { int ret; ret = ldb_transaction_cancel(sysdb->ldb); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel ldb transaction! (%d)\n", ret); } return sysdb_error_to_errno(ret); } /* =Initialization======================================================== */ int sysdb_get_db_file(TALLOC_CTX *mem_ctx, const char *provider, const char *name, const char *base_path, char **_ldb_file) { char *ldb_file; /* special case for the local domain */ if (strcasecmp(provider, "local") == 0) { ldb_file = talloc_asprintf(mem_ctx, "%s/"LOCAL_SYSDB_FILE, base_path); } else { ldb_file = talloc_asprintf(mem_ctx, "%s/"CACHE_SYSDB_FILE, base_path, name); } if (!ldb_file) { return ENOMEM; } *_ldb_file = ldb_file; return EOK; } errno_t sysdb_domain_create(struct sysdb_ctx *sysdb, const char *domain_name) { struct ldb_message *msg; TALLOC_CTX *tmp_ctx; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } /* == create base domain object == */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new_fmt(msg, sysdb->ldb, SYSDB_DOM_BASE, domain_name); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "cn", domain_name); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } /* do a synchronous add */ ret = ldb_add(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to initialize DB (%d, [%s]) " "for domain %s!\n", ret, ldb_errstring(sysdb->ldb), domain_name); ret = EIO; goto done; } talloc_zfree(msg); /* == create Users tree == */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new_fmt(msg, sysdb->ldb, SYSDB_TMPL_USER_BASE, domain_name); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "cn", "Users"); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } /* do a synchronous add */ ret = ldb_add(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to initialize DB (%d, [%s]) " "for domain %s!\n", ret, ldb_errstring(sysdb->ldb), domain_name); ret = EIO; goto done; } talloc_zfree(msg); /* == create Groups tree == */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new_fmt(msg, sysdb->ldb, SYSDB_TMPL_GROUP_BASE, domain_name); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "cn", "Groups"); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } /* do a synchronous add */ ret = ldb_add(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to initialize DB (%d, [%s]) for " "domain %s!\n", ret, ldb_errstring(sysdb->ldb), domain_name); ret = EIO; goto done; } talloc_zfree(msg); ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } /* Compare versions of sysdb, returns ERRNO accordingly */ static errno_t sysdb_version_check(const char *expected, const char *received) { int ret; unsigned int exp_major, exp_minor, recv_major, recv_minor; ret = sscanf(expected, "%u.%u", &exp_major, &exp_minor); if (ret != 2) { return EINVAL; } ret = sscanf(received, "%u.%u", &recv_major, &recv_minor); if (ret != 2) { return EINVAL; } if (recv_major > exp_major) { return EUCLEAN; } else if (recv_major < exp_major) { return EMEDIUMTYPE; } if (recv_minor > exp_minor) { return EUCLEAN; } else if (recv_minor < exp_minor) { return EMEDIUMTYPE; } return EOK; } int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *db_path, bool allow_upgrade, struct sysdb_ctx **_ctx) { TALLOC_CTX *tmp_ctx = NULL; struct sysdb_ctx *sysdb; const char *base_ldif; struct ldb_ldif *ldif; struct ldb_message_element *el; struct ldb_result *res; struct ldb_dn *verdn; const char *version = NULL; int ret; sysdb = talloc_zero(mem_ctx, struct sysdb_ctx); if (!sysdb) { return ENOMEM; } ret = sysdb_get_db_file(sysdb, domain->provider, domain->name, db_path, &sysdb->ldb_file); if (ret != EOK) { goto done; } DEBUG(SSSDBG_FUNC_DATA, "DB File for %s: %s\n", domain->name, sysdb->ldb_file); ret = sysdb_ldb_connect(sysdb, sysdb->ldb_file, &sysdb->ldb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_ldb_connect failed.\n"); goto done; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } verdn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE); if (!verdn) { ret = EIO; goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, verdn, LDB_SCOPE_BASE, NULL, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } if (res->count > 1) { ret = EIO; goto done; } if (res->count == 1) { el = ldb_msg_find_element(res->msgs[0], "version"); if (!el) { ret = EIO; goto done; } if (el->num_values != 1) { ret = EINVAL; goto done; } version = talloc_strndup(tmp_ctx, (char *)(el->values[0].data), el->values[0].length); if (!version) { ret = ENOMEM; goto done; } if (strcmp(version, SYSDB_VERSION) == 0) { /* all fine, return */ ret = EOK; goto done; } if (!allow_upgrade) { DEBUG(SSSDBG_FATAL_FAILURE, "Wrong DB version (got %s expected %s)\n", version, SYSDB_VERSION); ret = sysdb_version_check(SYSDB_VERSION, version); goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Upgrading DB [%s] from version: %s\n", domain->name, version); if (strcmp(version, SYSDB_VERSION_0_3) == 0) { ret = sysdb_upgrade_03(sysdb, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_4) == 0) { ret = sysdb_upgrade_04(sysdb, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_5) == 0) { ret = sysdb_upgrade_05(sysdb, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_6) == 0) { ret = sysdb_upgrade_06(sysdb, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_7) == 0) { ret = sysdb_upgrade_07(sysdb, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_8) == 0) { ret = sysdb_upgrade_08(sysdb, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_9) == 0) { ret = sysdb_upgrade_09(sysdb, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_10) == 0) { ret = sysdb_upgrade_10(sysdb, domain, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_11) == 0) { ret = sysdb_upgrade_11(sysdb, domain, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_12) == 0) { ret = sysdb_upgrade_12(sysdb, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_13) == 0) { ret = sysdb_upgrade_13(sysdb, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_14) == 0) { ret = sysdb_upgrade_14(sysdb, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_15) == 0) { ret = sysdb_upgrade_15(sysdb, &version); if (ret != EOK) { goto done; } } if (strcmp(version, SYSDB_VERSION_0_16) == 0) { ret = sysdb_upgrade_16(sysdb, &version); if (ret != EOK) { goto done; } } /* The version should now match SYSDB_VERSION. * If not, it means we didn't match any of the * known older versions. The DB might be * corrupt or generated by a newer version of * SSSD. */ if (strcmp(version, SYSDB_VERSION) == 0) { /* The cache has been upgraded. * We need to reopen the LDB to ensure that * any changes made above take effect. */ talloc_zfree(sysdb->ldb); ret = sysdb_ldb_connect(sysdb, sysdb->ldb_file, &sysdb->ldb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_ldb_connect failed.\n"); } goto done; } DEBUG(SSSDBG_FATAL_FAILURE, "Unknown DB version [%s], expected [%s] for domain %s!\n", version, SYSDB_VERSION, domain->name); ret = sysdb_version_check(SYSDB_VERSION, version); goto done; } /* SYSDB_BASE does not exists, means db is empty, populate */ base_ldif = SYSDB_BASE_LDIF; while ((ldif = ldb_ldif_read_string(sysdb->ldb, &base_ldif))) { ret = ldb_add(sysdb->ldb, ldif->msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to initialize DB (%d, [%s]) for domain %s!\n", ret, ldb_errstring(sysdb->ldb), domain->name); ret = EIO; goto done; } ldb_ldif_read_free(sysdb->ldb, ldif); } ret = sysdb_domain_create(sysdb, domain->name); if (ret != EOK) { goto done; } /* The cache has been newly created. * We need to reopen the LDB to ensure that * all of the special values take effect * (such as enabling the memberOf plugin and * the various indexes). */ talloc_zfree(sysdb->ldb); ret = sysdb_ldb_connect(sysdb, sysdb->ldb_file, &sysdb->ldb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_ldb_connect failed.\n"); } done: talloc_free(tmp_ctx); if (ret == EOK) { *_ctx = sysdb; } else { talloc_free(sysdb); } return ret; } int sysdb_init(TALLOC_CTX *mem_ctx, struct sss_domain_info *domains, bool allow_upgrade) { return sysdb_init_ext(mem_ctx, domains, allow_upgrade, false, 0, 0); } int sysdb_init_ext(TALLOC_CTX *mem_ctx, struct sss_domain_info *domains, bool allow_upgrade, bool chown_dbfile, uid_t uid, gid_t gid) { struct sss_domain_info *dom; struct sysdb_ctx *sysdb; int ret; if (allow_upgrade) { /* check if we have an old sssd.ldb to upgrade */ ret = sysdb_check_upgrade_02(domains, DB_PATH); if (ret != EOK) { return ret; } } /* open a db for each domain */ for (dom = domains; dom; dom = dom->next) { ret = sysdb_domain_init_internal(mem_ctx, dom, DB_PATH, allow_upgrade, &sysdb); if (ret != EOK) { return ret; } if (chown_dbfile) { ret = chown(sysdb->ldb_file, uid, gid); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set sysdb ownership to %"SPRIuid":%"SPRIgid"\n", uid, gid); return ret; } } dom->sysdb = talloc_move(dom, &sysdb); } return EOK; } int sysdb_domain_init(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *db_path, struct sysdb_ctx **_ctx) { return sysdb_domain_init_internal(mem_ctx, domain, db_path, false, _ctx); } int compare_ldb_dn_comp_num(const void *m1, const void *m2) { struct ldb_message *msg1 = talloc_get_type(*(void **) discard_const(m1), struct ldb_message); struct ldb_message *msg2 = talloc_get_type(*(void **) discard_const(m2), struct ldb_message); return ldb_dn_get_comp_num(msg2->dn) - ldb_dn_get_comp_num(msg1->dn); } int sysdb_attrs_replace_name(struct sysdb_attrs *attrs, const char *oldname, const char *newname) { struct ldb_message_element *e = NULL; int i; const char *dummy; if (attrs == NULL || oldname == NULL || newname == NULL) return EINVAL; for (i = 0; i < attrs->num; i++) { if (strcasecmp(oldname, attrs->a[i].name) == 0) { e = &(attrs->a[i]); } if (strcasecmp(newname, attrs->a[i].name) == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "New attribute name [%s] already exists.\n", newname); return EEXIST; } } if (e != NULL) { dummy = talloc_strdup(attrs, newname); if (dummy == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); return ENOMEM; } talloc_free(discard_const(e->name)); e->name = dummy; } return EOK; } /* Search for all incidences of attr_name in a list of * sysdb_attrs and add their value to a list * * TODO: Currently only works for single-valued * attributes. Multi-valued attributes will return * only the first entry */ errno_t sysdb_attrs_to_list(TALLOC_CTX *mem_ctx, struct sysdb_attrs **attrs, int attr_count, const char *attr_name, char ***_list) { int attr_idx; int i; char **list; char **tmp_list; int list_idx; *_list = NULL; /* Assume that every attrs entry contains the attr_name * This may waste a little memory if some entries don't * have the attribute, but it will save us the trouble * of continuously resizing the array. */ list = talloc_array(mem_ctx, char *, attr_count+1); if (!list) { return ENOMEM; } list_idx = 0; /* Loop through all entries in attrs */ for (attr_idx = 0; attr_idx < attr_count; attr_idx++) { /* Examine each attribute within the entry */ for (i = 0; i < attrs[attr_idx]->num; i++) { if (strcasecmp(attrs[attr_idx]->a[i].name, attr_name) == 0) { /* Attribute name matches the requested name * Copy it to the output list */ list[list_idx] = talloc_strdup( list, (const char *)attrs[attr_idx]->a[i].values[0].data); if (!list[list_idx]) { talloc_free(list); return ENOMEM; } list_idx++; /* We only support single-valued attributes * Break here and go on to the next entry */ break; } } } list[list_idx] = NULL; /* if list_idx < attr_count, do a realloc to * reclaim unused memory */ if (list_idx < attr_count) { tmp_list = talloc_realloc(mem_ctx, list, char *, list_idx+1); if (!tmp_list) { talloc_zfree(list); return ENOMEM; } list = tmp_list; } *_list = list; return EOK; } errno_t sysdb_get_bool(struct sysdb_ctx *sysdb, struct ldb_dn *dn, const char *attr_name, bool *value) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; errno_t ret; int lret; const char *attrs[2] = {attr_name, NULL}; struct ldb_message_element *el; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } lret = ldb_search(sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } if (res->count == 0) { /* This entry has not been populated in LDB * This is a common case, as unlike LDAP, * LDB does not need to have all of its parent * objects actually exist. * This object in the sysdb exists mostly just * to contain this attribute. */ *value = false; ret = ENOENT; goto done; } else if (res->count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Got more than one reply for base search!\n"); ret = EIO; goto done; } el = ldb_msg_find_element(res->msgs[0], attr_name); if (el == NULL || el->num_values == 0) { ret = ENOENT; goto done; } *value = ldb_msg_find_attr_as_bool(res->msgs[0], attr_name, false); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_set_bool(struct sysdb_ctx *sysdb, struct ldb_dn *dn, const char *cn_value, const char *attr_name, bool value) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_message *msg = NULL; struct ldb_result *res = NULL; errno_t ret; int lret; if (dn == NULL || cn_value == NULL || attr_name == NULL) { return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } lret = ldb_search(sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = dn; if (res->count == 0) { lret = ldb_msg_add_string(msg, "cn", cn_value); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } else if (res->count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Got more than one reply for base search!\n"); ret = EIO; goto done; } else { lret = ldb_msg_add_empty(msg, attr_name, LDB_FLAG_MOD_REPLACE, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } lret = ldb_msg_add_string(msg, attr_name, value ? "TRUE" : "FALSE"); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } if (res->count) { lret = ldb_modify(sysdb->ldb, msg); } else { lret = ldb_add(sysdb->ldb, msg); } if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb operation failed: [%s](%d)[%s]\n", ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)); } ret = sysdb_error_to_errno(lret); done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_has_enumerated(struct sss_domain_info *domain, bool *has_enumerated) { errno_t ret; struct ldb_dn *dn; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_DOM_BASE, domain->name); if (!dn) { ret = ENOMEM; goto done; } ret = sysdb_get_bool(domain->sysdb, dn, SYSDB_HAS_ENUMERATED, has_enumerated); done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_set_enumerated(struct sss_domain_info *domain, bool enumerated) { errno_t ret; TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_DOM_BASE, domain->name); if (!dn) { ret = ENOMEM; goto done; } ret = sysdb_set_bool(domain->sysdb, dn, domain->name, SYSDB_HAS_ENUMERATED, enumerated); done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_attrs_primary_name(struct sysdb_ctx *sysdb, struct sysdb_attrs *attrs, const char *ldap_attr, const char **_primary) { errno_t ret; char *rdn_attr = NULL; char *rdn_val = NULL; struct ldb_message_element *sysdb_name_el; struct ldb_message_element *orig_dn_el; size_t i; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_attrs_get_el(attrs, SYSDB_NAME, &sysdb_name_el); if (ret != EOK || sysdb_name_el->num_values == 0) { ret = EINVAL; goto done; } if (sysdb_name_el->num_values == 1) { /* Entry contains only one name. Just return that */ *_primary = (const char *)sysdb_name_el->values[0].data; ret = EOK; goto done; } /* Multiple values for name. Check whether one matches the RDN */ ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &orig_dn_el); if (ret) { goto done; } if (orig_dn_el->num_values == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Original DN is not available.\n"); ret = EINVAL; goto done; } else if (orig_dn_el->num_values == 1) { ret = sysdb_get_rdn(sysdb, tmp_ctx, (const char *) orig_dn_el->values[0].data, &rdn_attr, &rdn_val); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get rdn from [%s]\n", (const char *) orig_dn_el->values[0].data); goto done; } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Should not have more than one origDN\n"); ret = EINVAL; goto done; } /* First check whether the attribute name matches */ DEBUG(SSSDBG_TRACE_INTERNAL, "Comparing attribute names [%s] and [%s]\n", rdn_attr, ldap_attr); if (strcasecmp(rdn_attr, ldap_attr) != 0) { /* Multiple entries, and the RDN attribute doesn't match. * We have no way of resolving this deterministically, * so we'll use the first value as a fallback. */ DEBUG(SSSDBG_MINOR_FAILURE, "The entry has multiple names and the RDN attribute does " "not match. Will use the first value as fallback.\n"); *_primary = (const char *)sysdb_name_el->values[0].data; ret = EOK; goto done; } for (i = 0; i < sysdb_name_el->num_values; i++) { if (strcasecmp(rdn_val, (const char *)sysdb_name_el->values[i].data) == 0) { /* This name matches the RDN. Use it */ break; } } if (i < sysdb_name_el->num_values) { /* Match was found */ *_primary = (const char *)sysdb_name_el->values[i].data; } else { /* If we can't match the name to the RDN, we just have to * throw up our hands. There's no deterministic way to * decide which name is correct. */ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot save entry. Unable to determine groupname\n"); ret = EINVAL; goto done; } ret = EOK; done: if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not determine primary name: [%d][%s]\n", ret, strerror(ret)); } talloc_free(tmp_ctx); return ret; } /* * An entity with multiple names would have multiple SYSDB_NAME attributes * after being translated into sysdb names using a map. * Given a primary name returned by sysdb_attrs_primary_name(), this function * returns the other SYSDB_NAME attribute values so they can be saved as * SYSDB_NAME_ALIAS into cache. * * If lowercase is set, all aliases are duplicated in lowercase as well. */ errno_t sysdb_attrs_get_aliases(TALLOC_CTX *mem_ctx, struct sysdb_attrs *attrs, const char *primary, bool lowercase, const char ***_aliases) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_message_element *sysdb_name_el; size_t i, j, ai; errno_t ret; const char **aliases = NULL; const char *name; char *lower; if (_aliases == NULL) return EINVAL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_attrs_get_el(attrs, SYSDB_NAME, &sysdb_name_el); if (ret != EOK || sysdb_name_el->num_values == 0) { ret = EINVAL; goto done; } aliases = talloc_array(tmp_ctx, const char *, sysdb_name_el->num_values + 1); if (!aliases) { ret = ENOMEM; goto done; } if (lowercase) { DEBUG(SSSDBG_TRACE_INTERNAL, "Domain is case-insensitive; will add lowercased aliases\n"); } ai = 0; for (i=0; i < sysdb_name_el->num_values; i++) { name = (const char *)sysdb_name_el->values[i].data; if (lowercase) { /* Domain is case-insensitive. Save the lower-cased version */ lower = sss_tc_utf8_str_tolower(tmp_ctx, name); if (!lower) { ret = ENOMEM; goto done; } for (j=0; j < ai; j++) { if (sss_utf8_case_eq((const uint8_t *) aliases[j], (const uint8_t *) lower) == ENOMATCH) { break; } } if (ai == 0 || j < ai) { aliases[ai] = talloc_strdup(aliases, lower); if (!aliases[ai]) { ret = ENOMEM; goto done; } ai++; } } else { /* Domain is case-sensitive. Save it as-is */ if (strcmp(primary, name) != 0) { aliases[ai] = talloc_strdup(aliases, name); if (!aliases[ai]) { ret = ENOMEM; goto done; } ai++; } } } aliases[ai] = NULL; ret = EOK; done: *_aliases = talloc_steal(mem_ctx, aliases); talloc_free(tmp_ctx); return ret; } errno_t sysdb_attrs_primary_name_list(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx, struct sysdb_attrs **attr_list, size_t attr_count, const char *ldap_attr, char ***name_list) { errno_t ret; size_t i, j; char **list; const char *name; /* Assume that every entry has a primary name */ list = talloc_array(mem_ctx, char *, attr_count+1); if (!list) { return ENOMEM; } j = 0; for (i = 0; i < attr_count; i++) { ret = sysdb_attrs_primary_name(sysdb, attr_list[i], ldap_attr, &name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not determine primary name\n"); /* Skip and continue. Don't advance 'j' */ continue; } list[j] = talloc_strdup(list, name); if (!list[j]) { ret = ENOMEM; goto done; } j++; } /* NULL-terminate the list */ list[j] = NULL; *name_list = list; ret = EOK; done: if (ret != EOK) { talloc_free(list); } return ret; } errno_t sysdb_msg2attrs(TALLOC_CTX *mem_ctx, size_t count, struct ldb_message **msgs, struct sysdb_attrs ***attrs) { int i; struct sysdb_attrs **a; a = talloc_array(mem_ctx, struct sysdb_attrs *, count); if (a == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array failed.\n"); return ENOMEM; } for (i = 0; i < count; i++) { a[i] = talloc(a, struct sysdb_attrs); if (a[i] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); talloc_free(a); return ENOMEM; } a[i]->num = msgs[i]->num_elements; a[i]->a = talloc_steal(a[i], msgs[i]->elements); } *attrs = a; return EOK; } int sysdb_compare_usn(const char *a, const char *b) { size_t len_a; size_t len_b; if (a == NULL) { return -1; } if (b == NULL) { return 1; } len_a = strlen(a); len_b = strlen(b); /* trim leading zeros */ while (len_a > 0 && *a == '0') { a++; len_a--; } while (len_b > 0 && *b == '0') { b++; len_b--; } /* less digits means lower number */ if (len_a < len_b) { return -1; } /* more digits means bigger number */ if (len_a > len_b) { return 1; } /* now we can compare digits since alphabetical order is the same * as numeric order */ return strcmp(a, b); } errno_t sysdb_get_highest_usn(TALLOC_CTX *mem_ctx, struct sysdb_attrs **attrs, size_t num_attrs, char **_usn) { const char *highest = NULL; const char *current = NULL; char *usn; errno_t ret; size_t i; if (num_attrs == 0 || attrs == NULL) { goto done; } for (i = 0; i < num_attrs; i++) { ret = sysdb_attrs_get_string(attrs[i], SYSDB_USN, ¤t); if (ret == ENOENT) { /* USN value is not present, assuming zero. */ current = "0"; } else if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to retrieve USN value " "[%d]: %s\n", ret, sss_strerror(ret)); return ret; } if (current == NULL) { continue; } if (highest == NULL) { highest = current; continue; } if (sysdb_compare_usn(current, highest) > 0 ) { highest = current; } } done: if (highest == NULL) { usn = talloc_strdup(mem_ctx, "0"); } else { usn = talloc_strdup(mem_ctx, highest); } if (usn == NULL) { return ENOMEM; } *_usn = usn; return EOK; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_upgrade.c0000644000000000000000000000007312703456111016477 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.833794236 sssd-1.13.4/src/db/sysdb_upgrade.c0000644002412700241270000012672212703456111020161 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Simo Sorce Stephen Gallagher Copyright (C) 2008-2011 Simo Sorce Copyright (C) 2008-2011 Stephen Gallagher This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb_private.h" #include "db/sysdb_autofs.h" struct upgrade_ctx { struct ldb_context *ldb; const char *new_version; }; static errno_t commence_upgrade(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *new_ver, struct upgrade_ctx **_ctx) { struct upgrade_ctx *ctx; int ret; DEBUG(SSSDBG_CRIT_FAILURE, "UPGRADING DB TO VERSION %s\n", new_ver); ctx = talloc(mem_ctx, struct upgrade_ctx); if (!ctx) { return ENOMEM; } ctx->ldb = ldb; ctx->new_version = new_ver; ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } ret = EOK; done: if (ret != EOK) { talloc_free(ctx); } else { *_ctx = ctx; } return ret; } static errno_t update_version(struct upgrade_ctx *ctx) { struct ldb_message *msg = NULL; errno_t ret; msg = ldb_msg_new(ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(msg, ctx->ldb, SYSDB_BASE); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "version", ctx->new_version); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(ctx->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = EOK; done: talloc_free(msg); return ret; } static int finish_upgrade(int ret, struct upgrade_ctx **ctx, const char **ver) { int lret; if (ret == EOK) { lret = ldb_transaction_commit((*ctx)->ldb); ret = sysdb_error_to_errno(lret); if (ret == EOK) { *ver = (*ctx)->new_version; } } if (ret != EOK) { lret = ldb_transaction_cancel((*ctx)->ldb); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction! [%s]\n", ldb_strerror(lret)); /* Do not overwrite ret here, we want to return * the original failure, not the failure of the * transaction cancellation. */ } } talloc_zfree(*ctx); return ret; } /* serach all groups that have a memberUid attribute. * change it into a member attribute for a user of same domain. * remove the memberUid attribute * add the new member attribute * finally stop indexing memberUid * upgrade version to 0.2 */ int sysdb_upgrade_01(struct ldb_context *ldb, const char **ver) { struct ldb_message_element *el; struct ldb_result *res; struct ldb_dn *basedn; struct ldb_dn *mem_dn; struct ldb_message *msg; const struct ldb_val *val; const char *filter = "(&(memberUid=*)(objectclass=group))"; const char *attrs[] = { "memberUid", NULL }; const char *mdn; char *domain; int ret, i, j; TALLOC_CTX *tmp_ctx; struct upgrade_ctx *ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = commence_upgrade(tmp_ctx, ldb, SYSDB_VERSION_0_2, &ctx); if (ret) { talloc_free(tmp_ctx); return ret; } basedn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); if (!basedn) { ret = EIO; goto done; } ret = ldb_search(ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, "%s", filter); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } for (i = 0; i < res->count; i++) { el = ldb_msg_find_element(res->msgs[i], "memberUid"); if (!el) { DEBUG(SSSDBG_CRIT_FAILURE, "memberUid is missing from message [%s], skipping\n", ldb_dn_get_linearized(res->msgs[i]->dn)); continue; } /* create modification message */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = res->msgs[i]->dn; ret = ldb_msg_add_empty(msg, "memberUid", LDB_FLAG_MOD_DELETE, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, SYSDB_MEMBER, LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } /* get domain name component value */ val = ldb_dn_get_component_val(res->msgs[i]->dn, 2); domain = talloc_strndup(tmp_ctx, (const char *)val->data, val->length); if (!domain) { ret = ENOMEM; goto done; } for (j = 0; j < el->num_values; j++) { mem_dn = ldb_dn_new_fmt(tmp_ctx, ldb, SYSDB_TMPL_USER, (const char *)el->values[j].data, domain); if (!mem_dn) { ret = ENOMEM; goto done; } mdn = talloc_strdup(msg, ldb_dn_get_linearized(mem_dn)); if (!mdn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, SYSDB_MEMBER, mdn); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } talloc_zfree(mem_dn); } /* ok now we are ready to modify the entry */ ret = ldb_modify(ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } talloc_zfree(msg); } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_check_upgrade_02(struct sss_domain_info *domains, const char *db_path) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_context *ldb; char *ldb_file; struct sysdb_ctx *sysdb; struct sss_domain_info *dom; struct ldb_message_element *el; struct ldb_message *msg; struct ldb_result *res; struct ldb_dn *verdn; const char *version = NULL; bool do_02_upgrade = false; bool ctx_trans = false; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_get_db_file(tmp_ctx, "local", "UPGRADE", db_path, &ldb_file); if (ret != EOK) { goto exit; } ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_ldb_connect failed.\n"); return ret; } verdn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); if (!verdn) { ret = EIO; goto exit; } ret = ldb_search(ldb, tmp_ctx, &res, verdn, LDB_SCOPE_BASE, NULL, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto exit; } if (res->count > 1) { ret = EIO; goto exit; } if (res->count == 1) { el = ldb_msg_find_element(res->msgs[0], "version"); if (el) { if (el->num_values != 1) { ret = EINVAL; goto exit; } version = talloc_strndup(tmp_ctx, (char *)(el->values[0].data), el->values[0].length); if (!version) { ret = ENOMEM; goto exit; } if (strcmp(version, SYSDB_VERSION) == 0) { /* all fine, return */ ret = EOK; goto exit; } DEBUG(SSSDBG_CONF_SETTINGS, "Upgrading DB from version: %s\n", version); if (strcmp(version, SYSDB_VERSION_0_1) == 0) { /* convert database */ ret = sysdb_upgrade_01(ldb, &version); if (ret != EOK) goto exit; } if (strcmp(version, SYSDB_VERSION_0_2) == 0) { /* need to convert database to split files */ do_02_upgrade = true; } } } if (!do_02_upgrade) { /* not a v2 upgrade, return and let the normal code take over any * further upgrade */ ret = EOK; goto exit; } /* == V2->V3 UPGRADE == */ DEBUG(SSSDBG_FATAL_FAILURE, "UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_3); /* ldb uses posix locks, * posix is stupid and kills all locks when you close *any* file * descriptor associated to the same file. * Therefore we must close and reopen the ldb file here */ /* == Backup and reopen ldb == */ /* close */ talloc_zfree(ldb); /* backup*/ ret = backup_file(ldb_file, SSSDBG_FATAL_FAILURE); if (ret != EOK) { goto exit; } /* reopen */ ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_ldb_connect failed.\n"); return ret; } /* open a transaction */ ret = ldb_transaction_start(ldb); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start ldb transaction! (%d)\n", ret); ret = EIO; goto exit; } /* == Upgrade contents == */ for (dom = domains; dom; dom = dom->next) { struct ldb_dn *domain_dn; struct ldb_dn *users_dn; struct ldb_dn *groups_dn; int i; /* skip local */ if (strcasecmp(dom->provider, "local") == 0) { continue; } /* create new dom db */ ret = sysdb_domain_init_internal(tmp_ctx, dom, db_path, false, &sysdb); if (ret != EOK) { goto done; } ret = ldb_transaction_start(sysdb->ldb); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start ldb transaction! (%d)\n", ret); ret = EIO; goto done; } ctx_trans = true; /* search all entries for this domain in local, * copy them all in the new database, * then remove them from local */ domain_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, dom->name); if (!domain_dn) { ret = ENOMEM; goto done; } ret = ldb_search(ldb, tmp_ctx, &res, domain_dn, LDB_SCOPE_SUBTREE, NULL, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } users_dn = sysdb_user_base_dn(tmp_ctx, dom); if (!users_dn) { ret = ENOMEM; goto done; } groups_dn = sysdb_group_base_dn(tmp_ctx, dom); if (!groups_dn) { ret = ENOMEM; goto done; } for (i = 0; i < res->count; i++) { struct ldb_dn *orig_dn; msg = res->msgs[i]; /* skip pre-created congtainers */ if ((ldb_dn_compare(msg->dn, domain_dn) == 0) || (ldb_dn_compare(msg->dn, users_dn) == 0) || (ldb_dn_compare(msg->dn, groups_dn) == 0)) { continue; } /* regenerate the DN against the new ldb as it may have different * casefolding rules (example: name changing from case insensitive * to case sensitive) */ orig_dn = msg->dn; msg->dn = ldb_dn_new(msg, sysdb->ldb, ldb_dn_get_linearized(orig_dn)); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_add(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "WARNING: Could not add entry %s," " to new ldb file! (%d [%s])\n", ldb_dn_get_linearized(msg->dn), ret, ldb_errstring(sysdb->ldb)); } ret = ldb_delete(ldb, orig_dn); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "WARNING: Could not remove entry %s," " from old ldb file! (%d [%s])\n", ldb_dn_get_linearized(orig_dn), ret, ldb_errstring(ldb)); } } /* now remove the basic containers from local */ /* these were optional so debug at level 9 in case * of failure just for tracing */ ret = ldb_delete(ldb, groups_dn); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s," " from old ldb file! (%d [%s])\n", ldb_dn_get_linearized(groups_dn), ret, ldb_errstring(ldb)); } ret = ldb_delete(ldb, users_dn); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s," " from old ldb file! (%d [%s])\n", ldb_dn_get_linearized(users_dn), ret, ldb_errstring(ldb)); } ret = ldb_delete(ldb, domain_dn); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s," " from old ldb file! (%d [%s])\n", ldb_dn_get_linearized(domain_dn), ret, ldb_errstring(ldb)); } ret = ldb_transaction_commit(sysdb->ldb); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit ldb transaction! (%d)\n", ret); ret = EIO; goto done; } ctx_trans = false; talloc_zfree(domain_dn); talloc_zfree(groups_dn); talloc_zfree(users_dn); talloc_zfree(res); } /* conversion done, upgrade version number */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_3); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_transaction_commit(ldb); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit ldb transaction! (%d)\n", ret); ret = EIO; goto exit; } ret = EOK; done: if (ret != EOK) { if (ctx_trans) { ret = ldb_transaction_cancel(sysdb->ldb); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel ldb transaction! (%d)\n", ret); } } ret = ldb_transaction_cancel(ldb); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel ldb transaction! (%d)\n", ret); } } exit: talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_03(struct sysdb_ctx *sysdb, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_message *msg; struct upgrade_ctx *ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_4, &ctx); if (ret) { return ret; } /* Make this database case-sensitive */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_DELETE, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_04(struct sysdb_ctx *sysdb, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_message *msg; struct upgrade_ctx *ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_5, &ctx); if (ret) { return ret; } /* Add new index */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "@IDXATTR", "originalDN"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } /* Rebuild memberuid and memberoif attributes */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@MEMBEROF-REBUILD"); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_add(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_05(struct sysdb_ctx *sysdb, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_message *msg; struct upgrade_ctx *ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_6, &ctx); if (ret) { return ret; } /* Add new indexes */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); if (!msg->dn) { ret = ENOMEM; goto done; } /* Add Index for dataExpireTimestamp */ ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "@IDXATTR", "dataExpireTimestamp"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } /* Add index to speed up ONELEVEL searches */ ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "@IDXONE", "1"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_06(struct sysdb_ctx *sysdb, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_message *msg; struct upgrade_ctx *ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_7, &ctx); if (ret) { return ret; } /* Add new indexes */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); if (!msg->dn) { ret = ENOMEM; goto done; } /* Case insensitive search for originalDN */ ret = ldb_msg_add_empty(msg, SYSDB_ORIG_DN, LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, SYSDB_ORIG_DN, "CASE_INSENSITIVE"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_07(struct sysdb_ctx *sysdb, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_message *msg; struct upgrade_ctx *ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_8, &ctx); if (ret) { return ret; } /* Add new indexes */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); if (!msg->dn) { ret = ENOMEM; goto done; } /* Add Index for nameAlias */ ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "@IDXATTR", "nameAlias"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_08(struct sysdb_ctx *sysdb, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_message *msg; struct upgrade_ctx *ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_9, &ctx); if (ret) { return ret; } /* Add new indexes */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); if (!msg->dn) { ret = ENOMEM; goto done; } /* Add Index for servicePort and serviceProtocol */ ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "@IDXATTR", "servicePort"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "@IDXATTR", "serviceProtocol"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_09(struct sysdb_ctx *sysdb, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_message *msg; struct upgrade_ctx *ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_10, &ctx); if (ret) { return ret; } /* Add new indexes */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); if (!msg->dn) { ret = ENOMEM; goto done; } /* Add Index for servicePort and serviceProtocol */ ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "@IDXATTR", "sudoUser"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_10(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_result *res; struct ldb_message *msg; struct ldb_message *user; struct ldb_message_element *memberof_el; const char *name; struct ldb_dn *basedn; const char *filter = "(&(objectClass=user)(!(uidNumber=*))(memberOf=*))"; const char *attrs[] = { "name", "memberof", NULL }; struct upgrade_ctx *ctx; int i, j; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_11, &ctx); if (ret) { return ret; } basedn = sysdb_user_base_dn(tmp_ctx, domain); if (basedn == NULL) { ret = EIO; goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, "%s", filter); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } for (i = 0; i < res->count; i++) { user = res->msgs[i]; memberof_el = ldb_msg_find_element(user, "memberof"); name = ldb_msg_find_attr_as_string(user, "name", NULL); if (name == NULL) { ret = EIO; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "User [%s] is a member of %d groups\n", name, memberof_el->num_values); for (j = 0; j < memberof_el->num_values; j++) { msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, &memberof_el->values[j]); if (msg->dn == NULL) { ret = ENOMEM; goto done; } if (!ldb_dn_validate(msg->dn)) { DEBUG(SSSDBG_MINOR_FAILURE, "DN validation failed during " "upgrade: [%s]\n", memberof_el->values[j].data); talloc_zfree(msg); continue; } ret = ldb_msg_add_empty(msg, "ghost", LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "ghost", name); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Adding ghost [%s] to entry [%s]\n", name, ldb_dn_get_linearized(msg->dn)); ret = sss_ldb_modify_permissive(sysdb->ldb, msg); talloc_zfree(msg); if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) { /* If we failed adding the ghost user(s) because the values already * exist, they were probably propagated from a parent that was * upgraded before us. Mark the group as expired so that it is * refreshed on next request. */ msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, &memberof_el->values[j]); if (msg->dn == NULL) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, SYSDB_CACHE_EXPIRE, LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { goto done; } ret = ldb_msg_add_string(msg, SYSDB_CACHE_EXPIRE, "1"); if (ret != LDB_SUCCESS) { goto done; } ret = sss_ldb_modify_permissive(sysdb->ldb, msg); talloc_zfree(msg); if (ret != LDB_SUCCESS) { goto done; } } else if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } DEBUG(SSSDBG_TRACE_FUNC, "Removing fake user [%s]\n", ldb_dn_get_linearized(user->dn)); ret = ldb_delete(sysdb->ldb, user->dn); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_11(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char **ver) { TALLOC_CTX *tmp_ctx; errno_t ret; struct ldb_result *res; struct ldb_message *entry; const char *key; const char *value; struct ldb_message_element *memberof_el; struct ldb_dn *memberof_dn; struct ldb_dn *basedn; const struct ldb_val *val; const char *attrs[] = { SYSDB_AUTOFS_ENTRY_KEY, SYSDB_AUTOFS_ENTRY_VALUE, SYSDB_MEMBEROF, NULL }; struct upgrade_ctx *ctx; size_t i, j; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_12, &ctx); if (ret) { return ret; } basedn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE, AUTOFS_ENTRY_SUBDIR, domain->name); if (basedn == NULL) { ret = ENOMEM; goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, "(objectClass=%s)", SYSDB_AUTOFS_ENTRY_OC); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Found %d autofs entries\n", res->count); for (i = 0; i < res->count; i++) { entry = res->msgs[i]; key = ldb_msg_find_attr_as_string(entry, SYSDB_AUTOFS_ENTRY_KEY, NULL); value = ldb_msg_find_attr_as_string(entry, SYSDB_AUTOFS_ENTRY_VALUE, NULL); memberof_el = ldb_msg_find_element(entry, SYSDB_MEMBEROF); if (key && value && memberof_el) { for (j = 0; j < memberof_el->num_values; j++) { memberof_dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, &(memberof_el->values[j])); if (!memberof_dn) { DEBUG(SSSDBG_OP_FAILURE, "Cannot convert memberof into DN, skipping\n"); continue; } val = ldb_dn_get_rdn_val(memberof_dn); if (!val) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get map name from map DN\n"); continue; } ret = sysdb_save_autofsentry(domain, (const char *) val->data, key, value, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot save autofs entry [%s]-[%s] into map %s\n", key, value, val->data); continue; } } } /* Delete the old entry if it was either processed or incomplete */ DEBUG(SSSDBG_TRACE_LIBS, "Deleting [%s]\n", ldb_dn_get_linearized(entry->dn)); ret = ldb_delete(sysdb->ldb, entry->dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot delete old autofs entry %s\n", ldb_dn_get_linearized(entry->dn)); continue; } } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_12(struct sysdb_ctx *sysdb, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_message *msg; struct upgrade_ctx *ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_13, &ctx); if (ret) { return ret; } /* add new indexes */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST"); if (!msg->dn) { ret = ENOMEM; goto done; } /* add index for sshKnownHostsExpire */ ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "@IDXATTR", "sshKnownHostsExpire"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_13(struct sysdb_ctx *sysdb, const char **ver) { struct upgrade_ctx *ctx; struct ldb_result *dom_res; struct ldb_result *res; struct ldb_dn *basedn; const char *attrs[] = { "cn", "name", NULL }; const char *tmp_str; errno_t ret; int i, j, l, n; ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_14, &ctx); if (ret) { return ret; } basedn = ldb_dn_new(ctx, sysdb->ldb, SYSDB_BASE); if (!basedn) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n"); ret = EIO; goto done; } ret = ldb_search(sysdb->ldb, ctx, &dom_res, basedn, LDB_SCOPE_ONELEVEL, attrs, "objectclass=%s", SYSDB_SUBDOMAIN_CLASS); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Failed to search subdomains\n"); ret = EIO; goto done; } for (i = 0; i < dom_res->count; i++) { tmp_str = ldb_msg_find_attr_as_string(dom_res->msgs[i], "cn", NULL); if (tmp_str == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "The object [%s] doesn't have a name\n", ldb_dn_get_linearized(dom_res->msgs[i]->dn)); continue; } basedn = ldb_dn_new_fmt(ctx, sysdb->ldb, SYSDB_DOM_BASE, tmp_str); if (!basedn) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn for subdomain %s\n", tmp_str); continue; } ret = ldb_search(sysdb->ldb, ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, NULL); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Failed to search subdomain %s\n", tmp_str); talloc_free(basedn); continue; } l = ldb_dn_get_comp_num(basedn); for (j = 0; j < res->count; j++) { n = ldb_dn_get_comp_num(res->msgs[j]->dn); if (n <= l + 1) { /* Do not remove subdomain containers, only their contents */ continue; } ret = ldb_delete(sysdb->ldb, res->msgs[j]->dn); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to delete %s\n", ldb_dn_get_linearized(res->msgs[j]->dn)); continue; } } talloc_free(basedn); talloc_free(res); } talloc_free(dom_res); /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); return ret; } int sysdb_upgrade_14(struct sysdb_ctx *sysdb, const char **ver) { struct upgrade_ctx *ctx; struct ldb_message *msg; struct ldb_result *res; struct ldb_dn *basedn; struct ldb_dn *newdn; const char *attrs[] = { SYSDB_NAME, NULL }; const char *tmp_str; errno_t ret; int i; ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_15, &ctx); if (ret) { return ret; } basedn = ldb_dn_new(ctx, sysdb->ldb, SYSDB_BASE); if (!basedn) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n"); ret = EIO; goto done; } /* create base ranges container */ msg = ldb_msg_new(ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(msg, sysdb->ldb, SYSDB_TMPL_RANGE_BASE); if (!msg->dn) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "cn", "ranges"); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } /* do a synchronous add */ ret = ldb_add(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to upgrade DB (%d, [%s])!\n", ret, ldb_errstring(sysdb->ldb)); ret = EIO; goto done; } talloc_zfree(msg); ret = ldb_search(sysdb->ldb, ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs, "objectclass=%s", SYSDB_ID_RANGE_CLASS); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Failed to search range objects\n"); ret = EIO; goto done; } /* Failure to convert any range is not fatal. As long as there are no * left-over objects we can fail to move them around, as they will be * recreated on the next online access */ for (i = 0; i < res->count; i++) { tmp_str = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_NAME, NULL); if (tmp_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "The object [%s] doesn't have a name\n", ldb_dn_get_linearized(res->msgs[i]->dn)); ret = ldb_delete(sysdb->ldb, res->msgs[i]->dn); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to delete %s\n", ldb_dn_get_linearized(res->msgs[i]->dn)); ret = EIO; goto done; } continue; } newdn = ldb_dn_new_fmt(ctx, sysdb->ldb, SYSDB_TMPL_RANGE, tmp_str); if (!newdn) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create new DN to move [%s]\n", ldb_dn_get_linearized(res->msgs[i]->dn)); ret = ENOMEM; goto done; } ret = ldb_rename(sysdb->ldb, res->msgs[i]->dn, newdn); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to move [%s] to [%s]\n", ldb_dn_get_linearized(res->msgs[i]->dn), ldb_dn_get_linearized(newdn)); ret = ldb_delete(sysdb->ldb, res->msgs[i]->dn); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to delete %s\n", ldb_dn_get_linearized(res->msgs[i]->dn)); ret = EIO; goto done; } } talloc_zfree(newdn); } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); return ret; } int sysdb_upgrade_15(struct sysdb_ctx *sysdb, const char **ver) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_message *msg; struct upgrade_ctx *ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_16, &ctx); if (ret) { return ret; } /* Add new indexes */ msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES"); if (!msg->dn) { ret = ENOMEM; goto done; } /* Case insensitive search for canonicalUserPrincipalName */ ret = ldb_msg_add_empty(msg, SYSDB_CANONICAL_UPN, LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, SYSDB_CANONICAL_UPN, "CASE_INSENSITIVE"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); talloc_free(tmp_ctx); return ret; } int sysdb_upgrade_16(struct sysdb_ctx *sysdb, const char **ver) { struct ldb_message *msg; struct upgrade_ctx *ctx; errno_t ret; ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_17, &ctx); if (ret) { return ret; } msg = ldb_msg_new(ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(msg, sysdb->ldb, "@INDEXLIST"); if (msg->dn == NULL) { ret = ENOMEM; goto done; } /* add index for objectSIDString */ ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_msg_add_string(msg, "@IDXATTR", "objectSIDString"); if (ret != LDB_SUCCESS) { ret = ENOMEM; goto done; } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); return ret; } /* * Example template for future upgrades. * Copy and change version numbers as appropriate. */ #if 0 int sysdb_upgrade_13(struct sysdb_ctx *sysdb, const char **ver) { struct upgrade_ctx *ctx; errno_t ret; ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_14, &ctx); if (ret) { return ret; } /* DO STUFF HERE (use ctx, as the local temporary memory context) */ /* conversion done, update version number */ ret = update_version(ctx); done: ret = finish_upgrade(ret, &ctx, ver); return ret; } #endif sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_gpo.c0000644000000000000000000000007212703456111015634 xustar0029 atime=1460561751.63371557 29 ctime=1460561774.84079426 sssd-1.13.4/src/db/sysdb_gpo.c0000644002412700241270000004714112703456111017314 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Yassir Elley Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "db/sysdb.h" #include "db/sysdb_private.h" static struct ldb_dn * sysdb_gpo_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *gpo_guid) { errno_t ret; char *clean_gpo_guid; struct ldb_dn *dn; ret = sysdb_dn_sanitize(NULL, gpo_guid, &clean_gpo_guid); if (ret != EOK) { return NULL; } DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO"\n", clean_gpo_guid, domain->name); dn = ldb_dn_new_fmt(mem_ctx, domain->sysdb->ldb, SYSDB_TMPL_GPO, clean_gpo_guid, domain->name); talloc_free(clean_gpo_guid); return dn; } errno_t sysdb_gpo_store_gpo(struct sss_domain_info *domain, const char *gpo_guid, int gpo_version, int cache_timeout, time_t now) { errno_t ret, sret; int lret; struct ldb_message *update_msg; struct ldb_message **msgs; static const char *attrs[] = SYSDB_GPO_ATTRS; size_t count; bool in_transaction = false; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; update_msg = ldb_msg_new(tmp_ctx); if (!update_msg) { ret = ENOMEM; goto done; } update_msg->dn = sysdb_gpo_dn(update_msg, domain, gpo_guid); if (!update_msg->dn) { ret = ENOMEM; goto done; } ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } if (!now) { now = time(NULL); } in_transaction = true; /* Check for an existing gpo_guid entry */ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, update_msg->dn, LDB_SCOPE_BASE, NULL, attrs, &count, &msgs); if (ret == ENOENT) { /* Create new GPO */ DEBUG(SSSDBG_TRACE_FUNC, "Adding new GPO [gpo_guid:%s][gpo_version:%d]\n", gpo_guid, gpo_version); /* Add the objectClass */ lret = ldb_msg_add_empty(update_msg, SYSDB_OBJECTCLASS, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_string(update_msg, SYSDB_OBJECTCLASS, SYSDB_GPO_OC); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } /* Add the GPO GUID */ lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_GUID_ATTR, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_string(update_msg, SYSDB_GPO_GUID_ATTR, gpo_guid); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } /* Add the Version */ lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_VERSION_ATTR, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_fmt(update_msg, SYSDB_GPO_VERSION_ATTR, "%d", gpo_version); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } /* Add the Policy File Timeout */ lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_TIMEOUT_ATTR, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_fmt(update_msg, SYSDB_GPO_TIMEOUT_ATTR, "%lu", ((cache_timeout) ? (now + cache_timeout) : 0)); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_add(domain->sysdb->ldb, update_msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add GPO: [%s]\n", ldb_strerror(lret)); ret = sysdb_error_to_errno(lret); goto done; } } else if (ret == EOK && count == 1) { /* Update the existing GPO */ DEBUG(SSSDBG_TRACE_ALL, "Updating new GPO [%s][%s]\n", domain->name, gpo_guid); /* Add the Version */ lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_VERSION_ATTR, LDB_FLAG_MOD_REPLACE, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_fmt(update_msg, SYSDB_GPO_VERSION_ATTR, "%d", gpo_version); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } /* Add the Policy File Timeout */ lret = ldb_msg_add_empty(update_msg, SYSDB_GPO_TIMEOUT_ATTR, LDB_FLAG_MOD_REPLACE, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_fmt(update_msg, SYSDB_GPO_TIMEOUT_ATTR, "%lu", ((cache_timeout) ? (now + cache_timeout) : 0)); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_modify(domain->sysdb->ldb, update_msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to modify GPO: [%s](%d)[%s]\n", ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb)); ret = sysdb_error_to_errno(lret); goto done; } } else { ret = EIO; goto done; } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not commit transaction: [%s]\n", strerror(ret)); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } errno_t sysdb_gpo_get_gpo_by_guid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *gpo_guid, struct ldb_result **_result) { errno_t ret; int lret; struct ldb_dn *base_dn; TALLOC_CTX *tmp_ctx; struct ldb_result *res; const char *attrs[] = SYSDB_GPO_ATTRS; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_BASE"\n", domain->name); base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_GPO_BASE, domain->name); if (!base_dn) { ret = ENOMEM; goto done; } lret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, SYSDB_GPO_GUID_FILTER, gpo_guid); if (lret) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not locate GPO: [%s]\n", ldb_strerror(lret)); ret = sysdb_error_to_errno(lret); goto done; } if (res->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Search for GUID [%s] returned more than " \ "one object.\n", gpo_guid); ret = EINVAL; goto done; } else if (res->count == 0) { ret = ENOENT; goto done; } *_result = talloc_steal(mem_ctx, res); ret = EOK; done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "No such entry.\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(tmp_ctx); return ret; } errno_t sysdb_gpo_get_gpos(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_result) { errno_t ret; int lret; struct ldb_dn *base_dn; TALLOC_CTX *tmp_ctx; struct ldb_result *res; const char *attrs[] = SYSDB_GPO_ATTRS; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_BASE"\n", domain->name); base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_GPO_BASE, domain->name); if (!base_dn) { ret = ENOMEM; goto done; } lret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, SYSDB_GPO_FILTER); if (lret) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not locate GPOs: [%s]\n", ldb_strerror(lret)); ret = sysdb_error_to_errno(lret); goto done; } if (res->count == 0) { ret = ENOENT; goto done; } *_result = talloc_steal(mem_ctx, res); ret = EOK; done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "No GPO entries.\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(tmp_ctx); return ret; } /* GPO Result */ static struct ldb_dn * sysdb_gpo_result_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *result_name) { errno_t ret; char *clean_result_name; struct ldb_dn *dn; ret = sysdb_dn_sanitize(NULL, result_name, &clean_result_name); if (ret != EOK) { return NULL; } DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_RESULT"\n", clean_result_name, domain->name); dn = ldb_dn_new_fmt(mem_ctx, domain->sysdb->ldb, SYSDB_TMPL_GPO_RESULT, clean_result_name, domain->name); talloc_free(clean_result_name); return dn; } errno_t sysdb_gpo_store_gpo_result_setting(struct sss_domain_info *domain, const char *ini_key, const char *ini_value) { errno_t ret, sret; int lret; struct ldb_message *update_msg; struct ldb_message **msgs; size_t count; bool in_transaction = false; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; update_msg = ldb_msg_new(tmp_ctx); if (!update_msg) { ret = ENOMEM; goto done; } update_msg->dn = sysdb_gpo_result_dn(update_msg, domain, "gpo_result"); if (!update_msg->dn) { ret = ENOMEM; goto done; } ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; /* Check for an existing GPO Result object */ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, update_msg->dn, LDB_SCOPE_BASE, NULL, NULL, &count, &msgs); if (ret == ENOENT) { /* Create new GPO Result object */ DEBUG(SSSDBG_TRACE_FUNC, "Storing setting: key [%s] value [%s]\n", ini_key, ini_value); /* Add the objectClass */ lret = ldb_msg_add_empty(update_msg, SYSDB_OBJECTCLASS, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_string(update_msg, SYSDB_OBJECTCLASS, SYSDB_GPO_RESULT_OC); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } /* Store the policy_setting if it is non-NULL */ if (ini_value) { lret = ldb_msg_add_empty(update_msg, ini_key, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_string(update_msg, ini_key, ini_value); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } lret = ldb_add(domain->sysdb->ldb, update_msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add GPO Result: [%s]\n", ldb_strerror(lret)); ret = sysdb_error_to_errno(lret); goto done; } } else if (ret == EOK && count == 1) { /* Update existing GPO Result object*/ if (ini_value) { DEBUG(SSSDBG_TRACE_FUNC, "Updating setting: key [%s] value [%s]\n", ini_key, ini_value); /* Update the policy setting */ lret = ldb_msg_add_empty(update_msg, ini_key, LDB_FLAG_MOD_REPLACE, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_fmt(update_msg, ini_key, "%s", ini_value); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } else { /* If the value is NULL, we need to remove it from the cache */ DEBUG(SSSDBG_TRACE_FUNC, "Removing setting: key [%s]\n", ini_key); /* Update the policy setting */ lret = ldb_msg_add_empty(update_msg, ini_key, LDB_FLAG_MOD_DELETE, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } lret = ldb_modify(domain->sysdb->ldb, update_msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to modify GPO Result: [%s](%d)[%s]\n", ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb)); ret = sysdb_error_to_errno(lret); goto done; } } else { ret = EIO; goto done; } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not commit transaction: [%s]\n", strerror(ret)); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } static errno_t sysdb_gpo_get_gpo_result_object(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char **attrs, struct ldb_result **_result) { errno_t ret; int lret; struct ldb_dn *base_dn; TALLOC_CTX *tmp_ctx; struct ldb_result *res; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_GPO_RESULT_BASE"\n", domain->name); base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_GPO_RESULT_BASE, domain->name); if (!base_dn) { ret = ENOMEM; goto done; } lret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, SYSDB_GPO_RESULT_FILTER); if (lret) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not locate GPO Result object: [%s]\n", ldb_strerror(lret)); ret = sysdb_error_to_errno(lret); goto done; } if (res->count == 0) { ret = ENOENT; goto done; } *_result = talloc_steal(mem_ctx, res); ret = EOK; done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "No GPO Result object.\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(tmp_ctx); return ret; } errno_t sysdb_gpo_get_gpo_result_setting(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *ini_key, const char **_ini_value) { errno_t ret; TALLOC_CTX *tmp_ctx; struct ldb_result *res; const char *ini_value; const char *attrs[] = {ini_key, NULL}; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; ret = sysdb_gpo_get_gpo_result_object(tmp_ctx, domain, attrs, &res); if (ret != EOK) { goto done; } ini_value = ldb_msg_find_attr_as_string(res->msgs[0], ini_key, NULL); DEBUG(SSSDBG_TRACE_FUNC, "key [%s] value [%s]\n", ini_key, ini_value); *_ini_value = talloc_strdup(mem_ctx, ini_value); if (!*_ini_value && ini_value) { /* If ini_value was NULL, this is expected to also be NULL */ ret = ENOMEM; goto done; } ret = EOK; done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "No setting for key [%s].\n", ini_key); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(tmp_ctx); return ret; } errno_t sysdb_gpo_delete_gpo_result_object(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain) { struct ldb_result *res; errno_t ret, sret; bool in_transaction = false; ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; ret = sysdb_gpo_get_gpo_result_object(mem_ctx, domain, NULL, &res); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Could not delete GPO result object: %d\n", ret); goto done; } else if (ret != ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "Deleting GPO Result object\n"); ret = sysdb_delete_entry(domain->sysdb, res->msgs[0]->dn, true); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not delete GPO Result cache entry\n"); goto done; } } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not commit transaction: [%s]\n", strerror(ret)); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } return ret; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_ranges.c0000644000000000000000000000007312703456111016327 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.838794253 sssd-1.13.4/src/db/sysdb_ranges.c0000644002412700241270000002615012703456111020003 0ustar00jhrozekjhrozek00000000000000/* SSSD System Database - ID ranges related calls Copyright (C) 2012 Sumit Bose This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb_private.h" static errno_t find_attr_as_uint32_t(const struct ldb_message *msg, const char *attr_name, uint32_t *result) { uint64_t val; val = ldb_msg_find_attr_as_uint64(msg, attr_name, UINT64_MAX); if (val == UINT64_MAX) { return ENOENT; } else if (val >= UINT32_MAX) { return EINVAL; } *result = val; return EOK; } errno_t sysdb_get_ranges(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, size_t *range_count, struct range_info ***range_list) { size_t c; errno_t ret; TALLOC_CTX *tmp_ctx; struct ldb_result *res; const char *attrs[] = {SYSDB_NAME, SYSDB_BASE_ID, SYSDB_ID_RANGE_SIZE, SYSDB_BASE_RID, SYSDB_SECONDARY_BASE_RID, SYSDB_DOMAIN_ID, SYSDB_ID_RANGE_TYPE, NULL}; struct range_info **list; struct ldb_dn *basedn; const char *tmp_str; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } basedn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_TMPL_RANGE_BASE); if (basedn == NULL) { ret = EIO; goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_ONELEVEL, attrs, "objectclass=%s", SYSDB_ID_RANGE_CLASS); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } list = talloc_zero_array(tmp_ctx, struct range_info *, res->count + 1); if (list == NULL) { ret = ENOMEM; goto done; } for (c = 0; c < res->count; c++) { list[c] = talloc_zero(list, struct range_info); if (list[c] == NULL) { ret = ENOMEM; goto done; } tmp_str = ldb_msg_find_attr_as_string(res->msgs[c], SYSDB_NAME, NULL); if (tmp_str == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "The object [%s] doesn't have a name.\n", ldb_dn_get_linearized(res->msgs[c]->dn)); ret = EINVAL; goto done; } list[c]->name = talloc_strdup(list, tmp_str); if (list[c]->name == NULL) { ret = ENOMEM; goto done; } tmp_str = ldb_msg_find_attr_as_string(res->msgs[c], SYSDB_DOMAIN_ID, NULL); if (tmp_str != NULL) { list[c]->trusted_dom_sid = talloc_strdup(list, tmp_str); if (list[c]->trusted_dom_sid == NULL) { ret = ENOMEM; goto done; } } ret = find_attr_as_uint32_t(res->msgs[c], SYSDB_BASE_ID, &list[c]->base_id); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "find_attr_as_uint32_t failed.\n"); goto done; } ret = find_attr_as_uint32_t(res->msgs[c], SYSDB_ID_RANGE_SIZE, &list[c]->id_range_size); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "find_attr_as_uint32_t failed.\n"); goto done; } ret = find_attr_as_uint32_t(res->msgs[c], SYSDB_BASE_RID, &list[c]->base_rid); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "find_attr_as_uint32_t failed.\n"); goto done; } ret = find_attr_as_uint32_t(res->msgs[c], SYSDB_SECONDARY_BASE_RID, &list[c]->secondary_base_rid); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "find_attr_as_uint32_t failed.\n"); goto done; } tmp_str = ldb_msg_find_attr_as_string(res->msgs[c], SYSDB_ID_RANGE_TYPE, NULL); if (tmp_str != NULL) { list[c]->range_type = talloc_strdup(list, tmp_str); if (list[c]->range_type == NULL) { ret = ENOMEM; goto done; } } } list[res->count] = NULL; *range_count = res->count; *range_list = talloc_steal(mem_ctx, list); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_range_create(struct sysdb_ctx *sysdb, struct range_info *range) { struct ldb_message *msg; int ret; TALLOC_CTX *tmp_ctx; /* if both or none are set, skip */ if ((range->trusted_dom_sid == NULL && range->secondary_base_rid == 0) || (range->trusted_dom_sid != NULL && range->secondary_base_rid != 0)) { DEBUG(SSSDBG_OP_FAILURE, "Invalid range, skipping. Expected that " "either the secondary base RID or the SID of the trusted " "domain is set, but not both or none of them.\n"); return EOK; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_RANGE, range->name); if (!msg->dn) { ret = ENOMEM; goto done; } ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_OBJECTCLASS, SYSDB_ID_RANGE_CLASS); if (ret) goto done; if (range->trusted_dom_sid == NULL && range->secondary_base_rid != 0) { ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_OBJECTCLASS, SYSDB_DOMAIN_ID_RANGE_CLASS); if (ret) goto done; ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_SECONDARY_BASE_RID, (unsigned long) range->secondary_base_rid); if (ret) goto done; } else if (range->trusted_dom_sid != NULL && range->secondary_base_rid == 0) { ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_OBJECTCLASS, SYSDB_TRUSTED_AD_DOMAIN_RANGE_CLASS); if (ret) goto done; ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_DOMAIN_ID, range->trusted_dom_sid); if (ret) goto done; } ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_NAME, range->name); if (ret) goto done; ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_BASE_ID, (unsigned long) range->base_id); if (ret) goto done; ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_ID_RANGE_SIZE, (unsigned long) range->id_range_size); if (ret) goto done; ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_BASE_RID, (unsigned long) range->base_rid); if (ret) goto done; ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME, (unsigned long)time(NULL)); if (ret) goto done; ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_ID_RANGE_TYPE, range->range_type); if (ret) goto done; ret = ldb_add(sysdb->ldb, msg); if (ret) goto done; ret = sysdb_error_to_errno(ret); done: if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } errno_t sysdb_update_ranges(struct sysdb_ctx *sysdb, struct range_info **ranges) { int ret; int sret; size_t c; size_t d; TALLOC_CTX *tmp_ctx = NULL; size_t cur_range_count; struct range_info **cur_ranges; struct ldb_dn *dn; bool in_transaction = false; bool *keep_range; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } /* Retrieve all ranges that are currently in sysdb */ ret = sysdb_get_ranges(tmp_ctx, sysdb, &cur_range_count, &cur_ranges); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_ranges failed.\n"); goto done; } keep_range = talloc_zero_array(tmp_ctx, bool, cur_range_count); if (keep_range == NULL) { ret = ENOMEM; DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array failed.\n"); goto done; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_start failed.\n"); goto done; } in_transaction = true; /* Go through a list of retrieved ranges and: * - if a range already exists in sysdb, mark it for preservation * - if the range doesn't exist in sysdb, create it */ for (c = 0; ranges[c] != NULL; c++) { for (d = 0; d < cur_range_count; d++) { if (strcasecmp(ranges[c]->name, cur_ranges[d]->name) == 0) { keep_range[d] = true; /* range already in cache, nothing to do */ break; } } if (d == cur_range_count) { DEBUG(SSSDBG_TRACE_FUNC, "Adding range [%s].\n", ranges[c]->name); ret = sysdb_range_create(sysdb, ranges[c]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_range_create failed.\n"); goto done; } } } /* Now delete all ranges that have been in sysdb prior to * refreshing the list and are not marked for preservation * (i.e. they are not in the new list of ranges) */ for (d = 0; d < cur_range_count; d++) { if (!keep_range[d]) { DEBUG(SSSDBG_TRACE_FUNC, "Removing range [%s].\n", cur_ranges[d]->name); dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_RANGE, cur_ranges[d]->name); if (dn == NULL) { ret = ENOMEM; goto done; } ret = sysdb_delete_entry(sysdb, dn, true); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_delete_entry failed.\n"); goto done; } } } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not commit transaction\n"); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_selinux.h0000644000000000000000000000007312703456111016544 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.511793144 sssd-1.13.4/src/db/sysdb_selinux.h0000644002412700241270000000432212703456111020215 0ustar00jhrozekjhrozek00000000000000/* SSSD System Database Header - SELinux support Copyright (C) Jan Zeleny 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SYS_DB_SELINUX_H__ #define __SYS_DB_SELINUX_H__ #include "db/sysdb.h" #define SYSDB_SELINUX_CONTAINER "cn=selinux" #define SYSDB_TMPL_SELINUX_BASE SYSDB_SELINUX_CONTAINER",cn=%s,"SYSDB_BASE #define SYSDB_TMPL_SEUSERMAP SYSDB_NAME"=%s,"SYSDB_TMPL_SELINUX_BASE #define SYSDB_SELINUX_NAME "config" #define SYSDB_SELINUX_SEEALSO "seeAlso" #define SYSDB_SELINUX_USER "selinuxUser" #define SYSDB_SELINUX_ENABLED "enabled" #define SYSDB_SELINUX_DEFAULT_USER "user" #define SYSDB_SELINUX_DEFAULT_ORDER "order" #define SYSDB_SELINUX_HOST_PRIORITY "hostPriority" errno_t sysdb_store_selinux_usermap(struct sss_domain_info *domain, struct sysdb_attrs *attrs); errno_t sysdb_store_selinux_config(struct sss_domain_info *domain, const char *default_map, const char *order); errno_t sysdb_get_selinux_usermaps(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char **attrs, size_t *count, struct ldb_message ***messages); errno_t sysdb_search_selinux_config(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char **attrs, struct ldb_message **_config); errno_t sysdb_delete_usermaps(struct sss_domain_info *domain); #endif sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_private.h0000644000000000000000000000007312703456111016527 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.512793147 sssd-1.13.4/src/db/sysdb_private.h0000644002412700241270000001276612703456111020213 0ustar00jhrozekjhrozek00000000000000 /* SSSD Private System Database Header Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __INT_SYS_DB_H__ #define __INT_SYS_DB_H__ #define SYSDB_VERSION_0_17 "0.17" #define SYSDB_VERSION_0_16 "0.16" #define SYSDB_VERSION_0_15 "0.15" #define SYSDB_VERSION_0_14 "0.14" #define SYSDB_VERSION_0_13 "0.13" #define SYSDB_VERSION_0_12 "0.12" #define SYSDB_VERSION_0_11 "0.11" #define SYSDB_VERSION_0_10 "0.10" #define SYSDB_VERSION_0_9 "0.9" #define SYSDB_VERSION_0_8 "0.8" #define SYSDB_VERSION_0_7 "0.7" #define SYSDB_VERSION_0_6 "0.6" #define SYSDB_VERSION_0_5 "0.5" #define SYSDB_VERSION_0_4 "0.4" #define SYSDB_VERSION_0_3 "0.3" #define SYSDB_VERSION_0_2 "0.2" #define SYSDB_VERSION_0_1 "0.1" #define SYSDB_VERSION SYSDB_VERSION_0_17 #define SYSDB_BASE_LDIF \ "dn: @ATTRIBUTES\n" \ "userPrincipalName: CASE_INSENSITIVE\n" \ "canonicalUserPrincipalName: CASE_INSENSITIVE\n" \ "cn: CASE_INSENSITIVE\n" \ "dc: CASE_INSENSITIVE\n" \ "dn: CASE_INSENSITIVE\n" \ "originalDN: CASE_INSENSITIVE\n" \ "objectclass: CASE_INSENSITIVE\n" \ "\n" \ "dn: @INDEXLIST\n" \ "@IDXATTR: cn\n" \ "@IDXATTR: objectclass\n" \ "@IDXATTR: member\n" \ "@IDXATTR: memberof\n" \ "@IDXATTR: name\n" \ "@IDXATTR: uidNumber\n" \ "@IDXATTR: gidNumber\n" \ "@IDXATTR: lastUpdate\n" \ "@IDXATTR: dataExpireTimestamp\n" \ "@IDXATTR: originalDN\n" \ "@IDXATTR: nameAlias\n" \ "@IDXATTR: servicePort\n" \ "@IDXATTR: serviceProtocol\n" \ "@IDXATTR: sudoUser\n" \ "@IDXATTR: sshKnownHostsExpire\n" \ "@IDXATTR: objectSIDString\n" \ "@IDXONE: 1\n" \ "\n" \ "dn: @MODULES\n" \ "@LIST: asq,memberof\n" \ "\n" \ "dn: cn=sysdb\n" \ "cn: sysdb\n" \ "version: " SYSDB_VERSION "\n" \ "description: base object\n" \ "\n" \ "dn: cn=ranges,cn=sysdb\n" \ "cn: ranges\n" \ "\n" #include "db/sysdb.h" struct sysdb_ctx { struct ldb_context *ldb; char *ldb_file; }; /* Internal utility functions */ int sysdb_get_db_file(TALLOC_CTX *mem_ctx, const char *provider, const char *name, const char *base_path, char **_ldb_file); errno_t sysdb_ldb_connect(TALLOC_CTX *mem_ctx, const char *filename, struct ldb_context **_ldb); int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *db_path, bool allow_upgrade, struct sysdb_ctx **_ctx); /* Upgrade routines */ int sysdb_upgrade_01(struct ldb_context *ldb, const char **ver); int sysdb_check_upgrade_02(struct sss_domain_info *domains, const char *db_path); int sysdb_upgrade_03(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_04(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_05(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_06(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_07(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_08(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_09(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_10(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char **ver); int sysdb_upgrade_11(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char **ver); int sysdb_upgrade_12(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_13(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_14(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_15(struct sysdb_ctx *sysdb, const char **ver); int sysdb_upgrade_16(struct sysdb_ctx *sysdb, const char **ver); int add_string(struct ldb_message *msg, int flags, const char *attr, const char *value); int add_ulong(struct ldb_message *msg, int flags, const char *attr, unsigned long value); /* The utility function to create a subdomain sss_domain_info object is handy * for unit tests, so it should be available in a header, but not a public util * one, because the only interface for the deamon itself should be adding * the sysdb domain object and calling sysdb_update_subdomains() */ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, struct sss_domain_info *parent, const char *name, const char *realm, const char *flat_name, const char *id, bool mpg, bool enumerate, const char *forest, uint32_t trust_direction); #endif /* __INT_SYS_DB_H__ */ sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_services.c0000644000000000000000000000007312703456111016673 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.834794239 sssd-1.13.4/src/db/sysdb_services.c0000644002412700241270000005740312703456111020354 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "db/sysdb_private.h" #include "db/sysdb_services.h" static errno_t sysdb_svc_update(struct sysdb_ctx *sysdb, struct ldb_dn *dn, int port, const char **aliases, const char **protocols); errno_t sysdb_svc_remove_alias(struct sysdb_ctx *sysdb, struct ldb_dn *dn, const char *alias); errno_t sysdb_getservbyname(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char *proto, struct ldb_result **_res) { errno_t ret; TALLOC_CTX *tmp_ctx; static const char *attrs[] = SYSDB_SVC_ATTRS; char *sanitized_name; char *sanitized_proto; char *subfilter; struct ldb_result *res = NULL; struct ldb_message **msgs; size_t msgs_count; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sss_filter_sanitize(tmp_ctx, name, &sanitized_name); if (ret != EOK) { goto done; } if (proto) { ret = sss_filter_sanitize(tmp_ctx, proto, &sanitized_proto); if (ret != EOK) { goto done; } } subfilter = talloc_asprintf(tmp_ctx, SYSDB_SVC_BYNAME_FILTER, proto ? sanitized_proto : "*", sanitized_name, sanitized_name); if (!subfilter) { ret = ENOMEM; goto done; } ret = sysdb_search_services(mem_ctx, domain, subfilter, attrs, &msgs_count, &msgs); if (ret == EOK) { res = talloc_zero(mem_ctx, struct ldb_result); if (!res) { ret = ENOMEM; goto done; } res->count = msgs_count; res->msgs = talloc_steal(res, msgs); } *_res = res; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_getservbyport(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, int port, const char *proto, struct ldb_result **_res) { errno_t ret; TALLOC_CTX *tmp_ctx; static const char *attrs[] = SYSDB_SVC_ATTRS; char *sanitized_proto = NULL; char *subfilter; struct ldb_result *res = NULL; struct ldb_message **msgs; size_t msgs_count; if (port <= 0) { return EINVAL; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (proto) { ret = sss_filter_sanitize(tmp_ctx, proto, &sanitized_proto); if (ret != EOK) { goto done; } } subfilter = talloc_asprintf(tmp_ctx, SYSDB_SVC_BYPORT_FILTER, proto ? sanitized_proto : "*", (unsigned int) port); if (!subfilter) { ret = ENOMEM; goto done; } ret = sysdb_search_services(mem_ctx, domain, subfilter, attrs, &msgs_count, &msgs); if (ret == EOK) { res = talloc_zero(mem_ctx, struct ldb_result); if (!res) { ret = ENOMEM; goto done; } res->count = msgs_count; res->msgs = talloc_steal(res, msgs); } *_res = res; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_store_service(struct sss_domain_info *domain, const char *primary_name, int port, const char **aliases, const char **protocols, struct sysdb_attrs *extra_attrs, char **remove_attrs, uint64_t cache_timeout, time_t now) { errno_t ret; errno_t sret; TALLOC_CTX *tmp_ctx; bool in_transaction = false; struct ldb_result *res = NULL; const char *name; unsigned int i; struct ldb_dn *update_dn = NULL; struct sysdb_attrs *attrs; struct sysdb_ctx *sysdb; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; sysdb = domain->sysdb; ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; /* Check that the port is unique * If the port appears for any service other than * the one matching the primary_name, we need to * remove them so that getservbyport() can work * properly. Last entry saved to the cache should * always "win". */ ret = sysdb_getservbyport(tmp_ctx, domain, port, NULL, &res); if (ret != EOK && ret != ENOENT) { goto done; } else if (ret != ENOENT) { if (res->count != 1) { /* Somehow the cache has multiple entries with * the same port. This is corrupted. We'll delete * them all to sort it out. */ for (i = 0; i < res->count; i++) { DEBUG(SSSDBG_TRACE_FUNC, "Corrupt cache entry [%s] detected. Deleting\n", ldb_dn_canonical_string(tmp_ctx, res->msgs[i]->dn)); ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not delete corrupt cache entry [%s]\n", ldb_dn_canonical_string(tmp_ctx, res->msgs[i]->dn)); goto done; } } } else { /* Check whether this is the same name as we're currently * saving to the cache. */ name = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); if (!name || strcmp(name, primary_name) != 0) { if (!name) { DEBUG(SSSDBG_CRIT_FAILURE, "A service with no name?\n"); /* Corrupted */ } /* Either this is a corrupt entry or it's another service * claiming ownership of this port. In order to account * for port reassignments, we need to delete the old entry. */ DEBUG(SSSDBG_TRACE_FUNC, "Corrupt or replaced cache entry [%s] detected. " "Deleting\n", ldb_dn_canonical_string(tmp_ctx, res->msgs[0]->dn)); ret = sysdb_delete_entry(sysdb, res->msgs[0]->dn, true); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not delete cache entry [%s]\n", ldb_dn_canonical_string(tmp_ctx, res->msgs[0]->dn)); } } } } talloc_zfree(res); /* Ok, ports should now be unique. Now look * the service up by name to determine if we * need to update existing entries or modify * aliases. */ ret = sysdb_getservbyname(tmp_ctx, domain, primary_name, NULL, &res); if (ret != EOK && ret != ENOENT) { goto done; } else if (ret != ENOENT) { /* Found entries */ for (i = 0; i < res->count; i++) { /* Check whether this is the same name as we're currently * saving to the cache. */ name = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_NAME, NULL); if (!name) { /* Corrupted */ DEBUG(SSSDBG_CRIT_FAILURE, "A service with no name?\n"); DEBUG(SSSDBG_TRACE_FUNC, "Corrupt cache entry [%s] detected. Deleting\n", ldb_dn_canonical_string(tmp_ctx, res->msgs[i]->dn)); ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not delete corrupt cache entry [%s]\n", ldb_dn_canonical_string(tmp_ctx, res->msgs[i]->dn)); goto done; } } else if (strcmp(name, primary_name) == 0) { /* This is the same service name, so we need * to update this entry with the values * provided. */ if(update_dn) { DEBUG(SSSDBG_CRIT_FAILURE, "Two existing services with the same name: [%s]? " "Deleting both.\n", primary_name); /* Delete the entry from the previous pass */ ret = sysdb_delete_entry(sysdb, update_dn, true); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not delete cache entry [%s]\n", ldb_dn_canonical_string(tmp_ctx, update_dn)); goto done; } /* Delete the new entry as well */ ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not delete cache entry [%s]\n", ldb_dn_canonical_string(tmp_ctx, res->msgs[i]->dn)); goto done; } update_dn = NULL; } else { update_dn = talloc_steal(tmp_ctx, res->msgs[i]->dn); } } else { /* Another service is claiming this name as an alias. * In order to account for aliases being promoted to * primary names, we need to make sure to remove the * old alias entry. */ ret = sysdb_svc_remove_alias(sysdb, res->msgs[i]->dn, primary_name); if (ret != EOK) goto done; } } talloc_zfree(res); } if (update_dn) { /* Update the existing entry */ ret = sysdb_svc_update(sysdb, update_dn, port, aliases, protocols); } else { /* Add a new entry */ ret = sysdb_svc_add(tmp_ctx, domain, primary_name, port, aliases, protocols, &update_dn); } if (ret != EOK) goto done; /* Set the cache timeout */ if (!extra_attrs) { attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } } else { attrs = extra_attrs; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); if (ret) goto done; ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, ((cache_timeout) ? (now + cache_timeout) : 0)); if (ret) goto done; ret = sysdb_set_entry_attr(sysdb, update_dn, attrs, SYSDB_MOD_REP); if (ret != EOK) goto done; if (remove_attrs) { ret = sysdb_remove_attrs(domain, primary_name, SYSDB_MEMBER_SERVICE, remove_attrs); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not remove missing attributes: [%s]\n", strerror(ret)); goto done; } } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } struct ldb_dn * sysdb_svc_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx, const char *domain, const char *name) { errno_t ret; char *clean_name; struct ldb_dn *dn; ret = sysdb_dn_sanitize(NULL, name, &clean_name); if (ret != EOK) { return NULL; } dn = ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_TMPL_SVC, clean_name, domain); talloc_free(clean_name); return dn; } errno_t sysdb_svc_add(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *primary_name, int port, const char **aliases, const char **protocols, struct ldb_dn **dn) { errno_t ret; int lret; TALLOC_CTX *tmp_ctx; struct ldb_message *msg; unsigned long i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } /* svc dn */ msg->dn = sysdb_svc_dn(domain->sysdb, msg, domain->name, primary_name); if (!msg->dn) { ret = ENOMEM; goto done; } /* Objectclass */ ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_OBJECTCLASS, SYSDB_SVC_CLASS); if (ret != EOK) goto done; /* Set the primary name */ ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_NAME, primary_name); if (ret != EOK) goto done; /* Set the port number */ ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_SVC_PORT, port); if (ret != EOK) goto done; /* If this service has any aliases, include them */ if (aliases && aliases[0]) { /* Set the name aliases */ lret = ldb_msg_add_empty(msg, SYSDB_NAME_ALIAS, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } for (i=0; aliases[i]; i++) { lret = ldb_msg_add_string(msg, SYSDB_NAME_ALIAS, aliases[i]); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } } /* Set the protocols */ lret = ldb_msg_add_empty(msg, SYSDB_SVC_PROTO, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } for (i=0; protocols[i]; i++) { lret = ldb_msg_add_string(msg, SYSDB_SVC_PROTO, protocols[i]); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } /* creation time */ ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME, (unsigned long)time(NULL)); if (ret) goto done; lret = ldb_add(domain->sysdb->ldb, msg); ret = sysdb_error_to_errno(lret); if (ret == EOK && dn) { *dn = talloc_steal(mem_ctx, msg->dn); } done: if (ret) { DEBUG(SSSDBG_TRACE_INTERNAL, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(tmp_ctx); return ret; } static errno_t sysdb_svc_update(struct sysdb_ctx *sysdb, struct ldb_dn *dn, int port, const char **aliases, const char **protocols) { errno_t ret; struct ldb_message *msg; int lret; unsigned int i; if (!dn || !protocols || !protocols[0]) { return EINVAL; } msg = ldb_msg_new(NULL); if (!msg) { ret = ENOMEM; goto done; } msg->dn = dn; /* Update the port */ ret = add_ulong(msg, SYSDB_MOD_REP, SYSDB_SVC_PORT, port); if (ret != EOK) goto done; if (aliases && aliases[0]) { /* Update the aliases */ lret = ldb_msg_add_empty(msg, SYSDB_NAME_ALIAS, SYSDB_MOD_REP, NULL); if (lret != LDB_SUCCESS) { ret = ENOMEM; goto done; } for (i = 0; aliases[i]; i++) { lret = ldb_msg_add_string(msg, SYSDB_NAME_ALIAS, aliases[i]); if (lret != LDB_SUCCESS) { ret = EINVAL; goto done; } } } /* Update the protocols */ lret = ldb_msg_add_empty(msg, SYSDB_SVC_PROTO, SYSDB_MOD_REP, NULL); if (lret != LDB_SUCCESS) { ret = ENOMEM; goto done; } for (i = 0; protocols[i]; i++) { lret = ldb_msg_add_string(msg, SYSDB_SVC_PROTO, protocols[i]); if (lret != LDB_SUCCESS) { ret = EINVAL; goto done; } } lret = ldb_modify(sysdb->ldb, msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)); } ret = sysdb_error_to_errno(lret); done: if (ret) { DEBUG(SSSDBG_TRACE_INTERNAL, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(msg); return ret; } errno_t sysdb_svc_remove_alias(struct sysdb_ctx *sysdb, struct ldb_dn *dn, const char *alias) { errno_t ret; struct ldb_message *msg; int lret; msg = ldb_msg_new(NULL); if (!msg) { ret = ENOMEM; goto done; } msg->dn = dn; ret = add_string(msg, SYSDB_MOD_DEL, SYSDB_NAME_ALIAS, alias); if (ret != EOK) goto done; lret = ldb_modify(sysdb->ldb, msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)); } ret = sysdb_error_to_errno(lret); done: if (ret) { DEBUG(SSSDBG_TRACE_INTERNAL, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(msg); return ret; } errno_t sysdb_svc_delete(struct sss_domain_info *domain, const char *name, int port, const char *proto) { errno_t ret, sret; TALLOC_CTX *tmp_ctx; struct ldb_result *res; unsigned int i; bool in_transaction = false; struct sysdb_ctx *sysdb = domain->sysdb; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; if (name) { ret = sysdb_getservbyname(tmp_ctx, domain, name, proto, &res); if (ret != EOK && ret != ENOENT) goto done; if (ret == ENOENT) { /* Doesn't exist in the DB. Nothing to do */ ret = EOK; goto done; } } else { ret = sysdb_getservbyport(tmp_ctx, domain, port, proto, &res); if (ret != EOK && ret != ENOENT) goto done; if (ret == ENOENT) { /* Doesn't exist in the DB. Nothing to do */ ret = EOK; goto done; } } /* There should only be one matching entry, * but if there are multiple, we should delete * them all to de-corrupt the DB. */ for (i = 0; i < res->count; i++) { ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, false); if (ret != EOK) goto done; } ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_TRACE_INTERNAL, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } errno_t sysdb_enumservent(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_res) { errno_t ret; TALLOC_CTX *tmp_ctx; static const char *attrs[] = SYSDB_SVC_ATTRS; struct ldb_result *res = NULL; struct ldb_message **msgs; size_t msgs_count; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_search_services(mem_ctx, domain, "", attrs, &msgs_count, &msgs); if (ret == EOK) { res = talloc_zero(mem_ctx, struct ldb_result); if (!res) { ret = ENOMEM; goto done; } res->count = msgs_count; res->msgs = talloc_steal(res, msgs); } *_res = res; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_set_service_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op) { errno_t ret; struct ldb_dn *dn; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } dn = sysdb_svc_dn(domain->sysdb, tmp_ctx, domain->name, name); if (!dn) { ret = ENOMEM; goto done; } ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, mod_op); done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_search_services(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs) { TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn; char *filter; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_SVC_BASE, domain->name); if (!basedn) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n"); ret = ENOMEM; goto fail; } filter = talloc_asprintf(tmp_ctx, "(&(%s)%s)", SYSDB_SC, sub_filter); if (!filter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "Search services with filter: %s\n", filter); ret = sysdb_search_entry(mem_ctx, domain->sysdb, basedn, LDB_SCOPE_SUBTREE, filter, attrs, msgs_count, msgs); if (ret) { goto fail; } talloc_zfree(tmp_ctx); return EOK; fail: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_INTERNAL, "No such entry\n"); } else if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb.h0000644000000000000000000000007312703456111014775 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.505793123 sssd-1.13.4/src/db/sysdb.h0000644002412700241270000014662012703456111016456 0ustar00jhrozekjhrozek00000000000000/* SSSD System Database Header Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SYS_DB_H__ #define __SYS_DB_H__ #include "util/util.h" #include "confdb/confdb.h" #include "sss_client/sss_cli.h" #include #define CACHE_SYSDB_FILE "cache_%s.ldb" #define LOCAL_SYSDB_FILE "sssd.ldb" #define SYSDB_BASE "cn=sysdb" #define SYSDB_DOM_BASE "cn=%s,cn=sysdb" #define SYSDB_USERS_CONTAINER "cn=users" #define SYSDB_GROUPS_CONTAINER "cn=groups" #define SYSDB_CUSTOM_CONTAINER "cn=custom" #define SYSDB_NETGROUP_CONTAINER "cn=Netgroups" #define SYSDB_RANGE_CONTAINER "cn=ranges" #define SYSDB_VIEW_CONTAINER "cn=views" #define SYSDB_TMPL_USER_BASE SYSDB_USERS_CONTAINER","SYSDB_DOM_BASE #define SYSDB_TMPL_GROUP_BASE SYSDB_GROUPS_CONTAINER","SYSDB_DOM_BASE #define SYSDB_TMPL_CUSTOM_BASE SYSDB_CUSTOM_CONTAINER","SYSDB_DOM_BASE #define SYSDB_TMPL_NETGROUP_BASE SYSDB_NETGROUP_CONTAINER","SYSDB_DOM_BASE #define SYSDB_TMPL_RANGE_BASE SYSDB_RANGE_CONTAINER","SYSDB_BASE #define SYSDB_TMPL_VIEW_BASE SYSDB_VIEW_CONTAINER","SYSDB_BASE #define SYSDB_TMPL_VIEW_SEARCH_BASE "cn=%s,"SYSDB_TMPL_VIEW_BASE #define SYSDB_SUBDOMAIN_CLASS "subdomain" #define SYSDB_USER_CLASS "user" #define SYSDB_GROUP_CLASS "group" #define SYSDB_NETGROUP_CLASS "netgroup" #define SYSDB_HOST_CLASS "host" #define SYSDB_HOSTGROUP_CLASS "hostgroup" #define SYSDB_SELINUX_USERMAP_CLASS "selinuxusermap" #define SYSDB_SELINUX_CLASS "selinux" #define SYSDB_ID_RANGE_CLASS "idRange" #define SYSDB_DOMAIN_ID_RANGE_CLASS "domainIDRange" #define SYSDB_TRUSTED_AD_DOMAIN_RANGE_CLASS "TrustedADDomainRange" #define SYSDB_NAME "name" #define SYSDB_NAME_ALIAS "nameAlias" #define SYSDB_OBJECTCLASS "objectClass" #define SYSDB_NEXTID "nextID" #define SYSDB_UIDNUM "uidNumber" #define SYSDB_GIDNUM "gidNumber" #define SYSDB_CREATE_TIME "createTimestamp" #define SYSDB_PWD "userPassword" #define SYSDB_FULLNAME "fullName" #define SYSDB_HOMEDIR "homeDirectory" #define SYSDB_SHELL "loginShell" #define SYSDB_MEMBEROF "memberOf" #define SYSDB_DISABLED "disabled" #define SYSDB_MEMBER "member" #define SYSDB_MEMBERUID "memberUid" #define SYSDB_GHOST "ghost" #define SYSDB_POSIX "isPosix" #define SYSDB_USER_CATEGORY "userCategory" #define SYSDB_HOST_CATEGORY "hostCategory" #define SYSDB_GROUP_TYPE "groupType" #define SYSDB_EXTERNAL_MEMBER "externalMember" #define SYSDB_GECOS "gecos" #define SYSDB_LAST_LOGIN "lastLogin" #define SYSDB_LAST_ONLINE_AUTH "lastOnlineAuth" #define SYSDB_LAST_FAILED_LOGIN "lastFailedLogin" #define SYSDB_FAILED_LOGIN_ATTEMPTS "failedLoginAttempts" #define SYSDB_LAST_ONLINE_AUTH_WITH_CURR_TOKEN "lastOnlineAuthWithCurrentToken" #define SYSDB_LAST_UPDATE "lastUpdate" #define SYSDB_CACHE_EXPIRE "dataExpireTimestamp" #define SYSDB_INITGR_EXPIRE "initgrExpireTimestamp" #define SYSDB_IFP_CACHED "ifpCached" #define SYSDB_AUTHORIZED_SERVICE "authorizedService" #define SYSDB_AUTHORIZED_HOST "authorizedHost" #define SYSDB_NETGROUP_TRIPLE "netgroupTriple" #define SYSDB_ORIG_NETGROUP_MEMBER "originalMemberNisNetgroup" #define SYSDB_ORIG_NETGROUP_EXTERNAL_HOST "originalExternalHost" #define SYSDB_NETGROUP_DOMAIN "nisDomain" #define SYSDB_NETGROUP_MEMBER "memberNisNetgroup" #define SYSDB_DESCRIPTION "description" #define SYSDB_FQDN "fqdn" #define SYSDB_SERVERHOSTNAME "serverHostname" #define SYSDB_CACHEDPWD "cachedPassword" #define SYSDB_CACHEDPWD_TYPE "cachedPasswordType" #define SYSDB_CACHEDPWD_FA2_LEN "cachedPasswordSecondFactorLen" #define SYSDB_UUID "uniqueID" #define SYSDB_SID "objectSID" #define SYSDB_PRIMARY_GROUP "ADPrimaryGroupID" #define SYSDB_PRIMARY_GROUP_GIDNUM "origPrimaryGroupGidNumber" #define SYSDB_SID_STR "objectSIDString" #define SYSDB_UPN "userPrincipalName" #define SYSDB_CANONICAL_UPN "canonicalUserPrincipalName" #define SYSDB_CCACHE_FILE "ccacheFile" #define SYSDB_ORIG_DN "originalDN" #define SYSDB_ORIG_MODSTAMP "originalModifyTimestamp" #define SYSDB_ORIG_MEMBEROF "originalMemberOf" #define SYSDB_ORIG_MEMBER "orig_member" #define SYSDB_ORIG_MEMBER_USER "originalMemberUser" #define SYSDB_ORIG_MEMBER_HOST "originalMemberHost" #define SYSDB_USN "entryUSN" #define SYSDB_HIGH_USN "highestUSN" #define SYSDB_SSH_PUBKEY "sshPublicKey" #define SYSDB_AUTH_TYPE "authType" #define SYSDB_USER_CERT "userCertificate" #define SYSDB_SUBDOMAIN_REALM "realmName" #define SYSDB_SUBDOMAIN_FLAT "flatName" #define SYSDB_SUBDOMAIN_ID "domainID" #define SYSDB_SUBDOMAIN_MPG "mpg" #define SYSDB_SUBDOMAIN_ENUM "enumerate" #define SYSDB_SUBDOMAIN_FOREST "memberOfForest" #define SYSDB_SUBDOMAIN_TRUST_DIRECTION "trustDirection" #define SYSDB_BASE_ID "baseID" #define SYSDB_ID_RANGE_SIZE "idRangeSize" #define SYSDB_BASE_RID "baseRID" #define SYSDB_SECONDARY_BASE_RID "secondaryBaseRID" #define SYSDB_DOMAIN_ID "domainID" #define SYSDB_ID_RANGE_TYPE "idRangeType" #define ORIGINALAD_PREFIX "originalAD" #define OVERRIDE_PREFIX "override" #define SYSDB_DEFAULT_OVERRIDE_NAME "defaultOverrideName" #define SYSDB_AD_ACCOUNT_EXPIRES "adAccountExpires" #define SYSDB_AD_USER_ACCOUNT_CONTROL "adUserAccountControl" #define SYSDB_DEFAULT_VIEW_NAME "default" #define SYSDB_LOCAL_VIEW_NAME "LOCAL" /* reserved for client-side overrides */ #define SYSDB_VIEW_CLASS "view" #define SYSDB_VIEW_NAME "viewName" #define SYSDB_OVERRIDE_CLASS "overrride" #define SYSDB_OVERRIDE_ANCHOR_UUID "overrideAnchorUUID" #define SYSDB_OVERRIDE_USER_CLASS "userOverride" #define SYSDB_OVERRIDE_GROUP_CLASS "groupOverride" #define SYSDB_OVERRIDE_DN "overrideDN" #define SYSDB_OVERRIDE_OBJECT_DN "overrideObjectDN" #define SYSDB_NEXTID_FILTER "("SYSDB_NEXTID"=*)" #define SYSDB_UC "objectclass="SYSDB_USER_CLASS #define SYSDB_GC "objectclass="SYSDB_GROUP_CLASS #define SYSDB_NC "objectclass="SYSDB_NETGROUP_CLASS #define SYSDB_MPGC "|("SYSDB_UC")("SYSDB_GC")" #define SYSDB_PWNAM_FILTER "(&("SYSDB_UC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_PWUID_FILTER "(&("SYSDB_UC")("SYSDB_UIDNUM"=%lu))" #define SYSDB_PWSID_FILTER "(&("SYSDB_UC")("SYSDB_SID_STR"=%s))" #define SYSDB_PWUPN_FILTER "(&("SYSDB_UC")(|("SYSDB_UPN"=%s)("SYSDB_CANONICAL_UPN"=%s)))" #define SYSDB_PWENT_FILTER "("SYSDB_UC")" #define SYSDB_GRNAM_FILTER "(&("SYSDB_GC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_GRGID_FILTER "(&("SYSDB_GC")("SYSDB_GIDNUM"=%lu))" #define SYSDB_GRSID_FILTER "(&("SYSDB_GC")("SYSDB_SID_STR"=%s))" #define SYSDB_GRENT_FILTER "("SYSDB_GC")" #define SYSDB_GRNAM_MPG_FILTER "(&("SYSDB_MPGC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_GRGID_MPG_FILTER "(&("SYSDB_MPGC")("SYSDB_GIDNUM"=%lu))" #define SYSDB_GRENT_MPG_FILTER "("SYSDB_MPGC")" #define SYSDB_INITGR_FILTER "(&("SYSDB_GC")("SYSDB_GIDNUM"=*))" #define SYSDB_NETGR_FILTER "(&("SYSDB_NC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_NETGR_TRIPLES_FILTER "(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_MEMBEROF"=%s))" #define SYSDB_SID_FILTER "(&(|("SYSDB_UC")("SYSDB_GC"))("SYSDB_SID_STR"=%s))" #define SYSDB_UUID_FILTER "(&(|("SYSDB_UC")("SYSDB_GC"))("SYSDB_UUID"=%s))" #define SYSDB_USER_CERT_FILTER "(&("SYSDB_UC")%s)" #define SYSDB_HAS_ENUMERATED "has_enumerated" #define SYSDB_DEFAULT_ATTRS SYSDB_LAST_UPDATE, \ SYSDB_CACHE_EXPIRE, \ SYSDB_INITGR_EXPIRE, \ SYSDB_OBJECTCLASS #define SYSDB_PW_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \ SYSDB_GIDNUM, SYSDB_GECOS, \ SYSDB_HOMEDIR, SYSDB_SHELL, \ SYSDB_DEFAULT_ATTRS, \ SYSDB_PRIMARY_GROUP_GIDNUM, \ SYSDB_SID_STR, \ SYSDB_UPN, \ SYSDB_OVERRIDE_DN, \ SYSDB_OVERRIDE_OBJECT_DN, \ SYSDB_DEFAULT_OVERRIDE_NAME, \ NULL} #define SYSDB_GRSRC_ATTRS {SYSDB_NAME, SYSDB_GIDNUM, \ SYSDB_MEMBERUID, \ SYSDB_MEMBER, \ SYSDB_GHOST, \ SYSDB_DEFAULT_ATTRS, \ SYSDB_SID_STR, \ SYSDB_OVERRIDE_DN, \ SYSDB_OVERRIDE_OBJECT_DN, \ SYSDB_DEFAULT_OVERRIDE_NAME, \ NULL} #define SYSDB_NETGR_ATTRS {SYSDB_NAME, SYSDB_NETGROUP_TRIPLE, \ SYSDB_NETGROUP_MEMBER, \ SYSDB_DEFAULT_ATTRS, \ NULL} #define SYSDB_INITGR_ATTR SYSDB_MEMBEROF #define SYSDB_INITGR_ATTRS {SYSDB_GIDNUM, SYSDB_POSIX, \ SYSDB_DEFAULT_ATTRS, \ SYSDB_ORIG_DN, \ SYSDB_SID_STR, \ SYSDB_NAME, \ SYSDB_OVERRIDE_DN, \ NULL} #define SYSDB_TMPL_USER SYSDB_NAME"=%s,"SYSDB_TMPL_USER_BASE #define SYSDB_TMPL_GROUP SYSDB_NAME"=%s,"SYSDB_TMPL_GROUP_BASE #define SYSDB_TMPL_NETGROUP SYSDB_NAME"=%s,"SYSDB_TMPL_NETGROUP_BASE #define SYSDB_TMPL_CUSTOM_SUBTREE "cn=%s,"SYSDB_TMPL_CUSTOM_BASE #define SYSDB_TMPL_CUSTOM SYSDB_NAME"=%s,cn=%s,"SYSDB_TMPL_CUSTOM_BASE #define SYSDB_TMPL_RANGE SYSDB_NAME"=%s,"SYSDB_TMPL_RANGE_BASE #define SYSDB_TMPL_OVERRIDE SYSDB_OVERRIDE_ANCHOR_UUID"=%s,"SYSDB_TMPL_VIEW_SEARCH_BASE #define SYSDB_MOD_ADD LDB_FLAG_MOD_ADD #define SYSDB_MOD_DEL LDB_FLAG_MOD_DELETE #define SYSDB_MOD_REP LDB_FLAG_MOD_REPLACE /* sysdb version check macros */ #define SYSDB_VERSION_ERROR_HINT \ ERROR("Removing cache files in "DB_PATH" should fix the issue, " \ "but note that removing cache files will also remove all of your " \ "cached credentials.\n") #define SYSDB_VERSION_LOWER_ERROR(ret) do { \ if (ret == EUCLEAN) { \ ERROR("Lower version of database is expected!\n"); \ SYSDB_VERSION_ERROR_HINT; \ } \ } while(0) #define SYSDB_VERSION_HIGHER_ERROR(ret) do { \ if (ret == EMEDIUMTYPE) { \ ERROR("Higher version of database is expected!\n"); \ ERROR("In order to upgrade the database, you must run SSSD.\n"); \ SYSDB_VERSION_ERROR_HINT; \ } \ } while(0) /* use this in daemons */ #define SYSDB_VERSION_ERROR_DAEMON(ret) \ SYSDB_VERSION_LOWER_ERROR(ret) /* use this in tools */ #define SYSDB_VERSION_ERROR(ret) \ SYSDB_VERSION_LOWER_ERROR(ret); \ SYSDB_VERSION_HIGHER_ERROR(ret) struct confdb_ctx; struct sysdb_ctx; struct sysdb_attrs { int num; struct ldb_message_element *a; }; /* sysdb_attrs helper functions */ struct sysdb_attrs *sysdb_new_attrs(TALLOC_CTX *mem_ctx); struct range_info { char *name; uint32_t base_id; uint32_t id_range_size; uint32_t base_rid; uint32_t secondary_base_rid; char *trusted_dom_sid; char *range_type; }; /* values are copied in the structure, allocated on "attrs" */ int sysdb_attrs_add_val(struct sysdb_attrs *attrs, const char *name, const struct ldb_val *val); int sysdb_attrs_add_val_safe(struct sysdb_attrs *attrs, const char *name, const struct ldb_val *val); int sysdb_attrs_add_string_safe(struct sysdb_attrs *attrs, const char *name, const char *str); int sysdb_attrs_add_string(struct sysdb_attrs *attrs, const char *name, const char *str); int sysdb_attrs_add_lower_case_string(struct sysdb_attrs *attrs, bool safe, const char *name, const char *str); int sysdb_attrs_add_mem(struct sysdb_attrs *attrs, const char *name, const void *mem, size_t size); int sysdb_attrs_add_bool(struct sysdb_attrs *attrs, const char *name, bool value); int sysdb_attrs_add_long(struct sysdb_attrs *attrs, const char *name, long value); int sysdb_attrs_add_uint32(struct sysdb_attrs *attrs, const char *name, uint32_t value); int sysdb_attrs_add_time_t(struct sysdb_attrs *attrs, const char *name, time_t value); int sysdb_attrs_add_lc_name_alias(struct sysdb_attrs *attrs, const char *value); int sysdb_attrs_add_lc_name_alias_safe(struct sysdb_attrs *attrs, const char *value); int sysdb_attrs_copy_values(struct sysdb_attrs *src, struct sysdb_attrs *dst, const char *name); int sysdb_attrs_get_el(struct sysdb_attrs *attrs, const char *name, struct ldb_message_element **el); int sysdb_attrs_get_el_ext(struct sysdb_attrs *attrs, const char *name, bool alloc, struct ldb_message_element **el); int sysdb_attrs_steal_string(struct sysdb_attrs *attrs, const char *name, char *str); int sysdb_attrs_get_string(struct sysdb_attrs *attrs, const char *name, const char **string); const char **sss_ldb_el_to_string_list(TALLOC_CTX *mem_ctx, struct ldb_message_element *el); int sysdb_attrs_get_string_array(struct sysdb_attrs *attrs, const char *name, TALLOC_CTX *mem_ctx, const char ***string); errno_t sysdb_attrs_get_bool(struct sysdb_attrs *attrs, const char *name, bool *value); int sysdb_attrs_get_uint16_t(struct sysdb_attrs *attrs, const char *name, uint16_t *value); int sysdb_attrs_get_int32_t(struct sysdb_attrs *attrs, const char *name, int32_t *value); int sysdb_attrs_get_uint32_t(struct sysdb_attrs *attrs, const char *name, uint32_t *value); int sysdb_attrs_replace_name(struct sysdb_attrs *attrs, const char *oldname, const char *newname); int sysdb_attrs_users_from_str_list(struct sysdb_attrs *attrs, const char *attr_name, const char *domain, const char *const *list); errno_t sysdb_attrs_primary_name(struct sysdb_ctx *sysdb, struct sysdb_attrs *attrs, const char *ldap_attr, const char **_primary); errno_t sysdb_attrs_get_aliases(TALLOC_CTX *mem_ctx, struct sysdb_attrs *attrs, const char *primary, bool lowercase, const char ***_aliases); errno_t sysdb_attrs_primary_name_list(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx, struct sysdb_attrs **attr_list, size_t attr_count, const char *ldap_attr, char ***name_list); errno_t sysdb_get_real_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_or_upn, const char **_cname); errno_t sysdb_msg2attrs(TALLOC_CTX *mem_ctx, size_t count, struct ldb_message **msgs, struct sysdb_attrs ***attrs); int sysdb_compare_usn(const char *a, const char *b); errno_t sysdb_get_highest_usn(TALLOC_CTX *mem_ctx, struct sysdb_attrs **attrs, size_t num_attrs, char **_usn); /* convert an ldb error into an errno error */ int sysdb_error_to_errno(int ldberr); /* DNs related helper functions */ errno_t sysdb_get_rdn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx, const char *dn, char **_name, char **_val); struct ldb_dn *sysdb_user_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *name); struct ldb_dn *sysdb_user_base_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom); struct ldb_dn *sysdb_group_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *name); struct ldb_dn *sysdb_group_base_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom); struct ldb_dn *sysdb_netgroup_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *name); struct ldb_dn *sysdb_netgroup_base_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom); errno_t sysdb_group_dn_name(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx, const char *dn_str, char **name); struct ldb_dn *sysdb_domain_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom); struct ldb_dn *sysdb_base_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx); struct ldb_dn *sysdb_custom_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *object_name, const char *subtree_name); struct ldb_dn *sysdb_custom_subtree_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *subtree_name); char *sysdb_user_strdn(TALLOC_CTX *mem_ctx, const char *domain, const char *name); char *sysdb_group_strdn(TALLOC_CTX *mem_ctx, const char *domain, const char *name); struct ldb_context *sysdb_ctx_get_ldb(struct sysdb_ctx *sysdb); int compare_ldb_dn_comp_num(const void *m1, const void *m2); /* functions to start and finish transactions */ int sysdb_transaction_start(struct sysdb_ctx *sysdb); int sysdb_transaction_commit(struct sysdb_ctx *sysdb); int sysdb_transaction_cancel(struct sysdb_ctx *sysdb); /* functions related to subdomains */ errno_t sysdb_domain_create(struct sysdb_ctx *sysdb, const char *domain_name); errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, const char *name, const char *realm, const char *flat_name, const char *domain_id, bool mpg, bool enumerate, const char *forest, uint32_t trust_direction); errno_t sysdb_update_subdomains(struct sss_domain_info *domain); errno_t sysdb_master_domain_update(struct sss_domain_info *domain); errno_t sysdb_master_domain_add_info(struct sss_domain_info *domain, const char *realm, const char *flat, const char *id, const char* forest); errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name); errno_t sysdb_get_ranges(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, size_t *range_count, struct range_info ***range_list); errno_t sysdb_range_create(struct sysdb_ctx *sysdb, struct range_info *range); errno_t sysdb_update_ranges(struct sysdb_ctx *sysdb, struct range_info **ranges); errno_t sysdb_update_view_name(struct sysdb_ctx *sysdb, const char *view_name); errno_t sysdb_get_view_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, char **view_name); static inline bool is_default_view(const char *view_name) { /* NULL is treated as default */ if (view_name == NULL || strcmp(view_name, SYSDB_DEFAULT_VIEW_NAME) == 0) { return true; } else { return false; } } static inline bool is_local_view(const char *view_name) { /* NULL is treated as default */ if (view_name != NULL && strcmp(view_name, SYSDB_LOCAL_VIEW_NAME) == 0) { return true; } else { return false; } } errno_t sysdb_delete_view_tree(struct sysdb_ctx *sysdb, const char *view_name); errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb); errno_t sysdb_apply_default_override(struct sss_domain_info *domain, struct sysdb_attrs *override_attrs, struct ldb_dn *obj_dn); errno_t sysdb_search_user_override_attrs_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_result **override_obj, struct ldb_result **orig_obj); errno_t sysdb_search_group_override_attrs_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_result **override_obj, struct ldb_result **orig_obj); errno_t sysdb_search_user_override_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **override_obj, struct ldb_result **orig_obj); errno_t sysdb_search_group_override_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **override_obj, struct ldb_result **orig_obj); errno_t sysdb_search_user_override_by_uid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, uid_t uid, struct ldb_result **override_obj, struct ldb_result **orig_obj); errno_t sysdb_search_group_override_by_gid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, gid_t gid, struct ldb_result **override_obj, struct ldb_result **orig_obj); errno_t sysdb_add_overrides_to_object(struct sss_domain_info *domain, struct ldb_message *obj, struct ldb_message *override_obj, const char **req_attrs); errno_t sysdb_add_group_member_overrides(struct sss_domain_info *domain, struct ldb_message *obj); errno_t sysdb_getpwnam_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **res); errno_t sysdb_getpwuid_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, uid_t uid, struct ldb_result **res); int sysdb_getgrnam_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **res); int sysdb_getgrgid_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, gid_t gid, struct ldb_result **res); struct ldb_message_element * sss_view_ldb_msg_find_element(struct sss_domain_info *dom, const struct ldb_message *msg, const char *attr_name); const char *sss_view_ldb_msg_find_attr_as_string(struct sss_domain_info *dom, const struct ldb_message *msg, const char *attr_name, const char * default_value); uint64_t sss_view_ldb_msg_find_attr_as_uint64(struct sss_domain_info *dom, const struct ldb_message *msg, const char *attr_name, uint64_t default_value); /* Sysdb initialization. * call this function *only* once to initialize the database and get * the sysdb ctx */ int sysdb_init(TALLOC_CTX *mem_ctx, struct sss_domain_info *domains, bool allow_upgrade); /* Same as sysdb_init, but additionally allows to change * file ownership of the sysdb databases. */ int sysdb_init_ext(TALLOC_CTX *mem_ctx, struct sss_domain_info *domains, bool allow_upgrade, bool chown_dbfile, uid_t uid, gid_t gid); /* used to initialize only one domain database. * Do NOT use if sysdb_init has already been called */ int sysdb_domain_init(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *db_path, struct sysdb_ctx **_ctx); /* functions to retrieve information from sysdb * These functions automatically starts an operation * therefore they cannot be called within a transaction */ int sysdb_getpwnam(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **res); int sysdb_getpwuid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, uid_t uid, struct ldb_result **res); int sysdb_getpwupn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *upn, struct ldb_result **res); int sysdb_enumpwent(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **res); int sysdb_enumpwent_filter(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_filter, const char *addtl_filter, struct ldb_result **res); int sysdb_enumpwent_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **res); int sysdb_enumpwent_filter_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_filter, const char *addtl_filter, struct ldb_result **res); int sysdb_getgrnam(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **res); int sysdb_getgrgid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, gid_t gid, struct ldb_result **res); int sysdb_enumgrent(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **res); int sysdb_enumgrent_filter(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_filter, const char *addtl_filter, struct ldb_result **res); int sysdb_enumgrent_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **res); int sysdb_enumgrent_filter_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_filter, const char *addtl_filter, struct ldb_result **res); struct sysdb_netgroup_ctx { enum {SYSDB_NETGROUP_TRIPLE_VAL, SYSDB_NETGROUP_GROUP_VAL} type; union { struct { char *hostname; char *username; char *domainname; } triple; char *groupname; } value; }; errno_t sysdb_getnetgr(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *netgroup, struct ldb_result **res); int sysdb_initgroups(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **res); int sysdb_initgroups_by_upn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *upn, struct ldb_result **res); int sysdb_initgroups_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **res); int sysdb_get_user_attr(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attributes, struct ldb_result **res); int sysdb_get_user_attr_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attributes, struct ldb_result **res); int sysdb_get_netgroup_attr(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *netgrname, const char **attributes, struct ldb_result **res); /* functions that modify the databse * they have to be called within a transaction * See sysdb_transaction_send()/_recv() */ /* Permissive modify */ int sss_ldb_modify_permissive(struct ldb_context *ldb, struct ldb_message *msg); /* Delete Entry */ int sysdb_delete_entry(struct sysdb_ctx *sysdb, struct ldb_dn *dn, bool ignore_not_found); int sysdb_delete_recursive(struct sysdb_ctx *sysdb, struct ldb_dn *dn, bool ignore_not_found); /* Mark entry as expired */ errno_t sysdb_mark_entry_as_expired_ldb_dn(struct sss_domain_info *dom, struct ldb_dn *ldbdn); errno_t sysdb_mark_entry_as_expired_ldb_val(struct sss_domain_info *dom, struct ldb_val *dn_val); /* Search Entry */ int sysdb_search_entry(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct ldb_dn *base_dn, enum ldb_scope scope, const char *filter, const char **attrs, size_t *_msgs_count, struct ldb_message ***_msgs); #define SSS_LDB_SEARCH(ret, ldb, mem_ctx, _result, base, scope, attrs, \ exp_fmt, ...) do { \ int _sls_lret; \ \ _sls_lret = ldb_search(ldb, mem_ctx, _result, base, scope, attrs, \ exp_fmt, ##__VA_ARGS__); \ ret = sysdb_error_to_errno(_sls_lret); \ if (ret == EOK && (*_result)->count == 0) { \ ret = ENOENT; \ } \ } while(0) /* Search User (by uid, sid or name) */ int sysdb_search_user_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_message **msg); int sysdb_search_user_by_uid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, uid_t uid, const char **attrs, struct ldb_message **msg); int sysdb_search_user_by_sid_str(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sid_str, const char **attrs, struct ldb_message **msg); int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *upn, const char **attrs, struct ldb_result **out_res); int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sid_str, const char **attrs, struct ldb_message **msg); /* Search Group (by gid, sid or name) */ int sysdb_search_group_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_message **msg); int sysdb_search_group_by_gid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, gid_t gid, const char **attrs, struct ldb_message **msg); int sysdb_search_group_by_sid_str(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sid_str, const char **attrs, struct ldb_message **msg); /* Search Netgroup (by name) */ int sysdb_search_netgroup_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_message **msg); /* Replace entry attrs */ int sysdb_set_entry_attr(struct sysdb_ctx *sysdb, struct ldb_dn *entry_dn, struct sysdb_attrs *attrs, int mod_op); /* Replace user attrs */ int sysdb_set_user_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op); /* Replace group attrs */ int sysdb_set_group_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op); /* Replace netgroup attrs */ int sysdb_set_netgroup_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op); /* Allocate a new id */ int sysdb_get_new_id(struct sss_domain_info *domain, uint32_t *id); /* Add user (only basic attrs and w/o checks) */ int sysdb_add_basic_user(struct sss_domain_info *domain, const char *name, uid_t uid, gid_t gid, const char *gecos, const char *homedir, const char *shell); /* Add user (all checks) */ int sysdb_add_user(struct sss_domain_info *domain, const char *name, uid_t uid, gid_t gid, const char *gecos, const char *homedir, const char *shell, const char *orig_dn, struct sysdb_attrs *attrs, int cache_timeout, time_t now); /* Add group (only basic attrs and w/o checks) */ int sysdb_add_basic_group(struct sss_domain_info *domain, const char *name, gid_t gid); /* Add group (all checks) */ int sysdb_add_group(struct sss_domain_info *domain, const char *name, gid_t gid, struct sysdb_attrs *attrs, int cache_timeout, time_t now); int sysdb_add_incomplete_group(struct sss_domain_info *domain, const char *name, gid_t gid, const char *original_dn, const char *sid_str, const char *uuid, bool posix, time_t now); /* Add netgroup (only basic attrs and w/o checks) */ int sysdb_add_basic_netgroup(struct sss_domain_info *domain, const char *name, const char *description); int sysdb_add_netgroup(struct sss_domain_info *domain, const char *name, const char *description, struct sysdb_attrs *attrs, char **missing, int cache_timeout, time_t now); /* mod_op must be either LDB_FLAG_MOD_ADD or LDB_FLAG_MOD_DELETE */ int sysdb_mod_group_member(struct sss_domain_info *domain, struct ldb_dn *member_dn, struct ldb_dn *group_dn, int mod_op); int sysdb_store_user(struct sss_domain_info *domain, const char *name, const char *pwd, uid_t uid, gid_t gid, const char *gecos, const char *homedir, const char *shell, const char *orig_dn, struct sysdb_attrs *attrs, char **remove_attrs, uint64_t cache_timeout, time_t now); int sysdb_store_group(struct sss_domain_info *domain, const char *name, gid_t gid, struct sysdb_attrs *attrs, uint64_t cache_timeout, time_t now); enum sysdb_member_type { SYSDB_MEMBER_USER, SYSDB_MEMBER_GROUP, SYSDB_MEMBER_NETGROUP, SYSDB_MEMBER_SERVICE, }; int sysdb_add_group_member(struct sss_domain_info *domain, const char *group, const char *member, enum sysdb_member_type type, bool is_dn); int sysdb_remove_group_member(struct sss_domain_info *domain, const char *group, const char *member, enum sysdb_member_type type, bool is_dn); errno_t sysdb_update_members(struct sss_domain_info *domain, const char *member, enum sysdb_member_type type, const char *const *add_groups, const char *const *del_groups); errno_t sysdb_update_members_dn(struct sss_domain_info *member_domain, const char *member, enum sysdb_member_type type, const char *const *add_groups, const char *const *del_groups); errno_t sysdb_store_override(struct sss_domain_info *domain, const char *view_name, enum sysdb_member_type type, struct sysdb_attrs *attrs, struct ldb_dn *obj_dn); /* Password caching function. * If you are in a transaction ignore sysdb and pass in the handle. * If you are not in a transaction pass NULL in handle and provide sysdb, * in this case a transaction will be automatically started and the * function will be completely wrapped in it's own sysdb transaction */ int sysdb_cache_password(struct sss_domain_info *domain, const char *username, const char *password); int sysdb_cache_password_ex(struct sss_domain_info *domain, const char *username, const char *password, enum sss_authtok_type authtok_type, size_t second_factor_size); errno_t check_failed_login_attempts(struct confdb_ctx *cdb, struct ldb_message *ldb_msg, uint32_t *failed_login_attempts, time_t *delayed_until); int sysdb_cache_auth(struct sss_domain_info *domain, const char *name, const char *password, struct confdb_ctx *cdb, bool just_check, time_t *_expire_date, time_t *_delayed_until); int sysdb_store_custom(struct sss_domain_info *domain, const char *object_name, const char *subtree_name, struct sysdb_attrs *attrs); int sysdb_search_custom(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *filter, const char *subtree_name, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs); int sysdb_search_custom_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *object_name, const char *subtree_name, const char **attrs, size_t *_count, struct ldb_message ***_msgs); int sysdb_delete_custom(struct sss_domain_info *domain, const char *object_name, const char *subtree_name); int sysdb_asq_search(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_dn *base_dn, const char *expression, const char *asq_attribute, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs); int sysdb_search_users(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs); int sysdb_delete_user(struct sss_domain_info *domain, const char *name, uid_t uid); int sysdb_search_groups(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs); int sysdb_delete_group(struct sss_domain_info *domain, const char *name, gid_t gid); int sysdb_search_netgroups(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs); int sysdb_delete_netgroup(struct sss_domain_info *domain, const char *name); int sysdb_delete_by_sid(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *sid_str); errno_t sysdb_attrs_to_list(TALLOC_CTX *mem_ctx, struct sysdb_attrs **attrs, int attr_count, const char *attr_name, char ***_list); errno_t sysdb_netgr_to_entries(TALLOC_CTX *mem_ctx, struct ldb_result *res, struct sysdb_netgroup_ctx ***entries); errno_t sysdb_dn_sanitize(TALLOC_CTX *mem_ctx, const char *input, char **sanitized); errno_t sysdb_get_bool(struct sysdb_ctx *sysdb, struct ldb_dn *dn, const char *attr_name, bool *value); errno_t sysdb_set_bool(struct sysdb_ctx *sysdb, struct ldb_dn *dn, const char *cn_value, const char *attr_name, bool value); errno_t sysdb_has_enumerated(struct sss_domain_info *domain, bool *has_enumerated); errno_t sysdb_set_enumerated(struct sss_domain_info *domain, bool enumerated); errno_t sysdb_remove_attrs(struct sss_domain_info *domain, const char *name, enum sysdb_member_type type, char **remove_attrs); errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, enum sysdb_member_type mtype, const char *name, char ***_direct_parents); /* === Functions related to ID-mapping === */ #define SYSDB_IDMAP_CONTAINER "cn=id_mappings" #define SYSDB_IDMAP_SUBTREE "idmap" #define SYSDB_IDMAP_MAPPING_OC "id_mapping" #define SYSDB_IDMAP_FILTER "(objectClass="SYSDB_IDMAP_MAPPING_OC")" #define SYSDB_IDMAP_SID_ATTR "objectSID" #define SYSDB_IDMAP_SLICE_ATTR "slice" #define SYSDB_IDMAP_ATTRS { \ SYSDB_NAME, \ SYSDB_IDMAP_SID_ATTR, \ SYSDB_IDMAP_SLICE_ATTR, \ NULL } #define SYSDB_TMPL_IDMAP_BASE SYSDB_IDMAP_CONTAINER",cn=%s,"SYSDB_BASE #define SYSDB_TMPL_IDMAP SYSDB_IDMAP_SID_ATTR"=%s,"SYSDB_TMPL_IDMAP_BASE errno_t sysdb_idmap_store_mapping(struct sss_domain_info *domain, const char *dom_name, const char *dom_sid, id_t slice_num); errno_t sysdb_idmap_get_mappings(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_result); errno_t sysdb_search_object_by_sid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sid_str, const char **attrs, struct ldb_result **res); errno_t sysdb_search_object_by_uuid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *uuid_str, const char **attrs, struct ldb_result **res); errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *cert, const char **attrs, struct ldb_result **res); errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *cert, struct ldb_result **res); errno_t sysdb_remove_cert(struct sss_domain_info *domain, const char *cert); /* === Functions related to GPOs === */ #define SYSDB_GPO_CONTAINER "cn=gpos,cn=ad,cn=custom" /* === Functions related to GPO entries === */ #define SYSDB_GPO_OC "gpo" #define SYSDB_GPO_FILTER "(objectClass="SYSDB_GPO_OC")" #define SYSDB_GPO_GUID_FILTER "(&(objectClass="SYSDB_GPO_OC")("SYSDB_GPO_GUID_ATTR"=%s))" #define SYSDB_GPO_GUID_ATTR "gpoGUID" #define SYSDB_GPO_VERSION_ATTR "gpoVersion" #define SYSDB_GPO_TIMEOUT_ATTR "gpoPolicyFileTimeout" #define SYSDB_TMPL_GPO_BASE SYSDB_GPO_CONTAINER","SYSDB_DOM_BASE #define SYSDB_TMPL_GPO SYSDB_GPO_GUID_ATTR"=%s,"SYSDB_TMPL_GPO_BASE #define SYSDB_GPO_ATTRS { \ SYSDB_NAME, \ SYSDB_GPO_GUID_ATTR, \ SYSDB_GPO_VERSION_ATTR, \ SYSDB_GPO_TIMEOUT_ATTR, \ NULL } errno_t sysdb_gpo_store_gpo(struct sss_domain_info *domain, const char *gpo_guid, int gpo_version, int cache_timeout, time_t now); errno_t sysdb_gpo_get_gpo_by_guid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *gpo_guid, struct ldb_result **_result); errno_t sysdb_gpo_get_gpos(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_result); /* === Functions related to GPO Result object === */ #define SYSDB_GPO_RESULT_OC "gpo_result" #define SYSDB_GPO_RESULT_FILTER "(objectClass="SYSDB_GPO_RESULT_OC")" #define SYSDB_TMPL_GPO_RESULT_BASE SYSDB_GPO_CONTAINER","SYSDB_DOM_BASE #define SYSDB_TMPL_GPO_RESULT "cn=%s,"SYSDB_TMPL_GPO_RESULT_BASE errno_t sysdb_gpo_delete_gpo_result_object(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain); errno_t sysdb_gpo_store_gpo_result_setting(struct sss_domain_info *domain, const char *policy_setting_key, const char *policy_setting_value); errno_t sysdb_gpo_get_gpo_result_setting(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *policy_setting_key, const char **policy_setting_value); errno_t sysdb_get_sids_of_members(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *group_name, const char ***_sids, const char ***_dns, size_t *_n); errno_t sysdb_handle_original_uuid(const char *orig_name, struct sysdb_attrs *src_attrs, const char *src_name, struct sysdb_attrs *dest_attrs, const char *dest_name); errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, const char *domain_component_name, struct sysdb_attrs **usr_attrs, size_t count, struct sysdb_attrs **exp_usr); #endif /* __SYS_DB_H__ */ sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_idmap.c0000644000000000000000000000007312703456111016142 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.839794256 sssd-1.13.4/src/db/sysdb_idmap.c0000644002412700241270000002311012703456111017607 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "db/sysdb.h" #include "db/sysdb_private.h" static struct ldb_dn * sysdb_idmap_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *object_sid) { errno_t ret; char *clean_sid; struct ldb_dn *dn; ret = sysdb_dn_sanitize(NULL, object_sid, &clean_sid); if (ret != EOK) { return NULL; } DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_IDMAP"\n", clean_sid, domain->name); dn = ldb_dn_new_fmt(mem_ctx, domain->sysdb->ldb, SYSDB_TMPL_IDMAP, clean_sid, domain->name); talloc_free(clean_sid); return dn; } errno_t sysdb_idmap_store_mapping(struct sss_domain_info *domain, const char *dom_name, const char *dom_sid, id_t slice_num) { errno_t ret, sret; int lret; bool in_transaction = false; TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; static const char *attrs[] = SYSDB_IDMAP_ATTRS; size_t count; struct ldb_message *update_msg; struct ldb_message **msgs; const char *old_name; id_t old_slice; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; dn = sysdb_idmap_dn(tmp_ctx, domain, dom_sid); if (!dn) { ret = ENOMEM; goto done; } update_msg = ldb_msg_new(tmp_ctx); if (!update_msg) { ret = ENOMEM; goto done; } update_msg->dn = dn; ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; /* Check for an existing mapping */ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, dn, LDB_SCOPE_BASE, NULL, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) goto done; if (ret == EOK && count != 1) { /* More than one reply for a base search? */ ret = EIO; goto done; } else if (ret == ENOENT) { /* Create a new mapping */ DEBUG(SSSDBG_CONF_SETTINGS, "Adding new ID mapping [%s][%s][%lu]\n", dom_name, dom_sid, (unsigned long)slice_num); /* Add the objectClass */ lret = ldb_msg_add_empty(update_msg, SYSDB_OBJECTCLASS, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_string(update_msg, SYSDB_OBJECTCLASS, SYSDB_IDMAP_MAPPING_OC); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } /* Add the domain objectSID */ lret = ldb_msg_add_empty(update_msg, SYSDB_IDMAP_SID_ATTR, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_string(update_msg, SYSDB_IDMAP_SID_ATTR, dom_sid); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } /* Add the domain name */ lret = ldb_msg_add_empty(update_msg, SYSDB_NAME, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_string(update_msg, SYSDB_NAME, dom_name); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } /* Add the slice number */ lret = ldb_msg_add_empty(update_msg, SYSDB_IDMAP_SLICE_ATTR, LDB_FLAG_MOD_ADD, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_fmt(update_msg, SYSDB_IDMAP_SLICE_ATTR, "%lu", (unsigned long)slice_num); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_add(domain->sysdb->ldb, update_msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to add mapping: [%s]\n", ldb_strerror(lret)); ret = sysdb_error_to_errno(lret); goto done; } } else { /* Update the existing mapping */ /* Check whether the slice has changed * This should never happen, and it's a recipe for * disaster. We'll throw an error if it does. */ old_slice = ldb_msg_find_attr_as_int(msgs[0], SYSDB_IDMAP_SLICE_ATTR, -1); if (old_slice == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not identify original slice for SID [%s]\n", dom_sid); ret = ENOENT; goto done; } if (slice_num != old_slice) { DEBUG(SSSDBG_FATAL_FAILURE, "Detected attempt to change slice value for sid [%s] " "This will break existing users. Refusing to perform.\n", dom_sid); ret = EINVAL; goto done; } /* Check whether the name has changed. This may happen * if we're told the real name of a domain and want to * replace the SID as placeholder. */ old_name = ldb_msg_find_attr_as_string(msgs[0], SYSDB_NAME, NULL); if (!old_name) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not identify original domain name of SID [%s]\n", dom_sid); ret = ENOENT; goto done; } if (strcmp(old_name, dom_name) == 0) { /* There's nothing to be done. We don't need to * make any changes here. Just return success. */ DEBUG(SSSDBG_TRACE_LIBS, "No changes needed, canceling transaction\n"); ret = EOK; goto done; } else { /* The name has changed. Replace it */ DEBUG(SSSDBG_CONF_SETTINGS, "Changing domain name of SID [%s] from [%s] to [%s]\n", dom_sid, old_name, dom_name); /* Set the new name */ lret = ldb_msg_add_empty(update_msg, SYSDB_NAME, LDB_FLAG_MOD_REPLACE, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } lret = ldb_msg_add_string(update_msg, SYSDB_NAME, dom_name); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } lret = ldb_modify(domain->sysdb->ldb, update_msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to update mapping: [%s](%d)[%s]\n", ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb)); ret = sysdb_error_to_errno(lret); goto done; } } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not commit transaction: [%s]\n", strerror(ret)); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } errno_t sysdb_idmap_get_mappings(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_result) { errno_t ret; struct ldb_dn *base_dn; TALLOC_CTX *tmp_ctx; struct ldb_result *res; static const char *attrs[] = SYSDB_IDMAP_ATTRS; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; DEBUG(SSSDBG_TRACE_ALL, SYSDB_TMPL_IDMAP_BASE"\n", domain->name); base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_IDMAP_BASE, domain->name); if (!base_dn) { ret = ENOMEM; goto done; } SSS_LDB_SEARCH(ret, domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, SYSDB_IDMAP_FILTER); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not locate ID mappings: [%s]\n", sss_strerror(ret)); goto done; } *_result = talloc_steal(mem_ctx, res); ret = EOK; done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_services.h0000644000000000000000000000007312703456111016700 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.514793154 sssd-1.13.4/src/db/sysdb_services.h0000644002412700241270000000700412703456111020351 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SYSDB_SERVICES_H_ #define SYSDB_SERVICES_H_ #include "db/sysdb.h" #define SYSDB_SVC_CLASS "service" #define SYSDB_SVC_CONTAINER "cn=services" #define SYSDB_SC "objectclass="SYSDB_SVC_CLASS #define SYSDB_SVC_PORT "servicePort" #define SYSDB_SVC_PROTO "serviceProtocol" #define SYSDB_TMPL_SVC_BASE SYSDB_SVC_CONTAINER",cn=%s,"SYSDB_BASE #define SYSDB_TMPL_SVC SYSDB_NAME"=%s,"SYSDB_TMPL_SVC_BASE #define SYSDB_SVC_BYNAME_FILTER "(&("SYSDB_SVC_PROTO"=%s)(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_SVC_BYPORT_FILTER "(&("SYSDB_SVC_PROTO"=%s)("SYSDB_SVC_PORT"=%u))" #define SYSDB_SVC_ATTRS { \ SYSDB_NAME, \ SYSDB_NAME_ALIAS, \ SYSDB_SVC_PORT, \ SYSDB_SVC_PROTO, \ SYSDB_DEFAULT_ATTRS, \ NULL } errno_t sysdb_getservbyname(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char *proto, struct ldb_result **_res); errno_t sysdb_getservbyport(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, int port, const char *proto, struct ldb_result **_res); errno_t sysdb_enumservent(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_res); errno_t sysdb_store_service(struct sss_domain_info *domain, const char *primary_name, int port, const char **aliases, const char **protocols, struct sysdb_attrs *extra_attrs, char **remove_attrs, uint64_t cache_timeout, time_t now); struct ldb_dn * sysdb_svc_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx, const char *domain, const char *name); errno_t sysdb_svc_add(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *primary_name, int port, const char **aliases, const char **protocols, struct ldb_dn **dn); errno_t sysdb_svc_delete(struct sss_domain_info *domain, const char *name, int port, const char *proto); errno_t sysdb_set_service_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op); errno_t sysdb_search_services(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs); #endif /* SYSDB_SERVICES_H_ */ sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_autofs.h0000644000000000000000000000007312703456111016356 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.509793137 sssd-1.13.4/src/db/sysdb_autofs.h0000644002412700241270000000573612703456111020041 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SYSDB_AUTOFS_H_ #define _SYSDB_AUTOFS_H_ #include "db/sysdb.h" /* subdirs in cn=custom in sysdb. We don't store autofs stuff in sysdb directly * b/c it's not name-service-switch data */ #define AUTOFS_MAP_SUBDIR "autofsmaps" #define AUTOFS_ENTRY_SUBDIR "autofsentries" #define SYSDB_AUTOFS_MAP_OC "automountMap" #define SYSDB_AUTOFS_MAP_NAME "automountMapName" #define SYSDB_AUTOFS_ENTRY_OC "automount" #define SYSDB_AUTOFS_ENTRY_KEY "automountKey" #define SYSDB_AUTOFS_ENTRY_VALUE "automountInformation" errno_t sysdb_save_autofsmap(struct sss_domain_info *domain, const char *name, const char *autofsmapname, struct sysdb_attrs *attrs, int cache_timeout, time_t now); errno_t sysdb_get_map_byname(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *map_name, struct ldb_message **map); errno_t sysdb_delete_autofsmap(struct sss_domain_info *domain, const char *name); errno_t sysdb_save_autofsentry(struct sss_domain_info *domain, const char *map, const char *key, const char *value, struct sysdb_attrs *attrs); errno_t sysdb_del_autofsentry(struct sss_domain_info *domain, const char *entry_dn); errno_t sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *mapname, size_t *_count, struct ldb_message ***_entries); errno_t sysdb_set_autofsmap_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op); errno_t sysdb_invalidate_autofs_maps(struct sss_domain_info *domain); char * sysdb_autofsentry_strdn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *map_name, const char *entry_name, const char *entry_value); #endif /* _SYSDB_AUTOFS_H_ */ sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_search.c0000644000000000000000000000007312703456111016315 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.831794229 sssd-1.13.4/src/db/sysdb_search.c0000644002412700241270000015125312703456111017774 0ustar00jhrozekjhrozek00000000000000/* SSSD System Database Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb_private.h" #include "confdb/confdb.h" #include #include /* users */ int sysdb_getpwnam(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; static const char *attrs[] = SYSDB_PW_ATTRS; struct ldb_dn *base_dn; struct ldb_result *res; char *sanitized_name; char *lc_sanitized_name; const char *src_name; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } base_dn = sysdb_user_base_dn(tmp_ctx, domain); if (!base_dn) { ret = ENOMEM; goto done; } /* If this is a subdomain we need to use fully qualified names for the * search as well by default */ src_name = sss_get_domain_name(tmp_ctx, name, domain); if (!src_name) { ret = ENOMEM; goto done; } ret = sss_filter_sanitize_for_dom(tmp_ctx, src_name, domain, &sanitized_name, &lc_sanitized_name); if (ret != EOK) { goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, SYSDB_PWNAM_FILTER, lc_sanitized_name, sanitized_name, sanitized_name); if (ret) { ret = sysdb_error_to_errno(ret); goto done; } *_res = talloc_steal(mem_ctx, res); done: talloc_zfree(tmp_ctx); return ret; } errno_t sysdb_getpwnam_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **res) { int ret; struct ldb_result *orig_obj = NULL; struct ldb_result *override_obj = NULL; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } /* If there are views we first have to search the overrides for matches */ if (DOM_HAS_VIEWS(domain)) { ret = sysdb_search_user_override_by_name(tmp_ctx, domain, name, &override_obj, &orig_obj); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_override_by_name failed.\n"); goto done; } } /* If there are no views or nothing was found in the overrides the * original objects are searched. */ if (orig_obj == NULL) { ret = sysdb_getpwnam(tmp_ctx, domain, name, &orig_obj); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_getpwnam failed.\n"); goto done; } } /* If there are views we have to check if override values must be added to * the original object. */ if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) { ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0], override_obj == NULL ? NULL : override_obj->msgs[0], NULL); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); goto done; } if (ret == ENOENT) { *res = talloc_zero(mem_ctx, struct ldb_result); if (*res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; } else { ret = EOK; } goto done; } } *res = talloc_steal(mem_ctx, orig_obj); ret = EOK; done: talloc_free(tmp_ctx); return ret; } int sysdb_getpwuid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, uid_t uid, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; unsigned long int ul_uid = uid; static const char *attrs[] = SYSDB_PW_ATTRS; struct ldb_dn *base_dn; struct ldb_result *res; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } base_dn = sysdb_user_base_dn(tmp_ctx, domain); if (!base_dn) { ret = ENOMEM; goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, SYSDB_PWUID_FILTER, ul_uid); if (ret) { ret = sysdb_error_to_errno(ret); goto done; } *_res = talloc_steal(mem_ctx, res); done: talloc_zfree(tmp_ctx); return ret; } errno_t sysdb_getpwuid_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, uid_t uid, struct ldb_result **res) { int ret; struct ldb_result *orig_obj = NULL; struct ldb_result *override_obj = NULL; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } /* If there are views we first have to search the overrides for matches */ if (DOM_HAS_VIEWS(domain)) { ret = sysdb_search_user_override_by_uid(tmp_ctx, domain, uid, &override_obj, &orig_obj); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_override_by_uid failed.\n"); goto done; } } /* If there are no views or nothing was found in the overrides the * original objects are searched. */ if (orig_obj == NULL) { ret = sysdb_getpwuid(tmp_ctx, domain, uid, &orig_obj); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_getpwuid failed.\n"); goto done; } } /* If there are views we have to check if override values must be added to * the original object. */ if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) { ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0], override_obj == NULL ? NULL : override_obj->msgs[0], NULL); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); goto done; } if (ret == ENOENT) { *res = talloc_zero(mem_ctx, struct ldb_result); if (*res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; } else { ret = EOK; } goto done; } } *res = talloc_steal(mem_ctx, orig_obj); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static char *enum_filter(TALLOC_CTX *mem_ctx, const char *base_filter, const char *name_filter, const char *addtl_filter) { char *filter; TALLOC_CTX *tmp_ctx = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NULL; } if (name_filter == NULL && addtl_filter == NULL) { filter = talloc_strdup(tmp_ctx, base_filter); } else { filter = talloc_asprintf(tmp_ctx, "(&%s", base_filter); if (filter != NULL && name_filter != NULL) { filter = talloc_asprintf_append(filter, "(%s=%s)", SYSDB_NAME, name_filter); } if (filter != NULL && addtl_filter != NULL) { filter = talloc_asprintf_append(filter, "%s", addtl_filter); } if (filter != NULL) { filter = talloc_asprintf_append(filter, ")"); } } if (filter) { talloc_steal(mem_ctx, filter); } talloc_free(tmp_ctx); return filter; } int sysdb_getpwupn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *upn, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; static const char *attrs[] = SYSDB_PW_ATTRS; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } ret = sysdb_search_user_by_upn_res(tmp_ctx, domain, upn, attrs, &res); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn_res() failed.\n"); goto done; } *_res = talloc_steal(mem_ctx, res); done: talloc_free(tmp_ctx); return ret; } int sysdb_enumpwent_filter(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_filter, const char *addtl_filter, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; static const char *attrs[] = SYSDB_PW_ATTRS; char *filter = NULL; struct ldb_dn *base_dn; struct ldb_result *res; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } base_dn = sysdb_user_base_dn(tmp_ctx, domain); if (!base_dn) { ret = ENOMEM; goto done; } filter = enum_filter(tmp_ctx, SYSDB_PWENT_FILTER, name_filter, addtl_filter); if (filter == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Searching cache with [%s]\n", filter); ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, "%s", filter); if (ret) { ret = sysdb_error_to_errno(ret); goto done; } *_res = talloc_steal(mem_ctx, res); done: talloc_zfree(tmp_ctx); return ret; } int sysdb_enumpwent(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_res) { return sysdb_enumpwent_filter(mem_ctx, domain, NULL, 0, _res); } int sysdb_enumpwent_filter_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_filter, const char *addtl_filter, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; size_t c; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = sysdb_enumpwent_filter(tmp_ctx, domain, name_filter, addtl_filter, &res); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_enumpwent failed.\n"); goto done; } if (DOM_HAS_VIEWS(domain)) { for (c = 0; c < res->count; c++) { ret = sysdb_add_overrides_to_object(domain, res->msgs[c], NULL, NULL); /* enumeration assumes that the cache is up-to-date, hence we do not * need to handle ENOENT separately. */ if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); goto done; } } } *_res = talloc_steal(mem_ctx, res); done: talloc_zfree(tmp_ctx); return ret; } int sysdb_enumpwent_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_res) { return sysdb_enumpwent_filter_with_views(mem_ctx, domain, NULL, NULL, _res); } /* groups */ static int mpg_convert(struct ldb_message *msg) { struct ldb_message_element *el; struct ldb_val *val = NULL; int i; el = ldb_msg_find_element(msg, "objectClass"); if (!el) return EINVAL; /* see if this is a user to convert to a group */ for (i = 0; i < el->num_values; i++) { val = &(el->values[i]); if (strncasecmp(SYSDB_USER_CLASS, (char *)val->data, val->length) == 0) { break; } } /* no, leave as is */ if (i == el->num_values) return EOK; /* yes, convert */ val->data = (uint8_t *)talloc_strdup(msg, SYSDB_GROUP_CLASS); if (val->data == NULL) return ENOMEM; val->length = strlen(SYSDB_GROUP_CLASS); return EOK; } static int mpg_res_convert(struct ldb_result *res) { int ret; int i; for (i = 0; i < res->count; i++) { ret = mpg_convert(res->msgs[i]); if (ret) { return ret; } } return EOK; } int sysdb_getgrnam_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **res) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_result *orig_obj = NULL; struct ldb_result *override_obj = NULL; struct ldb_message_element *el; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } /* If there are views we first have to search the overrides for matches */ if (DOM_HAS_VIEWS(domain)) { ret = sysdb_search_group_override_by_name(tmp_ctx, domain, name, &override_obj, &orig_obj); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_group_override_by_name failed.\n"); goto done; } } /* If there are no views or nothing was found in the overrides the * original objects are searched. */ if (orig_obj == NULL) { ret = sysdb_getgrnam(tmp_ctx, domain, name, &orig_obj); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_getgrnam failed.\n"); goto done; } } /* If there are views we have to check if override values must be added to * the original object. */ if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) { if (!is_local_view(domain->view_name)) { el = ldb_msg_find_element(orig_obj->msgs[0], SYSDB_GHOST); if (el != NULL && el->num_values != 0) { DEBUG(SSSDBG_TRACE_ALL, "Group object [%s], contains ghost " "entries which must be resolved before overrides can be " "applied.\n", ldb_dn_get_linearized(orig_obj->msgs[0]->dn)); ret = ENOENT; goto done; } } ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0], override_obj == NULL ? NULL : override_obj ->msgs[0], NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); goto done; } ret = sysdb_add_group_member_overrides(domain, orig_obj->msgs[0]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_group_member_overrides failed.\n"); goto done; } } *res = talloc_steal(mem_ctx, orig_obj); ret = EOK; done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "Returning empty result.\n"); *res = talloc_zero(mem_ctx, struct ldb_result); if (*res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; } else { ret = EOK; } } talloc_free(tmp_ctx); return ret; } int sysdb_getgrnam(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; static const char *attrs[] = SYSDB_GRSRC_ATTRS; const char *fmt_filter; char *sanitized_name; struct ldb_dn *base_dn; struct ldb_result *res; const char *src_name; char *lc_sanitized_name; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (domain->mpg) { fmt_filter = SYSDB_GRNAM_MPG_FILTER; base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_DOM_BASE, domain->name); } else { fmt_filter = SYSDB_GRNAM_FILTER; base_dn = sysdb_group_base_dn(tmp_ctx, domain); } if (!base_dn) { ret = ENOMEM; goto done; } /* If this is a subomain we need to use fully qualified names for the * search as well by default */ src_name = sss_get_domain_name(tmp_ctx, name, domain); if (!src_name) { ret = ENOMEM; goto done; } ret = sss_filter_sanitize_for_dom(tmp_ctx, src_name, domain, &sanitized_name, &lc_sanitized_name); if (ret != EOK) { goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, fmt_filter, lc_sanitized_name, sanitized_name, sanitized_name); if (ret) { ret = sysdb_error_to_errno(ret); goto done; } ret = mpg_res_convert(res); if (ret) { goto done; } *_res = talloc_steal(mem_ctx, res); done: talloc_zfree(tmp_ctx); return ret; } int sysdb_getgrgid_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, gid_t gid, struct ldb_result **res) { TALLOC_CTX *tmp_ctx; int ret; struct ldb_result *orig_obj = NULL; struct ldb_result *override_obj = NULL; struct ldb_message_element *el; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } /* If there are views we first have to search the overrides for matches */ if (DOM_HAS_VIEWS(domain)) { ret = sysdb_search_group_override_by_gid(tmp_ctx, domain, gid, &override_obj, &orig_obj); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_group_override_by_gid failed.\n"); goto done; } } /* If there are no views or nothing was found in the overrides the * original objects are searched. */ if (orig_obj == NULL) { ret = sysdb_getgrgid(tmp_ctx, domain, gid, &orig_obj); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_getgrgid failed.\n"); goto done; } } /* If there are views we have to check if override values must be added to * the original object. */ if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) { if (!is_local_view(domain->view_name)) { el = ldb_msg_find_element(orig_obj->msgs[0], SYSDB_GHOST); if (el != NULL && el->num_values != 0) { DEBUG(SSSDBG_TRACE_ALL, "Group object [%s], contains ghost " "entries which must be resolved before overrides can be " "applied.\n", ldb_dn_get_linearized(orig_obj->msgs[0]->dn)); ret = ENOENT; goto done; } } ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0], override_obj == NULL ? NULL : override_obj ->msgs[0], NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); goto done; } ret = sysdb_add_group_member_overrides(domain, orig_obj->msgs[0]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_group_member_overrides failed.\n"); goto done; } } *res = talloc_steal(mem_ctx, orig_obj); ret = EOK; done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_ALL, "Returning empty result.\n"); *res = talloc_zero(mem_ctx, struct ldb_result); if (*res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; } else { ret = EOK; } } talloc_free(tmp_ctx); return ret; } int sysdb_getgrgid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, gid_t gid, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; unsigned long int ul_gid = gid; static const char *attrs[] = SYSDB_GRSRC_ATTRS; const char *fmt_filter; struct ldb_dn *base_dn; struct ldb_result *res; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (domain->mpg) { fmt_filter = SYSDB_GRGID_MPG_FILTER; base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_DOM_BASE, domain->name); } else { fmt_filter = SYSDB_GRGID_FILTER; base_dn = sysdb_group_base_dn(tmp_ctx, domain); } if (!base_dn) { ret = ENOMEM; goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, fmt_filter, ul_gid); if (ret) { ret = sysdb_error_to_errno(ret); goto done; } ret = mpg_res_convert(res); if (ret) { goto done; } *_res = talloc_steal(mem_ctx, res); done: talloc_zfree(tmp_ctx); return ret; } int sysdb_enumgrent_filter(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_filter, const char *addtl_filter, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; static const char *attrs[] = SYSDB_GRSRC_ATTRS; const char *filter = NULL; const char *base_filter; struct ldb_dn *base_dn; struct ldb_result *res; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (domain->mpg) { base_filter = SYSDB_GRENT_MPG_FILTER; base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_DOM_BASE, domain->name); } else { base_filter = SYSDB_GRENT_FILTER; base_dn = sysdb_group_base_dn(tmp_ctx, domain); } if (!base_dn) { ret = ENOMEM; goto done; } filter = enum_filter(tmp_ctx, base_filter, name_filter, addtl_filter); if (filter == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Searching cache with [%s]\n", filter); ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs, "%s", filter); if (ret) { ret = sysdb_error_to_errno(ret); goto done; } ret = mpg_res_convert(res); if (ret) { goto done; } *_res = talloc_steal(mem_ctx, res); done: talloc_zfree(tmp_ctx); return ret; } int sysdb_enumgrent(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_res) { return sysdb_enumgrent_filter(mem_ctx, domain, NULL, 0, _res); } int sysdb_enumgrent_filter_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_filter, const char *addtl_filter, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; size_t c; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = sysdb_enumgrent_filter(tmp_ctx, domain, name_filter, addtl_filter, &res); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_enumgrent failed.\n"); goto done; } if (DOM_HAS_VIEWS(domain)) { for (c = 0; c < res->count; c++) { ret = sysdb_add_overrides_to_object(domain, res->msgs[c], NULL, NULL); /* enumeration assumes that the cache is up-to-date, hence we do not * need to handle ENOENT separately. */ if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); goto done; } ret = sysdb_add_group_member_overrides(domain, res->msgs[c]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_group_member_overrides failed.\n"); goto done; } } } *_res = talloc_steal(mem_ctx, res); done: talloc_zfree(tmp_ctx); return ret; } int sysdb_enumgrent_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_result **_res) { return sysdb_enumgrent_filter_with_views(mem_ctx, domain, NULL, NULL, _res); } int sysdb_initgroups(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_dn *user_dn; struct ldb_request *req; struct ldb_control **ctrl; struct ldb_asq_control *control; static const char *attrs[] = SYSDB_INITGR_ATTRS; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_getpwnam(tmp_ctx, domain, name, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_getpwnam failed: [%d][%s]\n", ret, strerror(ret)); goto done; } if (res->count == 0) { /* User is not cached yet */ *_res = talloc_steal(mem_ctx, res); ret = EOK; goto done; } else if (res->count != 1) { ret = EIO; DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_getpwnam returned count: [%d]\n", res->count); goto done; } /* no need to steal the dn, we are not freeing the result */ user_dn = res->msgs[0]->dn; /* note we count on the fact that the default search callback * will just keep appending values. This is by design and can't * change so it is ok to already have a result (from the getpwnam) * even before we call the next search */ ctrl = talloc_array(tmp_ctx, struct ldb_control *, 2); if (!ctrl) { ret = ENOMEM; goto done; } ctrl[1] = NULL; ctrl[0] = talloc(ctrl, struct ldb_control); if (!ctrl[0]) { ret = ENOMEM; goto done; } ctrl[0]->oid = LDB_CONTROL_ASQ_OID; ctrl[0]->critical = 1; control = talloc(ctrl[0], struct ldb_asq_control); if (!control) { ret = ENOMEM; goto done; } control->request = 1; control->source_attribute = talloc_strdup(control, SYSDB_INITGR_ATTR); if (!control->source_attribute) { ret = ENOMEM; goto done; } control->src_attr_len = strlen(control->source_attribute); ctrl[0]->data = control; ret = ldb_build_search_req(&req, domain->sysdb->ldb, tmp_ctx, user_dn, LDB_SCOPE_BASE, SYSDB_INITGR_FILTER, attrs, ctrl, res, ldb_search_default_callback, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_request(domain->sysdb->ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } *_res = talloc_steal(mem_ctx, res); done: talloc_zfree(tmp_ctx); return ret; } int sysdb_initgroups_by_upn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *upn, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; struct ldb_result *res; const char *sysdb_name; static const char *attrs[] = SYSDB_INITGR_ATTRS; size_t i; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } ret = sysdb_search_user_by_upn(tmp_ctx, domain, upn, attrs, &msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn() failed.\n"); goto done; } res = talloc_zero(tmp_ctx, struct ldb_result); if (res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero() failed.\n"); ret = ENOMEM; goto done; } if (ret == ENOENT) { res->count = 0; res->msgs = NULL; } else { sysdb_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); if (sysdb_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Sysdb entry does not have a name.\n"); return EINVAL; } ret = sysdb_initgroups(tmp_ctx, domain, sysdb_name, &res); if (ret == EOK && DOM_HAS_VIEWS(domain)) { for (i = 0; i < res->count; i++) { ret = sysdb_add_overrides_to_object(domain, res->msgs[i], NULL, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object() failed.\n"); return ret; } } } } *_res = talloc_steal(mem_ctx, res); ret = EOK; done: talloc_free(tmp_ctx); return ret; } int sysdb_initgroups_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_dn *user_dn; struct ldb_request *req; struct ldb_control **ctrl; struct ldb_asq_control *control; static const char *attrs[] = SYSDB_INITGR_ATTRS; int ret; size_t c; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_getpwnam_with_views(tmp_ctx, domain, name, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_getpwnam failed: [%d][%s]\n", ret, strerror(ret)); goto done; } if (res->count == 0) { /* User is not cached yet */ *_res = talloc_steal(mem_ctx, res); ret = EOK; goto done; } else if (res->count != 1) { ret = EIO; DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_getpwnam returned count: [%d]\n", res->count); goto done; } /* no need to steal the dn, we are not freeing the result */ user_dn = res->msgs[0]->dn; /* note we count on the fact that the default search callback * will just keep appending values. This is by design and can't * change so it is ok to already have a result (from the getpwnam) * even before we call the next search */ ctrl = talloc_array(tmp_ctx, struct ldb_control *, 2); if (!ctrl) { ret = ENOMEM; goto done; } ctrl[1] = NULL; ctrl[0] = talloc(ctrl, struct ldb_control); if (!ctrl[0]) { ret = ENOMEM; goto done; } ctrl[0]->oid = LDB_CONTROL_ASQ_OID; ctrl[0]->critical = 1; control = talloc(ctrl[0], struct ldb_asq_control); if (!control) { ret = ENOMEM; goto done; } control->request = 1; control->source_attribute = talloc_strdup(control, SYSDB_INITGR_ATTR); if (!control->source_attribute) { ret = ENOMEM; goto done; } control->src_attr_len = strlen(control->source_attribute); ctrl[0]->data = control; ret = ldb_build_search_req(&req, domain->sysdb->ldb, tmp_ctx, user_dn, LDB_SCOPE_BASE, SYSDB_INITGR_FILTER, attrs, ctrl, res, ldb_search_default_callback, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_request(domain->sysdb->ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } if (DOM_HAS_VIEWS(domain)) { /* Skip user entry because it already has override values added */ for (c = 1; c < res->count; c++) { ret = sysdb_add_overrides_to_object(domain, res->msgs[c], NULL, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); goto done; } } } *_res = talloc_steal(mem_ctx, res); done: talloc_zfree(tmp_ctx); return ret; } int sysdb_get_user_attr(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attributes, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; struct ldb_dn *base_dn; struct ldb_result *res; const char *src_name; char *sanitized_name; char *lc_sanitized_name; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } base_dn = sysdb_user_base_dn(tmp_ctx, domain); if (!base_dn) { ret = ENOMEM; goto done; } /* If this is a subdomain we need to use fully qualified names for the * search as well by default */ src_name = sss_get_domain_name(tmp_ctx, name, domain); if (!src_name) { ret = ENOMEM; goto done; } ret = sss_filter_sanitize_for_dom(tmp_ctx, src_name, domain, &sanitized_name, &lc_sanitized_name); if (ret != EOK) { goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attributes, SYSDB_PWNAM_FILTER, lc_sanitized_name, sanitized_name, sanitized_name); if (ret) { ret = sysdb_error_to_errno(ret); goto done; } *_res = talloc_steal(mem_ctx, res); done: talloc_zfree(tmp_ctx); return ret; } int sysdb_get_user_attr_with_views(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attributes, struct ldb_result **_res) { int ret; struct ldb_result *orig_obj = NULL; struct ldb_result *override_obj = NULL; const char **attrs = NULL; const char *mandatory_override_attrs[] = {SYSDB_OVERRIDE_DN, SYSDB_OVERRIDE_OBJECT_DN, NULL}; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } attrs = attributes; /* If there are views we first have to search the overrides for matches */ if (DOM_HAS_VIEWS(domain)) { ret = add_strings_lists(tmp_ctx, attributes, mandatory_override_attrs, false, discard_const(&attrs)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_strings_lists failed.\n"); goto done; } ret = sysdb_search_user_override_attrs_by_name(tmp_ctx, domain, name, attrs, &override_obj, &orig_obj); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_override_attrs_by_name failed.\n"); return ret; } } /* If there are no views or nothing was found in the overrides the * original objects are searched. */ if (orig_obj == NULL) { ret = sysdb_get_user_attr(tmp_ctx, domain, name, attrs, &orig_obj); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_user_attr failed.\n"); return ret; } } /* If there are views we have to check if override values must be added to * the original object. */ if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) { ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0], override_obj == NULL ? NULL : override_obj ->msgs[0], attrs); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); return ret; } if (ret == ENOENT) { *_res = talloc_zero(mem_ctx, struct ldb_result); if (*_res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; } else { ret = EOK; } goto done; } } *_res = talloc_steal(mem_ctx, orig_obj); ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* This function splits a three-tuple into three strings * It assumes that any whitespace between the parentheses * and commas are intentional and does not attempt to * strip them out. Leading and trailing whitespace is * ignored. * * This behavior is compatible with nss_ldap's * implementation. */ static errno_t sysdb_netgr_split_triple(TALLOC_CTX *mem_ctx, const char *triple, char **hostname, char **username, char **domainname) { errno_t ret; TALLOC_CTX *tmp_ctx; const char *p = triple; const char *p_host; const char *p_user; const char *p_domain; size_t len; char *host = NULL; char *user = NULL; char *domain = NULL; /* Pre-set the values to NULL here so if they are not * copied, we don't return garbage below. */ *hostname = NULL; *username = NULL; *domainname = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } /* Remove any leading whitespace */ while (*p && isspace(*p)) p++; if (*p != '(') { /* Triple must start and end with parentheses */ ret = EINVAL; goto done; } p++; p_host = p; /* Find the first comma */ while (*p && *p != ',') p++; if (!*p) { /* No comma was found: parse error */ ret = EINVAL; goto done; } len = p - p_host; if (len > 0) { /* Copy the host string */ host = talloc_strndup(tmp_ctx, p_host, len); if (!host) { ret = ENOMEM; goto done; } } p++; p_user = p; /* Find the second comma */ while (*p && *p != ',') p++; if (!*p) { /* No comma was found: parse error */ ret = EINVAL; goto done; } len = p - p_user; if (len > 0) { /* Copy the user string */ user = talloc_strndup(tmp_ctx, p_user, len); if (!user) { ret = ENOMEM; goto done; } } p++; p_domain = p; /* Find the closing parenthesis */ while (*p && *p != ')') p++; if (*p != ')') { /* No trailing parenthesis: parse error */ ret = EINVAL; goto done; } len = p - p_domain; if (len > 0) { /* Copy the domain string */ domain = talloc_strndup(tmp_ctx, p_domain, len); if (!domain) { ret = ENOMEM; goto done; } } p++; /* skip trailing whitespace */ while (*p && isspace(*p)) p++; if (*p) { /* Extra data after the closing parenthesis * is a parse error */ ret = EINVAL; goto done; } /* Return any non-NULL values */ if (host) { *hostname = talloc_steal(mem_ctx, host); } if (user) { *username = talloc_steal(mem_ctx, user); } if (domain) { *domainname = talloc_steal(mem_ctx, domain); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_netgr_to_entries(TALLOC_CTX *mem_ctx, struct ldb_result *res, struct sysdb_netgroup_ctx ***entries) { errno_t ret; size_t size = 0; size_t c = 0; char *triple_str; TALLOC_CTX *tmp_ctx; struct sysdb_netgroup_ctx **tmp_entry = NULL; struct ldb_message_element *el; int i, j; if(!res || res->count == 0) { return ENOENT; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } for (i=0; i < res->count; i++) { el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_TRIPLE); if (el != NULL) { size += el->num_values; } el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_MEMBER); if (el != NULL) { size += el->num_values; } } tmp_entry = talloc_array(tmp_ctx, struct sysdb_netgroup_ctx *, size + 1); if (tmp_entry == NULL) { ret = ENOMEM; goto done; } if (size != 0) { for (i=0; i < res->count; i++) { el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_TRIPLE); if (el != NULL) { /* Copy in all of the entries */ for(j = 0; j < el->num_values; j++) { triple_str = talloc_strndup(tmp_ctx, (const char *)el->values[j].data, el->values[j].length); if (!triple_str) { ret = ENOMEM; goto done; } tmp_entry[c] = talloc_zero(tmp_entry, struct sysdb_netgroup_ctx); if (!tmp_entry[c]) { ret = ENOMEM; goto done; } tmp_entry[c]->type = SYSDB_NETGROUP_TRIPLE_VAL; ret = sysdb_netgr_split_triple(tmp_entry[c], triple_str, &tmp_entry[c]->value.triple.hostname, &tmp_entry[c]->value.triple.username, &tmp_entry[c]->value.triple.domainname); if (ret != EOK) { DEBUG(SSSDBG_IMPORTANT_INFO, "Cannot split netgroup triple [%s], " "this attribute will be skipped \n", triple_str); continue; } c++; } } el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_MEMBER); if (el != NULL) { for(j = 0; j < el->num_values; j++) { tmp_entry[c] = talloc_zero(tmp_entry, struct sysdb_netgroup_ctx); if (!tmp_entry[c]) { ret = ENOMEM; goto done; } tmp_entry[c]->type = SYSDB_NETGROUP_GROUP_VAL; tmp_entry[c]->value.groupname = talloc_strndup(tmp_entry[c], (const char *)el->values[j].data, el->values[j].length); if (tmp_entry[c]->value.groupname == NULL) { ret = ENOMEM; goto done; } c++; } } } } /* Add NULL terminator */ tmp_entry[c] = NULL; *entries = talloc_steal(mem_ctx, tmp_entry); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_getnetgr(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *netgroup, struct ldb_result **res) { TALLOC_CTX *tmp_ctx; static const char *attrs[] = SYSDB_NETGR_ATTRS; struct ldb_dn *base_dn; struct ldb_result *result = NULL; char *sanitized_netgroup; char *lc_sanitized_netgroup; char *netgroup_dn; errno_t ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_NETGROUP_BASE, domain->name); if (!base_dn) { ret = ENOMEM; goto done; } ret = sss_filter_sanitize_for_dom(tmp_ctx, netgroup, domain, &sanitized_netgroup, &lc_sanitized_netgroup); if (ret != EOK) { goto done; } netgroup_dn = talloc_asprintf(tmp_ctx, SYSDB_TMPL_NETGROUP, sanitized_netgroup, domain->name); if (!netgroup_dn) { ret = ENOMEM; goto done; } SSS_LDB_SEARCH(ret, domain->sysdb->ldb, tmp_ctx, &result, base_dn, LDB_SCOPE_SUBTREE, attrs, SYSDB_NETGR_TRIPLES_FILTER, lc_sanitized_netgroup, sanitized_netgroup, sanitized_netgroup, netgroup_dn); if (ret == EOK || ret == ENOENT) { *res = talloc_steal(mem_ctx, result); } done: talloc_zfree(tmp_ctx); return ret; } int sysdb_get_netgroup_attr(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *netgrname, const char **attributes, struct ldb_result **res) { TALLOC_CTX *tmp_ctx; struct ldb_dn *base_dn; struct ldb_result *result; char *sanitized_netgroup; char *lc_sanitized_netgroup; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_NETGROUP_BASE, domain->name); if (!base_dn) { ret = ENOMEM; goto done; } ret = sss_filter_sanitize_for_dom(tmp_ctx, netgrname, domain, &sanitized_netgroup, &lc_sanitized_netgroup); if (ret != EOK) { goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &result, base_dn, LDB_SCOPE_SUBTREE, attributes, SYSDB_NETGR_FILTER, lc_sanitized_netgroup, sanitized_netgroup, sanitized_netgroup); if (ret) { ret = sysdb_error_to_errno(ret); goto done; } *res = talloc_steal(mem_ctx, result); done: talloc_zfree(tmp_ctx); return ret; } errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, enum sysdb_member_type mtype, const char *name, char ***_direct_parents) { errno_t ret; const char *dn; char *sanitized_dn; struct ldb_dn *basedn; static const char *group_attrs[] = { SYSDB_NAME, NULL }; const char *member_filter; size_t direct_sysdb_count = 0; struct ldb_message **direct_sysdb_groups = NULL; char **direct_parents = NULL; TALLOC_CTX *tmp_ctx = NULL; int i, pi; const char *tmp_str; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; if (mtype == SYSDB_MEMBER_USER) { dn = sysdb_user_strdn(tmp_ctx, dom->name, name); } else if (mtype == SYSDB_MEMBER_GROUP) { dn = sysdb_group_strdn(tmp_ctx, dom->name, name); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown member type\n"); ret = EINVAL; goto done; } if (!dn) { ret = ENOMEM; goto done; } ret = sss_filter_sanitize(tmp_ctx, dn, &sanitized_dn); if (ret != EOK) { goto done; } member_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(%s=%s))", SYSDB_OBJECTCLASS, SYSDB_GROUP_CLASS, SYSDB_MEMBER, sanitized_dn); if (!member_filter) { ret = ENOMEM; goto done; } basedn = sysdb_group_base_dn(tmp_ctx, dom); if (!basedn) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "searching sysdb with filter [%s]\n", member_filter); ret = sysdb_search_entry(tmp_ctx, dom->sysdb, basedn, LDB_SCOPE_SUBTREE, member_filter, group_attrs, &direct_sysdb_count, &direct_sysdb_groups); if (ret == ENOENT) { direct_sysdb_count = 0; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed: [%d]: %s\n", ret, strerror(ret)); goto done; } /* EOK */ /* Get the list of sysdb groups by name */ direct_parents = talloc_array(tmp_ctx, char *, direct_sysdb_count+1); if (!direct_parents) { ret = ENOMEM; goto done; } pi = 0; for(i = 0; i < direct_sysdb_count; i++) { tmp_str = ldb_msg_find_attr_as_string(direct_sysdb_groups[i], SYSDB_NAME, NULL); if (!tmp_str) { /* This should never happen, but if it does, just continue */ continue; } direct_parents[pi] = talloc_strdup(direct_parents, tmp_str); if (!direct_parents[pi]) { DEBUG(SSSDBG_CRIT_FAILURE, "A group with no name?\n"); ret = EIO; goto done; } pi++; } direct_parents[pi] = NULL; DEBUG(SSSDBG_TRACE_LIBS, "%s is a member of %zu sysdb groups\n", name, direct_sysdb_count); *_direct_parents = talloc_steal(mem_ctx, direct_parents); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_get_real_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_or_upn_or_sid, const char **_cname) { errno_t ret; TALLOC_CTX *tmp_ctx; struct ldb_result *res; const char *cname; struct ldb_message *msg; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_getpwnam(tmp_ctx, domain, name_or_upn_or_sid, &res); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot canonicalize username\n"); goto done; } if (res->count == 0) { ret = sysdb_search_user_by_upn(tmp_ctx, domain, name_or_upn_or_sid, NULL, &msg); if (ret == ENOENT) { ret = sysdb_search_user_by_sid_str(tmp_ctx, domain, name_or_upn_or_sid, NULL, &msg); if (ret == ENOENT) { ret = sysdb_search_object_by_uuid(tmp_ctx, domain, name_or_upn_or_sid, NULL, &res); if (ret == EOK && res->count == 1) { msg = res->msgs[0]; } else if (ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_object_by_uuid failed or returned " "more than one result [%d][%s].\n", ret, sss_strerror(ret)); ret = ENOENT; goto done; } } } if (ret != EOK) { /* User cannot be found in cache */ DEBUG(SSSDBG_OP_FAILURE, "Cannot find user [%s] in cache\n", name_or_upn_or_sid); goto done; } } else if (res->count == 1) { msg = res->msgs[0]; } else { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_getpwnam returned count: [%d]\n", res->count); ret = EIO; goto done; } cname = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); if (!cname) { DEBUG(SSSDBG_CRIT_FAILURE, "A user with no name?\n"); ret = ENOENT; goto done; } ret = EOK; *_cname = talloc_steal(mem_ctx, cname); done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_subdomains.c0000644000000000000000000000007312703456111017214 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.836794246 sssd-1.13.4/src/db/sysdb_subdomains.c0000644002412700241270000011613612703456111020674 0ustar00jhrozekjhrozek00000000000000/* SSSD System Database - Sub-domain related calls Copyright (C) 2012 Jan Zeleny Copyright (C) 2012 Sumit Bose This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb_private.h" struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx, struct sss_domain_info *parent, const char *name, const char *realm, const char *flat_name, const char *id, bool mpg, bool enumerate, const char *forest, uint32_t trust_direction) { struct sss_domain_info *dom; bool inherit_option; DEBUG(SSSDBG_TRACE_FUNC, "Creating [%s] as subdomain of [%s]!\n", name, parent->name); dom = talloc_zero(mem_ctx, struct sss_domain_info); if (dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); return NULL; } dom->parent = parent; /* Sub-domains always have the same view as the parent */ dom->has_views = parent->has_views; if (parent->view_name != NULL) { dom->view_name = talloc_strdup(dom, parent->view_name); if (dom->view_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to copy parent's view name.\n"); goto fail; } } dom->name = talloc_strdup(dom, name); if (dom->name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to copy domain name.\n"); goto fail; } dom->provider = talloc_strdup(dom, parent->provider); if (dom->provider == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to copy provider name.\n"); goto fail; } dom->conn_name = talloc_strdup(dom, parent->conn_name); if (dom->conn_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to copy connection name.\n"); goto fail; } if (realm != NULL) { dom->realm = talloc_strdup(dom, realm); if (dom->realm == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to copy realm name.\n"); goto fail; } } if (flat_name != NULL) { dom->flat_name = talloc_strdup(dom, flat_name); if (dom->flat_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to copy flat name.\n"); goto fail; } } if (id != NULL) { dom->domain_id = talloc_strdup(dom, id); if (dom->domain_id == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to copy id.\n"); goto fail; } } if (forest != NULL) { dom->forest = talloc_strdup(dom, forest); if (dom->forest == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to copy forest.\n"); goto fail; } } dom->enumerate = enumerate; dom->fqnames = true; dom->mpg = mpg; dom->state = DOM_ACTIVE; /* If the parent domain filters out group members, the subdomain should * as well if configured */ inherit_option = string_in_list(CONFDB_DOMAIN_IGNORE_GROUP_MEMBERS, parent->sd_inherit, false); if (inherit_option) { dom->ignore_group_members = parent->ignore_group_members; } dom->trust_direction = trust_direction; /* If the parent domain explicitly limits ID ranges, the subdomain * should honour the limits as well. */ dom->id_min = parent->id_min ? parent->id_min : 0; dom->id_max = parent->id_max ? parent->id_max : 0xffffffff; dom->pwd_expiration_warning = parent->pwd_expiration_warning; dom->cache_credentials = parent->cache_credentials; dom->cache_credentials_min_ff_length = parent->cache_credentials_min_ff_length; dom->case_sensitive = false; dom->user_timeout = parent->user_timeout; dom->group_timeout = parent->group_timeout; dom->netgroup_timeout = parent->netgroup_timeout; dom->service_timeout = parent->service_timeout; dom->names = parent->names; dom->override_homedir = parent->override_homedir; dom->fallback_homedir = parent->fallback_homedir; dom->subdomain_homedir = parent->subdomain_homedir; dom->override_shell = parent->override_shell; dom->default_shell = parent->default_shell; dom->homedir_substr = parent->homedir_substr; if (parent->sysdb == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing sysdb context in parent domain.\n"); goto fail; } dom->sysdb = parent->sysdb; return dom; fail: talloc_free(dom); return NULL; } static bool is_forest_root(struct sss_domain_info *d) { if (d->forest == NULL) { /* IPA subdomain provider saves/saved trusted forest root domains * without the forest attribute. Those are automatically forest * roots */ return true; } if (d->realm && (strcasecmp(d->forest, d->realm) == 0)) { return true; } return false; } static bool is_same_forest(struct sss_domain_info *root, struct sss_domain_info *member) { if (member->forest != NULL && root->realm != NULL && strcasecmp(member->forest, root->realm) == 0) { return true; } return false; } static void link_forest_roots(struct sss_domain_info *domain) { struct sss_domain_info *d; struct sss_domain_info *dd; uint32_t gnd_flags = SSS_GND_ALL_DOMAINS; for (d = domain; d; d = get_next_domain(d, gnd_flags)) { d->forest_root = NULL; } for (d = domain; d; d = get_next_domain(d, gnd_flags)) { if (d->forest_root != NULL) { continue; } if (is_forest_root(d) == true) { d->forest_root = d; DEBUG(SSSDBG_TRACE_INTERNAL, "[%s] is a forest root\n", d->name); for (dd = domain; dd; dd = get_next_domain(dd, gnd_flags)) { if (dd->forest_root != NULL) { continue; } if (is_same_forest(d, dd) == true) { dd->forest_root = d; DEBUG(SSSDBG_TRACE_INTERNAL, "[%s] is a forest root of [%s]\n", d->forest_root->name, dd->name); } } } } } errno_t sysdb_update_subdomains(struct sss_domain_info *domain) { int i; errno_t ret; TALLOC_CTX *tmp_ctx; struct ldb_result *res; const char *attrs[] = {"cn", SYSDB_SUBDOMAIN_REALM, SYSDB_SUBDOMAIN_FLAT, SYSDB_SUBDOMAIN_ID, SYSDB_SUBDOMAIN_MPG, SYSDB_SUBDOMAIN_ENUM, SYSDB_SUBDOMAIN_FOREST, SYSDB_SUBDOMAIN_TRUST_DIRECTION, NULL}; struct sss_domain_info *dom; struct ldb_dn *basedn; const char *name; const char *realm; const char *flat; const char *id; const char *forest; bool mpg; bool enumerate; uint32_t trust_direction; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } basedn = ldb_dn_new(tmp_ctx, domain->sysdb->ldb, SYSDB_BASE); if (basedn == NULL) { ret = EIO; goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_ONELEVEL, attrs, "objectclass=%s", SYSDB_SUBDOMAIN_CLASS); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } /* disable all domains, * let the search result refresh any that are still valid */ for (dom = domain->subdomains; dom; dom = get_next_domain(dom, false)) { sss_domain_set_state(dom, DOM_DISABLED); } if (res->count == 0) { ret = EOK; goto done; } for (i = 0; i < res->count; i++) { name = ldb_msg_find_attr_as_string(res->msgs[i], "cn", NULL); if (name == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "The object [%s] doesn't have a name\n", ldb_dn_get_linearized(res->msgs[i]->dn)); ret = EINVAL; goto done; } realm = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_SUBDOMAIN_REALM, NULL); flat = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_SUBDOMAIN_FLAT, NULL); id = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_SUBDOMAIN_ID, NULL); mpg = ldb_msg_find_attr_as_bool(res->msgs[i], SYSDB_SUBDOMAIN_MPG, false); enumerate = ldb_msg_find_attr_as_bool(res->msgs[i], SYSDB_SUBDOMAIN_ENUM, false); forest = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_SUBDOMAIN_FOREST, NULL); trust_direction = ldb_msg_find_attr_as_int(res->msgs[i], SYSDB_SUBDOMAIN_TRUST_DIRECTION, 0); for (dom = domain->subdomains; dom; dom = get_next_domain(dom, SSS_GND_INCLUDE_DISABLED)) { if (strcasecmp(dom->name, name) == 0) { sss_domain_set_state(dom, DOM_ACTIVE); /* in theory these may change, but it should never happen */ if (strcasecmp(dom->realm, realm) != 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "Realm name changed from [%s] to [%s]!\n", dom->realm, realm); talloc_zfree(dom->realm); dom->realm = talloc_strdup(dom, realm); if (dom->realm == NULL) { ret = ENOMEM; goto done; } } if (strcasecmp(dom->flat_name, flat) != 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "Flat name changed from [%s] to [%s]!\n", dom->flat_name, flat); talloc_zfree(dom->flat_name); dom->flat_name = talloc_strdup(dom, flat); if (dom->flat_name == NULL) { ret = ENOMEM; goto done; } } if (strcasecmp(dom->domain_id, id) != 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "Domain changed from [%s] to [%s]!\n", dom->domain_id, id); talloc_zfree(dom->domain_id); dom->domain_id = talloc_strdup(dom, id); if (dom->domain_id == NULL) { ret = ENOMEM; goto done; } } if (dom->mpg != mpg) { DEBUG(SSSDBG_TRACE_INTERNAL, "MPG state change from [%s] to [%s]!\n", dom->mpg ? "true" : "false", mpg ? "true" : "false"); dom->mpg = mpg; } if (dom->enumerate != enumerate) { DEBUG(SSSDBG_TRACE_INTERNAL, "enumerate state change from [%s] to [%s]!\n", dom->enumerate ? "true" : "false", enumerate ? "true" : "false"); dom->enumerate = enumerate; } if ((dom->forest == NULL && forest != NULL) || (dom->forest != NULL && forest != NULL && strcasecmp(dom->forest, forest) != 0)) { DEBUG(SSSDBG_TRACE_INTERNAL, "Forest changed from [%s] to [%s]!\n", dom->forest, forest); talloc_zfree(dom->forest); dom->forest = talloc_strdup(dom, forest); if (dom->forest == NULL) { ret = ENOMEM; goto done; } } if (!dom->has_views && dom->view_name == NULL) { /* maybe views are not initialized, copy from parent */ dom->has_views = dom->parent->has_views; if (dom->parent->view_name != NULL) { dom->view_name = talloc_strdup(dom, dom->parent->view_name); if (dom->view_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to copy parent's view name.\n"); ret = ENOMEM; goto done; } } } else { if (dom->has_views != dom->parent->has_views || strcmp(dom->view_name, dom->parent->view_name) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Sub-domain [%s][%s] and parent [%s][%s] " \ "views are different.\n", dom->has_views ? "has view" : "has no view", dom->view_name, dom->parent->has_views ? "has view" : "has no view", dom->parent->view_name); ret = EINVAL; goto done; } } if (dom->trust_direction != trust_direction) { DEBUG(SSSDBG_TRACE_INTERNAL, "Trust direction change from [%d] to [%d]!\n", dom->trust_direction, trust_direction); dom->trust_direction = trust_direction; } break; } } /* If not found in loop it is a new subdomain */ if (dom == NULL) { dom = new_subdomain(domain, domain, name, realm, flat, id, mpg, enumerate, forest, trust_direction); if (dom == NULL) { ret = ENOMEM; goto done; } DLIST_ADD_END(domain->subdomains, dom, struct sss_domain_info *); } } link_forest_roots(domain); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_master_domain_update(struct sss_domain_info *domain) { errno_t ret; TALLOC_CTX *tmp_ctx; const char *tmp_str; struct ldb_dn *basedn; struct ldb_result *res; const char *attrs[] = {"cn", SYSDB_SUBDOMAIN_REALM, SYSDB_SUBDOMAIN_FLAT, SYSDB_SUBDOMAIN_ID, SYSDB_SUBDOMAIN_FOREST, NULL}; char *view_name = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } basedn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_DOM_BASE, domain->name); if (basedn == NULL) { ret = EIO; goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } if (res->count == 0) { ret = ENOENT; goto done; } if (res->count > 1) { DEBUG(SSSDBG_OP_FAILURE, "Base search returned [%d] results, " "expected 1.\n", res->count); ret = EINVAL; goto done; } tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_REALM, NULL); if (tmp_str != NULL && (domain->realm == NULL || strcasecmp(tmp_str, domain->realm) != 0)) { talloc_free(domain->realm); domain->realm = talloc_strdup(domain, tmp_str); if (domain->realm == NULL) { ret = ENOMEM; goto done; } } tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_FLAT, NULL); if (tmp_str != NULL && (domain->flat_name == NULL || strcasecmp(tmp_str, domain->flat_name) != 0)) { talloc_free(domain->flat_name); domain->flat_name = talloc_strdup(domain, tmp_str); if (domain->flat_name == NULL) { ret = ENOMEM; goto done; } } tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_ID, NULL); if (tmp_str != NULL && (domain->domain_id == NULL || strcasecmp(tmp_str, domain->domain_id) != 0)) { talloc_free(domain->domain_id); domain->domain_id = talloc_strdup(domain, tmp_str); if (domain->domain_id == NULL) { ret = ENOMEM; goto done; } } tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_FOREST, NULL); if (tmp_str != NULL && (domain->forest == NULL || strcasecmp(tmp_str, domain->forest) != 0)) { talloc_free(domain->forest); domain->forest = talloc_strdup(domain, tmp_str); if (domain->forest == NULL) { ret = ENOMEM; goto done; } } ret = sysdb_get_view_name(tmp_ctx, domain->sysdb, &view_name); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_view_name failed.\n"); goto done; } /* If no view is defined the default view will be used. In this case * domain->has_views is FALSE and * domain->view_name is set to SYSDB_DEFAULT_VIEW_NAME * * If there is a view defined * domain->has_views is TRUE and * domain->view_name is set to the given view name * * Currently changing the view is not supported hence we have to check for * changes and error out accordingly. */ if (ret == ENOENT || is_default_view(view_name)) { /* handle default view */ if (domain->has_views) { DEBUG(SSSDBG_CRIT_FAILURE, "View name change is currently not supported. " \ "New view is the default view while current view is [%s]. " \ "View name is not changed!\n", domain->view_name); } else { if (domain->view_name == NULL) { domain->view_name = talloc_strdup(domain, SYSDB_DEFAULT_VIEW_NAME); if (domain->view_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } else { if (strcmp(domain->view_name, SYSDB_DEFAULT_VIEW_NAME) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Domain [%s] has no view but view name [%s] " \ "is not the default view name [%s].\n", domain->name, domain->view_name, SYSDB_DEFAULT_VIEW_NAME); ret = EINVAL; goto done; } } } } else { /* handle view other than default */ if (domain->has_views) { if (strcmp(domain->view_name, view_name) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "View name change is currently not supported. " \ "New view is [%s] while current view is [%s]. " \ "View name is not changed!\n", view_name, domain->view_name); } } else { if (domain->view_name == NULL) { domain->has_views = true; domain->view_name = talloc_steal(domain, view_name); if (domain->view_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_steal failed.\n"); ret = ENOMEM; goto done; } } else { if (strcmp(domain->view_name, SYSDB_DEFAULT_VIEW_NAME) == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "View name change is currently not supported. " \ "New view is [%s] while current is the default view. " \ "View name is not changed!\n", view_name); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Domain currently has no views, " \ "but current view name is set to [%s] " \ "and new view name is [%s].\n", domain->view_name, view_name); ret = EINVAL; goto done; } } } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_master_domain_add_info(struct sss_domain_info *domain, const char *realm, const char *flat, const char *id, const char* forest) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; int ret; bool do_update = false; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_DOM_BASE, domain->name); if (msg->dn == NULL) { ret = EIO; goto done; } if (flat != NULL && (domain->flat_name == NULL || strcmp(domain->flat_name, flat) != 0)) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_FLAT, LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_FLAT, flat); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } do_update = true; } if (id != NULL && (domain->domain_id == NULL || strcmp(domain->domain_id, id) != 0)) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_ID, LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_ID, id); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } do_update = true; } if (forest != NULL && (domain->forest == NULL || strcmp(domain->forest, forest) != 0)) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_FOREST, LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_FOREST, forest); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } do_update = true; } if (realm != NULL && (domain->realm == NULL || strcmp(domain->realm, realm) != 0)) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_REALM, LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_REALM, realm); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } do_update = true; } if (do_update == false) { ret = EOK; goto done; } ret = ldb_modify(domain->sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add subdomain attributes to " "[%s]: [%d][%s]!\n", domain->name, ret, ldb_errstring(domain->sysdb->ldb)); ret = sysdb_error_to_errno(ret); goto done; } ret = sysdb_master_domain_update(domain); if (ret != EOK) { goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, const char *name, const char *realm, const char *flat_name, const char *domain_id, bool mpg, bool enumerate, const char *forest, uint32_t trust_direction) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; struct ldb_dn *dn; struct ldb_result *res; const char *attrs[] = {"cn", SYSDB_SUBDOMAIN_REALM, SYSDB_SUBDOMAIN_FLAT, SYSDB_SUBDOMAIN_ID, SYSDB_SUBDOMAIN_MPG, SYSDB_SUBDOMAIN_ENUM, SYSDB_SUBDOMAIN_FOREST, SYSDB_SUBDOMAIN_TRUST_DIRECTION, NULL}; const char *tmp_str; bool tmp_bool; bool store = false; int realm_flags = 0; int flat_flags = 0; int id_flags = 0; int mpg_flags = 0; int enum_flags = 0; int forest_flags = 0; int td_flags = 0; uint32_t tmp_td; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, name); if (dn == NULL) { ret = EIO; goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } if (res->count == 0) { ret = sysdb_domain_create(sysdb, name); if (ret) { goto done; } store = true; if (realm) realm_flags = LDB_FLAG_MOD_ADD; if (flat_name) flat_flags = LDB_FLAG_MOD_ADD; if (domain_id) id_flags = LDB_FLAG_MOD_ADD; mpg_flags = LDB_FLAG_MOD_ADD; enum_flags = LDB_FLAG_MOD_ADD; if (forest) forest_flags = LDB_FLAG_MOD_ADD; if (trust_direction) td_flags = LDB_FLAG_MOD_ADD; } else if (res->count != 1) { ret = EINVAL; goto done; } else { /* 1 found */ if (realm) { tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_REALM, NULL); if (!tmp_str || strcasecmp(tmp_str, realm) != 0) { realm_flags = LDB_FLAG_MOD_REPLACE; } } if (flat_name) { tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_FLAT, NULL); if (!tmp_str || strcasecmp(tmp_str, flat_name) != 0) { flat_flags = LDB_FLAG_MOD_REPLACE; } } if (domain_id) { tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_ID, NULL); if (!tmp_str || strcasecmp(tmp_str, domain_id) != 0) { id_flags = LDB_FLAG_MOD_REPLACE; } } tmp_bool = ldb_msg_find_attr_as_bool(res->msgs[0], SYSDB_SUBDOMAIN_MPG, !mpg); if (tmp_bool != mpg) { mpg_flags = LDB_FLAG_MOD_REPLACE; } tmp_bool = ldb_msg_find_attr_as_bool(res->msgs[0], SYSDB_SUBDOMAIN_ENUM, !enumerate); if (tmp_bool != enumerate) { enum_flags = LDB_FLAG_MOD_REPLACE; } if (forest) { tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SUBDOMAIN_FOREST, NULL); if (!tmp_str || strcasecmp(tmp_str, forest) != 0) { forest_flags = LDB_FLAG_MOD_REPLACE; } } tmp_td = ldb_msg_find_attr_as_uint(res->msgs[0], SYSDB_SUBDOMAIN_TRUST_DIRECTION, 0); if (tmp_td != trust_direction) { td_flags = LDB_FLAG_MOD_REPLACE; } } if (!store && realm_flags == 0 && flat_flags == 0 && id_flags == 0 && mpg_flags == 0 && enum_flags == 0 && forest_flags == 0 && td_flags == 0) { ret = EOK; goto done; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = dn; if (store) { ret = ldb_msg_add_empty(msg, SYSDB_OBJECTCLASS, LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_OBJECTCLASS, SYSDB_SUBDOMAIN_CLASS); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (realm_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_REALM, realm_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_REALM, realm); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (flat_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_FLAT, flat_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_FLAT, flat_name); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (id_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_ID, id_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_ID, domain_id); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (mpg_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_MPG, mpg_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_MPG, mpg ? "TRUE" : "FALSE"); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (enum_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_ENUM, enum_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_ENUM, enumerate ? "TRUE" : "FALSE"); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (forest_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_FOREST, forest_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_SUBDOMAIN_FOREST, forest); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } if (td_flags) { ret = ldb_msg_add_empty(msg, SYSDB_SUBDOMAIN_TRUST_DIRECTION, td_flags, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_fmt(msg, SYSDB_SUBDOMAIN_TRUST_DIRECTION, "%u", trust_direction); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } } ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to add subdomain attributes to " "[%s]: [%d][%s]!\n", name, ret, ldb_errstring(sysdb->ldb)); ret = sysdb_error_to_errno(ret); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_dn *dn; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Removing sub-domain [%s] from db.\n", name); dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_DOM_BASE, name); if (dn == NULL) { ret = ENOMEM; goto done; } ret = sysdb_delete_recursive(sysdb, dn, true); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_delete_recursive failed.\n"); goto done; } done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, const char *domain_component_name, struct sysdb_attrs **usr_attrs, size_t count, struct sysdb_attrs **exp_usr) { char *dom_basedn; size_t dom_basedn_len; char *expected_basedn; size_t expected_basedn_len; size_t dn_len; const char *orig_dn; size_t c = 0; int ret; TALLOC_CTX *tmp_ctx; struct ldb_context *ldb_ctx; struct ldb_dn *ldb_dom_basedn; int dom_basedn_comp_num; struct ldb_dn *ldb_dn; int dn_comp_num; const char *component_name; struct sysdb_attrs *result = NULL; const char *result_dn_str = NULL; if (dom == NULL || domain_component_name == NULL || usr_attrs == NULL || count == 0) { return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n"); goto done; } expected_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn); if (expected_basedn == NULL) { ret = ENOMEM; goto done; } ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb); if (ldb_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n"); ret = EINVAL; goto done; } ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn); if (ldb_dom_basedn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); ret = ENOMEM; goto done; } dom_basedn_comp_num = ldb_dn_get_comp_num(ldb_dom_basedn); dom_basedn_comp_num++; DEBUG(SSSDBG_TRACE_ALL, "Expected BaseDN is [%s].\n", expected_basedn); expected_basedn_len = strlen(expected_basedn); dom_basedn_len = strlen(dom_basedn); for (c = 0; c < count; c++) { ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } dn_len = strlen(orig_dn); if (dn_len > expected_basedn_len && strcasecmp(orig_dn + (dn_len - expected_basedn_len), expected_basedn) == 0) { DEBUG(SSSDBG_TRACE_ALL, "Found matching dn [%s].\n", orig_dn); if (result != NULL) { DEBUG(SSSDBG_OP_FAILURE, "Found 2 matching DN [%s] and [%s], expecting only 1.\n", result_dn_str, orig_dn); ret = EINVAL; goto done; } result = usr_attrs[c]; result_dn_str = orig_dn; } } if (result == NULL) { for (c = 0; c < count; c++) { ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } dn_len = strlen(orig_dn); if (dn_len > dom_basedn_len && strcasecmp(orig_dn + (dn_len - dom_basedn_len), dom_basedn) == 0) { ldb_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn); if (ldb_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed"); ret = ENOMEM; goto done; } dn_comp_num = ldb_dn_get_comp_num(ldb_dn); if (dn_comp_num > dom_basedn_comp_num) { component_name = ldb_dn_get_component_name(ldb_dn, (dn_comp_num - dom_basedn_comp_num)); DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n", component_name, domain_component_name); if (component_name != NULL && strcasecmp(component_name, domain_component_name) != 0) { DEBUG(SSSDBG_TRACE_ALL, "Found matching dn [%s].\n", orig_dn); if (result != NULL) { DEBUG(SSSDBG_OP_FAILURE, "Found 2 matching DN [%s] and [%s], " "expecting only 1.\n", result_dn_str, orig_dn); ret = EINVAL; goto done; } result = usr_attrs[c]; result_dn_str = orig_dn; } } } } } if (result == NULL) { DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n"); ret = ENOENT; goto done; } *exp_usr = result; ret = EOK; done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_views.c0000644000000000000000000000007312703456111016205 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.837794249 sssd-1.13.4/src/db/sysdb_views.c0000644002412700241270000014736512703456111017675 0ustar00jhrozekjhrozek00000000000000/* SSSD System Database - View and Override related calls Copyright (C) 2014 Sumit Bose This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb_private.h" /* In general is should not be possible that there is a view container without * a view name set. But to be on the safe side we return both information * separately. */ static errno_t sysdb_get_view_name_ex(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, char **_view_name, bool *view_container_exists) { errno_t ret; TALLOC_CTX *tmp_ctx; const char *tmp_str; struct ldb_dn *view_base_dn; struct ldb_result *res; const char *attrs[] = {SYSDB_VIEW_NAME, NULL}; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } view_base_dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_TMPL_VIEW_BASE); if (view_base_dn == NULL) { ret = EIO; goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, view_base_dn, LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) { ret = EIO; goto done; } if (res->count > 1) { DEBUG(SSSDBG_OP_FAILURE, "Base search returned [%d] results, " "expected 1.\n", res->count); ret = EINVAL; goto done; } if (res->count == 0) { *view_container_exists = false; ret = ENOENT; goto done; } else { *view_container_exists = true; tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_VIEW_NAME, NULL); if (tmp_str == NULL) { ret = ENOENT; goto done; } } *_view_name = talloc_steal(mem_ctx, discard_const(tmp_str)); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_get_view_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, char **view_name) { bool view_container_exists; return sysdb_get_view_name_ex(mem_ctx, sysdb, view_name, &view_container_exists); } errno_t sysdb_update_view_name(struct sysdb_ctx *sysdb, const char *view_name) { errno_t ret; TALLOC_CTX *tmp_ctx; char *tmp_str; bool view_container_exists = false; bool add_view_name = false; struct ldb_message *msg; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = sysdb_get_view_name_ex(tmp_ctx, sysdb, &tmp_str, &view_container_exists); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_view_name_ex failed.\n"); goto done; } if (ret == EOK) { if (strcmp(tmp_str, view_name) == 0) { /* view name already known, nothing to do */ DEBUG(SSSDBG_TRACE_ALL, "View name already in place.\n"); ret = EOK; goto done; } else { /* view name changed */ DEBUG(SSSDBG_CONF_SETTINGS, "View name changed from [%s] to [%s].\n", tmp_str, view_name); } } else { add_view_name = true; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n"); ret = ENOMEM; goto done; } msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_TMPL_VIEW_BASE); if (msg->dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); ret = EIO; goto done; } ret = ldb_msg_add_empty(msg, SYSDB_VIEW_NAME, add_view_name ? LDB_FLAG_MOD_ADD : LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_VIEW_NAME, view_name); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } if (view_container_exists) { ret = ldb_modify(sysdb->ldb, msg); } else { ret = ldb_add(sysdb->ldb, msg); } if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to %s view container [%s](%d)[%s]\n", view_container_exists ? "modify" : "add", ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); ret = sysdb_error_to_errno(ret); goto done; } done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_delete_view_tree(struct sysdb_ctx *sysdb, const char *view_name) { struct ldb_dn *dn; TALLOC_CTX *tmp_ctx; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_VIEW_SEARCH_BASE, view_name); if (dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n"); ret = EIO; goto done; } ret = sysdb_delete_recursive(sysdb, dn, true); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_delete_recursive failed.\n"); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) { int ret; int sret; TALLOC_CTX *tmp_ctx; bool in_transaction = false; struct ldb_result *res; size_t c; struct ldb_message *msg; struct ldb_dn *base_dn; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n"); ret = ENOMEM; goto done; } base_dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE); if (base_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed\n"); ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, SYSDB_CACHE_EXPIRE, LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_CACHE_EXPIRE, "1"); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_empty(msg, SYSDB_OVERRIDE_DN, LDB_FLAG_MOD_DELETE, NULL); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_start failed.\n"); goto done; } in_transaction = true; ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, NULL, "%s", SYSDB_UC); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } for (c = 0; c < res->count; c++) { msg->dn = res->msgs[c]->dn; ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { DEBUG(SSSDBG_OP_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); ret = sysdb_error_to_errno(ret); goto done; } } talloc_free(res); ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, NULL, "%s", SYSDB_GC); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } for (c = 0; c < res->count; c++) { msg->dn = res->msgs[c]->dn; ret = ldb_modify(sysdb->ldb, msg); if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { DEBUG(SSSDBG_OP_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); ret = sysdb_error_to_errno(ret); goto done; } } ret = EOK; done: if (in_transaction) { if (ret == EOK) { sret = sysdb_transaction_commit(sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_commit failed, " \ "nothing we can do about.\n"); ret = sret; } } else { sret = sysdb_transaction_cancel(sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_cancel failed, " \ "nothing we can do about.\n"); } } } talloc_free(tmp_ctx); return ret; } static errno_t add_name_and_aliases_for_name_override(struct sss_domain_info *domain, struct sysdb_attrs *attrs, bool add_name, const char *name_override) { char *fq_name = NULL; int ret; if (strchr(name_override, '@') == NULL) { fq_name = sss_tc_fqname(attrs, domain->names, domain, name_override); if (fq_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_tc_fqname failed.\n"); return ENOMEM; } if (!domain->case_sensitive) { ret = sysdb_attrs_add_lc_name_alias(attrs, fq_name); } else { ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, fq_name); } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_lc_name_alias failed.\n"); goto done; } } if (add_name) { ret = sysdb_attrs_add_string(attrs, SYSDB_DEFAULT_OVERRIDE_NAME, fq_name == NULL ? name_override : fq_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_lc_name_alias failed.\n"); goto done; } } if (!domain->case_sensitive) { ret = sysdb_attrs_add_lc_name_alias(attrs, name_override); } else { ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, name_override); } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_lc_name_alias failed.\n"); goto done; } ret = EOK; done: talloc_free(fq_name); return ret; } errno_t sysdb_store_override(struct sss_domain_info *domain, const char *view_name, enum sysdb_member_type type, struct sysdb_attrs *attrs, struct ldb_dn *obj_dn) { TALLOC_CTX *tmp_ctx; const char *anchor; int ret; struct ldb_dn *override_dn; const char *override_dn_str; const char *obj_dn_str; const char *obj_attrs[] = { SYSDB_OBJECTCLASS, SYSDB_OVERRIDE_DN, NULL}; size_t count = 0; struct ldb_message **msgs; struct ldb_message *msg = NULL; const char *obj_override_dn; bool add_ref = true; size_t c; bool in_transaction = false; bool has_override = true; const char *name_override; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } if (attrs != NULL) { has_override = true; ret = sysdb_attrs_get_string(attrs, SYSDB_OVERRIDE_ANCHOR_UUID, &anchor); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing anchor in override attributes.\n"); ret = EINVAL; goto done; } override_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_OVERRIDE, anchor, view_name); if (override_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n"); ret = ENOMEM; goto done; } } else { /* if there is no override for the given object, just store the DN of * the object iself in the SYSDB_OVERRIDE_DN attribute to indicate * that it was checked if an override exists and none was found. */ has_override = false; override_dn = obj_dn; } override_dn_str = ldb_dn_get_linearized(override_dn); obj_dn_str = ldb_dn_get_linearized(obj_dn); if (override_dn_str == NULL || obj_dn_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_get_linearized failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, obj_dn, LDB_SCOPE_BASE, NULL, obj_attrs, &count, &msgs); if (ret != EOK) { if (ret == ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Object to override does not exists.\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed.\n"); } goto done; } if (count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Base searched returned more than one object.\n"); ret = EINVAL; goto done; } obj_override_dn = ldb_msg_find_attr_as_string(msgs[0], SYSDB_OVERRIDE_DN, NULL); if (obj_override_dn != NULL) { if (strcmp(obj_override_dn, override_dn_str) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Existing [%s] and new [%s] override DN do not match.\n", obj_override_dn, override_dn_str); ret = EINVAL; goto done; } add_ref = false; } ret = ldb_transaction_start(domain->sysdb->ldb); if (ret != EOK) { return sysdb_error_to_errno(ret); } in_transaction = true; if (has_override) { ret = ldb_delete(domain->sysdb->ldb, override_dn); if (ret != EOK) { DEBUG(SSSDBG_TRACE_ALL, "ldb_delete failed, maybe object did not exist. Ignoring.\n"); } ret = sysdb_attrs_get_string(attrs, SYSDB_NAME, &name_override); if (ret == EOK) { ret = add_name_and_aliases_for_name_override(domain, attrs, false, name_override); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_name_and_aliases_for_name_override failed.\n"); goto done; } } else if (ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); goto done; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = override_dn; msg->elements = talloc_array(msg, struct ldb_message_element, attrs->num); if (msg->elements == NULL) { ret = ENOMEM; goto done; } for (c = 0; c < attrs->num; c++) { /* Set num_values to 1 because by default user and group overrides * use the same attribute name for the GID and this cause SSSD * machinery to add the same value twice */ if (attrs->a[c].num_values > 1 && strcmp(attrs->a[c].name, SYSDB_GIDNUM) == 0) { attrs->a[c].num_values = 1; } msg->elements[c] = attrs->a[c]; msg->elements[c].flags = LDB_FLAG_MOD_ADD; } msg->num_elements = attrs->num; ret = ldb_msg_add_empty(msg, SYSDB_OBJECTCLASS, LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } switch(type) { case SYSDB_MEMBER_USER: ret = ldb_msg_add_string(msg, SYSDB_OBJECTCLASS, SYSDB_OVERRIDE_USER_CLASS); break; case SYSDB_MEMBER_GROUP: ret = ldb_msg_add_string(msg, SYSDB_OBJECTCLASS, SYSDB_OVERRIDE_GROUP_CLASS); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected object type.\n"); ret = EINVAL; goto done; } if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_empty(msg, SYSDB_OVERRIDE_OBJECT_DN, LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_OVERRIDE_OBJECT_DN, obj_dn_str); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_add(domain->sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store override entry: %s(%d)[%s]\n", ldb_strerror(ret), ret, ldb_errstring(domain->sysdb->ldb)); ret = sysdb_error_to_errno(ret); goto done; } } if (add_ref) { talloc_free(msg); msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = obj_dn; ret = ldb_msg_add_empty(msg, SYSDB_OVERRIDE_DN, LDB_FLAG_MOD_ADD, NULL); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_OVERRIDE_DN, override_dn_str); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_modify(domain->sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store override DN: %s(%d)[%s]\n", ldb_strerror(ret), ret, ldb_errstring(domain->sysdb->ldb)); ret = sysdb_error_to_errno(ret); goto done; } } ret = EOK; done: if (in_transaction) { if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); ldb_transaction_cancel(domain->sysdb->ldb); } else { ret = ldb_transaction_commit(domain->sysdb->ldb); ret = sysdb_error_to_errno(ret); } } talloc_zfree(tmp_ctx); return ret; } static errno_t safe_original_attributes(struct sss_domain_info *domain, struct sysdb_attrs *attrs, struct ldb_dn *obj_dn, const char **allowed_attrs) { int ret; size_t c; TALLOC_CTX *tmp_ctx; struct ldb_result *orig_obj; char *orig_attr_name; struct ldb_message_element *el = NULL; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &orig_obj, obj_dn, LDB_SCOPE_BASE, NULL, NULL); if (ret != EOK || orig_obj->count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Original object not found.\n"); goto done; } /* Safe orginal values in attributes prefixed by OriginalAD. */ for (c = 0; allowed_attrs[c] != NULL; c++) { el = ldb_msg_find_element(orig_obj->msgs[0], allowed_attrs[c]); if (el != NULL) { orig_attr_name = talloc_asprintf(tmp_ctx, "%s%s", ORIGINALAD_PREFIX, allowed_attrs[c]); if (orig_attr_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_add_val(attrs, orig_attr_name, &el->values[0]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_val failed.\n"); goto done; } } else { DEBUG(SSSDBG_TRACE_ALL, "Original object does not have [%s] set.\n", allowed_attrs[c]); } } /* Add existing aliases to new ones */ el = ldb_msg_find_element(orig_obj->msgs[0], SYSDB_NAME_ALIAS); if (el != NULL) { for (c = 0; c < el->num_values; c++) { /* To avoid issue with ldb_modify if e.g. the orginal and the * override name are the same, we use the *_safe version here. */ ret = sysdb_attrs_add_val_safe(attrs, SYSDB_NAME_ALIAS, &el->values[c]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_val failed.\n"); goto done; } } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_apply_default_override(struct sss_domain_info *domain, struct sysdb_attrs *override_attrs, struct ldb_dn *obj_dn) { int ret; TALLOC_CTX *tmp_ctx; struct sysdb_attrs *attrs; size_t c; size_t d; size_t num_values; struct ldb_message_element *el = NULL; const char *allowed_attrs[] = { SYSDB_UIDNUM, SYSDB_GIDNUM, SYSDB_GECOS, SYSDB_HOMEDIR, SYSDB_SHELL, SYSDB_NAME, SYSDB_SSH_PUBKEY, NULL }; bool override_attrs_found = false; if (override_attrs == NULL) { /* nothing to do */ return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } attrs = sysdb_new_attrs(tmp_ctx); if (attrs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); ret = ENOMEM; goto done; } for (c = 0; allowed_attrs[c] != NULL; c++) { ret = sysdb_attrs_get_el_ext(override_attrs, allowed_attrs[c], false, &el); if (ret == EOK) { override_attrs_found = true; if (strcmp(allowed_attrs[c], SYSDB_NAME) == 0) { if (el->values[0].data[el->values[0].length] != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "String attribute does not end with \\0.\n"); ret = EINVAL; goto done; } ret = add_name_and_aliases_for_name_override(domain, attrs, true, (char *) el->values[0].data); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_name_and_aliases_for_name_override failed.\n"); goto done; } } else { num_values = el->num_values; /* Only SYSDB_SSH_PUBKEY is allowed to have multiple values. */ if (strcmp(allowed_attrs[c], SYSDB_SSH_PUBKEY) != 0 && num_values != 1) { DEBUG(SSSDBG_MINOR_FAILURE, "Override attribute for [%s] has more [%zd] " \ "than one value, using only the first.\n", allowed_attrs[c], num_values); num_values = 1; } for (d = 0; d < num_values; d++) { ret = sysdb_attrs_add_val(attrs, allowed_attrs[c], &el->values[d]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_val failed.\n"); goto done; } DEBUG(SSSDBG_TRACE_ALL, "Override [%s] with [%.*s] for [%s].\n", allowed_attrs[c], (int) el->values[d].length, el->values[d].data, ldb_dn_get_linearized(obj_dn)); } } } else if (ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el_ext failed.\n"); goto done; } } if (override_attrs_found) { ret = safe_original_attributes(domain, attrs, obj_dn, allowed_attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "safe_original_attributes failed.\n"); goto done; } ret = sysdb_set_entry_attr(domain->sysdb, obj_dn, attrs, SYSDB_MOD_REP); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_entry_attr failed.\n"); goto done; } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } #define SYSDB_USER_NAME_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_USER_CLASS")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_USER_UID_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_USER_CLASS")("SYSDB_UIDNUM"=%lu))" #define SYSDB_GROUP_NAME_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_GROUP_CLASS")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" #define SYSDB_GROUP_GID_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_GROUP_CLASS")("SYSDB_GIDNUM"=%lu))" enum override_object_type { OO_TYPE_UNDEF = 0, OO_TYPE_USER, OO_TYPE_GROUP }; static errno_t sysdb_search_override_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char *filter, const char **attrs, struct ldb_result **override_obj, struct ldb_result **orig_obj) { TALLOC_CTX *tmp_ctx; struct ldb_dn *base_dn; struct ldb_result *override_res; struct ldb_result *orig_res; char *sanitized_name; char *lc_sanitized_name; const char *src_name; int ret; const char *orig_obj_dn; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_VIEW_SEARCH_BASE, domain->view_name); if (base_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n"); ret = ENOMEM; goto done; } /* If this is a subdomain we need to use fully qualified names for the * search as well by default */ src_name = sss_get_domain_name(tmp_ctx, name, domain); if (src_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_get_domain_name failed.\n"); ret = ENOMEM; goto done; } ret = sss_filter_sanitize_for_dom(tmp_ctx, src_name, domain, &sanitized_name, &lc_sanitized_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize_for_dom failed.\n"); goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &override_res, base_dn, LDB_SCOPE_SUBTREE, attrs, filter, lc_sanitized_name, sanitized_name, sanitized_name); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } if (override_res->count == 0) { DEBUG(SSSDBG_TRACE_FUNC, "No user override found for name [%s].\n", name); ret = ENOENT; goto done; } else if (override_res->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Found more than one override for name [%s].\n", name); ret = EINVAL; goto done; } if (orig_obj != NULL) { orig_obj_dn = ldb_msg_find_attr_as_string(override_res->msgs[0], SYSDB_OVERRIDE_OBJECT_DN, NULL); if (orig_obj_dn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing link to original object in override [%s].\n", ldb_dn_get_linearized(override_res->msgs[0]->dn)); ret = EINVAL; goto done; } base_dn = ldb_dn_new(tmp_ctx, domain->sysdb->ldb, orig_obj_dn); if (base_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); ret = ENOMEM; goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &orig_res, base_dn, LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } *orig_obj = talloc_steal(mem_ctx, orig_res); } *override_obj = talloc_steal(mem_ctx, override_res); ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } errno_t sysdb_search_user_override_attrs_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_result **override_obj, struct ldb_result **orig_obj) { return sysdb_search_override_by_name(mem_ctx, domain, name, SYSDB_USER_NAME_OVERRIDE_FILTER, attrs, override_obj, orig_obj); } errno_t sysdb_search_group_override_attrs_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_result **override_obj, struct ldb_result **orig_obj) { return sysdb_search_override_by_name(mem_ctx, domain, name, SYSDB_GROUP_NAME_OVERRIDE_FILTER, attrs, override_obj, orig_obj); } errno_t sysdb_search_user_override_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **override_obj, struct ldb_result **orig_obj) { const char *attrs[] = SYSDB_PW_ATTRS; return sysdb_search_override_by_name(mem_ctx, domain, name, SYSDB_USER_NAME_OVERRIDE_FILTER, attrs, override_obj, orig_obj); } errno_t sysdb_search_group_override_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct ldb_result **override_obj, struct ldb_result **orig_obj) { const char *attrs[] = SYSDB_GRSRC_ATTRS; return sysdb_search_override_by_name(mem_ctx, domain, name, SYSDB_GROUP_NAME_OVERRIDE_FILTER, attrs, override_obj, orig_obj); } static errno_t sysdb_search_override_by_id(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, unsigned long int id, enum override_object_type type, struct ldb_result **override_obj, struct ldb_result **orig_obj) { TALLOC_CTX *tmp_ctx; static const char *user_attrs[] = SYSDB_PW_ATTRS; static const char *group_attrs[] = SYSDB_GRSRC_ATTRS; const char **attrs; struct ldb_dn *base_dn; struct ldb_result *override_res; struct ldb_result *orig_res; int ret; const char *orig_obj_dn; const char *filter; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_VIEW_SEARCH_BASE, domain->view_name); if (base_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n"); ret = ENOMEM; goto done; } switch(type) { case OO_TYPE_USER: filter = SYSDB_USER_UID_OVERRIDE_FILTER; attrs = user_attrs; break; case OO_TYPE_GROUP: filter = SYSDB_GROUP_GID_OVERRIDE_FILTER; attrs = group_attrs; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected override object type [%d].\n", type); ret = EINVAL; goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &override_res, base_dn, LDB_SCOPE_SUBTREE, attrs, filter, id); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } if (override_res->count == 0) { DEBUG(SSSDBG_TRACE_FUNC, "No user override found for %s with id [%lu].\n", (type == OO_TYPE_USER ? "user" : "group"), id); ret = ENOENT; goto done; } else if (override_res->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Found more than one override for id [%lu].\n", id); ret = EINVAL; goto done; } if (orig_obj != NULL) { orig_obj_dn = ldb_msg_find_attr_as_string(override_res->msgs[0], SYSDB_OVERRIDE_OBJECT_DN, NULL); if (orig_obj_dn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing link to original object in override [%s].\n", ldb_dn_get_linearized(override_res->msgs[0]->dn)); ret = EINVAL; goto done; } base_dn = ldb_dn_new(tmp_ctx, domain->sysdb->ldb, orig_obj_dn); if (base_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); ret = ENOMEM; goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &orig_res, base_dn, LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } *orig_obj = talloc_steal(mem_ctx, orig_res); } *override_obj = talloc_steal(mem_ctx, override_res); ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } errno_t sysdb_search_user_override_by_uid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, uid_t uid, struct ldb_result **override_obj, struct ldb_result **orig_obj) { return sysdb_search_override_by_id(mem_ctx, domain, uid, OO_TYPE_USER, override_obj, orig_obj); } errno_t sysdb_search_group_override_by_gid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, gid_t gid, struct ldb_result **override_obj, struct ldb_result **orig_obj) { return sysdb_search_override_by_id(mem_ctx, domain, gid, OO_TYPE_GROUP, override_obj, orig_obj); } /** * @brief Add override data to the original object * * @param[in] domain Domain struct, needed to access the cache * @oaram[in] obj The original object * @param[in] override_obj The object with the override data, may be NULL * @param[in] req_attrs List of attributes to be requested, if not set a * default list dependig on the object type will be used * * @return EOK - Override data was added successfully * @return ENOMEM - There was insufficient memory to complete the operation * @return ENOENT - The original object did not have the SYSDB_OVERRIDE_DN * attribute or the value of the attribute points an object * which does not exists. Both conditions indicate that the * cache must be refreshed. */ errno_t sysdb_add_overrides_to_object(struct sss_domain_info *domain, struct ldb_message *obj, struct ldb_message *override_obj, const char **req_attrs) { int ret; const char *override_dn_str; struct ldb_dn *override_dn; TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_message *override; uint64_t uid; static const char *user_attrs[] = SYSDB_PW_ATTRS; static const char *group_attrs[] = SYSDB_GRSRC_ATTRS; const char **attrs; struct attr_map { const char *attr; const char *new_attr; } attr_map[] = { {SYSDB_UIDNUM, OVERRIDE_PREFIX SYSDB_UIDNUM}, {SYSDB_GIDNUM, OVERRIDE_PREFIX SYSDB_GIDNUM}, {SYSDB_GECOS, OVERRIDE_PREFIX SYSDB_GECOS}, {SYSDB_HOMEDIR, OVERRIDE_PREFIX SYSDB_HOMEDIR}, {SYSDB_SHELL, OVERRIDE_PREFIX SYSDB_SHELL}, {SYSDB_NAME, OVERRIDE_PREFIX SYSDB_NAME}, {SYSDB_SSH_PUBKEY, OVERRIDE_PREFIX SYSDB_SSH_PUBKEY}, {NULL, NULL} }; size_t c; size_t d; struct ldb_message_element *tmp_el; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } if (override_obj == NULL) { override_dn_str = ldb_msg_find_attr_as_string(obj, SYSDB_OVERRIDE_DN, NULL); if (override_dn_str == NULL) { if (is_local_view(domain->view_name)) { /* LOCAL view doesn't have to have overrideDN specified. */ ret = EOK; goto done; } DEBUG(SSSDBG_CRIT_FAILURE, "Missing override DN for object [%s].\n", ldb_dn_get_linearized(obj->dn)); ret = ENOENT; goto done; } override_dn = ldb_dn_new(tmp_ctx, domain->sysdb->ldb, override_dn_str); if (override_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); ret = ENOMEM; goto done; } if (ldb_dn_compare(obj->dn, override_dn) == 0) { DEBUG(SSSDBG_TRACE_ALL, "Object [%s] has no overrides.\n", ldb_dn_get_linearized(obj->dn)); ret = EOK; goto done; } attrs = req_attrs; if (attrs == NULL) { uid = ldb_msg_find_attr_as_uint64(obj, SYSDB_UIDNUM, 0); if (uid == 0) { /* No UID hence group object */ attrs = group_attrs; } else { attrs = user_attrs; } } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, override_dn, LDB_SCOPE_BASE, attrs, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } if (res->count == 1) { override = res->msgs[0]; } else if (res->count == 0) { DEBUG(SSSDBG_TRACE_FUNC, "Override object [%s] does not exists.\n", override_dn_str); ret = ENOENT; goto done; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Base search for override object returned [%d] results.\n", res->count); ret = EINVAL; goto done; } } else { override = override_obj; } for (c = 0; attr_map[c].attr != NULL; c++) { tmp_el = ldb_msg_find_element(override, attr_map[c].attr); if (tmp_el != NULL) { for (d = 0; d < tmp_el->num_values; d++) { ret = ldb_msg_add_steal_value(obj, attr_map[c].new_attr, &tmp_el->values[d]); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_value failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } } } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_add_group_member_overrides(struct sss_domain_info *domain, struct ldb_message *obj) { int ret; size_t c; struct ldb_message_element *members; TALLOC_CTX *tmp_ctx; struct ldb_dn *member_dn; struct ldb_result *member_obj; struct ldb_result *override_obj; static const char *member_attrs[] = SYSDB_PW_ATTRS; const char *override_dn_str; struct ldb_dn *override_dn; const char *memberuid; const char *orig_name; char *orig_domain; char *val; struct sss_domain_info *orig_dom; members = ldb_msg_find_element(obj, SYSDB_MEMBER); if (members == NULL || members->num_values == 0) { DEBUG(SSSDBG_TRACE_ALL, "Group has no members.\n"); return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); ret = ENOMEM; goto done; } for (c = 0; c < members->num_values; c++) { member_dn = ldb_dn_from_ldb_val(tmp_ctx, domain->sysdb->ldb, &members->values[c]); if (member_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_from_ldb_val failed.\n"); ret = ENOMEM; goto done; } ret = ldb_search(domain->sysdb->ldb, member_dn, &member_obj, member_dn, LDB_SCOPE_BASE, member_attrs, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } if (member_obj->count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Base search for member object returned [%d] results.\n", member_obj->count); ret = EINVAL; goto done; } if (ldb_msg_find_attr_as_uint64(member_obj->msgs[0], SYSDB_UIDNUM, 0) == 0) { /* Skip non-POSIX-user members i.e. groups and non-POSIX users */ continue; } override_dn_str = ldb_msg_find_attr_as_string(member_obj->msgs[0], SYSDB_OVERRIDE_DN, NULL); if (override_dn_str == NULL) { if (is_local_view(domain->view_name)) { /* LOCAL view doesn't have to have overrideDN specified. */ ret = EOK; goto done; } DEBUG(SSSDBG_CRIT_FAILURE, "Missing override DN for object [%s].\n", ldb_dn_get_linearized(member_obj->msgs[0]->dn)); ret = ENOENT; goto done; } override_dn = ldb_dn_new(member_obj, domain->sysdb->ldb, override_dn_str); if (override_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); ret = ENOMEM; goto done; } orig_name = ldb_msg_find_attr_as_string(member_obj->msgs[0], SYSDB_NAME, NULL); if (orig_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Object [%s] has no name.\n", ldb_dn_get_linearized(member_obj->msgs[0]->dn)); ret = EINVAL; goto done; } memberuid = NULL; if (ldb_dn_compare(member_obj->msgs[0]->dn, override_dn) != 0) { DEBUG(SSSDBG_TRACE_ALL, "Checking override for object [%s].\n", ldb_dn_get_linearized(member_obj->msgs[0]->dn)); ret = ldb_search(domain->sysdb->ldb, member_obj, &override_obj, override_dn, LDB_SCOPE_BASE, member_attrs, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } if (override_obj->count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Base search for override object returned [%d] results.\n", member_obj->count); ret = EINVAL; goto done; } memberuid = ldb_msg_find_attr_as_string(override_obj->msgs[0], SYSDB_NAME, NULL); if (memberuid != NULL) { ret = sss_parse_name(tmp_ctx, domain->names, orig_name, &orig_domain, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_parse_name failed to split original name [%s].\n", orig_name); goto done; } if (orig_domain != NULL) { orig_dom = find_domain_by_name(get_domains_head(domain), orig_domain, true); if (orig_dom == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find domain with name [%s].\n", orig_domain); ret = EINVAL; goto done; } memberuid = sss_get_domain_name(tmp_ctx, memberuid, orig_dom); if (memberuid == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_get_domain_name failed.\n"); ret = ENOMEM; goto done; } } } } if (memberuid == NULL) { DEBUG(SSSDBG_TRACE_ALL, "No override name available.\n"); memberuid = orig_name; } val = talloc_strdup(obj, memberuid); if (val == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } ret = ldb_msg_add_string(obj, OVERRIDE_PREFIX SYSDB_MEMBERUID, val); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed.\n"); ret = sysdb_error_to_errno(ret); goto done; } DEBUG(SSSDBG_TRACE_ALL, "Added [%s] to [%s].\n", memberuid, OVERRIDE_PREFIX SYSDB_MEMBERUID); /* Free all temporary data of the current member to avoid memory usage * spikes. All temporary data should be allocated below member_dn. */ talloc_free(member_dn); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } struct ldb_message_element * sss_view_ldb_msg_find_element(struct sss_domain_info *dom, const struct ldb_message *msg, const char *attr_name) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_message_element *val; char *override_attr_name; if (DOM_HAS_VIEWS(dom)) { tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); val = NULL; goto done; } override_attr_name = talloc_asprintf(tmp_ctx, "%s%s", OVERRIDE_PREFIX, attr_name); if (override_attr_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); val = NULL; goto done; } val = ldb_msg_find_element(msg, override_attr_name); if (val != NULL) { goto done; } } val = ldb_msg_find_element(msg, attr_name); done: talloc_free(tmp_ctx); return val; } uint64_t sss_view_ldb_msg_find_attr_as_uint64(struct sss_domain_info *dom, const struct ldb_message *msg, const char *attr_name, uint64_t default_value) { TALLOC_CTX *tmp_ctx = NULL; uint64_t val; char *override_attr_name; if (DOM_HAS_VIEWS(dom)) { tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); val = default_value; goto done; } override_attr_name = talloc_asprintf(tmp_ctx, "%s%s", OVERRIDE_PREFIX, attr_name); if (override_attr_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); val = default_value; goto done; } if (ldb_msg_find_element(msg, override_attr_name) != NULL) { val = ldb_msg_find_attr_as_uint64(msg, override_attr_name, default_value); goto done; } } val = ldb_msg_find_attr_as_uint64(msg, attr_name, default_value); done: talloc_free(tmp_ctx); return val; } const char *sss_view_ldb_msg_find_attr_as_string(struct sss_domain_info *dom, const struct ldb_message *msg, const char *attr_name, const char * default_value) { TALLOC_CTX *tmp_ctx = NULL; const char *val; char *override_attr_name; if (DOM_HAS_VIEWS(dom)) { tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); val = default_value; goto done; } override_attr_name = talloc_asprintf(tmp_ctx, "%s%s", OVERRIDE_PREFIX, attr_name); if (override_attr_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); val = default_value; goto done; } if (ldb_msg_find_element(msg, override_attr_name) != NULL) { val = ldb_msg_find_attr_as_string(msg, override_attr_name, default_value); goto done; } } val = ldb_msg_find_attr_as_string(msg, attr_name, default_value); done: talloc_free(tmp_ctx); return val; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_ops.c0000644000000000000000000000007312703456111015651 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.830794226 sssd-1.13.4/src/db/sysdb_ops.c0000644002412700241270000034046212703456111017332 0ustar00jhrozekjhrozek00000000000000/* SSSD System Database Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb_private.h" #include "db/sysdb_services.h" #include "db/sysdb_autofs.h" #include "util/crypto/sss_crypto.h" #include "util/cert.h" #include int add_string(struct ldb_message *msg, int flags, const char *attr, const char *value) { int ret; ret = ldb_msg_add_empty(msg, attr, flags, NULL); if (ret == LDB_SUCCESS) { ret = ldb_msg_add_string(msg, attr, value); if (ret == LDB_SUCCESS) return EOK; } return ENOMEM; } int add_ulong(struct ldb_message *msg, int flags, const char *attr, unsigned long value) { int ret; ret = ldb_msg_add_empty(msg, attr, flags, NULL); if (ret == LDB_SUCCESS) { ret = ldb_msg_add_fmt(msg, attr, "%lu", value); if (ret == LDB_SUCCESS) return EOK; } return ENOMEM; } static uint32_t get_attr_as_uint32(struct ldb_message *msg, const char *attr) { const struct ldb_val *v = ldb_msg_find_ldb_val(msg, attr); long long int l; if (!v || !v->data) { return 0; } errno = 0; l = strtoll((const char *)v->data, NULL, 10); if (errno) { return (uint32_t)-1; } if (l < 0 || l > ((uint32_t)(-1))) { return (uint32_t)-1; } return l; } /* * The wrapper around ldb_modify that uses LDB_CONTROL_PERMISSIVE_MODIFY_OID * so that on adds entries that already exist are skipped and similarly * entries that are missing are ignored on deletes * * Please note this function returns LDB error codes, not sysdb error * codes on purpose, see usage in callers! */ int sss_ldb_modify_permissive(struct ldb_context *ldb, struct ldb_message *msg) { struct ldb_request *req; int ret = EOK; ret = ldb_build_mod_req(&req, ldb, ldb, msg, NULL, NULL, ldb_op_default_callback, NULL); if (ret != LDB_SUCCESS) return ret; ret = ldb_request_add_control(req, LDB_CONTROL_PERMISSIVE_MODIFY_OID, false, NULL); if (ret != LDB_SUCCESS) { talloc_free(req); return ret; } ret = ldb_request(ldb, req); if (ret == LDB_SUCCESS) { ret = ldb_wait(req->handle, LDB_WAIT_ALL); } talloc_free(req); /* Please note this function returns LDB error codes, not sysdb error * codes on purpose, see usage in callers! */ return ret; } #define ERROR_OUT(v, r, l) do { v = r; goto l; } while(0) /* =Remove-Entry-From-Sysdb=============================================== */ int sysdb_delete_entry(struct sysdb_ctx *sysdb, struct ldb_dn *dn, bool ignore_not_found) { int ret; ret = ldb_delete(sysdb->ldb, dn); switch (ret) { case LDB_SUCCESS: return EOK; case LDB_ERR_NO_SUCH_OBJECT: if (ignore_not_found) { return EOK; } /* fall through */ default: DEBUG(SSSDBG_CRIT_FAILURE, "LDB Error: %s(%d)\nError Message: [%s]\n", ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); return sysdb_error_to_errno(ret); } } /* =Remove-Subentries-From-Sysdb=========================================== */ int sysdb_delete_recursive(struct sysdb_ctx *sysdb, struct ldb_dn *dn, bool ignore_not_found) { const char *no_attrs[] = { NULL }; struct ldb_message **msgs; size_t msgs_count; int ret; int i; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = ldb_transaction_start(sysdb->ldb); if (ret) { ret = sysdb_error_to_errno(ret); goto done; } ret = sysdb_search_entry(tmp_ctx, sysdb, dn, LDB_SCOPE_SUBTREE, "(distinguishedName=*)", no_attrs, &msgs_count, &msgs); if (ret) { if (ignore_not_found && ret == ENOENT) { ret = EOK; } if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Search error: %d (%s)\n", ret, strerror(ret)); } goto done; } DEBUG(SSSDBG_TRACE_ALL, "Found [%zu] items to delete.\n", msgs_count); qsort(msgs, msgs_count, sizeof(struct ldb_message *), compare_ldb_dn_comp_num); for (i = 0; i < msgs_count; i++) { DEBUG(SSSDBG_TRACE_ALL, "Trying to delete [%s].\n", ldb_dn_get_linearized(msgs[i]->dn)); ret = sysdb_delete_entry(sysdb, msgs[i]->dn, false); if (ret) { goto done; } } done: if (ret == EOK) { ret = ldb_transaction_commit(sysdb->ldb); ret = sysdb_error_to_errno(ret); } else { ldb_transaction_cancel(sysdb->ldb); } talloc_free(tmp_ctx); return ret; } /* =Search-Entry========================================================== */ int sysdb_search_entry(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct ldb_dn *base_dn, enum ldb_scope scope, const char *filter, const char **attrs, size_t *_msgs_count, struct ldb_message ***_msgs) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, scope, attrs, filter?"%s":NULL, filter); if (ret != EOK) { ret = sysdb_error_to_errno(ret); goto done; } *_msgs_count = res->count; *_msgs = talloc_steal(mem_ctx, res->msgs); if (res->count == 0) { ret = ENOENT; goto done; } done: talloc_zfree(tmp_ctx); return ret; } /* =Search-Entry-by-SID-string============================================ */ int sysdb_search_entry_by_sid_str(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *search_base, const char *filter_str, const char *sid_str, const char **attrs, struct ldb_message **msg) { TALLOC_CTX *tmp_ctx; const char *def_attrs[] = { SYSDB_NAME, SYSDB_SID_STR, NULL }; struct ldb_message **msgs = NULL; struct ldb_dn *basedn; size_t msgs_count = 0; char *filter; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, search_base, domain->name); if (!basedn) { ret = ENOMEM; goto done; } filter = talloc_asprintf(tmp_ctx, filter_str, sid_str); if (!filter) { ret = ENOMEM; goto done; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, basedn, LDB_SCOPE_SUBTREE, filter, attrs?attrs:def_attrs, &msgs_count, &msgs); if (ret) { goto done; } *msg = talloc_steal(mem_ctx, msgs[0]); done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No such entry\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Search-User-by-[UID/SID/NAME]============================================= */ enum sysdb_obj_type { SYSDB_UNKNOWN = 0, SYSDB_USER, SYSDB_GROUP }; static int sysdb_search_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, enum sysdb_obj_type type, const char **attrs, struct ldb_message **msg) { TALLOC_CTX *tmp_ctx; const char *def_attrs[] = { SYSDB_NAME, NULL, NULL }; const char *base_tmpl = NULL; const char *filter_tmpl = NULL; struct ldb_message **msgs = NULL; struct ldb_dn *basedn; size_t msgs_count = 0; char *sanitized_name; char *lc_sanitized_name; char *filter; int ret; switch (type) { case SYSDB_USER: def_attrs[1] = SYSDB_UIDNUM; base_tmpl = SYSDB_TMPL_USER_BASE; filter_tmpl = SYSDB_PWNAM_FILTER; break; case SYSDB_GROUP: def_attrs[1] = SYSDB_GIDNUM; base_tmpl = SYSDB_TMPL_GROUP_BASE; filter_tmpl = SYSDB_GRNAM_FILTER; break; default: return EINVAL; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, base_tmpl, domain->name); if (!basedn) { ret = ENOMEM; goto done; } ret = sss_filter_sanitize_for_dom(tmp_ctx, name, domain, &sanitized_name, &lc_sanitized_name); if (ret != EOK) { goto done; } filter = talloc_asprintf(tmp_ctx, filter_tmpl, lc_sanitized_name, sanitized_name, sanitized_name); if (!filter) { ret = ENOMEM; goto done; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, basedn, LDB_SCOPE_SUBTREE, filter, attrs?attrs:def_attrs, &msgs_count, &msgs); if (ret) { goto done; } *msg = talloc_steal(mem_ctx, msgs[0]); done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No such entry\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } int sysdb_search_user_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_message **msg) { return sysdb_search_by_name(mem_ctx, domain, name, SYSDB_USER, attrs, msg); } int sysdb_search_user_by_uid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, uid_t uid, const char **attrs, struct ldb_message **msg) { TALLOC_CTX *tmp_ctx; const char *def_attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, NULL }; struct ldb_message **msgs = NULL; struct ldb_dn *basedn; size_t msgs_count = 0; char *filter; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = sysdb_user_base_dn(tmp_ctx, domain); if (!basedn) { ret = ENOMEM; goto done; } filter = talloc_asprintf(tmp_ctx, SYSDB_PWUID_FILTER, (unsigned long)uid); if (!filter) { ret = ENOMEM; goto done; } /* Use SUBTREE scope here, not ONELEVEL * There is a bug in LDB that makes ONELEVEL searches extremely * slow (it ignores indexing) */ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, basedn, LDB_SCOPE_SUBTREE, filter, attrs?attrs:def_attrs, &msgs_count, &msgs); if (ret) { goto done; } *msg = talloc_steal(mem_ctx, msgs[0]); done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No such entry\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } int sysdb_search_user_by_sid_str(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sid_str, const char **attrs, struct ldb_message **msg) { return sysdb_search_entry_by_sid_str(mem_ctx, domain, SYSDB_TMPL_USER_BASE, SYSDB_PWSID_FILTER, sid_str, attrs, msg); } int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *upn, const char **attrs, struct ldb_result **out_res) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; struct ldb_dn *base_dn; int ret; const char *def_attrs[] = { SYSDB_NAME, SYSDB_UPN, SYSDB_CANONICAL_UPN, NULL }; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } base_dn = sysdb_base_dn(domain->sysdb, tmp_ctx); if (base_dn == NULL) { ret = ENOMEM; goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE, attrs ? attrs : def_attrs, SYSDB_PWUPN_FILTER, upn, upn); if (ret != EOK) { ret = sysdb_error_to_errno(ret); goto done; } if (res->count == 0) { /* set result anyway */ *out_res = talloc_steal(mem_ctx, res); ret = ENOENT; goto done; } else if (res->count > 1) { DEBUG(SSSDBG_OP_FAILURE, "Search for upn [%s] returns more than one result.\n", upn); ret = EINVAL; goto done; } *out_res = talloc_steal(mem_ctx, res); ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } int sysdb_search_user_by_upn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *upn, const char **attrs, struct ldb_message **msg) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ret = sysdb_search_user_by_upn_res(tmp_ctx, domain, upn, attrs, &res); if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No entry with upn [%s] found.\n", upn); goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); goto done; } *msg = talloc_steal(mem_ctx, res->msgs[0]); ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } /* =Search-Group-by-[GID/SID/NAME]============================================ */ int sysdb_search_group_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_message **msg) { return sysdb_search_by_name(mem_ctx, domain, name, SYSDB_GROUP, attrs, msg); } int sysdb_search_group_by_gid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, gid_t gid, const char **attrs, struct ldb_message **msg) { TALLOC_CTX *tmp_ctx; const char *def_attrs[] = { SYSDB_NAME, SYSDB_GIDNUM, NULL }; struct ldb_message **msgs = NULL; struct ldb_dn *basedn; size_t msgs_count = 0; char *filter; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = sysdb_group_base_dn(tmp_ctx, domain); if (!basedn) { ret = ENOMEM; goto done; } filter = talloc_asprintf(tmp_ctx, SYSDB_GRGID_FILTER, (unsigned long)gid); if (!filter) { ret = ENOMEM; goto done; } /* Use SUBTREE scope here, not ONELEVEL * There is a bug in LDB that makes ONELEVEL searches extremely * slow (it ignores indexing) */ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, basedn, LDB_SCOPE_SUBTREE, filter, attrs?attrs:def_attrs, &msgs_count, &msgs); if (ret) { goto done; } *msg = talloc_steal(mem_ctx, msgs[0]); done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No such entry\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } int sysdb_search_group_by_sid_str(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sid_str, const char **attrs, struct ldb_message **msg) { return sysdb_search_entry_by_sid_str(mem_ctx, domain, SYSDB_TMPL_GROUP_BASE, SYSDB_GRSID_FILTER, sid_str, attrs, msg); } /* =Search-Group-by-Name============================================ */ int sysdb_search_netgroup_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_message **msg) { TALLOC_CTX *tmp_ctx; static const char *def_attrs[] = { SYSDB_NAME, NULL }; struct ldb_message **msgs = NULL; struct ldb_dn *basedn; size_t msgs_count = 0; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = sysdb_netgroup_dn(tmp_ctx, domain, name); if (!basedn) { ret = ENOMEM; goto done; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, basedn, LDB_SCOPE_BASE, NULL, attrs?attrs:def_attrs, &msgs_count, &msgs); if (ret) { goto done; } *msg = talloc_steal(mem_ctx, msgs[0]); done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No such entry\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Replace-Attributes-On-Entry=========================================== */ int sysdb_set_entry_attr(struct sysdb_ctx *sysdb, struct ldb_dn *entry_dn, struct sysdb_attrs *attrs, int mod_op) { struct ldb_message *msg; int i, ret; int lret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (!entry_dn || attrs->num == 0) { ret = EINVAL; goto done; } msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = entry_dn; msg->elements = talloc_array(msg, struct ldb_message_element, attrs->num); if (!msg->elements) { ret = ENOMEM; goto done; } for (i = 0; i < attrs->num; i++) { msg->elements[i] = attrs->a[i]; msg->elements[i].flags = mod_op; } msg->num_elements = attrs->num; lret = ldb_modify(sysdb->ldb, msg); if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(lret), lret, ldb_errstring(sysdb->ldb)); } ret = sysdb_error_to_errno(lret); done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No such entry\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Replace-Attributes-On-User============================================ */ int sysdb_set_user_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op) { struct ldb_dn *dn; TALLOC_CTX *tmp_ctx; errno_t ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } dn = sysdb_user_dn(tmp_ctx, domain, name); if (!dn) { ret = ENOMEM; goto done; } ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, mod_op); if (ret != EOK) { goto done; } ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } /* =Replace-Attributes-On-Group=========================================== */ int sysdb_set_group_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op) { struct ldb_dn *dn; TALLOC_CTX *tmp_ctx; errno_t ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } dn = sysdb_group_dn(tmp_ctx, domain, name); if (!dn) { ret = ENOMEM; goto done; } ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, mod_op); if (ret) { goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* =Replace-Attributes-On-Netgroup=========================================== */ int sysdb_set_netgroup_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op) { errno_t ret; struct ldb_dn *dn; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } dn = sysdb_netgroup_dn(tmp_ctx, domain, name); if (!dn) { ret = ENOMEM; goto done; } ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, mod_op); done: talloc_free(tmp_ctx); return ret; } /* =Get-New-ID============================================================ */ int sysdb_get_new_id(struct sss_domain_info *domain, uint32_t *_id) { TALLOC_CTX *tmp_ctx; const char *attrs_1[] = { SYSDB_NEXTID, NULL }; const char *attrs_2[] = { SYSDB_UIDNUM, SYSDB_GIDNUM, NULL }; struct ldb_dn *base_dn; char *filter; uint32_t new_id = 0; struct ldb_message **msgs; size_t count; struct ldb_message *msg; uint32_t id; int ret; int i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } base_dn = sysdb_domain_dn(tmp_ctx, domain); if (!base_dn) { talloc_zfree(tmp_ctx); return ENOMEM; } ret = ldb_transaction_start(domain->sysdb->ldb); if (ret) { talloc_zfree(tmp_ctx); ret = sysdb_error_to_errno(ret); return ret; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, base_dn, LDB_SCOPE_BASE, SYSDB_NEXTID_FILTER, attrs_1, &count, &msgs); switch (ret) { case EOK: new_id = get_attr_as_uint32(msgs[0], SYSDB_NEXTID); if (new_id == (uint32_t)(-1)) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid Next ID in domain %s\n", domain->name); ret = ERANGE; goto done; } if (new_id < domain->id_min) { new_id = domain->id_min; } if ((domain->id_max != 0) && (new_id > domain->id_max)) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to allocate new id, out of range (%u/%u)\n", new_id, domain->id_max); ret = ERANGE; goto done; } break; case ENOENT: /* looks like the domain is not initialized yet, use min_id */ new_id = domain->id_min; break; default: goto done; } talloc_zfree(msgs); count = 0; /* verify the id is actually really free. * search all entries with id >= new_id and < max_id */ if (domain->id_max) { filter = talloc_asprintf(tmp_ctx, "(|(&(%s>=%u)(%s<=%u))(&(%s>=%u)(%s<=%u)))", SYSDB_UIDNUM, new_id, SYSDB_UIDNUM, domain->id_max, SYSDB_GIDNUM, new_id, SYSDB_GIDNUM, domain->id_max); } else { filter = talloc_asprintf(tmp_ctx, "(|(%s>=%u)(%s>=%u))", SYSDB_UIDNUM, new_id, SYSDB_GIDNUM, new_id); } if (!filter) { DEBUG(SSSDBG_TRACE_FUNC, "Error: Out of memory\n"); ret = ENOMEM; goto done; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, base_dn, LDB_SCOPE_SUBTREE, filter, attrs_2, &count, &msgs); switch (ret) { /* if anything was found, find the maximum and increment past it */ case EOK: for (i = 0; i < count; i++) { id = get_attr_as_uint32(msgs[i], SYSDB_UIDNUM); if (id != (uint32_t)(-1)) { if (id > new_id) new_id = id; } id = get_attr_as_uint32(msgs[i], SYSDB_GIDNUM); if (id != (uint32_t)(-1)) { if (id > new_id) new_id = id; } } new_id++; /* check again we are not falling out of range */ if ((domain->id_max != 0) && (new_id > domain->id_max)) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to allocate new id, out of range (%u/%u)\n", new_id, domain->id_max); ret = ERANGE; goto done; } break; case ENOENT: break; default: goto done; } talloc_zfree(msgs); count = 0; /* finally store the new next id */ msg = ldb_msg_new(tmp_ctx); if (!msg) { DEBUG(SSSDBG_TRACE_FUNC, "Error: Out of memory\n"); ret = ENOMEM; goto done; } msg->dn = base_dn; ret = add_ulong(msg, LDB_FLAG_MOD_REPLACE, SYSDB_NEXTID, new_id + 1); if (ret) { goto done; } ret = ldb_modify(domain->sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(ret), ret, ldb_errstring(domain->sysdb->ldb)); } ret = sysdb_error_to_errno(ret); *_id = new_id; done: if (ret == EOK) { ret = ldb_transaction_commit(domain->sysdb->ldb); ret = sysdb_error_to_errno(ret); } else { ldb_transaction_cancel(domain->sysdb->ldb); } if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Add-Basic-User-NO-CHECKS============================================== */ int sysdb_add_basic_user(struct sss_domain_info *domain, const char *name, uid_t uid, gid_t gid, const char *gecos, const char *homedir, const char *shell) { struct ldb_message *msg; int ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } /* user dn */ msg->dn = sysdb_user_dn(msg, domain, name); if (!msg->dn) { ERROR_OUT(ret, ENOMEM, done); } ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_OBJECTCLASS, SYSDB_USER_CLASS); if (ret) goto done; ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_NAME, name); if (ret) goto done; ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_UIDNUM, (unsigned long)uid); if (ret) goto done; ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_GIDNUM, (unsigned long)gid); if (ret) goto done; /* We set gecos to be the same as fullname on user creation, * But we will not enforce coherency after that, it's up to * admins to decide if they want to keep it in sync if they change * one of the 2 */ if (gecos && *gecos) { ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_FULLNAME, gecos); if (ret) goto done; ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_GECOS, gecos); if (ret) goto done; } if (homedir && *homedir) { ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_HOMEDIR, homedir); if (ret) goto done; } if (shell && *shell) { ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_SHELL, shell); if (ret) goto done; } /* creation time */ ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME, (unsigned long)time(NULL)); if (ret) goto done; ret = ldb_add(domain->sysdb->ldb, msg); ret = sysdb_error_to_errno(ret); done: if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } static errno_t sysdb_remove_ghost_from_group(struct sss_domain_info *dom, struct ldb_message *group, struct ldb_message_element *alias_el, const char *name, const char *orig_dn, const char *userdn) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; struct ldb_message_element *orig_members; bool add_member = false; errno_t ret = EOK; int i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOENT; } msg = ldb_msg_new(tmp_ctx); if (!msg) { ERROR_OUT(ret, ENOMEM, done); } msg->dn = group->dn; if (orig_dn == NULL) { /* We have no way of telling which groups this user belongs to. * Add it to all that reference it in the ghost attribute */ add_member = true; } else { add_member = false; orig_members = ldb_msg_find_element(group, SYSDB_ORIG_MEMBER); if (orig_members) { for (i = 0; i < orig_members->num_values; i++) { if (strcmp((const char *) orig_members->values[i].data, orig_dn) == 0) { /* This is a direct member. Add the member attribute */ add_member = true; } } } else { /* Nothing to compare the originalDN with. Let's rely on the * memberof plugin to do the right thing during initgroups.. */ add_member = true; } } if (add_member) { ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_MEMBER, userdn); if (ret) goto done; } ret = add_string(msg, LDB_FLAG_MOD_DELETE, SYSDB_GHOST, name); if (ret) goto done; /* Delete aliases from the ghost attribute as well */ for (i = 0; i < alias_el->num_values; i++) { if (strcmp((const char *)alias_el->values[i].data, name) == 0) { continue; } ret = ldb_msg_add_string(msg, SYSDB_GHOST, (char *) alias_el->values[i].data); if (ret != LDB_SUCCESS) { ERROR_OUT(ret, EINVAL, done); } } ret = sss_ldb_modify_permissive(dom->sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_ldb_modify_permissive failed: [%s](%d)[%s]\n", ldb_strerror(ret), ret, ldb_errstring(dom->sysdb->ldb)); } ret = sysdb_error_to_errno(ret); if (ret != EOK) { goto done; } talloc_zfree(msg); done: talloc_free(tmp_ctx); return ret; } static errno_t sysdb_remove_ghostattr_from_groups(struct sss_domain_info *domain, const char *orig_dn, struct sysdb_attrs *attrs, const char *name) { TALLOC_CTX *tmp_ctx; struct ldb_message **groups; struct ldb_message_element *alias_el; struct ldb_dn *tmpdn; const char *group_attrs[] = {SYSDB_NAME, SYSDB_GHOST, SYSDB_ORIG_MEMBER, NULL}; const char *userdn; char *sanitized_name; char *filter; errno_t ret = EOK; size_t group_count = 0; int i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOENT; } ret = sss_filter_sanitize(tmp_ctx, name, &sanitized_name); if (ret != EOK) { goto done; } filter = talloc_asprintf(tmp_ctx, "(|(%s=%s)", SYSDB_GHOST, sanitized_name); if (!filter) { ret = ENOMEM; goto done; } ret = sysdb_attrs_get_el(attrs, SYSDB_NAME_ALIAS, &alias_el); if (ret != EOK) { goto done; } for (i = 0; i < alias_el->num_values; i++) { if (strcmp((const char *)alias_el->values[i].data, name) == 0) { continue; } filter = talloc_asprintf_append(filter, "(%s=%s)", SYSDB_GHOST, alias_el->values[i].data); if (filter == NULL) { ret = ENOMEM; goto done; } } filter = talloc_asprintf_append(filter, ")"); if (filter == NULL) { ret = ENOMEM; goto done; } tmpdn = sysdb_user_dn(tmp_ctx, domain, name); if (!tmpdn) { ERROR_OUT(ret, ENOMEM, done); } userdn = ldb_dn_get_linearized(tmpdn); if (!userdn) { ERROR_OUT(ret, EINVAL, done); } /* To cover cross-domain group-membership we must search in all * sub-domains. */ tmpdn = ldb_dn_new(tmp_ctx, domain->sysdb->ldb, SYSDB_BASE); if (!tmpdn) { ret = ENOMEM; goto done; } /* We need to find all groups that contain this object as a ghost user * and replace the ghost user by actual member record in direct parents. * Note that this object can be referred to either by its name or any * of its aliases */ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, tmpdn, LDB_SCOPE_SUBTREE, filter, group_attrs, &group_count, &groups); if (ret != EOK && ret != ENOENT) { goto done; } for (i = 0; i < group_count; i++) { sysdb_remove_ghost_from_group(domain, groups[i], alias_el, name, orig_dn, userdn); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* =Add-User-Function===================================================== */ int sysdb_add_user(struct sss_domain_info *domain, const char *name, uid_t uid, gid_t gid, const char *gecos, const char *homedir, const char *shell, const char *orig_dn, struct sysdb_attrs *attrs, int cache_timeout, time_t now) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; struct sysdb_attrs *id_attrs; uint32_t id; int ret; if (domain->mpg) { if (gid != 0) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot add user with arbitrary GID in MPG domain!\n"); return EINVAL; } gid = uid; } if (domain->id_max != 0 && uid != 0 && (uid < domain->id_min || uid > domain->id_max)) { DEBUG(SSSDBG_OP_FAILURE, "Supplied uid [%"SPRIuid"] is not in the allowed range " "[%d-%d].\n", uid, domain->id_min, domain->id_max); return ERANGE; } if (domain->id_max != 0 && gid != 0 && (gid < domain->id_min || gid > domain->id_max)) { DEBUG(SSSDBG_OP_FAILURE, "Supplied gid [%"SPRIgid"] is not in the allowed range " "[%d-%d].\n", gid, domain->id_min, domain->id_max); return ERANGE; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = ldb_transaction_start(domain->sysdb->ldb); if (ret) { ret = sysdb_error_to_errno(ret); talloc_free(tmp_ctx); return ret; } if (domain->mpg) { /* In MPG domains you can't have groups with the same name as users, * search if a group with the same name exists. * Don't worry about users, if we try to add a user with the same * name the operation will fail */ ret = sysdb_search_group_by_name(tmp_ctx, domain, name, NULL, &msg); if (ret != ENOENT) { if (ret == EOK) ret = EEXIST; goto done; } } /* check no other user with the same uid exist */ if (uid != 0) { ret = sysdb_search_user_by_uid(tmp_ctx, domain, uid, NULL, &msg); if (ret != ENOENT) { if (ret == EOK) ret = EEXIST; goto done; } } /* try to add the user */ ret = sysdb_add_basic_user(domain, name, uid, gid, gecos, homedir, shell); if (ret) goto done; if (uid == 0) { ret = sysdb_get_new_id(domain, &id); if (ret) goto done; id_attrs = sysdb_new_attrs(tmp_ctx); if (!id_attrs) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_uint32(id_attrs, SYSDB_UIDNUM, id); if (ret) goto done; if (domain->mpg) { ret = sysdb_attrs_add_uint32(id_attrs, SYSDB_GIDNUM, id); if (ret) goto done; } ret = sysdb_set_user_attr(domain, name, id_attrs, SYSDB_MOD_REP); /* continue on success, to commit additional attrs */ if (ret) goto done; } if (!attrs) { attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } } if (!now) { now = time(NULL); } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); if (ret) goto done; ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, ((cache_timeout) ? (now + cache_timeout) : 0)); if (ret) goto done; ret = sysdb_set_user_attr(domain, name, attrs, SYSDB_MOD_REP); if (ret) goto done; if (domain->enumerate == false) { /* If we're not enumerating, previous getgr{nam,gid} calls might * have stored ghost users into the cache, so we need to link them * with the newly-created user entry */ ret = sysdb_remove_ghostattr_from_groups(domain, orig_dn, attrs, name); if (ret) goto done; } ret = EOK; done: if (ret == EOK) { ret = ldb_transaction_commit(domain->sysdb->ldb); ret = sysdb_error_to_errno(ret); } else { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); ldb_transaction_cancel(domain->sysdb->ldb); } talloc_zfree(tmp_ctx); return ret; } /* =Add-Basic-Group-NO-CHECKS============================================= */ int sysdb_add_basic_group(struct sss_domain_info *domain, const char *name, gid_t gid) { struct ldb_message *msg; int ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } /* group dn */ msg->dn = sysdb_group_dn(msg, domain, name); if (!msg->dn) { ERROR_OUT(ret, ENOMEM, done); } ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_OBJECTCLASS, SYSDB_GROUP_CLASS); if (ret) goto done; ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_NAME, name); if (ret) goto done; ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_GIDNUM, (unsigned long)gid); if (ret) goto done; /* creation time */ ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME, (unsigned long)time(NULL)); if (ret) goto done; ret = ldb_add(domain->sysdb->ldb, msg); ret = sysdb_error_to_errno(ret); done: if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Add-Group-Function==================================================== */ int sysdb_add_group(struct sss_domain_info *domain, const char *name, gid_t gid, struct sysdb_attrs *attrs, int cache_timeout, time_t now) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; uint32_t id; int ret; bool posix; if (domain->id_max != 0 && gid != 0 && (gid < domain->id_min || gid > domain->id_max)) { DEBUG(SSSDBG_OP_FAILURE, "Supplied gid [%"SPRIgid"] is not in the allowed range " "[%d-%d].\n", gid, domain->id_min, domain->id_max); return ERANGE; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = ldb_transaction_start(domain->sysdb->ldb); if (ret) { ret = sysdb_error_to_errno(ret); talloc_free(tmp_ctx); return ret; } if (domain->mpg) { /* In MPG domains you can't have groups with the same name as users, * search if a group with the same name exists. * Don't worry about users, if we try to add a user with the same * name the operation will fail */ ret = sysdb_search_user_by_name(tmp_ctx, domain, name, NULL, &msg); if (ret != ENOENT) { if (ret == EOK) { DEBUG(SSSDBG_TRACE_LIBS, "MPG domain contains a user " "with the same name - %s.\n", name); ret = EEXIST; } else { DEBUG(SSSDBG_TRACE_LIBS, "sysdb_search_user_by_name failed for user %s.\n", name); } goto done; } } /* check no other groups with the same gid exist */ if (gid != 0) { ret = sysdb_search_group_by_gid(tmp_ctx, domain, gid, NULL, &msg); if (ret != ENOENT) { if (ret == EOK) { DEBUG(SSSDBG_TRACE_LIBS, "Group with the same gid exists: [%"SPRIgid"].\n", gid); ret = EEXIST; } else { DEBUG(SSSDBG_TRACE_LIBS, "sysdb_search_group_by_gid failed for gid: " "[%"SPRIgid"].\n", gid); } goto done; } } /* try to add the group */ ret = sysdb_add_basic_group(domain, name, gid); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "sysdb_add_basic_group failed for: %s with gid: " "[%"SPRIgid"].\n", name, gid); goto done; } if (!attrs) { attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { DEBUG(SSSDBG_TRACE_LIBS, "sysdb_new_attrs failed.\n"); ret = ENOMEM; goto done; } } ret = sysdb_attrs_get_bool(attrs, SYSDB_POSIX, &posix); if (ret == ENOENT) { posix = true; ret = sysdb_attrs_add_bool(attrs, SYSDB_POSIX, true); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "Failed to add posix attribute.\n"); goto done; } } else if (ret != EOK) { DEBUG(SSSDBG_TRACE_LIBS, "Failed to get posix attribute.\n"); goto done; } if (posix && gid == 0) { ret = sysdb_get_new_id(domain, &id); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "sysdb_get_new_id failed.\n"); goto done; } ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, id); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "Failed to add new gid.\n"); goto done; } } if (!now) { now = time(NULL); } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "Failed to add sysdb-last-update.\n"); goto done; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, ((cache_timeout) ? (now + cache_timeout) : 0)); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "Failed to add sysdb-cache-expire.\n"); goto done; } ret = sysdb_set_group_attr(domain, name, attrs, SYSDB_MOD_REP); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "sysdb_set_group_attr failed.\n"); goto done; } done: if (ret == EOK) { ret = ldb_transaction_commit(domain->sysdb->ldb); ret = sysdb_error_to_errno(ret); } else { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); ldb_transaction_cancel(domain->sysdb->ldb); } talloc_zfree(tmp_ctx); return ret; } int sysdb_add_incomplete_group(struct sss_domain_info *domain, const char *name, gid_t gid, const char *original_dn, const char *sid_str, const char *uuid, bool posix, time_t now) { TALLOC_CTX *tmp_ctx; int ret; struct sysdb_attrs *attrs; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } /* try to add the group */ ret = sysdb_add_basic_group(domain, name, gid); if (ret) goto done; attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } if (!now) { now = time(NULL); } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); if (ret) goto done; ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, now-1); if (ret) goto done; ret = sysdb_attrs_add_bool(attrs, SYSDB_POSIX, posix); if (ret) goto done; if (original_dn) { ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_DN, original_dn); if (ret) goto done; } if (sid_str) { ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, sid_str); if (ret) goto done; } if (uuid) { ret = sysdb_attrs_add_string(attrs, SYSDB_UUID, uuid); if (ret) goto done; } ret = sysdb_set_group_attr(domain, name, attrs, SYSDB_MOD_REP); done: if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Add-Or-Remove-Group-Memeber=========================================== */ /* mod_op must be either SYSDB_MOD_ADD or SYSDB_MOD_DEL */ int sysdb_mod_group_member(struct sss_domain_info *domain, struct ldb_dn *member_dn, struct ldb_dn *group_dn, int mod_op) { struct ldb_message *msg; const char *dn; int ret; msg = ldb_msg_new(NULL); if (!msg) { ERROR_OUT(ret, ENOMEM, fail); } msg->dn = group_dn; ret = ldb_msg_add_empty(msg, SYSDB_MEMBER, mod_op, NULL); if (ret != LDB_SUCCESS) { ERROR_OUT(ret, ENOMEM, fail); } dn = ldb_dn_get_linearized(member_dn); if (!dn) { ERROR_OUT(ret, EINVAL, fail); } ret = ldb_msg_add_string(msg, SYSDB_MEMBER, dn); if (ret != LDB_SUCCESS) { ERROR_OUT(ret, EINVAL, fail); } ret = ldb_modify(domain->sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(ret), ret, ldb_errstring(domain->sysdb->ldb)); } ret = sysdb_error_to_errno(ret); fail: if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(msg); return ret; } /* =Add-Basic-Netgroup-NO-CHECKS============================================= */ int sysdb_add_basic_netgroup(struct sss_domain_info *domain, const char *name, const char *description) { struct ldb_message *msg; int ret; msg = ldb_msg_new(NULL); if (!msg) { return ENOMEM; } /* netgroup dn */ msg->dn = sysdb_netgroup_dn(msg, domain, name); if (!msg->dn) { ERROR_OUT(ret, ENOMEM, done); } ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_OBJECTCLASS, SYSDB_NETGROUP_CLASS); if (ret) goto done; ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_NAME, name); if (ret) goto done; if (description && *description) { ret = add_string(msg, LDB_FLAG_MOD_ADD, SYSDB_DESCRIPTION, description); if (ret) goto done; } /* creation time */ ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME, (unsigned long) time(NULL)); if (ret) goto done; ret = ldb_add(domain->sysdb->ldb, msg); ret = sysdb_error_to_errno(ret); done: if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(msg); return ret; } /* =Add-Netgroup-Function==================================================== */ int sysdb_add_netgroup(struct sss_domain_info *domain, const char *name, const char *description, struct sysdb_attrs *attrs, char **missing, int cache_timeout, time_t now) { TALLOC_CTX *tmp_ctx; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = ldb_transaction_start(domain->sysdb->ldb); if (ret) { ret = sysdb_error_to_errno(ret); talloc_free(tmp_ctx); return ret; } /* try to add the netgroup */ ret = sysdb_add_basic_netgroup(domain, name, description); if (ret && ret != EEXIST) goto done; if (!attrs) { attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } } if (!now) { now = time(NULL); } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); if (ret) goto done; ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, ((cache_timeout) ? (now + cache_timeout) : 0)); if (ret) goto done; ret = sysdb_set_netgroup_attr(domain, name, attrs, SYSDB_MOD_REP); if (missing) { ret = sysdb_remove_attrs(domain, name, SYSDB_MEMBER_NETGROUP, missing); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not remove missing attributes\n"); } } done: if (ret == EOK) { ret = ldb_transaction_commit(domain->sysdb->ldb); ret = sysdb_error_to_errno(ret); } if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); ldb_transaction_cancel(domain->sysdb->ldb); } talloc_zfree(tmp_ctx); return ret; } /* =Store-Users-(Native/Legacy)-(replaces-existing-data)================== */ /* if one of the basic attributes is empty ("") as opposed to NULL, * this will just remove it */ int sysdb_store_user(struct sss_domain_info *domain, const char *name, const char *pwd, uid_t uid, gid_t gid, const char *gecos, const char *homedir, const char *shell, const char *orig_dn, struct sysdb_attrs *attrs, char **remove_attrs, uint64_t cache_timeout, time_t now) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; int ret; errno_t sret = EOK; bool in_transaction = false; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (!attrs) { attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto fail; } } if (pwd && (domain->legacy_passwords || !*pwd)) { ret = sysdb_attrs_add_string(attrs, SYSDB_PWD, pwd); if (ret) goto fail; } ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto fail; } in_transaction = true; ret = sysdb_search_user_by_name(tmp_ctx, domain, name, NULL, &msg); if (ret && ret != ENOENT) { goto fail; } /* get transaction timestamp */ if (!now) { now = time(NULL); } if (ret == ENOENT) { /* users doesn't exist, turn into adding a user */ ret = sysdb_add_user(domain, name, uid, gid, gecos, homedir, shell, orig_dn, attrs, cache_timeout, now); if (ret == EEXIST) { /* This may be a user rename. If there is a user with the * same UID, remove it and try to add the basic user again */ ret = sysdb_delete_user(domain, NULL, uid); if (ret == ENOENT) { /* Not found by UID, return the original EEXIST, * this may be a conflict in MPG domain or something * else */ ret = EEXIST; goto fail; } else if (ret != EOK) { goto fail; } DEBUG(SSSDBG_MINOR_FAILURE, "A user with the same UID [%llu] was removed from the " "cache\n", (unsigned long long) uid); ret = sysdb_add_user(domain, name, uid, gid, gecos, homedir, shell, orig_dn, attrs, cache_timeout, now); } /* Handle the result of sysdb_add_user */ if (ret == EOK) { goto done; } else { DEBUG(SSSDBG_OP_FAILURE, "Could not add user\n"); goto fail; } } /* the user exists, let's just replace attributes when set */ if (uid) { ret = sysdb_attrs_add_uint32(attrs, SYSDB_UIDNUM, uid); if (ret) goto fail; } if (gid) { ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid); if (ret) goto fail; } if (uid && !gid && domain->mpg) { ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, uid); if (ret) goto fail; } if (gecos) { ret = sysdb_attrs_add_string(attrs, SYSDB_GECOS, gecos); if (ret) goto fail; } if (homedir) { ret = sysdb_attrs_add_string(attrs, SYSDB_HOMEDIR, homedir); if (ret) goto fail; } if (shell) { ret = sysdb_attrs_add_string(attrs, SYSDB_SHELL, shell); if (ret) goto fail; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); if (ret) goto fail; ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, ((cache_timeout) ? (now + cache_timeout) : 0)); if (ret) goto fail; ret = sysdb_set_user_attr(domain, name, attrs, SYSDB_MOD_REP); if (ret != EOK) goto fail; if (remove_attrs) { ret = sysdb_remove_attrs(domain, name, SYSDB_MEMBER_USER, remove_attrs); if (ret != EOK) { DEBUG(SSSDBG_CONF_SETTINGS, "Could not remove missing attributes\n"); } } done: ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto fail; } in_transaction = false; fail: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Store-Group-(Native/Legacy)-(replaces-existing-data)================== */ /* this function does not check that all user members are actually present */ int sysdb_store_group(struct sss_domain_info *domain, const char *name, gid_t gid, struct sysdb_attrs *attrs, uint64_t cache_timeout, time_t now) { TALLOC_CTX *tmp_ctx; static const char *src_attrs[] = { SYSDB_NAME, SYSDB_GIDNUM, SYSDB_ORIG_MODSTAMP, NULL }; struct ldb_message *msg; bool new_group = false; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_search_group_by_name(tmp_ctx, domain, name, src_attrs, &msg); if (ret && ret != ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_search_group_by_name failed for %s with: [%d][%s].\n", name, ret, strerror(ret)); goto done; } if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_LIBS, "Group %s does not exist.\n", name); new_group = true; } if (!attrs) { attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } } /* get transaction timestamp */ if (!now) { now = time(NULL); } /* FIXME: use the remote modification timestamp to know if the * group needs any update */ if (new_group) { /* group doesn't exist, turn into adding a group */ ret = sysdb_add_group(domain, name, gid, attrs, cache_timeout, now); if (ret == EEXIST) { /* This may be a group rename. If there is a group with the * same GID, remove it and try to add the basic group again */ DEBUG(SSSDBG_TRACE_LIBS, "sysdb_add_group failed: [EEXIST].\n"); ret = sysdb_delete_group(domain, NULL, gid); if (ret == ENOENT) { /* Not found by GID, return the original EEXIST, * this may be a conflict in MPG domain or something * else */ DEBUG(SSSDBG_TRACE_LIBS, "sysdb_delete_group failed (while renaming group). Not " "found by gid: [%"SPRIgid"].\n", gid); return EEXIST; } else if (ret != EOK) { DEBUG(SSSDBG_TRACE_LIBS, "sysdb_add_group failed.\n"); goto done; } DEBUG(SSSDBG_MINOR_FAILURE, "A group with the same GID [%"SPRIgid"] was removed from " "the cache\n", gid); ret = sysdb_add_group(domain, name, gid, attrs, cache_timeout, now); if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_add_group failed (while renaming group) for: " "%s [%"SPRIgid"].\n", name, gid); } } goto done; } /* the group exists, let's just replace attributes when set */ if (gid) { ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "Failed to add GID.\n"); goto done; } } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "Failed to add sysdb-last-update.\n"); goto done; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, ((cache_timeout) ? (now + cache_timeout) : 0)); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "Failed to add sysdb-cache-expire.\n"); goto done; } ret = sysdb_set_group_attr(domain, name, attrs, SYSDB_MOD_REP); if (ret) { DEBUG(SSSDBG_TRACE_LIBS, "sysdb_set_group_attr failed.\n"); goto done; } done: if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Add-User-to-Group(Native/Legacy)====================================== */ static int sysdb_group_membership_mod(struct sss_domain_info *domain, const char *group, const char *member, enum sysdb_member_type type, int modify_op, bool is_dn) { struct ldb_dn *group_dn; struct ldb_dn *member_dn; int ret; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (type == SYSDB_MEMBER_USER) { member_dn = sysdb_user_dn(tmp_ctx, domain, member); } else if (type == SYSDB_MEMBER_GROUP) { member_dn = sysdb_group_dn(tmp_ctx, domain, member); } else { ret = EINVAL; goto done; } if (!member_dn) { ret = ENOMEM; goto done; } if (!is_dn) { group_dn = sysdb_group_dn(tmp_ctx, domain, group); } else { group_dn = ldb_dn_new(tmp_ctx, domain->sysdb->ldb, group); } if (!group_dn) { ret = ENOMEM; goto done; } ret = sysdb_mod_group_member(domain, member_dn, group_dn, modify_op); done: talloc_free(tmp_ctx); return ret; } int sysdb_add_group_member(struct sss_domain_info *domain, const char *group, const char *member, enum sysdb_member_type type, bool is_dn) { return sysdb_group_membership_mod(domain, group, member, type, SYSDB_MOD_ADD, is_dn); } /* =Remove-member-from-Group(Native/Legacy)=============================== */ int sysdb_remove_group_member(struct sss_domain_info *domain, const char *group, const char *member, enum sysdb_member_type type, bool is_dn) { return sysdb_group_membership_mod(domain, group, member, type, SYSDB_MOD_DEL, is_dn); } /* =Password-Caching====================================================== */ int sysdb_cache_password_ex(struct sss_domain_info *domain, const char *username, const char *password, enum sss_authtok_type authtok_type, size_t second_factor_len) { TALLOC_CTX *tmp_ctx; struct sysdb_attrs *attrs; char *hash = NULL; char *salt; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = s3crypt_gen_salt(tmp_ctx, &salt); if (ret) { DEBUG(SSSDBG_CONF_SETTINGS, "Failed to generate random salt.\n"); goto fail; } ret = s3crypt_sha512(tmp_ctx, password, salt, &hash); if (ret) { DEBUG(SSSDBG_CONF_SETTINGS, "Failed to create password hash.\n"); goto fail; } attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ERROR_OUT(ret, ENOMEM, fail); } ret = sysdb_attrs_add_string(attrs, SYSDB_CACHEDPWD, hash); if (ret) goto fail; ret = sysdb_attrs_add_long(attrs, SYSDB_CACHEDPWD_TYPE, authtok_type); if (ret) goto fail; if (authtok_type == SSS_AUTHTOK_TYPE_2FA && second_factor_len > 0) { ret = sysdb_attrs_add_long(attrs, SYSDB_CACHEDPWD_FA2_LEN, second_factor_len); if (ret) goto fail; } /* FIXME: should we use a different attribute for chache passwords ?? */ ret = sysdb_attrs_add_long(attrs, "lastCachedPasswordChange", (long)time(NULL)); if (ret) goto fail; ret = sysdb_attrs_add_uint32(attrs, SYSDB_FAILED_LOGIN_ATTEMPTS, 0U); if (ret) goto fail; ret = sysdb_set_user_attr(domain, username, attrs, SYSDB_MOD_REP); if (ret) { goto fail; } talloc_zfree(tmp_ctx); return EOK; fail: if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } int sysdb_cache_password(struct sss_domain_info *domain, const char *username, const char *password) { return sysdb_cache_password_ex(domain, username, password, SSS_AUTHTOK_TYPE_PASSWORD, 0); } /* =Custom Search================== */ int sysdb_search_custom(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *filter, const char *subtree_name, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs) { TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn = NULL; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } if (filter == NULL || subtree_name == NULL) { ret = EINVAL; goto done; } basedn = sysdb_custom_subtree_dn(tmp_ctx, domain, subtree_name); if (basedn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_custom_subtree_dn failed.\n"); ret = ENOMEM; goto done; } if (!ldb_dn_validate(basedn)) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create DN.\n"); ret = EINVAL; goto done; } ret = sysdb_search_entry(mem_ctx, domain->sysdb, basedn, LDB_SCOPE_SUBTREE, filter, attrs, msgs_count, msgs); done: talloc_free(tmp_ctx); return ret; } int sysdb_search_custom_by_name(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *object_name, const char *subtree_name, const char **attrs, size_t *_count, struct ldb_message ***_msgs) { TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn; struct ldb_message **msgs; size_t count; int ret; if (object_name == NULL || subtree_name == NULL) { return EINVAL; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = sysdb_custom_dn(tmp_ctx, domain, object_name, subtree_name); if (basedn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_custom_dn failed.\n"); ret = ENOMEM; goto done; } if (!ldb_dn_validate(basedn)) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create DN.\n"); ret = EINVAL; goto done; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, basedn, LDB_SCOPE_BASE, NULL, attrs, &count, &msgs); if (ret) { goto done; } if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "More than one result found.\n"); ret = EFAULT; goto done; } *_count = count; *_msgs = talloc_move(mem_ctx, &msgs); done: talloc_zfree(tmp_ctx); return ret; } /* =Custom Store (replaces-existing-data)================== */ int sysdb_store_custom(struct sss_domain_info *domain, const char *object_name, const char *subtree_name, struct sysdb_attrs *attrs) { TALLOC_CTX *tmp_ctx; const char *search_attrs[] = { "*", NULL }; size_t resp_count = 0; struct ldb_message **resp; struct ldb_message *msg; struct ldb_message_element *el; bool add_object = false; int ret; int i; if (object_name == NULL || subtree_name == NULL) { return EINVAL; } ret = ldb_transaction_start(domain->sysdb->ldb); if (ret) { return sysdb_error_to_errno(ret); } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } ret = sysdb_search_custom_by_name(tmp_ctx, domain, object_name, subtree_name, search_attrs, &resp_count, &resp); if (ret != EOK && ret != ENOENT) { goto done; } if (ret == ENOENT) { add_object = true; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = sysdb_custom_dn(tmp_ctx, domain, object_name, subtree_name); if (!msg->dn) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_custom_dn failed.\n"); ret = ENOMEM; goto done; } msg->elements = talloc_array(msg, struct ldb_message_element, attrs->num); if (!msg->elements) { ret = ENOMEM; goto done; } for (i = 0; i < attrs->num; i++) { msg->elements[i] = attrs->a[i]; if (add_object) { msg->elements[i].flags = LDB_FLAG_MOD_ADD; } else { el = ldb_msg_find_element(resp[0], attrs->a[i].name); if (el == NULL) { msg->elements[i].flags = LDB_FLAG_MOD_ADD; } else { msg->elements[i].flags = LDB_FLAG_MOD_REPLACE; } } } msg->num_elements = attrs->num; if (add_object) { ret = ldb_add(domain->sysdb->ldb, msg); } else { ret = ldb_modify(domain->sysdb->ldb, msg); } if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store custom entry: %s(%d)[%s]\n", ldb_strerror(ret), ret, ldb_errstring(domain->sysdb->ldb)); ret = sysdb_error_to_errno(ret); } done: if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); ldb_transaction_cancel(domain->sysdb->ldb); } else { ret = ldb_transaction_commit(domain->sysdb->ldb); ret = sysdb_error_to_errno(ret); } talloc_zfree(tmp_ctx); return ret; } /* = Custom Delete======================================= */ int sysdb_delete_custom(struct sss_domain_info *domain, const char *object_name, const char *subtree_name) { TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; int ret; if (object_name == NULL || subtree_name == NULL) { return EINVAL; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } dn = sysdb_custom_dn(tmp_ctx, domain, object_name, subtree_name); if (dn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_custom_dn failed.\n"); ret = ENOMEM; goto done; } ret = ldb_delete(domain->sysdb->ldb, dn); switch (ret) { case LDB_SUCCESS: case LDB_ERR_NO_SUCH_OBJECT: ret = EOK; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "LDB Error: %s(%d)\nError Message: [%s]\n", ldb_strerror(ret), ret, ldb_errstring(domain->sysdb->ldb)); ret = sysdb_error_to_errno(ret); break; } done: talloc_zfree(tmp_ctx); return ret; } /* = ASQ search request ======================================== */ int sysdb_asq_search(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_dn *base_dn, const char *expression, const char *asq_attribute, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs) { TALLOC_CTX *tmp_ctx; struct ldb_request *ldb_req; struct ldb_control **ctrl; struct ldb_asq_control *asq_control; struct ldb_result *res; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ctrl = talloc_array(tmp_ctx, struct ldb_control *, 2); if (ctrl == NULL) { ret = ENOMEM; goto fail; } ctrl[0] = talloc(ctrl, struct ldb_control); if (ctrl[0] == NULL) { ret = ENOMEM; goto fail; } ctrl[1] = NULL; ctrl[0]->oid = LDB_CONTROL_ASQ_OID; ctrl[0]->critical = 1; asq_control = talloc(ctrl[0], struct ldb_asq_control); if (asq_control == NULL) { ret = ENOMEM; goto fail; } asq_control->request = 1; asq_control->source_attribute = talloc_strdup(asq_control, asq_attribute); if (asq_control->source_attribute == NULL) { ret = ENOMEM; goto fail; } asq_control->src_attr_len = strlen(asq_control->source_attribute); ctrl[0]->data = asq_control; res = talloc_zero(tmp_ctx, struct ldb_result); if (!res) { ret = ENOMEM; goto fail; } ret = ldb_build_search_req(&ldb_req, domain->sysdb->ldb, tmp_ctx, base_dn, LDB_SCOPE_BASE, expression, attrs, ctrl, res, ldb_search_default_callback, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto fail; } ret = ldb_request(domain->sysdb->ldb, ldb_req); if (ret == LDB_SUCCESS) { ret = ldb_wait(ldb_req->handle, LDB_WAIT_ALL); } if (ret) { ret = sysdb_error_to_errno(ret); goto fail; } *msgs_count = res->count; *msgs = talloc_move(mem_ctx, &res->msgs); talloc_zfree(tmp_ctx); return EOK; fail: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No such entry\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Search-Users-with-Custom-Filter====================================== */ int sysdb_search_users(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs) { TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn; char *filter; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = sysdb_user_base_dn(tmp_ctx, domain); if (!basedn) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n"); ret = ENOMEM; goto fail; } filter = talloc_asprintf(tmp_ctx, "(&(%s)%s)", SYSDB_UC, sub_filter); if (!filter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "Search users with filter: %s\n", filter); ret = sysdb_search_entry(mem_ctx, domain->sysdb, basedn, LDB_SCOPE_SUBTREE, filter, attrs, msgs_count, msgs); if (ret) { goto fail; } talloc_zfree(tmp_ctx); return EOK; fail: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_INTERNAL, "No such entry\n"); } else if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Delete-User-by-Name-OR-uid============================================ */ int sysdb_delete_user(struct sss_domain_info *domain, const char *name, uid_t uid) { TALLOC_CTX *tmp_ctx; const char *attrs[] = {SYSDB_GHOST, NULL}; size_t msg_count; char *filter; struct ldb_message **msgs; struct ldb_message *msg; int ret; int i; char *sanitized_name; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (name) { ret = sysdb_search_user_by_name(tmp_ctx, domain, name, NULL, &msg); } else { ret = sysdb_search_user_by_uid(tmp_ctx, domain, uid, NULL, &msg); } if (ret == EOK) { if (name && uid) { /* verify name/gid match */ const char *c_name; uint64_t c_uid; c_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); c_uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0); if (c_name == NULL || c_uid == 0) { DEBUG(SSSDBG_OP_FAILURE, "Attribute is missing but this should never happen!\n"); ret = EFAULT; goto fail; } if (strcmp(name, c_name) || uid != c_uid) { /* this is not the entry we are looking for */ ret = EINVAL; goto fail; } } ret = sysdb_delete_entry(domain->sysdb, msg->dn, false); if (ret) { goto fail; } } else if (ret == ENOENT && name != NULL) { /* Perhaps a ghost user? */ ret = sss_filter_sanitize(tmp_ctx, name, &sanitized_name); if (ret != EOK) { goto fail; } filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_GHOST, sanitized_name); if (filter == NULL) { ret = ENOMEM; goto fail; } ret = sysdb_search_groups(tmp_ctx, domain, filter, attrs, &msg_count, &msgs); if (ret != EOK) { goto fail; } for (i = 0; i < msg_count; i++) { msg = ldb_msg_new(tmp_ctx); if (!msg) { ERROR_OUT(ret, ENOMEM, fail); } msg->dn = msgs[i]->dn; ret = add_string(msg, LDB_FLAG_MOD_DELETE, SYSDB_GHOST, name); if (ret) goto fail; ret = ldb_modify(domain->sysdb->ldb, msg); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(ret), ret, ldb_errstring(domain->sysdb->ldb)); } ret = sysdb_error_to_errno(ret); if (ret != EOK) { goto fail; } talloc_zfree(msg); } } else { goto fail; } talloc_zfree(tmp_ctx); return EOK; fail: DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); talloc_zfree(tmp_ctx); return ret; } /* =Search-Groups-with-Custom-Filter===================================== */ int sysdb_search_groups(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs) { TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn; char *filter; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = sysdb_group_base_dn(tmp_ctx, domain); if (!basedn) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n"); ret = ENOMEM; goto fail; } filter = talloc_asprintf(tmp_ctx, "(&(%s)%s)", SYSDB_GC, sub_filter); if (!filter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto fail; } DEBUG(SSSDBG_TRACE_INTERNAL, "Search groups with filter: %s\n", filter); ret = sysdb_search_entry(mem_ctx, domain->sysdb, basedn, LDB_SCOPE_SUBTREE, filter, attrs, msgs_count, msgs); if (ret) { goto fail; } talloc_zfree(tmp_ctx); return EOK; fail: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_INTERNAL, "No such entry\n"); } else if (ret) { DEBUG(SSSDBG_MINOR_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Delete-Group-by-Name-OR-gid=========================================== */ int sysdb_delete_group(struct sss_domain_info *domain, const char *name, gid_t gid) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (name) { ret = sysdb_search_group_by_name(tmp_ctx, domain, name, NULL, &msg); } else { ret = sysdb_search_group_by_gid(tmp_ctx, domain, gid, NULL, &msg); } if (ret) { goto fail; } if (name && gid) { /* verify name/gid match */ const char *c_name; uint64_t c_gid; c_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); c_gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0); if (c_name == NULL || c_gid == 0) { DEBUG(SSSDBG_OP_FAILURE, "Attribute is missing but this should never happen!\n"); ret = EFAULT; goto fail; } if (strcmp(name, c_name) || gid != c_gid) { /* this is not the entry we are looking for */ ret = EINVAL; goto fail; } } ret = sysdb_delete_entry(domain->sysdb, msg->dn, false); if (ret) { goto fail; } talloc_zfree(tmp_ctx); return EOK; fail: DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); talloc_zfree(tmp_ctx); return ret; } /* =Search-Netgroups-with-Custom-Filter===================================== */ int sysdb_search_netgroups(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs) { TALLOC_CTX *tmp_ctx; struct ldb_dn *basedn; char *filter; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_NETGROUP_BASE, domain->name); if (!basedn) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n"); ret = ENOMEM; goto fail; } filter = talloc_asprintf(tmp_ctx, "(&(%s)%s)", SYSDB_NC, sub_filter); if (!filter) { DEBUG(SSSDBG_OP_FAILURE, "Failed to build filter\n"); ret = ENOMEM; goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "Search netgroups with filter: %s\n", filter); ret = sysdb_search_entry(mem_ctx, domain->sysdb, basedn, LDB_SCOPE_SUBTREE, filter, attrs, msgs_count, msgs); if (ret) { goto fail; } talloc_zfree(tmp_ctx); return EOK; fail: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "Entry not found\n"); } else { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } /* =Delete-Netgroup-by-Name============================================== */ int sysdb_delete_netgroup(struct sss_domain_info *domain, const char *name) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; int ret; if (!name) return EINVAL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_search_netgroup_by_name(tmp_ctx, domain, name, NULL, &msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "sysdb_search_netgroup_by_name failed: %d (%s)\n", ret, strerror(ret)); goto done; } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "Netgroup does not exist, nothing to delete\n"); ret = EOK; goto done; } ret = sysdb_delete_entry(domain->sysdb, msg->dn, false); if (ret != EOK) { goto done; } done: if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(tmp_ctx); return ret; } int sysdb_delete_by_sid(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, const char *sid_str) { TALLOC_CTX *tmp_ctx; struct ldb_result *res; int ret; if (!sid_str) return EINVAL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_search_object_by_sid(tmp_ctx, domain, sid_str, NULL, &res); if (ret == ENOENT) { /* No existing entry. Just quit. */ DEBUG(SSSDBG_TRACE_FUNC, "search by sid did not return any results.\n"); ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "search by sid failed: %d (%s)\n", ret, strerror(ret)); goto done; } if (res->count > 1) { DEBUG(SSSDBG_FATAL_FAILURE, "getbysid call returned more than one " \ "result !?!\n"); ret = EIO; goto done; } ret = sysdb_delete_entry(sysdb, res->msgs[0]->dn, false); if (ret != EOK) { goto done; } done: if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(tmp_ctx); return ret; } /* ========= Authentication against cached password ============ */ errno_t check_failed_login_attempts(struct confdb_ctx *cdb, struct ldb_message *ldb_msg, uint32_t *failed_login_attempts, time_t *delayed_until) { int ret; int allowed_failed_login_attempts; int failed_login_delay; time_t last_failed_login; time_t end; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } *delayed_until = -1; *failed_login_attempts = ldb_msg_find_attr_as_uint(ldb_msg, SYSDB_FAILED_LOGIN_ATTEMPTS, 0); last_failed_login = (time_t) ldb_msg_find_attr_as_int64(ldb_msg, SYSDB_LAST_FAILED_LOGIN, 0); ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_FAILED_LOGIN_ATTEMPTS, CONFDB_DEFAULT_PAM_FAILED_LOGIN_ATTEMPTS, &allowed_failed_login_attempts); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read the number of allowed failed login " "attempts.\n"); ret = ERR_INTERNAL; goto done; } ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_FAILED_LOGIN_DELAY, CONFDB_DEFAULT_PAM_FAILED_LOGIN_DELAY, &failed_login_delay); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read the failed login delay.\n"); ret = ERR_INTERNAL; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Failed login attempts [%d], allowed failed login attempts [%d], " "failed login delay [%d].\n", *failed_login_attempts, allowed_failed_login_attempts, failed_login_delay); if (allowed_failed_login_attempts) { if (*failed_login_attempts >= allowed_failed_login_attempts) { if (failed_login_delay) { end = last_failed_login + (failed_login_delay * 60); if (end < time(NULL)) { DEBUG(SSSDBG_TRACE_LIBS, "failed_login_delay has passed, " "resetting failed_login_attempts.\n"); *failed_login_attempts = 0; } else { DEBUG(SSSDBG_TRACE_LIBS, "login delayed until %lld.\n", (long long) end); *delayed_until = end; ret = ERR_AUTH_DENIED; goto done; } } else { DEBUG(SSSDBG_CONF_SETTINGS, "Too many failed logins.\n"); ret = ERR_AUTH_DENIED; goto done; } } } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t check_for_combined_2fa_password(struct sss_domain_info *domain, struct ldb_message *ldb_msg, const char *password, const char *userhash) { unsigned int cached_authtok_type; unsigned int cached_fa2_len; char *short_pw; char *comphash; size_t pw_len; TALLOC_CTX *tmp_ctx; int ret; cached_authtok_type = ldb_msg_find_attr_as_uint(ldb_msg, SYSDB_CACHEDPWD_TYPE, SSS_AUTHTOK_TYPE_EMPTY); if (cached_authtok_type != SSS_AUTHTOK_TYPE_2FA) { DEBUG(SSSDBG_TRACE_LIBS, "Wrong authtok type.\n"); return EINVAL; } cached_fa2_len = ldb_msg_find_attr_as_uint(ldb_msg, SYSDB_CACHEDPWD_FA2_LEN, 0); if (cached_fa2_len == 0) { DEBUG(SSSDBG_TRACE_LIBS, "Second factor size not available.\n"); return EINVAL; } pw_len = strlen(password); if (pw_len < cached_fa2_len + domain->cache_credentials_min_ff_length) { DEBUG(SSSDBG_TRACE_LIBS, "Password too short.\n"); return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } short_pw = talloc_strndup(tmp_ctx, password, (pw_len - cached_fa2_len)); if (short_pw == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); ret = ENOMEM; goto done; } ret = s3crypt_sha512(tmp_ctx, short_pw, userhash, &comphash); if (ret != EOK) { DEBUG(SSSDBG_CONF_SETTINGS, "Failed to create password hash.\n"); ret = ERR_INTERNAL; goto done; } if (strcmp(userhash, comphash) != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Hash of shorten password does not match.\n"); ret = ERR_AUTH_FAILED; goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } int sysdb_cache_auth(struct sss_domain_info *domain, const char *name, const char *password, struct confdb_ctx *cdb, bool just_check, time_t *_expire_date, time_t *_delayed_until) { TALLOC_CTX *tmp_ctx; const char *attrs[] = { SYSDB_NAME, SYSDB_CACHEDPWD, SYSDB_DISABLED, SYSDB_LAST_LOGIN, SYSDB_LAST_ONLINE_AUTH, "lastCachedPasswordChange", "accountExpires", SYSDB_FAILED_LOGIN_ATTEMPTS, SYSDB_LAST_FAILED_LOGIN, SYSDB_CACHEDPWD_TYPE, SYSDB_CACHEDPWD_FA2_LEN, NULL }; struct ldb_message *ldb_msg; const char *userhash; char *comphash; uint64_t lastLogin = 0; int cred_expiration; uint32_t failed_login_attempts = 0; struct sysdb_attrs *update_attrs; bool authentication_successful = false; time_t expire_date = -1; time_t delayed_until = -1; int ret; if (name == NULL || *name == '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Missing user name.\n"); return EINVAL; } if (cdb == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing config db context.\n"); return EINVAL; } if (domain->sysdb == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing sysdb db context.\n"); return EINVAL; } if (!domain->cache_credentials) { DEBUG(SSSDBG_MINOR_FAILURE, "Cached credentials not available.\n"); return EINVAL; } tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = ldb_transaction_start(domain->sysdb->ldb); if (ret) { talloc_zfree(tmp_ctx); ret = sysdb_error_to_errno(ret); return ret; } ret = sysdb_search_user_by_name(tmp_ctx, domain, name, attrs, &ldb_msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_search_user_by_name failed [%d][%s].\n", ret, strerror(ret)); if (ret == ENOENT) ret = ERR_ACCOUNT_UNKNOWN; goto done; } /* Check offline_auth_cache_timeout */ lastLogin = ldb_msg_find_attr_as_uint64(ldb_msg, SYSDB_LAST_ONLINE_AUTH, 0); ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_CRED_TIMEOUT, 0, &cred_expiration); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read expiration time of offline credentials.\n"); goto done; } DEBUG(SSSDBG_TRACE_ALL, "Offline credentials expiration is [%d] days.\n", cred_expiration); if (cred_expiration) { expire_date = lastLogin + (cred_expiration * 86400); if (expire_date < time(NULL)) { DEBUG(SSSDBG_CONF_SETTINGS, "Cached user entry is too old.\n"); expire_date = 0; ret = ERR_CACHED_CREDS_EXPIRED; goto done; } } else { expire_date = 0; } ret = check_failed_login_attempts(cdb, ldb_msg, &failed_login_attempts, &delayed_until); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to check login attempts\n"); goto done; } /* TODO: verify user account (disabled, expired ...) */ userhash = ldb_msg_find_attr_as_string(ldb_msg, SYSDB_CACHEDPWD, NULL); if (userhash == NULL || *userhash == '\0') { DEBUG(SSSDBG_CONF_SETTINGS, "Cached credentials not available.\n"); ret = ERR_NO_CACHED_CREDS; goto done; } ret = s3crypt_sha512(tmp_ctx, password, userhash, &comphash); if (ret) { DEBUG(SSSDBG_CONF_SETTINGS, "Failed to create password hash.\n"); ret = ERR_INTERNAL; goto done; } update_attrs = sysdb_new_attrs(tmp_ctx); if (update_attrs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_new_attrs failed.\n"); ret = ENOMEM; goto done; } if (strcmp(userhash, comphash) == 0 || check_for_combined_2fa_password(domain, ldb_msg, password, userhash) == EOK) { /* TODO: probable good point for audit logging */ DEBUG(SSSDBG_CONF_SETTINGS, "Hashes do match!\n"); authentication_successful = true; if (just_check) { ret = EOK; goto done; } ret = sysdb_attrs_add_time_t(update_attrs, SYSDB_LAST_LOGIN, time(NULL)); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_attrs_add_time_t failed, " "but authentication is successful.\n"); ret = EOK; goto done; } ret = sysdb_attrs_add_uint32(update_attrs, SYSDB_FAILED_LOGIN_ATTEMPTS, 0U); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_attrs_add_uint32 failed, " "but authentication is successful.\n"); ret = EOK; goto done; } } else { DEBUG(SSSDBG_CONF_SETTINGS, "Authentication failed.\n"); authentication_successful = false; ret = sysdb_attrs_add_time_t(update_attrs, SYSDB_LAST_FAILED_LOGIN, time(NULL)); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_attrs_add_time_t failed.\n"); goto done; } ret = sysdb_attrs_add_uint32(update_attrs, SYSDB_FAILED_LOGIN_ATTEMPTS, ++failed_login_attempts); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_attrs_add_uint32 failed.\n"); goto done; } } ret = sysdb_set_user_attr(domain, name, update_attrs, LDB_FLAG_MOD_REPLACE); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to update Login attempt information!\n"); } done: if (_expire_date != NULL) { *_expire_date = expire_date; } if (_delayed_until != NULL) { *_delayed_until = delayed_until; } if (ret) { ldb_transaction_cancel(domain->sysdb->ldb); } else { ret = ldb_transaction_commit(domain->sysdb->ldb); ret = sysdb_error_to_errno(ret); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to commit transaction!\n"); } } if (authentication_successful) { ret = EOK; } else { if (ret == EOK) { ret = ERR_AUTH_FAILED; } } talloc_free(tmp_ctx); return ret; } static errno_t sysdb_update_members_ex(struct sss_domain_info *domain, const char *member, enum sysdb_member_type type, const char *const *add_groups, const char *const *del_groups, bool is_dn) { errno_t ret; errno_t sret; int i; bool in_transaction = false; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if(!tmp_ctx) { return ENOMEM; } ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to start update transaction\n"); goto done; } in_transaction = true; if (add_groups) { /* Add the user to all add_groups */ for (i = 0; add_groups[i]; i++) { ret = sysdb_add_group_member(domain, add_groups[i], member, type, is_dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not add member [%s] to group [%s]. " "Skipping.\n", member, add_groups[i]); /* Continue on, we should try to finish the rest */ } } } if (del_groups) { /* Remove the user from all del_groups */ for (i = 0; del_groups[i]; i++) { ret = sysdb_remove_group_member(domain, del_groups[i], member, type, is_dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not remove member [%s] from group [%s]. " "Skipping\n", member, del_groups[i]); /* Continue on, we should try to finish the rest */ } } } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } errno_t sysdb_update_members(struct sss_domain_info *domain, const char *member, enum sysdb_member_type type, const char *const *add_groups, const char *const *del_groups) { return sysdb_update_members_ex(domain, member, type, add_groups, del_groups, false); } errno_t sysdb_update_members_dn(struct sss_domain_info *member_domain, const char *member, enum sysdb_member_type type, const char *const *add_groups, const char *const *del_groups) { return sysdb_update_members_ex(member_domain, member, type, add_groups, del_groups, true); } errno_t sysdb_remove_attrs(struct sss_domain_info *domain, const char *name, enum sysdb_member_type type, char **remove_attrs) { errno_t ret; errno_t sret = EOK; bool in_transaction = false; struct ldb_message *msg; int lret; size_t i; msg = ldb_msg_new(NULL); if (!msg) return ENOMEM; switch(type) { case SYSDB_MEMBER_USER: msg->dn = sysdb_user_dn(msg, domain, name); break; case SYSDB_MEMBER_GROUP: msg->dn = sysdb_group_dn(msg, domain, name); break; case SYSDB_MEMBER_NETGROUP: msg->dn = sysdb_netgroup_dn(msg, domain, name); break; case SYSDB_MEMBER_SERVICE: msg->dn = sysdb_svc_dn(domain->sysdb, msg, domain->name, name); break; } if (!msg->dn) { ret = ENOMEM; goto done; } ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; for (i = 0; remove_attrs[i]; i++) { /* SYSDB_MEMBEROF is exclusively handled by the memberof plugin */ if (strcasecmp(remove_attrs[i], SYSDB_MEMBEROF) == 0) { continue; } DEBUG(SSSDBG_TRACE_INTERNAL, "Removing attribute [%s] from [%s]\n", remove_attrs[i], name); lret = ldb_msg_add_empty(msg, remove_attrs[i], LDB_FLAG_MOD_DELETE, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } /* We need to do individual modifies so that we can * skip unknown attributes. Otherwise, any nonexistent * attribute in the sysdb will cause other removals to * fail. */ lret = ldb_modify(domain->sysdb->ldb, msg); if (lret != LDB_SUCCESS && lret != LDB_ERR_NO_SUCH_ATTRIBUTE) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb_modify failed: [%s](%d)[%s]\n", ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb)); ret = sysdb_error_to_errno(lret); goto done; } /* Remove this attribute and move on to the next one */ ldb_msg_remove_attr(msg, remove_attrs[i]); } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(msg); return ret; } static errno_t sysdb_search_object_by_str_attr(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *filter_tmpl, const char *str, const char **attrs, struct ldb_result **_res) { TALLOC_CTX *tmp_ctx; const char *def_attrs[] = { SYSDB_NAME, SYSDB_UIDNUM, SYSDB_GIDNUM, ORIGINALAD_PREFIX SYSDB_NAME, SYSDB_DEFAULT_ATTRS, NULL }; struct ldb_dn *basedn; int ret; struct ldb_result *res = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } basedn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_DOM_BASE, domain->name); if (basedn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n"); ret = ENOMEM; goto done; } ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE, attrs?attrs:def_attrs, filter_tmpl, str); if (ret != EOK) { ret = sysdb_error_to_errno(ret); DEBUG(SSSDBG_OP_FAILURE, "ldb_search failed.\n"); goto done; } if (res->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Search for [%s] with filter [%s] " \ "returned more than one object.\n", str, filter_tmpl); ret = EINVAL; goto done; } else if (res->count == 0) { ret = ENOENT; goto done; } *_res = talloc_steal(mem_ctx, res); done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No such entry.\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } errno_t sysdb_search_object_by_sid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sid_str, const char **attrs, struct ldb_result **res) { return sysdb_search_object_by_str_attr(mem_ctx, domain, SYSDB_SID_FILTER, sid_str, attrs, res); } errno_t sysdb_search_object_by_uuid(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *uuid_str, const char **attrs, struct ldb_result **res) { return sysdb_search_object_by_str_attr(mem_ctx, domain, SYSDB_UUID_FILTER, uuid_str, attrs, res); } errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *cert, const char **attrs, struct ldb_result **res) { int ret; char *user_filter; ret = sss_cert_derb64_to_ldap_filter(mem_ctx, cert, SYSDB_USER_CERT, &user_filter); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n"); return ret; } ret = sysdb_search_object_by_str_attr(mem_ctx, domain, SYSDB_USER_CERT_FILTER, user_filter, attrs, res); talloc_free(user_filter); return ret; } errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *cert, struct ldb_result **res) { const char *user_attrs[] = SYSDB_PW_ATTRS; return sysdb_search_object_by_cert(mem_ctx, domain, cert, user_attrs, res); } errno_t sysdb_remove_cert(struct sss_domain_info *domain, const char *cert) { struct ldb_message_element el = { 0, SYSDB_USER_CERT, 0, NULL }; struct sysdb_attrs del_attrs = { 1, &el }; const char *attrs[] = {SYSDB_NAME, NULL}; struct ldb_result *res = NULL; unsigned int i; errno_t ret; ret = sysdb_search_object_by_cert(NULL, domain, cert, attrs, &res); if (ret == ENOENT || res == NULL) { ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to lookup object by cert " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } /* Certificate may be found on more objects, remove it from all. * If object contains more then one certificate, we still remove the * whole attribute since it will be downloaded again. */ for (i = 0; i < res->count; i++) { ret = sysdb_set_entry_attr(domain->sysdb, res->msgs[0]->dn, &del_attrs, SYSDB_MOD_DEL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to remove certificate " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sysdb_mark_entry_as_expired_ldb_dn(domain, res->msgs[0]->dn); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to expire object " "[%d]: %s\n", ret, sss_strerror(ret)); continue; } } done: talloc_free(res); return ret; } errno_t sysdb_get_sids_of_members(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *group_name, const char ***_sids, const char ***_dns, size_t *_n) { errno_t ret; size_t i, m_count; TALLOC_CTX *tmp_ctx; struct ldb_message *msg; struct ldb_message **members; const char *attrs[] = { SYSDB_SID_STR, NULL }; const char **sids = NULL, **dns = NULL; size_t n = 0; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = sysdb_search_group_by_name(tmp_ctx, dom, group_name, NULL, &msg); if (ret != EOK) { goto done; } /* Get sid_str attribute of all elemets pointed to by group members */ ret = sysdb_asq_search(tmp_ctx, dom, msg->dn, NULL, SYSDB_MEMBER, attrs, &m_count, &members); if (ret != EOK) { goto done; } sids = talloc_array(tmp_ctx, const char*, m_count); if (sids == NULL) { ret = ENOMEM; goto done; } dns = talloc_array(tmp_ctx, const char*, m_count); if (dns == NULL) { ret = ENOMEM; goto done; } for (i=0; i < m_count; i++) { const char *sidstr; sidstr = ldb_msg_find_attr_as_string(members[i], SYSDB_SID_STR, NULL); if (sidstr != NULL) { sids[n] = talloc_steal(sids, sidstr); dns[n] = talloc_steal(dns, ldb_dn_get_linearized(members[i]->dn)); if (dns[n] == NULL) { ret = ENOMEM; goto done; } n++; } } if (n == 0) { ret = ENOENT; goto done; } *_n = n; *_sids = talloc_steal(mem_ctx, sids); *_dns = talloc_steal(mem_ctx, dns); ret = EOK; done: if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No such entry\n"); } else if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Error: %d (%s)\n", ret, strerror(ret)); } talloc_free(tmp_ctx); return ret; } errno_t sysdb_handle_original_uuid(const char *orig_name, struct sysdb_attrs *src_attrs, const char *src_name, struct sysdb_attrs *dest_attrs, const char *dest_name) { int ret; struct ldb_message_element *el; char guid_str_buf[GUID_STR_BUF_SIZE]; if (orig_name == NULL) { /* This provider doesn't handle UUIDs */ return ENOENT; } if (src_attrs == NULL || src_name == NULL || dest_attrs == NULL || dest_name == NULL) { return EINVAL; } ret = sysdb_attrs_get_el_ext(src_attrs, src_name, false, &el); if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el failed.\n"); } return ret; } if (el->num_values != 1) { DEBUG(SSSDBG_MINOR_FAILURE, "Found more than one UUID value, using the first.\n"); } /* Check if we got a binary AD objectGUID */ if (el->values[0].length == GUID_BIN_LENGTH && strcasecmp(orig_name, "objectGUID") == 0) { ret = guid_blob_to_string_buf(el->values[0].data, guid_str_buf, GUID_STR_BUF_SIZE); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "guid_blob_to_string_buf failed.\n"); return ret; } ret = sysdb_attrs_add_string(dest_attrs, dest_name, guid_str_buf); } else { ret = sysdb_attrs_add_string(dest_attrs, dest_name, (const char *)el->values[0].data); } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); return ret;; } return EOK; } /* Mark entry as expired */ errno_t sysdb_mark_entry_as_expired_ldb_dn(struct sss_domain_info *dom, struct ldb_dn *ldbdn) { struct ldb_message *msg; errno_t ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = ldbdn; ret = ldb_msg_add_empty(msg, SYSDB_CACHE_EXPIRE, LDB_FLAG_MOD_REPLACE, NULL); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_msg_add_string(msg, SYSDB_CACHE_EXPIRE, "1"); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_modify(dom->sysdb->ldb, msg); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_mark_entry_as_expired_ldb_val(struct sss_domain_info *dom, struct ldb_val *dn_val) { struct ldb_dn *ldbdn; errno_t ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ldbdn = ldb_dn_from_ldb_val(tmp_ctx, dom->sysdb->ldb, dn_val); if (ldbdn == NULL) { ret = ENOMEM; goto done; } ret = sysdb_mark_entry_as_expired_ldb_dn(dom, ldbdn); done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_sudo.c0000644000000000000000000000007312703456111016022 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.882794402 sssd-1.13.4/src/db/sysdb_sudo.c0000644002412700241270000006325112703456111017501 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include "db/sysdb.h" #include "db/sysdb_private.h" #include "db/sysdb_sudo.h" #define SUDO_ALL_FILTER "(" SYSDB_OBJECTCLASS "=" SYSDB_SUDO_CACHE_OC ")" #define NULL_CHECK(val, rval, label) do { \ if (!val) { \ rval = ENOMEM; \ goto label; \ } \ } while(0) /* ==================== Utility functions ==================== */ static errno_t sysdb_sudo_convert_time(const char *str, time_t *unix_time) { struct tm tm; char *tret = NULL; /* SUDO requires times to be in generalized time format: * YYYYMMDDHHMMSS[.|,fraction][(+|-HHMM)|Z] * * We need to use more format strings to parse this with strptime(). */ const char **format = NULL; const char *formats[] = {"%Y%m%d%H%M%SZ", /* 201212121300Z */ "%Y%m%d%H%M%S%z", /* 201212121300+-0200 */ "%Y%m%d%H%M%S.0Z", "%Y%m%d%H%M%S.0%z", "%Y%m%d%H%M%S,0Z", "%Y%m%d%H%M%S,0%z", NULL}; for (format = formats; *format != NULL; format++) { /* strptime() may leave some fields uninitialized */ memset(&tm, 0, sizeof(struct tm)); tret = strptime(str, *format, &tm); if (tret != NULL && *tret == '\0') { *unix_time = mktime(&tm); return EOK; } } return EINVAL; } static errno_t sysdb_sudo_check_time(struct sysdb_attrs *rule, time_t now, bool *result) { TALLOC_CTX *tmp_ctx = NULL; const char **values = NULL; const char *name = NULL; time_t notBefore = 0; time_t notAfter = 0; time_t converted; errno_t ret; int i; if (!result) return EINVAL; *result = false; tmp_ctx = talloc_new(NULL); NULL_CHECK(tmp_ctx, ret, done); ret = sysdb_attrs_get_string(rule, SYSDB_SUDO_CACHE_AT_CN, &name); if (ret == ENOENT) { name = ""; } else if(ret != EOK) { goto done; } /* * From man sudoers.ldap: * * If multiple sudoNotBefore entries are present, the *earliest* is used. * If multiple sudoNotAfter entries are present, the *last one* is used. * * From sudo sources, ldap.c: * If either the sudoNotAfter or sudoNotBefore attributes are missing, * no time restriction shall be imposed. */ /* check for sudoNotBefore */ ret = sysdb_attrs_get_string_array(rule, SYSDB_SUDO_CACHE_AT_NOTBEFORE, tmp_ctx, &values); if (ret == EOK) { for (i=0; values[i] ; i++) { ret = sysdb_sudo_convert_time(values[i], &converted); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Invalid time format in rule [%s]!\n", name); goto done; } /* Grab the earliest */ if (!notBefore) { notBefore = converted; } else if (notBefore > converted) { notBefore = converted; } } } else if (ret != ENOENT) { goto done; } /* check for sudoNotAfter */ ret = sysdb_attrs_get_string_array(rule, SYSDB_SUDO_CACHE_AT_NOTAFTER, tmp_ctx, &values); if (ret == EOK) { for (i=0; values[i] ; i++) { ret = sysdb_sudo_convert_time(values[i], &converted); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Invalid time format in rule [%s]!\n", name); goto done; } /* Grab the latest */ if (!notAfter) { notAfter = converted; } else if (notAfter < converted) { notAfter = converted; } } } else if (ret != ENOENT) { goto done; } if ((notBefore == 0 || now >= notBefore) && (notAfter == 0 || now <= notAfter)) { *result = true; } if (*result) { DEBUG(SSSDBG_TRACE_ALL, "Rule [%s] matches time restrictions\n", name); } else { DEBUG(SSSDBG_TRACE_ALL, "Rule [%s] does not match time " "restrictions\n", name); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_sudo_filter_rules_by_time(TALLOC_CTX *mem_ctx, uint32_t in_num_rules, struct sysdb_attrs **in_rules, time_t now, uint32_t *_num_rules, struct sysdb_attrs ***_rules) { uint32_t num_rules = 0; struct sysdb_attrs **rules = NULL; TALLOC_CTX *tmp_ctx = NULL; bool allowed = false; errno_t ret; int i; tmp_ctx = talloc_new(NULL); NULL_CHECK(tmp_ctx, ret, done); if (now == 0) { now = time(NULL); } for (i = 0; i < in_num_rules; i++) { ret = sysdb_sudo_check_time(in_rules[i], now, &allowed); if (ret == EOK && allowed) { num_rules++; rules = talloc_realloc(tmp_ctx, rules, struct sysdb_attrs *, num_rules); NULL_CHECK(rules, ret, done); rules[num_rules - 1] = in_rules[i]; } } *_num_rules = num_rules; *_rules = talloc_steal(mem_ctx, rules); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_get_sudo_filter(TALLOC_CTX *mem_ctx, const char *username, uid_t uid, char **groupnames, unsigned int flags, char **_filter) { TALLOC_CTX *tmp_ctx = NULL; char *filter = NULL; char *specific_filter = NULL; char *sanitized = NULL; time_t now; errno_t ret; int i; tmp_ctx = talloc_new(NULL); NULL_CHECK(tmp_ctx, ret, done); /* build specific filter */ specific_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */ NULL_CHECK(specific_filter, ret, done); if (flags & SYSDB_SUDO_FILTER_INCLUDE_ALL) { specific_filter = talloc_asprintf_append(specific_filter, "(%s=ALL)", SYSDB_SUDO_CACHE_AT_USER); NULL_CHECK(specific_filter, ret, done); } if (flags & SYSDB_SUDO_FILTER_INCLUDE_DFL) { specific_filter = talloc_asprintf_append(specific_filter, "(%s=defaults)", SYSDB_NAME); NULL_CHECK(specific_filter, ret, done); } if ((flags & SYSDB_SUDO_FILTER_USERNAME) && (username != NULL)) { ret = sss_filter_sanitize(tmp_ctx, username, &sanitized); if (ret != EOK) { goto done; } specific_filter = talloc_asprintf_append(specific_filter, "(%s=%s)", SYSDB_SUDO_CACHE_AT_USER, sanitized); NULL_CHECK(specific_filter, ret, done); } if ((flags & SYSDB_SUDO_FILTER_UID) && (uid != 0)) { specific_filter = talloc_asprintf_append(specific_filter, "(%s=#%llu)", SYSDB_SUDO_CACHE_AT_USER, (unsigned long long) uid); NULL_CHECK(specific_filter, ret, done); } if ((flags & SYSDB_SUDO_FILTER_GROUPS) && (groupnames != NULL)) { for (i=0; groupnames[i] != NULL; i++) { ret = sss_filter_sanitize(tmp_ctx, groupnames[i], &sanitized); if (ret != EOK) { goto done; } specific_filter = talloc_asprintf_append(specific_filter, "(%s=%%%s)", SYSDB_SUDO_CACHE_AT_USER, sanitized); NULL_CHECK(specific_filter, ret, done); } } if (flags & SYSDB_SUDO_FILTER_NGRS) { specific_filter = talloc_asprintf_append(specific_filter, "(%s=+*)", SYSDB_SUDO_CACHE_AT_USER); NULL_CHECK(specific_filter, ret, done); } /* build global filter */ filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)", SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC); NULL_CHECK(filter, ret, done); if (specific_filter[0] != '\0') { filter = talloc_asprintf_append(filter, "(|%s)", specific_filter); NULL_CHECK(filter, ret, done); } if (flags & SYSDB_SUDO_FILTER_ONLY_EXPIRED) { now = time(NULL); filter = talloc_asprintf_append(filter, "(&(%s<=%lld))", SYSDB_CACHE_EXPIRE, (long long)now); NULL_CHECK(filter, ret, done); } filter = talloc_strdup_append(filter, ")"); NULL_CHECK(filter, ret, done); ret = EOK; *_filter = talloc_steal(mem_ctx, filter); done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_get_sudo_user_info(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *username, uid_t *_uid, char ***groupnames) { TALLOC_CTX *tmp_ctx; errno_t ret; struct ldb_message *msg; struct ldb_message *group_msg = NULL; char **sysdb_groupnames = NULL; const char *primary_group = NULL; struct ldb_message_element *groups; uid_t uid = 0; gid_t gid = 0; size_t num_groups = 0; int i; const char *attrs[] = { SYSDB_MEMBEROF, SYSDB_GIDNUM, SYSDB_UIDNUM, NULL }; const char *group_attrs[] = { SYSDB_NAME, NULL }; tmp_ctx = talloc_new(NULL); NULL_CHECK(tmp_ctx, ret, done); ret = sysdb_search_user_by_name(tmp_ctx, domain, username, attrs, &msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up user %s\n", username); goto done; } if (_uid != NULL) { uid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0); if (!uid) { DEBUG(SSSDBG_CRIT_FAILURE, "A user with no UID?\n"); ret = EIO; goto done; } } /* resolve secondary groups */ if (groupnames != NULL) { groups = ldb_msg_find_element(msg, SYSDB_MEMBEROF); if (!groups || groups->num_values == 0) { /* No groups for this user in sysdb currently */ sysdb_groupnames = NULL; num_groups = 0; } else { num_groups = groups->num_values; sysdb_groupnames = talloc_array(tmp_ctx, char *, num_groups + 1); NULL_CHECK(sysdb_groupnames, ret, done); /* Get a list of the groups by groupname only */ for (i = 0; i < groups->num_values; i++) { ret = sysdb_group_dn_name(domain->sysdb, sysdb_groupnames, (const char *)groups->values[i].data, &sysdb_groupnames[i]); if (ret != EOK) { ret = ENOMEM; goto done; } } sysdb_groupnames[groups->num_values] = NULL; } } /* resolve primary group */ gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0); if (gid != 0) { ret = sysdb_search_group_by_gid(tmp_ctx, domain, gid, group_attrs, &group_msg); if (ret == EOK) { primary_group = ldb_msg_find_attr_as_string(group_msg, SYSDB_NAME, NULL); if (primary_group == NULL) { ret = ENOMEM; goto done; } num_groups++; sysdb_groupnames = talloc_realloc(tmp_ctx, sysdb_groupnames, char *, num_groups + 1); NULL_CHECK(sysdb_groupnames, ret, done); sysdb_groupnames[num_groups - 1] = talloc_strdup(sysdb_groupnames, primary_group); NULL_CHECK(sysdb_groupnames[num_groups - 1], ret, done); sysdb_groupnames[num_groups] = NULL; } else if (ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up group [%d]: %s\n", ret, strerror(ret)); goto done; } } ret = EOK; if (_uid != NULL) { *_uid = uid; } if (groupnames != NULL) { *groupnames = talloc_steal(mem_ctx, sysdb_groupnames); } done: talloc_free(tmp_ctx); return ret; } static errno_t sysdb_sudo_set_refresh_time(struct sss_domain_info *domain, const char *attr_name, time_t value) { TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; struct ldb_message *msg = NULL; struct ldb_result *res = NULL; errno_t ret; int lret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { ret = ENOMEM; goto done; } dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE, SUDORULE_SUBDIR, domain->name); if (!dn) { ret = ENOMEM; goto done; } lret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, NULL, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = dn; if (res->count == 0) { lret = ldb_msg_add_string(msg, "cn", SUDORULE_SUBDIR); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } else if (res->count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Got more than one reply for base search!\n"); ret = EIO; goto done; } else { lret = ldb_msg_add_empty(msg, attr_name, LDB_FLAG_MOD_REPLACE, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } } lret = ldb_msg_add_fmt(msg, attr_name, "%lld", (long long)value); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } if (res->count) { lret = ldb_modify(domain->sysdb->ldb, msg); } else { lret = ldb_add(domain->sysdb->ldb, msg); } if (lret != LDB_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "ldb operation failed: [%s](%d)[%s]\n", ldb_strerror(lret), lret, ldb_errstring(domain->sysdb->ldb)); } ret = sysdb_error_to_errno(lret); done: talloc_free(tmp_ctx); return ret; } static errno_t sysdb_sudo_get_refresh_time(struct sss_domain_info *domain, const char *attr_name, time_t *value) { TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; struct ldb_result *res; errno_t ret; int lret; const char *attrs[2] = {attr_name, NULL}; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE, SUDORULE_SUBDIR, domain->name); if (!dn) { ret = ENOMEM; goto done; } lret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, attrs, NULL); if (lret != LDB_SUCCESS) { ret = sysdb_error_to_errno(lret); goto done; } if (res->count == 0) { /* This entry has not been populated in LDB * This is a common case, as unlike LDAP, * LDB does not need to have all of its parent * objects actually exist. */ *value = 0; ret = EOK; goto done; } else if (res->count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Got more than one reply for base search!\n"); ret = EIO; goto done; } *value = ldb_msg_find_attr_as_int(res->msgs[0], attr_name, 0); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_sudo_set_last_full_refresh(struct sss_domain_info *domain, time_t value) { return sysdb_sudo_set_refresh_time(domain, SYSDB_SUDO_AT_LAST_FULL_REFRESH, value); } errno_t sysdb_sudo_get_last_full_refresh(struct sss_domain_info *domain, time_t *value) { return sysdb_sudo_get_refresh_time(domain, SYSDB_SUDO_AT_LAST_FULL_REFRESH, value); } /* ==================== Purge functions ==================== */ static const char * sysdb_sudo_get_rule_name(struct sysdb_attrs *rule) { const char *name; errno_t ret; ret = sysdb_attrs_get_string(rule, SYSDB_SUDO_CACHE_AT_CN, &name); if (ret == ERANGE) { DEBUG(SSSDBG_MINOR_FAILURE, "Warning: found rule that contains none " "or multiple CN values. It will be skipped.\n"); return NULL; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to obtain rule name [%d]: %s\n", ret, strerror(ret)); return NULL; } return name; } static errno_t sysdb_sudo_purge_all(struct sss_domain_info *domain) { struct ldb_dn *base_dn = NULL; TALLOC_CTX *tmp_ctx = NULL; errno_t ret; tmp_ctx = talloc_new(NULL); NULL_CHECK(tmp_ctx, ret, done); base_dn = sysdb_custom_subtree_dn(tmp_ctx, domain, SUDORULE_SUBDIR); NULL_CHECK(base_dn, ret, done); DEBUG(SSSDBG_TRACE_FUNC, "Deleting all cached sudo rules\n"); ret = sysdb_delete_recursive(domain->sysdb, base_dn, true); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_delete_recursive failed.\n"); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t sysdb_sudo_purge_byname(struct sss_domain_info *domain, const char *name) { DEBUG(SSSDBG_TRACE_INTERNAL, "Deleting sudo rule %s\n", name); return sysdb_delete_custom(domain, name, SUDORULE_SUBDIR); } static errno_t sysdb_sudo_purge_byrules(struct sss_domain_info *dom, struct sysdb_attrs **rules, size_t num_rules) { const char *name; errno_t ret; size_t i; DEBUG(SSSDBG_TRACE_FUNC, "About to remove rules from sudo cache\n"); if (num_rules == 0 || rules == NULL) { return EOK; } for (i = 0; i < num_rules; i++) { name = sysdb_sudo_get_rule_name(rules[i]); if (name == NULL) { continue; } ret = sysdb_sudo_purge_byname(dom, name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to delete rule " "%s [%d]: %s\n", name, ret, sss_strerror(ret)); continue; } } return EOK; } static errno_t sysdb_sudo_purge_byfilter(struct sss_domain_info *domain, const char *filter) { TALLOC_CTX *tmp_ctx; struct sysdb_attrs **rules; struct ldb_message **msgs; size_t count; errno_t ret; const char *attrs[] = { SYSDB_OBJECTCLASS, SYSDB_NAME, SYSDB_SUDO_CACHE_AT_CN, NULL }; if (filter == NULL || strcmp(filter, SUDO_ALL_FILTER) == 0) { return sysdb_sudo_purge_all(domain); } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ret = sysdb_search_custom(tmp_ctx, domain, filter, SUDORULE_SUBDIR, attrs, &count, &msgs); if (ret == ENOENT || count == 0) { DEBUG(SSSDBG_TRACE_FUNC, "No rules matched\n"); ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up SUDO rules\n"); goto done; } ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &rules); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to convert ldb message to " "sysdb attrs [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sysdb_sudo_purge_byrules(domain, rules, count); done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_sudo_purge(struct sss_domain_info *domain, const char *delete_filter, struct sysdb_attrs **rules, size_t num_rules) { bool in_transaction = false; errno_t sret; errno_t ret; ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); return ret; } in_transaction = true; if (delete_filter) { ret = sysdb_sudo_purge_byfilter(domain, delete_filter); } else { ret = sysdb_sudo_purge_byrules(domain, rules, num_rules); } if (ret != EOK) { goto done; } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not cancel transaction\n"); } } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to purge sudo cache [%d]: %s\n", ret, sss_strerror(ret)); } return ret; } static errno_t sysdb_sudo_add_sss_attrs(struct sysdb_attrs *rule, const char *name, int cache_timeout, time_t now) { time_t expire; errno_t ret; ret = sysdb_attrs_add_string(rule, SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to add %s attribute [%d]: %s\n", SYSDB_OBJECTCLASS, ret, strerror(ret)); return ret; } ret = sysdb_attrs_add_string(rule, SYSDB_NAME, name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to add %s attribute [%d]: %s\n", SYSDB_OBJECTCLASS, ret, strerror(ret)); return ret; } expire = cache_timeout > 0 ? now + cache_timeout : 0; ret = sysdb_attrs_add_time_t(rule, SYSDB_CACHE_EXPIRE, expire); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Unable to add %s attribute [%d]: %s\n", SYSDB_CACHE_EXPIRE, ret, strerror(ret)); return ret; } return EOK; } static errno_t sysdb_sudo_store_rule(struct sss_domain_info *domain, struct sysdb_attrs *rule, int cache_timeout, time_t now) { const char *name; errno_t ret; name = sysdb_sudo_get_rule_name(rule); if (name == NULL) { return EINVAL; } DEBUG(SSSDBG_TRACE_FUNC, "Adding sudo rule %s\n", name); ret = sysdb_sudo_add_sss_attrs(rule, name, cache_timeout, now); if (ret != EOK) { return ret; } ret = sysdb_store_custom(domain, name, SUDORULE_SUBDIR, rule); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to store rule %s [%d]: %s\n", name, ret, strerror(ret)); return ret; } return EOK; } errno_t sysdb_sudo_store(struct sss_domain_info *domain, struct sysdb_attrs **rules, size_t num_rules) { bool in_transaction = false; errno_t sret; errno_t ret; time_t now; size_t i; if (num_rules == 0 || rules == NULL) { return EOK; } ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); return ret; } in_transaction = true; now = time(NULL); for (i = 0; i < num_rules; i++) { ret = sysdb_sudo_store_rule(domain, rules[i], domain->sudo_timeout, now); if (ret == EINVAL) { /* Multiple CNs are error on server side, we can just ignore this * rule and save the others. Loud debug message is in logs. */ continue; } else if (ret != EOK) { goto done; } } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not cancel transaction\n"); } } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to store sudo rules [%d]: %s\n", ret, sss_strerror(ret)); } return ret; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_ssh.h0000644000000000000000000000007312703456111015652 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.515793157 sssd-1.13.4/src/db/sysdb_ssh.h0000644002412700241270000000503012703456111017320 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SYSDB_SSH_H_ #define _SYSDB_SSH_H_ #include "db/sysdb.h" #define SSH_HOSTS_SUBDIR "ssh_hosts" #define SYSDB_SSH_HOST_OC "sshHost" #define SYSDB_SSH_KNOWN_HOSTS_EXPIRE "sshKnownHostsExpire" errno_t sysdb_store_ssh_host(struct sss_domain_info *domain, const char *name, const char *alias, int cache_timeout, time_t now, struct sysdb_attrs *attrs); errno_t sysdb_update_ssh_known_host_expire(struct sss_domain_info *domain, const char *name, time_t now, int known_hosts_timeout); int sysdb_set_ssh_host_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op); errno_t sysdb_delete_ssh_host(struct sss_domain_info *domain, const char *name); errno_t sysdb_search_ssh_hosts(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *filter, const char **attrs, size_t *num_hosts, struct ldb_message ***hosts); errno_t sysdb_get_ssh_host(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_message **host); errno_t sysdb_get_ssh_known_hosts(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, time_t now, const char **attrs, struct ldb_message ***hosts, size_t *num_hosts); #endif /* _SYSDB_SSH_H_ */ sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_ssh.c0000644000000000000000000000007312703456111015645 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.883794405 sssd-1.13.4/src/db/sysdb_ssh.c0000644002412700241270000002475412703456111017331 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "db/sysdb_ssh.h" #include "db/sysdb_private.h" static struct ldb_dn * sysdb_ssh_host_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name) { return sysdb_custom_dn(mem_ctx, domain, name, SSH_HOSTS_SUBDIR); } static errno_t sysdb_update_ssh_host(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs) { errno_t ret; ret = sysdb_store_custom(domain, name, SSH_HOSTS_SUBDIR, attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error storing host %s [%d]: %s\n", name, ret, strerror(ret)); return ret; } return EOK; } errno_t sysdb_store_ssh_host(struct sss_domain_info *domain, const char *name, const char *alias, int cache_timeout, time_t now, struct sysdb_attrs *attrs) { TALLOC_CTX *tmp_ctx; errno_t ret, sret; bool in_transaction = false; const char *search_attrs[] = { SYSDB_NAME_ALIAS, NULL }; bool new_alias; struct ldb_message *host = NULL; struct ldb_message_element *el; unsigned int i; DEBUG(SSSDBG_TRACE_FUNC, "Storing host %s\n", name); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; ret = sysdb_get_ssh_host(tmp_ctx, domain, name, search_attrs, &host); if (ret != EOK && ret != ENOENT) { goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, SYSDB_SSH_HOST_OC); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set object class [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set name attribute [%d]: %s\n", ret, strerror(ret)); goto done; } if (alias) { new_alias = true; /* copy aliases from the existing entry */ if (host) { el = ldb_msg_find_element(host, SYSDB_NAME_ALIAS); if (el) { for (i = 0; i < el->num_values; i++) { if (strcmp((char *)el->values[i].data, alias) == 0) { new_alias = false; } ret = sysdb_attrs_add_val(attrs, SYSDB_NAME_ALIAS, &el->values[i]); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not add name alias %s [%d]: %s\n", el->values[i].data, ret, strerror(ret)); goto done; } } } } /* add alias only if it is not already present */ if (new_alias) { ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, alias); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not add name alias %s [%d]: %s\n", alias, ret, strerror(ret)); goto done; } } } /* make sure sshPublicKey is present when modifying an existing host */ if (host) { ret = sysdb_attrs_get_el(attrs, SYSDB_SSH_PUBKEY, &el); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not get sysdb sshPublicKey [%d]: %s\n", ret, strerror(ret)); goto done; } } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set sysdb lastUpdate [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, cache_timeout ? (now + cache_timeout) : 0); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set sysdb cache expire [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_update_ssh_host(domain, name, attrs); if (ret != EOK) { goto done; } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } errno_t sysdb_set_ssh_host_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op) { errno_t ret; struct ldb_dn *dn; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } dn = sysdb_ssh_host_dn(tmp_ctx, domain, name); if (!dn) { ret = ENOMEM; goto done; } ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, mod_op); done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_update_ssh_known_host_expire(struct sss_domain_info *domain, const char *name, time_t now, int known_hosts_timeout) { TALLOC_CTX *tmp_ctx; errno_t ret; struct sysdb_attrs *attrs; DEBUG(SSSDBG_TRACE_FUNC, "Updating known_hosts expire time of host %s\n", name); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_SSH_KNOWN_HOSTS_EXPIRE, now + known_hosts_timeout); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set known_hosts expire time [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_update_ssh_host(domain, name, attrs); if (ret != EOK) { goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_delete_ssh_host(struct sss_domain_info *domain, const char *name) { DEBUG(SSSDBG_TRACE_FUNC, "Deleting host %s\n", name); return sysdb_delete_custom(domain, name, SSH_HOSTS_SUBDIR); } errno_t sysdb_search_ssh_hosts(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *filter, const char **attrs, size_t *num_hosts, struct ldb_message ***hosts) { errno_t ret; TALLOC_CTX *tmp_ctx; struct ldb_message **results; size_t num_results; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = sysdb_search_custom(tmp_ctx, domain, filter, SSH_HOSTS_SUBDIR, attrs, &num_results, &results); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up host [%d]: %s\n", ret, strerror(ret)); goto done; } if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No such host\n"); *hosts = NULL; *num_hosts = 0; goto done; } *hosts = talloc_steal(mem_ctx, results); *num_hosts = num_results; ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_get_ssh_host(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **attrs, struct ldb_message **host) { TALLOC_CTX *tmp_ctx; errno_t ret; const char *filter; struct ldb_message **hosts; size_t num_hosts; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_NAME, name); if (!filter) { ret = ENOMEM; goto done; } ret = sysdb_search_ssh_hosts(tmp_ctx, domain, filter, attrs, &num_hosts, &hosts); if (ret != EOK) { goto done; } if (num_hosts > 1) { ret = EINVAL; DEBUG(SSSDBG_CRIT_FAILURE, "Found more than one host with name %s\n", name); goto done; } *host = talloc_steal(mem_ctx, hosts[0]); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_get_ssh_known_hosts(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, time_t now, const char **attrs, struct ldb_message ***hosts, size_t *num_hosts) { TALLOC_CTX *tmp_ctx; errno_t ret; const char *filter; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } filter = talloc_asprintf(tmp_ctx, "(&(|(!(%s=*))(%s=0)(%s>=%lld))(%s>=%lld))", SYSDB_CACHE_EXPIRE, SYSDB_CACHE_EXPIRE, SYSDB_CACHE_EXPIRE, (long long)now + 1, SYSDB_SSH_KNOWN_HOSTS_EXPIRE, (long long)now + 1); if (!filter) { ret = ENOMEM; goto done; } ret = sysdb_search_ssh_hosts(mem_ctx, domain, filter, attrs, num_hosts, hosts); done: talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_autofs.c0000644000000000000000000000007312703456111016351 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.835794242 sssd-1.13.4/src/db/sysdb_autofs.c0000644002412700241270000003367112703456111020033 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "db/sysdb.h" #include "db/sysdb_private.h" #include "db/sysdb_autofs.h" #define SYSDB_TMPL_AUTOFS_ENTRY SYSDB_NAME"=%s,"SYSDB_TMPL_CUSTOM static struct ldb_dn * sysdb_autofsmap_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *map_name) { return sysdb_custom_dn(mem_ctx, domain, map_name, AUTOFS_MAP_SUBDIR); } static struct ldb_dn * sysdb_autofsentry_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *map_name, const char *entry_name, const char *entry_value) { errno_t ret; TALLOC_CTX *tmp_ctx; char *clean_name; char *clean_value; const char *rdn; struct ldb_dn *dn = NULL; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return NULL; } ret = sysdb_dn_sanitize(tmp_ctx, entry_name, &clean_name); if (ret != EOK) { goto done; } ret = sysdb_dn_sanitize(tmp_ctx, entry_value, &clean_value); if (ret != EOK) { goto done; } rdn = talloc_asprintf(tmp_ctx, "%s%s", clean_name, clean_value); if (!rdn) { goto done; } dn = ldb_dn_new_fmt(mem_ctx, domain->sysdb->ldb, SYSDB_TMPL_AUTOFS_ENTRY, rdn, map_name, AUTOFS_MAP_SUBDIR, domain->name); done: talloc_free(tmp_ctx); return dn; } char * sysdb_autofsentry_strdn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *map_name, const char *entry_name, const char *entry_value) { struct ldb_dn *dn; char *strdn; dn = sysdb_autofsentry_dn(mem_ctx, domain, map_name, entry_name, entry_value); if (!dn) return NULL; strdn = talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn)); talloc_free(dn); return strdn; } errno_t sysdb_save_autofsmap(struct sss_domain_info *domain, const char *name, const char *autofsmapname, struct sysdb_attrs *attrs, int cache_timeout, time_t now) { errno_t ret; TALLOC_CTX *tmp_ctx; DEBUG(SSSDBG_TRACE_FUNC, "Adding autofs map %s\n", autofsmapname); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (!attrs) { attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } } ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, SYSDB_AUTOFS_MAP_OC); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set map object class [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_MAP_NAME, autofsmapname); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set map name [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set name attribute [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not set sysdb lastUpdate [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, ((cache_timeout) ? (now + cache_timeout) : 0)); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Could not set sysdb cache expire [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_store_custom(domain, name, AUTOFS_MAP_SUBDIR, attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_custom failed [%d]: %s\n", ret, strerror(ret)); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_delete_autofsmap(struct sss_domain_info *domain, const char *name) { DEBUG(SSSDBG_TRACE_FUNC, "Deleting autofs map %s\n", name); return sysdb_delete_custom(domain, name, AUTOFS_MAP_SUBDIR); } errno_t sysdb_get_map_byname(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *map_name, struct ldb_message **_map) { errno_t ret; TALLOC_CTX *tmp_ctx; const char *filter; char *safe_map_name; size_t count; struct ldb_message **msgs; const char *attrs[] = { SYSDB_OBJECTCLASS, SYSDB_CACHE_EXPIRE, SYSDB_LAST_UPDATE, SYSDB_AUTOFS_MAP_NAME, SYSDB_MEMBER, NULL }; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; ret = sss_filter_sanitize(tmp_ctx, map_name, &safe_map_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot sanitize map [%s] error [%d]: %s\n", map_name, ret, strerror(ret)); goto done; } filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)(%s=%s))", SYSDB_AUTOFS_MAP_OC, SYSDB_NAME, safe_map_name); if (!filter) { ret = ENOMEM; goto done; } ret = sysdb_search_custom(tmp_ctx, domain, filter, AUTOFS_MAP_SUBDIR, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up autofs map [%s]\n", safe_map_name); goto done; } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No such map\n"); *_map = NULL; goto done; } if (count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "More than one map named %s\n", safe_map_name); goto done; } *_map = talloc_steal(mem_ctx, msgs[0]); ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_save_autofsentry(struct sss_domain_info *domain, const char *map, const char *key, const char *value, struct sysdb_attrs *attrs) { errno_t ret; TALLOC_CTX *tmp_ctx; struct ldb_message *msg; struct ldb_dn *dn; const char *name; DEBUG(SSSDBG_TRACE_FUNC, "Adding autofs entry [%s] - [%s]\n", key, value); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (!attrs) { attrs = sysdb_new_attrs(tmp_ctx); if (!attrs) { ret = ENOMEM; goto done; } } ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, SYSDB_AUTOFS_ENTRY_OC); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set entry object class [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_ENTRY_KEY, key); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set entry key [%d]: %s\n", ret, strerror(ret)); goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_AUTOFS_ENTRY_VALUE, value); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set entry key [%d]: %s\n", ret, strerror(ret)); goto done; } name = talloc_asprintf(tmp_ctx, "%s%s", key, value); if (!name) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set name attribute [%d]: %s\n", ret, strerror(ret)); goto done; } dn = sysdb_autofsentry_dn(tmp_ctx, domain, map, key, value); if (!dn) { ret = ENOMEM; goto done; } msg = ldb_msg_new(tmp_ctx); if (!msg) { ret = ENOMEM; goto done; } msg->dn = dn; msg->elements = attrs->a; msg->num_elements = attrs->num; ret = ldb_add(domain->sysdb->ldb, msg); ret = sysdb_error_to_errno(ret); done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_del_autofsentry(struct sss_domain_info *domain, const char *entry_dn) { struct ldb_dn *dn; errno_t ret; dn = ldb_dn_new(NULL, sysdb_ctx_get_ldb(domain->sysdb), entry_dn); if (!dn) { return ENOMEM; } ret = sysdb_delete_entry(domain->sysdb, dn, true); talloc_free(dn); return ret; } errno_t sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *mapname, size_t *_count, struct ldb_message ***_entries) { errno_t ret; TALLOC_CTX *tmp_ctx; char *filter; const char *attrs[] = { SYSDB_AUTOFS_ENTRY_KEY, SYSDB_AUTOFS_ENTRY_VALUE, NULL }; size_t count; struct ldb_message **msgs; struct ldb_dn *mapdn; DEBUG(SSSDBG_TRACE_FUNC, "Getting entries for map %s\n", mapname); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } mapdn = sysdb_autofsmap_dn(tmp_ctx, domain, mapname); if (!mapdn) { ret = ENOMEM; goto done; } filter = talloc_asprintf(tmp_ctx, "(objectclass=%s)", SYSDB_AUTOFS_ENTRY_OC); if (!filter) { ret = ENOMEM; goto done; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, mapdn, LDB_SCOPE_ONELEVEL, filter, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb search failed: %d\n", ret); goto done; } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "No entries for the map\n"); *_count = 0; *_entries = NULL; goto done; } *_count = count; *_entries = talloc_steal(mem_ctx, msgs); ret = EOK; DEBUG(SSSDBG_TRACE_INTERNAL, "found %zu entries for map %s\n", count, mapname); done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_set_autofsmap_attr(struct sss_domain_info *domain, const char *name, struct sysdb_attrs *attrs, int mod_op) { errno_t ret; struct ldb_dn *dn; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } dn = sysdb_autofsmap_dn(tmp_ctx, domain, name); if (!dn) { ret = ENOMEM; goto done; } ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, mod_op); done: talloc_free(tmp_ctx); return ret; } errno_t sysdb_invalidate_autofs_maps(struct sss_domain_info *domain) { errno_t ret; TALLOC_CTX *tmp_ctx; const char *filter; struct sysdb_attrs *sys_attrs = NULL; const char *attrs[] = { SYSDB_OBJECTCLASS, SYSDB_NAME, SYSDB_CACHE_EXPIRE, NULL }; size_t count; struct ldb_message **msgs; const char *name; bool in_transaction = false; int sret; int i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; filter = talloc_asprintf(tmp_ctx, "(&(objectclass=%s)(%s=*))", SYSDB_AUTOFS_MAP_OC, SYSDB_NAME); if (!filter) { ret = ENOMEM; goto done; } ret = sysdb_search_custom(tmp_ctx, domain, filter, AUTOFS_MAP_SUBDIR, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up autofs maps\n"); goto done; } else if (ret == ENOENT) { ret = EOK; goto done; } sys_attrs = sysdb_new_attrs(tmp_ctx); if (!sys_attrs) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_time_t(sys_attrs, SYSDB_CACHE_EXPIRE, 1); if (ret != EOK) { goto done; } ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; for (i = 0; i < count; i++) { name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL); if (!name) { DEBUG(SSSDBG_MINOR_FAILURE, "A map with no name?\n"); continue; } ret = sysdb_set_autofsmap_attr(domain, name, sys_attrs, SYSDB_MOD_REP); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not expire map %s\n", name); continue; } } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not commit transaction\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/db/PaxHeaders.16287/sysdb_sudo.h0000644000000000000000000000007212703456111016026 xustar0029 atime=1460561751.63371557 29 ctime=1460561774.50779313 sssd-1.13.4/src/db/sysdb_sudo.h0000644002412700241270000001331412703456111017501 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SYSDB_SUDO_H_ #define _SYSDB_SUDO_H_ #include "db/sysdb.h" /* subdirs in cn=custom in sysdb. We don't store sudo stuff in sysdb directly * b/c it's not name-service-switch data */ #define SUDORULE_SUBDIR "sudorules" /* attribute of SUDORULE_SUBDIR * should be true if we have downloaded all rules atleast once */ #define SYSDB_SUDO_AT_REFRESHED "refreshed" #define SYSDB_SUDO_AT_LAST_FULL_REFRESH "sudoLastFullRefreshTime" /* sysdb attributes */ #define SYSDB_SUDO_CACHE_OC "sudoRule" #define SYSDB_SUDO_CACHE_AT_CN "cn" #define SYSDB_SUDO_CACHE_AT_USER "sudoUser" #define SYSDB_SUDO_CACHE_AT_HOST "sudoHost" #define SYSDB_SUDO_CACHE_AT_COMMAND "sudoCommand" #define SYSDB_SUDO_CACHE_AT_OPTION "sudoOption" #define SYSDB_SUDO_CACHE_AT_RUNAS "sudoRunAs" #define SYSDB_SUDO_CACHE_AT_RUNASUSER "sudoRunAsUser" #define SYSDB_SUDO_CACHE_AT_RUNASGROUP "sudoRunAsGroup" #define SYSDB_SUDO_CACHE_AT_NOTBEFORE "sudoNotBefore" #define SYSDB_SUDO_CACHE_AT_NOTAFTER "sudoNotAfter" #define SYSDB_SUDO_CACHE_AT_ORDER "sudoOrder" /* sysdb ipa attributes */ #define SYSDB_IPA_SUDORULE_OC "ipasudorule" #define SYSDB_IPA_SUDORULE_ENABLED "ipaEnabledFlag" #define SYSDB_IPA_SUDORULE_OPTION "ipaSudoOpt" #define SYSDB_IPA_SUDORULE_RUNASUSER "ipaSudoRunAs" #define SYSDB_IPA_SUDORULE_RUNASGROUP "ipaSudoRunAsGroup" #define SYSDB_IPA_SUDORULE_ORIGCMD "originalMemberCommand" #define SYSDB_IPA_SUDORULE_ALLOWCMD "memberAllowCmd" #define SYSDB_IPA_SUDORULE_DENYCMD "memberDenyCmd" #define SYSDB_IPA_SUDORULE_HOST "memberHost" #define SYSDB_IPA_SUDORULE_USER "memberUser" #define SYSDB_IPA_SUDORULE_NOTAFTER "sudoNotAfter" #define SYSDB_IPA_SUDORULE_NOTBEFORE "sudoNotBefore" #define SYSDB_IPA_SUDORULE_SUDOORDER "sudoOrder" #define SYSDB_IPA_SUDORULE_CMDCATEGORY "cmdCategory" #define SYSDB_IPA_SUDORULE_HOSTCATEGORY "hostCategory" #define SYSDB_IPA_SUDORULE_USERCATEGORY "userCategory" #define SYSDB_IPA_SUDORULE_RUNASUSERCATEGORY "ipaSudoRunAsUserCategory" #define SYSDB_IPA_SUDORULE_RUNASGROUPCATEGORY "ipaSudoRunAsGroupCategory" #define SYSDB_IPA_SUDORULE_RUNASEXTUSER "ipaSudoRunAsExtUser" #define SYSDB_IPA_SUDORULE_RUNASEXTGROUP "ipaSudoRunAsExtGroup" #define SYSDB_IPA_SUDORULE_RUNASEXTUSERGROUP "ipaSudoRunAsExtUserGroup" #define SYSDB_IPA_SUDORULE_EXTUSER "externalUser" #define SYSDB_IPA_SUDOCMDGROUP_OC "ipasudocmdgrp" #define SYSDB_IPA_SUDOCMD_OC "ipasudocmd" #define SYSDB_IPA_SUDOCMD_SUDOCMD "sudoCmd" /* When constructing a sysdb filter, OR these values to include.. */ #define SYSDB_SUDO_FILTER_NONE 0x00 /* no additional filter */ #define SYSDB_SUDO_FILTER_USERNAME 0x01 /* username */ #define SYSDB_SUDO_FILTER_UID 0x02 /* uid */ #define SYSDB_SUDO_FILTER_GROUPS 0x04 /* groups */ #define SYSDB_SUDO_FILTER_NGRS 0x08 /* netgroups */ #define SYSDB_SUDO_FILTER_ONLY_EXPIRED 0x10 /* only expired */ #define SYSDB_SUDO_FILTER_INCLUDE_ALL 0x20 /* ALL */ #define SYSDB_SUDO_FILTER_INCLUDE_DFL 0x40 /* include cn=default */ #define SYSDB_SUDO_FILTER_USERINFO SYSDB_SUDO_FILTER_USERNAME \ | SYSDB_SUDO_FILTER_UID \ | SYSDB_SUDO_FILTER_GROUPS \ | SYSDB_SUDO_FILTER_NGRS errno_t sysdb_sudo_filter_rules_by_time(TALLOC_CTX *mem_ctx, uint32_t in_num_rules, struct sysdb_attrs **in_rules, time_t now, uint32_t *_num_rules, struct sysdb_attrs ***_rules); errno_t sysdb_get_sudo_filter(TALLOC_CTX *mem_ctx, const char *username, uid_t uid, char **groupnames, unsigned int flags, char **_filter); errno_t sysdb_get_sudo_user_info(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *username, uid_t *_uid, char ***groupnames); errno_t sysdb_sudo_set_last_full_refresh(struct sss_domain_info *domain, time_t value); errno_t sysdb_sudo_get_last_full_refresh(struct sss_domain_info *domain, time_t *value); errno_t sysdb_sudo_purge(struct sss_domain_info *domain, const char *delete_filter, struct sysdb_attrs **rules, size_t num_rules); errno_t sysdb_sudo_store(struct sss_domain_info *domain, struct sysdb_attrs **rules, size_t num_rules); #endif /* _SYSDB_SUDO_H_ */ sssd-1.13.4/src/PaxHeaders.16287/lib0000644000000000000000000000013212703463556013613 xustar0030 mtime=1460561774.275792344 30 atime=1460561776.118798593 30 ctime=1460561774.275792344 sssd-1.13.4/src/lib/0000755002412700241270000000000012703463556015344 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/lib/PaxHeaders.16287/cifs_idmap_sss0000644000000000000000000000013212703463556016601 xustar0030 mtime=1460561774.652793622 30 atime=1460561776.118798593 30 ctime=1460561774.652793622 sssd-1.13.4/src/lib/cifs_idmap_sss/0000755002412700241270000000000012703463556020332 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/lib/cifs_idmap_sss/PaxHeaders.16287/cifs_idmap_sss.c0000644000000000000000000000007412703456111022002 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.652793622 sssd-1.13.4/src/lib/cifs_idmap_sss/cifs_idmap_sss.c0000644002412700241270000001723512703456111023461 0ustar00jhrozekjhrozek00000000000000/* Authors: Benjamin Franzke Copyright (C) 2013 Benjamin Franzke This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* TODO: Support of [all] samba's Unix SIDs: * Users: S-1-22-1-%UID * Groups: S-1-22-2-%GID */ #include #include #include #include #include #include #include #include "lib/idmap/sss_idmap.h" #include "sss_client/idmap/sss_nss_idmap.h" #ifdef DEBUG #include #define debug(str, ...) \ syslog(0, "%s: " str "\n", \ __FUNCTION__, ##__VA_ARGS__) #else #define debug(...) do { } while(0) #endif struct sssd_ctx { struct sss_idmap_ctx *idmap; const char **errmsg; }; #define ctx_set_error(ctx, error) \ do { \ *ctx->errmsg = error; \ debug("%s", error ? error : ""); \ } while (0); int cifs_idmap_init_plugin(void **handle, const char **errmsg) { struct sssd_ctx *ctx; enum idmap_error_code err; if (handle == NULL || errmsg == NULL) return EINVAL; ctx = malloc(sizeof *ctx); if (!ctx) { *errmsg = "Failed to allocate context"; return -1; } ctx->errmsg = errmsg; ctx_set_error(ctx, NULL); err = sss_idmap_init(NULL, NULL, NULL, &ctx->idmap); if (err != IDMAP_SUCCESS) { ctx_set_error(ctx, idmap_error_string(err)); free(ctx); return -1; } *handle = ctx; return 0; } void cifs_idmap_exit_plugin(void *handle) { struct sssd_ctx *ctx = handle; debug("exit"); if (ctx == NULL) return; sss_idmap_free(ctx->idmap); free(ctx); } /* Test with `getcifsacl file` on client. */ int cifs_idmap_sid_to_str(void *handle, const struct cifs_sid *csid, char **name) { struct sssd_ctx *ctx = handle; enum idmap_error_code iderr; char *sid; enum sss_id_type id_type; int err; iderr = sss_idmap_bin_sid_to_sid(ctx->idmap, (const uint8_t *) csid, sizeof(*csid), &sid); if (iderr != IDMAP_SUCCESS) { ctx_set_error(ctx, idmap_error_string(iderr)); *name = NULL; return -1; } debug("sid: %s", sid); err = sss_nss_getnamebysid(sid, name, &id_type); if (err != 0) { ctx_set_error(ctx, strerror(err)); *name = NULL; return -err; } /* FIXME: Map Samba Unix SIDs? (sid->id and use getpwuid)? */ debug("name: %s", *name); return 0; } static int sid_to_cifs_sid(struct sssd_ctx *ctx, const char *sid, struct cifs_sid *csid) { uint8_t *bsid = NULL; enum idmap_error_code err; size_t length; err = sss_idmap_sid_to_bin_sid(ctx->idmap, sid, &bsid, &length); if (err != IDMAP_SUCCESS) { ctx_set_error(ctx, idmap_error_string(err)); return -1; } if (length > sizeof(struct cifs_sid)) { ctx_set_error(ctx, "too large sid length"); free(bsid); return -1; } memcpy(csid, bsid, length); sss_idmap_free_bin_sid(ctx->idmap, bsid); return 0; } /* Test with setcifsacl -a */ int cifs_idmap_str_to_sid(void *handle, const char *name, struct cifs_sid *csid) { struct sssd_ctx *ctx = handle; int err; enum sss_id_type id_type; char *sid = NULL; int success = 0; debug("%s", name); err = sss_nss_getsidbyname(name, &sid, &id_type); if (err != 0) { /* Might be a raw string representation of SID, * try converting that before returning an error. */ if (sid_to_cifs_sid(ctx, name, csid) == 0) return 0; ctx_set_error(ctx, strerror(err)); return -err; } if (sid_to_cifs_sid(ctx, sid, csid) != 0) success = -1; free(sid); return success; } static int samba_unix_sid_to_id(const char *sid, struct cifs_uxid *cuxid) { id_t id; uint8_t type; if (sscanf(sid, "S-1-22-%hhu-%u", &type, &id) != 2) return -1; switch (type) { case 1: cuxid->type = CIFS_UXID_TYPE_UID; cuxid->id.uid = id; break; case 2: cuxid->type = CIFS_UXID_TYPE_GID; cuxid->id.gid = id; break; default: cuxid->type = CIFS_UXID_TYPE_UNKNOWN; return -1; } return 0; } static int sss_sid_to_id(struct sssd_ctx *ctx, const char *sid, struct cifs_uxid *cuxid) { int err; enum sss_id_type id_type; err = sss_nss_getidbysid(sid, (uint32_t *)&cuxid->id.uid, &id_type); if (err != 0) { ctx_set_error(ctx, strerror(err)); return -1; } switch (id_type) { case SSS_ID_TYPE_UID: cuxid->type = CIFS_UXID_TYPE_UID; break; case SSS_ID_TYPE_GID: cuxid->type = CIFS_UXID_TYPE_GID; break; case SSS_ID_TYPE_BOTH: cuxid->type = CIFS_UXID_TYPE_BOTH; break; case SSS_ID_TYPE_NOT_SPECIFIED: default: return -1; } return 0; } /** * cifs_idmap_sids_to_ids - convert struct cifs_sids to struct cifs_uxids * usecase: mount.cifs -o sec=krb5,multiuser,cifsacl,nounix * test: ls -n on mounted share */ int cifs_idmap_sids_to_ids(void *handle, const struct cifs_sid *csid, const size_t num, struct cifs_uxid *cuxid) { struct sssd_ctx *ctx = handle; enum idmap_error_code err; int success = -1; size_t i; char *sid; debug("num: %zd", num); if (num > UINT_MAX) { ctx_set_error(ctx, "num is too large."); return EINVAL; } for (i = 0; i < num; ++i) { err = sss_idmap_bin_sid_to_sid(ctx->idmap, (const uint8_t *) &csid[i], sizeof(csid[i]), &sid); if (err != IDMAP_SUCCESS) { ctx_set_error(ctx, idmap_error_string(err)); continue; } cuxid[i].type = CIFS_UXID_TYPE_UNKNOWN; if (sss_sid_to_id(ctx, sid, &cuxid[i]) == 0 || samba_unix_sid_to_id(sid, &cuxid[i]) == 0) { debug("setting uid of %s to %d", sid, cuxid[i].id.uid); success = 0; } free(sid); } return success; } int cifs_idmap_ids_to_sids(void *handle, const struct cifs_uxid *cuxid, const size_t num, struct cifs_sid *csid) { struct sssd_ctx *ctx = handle; int err, success = -1; char *sid; enum sss_id_type id_type; size_t i; debug("num ids: %zd", num); if (num > UINT_MAX) { ctx_set_error(ctx, "num is too large."); return EINVAL; } for (i = 0; i < num; ++i) { err = sss_nss_getsidbyid((uint32_t)cuxid[i].id.uid, &sid, &id_type); if (err != 0) { ctx_set_error(ctx, strerror(err)); csid[i].revision = 0; /* FIXME: would it be safe to map *any* uid/gids unknown by sssd to * SAMBA's UNIX SIDs? */ continue; } if (sid_to_cifs_sid(ctx, sid, csid) == 0) success = 0; else csid[i].revision = 0; free(sid); } return success; } sssd-1.13.4/src/lib/PaxHeaders.16287/idmap0000644000000000000000000000013212703463556014705 xustar0030 mtime=1460561774.721793856 30 atime=1460561776.118798593 30 ctime=1460561774.721793856 sssd-1.13.4/src/lib/idmap/0000755002412700241270000000000012703463556016436 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/lib/idmap/PaxHeaders.16287/sss_idmap.h0000644000000000000000000000007412703456111017107 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.604793459 sssd-1.13.4/src/lib/idmap/sss_idmap.h0000644002412700241270000011064412703456111020564 0ustar00jhrozekjhrozek00000000000000/* SSSD ID-mapping library Authors: Sumit Bose Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_IDMAP_H_ #define SSS_IDMAP_H_ #include #include #include #include #define DOM_SID_PREFIX "S-1-5-21-" #define DOM_SID_PREFIX_LEN (sizeof(DOM_SID_PREFIX) - 1) /** * @defgroup sss_idmap Map Unix UIDs and GIDs to SIDs and back * Libsss_idmap provides a mechanism to translate a SID to a UNIX UID or GID * or the other way round. * @{ */ /** * Error codes used by libsss_idmap */ enum idmap_error_code { /** Success */ IDMAP_SUCCESS = 0, /** Function is not yet implemented */ IDMAP_NOT_IMPLEMENTED, /** General error */ IDMAP_ERROR, /** Ran out of memory during processing */ IDMAP_OUT_OF_MEMORY, /** No domain added */ IDMAP_NO_DOMAIN, /** The provided idmap context is invalid */ IDMAP_CONTEXT_INVALID, /** The provided SID is invalid */ IDMAP_SID_INVALID, /** The provided SID was not found */ IDMAP_SID_UNKNOWN, /** The provided UID or GID could not be mapped */ IDMAP_NO_RANGE, /** The provided SID is a built-in one */ IDMAP_BUILTIN_SID, /** No more free slices */ IDMAP_OUT_OF_SLICES, /** New domain collides with existing one */ IDMAP_COLLISION, /** External source should be consulted for idmapping */ IDMAP_EXTERNAL, /** The provided name was not found */ IDMAP_NAME_UNKNOWN }; /** * Typedef for memory allocation functions */ typedef void *(idmap_alloc_func)(size_t size, void *pvt); typedef void (idmap_free_func)(void *ptr, void *pvt); /** * Typedef for storing mappings of dynamically created domains */ typedef enum idmap_error_code (*idmap_store_cb)(const char *dom_name, const char *dom_sid, const char *range_id, uint32_t min_id, uint32_t max_id, uint32_t first_rid, void *pvt); /** * Structure for id ranges * FIXME: this struct might change when it is clear how ranges are handled on * the server side */ struct sss_idmap_range { uint32_t min; uint32_t max; }; /** * Opaque type for SIDs */ struct sss_dom_sid; /** * Opaque type for the idmap context */ struct sss_idmap_ctx; /** * Placeholder for Samba's struct dom_sid. Consumers of libsss_idmap should * include an appropriate Samba header file to define struct dom_sid. We use * it here to avoid a hard dependency on Samba devel packages. */ struct dom_sid; /** * @brief Initialize idmap context * * @param[in] alloc_func Function to allocate memory for the context, if * NULL malloc() id used * @param[in] alloc_pvt Private data for allocation routine * @param[in] free_func Function to free the memory the context, if * NULL free() id used * @param[out] ctx idmap context * * @return * - #IDMAP_OUT_OF_MEMORY: Insufficient memory to create the context */ enum idmap_error_code sss_idmap_init(idmap_alloc_func *alloc_func, void *alloc_pvt, idmap_free_func *free_func, struct sss_idmap_ctx **ctx); /** * @brief Set/unset autorid compatibility mode * * @param[in] ctx idmap context * @param[in] use_autorid If true, autorid compatibility mode will be used */ enum idmap_error_code sss_idmap_ctx_set_autorid(struct sss_idmap_ctx *ctx, bool use_autorid); /** * @brief Set the lower bound of the range of POSIX IDs * * @param[in] ctx idmap context * @param[in] lower lower bound of the range */ enum idmap_error_code sss_idmap_ctx_set_lower(struct sss_idmap_ctx *ctx, id_t lower); /** * @brief Set the upper bound of the range of POSIX IDs * * @param[in] ctx idmap context * @param[in] upper upper bound of the range */ enum idmap_error_code sss_idmap_ctx_set_upper(struct sss_idmap_ctx *ctx, id_t upper); /** * @brief Set the range size of POSIX IDs available for single domain * * @param[in] ctx idmap context * @param[in] rangesize range size of IDs */ enum idmap_error_code sss_idmap_ctx_set_rangesize(struct sss_idmap_ctx *ctx, id_t rangesize); /** * @brief Set the number of secondary slices available for domain * * @param[in] ctx idmap context * @param[in] extra_slice_init number of secondary slices to be generated * at startup */ enum idmap_error_code sss_idmap_ctx_set_extra_slice_init(struct sss_idmap_ctx *ctx, int extra_slice_init); /** * @brief Check if autorid compatibility mode is set * * @param[in] ctx idmap context * @param[out] _autorid true if autorid is used */ enum idmap_error_code sss_idmap_ctx_get_autorid(struct sss_idmap_ctx *ctx, bool *_autorid); /** * @brief Get the lower bound of the range of POSIX IDs * * @param[in] ctx idmap context * @param[out] _lower returned lower bound */ enum idmap_error_code sss_idmap_ctx_get_lower(struct sss_idmap_ctx *ctx, id_t *_lower); /** * @brief Get the upper bound of the range of POSIX IDs * * @param[in] ctx idmap context * @param[out] _upper returned upper bound */ enum idmap_error_code sss_idmap_ctx_get_upper(struct sss_idmap_ctx *ctx, id_t *_upper); /** * @brief Get the range size of POSIX IDs available for single domain * * @param[in] ctx idmap context * @param[out] rangesize returned range size */ enum idmap_error_code sss_idmap_ctx_get_rangesize(struct sss_idmap_ctx *ctx, id_t *rangesize); /** * @brief Calculate new range of available POSIX IDs * * @param[in] ctx Idmap context * @param[in] dom_sid Zero-terminated string representation of the domain * SID (S-1-15-.....) * @param[in,out] slice_num Slice number to be used. Set this pointer to NULL or * the addressed value to -1 to calculate slice number * automatically. The calculated value will be * returned in this parameter. * @param[out] range Structure containing upper and lower bound of the * range of POSIX IDs * * @return * - #IDMAP_OUT_OF_SLICES: Cannot calculate new range because all slices are * used. */ enum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx, const char *dom_sid, id_t *slice_num, struct sss_idmap_range *range); /** * @brief Add a domain to the idmap context * * @param[in] ctx Idmap context * @param[in] domain_name Zero-terminated string with the domain name * @param[in] domain_sid Zero-terminated string representation of the domain * SID (S-1-15-.....) * @param[in] range TBD Some information about the id ranges of this * domain * * @return * - #IDMAP_OUT_OF_MEMORY: Insufficient memory to store the data in the idmap * context * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_NO_DOMAIN: No domain domain name given * - #IDMAP_COLLISION: New domain collides with existing one */ enum idmap_error_code sss_idmap_add_domain(struct sss_idmap_ctx *ctx, const char *domain_name, const char *domain_sid, struct sss_idmap_range *range); /** * @brief Add a domain with the first mappable RID to the idmap context * * @param[in] ctx Idmap context * @param[in] domain_name Zero-terminated string with the domain name * @param[in] domain_sid Zero-terminated string representation of the domain * SID (S-1-15-.....) * @param[in] range TBD Some information about the id ranges of this * domain * @param[in] range_id optional unique identifier of a range, it is needed * to allow updates at runtime * @param[in] rid The RID that should be mapped to the first ID of the * given range. * @param[in] external_mapping If set to true the ID will not be mapped * algorithmically, but the *_to_unix and *_unix_to_* * calls will return IDMAP_EXTERNAL to instruct the * caller to check external sources. For a single * domain all ranges must be of the same type. It is * not possible to mix algorithmic and external * mapping. * * @return * - #IDMAP_OUT_OF_MEMORY: Insufficient memory to store the data in the idmap * context * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_NO_DOMAIN: No domain domain name given * - #IDMAP_COLLISION: New domain collides with existing one */ enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx, const char *domain_name, const char *domain_sid, struct sss_idmap_range *range, const char *range_id, uint32_t rid, bool external_mapping); /** * @brief Add a domain with the first mappable RID to the idmap context and * generate automatically secondary slices * * @param[in] ctx Idmap context * @param[in] domain_name Zero-terminated string with the domain name * @param[in] domain_sid Zero-terminated string representation of the domain * SID (S-1-15-.....) * @param[in] range TBD Some information about the id ranges of this * domain * @param[in] range_id optional unique identifier of a range, it is needed * to allow updates at runtime * @param[in] rid The RID that should be mapped to the first ID of the * given range. * @param[in] external_mapping If set to true the ID will not be mapped * algorithmically, but the *_to_unix and *_unix_to_* * calls will return IDMAP_EXTERNAL to instruct the * caller to check external sources. For a single * domain all ranges must be of the same type. It is * not possible to mix algorithmic and external * mapping. * @param[in] s_cv The callback for storing mapping of dynamically * created domains. * @param[in] pvt Private data for callback cb. * * @return * - #IDMAP_OUT_OF_MEMORY: Insufficient memory to store the data in the idmap * context * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_NO_DOMAIN: No domain domain name given * - #IDMAP_COLLISION: New domain collides with existing one */ enum idmap_error_code sss_idmap_add_auto_domain_ex(struct sss_idmap_ctx *ctx, const char *domain_name, const char *domain_sid, struct sss_idmap_range *range, const char *range_id, uint32_t rid, bool external_mapping, idmap_store_cb cb, void *pvt); /** * @brief Check if a new range would collide with any existing one * * @param[in] ctx Idmap context * @param[in] n_name Zero-terminated string with the domain name the new * range should belong to * @param[in] n_sid Zero-terminated string representation of the domain * SID (S-1-15-.....) the new range sould belong to * @param[in] n_range The new id range * @param[in] n_range_id unique identifier of the new range, it is needed * to allow updates at runtime, may be NULL * @param[in] n_first_rid The RID that should be mapped to the first ID of the * new range. * @param[in] n_external_mapping Mapping type of the new range * * @return * - #IDMAP_COLLISION: New range collides with existing one */ enum idmap_error_code sss_idmap_check_collision(struct sss_idmap_ctx *ctx, char *n_name, char *n_sid, struct sss_idmap_range *n_range, uint32_t n_first_rid, char *n_range_id, bool n_external_mapping); /** * @brief Check if two ranges would collide * * @param[in] o_name Zero-terminated string with the domain name the * first range should belong to * @param[in] o_sid Zero-terminated string representation of the domain * SID (S-1-15-.....) the first range sould belong to * @param[in] o_range The first id range * @param[in] o_range_id unique identifier of the first range, it is needed * to allow updates at runtime, may be NULL * @param[in] o_first_rid The RID that should be mapped to the first ID of the * first range. * @param[in] o_external_mapping Mapping type of the first range * @param[in] n_name Zero-terminated string with the domain name the * second range should belong to * @param[in] n_sid Zero-terminated string representation of the domain * SID (S-1-15-.....) the second range sould belong to * @param[in] n_range The second id range * @param[in] n_range_id unique identifier of the second range, it is needed * to allow updates at runtime, may be NULL * @param[in] n_first_rid The RID that should be mapped to the first ID of the * second range. * @param[in] n_external_mapping Mapping type of the second range * * @return * - #IDMAP_COLLISION: New range collides with existing one */ enum idmap_error_code sss_idmap_check_collision_ex(const char *o_name, const char *o_sid, struct sss_idmap_range *o_range, uint32_t o_first_rid, const char *o_range_id, bool o_external_mapping, const char *n_name, const char *n_sid, struct sss_idmap_range *n_range, uint32_t n_first_rid, const char *n_range_id, bool n_external_mapping); /** * @brief Translate SID to a unix UID or GID * * @param[in] ctx Idmap context * @param[in] sid Zero-terminated string representation of the SID * @param[out] id Returned unix UID or GID * * @return * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx, const char *sid, uint32_t *id); /** * @brief Translate a SID stucture to a unix UID or GID * * @param[in] ctx Idmap context * @param[in] dom_sid SID structure * @param[out] id Returned unix UID or GID * * @return * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_dom_sid_to_unix(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid, uint32_t *id); /** * @brief Translate a binary SID to a unix UID or GID * * @param[in] ctx Idmap context * @param[in] bin_sid Array with the binary SID * @param[in] length Size of the array containing the binary SID * @param[out] id Returned unix UID or GID * * @return * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_bin_sid_to_unix(struct sss_idmap_ctx *ctx, uint8_t *bin_sid, size_t length, uint32_t *id); /** * @brief Translate a Samba dom_sid stucture to a unix UID or GID * * @param[in] ctx Idmap context * @param[in] smb_sid Samba dom_sid structure * @param[out] id Returned unix UID or GID * * @return * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_smb_sid_to_unix(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid, uint32_t *id); /** * @brief Check if a SID and a unix UID or GID belong to the same range * * @param[in] ctx Idmap context * @param[in] sid Zero-terminated string representation of the SID * @param[in] id Unix UID or GID * * @return * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context * - #IDMAP_NO_RANGE No matching ID range found */ enum idmap_error_code sss_idmap_check_sid_unix(struct sss_idmap_ctx *ctx, const char *sid, uint32_t id); /** * @brief Check if a SID structure and a unix UID or GID belong to the same range * * @param[in] ctx Idmap context * @param[in] dom_sid SID structure * @param[in] id Unix UID or GID * * @return * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context * - #IDMAP_NO_RANGE No matching ID range found */ enum idmap_error_code sss_idmap_check_dom_sid_unix(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid, uint32_t id); /** * @brief Check if a binary SID and a unix UID or GID belong to the same range * * @param[in] ctx Idmap context * @param[in] bin_sid Array with the binary SID * @param[in] length Size of the array containing the binary SID * @param[in] id Unix UID or GID * * @return * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context * - #IDMAP_NO_RANGE No matching ID range found */ enum idmap_error_code sss_idmap_check_bin_sid_unix(struct sss_idmap_ctx *ctx, uint8_t *bin_sid, size_t length, uint32_t id); /** * @brief Check if a Samba dom_sid structure and a unix UID or GID belong to * the same range * * @param[in] ctx Idmap context * @param[in] smb_sid Samba dom_sid structure * @param[in] id Unix UID or GID * * @return * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_SID_INVALID: Invalid SID provided * - #IDMAP_SID_UNKNOWN: SID cannot be found in the domains added to the * idmap context * - #IDMAP_NO_RANGE No matching ID range found */ enum idmap_error_code sss_idmap_check_smb_sid_unix(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid, uint32_t id); /** * @brief Translate unix UID or GID to a SID * * @param[in] ctx Idmap context * @param[in] id unix UID or GID * @param[out] sid Zero-terminated string representation of the SID, must be * freed if not needed anymore * * @return * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_NO_RANGE: The provided ID cannot be found in the domains added * to the idmap context * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx, uint32_t id, char **sid); /** * @brief Translate unix UID or GID to a SID structure * * @param[in] ctx Idmap context * @param[in] id unix UID or GID * @param[out] dom_sid SID structure, must be freed if not needed anymore * * @return * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_NO_RANGE: The provided ID cannot be found in the domains added * to the idmap context * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_unix_to_dom_sid(struct sss_idmap_ctx *ctx, uint32_t id, struct sss_dom_sid **dom_sid); /** * @brief Translate unix UID or GID to a binary SID * * @param[in] ctx Idmap context * @param[in] id unix UID or GID * @param[out] bin_sid Array with the binary SID, * must be freed if not needed anymore * @param[out] length size of the array containing the binary SID * * @return * - #IDMAP_NO_DOMAIN: No domains are added to the idmap context * - #IDMAP_NO_RANGE: The provided ID cannot be found in the domains added * to the idmap context * - #IDMAP_EXTERNAL: external source is authoritative for mapping */ enum idmap_error_code sss_idmap_unix_to_bin_sid(struct sss_idmap_ctx *ctx, uint32_t id, uint8_t **bin_sid, size_t *length); /** * @brief Free all the allocated memory of the idmap context * * @param[in] ctx Idmap context * * @return * - #IDMAP_CONTEXT_INVALID: Provided context is invalid */ enum idmap_error_code sss_idmap_free(struct sss_idmap_ctx *ctx); /** * @brief Free mapped SID. * * @param[in] ctx Idmap context * @param[in] sid SID to be freed. * * @return * - #IDMAP_CONTEXT_INVALID: Provided context is invalid */ enum idmap_error_code sss_idmap_free_sid(struct sss_idmap_ctx *ctx, char *sid); /** * @brief Free mapped domain SID. * * @param[in] ctx Idmap context * @param[in] dom_sid Domain SID to be freed. * * @return * - #IDMAP_CONTEXT_INVALID: Provided context is invalid */ enum idmap_error_code sss_idmap_free_dom_sid(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid); /** * @brief Free mapped Samba SID. * * @param[in] ctx Idmap context * @param[in] smb_sid Samba SID to be freed. * * @return * - #IDMAP_CONTEXT_INVALID: Provided context is invalid */ enum idmap_error_code sss_idmap_free_smb_sid(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid); /** * @brief Free mapped binary SID. * * @param[in] ctx Idmap context * @param[in] bin_sid Binary SID to be freed. * * @return * - #IDMAP_CONTEXT_INVALID: Provided context is invalid */ enum idmap_error_code sss_idmap_free_bin_sid(struct sss_idmap_ctx *ctx, uint8_t *bin_sid); /** * @brief Translate error code to a string * * @param[in] err Idmap error code * * @return * - Error description as a zero-terminated string */ const char *idmap_error_string(enum idmap_error_code err); /** * @brief Check if given string can be used as domain SID * * @param[in] str String to check * * @return * - true: String can be used as domain SID * - false: String can not be used as domain SID */ bool is_domain_sid(const char *str); /** * @brief Check if a domain is configured with algorithmic mapping * * @param[in] ctx Idmap context * @param[in] dom_sid SID string, can be either a domain SID * or an object SID * @param[out] has_algorithmic_mapping Boolean value indicating if the given * domain is configured for algorithmic * mapping or not. * * @return * - #IDMAP_SUCCESS: Domain for the given SID was found and * has_algorithmic_mapping is set accordingly * - #IDMAP_SID_INVALID: Provided SID is invalid * - #IDMAP_CONTEXT_INVALID: Provided idmap context is invalid * - #IDMAP_NO_DOMAIN: No domains are available in the idmap context * - #IDMAP_SID_UNKNOWN: No domain with the given SID was found in the * idmap context */ enum idmap_error_code sss_idmap_domain_has_algorithmic_mapping(struct sss_idmap_ctx *ctx, const char *dom_sid, bool *has_algorithmic_mapping); /** * @brief Check if a domain is configured with algorithmic mapping * * @param[in] ctx Idmap context * @param[in] dom_name Name of the domain * @param[out] has_algorithmic_mapping Boolean value indicating if the given * domain is configured for algorithmic * mapping or not. * * @return * - #IDMAP_SUCCESS: Domain for the given name was found and * has_algorithmic_mapping is set accordingly * - #IDMAP_ERROR: Provided name is invalid * - #IDMAP_CONTEXT_INVALID: Provided idmap context is invalid * - #IDMAP_NO_DOMAIN: No domains are available in the idmap context * - #IDMAP_NAME_UNKNOWN: No domain with the given name was found in the * idmap context */ enum idmap_error_code sss_idmap_domain_by_name_has_algorithmic_mapping(struct sss_idmap_ctx *ctx, const char *dom_name, bool *has_algorithmic_mapping); /** * @brief Convert binary SID to SID structure * * @param[in] ctx Idmap context * @param[in] bin_sid Array with the binary SID * @param[in] length Size of the array containing the binary SID * @param[out] dom_sid SID structure, * must be freed if not needed anymore * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_bin_sid_to_dom_sid(struct sss_idmap_ctx *ctx, const uint8_t *bin_sid, size_t length, struct sss_dom_sid **dom_sid); /** * @brief Convert binary SID to SID string * * @param[in] ctx Idmap context * @param[in] bin_sid Array with the binary SID * @param[in] length Size of the array containing the binary SID * @param[out] sid Zero-terminated string representation of the SID, * must be freed if not needed anymore * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_bin_sid_to_sid(struct sss_idmap_ctx *ctx, const uint8_t *bin_sid, size_t length, char **sid); /** * @brief Convert SID structure to binary SID * * @param[in] ctx Idmap context * @param[in] dom_sid SID structure * @param[out] bin_sid Array with the binary SID, * must be freed if not needed anymore * @param[out] length Size of the array containing the binary SID * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_dom_sid_to_bin_sid(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid, uint8_t **bin_sid, size_t *length); /** * @brief Convert SID string to binary SID * * @param[in] ctx Idmap context * @param[in] sid Zero-terminated string representation of the SID * @param[out] bin_sid Array with the binary SID, * must be freed if not needed anymore * @param[out] length Size of the array containing the binary SID * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_sid_to_bin_sid(struct sss_idmap_ctx *ctx, const char *sid, uint8_t **bin_sid, size_t *length); /** * @brief Convert SID structure to SID string * * @param[in] ctx Idmap context * @param[in] dom_sid SID structure * @param[out] sid Zero-terminated string representation of the SID, * must be freed if not needed anymore * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_dom_sid_to_sid(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid, char **sid); /** * @brief Convert SID string to SID structure * * @param[in] ctx Idmap context * @param[in] sid Zero-terminated string representation of the SID * @param[out] dom_sid SID structure, * must be freed if not needed anymore * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_sid_to_dom_sid(struct sss_idmap_ctx *ctx, const char *sid, struct sss_dom_sid **dom_sid); /** * @brief Convert SID string to Samba dom_sid structure * * @param[in] ctx Idmap context * @param[in] sid Zero-terminated string representation of the SID * @param[out] smb_sid Samba dom_sid structure, * must be freed if not needed anymore * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_sid_to_smb_sid(struct sss_idmap_ctx *ctx, const char *sid, struct dom_sid **smb_sid); /** * @brief Convert Samba dom_sid structure to SID string * * @param[in] ctx Idmap context * @param[in] smb_sid Samba dom_sid structure * @param[out] sid Zero-terminated string representation of the SID, * must be freed if not needed anymore * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_smb_sid_to_sid(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid, char **sid); /** * @brief Convert SID stucture to Samba dom_sid structure * * @param[in] ctx Idmap context * @param[in] dom_sid SID structure * @param[out] smb_sid Samba dom_sid structure, * must be freed if not needed anymore * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_dom_sid_to_smb_sid(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid, struct dom_sid **smb_sid); /** * @brief Convert Samba dom_sid structure to SID structure * * @param[in] ctx Idmap context * @param[in] smb_sid Samba dom_sid structure * @param[out] dom_sid SID structure, * must be freed if not needed anymore * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_smb_sid_to_dom_sid(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid, struct sss_dom_sid **dom_sid); /** * @brief Convert binary SID to Samba dom_sid structure * * @param[in] ctx Idmap context * @param[in] bin_sid Array with the binary SID * @param[in] length Size of the array containing the binary SID * @param[out] smb_sid Samba dom_sid structure, * must be freed if not needed anymore * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_bin_sid_to_smb_sid(struct sss_idmap_ctx *ctx, const uint8_t *bin_sid, size_t length, struct dom_sid **smb_sid); /** * @brief Convert Samba dom_sid structure to binary SID * * @param[in] ctx Idmap context * @param[in] smb_sid Samba dom_sid structure * @param[out] bin_sid Array with the binary SID, * must be freed if not needed anymore * @param[out] length Size of the array containing the binary SID * * @return * - #IDMAP_SID_INVALID: Given SID is invalid * - #IDMAP_OUT_OF_MEMORY: Failed to allocate memory for the result */ enum idmap_error_code sss_idmap_smb_sid_to_bin_sid(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid, uint8_t **bin_sid, size_t *length); /** * @} */ #endif /* SSS_IDMAP_H_ */ sssd-1.13.4/src/lib/idmap/PaxHeaders.16287/sss_idmap.pc.in0000644000000000000000000000007412703456111017667 xustar0030 atime=1460561772.728787098 30 ctime=1460561774.627793537 sssd-1.13.4/src/lib/idmap/sss_idmap.pc.in0000644002412700241270000000036012703456111021335 0ustar00jhrozekjhrozek00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: sss_idmap Description: SSS idmap (SID <-> uid,gid) library Version: @VERSION@ Libs: -L${libdir} -lsss_idmap Cflags: URL: http://fedorahosted.org/sssd/ sssd-1.13.4/src/lib/idmap/PaxHeaders.16287/sss_idmap_conv.c0000644000000000000000000000007412703456111020127 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.721793856 sssd-1.13.4/src/lib/idmap/sss_idmap_conv.c0000644002412700241270000003617512703456111021612 0ustar00jhrozekjhrozek00000000000000/* SSSD ID-mapping library - conversion utilities Authors: Sumit Bose Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "lib/idmap/sss_idmap.h" #include "lib/idmap/sss_idmap_private.h" #include "util/util.h" #include "util/sss_endian.h" #define SID_ID_AUTHS 6 #define SID_SUB_AUTHS 15 struct sss_dom_sid { uint8_t sid_rev_num; int8_t num_auths; /* [range(0,15)] */ uint8_t id_auth[SID_ID_AUTHS]; /* highest order byte has index 0 */ uint32_t sub_auths[SID_SUB_AUTHS]; /* host byte-order */ }; enum idmap_error_code sss_idmap_bin_sid_to_dom_sid(struct sss_idmap_ctx *ctx, const uint8_t *bin_sid, size_t length, struct sss_dom_sid **_dom_sid) { enum idmap_error_code err; struct sss_dom_sid *dom_sid; size_t i = 0; size_t p = 0; uint32_t val; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); if (length > sizeof(struct sss_dom_sid)) return IDMAP_SID_INVALID; dom_sid = ctx->alloc_func(sizeof(struct sss_dom_sid), ctx->alloc_pvt); if (dom_sid == NULL) { return IDMAP_OUT_OF_MEMORY; } memset(dom_sid, 0, sizeof(struct sss_dom_sid)); /* Safely copy in the SID revision number */ dom_sid->sid_rev_num = (uint8_t) *(bin_sid + p); p++; /* Safely copy in the number of sub auth values */ dom_sid->num_auths = (uint8_t) *(bin_sid + p); p++; /* Make sure we aren't being told to read more bin_sid * than can fit in the structure */ if (dom_sid->num_auths > SID_SUB_AUTHS) { err = IDMAP_SID_INVALID; goto done; } /* Safely copy in the id_auth values */ for (i = 0; i < SID_ID_AUTHS; i++) { dom_sid->id_auth[i] = (uint8_t) *(bin_sid + p); p++; } /* Safely copy in the sub_auths values */ for (i = 0; i < dom_sid->num_auths; i++) { /* SID sub auth values in Active Directory are stored little-endian, * we store them in host order */ SAFEALIGN_COPY_UINT32(&val, bin_sid + p, &p); dom_sid->sub_auths[i] = le32toh(val); } *_dom_sid = dom_sid; err = IDMAP_SUCCESS; done: if (err != IDMAP_SUCCESS) { ctx->free_func(dom_sid, ctx->alloc_pvt); } return err; } enum idmap_error_code sss_idmap_dom_sid_to_bin_sid(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid, uint8_t **_bin_sid, size_t *_length) { enum idmap_error_code err; uint8_t *bin_sid; size_t length; size_t i = 0; size_t p = 0; uint32_t val; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); if (dom_sid->num_auths > SID_SUB_AUTHS) { return IDMAP_SID_INVALID; } length = 2 + SID_ID_AUTHS + dom_sid->num_auths * 4; bin_sid = ctx->alloc_func(length, ctx->alloc_pvt); if (bin_sid == NULL) { return IDMAP_OUT_OF_MEMORY; } bin_sid[p] = dom_sid->sid_rev_num; p++; bin_sid[p] = dom_sid->num_auths; p++; for (i = 0; i < SID_ID_AUTHS; i++) { bin_sid[p] = dom_sid->id_auth[i]; p++; } for (i = 0; i < dom_sid->num_auths; i++) { if (p + sizeof(uint32_t) > length) { err = IDMAP_SID_INVALID; goto done; } val = htole32(dom_sid->sub_auths[i]); SAFEALIGN_COPY_UINT32(bin_sid + p, &val, &p); } *_bin_sid = bin_sid; *_length = length; err = IDMAP_SUCCESS; done: if (err != IDMAP_SUCCESS) { ctx->free_func(bin_sid, ctx->alloc_pvt); } return err; } enum idmap_error_code sss_idmap_dom_sid_to_sid(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid, char **_sid) { enum idmap_error_code err; char *sid_buf; size_t sid_buf_len; char *p; int nc; int8_t i; uint32_t id_auth_val = 0; if (dom_sid->num_auths > SID_SUB_AUTHS) { return IDMAP_SID_INVALID; } sid_buf_len = 25 + dom_sid->num_auths * 11; sid_buf = ctx->alloc_func(sid_buf_len, ctx->alloc_pvt); if (sid_buf == NULL) { return IDMAP_OUT_OF_MEMORY; } memset(sid_buf, 0, sid_buf_len); /* Only 32bits are used for the string representation */ id_auth_val = (dom_sid->id_auth[2] << 24) + (dom_sid->id_auth[3] << 16) + (dom_sid->id_auth[4] << 8) + (dom_sid->id_auth[5]); nc = snprintf(sid_buf, sid_buf_len, "S-%u-%lu", dom_sid->sid_rev_num, (unsigned long) id_auth_val); if (nc < 0 || nc >= sid_buf_len) { err = IDMAP_SID_INVALID; goto done; } /* Loop through the sub-auths, if any, prepending a hyphen * for each one. */ p = sid_buf; for (i = 0; i < dom_sid->num_auths ; i++) { p += nc; sid_buf_len -= nc; nc = snprintf(p, sid_buf_len, "-%lu", (unsigned long) dom_sid->sub_auths[i]); if (nc < 0 || nc >= sid_buf_len) { err = IDMAP_SID_INVALID; goto done; } } *_sid = sid_buf; err = IDMAP_SUCCESS; done: if (err != IDMAP_SUCCESS) { ctx->free_func(sid_buf, ctx->alloc_pvt); } return err; } enum idmap_error_code sss_idmap_sid_to_dom_sid(struct sss_idmap_ctx *ctx, const char *sid, struct sss_dom_sid **_dom_sid) { enum idmap_error_code err; unsigned long ul; char *r; char *end; struct sss_dom_sid *dom_sid; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); if (sid == NULL || (sid[0] != 'S' && sid[0] != 's') || sid[1] != '-') { return IDMAP_SID_INVALID; } dom_sid = ctx->alloc_func(sizeof(struct sss_dom_sid), ctx->alloc_pvt); if (dom_sid == NULL) { return IDMAP_OUT_OF_MEMORY; } memset(dom_sid, 0, sizeof(struct sss_dom_sid)); if (!isdigit(sid[2])) { err = IDMAP_SID_INVALID; goto done; } errno = 0; ul = strtoul(sid + 2, &r, 10); if (errno != 0 || r == NULL || *r != '-' || ul > UINT8_MAX) { err = IDMAP_SID_INVALID; goto done; } dom_sid->sid_rev_num = (uint8_t) ul; r++; if (!isdigit(*r)) { err = IDMAP_SID_INVALID; goto done; } errno = 0; ul = strtoul(r, &r, 10); if (errno != 0 || r == NULL || ul > UINT32_MAX) { err = IDMAP_SID_INVALID; goto done; } /* id_auth in the string should always be <2^32 in decimal */ /* store values in the same order as the binary representation */ dom_sid->id_auth[0] = 0; dom_sid->id_auth[1] = 0; dom_sid->id_auth[2] = (ul & 0xff000000) >> 24; dom_sid->id_auth[3] = (ul & 0x00ff0000) >> 16; dom_sid->id_auth[4] = (ul & 0x0000ff00) >> 8; dom_sid->id_auth[5] = (ul & 0x000000ff); if (*r == '\0') { /* no sub auths given */ err = IDMAP_SUCCESS; goto done; } if (*r != '-') { err = IDMAP_SID_INVALID; goto done; } do { if (dom_sid->num_auths >= SID_SUB_AUTHS) { err = IDMAP_SID_INVALID; goto done; } r++; if (!isdigit(*r)) { err = IDMAP_SID_INVALID; goto done; } errno = 0; ul = strtoul(r, &end, 10); if (errno != 0 || ul > UINT32_MAX || end == NULL || (*end != '\0' && *end != '-')) { err = IDMAP_SID_INVALID; goto done; } dom_sid->sub_auths[dom_sid->num_auths++] = ul; r = end; } while (*r != '\0'); err = IDMAP_SUCCESS; done: if (err != IDMAP_SUCCESS) { ctx->free_func(dom_sid, ctx->alloc_pvt); } else { *_dom_sid = dom_sid; } return err; } enum idmap_error_code sss_idmap_sid_to_bin_sid(struct sss_idmap_ctx *ctx, const char *sid, uint8_t **_bin_sid, size_t *_length) { enum idmap_error_code err; struct sss_dom_sid *dom_sid = NULL; size_t length; uint8_t *bin_sid = NULL; err = sss_idmap_sid_to_dom_sid(ctx, sid, &dom_sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_dom_sid_to_bin_sid(ctx, dom_sid, &bin_sid, &length); if (err != IDMAP_SUCCESS) { goto done; } *_length = length; *_bin_sid = bin_sid; err = IDMAP_SUCCESS; done: ctx->free_func(dom_sid, ctx->alloc_pvt); if (err != IDMAP_SUCCESS) { ctx->free_func(bin_sid, ctx->alloc_pvt); } return err; } enum idmap_error_code sss_idmap_bin_sid_to_sid(struct sss_idmap_ctx *ctx, const uint8_t *bin_sid, size_t length, char **_sid) { enum idmap_error_code err; struct sss_dom_sid *dom_sid = NULL; char *sid = NULL; err = sss_idmap_bin_sid_to_dom_sid(ctx, bin_sid, length, &dom_sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_dom_sid_to_sid(ctx, dom_sid, &sid); if (err != IDMAP_SUCCESS) { goto done; } *_sid = sid; err = IDMAP_SUCCESS; done: ctx->free_func(dom_sid, ctx->alloc_pvt); if (err != IDMAP_SUCCESS) { ctx->free_func(sid, ctx->alloc_pvt); } return err; } enum idmap_error_code sss_idmap_sid_to_smb_sid(struct sss_idmap_ctx *ctx, const char *sid, struct dom_sid **_smb_sid) { enum idmap_error_code err; struct sss_dom_sid *dom_sid = NULL; struct dom_sid *smb_sid = NULL; err = sss_idmap_sid_to_dom_sid(ctx, sid, &dom_sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_dom_sid_to_smb_sid(ctx, dom_sid, &smb_sid); if (err != IDMAP_SUCCESS) { goto done; } *_smb_sid = smb_sid; err = IDMAP_SUCCESS; done: ctx->free_func(dom_sid, ctx->alloc_pvt); if (err != IDMAP_SUCCESS) { ctx->free_func(smb_sid, ctx->alloc_pvt); } return err; } enum idmap_error_code sss_idmap_smb_sid_to_sid(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid, char **_sid) { enum idmap_error_code err; struct sss_dom_sid *dom_sid = NULL; char *sid = NULL; err = sss_idmap_smb_sid_to_dom_sid(ctx, smb_sid, &dom_sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_dom_sid_to_sid(ctx, dom_sid, &sid); if (err != IDMAP_SUCCESS) { goto done; } *_sid = sid; err = IDMAP_SUCCESS; done: ctx->free_func(dom_sid, ctx->alloc_pvt); if (err != IDMAP_SUCCESS) { ctx->free_func(sid, ctx->alloc_pvt); } return err; } enum idmap_error_code sss_idmap_dom_sid_to_smb_sid(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid, struct dom_sid **_smb_sid) { struct dom_sid *smb_sid; size_t c; smb_sid = ctx->alloc_func(sizeof(struct dom_sid), ctx->alloc_pvt); if (smb_sid == NULL) { return IDMAP_OUT_OF_MEMORY; } memset(smb_sid, 0, sizeof(struct dom_sid)); smb_sid->sid_rev_num = dom_sid->sid_rev_num; smb_sid->num_auths = dom_sid->num_auths; for (c = 0; c < SID_ID_AUTHS; c++) { smb_sid->id_auth[c] = dom_sid->id_auth[c]; } for (c = 0; c < SID_SUB_AUTHS; c++) { smb_sid->sub_auths[c] = dom_sid->sub_auths[c]; } *_smb_sid = smb_sid; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_smb_sid_to_dom_sid(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid, struct sss_dom_sid **_dom_sid) { struct sss_dom_sid *dom_sid; size_t c; dom_sid = ctx->alloc_func(sizeof(struct sss_dom_sid), ctx->alloc_pvt); if (dom_sid == NULL) { return IDMAP_OUT_OF_MEMORY; } memset(dom_sid, 0, sizeof(struct sss_dom_sid)); dom_sid->sid_rev_num = smb_sid->sid_rev_num; dom_sid->num_auths = smb_sid->num_auths; for (c = 0; c < SID_ID_AUTHS; c++) { dom_sid->id_auth[c] = smb_sid->id_auth[c]; } for (c = 0; c < SID_SUB_AUTHS; c++) { dom_sid->sub_auths[c] = smb_sid->sub_auths[c]; } *_dom_sid = dom_sid; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_bin_sid_to_smb_sid(struct sss_idmap_ctx *ctx, const uint8_t *bin_sid, size_t length, struct dom_sid **_smb_sid) { enum idmap_error_code err; struct sss_dom_sid *dom_sid = NULL; struct dom_sid *smb_sid = NULL; err = sss_idmap_bin_sid_to_dom_sid(ctx, bin_sid, length, &dom_sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_dom_sid_to_smb_sid(ctx, dom_sid, &smb_sid); if (err != IDMAP_SUCCESS) { goto done; } *_smb_sid = smb_sid; err = IDMAP_SUCCESS; done: ctx->free_func(dom_sid, ctx->alloc_pvt); if (err != IDMAP_SUCCESS) { ctx->free_func(smb_sid, ctx->alloc_pvt); } return err; } enum idmap_error_code sss_idmap_smb_sid_to_bin_sid(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid, uint8_t **_bin_sid, size_t *_length) { enum idmap_error_code err; struct sss_dom_sid *dom_sid = NULL; uint8_t *bin_sid = NULL; size_t length; err = sss_idmap_smb_sid_to_dom_sid(ctx, smb_sid, &dom_sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_dom_sid_to_bin_sid(ctx, dom_sid, &bin_sid, &length); if (err != IDMAP_SUCCESS) { goto done; } *_bin_sid = bin_sid; *_length = length; err = IDMAP_SUCCESS; done: ctx->free_func(dom_sid, ctx->alloc_pvt); if (err != IDMAP_SUCCESS) { ctx->free_func(bin_sid, ctx->alloc_pvt); } return err; } sssd-1.13.4/src/lib/idmap/PaxHeaders.16287/sss_idmap_private.h0000644000000000000000000000007412703456111020641 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.598793439 sssd-1.13.4/src/lib/idmap/sss_idmap_private.h0000644002412700241270000000505112703456111022311 0ustar00jhrozekjhrozek00000000000000/* SSSD ID-mapping library - private headers Authors: Sumit Bose Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_IDMAP_PRIVATE_H_ #define SSS_IDMAP_PRIVATE_H_ #define SSS_IDMAP_DEFAULT_LOWER 200000 #define SSS_IDMAP_DEFAULT_UPPER 2000200000 #define SSS_IDMAP_DEFAULT_RANGESIZE 200000 #define SSS_IDMAP_DEFAULT_AUTORID false #define SSS_IDMAP_DEFAULT_EXTRA_SLICE_INIT 10 #define CHECK_IDMAP_CTX(ctx, ret) do { \ if (ctx == NULL || ctx->alloc_func == NULL || ctx->free_func == NULL) { \ return ret; \ } \ } while(0) struct sss_idmap_opts { /* true if autorid compatibility mode is used */ bool autorid_mode; /* smallest available id (for all domains) */ id_t idmap_lower; /* highest available id (for all domains) */ id_t idmap_upper; /* number of available UIDs (for single domain) */ id_t rangesize; /* maximal number of secondary slices */ int extra_slice_init; }; struct sss_idmap_ctx { idmap_alloc_func *alloc_func; void *alloc_pvt; idmap_free_func *free_func; struct sss_idmap_opts idmap_opts; struct idmap_domain_info *idmap_domain_info; }; /* This is a copy of the definition in the samba gen_ndr/security.h header * file. We use it here to be able to offer conversions form struct dom_sid to * string or binary representation since those are not made available by * public samba libraries. * * If the definition ever changes on the samba side we have to adopt the * change. But chances are very low that this will ever happen since e.g. this * struct is also defined in public documentation from Microsoft. See e.g. * section 2.4.2.3 of "[MS-DTYP]: Windows Data Types" * http://msdn.microsoft.com/en-us/library/cc230364(v=prot.10) */ struct dom_sid { uint8_t sid_rev_num; int8_t num_auths; uint8_t id_auth[6]; uint32_t sub_auths[15]; }; #endif /* SSS_IDMAP_PRIVATE_H_ */ sssd-1.13.4/src/lib/idmap/PaxHeaders.16287/sss_idmap.c0000644000000000000000000000007412703456111017102 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.720793853 sssd-1.13.4/src/lib/idmap/sss_idmap.c0000644002412700241270000012366312703456111020564 0ustar00jhrozekjhrozek00000000000000/* SSSD ID-mapping library Authors: Sumit Bose Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "lib/idmap/sss_idmap.h" #include "lib/idmap/sss_idmap_private.h" #include "util/murmurhash3.h" #define SID_FMT "%s-%d" #define SID_STR_MAX_LEN 1024 /* Hold all parameters for unix<->sid mapping relevant for * given slice. */ struct idmap_range_params { uint32_t min_id; uint32_t max_id; char *range_id; uint32_t first_rid; struct idmap_range_params *next; }; struct idmap_domain_info { char *name; char *sid; struct idmap_range_params range_params; struct idmap_domain_info *next; bool external_mapping; struct idmap_range_params *helpers; bool auto_add_ranges; bool helpers_owner; idmap_store_cb cb; void *pvt; }; static void *default_alloc(size_t size, void *pvt) { return malloc(size); } static void default_free(void *ptr, void *pvt) { free(ptr); } static char *idmap_strdup(struct sss_idmap_ctx *ctx, const char *str) { char *new = NULL; size_t len; CHECK_IDMAP_CTX(ctx, NULL); len = strlen(str) + 1; new = ctx->alloc_func(len, ctx->alloc_pvt); if (new == NULL) { return NULL; } memcpy(new, str, len); return new; } static bool id_is_in_range(uint32_t id, struct idmap_range_params *rp, uint32_t *rid) { if (id == 0 || rp == NULL) { return false; } if (id >= rp->min_id && id <= rp->max_id) { if (rid != NULL) { *rid = rp->first_rid + (id - rp->min_id); } return true; } return false; } const char *idmap_error_string(enum idmap_error_code err) { switch (err) { case IDMAP_SUCCESS: return "IDMAP operation successful"; break; case IDMAP_NOT_IMPLEMENTED: return "IDMAP Function is not yet implemented"; break; case IDMAP_ERROR: return "IDMAP general error"; break; case IDMAP_OUT_OF_MEMORY: return "IDMAP operation ran out of memory"; break; case IDMAP_NO_DOMAIN: return "IDMAP domain not found"; break; case IDMAP_CONTEXT_INVALID: return "IDMAP context is invalid"; break; case IDMAP_SID_INVALID: return "IDMAP SID is invalid"; break; case IDMAP_SID_UNKNOWN: return "IDMAP SID not found"; break; case IDMAP_NO_RANGE: return "IDMAP range not found"; default: return "IDMAP unknown error code"; } } bool is_domain_sid(const char *sid) { const char *p; long long a; char *endptr; size_t c; if (sid == NULL || strncmp(sid, DOM_SID_PREFIX, DOM_SID_PREFIX_LEN) != 0) { return false; } p = sid + DOM_SID_PREFIX_LEN; c = 0; do { errno = 0; a = strtoull(p, &endptr, 10); if (errno != 0 || a > UINT32_MAX) { return false; } if (*endptr == '-') { p = endptr + 1; } else if (*endptr != '\0') { return false; } c++; } while(c < 3 && *endptr != '\0'); if (c != 3 || *endptr != '\0') { return false; } return true; } enum idmap_error_code sss_idmap_init(idmap_alloc_func *alloc_func, void *alloc_pvt, idmap_free_func *free_func, struct sss_idmap_ctx **_ctx) { struct sss_idmap_ctx *ctx; if (alloc_func == NULL) { alloc_func = default_alloc; } ctx = alloc_func(sizeof(struct sss_idmap_ctx), alloc_pvt); if (ctx == NULL) { return IDMAP_OUT_OF_MEMORY; } memset(ctx, 0, sizeof(struct sss_idmap_ctx)); ctx->alloc_func = alloc_func; ctx->alloc_pvt = alloc_pvt; ctx->free_func = (free_func == NULL) ? default_free : free_func; /* Set default values. */ ctx->idmap_opts.autorid_mode = SSS_IDMAP_DEFAULT_AUTORID; ctx->idmap_opts.idmap_lower = SSS_IDMAP_DEFAULT_LOWER; ctx->idmap_opts.idmap_upper = SSS_IDMAP_DEFAULT_UPPER; ctx->idmap_opts.rangesize = SSS_IDMAP_DEFAULT_RANGESIZE; ctx->idmap_opts.extra_slice_init = SSS_IDMAP_DEFAULT_EXTRA_SLICE_INIT; *_ctx = ctx; return IDMAP_SUCCESS; } static void free_helpers(struct sss_idmap_ctx *ctx, struct idmap_range_params *helpers, bool helpers_owner) { struct idmap_range_params *it = helpers; struct idmap_range_params *tmp; if (helpers_owner == false) { return; } while (it != NULL) { tmp = it->next; ctx->free_func(it->range_id, ctx->alloc_pvt); ctx->free_func(it, ctx->alloc_pvt); it = tmp; } } static void sss_idmap_free_domain(struct sss_idmap_ctx *ctx, struct idmap_domain_info *dom) { if (ctx == NULL || dom == NULL) { return; } ctx->free_func(dom->range_params.range_id, ctx->alloc_pvt); free_helpers(ctx, dom->helpers, dom->helpers_owner); ctx->free_func(dom->name, ctx->alloc_pvt); ctx->free_func(dom->sid, ctx->alloc_pvt); ctx->free_func(dom, ctx->alloc_pvt); } enum idmap_error_code sss_idmap_free(struct sss_idmap_ctx *ctx) { struct idmap_domain_info *dom; struct idmap_domain_info *next; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); next = ctx->idmap_domain_info; while (next) { dom = next; next = dom->next; sss_idmap_free_domain(ctx, dom); } ctx->free_func(ctx, ctx->alloc_pvt); return IDMAP_SUCCESS; } static enum idmap_error_code sss_idmap_free_ptr(struct sss_idmap_ctx *ctx, void *ptr) { CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); if (ptr != NULL) { ctx->free_func(ptr, ctx->alloc_pvt); } return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_free_sid(struct sss_idmap_ctx *ctx, char *sid) { return sss_idmap_free_ptr(ctx, sid); } enum idmap_error_code sss_idmap_free_dom_sid(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid) { return sss_idmap_free_ptr(ctx, dom_sid); } enum idmap_error_code sss_idmap_free_smb_sid(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid) { return sss_idmap_free_ptr(ctx, smb_sid); } enum idmap_error_code sss_idmap_free_bin_sid(struct sss_idmap_ctx *ctx, uint8_t *bin_sid) { return sss_idmap_free_ptr(ctx, bin_sid); } static bool check_overlap(struct idmap_range_params *range, id_t min, id_t max) { return ((range->min_id <= min && range->max_id >= max) || (range->min_id >= min && range->min_id <= max) || (range->max_id >= min && range->max_id <= max)); } static bool check_dom_overlap(struct idmap_range_params *prim_range, /* struct idmap_range_params *sec_ranges, */ id_t min, id_t max) { return check_overlap(prim_range, min, max); } enum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx, const char *dom_sid, id_t *slice_num, struct sss_idmap_range *_range) { id_t max_slices; id_t orig_slice; id_t new_slice = 0; id_t min; id_t max; id_t idmap_lower; id_t idmap_upper; id_t rangesize; bool autorid_mode; uint32_t hash_val; struct idmap_domain_info *dom; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); idmap_lower = ctx->idmap_opts.idmap_lower; idmap_upper = ctx->idmap_opts.idmap_upper; rangesize = ctx->idmap_opts.rangesize; autorid_mode = ctx->idmap_opts.autorid_mode; max_slices = (idmap_upper - idmap_lower) / rangesize; if (slice_num && *slice_num != -1) { /* The slice is being set explicitly. * This may happen at system startup when we're loading * previously-determined slices. In the future, we may also * permit configuration to select the slice for a domain * explicitly. */ new_slice = *slice_num; } else { /* If slice is -1, we're being asked to pick a new slice */ if (autorid_mode) { /* In autorid compatibility mode, always start at 0 and find the * first free value. */ orig_slice = 0; } else { /* Hash the domain sid string */ hash_val = murmurhash3(dom_sid, strlen(dom_sid), 0xdeadbeef); /* Now get take the modulus of the hash val and the max_slices * to determine its optimal position in the range. */ new_slice = hash_val % max_slices; orig_slice = new_slice; } min = (rangesize * new_slice) + idmap_lower; max = min + rangesize - 1; /* Verify that this slice is not already in use */ do { for (dom = ctx->idmap_domain_info; dom != NULL; dom = dom->next) { if (check_dom_overlap(&dom->range_params, min, max)) { /* This range overlaps one already registered * We'll try the next available slot */ new_slice++; if (new_slice >= max_slices) { /* loop around to the beginning if necessary */ new_slice = 0; } min = (rangesize * new_slice) + idmap_lower; max = min + rangesize - 1; break; } } /* Keep trying until dom is NULL (meaning we got to the end * without matching) or we have run out of slices and gotten * back to the first one we tried. */ } while (dom && new_slice != orig_slice); if (dom) { /* We looped all the way through and found no empty slots */ return IDMAP_OUT_OF_SLICES; } } _range->min = (rangesize * new_slice) + idmap_lower; _range->max = _range->min + rangesize - 1; if (slice_num) { *slice_num = new_slice; } return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_check_collision_ex(const char *o_name, const char *o_sid, struct sss_idmap_range *o_range, uint32_t o_first_rid, const char *o_range_id, bool o_external_mapping, const char *n_name, const char *n_sid, struct sss_idmap_range *n_range, uint32_t n_first_rid, const char *n_range_id, bool n_external_mapping) { bool names_equal; bool sids_equal; /* TODO: if both ranges have the same ID check if an update is * needed. */ /* Check if ID ranges overlap. * ID ranges with external mapping may overlap. */ if ((!n_external_mapping && !o_external_mapping) && ((n_range->min >= o_range->min && n_range->min <= o_range->max) || (n_range->max >= o_range->min && n_range->max <= o_range->max))) { return IDMAP_COLLISION; } names_equal = (strcasecmp(n_name, o_name) == 0); sids_equal = ((n_sid == NULL && o_sid == NULL) || (n_sid != NULL && o_sid != NULL && strcasecmp(n_sid, o_sid) == 0)); /* check if domain name and SID are consistent */ if ((names_equal && !sids_equal) || (!names_equal && sids_equal)) { return IDMAP_COLLISION; } /* check if external_mapping is consistent */ if (names_equal && sids_equal && n_external_mapping != o_external_mapping) { return IDMAP_COLLISION; } /* check if RID ranges overlap */ if (names_equal && sids_equal && n_external_mapping == false && n_first_rid >= o_first_rid && n_first_rid <= o_first_rid + (o_range->max - o_range->min)) { return IDMAP_COLLISION; } return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_check_collision(struct sss_idmap_ctx *ctx, char *n_name, char *n_sid, struct sss_idmap_range *n_range, uint32_t n_first_rid, char *n_range_id, bool n_external_mapping) { struct idmap_domain_info *dom; enum idmap_error_code err; struct sss_idmap_range range; for (dom = ctx->idmap_domain_info; dom != NULL; dom = dom->next) { range.min = dom->range_params.min_id; range.max = dom->range_params.max_id; err = sss_idmap_check_collision_ex(dom->name, dom->sid, &range, dom->range_params.first_rid, dom->range_params.range_id, dom->external_mapping, n_name, n_sid, n_range, n_first_rid, n_range_id, n_external_mapping); if (err != IDMAP_SUCCESS) { return err; } } return IDMAP_SUCCESS; } static enum idmap_error_code dom_check_collision(struct idmap_domain_info *dom_list, struct idmap_domain_info *new_dom) { struct idmap_domain_info *dom; enum idmap_error_code err; struct sss_idmap_range range; struct sss_idmap_range new_dom_range = { new_dom->range_params.min_id, new_dom->range_params.max_id }; for (dom = dom_list; dom != NULL; dom = dom->next) { range.min = dom->range_params.min_id; range.max = dom->range_params.max_id; err = sss_idmap_check_collision_ex(dom->name, dom->sid, &range, dom->range_params.first_rid, dom->range_params.range_id, dom->external_mapping, new_dom->name, new_dom->sid, &new_dom_range, new_dom->range_params.first_rid, new_dom->range_params.range_id, new_dom->external_mapping); if (err != IDMAP_SUCCESS) { return err; } } return IDMAP_SUCCESS; } static char* generate_sec_slice_name(struct sss_idmap_ctx *ctx, const char *domain_name, uint32_t rid) { const char *SEC_SLICE_NAME_FMT = "%s-%"PRIu32; char *slice_name; int len, len2; len = snprintf(NULL, 0, SEC_SLICE_NAME_FMT, domain_name, rid); if (len <= 0) { return NULL; } slice_name = ctx->alloc_func(len + 1, ctx->alloc_pvt); if (slice_name == NULL) { return NULL; } len2 = snprintf(slice_name, len + 1, SEC_SLICE_NAME_FMT, domain_name, rid); if (len != len2) { ctx->free_func(slice_name, ctx->alloc_pvt); return NULL; } return slice_name; } static enum idmap_error_code generate_slice(struct sss_idmap_ctx *ctx, char *slice_name, uint32_t first_rid, struct idmap_range_params **_slice) { struct idmap_range_params *slice; struct sss_idmap_range tmp_range; enum idmap_error_code err; slice = ctx->alloc_func(sizeof(struct idmap_range_params), ctx->alloc_pvt); if (slice == NULL) { return IDMAP_OUT_OF_MEMORY; } slice->next = NULL; err = sss_idmap_calculate_range(ctx, slice_name, NULL, &tmp_range); if (err != IDMAP_SUCCESS) { ctx->free_func(slice, ctx->alloc_pvt); return err; } slice->min_id = tmp_range.min; slice->max_id = tmp_range.max; slice->range_id = slice_name; slice->first_rid = first_rid; *_slice = slice; return IDMAP_SUCCESS; } static enum idmap_error_code get_helpers(struct sss_idmap_ctx *ctx, const char *domain_sid, uint32_t first_rid, struct idmap_range_params **_sec_slices) { struct idmap_range_params *prev = NULL; struct idmap_range_params *sec_slices = NULL; static enum idmap_error_code err; struct idmap_range_params *slice; char *secondary_name; for (int i = 0; i < ctx->idmap_opts.extra_slice_init; i++) { secondary_name = generate_sec_slice_name(ctx, domain_sid, first_rid); if (secondary_name == NULL) { err = IDMAP_OUT_OF_MEMORY; goto fail; } err = generate_slice(ctx, secondary_name, first_rid, &slice); if (err != IDMAP_SUCCESS) { goto fail; } first_rid += ctx->idmap_opts.rangesize; if (prev != NULL) { prev->next = slice; } if (sec_slices == NULL) { sec_slices = slice; } prev = slice; } *_sec_slices = sec_slices; return IDMAP_SUCCESS; fail: ctx->free_func(secondary_name, ctx->alloc_pvt); /* Free already generated helpers. */ free_helpers(ctx, sec_slices, true); return err; } enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx, const char *domain_name, const char *domain_sid, struct sss_idmap_range *range, const char *range_id, uint32_t rid, bool external_mapping) { struct idmap_domain_info *dom = NULL; enum idmap_error_code err; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); if (domain_name == NULL) { return IDMAP_NO_DOMAIN; } if (range == NULL) { return IDMAP_NO_RANGE; } /* For algorithmic mapping a valid domain SID is required, for external * mapping it may be NULL, but if set it should be valid. */ if ((!external_mapping && !is_domain_sid(domain_sid)) || (external_mapping && domain_sid != NULL && !is_domain_sid(domain_sid))) { return IDMAP_SID_INVALID; } dom = ctx->alloc_func(sizeof(struct idmap_domain_info), ctx->alloc_pvt); if (dom == NULL) { return IDMAP_OUT_OF_MEMORY; } memset(dom, 0, sizeof(struct idmap_domain_info)); dom->name = idmap_strdup(ctx, domain_name); if (dom->name == NULL) { err = IDMAP_OUT_OF_MEMORY; goto fail; } if (domain_sid != NULL) { dom->sid = idmap_strdup(ctx, domain_sid); if (dom->sid == NULL) { err = IDMAP_OUT_OF_MEMORY; goto fail; } } dom->range_params.min_id = range->min; dom->range_params.max_id = range->max; if (range_id != NULL) { dom->range_params.range_id = idmap_strdup(ctx, range_id); if (dom->range_params.range_id == NULL) { err = IDMAP_OUT_OF_MEMORY; goto fail; } } dom->range_params.first_rid = rid; dom->external_mapping = external_mapping; err = dom_check_collision(ctx->idmap_domain_info, dom); if (err != IDMAP_SUCCESS) { goto fail; } dom->next = ctx->idmap_domain_info; ctx->idmap_domain_info = dom; return IDMAP_SUCCESS; fail: sss_idmap_free_domain(ctx, dom); return err; } enum idmap_error_code sss_idmap_add_auto_domain_ex(struct sss_idmap_ctx *ctx, const char *domain_name, const char *domain_sid, struct sss_idmap_range *range, const char *range_id, uint32_t rid, bool external_mapping, idmap_store_cb cb, void *pvt) { enum idmap_error_code err; err = sss_idmap_add_domain_ex(ctx, domain_name, domain_sid, range, range_id, rid, external_mapping); if (err != IDMAP_SUCCESS) { return err; } if (external_mapping) { /* There's no point in generating secondary ranges if external_mapping is enabled. */ ctx->idmap_domain_info->auto_add_ranges = false; return IDMAP_SUCCESS; } if ((range->max - range->min + 1) != ctx->idmap_opts.rangesize) { /* Range of primary slice is not equal to the value of ldap_idmap_range_size option. */ return IDMAP_ERROR; } /* No additional secondary ranges should be added if no sec ranges are predeclared. */ if (ctx->idmap_opts.extra_slice_init == 0) { ctx->idmap_domain_info->auto_add_ranges = false; return IDMAP_SUCCESS; } /* Add size of primary slice for first_rid of secondary slices. */ rid += ctx->idmap_opts.rangesize; err = get_helpers(ctx, domain_sid, rid, &ctx->idmap_domain_info->helpers); if (err == IDMAP_SUCCESS) { ctx->idmap_domain_info->auto_add_ranges = true; ctx->idmap_domain_info->helpers_owner = true; } else { /* Running out of slices for secondary mapping is a non-fatal * problem. */ if (err == IDMAP_OUT_OF_SLICES) { err = IDMAP_SUCCESS; } ctx->idmap_domain_info->auto_add_ranges = false; } ctx->idmap_domain_info->cb = cb; ctx->idmap_domain_info->pvt = pvt; return err; } enum idmap_error_code sss_idmap_add_domain(struct sss_idmap_ctx *ctx, const char *domain_name, const char *domain_sid, struct sss_idmap_range *range) { return sss_idmap_add_domain_ex(ctx, domain_name, domain_sid, range, NULL, 0, false); } static bool sss_idmap_sid_is_builtin(const char *sid) { if (strncmp(sid, "S-1-5-32-", 9) == 0) { return true; } return false; } static bool parse_rid(const char *sid, size_t dom_prefix_len, long long *_rid) { long long rid; char *endptr; errno = 0; /* Use suffix of sid - part after domain and following '-' */ rid = strtoull(sid + dom_prefix_len + 1, &endptr, 10); if (errno != 0 || rid > UINT32_MAX || *endptr != '\0') { return false; } *_rid = rid; return true; } static bool is_sid_from_dom(const char *dom_sid, const char *sid, size_t *_dom_sid_len) { size_t dom_sid_len; if (dom_sid == NULL) { return false; } dom_sid_len = strlen(dom_sid); *_dom_sid_len = dom_sid_len; if (strlen(sid) < dom_sid_len || sid[dom_sid_len] != '-') { return false; } return strncmp(sid, dom_sid, dom_sid_len) == 0; } static bool comp_id(struct idmap_range_params *range_params, long long rid, uint32_t *_id) { uint32_t id; if (rid >= range_params->first_rid && ((UINT32_MAX - range_params->min_id) > (rid - range_params->first_rid))) { id = range_params->min_id + (rid - range_params->first_rid); if (id <= range_params->max_id) { *_id = id; return true; } } return false; } static enum idmap_error_code get_range(struct sss_idmap_ctx *ctx, const char *dom_sid, long long rid, struct idmap_range_params **_range) { char *secondary_name; enum idmap_error_code err; int first_rid; struct idmap_range_params *range; first_rid = (rid / ctx->idmap_opts.rangesize) * ctx->idmap_opts.rangesize; secondary_name = generate_sec_slice_name(ctx, dom_sid, first_rid); if (secondary_name == NULL) { return IDMAP_OUT_OF_MEMORY; } err = generate_slice(ctx, secondary_name, first_rid, &range); if (err == IDMAP_OUT_OF_SLICES) { ctx->free_func(secondary_name, ctx->alloc_pvt); return err; } *_range = range; return IDMAP_SUCCESS; } static enum idmap_error_code spawn_dom(struct sss_idmap_ctx *ctx, struct idmap_domain_info *parent, struct idmap_range_params *range) { struct sss_idmap_range tmp; static enum idmap_error_code err; struct idmap_domain_info *it; tmp.min = range->min_id; tmp.max = range->max_id; err = sss_idmap_add_domain_ex(ctx, parent->name, parent->sid, &tmp, range->range_id, range->first_rid, false); if (err != IDMAP_SUCCESS) { return err; } it = ctx->idmap_domain_info; while (it != NULL) { /* Find the newly added domain. */ if (it->range_params.first_rid == range->first_rid && it->range_params.min_id == range->min_id && it->range_params.max_id == range->max_id) { /* Share helpers. */ it->helpers = parent->helpers; it->auto_add_ranges = parent->auto_add_ranges; /* Share call back for storing domains */ it->cb = parent->cb; it->pvt = parent->pvt; break; } it = it->next; } if (it == NULL) { /* Failed to find just added domain. */ return IDMAP_ERROR; } /* Store mapping for newly created domain. */ if (it->cb != NULL) { err = it->cb(it->name, it->sid, it->range_params.range_id, it->range_params.min_id, it->range_params.max_id, it->range_params.first_rid, it->pvt); if (err != IDMAP_SUCCESS) { return err; } } return IDMAP_SUCCESS; } static enum idmap_error_code add_dom_for_sid(struct sss_idmap_ctx *ctx, struct idmap_domain_info *matched_dom, const char *sid, uint32_t *_id) { enum idmap_error_code err; long long rid; struct idmap_range_params *range = NULL; if (parse_rid(sid, strlen(matched_dom->sid), &rid) == false) { err = IDMAP_SID_INVALID; goto done; } /* todo optimize */ err = get_range(ctx, matched_dom->sid, rid, &range); if (err != IDMAP_SUCCESS) { goto done; } err = spawn_dom(ctx, matched_dom, range); if (err != IDMAP_SUCCESS) { goto done; } if (!comp_id(range, rid, _id)) { err = IDMAP_ERROR; goto done; } err = IDMAP_SUCCESS; done: if (range != NULL) { ctx->free_func(range->range_id, ctx->alloc_pvt); } ctx->free_func(range, ctx->alloc_pvt); return err; } enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx, const char *sid, uint32_t *_id) { struct idmap_domain_info *idmap_domain_info; struct idmap_domain_info *matched_dom = NULL; size_t dom_len; long long rid; if (sid == NULL || _id == NULL) { return IDMAP_ERROR; } CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); idmap_domain_info = ctx->idmap_domain_info; if (sss_idmap_sid_is_builtin(sid)) { return IDMAP_BUILTIN_SID; } /* Try primary slices */ while (idmap_domain_info != NULL) { if (is_sid_from_dom(idmap_domain_info->sid, sid, &dom_len)) { if (idmap_domain_info->external_mapping == true) { return IDMAP_EXTERNAL; } if (parse_rid(sid, dom_len, &rid) == false) { return IDMAP_SID_INVALID; } if (comp_id(&idmap_domain_info->range_params, rid, _id)) { return IDMAP_SUCCESS; } matched_dom = idmap_domain_info; } idmap_domain_info = idmap_domain_info->next; } if (matched_dom != NULL && matched_dom->auto_add_ranges) { return add_dom_for_sid(ctx, matched_dom, sid, _id); } return matched_dom ? IDMAP_NO_RANGE : IDMAP_NO_DOMAIN; } enum idmap_error_code sss_idmap_check_sid_unix(struct sss_idmap_ctx *ctx, const char *sid, uint32_t id) { struct idmap_domain_info *idmap_domain_info; size_t dom_len; bool no_range = false; if (sid == NULL) { return IDMAP_ERROR; } CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); if (ctx->idmap_domain_info == NULL) { return IDMAP_NO_DOMAIN; } idmap_domain_info = ctx->idmap_domain_info; if (sss_idmap_sid_is_builtin(sid)) { return IDMAP_BUILTIN_SID; } while (idmap_domain_info != NULL) { if (idmap_domain_info->sid != NULL) { dom_len = strlen(idmap_domain_info->sid); if (strlen(sid) > dom_len && sid[dom_len] == '-' && strncmp(sid, idmap_domain_info->sid, dom_len) == 0) { if (id >= idmap_domain_info->range_params.min_id && id <= idmap_domain_info->range_params.max_id) { return IDMAP_SUCCESS; } no_range = true; } } idmap_domain_info = idmap_domain_info->next; } return no_range ? IDMAP_NO_RANGE : IDMAP_SID_UNKNOWN; } static enum idmap_error_code generate_sid(struct sss_idmap_ctx *ctx, const char *dom_sid, uint32_t rid, char **_sid) { char *sid; int len; int ret; len = snprintf(NULL, 0, SID_FMT, dom_sid, rid); if (len <= 0 || len > SID_STR_MAX_LEN) { return IDMAP_ERROR; } sid = ctx->alloc_func(len + 1, ctx->alloc_pvt); if (sid == NULL) { return IDMAP_OUT_OF_MEMORY; } ret = snprintf(sid, len + 1, SID_FMT, dom_sid, rid); if (ret != len) { ctx->free_func(sid, ctx->alloc_pvt); return IDMAP_ERROR; } *_sid = sid; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx, uint32_t id, char **_sid) { struct idmap_domain_info *idmap_domain_info; uint32_t rid; enum idmap_error_code err; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); idmap_domain_info = ctx->idmap_domain_info; while (idmap_domain_info != NULL) { if (id_is_in_range(id, &idmap_domain_info->range_params, &rid)) { if (idmap_domain_info->external_mapping == true || idmap_domain_info->sid == NULL) { return IDMAP_EXTERNAL; } return generate_sid(ctx, idmap_domain_info->sid, rid, _sid); } idmap_domain_info = idmap_domain_info->next; } /* Check secondary ranges. */ idmap_domain_info = ctx->idmap_domain_info; while (idmap_domain_info != NULL) { for (struct idmap_range_params *it = idmap_domain_info->helpers; it != NULL; it = it->next) { if (id_is_in_range(id, it, &rid)) { if (idmap_domain_info->external_mapping == true || idmap_domain_info->sid == NULL) { return IDMAP_EXTERNAL; } err = spawn_dom(ctx, idmap_domain_info, it); if (err != IDMAP_SUCCESS) { return err; } return generate_sid(ctx, idmap_domain_info->sid, rid, _sid); } } idmap_domain_info = idmap_domain_info->next; } return IDMAP_NO_DOMAIN; } enum idmap_error_code sss_idmap_dom_sid_to_unix(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid, uint32_t *id) { enum idmap_error_code err; char *sid; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); err = sss_idmap_dom_sid_to_sid(ctx, dom_sid, &sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_sid_to_unix(ctx, sid, id); done: ctx->free_func(sid, ctx->alloc_pvt); return err; } enum idmap_error_code sss_idmap_bin_sid_to_unix(struct sss_idmap_ctx *ctx, uint8_t *bin_sid, size_t length, uint32_t *id) { enum idmap_error_code err; char *sid; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); err = sss_idmap_bin_sid_to_sid(ctx, bin_sid, length, &sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_sid_to_unix(ctx, sid, id); done: ctx->free_func(sid, ctx->alloc_pvt); return err; } enum idmap_error_code sss_idmap_smb_sid_to_unix(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid, uint32_t *id) { enum idmap_error_code err; char *sid; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); err = sss_idmap_smb_sid_to_sid(ctx, smb_sid, &sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_sid_to_unix(ctx, sid, id); done: ctx->free_func(sid, ctx->alloc_pvt); return err; } enum idmap_error_code sss_idmap_check_dom_sid_to_unix(struct sss_idmap_ctx *ctx, struct sss_dom_sid *dom_sid, uint32_t id) { enum idmap_error_code err; char *sid; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); err = sss_idmap_dom_sid_to_sid(ctx, dom_sid, &sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_check_sid_unix(ctx, sid, id); done: ctx->free_func(sid, ctx->alloc_pvt); return err; } enum idmap_error_code sss_idmap_check_bin_sid_unix(struct sss_idmap_ctx *ctx, uint8_t *bin_sid, size_t length, uint32_t id) { enum idmap_error_code err; char *sid; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); err = sss_idmap_bin_sid_to_sid(ctx, bin_sid, length, &sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_check_sid_unix(ctx, sid, id); done: ctx->free_func(sid, ctx->alloc_pvt); return err; } enum idmap_error_code sss_idmap_check_smb_sid_unix(struct sss_idmap_ctx *ctx, struct dom_sid *smb_sid, uint32_t id) { enum idmap_error_code err; char *sid; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); err = sss_idmap_smb_sid_to_sid(ctx, smb_sid, &sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_check_sid_unix(ctx, sid, id); done: ctx->free_func(sid, ctx->alloc_pvt); return err; } enum idmap_error_code sss_idmap_unix_to_dom_sid(struct sss_idmap_ctx *ctx, uint32_t id, struct sss_dom_sid **_dom_sid) { enum idmap_error_code err; char *sid = NULL; struct sss_dom_sid *dom_sid = NULL; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); err = sss_idmap_unix_to_sid(ctx, id, &sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_sid_to_dom_sid(ctx, sid, &dom_sid); if (err != IDMAP_SUCCESS) { goto done; } *_dom_sid = dom_sid; err = IDMAP_SUCCESS; done: ctx->free_func(sid, ctx->alloc_pvt); if (err != IDMAP_SUCCESS) { ctx->free_func(dom_sid, ctx->alloc_pvt); } return err; } enum idmap_error_code sss_idmap_unix_to_bin_sid(struct sss_idmap_ctx *ctx, uint32_t id, uint8_t **_bin_sid, size_t *_length) { enum idmap_error_code err; char *sid = NULL; uint8_t *bin_sid = NULL; size_t length; CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); err = sss_idmap_unix_to_sid(ctx, id, &sid); if (err != IDMAP_SUCCESS) { goto done; } err = sss_idmap_sid_to_bin_sid(ctx, sid, &bin_sid, &length); if (err != IDMAP_SUCCESS) { goto done; } *_bin_sid = bin_sid; *_length = length; err = IDMAP_SUCCESS; done: ctx->free_func(sid, ctx->alloc_pvt); if (err != IDMAP_SUCCESS) { ctx->free_func(bin_sid, ctx->alloc_pvt); } return err; } enum idmap_error_code sss_idmap_ctx_set_autorid(struct sss_idmap_ctx *ctx, bool use_autorid) { CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); ctx->idmap_opts.autorid_mode = use_autorid; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_ctx_set_lower(struct sss_idmap_ctx *ctx, id_t lower) { CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); ctx->idmap_opts.idmap_lower = lower; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_ctx_set_upper(struct sss_idmap_ctx *ctx, id_t upper) { CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); ctx->idmap_opts.idmap_upper = upper; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_ctx_set_rangesize(struct sss_idmap_ctx *ctx, id_t rangesize) { CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); ctx->idmap_opts.rangesize = rangesize; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_ctx_set_extra_slice_init(struct sss_idmap_ctx *ctx, int extra_slice_init) { CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); ctx->idmap_opts.extra_slice_init = extra_slice_init; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_ctx_get_autorid(struct sss_idmap_ctx *ctx, bool *_autorid) { CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); *_autorid = ctx->idmap_opts.autorid_mode; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_ctx_get_lower(struct sss_idmap_ctx *ctx, id_t *_lower) { CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); *_lower = ctx->idmap_opts.idmap_lower; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_ctx_get_upper(struct sss_idmap_ctx *ctx, id_t *_upper) { CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); *_upper = ctx->idmap_opts.idmap_upper; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_ctx_get_rangesize(struct sss_idmap_ctx *ctx, id_t *_rangesize) { CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); *_rangesize = ctx->idmap_opts.rangesize; return IDMAP_SUCCESS; } enum idmap_error_code sss_idmap_domain_has_algorithmic_mapping(struct sss_idmap_ctx *ctx, const char *dom_sid, bool *has_algorithmic_mapping) { struct idmap_domain_info *idmap_domain_info; size_t len; size_t dom_sid_len; if (dom_sid == NULL) { return IDMAP_SID_INVALID; } CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); if (ctx->idmap_domain_info == NULL) { return IDMAP_NO_DOMAIN; } idmap_domain_info = ctx->idmap_domain_info; while (idmap_domain_info != NULL) { if (idmap_domain_info->sid != NULL) { len = strlen(idmap_domain_info->sid); dom_sid_len = strlen(dom_sid); if (((dom_sid_len > len && dom_sid[len] == '-') || dom_sid_len == len) && strncmp(dom_sid, idmap_domain_info->sid, len) == 0) { *has_algorithmic_mapping = !idmap_domain_info->external_mapping; return IDMAP_SUCCESS; } } idmap_domain_info = idmap_domain_info->next; } return IDMAP_SID_UNKNOWN; } enum idmap_error_code sss_idmap_domain_by_name_has_algorithmic_mapping(struct sss_idmap_ctx *ctx, const char *dom_name, bool *has_algorithmic_mapping) { struct idmap_domain_info *idmap_domain_info; if (dom_name == NULL) { return IDMAP_ERROR; } CHECK_IDMAP_CTX(ctx, IDMAP_CONTEXT_INVALID); if (ctx->idmap_domain_info == NULL) { return IDMAP_NO_DOMAIN; } idmap_domain_info = ctx->idmap_domain_info; while (idmap_domain_info != NULL) { if (idmap_domain_info->name != NULL && strcmp(dom_name, idmap_domain_info->name) == 0) { *has_algorithmic_mapping = !idmap_domain_info->external_mapping; return IDMAP_SUCCESS; } idmap_domain_info = idmap_domain_info->next; } return IDMAP_NAME_UNKNOWN; } sssd-1.13.4/src/lib/idmap/PaxHeaders.16287/sss_idmap.exports0000644000000000000000000000007412703456111020364 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.370792666 sssd-1.13.4/src/lib/idmap/sss_idmap.exports0000644002412700241270000000350512703456111022036 0ustar00jhrozekjhrozek00000000000000SSS_IDMAP_0.4 { # public functions global: sss_idmap_init; sss_idmap_ctx_set_autorid; sss_idmap_ctx_set_lower; sss_idmap_ctx_set_upper; sss_idmap_ctx_set_rangesize; sss_idmap_ctx_get_autorid; sss_idmap_ctx_get_lower; sss_idmap_ctx_get_upper; sss_idmap_ctx_get_rangesize; sss_idmap_calculate_range; sss_idmap_add_domain; sss_idmap_add_domain_ex; sss_idmap_check_collision; sss_idmap_check_collision_ex; sss_idmap_sid_to_unix; sss_idmap_dom_sid_to_unix; sss_idmap_bin_sid_to_unix; sss_idmap_smb_sid_to_unix; sss_idmap_check_sid_unix; sss_idmap_check_dom_sid_to_unix; sss_idmap_check_bin_sid_unix; sss_idmap_check_smb_sid_unix; sss_idmap_unix_to_sid; sss_idmap_unix_to_dom_sid; sss_idmap_unix_to_bin_sid; sss_idmap_free; sss_idmap_free_sid; sss_idmap_free_dom_sid; sss_idmap_free_smb_sid; sss_idmap_free_bin_sid; idmap_error_string; is_domain_sid; sss_idmap_domain_has_algorithmic_mapping; sss_idmap_domain_by_name_has_algorithmic_mapping; sss_idmap_bin_sid_to_dom_sid; sss_idmap_bin_sid_to_sid; sss_idmap_dom_sid_to_bin_sid; sss_idmap_sid_to_bin_sid; sss_idmap_dom_sid_to_sid; sss_idmap_sid_to_dom_sid; sss_idmap_sid_to_smb_sid; sss_idmap_smb_sid_to_sid; sss_idmap_dom_sid_to_smb_sid; sss_idmap_smb_sid_to_dom_sid; sss_idmap_bin_sid_to_smb_sid; sss_idmap_smb_sid_to_bin_sid; # everything else is local local: *; }; SSS_IDMAP_0.5 { # public functions global: sss_idmap_ctx_set_extra_slice_init; sss_idmap_add_auto_domain_ex; } SSS_IDMAP_0.4;sssd-1.13.4/src/lib/idmap/PaxHeaders.16287/sss_idmap.doxy.in0000644000000000000000000000007412703456111020250 xustar0030 atime=1460561772.739787135 30 ctime=1460561774.626793534 sssd-1.13.4/src/lib/idmap/sss_idmap.doxy.in0000644002412700241270000023501712703456111021727 0ustar00jhrozekjhrozek00000000000000# Doxyfile 1.8.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = sss_idmap # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = idmap_doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. Note that you specify absolute paths here, but also # relative paths, which will be relative from the directory where doxygen is # started. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, # and language is one of the parsers supported by doxygen: IDL, Java, # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, # C++. For instance to make doxygen treat .inc files as Fortran files (default # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented classes, # or namespaces to their corresponding documentation. Such a link can be # prevented in individual cases by by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES (the # default) will make doxygen replace the get and set methods by a property in # the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if section-label ... \endif # and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. Do not use # file names with spaces, bibtex cannot handle them. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @abs_top_srcdir@/src/lib/idmap/sss_idmap.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.cpp \ *.cc \ *.c \ *.h \ *.hh \ *.hpp \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.git/* \ */.svn/* \ */cmake/* \ */build/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = # If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page (index.html). # This can be useful if you have a project on for instance GitHub and want reuse # the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If left blank doxygen will # generate a default style sheet. Note that it is recommended to use # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET # since it does not replace the standard style sheet and is therefor more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user # can expand and collapse entries dynamically later on. Doxygen will expand # the tree to such a level that at most the specified number of entries are # visible (unless a fully collapsed tree already exceeds this amount). # So setting the number of entries 1 will produce a full collapsed tree by # default. 0 is a special value representing an infinite number of entries # and will result in a full expanded tree by default. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely # identify the documentation publisher. This should be a reverse domain-name # style string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NONE # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. # There are two flavours of web server based search depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. # See the manual for details. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain # the search results. Doxygen ships with an example indexer (doxyindexer) and # search engine (doxysearch.cgi) which are based on the open source search engine # library Xapian. See the manual for configuration details. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will returned the search results when EXTERNAL_SEARCH is enabled. # Doxygen ships with an example search engine (doxysearch) which is based on # the open source search engine library Xapian. See the manual for configuration # details. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. SEARCHDATA_FILE = searchdata.xml # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through other # doxygen projects that are not otherwise connected via tags files, but are # all added to the same search index. Each project needs to have a tag file set # via GENERATE_TAGFILE. The search mapping then maps the name of the tag file # to a relative location where the documentation can be found, # similar to the # TAGFILES option but without actually processing the tag file. # The format is: EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # managable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES sssd-1.13.4/src/lib/PaxHeaders.16287/sifp0000644000000000000000000000013212703463556014554 xustar0030 mtime=1460561774.820794192 30 atime=1460561776.118798593 30 ctime=1460561774.820794192 sssd-1.13.4/src/lib/sifp/0000755002412700241270000000000012703463556016305 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_sifp_private.h0000644000000000000000000000007412703456111020357 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.598793439 sssd-1.13.4/src/lib/sifp/sss_sifp_private.h0000644002412700241270000000604012703456111022026 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_SIFP_PRIVATE_H_ #define SSS_SIFP_PRIVATE_H_ #define SSS_SIFP_PATH_IFP "/org/freedesktop/sssd/infopipe" #include #include "lib/sifp/sss_sifp.h" void *sss_sifp_alloc_zero(sss_sifp_ctx *ctx, size_t size, size_t num); #define _alloc_zero(ctx, type, num) sss_sifp_alloc_zero(ctx, sizeof(type), num) #define _free(ctx, var) \ do { \ ctx->free_fn((var), ctx->alloc_pvt); \ (var) = NULL; \ } while (0) struct sss_sifp_ctx { DBusConnection *conn; sss_sifp_alloc_func *alloc_fn; sss_sifp_free_func *free_fn; void *alloc_pvt; DBusError *io_error; }; enum sss_sifp_attr_type { SSS_SIFP_ATTR_TYPE_BOOL, SSS_SIFP_ATTR_TYPE_INT16, SSS_SIFP_ATTR_TYPE_UINT16, SSS_SIFP_ATTR_TYPE_INT32, SSS_SIFP_ATTR_TYPE_UINT32, SSS_SIFP_ATTR_TYPE_INT64, SSS_SIFP_ATTR_TYPE_UINT64, SSS_SIFP_ATTR_TYPE_STRING, SSS_SIFP_ATTR_TYPE_STRING_DICT }; /** * D-Bus object attribute */ struct sss_sifp_attr { char *name; enum sss_sifp_attr_type type; unsigned int num_values; union { bool *boolean; int16_t *int16; uint16_t *uint16; int32_t *int32; uint32_t *uint32; int64_t *int64; uint64_t *uint64; char **str; hash_table_t *str_dict; } data; }; void sss_sifp_set_io_error(sss_sifp_ctx *ctx, DBusError *error); const char * sss_sifp_get_iface_for_object(const char *object_path); char * sss_sifp_strdup(sss_sifp_ctx *ctx, const char *str); char * sss_sifp_strcat(sss_sifp_ctx *ctx, const char *str1, const char *str2); sss_sifp_error sss_sifp_parse_attr(sss_sifp_ctx *ctx, const char *name, DBusMessage *msg, sss_sifp_attr ***_attrs); sss_sifp_error sss_sifp_parse_attr_list(sss_sifp_ctx *ctx, DBusMessage *msg, sss_sifp_attr ***_attrs); sss_sifp_error sss_sifp_parse_object_path(sss_sifp_ctx *ctx, DBusMessage *msg, char **_object_path); sss_sifp_error sss_sifp_parse_object_path_list(sss_sifp_ctx *ctx, DBusMessage *msg, char ***_object_paths); #endif /* SSS_SIFP_PRIVATE_H_ */ sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_sifp_common.c0000644000000000000000000000007412703456111020170 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.818794185 sssd-1.13.4/src/lib/sifp/sss_sifp_common.c0000644002412700241270000001152312703456111021641 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "lib/sifp/sss_sifp.h" #include "lib/sifp/sss_sifp_dbus.h" #include "lib/sifp/sss_sifp_private.h" #define SSS_SIFP_ATTR_NAME "name" static sss_sifp_error sss_sifp_fetch_object_by_attr(sss_sifp_ctx *ctx, const char *method, int attr_type, const void *attr, sss_sifp_object **_object) { sss_sifp_object *object = NULL; char *object_path = NULL; const char *interface = NULL; sss_sifp_error ret; if (method == NULL || attr == NULL || attr_type == DBUS_TYPE_INVALID) { return SSS_SIFP_INVALID_ARGUMENT; } ret = sss_sifp_invoke_find(ctx, method, &object_path, attr_type, attr, DBUS_TYPE_INVALID); if (ret != SSS_SIFP_OK) { goto done; } interface = sss_sifp_get_iface_for_object(object_path); if (interface == NULL) { return SSS_SIFP_INTERNAL_ERROR; } ret = sss_sifp_fetch_object(ctx, object_path, interface, &object); if (ret != SSS_SIFP_OK) { goto done; } *_object = object; ret = SSS_SIFP_OK; done: sss_sifp_free_string(ctx, &object_path); return ret; } static sss_sifp_error sss_sifp_fetch_object_by_name(sss_sifp_ctx *ctx, const char *method, const char *name, sss_sifp_object **_object) { return sss_sifp_fetch_object_by_attr(ctx, method, DBUS_TYPE_STRING, &name, _object); } sss_sifp_error sss_sifp_list_domains(sss_sifp_ctx *ctx, char ***_domains) { sss_sifp_attr **attrs = NULL; char **object_paths = NULL; char **domains = NULL; const char *name = NULL; unsigned int size; unsigned int i; sss_sifp_error ret; if (_domains == NULL) { return SSS_SIFP_INVALID_ARGUMENT; } ret = sss_sifp_invoke_list(ctx, "Domains", &object_paths, DBUS_TYPE_INVALID); if (ret != SSS_SIFP_OK) { goto done; } /* calculate number of paths acquired and allocate memory for domains */ for (size = 0; object_paths[size] != NULL; size++); domains = _alloc_zero(ctx, char *, size + 1); if (domains == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } /* fetch domain name */ for (i = 0; i < size; i++) { ret = sss_sifp_fetch_attr(ctx, object_paths[i], SSS_SIFP_IFACE_DOMAINS, SSS_SIFP_ATTR_NAME, &attrs); if (ret != SSS_SIFP_OK) { goto done; } ret = sss_sifp_find_attr_as_string(attrs, SSS_SIFP_ATTR_NAME, &name); if (ret != SSS_SIFP_OK) { goto done; } domains[i] = sss_sifp_strdup(ctx, name); if (domains[i] == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } sss_sifp_free_attrs(ctx, &attrs); } domains[i] = NULL; *_domains = domains; ret = SSS_SIFP_OK; done: sss_sifp_free_attrs(ctx, &attrs); sss_sifp_free_string_array(ctx, &object_paths); if (ret != SSS_SIFP_OK) { sss_sifp_free_string_array(ctx, &domains); } return ret; } sss_sifp_error sss_sifp_fetch_domain_by_name(sss_sifp_ctx *ctx, const char *name, sss_sifp_object **_domain) { return sss_sifp_fetch_object_by_name(ctx, "DomainByName", name, _domain); } sss_sifp_error sss_sifp_fetch_user_by_uid(sss_sifp_ctx *ctx, uid_t uid, sss_sifp_object **_user) { uint64_t _uid = uid; return sss_sifp_fetch_object_by_attr(ctx, "UserByID", DBUS_TYPE_UINT64, &_uid, _user); } sss_sifp_error sss_sifp_fetch_user_by_name(sss_sifp_ctx *ctx, const char *name, sss_sifp_object **_user) { return sss_sifp_fetch_object_by_name(ctx, "UserByName", name, _user); } sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_sifp_utils.c0000644000000000000000000000007412703456111020040 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.820794192 sssd-1.13.4/src/lib/sifp/sss_sifp_utils.c0000644002412700241270000000554512703456111021520 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "lib/sifp/sss_sifp.h" #include "lib/sifp/sss_sifp_private.h" void *sss_sifp_alloc_zero(sss_sifp_ctx *ctx, size_t size, size_t num) { void *addr = ctx->alloc_fn(size * num, ctx->alloc_pvt); if (addr == NULL) { return NULL; } memset(addr, '\0', size * num); return addr; } void sss_sifp_set_io_error(sss_sifp_ctx *ctx, DBusError *error) { dbus_error_free(ctx->io_error); dbus_error_init(ctx->io_error); dbus_set_error(ctx->io_error, error->name, error->message); } const char * sss_sifp_get_iface_for_object(const char *object_path) { int i; const char *path; static struct { const char *path; const char *iface; } known_types[] = { {SSS_SIFP_PATH_IFP "/Components/", SSS_SIFP_IFACE_COMPONENTS}, {SSS_SIFP_PATH_IFP "/Domains/", SSS_SIFP_IFACE_DOMAINS}, {SSS_SIFP_PATH_IFP "/Services/", SSS_SIFP_IFACE_SERVICES}, {SSS_SIFP_PATH_IFP "/Users/", SSS_SIFP_IFACE_USERS}, {SSS_SIFP_PATH_IFP "/Groups/", SSS_SIFP_IFACE_GROUPS}, {NULL, NULL} }; for (i = 0; known_types[i].path != NULL; i++) { path = known_types[i].path; if (strncmp(path, object_path, strlen(path)) == 0) { return known_types[i].iface; } } return NULL; } char * sss_sifp_strdup(sss_sifp_ctx *ctx, const char *str) { char *result = NULL; size_t str_len; if (str == NULL) { return NULL; } str_len = strlen(str); result = _alloc_zero(ctx, char, str_len + 1); if (result == NULL) { return NULL; } strncpy(result, str, str_len); return result; } char * sss_sifp_strcat(sss_sifp_ctx *ctx, const char *str1, const char *str2) { char *result = NULL; if (str1 == NULL) { return sss_sifp_strdup(ctx, str2); } if (str2 == NULL) { return sss_sifp_strdup(ctx, str1); } size_t len = strlen(str1) + strlen(str2) + 1; result = _alloc_zero(ctx, char, len); if (result == NULL) { return NULL; } strcat(result, str1); strcat(result, str2); return result; } sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_sifp_parser.c0000644000000000000000000000007412703456111020174 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.819794188 sssd-1.13.4/src/lib/sifp/sss_sifp_parser.c0000644002412700241270000004563112703456111021654 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "lib/sifp/sss_sifp.h" #include "lib/sifp/sss_sifp_private.h" #define check_dbus_arg(iter, type, ret, done) do { \ if (dbus_message_iter_get_arg_type((iter)) != (type)) { \ ret = SSS_SIFP_INTERNAL_ERROR; \ goto done; \ } \ } while (0) #define parse_basic(ctx, iter, ret, attr_type, dbus_type, \ data_type, field, done) \ do { \ dbus_type val; \ dbus_message_iter_get_basic(iter, &val); \ attr->type = attr_type; \ attr->data.field = _alloc_zero(ctx, data_type, 1); \ \ if (attr->data.field == NULL) { \ ret = SSS_SIFP_OUT_OF_MEMORY; \ goto done; \ } \ \ attr->data.field[0] = val; \ attr->num_values = 1; \ \ ret = SSS_SIFP_OK; \ } while (0) #define parse_array(ctx, iter, ret, attr_type, dbus_type, \ data_type, field, done) \ do { \ dbus_type val; \ unsigned int i; \ \ attr->type = attr_type; \ if (attr->num_values == 0) { \ attr->data.field = NULL; \ ret = SSS_SIFP_OK; \ goto done; \ } \ \ attr->data.field = _alloc_zero(ctx, data_type, attr->num_values); \ if (attr->data.field == NULL) { \ ret = SSS_SIFP_OUT_OF_MEMORY; \ goto done; \ } \ \ for (i = 0; i < attr->num_values; i++) { \ dbus_message_iter_get_basic(iter, &val); \ attr->data.field[i] = val; \ \ if (!dbus_message_iter_next(iter) && i + 1 < attr->num_values) { \ ret = SSS_SIFP_INTERNAL_ERROR; \ goto done; \ } \ } \ \ ret = SSS_SIFP_OK; \ } while (0) static unsigned int sss_sifp_get_array_length(DBusMessageIter *iter) { DBusMessageIter array_iter; unsigned int size; dbus_message_iter_recurse(iter, &array_iter); if (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_INVALID) { return 0; } size = 0; do { size++; } while (dbus_message_iter_next(&array_iter)); return size; } static void hash_delete_cb(hash_entry_t *item, hash_destroy_enum type, void *pvt) { sss_sifp_ctx *ctx = (sss_sifp_ctx*)pvt; char **values = (char**)(item->value.ptr); int i; if (values == NULL) { return; } for (i = 0; values[i] != NULL; i++) { _free(ctx, values[i]); values[i] = NULL; } _free(ctx, values); item->value.ptr = NULL; } static sss_sifp_error sss_sifp_parse_dict(sss_sifp_ctx *ctx, DBusMessageIter *iter, hash_table_t *table) { DBusMessageIter dict_iter; DBusMessageIter array_iter; sss_sifp_error ret; hash_key_t table_key; hash_value_t table_value; const char *key = NULL; const char *value = NULL; char **values = NULL; unsigned int i; unsigned int num_values; int hret; dbus_message_iter_recurse(iter, &dict_iter); /* get the key */ check_dbus_arg(&dict_iter, DBUS_TYPE_STRING, ret, done); dbus_message_iter_get_basic(&dict_iter, &key); table_key.type = HASH_KEY_STRING; table_key.str = sss_sifp_strdup(ctx, key); if (table_key.str == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } if (!dbus_message_iter_next(&dict_iter)) { ret = SSS_SIFP_INTERNAL_ERROR; goto done; } /* now read the value */ switch (dbus_message_iter_get_arg_type(&dict_iter)) { case DBUS_TYPE_STRING: dbus_message_iter_get_basic(&dict_iter, &value); values = _alloc_zero(ctx, char *, 2); if (values == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } values[0] = sss_sifp_strdup(ctx, value); if (values[0] == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } values[1] = NULL; ret = SSS_SIFP_OK; break; case DBUS_TYPE_ARRAY: num_values = sss_sifp_get_array_length(&dict_iter); if (num_values == 0) { values = NULL; ret = SSS_SIFP_OK; goto done; } if (dbus_message_iter_get_element_type(&dict_iter) != DBUS_TYPE_STRING) { ret = SSS_SIFP_NOT_SUPPORTED; goto done; } dbus_message_iter_recurse(&dict_iter, &array_iter); values = _alloc_zero(ctx, char*, num_values + 1); if (values == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } for (i = 0; i < num_values; i++) { dbus_message_iter_get_basic(&array_iter, &value); values[i] = sss_sifp_strdup(ctx, value); if (values[i] == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } dbus_message_iter_next(&array_iter); } ret = SSS_SIFP_OK; break; default: ret = SSS_SIFP_NOT_SUPPORTED; break; } table_value.type = HASH_VALUE_PTR; table_value.ptr = values; hret = hash_enter(table, &table_key, &table_value); if (hret == HASH_ERROR_NO_MEMORY) { ret = SSS_SIFP_OUT_OF_MEMORY; } else if (hret != HASH_SUCCESS) { ret = SSS_SIFP_INTERNAL_ERROR; } done: if (table_key.str != NULL) { _free(ctx, table_key.str); } if (ret != SSS_SIFP_OK) { if (values != NULL) { for (i = 0; values[i] != NULL; i++) { _free(ctx, values[i]); } _free(ctx, values); } } return ret; } static sss_sifp_error sss_sifp_parse_basic(sss_sifp_ctx *ctx, DBusMessageIter *iter, sss_sifp_attr *attr) { sss_sifp_error ret; switch (dbus_message_iter_get_arg_type(iter)) { case DBUS_TYPE_BOOLEAN: parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_BOOL, dbus_bool_t, bool, boolean, done); break; case DBUS_TYPE_INT16: parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_INT16, int16_t, int16_t, int16, done); break; case DBUS_TYPE_UINT16: parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_UINT16, uint16_t, uint16_t, uint16, done); break; case DBUS_TYPE_INT32: parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_INT32, int32_t, int32_t, int32, done); break; case DBUS_TYPE_UINT32: parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_UINT32, uint32_t, uint32_t, uint32, done); break; case DBUS_TYPE_INT64: parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_INT64, int64_t, int64_t, int64, done); break; case DBUS_TYPE_UINT64: parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_UINT64, uint64_t, uint64_t, uint64, done); break; case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: ; const char *val = NULL; dbus_message_iter_get_basic(iter, &val); attr->type = SSS_SIFP_ATTR_TYPE_STRING; attr->data.str = _alloc_zero(ctx, char*, 1); if (attr->data.str == NULL) { \ ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } attr->data.str[0] = sss_sifp_strdup(ctx, val); if (attr->data.str[0] == NULL) { _free(ctx, attr->data.str); ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } attr->num_values = 1; ret = SSS_SIFP_OK; break; default: ret = SSS_SIFP_INVALID_ARGUMENT; break; } done: return ret; } static sss_sifp_error sss_sifp_parse_array(sss_sifp_ctx *ctx, DBusMessageIter *iter, sss_sifp_attr *attr) { DBusMessageIter array_iter; sss_sifp_error ret; int hret; attr->num_values = sss_sifp_get_array_length(iter); dbus_message_iter_recurse(iter, &array_iter); switch (dbus_message_iter_get_element_type(iter)) { case DBUS_TYPE_BOOLEAN: parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_BOOL, dbus_bool_t, bool, boolean, done); break; case DBUS_TYPE_INT16: parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_INT16, int16_t, int16_t, int16, done); break; case DBUS_TYPE_UINT16: parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_UINT16, uint16_t, uint16_t, uint16, done); break; case DBUS_TYPE_INT32: parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_INT32, int32_t, int32_t, int32, done); break; case DBUS_TYPE_UINT32: parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_UINT32, uint32_t, uint32_t, uint32, done); break; case DBUS_TYPE_INT64: parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_INT64, int64_t, int64_t, int64, done); break; case DBUS_TYPE_UINT64: parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_UINT64, uint64_t, uint64_t, uint64, done); break; case DBUS_TYPE_STRING: case DBUS_TYPE_OBJECT_PATH: ; const char *val; unsigned int i; attr->type = SSS_SIFP_ATTR_TYPE_STRING; if (attr->num_values == 0) { attr->data.str = NULL; ret = SSS_SIFP_OK; goto done; } attr->data.str = _alloc_zero(ctx, char *, attr->num_values); if (attr->data.str == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } for (i = 0; i < attr->num_values; i++) { dbus_message_iter_get_basic(&array_iter, &val); attr->data.str[i] = sss_sifp_strdup(ctx, val); if (attr->data.str[i] == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } if (!dbus_message_iter_next(&array_iter) && i + 1 < attr->num_values) { ret = SSS_SIFP_INTERNAL_ERROR; goto done; } } ret = SSS_SIFP_OK; break; case DBUS_TYPE_DICT_ENTRY: attr->type = SSS_SIFP_ATTR_TYPE_STRING_DICT; if (attr->num_values == 0) { attr->data.str_dict = NULL; ret = SSS_SIFP_OK; goto done; } hret = hash_create_ex(10, &(attr->data.str_dict), 0, 0, 0, 0, ctx->alloc_fn, ctx->free_fn, ctx->alloc_pvt, hash_delete_cb, ctx); if (hret != HASH_SUCCESS) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } for (i = 0; i < attr->num_values; i++) { ret = sss_sifp_parse_dict(ctx, &array_iter, attr->data.str_dict); if (ret != SSS_SIFP_OK) { _free(ctx, attr->data.str_dict); goto done; } if (!dbus_message_iter_next(&array_iter) && i + 1 < attr->num_values) { ret = SSS_SIFP_INTERNAL_ERROR; goto done; } } ret = SSS_SIFP_OK; break; default: ret = SSS_SIFP_INVALID_ARGUMENT; break; } done: if (ret != SSS_SIFP_OK) { if (attr->type == SSS_SIFP_ATTR_TYPE_STRING && attr->data.str != NULL) { for (unsigned int i = 0; attr->data.str[i] != NULL && i < attr->num_values; i++) { _free(ctx, attr->data.str[i]); } _free(ctx, attr->data.str); } else if (attr->type == SSS_SIFP_ATTR_TYPE_STRING_DICT && attr->data.str_dict != NULL) { hash_destroy(attr->data.str_dict); attr->data.str_dict = NULL; } } return ret; } static sss_sifp_error sss_sifp_parse_variant(sss_sifp_ctx *ctx, DBusMessageIter *iter, sss_sifp_attr *attr) { DBusMessageIter variant_iter; sss_sifp_error ret; int type; check_dbus_arg(iter, DBUS_TYPE_VARIANT, ret, done); dbus_message_iter_recurse(iter, &variant_iter); type = dbus_message_iter_get_arg_type(&variant_iter); if (dbus_type_is_basic(type)) { ret = sss_sifp_parse_basic(ctx, &variant_iter, attr); } else { /* container types */ switch (type) { /* case DBUS_TYPE_DICT_ENTRY may only be contained within an array * in variant */ case DBUS_TYPE_ARRAY: ret = sss_sifp_parse_array(ctx, &variant_iter, attr);; break; default: ret = SSS_SIFP_NOT_SUPPORTED; break; } } done: return ret; } /** * DBusMessage format: * variant:value * * Iterator has to point to the variant but not inside the variant. */ static sss_sifp_error sss_sifp_parse_single_attr(sss_sifp_ctx *ctx, const char *name, DBusMessageIter *iter, sss_sifp_attr **_attr) { sss_sifp_attr *attr = NULL; sss_sifp_error ret; attr = _alloc_zero(ctx, sss_sifp_attr, 1); if (attr == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } attr->name = sss_sifp_strdup(ctx, name); if (attr->name == NULL) { _free(ctx, attr); ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } ret = sss_sifp_parse_variant(ctx, iter, attr); if (ret != SSS_SIFP_OK) { _free(ctx, attr->name); _free(ctx, attr); } *_attr = attr; done: return ret; } /** * DBusMessage format: * variant:value */ sss_sifp_error sss_sifp_parse_attr(sss_sifp_ctx *ctx, const char *name, DBusMessage *msg, sss_sifp_attr ***_attrs) { sss_sifp_attr **attrs = NULL; DBusMessageIter iter; sss_sifp_error ret; dbus_message_iter_init(msg, &iter); attrs = _alloc_zero(ctx, sss_sifp_attr *, 2); if (attrs == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } ret = sss_sifp_parse_single_attr(ctx, name, &iter, &attrs[0]); if (ret != SSS_SIFP_OK) { goto done; } *_attrs = attrs; ret = SSS_SIFP_OK; done: if (ret != SSS_SIFP_OK) { sss_sifp_free_attrs(ctx, &attrs); } return ret; } /** * DBusMessage format: * array of dict_entry(string:attr_name, variant:value) */ sss_sifp_error sss_sifp_parse_attr_list(sss_sifp_ctx *ctx, DBusMessage *msg, sss_sifp_attr ***_attrs) { DBusMessageIter iter; DBusMessageIter array_iter; DBusMessageIter dict_iter; sss_sifp_attr **attrs = NULL; const char *name = NULL; unsigned int num_values; sss_sifp_error ret; unsigned int i; dbus_message_iter_init(msg, &iter); check_dbus_arg(&iter, DBUS_TYPE_ARRAY, ret, done); if (dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) { ret = SSS_SIFP_INTERNAL_ERROR; goto done; } num_values = sss_sifp_get_array_length(&iter); attrs = _alloc_zero(ctx, sss_sifp_attr *, num_values + 1); if (attrs == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } dbus_message_iter_recurse(&iter, &array_iter); for (i = 0; i < num_values; i++) { dbus_message_iter_recurse(&array_iter, &dict_iter); /* get the key */ check_dbus_arg(&dict_iter, DBUS_TYPE_STRING, ret, done); dbus_message_iter_get_basic(&dict_iter, &name); if (!dbus_message_iter_next(&dict_iter)) { ret = SSS_SIFP_INTERNAL_ERROR; goto done; } /* now read the value */ check_dbus_arg(&dict_iter, DBUS_TYPE_VARIANT, ret, done); ret = sss_sifp_parse_single_attr(ctx, name, &dict_iter, &attrs[i]); if (ret != SSS_SIFP_OK) { goto done; } dbus_message_iter_next(&array_iter); } *_attrs = attrs; ret = SSS_SIFP_OK; done: if (ret != SSS_SIFP_OK) { sss_sifp_free_attrs(ctx, &attrs); } return ret; } sss_sifp_error sss_sifp_parse_object_path(sss_sifp_ctx *ctx, DBusMessage *msg, char **_object_path) { char *object_path = NULL; const char *dbus_path = NULL; DBusError dbus_error; dbus_bool_t bret; sss_sifp_error ret; dbus_error_init(&dbus_error); bret = dbus_message_get_args(msg, &dbus_error, DBUS_TYPE_OBJECT_PATH, &dbus_path, DBUS_TYPE_INVALID); if (!bret) { sss_sifp_set_io_error(ctx, &dbus_error); ret = SSS_SIFP_IO_ERROR; goto done; } object_path = sss_sifp_strdup(ctx, dbus_path); if (object_path == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } *_object_path = object_path; ret = SSS_SIFP_OK; done: dbus_error_free(&dbus_error); return ret; } sss_sifp_error sss_sifp_parse_object_path_list(sss_sifp_ctx *ctx, DBusMessage *msg, char ***_object_paths) { char **object_paths = NULL; char **dbus_paths = NULL; int num_paths; DBusError dbus_error; dbus_bool_t bret; sss_sifp_error ret; int i; dbus_error_init(&dbus_error); bret = dbus_message_get_args(msg, &dbus_error, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &dbus_paths, &num_paths, DBUS_TYPE_INVALID); if (!bret) { sss_sifp_set_io_error(ctx, &dbus_error); ret = SSS_SIFP_IO_ERROR; goto done; } object_paths = _alloc_zero(ctx, char *, num_paths + 1); if (object_paths == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } for (i = 0; i < num_paths; i++) { object_paths[i] = sss_sifp_strdup(ctx, dbus_paths[i]); if (object_paths[i] == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } } *_object_paths = object_paths; ret = SSS_SIFP_OK; done: dbus_error_free(&dbus_error); dbus_free_string_array(dbus_paths); if (ret != SSS_SIFP_OK && object_paths != NULL) { sss_sifp_free_string_array(ctx, &object_paths); } return ret; } sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_simpleifp.doxy.in0000644000000000000000000000007212703456111021013 xustar0029 atime=1460561772.82078741 29 ctime=1460561774.62879354 sssd-1.13.4/src/lib/sifp/sss_simpleifp.doxy.in0000644002412700241270000017550712703456111022503 0ustar00jhrozekjhrozek00000000000000# Doxyfile 1.6.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = sss_simpleifp # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = sss_simpleifp_doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @abs_top_srcdir@/src/lib/sifp/sss_sifp.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.cpp \ *.cc \ *.c \ *.h \ *.hh \ *.hpp \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.git/* \ */.svn/* \ */cmake/* \ */build/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated # HTML page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NONE # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) # there is already a search function so this one should typically # be disabled. SEARCHENGINE = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_sifp_dbus.c0000644000000000000000000000007412703456111017635 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.816794178 sssd-1.13.4/src/lib/sifp/sss_sifp_dbus.c0000644002412700241270000001153412703456111021310 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "lib/sifp/sss_sifp.h" #include "lib/sifp/sss_sifp_dbus.h" #include "lib/sifp/sss_sifp_private.h" static sss_sifp_error sss_sifp_ifp_call(sss_sifp_ctx *ctx, const char *method, int first_arg_type, va_list ap, DBusMessage **_reply) { DBusMessage *msg = NULL; sss_sifp_error ret; msg = sss_sifp_create_message(SSS_SIFP_PATH_IFP, SSS_SIFP_IFACE_IFP, method); if (msg == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } if (first_arg_type != DBUS_TYPE_INVALID) { dbus_message_append_args_valist(msg, first_arg_type, ap); } ret = sss_sifp_send_message(ctx, msg, _reply); done: if (msg != NULL) { dbus_message_unref(msg); } return ret; } DBusMessage * sss_sifp_create_message(const char *object_path, const char *interface, const char *method) { return dbus_message_new_method_call(SSS_SIFP_IFP, object_path, interface, method); } sss_sifp_error sss_sifp_send_message(sss_sifp_ctx *ctx, DBusMessage *msg, DBusMessage **_reply) { return sss_sifp_send_message_ex(ctx, msg, 5000, _reply); } sss_sifp_error sss_sifp_send_message_ex(sss_sifp_ctx *ctx, DBusMessage *msg, int timeout, DBusMessage **_reply) { DBusMessage *reply = NULL; DBusError dbus_error; sss_sifp_error ret; if (ctx == NULL || msg == NULL) { return SSS_SIFP_INVALID_ARGUMENT; } dbus_error_init(&dbus_error); reply = dbus_connection_send_with_reply_and_block(ctx->conn, msg, timeout, &dbus_error); if (dbus_error_is_set(&dbus_error)) { sss_sifp_set_io_error(ctx, &dbus_error); ret = SSS_SIFP_IO_ERROR; goto done; } if (_reply == NULL) { dbus_message_unref(reply); } else { *_reply = reply; } ret = SSS_SIFP_OK; done: dbus_error_free(&dbus_error); return ret; } sss_sifp_error sss_sifp_invoke_list(sss_sifp_ctx *ctx, const char *method, char ***_object_paths, int first_arg_type, ...) { DBusMessage *reply = NULL; char *dbus_method = NULL; sss_sifp_error ret; va_list ap; if (ctx == NULL || method == NULL || _object_paths == NULL) { return SSS_SIFP_INVALID_ARGUMENT; } dbus_method = sss_sifp_strcat(ctx, "List", method); if (dbus_method == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } va_start(ap, first_arg_type); ret = sss_sifp_ifp_call(ctx, dbus_method, first_arg_type, ap, &reply); va_end(ap); if (ret != SSS_SIFP_OK) { goto done; } ret = sss_sifp_parse_object_path_list(ctx, reply, _object_paths); done: sss_sifp_free_string(ctx, &dbus_method); if (reply != NULL) { dbus_message_unref(reply); } return ret; } sss_sifp_error sss_sifp_invoke_find(sss_sifp_ctx *ctx, const char *method, char **_object_path, int first_arg_type, ...) { DBusMessage *reply = NULL; char *dbus_method = NULL; sss_sifp_error ret; va_list ap; if (ctx == NULL || method == NULL || _object_path == NULL) { return SSS_SIFP_INVALID_ARGUMENT; } dbus_method = sss_sifp_strcat(ctx, "Find", method); if (dbus_method == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } va_start(ap, first_arg_type); ret = sss_sifp_ifp_call(ctx, dbus_method, first_arg_type, ap, &reply); va_end(ap); if (ret != SSS_SIFP_OK) { goto done; } ret = sss_sifp_parse_object_path(ctx, reply, _object_path); done: sss_sifp_free_string(ctx, &dbus_method); if (reply != NULL) { dbus_message_unref(reply); } return ret; } sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_simpleifp.exports0000644000000000000000000000007412703456111021131 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.373792676 sssd-1.13.4/src/lib/sifp/sss_simpleifp.exports0000644002412700241270000000271012703456111022600 0ustar00jhrozekjhrozek00000000000000SSS_SIMPLEIFP_0.0 { # public functions global: sss_sifp_init; sss_sifp_init_ex; sss_sifp_get_last_io_error_name; sss_sifp_get_last_io_error_message; sss_sifp_create_message; sss_sifp_send_message; sss_sifp_send_message_ex; sss_sifp_fetch_attr; sss_sifp_fetch_all_attrs; sss_sifp_fetch_object; sss_sifp_invoke_list; sss_sifp_invoke_find; sss_sifp_find_attr_as_bool; sss_sifp_find_attr_as_int16; sss_sifp_find_attr_as_uint16; sss_sifp_find_attr_as_int32; sss_sifp_find_attr_as_uint32; sss_sifp_find_attr_as_int64; sss_sifp_find_attr_as_uint64; sss_sifp_find_attr_as_string; sss_sifp_find_attr_as_string_dict; sss_sifp_find_attr_as_bool_array; sss_sifp_find_attr_as_int16_array; sss_sifp_find_attr_as_uint16_array; sss_sifp_find_attr_as_int32_array; sss_sifp_find_attr_as_uint32_array; sss_sifp_find_attr_as_int64_array; sss_sifp_find_attr_as_uint64_array; sss_sifp_find_attr_as_string_array; sss_sifp_free; sss_sifp_free_attrs; sss_sifp_free_object; sss_sifp_free_string; sss_sifp_free_string_array; sss_sifp_list_domains; sss_sifp_fetch_domain_by_name; sss_sifp_fetch_user_by_uid; sss_sifp_fetch_user_by_name; # everything else is local local: *; }; sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_sifp_dbus.h0000644000000000000000000000007412703456111017642 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.607793469 sssd-1.13.4/src/lib/sifp/sss_sifp_dbus.h0000644002412700241270000000771312703456111021321 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_SIFP_DBUS_H_ #define SSS_SIFP_DBUS_H_ #include #include /** * @defgroup sss_sifp_dbus Advanced InfoPipe method calls. * * Functions in this module provide a way to reuse sss_sifp connection * to the SSSD's InfoPipe responder. * * This allows the caller to send more sophisticated messages to the InfoPipe * and to use both sss_sifp and D-Bus without the need of maintaining two * separate D-Bus connections. * * However, these functions require the caller to understand the D-Bus * bindings from libdbus. * * @{ */ /** * @brief Create a new method call message for SSSD InfoPipe bus. * * @param[in] object_path D-Bus object path * @param[in] interface D-Bus interface * @param[in] method D-Bus method * * @return D-Bus message. */ DBusMessage * sss_sifp_create_message(const char *object_path, const char *interface, const char *method); /** * @brief Send D-Bus message to SSSD InfoPipe bus with 5 seconds timeout. * * @param[in] ctx sss_sifp context * @param[in] msg D-Bus message * @param[in] _reply D-Bus reply, may be NULL if the caller is not interested * * @return D-Bus message. */ sss_sifp_error sss_sifp_send_message(sss_sifp_ctx *ctx, DBusMessage *msg, DBusMessage **_reply); /** * @brief Send D-Bus message to SSSD InfoPipe bus. * * @param[in] ctx sss_sifp context * @param[in] msg D-Bus message * @param[in] timeout Timeout * @param[in] _reply D-Bus reply, may be NULL if the caller is not interested * * @return D-Bus message. */ sss_sifp_error sss_sifp_send_message_ex(sss_sifp_ctx *ctx, DBusMessage *msg, int timeout, DBusMessage **_reply); /** * @brief List objects that satisfies given conditions. This routine will * invoke List D-Bus method on SSSD InfoPipe interface. Arguments * to this method are given as standard variadic D-Bus arguments. * * @param[in] ctx sss_sifp context * @param[in] method D-Bus method to call without the 'List' prefix * @param[out] _object_paths List of object paths * @param[in] first_arg_type Type of the first D-Bus argument * @param[in] ... D-Bus arguments */ sss_sifp_error sss_sifp_invoke_list(sss_sifp_ctx *ctx, const char *method, char ***_object_paths, int first_arg_type, ...); /** * @brief Find single object that satisfies given conditions. This routine will * invoke Find D-Bus method on SSSD InfoPipe interface. Arguments * to this method are given as standard variadic D-Bus arguments. * * @param[in] ctx sss_sifp context * @param[in] method D-Bus method to call without the 'Find' prefix * @param[out] _object_path Object path * @param[in] first_arg_type Type of the first D-Bus argument * @param[in] ... D-Bus arguments */ sss_sifp_error sss_sifp_invoke_find(sss_sifp_ctx *ctx, const char *method, char **_object_path, int first_arg_type, ...); /** * @} */ #endif /* SSS_SIFP_DBUS_H_ */ sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_sifp.c0000644000000000000000000000007412703456111016620 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.816794178 sssd-1.13.4/src/lib/sifp/sss_sifp.c0000644002412700241270000002410412703456111020270 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "lib/sifp/sss_sifp.h" #include "lib/sifp/sss_sifp_dbus.h" #include "lib/sifp/sss_sifp_private.h" #define DBUS_IFACE_PROP "org.freedesktop.DBus.Properties" static void * default_alloc(size_t size, void *pvt) { return malloc(size); } static void default_free(void *ptr, void *pvt) { free(ptr); } static DBusMessage * sss_sifp_create_prop_msg(const char *object_path, const char *method) { return sss_sifp_create_message(object_path, DBUS_IFACE_PROP, method); } sss_sifp_error sss_sifp_init(sss_sifp_ctx **_ctx) { return sss_sifp_init_ex(NULL, default_alloc, default_free, _ctx); } sss_sifp_error sss_sifp_init_ex(void *alloc_pvt, sss_sifp_alloc_func *alloc_func, sss_sifp_free_func *free_func, sss_sifp_ctx **_ctx) { sss_sifp_ctx *ctx = NULL; DBusConnection *conn = NULL; DBusError dbus_error; sss_sifp_error ret; if (_ctx == NULL || alloc_func == NULL || free_func == NULL) { return SSS_SIFP_INVALID_ARGUMENT; } dbus_error_init(&dbus_error); ctx = alloc_func(sizeof(sss_sifp_ctx), alloc_pvt); if (ctx == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } ctx->conn = NULL; ctx->alloc_fn = alloc_func; ctx->free_fn = free_func; ctx->alloc_pvt = alloc_pvt; ctx->io_error = alloc_func(sizeof(DBusError), alloc_pvt); if (ctx->io_error == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } dbus_error_init(ctx->io_error); conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error); if (dbus_error_is_set(&dbus_error)) { sss_sifp_set_io_error(ctx, &dbus_error); ret = SSS_SIFP_IO_ERROR; goto done; } ctx->conn = conn; *_ctx = ctx; ret = SSS_SIFP_OK; done: if (ret != SSS_SIFP_OK) { sss_sifp_free(&ctx); } dbus_error_free(&dbus_error); return ret; } const char * sss_sifp_get_last_io_error_name(sss_sifp_ctx *ctx) { if (ctx == NULL) { return "Invalid sss_sifp context"; } if (!dbus_error_is_set(ctx->io_error)) { return NULL; } return ctx->io_error->name; } const char * sss_sifp_get_last_io_error_message(sss_sifp_ctx *ctx) { if (ctx == NULL) { return "Invalid sss_sifp context"; } if (!dbus_error_is_set(ctx->io_error)) { return NULL; } return ctx->io_error->message; } sss_sifp_error sss_sifp_fetch_attr(sss_sifp_ctx *ctx, const char *object_path, const char *interface, const char *name, sss_sifp_attr ***_attrs) { DBusMessage *msg = NULL; DBusMessage *reply = NULL; dbus_bool_t bret; sss_sifp_error ret; if (ctx == NULL || object_path == NULL || interface == NULL || name == NULL || _attrs == NULL) { return SSS_SIFP_INVALID_ARGUMENT; } /* Message format: * In: string:interface * In: string:attribute * Out: variant(misc:value) */ msg = sss_sifp_create_prop_msg(object_path, "Get"); if (msg == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } bret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID); if (!bret) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } ret = sss_sifp_send_message(ctx, msg, &reply); if (ret != SSS_SIFP_OK) { goto done; } ret = sss_sifp_parse_attr(ctx, name, reply, _attrs); done: if (msg != NULL) { dbus_message_unref(msg); } if (reply != NULL) { dbus_message_unref(reply); } return ret; } sss_sifp_error sss_sifp_fetch_all_attrs(sss_sifp_ctx *ctx, const char *object_path, const char *interface, sss_sifp_attr ***_attrs) { DBusMessage *msg = NULL; DBusMessage *reply = NULL; dbus_bool_t bret; sss_sifp_error ret; if (ctx == NULL || object_path == NULL || interface == NULL || _attrs == NULL) { return SSS_SIFP_INVALID_ARGUMENT; } msg = sss_sifp_create_prop_msg(object_path, "GetAll"); if (msg == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } bret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &interface, DBUS_TYPE_INVALID); if (!bret) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } ret = sss_sifp_send_message(ctx, msg, &reply); if (ret != SSS_SIFP_OK) { goto done; } ret = sss_sifp_parse_attr_list(ctx, reply, _attrs); done: if (msg != NULL) { dbus_message_unref(msg); } if (reply != NULL) { dbus_message_unref(reply); } return ret; } sss_sifp_error sss_sifp_fetch_object(sss_sifp_ctx *ctx, const char *object_path, const char *interface, sss_sifp_object **_object) { sss_sifp_object *object = NULL; sss_sifp_attr **attrs = NULL; const char *name = NULL; sss_sifp_error ret; if (ctx == NULL || object_path == NULL || interface == NULL || _object == NULL) { return SSS_SIFP_INVALID_ARGUMENT; } ret = sss_sifp_fetch_all_attrs(ctx, object_path, interface, &attrs); if (ret != SSS_SIFP_OK) { goto done; } ret = sss_sifp_find_attr_as_string(attrs, "name", &name); if (ret != SSS_SIFP_OK) { goto done; } object = _alloc_zero(ctx, sss_sifp_object, 1); if (object == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } object->attrs = attrs; object->name = sss_sifp_strdup(ctx, name); if (object->name == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } object->object_path = sss_sifp_strdup(ctx, object_path); if (object->object_path == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } object->interface = sss_sifp_strdup(ctx, interface); if (object->interface == NULL) { ret = SSS_SIFP_OUT_OF_MEMORY; goto done; } *_object = object; ret = SSS_SIFP_OK; done: if (ret != SSS_SIFP_OK) { sss_sifp_free_object(ctx, &object); } return ret; } void sss_sifp_free(sss_sifp_ctx **_ctx) { sss_sifp_ctx *ctx = NULL; if (_ctx == NULL || *_ctx == NULL) { return; } ctx = *_ctx; if (ctx->conn != NULL) { dbus_connection_unref(ctx->conn); } if (ctx->io_error != NULL) { dbus_error_free(ctx->io_error); _free(ctx, ctx->io_error); } _free(ctx, ctx); *_ctx = NULL; return; } void sss_sifp_free_attrs(sss_sifp_ctx *ctx, sss_sifp_attr ***_attrs) { sss_sifp_attr **attrs = NULL; unsigned int i, j; if (_attrs == NULL || *_attrs == NULL) { return; } attrs = *_attrs; for (i = 0; attrs[i] != NULL; i++) { switch (attrs[i]->type) { case SSS_SIFP_ATTR_TYPE_BOOL: _free(ctx, attrs[i]->data.boolean); break; case SSS_SIFP_ATTR_TYPE_INT16: _free(ctx, attrs[i]->data.int16); break; case SSS_SIFP_ATTR_TYPE_UINT16: _free(ctx, attrs[i]->data.uint16); break; case SSS_SIFP_ATTR_TYPE_INT32: _free(ctx, attrs[i]->data.int32); break; case SSS_SIFP_ATTR_TYPE_UINT32: _free(ctx, attrs[i]->data.uint32); break; case SSS_SIFP_ATTR_TYPE_INT64: _free(ctx, attrs[i]->data.int64); break; case SSS_SIFP_ATTR_TYPE_UINT64: _free(ctx, attrs[i]->data.uint64); break; case SSS_SIFP_ATTR_TYPE_STRING: for (j = 0; j < attrs[i]->num_values; j++) { _free(ctx, attrs[i]->data.str[j]); } _free(ctx, attrs[i]->data.str); break; case SSS_SIFP_ATTR_TYPE_STRING_DICT: if (attrs[i]->data.str_dict != NULL) { hash_destroy(attrs[i]->data.str_dict); } attrs[i]->data.str_dict = NULL; break; } _free(ctx, attrs[i]->name); _free(ctx, attrs[i]); } _free(ctx, attrs); *_attrs = NULL; } void sss_sifp_free_object(sss_sifp_ctx *ctx, sss_sifp_object **_object) { sss_sifp_object *object = NULL; if (_object == NULL || *_object == NULL) { return; } object = *_object; sss_sifp_free_attrs(ctx, &object->attrs); _free(ctx, object->object_path); _free(ctx, object->interface); _free(ctx, object->name); _free(ctx, object); *_object = NULL; } void sss_sifp_free_string(sss_sifp_ctx *ctx, char **_str) { if (_str == NULL || *_str == NULL) { return; } _free(ctx, *_str); *_str = NULL; } void sss_sifp_free_string_array(sss_sifp_ctx *ctx, char ***_str_array) { char **str_array = NULL; int i; if (_str_array == NULL || *_str_array == NULL) { return; } str_array = *_str_array; for (i = 0; str_array[i] != NULL; i++) { _free(ctx, str_array[i]); } _free(ctx, str_array); *_str_array = NULL; } sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_sifp_attrs.c0000644000000000000000000000007412703456111020035 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.817794181 sssd-1.13.4/src/lib/sifp/sss_sifp_attrs.c0000644002412700241270000002603412703456111021511 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "lib/sifp/sss_sifp.h" #include "lib/sifp/sss_sifp_private.h" #define GET_ATTR(attrs, name, rtype, field, out, ret) do { \ sss_sifp_attr *attr = sss_sifp_find_attr(attrs, name); \ \ if (attr == NULL) { \ ret = SSS_SIFP_ATTR_MISSING; \ break; \ } \ \ if (attr->type != rtype) { \ ret = SSS_SIFP_INCORRECT_TYPE; \ break; \ } \ \ if (attr->data.field == NULL) { \ ret = SSS_SIFP_ATTR_NULL; \ break; \ } \ \ out = attr->data.field[0]; \ \ ret = SSS_SIFP_OK; \ } while (0) #define GET_ATTR_ARRAY(attrs, name, rtype, field, out_num, out_val, ret) \ do { \ sss_sifp_attr *attr = sss_sifp_find_attr(attrs, name); \ \ if (attr == NULL) { \ ret = SSS_SIFP_ATTR_MISSING; \ break; \ } \ \ if (attr->type != rtype) { \ ret = SSS_SIFP_INCORRECT_TYPE; \ break; \ } \ \ if (attr->data.field == NULL) { \ out_num = 0; \ out_val = NULL; \ ret = SSS_SIFP_ATTR_NULL; \ break; \ } \ \ out_num = attr->num_values; \ out_val = attr->data.field; \ \ ret = SSS_SIFP_OK; \ } while (0) static sss_sifp_attr *sss_sifp_find_attr(sss_sifp_attr **attrs, const char *name) { int i; if (attrs == NULL || name == NULL) { return NULL; } for (i = 0; attrs[i] != NULL; i++) { if (strcmp(attrs[i]->name, name) == 0) { return attrs[i]; } } return NULL; } sss_sifp_error sss_sifp_find_attr_as_bool(sss_sifp_attr **attrs, const char *name, bool *_value) { sss_sifp_error ret; GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_BOOL, boolean, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_int16(sss_sifp_attr **attrs, const char *name, int16_t *_value) { sss_sifp_error ret; GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_INT16, int16, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_uint16(sss_sifp_attr **attrs, const char *name, uint16_t *_value) { sss_sifp_error ret; GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_UINT16, uint16, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_int32(sss_sifp_attr **attrs, const char *name, int32_t *_value) { sss_sifp_error ret; GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_INT32, int32, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_uint32(sss_sifp_attr **attrs, const char *name, uint32_t *_value) { sss_sifp_error ret; GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_UINT32, uint32, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_int64(sss_sifp_attr **attrs, const char *name, int64_t *_value) { sss_sifp_error ret; GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_INT64, int64, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_uint64(sss_sifp_attr **attrs, const char *name, uint64_t *_value) { sss_sifp_error ret; GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_UINT64, uint64, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_string(sss_sifp_attr **attrs, const char *name, const char **_value) { sss_sifp_error ret; const char *value = NULL; GET_ATTR(attrs, name, SSS_SIFP_ATTR_TYPE_STRING, str, value, ret); if (ret == SSS_SIFP_ATTR_NULL) { *_value = NULL; return ret; } *_value = value; return ret; } sss_sifp_error sss_sifp_find_attr_as_string_dict(sss_sifp_attr **attrs, const char *name, hash_table_t **_value) { sss_sifp_attr *attr = sss_sifp_find_attr(attrs, name); if (attr == NULL) { return SSS_SIFP_ATTR_MISSING; } if (attr->type != SSS_SIFP_ATTR_TYPE_STRING_DICT) { return SSS_SIFP_INCORRECT_TYPE; } if (attr->data.str_dict == NULL) { *_value = NULL; return SSS_SIFP_ATTR_NULL; } *_value = attr->data.str_dict; return SSS_SIFP_OK; } /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * * @return Attribute values or NULL if it is not found. */ sss_sifp_error sss_sifp_find_attr_as_bool_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, bool **_value) { sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_BOOL, boolean, *_num_values, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_int16_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, int16_t **_value) { sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_INT16, int16, *_num_values, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_uint16_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, uint16_t **_value) { sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_UINT16, uint16, *_num_values, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_int32_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, int32_t **_value) { sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_INT32, int32, *_num_values, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_uint32_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, uint32_t **_value) { sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_UINT32, uint32, *_num_values, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_int64_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, int64_t **_value) { sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_INT64, int64, *_num_values, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_uint64_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, uint64_t **_value) { sss_sifp_error ret; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_UINT64, uint64, *_num_values, *_value, ret); return ret; } sss_sifp_error sss_sifp_find_attr_as_string_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, const char * const **_value) { sss_sifp_error ret; char **value; GET_ATTR_ARRAY(attrs, name, SSS_SIFP_ATTR_TYPE_STRING, str, *_num_values, value, ret); if (ret == SSS_SIFP_OK || ret == SSS_SIFP_ATTR_NULL) { *_value = (const char * const *)value; } return ret; } sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_simpleifp.pc.in0000644000000000000000000000007412703456111020434 xustar0030 atime=1460561772.808787369 30 ctime=1460561774.629793544 sssd-1.13.4/src/lib/sifp/sss_simpleifp.pc.in0000644002412700241270000000046612703456111022111 0ustar00jhrozekjhrozek00000000000000prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: sss_simpleifp Description: A library that simplifies work with the InfoPipe responder Version: @VERSION@ Requires: dbus-1, dhash Libs: -L@libdir@ -lsss_simpleifp Cflags: -I${includedir} URL: http://fedorahosted.org/sssd/ sssd-1.13.4/src/lib/sifp/PaxHeaders.16287/sss_sifp.h0000644000000000000000000000007412703456111016625 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.606793466 sssd-1.13.4/src/lib/sifp/sss_sifp.h0000644002412700241270000003615112703456111020302 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SSS_SIFP_H_ #define SSS_SIFP_H_ #include #include #include #include /** * @defgroup sss_simpleifp Simple interface to SSSD InfoPipe responder. * Libsss_simpleifp provides a synchronous interface to simplify basic * communication with SSSD InfoPipe responder. * * This interface is not a full replacement for the complete D-Bus API and it * provides only access to the most common tasks like fetching attributes * of SSSD objects. * * If there is a need for a more sophisticated communication with the SSSD * InfoPipe responder a D-Bus API of your choice should be used. * * @{ */ /** SSSD InfoPipe bus address */ #define SSS_SIFP_IFP "org.freedesktop.sssd.infopipe" /** SSSD InfoPipe interface */ #define SSS_SIFP_IFACE_IFP SSS_SIFP_IFP #define SSS_SIFP_IFACE_COMPONENTS "org.freedesktop.sssd.infopipe.Components" #define SSS_SIFP_IFACE_SERVICES "org.freedesktop.sssd.infopipe.Services" #define SSS_SIFP_IFACE_DOMAINS "org.freedesktop.sssd.infopipe.Domains" #define SSS_SIFP_IFACE_USERS "org.freedesktop.sssd.infopipe.Users" #define SSS_SIFP_IFACE_GROUPS "org.freedesktop.sssd.infopipe.Groups" /** * Opaque libsss_sifp context. One context shall not be used by multiple * threads. Each thread needs to create and use its own context. * * @see sss_sifp_init * @see sss_sifp_init_ex */ typedef struct sss_sifp_ctx sss_sifp_ctx; /** * Typedef for memory allocation functions */ typedef void (sss_sifp_free_func)(void *ptr, void *pvt); typedef void *(sss_sifp_alloc_func)(size_t size, void *pvt); /** * Error codes used by libsss_sifp */ typedef enum sss_sifp_error { /** Success */ SSS_SIFP_OK = 0, /** Ran out of memory during processing */ SSS_SIFP_OUT_OF_MEMORY, /** Invalid argument */ SSS_SIFP_INVALID_ARGUMENT, /** * Input/output error * * @see sss_sifp_get_last_io_error() to get more information */ SSS_SIFP_IO_ERROR, /** Internal error */ SSS_SIFP_INTERNAL_ERROR, /** Operation not supported */ SSS_SIFP_NOT_SUPPORTED, /** Attribute does not exist */ SSS_SIFP_ATTR_MISSING, /** Attribute does not have any value set */ SSS_SIFP_ATTR_NULL, /** Incorrect attribute type */ SSS_SIFP_INCORRECT_TYPE, /** Always last */ SSS_SIFP_ERROR_SENTINEL } sss_sifp_error; /** * D-Bus object attribute */ typedef struct sss_sifp_attr sss_sifp_attr; /** * D-Bus object */ typedef struct sss_sifp_object { char *name; char *object_path; char *interface; sss_sifp_attr **attrs; } sss_sifp_object; /** * @brief Initialize sss_sifp context using default allocator (malloc) * * @param[out] _ctx sss_sifp context */ sss_sifp_error sss_sifp_init(sss_sifp_ctx **_ctx); /** * @brief Initialize sss_sifp context * * @param[in] alloc_pvt Private data for allocation routine * @param[in] alloc_func Function to allocate memory for the context, if * NULL malloc() is used * @param[in] free_func Function to free the memory of the context, if * NULL free() is used * @param[out] _ctx sss_sifp context */ sss_sifp_error sss_sifp_init_ex(void *alloc_pvt, sss_sifp_alloc_func *alloc_func, sss_sifp_free_func *free_func, sss_sifp_ctx **_ctx); /** * @brief Return last error name from underlying D-Bus communication * * @param[in] ctx sss_sifp context * @return Error message or NULL if no error occurred during last D-Bus call. */ const char * sss_sifp_get_last_io_error_name(sss_sifp_ctx *ctx); /** * @brief Return last error message from underlying D-Bus communication * * @param[in] ctx sss_sifp context * @return Error message or NULL if no error occurred during last D-Bus call. */ const char * sss_sifp_get_last_io_error_message(sss_sifp_ctx *ctx); /** * @brief Fetch selected attributes of given object. * * @param[in] ctx sss_sifp context * @param[in] object_path D-Bus object path * @param[in] interface D-Bus interface * @param[in] name Name of desired attribute * @param[out] _attrs List of acquired attributes */ sss_sifp_error sss_sifp_fetch_attr(sss_sifp_ctx *ctx, const char *object_path, const char *interface, const char *name, sss_sifp_attr ***_attrs); /** * @brief Fetch all attributes of given object. * * @param[in] ctx sss_sifp context * @param[in] object_path D-Bus object path * @param[in] interface D-Bus interface * @param[out] _attrs Acquired attributes */ sss_sifp_error sss_sifp_fetch_all_attrs(sss_sifp_ctx *ctx, const char *object_path, const char *interface, sss_sifp_attr ***_attrs); /** * @brief Fetch D-Bus object. * * @param[in] ctx sss_sifp context * @param[in] object_path D-Bus object path * @param[in] interface D-Bus interface * @param[out] _object Object and its attributes */ sss_sifp_error sss_sifp_fetch_object(sss_sifp_ctx *ctx, const char *object_path, const char *interface, sss_sifp_object **_object); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_sifp_error sss_sifp_find_attr_as_bool(sss_sifp_attr **attrs, const char *name, bool *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_sifp_error sss_sifp_find_attr_as_int16(sss_sifp_attr **attrs, const char *name, int16_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_sifp_error sss_sifp_find_attr_as_uint16(sss_sifp_attr **attrs, const char *name, uint16_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_sifp_error sss_sifp_find_attr_as_int32(sss_sifp_attr **attrs, const char *name, int32_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_sifp_error sss_sifp_find_attr_as_uint32(sss_sifp_attr **attrs, const char *name, uint32_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_sifp_error sss_sifp_find_attr_as_int64(sss_sifp_attr **attrs, const char *name, int64_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_sifp_error sss_sifp_find_attr_as_uint64(sss_sifp_attr **attrs, const char *name, uint64_t *_value); /** * @brief Find attribute in list and return its value. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_sifp_error sss_sifp_find_attr_as_string(sss_sifp_attr **attrs, const char *name, const char **_value); /** * @brief Find attribute in list and return its value. * * The dictionary is stored in dhash table, the values * are pointers to NULL-terminated string array. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _value Output value */ sss_sifp_error sss_sifp_find_attr_as_string_dict(sss_sifp_attr **attrs, const char *name, hash_table_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _value Output array */ sss_sifp_error sss_sifp_find_attr_as_bool_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, bool **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _value Output array */ sss_sifp_error sss_sifp_find_attr_as_int16_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, int16_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _value Output array */ sss_sifp_error sss_sifp_find_attr_as_uint16_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, uint16_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _value Output array */ sss_sifp_error sss_sifp_find_attr_as_int32_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, int32_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _value Output array */ sss_sifp_error sss_sifp_find_attr_as_uint32_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, uint32_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _value Output array */ sss_sifp_error sss_sifp_find_attr_as_int64_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, int64_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _value Output array */ sss_sifp_error sss_sifp_find_attr_as_uint64_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, uint64_t **_value); /** * @brief Find attribute in list and return its values. * * @param[in] attrs Attributes * @param[in] name Name of the attribute to find * @param[out] _num_values Number of values in the array * @param[out] _value Output array */ sss_sifp_error sss_sifp_find_attr_as_string_array(sss_sifp_attr **attrs, const char *name, unsigned int *_num_values, const char * const **_value); /** * @brief Free sss_sifp context and set it to NULL. * * @param[in,out] _ctx sss_sifp context */ void sss_sifp_free(sss_sifp_ctx **_ctx); /** * @brief Free attribute list and set it to NULL. * * @param[in] ctx sss_sifp context * @param[in,out] _attrs Attributes */ void sss_sifp_free_attrs(sss_sifp_ctx *ctx, sss_sifp_attr ***_attrs); /** * @brief Free sss_sifp object and set it to NULL. * * @param[in] ctx sss_sifp context * @param[in,out] _object Object */ void sss_sifp_free_object(sss_sifp_ctx *ctx, sss_sifp_object **_object); /** * @brief Free string and set it to NULL. * * @param[in] ctx sss_sifp context * @param[in,out] _str String */ void sss_sifp_free_string(sss_sifp_ctx *ctx, char **_str); /** * @brief Free array of strings and set it to NULL. * * @param[in] ctx sss_sifp context * @param[in,out] _str_array Array of strings */ void sss_sifp_free_string_array(sss_sifp_ctx *ctx, char ***_str_array); /** * @} */ /** * @defgroup common Most common use cases of SSSD InfoPipe responder. * @{ */ /** * @brief List names of available domains. * * @param[in] ctx sss_sifp context * @param[out] _domains List of domain names */ sss_sifp_error sss_sifp_list_domains(sss_sifp_ctx *ctx, char ***_domains); /** * @brief Fetch all information about domain by name. * * @param[in] ctx sss_sifp context * @param[in] name Domain name * @param[out] _domain Domain object */ sss_sifp_error sss_sifp_fetch_domain_by_name(sss_sifp_ctx *ctx, const char *name, sss_sifp_object **_domain); /** * @brief Fetch all information about user by uid. * * @param[in] ctx sss_sifp context * @param[in] uid User ID * @param[out] _user User object */ sss_sifp_error sss_sifp_fetch_user_by_uid(sss_sifp_ctx *ctx, uid_t uid, sss_sifp_object **_user); /** * @brief Fetch all information about user by name. * * @param[in] ctx sss_sifp context * @param[in] name User name * @param[out] _user User object */ sss_sifp_error sss_sifp_fetch_user_by_name(sss_sifp_ctx *ctx, const char *name, sss_sifp_object **_user); /** * @} */ #endif /* SSS_SIFP_H_ */ sssd-1.13.4/src/PaxHeaders.16287/doxy.config.in0000644000000000000000000000007412703456111015673 xustar0030 atime=1460561772.585786613 30 ctime=1460561774.624793527 sssd-1.13.4/src/doxy.config.in0000644002412700241270000023522712703456111017355 0ustar00jhrozekjhrozek00000000000000# Doxyfile 1.8.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = @PACKAGE_NAME@ # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ "The $name widget" \ "The $name file" \ is \ provides \ specifies \ contains \ represents \ a \ an \ the # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. Note that you specify absolute paths here, but also # relative paths, which will be relative from the directory where doxygen is # started. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, # and language is one of the parsers supported by doxygen: IDL, Java, # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, # C++. For instance to make doxygen treat .inc files as Fortran files (default # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented classes, # or namespaces to their corresponding documentation. Such a link can be # prevented in individual cases by by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES (the # default) will make doxygen replace the get and set methods by a property in # the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if section-label ... \endif # and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. Do not use # file names with spaces, bibtex cannot handle them. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @abs_top_srcdir@/src/confdb/confdb.h \ @abs_top_srcdir@/src/providers/data_provider.h \ @abs_top_srcdir@/src/sss_client/sss_cli.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.cpp \ *.cc \ *.c \ *.h \ *.hh \ *.hpp \ *.dox # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */.git/* \ */.svn/* \ */cmake/* \ */build/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = # If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page (index.html). # This can be useful if you have a project on for instance GitHub and want reuse # the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If left blank doxygen will # generate a default style sheet. Note that it is recommended to use # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET # since it does not replace the standard style sheet and is therefor more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user # can expand and collapse entries dynamically later on. Doxygen will expand # the tree to such a level that at most the specified number of entries are # visible (unless a fully collapsed tree already exceeds this amount). # So setting the number of entries 1 will produce a full collapsed tree by # default. 0 is a special value representing an infinite number of entries # and will result in a full expanded tree by default. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely # identify the documentation publisher. This should be a reverse domain-name # style string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NONE # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. # There are two flavours of web server based search depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. # See the manual for details. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain # the search results. Doxygen ships with an example indexer (doxyindexer) and # search engine (doxysearch.cgi) which are based on the open source search engine # library Xapian. See the manual for configuration details. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will returned the search results when EXTERNAL_SEARCH is enabled. # Doxygen ships with an example search engine (doxysearch) which is based on # the open source search engine library Xapian. See the manual for configuration # details. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. SEARCHDATA_FILE = searchdata.xml # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through other # doxygen projects that are not otherwise connected via tags files, but are # all added to the same search index. Each project needs to have a tag file set # via GENERATE_TAGFILE. The search mapping then maps the name of the tag file # to a relative location where the documentation can be found, # similar to the # TAGFILES option but without actually processing the tag file. # The format is: EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # managable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES sssd-1.13.4/src/PaxHeaders.16287/tests0000644000000000000000000000013212703463560014202 xustar0030 mtime=1460561776.058798389 30 atime=1460561776.118798593 30 ctime=1460561776.058798389 sssd-1.13.4/src/tests/0000755002412700241270000000000012703463560015733 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/tests/PaxHeaders.16287/common_dbus.c0000644000000000000000000000007412703456111016727 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.963794676 sssd-1.13.4/src/tests/common_dbus.c0000644002412700241270000001315212703456111020400 0ustar00jhrozekjhrozek00000000000000/* SSSD Common utilities for dbus based tests. Authors: Stef Walter Copyright (C) Red Hat, Inc 2014 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include "tests/common.h" struct mock_server { char *temp_dir; char *dbus_address; pid_t pid; DBusConnection *client; /* Used for synchronization */ int sync_fds[2]; /* Only used during init */ sbus_server_conn_init_fn init_fn; void *init_pvt_data; }; /* * If you think we're going to do full error propagation during tests ... * you're going to have a bad time (reading this code) */ #define verify_eq(x, y) \ do { if ((x) != (y)) { fprintf(stderr, "failed: %s == %s\n", #x, #y); abort(); } } while (0) #define verify_neq(x, y) \ do { if ((x) == (y)) { fprintf(stderr, "failed: %s != %s\n", #x, #y); abort(); } } while (0) static int mock_server_cleanup(struct mock_server *mock) { int child_status; const char *file; struct stat sb; dbus_connection_close(mock->client); dbus_connection_unref(mock->client); /* Tell the server thread to quit */ verify_eq (write(mock->sync_fds[0], "X", 1), 1); /* Wait for the server child, it always returns mock */ verify_eq (waitpid(mock->pid, &child_status, 0), mock->pid); verify_eq (child_status, 0); file = strchr(mock->dbus_address, '/'); if (stat(file, &sb) == 0) { verify_eq (unlink(file), 0); } verify_eq (rmdir(mock->temp_dir), 0); return EOK; } static int on_accept_connection(struct sbus_connection *conn, void *data) { struct mock_server *mock = data; verify_eq (mock->init_fn(conn, mock->init_pvt_data), EOK); /* Synchronization point: test_dbus_setup_mock() should return */ verify_eq (write(mock->sync_fds[1], "X", 1), 1); return EOK; } static void on_sync_fd_written(struct tevent_context *loop, struct tevent_fd *fde, uint16_t flags, void *data) { bool *stop_server = data; *stop_server = true; } static void mock_server_child(void *data) { struct mock_server *mock = data; struct tevent_context *loop; struct sbus_connection *server; bool stop_server = false; TALLOC_CTX *ctx; ctx = talloc_new(NULL); loop = tevent_context_init(ctx); verify_eq (sbus_new_server(ctx, loop, mock->dbus_address, geteuid(), getegid(), false, &server, on_accept_connection, mock), EOK); tevent_add_fd(loop, ctx, mock->sync_fds[1], TEVENT_FD_READ, on_sync_fd_written, &stop_server); /* Synchronization point: test_dbus_setup_mock() should connect */ verify_eq (write(mock->sync_fds[1], "X", 1), 1); /* Do the loop */ while(!stop_server) { verify_eq (tevent_loop_once(loop), 0); } /* TODO: sbus doesn't support cleanup of a server */ talloc_free(ctx); } struct DBusConnection * test_dbus_setup_mock(TALLOC_CTX *mem_ctx, struct tevent_context *loop, sbus_server_conn_init_fn init_fn, void *init_pvt_data) { struct mock_server *mock; char dummy; mock = talloc_zero(mem_ctx, struct mock_server); talloc_set_destructor(mock, mock_server_cleanup); mock->init_fn = init_fn; mock->init_pvt_data = init_pvt_data; mock->temp_dir = mkdtemp(talloc_strdup(mock, "/tmp/sssd-dbus-tests.XXXXXX")); verify_neq (mock->temp_dir, NULL); mock->dbus_address = talloc_asprintf(mock, "unix:path=%s/sbus", mock->temp_dir); verify_neq (mock->dbus_address, NULL); /* We use an fd pair as a synchronization device, integrates with tevent well */ verify_eq (socketpair(PF_LOCAL, SOCK_STREAM, 0, mock->sync_fds), 0); /* Run the dbus server in a child process */ mock->pid = fork(); if (mock->pid == 0) { mock_server_child(mock); _exit(0); } verify_neq (mock->pid, -1); /* Synchronization point: wait for sync point in mock_server_child */ verify_eq (read(mock->sync_fds[0], &dummy, 1), 1); /* Open a shared D-BUS connection to the address */ mock->client = dbus_connection_open_private(mock->dbus_address, NULL); verify_neq (mock->client, NULL); /* Synchronization point: wait for sync point in on_accept_connection */ verify_eq (read(mock->sync_fds[0], &dummy, 1), 1); return mock->client; } DBusMessage * test_dbus_call_sync(DBusConnection *conn, const char *object_path, const char *interface, const char *method, DBusError *error, int first_arg_type, ...) { DBusMessage *message; DBusMessage *reply; va_list va; message = dbus_message_new_method_call(NULL, object_path, interface, method); verify_neq(message, NULL); va_start(va, first_arg_type); verify_eq(dbus_message_append_args_valist(message, first_arg_type, va), TRUE); va_end(va); reply = dbus_connection_send_with_reply_and_block(conn, message, -1, error); dbus_message_unref(message); return reply; } sssd-1.13.4/src/tests/PaxHeaders.16287/stress-tests.c0000644000000000000000000000007412703456111017105 xustar0030 atime=1460561751.658715654 30 ctime=1460561775.022794877 sssd-1.13.4/src/tests/stress-tests.c0000644002412700241270000002075612703456111020566 0ustar00jhrozekjhrozek00000000000000/* SSSD Stress tests Copyright (C) Jakub Hrozek 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "tests/common.h" #define DEFAULT_START 10 #define DEFAULT_STOP 20 #define NAME_SIZE 255 #define CHUNK 64 /* How many tests failed */ int failure_count; /* Be chatty */ int verbose; /* * Look up one user. If the user is not found using getpwnam, the success * or failure depends on enoent_fail being set. */ int test_lookup_user(const char *name, int enoent_fail) { struct passwd *pwd = NULL; int ret = 0; int error; errno = 0; pwd = getpwnam(name); error = errno; if (pwd == NULL) { if (error == 0 || error == ENOENT) { ret = (enoent_fail == 1) ? ENOENT : 0; } } if (ret != 0 && verbose) { fprintf(stderr, "getpwnam failed (name: %s): errno = %d, error = %s\n", name, ret, strerror(ret)); } return ret; } /* * Look up one group. If the user is not found using getgrnam, the success * or failure depends on enoent_fail being set. */ int test_lookup_group(const char *name, int enoent_fail) { struct group *grp = NULL; int ret = 0; errno = 0; grp = getgrnam(name); if (grp == NULL) { if (errno == 0 || errno == ENOENT) { ret = enoent_fail ? ENOENT : 0; } } if (ret != 0 && verbose) { fprintf(stderr, "getgrnam failed (name %s): errno = %d, error = %s\n", name, ret, strerror(ret)); } return ret; } int run_one_testcase(const char *name, int group, int enoent_fail) { if (group) { return test_lookup_group(name, enoent_fail); } else { return test_lookup_user(name, enoent_fail); } } /* * Beware, has side-effects: changes global variable failure_count */ void child_handler(int signum) { int status, ret; while ((ret = wait(&status)) > 0) { if (ret == -1) { perror("wait"); exit(EXIT_FAILURE); } if (WIFEXITED(status)) { ret = WEXITSTATUS(status); if (ret) { if (verbose) { fprintf(stderr, "A child exited with error code %d\n", WEXITSTATUS(status)); } ++failure_count; } } else ++failure_count; } } int generate_names(TALLOC_CTX *mem_ctx, const char *prefix, int start, int stop, char ***_out) { char **out; int num_names = stop-start+1; int idx = 0; out = talloc_array(mem_ctx, char *, num_names+1); if (out == NULL) { return ENOMEM; } for (idx = 0; idx < num_names; ++idx) { out[idx] = talloc_asprintf(mem_ctx, "%s%d", prefix, idx); if (out[idx] == NULL) { return ENOMEM; } } out[idx] = NULL; *_out = out; return EOK; } int read_names(TALLOC_CTX *mem_ctx, FILE *stream, char ***_out) { char one_name[NAME_SIZE]; int n = 0; int array_size = CHUNK; int ret; char **out; out = talloc_array(mem_ctx, char *, CHUNK+1); if (out == NULL) { return ENOMEM; } while (fgets(one_name, NAME_SIZE, stream)) { out[n] = talloc_strdup(mem_ctx, one_name); if (out[n] == NULL) { return ENOMEM; } if ((n++ % CHUNK) == 0) { array_size += CHUNK; out = talloc_realloc(mem_ctx, out, char *, array_size); if (out == NULL) { return ENOMEM; } } } if ((ret = ferror(stream))) { return ret; } out[n] = NULL; *_out = out; return EOK; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int pc_start=DEFAULT_START; int pc_stop=DEFAULT_STOP; int pc_enoent_fail=0; int pc_groups=0; int pc_verbosity = 0; char *pc_prefix = NULL; TALLOC_CTX *ctx = NULL; char **names = NULL; int status, idx, ret; pid_t pid; struct sigaction action, old_action; struct poptOption long_options[] = { POPT_AUTOHELP { "groups", 'g', POPT_ARG_NONE, &pc_groups, 0, "Lookup in groups instead of users", NULL }, { "prefix", '\0', POPT_ARG_STRING, &pc_prefix, 0, "The username prefix", NULL }, { "start", '\0', POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &pc_start, 0, "Start value to append to prefix", NULL }, { "stop", '\0', POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &pc_stop, 0, "End value to append to prefix", NULL }, { "enoent-fail", '\0', POPT_ARG_NONE, &pc_enoent_fail, 0, "Fail on not getting the requested NSS data (default: No)", NULL }, { "verbose", 'v', POPT_ARG_NONE, 0, 'v', "Be verbose", NULL }, POPT_TABLEEND }; /* parse the params */ pc = poptGetContext(argv[0], argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case 'v': pc_verbosity = 1; break; default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); tests_set_cwd(); verbose = pc_verbosity; if (pc_prefix) { ret = generate_names(ctx, pc_prefix, pc_start, pc_stop, &names); if (ret != EOK) { if (verbose) { errno = ret; perror("generate_names"); } exit(EXIT_FAILURE); } } else { ret = read_names(ctx, stdin, &names); if (ret != EOK) { if (verbose) { errno = ret; perror("read_names"); } exit(EXIT_FAILURE); } } /* Reap the children in a handler asynchronously so we can * somehow protect against too many processes */ memset(&action, 0, sizeof(action)); action.sa_handler = child_handler; sigemptyset(&action.sa_mask); sigaddset(&action.sa_mask, SIGCHLD); action.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &action, &old_action); /* Fire up the child processes */ idx = 0; for (idx=0; names[idx]; idx++) { pid = fork(); if (pid == -1) { /* Try again in hope that some child has exited */ if (errno == EAGAIN) { continue; } perror("fork"); exit(EXIT_FAILURE); } else if ( pid == 0 ) { /* child */ ret = run_one_testcase(names[idx], pc_groups, pc_enoent_fail); exit(ret); } } /* Process the rest of the children here in main */ sigaction(SIGCHLD, &old_action, NULL); while ((ret = wait(&status)) > 0) { if (ret == -1) { perror("wait"); exit(EXIT_FAILURE); } if (WIFEXITED(status)) { ret = WEXITSTATUS(status); if (ret) { if (verbose) { fprintf(stderr, "A child exited with error code %d\n", WEXITSTATUS(status)); } ++failure_count; } } else ++failure_count; } if (pc_verbosity) { fprintf(stderr, "Total tests run: %d\nPassed: %d\nFailed: %d\n", idx, idx - failure_count, failure_count); } return (failure_count==0 ? EXIT_SUCCESS : EXIT_FAILURE); } sssd-1.13.4/src/tests/PaxHeaders.16287/pyhbac-test.py2.sh0000644000000000000000000000007412703456111017546 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.347792588 sssd-1.13.4/src/tests/pyhbac-test.py2.sh0000755002412700241270000000016012703456111021215 0ustar00jhrozekjhrozek00000000000000#!/bin/sh SCRIPT=$(readlink -f "$0") SCRIPT_PATH=$(dirname "$SCRIPT") exec python2 $SCRIPT_PATH/pyhbac-test.py sssd-1.13.4/src/tests/PaxHeaders.16287/common_tev.c0000644000000000000000000000007412703456111016570 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.823794202 sssd-1.13.4/src/tests/common_tev.c0000644002412700241270000000421512703456111020241 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat SSSD tests: Common utilities for tests that exercise domains This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "tests/common.h" struct sss_test_ctx * create_ev_test_ctx(TALLOC_CTX *mem_ctx) { struct sss_test_ctx *test_ctx; test_ctx = talloc_zero(mem_ctx, struct sss_test_ctx); if (test_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed\n"); goto fail; } /* Create an event context */ test_ctx->ev = tevent_context_init(test_ctx); if (test_ctx->ev == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_context_init failed\n"); goto fail; } return test_ctx; fail: talloc_free(test_ctx); return NULL; } struct tevent_req * test_request_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, errno_t err) { struct tevent_req *req; int *state; req = tevent_req_create(mem_ctx, &state, int); if (!req) return NULL; if (err == EOK) { tevent_req_done(req); } else { tevent_req_error(req, err); } tevent_req_post(req, ev); return req; } errno_t test_request_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } int test_ev_loop(struct sss_test_ctx *tctx) { while (!tctx->done) tevent_loop_once(tctx->ev); return tctx->error; } void test_ev_done(struct sss_test_ctx *tctx, errno_t ret) { tctx->error = ret; tctx->done = true; } sssd-1.13.4/src/tests/PaxHeaders.16287/common.h0000644000000000000000000000007412703456111015717 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.583793388 sssd-1.13.4/src/tests/common.h0000644002412700241270000001146412703456111017374 0ustar00jhrozekjhrozek00000000000000/* SSSD Common utilities for check-based tests using talloc. Authors: Martin Nagy Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __TESTS_COMMON_H__ #define __TESTS_COMMON_H__ #include "config.h" #include #include "util/util.h" #include "providers/data_provider.h" #include "providers/ldap/sdap.h" #ifdef HAVE_FUNCTION_ATTRIBUTE_WARN_UNUSED_RESULT #define SSS_ATTRIBUTE_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) #else #define SSS_ATTRIBUTE_WARN_UNUSED_RESULT #endif #define N_ELEMENTS(arr) (sizeof(arr) / sizeof(arr[0])) extern TALLOC_CTX *global_talloc_context; void check_leaks_push(TALLOC_CTX *ctx); #define check_leaks_pop(ctx) _check_leaks_pop((ctx), __location__) bool _check_leaks_pop(TALLOC_CTX *ctx, const char *location) SSS_ATTRIBUTE_WARN_UNUSED_RESULT; bool leak_check_setup(void) SSS_ATTRIBUTE_WARN_UNUSED_RESULT; bool leak_check_teardown(void) SSS_ATTRIBUTE_WARN_UNUSED_RESULT; const char *check_leaks_err_msg(void); void tests_set_cwd(void); errno_t compare_dp_options(struct dp_option *map1, size_t size1, struct dp_option *map2); errno_t compare_sdap_attr_maps(struct sdap_attr_map *map1, size_t size1, struct sdap_attr_map *map2); /* A common test structure for tests that require a domain to be set up. */ struct sss_test_ctx { struct sysdb_ctx *sysdb; struct confdb_ctx *confdb; struct tevent_context *ev; struct sss_domain_info *dom; struct sss_names_ctx *nctx; char *confdb_path; char *conf_dom_path; bool done; int error; }; struct sss_test_conf_param { const char *key; const char *value; }; struct sss_test_ctx *create_ev_test_ctx(TALLOC_CTX *mem_ctx); struct sss_test_ctx * create_multidom_test_ctx(TALLOC_CTX *mem_ctx, const char *tests_path, const char *cdb_file, const char **domains, const char *id_provider, struct sss_test_conf_param *params); struct sss_test_ctx * create_dom_test_ctx(TALLOC_CTX *mem_ctx, const char *tests_path, const char *confdb_path, const char *domain_name, const char *id_provider, struct sss_test_conf_param *params); void test_dom_suite_setup(const char *tests_path); void test_multidom_suite_cleanup(const char *tests_path, const char *cdb_file, const char **domains); void test_dom_suite_cleanup(const char *tests_path, const char *cdb_file, const char *domain); struct tevent_req * test_request_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, errno_t err); #define test_req_succeed_send(mem_ctx, ev) test_request_send(mem_ctx, ev, 0) errno_t test_request_recv(struct tevent_req *req); int test_ev_loop(struct sss_test_ctx *tctx); /* Mark the test as done with an error code */ void test_ev_done(struct sss_test_ctx *tctx, errno_t ret); bool ldb_modules_path_is_set(void); DBusConnection * test_dbus_setup_mock(TALLOC_CTX *mem_ctx, struct tevent_context *loop, sbus_server_conn_init_fn init_fn, void *init_pvt_data); DBusMessage * test_dbus_call_sync(DBusConnection *conn, const char *object_path, const char *interface, const char *method, DBusError *error, int first_arg_type, ...); struct sss_domain_info *named_domain(TALLOC_CTX *mem_ctx, const char *name, struct sss_domain_info *parent); /* Returns true if all values are in array (else returns false) */ bool are_values_in_array(const char **values, size_t values_len, const char **array, size_t array_len); #define tc_are_values_in_array(values, array) \ are_values_in_array(values, talloc_array_length(values), \ array, talloc_array_length(array)) #endif /* !__TESTS_COMMON_H__ */ sssd-1.13.4/src/tests/PaxHeaders.16287/find_uid-tests.c0000644000000000000000000000007412703456111017343 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.920794531 sssd-1.13.4/src/tests/find_uid-tests.c0000644002412700241270000000635412703456111021022 0ustar00jhrozekjhrozek00000000000000/* SSSD find_uid - Utilities tests Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/find_uid.h" #include "tests/common.h" START_TEST(test_check_if_uid_is_active_success) { uid_t uid; bool result; int ret; uid = getuid(); ret = check_if_uid_is_active(uid, &result); fail_unless(ret == EOK, "check_if_uid_is_active failed."); fail_unless(result, "check_if_uid_is_active did not found my uid [%d]", uid); } END_TEST START_TEST(test_check_if_uid_is_active_fail) { uid_t uid; bool result; int ret; uid = (uid_t) -4; ret = check_if_uid_is_active(uid, &result); fail_unless(ret == EOK, "check_if_uid_is_active failed."); fail_unless(!result, "check_if_uid_is_active found (hopefully not active) " "uid [%d]", uid); } END_TEST START_TEST(test_get_uid_table) { uid_t uid; int ret; TALLOC_CTX *tmp_ctx; hash_table_t *table; hash_key_t key; hash_value_t value; tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "talloc_new failed."); ret = get_uid_table(tmp_ctx, &table); fail_unless(ret == EOK, "get_uid_table failed."); uid = getuid(); key.type = HASH_KEY_ULONG; key.ul = (unsigned long) uid; ret = hash_lookup(table, &key, &value); fail_unless(ret == HASH_SUCCESS, "Cannot find my uid [%d] in the table", uid); uid = (uid_t) -4; key.type = HASH_KEY_ULONG; key.ul = (unsigned long) uid; ret = hash_lookup(table, &key, &value); fail_unless(ret == HASH_ERROR_KEY_NOT_FOUND, "Found (hopefully not active) " "uid [%d] in the table", uid); talloc_free(tmp_ctx); } END_TEST Suite *find_uid_suite (void) { Suite *s = suite_create ("find_uid"); TCase *tc_find_uid = tcase_create ("find_uid"); tcase_add_test (tc_find_uid, test_check_if_uid_is_active_success); tcase_add_test (tc_find_uid, test_check_if_uid_is_active_fail); tcase_add_test (tc_find_uid, test_get_uid_table); suite_add_tcase (s, tc_find_uid); return s; } int main(void) { debug_level = SSSDBG_MASK_ALL; int number_failed; tests_set_cwd(); Suite *s = find_uid_suite (); SRunner *sr = srunner_create (s); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed (sr); srunner_free (sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/safe-format-tests.c0000644000000000000000000000007412703456111017766 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.962794673 sssd-1.13.4/src/tests/safe-format-tests.c0000644002412700241270000001355612703456111021447 0ustar00jhrozekjhrozek00000000000000/* * This file originated in realmd * * Copyright 2012 Red Hat Inc * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2 of the licence or (at * your option) any later version. * * See the included COPYING file for more information. * * Author: Stef Walter */ #include "config.h" #include "src/util/safe-format-string.h" #include #include #include #include #ifndef ck_assert_int_ge #define ck_assert_int_ge(X, Y) _ck_assert_int(X, >=, Y) #endif #ifndef ck_assert_int_lt #define ck_assert_int_lt(X, Y) _ck_assert_int(X, <, Y) #endif typedef struct { const char *format; const char *args[8]; const char *result; } Fixture; static const Fixture fixtures[] = { { /* Just a bog standard string */ "%s", { "blah", NULL, }, "blah" }, { /* Empty to print */ "%s", { "", NULL, }, "" }, { /* Nothing to print */ "", { "blah", NULL, }, "" }, { /* Width right aligned */ "%8s", { "blah", NULL, }, " blah" }, { /* Width left aligned */ "whoop %-8s doo", { "dee", NULL, }, "whoop dee doo" }, { /* Width space aligned (ignored) */ "whoop % 8s doo", { "dee", NULL, }, "whoop dee doo" }, { /* Width left space aligned (ignored) */ "whoop % -8s doo", { "dee", NULL, }, "whoop dee doo" }, { /* Precision 1 digit */ "whoop %.3s doo", { "deedle-dee", NULL, }, "whoop dee doo" }, { /* Precision, N digits */ "whoop %.10s doo", { "deedle-dee-deedle-do-deedle-dum", NULL, }, "whoop deedle-dee doo" }, { /* Precision, zero digits */ "whoop %.s doo", { "deedle", NULL, }, "whoop doo" }, { /* Multiple simple arguments */ "space %s %s", { "man", "dances", NULL, }, "space man dances" }, { /* Literal percent */ "100%% of space folk dance", { NULL, }, "100% of space folk dance" }, { /* Multiple simple arguments */ "space %2$s %1$s", { "dances", "man", NULL, }, "space man dances" }, { /* Skipping an argument (not supported by standard printf) */ "space %2$s dances", { "dances", "man", NULL, }, "space man dances" }, /* Failures start here */ { /* Unsupported conversion */ "%x", { "blah", NULL, }, NULL }, { /* Bad positional argument */ "space %55$s dances", { "dances", "man", NULL, }, NULL }, { /* Zero positional argument */ "space %0$s dances", { "dances", "man", NULL, }, NULL }, { /* Too many args used */ "%s %s dances", { "space", NULL, }, NULL }, { /* Too many digits used */ "%1234567890s dances", { "space", NULL, }, NULL }, }; static void callback(void *data, const char *piece, size_t len) { char **str = data; *str = talloc_strndup_append(*str, piece, len); } START_TEST(test_safe_format_string_cb) { const Fixture *fixture; char *out; int num_args; int ret; void *mem_ctx; fixture = &fixtures[_i]; mem_ctx = talloc_init("safe-printf"); for (num_args = 0; fixture->args[num_args] != NULL; ) num_args++; out = talloc_strdup(mem_ctx, ""); ret = safe_format_string_cb(callback, &out, fixture->format, (const char * const*)fixture->args, num_args); if (fixture->result) { ck_assert_int_ge(ret, 0); ck_assert_str_eq(out, fixture->result); ck_assert_int_eq(ret, strlen(out)); } else { ck_assert_int_lt(ret, 0); } talloc_free(mem_ctx); } END_TEST START_TEST(test_safe_format_string) { char buffer[8]; int ret; ret = safe_format_string(buffer, 8, "%s", "space", "man", NULL); ck_assert_int_eq(ret, 5); ck_assert_str_eq(buffer, "space"); ret = safe_format_string(buffer, 8, "", "space", "man", NULL); ck_assert_int_eq(ret, 0); ck_assert_str_eq(buffer, ""); ret = safe_format_string(buffer, 8, "the %s %s dances away", "space", "man", NULL); ck_assert_int_eq(ret, 25); ck_assert_str_eq(buffer, "the spa"); ret = safe_format_string(NULL, 0, "the %s %s dances away", "space", "man", NULL); ck_assert_int_eq(ret, 25); ret = safe_format_string(buffer, 8, "%5$s", NULL); ck_assert_int_lt(ret, 0); } END_TEST static Suite * create_safe_format_suite(void) { Suite *s = suite_create("safe-format"); TCase *tc_format = tcase_create("safe-format-string"); /* One for each fixture */ tcase_add_loop_test(tc_format, test_safe_format_string_cb, 0, (sizeof (fixtures) / sizeof (fixtures[0]))); tcase_add_test(tc_format, test_safe_format_string); suite_add_tcase(s, tc_format); return s; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int failure_count; Suite *suite; SRunner *sr; struct poptOption long_options[] = { POPT_AUTOHELP POPT_TABLEEND }; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); suite = create_safe_format_suite(); sr = srunner_create(suite); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); failure_count = srunner_ntests_failed(sr); srunner_free(sr); return (failure_count==0 ? EXIT_SUCCESS : EXIT_FAILURE); } sssd-1.13.4/src/tests/PaxHeaders.16287/sysdb-tests.c0000644000000000000000000000007412703456111016706 xustar0030 atime=1460561751.658715654 30 ctime=1460561775.024794883 sssd-1.13.4/src/tests/sysdb-tests.c0000644002412700241270000067322512703456111020374 0ustar00jhrozekjhrozek00000000000000/* SSSD System Database Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "util/util.h" #include "util/crypto/sss_crypto.h" #include "confdb/confdb_setup.h" #include "db/sysdb_private.h" #include "db/sysdb_services.h" #include "db/sysdb_autofs.h" #include "tests/common.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_FILE "tests_conf.ldb" #define TEST_ATTR_NAME "test_attr_name" #define TEST_ATTR_VALUE "test_attr_value" #define TEST_ATTR_UPDATE_VALUE "test_attr_update_value" #define TEST_ATTR_ADD_NAME "test_attr_add_name" #define TEST_ATTR_ADD_VALUE "test_attr_add_value" #define CUSTOM_TEST_CONTAINER "custom_test_container" #define CUSTOM_TEST_OBJECT "custom_test_object" #define ASQ_TEST_USER "testuser27010" #define ASQ_TEST_USER_UID 27010 #define MBO_USER_BASE 27500 #define MBO_GROUP_BASE 28500 #define NUM_GHOSTS 10 #define TEST_AUTOFS_MAP_BASE 29500 struct sysdb_test_ctx { struct sysdb_ctx *sysdb; struct confdb_ctx *confdb; struct tevent_context *ev; struct sss_domain_info *domain; size_t null_pointer_size; }; static int _setup_sysdb_tests(struct sysdb_test_ctx **ctx, bool enumerate) { struct sysdb_test_ctx *test_ctx; char *conf_db; int ret; const char *val[2]; val[1] = NULL; /* Create tests directory if it doesn't exist */ /* (relative to current dir) */ ret = mkdir(TESTS_PATH, 0775); if (ret == -1 && errno != EEXIST) { fail("Could not create %s directory", TESTS_PATH); return EFAULT; } test_ctx = talloc_zero(NULL, struct sysdb_test_ctx); if (test_ctx == NULL) { fail("Could not allocate memory for test context"); return ENOMEM; } /* Create an event context * It will not be used except in confdb_init and sysdb_init */ test_ctx->ev = tevent_context_init(test_ctx); if (test_ctx->ev == NULL) { fail("Could not create event context"); talloc_free(test_ctx); return EIO; } conf_db = talloc_asprintf(test_ctx, "%s/%s", TESTS_PATH, TEST_CONF_FILE); if (conf_db == NULL) { fail("Out of memory, aborting!"); talloc_free(test_ctx); return ENOMEM; } DEBUG(SSSDBG_MINOR_FAILURE, "CONFDB: %s\n", conf_db); /* Connect to the conf db */ ret = confdb_init(test_ctx, &test_ctx->confdb, conf_db); if (ret != EOK) { fail("Could not initialize connection to the confdb"); talloc_free(test_ctx); return ret; } val[0] = "LOCAL"; ret = confdb_add_param(test_ctx->confdb, true, "config/sssd", "domains", val); if (ret != EOK) { fail("Could not initialize domains placeholder"); talloc_free(test_ctx); return ret; } val[0] = "local"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "id_provider", val); if (ret != EOK) { fail("Could not initialize provider"); talloc_free(test_ctx); return ret; } val[0] = enumerate ? "TRUE" : "FALSE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "enumerate", val); if (ret != EOK) { fail("Could not initialize LOCAL domain"); talloc_free(test_ctx); return ret; } val[0] = "TRUE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "cache_credentials", val); if (ret != EOK) { fail("Could not initialize LOCAL domain"); talloc_free(test_ctx); return ret; } ret = sssd_domain_init(test_ctx, test_ctx->confdb, "local", TESTS_PATH, &test_ctx->domain); if (ret != EOK) { fail("Could not initialize connection to the sysdb (%d)", ret); talloc_free(test_ctx); return ret; } test_ctx->sysdb = test_ctx->domain->sysdb; test_ctx->null_pointer_size = talloc_total_size(NULL); *ctx = test_ctx; return EOK; } static void null_ctx_get_size(struct sysdb_test_ctx *ctx) { ctx->null_pointer_size = talloc_total_size(NULL); } static void fail_if_null_ctx_leaks(struct sysdb_test_ctx *ctx) { size_t new_null_pointer_size; new_null_pointer_size = talloc_total_size(NULL); if(new_null_pointer_size != ctx->null_pointer_size) { fail("NULL pointer leaked memory, was %zu, is %zu\n", ctx->null_pointer_size, new_null_pointer_size); } } #define setup_sysdb_tests(ctx) _setup_sysdb_tests((ctx), false) struct test_data { struct tevent_context *ev; struct sysdb_test_ctx *ctx; const char *username; const char *groupname; const char *netgrname; const char *autofsmapname; uid_t uid; gid_t gid; const char *shell; bool finished; int error; struct sysdb_attrs *attrs; const char **attrlist; char **memberlist; struct ldb_message *msg; size_t msgs_count; struct ldb_message **msgs; }; static int test_add_user(struct test_data *data) { char *homedir; char *gecos; int ret; homedir = talloc_asprintf(data, "/home/testuser%d", data->uid); gecos = talloc_asprintf(data, "Test User %d", data->uid); ret = sysdb_add_user(data->ctx->domain, data->username, data->uid, 0, gecos, homedir, "/bin/bash", NULL, NULL, 0, 0); return ret; } static int test_store_user(struct test_data *data) { char *homedir; char *gecos; int ret; homedir = talloc_asprintf(data, "/home/testuser%d", data->uid); gecos = talloc_asprintf(data, "Test User %d", data->uid); ret = sysdb_store_user(data->ctx->domain, data->username, "x", data->uid, 0, gecos, homedir, data->shell ? data->shell : "/bin/bash", NULL, NULL, NULL, -1, 0); return ret; } static int test_remove_user(struct test_data *data) { struct ldb_dn *user_dn; int ret; user_dn = sysdb_user_dn(data, data->ctx->domain, data->username); if (!user_dn) return ENOMEM; ret = sysdb_delete_entry(data->ctx->sysdb, user_dn, true); return ret; } static int test_remove_user_by_uid(struct test_data *data) { int ret; ret = sysdb_delete_user(data->ctx->domain, NULL, data->uid); return ret; } static int test_remove_nonexistent_group(struct test_data *data) { int ret; ret = sysdb_delete_group(data->ctx->domain, NULL, data->uid); return ret; } static int test_remove_nonexistent_user(struct test_data *data) { int ret; ret = sysdb_delete_user(data->ctx->domain, NULL, data->uid); return ret; } static int test_add_group(struct test_data *data) { int ret; ret = sysdb_add_group(data->ctx->domain, data->groupname, data->gid, data->attrs, 0, 0); return ret; } static int test_add_incomplete_group(struct test_data *data) { int ret; ret = sysdb_add_incomplete_group(data->ctx->domain, data->groupname, data->gid, NULL, NULL, NULL, true, 0); return ret; } static int test_store_group(struct test_data *data) { int ret; ret = sysdb_store_group(data->ctx->domain, data->groupname, data->gid, data->attrs, -1, 0); return ret; } static int test_remove_group(struct test_data *data) { struct ldb_dn *group_dn; int ret; group_dn = sysdb_group_dn(data, data->ctx->domain, data->groupname); if (!group_dn) return ENOMEM; ret = sysdb_delete_entry(data->ctx->sysdb, group_dn, true); return ret; } static int test_remove_group_by_gid(struct test_data *data) { int ret; ret = sysdb_delete_group(data->ctx->domain, NULL, data->gid); if (ret == ENOENT) { ret = EOK; } return ret; } static int test_set_user_attr(struct test_data *data) { int ret; ret = sysdb_set_user_attr(data->ctx->domain, data->username, data->attrs, SYSDB_MOD_REP); return ret; } static int test_add_group_member(struct test_data *data) { const char *username; int ret; username = talloc_asprintf(data, "testuser%d", data->uid); if (username == NULL) { return ENOMEM; } ret = sysdb_add_group_member(data->ctx->domain, data->groupname, username, SYSDB_MEMBER_USER, false); return ret; } static int test_remove_group_member(struct test_data *data) { const char *username; int ret; username = talloc_asprintf(data, "testuser%d", data->uid); if (username == NULL) { return ENOMEM; } ret = sysdb_remove_group_member(data->ctx->domain, data->groupname, username, SYSDB_MEMBER_USER, false); return ret; } static int test_store_custom(struct test_data *data) { char *object_name; int ret; object_name = talloc_asprintf(data, "%s_%d", CUSTOM_TEST_OBJECT, data->uid); if (!object_name) { return ENOMEM; } ret = sysdb_store_custom(data->ctx->domain, object_name, CUSTOM_TEST_CONTAINER, data->attrs); return ret; } static int test_delete_custom(struct test_data *data) { int ret; ret = sysdb_delete_custom(data->ctx->domain, CUSTOM_TEST_OBJECT, CUSTOM_TEST_CONTAINER); return ret; } static int test_search_all_users(struct test_data *data) { struct ldb_dn *base_dn; int ret; base_dn = ldb_dn_new_fmt(data, data->ctx->sysdb->ldb, SYSDB_TMPL_USER_BASE, "LOCAL"); if (base_dn == NULL) { return ENOMEM; } ret = sysdb_search_entry(data, data->ctx->sysdb, base_dn, LDB_SCOPE_SUBTREE, "objectClass=user", data->attrlist, &data->msgs_count, &data->msgs); return ret; } static int test_delete_recursive(struct test_data *data) { struct ldb_dn *dn; int ret; dn = ldb_dn_new_fmt(data, data->ctx->sysdb->ldb, SYSDB_DOM_BASE, "LOCAL"); if (!dn) { return ENOMEM; } ret = sysdb_delete_recursive(data->ctx->sysdb, dn, false); fail_unless(ret == EOK, "sysdb_delete_recursive returned [%d]", ret); return ret; } static int test_memberof_store_group(struct test_data *data) { int ret; struct sysdb_attrs *attrs = NULL; char *member; int i; attrs = sysdb_new_attrs(data); if (!attrs) { return ENOMEM; } for (i = 0; data->attrlist && data->attrlist[i]; i++) { member = sysdb_group_strdn(data, data->ctx->domain->name, data->attrlist[i]); if (!member) { return ENOMEM; } ret = sysdb_attrs_steal_string(attrs, SYSDB_MEMBER, member); if (ret != EOK) { return ret; } } ret = sysdb_store_group(data->ctx->domain, data->groupname, data->gid, attrs, -1, 0); return ret; } static int test_memberof_store_group_with_ghosts(struct test_data *data) { int ret; struct sysdb_attrs *attrs = NULL; char *member; int i; attrs = sysdb_new_attrs(data); if (!attrs) { return ENOMEM; } for (i = 0; data->attrlist && data->attrlist[i]; i++) { member = sysdb_group_strdn(data, data->ctx->domain->name, data->attrlist[i]); if (!member) { return ENOMEM; } ret = sysdb_attrs_steal_string(attrs, SYSDB_MEMBER, member); if (ret != EOK) { return ret; } } for (i = 0; data->memberlist && data->memberlist[i]; i++) { ret = sysdb_attrs_steal_string(attrs, SYSDB_GHOST, data->memberlist[i]); if (ret != EOK) { return ret; } } ret = sysdb_store_group(data->ctx->domain, data->groupname, data->gid, attrs, -1, 0); return ret; } static int test_add_basic_netgroup(struct test_data *data) { const char *description; int ret; description = talloc_asprintf(data, "Test Netgroup %d", data->uid); ret = sysdb_add_basic_netgroup(data->ctx->domain, data->netgrname, description); return ret; } static int test_remove_netgroup_entry(struct test_data *data) { struct ldb_dn *netgroup_dn; int ret; netgroup_dn = sysdb_netgroup_dn(data, data->ctx->domain, data->netgrname); if (!netgroup_dn) return ENOMEM; ret = sysdb_delete_entry(data->ctx->sysdb, netgroup_dn, true); return ret; } static int test_remove_netgroup_by_name(struct test_data *data) { int ret; ret = sysdb_delete_netgroup(data->ctx->domain, data->netgrname); return ret; } static int test_set_netgroup_attr(struct test_data *data) { int ret; const char *description; struct sysdb_attrs *attrs = NULL; description = talloc_asprintf(data, "Sysdb Netgroup %d", data->uid); attrs = sysdb_new_attrs(data); if (!attrs) { return ENOMEM; } ret = sysdb_attrs_add_string(attrs, SYSDB_DESCRIPTION, description); if (ret) { return ret; } ret = sysdb_set_netgroup_attr(data->ctx->domain, data->netgrname, attrs, SYSDB_MOD_REP); return ret; } START_TEST (test_sysdb_user_new_id) { struct sysdb_test_ctx *test_ctx; int ret; const char *username; struct sysdb_attrs *attrs = NULL; struct ldb_message *msg; const char *get_attrs[] = { SYSDB_DESCRIPTION, NULL }; const char *desc; const char *desc_in = "testuser_new_id_desc"; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } username = "testuser_newid"; attrs = sysdb_new_attrs(test_ctx); fail_if(attrs == NULL); ret = sysdb_attrs_add_string(attrs, SYSDB_DESCRIPTION, desc_in); fail_if(ret != EOK); ret = sysdb_add_user(test_ctx->domain, username, 0, 0, username, "/", "/bin/bash", NULL, attrs, 0, 0); fail_if(ret != EOK, "Could not store user %s", username); ret = sysdb_search_user_by_name(test_ctx, test_ctx->domain, username, get_attrs, &msg); fail_if(ret != EOK, "Could not retrieve user %s", username); desc = ldb_msg_find_attr_as_string(msg, SYSDB_DESCRIPTION, NULL); fail_unless(desc != NULL); ck_assert_str_eq(desc, desc_in); ret = sysdb_delete_user(test_ctx->domain, username, 0); fail_unless(ret == EOK, "sysdb_delete_user error [%d][%s]", ret, strerror(ret)); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_store_user) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i; data->gid = _i; data->username = talloc_asprintf(data, "testuser%d", _i); ret = test_store_user(data); fail_if(ret != EOK, "Could not store user %s", data->username); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_store_user_existing) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i; data->gid = _i; data->username = talloc_asprintf(data, "testuser%d", _i); data->shell = talloc_asprintf(data, "/bin/ksh"); ret = test_store_user(data); fail_if(ret != EOK, "Could not store user %s", data->username); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_store_group) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->groupname = talloc_asprintf(data, "testgroup%d", _i); ret = test_store_group(data); fail_if(ret != EOK, "Could not store POSIX group #%d", _i); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_remove_local_user) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->username = talloc_asprintf(data, "testuser%d", _i); ret = test_remove_user(data); fail_if(ret != EOK, "Could not remove user %s", data->username); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_remove_local_user_by_uid) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i; ret = test_remove_user_by_uid(data); fail_if(ret != EOK, "Could not remove user with uid %d", _i); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_remove_local_group) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->groupname = talloc_asprintf(data, "testgroup%d", _i); ret = test_remove_group(data); fail_if(ret != EOK, "Could not remove group %s", data->groupname); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_remove_local_group_by_gid) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; null_ctx_get_size(data->ctx); ret = test_remove_group_by_gid(data); fail_if_null_ctx_leaks(test_ctx); fail_if(ret != EOK, "Could not remove group with gid %d", _i); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_add_user) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i; data->gid = _i; data->username = talloc_asprintf(data, "testuser%d", _i); ret = test_add_user(data); fail_if(ret != EOK, "Could not add user %s", data->username); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_add_group) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i; data->gid = _i; data->groupname = talloc_asprintf(data, "testgroup%d", _i); ret = test_add_group(data); fail_if(ret != EOK, "Could not add group %s", data->groupname); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_add_group_with_ghosts) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; char *membername; int j; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i; data->gid = _i; data->groupname = talloc_asprintf(data, "testgroup%d", _i); fail_unless(data->groupname != NULL, "Out of memory\n"); data->attrs = sysdb_new_attrs(data); if (ret != EOK) { fail("Could not create the changeset"); return; } for (j = MBO_GROUP_BASE; j < _i; j++) { membername = talloc_asprintf(data, "testghost%d", j); fail_unless(membername != NULL, "Out of memory\n"); ret = sysdb_attrs_steal_string(data->attrs, SYSDB_GHOST, membername); if (ret != EOK) { fail_unless(ret == EOK, "Cannot add attr\n"); } } ret = test_store_group(data); fail_if(ret != EOK, "Could not add group %s", data->groupname); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_add_incomplete_group) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i; data->gid = _i; data->groupname = talloc_asprintf(data, "testgroup%d", _i); ret = test_add_incomplete_group(data); fail_if(ret != EOK, "Could not add incomplete group %s", data->groupname); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_getpwnam) { struct sysdb_test_ctx *test_ctx; struct ldb_result *res; const char *username; uid_t uid; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } username = talloc_asprintf(test_ctx, "testuser%d", _i); ret = sysdb_getpwnam(test_ctx, test_ctx->domain, username, &res); if (ret) { fail("sysdb_getpwnam failed for username %s (%d: %s)", username, ret, strerror(ret)); goto done; } if (res->count != 1) { fail("Invalid number of replies. Expected 1, got %d", res->count); goto done; } uid = ldb_msg_find_attr_as_uint(res->msgs[0], SYSDB_UIDNUM, 0); fail_unless(uid == _i, "Did not find the expected UID"); /* Search for the user with the wrong case */ username = talloc_asprintf(test_ctx, "TESTUSER%d", _i); ret = sysdb_getpwnam(test_ctx, test_ctx->domain, username, &res); if (ret) { fail("sysdb_getpwnam failed for username %s (%d: %s)", username, ret, strerror(ret)); goto done; } if (res->count != 0) { fail("The upper-case username search should fail."); } done: talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_getgrnam) { struct sysdb_test_ctx *test_ctx; struct ldb_result *res; const char *groupname; gid_t gid; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } groupname = talloc_asprintf(test_ctx, "testgroup%d", _i); ret = sysdb_getgrnam(test_ctx, test_ctx->domain, groupname, &res); if (ret) { fail("sysdb_getgrnam failed for groupname %s (%d: %s)", groupname, ret, strerror(ret)); goto done; } if (res->count != 1) { fail("Invalid number of replies. Expected 1, got %d", res->count); goto done; } gid = ldb_msg_find_attr_as_uint(res->msgs[0], SYSDB_GIDNUM, 0); fail_unless(gid == _i, "Did not find the expected GID (found %d expected %d)", gid, _i); /* Search for the group with the wrong case */ groupname = talloc_asprintf(test_ctx, "TESTGROUP%d", _i); ret = sysdb_getgrnam(test_ctx, test_ctx->domain, groupname, &res); if (ret) { fail("sysdb_getgrnam failed for groupname %s (%d: %s)", groupname, ret, strerror(ret)); goto done; } if (res->count != 0) { fail("The upper-case groupname search should fail."); } done: talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_getgrgid) { struct sysdb_test_ctx *test_ctx; struct ldb_result *res; const char *e_groupname; const char *groupname; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } ret = sysdb_getgrgid(test_ctx, test_ctx->domain, _i, &res); if (ret) { fail("sysdb_getgrgid failed for gid %d (%d: %s)", _i, ret, strerror(ret)); goto done; } groupname = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, 0); e_groupname = talloc_asprintf(test_ctx, "testgroup%d", _i); if (e_groupname == NULL) { fail("Cannot allocate memory"); goto done; } fail_unless(strcmp(groupname, e_groupname) == 0, "Did not find the expected groupname (found %s expected %s)", groupname, e_groupname); done: talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_search_groups) { struct sysdb_test_ctx *test_ctx; int ret; const char *attrs[] = { SYSDB_NAME, NULL }; char *filter; size_t count; struct ldb_message **msgs; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); filter = talloc_asprintf(test_ctx, "("SYSDB_GIDNUM"=%d)", _i); fail_if(filter == NULL, "OOM"); ret = sysdb_search_groups(test_ctx, test_ctx->domain, filter, attrs, &count, &msgs); talloc_free(filter); fail_if(ret != EOK, "Search failed: %d", ret); fail_if(count != 1, "Did not find the expected group\n"); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_getpwuid) { struct sysdb_test_ctx *test_ctx; struct ldb_result *res; const char *e_username; const char *username; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } ret = sysdb_getpwuid(test_ctx, test_ctx->domain, _i, &res); if (ret) { fail("sysdb_getpwuid failed for uid %d (%d: %s)", _i, ret, strerror(ret)); goto done; } fail_unless(res->count == 1, "Expected 1 user entry, found %d\n", res->count); username = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, 0); e_username = talloc_asprintf(test_ctx, "testuser%d", _i); if (username == NULL) { fail("Cannot allocate memory"); goto done; } fail_unless(strcmp(username, e_username) == 0, "Did not find the expected username (found %s expected %s)", username, e_username); done: talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_enumgrent) { struct sysdb_test_ctx *test_ctx; struct ldb_result *res; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } ret = sysdb_enumgrent(test_ctx, test_ctx->domain, &res); fail_unless(ret == EOK, "sysdb_enumgrent failed (%d: %s)", ret, strerror(ret)); /* 10 groups + 10 users (we're MPG) */ fail_if(res->count != 20, "Expected 20 users, got %d", res->count); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_enumpwent) { struct sysdb_test_ctx *test_ctx; struct ldb_result *res; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } ret = sysdb_enumpwent(test_ctx, test_ctx->domain, &res); fail_unless(ret == EOK, "sysdb_enumpwent failed (%d: %s)", ret, strerror(ret)); fail_if(res->count != 10, "Expected 10 users, got %d", res->count); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_set_user_attr) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->username = talloc_asprintf(data, "testuser%d", _i); data->attrs = sysdb_new_attrs(test_ctx); if (ret != EOK) { fail("Could not create the changeset"); return; } ret = sysdb_attrs_add_string(data->attrs, SYSDB_SHELL, "/bin/ksh"); if (ret != EOK) { fail("Could not create the changeset"); return; } ret = test_set_user_attr(data); fail_if(ret != EOK, "Could not modify user %s", data->username); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_search_users) { struct sysdb_test_ctx *test_ctx; int ret; const char *attrs[] = { SYSDB_NAME, NULL }; char *filter; size_t count; struct ldb_message **msgs; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); filter = talloc_asprintf(test_ctx, "(&("SYSDB_UIDNUM"=%d)("SYSDB_SHELL"=/bin/ksh))", _i); fail_if(filter == NULL, "OOM"); ret = sysdb_search_users(test_ctx, test_ctx->domain, filter, attrs, &count, &msgs); talloc_free(filter); fail_if(ret != EOK, "Search failed: %d", ret); fail_if(count != 1, "Did not find the expected user\n"); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_remove_attrs) { struct sysdb_test_ctx *test_ctx; int ret; char *rmattrs[2]; char *username; struct ldb_result *res; const char *shell; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); username = talloc_asprintf(test_ctx, "testuser%d", _i); fail_if(username == NULL, "OOM"); ret = sysdb_getpwnam(test_ctx, test_ctx->domain, username, &res); fail_if(ret != EOK, "sysdb_getpwnam failed for username %s (%d: %s)", username, ret, strerror(ret)); shell = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL); fail_unless(shell != NULL, "Did not find user shell before removal"); rmattrs[0] = discard_const(SYSDB_SHELL); rmattrs[1] = NULL; ret = sysdb_remove_attrs(test_ctx->domain, username, SYSDB_MEMBER_USER, rmattrs); fail_if(ret != EOK, "Removing attributes failed: %d", ret); ret = sysdb_getpwnam(test_ctx, test_ctx->domain, username, &res); fail_if(ret != EOK, "sysdb_getpwnam failed for username %s (%d: %s)", username, ret, strerror(ret)); shell = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL); fail_unless(shell == NULL, "Found user shell after removal"); } END_TEST START_TEST (test_sysdb_get_user_attr) { struct sysdb_test_ctx *test_ctx; const char *attrs[] = { SYSDB_SHELL, NULL }; struct ldb_result *res; const char *attrval; char *username; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } username = talloc_asprintf(test_ctx, "testuser%d", _i); ret = sysdb_get_user_attr(test_ctx, test_ctx->domain, username, attrs, &res); if (ret) { fail("Could not get attributes for user %s", username); goto done; } fail_if(res->count != 1, "Invalid number of entries, expected 1, got %d", res->count); attrval = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, 0); fail_if(strcmp(attrval, "/bin/ksh"), "Got bad attribute value for user %s", username); done: talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_get_user_attr_subdomain) { struct sysdb_test_ctx *test_ctx; struct sss_domain_info *subdomain = NULL; const char *attrs[] = { SYSDB_SHELL, NULL }; struct ldb_result *res; const char *attrval; const char *username = "test_sysdb_get_user_attr_subdomain"; const char *fq_name; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); /* Create subdomain */ subdomain = new_subdomain(test_ctx, test_ctx->domain, "test.sub", "TEST.SUB", "test", "S-3", false, false, NULL, 0); fail_if(subdomain == NULL, "Failed to create new subdomain."); ret = sss_names_init_from_args(test_ctx, "(((?P[^\\\\]+)\\\\(?P.+$))|" \ "((?P[^@]+)@(?P.+$))|" \ "(^(?P[^@\\\\]+)$))", "%1$s@%2$s", &subdomain->names); fail_if(ret != EOK, "Failed to init names."); /* Create user */ fq_name = sss_tc_fqname(test_ctx, subdomain->names, subdomain, username); fail_if(fq_name == NULL, "Failed to create fq name."); ret = sysdb_store_user(subdomain, fq_name, NULL, 12345, 0, "Gecos", "/home/userhome", "/bin/bash", NULL, NULL, NULL, -1, 0); fail_if(ret != EOK, "sysdb_store_user failed."); /* Test */ ret = sysdb_get_user_attr(test_ctx, subdomain, username, attrs, &res); fail_if(ret != EOK, "Could not get user attributes."); fail_if(res->count != 1, "Invalid number of entries, expected 1, got %d", res->count); attrval = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, 0); fail_if(strcmp(attrval, "/bin/bash") != 0, "Got bad attribute value."); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_add_group_member) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->groupname = talloc_asprintf(data, "testgroup%d", _i); data->uid = _i - 1000; /* the UID of user to add */ ret = test_add_group_member(data); fail_if(ret != EOK, "Could not modify group %s", data->groupname); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_initgroups) { struct sysdb_test_ctx *test_ctx; int ret; const char *username; struct ldb_result *res; struct ldb_message *user; struct ldb_message *group; gid_t gid; uid_t uid; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } username = talloc_asprintf(test_ctx, "testuser%d", _i); ret = sysdb_initgroups(test_ctx, test_ctx->domain, username, &res); fail_if(ret != EOK, "sysdb_initgroups failed\n"); /* result should contain 2 messages - user and his group */ fail_if(res->count != 2, "expected 2 groups, got %d\n", res->count); /* check if it's the expected user and expected group */ user = res->msgs[0]; group = res->msgs[1]; uid = ldb_msg_find_attr_as_uint(user, SYSDB_UIDNUM, 0); fail_unless(uid == _i, "Did not find the expected UID (found %d expected %d)", uid, _i); fail_unless(strcmp(ldb_msg_find_attr_as_string(user, SYSDB_NAME, NULL), username) == 0, "Wrong username\n"); gid = ldb_msg_find_attr_as_uint(group, SYSDB_GIDNUM, 0); fail_unless(gid == _i + 1000, "Did not find the expected GID (found %d expected %d)", gid, _i); } END_TEST START_TEST (test_sysdb_remove_group_member) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->groupname = talloc_asprintf(data, "testgroup%d", _i); data->uid = _i - 1000; /* the UID of user to add */ ret = test_remove_group_member(data); fail_if(ret != EOK, "Remove group member failed: %d", ret); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_remove_nonexistent_user) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = 12345; ret = test_remove_nonexistent_user(data); fail_if(ret != ENOENT, "Unexpected return code %d, expected ENOENT", ret); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_remove_nonexistent_group) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = 12345; ret = test_remove_nonexistent_group(data); fail_if(ret != ENOENT, "Unexpected return code %d, expected ENOENT", ret); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_get_new_id) { struct sysdb_test_ctx *test_ctx; int ret; uint32_t id; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Cannot setup sysdb tests\n"); ret = sysdb_get_new_id(test_ctx->domain, &id); fail_if(ret != EOK, "Cannot get new ID\n"); fail_if(id != test_ctx->domain->id_min); } END_TEST START_TEST (test_sysdb_store_custom) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i; data->attrs = sysdb_new_attrs(test_ctx); if (ret != EOK) { fail("Could not create attribute list"); return; } ret = sysdb_attrs_add_string(data->attrs, TEST_ATTR_NAME, TEST_ATTR_VALUE); if (ret != EOK) { fail("Could not add attribute"); return; } ret = test_store_custom(data); fail_if(ret != EOK, "Could not add custom object"); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_search_custom_by_name) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; char *object_name; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); fail_unless(data != NULL, "talloc_zero failed"); data->ctx = test_ctx; data->ev = test_ctx->ev; data->attrlist = talloc_array(test_ctx, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed"); data->attrlist[0] = TEST_ATTR_NAME; data->attrlist[1] = NULL; object_name = talloc_asprintf(data, "%s_%d", CUSTOM_TEST_OBJECT, 29010); fail_unless(object_name != NULL, "talloc_asprintf failed"); ret = sysdb_search_custom_by_name(data, data->ctx->domain, object_name, CUSTOM_TEST_CONTAINER, data->attrlist, &data->msgs_count, &data->msgs); fail_if(ret != EOK, "Could not search custom object"); fail_unless(data->msgs_count == 1, "Wrong number of objects, exptected [1] got [%d]", data->msgs_count); fail_unless(data->msgs[0]->num_elements == 1, "Wrong number of results, expected [1] got [%d]", data->msgs[0]->num_elements); fail_unless(strcmp(data->msgs[0]->elements[0].name, TEST_ATTR_NAME) == 0, "Wrong attribute name"); fail_unless(data->msgs[0]->elements[0].num_values == 1, "Wrong number of attribute values"); fail_unless(strncmp((const char *)data->msgs[0]->elements[0].values[0].data, TEST_ATTR_VALUE, data->msgs[0]->elements[0].values[0].length) == 0, "Wrong attribute value"); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_update_custom) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = 29010; data->attrs = sysdb_new_attrs(test_ctx); if (ret != EOK) { fail("Could not create attribute list"); return; } ret = sysdb_attrs_add_string(data->attrs, TEST_ATTR_NAME, TEST_ATTR_UPDATE_VALUE); if (ret != EOK) { fail("Could not add attribute"); return; } ret = sysdb_attrs_add_string(data->attrs, TEST_ATTR_ADD_NAME, TEST_ATTR_ADD_VALUE); if (ret != EOK) { fail("Could not add attribute"); return; } ret = test_store_custom(data); fail_if(ret != EOK, "Could not add custom object"); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_search_custom_update) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; char *object_name; struct ldb_message_element *el; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); fail_unless(data != NULL, "talloc_zero failed"); data->ctx = test_ctx; data->ev = test_ctx->ev; data->attrlist = talloc_array(test_ctx, const char *, 3); fail_unless(data->attrlist != NULL, "talloc_array failed"); data->attrlist[0] = TEST_ATTR_NAME; data->attrlist[1] = TEST_ATTR_ADD_NAME; data->attrlist[2] = NULL; object_name = talloc_asprintf(data, "%s_%d", CUSTOM_TEST_OBJECT, 29010); fail_unless(object_name != NULL, "talloc_asprintf failed"); ret = sysdb_search_custom_by_name(data, data->ctx->domain, object_name, CUSTOM_TEST_CONTAINER, data->attrlist, &data->msgs_count, &data->msgs); fail_if(ret != EOK, "Could not search custom object"); fail_unless(data->msgs_count == 1, "Wrong number of objects, exptected [1] got [%d]", data->msgs_count); fail_unless(data->msgs[0]->num_elements == 2, "Wrong number of results, expected [2] got [%d]", data->msgs[0]->num_elements); el = ldb_msg_find_element(data->msgs[0], TEST_ATTR_NAME); fail_unless(el != NULL, "Attribute [%s] not found", TEST_ATTR_NAME); fail_unless(el->num_values == 1, "Wrong number ([%d] instead of 1) " "of attribute values for [%s]", el->num_values, TEST_ATTR_NAME); fail_unless(strncmp((const char *) el->values[0].data, TEST_ATTR_UPDATE_VALUE, el->values[0].length) == 0, "Wrong attribute value"); el = ldb_msg_find_element(data->msgs[0], TEST_ATTR_ADD_NAME); fail_unless(el != NULL, "Attribute [%s] not found", TEST_ATTR_ADD_NAME); fail_unless(el->num_values == 1, "Wrong number ([%d] instead of 1) " "of attribute values for [%s]", el->num_values, TEST_ATTR_ADD_NAME); fail_unless(strncmp((const char *) el->values[0].data, TEST_ATTR_ADD_VALUE, el->values[0].length) == 0, "Wrong attribute value"); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_search_custom) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; const char *filter = "(distinguishedName=*)"; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); fail_unless(data != NULL, "talloc_zero failed"); data->ctx = test_ctx; data->ev = test_ctx->ev; data->attrlist = talloc_array(test_ctx, const char *, 3); fail_unless(data->attrlist != NULL, "talloc_array failed"); data->attrlist[0] = TEST_ATTR_NAME; data->attrlist[1] = TEST_ATTR_ADD_NAME; data->attrlist[2] = NULL; ret = sysdb_search_custom(data, data->ctx->domain, filter, CUSTOM_TEST_CONTAINER, data->attrlist, &data->msgs_count, &data->msgs); fail_if(ret != EOK, "Could not search custom object"); fail_unless(data->msgs_count == 10, "Wrong number of objects, exptected [10] got [%d]", data->msgs_count); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_delete_custom) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; ret = test_delete_custom(data); fail_if(ret != EOK, "Could not delete custom object"); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_cache_password) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_unless(ret == EOK, "Could not set up the test"); data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->username = talloc_asprintf(data, "testuser%d", _i); ret = sysdb_cache_password(test_ctx->domain, data->username, data->username); fail_unless(ret == EOK, "sysdb_cache_password request failed [%d].", ret); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_cache_password_ex) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; struct ldb_result *res; const char *attrs[] = { SYSDB_CACHEDPWD_TYPE, SYSDB_CACHEDPWD_FA2_LEN, NULL }; int val; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_unless(ret == EOK, "Could not set up the test"); data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->username = talloc_asprintf(data, "testuser%d", _i); ret = sysdb_get_user_attr(test_ctx, test_ctx->domain, data->username, attrs, &res); fail_unless(ret == EOK, "sysdb_get_user_attr request failed [%d].", ret); val = ldb_msg_find_attr_as_int(res->msgs[0], SYSDB_CACHEDPWD_TYPE, 0); fail_unless(val == SSS_AUTHTOK_TYPE_PASSWORD, "Unexpected authtok type, found [%d], expected [%d].", val, SSS_AUTHTOK_TYPE_PASSWORD); ret = sysdb_cache_password_ex(test_ctx->domain, data->username, data->username, SSS_AUTHTOK_TYPE_2FA, 12); fail_unless(ret == EOK, "sysdb_cache_password request failed [%d].", ret); ret = sysdb_get_user_attr(test_ctx, test_ctx->domain, data->username, attrs, &res); fail_unless(ret == EOK, "sysdb_get_user_attr request failed [%d].", ret); val = ldb_msg_find_attr_as_int(res->msgs[0], SYSDB_CACHEDPWD_TYPE, 0); fail_unless(val == SSS_AUTHTOK_TYPE_2FA, "Unexpected authtok type, found [%d], expected [%d].", val, SSS_AUTHTOK_TYPE_2FA); val = ldb_msg_find_attr_as_int(res->msgs[0], SYSDB_CACHEDPWD_FA2_LEN, 0); fail_unless(val == 12, "Unexpected second factor length, found [%d], expected [%d].", val, 12); talloc_free(test_ctx); } END_TEST static void cached_authentication_without_expiration(const char *username, const char *password, int expected_result) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; time_t expire_date = -1; time_t delayed_until = -1; const char *val[2]; val[1] = NULL; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_unless(ret == EOK, "Could not set up the test"); data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->username = username; val[0] = "0"; ret = confdb_add_param(test_ctx->confdb, true, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_CRED_TIMEOUT, val); if (ret != EOK) { fail("Could not initialize provider"); talloc_free(test_ctx); return; } ret = sysdb_cache_auth(test_ctx->domain, data->username, password, test_ctx->confdb, false, &expire_date, &delayed_until); fail_unless(ret == expected_result, "sysdb_cache_auth request does not " "return expected result [%d].", expected_result); fail_unless(expire_date == 0, "Wrong expire date, expected [%d], got [%d]", 0, expire_date); fail_unless(delayed_until == -1, "Wrong delay, expected [%d], got [%d]", -1, delayed_until); talloc_free(test_ctx); } static void cached_authentication_with_expiration(const char *username, const char *password, int expected_result) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; time_t expire_date = -1; const char *val[2]; val[1] = NULL; time_t now; time_t expected_expire_date; time_t delayed_until = -1; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_unless(ret == EOK, "Could not set up the test"); data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->username = username; val[0] = "1"; ret = confdb_add_param(test_ctx->confdb, true, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_CRED_TIMEOUT, val); if (ret != EOK) { fail("Could not initialize provider"); talloc_free(test_ctx); return; } now = time(NULL); expected_expire_date = now + (24 * 60 * 60); DEBUG(SSSDBG_TRACE_ALL, "Setting SYSDB_LAST_ONLINE_AUTH to [%lld].\n", (long long) now); data->attrs = sysdb_new_attrs(data); ret = sysdb_attrs_add_time_t(data->attrs, SYSDB_LAST_ONLINE_AUTH, now); fail_unless(ret == EOK, "Could not mdd attribute "SYSDB_LAST_ONLINE_AUTH ": %s", data->username); ret = sysdb_set_user_attr(data->ctx->domain, data->username, data->attrs, SYSDB_MOD_REP); fail_unless(ret == EOK, "Could not modify user %s", data->username); ret = sysdb_cache_auth(data->ctx->domain, data->username, password, test_ctx->confdb, false, &expire_date, &delayed_until); fail_unless(ret == expected_result, "sysdb_cache_auth request does not return expected " "result [%d], got [%d].", expected_result, ret); fail_unless(expire_date == expected_expire_date, "Wrong expire date, expected [%d], got [%d]", expected_expire_date, expire_date); fail_unless(delayed_until == -1, "Wrong delay, expected [%d], got [%d]", -1, delayed_until); talloc_free(test_ctx); } START_TEST (test_sysdb_cached_authentication_missing_password) { TALLOC_CTX *tmp_ctx; char *username; tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "talloc_new failed."); username = talloc_asprintf(tmp_ctx, "testuser%d", _i); fail_unless(username != NULL, "talloc_asprintf failed."); cached_authentication_without_expiration(username, "abc", ERR_NO_CACHED_CREDS); cached_authentication_with_expiration(username, "abc", ERR_NO_CACHED_CREDS); talloc_free(tmp_ctx); } END_TEST START_TEST (test_sysdb_cached_authentication_wrong_password) { TALLOC_CTX *tmp_ctx; char *username; tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "talloc_new failed."); username = talloc_asprintf(tmp_ctx, "testuser%d", _i); fail_unless(username != NULL, "talloc_asprintf failed."); cached_authentication_without_expiration(username, "abc", ERR_AUTH_FAILED); cached_authentication_with_expiration(username, "abc", ERR_AUTH_FAILED); talloc_free(tmp_ctx); } END_TEST START_TEST (test_sysdb_cached_authentication) { TALLOC_CTX *tmp_ctx; char *username; tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "talloc_new failed."); username = talloc_asprintf(tmp_ctx, "testuser%d", _i); fail_unless(username != NULL, "talloc_asprintf failed."); cached_authentication_without_expiration(username, username, EOK); cached_authentication_with_expiration(username, username, EOK); talloc_free(tmp_ctx); } END_TEST START_TEST (test_sysdb_prepare_asq_test_user) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->groupname = talloc_asprintf(data, "testgroup%d", _i); data->uid = ASQ_TEST_USER_UID; ret = test_add_group_member(data); fail_if(ret != EOK, "Could not modify group %s", data->groupname); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_asq_search) { struct sysdb_test_ctx *test_ctx; struct test_data *data; struct ldb_dn *user_dn; int ret; size_t msgs_count; struct ldb_message **msgs; int i; char *gid_str; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed"); data->attrlist[0] = "gidNumber"; data->attrlist[1] = NULL; user_dn = sysdb_user_dn(data, data->ctx->domain, ASQ_TEST_USER); fail_unless(user_dn != NULL, "sysdb_user_dn failed"); ret = sysdb_asq_search(data, test_ctx->domain, user_dn, NULL, "memberof", data->attrlist, &msgs_count, &msgs); fail_if(ret != EOK, "Failed to send ASQ search request.\n"); fail_unless(msgs_count == 10, "wrong number of results, " "found [%d] expected [10]", msgs_count); for (i = 0; i < msgs_count; i++) { fail_unless(msgs[i]->num_elements == 1, "wrong number of elements, " "found [%d] expected [1]", msgs[i]->num_elements); fail_unless(msgs[i]->elements[0].num_values == 1, "wrong number of values, found [%d] expected [1]", msgs[i]->elements[0].num_values); gid_str = talloc_asprintf(data, "%d", 28010 + i); fail_unless(gid_str != NULL, "talloc_asprintf failed."); fail_unless(strncmp(gid_str, (const char *) msgs[i]->elements[0].values[0].data, msgs[i]->elements[0].values[0].length) == 0, "wrong value, found [%.*s] expected [%s]", msgs[i]->elements[0].values[0].length, msgs[i]->elements[0].values[0].data, gid_str); } talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_search_all_users) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; int i; char *uid_str; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed"); data->attrlist[0] = "uidNumber"; data->attrlist[1] = NULL; ret = test_search_all_users(data); fail_if(ret != EOK, "Search failed"); fail_unless(data->msgs_count == 10, "wrong number of results, found [%d] expected [10]", data->msgs_count); for (i = 0; i < data->msgs_count; i++) { fail_unless(data->msgs[i]->num_elements == 1, "wrong number of elements, found [%d] expected [1]", data->msgs[i]->num_elements); fail_unless(data->msgs[i]->elements[0].num_values == 1, "wrong number of values, found [%d] expected [1]", data->msgs[i]->elements[0].num_values); uid_str = talloc_asprintf(data, "%d", 27010 + i); fail_unless(uid_str != NULL, "talloc_asprintf failed."); fail_unless(strncmp(uid_str, (char *) data->msgs[i]->elements[0].values[0].data, data->msgs[i]->elements[0].values[0].length) == 0, "wrong value, found [%.*s] expected [%s]", data->msgs[i]->elements[0].values[0].length, data->msgs[i]->elements[0].values[0].data, uid_str); } talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_delete_recursive) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; ret = test_delete_recursive(data); fail_if(ret != EOK, "Recursive delete failed"); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_attrs_replace_name) { struct sysdb_attrs *attrs; struct ldb_message_element *el; int ret; attrs = sysdb_new_attrs(NULL); fail_unless(attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_string(attrs, "foo", "bar"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed"); ret = sysdb_attrs_add_string(attrs, "fool", "bool"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed"); ret = sysdb_attrs_add_string(attrs, "foot", "boot"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed"); ret = sysdb_attrs_replace_name(attrs, "foo", "foot"); fail_unless(ret == EEXIST, "sysdb_attrs_replace overwrites existing attribute"); ret = sysdb_attrs_replace_name(attrs, "foo", "oof"); fail_unless(ret == EOK, "sysdb_attrs_replace failed"); ret = sysdb_attrs_get_el(attrs, "foo", &el); fail_unless(ret == EOK, "sysdb_attrs_get_el failed"); fail_unless(el->num_values == 0, "Attribute foo is not empty."); ret = sysdb_attrs_get_el(attrs, "oof", &el); fail_unless(ret == EOK, "sysdb_attrs_get_el failed"); fail_unless(el->num_values == 1, "Wrong number of values for attribute oof, " "expected [1] got [%d].", el->num_values); fail_unless(strncmp("bar", (char *) el->values[0].data, el->values[0].length) == 0, "Wrong value, expected [bar] got [%.*s]", el->values[0].length, el->values[0].data); talloc_free(attrs); } END_TEST START_TEST (test_sysdb_memberof_store_group) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = MBO_GROUP_BASE + _i; data->groupname = talloc_asprintf(data, "testgroup%d", data->gid); if (_i == 0) { data->attrlist = NULL; } else { data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = talloc_asprintf(data, "testgroup%d", data->gid - 1); data->attrlist[1] = NULL; } ret = test_memberof_store_group(data); fail_if(ret != EOK, "Could not store POSIX group #%d", data->gid); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_store_group_with_ghosts) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->groupname = talloc_asprintf(data, "testgroup%d", data->gid); if (_i == 0) { data->attrlist = NULL; } else { data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = talloc_asprintf(data, "testgroup%d", data->gid - 1); data->attrlist[1] = NULL; } data->memberlist = talloc_array(data, char *, 2); fail_unless(data->memberlist != NULL, "talloc_array failed."); data->memberlist[0] = talloc_asprintf(data, "testuser%d", data->gid); data->memberlist[1] = NULL; ret = test_memberof_store_group_with_ghosts(data); fail_if(ret != EOK, "Could not store POSIX group #%d", data->gid); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_store_group_with_double_ghosts) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->groupname = talloc_asprintf(data, "testgroup%d", data->gid); if (_i == 0) { data->attrlist = NULL; } else { data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = talloc_asprintf(data, "testgroup%d", data->gid - 1); data->attrlist[1] = NULL; } data->memberlist = talloc_array(data, char *, 3); fail_unless(data->memberlist != NULL, "talloc_array failed."); data->memberlist[0] = talloc_asprintf(data, "testusera%d", data->gid); data->memberlist[1] = talloc_asprintf(data, "testuserb%d", data->gid); data->memberlist[2] = NULL; ret = test_memberof_store_group_with_ghosts(data); fail_if(ret != EOK, "Could not store POSIX group #%d", data->gid); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_mod_add) { struct sysdb_test_ctx *test_ctx; struct test_data *data; char *ghostname; int ret; struct ldb_message_element *el; struct ldb_val gv, *test_gv; gid_t itergid; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->groupname = talloc_asprintf(data, "testgroup%d", data->gid); data->attrs = sysdb_new_attrs(data); if (ret != EOK) { fail("Could not create the changeset"); return; } ghostname = talloc_asprintf(data, "testghost%d", _i); fail_unless(ghostname != NULL, "Out of memory\n"); ret = sysdb_attrs_steal_string(data->attrs, SYSDB_GHOST, ghostname); fail_unless(ret == EOK, "Cannot add attr\n"); data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = SYSDB_GHOST; data->attrlist[1] = NULL; /* Before the add, the groups should not contain the ghost attribute */ for (itergid = data->gid ; itergid < MBO_GROUP_BASE + NUM_GHOSTS; itergid++) { ret = sysdb_search_group_by_gid(data, test_ctx->domain, itergid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname; gv.length = strlen(ghostname); el = ldb_msg_find_element(data->msg, SYSDB_GHOST); if (data->gid > MBO_GROUP_BASE) { /* The first group would have the ghost attribute gone completely */ fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_unless(test_gv == NULL, "Ghost user %s unexpectedly found\n", ghostname); } else { fail_unless(el == NULL, "Stray values in ghost element?\n"); } } /* Perform the add operation */ ret = sysdb_set_group_attr(test_ctx->domain, data->groupname, data->attrs, SYSDB_MOD_ADD); fail_unless(ret == EOK, "Cannot set group attrs\n"); /* Before the delete, all groups with gid >= _i have the testuser%_i * as a member */ for (itergid = data->gid ; itergid < MBO_GROUP_BASE + NUM_GHOSTS; itergid++) { ret = sysdb_search_group_by_gid(data, test_ctx->domain, itergid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname; gv.length = strlen(ghostname); el = ldb_msg_find_element(data->msg, SYSDB_GHOST); fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find ghost user %s\n", ghostname); } talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_mod_replace) { struct sysdb_test_ctx *test_ctx; struct test_data *data; char *ghostname_del; char *ghostname_add; int ret; struct ldb_message_element *el; struct ldb_val gv, *test_gv; gid_t itergid; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->groupname = talloc_asprintf(data, "testgroup%d", data->gid); data->attrs = sysdb_new_attrs(data); if (ret != EOK) { fail("Could not create the changeset"); return; } /* The test replaces the testuser%i attribute with testghost%i */ ghostname_del = talloc_asprintf(data, "testuser%d", _i); fail_unless(ghostname_del != NULL, "Out of memory\n"); ghostname_add = talloc_asprintf(data, "testghost%d", _i); fail_unless(ghostname_add != NULL, "Out of memory\n"); ret = sysdb_attrs_steal_string(data->attrs, SYSDB_GHOST, ghostname_add); fail_unless(ret == EOK, "Cannot add attr\n"); data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = SYSDB_GHOST; data->attrlist[1] = NULL; /* Before the replace, all groups with gid >= _i have the testuser%_i * as a member */ for (itergid = data->gid ; itergid < MBO_GROUP_BASE + NUM_GHOSTS; itergid++) { ret = sysdb_search_group_by_gid(data, test_ctx->domain, itergid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname_del; gv.length = strlen(ghostname_del); el = ldb_msg_find_element(data->msg, SYSDB_GHOST); fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find ghost user %s\n", ghostname_del); } /* Perform the replace operation */ ret = sysdb_set_group_attr(test_ctx->domain, data->groupname, data->attrs, SYSDB_MOD_REP); fail_unless(ret == EOK, "Cannot set group attrs\n"); /* After the replace, all groups with gid >= _i have the testghost%_i * as a member */ for (itergid = data->gid ; itergid < MBO_GROUP_BASE + NUM_GHOSTS; itergid++) { ret = sysdb_search_group_by_gid(data, test_ctx->domain, itergid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname_add; gv.length = strlen(ghostname_add); el = ldb_msg_find_element(data->msg, SYSDB_GHOST); fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find ghost user %s\n", ghostname_add); } talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_mod_replace_keep) { struct sysdb_test_ctx *test_ctx; struct test_data *data; char *ghostname_rep; char *ghostname_del; char *ghostname_check; int ret; struct ldb_message_element *el; struct ldb_val gv, *test_gv; gid_t itergid; uid_t iteruid; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = MBO_GROUP_BASE + 10 - _i; data->groupname = talloc_asprintf(data, "testgroup%d", data->gid); data->attrs = sysdb_new_attrs(data); if (ret != EOK) { fail("Could not create the changeset"); return; } /* The test replaces the attributes (testusera$gid, testuserb$gid) with * just testusera$gid. The result should be not only testusera, but also * all ghost users inherited from child groups */ ghostname_rep = talloc_asprintf(data, "testusera%d", data->gid); fail_unless(ghostname_rep != NULL, "Out of memory\n"); ret = sysdb_attrs_steal_string(data->attrs, SYSDB_GHOST, ghostname_rep); fail_unless(ret == EOK, "Cannot add attr\n"); ghostname_del = talloc_asprintf(data, "testuserb%d", data->gid); fail_unless(ghostname_del != NULL, "Out of memory\n"); data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = SYSDB_GHOST; data->attrlist[1] = NULL; /* Before the replace, all groups with gid >= _i have both testuser a * and testuserb as a member */ for (itergid = data->gid ; itergid < MBO_GROUP_BASE + NUM_GHOSTS; itergid++) { ret = sysdb_search_group_by_gid(data, test_ctx->domain, itergid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname_rep; gv.length = strlen(ghostname_rep); el = ldb_msg_find_element(data->msg, SYSDB_GHOST); fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find ghost user %s\n", ghostname_rep); gv.data = (uint8_t *) ghostname_del; gv.length = strlen(ghostname_rep); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find ghost user %s\n", ghostname_del); /* inherited users must be there */ for (iteruid = MBO_GROUP_BASE ; iteruid < itergid ; iteruid++) { ghostname_check = talloc_asprintf(data, "testusera%d", iteruid); gv.data = (uint8_t *) ghostname_check; gv.length = strlen(ghostname_check); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find inherited ghost user %s\n", ghostname_check); if (iteruid < data->gid) { /* Also check the B user if it hasn't been deleted yet */ ghostname_check = talloc_asprintf(data, "testuserb%d", iteruid); gv.data = (uint8_t *) ghostname_check; gv.length = strlen(ghostname_check); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find inherited ghost user %s\n", ghostname_check); } talloc_zfree(ghostname_check); } } /* Perform the replace operation */ ret = sysdb_set_group_attr(test_ctx->domain, data->groupname, data->attrs, SYSDB_MOD_REP); fail_unless(ret == EOK, "Cannot set group attrs\n"); /* After the replace, testusera should still be there, but we also need * to keep ghost users inherited from other groups */ for (itergid = data->gid ; itergid < MBO_GROUP_BASE + NUM_GHOSTS; itergid++) { ret = sysdb_search_group_by_gid(data, test_ctx->domain, itergid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname_rep; gv.length = strlen(ghostname_rep); /* testusera must still be there */ el = ldb_msg_find_element(data->msg, SYSDB_GHOST); fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find ghost user %s\n", ghostname_rep); /* testuserb must be gone */ gv.data = (uint8_t *) ghostname_del; gv.length = strlen(ghostname_rep); test_gv = ldb_msg_find_val(el, &gv); fail_unless(test_gv == NULL, "Cannot find ghost user %s\n", ghostname_del); /* inherited users must still be there */ for (iteruid = MBO_GROUP_BASE ; iteruid < itergid ; iteruid++) { ghostname_check = talloc_asprintf(data, "testusera%d", iteruid); gv.data = (uint8_t *) ghostname_check; gv.length = strlen(ghostname_check); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find inherited ghost user %s\n", ghostname_check); if (iteruid < data->gid) { /* Also check the B user if it hasn't been deleted yet */ ghostname_check = talloc_asprintf(data, "testuserb%d", iteruid); gv.data = (uint8_t *) ghostname_check; gv.length = strlen(ghostname_check); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find inherited ghost user %s\n", ghostname_check); } talloc_zfree(ghostname_check); } } talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_close_loop) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = MBO_GROUP_BASE; data->groupname = talloc_asprintf(data, "testgroup%d", data->gid); data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = talloc_asprintf(data, "testgroup%d", data->gid + 9); data->attrlist[1] = NULL; ret = test_memberof_store_group(data); fail_if(ret != EOK, "Could not store POSIX group #%d", data->gid); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_store_user) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = MBO_USER_BASE + _i; data->gid = 0; /* MPG domain */ data->username = talloc_asprintf(data, "testuser%d", data->uid); ret = test_store_user(data); fail_if(ret != EOK, "Could not store user %s", data->username); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_add_group_member) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->groupname = talloc_asprintf(data, "testgroup%d", _i + MBO_GROUP_BASE); data->uid = MBO_USER_BASE + _i; ret = test_add_group_member(data); fail_if(ret != EOK, "Could not modify group %s", data->groupname); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_check_memberuid_without_group_5) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i + MBO_GROUP_BASE; data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "tallo_array failed."); data->attrlist[0] = "memberuid"; data->attrlist[1] = NULL; ret = sysdb_search_group_by_gid(data, test_ctx->domain, _i + MBO_GROUP_BASE, data->attrlist, &data->msg); if (_i == 5) { fail_unless(ret == ENOENT, "sysdb_search_group_by_gid found " "already deleted group"); if (ret == ENOENT) ret = EOK; fail_if(ret != EOK, "Could not check group %d", data->gid); } else { fail_if(ret != EOK, "Could not check group %d", data->gid); fail_unless(data->msg->num_elements == 1, "Wrong number of results, expected [1] got [%d]", data->msg->num_elements); fail_unless(strcmp(data->msg->elements[0].name, "memberuid") == 0, "Wrong attribute name"); fail_unless(data->msg->elements[0].num_values == ((_i + 1) % 6), "Wrong number of attribute values, " "expected [%d] got [%d]", ((_i + 1) % 6), data->msg->elements[0].num_values); } talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_check_memberuid) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i + MBO_GROUP_BASE; data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "tallo_array failed."); data->attrlist[0] = "memberuid"; data->attrlist[1] = NULL; ret = sysdb_search_group_by_gid(data, test_ctx->domain, _i + MBO_GROUP_BASE, data->attrlist, &data->msg); fail_if(ret != EOK, "Could not check group %d", data->gid); fail_unless(data->msg->num_elements == 1, "Wrong number of results, expected [1] got [%d]", data->msg->num_elements); fail_unless(strcmp(data->msg->elements[0].name, "memberuid") == 0, "Wrong attribute name"); fail_unless(data->msg->elements[0].num_values == _i + 1, "Wrong number of attribute values, expected [%d] got [%d]", _i + 1, data->msg->elements[0].num_values); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_check_memberuid_loop) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i + MBO_GROUP_BASE; data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "tallo_array failed."); data->attrlist[0] = "memberuid"; data->attrlist[1] = NULL; ret = sysdb_search_group_by_gid(data, test_ctx->domain, _i + MBO_GROUP_BASE, data->attrlist, &data->msg); fail_if(ret != EOK, "Could not check group %d", data->gid); fail_unless(data->msg->num_elements == 1, "Wrong number of results, expected [1] got [%d]", data->msg->num_elements); fail_unless(strcmp(data->msg->elements[0].name, "memberuid") == 0, "Wrong attribute name"); fail_unless(data->msg->elements[0].num_values == 10, "Wrong number of attribute values, expected [%d] got [%d]", 10, data->msg->elements[0].num_values); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_check_memberuid_loop_without_group_5) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i + MBO_GROUP_BASE; data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "tallo_array failed."); data->attrlist[0] = "memberuid"; data->attrlist[1] = NULL; ret = sysdb_search_group_by_gid(data, test_ctx->domain, _i + MBO_GROUP_BASE, data->attrlist, &data->msg); if (_i == 5) { fail_unless(ret == ENOENT, "sysdb_search_group_by_gid_send found " "already deleted group"); if (ret == ENOENT) ret = EOK; fail_if(ret != EOK, "Could not check group %d", data->gid); } else { fail_if(ret != EOK, "Could not check group %d", data->gid); fail_unless(data->msg->num_elements == 1, "Wrong number of results, expected [1] got [%d]", data->msg->num_elements); fail_unless(strcmp(data->msg->elements[0].name, "memberuid") == 0, "Wrong attribute name"); fail_unless(data->msg->elements[0].num_values == ((_i + 5) % 10), "Wrong number of attribute values, expected [%d] got [%d]", ((_i + 5) % 10), data->msg->elements[0].num_values); } talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_check_nested_ghosts) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = SYSDB_GHOST; data->attrlist[1] = NULL; ret = sysdb_search_group_by_gid(data, test_ctx->domain, data->gid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); fail_unless(strcmp(data->msg->elements[0].name, SYSDB_GHOST) == 0, "Wrong attribute name"); fail_unless(data->msg->elements[0].num_values == _i - MBO_GROUP_BASE + 1, "Wrong number of attribute values, expected [%d] got [%d]", _i + 1, data->msg->elements[0].num_values); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_check_nested_double_ghosts) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = SYSDB_GHOST; data->attrlist[1] = NULL; ret = sysdb_search_group_by_gid(data, test_ctx->domain, data->gid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); fail_unless(strcmp(data->msg->elements[0].name, SYSDB_GHOST) == 0, "Wrong attribute name"); fail_unless(data->msg->elements[0].num_values == (_i - MBO_GROUP_BASE + 1)*2, "Wrong number of attribute values, expected [%d] got [%d]", (_i - MBO_GROUP_BASE + 1)*2, data->msg->elements[0].num_values); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_remove_child_group_and_check_ghost) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; gid_t delgid; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; delgid = data->gid - 1; data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = SYSDB_GHOST; data->attrlist[1] = NULL; ret = sysdb_search_group_by_gid(data, test_ctx->domain, data->gid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); fail_unless(strcmp(data->msg->elements[0].name, SYSDB_GHOST) == 0, "Wrong attribute name"); /* Expect our own and our parent's */ fail_unless(data->msg->elements[0].num_values == 2, "Wrong number of attribute values, expected [%d] got [%d]", 2, data->msg->elements[0].num_values); /* Remove the parent */ ret = sysdb_delete_group(data->ctx->domain, NULL, delgid); fail_if(ret != EOK, "Cannot delete group %llu [%d]: %s\n", (unsigned long long) data->gid, ret, strerror(ret)); talloc_free(data->msg); /* Check the parent again. The inherited ghost user should be gone. */ ret = sysdb_search_group_by_gid(data, test_ctx->domain, data->gid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); fail_unless(strcmp(data->msg->elements[0].name, SYSDB_GHOST) == 0, "Wrong attribute name"); /* Expect our own now only */ fail_unless(data->msg->elements[0].num_values == 1, "Wrong number of attribute values, expected [%d] got [%d]", 1, data->msg->elements[0].num_values); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_mod_del) { struct sysdb_test_ctx *test_ctx; struct test_data *data; char *ghostname; int ret; struct ldb_message_element *el; struct ldb_val gv, *test_gv; gid_t itergid; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->groupname = talloc_asprintf(data, "testgroup%d", data->gid); data->attrs = sysdb_new_attrs(data); if (ret != EOK) { fail("Could not create the changeset"); return; } ghostname = talloc_asprintf(data, "testuser%d", _i); fail_unless(ghostname != NULL, "Out of memory\n"); ret = sysdb_attrs_steal_string(data->attrs, SYSDB_GHOST, ghostname); fail_unless(ret == EOK, "Cannot add attr\n"); data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = SYSDB_GHOST; data->attrlist[1] = NULL; /* Before the delete, all groups with gid >= _i have the testuser%_i * as a member */ for (itergid = data->gid ; itergid < MBO_GROUP_BASE + NUM_GHOSTS; itergid++) { ret = sysdb_search_group_by_gid(data, test_ctx->domain, itergid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname; gv.length = strlen(ghostname); el = ldb_msg_find_element(data->msg, SYSDB_GHOST); fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find ghost user %s\n", ghostname); } /* Delete the attribute */ null_ctx_get_size(test_ctx); ret = sysdb_set_group_attr(test_ctx->domain, data->groupname, data->attrs, SYSDB_MOD_DEL); fail_if_null_ctx_leaks(test_ctx); fail_unless(ret == EOK, "Cannot set group attrs\n"); /* After the delete, we shouldn't be able to find the ghost attribute */ for (itergid = data->gid ; itergid < MBO_GROUP_BASE + NUM_GHOSTS; itergid++) { ret = sysdb_search_group_by_gid(data, test_ctx->domain, itergid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname; gv.length = strlen(ghostname); el = ldb_msg_find_element(data->msg, SYSDB_GHOST); if (itergid > data->gid) { /* The first group would have the ghost attribute gone completely */ fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_unless(test_gv == NULL, "Ghost user %s unexpectedly found\n", ghostname); } else { fail_unless(el == NULL, "Stray values in ghost element?\n"); } } talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_check_ghost) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret, j; char *expected; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = SYSDB_GHOST; data->attrlist[1] = NULL; ret = sysdb_search_group_by_gid(data, test_ctx->domain, data->gid, data->attrlist, &data->msg); fail_if(ret != EOK, "Could not check group %d", data->gid); if (_i > MBO_GROUP_BASE) { /* After the previous test, the first group (gid == MBO_GROUP_BASE) * has no ghost users. That's a legitimate test case we need to account * for now. */ fail_unless(data->msg->num_elements == 1, "Wrong number of results, expected [1] got [%d] for %d", data->msg->num_elements, data->gid); } if (data->msg->num_elements == 0) { talloc_free(test_ctx); return; } fail_unless(strcmp(data->msg->elements[0].name, SYSDB_GHOST) == 0, "Wrong attribute name"); fail_unless(data->msg->elements[0].num_values == _i - MBO_GROUP_BASE, "Wrong number of attribute values, expected [%d] got [%d]", _i + 1, data->msg->elements[0].num_values); for (j = MBO_GROUP_BASE; j < _i; j++) { expected = talloc_asprintf(data, "testghost%d", j); fail_if(expected == NULL, "OOM\n"); fail_unless(strcmp(expected, (const char *) data->msg->elements[0].values[j-MBO_GROUP_BASE].data) == 0); talloc_free(expected); } talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_convert_to_real_users) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i * 2; data->gid = _i * 2; data->username = talloc_asprintf(data, "testghost%d", _i); ret = test_store_user(data); fail_if(ret != EOK, "Cannot add user %s\n", data->username); } END_TEST START_TEST (test_sysdb_memberof_check_convert) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; struct ldb_message_element *ghosts; struct ldb_message_element *members; int exp_mem, exp_gh; /* Eplicitly disable enumeration during setup as converting the ghost * users into real ones work only when enumeration is disabled */ ret = _setup_sysdb_tests(&test_ctx, false); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->attrlist = talloc_array(data, const char *, 3); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = SYSDB_GHOST; data->attrlist[1] = SYSDB_MEMBER; data->attrlist[2] = NULL; ret = sysdb_search_group_by_gid(data, test_ctx->domain, data->gid, data->attrlist, &data->msg); fail_if(ret != EOK, "Could not check group %d", data->gid); fail_unless(data->msg->num_elements == (_i == MBO_GROUP_BASE) ? 0 : 1, "Wrong number of results, expected [1] got [%d] for %d", data->msg->num_elements, data->gid); if (data->msg->num_elements == 0) { talloc_free(test_ctx); return; } members = ldb_msg_find_element(data->msg, SYSDB_MEMBER); exp_mem = _i - MBO_GROUP_BASE; if (exp_mem > NUM_GHOSTS/2) { exp_mem = NUM_GHOSTS/2; } ghosts = ldb_msg_find_element(data->msg, SYSDB_GHOST); exp_gh = _i - MBO_GROUP_BASE - 5; if (exp_gh < 0) { exp_gh = 0; } fail_if(exp_mem != members->num_values, "Expected %d members, found %d\n", exp_mem, members->num_values); if (exp_gh) { fail_if(exp_gh != ghosts->num_values, "Expected %d members, found %d\n", exp_gh, ghosts->num_values); } talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_memberof_ghost_replace) { struct sysdb_test_ctx *test_ctx; struct test_data *data; char *ghostname_del; char *ghostname_add; int ret; struct ldb_message_element *el; struct ldb_val gv, *test_gv; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->groupname = talloc_asprintf(data, "testgroup%d", data->gid); data->attrs = sysdb_new_attrs(data); if (ret != EOK) { fail("Could not create the changeset"); return; } /* The test replaces the testghost%i attribute with testuser%i */ ghostname_del = talloc_asprintf(data, "testghost%d", _i - 1); fail_unless(ghostname_del != NULL, "Out of memory\n"); ghostname_add = talloc_asprintf(data, "testuser%d", _i - 1); fail_unless(ghostname_add != NULL, "Out of memory\n"); ret = sysdb_attrs_steal_string(data->attrs, SYSDB_GHOST, ghostname_add); fail_unless(ret == EOK, "Cannot add attr\n"); data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = SYSDB_GHOST; data->attrlist[1] = NULL; /* Before the replace, the group has the testghost%_i as a member */ ret = sysdb_search_group_by_gid(data, test_ctx->domain, data->gid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname_del; gv.length = strlen(ghostname_del); el = ldb_msg_find_element(data->msg, SYSDB_GHOST); fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find ghost user %s\n", ghostname_del); /* Perform the replace operation */ ret = sysdb_set_group_attr(test_ctx->domain, data->groupname, data->attrs, SYSDB_MOD_REP); fail_unless(ret == EOK, "Cannot set group attrs\n"); /* After the replace, the group has the testghost%_i as a member */ ret = sysdb_search_group_by_gid(data, test_ctx->domain, data->gid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname_add; gv.length = strlen(ghostname_add); el = ldb_msg_find_element(data->msg, SYSDB_GHOST); fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find ghost user %s\n", ghostname_add); } END_TEST START_TEST (test_sysdb_memberof_ghost_replace_noop) { struct sysdb_test_ctx *test_ctx; struct test_data *data; char *ghostname_del; char *ghostname_add; int ret; struct ldb_message_element *el; struct ldb_val gv, *test_gv; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->gid = _i; data->groupname = talloc_asprintf(data, "testgroup%d", data->gid); data->attrs = sysdb_new_attrs(data); if (ret != EOK) { fail("Could not create the changeset"); return; } /* The test replaces the testghost%i attribute with testuser%i */ ghostname_del = talloc_asprintf(data, "testuser%d", _i - 1); fail_unless(ghostname_del != NULL, "Out of memory\n"); ghostname_add = talloc_asprintf(data, "testuser%d", _i - 1); fail_unless(ghostname_add != NULL, "Out of memory\n"); ret = sysdb_attrs_steal_string(data->attrs, SYSDB_GHOST, ghostname_add); fail_unless(ret == EOK, "Cannot add attr\n"); data->attrlist = talloc_array(data, const char *, 2); fail_unless(data->attrlist != NULL, "talloc_array failed."); data->attrlist[0] = SYSDB_GHOST; data->attrlist[1] = NULL; /* Before the replace, the group has the testghost%_i as a member */ ret = sysdb_search_group_by_gid(data, test_ctx->domain, data->gid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname_del; gv.length = strlen(ghostname_del); el = ldb_msg_find_element(data->msg, SYSDB_GHOST); fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find ghost user %s\n", ghostname_del); /* Perform the replace operation */ ret = sysdb_set_group_attr(test_ctx->domain, data->groupname, data->attrs, SYSDB_MOD_REP); fail_unless(ret == EOK, "Cannot set group attrs\n"); /* After the replace, the group has the testghost%_i as a member */ ret = sysdb_search_group_by_gid(data, test_ctx->domain, data->gid, data->attrlist, &data->msg); fail_if(ret != EOK, "Cannot retrieve group %llu\n", (unsigned long long) data->gid); gv.data = (uint8_t *) ghostname_add; gv.length = strlen(ghostname_add); el = ldb_msg_find_element(data->msg, SYSDB_GHOST); fail_if(el == NULL, "Cannot find ghost element\n"); test_gv = ldb_msg_find_val(el, &gv); fail_if(test_gv == NULL, "Cannot find ghost user %s\n", ghostname_add); } END_TEST START_TEST (test_sysdb_memberof_user_cleanup) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i * 2; ret = test_remove_user_by_uid(data); fail_if(ret != EOK, "Could not remove user with uid %d", _i); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_set_get_bool) { struct sysdb_test_ctx *test_ctx; struct ldb_dn *dn, *ne_dn; bool value; int ret; const char *attr_val = "BOOL_VALUE"; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } dn = sysdb_domain_dn(test_ctx, test_ctx->domain); fail_unless(dn != NULL); /* attribute is not created yet */ ret = sysdb_get_bool(test_ctx->sysdb, dn, attr_val, &value); fail_unless(ret == ENOENT, "sysdb_get_bool returned %d:[%s], but ENOENT is expected", ret, sss_strerror(ret)); /* add attribute */ ret = sysdb_set_bool(test_ctx->sysdb, dn, test_ctx->domain->name, attr_val, true); fail_unless(ret == EOK); /* successfully obtain attribute */ ret = sysdb_get_bool(test_ctx->sysdb, dn, attr_val, &value); fail_unless(ret == EOK, "sysdb_get_bool failed %d:[%s]", ret, sss_strerror(ret)); fail_unless(value == true); /* use non-existing DN */ ne_dn = ldb_dn_new_fmt(test_ctx, test_ctx->sysdb->ldb, SYSDB_DOM_BASE, "non-existing domain"); fail_unless(ne_dn != NULL); ret = sysdb_get_bool(test_ctx->sysdb, ne_dn, attr_val, &value); fail_unless(ret == ENOENT, "sysdb_get_bool returned %d:[%s], but ENOENT is expected", ret, sss_strerror(ret)); /* free ctx */ talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_attrs_to_list) { struct sysdb_attrs *attrs_list[3]; char **list; errno_t ret; TALLOC_CTX *test_ctx = talloc_new(NULL); attrs_list[0] = sysdb_new_attrs(test_ctx); ret = sysdb_attrs_add_string(attrs_list[0], "test_attr", "attr1"); fail_if(ret, "Add string failed"); attrs_list[1] = sysdb_new_attrs(test_ctx); ret = sysdb_attrs_add_string(attrs_list[1], "test_attr", "attr2"); fail_if(ret, "Add string failed"); attrs_list[2] = sysdb_new_attrs(test_ctx); ret = sysdb_attrs_add_string(attrs_list[2], "nottest_attr", "attr3"); fail_if(ret, "Add string failed"); ret = sysdb_attrs_to_list(test_ctx, attrs_list, 3, "test_attr", &list); fail_unless(ret == EOK, "sysdb_attrs_to_list failed with code %d", ret); fail_unless(strcmp(list[0],"attr1") == 0, "Expected [attr1], got [%s]", list[0]); fail_unless(strcmp(list[1],"attr2") == 0, "Expected [attr2], got [%s]", list[1]); fail_unless(list[2] == NULL, "List should be NULL-terminated"); talloc_free(test_ctx); } END_TEST START_TEST(test_sysdb_get_real_name) { errno_t ret; struct sysdb_test_ctx *test_ctx; struct sysdb_attrs *user_attrs; const char *str; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); user_attrs = sysdb_new_attrs(test_ctx); fail_unless(user_attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_string(user_attrs, SYSDB_NAME_ALIAS, "alias"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); ret = sysdb_attrs_add_string(user_attrs, SYSDB_UPN, "foo@bar"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); ret = sysdb_attrs_add_string(user_attrs, SYSDB_SID_STR, "S-1-5-21-123-456-789-111"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); ret = sysdb_attrs_add_string(user_attrs, SYSDB_UUID, "12345678-9012-3456-7890-123456789012"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); ret = sysdb_store_user(test_ctx->domain, "RealName", NULL, 22345, 0, "gecos", "/home/realname", "/bin/bash", NULL, user_attrs, NULL, -1, 0); fail_unless(ret == EOK, "sysdb_store_user failed."); /* Get real, uncanonicalized name as string */ ret = sysdb_get_real_name(test_ctx, test_ctx->domain, "alias", &str); fail_unless(ret == EOK, "sysdb_get_real_name failed."); fail_unless(strcmp(str, "RealName") == 0, "Expected [%s], got [%s].", "RealName", str); ret = sysdb_get_real_name(test_ctx, test_ctx->domain, "foo@bar", &str); fail_unless(ret == EOK, "sysdb_get_real_name failed."); fail_unless(strcmp(str, "RealName") == 0, "Expected [%s], got [%s].", "RealName", str); ret = sysdb_get_real_name(test_ctx, test_ctx->domain, "S-1-5-21-123-456-789-111", &str); fail_unless(ret == EOK, "sysdb_get_real_name failed."); fail_unless(strcmp(str, "RealName") == 0, "Expected [%s], got [%s].", "RealName", str); ret = sysdb_get_real_name(test_ctx, test_ctx->domain, "12345678-9012-3456-7890-123456789012", &str); fail_unless(ret == EOK, "sysdb_get_real_name failed."); fail_unless(strcmp(str, "RealName") == 0, "Expected [%s], got [%s].", "RealName", str); } END_TEST START_TEST(test_group_rename) { struct sysdb_test_ctx *test_ctx; errno_t ret; gid_t gid; const gid_t grgid = 38001; const char *name; const char *fromname = "fromgroup"; const char *toname = "togroup"; struct ldb_result *res; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_unless(ret == EOK, "Could not set up the test"); /* Store and verify the first group */ ret = sysdb_store_group(test_ctx->domain, fromname, grgid, NULL, 0, 0); fail_unless(ret == EOK, "Could not add first group"); ret = sysdb_getgrnam(test_ctx, test_ctx->domain, fromname, &res); fail_unless(ret == EOK, "Could not retrieve the group from cache\n"); if (res->count != 1) { fail("Invalid number of replies. Expected 1, got %d", res->count); goto done; } gid = ldb_msg_find_attr_as_uint(res->msgs[0], SYSDB_GIDNUM, 0); fail_unless(gid == grgid, "Did not find the expected GID (found %llu expected %llu)", (unsigned long long) gid, (unsigned long long) grgid); name = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); fail_unless(strcmp(fromname, name) == 0, "Did not find the expected name (found %s expected %s)", name, fromname); /* Perform rename and check that GID is the same, but name changed */ ret = sysdb_add_group(test_ctx->domain, toname, grgid, NULL, 0, 0); fail_unless(ret == EEXIST, "Group renamed with a low level call?"); ret = sysdb_store_group(test_ctx->domain, toname, grgid, NULL, 0, 0); fail_unless(ret == EOK, "Could not add first group"); ret = sysdb_getgrnam(test_ctx, test_ctx->domain, toname, &res); fail_unless(ret == EOK, "Could not retrieve the group from cache\n"); if (res->count != 1) { fail("Invalid number of replies. Expected 1, got %d", res->count); goto done; } gid = ldb_msg_find_attr_as_uint(res->msgs[0], SYSDB_GIDNUM, 0); fail_unless(gid == grgid, "Did not find the expected GID (found %llu expected %llu)", (unsigned long long) gid, (unsigned long long) grgid); name = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); fail_unless(strcmp(toname, name) == 0, "Did not find the expected GID (found %s expected %s)", name, toname); /* Verify the first name is gone */ ret = sysdb_getgrnam(test_ctx, test_ctx->domain, fromname, &res); fail_unless(ret == EOK, "Could not retrieve the group from cache\n"); fail_unless(res->count == 0, "Unexpectedly found the original user\n"); done: talloc_free(test_ctx); } END_TEST START_TEST(test_user_rename) { struct sysdb_test_ctx *test_ctx; errno_t ret; uid_t uid; const uid_t userid = 38002; const char *name; const char *fromname = "fromuser"; const char *toname = "touser"; struct ldb_result *res; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_unless(ret == EOK, "Could not set up the test"); /* Store and verify the first user */ ret = sysdb_store_user(test_ctx->domain, fromname, NULL, userid, 0, fromname, "/", "/bin/sh", NULL, NULL, NULL, 0, 0); fail_unless(ret == EOK, "Could not add first user"); ret = sysdb_getpwnam(test_ctx, test_ctx->domain, fromname, &res); fail_unless(ret == EOK, "Could not retrieve the user from cache\n"); if (res->count != 1) { fail("Invalid number of replies. Expected 1, got %d", res->count); goto done; } uid = ldb_msg_find_attr_as_uint(res->msgs[0], SYSDB_UIDNUM, 0); fail_unless(uid == userid, "Did not find the expected UID (found %llu expected %llu)", (unsigned long long) uid, (unsigned long long) userid); name = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); fail_unless(strcmp(fromname, name) == 0, "Did not find the expected name (found %s expected %s)", name, fromname); /* Perform rename and check that GID is the same, but name changed */ ret = sysdb_add_user(test_ctx->domain, toname, userid, 0, fromname, "/", "/bin/sh", NULL, NULL, 0, 0); fail_unless(ret == EEXIST, "A second user added with low level call?"); ret = sysdb_store_user(test_ctx->domain, toname, NULL, userid, 0, fromname, "/", "/bin/sh", NULL, NULL, NULL, 0, 0); fail_unless(ret == EOK, "Could not add second user"); ret = sysdb_getpwnam(test_ctx, test_ctx->domain, toname, &res); fail_unless(ret == EOK, "Could not retrieve the user from cache\n"); if (res->count != 1) { fail("Invalid number of replies. Expected 1, got %d", res->count); goto done; } uid = ldb_msg_find_attr_as_uint(res->msgs[0], SYSDB_UIDNUM, 0); fail_unless(uid == userid, "Did not find the expected UID (found %llu expected %llu)", (unsigned long long) uid, (unsigned long long) userid); name = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); fail_unless(strcmp(toname, name) == 0, "Did not find the expected name (found %s expected %s)", name, fromname); /* Verify the first name is gone */ ret = sysdb_getpwnam(test_ctx, test_ctx->domain, fromname, &res); fail_unless(ret == EOK, "Could not retrieve the user from cache\n"); fail_unless(res->count == 0, "Unexpectedly found the original user\n"); done: talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_update_members) { struct sysdb_test_ctx *test_ctx; char **add_groups; char **del_groups; const char *user = "testuser27000"; errno_t ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_unless(ret == EOK, "Could not set up the test"); /* Add a user to two groups */ add_groups = talloc_array(test_ctx, char *, 3); add_groups[0] = talloc_strdup(add_groups, "testgroup28001"); add_groups[1] = talloc_strdup(add_groups, "testgroup28002"); add_groups[2] = NULL; ret = sysdb_update_members(test_ctx->domain, user, SYSDB_MEMBER_USER, (const char *const *)add_groups, NULL); fail_unless(ret == EOK, "Could not add groups"); talloc_zfree(add_groups); /* Remove a user from one group and add to another */ del_groups = talloc_array(test_ctx, char *, 2); del_groups[0] = talloc_strdup(del_groups, "testgroup28001"); del_groups[1] = NULL; add_groups = talloc_array(test_ctx, char *, 2); add_groups[0] = talloc_strdup(add_groups, "testgroup28003"); add_groups[1] = NULL; ret = sysdb_update_members(test_ctx->domain, user, SYSDB_MEMBER_USER, (const char *const *)add_groups, (const char *const *)del_groups); fail_unless(ret == EOK, "Group replace failed"); talloc_zfree(add_groups); talloc_zfree(del_groups); /* Remove a user from two groups */ del_groups = talloc_array(test_ctx, char *, 3); del_groups[0] = talloc_strdup(del_groups, "testgroup28002"); del_groups[1] = talloc_strdup(del_groups, "testgroup28003"); del_groups[2] = NULL; ret = sysdb_update_members(test_ctx->domain, user, SYSDB_MEMBER_USER, NULL, (const char *const *)del_groups); fail_unless(ret == EOK, "Could not remove groups"); talloc_zfree(test_ctx); } END_TEST START_TEST (test_sysdb_group_dn_name) { struct sysdb_test_ctx *test_ctx; int ret; struct ldb_dn *group_dn; const char *groupname; char *parsed; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } groupname = talloc_asprintf(test_ctx, "testgroup%d", _i); group_dn = sysdb_group_dn(test_ctx, test_ctx->domain, groupname); if (!group_dn || !groupname) { fail("Out of memory"); return; } ret = sysdb_group_dn_name(test_ctx->sysdb, test_ctx, ldb_dn_get_linearized(group_dn), &parsed); fail_if(ret != EOK, "Cannot get the group name from DN"); fail_if(strcmp(groupname, parsed) != 0, "Names don't match (got %s)", parsed); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_add_basic_netgroup) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i; /* This is kinda abuse of uid, though */ data->netgrname = talloc_asprintf(data, "testnetgr%d", _i); ret = test_add_basic_netgroup(data); fail_if(ret != EOK, "Could not add netgroup %s", data->netgrname); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_search_netgroup_by_name) { struct sysdb_test_ctx *test_ctx; int ret; const char *netgrname; struct ldb_message *msg; struct ldb_dn *netgroup_dn; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } netgrname = talloc_asprintf(test_ctx, "testnetgr%d", _i); ret = sysdb_search_netgroup_by_name(test_ctx, test_ctx->domain, netgrname, NULL, &msg); fail_if(ret != EOK, "Could not find netgroup with name %s", netgrname); netgroup_dn = sysdb_netgroup_dn(test_ctx, test_ctx->domain, netgrname); fail_if(netgroup_dn == NULL); fail_if(ldb_dn_compare(msg->dn, netgroup_dn) != 0, "Found wrong netgroup!\n"); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_remove_netgroup_entry) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->netgrname = talloc_asprintf(data, "testnetgr%d", _i); ret = test_remove_netgroup_entry(data); fail_if(ret != EOK, "Could not remove netgroup %s", data->netgrname); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_remove_netgroup_by_name) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->netgrname = talloc_asprintf(data, "testnetgr%d", _i); ret = test_remove_netgroup_by_name(data); fail_if(ret != EOK, "Could not remove netgroup with name %s", data->netgrname); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_set_netgroup_attr) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); data->ctx = test_ctx; data->ev = test_ctx->ev; data->uid = _i; /* This is kinda abuse of uid, though */ data->netgrname = talloc_asprintf(data, "testnetgr%d", _i); ret = test_set_netgroup_attr(data); fail_if(ret != EOK, "Could not set netgroup attribute %s", data->netgrname); talloc_free(test_ctx); } END_TEST START_TEST (test_sysdb_get_netgroup_attr) { struct sysdb_test_ctx *test_ctx; int ret; const char *description; const char *netgrname; struct ldb_result *res; const char *attrs[] = { SYSDB_DESCRIPTION, NULL }; const char *attrval; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } description = talloc_asprintf(test_ctx, "Sysdb Netgroup %d", _i); netgrname = talloc_asprintf(test_ctx, "testnetgr%d", _i); ret = sysdb_get_netgroup_attr(test_ctx, test_ctx->domain, netgrname, attrs, &res); fail_if(ret != EOK, "Could not get netgroup attributes"); fail_if(res->count != 1, "Invalid number of entries, expected 1, got %d", res->count); attrval = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_DESCRIPTION, 0); fail_if(strcmp(attrval, description), "Got bad attribute value for netgroup %s", netgrname); talloc_free(test_ctx); } END_TEST START_TEST (test_netgroup_base_dn) { errno_t ret; struct sysdb_test_ctx *test_ctx; struct ldb_dn *base_dn; const char *strdn; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); base_dn = sysdb_netgroup_base_dn(test_ctx, test_ctx->domain); fail_if(base_dn == NULL, "Could not get netgroup base DN"); strdn = ldb_dn_get_linearized(base_dn); fail_if(strdn == NULL, "Could not get string netgroup base DN"); fail_if(strstr(strdn, SYSDB_NETGROUP_CONTAINER) != strdn, "Malformed netgroup baseDN"); } END_TEST START_TEST(test_odd_characters) { errno_t ret; struct sysdb_test_ctx *test_ctx; struct ldb_result *res; struct ldb_message *msg; const struct ldb_val *val; const char odd_username[] = "*(odd)\\user,name"; const char odd_username_orig_dn[] = "\\2a\\28odd\\29\\5cuser,name,cn=users,dc=example,dc=com"; const char odd_groupname[] = "*(odd\\*)\\group,name"; const char odd_netgroupname[] = "*(odd\\*)\\netgroup,name"; const char *received_user; const char *received_group; static const char *user_attrs[] = SYSDB_PW_ATTRS; static const char *netgr_attrs[] = SYSDB_NETGR_ATTRS; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } /* ===== Groups ===== */ /* Add */ ret = sysdb_add_incomplete_group(test_ctx->domain, odd_groupname, 20000, NULL, NULL, NULL, true, 0); fail_unless(ret == EOK, "sysdb_add_incomplete_group error [%d][%s]", ret, strerror(ret)); /* Retrieve */ ret = sysdb_search_group_by_name(test_ctx, test_ctx->domain, odd_groupname, NULL, &msg); fail_unless(ret == EOK, "sysdb_search_group_by_name error [%d][%s]", ret, strerror(ret)); talloc_zfree(msg); ret = sysdb_getgrnam(test_ctx, test_ctx->domain, odd_groupname, &res); fail_unless(ret == EOK, "sysdb_getgrnam error [%d][%s]", ret, strerror(ret)); fail_unless(res->count == 1, "Received [%d] responses", res->count); received_group = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); fail_unless(strcmp(received_group, odd_groupname) == 0, "Expected [%s], got [%s]", odd_groupname, received_group); talloc_free(res); /* ===== Users ===== */ /* Add */ ret = sysdb_add_basic_user(test_ctx->domain, odd_username, 10000, 10000, "","",""); fail_unless(ret == EOK, "sysdb_add_basic_user error [%d][%s]", ret, strerror(ret)); /* Retrieve */ ret = sysdb_search_user_by_name(test_ctx, test_ctx->domain, odd_username, NULL, &msg); fail_unless(ret == EOK, "sysdb_search_user_by_name error [%d][%s]", ret, strerror(ret)); val = ldb_dn_get_component_val(msg->dn, 0); fail_unless(strcmp((char *)val->data, odd_username)==0, "Expected [%s] got [%s]\n", odd_username, (char *)val->data); talloc_zfree(msg); /* Add to the group */ ret = sysdb_add_group_member(test_ctx->domain, odd_groupname, odd_username, SYSDB_MEMBER_USER, false); fail_unless(ret == EOK, "sysdb_add_group_member error [%d][%s]", ret, strerror(ret)); ret = sysdb_getpwnam(test_ctx, test_ctx->domain, odd_username, &res); fail_unless(ret == EOK, "sysdb_getpwnam error [%d][%s]", ret, strerror(ret)); fail_unless(res->count == 1, "Received [%d] responses", res->count); received_user = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); fail_unless(strcmp(received_user, odd_username) == 0, "Expected [%s], got [%s]", odd_username, received_user); talloc_zfree(res); /* Attributes */ ret = sysdb_get_user_attr(test_ctx, test_ctx->domain, odd_username, user_attrs, &res); fail_unless(ret == EOK, "sysdb_get_user_attr error [%d][%s]", ret, strerror(ret)); talloc_free(res); /* Delete User */ ret = sysdb_delete_user(test_ctx->domain, odd_username, 10000); fail_unless(ret == EOK, "sysdb_delete_user error [%d][%s]", ret, strerror(ret)); /* Delete non existing User */ ret = sysdb_delete_user(test_ctx->domain, odd_username, 10000); fail_unless(ret == ENOENT, "sysdb_delete_user error [%d][%s]", ret, strerror(ret)); /* Delete Group */ ret = sysdb_delete_group(test_ctx->domain, odd_groupname, 20000); fail_unless(ret == EOK, "sysdb_delete_group error [%d][%s]", ret, strerror(ret)); /* Add */ ret = sysdb_add_user(test_ctx->domain, odd_username, 10000, 0, "","","", odd_username_orig_dn, NULL, 5400, 0); fail_unless(ret == EOK, "sysdb_add_user error [%d][%s]", ret, strerror(ret)); /* Delete User */ ret = sysdb_delete_user(test_ctx->domain, odd_username, 10000); fail_unless(ret == EOK, "sysdb_delete_user error [%d][%s]", ret, strerror(ret)); /* ===== Netgroups ===== */ /* Add */ ret = sysdb_add_netgroup(test_ctx->domain, odd_netgroupname, "No description", NULL, NULL, 30, 0); fail_unless(ret == EOK, "sysdb_add_netgroup error [%d][%s]", ret, strerror(ret)); /* Retrieve */ ret = sysdb_getnetgr(test_ctx, test_ctx->domain, odd_netgroupname, &res); fail_unless(ret == EOK, "sysdb_getnetgr error [%d][%s]", ret, strerror(ret)); fail_unless(res->count == 1, "Received [%d] responses", res->count); talloc_zfree(res); ret = sysdb_get_netgroup_attr(test_ctx, test_ctx->domain, odd_netgroupname, netgr_attrs, &res); fail_unless(ret == EOK, "sysdb_get_netgroup_attr error [%d][%s]", ret, strerror(ret)); fail_unless(res->count == 1, "Received [%d] responses", res->count); talloc_zfree(res); /* ===== Arbitrary Entries ===== */ talloc_free(test_ctx); } END_TEST START_TEST(test_SSS_LDB_SEARCH) { errno_t ret; struct sysdb_test_ctx *test_ctx; struct ldb_dn *group_dn, *nonexist_dn; struct ldb_result *res; const char groupname[] = "test_group"; const char *received_group; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } check_leaks_push(test_ctx); group_dn = sysdb_group_dn(test_ctx, test_ctx->domain, groupname); fail_if(group_dn == NULL, "sysdb_group_dn failed"); nonexist_dn = sysdb_group_dn(test_ctx, test_ctx->domain, "non-existing-group"); fail_if(nonexist_dn == NULL, "sysdb_group_dn failed"); /* Add */ ret = sysdb_add_incomplete_group(test_ctx->domain, groupname, 20000, NULL, NULL, NULL, true, 0); fail_unless(ret == EOK, "sysdb_add_incomplete_group error [%d][%s]", ret, strerror(ret)); /* Retrieve */ /* Empty filter */ SSS_LDB_SEARCH(ret, test_ctx->sysdb->ldb, test_ctx, &res, group_dn, LDB_SCOPE_BASE, NULL, NULL); fail_unless(ret == EOK, "SSS_LDB_SEARCH error [%d][%s]", ret, strerror(ret)); fail_unless(res->count == 1, "Received [%d] responses", res->count); received_group = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); fail_unless(strcmp(received_group, groupname) == 0, "Expected [%s], got [%s]", groupname, received_group); talloc_zfree(res); /* Non-empty filter */ SSS_LDB_SEARCH(ret, test_ctx->sysdb->ldb, test_ctx, &res, group_dn, LDB_SCOPE_BASE, NULL, "objectClass=group"); fail_unless(ret == EOK, "SSS_LDB_SEARCH error [%d][%s]", ret, strerror(ret)); talloc_zfree(res); /* Filter yeilding no results */ SSS_LDB_SEARCH(ret, test_ctx->sysdb->ldb, test_ctx, &res, group_dn, LDB_SCOPE_BASE, NULL, "objectClass=nonExistingObjectClass"); fail_unless(ret == ENOENT, "sss_ldb_search error [%d][%s]", ret, strerror(ret)); talloc_zfree(res); /* Non-existing dn */ SSS_LDB_SEARCH(ret, test_ctx->sysdb->ldb, test_ctx, &res, nonexist_dn, LDB_SCOPE_BASE, NULL, NULL); fail_unless(ret == ENOENT, "SSS_LDB_SEARCH error [%d][%s]", ret, strerror(ret)); talloc_zfree(res); talloc_zfree(nonexist_dn); talloc_zfree(group_dn); fail_unless(check_leaks_pop(test_ctx) == true, "Memory leak"); } END_TEST /* == SERVICE TESTS == */ void services_check_match(struct sysdb_test_ctx *test_ctx, bool by_name, const char *primary_name, int port, const char **aliases, const char **protocols) { errno_t ret; unsigned int i, j; bool matched; const char *ret_name; int ret_port; struct ldb_result *res; struct ldb_message *msg; struct ldb_message_element *el; if (by_name) { /* Look up the service by name */ ret = sysdb_getservbyname(test_ctx, test_ctx->domain, primary_name, NULL, &res); fail_if(ret != EOK, "sysdb_getservbyname error [%s]\n", strerror(ret)); } else { /* Look up the newly-added service by port */ ret = sysdb_getservbyport(test_ctx, test_ctx->domain, port, NULL, &res); fail_if(ret != EOK, "sysdb_getservbyport error [%s]\n", strerror(ret)); } fail_if(res == NULL, "ENOMEM"); fail_if(res->count != 1); /* Make sure the returned entry matches */ msg = res->msgs[0]; ret_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); fail_if(ret_name == NULL); fail_unless(strcmp(ret_name, primary_name) == 0); ret_port = ldb_msg_find_attr_as_int(msg, SYSDB_SVC_PORT, 0); fail_if (ret_port != port); el = ldb_msg_find_element(msg, SYSDB_NAME_ALIAS); for (i = 0; i < el->num_values; i++) { matched = false; for (j = 0; aliases[j]; j++) { if (strcmp(aliases[j], (const char *)el->values[i].data) == 0) { matched = true; } } fail_if(!matched, "Unexpected value in LDB entry: [%s]", (const char *)el->values[i].data); } el = ldb_msg_find_element(msg, SYSDB_SVC_PROTO); for (i = 0; i < el->num_values; i++) { matched = false; for (j = 0; protocols[j]; j++) { if (strcmp(protocols[j], (const char *)el->values[i].data) == 0) { matched = true; } } fail_if(!matched, "Unexpected value in LDB entry: [%s]", (const char *)el->values[i].data); } } #define services_check_match_name(test_ctx, primary_name, port, aliases, protocols) \ do { \ services_check_match(test_ctx, true, primary_name, port, aliases, protocols); \ } while(0); #define services_check_match_port(test_ctx, primary_name, port, aliases, protocols) \ do { \ services_check_match(test_ctx, false, primary_name, port, aliases, protocols); \ } while(0); START_TEST(test_sysdb_add_services) { errno_t ret; struct sysdb_test_ctx *test_ctx; char *primary_name; const char **aliases; const char **protocols; int port = 3890; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); primary_name = talloc_asprintf(test_ctx, "test_service"); fail_if(primary_name == NULL); aliases = talloc_array(test_ctx, const char *, 3); fail_if(aliases == NULL); aliases[0] = talloc_asprintf(aliases, "test_service_alias1"); fail_if(aliases[0] == NULL); aliases[1] = talloc_asprintf(aliases, "test_service_alias2"); fail_if(aliases[1] == NULL); aliases[2] = NULL; protocols = talloc_array(test_ctx, const char *, 3); fail_if(protocols == NULL); protocols[0] = talloc_asprintf(protocols, "tcp"); fail_if(protocols[0] == NULL); protocols[1] = talloc_asprintf(protocols, "udp"); fail_if(protocols[1] == NULL); protocols[2] = NULL; ret = sysdb_transaction_start(test_ctx->sysdb); fail_if(ret != EOK, "[%s]", strerror(ret)); ret = sysdb_svc_add(NULL, test_ctx->domain, primary_name, port, aliases, protocols, NULL); fail_unless(ret == EOK, "sysdb_svc_add error [%s]\n", strerror(ret)); /* Search by name and make sure the results match */ services_check_match_name(test_ctx, primary_name, port, aliases, protocols); /* Search by port and make sure the results match */ services_check_match_port(test_ctx, primary_name, port, aliases, protocols); ret = sysdb_transaction_commit(test_ctx->sysdb); fail_if(ret != EOK, "[%s]", strerror(ret)); /* Clean up after ourselves (and test deleting by name) * * We have to do this after the transaction, because LDB * doesn't like adding and deleting the same entry in a * single transaction. */ ret = sysdb_svc_delete(test_ctx->domain, primary_name, 0, NULL); fail_if(ret != EOK, "[%s]", strerror(ret)); talloc_free(test_ctx); } END_TEST START_TEST(test_sysdb_store_services) { errno_t ret; struct sysdb_test_ctx *test_ctx; const char *primary_name = "test_store_service"; const char *alt_primary_name = "alt_test_store_service"; const char **aliases; const char **protocols; int port = 3890; int altport = 3891; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); aliases = talloc_array(test_ctx, const char *, 3); fail_if(aliases == NULL); aliases[0] = talloc_asprintf(aliases, "test_service_alias1"); fail_if(aliases[0] == NULL); aliases[1] = talloc_asprintf(aliases, "test_service_alias2"); fail_if(aliases[1] == NULL); aliases[2] = NULL; protocols = talloc_array(test_ctx, const char *, 3); fail_if(protocols == NULL); protocols[0] = talloc_asprintf(protocols, "tcp"); fail_if(protocols[0] == NULL); protocols[1] = talloc_asprintf(protocols, "udp"); fail_if(protocols[1] == NULL); protocols[2] = NULL; ret = sysdb_transaction_start(test_ctx->sysdb); fail_if(ret != EOK, "[%s]", strerror(ret)); /* Store this group (which will add it) */ ret = sysdb_store_service(test_ctx->domain, primary_name, port, aliases, protocols, NULL, NULL, 1, 1); fail_if(ret != EOK, "[%s]", strerror(ret)); /* Search by name and make sure the results match */ services_check_match_name(test_ctx, primary_name, port, aliases, protocols); /* Search by port and make sure the results match */ services_check_match_port(test_ctx, primary_name, port, aliases, protocols); /* Change the service name */ ret = sysdb_store_service(test_ctx->domain, alt_primary_name, port, aliases, protocols, NULL, NULL, 1, 1); fail_if (ret != EOK, "[%s]", strerror(ret)); services_check_match_name(test_ctx, alt_primary_name, port, aliases, protocols); /* Search by port and make sure the results match */ services_check_match_port(test_ctx, alt_primary_name, port, aliases, protocols); /* Change it back */ ret = sysdb_store_service(test_ctx->domain, primary_name, port, aliases, protocols, NULL, NULL, 1, 1); fail_if (ret != EOK, "[%s]", strerror(ret)); /* Change the port number */ ret = sysdb_store_service(test_ctx->domain, primary_name, altport, aliases, protocols, NULL, NULL, 1, 1); fail_if (ret != EOK, "[%s]", strerror(ret)); /* Search by name and make sure the results match */ services_check_match_name(test_ctx, primary_name, altport, aliases, protocols); /* Search by port and make sure the results match */ services_check_match_port(test_ctx, primary_name, altport, aliases, protocols); /* TODO: Test changing aliases and protocols */ ret = sysdb_transaction_commit(test_ctx->sysdb); fail_if(ret != EOK, "[%s]", strerror(ret)); /* Clean up after ourselves (and test deleting by port) * * We have to do this after the transaction, because LDB * doesn't like adding and deleting the same entry in a * single transaction. */ ret = sysdb_svc_delete(test_ctx->domain, NULL, altport, NULL); fail_if(ret != EOK, "[%s]", strerror(ret)); talloc_free(test_ctx); } END_TEST errno_t sysdb_svc_remove_alias(struct sysdb_ctx *sysdb, struct ldb_dn *dn, const char *alias); START_TEST(test_sysdb_svc_remove_alias) { errno_t ret; struct sysdb_test_ctx *test_ctx; const char *primary_name = "remove_alias_test"; const char **aliases; const char **protocols; int port = 3990; struct ldb_dn *dn; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); aliases = talloc_array(test_ctx, const char *, 3); fail_if(aliases == NULL); aliases[0] = talloc_asprintf(aliases, "remove_alias_alias1"); fail_if(aliases[0] == NULL); aliases[1] = talloc_asprintf(aliases, "remove_alias_alias2"); fail_if(aliases[1] == NULL); aliases[2] = NULL; protocols = talloc_array(test_ctx, const char *, 3); fail_if(protocols == NULL); protocols[0] = talloc_asprintf(protocols, "tcp"); fail_if(protocols[0] == NULL); protocols[1] = talloc_asprintf(protocols, "udp"); fail_if(protocols[1] == NULL); protocols[2] = NULL; ret = sysdb_transaction_start(test_ctx->sysdb); fail_if(ret != EOK, "[%s]", strerror(ret)); ret = sysdb_svc_add(NULL, test_ctx->domain, primary_name, port, aliases, protocols, NULL); fail_unless(ret == EOK, "sysdb_svc_add error [%s]\n", strerror(ret)); /* Search by name and make sure the results match */ services_check_match_name(test_ctx, primary_name, port, aliases, protocols); /* Search by port and make sure the results match */ services_check_match_port(test_ctx, primary_name, port, aliases, protocols); /* Now remove an alias */ dn = sysdb_svc_dn(test_ctx->sysdb, test_ctx, test_ctx->domain->name, primary_name); fail_if (dn == NULL); ret = sysdb_svc_remove_alias(test_ctx->sysdb, dn, aliases[1]); fail_if (ret != EOK, "[%s]", strerror(ret)); ret = sysdb_transaction_commit(test_ctx->sysdb); fail_if(ret != EOK); ret = sysdb_transaction_start(test_ctx->sysdb); fail_if(ret != EOK); /* Set aliases[1] to NULL to perform validation checks */ aliases[1] = NULL; /* Search by name and make sure the results match */ services_check_match_name(test_ctx, primary_name, port, aliases, protocols); /* Search by port and make sure the results match */ services_check_match_port(test_ctx, primary_name, port, aliases, protocols); ret = sysdb_transaction_commit(test_ctx->sysdb); fail_if(ret != EOK, "[%s]", strerror(ret)); talloc_free(test_ctx); } END_TEST #define LC_NAME_ALIAS_TEST_VAL "TeSt VaLuE" #define LC_NAME_ALIAS_CHECK_VAL "test value" START_TEST(test_sysdb_attrs_add_lc_name_alias) { int ret; struct sysdb_attrs *attrs; const char *str; const char **list = NULL; ret = sysdb_attrs_add_lc_name_alias(NULL, NULL); fail_unless(ret == EINVAL, "EINVAL not returned for NULL input"); attrs = sysdb_new_attrs(NULL); fail_unless(attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_lc_name_alias(attrs, LC_NAME_ALIAS_TEST_VAL); fail_unless(ret == EOK, "sysdb_attrs_add_lc_name_alias failed"); ret = sysdb_attrs_get_string(attrs, SYSDB_NAME_ALIAS, &str); fail_unless(ret == EOK, "sysdb_attrs_get_string failed"); fail_unless(strcmp(str, LC_NAME_ALIAS_CHECK_VAL) == 0, "Unexpected value, expected [%s], got [%s]", LC_NAME_ALIAS_CHECK_VAL, str); /* Add the same value a second time, it is not recommended to do this on * purpose but the test should illustrate the different to * sysdb_attrs_add_lc_name_alias_safe(). */ ret = sysdb_attrs_add_lc_name_alias(attrs, LC_NAME_ALIAS_TEST_VAL); fail_unless(ret == EOK, "sysdb_attrs_add_lc_name_alias failed"); ret = sysdb_attrs_get_string_array(attrs, SYSDB_NAME_ALIAS, attrs, &list); fail_unless(ret == EOK, "sysdb_attrs_get_string_array failed"); fail_unless(list != NULL, "No list returned"); fail_unless(list[0] != NULL, "Missing first list element"); fail_unless(strcmp(list[0], LC_NAME_ALIAS_CHECK_VAL) == 0, "Unexpected value, expected [%s], got [%s]", LC_NAME_ALIAS_CHECK_VAL, list[0]); fail_unless(list[1] != NULL, "Missing second list element"); fail_unless(strcmp(list[1], LC_NAME_ALIAS_CHECK_VAL) == 0, "Unexpected value, expected [%s], got [%s]", LC_NAME_ALIAS_CHECK_VAL, list[1]); fail_unless(list[2] == NULL, "Missing list terminator"); talloc_free(attrs); } END_TEST START_TEST(test_sysdb_attrs_add_lc_name_alias_safe) { int ret; struct sysdb_attrs *attrs; const char *str; const char **list = NULL; ret = sysdb_attrs_add_lc_name_alias_safe(NULL, NULL); fail_unless(ret == EINVAL, "EINVAL not returned for NULL input"); attrs = sysdb_new_attrs(NULL); fail_unless(attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_lc_name_alias_safe(attrs, LC_NAME_ALIAS_TEST_VAL); fail_unless(ret == EOK, "sysdb_attrs_add_lc_name_alias failed"); ret = sysdb_attrs_get_string(attrs, SYSDB_NAME_ALIAS, &str); fail_unless(ret == EOK, "sysdb_attrs_get_string failed"); fail_unless(strcmp(str, LC_NAME_ALIAS_CHECK_VAL) == 0, "Unexpected value, expected [%s], got [%s]", LC_NAME_ALIAS_CHECK_VAL, str); /* Adding the same value a second time should be ignored */ ret = sysdb_attrs_add_lc_name_alias_safe(attrs, LC_NAME_ALIAS_TEST_VAL); fail_unless(ret == EOK, "sysdb_attrs_add_lc_name_alias failed"); ret = sysdb_attrs_get_string_array(attrs, SYSDB_NAME_ALIAS, attrs, &list); fail_unless(ret == EOK, "sysdb_attrs_get_string_array failed"); fail_unless(list != NULL, "No list returned"); fail_unless(list[0] != NULL, "Missing first list element"); fail_unless(strcmp(list[0], LC_NAME_ALIAS_CHECK_VAL) == 0, "Unexpected value, expected [%s], got [%s]", LC_NAME_ALIAS_CHECK_VAL, list[0]); fail_unless(list[1] == NULL, "Missing list terminator"); /* Adding different value */ ret = sysdb_attrs_add_lc_name_alias_safe(attrs, "2nd_" LC_NAME_ALIAS_TEST_VAL); fail_unless(ret == EOK, "sysdb_attrs_add_lc_name_alias failed"); ret = sysdb_attrs_get_string_array(attrs, SYSDB_NAME_ALIAS, attrs, &list); fail_unless(ret == EOK, "sysdb_attrs_get_string_array failed"); fail_unless(list != NULL, "No list returned"); fail_unless(list[0] != NULL, "Missing first list element"); fail_unless(strcmp(list[0], LC_NAME_ALIAS_CHECK_VAL) == 0, "Unexpected value, expected [%s], got [%s]", LC_NAME_ALIAS_CHECK_VAL, list[0]); fail_unless(list[1] != NULL, "Missing first list element"); fail_unless(strcmp(list[1], "2nd_" LC_NAME_ALIAS_CHECK_VAL) == 0, "Unexpected value, expected [%s], got [%s]", "2nd_" LC_NAME_ALIAS_CHECK_VAL, list[1]); fail_unless(list[2] == NULL, "Missing list terminator"); talloc_free(attrs); } END_TEST START_TEST(test_sysdb_attrs_get_string_array) { int ret; struct sysdb_attrs *attrs; const char **list; const char *attrname = "test_attr"; TALLOC_CTX *tmp_ctx; struct ldb_message_element *el = NULL; tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "talloc_new failed"); attrs = sysdb_new_attrs(NULL); fail_unless(attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_string(attrs, attrname, "val1"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed"); ret = sysdb_attrs_add_string(attrs, attrname, "val2"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed"); ret = sysdb_attrs_get_el_ext(attrs, attrname, false, &el); fail_unless(ret == EOK, "sysdb_attrs_get_el_ext failed"); list = sss_ldb_el_to_string_list(tmp_ctx, el); fail_if(list == NULL, ("sss_ldb_el_to_string_list failed\n")); ck_assert_str_eq(list[0], "val1"); ck_assert_str_eq(list[1], "val2"); fail_unless(list[2] == NULL, "Expected terminated list"); talloc_free(list); ret = sysdb_attrs_get_string_array(attrs, attrname, tmp_ctx, &list); fail_unless(ret == EOK, "sysdb_attrs_get_string_array failed"); /* This test relies on values keeping the same order. It is the case * with LDB, but if we ever switch from LDB, we need to amend the test */ ck_assert_str_eq(list[0], "val1"); ck_assert_str_eq(list[1], "val2"); fail_unless(list[2] == NULL, "Expected terminated list"); talloc_free(tmp_ctx); } END_TEST START_TEST(test_sysdb_attrs_add_val) { int ret; struct sysdb_attrs *attrs; TALLOC_CTX *tmp_ctx; struct ldb_val val = {discard_const(TEST_ATTR_VALUE), sizeof(TEST_ATTR_VALUE) - 1}; tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "talloc_new failed"); attrs = sysdb_new_attrs(NULL); fail_unless(attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_val(attrs, TEST_ATTR_NAME, &val); fail_unless(ret == EOK, "sysdb_attrs_add_val failed."); ret = sysdb_attrs_add_val(attrs, TEST_ATTR_NAME, &val); fail_unless(ret == EOK, "sysdb_attrs_add_val failed."); fail_unless(attrs->num == 1, "Unexpected number of attributes."); fail_unless(strcmp(attrs->a[0].name, TEST_ATTR_NAME) == 0, "Unexpected attribute name."); fail_unless(attrs->a[0].num_values == 2, "Unexpected number of attribute values."); fail_unless(ldb_val_string_cmp(&attrs->a[0].values[0], TEST_ATTR_VALUE) == 0, "Unexpected attribute value."); fail_unless(ldb_val_string_cmp(&attrs->a[0].values[1], TEST_ATTR_VALUE) == 0, "Unexpected attribute value."); talloc_free(tmp_ctx); } END_TEST START_TEST(test_sysdb_attrs_add_val_safe) { int ret; struct sysdb_attrs *attrs; TALLOC_CTX *tmp_ctx; struct ldb_val val = {discard_const(TEST_ATTR_VALUE), sizeof(TEST_ATTR_VALUE) - 1}; tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "talloc_new failed"); attrs = sysdb_new_attrs(NULL); fail_unless(attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_val(attrs, TEST_ATTR_NAME, &val); fail_unless(ret == EOK, "sysdb_attrs_add_val failed."); ret = sysdb_attrs_add_val_safe(attrs, TEST_ATTR_NAME, &val); fail_unless(ret == EOK, "sysdb_attrs_add_val failed."); fail_unless(attrs->num == 1, "Unexpected number of attributes."); fail_unless(strcmp(attrs->a[0].name, TEST_ATTR_NAME) == 0, "Unexpected attribute name."); fail_unless(attrs->a[0].num_values == 1, "Unexpected number of attribute values."); fail_unless(ldb_val_string_cmp(&attrs->a[0].values[0], TEST_ATTR_VALUE) == 0, "Unexpected attribute value."); talloc_free(tmp_ctx); } END_TEST START_TEST(test_sysdb_attrs_add_string_safe) { int ret; struct sysdb_attrs *attrs; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "talloc_new failed"); attrs = sysdb_new_attrs(NULL); fail_unless(attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_string(attrs, TEST_ATTR_NAME, TEST_ATTR_VALUE); fail_unless(ret == EOK, "sysdb_attrs_add_val failed."); ret = sysdb_attrs_add_string_safe(attrs, TEST_ATTR_NAME, TEST_ATTR_VALUE); fail_unless(ret == EOK, "sysdb_attrs_add_val failed."); fail_unless(attrs->num == 1, "Unexpected number of attributes."); fail_unless(strcmp(attrs->a[0].name, TEST_ATTR_NAME) == 0, "Unexpected attribute name."); fail_unless(attrs->a[0].num_values == 1, "Unexpected number of attribute values."); fail_unless(ldb_val_string_cmp(&attrs->a[0].values[0], TEST_ATTR_VALUE) == 0, "Unexpected attribute value."); talloc_free(tmp_ctx); } END_TEST START_TEST (test_sysdb_search_return_ENOENT) { struct sysdb_test_ctx *test_ctx; int ret; struct ldb_dn *user_dn = NULL; struct ldb_message *msg = NULL; struct ldb_message **msgs = NULL; struct ldb_result *res = NULL; size_t count; const char *str = NULL; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); check_leaks_push(test_ctx); /* id mapping */ ret = sysdb_idmap_get_mappings(test_ctx, test_ctx->domain, &res); fail_unless(ret == ENOENT, "sysdb_idmap_get_mappings error [%d][%s].", ret, strerror(ret)); talloc_zfree(res); /* Search user */ ret = sysdb_search_user_by_name(test_ctx, test_ctx->domain, "nonexisting_user", NULL, &msg); fail_unless(ret == ENOENT, "sysdb_search_user_by_name error [%d][%s].", ret, strerror(ret)); talloc_zfree(msg); ret = sysdb_get_real_name(test_ctx, test_ctx->domain, "nonexisting_user", &str); fail_unless(ret == ENOENT, "sysdb_get_real_name error [%d][%s].", ret, strerror(ret)); talloc_zfree(str); ret = sysdb_search_user_by_uid(test_ctx, test_ctx->domain, 1234, NULL, &msg); fail_unless(ret == ENOENT, "sysdb_search_user_by_uid error [%d][%s].", ret, strerror(ret)); talloc_zfree(msg); ret = sysdb_search_user_by_sid_str(test_ctx, test_ctx->domain, "S-5-4-3-2-1", NULL, &msg); fail_unless(ret == ENOENT, "sysdb_search_user_by_sid_str failed with " "[%d][%s].", ret, strerror(ret)); /* Search group */ ret = sysdb_search_group_by_name(test_ctx, test_ctx->domain, "nonexisting_group", NULL, &msg); fail_unless(ret == ENOENT, "sysdb_search_group_by_name error [%d][%s].", ret, strerror(ret)); talloc_zfree(msg); ret = sysdb_search_group_by_gid(test_ctx, test_ctx->domain, 1234, NULL, &msg); fail_unless(ret == ENOENT, "sysdb_search_group_by_gid error [%d][%s].", ret, strerror(ret)); talloc_zfree(msg); ret = sysdb_search_group_by_sid_str(test_ctx, test_ctx->domain, "S-5-4-3-2-1", NULL, &msg); fail_unless(ret == ENOENT, "sysdb_search_group_by_sid_str failed with " "[%d][%s].", ret, strerror(ret)); talloc_zfree(msg); /* Search netgroup */ ret = sysdb_search_netgroup_by_name(test_ctx, test_ctx->domain, "nonexisting_netgroup", NULL, &msg); fail_unless(ret == ENOENT, "sysdb_search_netgroup_by_name error [%d][%s].", ret, strerror(ret)); talloc_zfree(msg); ret = sysdb_getnetgr(test_ctx, test_ctx->domain, "nonexisting_netgroup", &res); fail_unless(ret == ENOENT, "sysdb_getnetgr error [%d][%s]", ret, strerror(ret)); talloc_zfree(res); /* Search object */ ret = sysdb_search_object_by_sid(test_ctx, test_ctx->domain, "S-5-4-3-2-1", NULL, &res); fail_unless(ret == ENOENT, "sysdb_search_object_by_sid failed with " "[%d][%s].", ret, strerror(ret)); talloc_zfree(res); /* Search can return more results */ ret = sysdb_search_users(test_ctx, test_ctx->domain, "("SYSDB_SHELL"=/bin/nologin)", NULL, &count, &msgs); fail_unless(ret == ENOENT, "sysdb_search_users failed: %d, %s", ret, strerror(ret)); talloc_zfree(msgs); ret = sysdb_search_groups(test_ctx, test_ctx->domain, "("SYSDB_GIDNUM"=1234)", NULL, &count, &msgs); fail_unless(ret == ENOENT, "sysdb_search_groups failed: %d, %s", ret, strerror(ret)); talloc_zfree(msgs); ret = sysdb_search_netgroups(test_ctx, test_ctx->domain, "("SYSDB_NAME"=nonexisting)", NULL, &count, &msgs); fail_unless(ret == ENOENT, "sysdb_search_netgroups failed: %d, %s", ret, strerror(ret)); talloc_zfree(msgs); /* Search custom */ ret = sysdb_search_custom(test_ctx, test_ctx->domain, "(distinguishedName=nonexisting)", CUSTOM_TEST_CONTAINER, NULL, &count, &msgs); fail_unless(ret == ENOENT, "sysdb_search_custom failed: %d, %s", ret, strerror(ret)); talloc_zfree(msgs); ret = sysdb_search_custom_by_name(test_ctx, test_ctx->domain, "nonexisting", CUSTOM_TEST_CONTAINER, NULL, &count, &msgs); fail_unless(ret == ENOENT, "sysdb_search_custom_by_name failed: %d, %s", ret, strerror(ret)); talloc_zfree(msgs); /* General search */ user_dn = sysdb_user_dn(test_ctx, test_ctx->domain, "nonexisting_user"); fail_if(user_dn == NULL, "sysdb_user_dn failed"); ret = sysdb_asq_search(test_ctx, test_ctx->domain, user_dn, NULL, "memberof", NULL, &count, &msgs); fail_unless(ret == ENOENT, "sysdb_asq_search failed: %d, %s", ret, strerror(ret)); talloc_zfree(msgs); ret = sysdb_search_entry(test_ctx, test_ctx->sysdb, user_dn, LDB_SCOPE_SUBTREE, "objectClass=user", NULL, &count, &msgs); fail_unless(ret == ENOENT, "sysdb_search_entry failed: %d, %s", ret, strerror(ret)); talloc_zfree(msgs); talloc_zfree(user_dn); /* SSS_LDB_SEARCH */ user_dn = sysdb_user_dn(test_ctx, test_ctx->domain, "nonexisting_user"); fail_if(user_dn == NULL, "sysdb_user_dn failed"); SSS_LDB_SEARCH(ret, test_ctx->sysdb->ldb, test_ctx, &res, user_dn, LDB_SCOPE_BASE, NULL, "objectClass=user"); fail_unless(ret == ENOENT, "SSS_LDB_SEARCH failed: %d, %s", ret, strerror(ret)); talloc_zfree(res); talloc_zfree(user_dn); /* TODO: test sysdb_search_selinux_config */ fail_unless(check_leaks_pop(test_ctx) == true, "Memory leak"); talloc_free(test_ctx); } END_TEST START_TEST(test_sysdb_has_enumerated) { errno_t ret; struct sysdb_test_ctx *test_ctx; bool enumerated; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); ret = sysdb_has_enumerated(test_ctx->domain, &enumerated); fail_if(ret != ENOENT, "Error [%d][%s] checking enumeration ENOENT is expected", ret, strerror(ret)); ret = sysdb_set_enumerated(test_ctx->domain, true); fail_if(ret != EOK, "Error [%d][%s] setting enumeration", ret, strerror(ret)); /* Recheck enumeration status */ ret = sysdb_has_enumerated(test_ctx->domain, &enumerated); fail_if(ret != EOK, "Error [%d][%s] checking enumeration", ret, strerror(ret)); fail_unless(enumerated, "Enumeration should have been set to true"); talloc_free(test_ctx); } END_TEST START_TEST(test_sysdb_original_dn_case_insensitive) { errno_t ret; struct sysdb_test_ctx *test_ctx; const char *filter; struct ldb_dn *base_dn; const char *no_attrs[] = { NULL }; struct ldb_message **msgs; size_t num_msgs; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); ret = sysdb_add_incomplete_group(test_ctx->domain, "case_sensitive_group1", 29000, "cn=case_sensitive_group1,cn=example,cn=com", NULL, NULL, true, 0); fail_unless(ret == EOK, "sysdb_add_incomplete_group error [%d][%s]", ret, strerror(ret)); ret = sysdb_add_incomplete_group(test_ctx->domain, "case_sensitive_group2", 29001, "cn=CASE_SENSITIVE_GROUP1,cn=EXAMPLE,cn=COM", NULL, NULL, true, 0); fail_unless(ret == EOK, "sysdb_add_incomplete_group error [%d][%s]", ret, strerror(ret)); /* Search by originalDN should yield 2 entries */ filter = talloc_asprintf(test_ctx, "%s=%s", SYSDB_ORIG_DN, "cn=case_sensitive_group1,cn=example,cn=com"); fail_if(filter == NULL, "Cannot construct filter\n"); base_dn = sysdb_domain_dn(test_ctx, test_ctx->domain); fail_if(base_dn == NULL, "Cannot construct basedn\n"); ret = sysdb_search_entry(test_ctx, test_ctx->sysdb, base_dn, LDB_SCOPE_SUBTREE, filter, no_attrs, &num_msgs, &msgs); fail_unless(ret == EOK, "cache search error [%d][%s]", ret, strerror(ret)); fail_unless(num_msgs == 2, "Did not find the expected number of entries using " "case insensitive originalDN search"); } END_TEST START_TEST(test_sysdb_search_sid_str) { errno_t ret; struct sysdb_test_ctx *test_ctx; struct ldb_message *msg; struct sysdb_attrs *attrs = NULL; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); ret = sysdb_add_incomplete_group(test_ctx->domain, "group", 29000, "cn=group,cn=example,cn=com", "S-1-2-3-4", NULL, true, 0); fail_unless(ret == EOK, "sysdb_add_incomplete_group error [%d][%s]", ret, strerror(ret)); ret = sysdb_search_group_by_sid_str(test_ctx, test_ctx->domain, "S-1-2-3-4", NULL, &msg); fail_unless(ret == EOK, "sysdb_search_group_by_sid_str failed with [%d][%s].", ret, strerror(ret)); /* Delete the group by SID */ ret = sysdb_delete_by_sid(test_ctx->sysdb, test_ctx->domain, "S-1-2-3-4"); fail_unless(ret == EOK, "sysdb_delete_by_sid failed with [%d][%s].", ret, strerror(ret)); /* Verify it's gone */ ret = sysdb_search_group_by_sid_str(test_ctx, test_ctx->domain, "S-1-2-3-4", NULL, &msg); fail_unless(ret == ENOENT, "sysdb_search_group_by_sid_str failed with [%d][%s].", ret, strerror(ret)); talloc_free(msg); msg = NULL; attrs = sysdb_new_attrs(test_ctx); fail_unless(attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, "S-1-2-3-4-5"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed with [%d][%s].", ret, strerror(ret)); ret = sysdb_add_user(test_ctx->domain, "SIDuser", 12345, 0, "SID user", "/home/siduser", "/bin/bash", NULL, attrs, 0, 0); fail_unless(ret == EOK, "sysdb_add_user failed with [%d][%s].", ret, strerror(ret)); ret = sysdb_search_user_by_sid_str(test_ctx, test_ctx->domain, "S-1-2-3-4-5", NULL, &msg); fail_unless(ret == EOK, "sysdb_search_user_by_sid_str failed with [%d][%s].", ret, strerror(ret)); talloc_free(test_ctx); } END_TEST START_TEST(test_sysdb_search_object_by_uuid) { errno_t ret; struct sysdb_test_ctx *test_ctx; struct ldb_result *res; struct sysdb_attrs *attrs = NULL; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); attrs = sysdb_new_attrs(test_ctx); fail_unless(attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_string(attrs, SYSDB_UUID, "11111111-2222-3333-4444-555555555555"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed with [%d][%s].", ret, strerror(ret)); ret = sysdb_add_user(test_ctx->domain, "UUIDuser", 123456, 0, "UUID user", "/home/uuiduser", "/bin/bash", NULL, attrs, 0, 0); fail_unless(ret == EOK, "sysdb_add_user failed with [%d][%s].", ret, strerror(ret)); ret = sysdb_search_object_by_uuid(test_ctx, test_ctx->domain, "11111111-2222-3333-4444-555555555556", NULL, &res); fail_unless(ret == ENOENT, "Unexpected return code from sysdb_search_object_by_uuid for " "missing object, expected [%d], got [%d].", ENOENT, ret); ret = sysdb_search_object_by_uuid(test_ctx, test_ctx->domain, "11111111-2222-3333-4444-555555555555", NULL, &res); fail_unless(ret == EOK, "sysdb_search_object_by_uuid failed with [%d][%s].", ret, strerror(ret)); fail_unless(res->count == 1, "Unexpected number of results, " \ "expected [%u], get [%u].", 1, res->count); fail_unless(strcmp(ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, ""), "UUIDuser") == 0, "Unexpected object found, " \ "expected [%s], got [%s].", "UUIDuser", ldb_msg_find_attr_as_string(res->msgs[0],SYSDB_NAME, "")); talloc_free(test_ctx); } END_TEST /* For simple searches the content of the certificate does not matter */ #define TEST_USER_CERT_DERB64 "gJznJT7L0aETU5CMk+n+1Q==" START_TEST(test_sysdb_search_user_by_cert) { errno_t ret; struct sysdb_test_ctx *test_ctx; struct ldb_result *res; struct sysdb_attrs *attrs = NULL; struct ldb_val val; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); val.data = sss_base64_decode(test_ctx, TEST_USER_CERT_DERB64, &val.length); fail_unless(val.data != NULL, "sss_base64_decode failed."); attrs = sysdb_new_attrs(test_ctx); fail_unless(attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_val(attrs, SYSDB_USER_CERT, &val); fail_unless(ret == EOK, "sysdb_attrs_add_val failed with [%d][%s].", ret, strerror(ret)); ret = sysdb_add_user(test_ctx->domain, "certuser", 234567, 0, "cert user", "/home/certuser", "/bin/bash", NULL, attrs, 0, 0); fail_unless(ret == EOK, "sysdb_add_user failed with [%d][%s].", ret, strerror(ret)); ret = sysdb_search_user_by_cert(test_ctx, test_ctx->domain, "ABA=", &res); fail_unless(ret == ENOENT, "Unexpected return code from sysdb_search_user_by_cert for " "missing object, expected [%d], got [%d].", ENOENT, ret); ret = sysdb_search_user_by_cert(test_ctx, test_ctx->domain, TEST_USER_CERT_DERB64, &res); fail_unless(ret == EOK, "sysdb_search_user_by_cert failed with [%d][%s].", ret, strerror(ret)); fail_unless(res->count == 1, "Unexpected number of results, " \ "expected [%u], get [%u].", 1, res->count); fail_unless(strcmp(ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, ""), "certuser") == 0, "Unexpected object found, " \ "expected [%s], got [%s].", "certuser", ldb_msg_find_attr_as_string(res->msgs[0],SYSDB_NAME, "")); talloc_free(test_ctx); } END_TEST START_TEST(test_sysdb_delete_by_sid) { errno_t ret; struct sysdb_test_ctx *test_ctx; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); check_leaks_push(test_ctx); /* Delete the group by SID */ ret = sysdb_delete_by_sid(test_ctx->sysdb, test_ctx->domain, "S-1-2-3-4-NON_EXISTING_SID"); fail_unless(ret == EOK, "sysdb_delete_by_sid failed with [%d][%s].", ret, strerror(ret)); fail_unless(check_leaks_pop(test_ctx) == true, "Memory leak"); talloc_free(test_ctx); } END_TEST const char *const testdom[4] = { "test.sub", "TEST.SUB", "test", "S-3" }; START_TEST(test_sysdb_subdomain_store_user) { struct sysdb_test_ctx *test_ctx; errno_t ret; struct sss_domain_info *subdomain = NULL; struct ldb_result *results = NULL; struct ldb_dn *base_dn = NULL; struct ldb_dn *check_dn = NULL; const char *attrs[] = { SYSDB_NAME, SYSDB_NAME_ALIAS, NULL }; struct sysdb_attrs *user_attrs; struct ldb_message *msg; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); subdomain = new_subdomain(test_ctx, test_ctx->domain, testdom[0], testdom[1], testdom[2], testdom[3], false, false, NULL, 0); fail_unless(subdomain != NULL, "Failed to create new subdomin."); ret = sysdb_subdomain_store(test_ctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[3], false, false, NULL, 0); fail_if(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain); fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]", ret, strerror(ret)); user_attrs = sysdb_new_attrs(test_ctx); fail_unless(user_attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_string(user_attrs, SYSDB_NAME_ALIAS, "subdomuser"); fail_unless(ret == EOK, "sysdb_store_user failed."); ret = sysdb_store_user(subdomain, "SubDomUser", NULL, 12345, 0, "Sub Domain User", "/home/subdomuser", "/bin/bash", NULL, user_attrs, NULL, -1, 0); fail_unless(ret == EOK, "sysdb_store_user failed."); base_dn =ldb_dn_new(test_ctx, test_ctx->sysdb->ldb, "cn=sysdb"); fail_unless(base_dn != NULL); check_dn = ldb_dn_new(test_ctx, test_ctx->sysdb->ldb, "name=SubDomUser,cn=users,cn=test.sub,cn=sysdb"); fail_unless(check_dn != NULL); ret = ldb_search(test_ctx->sysdb->ldb, test_ctx, &results, base_dn, LDB_SCOPE_SUBTREE, NULL, "name=SubDomUser"); fail_unless(ret == EOK, "ldb_search failed."); fail_unless(results->count == 1, "Unexpected number of results, " "expected [%d], got [%d]", 1, results->count); fail_unless(ldb_dn_compare(results->msgs[0]->dn, check_dn) == 0, "Unexpedted DN returned"); /* Subdomains are case-insensitive. Test that the lowercased name * can be found, too */ ret = sysdb_search_user_by_name(test_ctx, subdomain, "subdomuser", attrs, &msg); fail_unless(ret == EOK, "sysdb_search_user_by_name failed."); ret = sysdb_delete_user(subdomain, "subdomuser", 0); fail_unless(ret == EOK, "sysdb_delete_user failed [%d][%s].", ret, strerror(ret)); ret = ldb_search(test_ctx->sysdb->ldb, test_ctx, &results, base_dn, LDB_SCOPE_SUBTREE, NULL, "name=subdomuser"); fail_unless(ret == EOK, "ldb_search failed."); fail_unless(results->count == 0, "Unexpected number of results, " "expected [%d], got [%d]", 0, results->count); } END_TEST START_TEST(test_sysdb_subdomain_user_ops) { struct sysdb_test_ctx *test_ctx; errno_t ret; struct sss_domain_info *subdomain = NULL; struct ldb_message *msg = NULL; struct ldb_dn *check_dn = NULL; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); subdomain = new_subdomain(test_ctx, test_ctx->domain, testdom[0], testdom[1], testdom[2], testdom[3], false, false, NULL, 0); fail_unless(subdomain != NULL, "Failed to create new subdomin."); ret = sysdb_subdomain_store(test_ctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[3], false, false, NULL, 0); fail_if(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain); fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]", ret, strerror(ret)); ret = sysdb_store_user(subdomain, "subdomuser", NULL, 12345, 0, "Sub Domain User", "/home/subdomuser", "/bin/bash", NULL, NULL, NULL, -1, 0); fail_unless(ret == EOK, "sysdb_store_domuser failed."); check_dn = ldb_dn_new(test_ctx, test_ctx->sysdb->ldb, "name=subdomuser,cn=users,cn=test.sub,cn=sysdb"); fail_unless(check_dn != NULL); ret = sysdb_search_user_by_name(test_ctx, subdomain, "subdomuser", NULL, &msg); fail_unless(ret == EOK, "sysdb_search_user_by_name failed with [%d][%s].", ret, strerror(ret)); fail_unless(ldb_dn_compare(msg->dn, check_dn) == 0, "Unexpedted DN returned"); ret = sysdb_search_user_by_uid(test_ctx, subdomain, 12345, NULL, &msg); fail_unless(ret == EOK, "sysdb_search_domuser_by_uid failed with [%d][%s].", ret, strerror(ret)); fail_unless(ldb_dn_compare(msg->dn, check_dn) == 0, "Unexpedted DN returned"); ret = sysdb_delete_user(subdomain, "subdomuser", 12345); fail_unless(ret == EOK, "sysdb_delete_domuser failed with [%d][%s].", ret, strerror(ret)); } END_TEST START_TEST(test_sysdb_subdomain_group_ops) { struct sysdb_test_ctx *test_ctx; errno_t ret; struct sss_domain_info *subdomain = NULL; struct ldb_message *msg = NULL; struct ldb_dn *check_dn = NULL; struct sysdb_attrs *group_attrs; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); subdomain = new_subdomain(test_ctx, test_ctx->domain, testdom[0], testdom[1], testdom[2], testdom[3], false, false, NULL, 0); fail_unless(subdomain != NULL, "Failed to create new subdomin."); ret = sysdb_subdomain_store(test_ctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[3], false, false, NULL, 0); fail_if(ret != EOK, "Could not set up the test (test subdom)"); ret = sysdb_update_subdomains(test_ctx->domain); fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]", ret, strerror(ret)); group_attrs = sysdb_new_attrs(test_ctx); fail_unless(group_attrs != NULL, "sysdb_new_attrs failed"); ret = sysdb_attrs_add_string(group_attrs, SYSDB_NAME_ALIAS, "subdomgroup"); fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); ret = sysdb_store_group(subdomain, "subDomGroup", 12345, group_attrs, -1, 0); fail_unless(ret == EOK, "sysdb_store_group failed."); check_dn = ldb_dn_new(test_ctx, test_ctx->sysdb->ldb, "name=subDomGroup,cn=groups,cn=test.sub,cn=sysdb"); fail_unless(check_dn != NULL); ret = sysdb_search_group_by_name(test_ctx, subdomain, "subDomGroup", NULL, &msg); fail_unless(ret == EOK, "sysdb_search_group_by_name failed with [%d][%s].", ret, strerror(ret)); fail_unless(ldb_dn_compare(msg->dn, check_dn) == 0, "Unexpected DN returned"); /* subdomains are case insensitive, so it should be possible to search the group with a lowercase name version, too */ ret = sysdb_search_group_by_name(test_ctx, subdomain, "subdomgroup", NULL, &msg); fail_unless(ret == EOK, "case-insensitive group search failed with [%d][%s].", ret, strerror(ret)); fail_unless(ldb_dn_compare(msg->dn, check_dn) == 0, "Unexpected DN returned"); ret = sysdb_search_group_by_gid(test_ctx, subdomain, 12345, NULL, &msg); fail_unless(ret == EOK, "sysdb_search_group_by_gid failed with [%d][%s].", ret, strerror(ret)); fail_unless(ldb_dn_compare(msg->dn, check_dn) == 0, "Unexpedted DN returned"); ret = sysdb_delete_group(subdomain, "subDomGroup", 12345); fail_unless(ret == EOK, "sysdb_delete_group failed with [%d][%s].", ret, strerror(ret)); } END_TEST #ifdef BUILD_AUTOFS START_TEST(test_autofs_create_map) { struct sysdb_test_ctx *test_ctx; const char *autofsmapname; errno_t ret; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i); fail_if(autofsmapname == NULL, "Out of memory\n"); ret = sysdb_save_autofsmap(test_ctx->domain, autofsmapname, autofsmapname, NULL, 0, 0); fail_if(ret != EOK, "Could not store autofs map %s", autofsmapname); talloc_free(test_ctx); } END_TEST START_TEST(test_autofs_retrieve_map) { struct sysdb_test_ctx *test_ctx; const char *autofsmapname; errno_t ret; struct ldb_message *map = NULL; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i); fail_if(autofsmapname == NULL, "Out of memory\n"); ret = sysdb_get_map_byname(test_ctx, test_ctx->domain, autofsmapname, &map); fail_if(ret != EOK, "Could not retrieve autofs map %s", autofsmapname); fail_if(map == NULL, "No map retrieved?\n"); talloc_free(test_ctx); } END_TEST START_TEST(test_autofs_delete_map) { struct sysdb_test_ctx *test_ctx; const char *autofsmapname; errno_t ret; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i); fail_if(autofsmapname == NULL, "Out of memory\n"); ret = sysdb_delete_autofsmap(test_ctx->domain, autofsmapname); fail_if(ret != EOK, "Could not retrieve autofs map %s", autofsmapname); talloc_free(test_ctx); } END_TEST START_TEST(test_autofs_retrieve_map_neg) { struct sysdb_test_ctx *test_ctx; const char *autofsmapname; errno_t ret; struct ldb_message *map = NULL; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i); fail_if(autofsmapname == NULL, "Out of memory\n"); ret = sysdb_get_map_byname(test_ctx, test_ctx->domain, autofsmapname, &map); fail_if(ret != ENOENT, "Expected ENOENT, got %d instead\n", ret); fail_if(map != NULL, "Unexpected map found\n"); talloc_free(test_ctx); } END_TEST START_TEST(test_autofs_store_entry_in_map) { struct sysdb_test_ctx *test_ctx; const char *autofsmapname; const char *autofskey; const char *autofsval; errno_t ret; int ii; const int limit = 10; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i); fail_if(autofsmapname == NULL, "Out of memory\n"); for (ii=0; ii < limit; ii++) { autofskey = talloc_asprintf(test_ctx, "%s_testkey%d", autofsmapname, ii); fail_if(autofskey == NULL, "Out of memory\n"); autofsval = talloc_asprintf(test_ctx, "testserver:/testval%d", ii); fail_if(autofsval == NULL, "Out of memory\n"); ret = sysdb_save_autofsentry(test_ctx->domain, autofsmapname, autofskey, autofsval, NULL); fail_if(ret != EOK, "Could not save autofs entry %s", autofskey); } talloc_free(test_ctx); } END_TEST START_TEST(test_autofs_retrieve_keys_by_map) { struct sysdb_test_ctx *test_ctx; const char *autofsmapname; errno_t ret; size_t count; struct ldb_message **entries; const int expected = 10; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i); fail_if(autofsmapname == NULL, "Out of memory\n"); ret = sysdb_autofs_entries_by_map(test_ctx, test_ctx->domain, autofsmapname, &count, &entries); fail_if(ret != EOK, "Cannot get autofs entries for map %s\n", autofsmapname); fail_if(count != expected, "Expected to find %d entries, got %d\n", expected, count); talloc_free(test_ctx); } END_TEST START_TEST(test_autofs_key_duplicate) { struct sysdb_test_ctx *test_ctx; const char *autofsmapname; const char *autofskey; const char *autofsval; errno_t ret; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); autofsmapname = talloc_asprintf(test_ctx, "testmap%d", _i); fail_if(autofsmapname == NULL, "Out of memory\n"); autofskey = talloc_asprintf(test_ctx, "testkey"); fail_if(autofskey == NULL, "Out of memory\n"); autofsval = talloc_asprintf(test_ctx, "testserver:/testval%d", _i); fail_if(autofsval == NULL, "Out of memory\n"); ret = sysdb_save_autofsentry(test_ctx->domain, autofsmapname, autofskey, autofsval, NULL); fail_if(ret != EOK, "Could not save autofs entry %s", autofskey); talloc_free(test_ctx); } END_TEST START_TEST(test_autofs_get_duplicate_keys) { struct sysdb_test_ctx *test_ctx; const char *autofskey; errno_t ret; const char *attrs[] = { SYSDB_AUTOFS_ENTRY_KEY, SYSDB_AUTOFS_ENTRY_VALUE, NULL }; size_t count; struct ldb_message **msgs; struct ldb_dn *dn; const char *filter; const int expected = 10; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); autofskey = talloc_asprintf(test_ctx, "testkey"); fail_if(autofskey == NULL, "Out of memory\n"); filter = talloc_asprintf(test_ctx, "(&(objectclass=%s)(%s=%s))", SYSDB_AUTOFS_ENTRY_OC, SYSDB_AUTOFS_ENTRY_KEY, autofskey); fail_if(filter == NULL, "Out of memory\n"); dn = ldb_dn_new_fmt(test_ctx, test_ctx->sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE, AUTOFS_MAP_SUBDIR, test_ctx->domain->name); fail_if(dn == NULL, "Out of memory\n"); ret = sysdb_search_entry(test_ctx, test_ctx->sysdb, dn, LDB_SCOPE_SUBTREE, filter, attrs, &count, &msgs); fail_unless(ret == EOK, "sysdb_search_entry returned [%d]", ret); fail_if(count != expected, "Found %d entries with name %s, expected %d\n", count, autofskey, expected); talloc_free(test_ctx); } END_TEST #endif /* BUILD_AUTOFS */ static struct confdb_ctx *test_cdb_domains_prep(TALLOC_CTX *mem_ctx) { char *conf_db; int ret; struct confdb_ctx *confdb; /* Create tests directory if it doesn't exist */ /* (relative to current dir) */ ret = mkdir(TESTS_PATH, 0775); if (ret == -1 && errno != EEXIST) { fail("Could not create %s directory", TESTS_PATH); return NULL; } conf_db = talloc_asprintf(mem_ctx, "%s/%s", TESTS_PATH, TEST_CONF_FILE); ck_assert(conf_db != NULL); /* Make sure the test domain does not interfere with our testing */ ret = unlink(TESTS_PATH"/"TEST_CONF_FILE); if (ret != EOK && errno != ENOENT) { fail("Could not remove confdb %s\n", TESTS_PATH"/"TEST_CONF_FILE); return NULL; } /* Connect to the conf db */ ret = confdb_init(mem_ctx, &confdb, conf_db); ck_assert_int_eq(ret, EOK); return confdb; } START_TEST(test_confdb_list_all_domain_names_no_dom) { int ret; TALLOC_CTX *tmp_ctx; struct confdb_ctx *confdb; char **names; tmp_ctx = talloc_new(NULL); ck_assert(tmp_ctx != NULL); confdb = test_cdb_domains_prep(tmp_ctx); ck_assert(confdb != NULL); /* No domain */ ret = confdb_list_all_domain_names(tmp_ctx, confdb, &names); ck_assert_int_eq(ret, EOK); ck_assert(names != NULL); ck_assert(names[0] == NULL); talloc_free(tmp_ctx); } END_TEST START_TEST(test_confdb_list_all_domain_names_single_dom) { int ret; TALLOC_CTX *tmp_ctx; struct confdb_ctx *confdb; char **names; const char *val[2]; val[1] = NULL; tmp_ctx = talloc_new(NULL); ck_assert(tmp_ctx != NULL); confdb = test_cdb_domains_prep(tmp_ctx); ck_assert(confdb != NULL); /* One domain */ val[0] = "LOCAL"; ret = confdb_add_param(confdb, true, "config/sssd", "domains", val); ck_assert_int_eq(ret, EOK); val[0] = "local"; ret = confdb_add_param(confdb, true, "config/domain/LOCAL", "id_provider", val); ck_assert_int_eq(ret, EOK); ret = confdb_list_all_domain_names(tmp_ctx, confdb, &names); ck_assert_int_eq(ret, EOK); ck_assert(names != NULL); ck_assert_str_eq(names[0], "LOCAL"); ck_assert(names[1] == NULL); talloc_free(tmp_ctx); } END_TEST #define UPN_USER_NAME "upn_user" #define UPN_PRINC "upn_user@UPN.TEST" #define UPN_PRINC_WRONG_CASE "UpN_uSeR@uPn.TeSt" #define UPN_CANON_PRINC "upn_user@UPN.CANON" #define UPN_CANON_PRINC_WRONG_CASE "uPn_UsEr@UpN.CaNoN" START_TEST(test_upn_basic) { struct sysdb_test_ctx *test_ctx; struct sysdb_attrs *attrs; int ret; struct ldb_message *msg; const char *str; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } attrs = sysdb_new_attrs(test_ctx); fail_unless(attrs != NULL, "sysdb_new_attrs failed.\n"); ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, UPN_PRINC); fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); ret = sysdb_attrs_add_string(attrs, SYSDB_CANONICAL_UPN, UPN_CANON_PRINC); fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); ret = sysdb_store_user(test_ctx->domain, UPN_USER_NAME, "x", 12345, 0, "UPN USER", "/home/upn_user", "/bin/bash", NULL, attrs, NULL, -1, 0); fail_unless(ret == EOK, "Could not store user."); ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, "abc@def.ghi", NULL, &msg); fail_unless(ret == ENOENT, "sysdb_search_user_by_upn failed with non-existing UPN."); ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, UPN_PRINC, NULL, &msg); fail_unless(ret == EOK, "sysdb_search_user_by_upn failed."); str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_USER_NAME) == 0, "Expected [%s], got [%s].", UPN_USER_NAME, str); str = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_PRINC) == 0, "Expected [%s], got [%s].", UPN_PRINC, str); talloc_free(test_ctx); } END_TEST START_TEST(test_upn_basic_case) { struct sysdb_test_ctx *test_ctx; int ret; struct ldb_message *msg; const char *str; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, UPN_PRINC_WRONG_CASE, NULL, &msg); fail_unless(ret == EOK, "sysdb_search_user_by_upn failed."); str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_USER_NAME) == 0, "Expected [%s], got [%s].", UPN_USER_NAME, str); str = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_PRINC) == 0, "Expected [%s], got [%s].", UPN_PRINC, str); talloc_free(test_ctx); } END_TEST START_TEST(test_upn_canon) { struct sysdb_test_ctx *test_ctx; int ret; struct ldb_message *msg; const char *str; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, UPN_CANON_PRINC, NULL, &msg); fail_unless(ret == EOK, "sysdb_search_user_by_upn failed."); str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_USER_NAME) == 0, "Expected [%s], got [%s].", UPN_USER_NAME, str); str = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_PRINC) == 0, "Expected [%s], got [%s].", UPN_PRINC, str); str = ldb_msg_find_attr_as_string(msg, SYSDB_CANONICAL_UPN, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_CANON_PRINC) == 0, "Expected [%s], got [%s].", UPN_CANON_PRINC, str); talloc_free(test_ctx); } END_TEST START_TEST(test_upn_canon_case) { struct sysdb_test_ctx *test_ctx; int ret; struct ldb_message *msg; const char *str; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, UPN_CANON_PRINC_WRONG_CASE, NULL, &msg); fail_unless(ret == EOK, "sysdb_search_user_by_upn failed."); str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_USER_NAME) == 0, "Expected [%s], got [%s].", UPN_USER_NAME, str); str = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_PRINC) == 0, "Expected [%s], got [%s].", UPN_PRINC, str); str = ldb_msg_find_attr_as_string(msg, SYSDB_CANONICAL_UPN, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_CANON_PRINC) == 0, "Expected [%s], got [%s].", UPN_CANON_PRINC, str); talloc_free(test_ctx); } END_TEST START_TEST(test_upn_dup) { struct sysdb_test_ctx *test_ctx; struct sysdb_attrs *attrs; int ret; struct ldb_message *msg; const char *str; /* Setup */ ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } attrs = sysdb_new_attrs(test_ctx); fail_unless(attrs != NULL, "sysdb_new_attrs failed.\n"); ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, UPN_CANON_PRINC); fail_unless(ret == EOK, "sysdb_attrs_add_string failed."); ret = sysdb_store_user(test_ctx->domain, UPN_USER_NAME"_dup", "x", 23456, 0, "UPN USER DUP", "/home/upn_user_dup", "/bin/bash", NULL, attrs, NULL, -1, 0); fail_unless(ret == EOK, "Could not store user."); ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, UPN_CANON_PRINC, NULL, &msg); fail_unless(ret == EINVAL, "sysdb_search_user_by_upn failed for duplicated UPN."); ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, UPN_PRINC, NULL, &msg); fail_unless(ret == EOK, "sysdb_search_user_by_upn failed."); str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_USER_NAME) == 0, "Expected [%s], got [%s].", UPN_USER_NAME, str); str = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_PRINC) == 0, "Expected [%s], got [%s].", UPN_PRINC, str); str = ldb_msg_find_attr_as_string(msg, SYSDB_CANONICAL_UPN, NULL); fail_unless(str != NULL, "ldb_msg_find_attr_as_string failed."); fail_unless(strcmp(str, UPN_CANON_PRINC) == 0, "Expected [%s], got [%s].", UPN_CANON_PRINC, str); talloc_free(test_ctx); } END_TEST START_TEST(test_gpo_store_retrieve) { struct sysdb_test_ctx *test_ctx; errno_t ret; struct ldb_result *result = NULL; const char *guid; int version; static const char *test_guid = "3610EDA5-77EF-11D2-8DC5-00C04FA31A66"; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not set up the test"); ret = sysdb_gpo_get_gpo_by_guid(test_ctx, test_ctx->domain, test_guid, &result); fail_if(ret != ENOENT, "GPO present in cache before store op"); ret = sysdb_gpo_get_gpos(test_ctx, test_ctx->domain, &result); fail_if(ret != ENOENT, "GPO present in cache before store op"); ret = sysdb_gpo_store_gpo(test_ctx->domain, test_guid, 1, 5, 0); fail_if(ret != EOK, "Could not store a test GPO"); ret = sysdb_gpo_get_gpos(test_ctx, test_ctx->domain, &result); fail_if(ret != EOK, "GPOs not in cache after store op"); fail_if(result == NULL); fail_if(result->count != 1); result = NULL; ret = sysdb_gpo_get_gpo_by_guid(test_ctx, test_ctx->domain, test_guid, &result); fail_if(ret != EOK, "GPO not in cache after store op"); fail_if(result == NULL); fail_if(result->count != 1); guid = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_GPO_GUID_ATTR, NULL); ck_assert_str_eq(guid, test_guid); version = ldb_msg_find_attr_as_uint(result->msgs[0], SYSDB_GPO_VERSION_ATTR, 0); ck_assert_int_eq(version, 1); talloc_free(test_ctx); } END_TEST START_TEST(test_gpo_replace) { struct sysdb_test_ctx *test_ctx; errno_t ret; struct ldb_result *result = NULL; const char *guid; int version; static const char *test_guid = "3610EDA5-77EF-11D2-8DC5-00C04FA31A66"; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not setup the test"); ret = sysdb_gpo_get_gpo_by_guid(test_ctx, test_ctx->domain, test_guid, &result); fail_if(ret != EOK, "GPO not in cache after store op"); fail_if(result == NULL); fail_if(result->count != 1); guid = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_GPO_GUID_ATTR, NULL); ck_assert_str_eq(guid, test_guid); version = ldb_msg_find_attr_as_uint(result->msgs[0], SYSDB_GPO_VERSION_ATTR, 0); ck_assert_int_eq(version, 1); /* Modify the version */ ret = sysdb_gpo_store_gpo(test_ctx->domain, test_guid, 2, 5, 0); fail_if(ret != EOK, "Could not store a test GPO"); ret = sysdb_gpo_get_gpo_by_guid(test_ctx, test_ctx->domain, test_guid, &result); fail_if(ret != EOK, "GPO not in cache after modify op"); fail_if(result == NULL); fail_if(result->count != 1); guid = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_GPO_GUID_ATTR, NULL); ck_assert_str_eq(guid, test_guid); version = ldb_msg_find_attr_as_uint(result->msgs[0], SYSDB_GPO_VERSION_ATTR, 0); ck_assert_int_eq(version, 2); talloc_free(test_ctx); } END_TEST START_TEST(test_gpo_result) { errno_t ret; struct sysdb_test_ctx *test_ctx; const char *allow_key = "SeRemoteInteractiveLogonRight"; const char *deny_key = "SeDenyRemoteInteractiveLogonRight"; const char *value = NULL; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not setup the test"); /* No result in cache */ ret = sysdb_gpo_get_gpo_result_setting(test_ctx, test_ctx->domain, allow_key, &value); ck_assert_int_eq(ret, ENOENT); ret = sysdb_gpo_get_gpo_result_setting(test_ctx, test_ctx->domain, deny_key, &value); ck_assert_int_eq(ret, ENOENT); /* Delete with no result object is a noop */ ret = sysdb_gpo_delete_gpo_result_object(test_ctx, test_ctx->domain); ck_assert_int_eq(ret, EOK); /* Store an allow value, triggering a new result object */ ret = sysdb_gpo_store_gpo_result_setting(test_ctx->domain, allow_key, "allow_val1"); ck_assert_int_eq(ret, EOK); /* Now both searches should succeed, but only allow_key should return * a valid value */ ret = sysdb_gpo_get_gpo_result_setting(test_ctx, test_ctx->domain, allow_key, &value); ck_assert_int_eq(ret, EOK); ck_assert_str_eq(value, "allow_val1"); ret = sysdb_gpo_get_gpo_result_setting(test_ctx, test_ctx->domain, deny_key, &value); ck_assert_int_eq(ret, EOK); fail_unless(value == NULL); /* Updating replaces the original value */ ret = sysdb_gpo_store_gpo_result_setting(test_ctx->domain, allow_key, "allow_val2"); ck_assert_int_eq(ret, EOK); ret = sysdb_gpo_get_gpo_result_setting(test_ctx, test_ctx->domain, allow_key, &value); ck_assert_int_eq(ret, EOK); ck_assert_str_eq(value, "allow_val2"); /* NULL removes the value completely */ ret = sysdb_gpo_store_gpo_result_setting(test_ctx->domain, allow_key, NULL); ck_assert_int_eq(ret, EOK); ret = sysdb_gpo_get_gpo_result_setting(test_ctx, test_ctx->domain, allow_key, &value); ck_assert_int_eq(ret, EOK); fail_unless(value == NULL); /* Delete the result */ ret = sysdb_gpo_delete_gpo_result_object(test_ctx, test_ctx->domain); ck_assert_int_eq(ret, EOK); /* No result in cache */ ret = sysdb_gpo_get_gpo_result_setting(test_ctx, test_ctx->domain, allow_key, &value); ck_assert_int_eq(ret, ENOENT); ret = sysdb_gpo_get_gpo_result_setting(test_ctx, test_ctx->domain, deny_key, &value); ck_assert_int_eq(ret, ENOENT); } END_TEST START_TEST(test_confdb_list_all_domain_names_multi_dom) { int ret; TALLOC_CTX *tmp_ctx; struct confdb_ctx *confdb; char **names; const char *val[2]; val[1] = NULL; tmp_ctx = talloc_new(NULL); ck_assert(tmp_ctx != NULL); confdb = test_cdb_domains_prep(tmp_ctx); ck_assert(confdb != NULL); /* Two domains */ val[0] = "LOCAL"; ret = confdb_add_param(confdb, true, "config/sssd", "domains", val); ck_assert_int_eq(ret, EOK); val[0] = "local"; ret = confdb_add_param(confdb, true, "config/domain/LOCAL", "id_provider", val); ck_assert_int_eq(ret, EOK); val[0] = "REMOTE"; ret = confdb_add_param(confdb, true, "config/sssd", "domains", val); ck_assert_int_eq(ret, EOK); val[0] = "local"; ret = confdb_add_param(confdb, true, "config/domain/REMOTE", "id_provider", val); ck_assert_int_eq(ret, EOK); ret = confdb_list_all_domain_names(tmp_ctx, confdb, &names); ck_assert_int_eq(ret, EOK); ck_assert(names != NULL); ck_assert_str_eq(names[0], "LOCAL"); ck_assert_str_eq(names[1], "REMOTE"); ck_assert(names[2] == NULL); talloc_free(tmp_ctx); } END_TEST START_TEST(test_sysdb_mark_entry_as_expired_ldb_dn) { errno_t ret; struct sysdb_test_ctx *test_ctx; const char *attrs[] = { SYSDB_CACHE_EXPIRE, NULL }; size_t count; struct ldb_message **msgs; uint64_t expire; struct ldb_dn *userdn; ret = setup_sysdb_tests(&test_ctx); fail_if(ret != EOK, "Could not setup the test"); /* Add something to database to test against */ ret = sysdb_transaction_start(test_ctx->sysdb); ck_assert_int_eq(ret, EOK); ret = sysdb_add_user(test_ctx->domain, "testuser", 2000, 0, "Test User", "/home/testuser", "/bin/bash", NULL, NULL, 500, 0); ck_assert_int_eq(ret, EOK); ret = sysdb_transaction_commit(test_ctx->sysdb); ck_assert_int_eq(ret, EOK); ret = sysdb_search_users(test_ctx, test_ctx->domain, "("SYSDB_UIDNUM"=2000)", attrs, &count, &msgs); ck_assert_int_eq(ret, EOK); ck_assert_int_eq(count, 1); expire = ldb_msg_find_attr_as_uint64(msgs[0], SYSDB_CACHE_EXPIRE, 0); ck_assert(expire != 1); userdn = sysdb_user_dn(test_ctx, test_ctx->domain, "testuser"); ck_assert(userdn != NULL); ret = sysdb_transaction_start(test_ctx->sysdb); ck_assert_int_eq(ret, EOK); /* Expire entry */ ret = sysdb_mark_entry_as_expired_ldb_dn(test_ctx->domain, userdn); ck_assert_int_eq(ret, EOK); ret = sysdb_transaction_commit(test_ctx->sysdb); ck_assert_int_eq(ret, EOK); ret = sysdb_search_users(test_ctx, test_ctx->domain, "("SYSDB_UIDNUM"=2000)", attrs, &count, &msgs); ck_assert_int_eq(ret, EOK); ck_assert_int_eq(count, 1); expire = ldb_msg_find_attr_as_uint64(msgs[0], SYSDB_CACHE_EXPIRE, 0); ck_assert_int_eq(expire, 1); /* Try to expire already expired entry. Should return EOK. */ ret = sysdb_transaction_start(test_ctx->sysdb); ck_assert_int_eq(ret, EOK); ret = sysdb_mark_entry_as_expired_ldb_dn(test_ctx->domain, userdn); ck_assert_int_eq(ret, EOK); ret = sysdb_transaction_commit(test_ctx->sysdb); ck_assert_int_eq(ret, EOK); } END_TEST Suite *create_sysdb_suite(void) { Suite *s = suite_create("sysdb"); TCase *tc_sysdb = tcase_create("SYSDB Tests"); /* test getting next id works */ tcase_add_test(tc_sysdb, test_sysdb_get_new_id); /* Add a user with an automatic ID */ tcase_add_test(tc_sysdb, test_sysdb_user_new_id); /* Create a new user */ tcase_add_loop_test(tc_sysdb, test_sysdb_add_user,27000,27010); /* Verify the users were added */ tcase_add_loop_test(tc_sysdb, test_sysdb_getpwnam, 27000, 27010); /* Create a new group */ tcase_add_loop_test(tc_sysdb, test_sysdb_add_group, 28000, 28010); /* Verify the groups were added */ tcase_add_loop_test(tc_sysdb, test_sysdb_getgrnam, 28000, 28010); /* sysdb_group_dn_name returns the name of the group in question */ tcase_add_loop_test(tc_sysdb, test_sysdb_group_dn_name, 28000, 28010); /* sysdb_store_user allows setting attributes for existing users */ tcase_add_loop_test(tc_sysdb, test_sysdb_store_user_existing, 27000, 27010); /* test the change */ tcase_add_loop_test(tc_sysdb, test_sysdb_get_user_attr, 27000, 27010); /* Add and remove users in a group with sysdb_update_members */ tcase_add_test(tc_sysdb, test_sysdb_update_members); /* Remove the other half by gid */ tcase_add_loop_test(tc_sysdb, test_sysdb_remove_local_group_by_gid, 28000, 28010); /* Remove the other half by uid */ tcase_add_loop_test(tc_sysdb, test_sysdb_remove_local_user_by_uid, 27000, 27010); /* Create a new user */ tcase_add_loop_test(tc_sysdb, test_sysdb_store_user, 27010, 27020); /* Verify the users were added */ tcase_add_loop_test(tc_sysdb, test_sysdb_getpwnam, 27010, 27020); /* Verify the users can be queried by UID */ tcase_add_loop_test(tc_sysdb, test_sysdb_getpwuid, 27010, 27020); /* Enumerate the users */ tcase_add_test(tc_sysdb, test_sysdb_enumpwent); /* Change their attribute */ tcase_add_loop_test(tc_sysdb, test_sysdb_set_user_attr, 27010, 27020); /* Find the users by their new attribute */ tcase_add_loop_test(tc_sysdb, test_sysdb_search_users, 27010, 27020); /* Verify the change */ tcase_add_loop_test(tc_sysdb, test_sysdb_get_user_attr, 27010, 27020); /* Remove the attribute */ tcase_add_loop_test(tc_sysdb, test_sysdb_remove_attrs, 27010, 27020); /* Create a new group */ tcase_add_loop_test(tc_sysdb, test_sysdb_store_group, 28010, 28020); /* Verify the groups were added */ /* Verify the groups can be queried by GID */ tcase_add_loop_test(tc_sysdb, test_sysdb_getgrgid, 28010, 28020); /* Find the users by GID using a filter */ tcase_add_loop_test(tc_sysdb, test_sysdb_search_groups, 28010, 28020); /* Enumerate the groups */ tcase_add_test(tc_sysdb, test_sysdb_enumgrent); /* Add some members to the groups */ tcase_add_loop_test(tc_sysdb, test_sysdb_add_group_member, 28010, 28020); /* Test that sysdb_initgroups() works */ tcase_add_loop_test(tc_sysdb, test_sysdb_initgroups, 27010, 27020); /* Authenticate with missing cached password */ tcase_add_loop_test(tc_sysdb, test_sysdb_cached_authentication_missing_password, 27010, 27011); /* Add a cached password */ tcase_add_loop_test(tc_sysdb, test_sysdb_cache_password, 27010, 27011); /* Authenticate against cached password */ tcase_add_loop_test(tc_sysdb, test_sysdb_cached_authentication_wrong_password, 27010, 27011); tcase_add_loop_test(tc_sysdb, test_sysdb_cached_authentication, 27010, 27011); tcase_add_loop_test(tc_sysdb, test_sysdb_cache_password_ex, 27010, 27011); /* ASQ search test */ tcase_add_loop_test(tc_sysdb, test_sysdb_prepare_asq_test_user, 28011, 28020); tcase_add_test(tc_sysdb, test_sysdb_asq_search); /* Test search with more than one result */ tcase_add_test(tc_sysdb, test_sysdb_search_all_users); /* Remove the members from the groups */ tcase_add_loop_test(tc_sysdb, test_sysdb_remove_group_member, 28010, 28020); /* Remove the users by name */ tcase_add_loop_test(tc_sysdb, test_sysdb_remove_local_user, 27010, 27020); /* Remove the groups by name */ tcase_add_loop_test(tc_sysdb, test_sysdb_remove_local_group, 28010, 28020); /* test the ignore_not_found parameter for users */ tcase_add_test(tc_sysdb, test_sysdb_remove_nonexistent_user); /* test the ignore_not_found parameter for groups */ tcase_add_test(tc_sysdb, test_sysdb_remove_nonexistent_group); /* Create incomplete groups - remove will fail if the LDB objects don't exist */ tcase_add_loop_test(tc_sysdb, test_sysdb_add_incomplete_group, 28000, 28010); tcase_add_loop_test(tc_sysdb, test_sysdb_remove_local_group_by_gid, 28000, 28010); /* test custom operations */ tcase_add_loop_test(tc_sysdb, test_sysdb_store_custom, 29010, 29020); tcase_add_test(tc_sysdb, test_sysdb_search_custom_by_name); tcase_add_test(tc_sysdb, test_sysdb_update_custom); tcase_add_test(tc_sysdb, test_sysdb_search_custom_update); tcase_add_test(tc_sysdb, test_sysdb_search_custom); tcase_add_test(tc_sysdb, test_sysdb_delete_custom); tcase_add_test(tc_sysdb, test_sysdb_delete_by_sid); /* test recursive delete */ tcase_add_test(tc_sysdb, test_sysdb_delete_recursive); tcase_add_test(tc_sysdb, test_sysdb_attrs_replace_name); tcase_add_test(tc_sysdb, test_sysdb_attrs_to_list); /* Test unusual characters */ tcase_add_test(tc_sysdb, test_odd_characters); /* Test sysdb enumerated flag */ tcase_add_test(tc_sysdb, test_sysdb_has_enumerated); /* Test originalDN searches */ tcase_add_test(tc_sysdb, test_sysdb_original_dn_case_insensitive); /* Test SID string searches */ tcase_add_test(tc_sysdb, test_sysdb_search_sid_str); /* Test UUID string searches */ tcase_add_test(tc_sysdb, test_sysdb_search_object_by_uuid); /* Test user by certificate searches */ tcase_add_test(tc_sysdb, test_sysdb_search_user_by_cert); /* Test canonicalizing names */ tcase_add_test(tc_sysdb, test_sysdb_get_real_name); /* Test user and group renames */ tcase_add_test(tc_sysdb, test_group_rename); tcase_add_test(tc_sysdb, test_user_rename); /* Test GetUserAttr with subdomain user */ tcase_add_test(tc_sysdb, test_sysdb_get_user_attr_subdomain); /* ===== NETGROUP TESTS ===== */ /* Create a new netgroup */ tcase_add_loop_test(tc_sysdb, test_sysdb_add_basic_netgroup, 27000, 27010); /* Verify the netgroups were added */ tcase_add_loop_test(tc_sysdb, test_sysdb_search_netgroup_by_name, 27000, 27010); /* Test setting attributes */ tcase_add_loop_test(tc_sysdb, test_sysdb_set_netgroup_attr, 27000, 27010); /* Verify they have been changed */ tcase_add_loop_test(tc_sysdb, test_sysdb_get_netgroup_attr, 27000, 27010); /* Remove half of them by name */ tcase_add_loop_test(tc_sysdb, test_sysdb_remove_netgroup_by_name, 27000, 27005); /* Remove the other half by DN */ tcase_add_loop_test(tc_sysdb, test_sysdb_remove_netgroup_entry, 27005, 27010); tcase_add_test(tc_sysdb, test_netgroup_base_dn); /* ===== SERVICE TESTS ===== */ /* Create a new service */ tcase_add_test(tc_sysdb, test_sysdb_add_services); tcase_add_test(tc_sysdb, test_sysdb_store_services); tcase_add_test(tc_sysdb, test_sysdb_svc_remove_alias); tcase_add_test(tc_sysdb, test_sysdb_attrs_add_lc_name_alias); tcase_add_test(tc_sysdb, test_sysdb_attrs_add_lc_name_alias_safe); /* ===== UTIL TESTS ===== */ tcase_add_test(tc_sysdb, test_sysdb_attrs_get_string_array); tcase_add_test(tc_sysdb, test_sysdb_attrs_add_val); tcase_add_test(tc_sysdb, test_sysdb_attrs_add_val_safe); tcase_add_test(tc_sysdb, test_sysdb_attrs_add_string_safe); /* ===== Test search return empty result ===== */ tcase_add_test(tc_sysdb, test_sysdb_search_return_ENOENT); /* ===== Misc ===== */ tcase_add_test(tc_sysdb, test_sysdb_set_get_bool); tcase_add_test(tc_sysdb, test_sysdb_mark_entry_as_expired_ldb_dn); /* Add all test cases to the test suite */ suite_add_tcase(s, tc_sysdb); TCase *tc_memberof = tcase_create("SYSDB member/memberof/memberuid Tests"); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_store_group, 0, 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_store_user, 0, 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_add_group_member, 0, 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_check_memberuid, 0, 10); tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid, MBO_GROUP_BASE + 5, MBO_GROUP_BASE + 6); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_check_memberuid_without_group_5, 0, 10); tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_store_group, 0, 10); tcase_add_test(tc_memberof, test_sysdb_memberof_close_loop); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_store_user, 0, 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_add_group_member, 0, 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_check_memberuid_loop, 0, 10); tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid, MBO_GROUP_BASE + 5, MBO_GROUP_BASE + 6); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_check_memberuid_loop_without_group_5, 0, 10); tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); /* Ghost users tests */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_store_group_with_ghosts, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_check_nested_ghosts, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_remove_child_group_and_check_ghost, MBO_GROUP_BASE + 1, MBO_GROUP_BASE + 10); /* Only one group should be left now */ tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid, MBO_GROUP_BASE + 9 , MBO_GROUP_BASE + 10); /* ghost users - RFC2307 */ /* Add groups with ghost users */ tcase_add_loop_test(tc_memberof, test_sysdb_add_group_with_ghosts, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); /* Check the ghost user attribute */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_check_ghost, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); /* Add user entries, converting the ghost attributes to member attributes */ /* We only convert half of the users and keep the ghost attributes for the * other half as we also want to test if we don't delete any ghost users * by accident */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_convert_to_real_users, MBO_GROUP_BASE , MBO_GROUP_BASE + NUM_GHOSTS/2); /* Check the members and ghosts are there as appropriate */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_check_convert, MBO_GROUP_BASE , MBO_GROUP_BASE + NUM_GHOSTS); /* Rename the other half */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_ghost_replace, MBO_GROUP_BASE + NUM_GHOSTS/2 + 1, MBO_GROUP_BASE + NUM_GHOSTS); /* Attempt to replace with the same data to check if noop works correctly */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_ghost_replace_noop, MBO_GROUP_BASE + NUM_GHOSTS/2 + 1, MBO_GROUP_BASE + NUM_GHOSTS); /* Remove the real users */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_user_cleanup, MBO_GROUP_BASE , MBO_GROUP_BASE + NUM_GHOSTS/2); tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid, MBO_GROUP_BASE , MBO_GROUP_BASE + NUM_GHOSTS); /* ghost users - memberof mod_del */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_store_group_with_ghosts, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_check_nested_ghosts, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_mod_del, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid, MBO_GROUP_BASE , MBO_GROUP_BASE + NUM_GHOSTS); /* ghost users - memberof mod_add */ /* Add groups without ghosts first */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_store_group, 0, 10); /* Add ghosts to groups so that they propagate */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_mod_add, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); /* Check if the ghosts in fact propagated */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_check_nested_ghosts, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); /* Clean up */ tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); /* ghost users - replace */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_store_group_with_ghosts, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_check_nested_ghosts, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_mod_replace, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); /* ghost users - replace but retain inherited */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_store_group_with_double_ghosts, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); tcase_add_loop_test(tc_memberof, test_sysdb_memberof_check_nested_double_ghosts, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); /* SSS_LDB_SEARCH */ tcase_add_test(tc_sysdb, test_SSS_LDB_SEARCH); /* This loop counts backwards so the indexing is a little odd */ tcase_add_loop_test(tc_memberof, test_sysdb_memberof_mod_replace_keep, 1 , 11); tcase_add_loop_test(tc_memberof, test_sysdb_remove_local_group_by_gid, MBO_GROUP_BASE , MBO_GROUP_BASE + 10); suite_add_tcase(s, tc_memberof); TCase *tc_subdomain = tcase_create("SYSDB sub-domain Tests"); tcase_add_test(tc_subdomain, test_sysdb_subdomain_store_user); tcase_add_test(tc_subdomain, test_sysdb_subdomain_user_ops); tcase_add_test(tc_subdomain, test_sysdb_subdomain_group_ops); suite_add_tcase(s, tc_subdomain); #ifdef BUILD_AUTOFS TCase *tc_autofs = tcase_create("SYSDB autofs Tests"); tcase_add_loop_test(tc_autofs, test_autofs_create_map, TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10); tcase_add_loop_test(tc_autofs, test_autofs_retrieve_map, TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10); tcase_add_loop_test(tc_autofs, test_autofs_store_entry_in_map, TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10); tcase_add_loop_test(tc_autofs, test_autofs_retrieve_keys_by_map, TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10); tcase_add_loop_test(tc_autofs, test_autofs_delete_map, TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10); tcase_add_loop_test(tc_autofs, test_autofs_retrieve_map_neg, TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10); tcase_add_loop_test(tc_autofs, test_autofs_key_duplicate, TEST_AUTOFS_MAP_BASE, TEST_AUTOFS_MAP_BASE+10); tcase_add_test(tc_autofs, test_autofs_get_duplicate_keys); suite_add_tcase(s, tc_autofs); #endif TCase *tc_upn = tcase_create("SYSDB UPN tests"); tcase_add_test(tc_upn, test_upn_basic); tcase_add_test(tc_upn, test_upn_basic_case); tcase_add_test(tc_upn, test_upn_canon); tcase_add_test(tc_upn, test_upn_canon_case); tcase_add_test(tc_upn, test_upn_dup); suite_add_tcase(s, tc_upn); TCase *tc_gpo = tcase_create("SYSDB GPO tests"); tcase_add_test(tc_gpo, test_gpo_store_retrieve); tcase_add_test(tc_gpo, test_gpo_replace); tcase_add_test(tc_gpo, test_gpo_result); suite_add_tcase(s, tc_gpo); /* ConfDB tests -- modify confdb, must always be last!! */ TCase *tc_confdb = tcase_create("confDB tests"); tcase_add_test(tc_confdb, test_confdb_list_all_domain_names_no_dom); tcase_add_test(tc_confdb, test_confdb_list_all_domain_names_single_dom); tcase_add_test(tc_confdb, test_confdb_list_all_domain_names_multi_dom); suite_add_tcase(s, tc_confdb); return s; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int failure_count; int no_cleanup = 0; Suite *sysdb_suite; SRunner *sr; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); if (!ldb_modules_path_is_set()) { fprintf(stderr, "Warning: LDB_MODULES_PATH is not set, " "will use LDB plugins installed in system paths.\n"); } tests_set_cwd(); talloc_enable_null_tracking(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_FILE, LOCAL_SYSDB_FILE); sysdb_suite = create_sysdb_suite(); sr = srunner_create(sysdb_suite); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); failure_count = srunner_ntests_failed(sr); srunner_free(sr); if (failure_count == 0 && !no_cleanup) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_FILE, LOCAL_SYSDB_FILE); } return (failure_count==0 ? EXIT_SUCCESS : EXIT_FAILURE); } sssd-1.13.4/src/tests/PaxHeaders.16287/whitespace_test0000644000000000000000000000007412703456111017374 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.352792605 sssd-1.13.4/src/tests/whitespace_test0000755002412700241270000000134612703456111021052 0ustar00jhrozekjhrozek00000000000000#!/bin/bash set -e -u -o pipefail # An AWK regex matching tracked file paths to be excluded from the search. # Example: '.*\.po|README' PATH_EXCLUDE_REGEX='.*\.po|.*\.patch|.*\.diff|\/debian\/.*' export GIT_DIR="$ABS_TOP_SRCDIR/.git" export GIT_WORK_TREE="$ABS_TOP_SRCDIR" if [ ! -d "$GIT_DIR" ]; then echo "Git repository is required for this test!" 1>&2 exit 77 fi git grep -n -I '\s\+$' -- "$(git rev-parse --show-toplevel)" | awk -- " BEGIN { found = 0 } ! /^($PATH_EXCLUDE_REGEX):/ { if (!found) { print \"Trailing whitespace found:\" found = 1 } print } END { exit found } " sssd-1.13.4/src/tests/PaxHeaders.16287/crypto-tests.c0000644000000000000000000000007412703456111017102 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.912794504 sssd-1.13.4/src/tests/crypto-tests.c0000644002412700241270000001357112703456111020560 0ustar00jhrozekjhrozek00000000000000/* SSSD Crypto tests Author: Jakub Hrozek Copyright (C) Red Hat, Inc 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "tests/common_check.h" /* interfaces under test */ #include "util/crypto/sss_crypto.h" #include "util/crypto/nss/nss_util.h" static TALLOC_CTX *test_ctx = NULL; #ifdef HAVE_NSS START_TEST(test_nss_init) { int ret; ret = nspr_nss_init(); fail_if(ret != EOK); ret = nspr_nss_cleanup(); fail_if(ret != EOK); } END_TEST #endif START_TEST(test_encrypt_decrypt) { const char *password[] = { "test123", /* general */ "12345678901234567", /* just above blocksize */ "", /* empty */ NULL}; /* sentinel */ int i; char *obfpwd = NULL; char *ctpwd = NULL; int ret; int expected; #if defined(HAVE_NSS) || defined(HAVE_LIBCRYPTO) expected = EOK; #else #error Unknown crypto back end #endif test_ctx = talloc_new(NULL); fail_if(test_ctx == NULL); ck_leaks_push(test_ctx); for (i=0; password[i]; i++) { ret = sss_password_encrypt(test_ctx, password[i], strlen(password[i])+1, AES_256, &obfpwd); fail_if(ret != expected); ret = sss_password_decrypt(test_ctx, obfpwd, &ctpwd); fail_if(ret != expected); fail_if(ctpwd && strcmp(password[i], ctpwd) != 0); talloc_free(obfpwd); talloc_free(ctpwd); } ck_leaks_pop(test_ctx); talloc_free(test_ctx); } END_TEST START_TEST(test_hmac_sha1) { const char *message = "test message"; const char *keys[] = { "short", "proper6789012345678901234567890123456789012345678901234567890123", "longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong", NULL }; const char *results[] = { "\x2b\x27\x53\x07\x17\xd8\xc0\x8f\x97\x27\xdd\xb3\xec\x41\xd8\xa3\x94\x97\xaa\x35", "\x37\xe7\x0a\x6f\x71\x0b\xa9\x93\x81\x53\x8f\x5c\x06\x83\x44\x2f\xc9\x41\xe3\xed", "\xbd\x99\xa7\x7f\xfc\x5e\xde\x04\x32\x7f\x7b\x71\x4d\xc0\x3f\x51\x2d\x25\x01\x28", NULL }; unsigned char out[SSS_SHA1_LENGTH]; int ret, expected; int i; #if defined(HAVE_NSS) || defined(HAVE_LIBCRYPTO) expected = EOK; #else #error Unknown crypto back end #endif for (i = 0; keys[i]; i++) { ret = sss_hmac_sha1((const unsigned char *)keys[i], strlen(keys[i]), (const unsigned char *)message, strlen(message), out); fail_if(ret != expected); fail_if(ret == EOK && memcmp(out, results[i], SSS_SHA1_LENGTH) != 0); } } END_TEST START_TEST(test_base64_encode) { const unsigned char obfbuf[] = "test"; const char expected[] = "dGVzdA=="; char *obfpwd = NULL; test_ctx = talloc_new(NULL); fail_if(test_ctx == NULL); /* Base64 encode the buffer */ obfpwd = sss_base64_encode(test_ctx, obfbuf, strlen((const char*)obfbuf)); fail_if(obfpwd == NULL); fail_if(strcmp(obfpwd,expected) != 0); talloc_free(test_ctx); } END_TEST START_TEST(test_base64_decode) { unsigned char *obfbuf = NULL; size_t obflen; const char b64encoded[] = "dGVzdA=="; const unsigned char expected[] = "test"; test_ctx = talloc_new(NULL); fail_if(test_ctx == NULL); /* Base64 decode the buffer */ obfbuf = sss_base64_decode(test_ctx, b64encoded, &obflen); fail_if(!obfbuf); fail_if(obflen != strlen((const char*)expected)); fail_if(memcmp(obfbuf, expected, obflen) != 0); talloc_free(test_ctx); } END_TEST Suite *crypto_suite(void) { Suite *s = suite_create("sss_crypto"); TCase *tc = tcase_create("sss crypto tests"); tcase_add_checked_fixture(tc, ck_leak_check_setup, ck_leak_check_teardown); /* Do some testing */ #ifdef HAVE_NSS tcase_add_test(tc, test_nss_init); #endif tcase_add_test(tc, test_encrypt_decrypt); tcase_add_test(tc, test_hmac_sha1); tcase_add_test(tc, test_base64_encode); tcase_add_test(tc, test_base64_decode); /* Add all test cases to the test suite */ suite_add_tcase(s, tc); return s; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int number_failed; struct poptOption long_options[] = { POPT_AUTOHELP { "debug-level", 'd', POPT_ARG_INT, &debug_level, 0, "Set debug level", NULL }, POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); Suite *s = crypto_suite(); SRunner *sr = srunner_create(s); srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } sssd-1.13.4/src/tests/PaxHeaders.16287/python-test.py0000644000000000000000000000007412703456111017126 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.352792605 sssd-1.13.4/src/tests/python-test.py0000644002412700241270000004051712703456111020604 0ustar00jhrozekjhrozek00000000000000#!/usr/bin/env python #coding=utf-8 # Authors: # Jakub Hrozek # # Copyright (C) 2009 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA import os import tempfile import shutil import unittest import subprocess import errno # module under test import pysss class LocalTest(unittest.TestCase): local_path = "/var/lib/sss/db/sssd.ldb" def setUp(self): self.local = pysss.local() def _run_and_check(self, runme): (status, output) = subprocess.call(runme, shell=True) self.failUnlessEqual(status, 0, output) def _get_object_info(self, name, subtree, domain): search_dn = "dn=name=%s,cn=%s,cn=%s,cn=sysdb" % (name, subtree, domain) try: output = subprocess.check_call("ldbsearch -H %s %s" % (self.local_path,search_dn), shell=True) output = output.decode('utf-8') except subprocess.CalledProcessError: return {} kw = {} for key, value in [ l.split(':') for l in output.split('\n') if ":" in l ]: kw[key] = value.strip() del kw['asq'] return kw def get_user_info(self, name, domain="LOCAL"): return self._get_object_info(name, "users", domain) def get_group_info(self, name, domain="LOCAL"): return self._get_object_info(name, "groups", domain) def _validate_object(self, kw, name, **kwargs): if kw == {}: self.fail("Could not get %s info" % name) for key in kwargs.keys(): self.assert_(str(kwargs[key]) == str(kw[key]), "%s %s != %s %s" % (key, kwargs[key], key, kw[key])) def validate_user(self, username, **kwargs): return self._validate_object(self.get_user_info(username), "user", **kwargs) def validate_group(self, groupname, **kwargs): return self._validate_object(self.get_group_info(groupname), "group", **kwargs) def _validate_no_object(self, kw, name): if kw != {}: self.fail("Got %s info" % name) def validate_no_user(self, username): return self._validate_no_object(self.get_user_info(username), "user") def validate_no_group(self, groupname): return self._validate_no_object(self.get_group_info(groupname), "group") def _get_object_membership(self, name, subtree, domain): search_dn = "dn=name=%s,cn=%s,cn=%s,cn=sysdb" % (name, subtree, domain) try: output = subprocess.check_call("ldbsearch -H %s %s" % (self.local_path,search_dn), shell=True) output = output.decode('utf-8') except subprocess.CalledProcessError: return [] members = [ value.strip() for key, value in [ l.split(':') for l in output.split('\n') if ":" in l ] if key == "memberof" ] return members def _assertMembership(self, name, group_list, subtree, domain): members = self._get_object_membership(name, subtree, domain) for group in group_list: group_dn = "name=%s,cn=groups,cn=%s,cn=sysdb" % (group, domain) if group_dn in members: members.remove(group_dn) else: self.fail("Cannot find required group %s" % group_dn) if len(members) > 0: self.fail("More groups than selected") def assertUserMembership(self, name, group_list, domain="LOCAL"): return self._assertMembership(name, group_list, "users", domain) def assertGroupMembership(self, name, group_list, domain="LOCAL"): return self._assertMembership(name, group_list, "groups", domain) def get_user_membership(self, name, domain="LOCAL"): return self._get_object_membership(name, "users", domain) def get_group_membership(self, name, domain="LOCAL"): return self._get_object_membership(name, "groups", domain) def add_group(self, groupname): self._run_and_check("sss_groupadd %s" % (groupname)) def remove_group(self, groupname): self._run_and_check("sss_groupdel %s" % (groupname)) def add_user(self, username): self._run_and_check("sss_useradd %s" % (username)) def add_user_not_home(self, username): self._run_and_check("sss_useradd -M %s" % (username)) def remove_user(self, username): self._run_and_check("sss_userdel %s" % (username)) def remove_user_not_home(self, username): self._run_and_check("sss_userdel -R %s" % (username)) class SanityTest(unittest.TestCase): def testInstantiate(self): "Test that the local backed binding can be instantiated" local = pysss.local() self.assert_(local.__class__, "") class UseraddTest(LocalTest): def tearDown(self): if self.username: self.remove_user(self.username) def testUseradd(self): "Test adding a local user" self.username = "testUseradd" self.local.useradd(self.username) self.validate_user(self.username) # check home directory was created with default name self.assertEquals(os.access("/home/%s" % self.username, os.F_OK), True) def testUseraddWithParams(self): "Test adding a local user with modified parameters" self.username = "testUseraddWithParams" self.local.useradd(self.username, gecos="foo bar", homedir="/home/foobar", shell="/bin/zsh") self.validate_user(self.username, gecos="foo bar", homeDirectory="/home/foobar", loginShell="/bin/zsh") # check home directory was created with nondefault name self.assertEquals(os.access("/home/foobar", os.F_OK), True) def testUseraddNoHomedir(self): "Test adding a local user without creating his home dir" self.username = "testUseraddNoHomedir" self.local.useradd(self.username, create_home = False) self.validate_user(self.username) # check home directory was not created self.assertEquals(os.access("/home/%s" % self.username, os.F_OK), False) self.local.userdel(self.username, remove = False) self.username = None # fool tearDown into not removing the user def testUseraddAlternateSkeldir(self): "Test adding a local user and init his homedir from a custom location" self.username = "testUseraddAlternateSkeldir" skeldir = tempfile.mkdtemp() fd, path = tempfile.mkstemp(dir=skeldir) fdo = os.fdopen(fd) fdo.flush() fdo.close self.assertEquals(os.access(path, os.F_OK), True) filename = os.path.basename(path) try: self.local.useradd(self.username, skel = skeldir) self.validate_user(self.username) self.assertEquals(os.access("/home/%s/%s"%(self.username,filename), os.F_OK), True) finally: shutil.rmtree(skeldir) def testUseraddToGroups(self): "Test adding a local user with group membership" self.username = "testUseraddToGroups" self.add_group("gr1") self.add_group("gr2") try: self.local.useradd(self.username, groups=["gr1","gr2"]) self.assertUserMembership(self.username, ["gr1","gr2"]) finally: self.remove_group("gr1") self.remove_group("gr2") def testUseraddWithUID(self): "Test adding a local user with a custom UID" self.username = "testUseraddWithUID" self.local.useradd(self.username, uid=1024) self.validate_user(self.username, uidNumber=1024) class UseraddTestNegative(LocalTest): def testUseraddNoParams(self): "Test that local.useradd() requires the username parameter" self.assertRaises(TypeError, self.local.useradd) def testUseraddUserAlreadyExists(self): "Test adding a local with a duplicite name" self.username = "testUseraddUserAlreadyExists" self.local.useradd(self.username) try: self.local.useradd(self.username) except IOError as e: self.assertEquals(e.errno, errno.EEXIST) else: self.fail("Was expecting exception") finally: self.remove_user(self.username) def testUseraddUIDAlreadyExists(self): "Test adding a local with a duplicite user ID" self.username = "testUseraddUIDAlreadyExists1" self.local.useradd(self.username, uid=1025) try: self.local.useradd("testUseraddUIDAlreadyExists2", uid=1025) except IOError as e: self.assertEquals(e.errno, errno.EEXIST) else: self.fail("Was expecting exception") finally: self.remove_user(self.username) class UserdelTest(LocalTest): def testUserdel(self): self.add_user("testUserdel") self.assertEquals(os.access("/home/testUserdel", os.F_OK), True) self.validate_user("testUserdel") self.local.userdel("testUserdel") self.validate_no_user("testUserdel") self.assertEquals(os.access("/home/testUserdel", os.F_OK), False) def testUserdelNotHomedir(self): self.add_user("testUserdel") self.assertEquals(os.access("/home/testUserdel", os.F_OK), True) self.validate_user("testUserdel") self.local.userdel("testUserdel", remove=False) self.validate_no_user("testUserdel") self.assertEquals(os.access("/home/testUserdel", os.F_OK), True) shutil.rmtree("/home/testUserdel") os.remove("/var/mail/testUserdel") def testUserdelNegative(self): self.validate_no_user("testUserdelNegative") try: self.local.userdel("testUserdelNegative") except IOError as e: self.assertEquals(e.errno, errno.ENOENT) else: fail("Was expecting exception") class UsermodTest(LocalTest): def setUp(self): self.local = pysss.local() self.username = "UsermodTest" self.add_user_not_home(self.username) def tearDown(self): self.remove_user_not_home(self.username) def testUsermod(self): "Test modifying user attributes" self.local.usermod(self.username, gecos="foo bar", homedir="/home/foobar", shell="/bin/zsh") self.validate_user(self.username, gecos="foo bar", homeDirectory="/home/foobar", loginShell="/bin/zsh") def testUsermodUID(self): "Test modifying UID" self.local.usermod(self.username, uid=1024) self.validate_user(self.username, uidNumber=1024) def testUsermodGroupMembership(self): "Test adding to and removing from groups" self.add_group("gr1") self.add_group("gr2") try: self.local.usermod(self.username, addgroups=["gr1","gr2"]) self.assertUserMembership(self.username, ["gr1","gr2"]) self.local.usermod(self.username, rmgroups=["gr2"]) self.assertUserMembership(self.username, ["gr1"]) self.local.usermod(self.username, rmgroups=["gr1"]) self.assertUserMembership(self.username, []) finally: self.remove_group("gr1") self.remove_group("gr2") def testUsermodLockUnlock(self): "Test locking and unlocking user" self.local.usermod(self.username, lock=self.local.lock) self.validate_user(self.username, disabled="true") self.local.usermod(self.username, lock=self.local.unlock) self.validate_user(self.username, disabled="false") class GroupaddTest(LocalTest): def tearDown(self): if self.groupname: self.remove_group(self.groupname) def testGroupadd(self): "Test adding a local group" self.groupname = "testGroupadd" self.local.groupadd(self.groupname) self.validate_group(self.groupname) def testGroupaddWithGID(self): "Test adding a local group with a custom GID" self.groupname = "testUseraddWithGID" self.local.groupadd(self.groupname, gid=1024) self.validate_group(self.groupname, gidNumber=1024) class GroupaddTestNegative(LocalTest): def testGroupaddNoParams(self): "Test that local.groupadd() requires the groupname parameter" self.assertRaises(TypeError, self.local.groupadd) def testGroupaddUserAlreadyExists(self): "Test adding a local with a duplicite name" self.groupname = "testGroupaddUserAlreadyExists" self.local.groupadd(self.groupname) try: self.local.groupadd(self.groupname) except IOError as e: self.assertEquals(e.errno, errno.EEXIST) else: self.fail("Was expecting exception") finally: self.remove_group(self.groupname) def testGroupaddGIDAlreadyExists(self): "Test adding a local with a duplicite group ID" self.groupname = "testGroupaddGIDAlreadyExists1" self.local.groupadd(self.groupname, gid=1025) try: self.local.groupadd("testGroupaddGIDAlreadyExists2", gid=1025) except IOError as e: self.assertEquals(e.errno, errno.EEXIST) else: self.fail("Was expecting exception") finally: self.remove_group(self.groupname) class GroupdelTest(LocalTest): def testGroupdel(self): self.add_group("testGroupdel") self.validate_group("testGroupdel") self.local.groupdel("testGroupdel") self.validate_no_group("testGroupdel") def testGroupdelNegative(self): self.validate_no_group("testGroupdelNegative") try: self.local.groupdel("testGroupdelNegative") except IOError as e: self.assertEquals(e.errno, errno.ENOENT) else: fail("Was expecting exception") class GroupmodTest(LocalTest): def setUp(self): self.local = pysss.local() self.groupname = "GroupmodTest" self.add_group(self.groupname) def tearDown(self): self.remove_group(self.groupname) def testGroupmodGID(self): "Test modifying UID" self.local.groupmod(self.groupname, gid=1024) self.validate_group(self.groupname, gidNumber=1024) def testGroupmodGroupMembership(self): "Test adding to groups" self.add_group("gr1") self.add_group("gr2") try: self.local.groupmod(self.groupname, addgroups=["gr1","gr2"]) self.assertGroupMembership(self.groupname, ["gr1","gr2"]) self.local.groupmod(self.groupname, rmgroups=["gr2"]) self.assertGroupMembership(self.groupname, ["gr1"]) self.local.groupmod(self.groupname, rmgroups=["gr1"]) self.assertGroupMembership(self.groupname, []) finally: self.remove_group("gr1") self.remove_group("gr2") # -------------- run the test suite -------------- # if __name__ == "__main__": unittest.main() sssd-1.13.4/src/tests/PaxHeaders.16287/cmocka0000644000000000000000000000013212703463557015445 xustar0030 mtime=1460561775.055794988 30 atime=1460561776.118798593 30 ctime=1460561775.055794988 sssd-1.13.4/src/tests/cmocka/0000755002412700241270000000000012703463557017176 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_data_provider_be.c0000644000000000000000000000007412703456111022207 xustar0030 atime=1460561751.655715644 30 ctime=1460561775.035794921 sssd-1.13.4/src/tests/cmocka/test_data_provider_be.c0000644002412700241270000002144112703456111023660 0ustar00jhrozekjhrozek00000000000000/* Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "providers/dp_backend.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_be.h" #include "tests/common.h" #define TESTS_PATH "tests_dp_be" #define TEST_CONF_DB "test_dp_be_conf.ldb" #define TEST_DOM_NAME "dp_be_test" #define TEST_ID_PROVIDER "ldap" #define OFFLINE_TIMEOUT 2 #define AS_STR(param) (#param) static TALLOC_CTX *global_mock_context = NULL; static bool global_timer_added; struct tevent_timer *__real__tevent_add_timer(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location); struct tevent_timer *__wrap__tevent_add_timer(struct tevent_context *ev, TALLOC_CTX *mem_ctx, struct timeval next_event, tevent_timer_handler_t handler, void *private_data, const char *handler_name, const char *location) { global_timer_added = true; return __real__tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, handler_name, location); } struct test_ctx { struct sss_test_ctx *tctx; struct be_ctx *be_ctx; }; static int test_setup(void **state) { struct test_ctx *test_ctx = NULL; struct sss_test_conf_param params[] = { { "offline_timeout", AS_STR(OFFLINE_TIMEOUT) }, { NULL, NULL }, /* Sentinel */ }; assert_true(leak_check_setup()); global_mock_context = talloc_new(global_talloc_context); assert_non_null(global_mock_context); test_ctx = talloc_zero(global_talloc_context, struct test_ctx); assert_non_null(test_ctx); test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, params); assert_non_null(test_ctx->tctx); test_ctx->be_ctx = mock_be_ctx(test_ctx, test_ctx->tctx); assert_non_null(test_ctx->be_ctx); test_ctx->be_ctx->domain->subdomains = named_domain(test_ctx, "subdomains", test_ctx->be_ctx->domain); assert_non_null(test_ctx->be_ctx->domain->subdomains); *state = test_ctx; return 0; } static int test_teardown(void **state) { talloc_zfree(*state); assert_true(leak_check_teardown()); return 0; } static void assert_domain_state(struct sss_domain_info *dom, enum sss_domain_state expected_state) { enum sss_domain_state dom_state; dom_state = sss_domain_get_state(dom); assert_int_equal(dom_state, expected_state); } static void test_mark_subdom_offline_check(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { struct test_ctx *test_ctx = talloc_get_type(pvt, struct test_ctx); assert_domain_state(test_ctx->be_ctx->domain->subdomains, DOM_ACTIVE); test_ctx->tctx->done = true; test_ctx->tctx->error = EOK; } static void test_mark_dom_offline(void **state) { struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx); assert_domain_state(test_ctx->be_ctx->domain, DOM_ACTIVE); assert_false(be_is_offline(test_ctx->be_ctx)); be_mark_dom_offline(test_ctx->be_ctx->domain, test_ctx->be_ctx); assert_true(be_is_offline(test_ctx->be_ctx)); assert_domain_state(test_ctx->be_ctx->domain, DOM_ACTIVE); } static void test_mark_subdom_offline(void **state) { struct timeval tv; struct tevent_timer *check_ev = NULL; struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx); errno_t ret; assert_domain_state(test_ctx->be_ctx->domain->subdomains, DOM_ACTIVE); assert_false(be_is_offline(test_ctx->be_ctx)); global_timer_added = false; be_mark_dom_offline(test_ctx->be_ctx->domain->subdomains, test_ctx->be_ctx); assert_domain_state(test_ctx->be_ctx->domain->subdomains, DOM_INACTIVE); /* A timer must be added that resets the state back */ assert_true(global_timer_added); /* Global offline state must not change */ assert_false(be_is_offline(test_ctx->be_ctx)); /* Make sure we don't add a second timer */ global_timer_added = false; be_mark_dom_offline(test_ctx->be_ctx->domain->subdomains, test_ctx->be_ctx); assert_domain_state(test_ctx->be_ctx->domain->subdomains, DOM_INACTIVE); assert_false(global_timer_added); /* Wait for the internal timer to reset our subdomain back */ tv = tevent_timeval_current_ofs(OFFLINE_TIMEOUT + 1, 0); check_ev = tevent_add_timer(test_ctx->tctx->ev, test_ctx, tv, test_mark_subdom_offline_check, test_ctx); if (check_ev == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Cannot create timer\n"); return; } ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, EOK); } static void test_mark_subdom_offline_disabled(void **state) { struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx); sss_domain_set_state(test_ctx->be_ctx->domain->subdomains, DOM_DISABLED); assert_domain_state(test_ctx->be_ctx->domain->subdomains, DOM_DISABLED); be_mark_dom_offline(test_ctx->be_ctx->domain->subdomains, test_ctx->be_ctx); assert_domain_state(test_ctx->be_ctx->domain->subdomains, DOM_DISABLED); } int main(int argc, const char *argv[]) { poptContext pc; int opt; int rv; int no_cleanup = 0; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_mark_dom_offline, test_setup, test_teardown), cmocka_unit_test_setup_teardown(test_mark_subdom_offline, test_setup, test_teardown), cmocka_unit_test_setup_teardown(test_mark_subdom_offline_disabled, test_setup, test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0 && !no_cleanup) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); } return rv; return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_ldap_id_cleanup.c0000644000000000000000000000007412703456111022021 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.044794951 sssd-1.13.4/src/tests/cmocka/test_ldap_id_cleanup.c0000644002412700241270000002411712703456111023475 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Reichl Copyright (C) 2015 Red Hat SSSD tests - id cleanup This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "tests/cmocka/common_mock.h" #include "providers/ldap/ldap_auth.h" #include "tests/cmocka/test_expire_common.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/ldap_opts.h" #include "providers/ipa/ipa_opts.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_FILE "tests_conf.ldb" struct sysdb_test_ctx { struct sysdb_ctx *sysdb; struct confdb_ctx *confdb; struct tevent_context *ev; struct sss_domain_info *domain; struct sdap_options *opts; }; static int _setup_sysdb_tests(struct sysdb_test_ctx **ctx, bool enumerate) { struct sysdb_test_ctx *test_ctx; char *conf_db; int ret; const char *val[2]; val[1] = NULL; /* Create tests directory if it doesn't exist */ /* (relative to current dir) */ ret = mkdir(TESTS_PATH, 0775); assert_true(ret == 0 || errno == EEXIST); test_ctx = talloc_zero(global_talloc_context, struct sysdb_test_ctx); assert_non_null(test_ctx); /* Create an event context * It will not be used except in confdb_init and sysdb_init */ test_ctx->ev = tevent_context_init(test_ctx); assert_non_null(test_ctx->ev); conf_db = talloc_asprintf(test_ctx, "%s/%s", TESTS_PATH, TEST_CONF_FILE); assert_non_null(conf_db); DEBUG(SSSDBG_MINOR_FAILURE, "CONFDB: %s\n", conf_db); /* Connect to the conf db */ ret = confdb_init(test_ctx, &test_ctx->confdb, conf_db); assert_int_equal(ret, EOK); val[0] = "LOCAL"; ret = confdb_add_param(test_ctx->confdb, true, "config/sssd", "domains", val); assert_int_equal(ret, EOK); val[0] = "local"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "id_provider", val); assert_int_equal(ret, EOK); val[0] = enumerate ? "TRUE" : "FALSE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "enumerate", val); assert_int_equal(ret, EOK); val[0] = "TRUE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "cache_credentials", val); assert_int_equal(ret, EOK); ret = sssd_domain_init(test_ctx, test_ctx->confdb, "local", TESTS_PATH, &test_ctx->domain); assert_int_equal(ret, EOK); test_ctx->domain->has_views = true; test_ctx->sysdb = test_ctx->domain->sysdb; *ctx = test_ctx; return EOK; } #define setup_sysdb_tests(ctx) _setup_sysdb_tests((ctx), false) static int test_sysdb_setup(void **state) { int ret; struct sysdb_test_ctx *test_ctx; assert_true(leak_check_setup()); ret = setup_sysdb_tests(&test_ctx); assert_int_equal(ret, EOK); test_ctx->domain->mpg = false; /* set options */ test_ctx->opts = talloc_zero(test_ctx, struct sdap_options); assert_non_null(test_ctx->opts); ret = sdap_copy_map(test_ctx->opts, rfc2307_user_map, SDAP_OPTS_USER, &test_ctx->opts->user_map); assert_int_equal(ret, ERR_OK); ret = dp_copy_defaults(test_ctx->opts, default_basic_opts, SDAP_OPTS_BASIC, &test_ctx->opts->basic); assert_int_equal(ret, ERR_OK); dp_opt_set_int(test_ctx->opts->basic, SDAP_ACCOUNT_CACHE_EXPIRATION, 1); *state = (void *) test_ctx; return 0; } static int test_sysdb_teardown(void **state) { struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } static errno_t invalidate_group(TALLOC_CTX *ctx, struct sss_domain_info *domain, const char *name) { struct sysdb_attrs *sys_attrs = NULL; errno_t ret; sys_attrs = sysdb_new_attrs(ctx); if (sys_attrs) { ret = sysdb_attrs_add_time_t(sys_attrs, SYSDB_CACHE_EXPIRE, 1); if (ret == EOK) { ret = sysdb_set_group_attr(domain, name, sys_attrs, SYSDB_MOD_REP); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add expiration time to attributes\n"); } talloc_zfree(sys_attrs); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not create sysdb attributes\n"); ret = ENOMEM; } return ret; } static void test_id_cleanup_exp_group(void **state) { errno_t ret; struct ldb_message *msg; struct sdap_domain sdom; const char *special_grp = "special_gr*o/u\\p(2016)"; const char *empty_special_grp = "empty_gr*o/u\\p(2016)"; const char *empty_grp = "empty_grp"; const char *grp = "grp"; /* This timeout can be bigger because we will call invalidate_group * to expire entries without waiting. */ const uint64_t CACHE_TIMEOUT = 30; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); ret = sysdb_store_group(test_ctx->domain, special_grp, 10002, NULL, CACHE_TIMEOUT, 0); assert_int_equal(ret, EOK); ret = sysdb_store_group(test_ctx->domain, empty_special_grp, 10003, NULL, CACHE_TIMEOUT, 0); assert_int_equal(ret, EOK); ret = sysdb_store_group(test_ctx->domain, grp, 10004, NULL, CACHE_TIMEOUT, 0); assert_int_equal(ret, EOK); ret = sysdb_store_group(test_ctx->domain, empty_grp, 10005, NULL, CACHE_TIMEOUT, 0); assert_int_equal(ret, EOK); ret = sysdb_store_user(test_ctx->domain, "test_user", NULL, 10001, 10002, "Test user", NULL, NULL, NULL, NULL, NULL, 0, 0); assert_int_equal(ret, EOK); ret = sysdb_store_user(test_ctx->domain, "test_user2", NULL, 10002, 10004, "Test user", NULL, NULL, NULL, NULL, NULL, 0, 0); assert_int_equal(ret, EOK); sdom.dom = test_ctx->domain; /* not expired */ ret = ldap_id_cleanup(test_ctx->opts, &sdom); assert_int_equal(ret, EOK); ret = sysdb_search_group_by_name(test_ctx, test_ctx->domain, special_grp, NULL, &msg); assert_int_equal(ret, EOK); ret = sysdb_search_group_by_name(test_ctx, test_ctx->domain, empty_special_grp, NULL, &msg); assert_int_equal(ret, EOK); ret = sysdb_search_group_by_name(test_ctx, test_ctx->domain, grp, NULL, &msg); assert_int_equal(ret, EOK); ret = sysdb_search_group_by_name(test_ctx, test_ctx->domain, empty_grp, NULL, &msg); assert_int_equal(ret, EOK); /* let records to expire */ invalidate_group(test_ctx, test_ctx->domain, special_grp); invalidate_group(test_ctx, test_ctx->domain, empty_special_grp); invalidate_group(test_ctx, test_ctx->domain, grp); invalidate_group(test_ctx, test_ctx->domain, empty_grp); ret = ldap_id_cleanup(test_ctx->opts, &sdom); assert_int_equal(ret, EOK); ret = sysdb_search_group_by_name(test_ctx, test_ctx->domain, special_grp, NULL, &msg); assert_int_equal(ret, EOK); ret = sysdb_search_group_by_name(test_ctx, test_ctx->domain, empty_special_grp, NULL, &msg); assert_int_equal(ret, ENOENT); ret = sysdb_search_group_by_name(test_ctx, test_ctx->domain, grp, NULL, &msg); assert_int_equal(ret, EOK); ret = sysdb_search_group_by_name(test_ctx, test_ctx->domain, empty_grp, NULL, &msg); assert_int_equal(ret, ENOENT); } int main(int argc, const char *argv[]) { int rv; int no_cleanup = 0; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS { "no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_id_cleanup_exp_group, test_sysdb_setup, test_sysdb_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_FILE, LOCAL_SYSDB_FILE); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0 && no_cleanup == 0) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_FILE, LOCAL_SYSDB_FILE); } return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/common_mock_sysdb_objects.h0000644000000000000000000000007412703456111023102 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.587793401 sssd-1.13.4/src/tests/cmocka/common_mock_sysdb_objects.h0000644002412700241270000000316112703456111024552 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef COMMON_MOCK_SYSDB_OBJECTS_H_ #define COMMON_MOCK_SYSDB_OBJECTS_H_ #include #include "util/util.h" #include "providers/ldap/sdap.h" struct sysdb_attrs * _mock_sysdb_object(TALLOC_CTX *mem_ctx, const char *base_dn, const char *name, ...); #define mock_sysdb_object(mem_ctx, base_dn, name, ...) \ _mock_sysdb_object(mem_ctx, base_dn, name, ##__VA_ARGS__, NULL) struct sysdb_attrs * mock_sysdb_group_rfc2307bis(TALLOC_CTX *mem_ctx, const char *base_dn, gid_t gid, const char *name, const char **members); struct sysdb_attrs * mock_sysdb_user(TALLOC_CTX *mem_ctx, const char *base_dn, uid_t uid, const char *name); #endif /* COMMON_MOCK_SYSDB_OBJECTS_H_ */ sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_search_bases.c0000644000000000000000000000007412703456111021340 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.048794965 sssd-1.13.4/src/tests/cmocka/test_search_bases.c0000644002412700241270000001254712703456111023020 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Reichl Copyright (C) 2013 Red Hat SSSD tests - Search bases This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "util/find_uid.h" #include "util/sss_ldap.h" #include "tests/common.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap.h" #include "dhash.h" #include "tests/common_check.h" enum sss_test_get_by_dn { DN_NOT_IN_DOMS, /* dn is not in any domain */ DN_IN_DOM1, /* dn is in the domain based on dns */ DN_IN_DOM2, /* dn is in the domain based on dns2 */ }; static struct sdap_search_base** generate_bases(TALLOC_CTX *mem_ctx, const char** dns, size_t n) { struct sdap_search_base **search_bases; errno_t err; int i; search_bases = talloc_array(mem_ctx, struct sdap_search_base *, n + 1); assert_non_null(search_bases); for (i=0; i < n; ++i) { err = sdap_create_search_base(mem_ctx, dns[i], LDAP_SCOPE_SUBTREE, NULL, &search_bases[i]); if (err != EOK) { fprintf(stderr, "Failed to create search base\n"); } assert_int_equal(err, EOK); } search_bases[n] = NULL; return search_bases; } static bool do_test_search_bases(const char* dn, const char** dns, size_t n) { TALLOC_CTX *tmp_ctx; struct sdap_search_base **search_bases; bool ret; tmp_ctx = talloc_new(NULL); assert_non_null(tmp_ctx); search_bases = generate_bases(tmp_ctx, dns, n); check_leaks_push(tmp_ctx); ret = sss_ldap_dn_in_search_bases(tmp_ctx, dn, search_bases, NULL); assert_true(check_leaks_pop(tmp_ctx) == true); talloc_free(tmp_ctx); return ret; } void test_search_bases_fail(void **state) { const char *dn = "cn=user, dc=sub, dc=ad, dc=pb"; const char *dns[] = {"dc=example, dc=com", "dc=subdom, dc=ad, dc=pb"}; bool ret; ret = do_test_search_bases(dn, dns, 2); assert_false(ret); } void test_search_bases_success(void **state) { const char *dn = "cn=user, dc=sub, dc=ad, dc=pb"; const char *dns[] = {"", "dc=ad, dc=pb", "dc=sub, dc=ad, dc=pb"}; bool ret; ret = do_test_search_bases(dn, dns, 3); assert_true(ret); } static void do_test_get_by_dn(const char *dn, const char **dns, size_t n, const char **dns2, size_t n2, int expected_result) { TALLOC_CTX *tmp_ctx; struct sdap_options *opts; struct sdap_domain *sdom; struct sdap_domain *sdom2; struct sdap_domain *res_sdom; struct sdap_search_base **search_bases; struct sdap_search_base **search_bases2; tmp_ctx = talloc_new(NULL); assert_non_null(tmp_ctx); search_bases = generate_bases(tmp_ctx, dns, n); search_bases2 = generate_bases(tmp_ctx, dns2, n2); sdom = talloc_zero(tmp_ctx, struct sdap_domain); assert_non_null(sdom); sdom2 = talloc_zero(tmp_ctx, struct sdap_domain); assert_non_null(sdom2); sdom->search_bases = search_bases; sdom->next = sdom2; sdom->prev = NULL; sdom2->search_bases = search_bases2; sdom2->next = NULL; sdom2->prev = sdom; opts = talloc(tmp_ctx, struct sdap_options); assert_non_null(opts); opts->sdom = sdom; res_sdom = sdap_domain_get_by_dn(opts, dn); switch (expected_result) { case DN_NOT_IN_DOMS: assert_null(res_sdom); break; case DN_IN_DOM1: assert_true(res_sdom == sdom); break; case DN_IN_DOM2: assert_true(res_sdom == sdom2); break; } talloc_free(tmp_ctx); } void test_get_by_dn(void **state) { const char *dn = "cn=user, dc=sub, dc=ad, dc=pb"; const char *dns[] = {"dc=ad, dc=pb"}; const char *dns2[] = {"dc=sub, dc=ad, dc=pb"}; do_test_get_by_dn(dn, dns, 1, dns2, 1, DN_IN_DOM2); } void test_get_by_dn2(void **state) { const char *dn = "cn=user, dc=ad, dc=com"; const char *dns[] = {"dc=ad, dc=com"}; const char *dns2[] = {"dc=sub, dc=ad, dc=pb"}; do_test_get_by_dn(dn, dns, 1, dns2, 1, DN_IN_DOM1); } void test_get_by_dn_fail(void **state) { const char *dn = "cn=user, dc=sub, dc=example, dc=com"; const char *dns[] = {"dc=ad, dc=pb"}; const char *dns2[] = {"dc=sub, dc=ad, dc=pb"}; do_test_get_by_dn(dn, dns, 1, dns2, 1, DN_NOT_IN_DOMS); } int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_search_bases_fail), cmocka_unit_test(test_search_bases_success), cmocka_unit_test(test_get_by_dn_fail), cmocka_unit_test(test_get_by_dn), cmocka_unit_test(test_get_by_dn2) }; return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_ad_common.c0000644000000000000000000000007412703456111020652 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.906794483 sssd-1.13.4/src/tests/cmocka/test_ad_common.c0000644002412700241270000004364012703456111022330 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat SSSD tests: AD access control filter tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include /* In order to access opaque types */ #include "providers/ad/ad_common.c" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_krb5.h" #define DOMNAME "domname" #define SUBDOMNAME "sub."DOMNAME #define REALMNAME DOMNAME #define HOST_NAME "ad."REALMNAME #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_AUTHID "host/"HOST_NAME #define KEYTAB_TEST_PRINC TEST_AUTHID"@"REALMNAME #define KEYTAB_PATH TESTS_PATH"/keytab_test.keytab" #define ONEWAY_DOMNAME "ONEWAY" #define ONEWAY_HOST_NAME "ad."ONEWAY_DOMNAME #define ONEWAY_KEYTAB_PATH TESTS_PATH"/oneway_test.keytab" #define ONEWAY_AUTHID "host/"ONEWAY_HOST_NAME #define ONEWAY_TEST_PRINC ONEWAY_AUTHID"@"ONEWAY_DOMNAME static bool call_real_sasl_options; krb5_error_code __wrap_krb5_kt_default(krb5_context context, krb5_keytab *id) { return krb5_kt_resolve(context, KEYTAB_PATH, id); } struct ad_common_test_ctx { struct ad_id_ctx *ad_ctx; struct ad_id_ctx *subdom_ad_ctx; struct sss_domain_info *dom; struct sss_domain_info *subdom; }; static void test_ad_create_default_options(void **state) { struct ad_options *ad_options; const char *s; ad_options = ad_create_default_options(global_talloc_context); assert_non_null(ad_options->basic); /* Not too much to test here except some defaults */ s = dp_opt_get_string(ad_options->basic, AD_DOMAIN); assert_null(s); assert_non_null(ad_options->id); } static int test_ad_common_setup(void **state) { struct ad_common_test_ctx *test_ctx; test_dom_suite_setup(TESTS_PATH); assert_true(leak_check_setup()); check_leaks_push(global_talloc_context); test_ctx = talloc_zero(global_talloc_context, struct ad_common_test_ctx); assert_non_null(test_ctx); test_ctx->dom = talloc_zero(test_ctx, struct sss_domain_info); assert_non_null(test_ctx->dom); test_ctx->dom->name = discard_const(DOMNAME); test_ctx->subdom = talloc_zero(test_ctx, struct sss_domain_info); assert_non_null(test_ctx->subdom); test_ctx->subdom->name = discard_const(SUBDOMNAME); test_ctx->subdom->parent = test_ctx->dom; test_ctx->ad_ctx = talloc_zero(test_ctx, struct ad_id_ctx); assert_non_null(test_ctx->ad_ctx); check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int test_ad_common_teardown(void **state) { int ret; struct ad_common_test_ctx *test_ctx = talloc_get_type(*state, struct ad_common_test_ctx); assert_non_null(test_ctx); assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(check_leaks_pop(global_talloc_context) == true); assert_true(leak_check_teardown()); ret = rmdir(TESTS_PATH); assert_return_code(ret, errno); return 0; } static void test_ad_create_1way_trust_options(void **state) { struct ad_common_test_ctx *test_ctx = talloc_get_type(*state, struct ad_common_test_ctx); const char *s; call_real_sasl_options = true; /* Make sure this is not the keytab that __wrap_krb5_kt_default uses */ mock_keytab_with_contents(test_ctx, ONEWAY_KEYTAB_PATH, ONEWAY_TEST_PRINC); test_ctx->ad_ctx->ad_options = ad_create_1way_trust_options( test_ctx->ad_ctx, ONEWAY_DOMNAME, ONEWAY_HOST_NAME, ONEWAY_KEYTAB_PATH, ONEWAY_AUTHID); assert_non_null(test_ctx->ad_ctx->ad_options); assert_int_equal(test_ctx->ad_ctx->ad_options->id->schema_type, SDAP_SCHEMA_AD); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->basic, AD_KRB5_REALM); assert_non_null(s); assert_string_equal(s, ONEWAY_DOMNAME); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->basic, AD_DOMAIN); assert_non_null(s); assert_string_equal(s, ONEWAY_DOMNAME); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->basic, AD_HOSTNAME); assert_non_null(s); assert_string_equal(s, ONEWAY_HOST_NAME); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->basic, AD_KEYTAB); assert_non_null(s); assert_string_equal(s, ONEWAY_KEYTAB_PATH); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->id->basic, SDAP_KRB5_KEYTAB); assert_non_null(s); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->id->basic, SDAP_SASL_REALM); assert_non_null(s); assert_string_equal(s, ONEWAY_DOMNAME); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->id->basic, SDAP_KRB5_REALM); assert_non_null(s); assert_string_equal(s, ONEWAY_DOMNAME); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->id->basic, SDAP_SASL_AUTHID); assert_non_null(s); assert_string_equal(s, ONEWAY_AUTHID); talloc_free(test_ctx->ad_ctx->ad_options); unlink(ONEWAY_KEYTAB_PATH); } static void test_ad_create_2way_trust_options(void **state) { struct ad_common_test_ctx *test_ctx = talloc_get_type(*state, struct ad_common_test_ctx); const char *s; call_real_sasl_options = true; mock_keytab_with_contents(test_ctx, KEYTAB_PATH, KEYTAB_TEST_PRINC); test_ctx->ad_ctx->ad_options = ad_create_2way_trust_options( test_ctx->ad_ctx, REALMNAME, DOMNAME, HOST_NAME); assert_non_null(test_ctx->ad_ctx->ad_options); assert_int_equal(test_ctx->ad_ctx->ad_options->id->schema_type, SDAP_SCHEMA_AD); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->basic, AD_KRB5_REALM); assert_non_null(s); assert_string_equal(s, REALMNAME); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->basic, AD_DOMAIN); assert_non_null(s); assert_string_equal(s, DOMNAME); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->basic, AD_HOSTNAME); assert_non_null(s); assert_string_equal(s, HOST_NAME); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->id->basic, SDAP_KRB5_KEYTAB); assert_null(s); /* This is the system keytab */ s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->id->basic, SDAP_SASL_REALM); assert_non_null(s); assert_string_equal(s, REALMNAME); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->id->basic, SDAP_KRB5_REALM); assert_non_null(s); assert_string_equal(s, REALMNAME); s = dp_opt_get_string(test_ctx->ad_ctx->ad_options->id->basic, SDAP_SASL_AUTHID); assert_non_null(s); assert_string_equal(s, TEST_AUTHID); talloc_free(test_ctx->ad_ctx->ad_options); unlink(KEYTAB_PATH); } static int test_ldap_conn_setup(void **state) { struct ad_common_test_ctx *test_ctx; errno_t ret; struct sdap_domain *sdom; struct ad_id_ctx *ad_ctx; struct ad_id_ctx *subdom_ad_ctx; struct sdap_id_conn_ctx *subdom_ldap_ctx; ret = test_ad_common_setup((void **) &test_ctx); assert_int_equal(ret, EOK); mock_keytab_with_contents(test_ctx, KEYTAB_PATH, KEYTAB_TEST_PRINC); ad_ctx = test_ctx->ad_ctx; ad_ctx->ad_options = ad_create_2way_trust_options(ad_ctx, REALMNAME, DOMNAME, HOST_NAME); assert_non_null(ad_ctx->ad_options); ad_ctx->gc_ctx = talloc_zero(ad_ctx, struct sdap_id_conn_ctx); assert_non_null(ad_ctx->gc_ctx); ad_ctx->ldap_ctx = talloc_zero(ad_ctx, struct sdap_id_conn_ctx); assert_non_null(ad_ctx->ldap_ctx); ad_ctx->sdap_id_ctx = talloc_zero(ad_ctx, struct sdap_id_ctx); assert_non_null(ad_ctx->sdap_id_ctx); ad_ctx->sdap_id_ctx->opts = talloc_zero(ad_ctx->sdap_id_ctx, struct sdap_options); assert_non_null(ad_ctx->sdap_id_ctx->opts); ret = sdap_domain_add(ad_ctx->sdap_id_ctx->opts, test_ctx->dom, &sdom); assert_int_equal(ret, EOK); sdom->pvt = ad_ctx; subdom_ad_ctx = talloc_zero(test_ctx, struct ad_id_ctx); assert_non_null(subdom_ad_ctx); subdom_ldap_ctx = talloc_zero(subdom_ad_ctx, struct sdap_id_conn_ctx); assert_non_null(subdom_ldap_ctx); subdom_ad_ctx->ldap_ctx = subdom_ldap_ctx; ret = sdap_domain_add(ad_ctx->sdap_id_ctx->opts, test_ctx->subdom, &sdom); assert_int_equal(ret, EOK); sdom->pvt = subdom_ad_ctx; test_ctx->subdom_ad_ctx = subdom_ad_ctx; *state = test_ctx; return 0; } static int test_ldap_conn_teardown(void **state) { struct ad_common_test_ctx *test_ctx = talloc_get_type(*state, struct ad_common_test_ctx); assert_non_null(test_ctx); unlink(KEYTAB_PATH); talloc_free(test_ctx->subdom_ad_ctx); talloc_free(test_ctx->ad_ctx->ad_options); talloc_free(test_ctx->ad_ctx->gc_ctx); talloc_free(test_ctx->ad_ctx->ldap_ctx); talloc_free(test_ctx->ad_ctx->sdap_id_ctx); test_ad_common_teardown((void **) &test_ctx); return 0; } errno_t __real_sdap_set_sasl_options(struct sdap_options *id_opts, char *default_primary, char *default_realm, const char *keytab_path); errno_t __wrap_sdap_set_sasl_options(struct sdap_options *id_opts, char *default_primary, char *default_realm, const char *keytab_path) { /* Pretend SASL is fine */ if (call_real_sasl_options == true) { return __real_sdap_set_sasl_options(id_opts, default_primary, default_realm, keytab_path); } return EOK; } void test_ad_get_dom_ldap_conn(void **state) { struct sdap_id_conn_ctx *conn; struct ad_common_test_ctx *test_ctx = talloc_get_type(*state, struct ad_common_test_ctx); assert_non_null(test_ctx); conn = ad_get_dom_ldap_conn(test_ctx->ad_ctx, test_ctx->dom); assert_true(conn == test_ctx->ad_ctx->ldap_ctx); conn = ad_get_dom_ldap_conn(test_ctx->ad_ctx, test_ctx->subdom); assert_true(conn == test_ctx->subdom_ad_ctx->ldap_ctx); } void test_gc_conn_list(void **state) { struct sdap_id_conn_ctx **conn_list; struct ad_common_test_ctx *test_ctx = talloc_get_type(*state, struct ad_common_test_ctx); assert_non_null(test_ctx); assert_true(dp_opt_get_bool(test_ctx->ad_ctx->ad_options->basic, AD_ENABLE_GC)); conn_list = ad_gc_conn_list(test_ctx, test_ctx->ad_ctx, test_ctx->dom); assert_non_null(conn_list); assert_true(conn_list[0] == test_ctx->ad_ctx->gc_ctx); /* If there is a fallback, we should ignore the offline mode */ assert_true(conn_list[0]->ignore_mark_offline); assert_true(conn_list[1] == test_ctx->ad_ctx->ldap_ctx); assert_false(conn_list[1]->ignore_mark_offline); assert_null(conn_list[2]); talloc_free(conn_list); conn_list = ad_gc_conn_list(test_ctx, test_ctx->ad_ctx, test_ctx->subdom); assert_non_null(conn_list); assert_true(conn_list[0] == test_ctx->ad_ctx->gc_ctx); assert_true(conn_list[0]->ignore_mark_offline); assert_true(conn_list[1] == test_ctx->subdom_ad_ctx->ldap_ctx); /* Subdomain error should not set the backend offline! */ assert_true(conn_list[1]->ignore_mark_offline); talloc_free(conn_list); dp_opt_set_bool(test_ctx->ad_ctx->ad_options->basic, AD_ENABLE_GC, false); assert_false(dp_opt_get_bool(test_ctx->ad_ctx->ad_options->basic, AD_ENABLE_GC)); conn_list = ad_gc_conn_list(test_ctx, test_ctx->ad_ctx, test_ctx->dom); assert_non_null(conn_list); assert_true(conn_list[0] == test_ctx->ad_ctx->ldap_ctx); assert_false(conn_list[0]->ignore_mark_offline); assert_null(conn_list[1]); talloc_free(conn_list); conn_list = ad_gc_conn_list(test_ctx, test_ctx->ad_ctx, test_ctx->subdom); assert_non_null(conn_list); assert_true(conn_list[0] == test_ctx->subdom_ad_ctx->ldap_ctx); assert_true(conn_list[0]->ignore_mark_offline); assert_null(conn_list[1]); talloc_free(conn_list); } void test_ldap_conn_list(void **state) { struct sdap_id_conn_ctx **conn_list; struct ad_common_test_ctx *test_ctx = talloc_get_type(*state, struct ad_common_test_ctx); assert_non_null(test_ctx); conn_list = ad_ldap_conn_list(test_ctx, test_ctx->ad_ctx, test_ctx->dom); assert_non_null(conn_list); assert_true(conn_list[0] == test_ctx->ad_ctx->ldap_ctx); assert_false(conn_list[0]->ignore_mark_offline); assert_null(conn_list[1]); talloc_free(conn_list); conn_list = ad_ldap_conn_list(test_ctx, test_ctx->ad_ctx, test_ctx->subdom); assert_non_null(conn_list); assert_true(conn_list[0] == test_ctx->subdom_ad_ctx->ldap_ctx); assert_true(conn_list[0]->ignore_mark_offline); assert_null(conn_list[1]); talloc_free(conn_list); } void test_user_conn_list(void **state) { struct sdap_id_conn_ctx **conn_list; struct ad_common_test_ctx *test_ctx = talloc_get_type(*state, struct ad_common_test_ctx); assert_non_null(test_ctx); conn_list = ad_user_conn_list(test_ctx, test_ctx->ad_ctx, test_ctx->dom); assert_non_null(conn_list); assert_true(conn_list[0] == test_ctx->ad_ctx->ldap_ctx); assert_false(conn_list[0]->ignore_mark_offline); assert_null(conn_list[1]); talloc_free(conn_list); conn_list = ad_user_conn_list(test_ctx, test_ctx->ad_ctx, test_ctx->subdom); assert_non_null(conn_list); assert_true(conn_list[0] == test_ctx->ad_ctx->gc_ctx); assert_true(conn_list[0]->ignore_mark_offline); assert_true(conn_list[1] == test_ctx->subdom_ad_ctx->ldap_ctx); /* Subdomain error should not set the backend offline! */ assert_true(conn_list[1]->ignore_mark_offline); talloc_free(conn_list); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test(test_ad_create_default_options), cmocka_unit_test_setup_teardown(test_ad_create_1way_trust_options, test_ad_common_setup, test_ad_common_teardown), cmocka_unit_test_setup_teardown(test_ad_create_2way_trust_options, test_ad_common_setup, test_ad_common_teardown), cmocka_unit_test_setup_teardown(test_ad_get_dom_ldap_conn, test_ldap_conn_setup, test_ldap_conn_teardown), cmocka_unit_test_setup_teardown(test_gc_conn_list, test_ldap_conn_setup, test_ldap_conn_teardown), cmocka_unit_test_setup_teardown(test_ldap_conn_list, test_ldap_conn_setup, test_ldap_conn_teardown), cmocka_unit_test_setup_teardown(test_user_conn_list, test_ldap_conn_setup, test_ldap_conn_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_copy_ccache.c0000644000000000000000000000007412703456111021156 xustar0030 atime=1460561751.655715644 30 ctime=1460561775.033794914 sssd-1.13.4/src/tests/cmocka/test_copy_ccache.c0000644002412700241270000001640012703456111022626 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2014 Red Hat SSSD tests: Tests ccache utilities This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/sss_krb5.h" #include "providers/krb5/krb5_common.h" #include "providers/krb5/krb5_ccache.h" #include "tests/cmocka/common_mock.h" #define CCACHE_TEST_CLIENT_PRINC "test/client@TEST.CCACHE" #define CCACHE_TEST_SERVER_PRINC "test/server@TEST.CCACHE" #define CCACHE_PATH TEST_DIR "/ccache_test.ccache" struct ccache_test_ctx { krb5_context kctx; const char *ccache_file_name; krb5_principal client_principal; krb5_principal server_principal; }; static int setup_ccache(void **state) { struct ccache_test_ctx *test_ctx; krb5_error_code kerr; krb5_ccache ccache; krb5_creds test_creds; static krb5_address addr; int add=0x12345; krb5_authdata *a; static krb5_address *addrs[] = { &addr, NULL, }; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct ccache_test_ctx); assert_non_null(test_ctx); kerr = krb5_init_context(&test_ctx->kctx); assert_int_equal(kerr, 0); addr.magic = KV5M_ADDRESS; addr.addrtype = ADDRTYPE_INET; addr.length = 4; addr.contents = (krb5_octet *) &add; memset(&test_creds, 0, sizeof(test_creds)); test_creds.magic = KV5M_CREDS; kerr = krb5_parse_name(test_ctx->kctx, CCACHE_TEST_CLIENT_PRINC, &test_ctx->client_principal); assert_int_equal(kerr, 0); test_creds.client = test_ctx->client_principal; kerr = krb5_parse_name(test_ctx->kctx, CCACHE_TEST_SERVER_PRINC, &test_ctx->server_principal); assert_int_equal(kerr, 0); test_creds.server = test_ctx->server_principal; test_creds.keyblock.magic = KV5M_KEYBLOCK; test_creds.keyblock.contents = 0; test_creds.keyblock.enctype = 1; test_creds.keyblock.length = 1; test_creds.keyblock.contents = (unsigned char *) discard_const("1"); test_creds.times.authtime = 1111; test_creds.times.starttime = 2222; test_creds.times.endtime = 3333; test_creds.times.renew_till = 4444; test_creds.is_skey = 1; test_creds.ticket_flags = 5555; test_creds.addresses = addrs; test_creds.ticket.magic = KV5M_DATA; test_creds.ticket.length = sizeof("Ticket"); test_creds.ticket.data = discard_const("Ticket"); test_creds.authdata = malloc (2 * sizeof(krb5_authdata *)); assert_non_null(test_creds.authdata); a = (krb5_authdata *) malloc(sizeof(krb5_authdata)); assert_non_null(a); a->magic = KV5M_AUTHDATA; a->ad_type = KRB5_AUTHDATA_IF_RELEVANT; a->contents = (krb5_octet * ) malloc(1); assert_non_null(a->contents); a->contents[0]=5; a->length = 1; test_creds.authdata[0] = a; test_creds.authdata[1] = NULL; test_ctx->ccache_file_name = "FILE:" CCACHE_PATH; kerr = krb5_cc_resolve(test_ctx->kctx, test_ctx->ccache_file_name, &ccache); assert_int_equal(kerr, 0); kerr = krb5_cc_initialize(test_ctx->kctx, ccache, test_creds.client); assert_int_equal(kerr, 0); kerr = krb5_cc_store_cred(test_ctx->kctx, ccache, &test_creds); assert_int_equal(kerr, 0); kerr = krb5_cc_close(test_ctx->kctx, ccache); assert_int_equal(kerr, 0); check_leaks_push(test_ctx); *state = test_ctx; krb5_free_authdata(test_ctx->kctx, test_creds.authdata); return 0; } static int teardown_ccache(void **state) { int ret; struct ccache_test_ctx *test_ctx = talloc_get_type(*state, struct ccache_test_ctx); assert_non_null(test_ctx); krb5_free_principal(test_ctx->kctx, test_ctx->client_principal); krb5_free_principal(test_ctx->kctx, test_ctx->server_principal); krb5_free_context(test_ctx->kctx); ret = unlink(CCACHE_PATH); assert_int_equal(ret, 0); assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } void test_copy_ccache(void **state) { krb5_error_code kerr; char *mem_ccache_name; krb5_ccache ccache; krb5_creds mcreds; krb5_creds creds; krb5_principal mem_principal; struct ccache_test_ctx *test_ctx = talloc_get_type(*state, struct ccache_test_ctx); assert_non_null(test_ctx); kerr = copy_ccache_into_memory(test_ctx, test_ctx->kctx, test_ctx->ccache_file_name, &mem_ccache_name); assert_int_equal(kerr, 0); assert_non_null(mem_ccache_name); kerr = krb5_cc_resolve(test_ctx->kctx, mem_ccache_name, &ccache); assert_int_equal(kerr, 0); talloc_free(mem_ccache_name); kerr = krb5_cc_get_principal(test_ctx->kctx, ccache, &mem_principal); assert_int_equal(kerr, 0); assert_non_null(mem_principal); assert_true(krb5_principal_compare(test_ctx->kctx, mem_principal, test_ctx->client_principal)); krb5_free_principal(test_ctx->kctx, mem_principal); memset(&mcreds, 0, sizeof(mcreds)); memset(&creds, 0, sizeof(mcreds)); mcreds.client = test_ctx->client_principal; mcreds.server = test_ctx->server_principal; kerr = krb5_cc_retrieve_cred(test_ctx->kctx, ccache, 0, &mcreds, &creds); assert_int_equal(kerr, 0); krb5_free_cred_contents(test_ctx->kctx, &creds); kerr = krb5_cc_destroy(test_ctx->kctx, ccache); assert_int_equal(kerr, 0); } int main(int argc, const char *argv[]) { poptContext pc; int opt; int rv; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_copy_ccache, setup_ccache, teardown_ccache), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); rv = cmocka_run_group_tests(tests, NULL, NULL); return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_fo_srv.c0000644000000000000000000000007412703456111020214 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.036794924 sssd-1.13.4/src/tests/cmocka/test_fo_srv.c0000644002412700241270000005261712703456111021676 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat SSSD tests: Resolver tests using a fake resolver library This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include "providers/fail_over_srv.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #define TEST_RESOLV_TIMEOUT 5 #define TEST_FO_TIMEOUT 3000 #define TEST_SRV_TTL 500 #define TEST_SRV_SHORT_TTL 2 static TALLOC_CTX *global_mock_context = NULL; enum host_database default_host_dbs[] = { DB_FILES, DB_DNS, DB_SENTINEL }; struct resolv_ctx { int foo; }; /* mock resolver interface. The resolver test is separate */ int resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, int timeout, struct resolv_ctx **ctxp) { *ctxp = talloc(mem_ctx, struct resolv_ctx); return EOK; } struct tevent_req * resolv_gethostbyname_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *ctx, const char *name, enum restrict_family family_order, enum host_database *db) { return test_req_succeed_send(mem_ctx, ev); } int resolv_gethostbyname_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, int *status, int *timeouts, struct resolv_hostent **rhostent) { return test_request_recv(req); } const char *resolv_strerror(int ares_code) { return NULL; } struct tevent_req *resolv_discover_srv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv_ctx, const char *service, const char *protocol, const char **discovery_domains) { return test_req_succeed_send(mem_ctx, ev); } errno_t resolv_discover_srv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ares_srv_reply **_reply_list, uint32_t *_ttl, char **_dns_domain) { struct ares_srv_reply *reply_list; uint32_t ttl; char *dns_domain; /* Need to always consume all mocked values */ reply_list = sss_mock_ptr_type(struct ares_srv_reply *); ttl = sss_mock_ptr_type(uint32_t); dns_domain = sss_mock_ptr_type(char *); if (_reply_list != NULL) { *_reply_list = reply_list; } if (_ttl != NULL) { *_ttl = ttl; } if (_dns_domain != NULL) { *_dns_domain = dns_domain; } return test_request_recv(req); } struct ares_srv_reply *pop_lowest_prio(struct ares_srv_reply **r) { struct ares_srv_reply *lowest; struct ares_srv_reply *iter; struct ares_srv_reply *prev; lowest = *r; iter = lowest; while (iter != NULL) { if (iter->priority < lowest->priority) { lowest = iter; } iter = iter->next; } prev = NULL; iter = *r; while (iter != lowest) { prev = iter; iter = iter->next; } /* iter points to the lowest prio. Prev points to the item before */ if (prev) { prev->next = lowest->next; } else { *r = lowest->next; } return lowest; } int resolv_sort_srv_reply(struct ares_srv_reply **reply) { struct ares_srv_reply *r; struct ares_srv_reply *lowest; struct ares_srv_reply *sorted = NULL; struct ares_srv_reply *sorted_head = NULL; r = *reply; if (r == NULL || r->next == NULL) { return EOK; } do { lowest = pop_lowest_prio(&r); if (sorted) { sorted->next = lowest; sorted = sorted->next; } else { sorted = lowest; sorted_head = sorted; } } while (r != NULL); *reply = sorted_head; return EOK; } struct tevent_req *resolv_get_domain_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resolv_ctx *resolv_ctx, const char *hostname, enum host_database *host_dbs, enum restrict_family family_order) { return test_req_succeed_send(mem_ctx, ev); } errno_t resolv_get_domain_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, char **_dns_domain) { return test_request_recv(req); } /* The unit test */ struct test_fo_ctx { struct resolv_ctx *resolv; struct fo_ctx *fo_ctx; struct fo_resolve_srv_dns_ctx *srv_ctx; struct fo_service *fo_svc; struct sss_test_ctx *ctx; int ttl; struct fo_server *srv; }; int test_fo_srv_data_cmp(void *ud1, void *ud2) { return strcasecmp((char*) ud1, (char*) ud2); } static int test_fo_setup(void **state) { struct test_fo_ctx *test_ctx; errno_t ret; struct fo_options fopts; assert_true(leak_check_setup()); global_mock_context = talloc_new(global_talloc_context); assert_non_null(global_mock_context); test_ctx = talloc_zero(global_mock_context, struct test_fo_ctx); assert_non_null(test_ctx); test_ctx->ctx = create_ev_test_ctx(test_ctx); assert_non_null(test_ctx->ctx); ret = resolv_init(test_ctx, test_ctx->ctx->ev, TEST_RESOLV_TIMEOUT, &test_ctx->resolv); assert_non_null(test_ctx->resolv); memset(&fopts, 0, sizeof(fopts)); fopts.retry_timeout = TEST_FO_TIMEOUT; fopts.family_order = IPV4_FIRST; test_ctx->fo_ctx = fo_context_init(test_ctx, &fopts); assert_non_null(test_ctx->fo_ctx); ret = fo_new_service(test_ctx->fo_ctx, "ldap", test_fo_srv_data_cmp, &test_ctx->fo_svc); assert_int_equal(ret, ERR_OK); *state = test_ctx; return 0; } static int test_fo_teardown(void **state) { struct test_fo_ctx *test_ctx = talloc_get_type(*state, struct test_fo_ctx); talloc_free(test_ctx); talloc_free(global_mock_context); assert_true(leak_check_teardown()); return 0; } static int test_fo_srv_setup(void **state) { struct test_fo_ctx *test_ctx; bool ok; test_fo_setup(state); test_ctx = *state; test_ctx->srv_ctx = fo_resolve_srv_dns_ctx_init(test_ctx, test_ctx->resolv, IPV4_FIRST, default_host_dbs, "client.sssd.com", "sssd.local"); assert_non_null(test_ctx->srv_ctx); ok = fo_set_srv_lookup_plugin(test_ctx->fo_ctx, fo_resolve_srv_dns_send, fo_resolve_srv_dns_recv, test_ctx->srv_ctx); assert_true(ok); *state = test_ctx; return 0; } static int test_fo_srv_teardown(void **state) { test_fo_teardown(state); return 0; } /* reply_list and dns_domain must be a talloc context so it can be used as * talloc_steal argument later */ static void mock_srv_results(struct ares_srv_reply *reply_list, uint32_t ttl, char *dns_domain) { will_return(resolv_discover_srv_recv, reply_list); will_return(resolv_discover_srv_recv, ttl); will_return(resolv_discover_srv_recv, dns_domain); } static void check_server(struct test_fo_ctx *ctx, struct fo_server *srv, int port, const char *name) { assert_non_null(srv); assert_int_equal(fo_get_server_port(srv), port); assert_string_equal(fo_get_server_name(srv), name); if (ctx->srv_ctx) { assert_true(fo_is_srv_lookup(srv)); } } static void test_fo_srv_step1(struct test_fo_ctx *test_ctx); static void test_fo_srv_done1(struct tevent_req *req); static void test_fo_srv_done2(struct tevent_req *req); static void test_fo_srv_done3(struct tevent_req *req); static void test_fo_srv_done4(struct tevent_req *req); static void test_fo_srv_done5(struct tevent_req *req); struct ares_srv_reply * mock_ares_reply(TALLOC_CTX *mem_ctx, const char *hostname, int weight, int priority, int port) { struct ares_srv_reply *s; s = talloc_zero(mem_ctx, struct ares_srv_reply); if (s == NULL) { return NULL; } s->host = talloc_strdup(s, hostname); if (s->host == NULL) { talloc_free(s); return NULL; } s->weight = weight; s->priority = priority; s->port = port; return s; } static void test_fo_srv_mock_dns(struct test_fo_ctx *test_ctx, int ttl) { struct ares_srv_reply *s1; struct ares_srv_reply *s2; char *dns_domain; s1 = mock_ares_reply(test_ctx, "ldap1.sssd.com", 100, 1, 389); assert_non_null(s1); s2 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 2, 389); assert_non_null(s2); s1->next = s2; dns_domain = talloc_strdup(test_ctx, "sssd.com"); assert_non_null(dns_domain); mock_srv_results(s1, ttl, dns_domain); } static void test_fo_srv(void **state) { errno_t ret; struct test_fo_ctx *test_ctx = talloc_get_type(*state, struct test_fo_ctx); test_fo_srv_mock_dns(test_ctx, TEST_SRV_TTL); ret = fo_add_srv_server(test_ctx->fo_svc, "_ldap", "sssd.com", "sssd.local", "tcp", test_ctx); assert_int_equal(ret, ERR_OK); test_fo_srv_step1(test_ctx); ret = test_ev_loop(test_ctx->ctx); assert_int_equal(ret, ERR_OK); } static void test_fo_srv_step1(struct test_fo_ctx *test_ctx) { struct tevent_req *req; req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, test_ctx->resolv, test_ctx->fo_ctx, test_ctx->fo_svc); assert_non_null(req); tevent_req_set_callback(req, test_fo_srv_done1, test_ctx); } static void test_fo_srv_done1(struct tevent_req *req) { struct test_fo_ctx *test_ctx = \ tevent_req_callback_data(req, struct test_fo_ctx); struct fo_server *srv; errno_t ret; ret = fo_resolve_service_recv(req, req, &srv); talloc_zfree(req); assert_int_equal(ret, ERR_OK); /* ldap1.sssd.com has lower priority, it must always be first */ check_server(test_ctx, srv, 389, "ldap1.sssd.com"); /* Mark the server as working and request the service again. The same server * must be returned */ fo_set_server_status(srv, SERVER_WORKING); req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, test_ctx->resolv, test_ctx->fo_ctx, test_ctx->fo_svc); assert_non_null(req); tevent_req_set_callback(req, test_fo_srv_done2, test_ctx); } static void test_fo_srv_done2(struct tevent_req *req) { struct test_fo_ctx *test_ctx = \ tevent_req_callback_data(req, struct test_fo_ctx); struct fo_server *srv; errno_t ret; ret = fo_resolve_service_recv(req, req, &srv); talloc_zfree(req); assert_int_equal(ret, ERR_OK); /* Must be ldap1 again */ check_server(test_ctx, srv, 389, "ldap1.sssd.com"); /* Mark it at wrong, next lookup should yield ldap2 */ fo_set_server_status(srv, SERVER_NOT_WORKING); req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, test_ctx->resolv, test_ctx->fo_ctx, test_ctx->fo_svc); assert_non_null(req); tevent_req_set_callback(req, test_fo_srv_done3, test_ctx); } static void test_fo_srv_done3(struct tevent_req *req) { struct test_fo_ctx *test_ctx = \ tevent_req_callback_data(req, struct test_fo_ctx); struct fo_server *srv; errno_t ret; ret = fo_resolve_service_recv(req, req, &srv); talloc_zfree(req); assert_int_equal(ret, ERR_OK); /* Must be ldap2 now */ check_server(test_ctx, srv, 389, "ldap2.sssd.com"); /* Mark is at wrong, next lookup must reach the end of the server list */ fo_set_server_status(srv, SERVER_NOT_WORKING); req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, test_ctx->resolv, test_ctx->fo_ctx, test_ctx->fo_svc); assert_non_null(req); tevent_req_set_callback(req, test_fo_srv_done4, test_ctx); } static void test_fo_srv_done4(struct tevent_req *req) { struct test_fo_ctx *test_ctx = \ tevent_req_callback_data(req, struct test_fo_ctx); struct fo_server *srv; errno_t ret; ret = fo_resolve_service_recv(req, req, &srv); talloc_zfree(req); /* No servers are left..*/ assert_int_equal(ret, ENOENT); /* reset the server status and try again.. */ fo_reset_servers(test_ctx->fo_svc); if (test_ctx->srv_ctx) { test_fo_srv_mock_dns(test_ctx, TEST_SRV_TTL); } req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, test_ctx->resolv, test_ctx->fo_ctx, test_ctx->fo_svc); assert_non_null(req); tevent_req_set_callback(req, test_fo_srv_done5, test_ctx); } static void test_fo_srv_done5(struct tevent_req *req) { struct test_fo_ctx *test_ctx = \ tevent_req_callback_data(req, struct test_fo_ctx); struct fo_server *srv; errno_t ret; ret = fo_resolve_service_recv(req, req, &srv); talloc_zfree(req); assert_int_equal(ret, ERR_OK); /* ldap1.sssd.com has lower priority, it must always be first */ check_server(test_ctx, srv, 389, "ldap1.sssd.com"); /* OK, we made a full circle with the test, done */ test_ctx->ctx->error = ERR_OK; test_ctx->ctx->done = true; } /* Make sure that two queries more than TTL seconds apart resolve * into two different lists */ static void test_fo_srv_ttl_change_step(struct test_fo_ctx *test_ctx); static void test_fo_srv_before(struct tevent_req *req); static void test_fo_srv_after(struct tevent_req *req); void test_fo_srv_ttl_change(void **state) { struct test_fo_ctx *test_ctx = talloc_get_type(*state, struct test_fo_ctx); test_ctx->ttl = TEST_SRV_SHORT_TTL; test_fo_srv_ttl_change_step(test_ctx); } static void test_fo_srv_ttl_change_step(struct test_fo_ctx *test_ctx) { errno_t ret; struct tevent_req *req; test_fo_srv_mock_dns(test_ctx, test_ctx->ttl); ret = fo_add_srv_server(test_ctx->fo_svc, "_ldap", "sssd.com", "sssd.local", "tcp", test_ctx); assert_int_equal(ret, ERR_OK); ret = fo_add_server(test_ctx->fo_svc, "ldap1.sssd.com", 389, (void *) discard_const("ldap://ldap1.sssd.com"), true); assert_int_equal(ret, ERR_OK); req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, test_ctx->resolv, test_ctx->fo_ctx, test_ctx->fo_svc); assert_non_null(req); tevent_req_set_callback(req, test_fo_srv_before, test_ctx); ret = test_ev_loop(test_ctx->ctx); assert_int_equal(ret, ERR_OK); } static void test_fo_srv_before(struct tevent_req *req) { struct test_fo_ctx *test_ctx = \ tevent_req_callback_data(req, struct test_fo_ctx); struct ares_srv_reply *s1; struct ares_srv_reply *s2; char *dns_domain; errno_t ret; ret = fo_resolve_service_recv(req, test_ctx, &test_ctx->srv); talloc_zfree(req); assert_int_equal(ret, ERR_OK); DEBUG(SSSDBG_TRACE_FUNC, "Before TTL change\n"); check_server(test_ctx, test_ctx->srv, 389, "ldap1.sssd.com"); fo_set_server_status(test_ctx->srv, SERVER_WORKING); /* Simulate changing the DNS environment. Change the host names */ s1 = mock_ares_reply(test_ctx, "ldap1.sssd.com", 100, 2, 389); assert_non_null(s1); s2 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 1, 389); assert_non_null(s2); s1->next = s2; dns_domain = talloc_strdup(test_ctx, "sssd.com"); assert_non_null(dns_domain); mock_srv_results(s1, test_ctx->ttl, dns_domain); sleep(test_ctx->ttl + 1); req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, test_ctx->resolv, test_ctx->fo_ctx, test_ctx->fo_svc); assert_non_null(req); tevent_req_set_callback(req, test_fo_srv_after, test_ctx); } static void test_fo_srv_after2(struct tevent_req *req); static void test_fo_srv_after(struct tevent_req *req) { struct test_fo_ctx *test_ctx = \ tevent_req_callback_data(req, struct test_fo_ctx); struct fo_server *srv; errno_t ret; struct ares_srv_reply *s1; struct ares_srv_reply *s2; char *dns_domain; ret = fo_resolve_service_recv(req, req, &srv); talloc_zfree(req); assert_int_equal(ret, ERR_OK); /* Try accessing server from a previous iteration. The * server should be collapsed, but at least we shouldn't crash */ fo_set_server_status(test_ctx->srv, SERVER_WORKING); sleep(test_ctx->ttl + 1); /* Must be a different server now */ check_server(test_ctx, srv, 389, "ldap2.sssd.com"); /* Simulate changing the DNS environment. Change the host names */ s1 = mock_ares_reply(test_ctx, "ldap1.sssd.com", 100, 1, 389); assert_non_null(s1); s2 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 2, 389); assert_non_null(s2); s1->next = s2; dns_domain = talloc_strdup(test_ctx, "sssd.com"); assert_non_null(dns_domain); mock_srv_results(s1, test_ctx->ttl, dns_domain); sleep(test_ctx->ttl + 1); req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev, test_ctx->resolv, test_ctx->fo_ctx, test_ctx->fo_svc); assert_non_null(req); tevent_req_set_callback(req, test_fo_srv_after2, test_ctx); } static void test_fo_srv_after2(struct tevent_req *req) { struct test_fo_ctx *test_ctx = \ tevent_req_callback_data(req, struct test_fo_ctx); struct fo_server *srv; errno_t ret; ret = fo_resolve_service_recv(req, req, &srv); talloc_zfree(req); assert_int_equal(ret, ERR_OK); /* Must be a different server now */ check_server(test_ctx, srv, 389, "ldap1.sssd.com"); test_ctx->ctx->error = ERR_OK; test_ctx->ctx->done = true; } void test_fo_srv_ttl_zero(void **state) { struct test_fo_ctx *test_ctx = talloc_get_type(*state, struct test_fo_ctx); test_ctx->ttl = 0; test_fo_srv_ttl_change_step(test_ctx); } static void test_fo_hostlist(void **state) { errno_t ret; struct test_fo_ctx *test_ctx = talloc_get_type(*state, struct test_fo_ctx); ret = fo_add_server(test_ctx->fo_svc, "ldap1.sssd.com", 389, test_ctx, true); assert_int_equal(ret, ERR_OK); ret = fo_add_server(test_ctx->fo_svc, "ldap2.sssd.com", 389, test_ctx, true); assert_int_equal(ret, ERR_OK); test_fo_srv_step1(test_ctx); ret = test_ev_loop(test_ctx->ctx); assert_int_equal(ret, ERR_OK); } int main(int argc, const char *argv[]) { int rv; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_fo_hostlist, test_fo_setup, test_fo_teardown), cmocka_unit_test_setup_teardown(test_fo_srv, test_fo_srv_setup, test_fo_srv_teardown), cmocka_unit_test_setup_teardown(test_fo_srv_ttl_change, test_fo_srv_setup, test_fo_srv_teardown), cmocka_unit_test_setup_teardown(test_fo_srv_ttl_zero, test_fo_srv_setup, test_fo_srv_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); rv = cmocka_run_group_tests(tests, NULL, NULL); return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_negcache.c0000644000000000000000000000007212703456111020451 xustar0030 atime=1460561751.656715648 28 ctime=1460561775.0297949 sssd-1.13.4/src/tests/cmocka/test_negcache.c0000644002412700241270000006626712703456111022143 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Responder Authors: Pallavi Jha Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #include "responder/nss/nsssrv.h" #include "responder/nss/nsssrv_private.h" #include "sss_client/idmap/sss_nss_idmap.h" #include "util/util_sss_idmap.h" #include "lib/idmap/sss_idmap.h" #include "util/util.h" #include "util/util_sss_idmap.h" #include "responder/common/responder.h" #include "responder/common/negcache.h" #define PORT 21 #define SID "S-1-2-3-4-5" #define CERT "MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEuREVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA0MjgxMDIxMTFaFw0xNzA0MjgxMDIxMTFaMDIxEjAQBgNVBAoMCUlQQS5ERVZFTDEcMBoGA1UEAwwTaXBhLWRldmVsLmlwYS5kZXZlbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALIykqtHuAwTVEofHikG/9BQy/dfeZFlsTkBg2qtnnc78w3XufbcnkpJp9Bmcsy/d9beqf5nlsxJ8TcjLsRQ9Ou6YtQjTfM3OILuOz8s0ICbF6qb66bd9hX/BrLO/9+KnpWFSR+E/YEmzgYyDTbKfBWBaGuPPrOi/K6vwkRYFZVA/FYZkYDtQhFmBO884HYzS4P6frRH3PvtRqWNCmaHpe97dGKsvnM2ybT+IMSB8/54GajQr3+BciRh2XaT4wvSTxkXM1fUgrDxqAP2AZmpuIyDyboZh+rWOwbrTPfx5SipELZG3uHhP8HMcr4qQ8b20LWgxCRuT73sIooHET350xUCAwEAAaOCASYwggEiMB8GA1UdIwQYMBaAFPKdQk4PxEglWC8czg+hPyLIVciRMDsGCCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL2lwYS1jYS5pcGEuZGV2ZWwvY2Evb2NzcDAOBgNVHQ8BAf8EBAMCBPAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHQGA1UdHwRtMGswaaAxoC+GLWh0dHA6Ly9pcGEtY2EuaXBhLmRldmVsL2lwYS9jcmwvTWFzdGVyQ1JMLmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAdBgNVHQ4EFgQULSs/y/Wy/zIsqMIc3b2MgB7dMYIwDQYJKoZIhvcNAQELBQADggEBAJpHLlCnTR1TD8lxQgzl2n1JZOeryN/fAsGH0Vve2m8r5PC+ugnfAoULiuabBn1pOGxy/0x7Kg0/Iy8WRv8Fk7DqJCjXEqFXuFkZJfNDCtP9DzeNuMoV50iKoMfHS38BPFjXN+X/fSsBrA2fUWrlQCTmXlUN97gvQqxt5Slrxgukvxm9OSfu/sWz22LUvtJHupYwWv1iALgnXS86lAuVNYVALLxn34r58XsZlj5CSBMjBJWpaxEzgUdag3L2IPqOQXuPd0d8x11G9E/9gQquOSe2aiZjsdO/VYOCmzZsM2QPUMBVlBPDhfTVcWXQwN385uycW/ARtSzzSME2jKKWSIQ=" #define PROTO "TCP" #define LIFETIME 200 #define SHORTSPAN 1 #define NAME "foo_name" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_nss_conf.ldb" #define TEST_DOM_NAME "nss_test" #define TEST_ID_PROVIDER "ldap" /* register_cli_protocol_version is required in test since it links with * responder_common.c module */ struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version responder_test_cli_protocol_version[] = { {0, NULL, NULL} }; return responder_test_cli_protocol_version; } /* Mock NSS structure */ static struct nss_ctx * mock_nctx(TALLOC_CTX *mem_ctx) { struct nss_ctx *nctx; errno_t ret; enum idmap_error_code err; nctx = talloc_zero(mem_ctx, struct nss_ctx); if (!nctx) { return NULL; } ret = sss_ncache_init(nctx, &nctx->ncache); if (ret != EOK) { talloc_free(nctx); return NULL; } nctx->neg_timeout = 10; nctx->pwfield = discard_const("*"); err = sss_idmap_init(sss_idmap_talloc, nctx, sss_idmap_talloc_free, &nctx->idmap_ctx); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, ("sss_idmap_init failed.\n")); talloc_free(nctx); return NULL; } return nctx; } /* responder context is duplicated here because linking * with common_mock_resp.c would get us duplicates */ struct resp_ctx * mock_rctx(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sss_domain_info *domains, void *pvt_ctx) { struct resp_ctx *rctx; errno_t ret; rctx = talloc_zero(mem_ctx, struct resp_ctx); if (!rctx) return NULL; ret = sss_hash_create(rctx, 30, &rctx->dp_request_table); if (ret != EOK) { talloc_free(rctx); return NULL; } rctx->ev = ev; rctx->domains = domains; rctx->pvt_ctx = pvt_ctx; return rctx; } struct test_state { struct sss_nc_ctx *ctx; struct nss_ctx *nctx; struct resp_ctx *rctx; }; static int setup(void **state) { int ret; struct test_state *ts; ts = talloc(NULL, struct test_state); assert_non_null(ts); ret = sss_ncache_init(ts, &ts->ctx); assert_int_equal(ret, EOK); assert_non_null(ts->ctx); *state = (void *)ts; return 0; } static int teardown(void **state) { struct test_state *ts = talloc_get_type_abort(*state, struct test_state); talloc_free(ts); return 0; } static void test_sss_ncache_init(void **state) { int ret; TALLOC_CTX *memctx; struct sss_nc_ctx *ctx; memctx = talloc_new(NULL); assert_non_null(memctx); ret = sss_ncache_init(memctx, &ctx ); assert_int_equal(ret, EOK); assert_non_null(ctx); talloc_free(memctx); } /* @test_sss_ncache_uid : test following functions * sss_ncache_set_uid * sss_ncache_check_uid */ static void test_sss_ncache_uid(void **state) { uid_t uid; int ret, ttl; bool permanent; struct test_state *ts; ttl = LIFETIME; uid = getuid(); ts = talloc_get_type_abort(*state, struct test_state); /* test when uid not present in database */ ret = sss_ncache_check_uid(ts->ctx, ttl, NULL, uid); assert_int_equal(ret, ENOENT); /* test when uid is present in database */ permanent = true; ret = sss_ncache_reset_permanent(ts->ctx); assert_int_equal(ret, EOK); ret = sss_ncache_set_uid(ts->ctx, permanent, NULL, uid); assert_int_equal(ret, EOK); ret = sss_ncache_check_uid(ts->ctx, ttl, NULL, uid); assert_int_equal(ret, EEXIST); ttl = SHORTSPAN; ret = sss_ncache_set_uid(ts->ctx, permanent, NULL, uid); assert_int_equal(ret, EOK); ret = sss_ncache_check_uid(ts->ctx, ttl, NULL, uid); assert_int_equal(ret, EEXIST); sleep(SHORTSPAN + 1); ret = sss_ncache_check_uid(ts->ctx, ttl, NULL, uid); assert_int_equal(ret, EEXIST); permanent = false; ret = sss_ncache_set_uid(ts->ctx, permanent, NULL, uid); assert_int_equal(ret, EOK); ret = sss_ncache_check_uid(ts->ctx, ttl, NULL, uid); assert_int_equal(ret, EEXIST); sleep(SHORTSPAN + 1); ret = sss_ncache_check_uid(ts->ctx, ttl, NULL, uid); assert_int_equal(ret, ENOENT); ret = sss_ncache_set_uid(ts->ctx, permanent, NULL, uid); assert_int_equal(ret, EOK); /* test when ttl is -1 with uid present in database*/ ttl = -1; ret = sss_ncache_check_uid(ts->ctx, ttl, NULL, uid); assert_int_equal(ret, EEXIST); } /* @test_sss_ncache_gid : test following functions * sss_ncache_set_gid * sss_ncache_check_gid */ static void test_sss_ncache_gid(void **state) { gid_t gid; int ret, ttl; bool permanent; struct test_state *ts; ttl = LIFETIME; gid = getgid(); ts = talloc_get_type_abort(*state, struct test_state); /* test when gid is not present in database */ ret = sss_ncache_check_gid(ts->ctx, ttl, NULL, gid); assert_int_equal(ret, ENOENT); /* test when gid is present in database */ permanent = true; ret = sss_ncache_set_gid(ts->ctx, permanent, NULL, gid); assert_int_equal(ret, EOK); ret = sss_ncache_check_gid(ts->ctx, ttl, NULL, gid); assert_int_equal(ret, EEXIST); permanent = false; ret = sss_ncache_set_uid(ts->ctx, permanent, NULL, gid); assert_int_equal(ret, EOK); ret = sss_ncache_check_uid(ts->ctx, ttl, NULL, gid); assert_int_equal(ret, EEXIST); /* test when ttl is -1 with gid present in database*/ ttl = -1; ret = sss_ncache_check_gid(ts->ctx, ttl, NULL, gid); assert_int_equal(ret, EEXIST); } /* @test_sss_ncache_sid : test following functions * sss_ncache_set_sid * sss_ncache_check_sid */ static void test_sss_ncache_sid(void **state) { int ret, ttl; bool permanent; const char *sid = NULL; struct test_state *ts; ttl = LIFETIME; sid = SID; ts = talloc_get_type_abort(*state, struct test_state); /*test when sid in not present in database */ ret = sss_ncache_check_sid(ts->ctx, ttl, sid); assert_int_equal(ret, ENOENT); /* test when sid is present in database */ permanent = true; ret = sss_ncache_set_sid(ts->ctx, permanent, sid); assert_int_equal(ret, EOK); ret = sss_ncache_check_sid(ts->ctx, ttl, sid); assert_int_equal(ret, EEXIST); permanent = false; ret = sss_ncache_set_sid(ts->ctx, permanent, sid); assert_int_equal(ret, EOK); ret = sss_ncache_check_sid(ts->ctx, ttl, sid); assert_int_equal(ret, EEXIST); /* test when ttl is -1 with sid present in database*/ ttl = -1; ret = sss_ncache_check_sid(ts->ctx, ttl, sid); assert_int_equal(ret, EEXIST); } /* @test_sss_ncache_cert : test following functions * sss_ncache_set_cert * sss_ncache_check_cert_ */ static void test_sss_ncache_cert(void **state) { int ret, ttl; bool permanent; const char *cert = NULL; struct test_state *ts; ttl = LIFETIME; cert = CERT; ts = talloc_get_type_abort(*state, struct test_state); /*test when cert in not present in database */ ret = sss_ncache_check_cert(ts->ctx, ttl, cert); assert_int_equal(ret, ENOENT); /* test when cert is present in database */ permanent = true; ret = sss_ncache_set_cert(ts->ctx, permanent, cert); assert_int_equal(ret, EOK); ret = sss_ncache_check_cert(ts->ctx, ttl, cert); assert_int_equal(ret, EEXIST); permanent = false; ret = sss_ncache_set_cert(ts->ctx, permanent, cert); assert_int_equal(ret, EOK); ret = sss_ncache_check_cert(ts->ctx, ttl, cert); assert_int_equal(ret, EEXIST); /* test when ttl is -1 with cert present in database*/ ttl = -1; ret = sss_ncache_check_cert(ts->ctx, ttl, cert); assert_int_equal(ret, EEXIST); } /* @test_sss_ncache_user : test following functions * sss_ncache_check_user * sss_ncache_set_user */ static void test_sss_ncache_user(void **state) { int ret, ttl; bool permanent; const char *name = NAME; struct test_state *ts; struct sss_domain_info *dom; ttl = LIFETIME; ts = talloc_get_type_abort(*state, struct test_state); dom = talloc(ts, struct sss_domain_info); dom->name = discard_const_p(char, TEST_DOM_NAME); /* test when domain name is not present in database */ dom->case_sensitive = false; ret = sss_ncache_check_user(ts->ctx, ttl, dom, name); assert_int_equal(ret, ENOENT); dom->case_sensitive = true; ret = sss_ncache_check_user(ts->ctx, ttl, dom, name); assert_int_equal(ret, ENOENT); /* test when domain name is present in database */ permanent = true; ret = sss_ncache_set_user(ts->ctx, permanent, dom, name); assert_int_equal(ret, EOK); ret = sss_ncache_check_user(ts->ctx, ttl, dom, name); assert_int_equal(ret, EEXIST); permanent = false; ret = sss_ncache_set_user(ts->ctx, permanent, dom, name); assert_int_equal(ret, EOK); ret = sss_ncache_check_user(ts->ctx, ttl, dom, name); assert_int_equal(ret, EEXIST); /* test when ttl is -1 with domain name present in database */ ttl = -1; ret = sss_ncache_check_user(ts->ctx, ttl, dom, name); assert_int_equal(ret, EEXIST); } /* @test_sss_ncache_group : test following functions * sss_ncache_check_group * sss_ncache_set_group */ static void test_sss_ncache_group(void **state) { int ret, ttl; bool permanent; const char *name = NAME; struct test_state *ts; struct sss_domain_info *dom; ttl = LIFETIME; ts = talloc_get_type_abort(*state, struct test_state); dom = talloc(ts, struct sss_domain_info); dom->name = discard_const_p(char, TEST_DOM_NAME); /* test when domain name is not present in database */ dom->case_sensitive = false; ret = sss_ncache_check_group(ts->ctx, ttl, dom, name); assert_int_equal(ret, ENOENT); dom->case_sensitive = true; ret = sss_ncache_check_group(ts->ctx, ttl, dom, name); assert_int_equal(ret, ENOENT); /* test when domain name is present in database */ permanent = true; ret = sss_ncache_set_group(ts->ctx, permanent, dom, name); assert_int_equal(ret, EOK); ret = sss_ncache_check_group(ts->ctx, ttl, dom, name); assert_int_equal(ret, EEXIST); permanent = false; ret = sss_ncache_set_group(ts->ctx, permanent, dom, name); assert_int_equal(ret, EOK); ret = sss_ncache_check_group(ts->ctx, ttl, dom, name); assert_int_equal(ret, EEXIST); /* test when ttl is -1 with domain name present in database */ ttl = -1; ret = sss_ncache_check_group(ts->ctx, ttl, dom, name); assert_int_equal(ret, EEXIST); } /* @test_sss_ncache_netgr : test following functions * sss_ncache_check_netgr * sss_ncache_set_netgr */ static void test_sss_ncache_netgr(void **state) { int ret, ttl; bool permanent; const char *name = NAME; struct test_state *ts; struct sss_domain_info *dom; ttl = LIFETIME; ts = talloc_get_type_abort(*state, struct test_state); dom = talloc(ts, struct sss_domain_info); dom->name = discard_const_p(char, TEST_DOM_NAME); /* test when domain name is not present in database */ dom->case_sensitive = false; ret = sss_ncache_check_netgr(ts->ctx, ttl, dom, name); assert_int_equal(ret, ENOENT); dom->case_sensitive = true; ret = sss_ncache_check_netgr(ts->ctx, ttl, dom, name); assert_int_equal(ret, ENOENT); /* test when domain name is present in database */ permanent = true; ret = sss_ncache_set_netgr(ts->ctx, permanent, dom, name); assert_int_equal(ret, EOK); ret = sss_ncache_check_netgr(ts->ctx, ttl, dom, name); assert_int_equal(ret, EEXIST); permanent = false; ret = sss_ncache_set_netgr(ts->ctx, permanent, dom, name); assert_int_equal(ret, EOK); ret = sss_ncache_check_netgr(ts->ctx, ttl, dom, name); assert_int_equal(ret, EEXIST); /* test when ttl is -1 with domain name present in database */ ttl = -1; ret = sss_ncache_check_netgr(ts->ctx, ttl, dom, name); assert_int_equal(ret, EEXIST); } /* @test_sss_ncache_service_name : test following functions * sss_ncache_check_service * sss_ncache_set_service_name */ static void test_sss_ncache_service_name(void **state) { int ret, ttl; bool permanent; const char *name = NAME; struct test_state *ts; struct sss_domain_info *dom; ttl = LIFETIME; ts = talloc_get_type_abort(*state, struct test_state); dom = talloc(ts, struct sss_domain_info); dom->name = discard_const_p(char, TEST_DOM_NAME); /* test when domain name and protocol are not present in database */ dom->case_sensitive = false; ret = sss_ncache_check_service(ts->ctx, ttl, dom, name, PROTO); assert_int_equal(ret, ENOENT); dom->case_sensitive = true; ret = sss_ncache_check_service(ts->ctx, ttl, dom, name, PROTO); assert_int_equal(ret, ENOENT); /* test when domain name and protocol are present in database */ permanent = true; ret = sss_ncache_set_service_name(ts->ctx, permanent, dom, name, PROTO); assert_int_equal(ret, EOK); ret = sss_ncache_check_service(ts->ctx, ttl, dom, name, PROTO); assert_int_equal(ret, EEXIST); permanent = false; ret = sss_ncache_set_service_name(ts->ctx, permanent, dom, name, PROTO); assert_int_equal(ret, EOK); ret = sss_ncache_check_service(ts->ctx, ttl, dom, name, PROTO); assert_int_equal(ret, EEXIST); /* test when ttl is -1 with domain name present in database */ ttl = -1; ret = sss_ncache_check_service(ts->ctx, ttl, dom, name, PROTO); assert_int_equal(ret, EEXIST); } /* @test_sss_ncache_service_port : test following functions * sss_ncache_check_service_port * sss_ncache_set_service_port */ static void test_sss_ncache_service_port(void **state) { int ret, ttl; bool permanent; struct test_state *ts; struct sss_domain_info *dom; ttl = LIFETIME; ts = talloc_get_type_abort(*state, struct test_state); dom = talloc(ts, struct sss_domain_info); dom->name = discard_const_p(char, TEST_DOM_NAME); /* test when domain name, port and protocol are not present in database */ dom->case_sensitive = false; ret = sss_ncache_check_service_port(ts->ctx, ttl, dom, (uint16_t)PORT, PROTO); assert_int_equal(ret, ENOENT); dom->case_sensitive = true; ret = sss_ncache_check_service_port(ts->ctx, ttl, dom, (uint16_t)PORT, PROTO); assert_int_equal(ret, ENOENT); /* test when domain name, port and protocol are present in database */ permanent = true; ret = sss_ncache_set_service_port(ts->ctx, permanent, dom, (uint16_t)PORT, PROTO); assert_int_equal(ret, EOK); ret = sss_ncache_check_service_port(ts->ctx, ttl, dom, (uint16_t)PORT, PROTO); assert_int_equal(ret, EEXIST); permanent = false; ret = sss_ncache_set_service_port(ts->ctx, permanent, dom, (uint16_t)PORT, PROTO); assert_int_equal(ret, EOK); ret = sss_ncache_check_service_port(ts->ctx, ttl, dom, (uint16_t)PORT, PROTO); assert_int_equal(ret, EEXIST); /* test when ttl is -1 with domain name present in database */ ttl = -1; ret = sss_ncache_check_service_port(ts->ctx, ttl, dom, (uint16_t)PORT, PROTO); assert_int_equal(ret, EEXIST); } static void test_sss_ncache_reset_permanent(void **state) { int ret; struct test_state *ts; const bool permanent = true; ts = talloc_get_type_abort(*state, struct test_state); ret = sss_ncache_set_uid(ts->ctx, permanent, NULL, 0); assert_int_equal(ret, EOK); ret = sss_ncache_check_uid(ts->ctx, 0, NULL, 0); assert_int_equal(ret, EEXIST); ret = sss_ncache_reset_permanent(ts->ctx); assert_int_equal(ret, EOK); ret = sss_ncache_check_uid(ts->ctx, 0, NULL, 0); assert_int_equal(ret, ENOENT); } static void test_sss_ncache_prepopulate(void **state) { int ret; struct test_state *ts; struct tevent_context *ev; struct sss_nc_ctx *ncache; struct sss_test_ctx *tc; struct sss_domain_info *dom; struct sss_test_conf_param params[] = { { "filter_users", "testuser1, testuser2@"TEST_DOM_NAME", testuser3@somedomain" }, { "filter_groups", "testgroup1, testgroup2@"TEST_DOM_NAME", testgroup3@somedomain" }, { NULL, NULL }, }; ts = talloc_get_type_abort(*state, struct test_state); ev = tevent_context_init(ts); assert_non_null(ev); dom = talloc_zero(ts, struct sss_domain_info); assert_non_null(dom); dom->name = discard_const_p(char, TEST_DOM_NAME); ts->nctx = mock_nctx(ts); assert_non_null(ts->nctx); tc = create_dom_test_ctx(ts, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, params); assert_non_null(tc); ncache = ts->ctx; ts->rctx = mock_rctx(ts, ev, dom, ts->nctx); assert_non_null(ts->rctx); ret = sss_names_init(ts, tc->confdb, TEST_DOM_NAME, &dom->names); assert_int_equal(ret, EOK); ret = sss_ncache_prepopulate(ncache, tc->confdb, ts->rctx); assert_int_equal(ret, EOK); sleep(SHORTSPAN); ret = sss_ncache_check_user(ncache, 1, dom, "testuser1"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_group(ncache, 1, dom, "testgroup1"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_user(ncache, 1, dom, "testuser2"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_group(ncache, 1, dom, "testgroup2"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_user(ncache, 1, dom, "testuser3"); assert_int_equal(ret, ENOENT); ret = sss_ncache_check_group(ncache, 1, dom, "testgroup3"); assert_int_equal(ret, ENOENT); ret = sss_ncache_check_user(ncache, 1, dom, "testuser3@somedomain"); assert_int_equal(ret, ENOENT); ret = sss_ncache_check_group(ncache, 1, dom, "testgroup3@somedomain"); assert_int_equal(ret, ENOENT); } static void test_sss_ncache_default_domain_suffix(void **state) { int ret; struct test_state *ts; struct tevent_context *ev; struct sss_nc_ctx *ncache; struct sss_test_ctx *tc; struct sss_domain_info *dom; struct sss_test_conf_param params[] = { { "filter_users", "testuser1, testuser2@"TEST_DOM_NAME", testuser3@somedomain" }, { "filter_groups", "testgroup1, testgroup2@"TEST_DOM_NAME", testgroup3@somedomain" }, { NULL, NULL }, }; ts = talloc_get_type_abort(*state, struct test_state); ev = tevent_context_init(ts); assert_non_null(ev); dom = talloc_zero(ts, struct sss_domain_info); assert_non_null(dom); dom->name = discard_const_p(char, TEST_DOM_NAME); ts->nctx = mock_nctx(ts); assert_non_null(ts->nctx); tc = create_dom_test_ctx(ts, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, params); assert_non_null(tc); ncache = ts->ctx; ts->rctx = mock_rctx(ts, ev, dom, ts->nctx); assert_non_null(ts->rctx); ts->rctx->default_domain = discard_const(TEST_DOM_NAME); ret = sss_names_init(ts, tc->confdb, TEST_DOM_NAME, &dom->names); assert_int_equal(ret, EOK); ret = sss_ncache_prepopulate(ncache, tc->confdb, ts->rctx); assert_int_equal(ret, EOK); ret = sss_ncache_check_user(ncache, 1, dom, "testuser1"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_group(ncache, 1, dom, "testgroup1"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_user(ncache, 1, dom, "testuser2"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_group(ncache, 1, dom, "testgroup2"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_user(ncache, 1, dom, "testuser3"); assert_int_equal(ret, ENOENT); ret = sss_ncache_check_group(ncache, 1, dom, "testgroup3"); assert_int_equal(ret, ENOENT); } static void test_sss_ncache_reset_prepopulate(void **state) { int ret; struct test_state *ts; struct tevent_context *ev; struct sss_nc_ctx *ncache; struct sss_test_ctx *tc; struct sss_domain_info *dom; struct sss_domain_info *dom2; struct sss_test_conf_param params[] = { { "filter_users", "testuser1@"TEST_DOM_NAME", testuser2@"TEST_DOM_NAME"2" }, { "filter_groups", "testgroup1@"TEST_DOM_NAME", testgroup2@"TEST_DOM_NAME"2" }, { NULL, NULL }, }; const char *nss_filter_users[] = { params[0].value, NULL}; const char *nss_filter_groups[] = { params[1].value, NULL}; ts = talloc_get_type_abort(*state, struct test_state); ev = tevent_context_init(ts); assert_non_null(ev); dom = talloc_zero(ts, struct sss_domain_info); assert_non_null(dom); dom->name = discard_const_p(char, TEST_DOM_NAME); ts->nctx = mock_nctx(ts); assert_non_null(ts->nctx); tc = create_dom_test_ctx(ts, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, params); assert_non_null(tc); ret = confdb_add_param(tc->confdb, true, "config/nss", "filter_users", nss_filter_users); assert_int_equal(ret, EOK); ret = confdb_add_param(tc->confdb, true, "config/nss", "filter_groups", nss_filter_groups); assert_int_equal(ret, EOK); ncache = ts->ctx; ts->rctx = mock_rctx(ts, ev, dom, ts->nctx); assert_non_null(ts->rctx); ts->rctx->default_domain = discard_const(TEST_DOM_NAME); ts->rctx->cdb = tc->confdb; ret = sss_names_init(ts, tc->confdb, TEST_DOM_NAME, &dom->names); assert_int_equal(ret, EOK); ret = sss_ncache_reset_repopulate_permanent(ts->rctx, ncache); assert_int_equal(ret, EOK); /* Add another domain */ dom2 = talloc_zero(ts, struct sss_domain_info); assert_non_null(dom2); dom2->name = discard_const_p(char, TEST_DOM_NAME"2"); dom->next = dom2; dom2->names = dom->names; /* First domain should not be known, the second not */ ret = sss_ncache_check_user(ncache, 1, dom, "testuser1"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_group(ncache, 1, dom, "testgroup1"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_user(ncache, 1, dom2, "testuser2"); assert_int_equal(ret, ENOENT); ret = sss_ncache_check_group(ncache, 1, dom2, "testgroup2"); assert_int_equal(ret, ENOENT); ret = sss_ncache_reset_repopulate_permanent(ts->rctx, ncache); assert_int_equal(ret, EOK); /* First domain should not be known, the second not */ ret = sss_ncache_check_user(ncache, 1, dom, "testuser1"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_group(ncache, 1, dom, "testgroup1"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_user(ncache, 1, dom2, "testuser2"); assert_int_equal(ret, EEXIST); ret = sss_ncache_check_group(ncache, 1, dom2, "testgroup2"); assert_int_equal(ret, EEXIST); } int main(void) { int rv; const struct CMUnitTest tests[] = { cmocka_unit_test(test_sss_ncache_init), cmocka_unit_test_setup_teardown(test_sss_ncache_uid, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_gid, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_sid, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_cert, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_user, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_group, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_netgr, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_service_name, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_service_port, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_reset_permanent, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_prepopulate, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_default_domain_suffix, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_ncache_reset_prepopulate, setup, teardown), }; tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); } return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_sbus_opath.c0000644000000000000000000000007412703456111021065 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.046794958 sssd-1.13.4/src/tests/cmocka/test_sbus_opath.c0000644002412700241270000002252712703456111022544 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "sbus/sssd_dbus.h" #include "tests/cmocka/common_mock.h" #include "tests/common.h" #define BASE_PATH "/some/path" void test_sbus_opath_strip_prefix(void **state) { const char *prefix = "/org/freedesktop/sssd/"; const char *path = "/org/freedesktop/sssd/infopipe"; const char *strip; strip = sbus_opath_strip_prefix(path, prefix); assert_non_null(prefix); assert_string_equal(strip, "infopipe"); strip = sbus_opath_strip_prefix("/other/path", prefix); assert_null(strip); } void test_sbus_opath_escape_unescape(void **state) { char *escaped; char *raw; TALLOC_CTX *mem_ctx; assert_true(leak_check_setup()); mem_ctx = talloc_new(global_talloc_context); escaped = sbus_opath_escape_part(mem_ctx, "noescape"); assert_non_null(escaped); assert_string_equal(escaped, "noescape"); raw = sbus_opath_unescape_part(mem_ctx, escaped); talloc_free(escaped); assert_non_null(raw); assert_string_equal(raw, "noescape"); talloc_free(raw); escaped = sbus_opath_escape_part(mem_ctx, "redhat.com"); assert_non_null(escaped); assert_string_equal(escaped, "redhat_2ecom"); /* dot is 0x2E in ASCII */ raw = sbus_opath_unescape_part(mem_ctx, escaped); talloc_free(escaped); assert_non_null(raw); assert_string_equal(raw, "redhat.com"); talloc_free(raw); escaped = sbus_opath_escape_part(mem_ctx, "path_with_underscore"); assert_non_null(escaped); /* underscore is 0x5F in ascii */ assert_string_equal(escaped, "path_5fwith_5funderscore"); raw = sbus_opath_unescape_part(mem_ctx, escaped); talloc_free(escaped); assert_non_null(raw); assert_string_equal(raw, "path_with_underscore"); talloc_free(raw); /* empty string */ escaped = sbus_opath_escape_part(mem_ctx, ""); assert_non_null(escaped); assert_string_equal(escaped, "_"); raw = sbus_opath_unescape_part(mem_ctx, escaped); talloc_free(escaped); assert_non_null(raw); assert_string_equal(raw, ""); talloc_free(raw); /* negative tests */ escaped = sbus_opath_escape_part(mem_ctx, NULL); assert_null(escaped); raw = sbus_opath_unescape_part(mem_ctx, "wrongpath_"); assert_null(raw); assert_true(leak_check_teardown()); } void test_sbus_opath_compose(void **state) { char *path; /* Doesn't need escaping */ path = sbus_opath_compose(NULL, BASE_PATH, "domname"); assert_non_null(path); assert_string_equal(path, BASE_PATH "/domname"); talloc_free(path); } void test_sbus_opath_compose_escape(void **state) { char *path; /* A dot needs escaping */ path = sbus_opath_compose(NULL, BASE_PATH, "redhat.com", NULL); assert_non_null(path); assert_string_equal(path, BASE_PATH "/redhat_2ecom"); talloc_free(path); } static void check_opath_components(char **input, const char **expected) { int i; assert_non_null(input); assert_non_null(expected); for (i = 0; input[i] != NULL; i++) { assert_non_null(input[i]); assert_non_null(expected[i]); assert_string_equal(input[i], expected[i]); } assert_null(input[i]); assert_null(expected[i]); } static void check_opath_components_and_length(char **input, size_t input_len, const char **expected, size_t expected_len) { assert_true(input_len == expected_len); check_opath_components(input, expected); } void test_sbus_opath_decompose_noprefix(void **state) { const char *path = "/object/path/parts"; const char *expected[] = {"object", "path", "parts", NULL}; size_t expected_len = sizeof(expected) / sizeof(char *) - 1; char **components; size_t len; errno_t ret; ret = sbus_opath_decompose(NULL, path, NULL, &components, &len); assert_int_equal(ret, EOK); check_opath_components_and_length(components, len, expected, expected_len); talloc_free(components); } void test_sbus_opath_decompose_prefix(void **state) { const char *path = "/object/path/parts"; const char *expected[] = {"parts", NULL}; size_t expected_len = sizeof(expected) / sizeof(char *) - 1; char **components; size_t len; errno_t ret; ret = sbus_opath_decompose(NULL, path, "/object/path", &components, &len); assert_int_equal(ret, EOK); check_opath_components_and_length(components, len, expected, expected_len); talloc_free(components); } void test_sbus_opath_decompose_prefix_slash(void **state) { const char *path = "/object/path/parts"; const char *expected[] = {"parts", NULL}; size_t expected_len = sizeof(expected) / sizeof(char *) - 1; char **components; size_t len; errno_t ret; ret = sbus_opath_decompose(NULL, path, "/object/path/", &components, &len); assert_int_equal(ret, EOK); check_opath_components_and_length(components, len, expected, expected_len); talloc_free(components); } void test_sbus_opath_decompose_wrong_prefix(void **state) { const char *path = "/object/path/parts"; char **components; size_t len; errno_t ret; ret = sbus_opath_decompose(NULL, path, "/wrong/prefix", &components, &len); assert_int_equal(ret, ERR_SBUS_INVALID_PATH); } void test_sbus_opath_decompose_escaped(void **state) { const char *path = "/object/redhat_2ecom"; const char *expected[] = {"object", "redhat.com", NULL}; size_t expected_len = sizeof(expected) / sizeof(char *) - 1; char **components; size_t len; errno_t ret; ret = sbus_opath_decompose(NULL, path, NULL, &components, &len); assert_int_equal(ret, EOK); check_opath_components_and_length(components, len, expected, expected_len); talloc_free(components); } void test_sbus_opath_decompose_exact_correct(void **state) { const char *path = "/object/path/parts"; const char *expected[] = {"object", "path", "parts", NULL}; char **components; errno_t ret; ret = sbus_opath_decompose_exact(NULL, path, NULL, 3, &components); assert_int_equal(ret, EOK); check_opath_components(components, expected); talloc_free(components); } void test_sbus_opath_decompose_exact_wrong(void **state) { const char *path = "/object/path/parts"; char **components; errno_t ret; ret = sbus_opath_decompose_exact(NULL, path, NULL, 2, &components); assert_int_equal(ret, ERR_SBUS_INVALID_PATH); } void test_sbus_opath_get_object_name(void **state) { const char *path = BASE_PATH "/redhat_2ecom"; char *name; name = sbus_opath_get_object_name(NULL, path, BASE_PATH); assert_non_null(name); assert_string_equal(name, "redhat.com"); talloc_free(name); name = sbus_opath_get_object_name(NULL, path, BASE_PATH "/"); assert_non_null(name); assert_string_equal(name, "redhat.com"); talloc_free(name); name = sbus_opath_get_object_name(NULL, BASE_PATH, BASE_PATH); assert_null(name); name = sbus_opath_get_object_name(NULL, "invalid", BASE_PATH); assert_null(name); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test(test_sbus_opath_strip_prefix), cmocka_unit_test(test_sbus_opath_escape_unescape), cmocka_unit_test(test_sbus_opath_compose), cmocka_unit_test(test_sbus_opath_compose_escape), cmocka_unit_test(test_sbus_opath_decompose_noprefix), cmocka_unit_test(test_sbus_opath_decompose_prefix), cmocka_unit_test(test_sbus_opath_decompose_prefix_slash), cmocka_unit_test(test_sbus_opath_decompose_wrong_prefix), cmocka_unit_test(test_sbus_opath_decompose_escaped), cmocka_unit_test(test_sbus_opath_decompose_exact_correct), cmocka_unit_test(test_sbus_opath_decompose_exact_wrong), cmocka_unit_test(test_sbus_opath_get_object_name) }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_expire_common.h0000644000000000000000000000007412703456111021567 xustar0030 atime=1460561751.656715648 30 ctime=1460561774.590793412 sssd-1.13.4/src/tests/cmocka/test_expire_common.h0000644002412700241270000000231512703456111023237 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Reichl Copyright (C) 2015 Red Hat SSSD tests: Tests for password expiration related functionality This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __TEST_EXPIRE_COMMON_H #define __TEST_EXPIRE_COMMON_H struct expire_test_ctx { char *past_time; char *future_time; char *invalid_format; char *invalid_longer_format; }; int expire_test_setup(void **state); int expire_test_teardown(void **state); void expire_test_tz(const char* tz, void (*f)(void*, void*), void *in, void *_out); #endif /* __TEST_EXPIRE_COMMON_H */ sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_cert_utils.c0000644000000000000000000000007412703456111021073 xustar0030 atime=1460561751.655715644 30 ctime=1460561775.031794907 sssd-1.13.4/src/tests/cmocka/test_cert_utils.c0000644002412700241270000004562412703456111022555 0ustar00jhrozekjhrozek00000000000000/* SSSD Certificates - Utilities tests Authors: Sumit Bose Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #ifdef HAVE_LIBCRYPTO #include #include #endif #include "util/cert.h" #include "tests/cmocka/common_mock.h" #include "util/crypto/nss/nss_util.h" #include "util/crypto/sss_crypto.h" /* TODO: create a certificate for this test */ const uint8_t test_cert_der[] = { 0x30, 0x82, 0x04, 0x09, 0x30, 0x82, 0x02, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x09, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x34, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x49, 0x50, 0x41, 0x2e, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x15, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x34, 0x32, 0x38, 0x31, 0x30, 0x32, 0x31, 0x31, 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x34, 0x32, 0x38, 0x31, 0x30, 0x32, 0x31, 0x31, 0x31, 0x5a, 0x30, 0x32, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x49, 0x50, 0x41, 0x2e, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x69, 0x70, 0x61, 0x2d, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x2e, 0x69, 0x70, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb2, 0x32, 0x92, 0xab, 0x47, 0xb8, 0x0c, 0x13, 0x54, 0x4a, 0x1f, 0x1e, 0x29, 0x06, 0xff, 0xd0, 0x50, 0xcb, 0xf7, 0x5f, 0x79, 0x91, 0x65, 0xb1, 0x39, 0x01, 0x83, 0x6a, 0xad, 0x9e, 0x77, 0x3b, 0xf3, 0x0d, 0xd7, 0xb9, 0xf6, 0xdc, 0x9e, 0x4a, 0x49, 0xa7, 0xd0, 0x66, 0x72, 0xcc, 0xbf, 0x77, 0xd6, 0xde, 0xa9, 0xfe, 0x67, 0x96, 0xcc, 0x49, 0xf1, 0x37, 0x23, 0x2e, 0xc4, 0x50, 0xf4, 0xeb, 0xba, 0x62, 0xd4, 0x23, 0x4d, 0xf3, 0x37, 0x38, 0x82, 0xee, 0x3b, 0x3f, 0x2c, 0xd0, 0x80, 0x9b, 0x17, 0xaa, 0x9b, 0xeb, 0xa6, 0xdd, 0xf6, 0x15, 0xff, 0x06, 0xb2, 0xce, 0xff, 0xdf, 0x8a, 0x9e, 0x95, 0x85, 0x49, 0x1f, 0x84, 0xfd, 0x81, 0x26, 0xce, 0x06, 0x32, 0x0d, 0x36, 0xca, 0x7c, 0x15, 0x81, 0x68, 0x6b, 0x8f, 0x3e, 0xb3, 0xa2, 0xfc, 0xae, 0xaf, 0xc2, 0x44, 0x58, 0x15, 0x95, 0x40, 0xfc, 0x56, 0x19, 0x91, 0x80, 0xed, 0x42, 0x11, 0x66, 0x04, 0xef, 0x3c, 0xe0, 0x76, 0x33, 0x4b, 0x83, 0xfa, 0x7e, 0xb4, 0x47, 0xdc, 0xfb, 0xed, 0x46, 0xa5, 0x8d, 0x0a, 0x66, 0x87, 0xa5, 0xef, 0x7b, 0x74, 0x62, 0xac, 0xbe, 0x73, 0x36, 0xc9, 0xb4, 0xfe, 0x20, 0xc4, 0x81, 0xf3, 0xfe, 0x78, 0x19, 0xa8, 0xd0, 0xaf, 0x7f, 0x81, 0x72, 0x24, 0x61, 0xd9, 0x76, 0x93, 0xe3, 0x0b, 0xd2, 0x4f, 0x19, 0x17, 0x33, 0x57, 0xd4, 0x82, 0xb0, 0xf1, 0xa8, 0x03, 0xf6, 0x01, 0x99, 0xa9, 0xb8, 0x8c, 0x83, 0xc9, 0xba, 0x19, 0x87, 0xea, 0xd6, 0x3b, 0x06, 0xeb, 0x4c, 0xf7, 0xf1, 0xe5, 0x28, 0xa9, 0x10, 0xb6, 0x46, 0xde, 0xe1, 0xe1, 0x3f, 0xc1, 0xcc, 0x72, 0xbe, 0x2a, 0x43, 0xc6, 0xf6, 0xd0, 0xb5, 0xa0, 0xc4, 0x24, 0x6e, 0x4f, 0xbd, 0xec, 0x22, 0x8a, 0x07, 0x11, 0x3d, 0xf9, 0xd3, 0x15, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x26, 0x30, 0x82, 0x01, 0x22, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xf2, 0x9d, 0x42, 0x4e, 0x0f, 0xc4, 0x48, 0x25, 0x58, 0x2f, 0x1c, 0xce, 0x0f, 0xa1, 0x3f, 0x22, 0xc8, 0x55, 0xc8, 0x91, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x70, 0x61, 0x2d, 0x63, 0x61, 0x2e, 0x69, 0x70, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x2f, 0x63, 0x61, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x04, 0xf0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x74, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x6d, 0x30, 0x6b, 0x30, 0x69, 0xa0, 0x31, 0xa0, 0x2f, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x70, 0x61, 0x2d, 0x63, 0x61, 0x2e, 0x69, 0x70, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x2f, 0x69, 0x70, 0x61, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x43, 0x52, 0x4c, 0x2e, 0x62, 0x69, 0x6e, 0xa2, 0x34, 0xa4, 0x32, 0x30, 0x30, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x05, 0x69, 0x70, 0x61, 0x63, 0x61, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x15, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2d, 0x2b, 0x3f, 0xcb, 0xf5, 0xb2, 0xff, 0x32, 0x2c, 0xa8, 0xc2, 0x1c, 0xdd, 0xbd, 0x8c, 0x80, 0x1e, 0xdd, 0x31, 0x82, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9a, 0x47, 0x2e, 0x50, 0xa7, 0x4d, 0x1d, 0x53, 0x0f, 0xc9, 0x71, 0x42, 0x0c, 0xe5, 0xda, 0x7d, 0x49, 0x64, 0xe7, 0xab, 0xc8, 0xdf, 0xdf, 0x02, 0xc1, 0x87, 0xd1, 0x5b, 0xde, 0xda, 0x6f, 0x2b, 0xe4, 0xf0, 0xbe, 0xba, 0x09, 0xdf, 0x02, 0x85, 0x0b, 0x8a, 0xe6, 0x9b, 0x06, 0x7d, 0x69, 0x38, 0x6c, 0x72, 0xff, 0x4c, 0x7b, 0x2a, 0x0d, 0x3f, 0x23, 0x2f, 0x16, 0x46, 0xff, 0x05, 0x93, 0xb0, 0xea, 0x24, 0x28, 0xd7, 0x12, 0xa1, 0x57, 0xb8, 0x59, 0x19, 0x25, 0xf3, 0x43, 0x0a, 0xd3, 0xfd, 0x0f, 0x37, 0x8d, 0xb8, 0xca, 0x15, 0xe7, 0x48, 0x8a, 0xa0, 0xc7, 0xc7, 0x4b, 0x7f, 0x01, 0x3c, 0x58, 0xd7, 0x37, 0xe5, 0xff, 0x7d, 0x2b, 0x01, 0xac, 0x0d, 0x9f, 0x51, 0x6a, 0xe5, 0x40, 0x24, 0xe6, 0x5e, 0x55, 0x0d, 0xf7, 0xb8, 0x2f, 0x42, 0xac, 0x6d, 0xe5, 0x29, 0x6b, 0xc6, 0x0b, 0xa4, 0xbf, 0x19, 0xbd, 0x39, 0x27, 0xee, 0xfe, 0xc5, 0xb3, 0xdb, 0x62, 0xd4, 0xbe, 0xd2, 0x47, 0xba, 0x96, 0x30, 0x5a, 0xfd, 0x62, 0x00, 0xb8, 0x27, 0x5d, 0x2f, 0x3a, 0x94, 0x0b, 0x95, 0x35, 0x85, 0x40, 0x2c, 0xbc, 0x67, 0xdf, 0x8a, 0xf9, 0xf1, 0x7b, 0x19, 0x96, 0x3e, 0x42, 0x48, 0x13, 0x23, 0x04, 0x95, 0xa9, 0x6b, 0x11, 0x33, 0x81, 0x47, 0x5a, 0x83, 0x72, 0xf6, 0x20, 0xfa, 0x8e, 0x41, 0x7b, 0x8f, 0x77, 0x47, 0x7c, 0xc7, 0x5d, 0x46, 0xf4, 0x4f, 0xfd, 0x81, 0x0a, 0xae, 0x39, 0x27, 0xb6, 0x6a, 0x26, 0x63, 0xb1, 0xd3, 0xbf, 0x55, 0x83, 0x82, 0x9b, 0x36, 0x6c, 0x33, 0x64, 0x0f, 0x50, 0xc0, 0x55, 0x94, 0x13, 0xc3, 0x85, 0xf4, 0xd5, 0x71, 0x65, 0xd0, 0xc0, 0xdd, 0xfc, 0xe6, 0xec, 0x9c, 0x5b, 0xf0, 0x11, 0xb5, 0x2c, 0xf3, 0x48, 0xc1, 0x36, 0x8c, 0xa2, 0x96, 0x48, 0x84}; #define TEST_CERT_PEM "-----BEGIN CERTIFICATE-----\n" \ "MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu\n" \ "REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA0Mjgx\n" \ "MDIxMTFaFw0xNzA0MjgxMDIxMTFaMDIxEjAQBgNVBAoMCUlQQS5ERVZFTDEcMBoG\n" \ "A1UEAwwTaXBhLWRldmVsLmlwYS5kZXZlbDCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" \ "ADCCAQoCggEBALIykqtHuAwTVEofHikG/9BQy/dfeZFlsTkBg2qtnnc78w3Xufbc\n" \ "nkpJp9Bmcsy/d9beqf5nlsxJ8TcjLsRQ9Ou6YtQjTfM3OILuOz8s0ICbF6qb66bd\n" \ "9hX/BrLO/9+KnpWFSR+E/YEmzgYyDTbKfBWBaGuPPrOi/K6vwkRYFZVA/FYZkYDt\n" \ "QhFmBO884HYzS4P6frRH3PvtRqWNCmaHpe97dGKsvnM2ybT+IMSB8/54GajQr3+B\n" \ "ciRh2XaT4wvSTxkXM1fUgrDxqAP2AZmpuIyDyboZh+rWOwbrTPfx5SipELZG3uHh\n" \ "P8HMcr4qQ8b20LWgxCRuT73sIooHET350xUCAwEAAaOCASYwggEiMB8GA1UdIwQY\n" \ "MBaAFPKdQk4PxEglWC8czg+hPyLIVciRMDsGCCsGAQUFBwEBBC8wLTArBggrBgEF\n" \ "BQcwAYYfaHR0cDovL2lwYS1jYS5pcGEuZGV2ZWwvY2Evb2NzcDAOBgNVHQ8BAf8E\n" \ "BAMCBPAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHQGA1UdHwRtMGsw\n" \ "aaAxoC+GLWh0dHA6Ly9pcGEtY2EuaXBhLmRldmVsL2lwYS9jcmwvTWFzdGVyQ1JM\n" \ "LmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRpZmljYXRl\n" \ "IEF1dGhvcml0eTAdBgNVHQ4EFgQULSs/y/Wy/zIsqMIc3b2MgB7dMYIwDQYJKoZI\n" \ "hvcNAQELBQADggEBAJpHLlCnTR1TD8lxQgzl2n1JZOeryN/fAsGH0Vve2m8r5PC+\n" \ "ugnfAoULiuabBn1pOGxy/0x7Kg0/Iy8WRv8Fk7DqJCjXEqFXuFkZJfNDCtP9DzeN\n" \ "uMoV50iKoMfHS38BPFjXN+X/fSsBrA2fUWrlQCTmXlUN97gvQqxt5Slrxgukvxm9\n" \ "OSfu/sWz22LUvtJHupYwWv1iALgnXS86lAuVNYVALLxn34r58XsZlj5CSBMjBJWp\n" \ "axEzgUdag3L2IPqOQXuPd0d8x11G9E/9gQquOSe2aiZjsdO/VYOCmzZsM2QPUMBV\n" \ "lBPDhfTVcWXQwN385uycW/ARtSzzSME2jKKWSIQ=\n" \ "-----END CERTIFICATE-----\n" #define TEST_CERT_DERB64 \ "MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \ "REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA0Mjgx" \ "MDIxMTFaFw0xNzA0MjgxMDIxMTFaMDIxEjAQBgNVBAoMCUlQQS5ERVZFTDEcMBoG" \ "A1UEAwwTaXBhLWRldmVsLmlwYS5kZXZlbDCCASIwDQYJKoZIhvcNAQEBBQADggEP" \ "ADCCAQoCggEBALIykqtHuAwTVEofHikG/9BQy/dfeZFlsTkBg2qtnnc78w3Xufbc" \ "nkpJp9Bmcsy/d9beqf5nlsxJ8TcjLsRQ9Ou6YtQjTfM3OILuOz8s0ICbF6qb66bd" \ "9hX/BrLO/9+KnpWFSR+E/YEmzgYyDTbKfBWBaGuPPrOi/K6vwkRYFZVA/FYZkYDt" \ "QhFmBO884HYzS4P6frRH3PvtRqWNCmaHpe97dGKsvnM2ybT+IMSB8/54GajQr3+B" \ "ciRh2XaT4wvSTxkXM1fUgrDxqAP2AZmpuIyDyboZh+rWOwbrTPfx5SipELZG3uHh" \ "P8HMcr4qQ8b20LWgxCRuT73sIooHET350xUCAwEAAaOCASYwggEiMB8GA1UdIwQY" \ "MBaAFPKdQk4PxEglWC8czg+hPyLIVciRMDsGCCsGAQUFBwEBBC8wLTArBggrBgEF" \ "BQcwAYYfaHR0cDovL2lwYS1jYS5pcGEuZGV2ZWwvY2Evb2NzcDAOBgNVHQ8BAf8E" \ "BAMCBPAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHQGA1UdHwRtMGsw" \ "aaAxoC+GLWh0dHA6Ly9pcGEtY2EuaXBhLmRldmVsL2lwYS9jcmwvTWFzdGVyQ1JM" \ "LmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRpZmljYXRl" \ "IEF1dGhvcml0eTAdBgNVHQ4EFgQULSs/y/Wy/zIsqMIc3b2MgB7dMYIwDQYJKoZI" \ "hvcNAQELBQADggEBAJpHLlCnTR1TD8lxQgzl2n1JZOeryN/fAsGH0Vve2m8r5PC+" \ "ugnfAoULiuabBn1pOGxy/0x7Kg0/Iy8WRv8Fk7DqJCjXEqFXuFkZJfNDCtP9DzeN" \ "uMoV50iKoMfHS38BPFjXN+X/fSsBrA2fUWrlQCTmXlUN97gvQqxt5Slrxgukvxm9" \ "OSfu/sWz22LUvtJHupYwWv1iALgnXS86lAuVNYVALLxn34r58XsZlj5CSBMjBJWp" \ "axEzgUdag3L2IPqOQXuPd0d8x11G9E/9gQquOSe2aiZjsdO/VYOCmzZsM2QPUMBV" \ "lBPDhfTVcWXQwN385uycW/ARtSzzSME2jKKWSIQ=" struct test_state { void *dummy; }; static int setup(void **state) { struct test_state *ts = NULL; assert_true(leak_check_setup()); ts = talloc(global_talloc_context, struct test_state); assert_non_null(ts); check_leaks_push(ts); *state = (void *)ts; return 0; } static int teardown(void **state) { struct test_state *ts = talloc_get_type_abort(*state, struct test_state); assert_non_null(ts); assert_true(check_leaks_pop(ts)); talloc_free(ts); assert_true(leak_check_teardown()); return 0; } void test_sss_cert_der_to_pem(void **state) { int ret; char *pem_str; size_t pem_size; struct test_state *ts = talloc_get_type_abort(*state, struct test_state); assert_non_null(ts); ret = sss_cert_der_to_pem(NULL, NULL, 0, NULL, NULL); assert_int_equal(ret, EINVAL); ret = sss_cert_der_to_pem(ts, test_cert_der, sizeof(test_cert_der), &pem_str, &pem_size); assert_int_equal(ret, EOK); assert_int_equal(sizeof(TEST_CERT_PEM) - 1, pem_size); assert_string_equal(pem_str, TEST_CERT_PEM); talloc_free(pem_str); } void test_sss_cert_pem_to_der(void **state) { int ret; uint8_t *der; size_t der_size; struct test_state *ts = talloc_get_type_abort(*state, struct test_state); assert_non_null(ts); ret = sss_cert_pem_to_der(NULL, NULL, NULL, NULL); assert_int_equal(ret, EINVAL); ret = sss_cert_pem_to_der(ts, TEST_CERT_PEM, &der, &der_size); assert_int_equal(ret, EOK); assert_int_equal(sizeof(test_cert_der), der_size); assert_memory_equal(der, test_cert_der, der_size); talloc_free(der); } void test_sss_cert_derb64_to_pem(void **state) { int ret; char *pem_str; size_t pem_size; struct test_state *ts = talloc_get_type_abort(*state, struct test_state); assert_non_null(ts); ret = sss_cert_derb64_to_pem(NULL, NULL, NULL, NULL); assert_int_equal(ret, EINVAL); ret = sss_cert_derb64_to_pem(ts, TEST_CERT_DERB64, &pem_str, &pem_size); assert_int_equal(ret, EOK); assert_int_equal(sizeof(TEST_CERT_PEM) - 1, pem_size); assert_string_equal(pem_str, TEST_CERT_PEM); talloc_free(pem_str); } void test_sss_cert_pem_to_derb64(void **state) { int ret; char *derb64; struct test_state *ts = talloc_get_type_abort(*state, struct test_state); assert_non_null(ts); ret = sss_cert_pem_to_derb64(NULL, NULL, NULL); assert_int_equal(ret, EINVAL); ret = sss_cert_pem_to_derb64(ts, TEST_CERT_PEM, &derb64); assert_int_equal(ret, EOK); assert_string_equal(derb64, TEST_CERT_DERB64); talloc_free(derb64); } void test_bin_to_ldap_filter_value(void **state) { int ret; size_t c; char *str; struct test_state *ts = talloc_get_type_abort(*state, struct test_state); assert_non_null(ts); struct test_data { uint8_t blob[5]; const char *str; } test_data[] = { {{0x01, 0x02, 0x03, 0x04, 0x05}, "\\01\\02\\03\\04\\05"}, {{0x00, 0x00, 0x00, 0x00, 0x00}, "\\00\\00\\00\\00\\00"}, {{0xff, 0xff, 0xff, 0xff, 0xff}, "\\ff\\ff\\ff\\ff\\ff"}, {{0xca, 0xfe, 0xc0, 0xff, 0xee}, "\\ca\\fe\\c0\\ff\\ee"}, {{0}, NULL} }; ret = bin_to_ldap_filter_value(ts, NULL, 0, NULL); assert_int_equal(ret, EINVAL); for (c = 0; test_data[c].str != NULL; c++) { ret = bin_to_ldap_filter_value(ts, test_data[c].blob, 5, &str); assert_int_equal(ret, EOK); assert_string_equal(str, test_data[c].str); talloc_free(str); } } void test_sss_cert_derb64_to_ldap_filter(void **state) { int ret; char *filter; struct test_state *ts = talloc_get_type_abort(*state, struct test_state); assert_non_null(ts); ret = sss_cert_derb64_to_ldap_filter(ts, NULL, NULL, NULL); assert_int_equal(ret, EINVAL); ret = sss_cert_derb64_to_ldap_filter(ts, "AAECAwQFBgcICQ==", "attrName", &filter); assert_int_equal(ret, EOK); assert_string_equal(filter, "(attrName=\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09)"); talloc_free(filter); } #define SSH_TEST_CERT \ "MIIECTCCAvGgAwIBAgIBCDANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \ "REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA2MjMx" \ "NjMyMDdaFw0xNzA2MjMxNjMyMDdaMDIxEjAQBgNVBAoMCUlQQS5ERVZFTDEcMBoG" \ "A1UEAwwTaXBhLWRldmVsLmlwYS5kZXZlbDCCASIwDQYJKoZIhvcNAQEBBQADggEP" \ "ADCCAQoCggEBALXUq56VlY+Z0aWLLpFAjFfbElPBXGQsbZb85J3cGyPjaMHC9wS+" \ "wjB6Ve4HmQyPLx8hbINdDmbawMHYQvTScLYfsqLtj0Lqw20sUUmedk+Es5Oh9VHo" \ "nd8MavYx25Du2u+T0iSgNIDikXguiwCmtAj8VC49ebbgITcjJGzMmiiuJkV3o93Y" \ "vvYF0VjLGDQbQWOy7IxzYJeNVJnZWKo67CHdok6qOrm9rxQt81rzwV/mGLbCMUbr" \ "+N4M8URtd7EmzaYZQmNm//s2owFrCYMxpLiURPj+URZVuB72504/Ix7X0HCbA/AV" \ "26J27fPY5nc8DMwfhUDCbTqPH/JEjd3mvY8CAwEAAaOCASYwggEiMB8GA1UdIwQY" \ "MBaAFJOq+KAQmPEnNp8Wok23eGTdE7aDMDsGCCsGAQUFBwEBBC8wLTArBggrBgEF" \ "BQcwAYYfaHR0cDovL2lwYS1jYS5pcGEuZGV2ZWwvY2Evb2NzcDAOBgNVHQ8BAf8E" \ "BAMCBPAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHQGA1UdHwRtMGsw" \ "aaAxoC+GLWh0dHA6Ly9pcGEtY2EuaXBhLmRldmVsL2lwYS9jcmwvTWFzdGVyQ1JM" \ "LmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRpZmljYXRl" \ "IEF1dGhvcml0eTAdBgNVHQ4EFgQUFaDNd5a53QGpaw5m63hnwXicMQ8wDQYJKoZI" \ "hvcNAQELBQADggEBADH7Nj00qqGhGJeXJQAsepqSskz/wooqXh8vgVyb8SS4N0/c" \ "0aQtVmY81xamlXE12ZFpwDX43d+EufBkwCUKFX/+8JFDd2doAyeJxv1xM22kKRpc" \ "AqITPgMsa9ToGMWxjbVpc/X/5YfZixWPF0/eZUTotBj9oaR039UrhGfyN7OguF/G" \ "rzmxtB5y4ZrMpcD/Oe90mkd9HY7sA/fB8OWOUgeRfQoh97HNS0UiDWsPtfxmjQG5" \ "zotpoBIZmdH+ipYsu58HohHVlM9Wi5H4QmiiXl+Soldkq7eXYlafcmT7wv8+cKwz" \ "Nz0Tm3+eYpFqRo3skr6QzXi525Jkg3r6r+kkhxU=" #define SSH_PUB_KEY "AAAAB3NzaC1yc2EAAAADAQABAAABAQC11KuelZWPmdGliy6RQIxX2xJTwVxkLG2W/OSd3Bsj42jBwvcEvsIwelXuB5kMjy8fIWyDXQ5m2sDB2EL00nC2H7Ki7Y9C6sNtLFFJnnZPhLOTofVR6J3fDGr2MduQ7trvk9IkoDSA4pF4LosAprQI/FQuPXm24CE3IyRszJooriZFd6Pd2L72BdFYyxg0G0FjsuyMc2CXjVSZ2ViqOuwh3aJOqjq5va8ULfNa88Ff5hi2wjFG6/jeDPFEbXexJs2mGUJjZv/7NqMBawmDMaS4lET4/lEWVbge9udOPyMe19BwmwPwFduidu3z2OZ3PAzMH4VAwm06jx/yRI3d5r2P" void test_cert_to_ssh_key(void **state) { int ret; uint8_t *key; size_t key_size; uint8_t *exp_key; size_t exp_key_size; uint8_t *der; size_t der_size; struct test_state *ts = talloc_get_type_abort(*state, struct test_state); assert_non_null(ts); der = sss_base64_decode(ts, SSH_TEST_CERT, &der_size); assert_non_null(der); exp_key = sss_base64_decode(ts, SSH_PUB_KEY, &exp_key_size); assert_non_null(exp_key); ret = cert_to_ssh_key(ts, "sql:" ABS_SRC_DIR "/src/tests/cmocka/p11_nssdb", der, der_size, false, &key, &key_size); assert_int_equal(ret, EOK); assert_int_equal(key_size, exp_key_size); assert_memory_equal(key, exp_key, exp_key_size); talloc_free(der); talloc_free(key); talloc_free(exp_key); } int main(int argc, const char *argv[]) { poptContext pc; int opt; int ret; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_sss_cert_der_to_pem, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_cert_pem_to_der, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_cert_derb64_to_pem, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_cert_pem_to_derb64, setup, teardown), cmocka_unit_test_setup_teardown(test_bin_to_ldap_filter_value, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_cert_derb64_to_ldap_filter, setup, teardown), cmocka_unit_test_setup_teardown(test_cert_to_ssh_key, setup, teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); ret = cmocka_run_group_tests(tests, NULL, NULL); #ifdef HAVE_LIBCRYPTO CRYPTO_cleanup_all_ex_data(); /* to make valgrind happy */ #endif #ifdef HAVE_NSS /* Cleanup NSS and NSPR to make valgrind happy. */ nspr_nss_cleanup(); #endif return ret; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_io.c0000644000000000000000000000007412703456111017325 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.027794894 sssd-1.13.4/src/tests/cmocka/test_io.c0000644002412700241270000001336212703456111021001 0ustar00jhrozekjhrozek00000000000000/* SSSD find_uid - Utilities tests Authors: Abhishek Singh Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include "limits.h" #include "util/io.h" #include "util/util.h" #include "tests/common.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define FILE_TEMPLATE TESTS_PATH"/test_io.XXXXXX" #define NON_EX_PATH TESTS_PATH"/non-existent-path" /* Creates a unique temporary file inside TEST_DIR and returns its path*/ static char *get_random_filepath(const char *template) { int ret; char *path; path = strdup(template); assert_non_null(path); ret = mkstemp(path); if (ret == -1) { int err = errno; fprintf(stderr, "mkstemp failed with path:'%s' [%s]\n", path, strerror(err)); } assert_int_not_equal(ret, -1); /* We do not need this file descriptor */ close(ret); return path; } static int test_file_setup(void **state) { int ret; char *file_path; ret = mkdir(TESTS_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); assert_int_equal(ret, EOK); file_path = get_random_filepath(FILE_TEMPLATE); assert_non_null(file_path); ret = unlink(NON_EX_PATH); ret = errno; assert_int_equal(ret, ENOENT); *state = file_path; return 0; } static int test_file_teardown(void **state) { int ret; char *file_path = (char *)*state; ret = unlink(file_path); assert_int_equal(ret, EOK); free(file_path); ret = rmdir(TESTS_PATH); assert_int_equal(ret, EOK); return 0; } struct dir_state { int dir_fd; char *basename; /* resources for cleanup*/ DIR *dirp; char *filename; }; static int test_dir_setup(void **state) { struct dir_state *data; int ret; data = (struct dir_state *)calloc(1, sizeof(struct dir_state)); assert_non_null(data); ret = mkdir(TESTS_PATH, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); assert_int_equal(ret, EOK); data->dirp = opendir(TESTS_PATH); if (data->dirp == NULL) { int err = errno; fprintf(stderr, "Could not open directory:'%s' [%s]\n", TESTS_PATH, strerror(err)); } assert_non_null(data->dirp); data->dir_fd = dirfd(data->dirp); assert_int_not_equal(data->dir_fd, -1); data->filename = get_random_filepath(FILE_TEMPLATE); assert_non_null(data->filename); data->basename = basename(data->filename); ret = unlink(NON_EX_PATH); ret = errno; assert_int_equal(ret, ENOENT); *state = data; return 0; } static int test_dir_teardown(void **state) { int ret; struct dir_state *data = (struct dir_state *) *state; ret = unlink(data->filename); assert_int_equal(ret, EOK); free(data->filename); ret = closedir(data->dirp); assert_int_equal(ret, EOK); ret = rmdir(TESTS_PATH); assert_int_equal(ret, EOK); free(data); return 0; } void test_sss_open_cloexec_success(void **state) { int fd; int ret; int ret_flag; int expec_flag; int flags = O_RDWR; char *file_path = (char *) *state; fd = sss_open_cloexec(file_path, flags, &ret); assert_int_not_equal(fd, -1); ret_flag = fcntl(fd, F_GETFD, 0); expec_flag = FD_CLOEXEC; assert_true(ret_flag & expec_flag); close(fd); } void test_sss_open_cloexec_fail(void **state) { int fd; int ret; int flags = O_RDWR; fd = sss_open_cloexec(NON_EX_PATH, flags, &ret); assert_true(fd == -1); assert_int_not_equal(ret, 0); } void test_sss_openat_cloexec_success(void **state) { int fd; int ret; int ret_flag; int expec_flag; const int flags = O_RDWR; struct dir_state *data = (struct dir_state *) *state; fd = sss_openat_cloexec(data->dir_fd, data->basename, flags, &ret); assert_int_not_equal(fd, -1); ret_flag = fcntl(fd, F_GETFD, 0); expec_flag = FD_CLOEXEC; assert_true(ret_flag & expec_flag); close(fd); } void test_sss_openat_cloexec_fail(void **state) { int fd; int ret; int flags = O_RDWR; struct dir_state *data = (struct dir_state *) *state; fd = sss_openat_cloexec(data->dir_fd, NON_EX_PATH, flags, &ret); assert_int_equal(fd, -1); assert_int_equal(ret, ENOENT); } int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_sss_open_cloexec_success, test_file_setup, test_file_teardown), cmocka_unit_test_setup_teardown(test_sss_open_cloexec_fail, test_file_setup, test_file_teardown), cmocka_unit_test_setup_teardown(test_sss_openat_cloexec_success, test_dir_setup, test_dir_teardown), cmocka_unit_test_setup_teardown(test_sss_openat_cloexec_fail, test_dir_setup, test_dir_teardown) }; tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_nss_srv.c0000644000000000000000000000007412703456111020413 xustar0030 atime=1460561751.656715648 30 ctime=1460561774.943794609 sssd-1.13.4/src/tests/cmocka/test_nss_srv.c0000644002412700241270000030426012703456111022067 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat SSSD tests: NSS responder tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #include "responder/common/negcache.h" #include "responder/nss/nsssrv.h" #include "responder/nss/nsssrv_private.h" #include "sss_client/idmap/sss_nss_idmap.h" #include "util/util_sss_idmap.h" #include "db/sysdb_private.h" /* new_subdomain() */ #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_nss_conf.ldb" #define TEST_DOM_NAME "nss_test" #define TEST_SUBDOM_NAME "test.subdomain" #define TEST_ID_PROVIDER "ldap" #define TEST_DOM_SID "S-1-5-21-444379608-1639770488-2995963434" struct nss_test_ctx { struct sss_test_ctx *tctx; struct sss_domain_info *subdom; struct resp_ctx *rctx; struct cli_ctx *cctx; struct sss_cmd_table *nss_cmds; struct nss_ctx *nctx; int ncache_hits; }; const char *global_extra_attrs[] = {"phone", "mobile", NULL}; struct nss_test_ctx *nss_test_ctx; /* Mock NSS structure */ struct nss_ctx * mock_nctx(TALLOC_CTX *mem_ctx) { struct nss_ctx *nctx; errno_t ret; enum idmap_error_code err; nctx = talloc_zero(mem_ctx, struct nss_ctx); if (!nctx) { return NULL; } ret = sss_ncache_init(nctx, &nctx->ncache); if (ret != EOK) { talloc_free(nctx); return NULL; } nctx->neg_timeout = 10; nctx->pwfield = discard_const("*"); err = sss_idmap_init(sss_idmap_talloc, nctx, sss_idmap_talloc_free, &nctx->idmap_ctx); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "sss_idmap_init failed.\n"); talloc_free(nctx); return NULL; } return nctx; } /* Mock reading requests from a client. Use values passed from mock * instead */ void __real_sss_packet_get_body(struct sss_packet *packet, uint8_t **body, size_t *blen); void __wrap_sss_packet_get_body(struct sss_packet *packet, uint8_t **body, size_t *blen) { enum sss_test_wrapper_call wtype = sss_mock_type(enum sss_test_wrapper_call); size_t len; if (wtype == WRAP_CALL_REAL) { return __real_sss_packet_get_body(packet, body, blen); } *body = sss_mock_ptr_type(uint8_t *); len = sss_mock_type(size_t); if (len == 0) { len = strlen((const char *) *body)+1; } *blen = len; return; } /* Mock returning result to client. Terminate the unit test instead. */ typedef int (*cmd_cb_fn_t)(uint32_t, uint8_t *, size_t ); static void set_cmd_cb(cmd_cb_fn_t fn) { will_return(__wrap_sss_cmd_done, fn); } void __wrap_sss_cmd_done(struct cli_ctx *cctx, void *freectx) { struct sss_packet *packet = cctx->creq->out; uint8_t *body; size_t blen; cmd_cb_fn_t check_cb; check_cb = sss_mock_ptr_type(cmd_cb_fn_t); __real_sss_packet_get_body(packet, &body, &blen); nss_test_ctx->tctx->error = check_cb(sss_packet_get_status(packet), body, blen); nss_test_ctx->tctx->done = true; } enum sss_cli_command __wrap_sss_packet_get_cmd(struct sss_packet *packet) { return sss_mock_type(enum sss_cli_command); } int __wrap_sss_cmd_send_empty(struct cli_ctx *cctx, TALLOC_CTX *freectx) { nss_test_ctx->tctx->done = true; nss_test_ctx->tctx->error = ENOENT; return EOK; } /* Intercept negative cache lookups */ int __real_sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, const char *name); int __wrap_sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, const char *name) { int ret; ret = __real_sss_ncache_check_user(ctx, ttl, dom, name); if (ret == EEXIST) { nss_test_ctx->ncache_hits++; } return ret; } int __real_sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, uid_t uid); int __wrap_sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, uid_t uid) { int ret; ret = __real_sss_ncache_check_uid(ctx, ttl, dom, uid); if (ret == EEXIST) { nss_test_ctx->ncache_hits++; } return ret; } int __real_sss_ncache_check_sid(struct sss_nc_ctx *ctx, int ttl, const char *sid); int __wrap_sss_ncache_check_sid(struct sss_nc_ctx *ctx, int ttl, const char *sid) { int ret; ret = __real_sss_ncache_check_sid(ctx, ttl, sid); if (ret == EEXIST) { nss_test_ctx->ncache_hits++; } return ret; } /* Mock input from the client library */ static void mock_input_user_or_group(const char *username) { will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, username); will_return(__wrap_sss_packet_get_body, 0); } static void mock_input_id(TALLOC_CTX *mem_ctx, uint32_t id) { uint8_t *body; body = talloc_zero_array(mem_ctx, uint8_t, 4); if (body == NULL) return; SAFEALIGN_SETMEM_UINT32(body, id, NULL); will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, body); will_return(__wrap_sss_packet_get_body, sizeof(uint32_t)); } static void mock_fill_user(void) { /* One packet for the entry and one for num entries */ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); } static void mock_fill_bysid(void) { /* One packet for the entry and one for num entries */ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); } static void mock_fill_initgr_user(void) { will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); } static void mock_fill_group_with_members(unsigned members) { unsigned i; will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); if (members == 0) return; will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); /* Member header , one per member */ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); for (i=0; ipw_uid, body+rp, &rp); SAFEALIGN_COPY_UINT32(&pwd->pw_gid, body+rp, &rp); /* Sequence of null terminated strings (name, passwd, gecos, dir, shell) */ pwd->pw_name = (char *) body+rp; rp += strlen(pwd->pw_name) + 1; if (rp >= blen) return EINVAL; pwd->pw_passwd = (char *) body+rp; rp += strlen(pwd->pw_passwd) + 1; if (rp >= blen) return EINVAL; pwd->pw_gecos = (char *) body+rp; rp += strlen(pwd->pw_gecos) + 1; if (rp >= blen) return EINVAL; pwd->pw_dir = (char *) body+rp; rp += strlen(pwd->pw_dir) + 1; if (rp >= blen) return EINVAL; pwd->pw_shell = (char *) body+rp; rp += strlen(pwd->pw_shell) + 1; if (rp != blen) return EINVAL; return EOK; } static int parse_group_packet(uint8_t *body, size_t blen, struct group *gr, uint32_t *nmem) { size_t rp = 2 * sizeof(uint32_t); /* Len and reserved */ unsigned i; SAFEALIGN_COPY_UINT32(&gr->gr_gid, body+rp, &rp); SAFEALIGN_COPY_UINT32(nmem, body+rp, &rp); gr->gr_name = (char *) body+rp; rp += strlen(gr->gr_name) + 1; if (rp >= blen) return EINVAL; gr->gr_passwd = (char *) body+rp; rp += strlen(gr->gr_passwd) + 1; if (*nmem > 0) { gr->gr_mem = talloc_zero_array(nss_test_ctx, char *, *nmem); if (gr->gr_mem == NULL) return ENOMEM; for (i = 0; i < *nmem; i++) { if (rp >= blen) return EINVAL; gr->gr_mem[i] = talloc_strdup(gr->gr_mem, (char *) body+rp); rp += strlen(gr->gr_mem[i]) + 1; } } /* Make sure we exactly matched the end of the packet */ if (rp != blen) return EINVAL; return EOK; } static void check_initgr_packet(uint8_t *body, size_t blen, gid_t *gids, size_t num_gids) { size_t rp; unsigned i; gid_t cur_gid; uint32_t num_ret; rp = 0; SAFEALIGN_COPY_UINT32(&num_ret, body, NULL); assert_int_equal(num_ret, num_gids); rp = 2 * sizeof(uint32_t); /* Len and reserved */ for (i = 0; i < num_gids; i++) { SAFEALIGN_COPY_UINT32(&cur_gid, body + rp, &rp); assert_int_equal(cur_gid, gids[i]); } } /* ====================== The tests =============================== */ /* Check getting cached and valid user from cache. Account callback will * not be called and test_nss_getpwnam_check will make sure the user is * the same as the test entered before starting */ static int test_nss_getpwnam_check(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; errno_t ret; assert_int_equal(status, EOK); ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); assert_int_equal(pwd.pw_uid, 123); assert_int_equal(pwd.pw_gid, 456); assert_string_equal(pwd.pw_name, "testuser"); assert_string_equal(pwd.pw_shell, "/bin/sh"); assert_string_equal(pwd.pw_passwd, "*"); return EOK; } void test_nss_getpwnam(void **state) { errno_t ret; /* Prime the cache with a valid user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testuser", 123, 456, "test user", "/home/testuser", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuser"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM); mock_fill_user(); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_getpwnam_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } /* Test that searching for a nonexistant user yields ENOENT. * Account callback will be called */ void test_nss_getpwnam_neg(void **state) { errno_t ret; mock_input_user_or_group("testuser_neg"); mock_account_recv_simple(); assert_int_equal(nss_test_ctx->ncache_hits, 0); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_int_equal(nss_test_ctx->ncache_hits, 0); /* Test that subsequent search for a nonexistent user yields * ENOENT and Account callback is not called, on the other hand * the ncache functions will be called */ nss_test_ctx->tctx->done = false; mock_input_user_or_group("testuser_neg"); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); /* Negative cache was hit this time */ assert_int_equal(nss_test_ctx->ncache_hits, 1); } static int test_nss_getpwnam_search_acct_cb(void *pvt) { errno_t ret; struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx); ret = sysdb_add_user(ctx->tctx->dom, "testuser_search", 567, 890, "test search", "/home/testsearch", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); return EOK; } static int test_nss_getpwnam_search_check(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; errno_t ret; assert_int_equal(status, EOK); ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); assert_int_equal(pwd.pw_uid, 567); assert_int_equal(pwd.pw_gid, 890); assert_string_equal(pwd.pw_name, "testuser_search"); assert_string_equal(pwd.pw_shell, "/bin/sh"); return EOK; } void test_nss_getpwnam_search(void **state) { errno_t ret; struct ldb_result *res; mock_input_user_or_group("testuser_search"); mock_account_recv(0, 0, NULL, test_nss_getpwnam_search_acct_cb, nss_test_ctx); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM); mock_fill_user(); set_cmd_cb(test_nss_getpwnam_search_check); ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, "testuser_search", &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); /* test_nss_getpwnam_search_check will check the user attributes */ ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, "testuser_search", &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); } /* Test that searching for a user that is expired in the cache goes to the DP * which updates the record and the NSS responder returns the updated record * * The user's shell attribute is updated. */ static int test_nss_getpwnam_update_acct_cb(void *pvt) { errno_t ret; struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx); ret = sysdb_store_user(ctx->tctx->dom, "testuser_update", NULL, 10, 11, "test user", "/home/testuser", "/bin/ksh", NULL, NULL, NULL, 300, 0); assert_int_equal(ret, EOK); return EOK; } static int test_nss_getpwnam_update_check(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; errno_t ret; assert_int_equal(status, EOK); ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); assert_int_equal(pwd.pw_uid, 10); assert_int_equal(pwd.pw_gid, 11); assert_string_equal(pwd.pw_name, "testuser_update"); assert_string_equal(pwd.pw_shell, "/bin/ksh"); return EOK; } void test_nss_getpwnam_update(void **state) { errno_t ret; struct ldb_result *res; const char *shell; /* Prime the cache with a valid but expired user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testuser_update", 10, 11, "test user", "/home/testuser", "/bin/sh", NULL, NULL, 1, 1); assert_int_equal(ret, EOK); /* Mock client input */ mock_input_user_or_group("testuser_update"); /* Mock client command */ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM); /* Call this function when user is updated by the mock DP request */ mock_account_recv(0, 0, NULL, test_nss_getpwnam_update_acct_cb, nss_test_ctx); /* Call this function to check what the responder returned to the client */ set_cmd_cb(test_nss_getpwnam_update_check); /* Mock output buffer */ mock_fill_user(); /* Fire the command */ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); /* Check the user was updated in the cache */ ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, "testuser_update", &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); shell = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL); assert_string_equal(shell, "/bin/ksh"); } /* Check that a FQDN is returned if the domain is FQDN-only and a * FQDN is requested */ static int test_nss_getpwnam_check_fqdn(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; errno_t ret; assert_int_equal(status, EOK); nss_test_ctx->cctx->rctx->domains[0].fqnames = false; ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); assert_int_equal(pwd.pw_uid, 124); assert_int_equal(pwd.pw_gid, 457); assert_string_equal(pwd.pw_name, "testuser_fqdn@"TEST_DOM_NAME); assert_string_equal(pwd.pw_shell, "/bin/sh"); return EOK; } void test_nss_getpwnam_fqdn(void **state) { errno_t ret; /* Prime the cache with a valid user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testuser_fqdn", 124, 457, "test user", "/home/testuser", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuser_fqdn@"TEST_DOM_NAME); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM); mock_fill_user(); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_getpwnam_check_fqdn); nss_test_ctx->cctx->rctx->domains[0].fqnames = true; ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } /* Check that a user with a space in his username is returned fine. */ static int test_nss_getpwnam_check_space(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; errno_t ret; assert_int_equal(status, EOK); ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); assert_int_equal(pwd.pw_uid, 225); assert_int_equal(pwd.pw_gid, 558); assert_string_equal(pwd.pw_name, "space user"); assert_string_equal(pwd.pw_shell, "/bin/sh"); return EOK; } void test_nss_getpwnam_space(void **state) { errno_t ret; /* Prime the cache with a valid user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "space user", 225, 558, "space user", "/home/testuser", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("space user"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM); mock_fill_user(); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_getpwnam_check_space); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } static int test_nss_getpwnam_check_space_sub(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; errno_t ret; assert_int_equal(status, EOK); ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); assert_int_equal(pwd.pw_uid, 225); assert_int_equal(pwd.pw_gid, 558); assert_string_equal(pwd.pw_name, "space_user"); assert_string_equal(pwd.pw_shell, "/bin/sh"); return EOK; } void test_nss_getpwnam_space_sub(void **state) { errno_t ret; /* Set whitespace substitution */ nss_test_ctx->rctx->override_space = '_'; mock_input_user_or_group("space user"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM); mock_fill_user(); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_getpwnam_check_space_sub); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); nss_test_ctx->rctx->override_space = '\0'; assert_int_equal(ret, EOK); } void test_nss_getpwnam_space_sub_query(void **state) { errno_t ret; /* Set whitespace substitution */ nss_test_ctx->rctx->override_space = '_'; mock_input_user_or_group("space_user"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM); mock_fill_user(); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_getpwnam_check_space_sub); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); nss_test_ctx->rctx->override_space = '\0'; assert_int_equal(ret, EOK); } /* * Check that FQDN processing is able to handle arbitrarily sized * delimeter */ static int test_nss_getpwnam_check_fancy_fqdn(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; errno_t ret; assert_int_equal(status, EOK); nss_test_ctx->cctx->rctx->domains[0].fqnames = false; ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); assert_int_equal(pwd.pw_uid, 125); assert_int_equal(pwd.pw_gid, 458); assert_string_equal(pwd.pw_name, "testuser_fqdn_fancy@@@@@"TEST_DOM_NAME); assert_string_equal(pwd.pw_shell, "/bin/sh"); return EOK; } void test_nss_getpwnam_fqdn_fancy(void **state) { errno_t ret; /* Prime the cache with a valid user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testuser_fqdn_fancy", 125, 458, "test user", "/home/testuser", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuser_fqdn_fancy@"TEST_DOM_NAME); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM); mock_fill_user(); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_getpwnam_check_fancy_fqdn); nss_test_ctx->cctx->rctx->domains[0].fqnames = true; ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } /* Check getting cached and valid id from cache. Account callback will * not be called and test_nss_getpwuid_check will make sure the id is * the same as the test entered before starting */ static int test_nss_getpwuid_check(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; errno_t ret; assert_int_equal(status, EOK); ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); assert_int_equal(pwd.pw_uid, 101); assert_int_equal(pwd.pw_gid, 401); assert_string_equal(pwd.pw_name, "testuser1"); assert_string_equal(pwd.pw_shell, "/bin/sh"); assert_string_equal(pwd.pw_passwd, "*"); return EOK; } void test_nss_getpwuid(void **state) { errno_t ret; /* Prime the cache with a valid user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testuser1", 101, 401, "test user1", "/home/testuser1", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); uint32_t id = 101; mock_input_id(nss_test_ctx, id); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID); mock_fill_user(); /* Query for that id, call a callback when command finishes */ set_cmd_cb(test_nss_getpwuid_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } /* Test that searching for a nonexistent id yields ENOENT. * Account callback will be called */ void test_nss_getpwuid_neg(void **state) { errno_t ret; uint8_t id = 102; mock_input_id(nss_test_ctx, id); mock_account_recv_simple(); assert_int_equal(nss_test_ctx->ncache_hits, 0); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_int_equal(nss_test_ctx->ncache_hits, 0); /* Test that subsequent search for a nonexistent id yields * ENOENT and Account callback is not called, on the other hand * the ncache functions will be called */ nss_test_ctx->tctx->done = false; mock_input_id(nss_test_ctx, id); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); /* Negative cache was hit this time */ assert_int_equal(nss_test_ctx->ncache_hits, 1); } static int test_nss_getpwuid_search_acct_cb(void *pvt) { errno_t ret; struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx); ret = sysdb_add_user(ctx->tctx->dom, "exampleuser_search", 107, 987, "example search", "/home/examplesearch", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); return EOK; } static int test_nss_getpwuid_search_check(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; errno_t ret; assert_int_equal(status, EOK); ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); assert_int_equal(pwd.pw_uid, 107); assert_int_equal(pwd.pw_gid, 987); assert_string_equal(pwd.pw_name, "exampleuser_search"); assert_string_equal(pwd.pw_shell, "/bin/sh"); return EOK; } void test_nss_getpwuid_search(void **state) { errno_t ret; struct ldb_result *res; uint8_t id = 107; mock_input_id(nss_test_ctx, id); mock_account_recv(0, 0, NULL, test_nss_getpwuid_search_acct_cb, nss_test_ctx); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID); mock_fill_user(); set_cmd_cb(test_nss_getpwuid_search_check); ret = sysdb_getpwuid(nss_test_ctx, nss_test_ctx->tctx->dom, 107, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); /* test_nss_getpwuid_search_check will check the id attributes */ ret = sysdb_getpwuid(nss_test_ctx, nss_test_ctx->tctx->dom, 107, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); } /* Test that searching for an id that is expired in the cache goes to the DP * which updates the record and the NSS responder returns the updated record * * The user's shell attribute is updated. */ static int test_nss_getpwuid_update_acct_cb(void *pvt) { errno_t ret; struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx); ret = sysdb_store_user(ctx->tctx->dom, "exampleuser_update", NULL, 109, 11000, "example user", "/home/exampleuser", "/bin/ksh", NULL, NULL, NULL, 300, 0); assert_int_equal(ret, EOK); return EOK; } static int test_nss_getpwuid_update_check(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; errno_t ret; assert_int_equal(status, EOK); ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); assert_int_equal(pwd.pw_uid, 109); assert_int_equal(pwd.pw_gid, 11000); assert_string_equal(pwd.pw_name, "exampleuser_update"); assert_string_equal(pwd.pw_shell, "/bin/ksh"); return EOK; } void test_nss_getpwuid_update(void **state) { errno_t ret; struct ldb_result *res; const char *shell; /* Prime the cache with a valid but expired user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "exampleuser_update", 109, 11000, "example user", "/home/exampleuser", "/bin/sh", NULL, NULL, 1, 1); assert_int_equal(ret, EOK); /* Mock client input */ uint8_t id = 109; mock_input_id(nss_test_ctx, id); /* Mock client command */ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID); /* Call this function when id is updated by the mock DP request */ mock_account_recv(0, 0, NULL, test_nss_getpwuid_update_acct_cb, nss_test_ctx); /* Call this function to check what the responder returned to the client */ set_cmd_cb(test_nss_getpwuid_update_check); /* Mock output buffer */ mock_fill_user(); /* Fire the command */ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); /* Check the user was updated in the cache */ ret = sysdb_getpwuid(nss_test_ctx, nss_test_ctx->tctx->dom, 109, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); shell = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL); assert_string_equal(shell, "/bin/ksh"); } /* Testsuite setup and teardown */ void test_nss_setup(struct sss_test_conf_param params[], void **state) { errno_t ret; nss_test_ctx = talloc_zero(NULL, struct nss_test_ctx); assert_non_null(nss_test_ctx); nss_test_ctx->tctx = create_dom_test_ctx(nss_test_ctx, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, params); assert_non_null(nss_test_ctx->tctx); nss_test_ctx->tctx->dom->domain_id = discard_const(TEST_DOM_SID); nss_test_ctx->nss_cmds = get_nss_cmds(); assert_non_null(nss_test_ctx->nss_cmds); /* FIXME - perhaps this should be folded into sssd_domain_init or stricty * used together */ ret = sss_names_init(nss_test_ctx, nss_test_ctx->tctx->confdb, TEST_DOM_NAME, &nss_test_ctx->tctx->dom->names); assert_int_equal(ret, EOK); /* Initialize the NSS responder */ nss_test_ctx->nctx = mock_nctx(nss_test_ctx); assert_non_null(nss_test_ctx->nctx); ret = sss_ad_default_names_ctx(nss_test_ctx->nctx, &nss_test_ctx->nctx->global_names); assert_int_equal(ret, EOK); assert_non_null(nss_test_ctx->nctx->global_names); nss_test_ctx->rctx = mock_rctx(nss_test_ctx, nss_test_ctx->tctx->ev, nss_test_ctx->tctx->dom, nss_test_ctx->nctx); assert_non_null(nss_test_ctx->rctx); nss_test_ctx->rctx->cdb = nss_test_ctx->tctx->confdb; nss_test_ctx->nctx->rctx = nss_test_ctx->rctx; /* Create client context */ nss_test_ctx->cctx = mock_cctx(nss_test_ctx, nss_test_ctx->rctx); assert_non_null(nss_test_ctx->cctx); } static int test_nss_getgrnam_check(struct group *expected, struct group *gr, const int nmem) { int i; assert_int_equal(gr->gr_gid, expected->gr_gid); assert_string_equal(gr->gr_name, expected->gr_name); assert_string_equal(gr->gr_passwd, expected->gr_passwd); for (i = 0; i < nmem; i++) { assert_string_equal(gr->gr_mem[i], expected->gr_mem[i]); } return EOK; } static int test_nss_getgrnam_no_members_check(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; struct group expected = { .gr_gid = 1123, .gr_name = discard_const("testgroup"), .gr_passwd = discard_const("*"), .gr_mem = NULL, }; assert_int_equal(status, EOK); ret = parse_group_packet(body, blen, &gr, &nmem); assert_int_equal(ret, EOK); assert_int_equal(nmem, 0); ret = test_nss_getgrnam_check(&expected, &gr, nmem); assert_int_equal(ret, EOK); return EOK; } /* Test that requesting a valid, cached group with no members returns a valid * group structure */ void test_nss_getgrnam_no_members(void **state) { errno_t ret; /* Prime the cache with a valid group */ ret = sysdb_add_group(nss_test_ctx->tctx->dom, "testgroup", 1123, NULL, 300, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testgroup"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM); mock_fill_group_with_members(0); /* Query for that group, call a callback when command finishes */ set_cmd_cb(test_nss_getgrnam_no_members_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } static int test_nss_getgrnam_members_check(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; const char *exp_members[] = { "testmember1", "testmember2" }; struct group expected = { .gr_gid = 1124, .gr_name = discard_const("testgroup_members"), .gr_passwd = discard_const("*"), .gr_mem = discard_const(exp_members) }; assert_int_equal(status, EOK); ret = parse_group_packet(body, blen, &gr, &nmem); assert_int_equal(ret, EOK); assert_int_equal(nmem, 2); ret = test_nss_getgrnam_check(&expected, &gr, nmem); assert_int_equal(ret, EOK); return EOK; } /* Test that requesting a valid, cached group with some members returns a valid * group structure with those members present */ void test_nss_getgrnam_members(void **state) { errno_t ret; /* Prime the cache with a valid group and some members */ ret = sysdb_add_group(nss_test_ctx->tctx->dom, "testgroup_members", 1124, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testmember1", 2001, 456, "test member1", "/home/testmember2", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testmember2", 2002, 456, "test member2", "/home/testmember2", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, "testgroup_members", "testmember1", SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, "testgroup_members", "testmember2", SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); mock_input_user_or_group("testgroup_members"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM); mock_fill_group_with_members(2); /* Query for that group, call a callback when command finishes */ set_cmd_cb(test_nss_getgrnam_members_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } static int test_nss_getgrnam_members_check_fqdn(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; const char *exp_members[] = { "testmember1@"TEST_DOM_NAME, "testmember2@"TEST_DOM_NAME }; struct group expected = { .gr_gid = 1124, .gr_name = discard_const("testgroup_members@"TEST_DOM_NAME), .gr_passwd = discard_const("*"), .gr_mem = discard_const(exp_members) }; assert_int_equal(status, EOK); ret = parse_group_packet(body, blen, &gr, &nmem); assert_int_equal(ret, EOK); assert_int_equal(nmem, 2); ret = test_nss_getgrnam_check(&expected, &gr, nmem); assert_int_equal(ret, EOK); return EOK; } /* Test that requesting a valid, cached group with some members returns a valid * group structure with those members present as fully qualified names */ void test_nss_getgrnam_members_fqdn(void **state) { errno_t ret; nss_test_ctx->tctx->dom->fqnames = true; mock_input_user_or_group("testgroup_members@"TEST_DOM_NAME); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM); mock_fill_group_with_members(2); /* Query for that group, call a callback when command finishes */ set_cmd_cb(test_nss_getgrnam_members_check_fqdn); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); /* Restore FQDN settings */ nss_test_ctx->tctx->dom->fqnames = false; assert_int_equal(ret, EOK); } static int test_nss_getgrnam_members_check_subdom(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; const char *exp_members[] = { "submember1@"TEST_SUBDOM_NAME, "submember2@"TEST_SUBDOM_NAME }; struct group expected = { .gr_gid = 2124, .gr_name = discard_const("testsubdomgroup@"TEST_SUBDOM_NAME), .gr_passwd = discard_const("*"), .gr_mem = discard_const(exp_members) }; assert_int_equal(status, EOK); ret = parse_group_packet(body, blen, &gr, &nmem); assert_int_equal(ret, EOK); assert_int_equal(nmem, 2); ret = test_nss_getgrnam_check(&expected, &gr, nmem); assert_int_equal(ret, EOK); return EOK; } /* Test that requesting a valid, cached group with some members returns a valid * group structure with those members present as fully qualified names */ void test_nss_getgrnam_members_subdom(void **state) { errno_t ret; nss_test_ctx->tctx->dom->fqnames = true; /* Add a group from a subdomain and two members from the same subdomain */ ret = sysdb_add_group(nss_test_ctx->subdom, "testsubdomgroup@"TEST_SUBDOM_NAME, 2124, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_user(nss_test_ctx->subdom, "submember1@"TEST_SUBDOM_NAME, 4001, 456, "test subdomain member1", "/home/submember1", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_user(nss_test_ctx->subdom, "submember2@"TEST_SUBDOM_NAME, 2002, 456, "test subdomain member2", "/home/submember2", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->subdom, "testsubdomgroup@"TEST_SUBDOM_NAME, "submember1@"TEST_SUBDOM_NAME, SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->subdom, "testsubdomgroup@"TEST_SUBDOM_NAME, "submember2@"TEST_SUBDOM_NAME, SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); mock_input_user_or_group("testsubdomgroup@"TEST_SUBDOM_NAME); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM); mock_fill_group_with_members(2); /* Query for that group, call a callback when command finishes */ set_cmd_cb(test_nss_getgrnam_members_check_subdom); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); /* Restore FQDN settings */ nss_test_ctx->tctx->dom->fqnames = false; assert_int_equal(ret, EOK); } static int test_nss_getgrnam_check_mix_dom(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; const char *exp_members[] = { "testmember1", "testmember2", "submember1@"TEST_SUBDOM_NAME }; struct group expected = { .gr_gid = 1124, .gr_name = discard_const("testgroup_members"), .gr_passwd = discard_const("*"), .gr_mem = discard_const(exp_members) }; assert_int_equal(status, EOK); ret = parse_group_packet(body, blen, &gr, &nmem); assert_int_equal(ret, EOK); assert_int_equal(nmem, 3); ret = test_nss_getgrnam_check(&expected, &gr, nmem); assert_int_equal(ret, EOK); return EOK; } void test_nss_getgrnam_mix_dom(void **state) { errno_t ret; const char *group_strdn = NULL; const char *add_groups[] = { NULL, NULL }; /* Add a subdomain user to a parent domain group */ group_strdn = sysdb_group_strdn(nss_test_ctx, nss_test_ctx->tctx->dom->name, "testgroup_members"); assert_non_null(group_strdn); add_groups[0] = group_strdn; ret = sysdb_update_members_dn(nss_test_ctx->subdom, "submember1@"TEST_SUBDOM_NAME, SYSDB_MEMBER_USER, add_groups, NULL); assert_int_equal(ret, EOK); mock_input_user_or_group("testgroup_members"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM); mock_fill_group_with_members(3); /* Query for that group, call a callback when command finishes */ set_cmd_cb(test_nss_getgrnam_check_mix_dom); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } static int test_nss_getgrnam_check_mix_dom_fqdn(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; const char *exp_members[] = { "testmember1@"TEST_DOM_NAME, "testmember2@"TEST_DOM_NAME, "submember1@"TEST_SUBDOM_NAME }; struct group expected = { .gr_gid = 1124, .gr_name = discard_const("testgroup_members@"TEST_DOM_NAME), .gr_passwd = discard_const("*"), .gr_mem = discard_const(exp_members) }; assert_int_equal(status, EOK); ret = parse_group_packet(body, blen, &gr, &nmem); assert_int_equal(ret, EOK); assert_int_equal(nmem, 3); ret = test_nss_getgrnam_check(&expected, &gr, nmem); assert_int_equal(ret, EOK); return EOK; } void test_nss_getgrnam_mix_dom_fqdn(void **state) { errno_t ret; nss_test_ctx->tctx->dom->fqnames = true; mock_input_user_or_group("testgroup_members@"TEST_DOM_NAME); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM); mock_fill_group_with_members(3); /* Query for that group, call a callback when command finishes */ set_cmd_cb(test_nss_getgrnam_check_mix_dom_fqdn); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); /* Restore FQDN settings */ nss_test_ctx->tctx->dom->fqnames = false; assert_int_equal(ret, EOK); } static int test_nss_getgrnam_check_mix_subdom(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; const char *exp_members[] = { "submember1@"TEST_SUBDOM_NAME, "submember2@"TEST_SUBDOM_NAME, "testmember1@"TEST_DOM_NAME }; struct group expected = { .gr_gid = 2124, .gr_name = discard_const("testsubdomgroup@"TEST_SUBDOM_NAME), .gr_passwd = discard_const("*"), .gr_mem = discard_const(exp_members) }; assert_int_equal(status, EOK); ret = parse_group_packet(body, blen, &gr, &nmem); assert_int_equal(ret, EOK); assert_int_equal(nmem, 3); ret = test_nss_getgrnam_check(&expected, &gr, nmem); assert_int_equal(ret, EOK); return EOK; } void test_nss_getgrnam_mix_subdom(void **state) { errno_t ret; const char *group_strdn = NULL; const char *add_groups[] = { NULL, NULL }; /* Add a subdomain user to a parent domain group */ group_strdn = sysdb_group_strdn(nss_test_ctx, nss_test_ctx->subdom->name, "testsubdomgroup@"TEST_SUBDOM_NAME); assert_non_null(group_strdn); add_groups[0] = group_strdn; ret = sysdb_update_members_dn(nss_test_ctx->tctx->dom, "testmember1", SYSDB_MEMBER_USER, add_groups, NULL); assert_int_equal(ret, EOK); mock_input_user_or_group("testsubdomgroup@"TEST_SUBDOM_NAME); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM); mock_fill_group_with_members(3); /* Query for that group, call a callback when command finishes */ set_cmd_cb(test_nss_getgrnam_check_mix_subdom); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } static int test_nss_getgrnam_space_check(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; struct group expected = { .gr_gid = 2123, .gr_name = discard_const("space group"), .gr_passwd = discard_const("*"), .gr_mem = NULL, }; assert_int_equal(status, EOK); ret = parse_group_packet(body, blen, &gr, &nmem); assert_int_equal(ret, EOK); assert_int_equal(nmem, 0); ret = test_nss_getgrnam_check(&expected, &gr, nmem); assert_int_equal(ret, EOK); return EOK; } /* Test that requesting a valid, cached group with space in its name returns a valid * group structure */ void test_nss_getgrnam_space(void **state) { errno_t ret; /* Prime the cache with a valid group */ ret = sysdb_add_group(nss_test_ctx->tctx->dom, "space group", 2123, NULL, 300, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("space group"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM); mock_fill_group_with_members(0); /* Query for that group, call a callback when command finishes */ set_cmd_cb(test_nss_getgrnam_space_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } static int test_nss_getgrnam_space_sub_check(uint32_t status, uint8_t *body, size_t blen) { int ret; uint32_t nmem; struct group gr; struct group expected = { .gr_gid = 2123, .gr_name = discard_const("space_group"), .gr_passwd = discard_const("*"), .gr_mem = NULL, }; assert_int_equal(status, EOK); ret = parse_group_packet(body, blen, &gr, &nmem); assert_int_equal(ret, EOK); assert_int_equal(nmem, 0); ret = test_nss_getgrnam_check(&expected, &gr, nmem); assert_int_equal(ret, EOK); return EOK; } /* Test that requesting a valid, cached group with space in its name returns a valid * group structure */ void test_nss_getgrnam_space_sub(void **state) { errno_t ret; /* Set whitespace substitution */ nss_test_ctx->rctx->override_space = '_'; mock_input_user_or_group("space group"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM); mock_fill_group_with_members(0); /* Query for that group, call a callback when command finishes */ set_cmd_cb(test_nss_getgrnam_space_sub_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); nss_test_ctx->rctx->override_space = '\0'; assert_int_equal(ret, EOK); } static int test_nss_well_known_sid_check(uint32_t status, uint8_t *body, size_t blen) { const char *name; enum sss_id_type type; size_t rp = 2 * sizeof(uint32_t); char *expected_result = sss_mock_ptr_type(char *); if (expected_result == NULL) { assert_int_equal(status, EINVAL); assert_int_equal(blen, 0); } else { assert_int_equal(status, EOK); SAFEALIGN_COPY_UINT32(&type, body+rp, &rp); name = (char *) body+rp; assert_int_equal(type, SSS_ID_TYPE_GID); assert_string_equal(name, expected_result); } return EOK; } void test_nss_well_known_getnamebysid(void **state) { errno_t ret; will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, "S-1-5-32-550"); will_return(__wrap_sss_packet_get_body, 0); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); will_return(test_nss_well_known_sid_check, "Print Operators@BUILTIN"); set_cmd_cb(test_nss_well_known_sid_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_nss_well_known_getnamebysid_special(void **state) { errno_t ret; will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, "S-1-2-0"); will_return(__wrap_sss_packet_get_body, 0); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); will_return(test_nss_well_known_sid_check, "LOCAL@LOCAL AUTHORITY"); set_cmd_cb(test_nss_well_known_sid_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_nss_well_known_getnamebysid_non_existing(void **state) { errno_t ret; will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, "S-1-5-32-123"); will_return(__wrap_sss_packet_get_body, 0); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID); will_return(test_nss_well_known_sid_check, NULL); set_cmd_cb(test_nss_well_known_sid_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_nss_well_known_getidbysid_failure(void **state) { errno_t ret; will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, "S-1-5-32-550"); will_return(__wrap_sss_packet_get_body, 0); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETIDBYSID); will_return(test_nss_well_known_sid_check, NULL); set_cmd_cb(test_nss_well_known_sid_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETIDBYSID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_nss_well_known_getsidbyname(void **state) { errno_t ret; const char *names[] = { "Cryptographic Operators@BUILTIN", "BUILTIN\\Cryptographic Operators", NULL}; size_t c; for (c = 0; names[c] != NULL; c++) { will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, names[c]); will_return(__wrap_sss_packet_get_body, 0); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETSIDBYNAME); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); will_return(test_nss_well_known_sid_check, "S-1-5-32-569"); set_cmd_cb(test_nss_well_known_sid_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETSIDBYNAME, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } } void test_nss_well_known_getsidbyname_nonexisting(void **state) { errno_t ret; const char *names[] = { "Abc@BUILTIN", "BUILTIN\\Abc", NULL }; size_t c; for (c = 0; names[c] != NULL; c++) { will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, names[c]); will_return(__wrap_sss_packet_get_body, 0); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETSIDBYNAME); will_return(test_nss_well_known_sid_check, NULL); set_cmd_cb(test_nss_well_known_sid_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETSIDBYNAME, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } } void test_nss_well_known_getsidbyname_special(void **state) { errno_t ret; const char *names[] = { "CREATOR OWNER@CREATOR AUTHORITY", "CREATOR AUTHORITY\\CREATOR OWNER", NULL }; size_t c; for (c = 0; names[c] != NULL; c++) { will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, names[c]); will_return(__wrap_sss_packet_get_body, 0); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETSIDBYNAME); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); will_return(test_nss_well_known_sid_check, "S-1-3-0"); set_cmd_cb(test_nss_well_known_sid_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETSIDBYNAME, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } } static int test_nss_getorigbyname_check(uint32_t status, uint8_t *body, size_t blen) { const char *s; enum sss_id_type id_type; size_t rp = 2 * sizeof(uint32_t); assert_int_equal(status, EOK); SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp); assert_int_equal(id_type, SSS_ID_TYPE_UID); /* Sequence of null terminated strings */ s = (char *) body+rp; assert_string_equal(s, SYSDB_SID_STR); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "S-1-2-3-4"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_NAME); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "orig_name"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_UIDNUM); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "1234"); rp += strlen(s) + 1; assert_int_equal(rp, blen); return EOK; } void test_nss_getorigbyname(void **state) { errno_t ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, "S-1-2-3-4"); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(attrs, ORIGINALAD_PREFIX SYSDB_NAME, "orig_name"); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_uint32(attrs, ORIGINALAD_PREFIX SYSDB_UIDNUM, 1234); assert_int_equal(ret, EOK); /* Prime the cache with a valid user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testuserorig", 1234, 5689, "test user orig", "/home/testuserorig", "/bin/sh", NULL, attrs, 300, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuserorig"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETORIGBYNAME); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_getorigbyname_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETORIGBYNAME, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } static int test_nss_getorigbyname_extra_check(uint32_t status, uint8_t *body, size_t blen) { const char *s; enum sss_id_type id_type; size_t rp = 2 * sizeof(uint32_t); assert_int_equal(status, EOK); SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp); assert_int_equal(id_type, SSS_ID_TYPE_UID); /* Sequence of null terminated strings */ s = (char *) body+rp; assert_string_equal(s, SYSDB_SID_STR); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "S-1-2-3-4"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_NAME); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "orig_name"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_UIDNUM); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "1234"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "phone"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "+12-34 56 78"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "mobile"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "+98-76 54 32"); rp += strlen(s) + 1; assert_int_equal(rp, blen); return EOK; } void test_nss_getorigbyname_extra_attrs(void **state) { errno_t ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, "S-1-2-3-4"); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(attrs, ORIGINALAD_PREFIX SYSDB_NAME, "orig_name"); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_uint32(attrs, ORIGINALAD_PREFIX SYSDB_UIDNUM, 1234); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(attrs, "phone", "+12-34 56 78"); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(attrs, "mobile", "+98-76 54 32"); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(attrs, "not_extra", "abc"); assert_int_equal(ret, EOK); /* Prime the cache with a valid user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testuserorigextra", 2345, 6789, "test user orig extra", "/home/testuserorigextra", "/bin/sh", NULL, attrs, 300, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuserorigextra"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETORIGBYNAME); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_getorigbyname_extra_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETORIGBYNAME, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } static int test_nss_getorigbyname_multi_check(uint32_t status, uint8_t *body, size_t blen) { const char *s; enum sss_id_type id_type; size_t rp = 2 * sizeof(uint32_t); assert_int_equal(status, EOK); SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp); assert_int_equal(id_type, SSS_ID_TYPE_UID); /* Sequence of null terminated strings */ s = (char *) body+rp; assert_string_equal(s, SYSDB_SID_STR); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "S-1-2-3-4"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_NAME); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "orig_name"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, ORIGINALAD_PREFIX SYSDB_UIDNUM); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "1234"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, SYSDB_ORIG_MEMBEROF); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "cn=abc"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, SYSDB_ORIG_MEMBEROF); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "cn=def"); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, SYSDB_ORIG_MEMBEROF); rp += strlen(s) + 1; assert_true(rp < blen); s = (char *) body+rp; assert_string_equal(s, "cn=123"); rp += strlen(s) + 1; assert_int_equal(rp, blen); return EOK; } void test_nss_getorigbyname_multi_value_attrs(void **state) { errno_t ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, "S-1-2-3-4"); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(attrs, ORIGINALAD_PREFIX SYSDB_NAME, "orig_name"); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_uint32(attrs, ORIGINALAD_PREFIX SYSDB_UIDNUM, 1234); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_MEMBEROF, "cn=abc"); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_MEMBEROF, "cn=def"); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_MEMBEROF, "cn=123"); assert_int_equal(ret, EOK); /* Prime the cache with a valid user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testuserorigmulti", 3456, 7890, "test user orig multi value", "/home/testuserorigextra", "/bin/sh", NULL, attrs, 300, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("testuserorigmulti"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETORIGBYNAME); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_getorigbyname_multi_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETORIGBYNAME, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } static int test_nss_getpwnam_upn_check(uint32_t status, uint8_t *body, size_t blen) { struct passwd pwd; errno_t ret; assert_int_equal(status, EOK); ret = parse_user_packet(body, blen, &pwd); assert_int_equal(ret, EOK); assert_int_equal(pwd.pw_uid, 34567); assert_int_equal(pwd.pw_gid, 45678); assert_string_equal(pwd.pw_name, "upnuser"); assert_string_equal(pwd.pw_shell, "/bin/sh"); assert_string_equal(pwd.pw_passwd, "*"); return EOK; } void test_nss_getpwnam_upn(void **state) { errno_t ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, "upnuser@upndomain.test"); assert_int_equal(ret, EOK); /* Prime the cache with a valid user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "upnuser", 34567, 45678, "up user", "/home/upnuser", "/bin/sh", NULL, attrs, 300, 0); assert_int_equal(ret, EOK); mock_input_user_or_group("upnuser@upndomain.test"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM); mock_fill_user(); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_getpwnam_upn_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } /* Test that searching for a nonexistant user yields ENOENT. * Account callback will be called */ void test_nss_getpwnam_upn_neg(void **state) { errno_t ret; mock_input_user_or_group("nosuchupnuser@upndomain.test"); mock_account_recv_simple(); assert_int_equal(nss_test_ctx->ncache_hits, 0); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_int_equal(nss_test_ctx->ncache_hits, 1); /* Test that subsequent search for a nonexistent user yields * ENOENT and Account callback is not called, on the other hand * the ncache functions will be called */ nss_test_ctx->tctx->done = false; nss_test_ctx->ncache_hits = 0; mock_input_user_or_group("nosuchupnuser@upndomain.test"); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); /* Negative cache was hit this time */ assert_int_equal(nss_test_ctx->ncache_hits, 1); } static int test_nss_initgr_check(uint32_t status, uint8_t *body, size_t blen) { gid_t expected_gids[] = { 3211, 3212 }; assert_int_equal(status, EOK); check_initgr_packet(body, blen, expected_gids, N_ELEMENTS(expected_gids)); return EOK; } void test_nss_initgroups(void **state) { errno_t ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, time(NULL) + 300); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, "upninitgr@upndomain.test"); assert_int_equal(ret, EOK); ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testinitgr", 321, 654, "test initgroups", "/home/testinitgr", "/bin/sh", NULL, attrs, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group(nss_test_ctx->tctx->dom, "testinitgr_gr1", 3211, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group(nss_test_ctx->tctx->dom, "testinitgr_gr2", 3212, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, "testinitgr_gr1", "testinitgr", SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, "testinitgr_gr2", "testinitgr", SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); mock_input_user_or_group("testinitgr"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR); mock_fill_initgr_user(); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_initgr_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } /* Test that searching for a nonexistant user yields ENOENT. * Account callback will be called */ void test_initgr_neg_by_name(const char *name, bool is_upn) { errno_t ret; mock_input_user_or_group(name); mock_account_recv_simple(); assert_int_equal(nss_test_ctx->ncache_hits, 0); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); /* UPN lookup will first hit negcache with the username */ assert_int_equal(nss_test_ctx->ncache_hits, is_upn ? 1 : 0); /* Test that subsequent search for a nonexistent user yields * ENOENT and Account callback is not called, on the other hand * the ncache functions will be called */ nss_test_ctx->tctx->done = false; nss_test_ctx->ncache_hits = 0; mock_input_user_or_group(name); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); /* Negative cache was hit this time */ assert_int_equal(nss_test_ctx->ncache_hits, 1); } void test_nss_initgr_neg(void **state) { test_initgr_neg_by_name("testinitgr_neg", false); } static int test_nss_initgr_search_acct_cb(void *pvt) { errno_t ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, time(NULL) + 300); assert_int_equal(ret, EOK); ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testinitgr_srch", 421, 654, "test initgroups", "/home/testinitgr", "/bin/sh", NULL, attrs, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group(nss_test_ctx->tctx->dom, "testinitgr_srch_gr1", 4211, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group(nss_test_ctx->tctx->dom, "testinitgr_srch_gr2", 4212, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, "testinitgr_srch_gr1", "testinitgr_srch", SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, "testinitgr_srch_gr2", "testinitgr_srch", SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); return EOK; } static int test_nss_initgr_search_check(uint32_t status, uint8_t *body, size_t blen) { gid_t expected_gids[] = { 4211, 4212 }; assert_int_equal(status, EOK); check_initgr_packet(body, blen, expected_gids, N_ELEMENTS(expected_gids)); return EOK; } void test_nss_initgr_search(void **state) { errno_t ret; struct ldb_result *res; mock_input_user_or_group("testinitgr_srch"); mock_account_recv(0, 0, NULL, test_nss_initgr_search_acct_cb, nss_test_ctx); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR); mock_fill_initgr_user(); set_cmd_cb(test_nss_initgr_search_check); ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, "testinitgr_srch", &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); /* test_nss_getpwnam_search_check will check the user attributes */ ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, "testinitgr_srch", &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); } static int test_nss_initgr_update_acct_cb(void *pvt) { errno_t ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, time(NULL) + 300); assert_int_equal(ret, EOK); ret = sysdb_set_user_attr(nss_test_ctx->tctx->dom, "testinitgr_update", attrs, SYSDB_MOD_REP); assert_int_equal(ret, EOK); ret = sysdb_add_group(nss_test_ctx->tctx->dom, "testinitgr_check_gr2", 5212, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, "testinitgr_check_gr2", "testinitgr_update", SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); return EOK; } static int test_nss_initgr_update_check(uint32_t status, uint8_t *body, size_t blen) { gid_t expected_gids[] = { 5211, 5212 }; assert_int_equal(status, EOK); check_initgr_packet(body, blen, expected_gids, N_ELEMENTS(expected_gids)); return EOK; } void test_nss_initgr_update(void **state) { errno_t ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, time(NULL) - 1); assert_int_equal(ret, EOK); ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testinitgr_update", 521, 654, "test initgroups", "/home/testinitgr", "/bin/sh", NULL, attrs, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group(nss_test_ctx->tctx->dom, "testinitgr_update_gr1", 5211, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, "testinitgr_update_gr1", "testinitgr_update", SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); mock_input_user_or_group("testinitgr_update"); mock_account_recv(0, 0, NULL, test_nss_initgr_update_acct_cb, nss_test_ctx); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR); mock_fill_initgr_user(); set_cmd_cb(test_nss_initgr_update_check); /* Query for that user, call a callback when command finishes */ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } static int test_nss_initgr_update_acct_2expire_attributes_cb(void *pvt) { errno_t ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, time(NULL) + 300); assert_int_equal(ret, EOK); ret = sysdb_set_user_attr(nss_test_ctx->tctx->dom, "testinitgr_2attr", attrs, SYSDB_MOD_REP); assert_int_equal(ret, EOK); ret = sysdb_add_group(nss_test_ctx->tctx->dom, "testinitgr_2attr_gr12", 5222, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, "testinitgr_2attr_gr12", "testinitgr_2attr", SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); return EOK; } static int test_nss_initgr_update_2expire_attributes_check(uint32_t status, uint8_t *body, size_t blen) { gid_t expected_gids[] = { 5221, 5222 }; assert_int_equal(status, EOK); check_initgr_packet(body, blen, expected_gids, N_ELEMENTS(expected_gids)); return EOK; } /* * SYSDB_INITGR_EXPIRE has default value 0 => initgroups was not finished. * SYSDB_CACHE_EXPIRE has value from future => getpwnam finished successfully * * Test result: DP should be contacted for update. */ void test_nss_initgr_update_two_expire_attributes(void **state) { errno_t ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, 0); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, time(NULL) + 100); assert_int_equal(ret, EOK); ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testinitgr_2attr", 522, 655, "test initgroups2", "/home/testinitgr_2attr", "/bin/sh", NULL, attrs, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group(nss_test_ctx->tctx->dom, "testinitgr_2attr_gr11", 5221, NULL, 300, 0); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(nss_test_ctx->tctx->dom, "testinitgr_2attr_gr11", "testinitgr_2attr", SYSDB_MEMBER_USER, false); assert_int_equal(ret, EOK); mock_input_user_or_group("testinitgr_2attr"); mock_account_recv(0, 0, NULL, test_nss_initgr_update_acct_2expire_attributes_cb, nss_test_ctx); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR); mock_fill_initgr_user(); set_cmd_cb(test_nss_initgr_update_2expire_attributes_check); /* Query for that user, call a callback when command finishes */ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_nss_initgroups_upn(void **state) { errno_t ret; mock_input_user_or_group("upninitgr@upndomain.test"); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR); mock_fill_initgr_user(); /* Query for that user, call a callback when command finishes */ set_cmd_cb(test_nss_initgr_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } /* Test that searching for a nonexistant user yields ENOENT. * Account callback will be called */ void test_nss_initgr_neg_upn(void **state) { test_initgr_neg_by_name("upninitgr_neg@upndomain.test", true); } static int nss_test_setup(void **state) { struct sss_test_conf_param params[] = { { "enumerate", "false" }, { NULL, NULL }, /* Sentinel */ }; test_nss_setup(params, state); return 0; } static int nss_fqdn_test_setup(void **state) { struct sss_test_conf_param params[] = { { "enumerate", "false" }, { "full_name_format", "%1$s@%2$s" }, { NULL, NULL }, /* Sentinel */ }; test_nss_setup(params, state); return 0; } static int nss_test_setup_extra_attr(void **state) { struct sss_test_conf_param params[] = { { "enumerate", "false" }, { NULL, NULL }, /* Sentinel */ }; test_nss_setup(params, state); nss_test_ctx->nctx->extra_attributes = global_extra_attrs; return 0; } static int nss_subdom_test_setup(void **state) { const char *const testdom[4] = { TEST_SUBDOM_NAME, "TEST.SUB", "test", "S-3" }; struct sss_domain_info *subdomain; errno_t ret; nss_test_setup(state); subdomain = new_subdomain(nss_test_ctx, nss_test_ctx->tctx->dom, testdom[0], testdom[1], testdom[2], testdom[3], false, false, NULL, 0); assert_non_null(subdomain); ret = sysdb_subdomain_store(nss_test_ctx->tctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[3], false, false, NULL, 0); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(nss_test_ctx->tctx->dom); assert_int_equal(ret, EOK); nss_test_ctx->subdom = subdomain; return 0; } static int nss_fqdn_fancy_test_setup(void **state) { struct sss_test_conf_param params[] = { { "enumerate", "false" }, { "full_name_format", "%1$s@@@@@%2$s" }, { NULL, NULL }, /* Sentinel */ }; test_nss_setup(params, state); return 0; } static int nss_test_teardown(void **state) { talloc_free(nss_test_ctx); return 0; } static int test_nss_getnamebysid_check(uint32_t status, uint8_t *body, size_t blen) { size_t rp = 2 * sizeof(uint32_t); /* num_results and reserved */ uint32_t id_type; const char *name; assert_int_equal(status, EOK); SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp); assert_int_equal(id_type, SSS_ID_TYPE_UID); name = (const char *) body + rp; assert_string_equal(name, "testsiduser"); return EOK; } static void test_nss_getnamebysid(void **state) { errno_t ret; struct sysdb_attrs *attrs; char *user_sid; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); user_sid = talloc_asprintf(attrs, "%s-500", nss_test_ctx->tctx->dom->domain_id); assert_non_null(user_sid); ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, user_sid); assert_int_equal(ret, EOK); /* Prime the cache with a valid user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testsiduser", 12345, 6890, "test sid user", "/home/testsiduser", "/bin/sh", NULL, attrs, 300, 0); assert_int_equal(ret, EOK); mock_input_user_or_group(user_sid); will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID); mock_fill_bysid(); /* Query for that user, call a callback when command finishes */ /* Should go straight to back end, without contacting DP */ set_cmd_cb(test_nss_getnamebysid_check); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); } /* Test that searching for a nonexistant user yields ENOENT. * Account callback will be called */ void test_nss_getnamebysid_neg(void **state) { errno_t ret; char *user_sid; user_sid = talloc_asprintf(nss_test_ctx, "%s-499", nss_test_ctx->tctx->dom->domain_id); assert_non_null(user_sid); mock_input_user_or_group(user_sid); mock_account_recv_simple(); assert_int_equal(nss_test_ctx->ncache_hits, 0); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_int_equal(nss_test_ctx->ncache_hits, 0); /* Test that subsequent search for a nonexistent user yields * ENOENT and Account callback is not called, on the other hand * the ncache functions will be called */ nss_test_ctx->tctx->done = false; mock_input_user_or_group(user_sid); ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with ENOENT */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, ENOENT); /* Negative cache was hit this time */ assert_int_equal(nss_test_ctx->ncache_hits, 1); } static int test_nss_getnamebysid_update_check(uint32_t status, uint8_t *body, size_t blen) { size_t rp = 2 * sizeof(uint32_t); /* num_results and reserved */ uint32_t id_type; const char *name; assert_int_equal(status, EOK); SAFEALIGN_COPY_UINT32(&id_type, body+rp, &rp); assert_int_equal(id_type, SSS_ID_TYPE_UID); name = (const char *) body + rp; assert_string_equal(name, "testsidbyname_update"); return EOK; } static int test_nss_getnamebysid_update_acct_cb(void *pvt) { errno_t ret; struct nss_test_ctx *ctx = talloc_get_type(pvt, struct nss_test_ctx); ret = sysdb_store_user(ctx->tctx->dom, "testsidbyname_update", NULL, 123456, 789, "test user", "/home/testsidbyname_update", "/bin/ksh", NULL, NULL, NULL, 300, 0); assert_int_equal(ret, EOK); return EOK; } void test_nss_getnamebysid_update(void **state) { errno_t ret; struct ldb_result *res; struct sysdb_attrs *attrs; const char *shell; char *user_sid; attrs = sysdb_new_attrs(nss_test_ctx); assert_non_null(attrs); user_sid = talloc_asprintf(attrs, "%s-123456", nss_test_ctx->tctx->dom->domain_id); assert_non_null(user_sid); ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, user_sid); assert_int_equal(ret, EOK); /* Prime the cache with a valid but expired user */ ret = sysdb_add_user(nss_test_ctx->tctx->dom, "testsidbyname_update", 123456, 789, "test user", "/home/testsidbyname_update", "/bin/sh", NULL, attrs, 1, 1); assert_int_equal(ret, EOK); /* Mock client input */ mock_input_user_or_group(user_sid); /* Mock client command */ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETNAMEBYSID); /* Call this function when user is updated by the mock DP request */ mock_account_recv(0, 0, NULL, test_nss_getnamebysid_update_acct_cb, nss_test_ctx); /* Call this function to check what the responder returned to the client */ set_cmd_cb(test_nss_getnamebysid_update_check); /* Mock output buffer */ mock_fill_bysid(); /* Fire the command */ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETNAMEBYSID, nss_test_ctx->nss_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(nss_test_ctx->tctx); assert_int_equal(ret, EOK); /* Check the user was updated in the cache */ ret = sysdb_getpwnam(nss_test_ctx, nss_test_ctx->tctx->dom, "testsidbyname_update", &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); shell = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL); assert_string_equal(shell, "/bin/ksh"); } int main(int argc, const char *argv[]) { int rv; int no_cleanup = 0; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_nss_getpwnam, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwuid, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwnam_neg, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwuid_neg, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwnam_search, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwuid_search, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwnam_update, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwuid_update, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwnam_fqdn, nss_fqdn_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwnam_fqdn_fancy, nss_fqdn_fancy_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwnam_space, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwnam_space_sub, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwnam_space_sub_query, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getgrnam_no_members, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getgrnam_members, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_fqdn, nss_fqdn_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getgrnam_members_subdom, nss_subdom_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom, nss_subdom_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_dom_fqdn, nss_subdom_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getgrnam_mix_subdom, nss_subdom_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getgrnam_space, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getgrnam_space_sub, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_well_known_getnamebysid, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_well_known_getnamebysid_special, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_well_known_getnamebysid_non_existing, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_well_known_getidbysid_failure, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_well_known_getsidbyname, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_well_known_getsidbyname_nonexisting, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_well_known_getsidbyname_special, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getorigbyname, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getorigbyname_extra_attrs, nss_test_setup_extra_attr, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getorigbyname_multi_value_attrs, nss_test_setup_extra_attr, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwnam_upn, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getpwnam_upn_neg, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_initgroups, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_initgr_neg, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_initgr_search, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_initgr_update, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_initgr_update_two_expire_attributes, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_initgroups_upn, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_initgr_neg_upn, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getnamebysid, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getnamebysid_neg, nss_test_setup, nss_test_teardown), cmocka_unit_test_setup_teardown(test_nss_getnamebysid_update, nss_test_setup, nss_test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0 && !no_cleanup) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); } return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_authtok.c0000644000000000000000000000007312703456111020374 xustar0030 atime=1460561751.655715644 29 ctime=1460561775.02679489 sssd-1.13.4/src/tests/cmocka/test_authtok.c0000644002412700241270000004622712703456111022057 0ustar00jhrozekjhrozek00000000000000/* SSSD authtok - Utilities tests Authors: Pallavi Jha Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "tests/cmocka/common_mock.h" #include "util/authtok.h" struct test_state { struct sss_auth_token *authtoken; }; static int setup(void **state) { struct test_state *ts = NULL; assert_true(leak_check_setup()); ts = talloc(global_talloc_context, struct test_state); assert_non_null(ts); ts->authtoken = sss_authtok_new(ts); assert_non_null(ts->authtoken); check_leaks_push(ts); *state = (void *)ts; return 0; } static int teardown(void **state) { struct test_state *ts = talloc_get_type_abort(*state, struct test_state); assert_non_null(ts); assert_true(check_leaks_pop(ts)); talloc_free(ts); assert_true(leak_check_teardown()); return 0; } static void test_sss_authtok_new(void **state) { struct test_state *ts = talloc_get_type_abort(*state, struct test_state); struct sss_auth_token *authtoken; authtoken = sss_authtok_new(ts); assert_non_null(authtoken); talloc_free(authtoken); } /* @test_authtok_type_x : tests following functions for different value of type * sss_authtok_set * sss_authtok_get_type * sss_authtok_get_size * sss_authtok_get_data * sss_authtok_get_password * sss_authtok_get_ccfile * * @test_authtok_type_password : type => SSS_AUTHTOK_TYPE_PASSWORD * @test_authtok_type_ccfile : type => SSS_AUTHTOK_TYPE_CCFILE * @test_authtok_type_empty : type => SSS_AUTHTOK_TYPE_EMPTY */ /* Test when type has value SSS_AUTHTOK_TYPE_PASSWORD */ static void test_sss_authtok_password(void **state) { size_t len; errno_t ret; char *data; size_t ret_len; const char *pwd; struct test_state *ts; enum sss_authtok_type type; ts = talloc_get_type_abort(*state, struct test_state); data = talloc_strdup(ts, "password"); assert_non_null(data); len = strlen(data) + 1; type = SSS_AUTHTOK_TYPE_PASSWORD; ret = sss_authtok_set(ts->authtoken, type, (const uint8_t *)data, len); assert_int_equal(ret, EOK); assert_int_equal(type, sss_authtok_get_type(ts->authtoken)); assert_int_equal(len, sss_authtok_get_size(ts->authtoken)); assert_string_equal(data, sss_authtok_get_data(ts->authtoken)); ret = sss_authtok_get_password(ts->authtoken, &pwd, &ret_len); assert_int_equal(ret, EOK); assert_string_equal(data, pwd); assert_int_equal(len - 1, ret_len); ret = sss_authtok_set_password(ts->authtoken, data, len); assert_int_equal(ret, EOK); ret = sss_authtok_get_password(ts->authtoken, &pwd, &ret_len); assert_int_equal(ret, EOK); assert_string_equal(data, pwd); assert_int_equal(len - 1, ret_len); talloc_free(data); sss_authtok_set_empty(ts->authtoken); } /* Test when type has value SSS_AUTHTOK_TYPE_CCFILE */ static void test_sss_authtok_ccfile(void **state) { size_t len; errno_t ret; char *data; size_t ret_len; const char *pwd; struct test_state *ts; enum sss_authtok_type type; ts = talloc_get_type_abort(*state, struct test_state); data = talloc_strdup(ts, "path/to/cc_file"); assert_non_null(data); len = strlen(data) + 1; type = SSS_AUTHTOK_TYPE_CCFILE; ret = sss_authtok_set(ts->authtoken, type, (const uint8_t *)data, len); assert_int_equal(ret, EOK); assert_int_equal(type, sss_authtok_get_type(ts->authtoken)); assert_int_equal(len, sss_authtok_get_size(ts->authtoken)); assert_string_equal(data, sss_authtok_get_data(ts->authtoken)); ret = sss_authtok_get_ccfile(ts->authtoken, &pwd, &ret_len); assert_int_equal(ret, EOK); assert_string_equal(data, pwd); assert_int_equal(len - 1, ret_len); ret = sss_authtok_set_ccfile(ts->authtoken, data, len); assert_int_equal(ret, EOK); ret = sss_authtok_get_ccfile(ts->authtoken, &pwd, &ret_len); assert_int_equal(ret, EOK); assert_string_equal(data, pwd); assert_int_equal(len - 1, ret_len); ret = sss_authtok_set(ts->authtoken, type, (const uint8_t *) data, 0); assert_int_equal(ret, EOK); assert_int_equal(type, sss_authtok_get_type(ts->authtoken)); assert_int_equal(len, sss_authtok_get_size(ts->authtoken)); assert_string_equal(data, sss_authtok_get_data(ts->authtoken)); ret = sss_authtok_get_ccfile(ts->authtoken, &pwd, &ret_len); assert_int_equal(ret, EOK); assert_string_equal(data, pwd); assert_int_equal(len - 1, ret_len); talloc_free(data); sss_authtok_set_empty(ts->authtoken); } /* Test when type has value SSS_AUTHTOK_TYPE_EMPTY */ static void test_sss_authtok_empty(void **state) { errno_t ret; size_t ret_len; const char *pwd; struct test_state *ts; enum sss_authtok_type type; type = SSS_AUTHTOK_TYPE_EMPTY; ts = talloc_get_type_abort(*state, struct test_state); ret = sss_authtok_set(ts->authtoken, type, NULL, 0); assert_int_equal(ret, EOK); assert_int_equal(type, sss_authtok_get_type(ts->authtoken)); assert_int_equal(0, sss_authtok_get_size(ts->authtoken)); assert_null(sss_authtok_get_data(ts->authtoken)); ret = sss_authtok_get_password(ts->authtoken, &pwd, &ret_len); assert_int_equal(ret, ENOENT); ret = sss_authtok_get_ccfile(ts->authtoken, &pwd, &ret_len); assert_int_equal(ret, ENOENT); sss_authtok_set_empty(ts->authtoken); assert_int_equal(type, sss_authtok_get_type(ts->authtoken)); assert_int_equal(0, sss_authtok_get_size(ts->authtoken)); assert_null(sss_authtok_get_data(ts->authtoken)); ret = sss_authtok_set(ts->authtoken, type, (const uint8_t*)"", 0); assert_int_equal(ret, EOK); assert_int_equal(type, sss_authtok_get_type(ts->authtoken)); assert_int_equal(EOK, sss_authtok_get_size(ts->authtoken)); assert_null(sss_authtok_get_data(ts->authtoken)); ret = sss_authtok_get_password(ts->authtoken, &pwd, &ret_len); assert_int_equal(ret, ENOENT); ret = sss_authtok_get_ccfile(ts->authtoken, &pwd, &ret_len); assert_int_equal(ret, ENOENT); } static void test_sss_authtok_wipe_password(void **state) { size_t len; errno_t ret; char *data; size_t ret_len; const char *pwd; struct test_state *ts; enum sss_authtok_type type; ts = talloc_get_type_abort(*state, struct test_state); data = talloc_strdup(ts, "password"); assert_non_null(data); len = strlen(data) + 1; type = SSS_AUTHTOK_TYPE_PASSWORD; ret = sss_authtok_set(ts->authtoken, type, (const uint8_t *)data, len); assert_int_equal(ret, EOK); sss_authtok_wipe_password(ts->authtoken); ret = sss_authtok_get_password(ts->authtoken, &pwd, &ret_len); assert_int_equal(ret, EOK); assert_string_equal(pwd, ""); assert_int_equal(len - 1, ret_len); sss_authtok_set_empty(ts->authtoken); talloc_free(data); } static void test_sss_authtok_copy(void **state) { size_t len; errno_t ret; char *data; struct test_state *ts; enum sss_authtok_type type; struct sss_auth_token *dest_authtoken; ts= talloc_get_type_abort(*state, struct test_state); dest_authtoken = sss_authtok_new(ts); assert_non_null(dest_authtoken); data = talloc_strdup(ts, "password"); assert_non_null(data); len = strlen(data) + 1; type = SSS_AUTHTOK_TYPE_EMPTY; ret = sss_authtok_set(ts->authtoken, type, (const uint8_t *)data, len); assert_int_equal(ret, EOK); assert_int_equal(EOK, sss_authtok_copy(ts->authtoken, dest_authtoken)); assert_int_equal(type, sss_authtok_get_type(dest_authtoken)); sss_authtok_set_empty(dest_authtoken); type = SSS_AUTHTOK_TYPE_PASSWORD; ret = sss_authtok_set(ts->authtoken, type, (const uint8_t *)data, len); assert_int_equal(ret, EOK); ret = sss_authtok_copy(ts->authtoken, dest_authtoken); assert_int_equal(ret, EOK); assert_int_equal(type, sss_authtok_get_type(dest_authtoken)); assert_string_equal(data, sss_authtok_get_data(dest_authtoken)); assert_int_equal(len, sss_authtok_get_size(dest_authtoken)); sss_authtok_set_empty(dest_authtoken); talloc_free(dest_authtoken); sss_authtok_set_empty(ts->authtoken); talloc_free(data); } void test_sss_authtok_2fa(void **state) { int ret; const char *fa1; size_t fa1_size; const char *fa2; size_t fa2_size; struct test_state *ts; ts = talloc_get_type_abort(*state, struct test_state); ret = sss_authtok_set_2fa(NULL, "a", 0, "b", 0); assert_int_equal(ret, EINVAL); /* Test missing first factor */ ret = sss_authtok_set_2fa(ts->authtoken, NULL, 1, "b", 1); assert_int_equal(ret, EINVAL); /* Test missing second factor */ ret = sss_authtok_set_2fa(ts->authtoken, "a", 1, NULL, 1); assert_int_equal(ret, EINVAL); /* Test wrong first factor length */ ret = sss_authtok_set_2fa(ts->authtoken, "ab", 1, "b", 1); assert_int_equal(ret, EINVAL); /* Test wrong second factor length */ ret = sss_authtok_set_2fa(ts->authtoken, "a", 1, "bc", 1); assert_int_equal(ret, EINVAL); ret = sss_authtok_set_2fa(ts->authtoken, "a", 1, "bc", 2); assert_int_equal(ret, EOK); assert_int_equal(sss_authtok_get_size(ts->authtoken), 2 * sizeof(uint32_t) + 5); assert_int_equal(sss_authtok_get_type(ts->authtoken), SSS_AUTHTOK_TYPE_2FA); #if __BYTE_ORDER == __LITTLE_ENDIAN assert_memory_equal(sss_authtok_get_data(ts->authtoken), "\2\0\0\0\3\0\0\0a\0bc\0", 2 * sizeof(uint32_t) + 5); #else assert_memory_equal(sss_authtok_get_data(ts->authtoken), "\0\0\0\2\0\0\0\3a\0bc\0", 2 * sizeof(uint32_t) + 5); #endif ret = sss_authtok_get_2fa(ts->authtoken, &fa1, &fa1_size, &fa2, &fa2_size); assert_int_equal(ret, EOK); assert_int_equal(fa1_size, 1); assert_string_equal(fa1, "a"); assert_int_equal(fa2_size, 2); assert_string_equal(fa2, "bc"); sss_authtok_set_empty(ts->authtoken); /* check return code of empty token */ ret = sss_authtok_get_2fa(ts->authtoken, &fa1, &fa1_size, &fa2, &fa2_size); assert_int_equal(ret, ENOENT); /* check return code for other token type */ ret = sss_authtok_set_password(ts->authtoken, "abc", 0); assert_int_equal(ret, EOK); ret = sss_authtok_get_2fa(ts->authtoken, &fa1, &fa1_size, &fa2, &fa2_size); assert_int_equal(ret, EACCES); sss_authtok_set_empty(ts->authtoken); /* check return code for garbage */ ret = sss_authtok_set(ts->authtoken, SSS_AUTHTOK_TYPE_2FA, (const uint8_t *) "1111222233334444", 16); assert_int_equal(ret, EINVAL); sss_authtok_set_empty(ts->authtoken); } void test_sss_authtok_2fa_blobs(void **state) { int ret; struct test_state *ts; size_t needed_size; uint8_t *buf; char *fa1; size_t fa1_len; char *fa2; size_t fa2_len; ts = talloc_get_type_abort(*state, struct test_state); ret = sss_auth_pack_2fa_blob(NULL, 0, "defg", 0, NULL, 0, &needed_size); assert_int_equal(ret, EINVAL); ret = sss_auth_pack_2fa_blob("abc", 0, NULL, 0, NULL, 0, &needed_size); assert_int_equal(ret, EINVAL); ret = sss_auth_pack_2fa_blob("", 0, "defg", 0, NULL, 0, &needed_size); assert_int_equal(ret, EINVAL); ret = sss_auth_pack_2fa_blob("abc", 0, "", 0, NULL, 0, &needed_size); assert_int_equal(ret, EINVAL); ret = sss_auth_pack_2fa_blob("abc", 0, "defg", 0, NULL, 0, &needed_size); assert_int_equal(ret, EAGAIN); buf = talloc_size(ts, needed_size); assert_non_null(buf); ret = sss_auth_pack_2fa_blob("abc", 0, "defg", 0, buf, needed_size, &needed_size); assert_int_equal(ret, EOK); #if __BYTE_ORDER == __LITTLE_ENDIAN assert_memory_equal(buf, "\4\0\0\0\5\0\0\0abc\0defg\0", needed_size); #else assert_memory_equal(buf, "\0\0\0\4\0\0\0\5abc\0defg\0", needed_size); #endif ret = sss_auth_unpack_2fa_blob(ts, buf, needed_size, &fa1, &fa1_len, &fa2, &fa2_len); assert_int_equal(ret, EOK); assert_int_equal(fa1_len, 3); assert_string_equal(fa1, "abc"); assert_int_equal(fa2_len, 4); assert_string_equal(fa2, "defg"); talloc_free(buf); talloc_free(fa1); talloc_free(fa2); } #define MISSING_NULL_CHECK do { \ assert_int_equal(ret, EOK); \ assert_int_equal(fa1_len, 3); \ assert_string_equal(fa1, "abc"); \ assert_int_equal(fa2_len, 4); \ assert_string_equal(fa2, "defg"); \ \ talloc_free(fa1); \ talloc_free(fa2); \ } while (0) void test_sss_authtok_2fa_blobs_missing_null(void **state) { int ret; struct test_state *ts; char *fa1; size_t fa1_len; char *fa2; size_t fa2_len; #if __BYTE_ORDER == __LITTLE_ENDIAN uint8_t b0[] = {0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 'a', 'b', 'c', 0x00, 'd', 'e', 'f', 'g', 0x00}; uint8_t b1[] = {0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 0x00}; uint8_t b2[] = {0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 'a', 'b', 'c', 0x00, 'd', 'e', 'f', 'g'}; uint8_t b3[] = {0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 'a', 'b', 'c', 'd', 'e', 'f', 'g'}; #else uint8_t b0[] = {0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 'a', 'b', 'c', 0x00, 'd', 'e', 'f', 'g', 0x00}; uint8_t b1[] = {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 0x00}; uint8_t b2[] = {0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 'a', 'b', 'c', 0x00, 'd', 'e', 'f', 'g'}; uint8_t b3[] = {0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 'a', 'b', 'c', 'd', 'e', 'f', 'g'}; #endif ts = talloc_get_type_abort(*state, struct test_state); ret = sss_auth_unpack_2fa_blob(ts, b0, sizeof(b0), &fa1, &fa1_len, &fa2, &fa2_len); MISSING_NULL_CHECK; ret = sss_auth_unpack_2fa_blob(ts, b1, sizeof(b1), &fa1, &fa1_len, &fa2, &fa2_len); MISSING_NULL_CHECK; ret = sss_auth_unpack_2fa_blob(ts, b2, sizeof(b2), &fa1, &fa1_len, &fa2, &fa2_len); MISSING_NULL_CHECK; ret = sss_auth_unpack_2fa_blob(ts, b3, sizeof(b3), &fa1, &fa1_len, &fa2, &fa2_len); MISSING_NULL_CHECK; } void test_sss_authtok_sc_keypad(void **state) { struct test_state *ts; ts = talloc_get_type_abort(*state, struct test_state); sss_authtok_set_sc_keypad(NULL); sss_authtok_set_sc_keypad(ts->authtoken); assert_int_equal(sss_authtok_get_type(ts->authtoken), SSS_AUTHTOK_TYPE_SC_KEYPAD); assert_int_equal(sss_authtok_get_size(ts->authtoken), 0); assert_null(sss_authtok_get_data(ts->authtoken)); } void test_sss_authtok_sc_pin(void **state) { struct test_state *ts; int ret; size_t size; const char *pin; size_t len; ts = talloc_get_type_abort(*state, struct test_state); ret = sss_authtok_set_sc_pin(NULL, NULL, 0); assert_int_equal(ret, EFAULT); ret = sss_authtok_set_sc_pin(ts->authtoken, NULL, 0); assert_int_equal(ret, EINVAL); ret = sss_authtok_set_sc_pin(ts->authtoken, "12345678", 0); assert_int_equal(ret, EOK); assert_int_equal(sss_authtok_get_type(ts->authtoken), SSS_AUTHTOK_TYPE_SC_PIN); size = sss_authtok_get_size(ts->authtoken); assert_int_equal(size, 9); assert_memory_equal(sss_authtok_get_data(ts->authtoken), "12345678\0", size); ret = sss_authtok_set_sc_pin(ts->authtoken, "12345678", 5); assert_int_equal(ret, EOK); assert_int_equal(sss_authtok_get_type(ts->authtoken), SSS_AUTHTOK_TYPE_SC_PIN); size = sss_authtok_get_size(ts->authtoken); assert_int_equal(size, 6); assert_memory_equal(sss_authtok_get_data(ts->authtoken), "12345\0", size); ret = sss_authtok_get_sc_pin(ts->authtoken, &pin, &len); assert_int_equal(ret, EOK); assert_int_equal(len, 5); assert_string_equal(pin, "12345"); sss_authtok_set_empty(ts->authtoken); ret = sss_authtok_get_sc_pin(ts->authtoken, &pin, &len); assert_int_equal(ret, ENOENT); ret = sss_authtok_set_password(ts->authtoken, "12345", 0); assert_int_equal(ret, EOK); ret = sss_authtok_get_sc_pin(ts->authtoken, &pin, &len); assert_int_equal(ret, EACCES); sss_authtok_set_empty(ts->authtoken); ret = sss_authtok_get_sc_pin(NULL, &pin, &len); assert_int_equal(ret, EFAULT); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_sss_authtok_new, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_authtok_password, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_authtok_ccfile, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_authtok_empty, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_authtok_wipe_password, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_authtok_copy, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_authtok_2fa, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_authtok_2fa_blobs, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_authtok_2fa_blobs_missing_null, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_authtok_sc_keypad, setup, teardown), cmocka_unit_test_setup_teardown(test_sss_authtok_sc_pin, setup, teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/common_mock_resp.h0000644000000000000000000000007412703456111021216 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.585793395 sssd-1.13.4/src/tests/cmocka/common_mock_resp.h0000644002412700241270000000434612703456111022674 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat SSSD tests: Common utilities for tests that exercise domains This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __COMMON_MOCK_RESP_H_ #define __COMMON_MOCK_RESP_H_ #include "util/util.h" #include "responder/common/responder.h" #include "tests/cmocka/common_mock.h" /* Mock a responder context */ struct resp_ctx * mock_rctx(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sss_domain_info *domains, void *pvt_ctx); /* Mock a client context */ struct cli_ctx * mock_cctx(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx); /* When mocking a module that calls sss_dp_get_account_{send,recv} * requests, your test, when linked against this module, will call * the mock functions instead. Then you can simulate results of the * sss_dp_get_account_recv call by calling mock_account_recv. * * The mocked sss_sp_get_account_recv shall return the return values * given with parameters dp_err, dp_ret and msg and optionally also call * the acct_cb_t callback, if given with the pvt pointer as user data. * The callback can for instance populate the cache, thus simulating * Data Provider lookup. * * There is also even simpler wrapper called mock_account_recv_simple * that just finishes the account request with a success. */ typedef int (*acct_cb_t)(void *); void mock_account_recv(uint16_t dp_err, uint32_t dp_ret, char *msg, acct_cb_t acct_cb, void *pvt); void mock_account_recv_simple(void); void mock_parse_inp(const char *name, const char *domname, errno_t ret); #endif /* __COMMON_MOCK_RESP_H_ */ sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/common_mock_sdap.h0000644000000000000000000000007412703456111021174 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.586793398 sssd-1.13.4/src/tests/cmocka/common_mock_sdap.h0000644002412700241270000000265412703456111022652 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef COMMON_MOCK_SDAP_H_ #define COMMON_MOCK_SDAP_H_ #include #include "util/util.h" #include "providers/ldap/sdap.h" struct sdap_options *mock_sdap_options_ldap(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct confdb_ctx *confdb_ctx, const char *conf_path); struct sdap_id_ctx *mock_sdap_id_ctx(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct sdap_options *sdap_opts); struct sdap_handle *mock_sdap_handle(TALLOC_CTX *mem_ctx); #endif /* COMMON_MOCK_SDAP_H_ */ sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_ldap_auth.c0000644000000000000000000000007412703456111020657 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.043794948 sssd-1.13.4/src/tests/cmocka/test_ldap_auth.c0000644002412700241270000000614112703456111022330 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Reichl Copyright (C) 2015 Red Hat SSSD tests - ldap auth This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "tests/common_check.h" #include "providers/ldap/ldap_auth.h" #include "tests/cmocka/test_expire_common.h" struct check_pwexpire_policy_wrap_indata { enum pwexpire type; void *time_fmt; }; static void check_pwexpire_policy_wrap(void *in, void *_out) { errno_t ret; struct check_pwexpire_policy_wrap_indata *data = (struct check_pwexpire_policy_wrap_indata*) in; ret = check_pwexpire_policy(data->type, data->time_fmt, NULL, 0); *(errno_t*)_out = ret; } static void test_pwexpire_krb(void **state) { struct expire_test_ctx *tc; enum pwexpire type = PWEXPIRE_KERBEROS; errno_t ret; tc = talloc_get_type(*state, struct expire_test_ctx); assert_non_null(tc); ret = check_pwexpire_policy(type, (void*) tc->invalid_longer_format, NULL, 0); assert_int_equal(ret, ERR_TIMESPEC_NOT_SUPPORTED); ret = check_pwexpire_policy(type, (void*) tc->invalid_format, NULL, 0); assert_int_equal(ret, ERR_TIMESPEC_NOT_SUPPORTED); ret = check_pwexpire_policy(type, (void*) tc->past_time, NULL, 0); assert_int_equal(ret, ERR_PASSWORD_EXPIRED); ret = check_pwexpire_policy(type, (void*) tc->future_time, NULL, 0); assert_int_equal(ret, EOK); /* changing time zone has no effect as time of expiration is in UTC */ struct check_pwexpire_policy_wrap_indata data; data.type = type; data.time_fmt = (void*)tc->future_time; expire_test_tz("GST-2", check_pwexpire_policy_wrap, (void*)&data, (void*)&ret); assert_int_equal(ret, EOK); data.time_fmt = (void*)tc->past_time; expire_test_tz("GST-2", check_pwexpire_policy_wrap, (void*)&data, (void*)&ret); assert_int_equal(ret, ERR_PASSWORD_EXPIRED); } int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_pwexpire_krb, expire_test_setup, expire_test_teardown), }; return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_krb5_wait_queue.c0000644000000000000000000000007412703456111022011 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.042794944 sssd-1.13.4/src/tests/cmocka/test_krb5_wait_queue.c0000644002412700241270000002545212703456111023470 0ustar00jhrozekjhrozek00000000000000/* Copyright (C) 2015 Red Hat SSSD tests: Kerberos wait queue tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "util/util.h" #include "providers/krb5/krb5_common.h" #include "providers/krb5/krb5_auth.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_be.h" struct krb5_mocked_auth_state { const char *user; time_t us_delay; int ret; int pam_status; int dp_err; }; static void krb5_mocked_auth_done(struct tevent_context *ev, struct tevent_timer *tt, struct timeval tv, void *pvt); struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct pam_data *pd, struct krb5_ctx *krb5_ctx) { struct tevent_req *req; struct krb5_mocked_auth_state *state; struct tevent_timer *tt; struct timeval tv; req = tevent_req_create(mem_ctx, &state, struct krb5_mocked_auth_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create failed.\n"); return NULL; } state->user = sss_mock_ptr_type(const char *); state->us_delay = sss_mock_type(time_t); state->ret = sss_mock_type(int); state->pam_status = sss_mock_type(int); state->dp_err = sss_mock_type(int); tv = tevent_timeval_current_ofs(0, state->us_delay); tt = tevent_add_timer(ev, req, tv, krb5_mocked_auth_done, req); if (tt == NULL) { return NULL; } return req; } static void krb5_mocked_auth_done(struct tevent_context *ev, struct tevent_timer *tt, struct timeval tv, void *pvt) { struct tevent_req *req; struct krb5_mocked_auth_state *state; req = talloc_get_type(pvt, struct tevent_req); state = tevent_req_data(req, struct krb5_mocked_auth_state); DEBUG(SSSDBG_TRACE_LIBS, "Finished auth request of %s\n", state->user); if (state->ret == 0) { tevent_req_done(req); } else { tevent_req_error(req, state->ret); } } int krb5_auth_recv(struct tevent_req *req, int *_pam_status, int *_dp_err) { struct krb5_mocked_auth_state *state; state = tevent_req_data(req, struct krb5_mocked_auth_state); if (_pam_status != NULL) { *_pam_status = state->pam_status; } if (_dp_err != NULL) { *_dp_err = state->dp_err; } TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct test_krb5_wait_queue { struct sss_test_ctx *tctx; int num_auths; int num_finished_auths; struct be_ctx *be_ctx; struct pam_data *pd; struct krb5_ctx *krb5_ctx; }; static int test_krb5_wait_queue_setup(void **state) { struct test_krb5_wait_queue *test_ctx; test_ctx = talloc_zero(global_talloc_context, struct test_krb5_wait_queue); assert_non_null(test_ctx); test_ctx->tctx = create_ev_test_ctx(test_ctx); assert_non_null(test_ctx); test_ctx->be_ctx = mock_be_ctx(test_ctx, test_ctx->tctx); assert_non_null(test_ctx->be_ctx); test_ctx->pd = talloc_zero(test_ctx, struct pam_data); assert_non_null(test_ctx->pd); test_ctx->krb5_ctx = talloc_zero(test_ctx, struct krb5_ctx); assert_non_null(test_ctx->krb5_ctx); *state = test_ctx; return 0; } static int test_krb5_wait_queue_teardown(void **state) { struct test_krb5_wait_queue *test_ctx = talloc_get_type(*state, struct test_krb5_wait_queue); talloc_free(test_ctx); return 0; } static void test_krb5_wait_mock(struct test_krb5_wait_queue *test_ctx, const char *username, time_t us_delay, int ret, int pam_status, int dp_err) { test_ctx->pd->user = discard_const(username); will_return(krb5_auth_send, username); will_return(krb5_auth_send, us_delay); will_return(krb5_auth_send, ret); will_return(krb5_auth_send, pam_status); will_return(krb5_auth_send, dp_err); } static void test_krb5_wait_mock_success(struct test_krb5_wait_queue *test_ctx, const char *username) { return test_krb5_wait_mock(test_ctx, username, 200, 0, 0, 0); } static void test_krb5_wait_queue_single_done(struct tevent_req *req); static void test_krb5_wait_queue_single(void **state) { errno_t ret; struct tevent_req *req; struct test_krb5_wait_queue *test_ctx = talloc_get_type(*state, struct test_krb5_wait_queue); test_krb5_wait_mock_success(test_ctx, "krb5_user"); req = krb5_auth_queue_send(test_ctx, test_ctx->tctx->ev, test_ctx->be_ctx, test_ctx->pd, test_ctx->krb5_ctx); assert_non_null(req); tevent_req_set_callback(req, test_krb5_wait_queue_single_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, EOK); } static void test_krb5_wait_queue_single_done(struct tevent_req *req) { struct test_krb5_wait_queue *test_ctx = \ tevent_req_callback_data(req, struct test_krb5_wait_queue); errno_t ret; int pam_status; int dp_err; ret = krb5_auth_queue_recv(req, &pam_status, &dp_err); talloc_free(req); assert_int_equal(ret, EOK); test_ev_done(test_ctx->tctx, EOK); } static void test_krb5_wait_queue_multi_done(struct tevent_req *req); static void test_krb5_wait_queue_multi(void **state) { int i; errno_t ret; struct tevent_req *req; struct test_krb5_wait_queue *test_ctx = talloc_get_type(*state, struct test_krb5_wait_queue); test_ctx->num_auths = 1000; for (i=0; i < test_ctx->num_auths; i++) { test_krb5_wait_mock_success(test_ctx, "krb5_user"); req = krb5_auth_queue_send(test_ctx, test_ctx->tctx->ev, test_ctx->be_ctx, test_ctx->pd, test_ctx->krb5_ctx); assert_non_null(req); tevent_req_set_callback(req, test_krb5_wait_queue_multi_done, test_ctx); } ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, EOK); } static void test_krb5_wait_queue_multi_done(struct tevent_req *req) { struct test_krb5_wait_queue *test_ctx = \ tevent_req_callback_data(req, struct test_krb5_wait_queue); errno_t ret; int pam_status; int dp_err; ret = krb5_auth_queue_recv(req, &pam_status, &dp_err); talloc_free(req); assert_int_equal(ret, EOK); test_ctx->num_finished_auths++; if (test_ctx->num_finished_auths == test_ctx->num_auths) { test_ev_done(test_ctx->tctx, EOK); } } static void test_krb5_wait_queue_fail_odd_done(struct tevent_req *req); static void test_krb5_wait_queue_fail_odd(void **state) { int i; errno_t ret; struct tevent_req *req; struct test_krb5_wait_queue *test_ctx = talloc_get_type(*state, struct test_krb5_wait_queue); test_ctx->num_auths = 10; for (i=0; i < test_ctx->num_auths; i++) { test_krb5_wait_mock(test_ctx, "krb5_user", 0, i+1 % 2, PAM_SUCCESS, 0); req = krb5_auth_queue_send(test_ctx, test_ctx->tctx->ev, test_ctx->be_ctx, test_ctx->pd, test_ctx->krb5_ctx); assert_non_null(req); tevent_req_set_callback(req, test_krb5_wait_queue_fail_odd_done, test_ctx); } ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, EOK); } static void test_krb5_wait_queue_fail_odd_done(struct tevent_req *req) { struct test_krb5_wait_queue *test_ctx = \ tevent_req_callback_data(req, struct test_krb5_wait_queue); errno_t ret; int pam_status; int dp_err; ret = krb5_auth_queue_recv(req, &pam_status, &dp_err); talloc_free(req); assert_int_equal(ret, test_ctx->num_finished_auths+1 % 2); test_ctx->num_finished_auths++; if (test_ctx->num_finished_auths == test_ctx->num_auths) { test_ev_done(test_ctx->tctx, EOK); } } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { /* Run a single auth request */ cmocka_unit_test_setup_teardown(test_krb5_wait_queue_single, test_krb5_wait_queue_setup, test_krb5_wait_queue_teardown), /* Run multiple auth requests */ cmocka_unit_test_setup_teardown(test_krb5_wait_queue_multi, test_krb5_wait_queue_setup, test_krb5_wait_queue_teardown), /* Make sure that all requests in queue run even if some fail */ cmocka_unit_test_setup_teardown(test_krb5_wait_queue_fail_odd, test_krb5_wait_queue_setup, test_krb5_wait_queue_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_copy_keytab.c0000644000000000000000000000007412703456111021227 xustar0030 atime=1460561751.655715644 30 ctime=1460561775.034794917 sssd-1.13.4/src/tests/cmocka/test_copy_keytab.c0000644002412700241270000002352512703456111022705 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2014 Red Hat SSSD tests: Tests keytab utilities This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/sss_krb5.h" #include "providers/krb5/krb5_common.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_krb5.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define KEYTAB_TEST_PRINC "test/keytab@TEST.KEYTAB" #define KEYTAB_PATH TESTS_PATH "/keytab_test.keytab" #define EMPTY_KEYTAB_PATH TESTS_PATH "/empty_keytab_test.keytab" struct keytab_test_ctx { krb5_context kctx; const char *keytab_file_name; krb5_principal principal; }; static int setup_keytab(void **state) { struct keytab_test_ctx *test_ctx; krb5_error_code kerr; size_t nkeys = 4; krb5_keytab_entry keys[nkeys]; test_dom_suite_setup(TESTS_PATH); assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct keytab_test_ctx); assert_non_null(test_ctx); kerr = krb5_init_context(&test_ctx->kctx); assert_int_equal(kerr, 0); test_ctx->keytab_file_name = "FILE:" KEYTAB_PATH; kerr = krb5_parse_name(test_ctx->kctx, KEYTAB_TEST_PRINC, &test_ctx->principal); assert_int_equal(kerr, 0); memset(&keys, nkeys, nkeys * sizeof(krb5_keytab_entry)); mock_krb5_keytab_entry(&keys[0], test_ctx->principal, 12345, 1, 1, "11"); mock_krb5_keytab_entry(&keys[1], test_ctx->principal, 12345, 1, 2, "12"); mock_krb5_keytab_entry(&keys[2], test_ctx->principal, 12345, 2, 1, "21"); mock_krb5_keytab_entry(&keys[3], test_ctx->principal, 12345, 2, 2, "22"); kerr = mock_keytab(test_ctx->kctx, test_ctx->keytab_file_name, keys, nkeys); assert_int_equal(kerr, 0); check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int teardown_keytab(void **state) { int ret; struct keytab_test_ctx *test_ctx = talloc_get_type(*state, struct keytab_test_ctx); assert_non_null(test_ctx); krb5_free_principal(test_ctx->kctx, test_ctx->principal); krb5_free_context(test_ctx->kctx); ret = unlink(KEYTAB_PATH); assert_int_equal(ret, 0); assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(leak_check_teardown()); ret = rmdir(TESTS_PATH); assert_return_code(ret, errno); return 0; } void test_copy_keytab(void **state) { krb5_error_code kerr; char *mem_keytab_name; krb5_keytab mem_keytab; krb5_keytab keytab; krb5_keytab_entry kent; struct keytab_test_ctx *test_ctx = talloc_get_type(*state, struct keytab_test_ctx); assert_non_null(test_ctx); kerr = copy_keytab_into_memory(test_ctx, test_ctx->kctx, test_ctx->keytab_file_name, &mem_keytab_name, &mem_keytab); assert_int_equal(kerr, 0); assert_non_null(mem_keytab_name); kerr = krb5_kt_resolve(test_ctx->kctx, mem_keytab_name, &keytab); assert_int_equal(kerr, 0); kerr = krb5_kt_get_entry(test_ctx->kctx, keytab, test_ctx->principal, 9, 9, &kent); assert_int_not_equal(kerr, 0); kerr = krb5_kt_get_entry(test_ctx->kctx, keytab, test_ctx->principal, 1, 1, &kent); assert_int_equal(kerr, 0); krb5_free_keytab_entry_contents(test_ctx->kctx, &kent); kerr = krb5_kt_get_entry(test_ctx->kctx, keytab, test_ctx->principal, 1, 2, &kent); assert_int_equal(kerr, 0); krb5_free_keytab_entry_contents(test_ctx->kctx, &kent); kerr = krb5_kt_get_entry(test_ctx->kctx, keytab, test_ctx->principal, 2, 1, &kent); assert_int_equal(kerr, 0); krb5_free_keytab_entry_contents(test_ctx->kctx, &kent); kerr = krb5_kt_get_entry(test_ctx->kctx, keytab, test_ctx->principal, 2, 2, &kent); assert_int_equal(kerr, 0); krb5_free_keytab_entry_contents(test_ctx->kctx, &kent); talloc_free(mem_keytab_name); kerr = krb5_kt_close(test_ctx->kctx, keytab); assert_int_equal(kerr, 0); kerr = krb5_kt_close(test_ctx->kctx, mem_keytab); assert_int_equal(kerr, 0); } void test_sss_krb5_kt_have_content(void **state) { krb5_error_code kerr; krb5_keytab keytab; struct keytab_test_ctx *test_ctx = talloc_get_type(*state, struct keytab_test_ctx); assert_non_null(test_ctx); kerr = krb5_kt_resolve(test_ctx->kctx, test_ctx->keytab_file_name, &keytab); assert_int_equal(kerr, 0); kerr = sss_krb5_kt_have_content(test_ctx->kctx, keytab); assert_int_equal(kerr, 0); kerr = krb5_kt_close(test_ctx->kctx, keytab); assert_int_equal(kerr, 0); kerr = krb5_kt_resolve(test_ctx->kctx, "FILE:" EMPTY_KEYTAB_PATH, &keytab); assert_int_equal(kerr, 0); kerr = sss_krb5_kt_have_content(test_ctx->kctx, keytab); assert_int_equal(kerr, KRB5_KT_NOTFOUND); kerr = krb5_kt_close(test_ctx->kctx, keytab); assert_int_equal(kerr, 0); /* no need to remove EMPTY_KEYTAB_PATH because krb5_kt_close() does not * create empty keytab files */ } static bool keytab_entries_equal(krb5_keytab_entry kent1, krb5_keytab_entry kent2) { if (kent1.vno != kent2.vno || kent1.key.enctype != kent2.key.enctype || kent1.key.length != kent2.key.length || memcmp(kent1.key.contents, kent2.key.contents, kent1.key.length) != 0 ) { return false; } return true; } void test_copy_keytab_order(void **state) { krb5_error_code kerr; krb5_error_code kerr_mem; char *mem_keytab_name; krb5_keytab mem_keytab; krb5_kt_cursor mem_cursor; krb5_keytab_entry mem_kent; krb5_keytab keytab; krb5_kt_cursor cursor; krb5_keytab_entry kent; struct keytab_test_ctx *test_ctx = talloc_get_type(*state, struct keytab_test_ctx); assert_non_null(test_ctx); kerr = copy_keytab_into_memory(test_ctx, test_ctx->kctx, test_ctx->keytab_file_name, &mem_keytab_name, &mem_keytab); assert_int_equal(kerr, 0); assert_non_null(mem_keytab_name); kerr = krb5_kt_resolve(test_ctx->kctx, mem_keytab_name, &mem_keytab); assert_int_equal(kerr, 0); kerr = krb5_kt_resolve(test_ctx->kctx, test_ctx->keytab_file_name, &keytab); assert_int_equal(kerr, 0); kerr = krb5_kt_start_seq_get(test_ctx->kctx, mem_keytab, &mem_cursor); assert_int_equal(kerr, 0); kerr = krb5_kt_start_seq_get(test_ctx->kctx, keytab, &cursor); assert_int_equal(kerr, 0); while ((kerr = krb5_kt_next_entry(test_ctx->kctx, keytab, &kent, &cursor)) == 0) { kerr_mem = krb5_kt_next_entry(test_ctx->kctx, mem_keytab, &mem_kent, &mem_cursor); assert_int_equal(kerr_mem, 0); assert_true(keytab_entries_equal(kent, mem_kent)); krb5_free_keytab_entry_contents(test_ctx->kctx, &kent); krb5_free_keytab_entry_contents(test_ctx->kctx, &mem_kent); } assert_int_equal(kerr, KRB5_KT_END); kerr_mem = krb5_kt_next_entry(test_ctx->kctx, mem_keytab, &mem_kent, &mem_cursor); assert_int_equal(kerr_mem, KRB5_KT_END); kerr = krb5_kt_end_seq_get(test_ctx->kctx, mem_keytab, &mem_cursor); assert_int_equal(kerr, 0); kerr = krb5_kt_end_seq_get(test_ctx->kctx, keytab, &cursor); assert_int_equal(kerr, 0); talloc_free(mem_keytab_name); kerr = krb5_kt_close(test_ctx->kctx, keytab); assert_int_equal(kerr, 0); kerr = krb5_kt_close(test_ctx->kctx, mem_keytab); assert_int_equal(kerr, 0); } int main(int argc, const char *argv[]) { poptContext pc; int opt; int rv; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_copy_keytab, setup_keytab, teardown_keytab), cmocka_unit_test_setup_teardown(test_sss_krb5_kt_have_content, setup_keytab, teardown_keytab), cmocka_unit_test_setup_teardown(test_copy_keytab_order, setup_keytab, teardown_keytab), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); rv = cmocka_run_group_tests(tests, NULL, NULL); return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/common_mock_resp_dp.c0000644000000000000000000000007412703456111021674 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.924794544 sssd-1.13.4/src/tests/cmocka/common_mock_resp_dp.c0000644002412700241270000000660512703456111023352 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat SSSD tests: Fake Data Provider requests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "tests/cmocka/common_mock_resp.h" /* Mock DP requests that finish immediatelly and return * mocked values as per previous set by mock_account_recv */ struct tevent_req * sss_dp_get_account_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, bool fast_reply, enum sss_dp_acct_type type, const char *opt_name, uint32_t opt_id, const char *extra) { return test_req_succeed_send(mem_ctx, rctx->ev); } errno_t sss_dp_get_account_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret, char **err_msg) { acct_cb_t cb; *dp_err = sss_mock_type(dbus_uint16_t); *dp_ret = sss_mock_type(dbus_uint32_t); *err_msg = sss_mock_ptr_type(char *); cb = sss_mock_ptr_type(acct_cb_t); if (cb) { (cb)(sss_mock_ptr_type(void *)); } return test_request_recv(req); } void mock_account_recv(uint16_t dp_err, uint32_t dp_ret, char *msg, acct_cb_t acct_cb, void *pvt) { will_return(sss_dp_get_account_recv, dp_err); will_return(sss_dp_get_account_recv, dp_ret); will_return(sss_dp_get_account_recv, msg); will_return(sss_dp_get_account_recv, acct_cb); if (acct_cb) { will_return(sss_dp_get_account_recv, pvt); } } void mock_account_recv_simple(void) { return mock_account_recv(0, 0, NULL, NULL, NULL); } struct tevent_req * sss_parse_inp_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, const char *rawinp) { return test_req_succeed_send(mem_ctx, rctx->ev); } errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **_name, char **_domname) { *_name = sss_mock_ptr_type(char *); *_domname = sss_mock_ptr_type(char *); return sss_mock_type(errno_t); } void mock_parse_inp(const char *name, const char *domname, errno_t ret) { will_return(sss_parse_inp_recv, name); will_return(sss_parse_inp_recv, domname); will_return(sss_parse_inp_recv, ret); } /* Mock subdomain requests */ struct tevent_req * sss_dp_get_domains_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, bool force, const char *hint) { return test_req_succeed_send(mem_ctx, rctx->ev); } errno_t sss_dp_get_domains_recv(struct tevent_req *req) { return test_request_recv(req); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_ad_gpo.c0000644000000000000000000000007412703456111020147 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.907794486 sssd-1.13.4/src/tests/cmocka/test_ad_gpo.c0000644002412700241270000002667212703456111021633 0ustar00jhrozekjhrozek00000000000000/* Authors: Yassir Elley Copyright (C) 2014 Red Hat SSSD tests: GPO unit tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include /* In order to access opaque types */ #include "providers/ad/ad_gpo.c" #include "tests/cmocka/common_mock.h" struct ad_gpo_test_ctx { struct ldb_context *ldb_ctx; }; static struct ad_gpo_test_ctx *test_ctx; static int ad_gpo_test_setup(void **state) { assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct ad_gpo_test_ctx); assert_non_null(test_ctx); test_ctx->ldb_ctx = ldb_init(test_ctx, NULL); assert_non_null(test_ctx->ldb_ctx); return 0; } static int ad_gpo_test_teardown(void **state) { talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } struct som_list_result { const int result; const int num_soms; const char **som_dns; }; /* * Test parsing target dn into som components */ static void test_populate_som_list(const char *target_dn, struct som_list_result *expected) { errno_t ret; int i; int num_soms; struct gp_som **som_list = NULL; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); ret = ad_gpo_populate_som_list(tmp_ctx, test_ctx->ldb_ctx, target_dn, &num_soms, &som_list); assert_int_equal(ret, expected->result); if (ret != EOK) { goto done; } assert_int_equal(num_soms, expected->num_soms); for (i=0; inum_soms; i++){ bool equal = true; if (strncmp(som_list[i]->som_dn, expected->som_dns[i], strlen(expected->som_dns[i])) != 0) { equal = false; } assert_int_equal(equal, true); } if (som_list) { talloc_free(som_list); } done: assert_true(check_leaks_pop(tmp_ctx) == true); talloc_free(tmp_ctx); } void test_populate_som_list_plain(void **state) { const char *som_dns[] = {"OU=West OU,OU=Sales OU,DC=foo,DC=com", "OU=Sales OU,DC=foo,DC=com", "DC=foo,DC=com"}; struct som_list_result expected = { .result = EOK, .num_soms = 3, .som_dns = som_dns }; test_populate_som_list("CN=F21-Client,OU=West OU,OU=Sales OU,DC=foo,DC=com", &expected); } void test_populate_som_list_malformed(void **state) { struct som_list_result expected = { .result = EINVAL, }; test_populate_som_list("malformed target dn", &expected); } struct gplink_list_result { const int result; const int num_gplinks; const char **gpo_dns; bool *enforced; }; /* * Test parsing raw_gplink_value into gplink components */ static void test_populate_gplink_list(const char *input_gplink_value, bool allow_enforced_only, struct gplink_list_result *expected) { errno_t ret; int i; struct gp_gplink **gplink_list = NULL; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); char *raw_gplink_value = talloc_strdup(tmp_ctx, input_gplink_value); ret = ad_gpo_populate_gplink_list(tmp_ctx, NULL, raw_gplink_value, &gplink_list, allow_enforced_only); talloc_free(raw_gplink_value); assert_int_equal(ret, expected->result); if (ret != EOK) { goto done; } for (i=0; inum_gplinks; i++){ bool equal = true; if (strncmp(gplink_list[i]->gpo_dn, expected->gpo_dns[i], strlen(expected->gpo_dns[i])) != 0) { equal = false; } if (gplink_list[i]->enforced != expected->enforced[i]) equal = false; assert_int_equal(equal, true); } if (gplink_list) { talloc_free(gplink_list); } done: assert_true(check_leaks_pop(tmp_ctx) == true); talloc_free(tmp_ctx); } void test_populate_gplink_list_plain(void **state) { const char *gpo_dns[] = {"OU=Sales,DC=FOO,DC=COM", "DC=FOO,DC=COM"}; bool enforced[] = {false, true}; struct gplink_list_result expected = { .result = EOK, .num_gplinks = 2, .gpo_dns = gpo_dns, .enforced = enforced }; test_populate_gplink_list("[OU=Sales,DC=FOO,DC=COM;0][DC=FOO,DC=COM;2]", false, &expected); } void test_populate_gplink_list_with_ignored(void **state) { const char *gpo_dns[] = {"OU=Sales,DC=FOO,DC=COM"}; bool enforced[] = {false}; struct gplink_list_result expected = { .result = EOK, .num_gplinks = 1, .gpo_dns = gpo_dns, .enforced = enforced }; test_populate_gplink_list("[OU=Sales,DC=FOO,DC=COM;0][DC=ignored;1]", false, &expected); } void test_populate_gplink_list_with_allow_enforced(void **state) { const char *gpo_dns[] = {"DC=FOO,DC=COM"}; bool enforced[] = {true}; struct gplink_list_result expected = { .result = EOK, .num_gplinks = 1, .gpo_dns = gpo_dns, .enforced = enforced }; test_populate_gplink_list("[OU=Sales,DC=FOO,DC=COM;0][DC=FOO,DC=COM;2]", true, &expected); } void test_populate_gplink_list_malformed(void **state) { struct gplink_list_result expected = { .result = EINVAL, }; test_populate_gplink_list(NULL, false, &expected); test_populate_gplink_list("[malformed]", false, &expected); /* the GPLinkOptions value (after semicolon) must be between 0 and 3 */ test_populate_gplink_list("[gpo_dn; 4]", false, &expected); } /* * Test sid-matching logic */ static void test_ad_gpo_ace_includes_client_sid(const char *user_sid, const char **group_sids, int group_size, struct dom_sid ace_dom_sid, bool expected) { errno_t ret; enum idmap_error_code err; struct sss_idmap_ctx *idmap_ctx; bool includes_client_sid; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); err = sss_idmap_init(sss_idmap_talloc, tmp_ctx, sss_idmap_talloc_free, &idmap_ctx); assert_int_equal(err, IDMAP_SUCCESS); ret = ad_gpo_ace_includes_client_sid(user_sid, group_sids, group_size, ace_dom_sid, idmap_ctx, &includes_client_sid); talloc_free(idmap_ctx); assert_int_equal(ret, EOK); assert_int_equal(includes_client_sid, expected); assert_true(check_leaks_pop(tmp_ctx) == true); talloc_free(tmp_ctx); } void test_ad_gpo_ace_includes_client_sid_true(void **state) { /* ace_dom_sid represents "S-1-5-21-2-3-4" */ struct dom_sid ace_dom_sid = {1, 4, {0, 0, 0, 0, 0, 5}, {21, 2, 3, 4}}; const char *user_sid = "S-1-5-21-1175337206-4250576914-2321192831-1103"; int group_size = 2; const char *group_sids[] = {"S-1-5-21-2-3-4", "S-1-5-21-2-3-5"}; test_ad_gpo_ace_includes_client_sid(user_sid, group_sids, group_size, ace_dom_sid, true); } void test_ad_gpo_ace_includes_client_sid_false(void **state) { /* ace_dom_sid represents "S-1-5-21-2-3-4" */ struct dom_sid ace_dom_sid = {1, 4, {0, 0, 0, 0, 0, 5}, {21, 2, 3, 4}}; const char *user_sid = "S-1-5-21-1175337206-4250576914-2321192831-1103"; int group_size = 2; const char *group_sids[] = {"S-1-5-21-2-3-5", "S-1-5-21-2-3-6"}; test_ad_gpo_ace_includes_client_sid(user_sid, group_sids, group_size, ace_dom_sid, false); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_populate_som_list_plain, ad_gpo_test_setup, ad_gpo_test_teardown), cmocka_unit_test_setup_teardown(test_populate_som_list_malformed, ad_gpo_test_setup, ad_gpo_test_teardown), cmocka_unit_test_setup_teardown(test_populate_gplink_list_plain, ad_gpo_test_setup, ad_gpo_test_teardown), cmocka_unit_test_setup_teardown(test_populate_gplink_list_with_ignored, ad_gpo_test_setup, ad_gpo_test_teardown), cmocka_unit_test_setup_teardown(test_populate_gplink_list_with_allow_enforced, ad_gpo_test_setup, ad_gpo_test_teardown), cmocka_unit_test_setup_teardown(test_populate_gplink_list_malformed, ad_gpo_test_setup, ad_gpo_test_teardown), cmocka_unit_test_setup_teardown(test_ad_gpo_ace_includes_client_sid_true, ad_gpo_test_setup, ad_gpo_test_teardown), cmocka_unit_test_setup_teardown(test_ad_gpo_ace_includes_client_sid_false, ad_gpo_test_setup, ad_gpo_test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_utils.c0000644000000000000000000000007412703456111020056 xustar0030 atime=1460561751.657715651 30 ctime=1460561775.053794982 sssd-1.13.4/src/tests/cmocka/test_utils.c0000644002412700241270000014303012703456111021526 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2013 Red Hat SSSD tests: Tests for utility functions This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #define _GNU_SOURCE #include #include #include "tests/cmocka/common_mock.h" #include "util/sss_nss.h" #include "test_utils.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_utils_conf.ldb" #define TEST_DOM_NAME "utils_test.ldb" #define DOM_COUNT 10 #define DOMNAME_TMPL "name_%zu.dom" #define FLATNAME_TMPL "name_%zu" #define SID_TMPL "S-1-5-21-1-2-%zu" #define MACRO_EXPAND(tok) #tok #define STR(tok) MACRO_EXPAND(tok) #define USERNAME "sssduser" #define UID 1234 #define DOMAIN "sssddomain" #define ORIGINAL_HOME "/home/user" #define FLATNAME "flatname" #define HOMEDIR_SUBSTR "/mnt/home" #define DUMMY "dummy" #define DUMMY2 "dummy2" struct dom_list_test_ctx { size_t dom_count; struct sss_domain_info *dom_list; }; static int setup_dom_list(void **state) { struct dom_list_test_ctx *test_ctx; struct sss_domain_info *dom = NULL; size_t c; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct dom_list_test_ctx); assert_non_null(test_ctx); test_ctx->dom_count = DOM_COUNT; for (c = 0; c < test_ctx->dom_count; c++) { dom = talloc_zero(test_ctx, struct sss_domain_info); assert_non_null(dom); dom->name = talloc_asprintf(dom, DOMNAME_TMPL, c); assert_non_null(dom->name); dom->flat_name = talloc_asprintf(dom, FLATNAME_TMPL, c); assert_non_null(dom->flat_name); dom->domain_id = talloc_asprintf(dom, SID_TMPL, c); assert_non_null(dom->domain_id); DLIST_ADD(test_ctx->dom_list, dom); } check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int teardown_dom_list(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); if (test_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); return 1; } assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } void test_find_domain_by_name_null(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom; dom = find_domain_by_name(NULL, NULL, false); assert_null(dom); dom = find_domain_by_name(test_ctx->dom_list, NULL, false); assert_null(dom); dom = find_domain_by_name(NULL, "test", false); assert_null(dom); } void test_find_domain_by_name(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom; size_t c; char *name; char *flat_name; char *sid; for (c = 0; c < test_ctx->dom_count; c++) { name = talloc_asprintf(global_talloc_context, DOMNAME_TMPL, c); assert_non_null(name); flat_name = talloc_asprintf(global_talloc_context, FLATNAME_TMPL, c); assert_non_null(flat_name); sid = talloc_asprintf(global_talloc_context, SID_TMPL, c); assert_non_null(sid); dom = find_domain_by_name(test_ctx->dom_list, name, false); assert_non_null(dom); assert_string_equal(name, dom->name); assert_string_equal(flat_name, dom->flat_name); assert_string_equal(sid, dom->domain_id); dom = find_domain_by_name(test_ctx->dom_list, name, true); assert_non_null(dom); assert_string_equal(name, dom->name); assert_string_equal(flat_name, dom->flat_name); assert_string_equal(sid, dom->domain_id); dom = find_domain_by_name(test_ctx->dom_list, flat_name, true); assert_non_null(dom); assert_string_equal(name, dom->name); assert_string_equal(flat_name, dom->flat_name); assert_string_equal(sid, dom->domain_id); dom = find_domain_by_name(test_ctx->dom_list, flat_name, false); assert_null(dom); talloc_free(name); talloc_free(flat_name); talloc_free(sid); } } void test_find_domain_by_name_missing_flat_name(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom; size_t c; char *name; char *flat_name; char *sid; size_t mis; mis = test_ctx->dom_count/2; assert_true((mis >= 1 && mis < test_ctx->dom_count)); dom = test_ctx->dom_list; for (c = 0; c < mis; c++) { assert_non_null(dom); dom = dom->next; } assert_non_null(dom); dom->flat_name = NULL; for (c = 0; c < test_ctx->dom_count; c++) { name = talloc_asprintf(global_talloc_context, DOMNAME_TMPL, c); assert_non_null(name); flat_name = talloc_asprintf(global_talloc_context, FLATNAME_TMPL, c); assert_non_null(flat_name); sid = talloc_asprintf(global_talloc_context, SID_TMPL, c); assert_non_null(sid); dom = find_domain_by_name(test_ctx->dom_list, name, true); assert_non_null(dom); assert_string_equal(name, dom->name); if (c == mis - 1) { assert_null(dom->flat_name); } else { assert_string_equal(flat_name, dom->flat_name); } assert_string_equal(sid, dom->domain_id); dom = find_domain_by_name(test_ctx->dom_list, name, false); assert_non_null(dom); assert_string_equal(name, dom->name); if (c == mis - 1) { assert_null(dom->flat_name); } else { assert_string_equal(flat_name, dom->flat_name); } assert_string_equal(sid, dom->domain_id); dom = find_domain_by_name(test_ctx->dom_list, flat_name, true); if (c == mis - 1) { assert_null(dom); } else { assert_non_null(dom); assert_string_equal(name, dom->name); assert_string_equal(flat_name, dom->flat_name); assert_string_equal(sid, dom->domain_id); } dom = find_domain_by_name(test_ctx->dom_list, flat_name, false); assert_null(dom); talloc_free(name); talloc_free(flat_name); talloc_free(sid); } } void test_find_domain_by_name_disabled(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom; size_t c; char *name; char *flat_name; char *sid; size_t mis; mis = test_ctx->dom_count/2; assert_true((mis >= 1 && mis < test_ctx->dom_count)); dom = test_ctx->dom_list; for (c = 0; c < mis; c++) { assert_non_null(dom); dom = dom->next; } assert_non_null(dom); sss_domain_set_state(dom, DOM_DISABLED); for (c = 0; c < test_ctx->dom_count; c++) { name = talloc_asprintf(global_talloc_context, DOMNAME_TMPL, c); assert_non_null(name); flat_name = talloc_asprintf(global_talloc_context, FLATNAME_TMPL, c); assert_non_null(flat_name); sid = talloc_asprintf(global_talloc_context, SID_TMPL, c); assert_non_null(sid); dom = find_domain_by_name(test_ctx->dom_list, name, true); if (c == mis - 1) { assert_null(dom); } else { assert_non_null(dom); assert_string_equal(name, dom->name); assert_string_equal(flat_name, dom->flat_name); assert_string_equal(sid, dom->domain_id); } dom = find_domain_by_name(test_ctx->dom_list, name, false); if (c == mis - 1) { assert_null(dom); } else { assert_non_null(dom); assert_string_equal(name, dom->name); assert_string_equal(flat_name, dom->flat_name); assert_string_equal(sid, dom->domain_id); } dom = find_domain_by_name(test_ctx->dom_list, flat_name, true); if (c == mis - 1) { assert_null(dom); } else { assert_non_null(dom); assert_string_equal(name, dom->name); assert_string_equal(flat_name, dom->flat_name); assert_string_equal(sid, dom->domain_id); } dom = find_domain_by_name(test_ctx->dom_list, flat_name, false); assert_null(dom); talloc_free(name); talloc_free(flat_name); talloc_free(sid); } } void test_find_domain_by_sid_null(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom; dom = find_domain_by_sid(NULL, NULL); assert_null(dom); dom = find_domain_by_sid(test_ctx->dom_list, NULL); assert_null(dom); dom = find_domain_by_sid(NULL, "S-1-5-21-1-2-3"); assert_null(dom); } void test_find_domain_by_sid(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom; size_t c; char *name; char *flat_name; char *sid; for (c = 0; c < test_ctx->dom_count; c++) { name = talloc_asprintf(global_talloc_context, DOMNAME_TMPL, c); assert_non_null(name); flat_name = talloc_asprintf(global_talloc_context, FLATNAME_TMPL, c); assert_non_null(flat_name); sid = talloc_asprintf(global_talloc_context, SID_TMPL, c); assert_non_null(sid); dom = find_domain_by_sid(test_ctx->dom_list, sid); assert_non_null(dom); assert_string_equal(name, dom->name); assert_string_equal(flat_name, dom->flat_name); assert_string_equal(sid, dom->domain_id); talloc_free(name); talloc_free(flat_name); talloc_free(sid); } } void test_find_domain_by_sid_missing_sid(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom; size_t c; char *name; char *flat_name; char *sid; size_t mis; mis = test_ctx->dom_count/2; assert_true((mis >= 1 && mis < test_ctx->dom_count)); dom = test_ctx->dom_list; for (c = 0; c < mis; c++) { assert_non_null(dom); dom = dom->next; } assert_non_null(dom); dom->domain_id = NULL; for (c = 0; c < test_ctx->dom_count; c++) { name = talloc_asprintf(global_talloc_context, DOMNAME_TMPL, c); assert_non_null(name); flat_name = talloc_asprintf(global_talloc_context, FLATNAME_TMPL, c); assert_non_null(flat_name); sid = talloc_asprintf(global_talloc_context, SID_TMPL, c); assert_non_null(sid); dom = find_domain_by_sid(test_ctx->dom_list, sid); if (c == mis - 1) { assert_null(dom); } else { assert_non_null(dom); assert_string_equal(name, dom->name); assert_string_equal(flat_name, dom->flat_name); assert_string_equal(sid, dom->domain_id); } talloc_free(name); talloc_free(flat_name); talloc_free(sid); } } void test_find_domain_by_sid_disabled(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom; size_t c; char *name; char *flat_name; char *sid; size_t mis; mis = test_ctx->dom_count/2; assert_true((mis >= 1 && mis < test_ctx->dom_count)); dom = test_ctx->dom_list; for (c = 0; c < mis; c++) { assert_non_null(dom); dom = dom->next; } assert_non_null(dom); sss_domain_set_state(dom, DOM_DISABLED); for (c = 0; c < test_ctx->dom_count; c++) { name = talloc_asprintf(global_talloc_context, DOMNAME_TMPL, c); assert_non_null(name); flat_name = talloc_asprintf(global_talloc_context, FLATNAME_TMPL, c); assert_non_null(flat_name); sid = talloc_asprintf(global_talloc_context, SID_TMPL, c); assert_non_null(sid); dom = find_domain_by_sid(test_ctx->dom_list, sid); if (c == mis - 1) { assert_null(dom); } else { assert_non_null(dom); assert_string_equal(name, dom->name); assert_string_equal(flat_name, dom->flat_name); assert_string_equal(sid, dom->domain_id); } talloc_free(name); talloc_free(flat_name); talloc_free(sid); } } /* * dom1 -> sub1a * | * dom2 -> sub2a -> sub2b * */ static int setup_dom_tree(void **state) { struct dom_list_test_ctx *test_ctx; struct sss_domain_info *head = NULL; struct sss_domain_info *dom = NULL; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct dom_list_test_ctx); assert_non_null(test_ctx); dom = named_domain(test_ctx, "dom1", NULL); assert_non_null(dom); head = dom; dom = named_domain(test_ctx, "sub1a", head); assert_non_null(dom); head->subdomains = dom; dom = named_domain(test_ctx, "dom2", NULL); assert_non_null(dom); head->next = dom; dom = named_domain(test_ctx, "sub2a", head->next); assert_non_null(dom); head->next->subdomains = dom; dom = named_domain(test_ctx, "sub2b", head->next); assert_non_null(dom); head->next->subdomains->next = dom; test_ctx->dom_count = 2; test_ctx->dom_list = head; check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int teardown_dom_tree(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); if (test_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); return 1; } assert_true(check_leaks_pop(test_ctx)); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } static void test_get_next_domain(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom = NULL; dom = get_next_domain(test_ctx->dom_list, 0); assert_non_null(dom); assert_string_equal(dom->name, "dom2"); dom = get_next_domain(dom, 0); assert_null(dom); } static void test_get_next_domain_descend(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom = NULL; dom = get_next_domain(test_ctx->dom_list, SSS_GND_DESCEND); assert_non_null(dom); assert_string_equal(dom->name, "sub1a"); dom = get_next_domain(dom, SSS_GND_DESCEND); assert_non_null(dom); assert_string_equal(dom->name, "dom2"); dom = get_next_domain(dom, SSS_GND_DESCEND); assert_non_null(dom); assert_string_equal(dom->name, "sub2a"); dom = get_next_domain(dom, SSS_GND_DESCEND); assert_non_null(dom); assert_string_equal(dom->name, "sub2b"); dom = get_next_domain(dom, 0); assert_null(dom); } static void test_get_next_domain_disabled(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom = NULL; for (dom = test_ctx->dom_list; dom; dom = get_next_domain(dom, SSS_GND_DESCEND)) { sss_domain_set_state(dom, DOM_DISABLED); } dom = get_next_domain(test_ctx->dom_list, SSS_GND_DESCEND); assert_null(dom); } static void test_get_next_domain_flags(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); struct sss_domain_info *dom = NULL; uint32_t gnd_flags; /* No flags; all doms enabled */ gnd_flags = 0; dom = get_next_domain(test_ctx->dom_list, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "dom2"); dom = get_next_domain(dom, gnd_flags); assert_null(dom); /* Descend flag onlyl; all doms enabled */ gnd_flags = SSS_GND_DESCEND; dom = get_next_domain(test_ctx->dom_list, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "sub1a"); dom = get_next_domain(dom, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "dom2"); dom = get_next_domain(dom, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "sub2a"); dom = get_next_domain(dom, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "sub2b"); dom = get_next_domain(dom, gnd_flags); assert_null(dom); /* Incl. disabled flag only; all doms enabled */ gnd_flags = SSS_GND_INCLUDE_DISABLED; dom = get_next_domain(test_ctx->dom_list, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "dom2"); dom = get_next_domain(dom, gnd_flags); assert_null(dom); /* Descend and inculude disabled; all doms enabled */ gnd_flags = SSS_GND_DESCEND | SSS_GND_INCLUDE_DISABLED; dom = get_next_domain(test_ctx->dom_list, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "sub1a"); dom = get_next_domain(dom, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "dom2"); dom = get_next_domain(dom, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "sub2a"); dom = get_next_domain(dom, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "sub2b"); dom = get_next_domain(dom, gnd_flags); assert_null(dom); /* Now disable dom2 and sub2a */ dom = find_domain_by_name(test_ctx->dom_list, "dom2", false); assert_non_null(dom); sss_domain_set_state(dom, DOM_DISABLED); dom = find_domain_by_name(test_ctx->dom_list, "sub2a", false); assert_non_null(dom); sss_domain_set_state(dom, DOM_DISABLED); /* No flags; dom2 and sub2a disabled */ gnd_flags = 0; dom = get_next_domain(test_ctx->dom_list, gnd_flags); assert_null(dom); /* Descend flag onlyl; dom2 and sub2a disabled */ gnd_flags = SSS_GND_DESCEND; dom = get_next_domain(test_ctx->dom_list, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "sub1a"); dom = get_next_domain(dom, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "sub2b"); dom = get_next_domain(dom, gnd_flags); assert_null(dom); /* Incl. disabled flag only; dom2 and sub2a disabled */ gnd_flags = SSS_GND_INCLUDE_DISABLED; dom = get_next_domain(test_ctx->dom_list, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "dom2"); dom = get_next_domain(dom, gnd_flags); assert_null(dom); /* Descend and inculude disabled; dom2 and sub2a disabled */ gnd_flags = SSS_GND_DESCEND | SSS_GND_INCLUDE_DISABLED; dom = get_next_domain(test_ctx->dom_list, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "sub1a"); dom = get_next_domain(dom, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "dom2"); dom = get_next_domain(dom, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "sub2a"); dom = get_next_domain(dom, gnd_flags); assert_non_null(dom); assert_string_equal(dom->name, "sub2b"); dom = get_next_domain(dom, gnd_flags); assert_null(dom); } struct name_init_test_ctx { struct confdb_ctx *confdb; }; #define GLOBAL_FULL_NAME_FORMAT "%1$s@%2$s" #define GLOBAL_RE_EXPRESSION "(?P[^@]+)@?(?P[^@]*$)" #define TEST_DOMAIN_NAME "test.dom" #define DOMAIN_FULL_NAME_FORMAT "%3$s\\%1$s" #define DOMAIN_RE_EXPRESSION "(((?P[^\\\\]+)\\\\(?P.+$))|" \ "((?P[^@]+)@(?P.+$))|" \ "(^(?P[^@\\\\]+)$))" static int confdb_test_setup(void **state) { struct name_init_test_ctx *test_ctx; char *conf_db = NULL; char *dompath = NULL; int ret; const char *val[2]; val[1] = NULL; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct name_init_test_ctx); assert_non_null(test_ctx); conf_db = talloc_asprintf(test_ctx, "%s/%s", TESTS_PATH, TEST_CONF_DB); assert_non_null(conf_db); ret = confdb_init(test_ctx, &test_ctx->confdb, conf_db); assert_int_equal(ret, EOK); talloc_free(conf_db); val[0] = TEST_DOMAIN_NAME; ret = confdb_add_param(test_ctx->confdb, true, "config/sssd", "domains", val); assert_int_equal(ret, EOK); val[0] = GLOBAL_FULL_NAME_FORMAT; ret = confdb_add_param(test_ctx->confdb, true, "config/sssd", "full_name_format", val); assert_int_equal(ret, EOK); val[0] = GLOBAL_RE_EXPRESSION; ret = confdb_add_param(test_ctx->confdb, true, "config/sssd", "re_expression", val); assert_int_equal(ret, EOK); dompath = talloc_asprintf(test_ctx, "config/domain/%s", TEST_DOMAIN_NAME); assert_non_null(dompath); val[0] = "ldap"; ret = confdb_add_param(test_ctx->confdb, true, dompath, "id_provider", val); assert_int_equal(ret, EOK); val[0] = DOMAIN_FULL_NAME_FORMAT; ret = confdb_add_param(test_ctx->confdb, true, dompath, "full_name_format", val); assert_int_equal(ret, EOK); val[0] = DOMAIN_RE_EXPRESSION; ret = confdb_add_param(test_ctx->confdb, true, dompath, "re_expression", val); assert_int_equal(ret, EOK); talloc_free(dompath); check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int confdb_test_teardown(void **state) { struct name_init_test_ctx *test_ctx; test_ctx = talloc_get_type(*state, struct name_init_test_ctx); assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } void test_sss_names_init(void **state) { struct name_init_test_ctx *test_ctx; struct sss_names_ctx *names_ctx; int ret; test_ctx = talloc_get_type(*state, struct name_init_test_ctx); ret = sss_names_init(test_ctx, test_ctx->confdb, NULL, &names_ctx); assert_int_equal(ret, EOK); assert_non_null(names_ctx); assert_string_equal(names_ctx->re_pattern, GLOBAL_RE_EXPRESSION); assert_string_equal(names_ctx->fq_fmt, GLOBAL_FULL_NAME_FORMAT); talloc_free(names_ctx); ret = sss_names_init(test_ctx, test_ctx->confdb, TEST_DOMAIN_NAME, &names_ctx); assert_int_equal(ret, EOK); assert_non_null(names_ctx); assert_string_equal(names_ctx->re_pattern, DOMAIN_RE_EXPRESSION); assert_string_equal(names_ctx->fq_fmt, DOMAIN_FULL_NAME_FORMAT); talloc_free(names_ctx); } void test_well_known_sid_to_name(void **state) { int ret; const char *name; const char *dom; ret = well_known_sid_to_name(NULL, NULL, NULL); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("abc", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1-", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1-0", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1-0-", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1-0-0", &dom, &name); assert_int_equal(ret, EOK); assert_string_equal(dom, "NULL AUTHORITY"); assert_string_equal(name, "NULL SID"); ret = well_known_sid_to_name("S-1-0-0-", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1-5", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1-5-", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1-5-6", &dom, &name); assert_int_equal(ret, EOK); assert_string_equal(dom, "NT AUTHORITY"); assert_string_equal(name, "SERVICE"); ret = well_known_sid_to_name("S-1-5-6-", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1-5-21", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1-5-21-", &dom, &name); assert_int_equal(ret, ENOENT); ret = well_known_sid_to_name("S-1-5-21-abc", &dom, &name); assert_int_equal(ret, ENOENT); ret = well_known_sid_to_name("S-1-5-32", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1-5-32-", &dom, &name); assert_int_equal(ret, EINVAL); ret = well_known_sid_to_name("S-1-5-32-551", &dom, &name); assert_int_equal(ret, EOK); assert_string_equal(dom, "BUILTIN"); assert_string_equal(name, "Backup Operators"); ret = well_known_sid_to_name("S-1-5-32-551-", &dom, &name); assert_int_equal(ret, EINVAL); } void test_name_to_well_known_sid(void **state) { int ret; const char *sid; ret = name_to_well_known_sid(NULL, NULL, NULL); assert_int_equal(ret, EINVAL); ret = name_to_well_known_sid("abc", "def", &sid); assert_int_equal(ret, ENOENT); ret = name_to_well_known_sid("", "def", &sid); assert_int_equal(ret, ENOENT); ret = name_to_well_known_sid("BUILTIN", "def", &sid); assert_int_equal(ret, EINVAL); ret = name_to_well_known_sid("NT AUTHORITY", "def", &sid); assert_int_equal(ret, EINVAL); ret = name_to_well_known_sid("LOCAL AUTHORITY", "LOCAL", &sid); assert_int_equal(ret, EOK); assert_string_equal(sid, "S-1-2-0"); ret = name_to_well_known_sid(NULL, "LOCAL", &sid); assert_int_equal(ret, EINVAL); ret = name_to_well_known_sid("BUILTIN", "Cryptographic Operators", &sid); assert_int_equal(ret, EOK); assert_string_equal(sid, "S-1-5-32-569"); ret = name_to_well_known_sid("NT AUTHORITY", "DIALUP", &sid); assert_int_equal(ret, EOK); assert_string_equal(sid, "S-1-5-1"); } #define TEST_SANITIZE_INPUT "TestUser@Test.Domain" #define TEST_SANITIZE_LC_INPUT "testuser@test.domain" void test_sss_filter_sanitize_for_dom(void **state) { struct dom_list_test_ctx *test_ctx; int ret; char *sanitized; char *lc_sanitized; struct sss_domain_info *dom; test_ctx = talloc_get_type(*state, struct dom_list_test_ctx); dom = test_ctx->dom_list; dom->case_sensitive = true; ret = sss_filter_sanitize_for_dom(test_ctx, TEST_SANITIZE_INPUT, dom, &sanitized, &lc_sanitized); assert_int_equal(ret, EOK); assert_string_equal(sanitized, TEST_SANITIZE_INPUT); assert_string_equal(lc_sanitized, TEST_SANITIZE_INPUT); talloc_free(sanitized); talloc_free(lc_sanitized); dom->case_sensitive = false; ret = sss_filter_sanitize_for_dom(test_ctx, TEST_SANITIZE_INPUT, dom, &sanitized, &lc_sanitized); assert_int_equal(ret, EOK); assert_string_equal(sanitized, TEST_SANITIZE_INPUT); assert_string_equal(lc_sanitized, TEST_SANITIZE_LC_INPUT); talloc_free(sanitized); talloc_free(lc_sanitized); } void check_expanded_value(TALLOC_CTX *tmp_ctx, struct sss_nss_homedir_ctx *homedir_ctx, const char *template, const char *exp_val) { char *homedir; homedir = expand_homedir_template(tmp_ctx, template, homedir_ctx); if (exp_val != NULL) { assert_string_equal(homedir, exp_val); } else { assert_null(homedir); } talloc_free(homedir); } static int setup_homedir_ctx(void **state) { struct sss_nss_homedir_ctx *homedir_ctx; assert_true(leak_check_setup()); homedir_ctx= talloc_zero(global_talloc_context, struct sss_nss_homedir_ctx); assert_non_null(homedir_ctx); homedir_ctx->username = USERNAME; homedir_ctx->uid = UID; homedir_ctx->original = ORIGINAL_HOME; homedir_ctx->domain = DOMAIN; homedir_ctx->flatname = FLATNAME; homedir_ctx->config_homedir_substr = HOMEDIR_SUBSTR; check_leaks_push(homedir_ctx); *state = homedir_ctx; return 0; } static int teardown_homedir_ctx(void **state) { struct sss_nss_homedir_ctx *homedir_ctx = talloc_get_type(*state, struct sss_nss_homedir_ctx); if (homedir_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); return 1; } assert_true(check_leaks_pop(homedir_ctx) == true); talloc_free(homedir_ctx); assert_true(leak_check_teardown()); return 0; } void test_expand_homedir_template_NULL(void **state) { TALLOC_CTX *tmp_ctx; char *homedir; struct sss_nss_homedir_ctx *homedir_ctx; /* following format strings requires data in homedir_ctx */ const char *format_strings[] = { "%u", "%U", "%d", "%f", "%F", "%H", NULL }; int i; tmp_ctx = talloc_new(NULL); assert_non_null(tmp_ctx); homedir_ctx = talloc_zero(tmp_ctx, struct sss_nss_homedir_ctx); assert_non_null(homedir_ctx); homedir = expand_homedir_template(tmp_ctx, NULL, NULL); assert_null(homedir); homedir = expand_homedir_template(tmp_ctx, "template", NULL); assert_null(homedir); /* missing data in homedir_ctx */ check_expanded_value(tmp_ctx, homedir_ctx, "%%", "%"); check_expanded_value(tmp_ctx, homedir_ctx, "%o", ""); for (i = 0; format_strings[i] != NULL; ++i) { check_expanded_value(tmp_ctx, homedir_ctx, format_strings[i], NULL); } /* flatname requires domain and username */ homedir_ctx->username = DUMMY; check_expanded_value(tmp_ctx, homedir_ctx, "%f", NULL); homedir_ctx->username = NULL; homedir_ctx->domain = DUMMY; check_expanded_value(tmp_ctx, homedir_ctx, "%f", NULL); /* test unknown format string */ check_expanded_value(tmp_ctx, homedir_ctx, "%x", NULL); /* test malformed format string */ check_expanded_value(tmp_ctx, homedir_ctx, "%", NULL); talloc_free(tmp_ctx); } void test_expand_homedir_template(void **state) { struct sss_nss_homedir_ctx *homedir_ctx = talloc_get_type(*state, struct sss_nss_homedir_ctx); TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); assert_non_null(tmp_ctx); /* string without template */ check_expanded_value(tmp_ctx, homedir_ctx, DUMMY, DUMMY); check_expanded_value(tmp_ctx, homedir_ctx, "%u", USERNAME); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%u", DUMMY USERNAME); check_expanded_value(tmp_ctx, homedir_ctx, "%u"DUMMY, USERNAME DUMMY); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%u"DUMMY2, DUMMY USERNAME DUMMY2); check_expanded_value(tmp_ctx, homedir_ctx, "%U", STR(UID)); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%U", DUMMY STR(UID)); check_expanded_value(tmp_ctx, homedir_ctx, "%U"DUMMY, STR(UID) DUMMY); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%U"DUMMY2, DUMMY STR(UID) DUMMY2); check_expanded_value(tmp_ctx, homedir_ctx, "%d", DOMAIN); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%d", DUMMY DOMAIN); check_expanded_value(tmp_ctx, homedir_ctx, "%d"DUMMY, DOMAIN DUMMY); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%d"DUMMY2, DUMMY DOMAIN DUMMY2); check_expanded_value(tmp_ctx, homedir_ctx, "%f", USERNAME"@"DOMAIN); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%f", DUMMY USERNAME"@"DOMAIN); check_expanded_value(tmp_ctx, homedir_ctx, "%f"DUMMY, USERNAME"@"DOMAIN DUMMY); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%f"DUMMY2, DUMMY USERNAME"@"DOMAIN DUMMY2); check_expanded_value(tmp_ctx, homedir_ctx, "%o", ORIGINAL_HOME); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%o", DUMMY ORIGINAL_HOME); check_expanded_value(tmp_ctx, homedir_ctx, "%o"DUMMY, ORIGINAL_HOME DUMMY); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%o"DUMMY2, DUMMY ORIGINAL_HOME DUMMY2); check_expanded_value(tmp_ctx, homedir_ctx, "%F", FLATNAME); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%F", DUMMY FLATNAME); check_expanded_value(tmp_ctx, homedir_ctx, "%F"DUMMY, FLATNAME DUMMY); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%F"DUMMY2, DUMMY FLATNAME DUMMY2); check_expanded_value(tmp_ctx, homedir_ctx, "%H", HOMEDIR_SUBSTR); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%H", DUMMY HOMEDIR_SUBSTR); check_expanded_value(tmp_ctx, homedir_ctx, "%H"DUMMY, HOMEDIR_SUBSTR DUMMY); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%H"DUMMY2, DUMMY HOMEDIR_SUBSTR DUMMY2); check_expanded_value(tmp_ctx, homedir_ctx, "%%", "%"); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%%", DUMMY"%"); check_expanded_value(tmp_ctx, homedir_ctx, "%%"DUMMY, "%"DUMMY); check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"%%"DUMMY2, DUMMY"%"DUMMY2); /* test all format strings */ check_expanded_value(tmp_ctx, homedir_ctx, DUMMY"/%u/%U/%d/%f/%o/%F/%%/%H/"DUMMY2, DUMMY"/"USERNAME"/" STR(UID) "/"DOMAIN"/" USERNAME"@"DOMAIN"/"ORIGINAL_HOME"/"FLATNAME"/%/" HOMEDIR_SUBSTR"/"DUMMY2); talloc_free(tmp_ctx); } static int setup_add_strings_lists(void **state) { assert_true(leak_check_setup()); check_leaks_push(global_talloc_context); return 0; } static int teardown_add_strings_lists(void **state) { assert_true(check_leaks_pop(global_talloc_context) == true); assert_true(leak_check_teardown()); return 0; } void test_add_strings_lists(void **state) { const char *l1[] = {"a", "b", "c", NULL}; const char *l2[] = {"1", "2", "3", NULL}; char **res; int ret; size_t c; size_t d; ret = add_strings_lists(global_talloc_context, NULL, NULL, true, &res); assert_int_equal(ret, EOK); assert_non_null(res); assert_null(res[0]); talloc_free(res); ret = add_strings_lists(global_talloc_context, NULL, NULL, false, &res); assert_int_equal(ret, EOK); assert_non_null(res); assert_null(res[0]); talloc_free(res); ret = add_strings_lists(global_talloc_context, l1, NULL, false, &res); assert_int_equal(ret, EOK); assert_non_null(res); for (c = 0; l1[c] != NULL; c++) { /* 'copy_strings' is 'false', pointers must be equal */ assert_int_equal(memcmp(&l1[c], &res[c], sizeof(char *)), 0); } assert_null(res[c]); talloc_free(res); ret = add_strings_lists(global_talloc_context, l1, NULL, true, &res); assert_int_equal(ret, EOK); assert_non_null(res); for (c = 0; l1[c] != NULL; c++) { /* 'copy_strings' is 'true', pointers must be different, but strings * must be equal */ assert_int_not_equal(memcmp(&l1[c], &res[c], sizeof(char *)), 0); assert_string_equal(l1[c], res[c]); } assert_null(res[c]); talloc_free(res); ret = add_strings_lists(global_talloc_context, NULL, l1, false, &res); assert_int_equal(ret, EOK); assert_non_null(res); for (c = 0; l1[c] != NULL; c++) { /* 'copy_strings' is 'false', pointers must be equal */ assert_int_equal(memcmp(&l1[c], &res[c], sizeof(char *)), 0); } assert_null(res[c]); talloc_free(res); ret = add_strings_lists(global_talloc_context, NULL, l1, true, &res); assert_int_equal(ret, EOK); assert_non_null(res); for (c = 0; l1[c] != NULL; c++) { /* 'copy_strings' is 'true', pointers must be different, but strings * must be equal */ assert_int_not_equal(memcmp(&l1[c], &res[c], sizeof(char *)), 0); assert_string_equal(l1[c], res[c]); } assert_null(res[c]); talloc_free(res); ret = add_strings_lists(global_talloc_context, l1, l2, false, &res); assert_int_equal(ret, EOK); assert_non_null(res); for (c = 0; l1[c] != NULL; c++) { /* 'copy_strings' is 'false', pointers must be equal */ assert_int_equal(memcmp(&l1[c], &res[c], sizeof(char *)), 0); } for (d = 0; l2[d] != NULL; d++) { assert_int_equal(memcmp(&l2[d], &res[c+d], sizeof(char *)), 0); } assert_null(res[c+d]); talloc_free(res); ret = add_strings_lists(global_talloc_context, l1, l2, true, &res); assert_int_equal(ret, EOK); assert_non_null(res); for (c = 0; l1[c] != NULL; c++) { /* 'copy_strings' is 'true', pointers must be different, but strings * must be equal */ assert_int_not_equal(memcmp(&l1[c], &res[c], sizeof(char *)), 0); assert_string_equal(l1[c], res[c]); } for (d = 0; l2[d] != NULL; d++) { assert_int_not_equal(memcmp(&l2[d], &res[c+d], sizeof(char *)), 0); assert_string_equal(l2[d], res[c+d]); } assert_null(res[c+d]); talloc_free(res); } void test_sss_write_krb5_conf_snippet(void **state) { int ret; char buf[PATH_MAX]; char *cwd; char *path; char *file; ret = sss_write_krb5_conf_snippet(NULL); assert_int_equal(ret, EINVAL); ret = sss_write_krb5_conf_snippet("abc"); assert_int_equal(ret, EINVAL); ret = sss_write_krb5_conf_snippet(""); assert_int_equal(ret, EOK); ret = sss_write_krb5_conf_snippet("none"); assert_int_equal(ret, EOK); cwd = getcwd(buf, PATH_MAX); assert_non_null(cwd); ret = asprintf(&path, "%s/%s", cwd, TESTS_PATH); assert_true(ret > 0); ret = asprintf(&file, "%s/%s/localauth_plugin", cwd, TESTS_PATH); assert_true(ret > 0); ret = sss_write_krb5_conf_snippet(path); assert_int_equal(ret, EOK); /* Check if writing a second time will work as well */ ret = sss_write_krb5_conf_snippet(path); assert_int_equal(ret, EOK); #ifdef HAVE_KRB5_LOCALAUTH_PLUGIN ret = unlink(file); assert_int_equal(ret, EOK); #endif free(file); free(path); } void test_fix_domain_in_name_list(void **state) { struct name_init_test_ctx *test_ctx; int ret; struct sss_domain_info *sd; struct sss_domain_info *dom; const char *in[] = { "abc@test.case.dom", "def@TEST.case.DOM", NULL}; char **out = NULL; test_ctx = talloc_get_type(*state, struct name_init_test_ctx); assert_non_null(test_ctx); ret = confdb_get_domains(test_ctx->confdb, &dom); assert_int_equal(ret, EOK); ret = sss_names_init(dom, test_ctx->confdb, NULL, &dom->names); assert_int_equal(ret, EOK); sd = talloc_zero(test_ctx, struct sss_domain_info); assert_non_null(sd); sd->name = talloc_strdup(sd, "TesT.CasE.DoM"); assert_non_null(sd->name); sd->names = dom->names; sd->fqnames = true; DLIST_ADD(dom->subdomains, sd); sd->parent = dom; ret = fix_domain_in_name_list(test_ctx, dom, discard_const(in), &out); assert_int_equal(ret, EOK); assert_non_null(out); assert_non_null(out[0]); assert_string_equal(out[0], "abc@TesT.CasE.DoM"); assert_non_null(out[1]); assert_string_equal(out[1], "def@TesT.CasE.DoM"); assert_null(out[2]); talloc_free(out); talloc_free(sd); talloc_free(dom); } struct unique_file_test_ctx { char *filename; }; static int unique_file_test_setup(void **state) { struct unique_file_test_ctx *test_ctx; assert_true(leak_check_setup()); check_leaks_push(global_talloc_context); test_ctx = talloc_zero(global_talloc_context, struct unique_file_test_ctx); assert_non_null(test_ctx); test_ctx->filename = talloc_strdup(test_ctx, "test_unique_file_XXXXXX"); assert_non_null(test_ctx); *state = test_ctx; return 0; } static int unique_file_test_teardown(void **state) { struct unique_file_test_ctx *test_ctx; errno_t ret; test_ctx = talloc_get_type(*state, struct unique_file_test_ctx); errno = 0; ret = unlink(test_ctx->filename); if (ret != 0 && errno != ENOENT) { fail(); } talloc_free(test_ctx); assert_true(check_leaks_pop(global_talloc_context) == true); assert_true(leak_check_teardown()); return 0; } static void assert_destructor(TALLOC_CTX *owner, struct unique_file_test_ctx *test_ctx) { int fd; errno_t ret; char *check_filename; /* Test that the destructor works */ if (owner == NULL) { return; } check_filename = talloc_strdup(test_ctx, test_ctx->filename); assert_non_null(check_filename); talloc_free(owner); ret = check_and_open_readonly(test_ctx->filename, &fd, geteuid(), getegid(), (S_IRUSR | S_IWUSR | S_IFREG), 0); close(fd); assert_int_not_equal(ret, EOK); } static void sss_unique_file_test(struct unique_file_test_ctx *test_ctx, bool test_destructor) { int fd; errno_t ret; struct stat sb; TALLOC_CTX *owner = NULL; if (test_destructor) { owner = talloc_new(test_ctx); assert_non_null(owner); } fd = sss_unique_file(owner, test_ctx->filename, &ret); assert_int_not_equal(fd, -1); assert_int_equal(ret, EOK); ret = check_fd(fd, geteuid(), getegid(), (S_IRUSR | S_IWUSR | S_IFREG), 0, &sb); close(fd); assert_int_equal(ret, EOK); assert_destructor(owner, test_ctx); } static void test_sss_unique_file(void **state) { struct unique_file_test_ctx *test_ctx; test_ctx = talloc_get_type(*state, struct unique_file_test_ctx); sss_unique_file_test(test_ctx, false); } static void test_sss_unique_file_destruct(void **state) { struct unique_file_test_ctx *test_ctx; test_ctx = talloc_get_type(*state, struct unique_file_test_ctx); sss_unique_file_test(test_ctx, true); } static void test_sss_unique_file_neg(void **state) { int fd; errno_t ret; fd = sss_unique_file(NULL, discard_const("badpattern"), &ret); assert_int_equal(fd, -1); assert_int_equal(ret, EINVAL); } static void sss_unique_filename_test(struct unique_file_test_ctx *test_ctx, bool test_destructor) { int fd; errno_t ret; char *tmp_filename; TALLOC_CTX *owner = NULL; tmp_filename = talloc_strdup(test_ctx, test_ctx->filename); assert_non_null(tmp_filename); if (test_destructor) { owner = talloc_new(test_ctx); assert_non_null(owner); } ret = sss_unique_filename(owner, test_ctx->filename); assert_int_equal(ret, EOK); assert_int_equal(strncmp(test_ctx->filename, tmp_filename, strlen(tmp_filename) - sizeof("XXXXXX")), 0); ret = check_and_open_readonly(test_ctx->filename, &fd, geteuid(), getegid(), (S_IRUSR | S_IWUSR | S_IFREG), 0); close(fd); assert_int_equal(ret, EOK); assert_destructor(owner, test_ctx); } static void test_sss_unique_filename(void **state) { struct unique_file_test_ctx *test_ctx; test_ctx = talloc_get_type(*state, struct unique_file_test_ctx); sss_unique_filename_test(test_ctx, false); } static void test_sss_unique_filename_destruct(void **state) { struct unique_file_test_ctx *test_ctx; test_ctx = talloc_get_type(*state, struct unique_file_test_ctx); sss_unique_filename_test(test_ctx, true); } int main(int argc, const char *argv[]) { poptContext pc; int opt; int rv; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_find_domain_by_sid_null, setup_dom_list, teardown_dom_list), cmocka_unit_test_setup_teardown(test_find_domain_by_sid, setup_dom_list, teardown_dom_list), cmocka_unit_test_setup_teardown(test_find_domain_by_sid_missing_sid, setup_dom_list, teardown_dom_list), cmocka_unit_test_setup_teardown(test_find_domain_by_sid_disabled, setup_dom_list, teardown_dom_list), cmocka_unit_test_setup_teardown(test_find_domain_by_name_null, setup_dom_list, teardown_dom_list), cmocka_unit_test_setup_teardown(test_find_domain_by_name, setup_dom_list, teardown_dom_list), cmocka_unit_test_setup_teardown(test_find_domain_by_name_missing_flat_name, setup_dom_list, teardown_dom_list), cmocka_unit_test_setup_teardown(test_find_domain_by_name_disabled, setup_dom_list, teardown_dom_list), cmocka_unit_test_setup_teardown(test_sss_names_init, confdb_test_setup, confdb_test_teardown), cmocka_unit_test_setup_teardown(test_get_next_domain, setup_dom_tree, teardown_dom_tree), cmocka_unit_test_setup_teardown(test_get_next_domain_descend, setup_dom_tree, teardown_dom_tree), cmocka_unit_test_setup_teardown(test_get_next_domain_disabled, setup_dom_tree, teardown_dom_tree), cmocka_unit_test_setup_teardown(test_get_next_domain_flags, setup_dom_tree, teardown_dom_tree), cmocka_unit_test(test_well_known_sid_to_name), cmocka_unit_test(test_name_to_well_known_sid), cmocka_unit_test_setup_teardown(test_sss_filter_sanitize_for_dom, setup_dom_list, teardown_dom_list), cmocka_unit_test(test_expand_homedir_template_NULL), cmocka_unit_test_setup_teardown(test_expand_homedir_template, setup_homedir_ctx, teardown_homedir_ctx), cmocka_unit_test(test_textual_public_key), cmocka_unit_test(test_replace_whitespaces), cmocka_unit_test(test_reverse_replace_whitespaces), cmocka_unit_test(test_guid_blob_to_string_buf), cmocka_unit_test(test_get_last_x_chars), cmocka_unit_test_setup_teardown(test_add_strings_lists, setup_add_strings_lists, teardown_add_strings_lists), cmocka_unit_test(test_sss_write_krb5_conf_snippet), cmocka_unit_test_setup_teardown(test_fix_domain_in_name_list, confdb_test_setup, confdb_test_teardown), cmocka_unit_test_setup_teardown(test_sss_unique_file, unique_file_test_setup, unique_file_test_teardown), cmocka_unit_test_setup_teardown(test_sss_unique_file_destruct, unique_file_test_setup, unique_file_test_teardown), cmocka_unit_test(test_sss_unique_file_neg), cmocka_unit_test_setup_teardown(test_sss_unique_filename, unique_file_test_setup, unique_file_test_teardown), cmocka_unit_test_setup_teardown(test_sss_unique_filename_destruct, unique_file_test_setup, unique_file_test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); } return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_ipa_dn.c0000644000000000000000000000007412703456111020150 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.037794927 sssd-1.13.4/src/tests/cmocka/test_ipa_dn.c0000644002412700241270000001743312703456111021627 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "tests/cmocka/common_mock.h" #include "providers/ipa/ipa_dn.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_ipa_dn_conf.ldb" #define TEST_DOM_NAME "ipa_dn_test" #define TEST_ID_PROVIDER "ipa" struct ipa_dn_test_ctx { struct sss_test_ctx *tctx; struct sysdb_ctx *sysdb; }; static int ipa_dn_test_setup(void **state) { struct ipa_dn_test_ctx *test_ctx = NULL; test_ctx = talloc_zero(NULL, struct ipa_dn_test_ctx); assert_non_null(test_ctx); *state = test_ctx; /* initialize domain */ test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, NULL); assert_non_null(test_ctx->tctx); test_ctx->sysdb = test_ctx->tctx->sysdb; return 0; } static int ipa_dn_test_teardown(void **state) { talloc_zfree(*state); return 0; } static void ipa_check_rdn_test(void **state) { struct ipa_dn_test_ctx *test_ctx = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct ipa_dn_test_ctx); ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,dc=example,dc=com", "cn"); assert_int_equal(ret, EOK); ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "attr1", "value1"); assert_int_equal(ret, EOK); ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", "cn", "attr1", "value1", "attr2", "value2"); assert_int_equal(ret, EOK); ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,dc=example,dc=com", "nope"); assert_int_equal(ret, ENOENT); ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "nope", "value1"); assert_int_equal(ret, ENOENT); ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", "cn", "attr1", "nope"); assert_int_equal(ret, ENOENT); ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "attr1"); assert_int_equal(ret, ENOENT); ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1", "cn", "attr1", "value1"); assert_int_equal(ret, ENOENT); } static void ipa_check_rdn_bool_test(void **state) { struct ipa_dn_test_ctx *test_ctx = NULL; bool bret; test_ctx = talloc_get_type_abort(*state, struct ipa_dn_test_ctx); bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,dc=example,dc=com", "cn"); assert_true(bret); bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "attr1", "value1"); assert_true(bret); bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", "cn", "attr1", "value1", "attr2", "value2"); assert_true(bret); bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,dc=example,dc=com", "nope"); assert_false(bret); bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "nope", "value1"); assert_false(bret); bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", "cn", "attr1", "nope"); assert_false(bret); bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "attr1"); assert_false(bret); bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1", "cn", "attr1", "value1"); assert_false(bret); } static void ipa_get_rdn_test(void **state) { struct ipa_dn_test_ctx *test_ctx = NULL; const char *exprdn = "rdn"; char *rdn = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct ipa_dn_test_ctx); ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,dc=example,dc=com", &rdn, "cn"); assert_int_equal(ret, EOK); assert_non_null(rdn); assert_string_equal(exprdn, rdn); ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", &rdn, "cn", "attr1", "value1"); assert_int_equal(ret, EOK); assert_non_null(rdn); assert_string_equal(exprdn, rdn); ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", &rdn, "cn", "attr1", "value1", "attr2", "value2"); assert_int_equal(ret, EOK); assert_non_null(rdn); assert_string_equal(exprdn, rdn); rdn = NULL; ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,dc=example,dc=com", &rdn, "nope"); assert_int_equal(ret, ENOENT); assert_null(rdn); ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", &rdn, "cn", "nope", "value1"); assert_int_equal(ret, ENOENT); assert_null(rdn); ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", &rdn, "cn", "attr1", "nope"); assert_int_equal(ret, ENOENT); assert_null(rdn); ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", &rdn, "cn", "attr1"); assert_int_equal(ret, ENOENT); assert_null(rdn); ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1", &rdn, "cn", "attr1", "value1"); assert_int_equal(ret, ENOENT); assert_null(rdn); } int main(int argc, const char *argv[]) { int rv; int no_cleanup = 0; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(ipa_check_rdn_test, ipa_dn_test_setup, ipa_dn_test_teardown), cmocka_unit_test_setup_teardown(ipa_check_rdn_bool_test, ipa_dn_test_setup, ipa_dn_test_teardown), cmocka_unit_test_setup_teardown(ipa_get_rdn_test, ipa_dn_test_setup, ipa_dn_test_teardown) }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0 && !no_cleanup) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); } return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_sss_ssh.c0000644000000000000000000000007412703456111020403 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.054794985 sssd-1.13.4/src/tests/cmocka/test_sss_ssh.c0000644002412700241270000001147112703456111022056 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Reichl Copyright (C) 2014 Red Hat Test for the NSS Responder ID-SID mapping interface This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/sss_ssh.h" #include "tests/cmocka/common_mock.h" #include "test_utils.h" uint8_t key_data_noLF[] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfymad64oZkWa6q3xLXmCt/LfCRnd6yZSDp7UK6Irx5/Dv69dEKK2kBGL9Wfn+3ZDa6ov2XZrBmUthh8KOJvTw72+axox3kcJ5HwOYZCMeKbcr10RNScGuHErA1HhjTY6M9L8d0atVH2QIxw7ZHoVVnTHC4U4+541YfJkNUiOUIj65cFFZm9ULp32ZPrK+j2wW+XZkHhrZeFMlg4x4fe5FocO6ik1eqLxBejo7tMy+1m3R2a795AIguf6vNWeE5aNMd4pcmPcZHb3JOq3ItzE/3lepXD/3wqMt36EqNykBVE7aJj+LVkcEgjP9CDDsg9j9NB+AuWYmIYqrHW/Rg/vJ developer@sssd.dev.work"; uint8_t key_data_LF[] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfymad64oZkWa6q3xLXmCt/LfCRnd6yZSDp7UK6Irx5/Dv69dEKK2kBGL9Wfn+3ZDa6ov2XZrBmUthh8KOJvTw72+axox3kcJ5HwOYZCMeKbcr10RNScGuHErA1HhjTY6M9L8d0atVH2QIxw7ZHoVVnTHC4U4+541YfJkNUiOUIj65cFFZm9ULp32ZPrK+j2wW+XZkHhrZeFMlg4x4fe5FocO6ik1eqLxBejo7tMy+1m3R2a795AIguf6vNWeE5aNMd4pcmPcZHb3JOq3ItzE/3lepXD/3wqMt36EqNykBVE7aJj+LVkcEgjP9CDDsg9j9NB+AuWYmIYqrHW/Rg/vJ developer@sssd.dev.work\n"; uint8_t key_data_LFLF[] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfymad64oZkWa6q3xLXmCt/LfCRnd6yZSDp7UK6Irx5/Dv69dEKK2kBGL9Wfn+3ZDa6ov2XZrBmUthh8KOJvTw72+axox3kcJ5HwOYZCMeKbcr10RNScGuHErA1HhjTY6M9L8d0atVH2QIxw7ZHoVVnTHC4U4+541YfJkNUiOUIj65cFFZm9ULp32ZPrK+j2wW+XZkHhrZeFMlg4x4fe5FocO6ik1eqLxBejo7tMy+1m3R2a795AIguf6vNWeE5aNMd4pcmPcZHb3JOq3ItzE/3lepXD/3wqMt36EqNykBVE7aJj+LVkcEgjP9CDDsg9j9NB+AuWYmIYqrHW/Rg/vJ developer@sssd.dev.work\n\n"; uint8_t key_data_CRLF[] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDfymad64oZkWa6q3xLXmCt/LfCRnd6yZSDp7UK6Irx5/Dv69dEKK2kBGL9Wfn+3ZDa6ov2XZrBmUthh8KOJvTw72+axox3kcJ5HwOYZCMeKbcr10RNScGuHErA1HhjTY6M9L8d0atVH2QIxw7ZHoVVnTHC4U4+541YfJkNUiOUIj65cFFZm9ULp32ZPrK+j2wW+XZkHhrZeFMlg4x4fe5FocO6ik1eqLxBejo7tMy+1m3R2a795AIguf6vNWeE5aNMd4pcmPcZHb3JOq3ItzE/3lepXD/3wqMt36EqNykBVE7aJj+LVkcEgjP9CDDsg9j9NB+AuWYmIYqrHW/Rg/vJ developer@sssd.dev.work\r\n"; uint8_t key_data_CR_somewhere[] = "ssh-rsa AA\rAAB3NzaC1yc2EAAAADAQABAAABAQDfymad64oZkWa6q3xLXmCt/LfCRnd6yZSDp7UK6Irx5/Dv69dEKK2kBGL9Wf+3ZDa6ov2XZrBmUthh8KOJvTw72+axox3kcJ5HwOYZCMeKbcr10RNScGuHErA1HhjTY6M9L8d0atVH2QIxw7ZHoVVnTHC4U4+541YfJkNUiOUIj65cFFZm9ULp32ZPrK+j2wW+XZkHhrZeFMlg4x4fe5FocO6ik1eqLxBejo7tMy+1m3R2a795AIguf6vNWeE5aNMd4pcmPcZHb3JOq3ItzE/3lepXD/3wqMt36EqNykBVE7aJj+LVkcEgjP9CDDsg9j9NB+AuWYmIYqrHW/Rg/vJ developer@sssd.dev.work\n"; void test_textual_public_key(void **state) { TALLOC_CTX *mem_ctx; errno_t ret; char *res; struct sss_ssh_pubkey pkey_null_terminated = { .data = key_data_noLF, .data_len = sizeof(key_data_noLF) }; struct sss_ssh_pubkey pkey = { .data = key_data_noLF, .data_len = sizeof(key_data_noLF) - 1 /* ignore trailling '\0' */ }; struct sss_ssh_pubkey pkey_LF = { .data = key_data_LF, .data_len = sizeof(key_data_LF) - 1 /* ignore trailling '\0' */ }; struct sss_ssh_pubkey pkey_LFLF = { .data = key_data_LFLF, .data_len = sizeof(key_data_LFLF) - 1 /* ignore trailling '\0' */ }; struct sss_ssh_pubkey pkey_CRLF = { .data = key_data_CRLF, .data_len = sizeof(key_data_CRLF) - 1 /* ignore trailling '\0' */ }; struct sss_ssh_pubkey pkey_CR_somewhere = { .data = key_data_CR_somewhere, .data_len = sizeof(key_data_CR_somewhere) - 1 /* ignore traill. '\0' */ }; mem_ctx = talloc_new(NULL); assert_non_null(mem_ctx); check_leaks_push(mem_ctx); ret = sss_ssh_format_pubkey(mem_ctx, &pkey, &res); assert_int_equal(ret, EOK); talloc_free(res); ret = sss_ssh_format_pubkey(mem_ctx, &pkey_LF, &res); assert_int_equal(ret, EOK); talloc_free(res); ret = sss_ssh_format_pubkey(mem_ctx, &pkey_LFLF, &res); assert_int_equal(ret, EINVAL); ret = sss_ssh_format_pubkey(mem_ctx, &pkey_null_terminated, &res); assert_int_equal(ret, EINVAL); ret = sss_ssh_format_pubkey(mem_ctx, &pkey_CRLF, &res); assert_int_equal(ret, EINVAL); ret = sss_ssh_format_pubkey(mem_ctx, &pkey_CR_somewhere, &res); assert_int_equal(ret, EINVAL); assert_true(check_leaks_pop(mem_ctx) == true); talloc_free(mem_ctx); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/dummy_child.c0000644000000000000000000000007412703456111020155 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.916794517 sssd-1.13.4/src/tests/cmocka/dummy_child.c0000644002412700241270000000754212703456111021634 0ustar00jhrozekjhrozek00000000000000/* SSSD Tests -- a simple test process that echoes input back Authors: Jakub Hrozek Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "util/child_common.h" int main(int argc, const char *argv[]) { int opt; int debug_fd = -1; poptContext pc; ssize_t len; ssize_t written; errno_t ret; uint8_t buf[IN_BUF_SIZE]; const char *action = NULL; const char *guitar; const char *drums; struct poptOption long_options[] = { POPT_AUTOHELP {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, _("Debug level"), NULL}, {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0, _("Add debug timestamps"), NULL}, {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0, _("Show timestamps with microseconds"), NULL}, {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0, _("An open file descriptor for the debug logs"), NULL}, {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, \ _("Send the debug output to stderr directly."), NULL }, {"guitar", 0, POPT_ARG_STRING, &guitar, 0, _("Who plays guitar"), NULL }, {"drums", 0, POPT_ARG_STRING, &drums, 0, _("Who plays drums"), NULL }, POPT_TABLEEND }; /* Set debug level to invalid value so we can decide if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); poptFreeContext(pc); _exit(1); } } poptFreeContext(pc); action = getenv("TEST_CHILD_ACTION"); if (action) { if (strcasecmp(action, "check_extra_args") == 0) { if (!(strcmp(guitar, "george") == 0 \ && strcmp(drums, "ringo") == 0)) { DEBUG(SSSDBG_CRIT_FAILURE, "This band sounds weird\n"); _exit(1); } } else if (strcasecmp(action, "echo") == 0) { errno = 0; len = sss_atomic_read_s(STDIN_FILENO, buf, IN_BUF_SIZE); if (len == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret)); _exit(1); } close(STDIN_FILENO); errno = 0; written = sss_atomic_write_s(3, buf, len); if (written == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret, strerror(ret)); _exit(1); } close(STDOUT_FILENO); if (written != len) { DEBUG(SSSDBG_CRIT_FAILURE, "Expected to write %zu bytes, wrote %zu\n", len, written); _exit(1); } } } DEBUG(SSSDBG_TRACE_FUNC, "test_child completed successfully\n"); _exit(0); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_be_ptask.c0000644000000000000000000000007412703456111020506 xustar0030 atime=1460561751.655715644 30 ctime=1460561775.030794904 sssd-1.13.4/src/tests/cmocka/test_be_ptask.c0000644002412700241270000007367012703456111022172 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "providers/dp_backend.h" #include "providers/dp_ptask_private.h" #include "providers/dp_ptask.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_be.h" #include "tests/common.h" #define DELAY 2 #define PERIOD 1 #define TIMEOUT 123 #define new_test(test) \ cmocka_unit_test_setup_teardown(test_ ## test, test_setup, test_teardown) struct test_ctx { struct sss_test_ctx *tctx; struct be_ctx *be_ctx; time_t when; bool done; bool add_online_cb_called; bool add_offline_cb_called; }; #define mark_online(test_ctx) do { \ test_ctx->be_ctx->offstat.went_offline = 0; \ test_ctx->be_ctx->offstat.offline = false; \ } while (0) #define mark_offline(test_ctx) do { \ test_ctx->be_ctx->offstat.went_offline = get_current_time(); \ test_ctx->be_ctx->offstat.offline = true; \ } while (0) /* Since both test_ctx->done and ptask->req is marked as finished already * in the sync _send function before a new execution is scheduled we need to * rely on the fact that ptask->req is set to zero when a new timer is * created. This way we guarantee that the condition is true only when * the ptask is executed and a new one is scheduled. */ #define is_sync_ptask_finished(test_ctx, ptask) \ (test_ctx->done && ptask->req == NULL) static time_t get_current_time(void) { struct timeval tv; int ret; ret = gettimeofday(&tv, NULL); assert_int_equal(0, ret); return tv.tv_sec; } /* Mock few backend functions so we don't have to bring the whole * data provider into this test. */ bool be_is_offline(struct be_ctx *ctx) { return ctx->offstat.offline; } int be_add_online_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, void *pvt, struct be_cb **online_cb) { struct test_ctx *test_ctx = NULL; test_ctx = sss_mock_ptr_type(struct test_ctx *); test_ctx->add_online_cb_called = true; return ERR_OK; } int be_add_offline_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, void *pvt, struct be_cb **offline_cb) { struct test_ctx *test_ctx = NULL; test_ctx = sss_mock_ptr_type(struct test_ctx *); test_ctx->add_offline_cb_called = true; return ERR_OK; } struct test_be_ptask_state { struct test_ctx *test_ctx; }; struct tevent_req * test_be_ptask_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct test_be_ptask_state *state = NULL; struct test_ctx *test_ctx = NULL; struct tevent_req *req = NULL; assert_non_null(ev); assert_non_null(be_ctx); assert_non_null(be_ptask); assert_non_null(pvt); test_ctx = talloc_get_type(pvt, struct test_ctx); assert_non_null(test_ctx); test_ctx->when = get_current_time(); req = tevent_req_create(mem_ctx, &state, struct test_be_ptask_state); assert_non_null(req); state->test_ctx = test_ctx; tevent_req_done(req); tevent_req_post(req, ev); return req; } struct tevent_req * test_be_ptask_null_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct test_ctx *test_ctx = NULL; assert_non_null(ev); assert_non_null(be_ctx); assert_non_null(be_ptask); assert_non_null(pvt); test_ctx = talloc_get_type(pvt, struct test_ctx); assert_non_null(test_ctx); test_ctx->when = get_current_time(); test_ctx->done = true; return NULL; } struct tevent_req * test_be_ptask_timeout_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct test_be_ptask_state *state = NULL; struct test_ctx *test_ctx = NULL; struct tevent_req *req = NULL; assert_non_null(ev); assert_non_null(be_ctx); assert_non_null(be_ptask); assert_non_null(pvt); test_ctx = talloc_get_type(pvt, struct test_ctx); assert_non_null(test_ctx); test_ctx->when = get_current_time(); req = tevent_req_create(mem_ctx, &state, struct test_be_ptask_state); assert_non_null(req); state->test_ctx = test_ctx; /* we won't finish the request */ return req; } errno_t test_be_ptask_recv(struct tevent_req *req) { struct test_be_ptask_state *state = NULL; state = tevent_req_data(req, struct test_be_ptask_state); assert_non_null(state); state->test_ctx->done = true; TEVENT_REQ_RETURN_ON_ERROR(req); return ERR_OK; } errno_t test_be_ptask_error_recv(struct tevent_req *req) { struct test_be_ptask_state *state = NULL; state = tevent_req_data(req, struct test_be_ptask_state); assert_non_null(state); state->test_ctx->done = true; return ERR_INTERNAL; } errno_t test_be_ptask_sync(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct test_ctx *test_ctx = NULL; assert_non_null(ev); assert_non_null(be_ctx); assert_non_null(be_ptask); assert_non_null(pvt); test_ctx = talloc_get_type(pvt, struct test_ctx); assert_non_null(test_ctx); test_ctx->when = get_current_time(); test_ctx->done = true; return ERR_OK; } errno_t test_be_ptask_sync_error(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct be_ctx *be_ctx, struct be_ptask *be_ptask, void *pvt) { struct test_ctx *test_ctx = NULL; assert_non_null(ev); assert_non_null(be_ctx); assert_non_null(be_ptask); assert_non_null(pvt); test_ctx = talloc_get_type(pvt, struct test_ctx); assert_non_null(test_ctx); test_ctx->when = get_current_time(); test_ctx->done = true; return ERR_INTERNAL; } static int test_setup(void **state) { struct test_ctx *test_ctx = NULL; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct test_ctx); assert_non_null(test_ctx); test_ctx->tctx = create_ev_test_ctx(test_ctx); assert_non_null(test_ctx->tctx); test_ctx->be_ctx = mock_be_ctx(test_ctx, test_ctx->tctx); assert_non_null(test_ctx->be_ctx); test_ctx->be_ctx->ev = tevent_context_init(test_ctx->be_ctx); assert_non_null(test_ctx->be_ctx->ev); check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int test_teardown(void **state) { assert_true(check_leaks_pop(*state)); talloc_zfree(*state); assert_true(leak_check_teardown()); return 0; } void test_be_ptask_create_einval_be(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; errno_t ret; ret = be_ptask_create(test_ctx, NULL, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, NULL, "Test ptask", &ptask); assert_int_equal(ret, EINVAL); assert_null(ptask); } void test_be_ptask_create_einval_period(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; errno_t ret; ret = be_ptask_create(test_ctx, test_ctx->be_ctx, 0, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, NULL, "Test ptask", &ptask); assert_int_equal(ret, EINVAL); assert_null(ptask); } void test_be_ptask_create_einval_send(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; errno_t ret; ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, NULL, test_be_ptask_recv, NULL, "Test ptask", &ptask); assert_int_equal(ret, EINVAL); assert_null(ptask); } void test_be_ptask_create_einval_recv(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; errno_t ret; ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, NULL, NULL, "Test ptask", &ptask); assert_int_equal(ret, EINVAL); assert_null(ptask); } void test_be_ptask_create_einval_name(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; errno_t ret; ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, NULL, NULL, &ptask); assert_int_equal(ret, EINVAL); assert_null(ptask); } void test_be_ptask_create_no_delay(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t now; errno_t ret; now = get_current_time(); ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); while (!test_ctx->done) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now <= ptask->last_execution); assert_true(now <= test_ctx->when); assert_true(ptask->last_execution <= test_ctx->when); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_create_first_delay(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t now; errno_t ret; now = get_current_time(); ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, DELAY, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); while (!test_ctx->done) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now + DELAY <= ptask->last_execution); assert_true(now + DELAY <= test_ctx->when); assert_true(ptask->last_execution <= test_ctx->when); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_disable(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; errno_t ret; ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); be_ptask_disable(ptask); assert_null(ptask->timer); assert_false(ptask->enabled); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_enable(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t now; errno_t ret; now = get_current_time(); ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); be_ptask_disable(ptask); now = get_current_time(); be_ptask_enable(ptask); assert_non_null(ptask->timer); while (!test_ctx->done) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now <= ptask->last_execution); assert_true(now <= test_ctx->when); assert_true(ptask->last_execution <= test_ctx->when); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_enable_delay(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t now; errno_t ret; ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, DELAY, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); while (!test_ctx->done) { tevent_loop_once(test_ctx->be_ctx->ev); } be_ptask_disable(ptask); test_ctx->done = false; now = get_current_time(); be_ptask_enable(ptask); while (!test_ctx->done) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now + DELAY <= ptask->last_execution); assert_true(now + DELAY <= test_ctx->when); assert_true(ptask->last_execution <= test_ctx->when); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_offline_skip(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t next_execution; time_t now; errno_t ret; mark_offline(test_ctx); now = get_current_time(); ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); next_execution = ptask->next_execution; assert_true(now <= next_execution); while (ptask->next_execution == next_execution && !test_ctx->done) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(next_execution + PERIOD <= ptask->next_execution); assert_true(ptask->enabled); assert_non_null(ptask->timer); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_offline_disable(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; errno_t ret; mark_offline(test_ctx); will_return(be_add_online_cb, test_ctx); will_return(be_add_offline_cb, test_ctx); ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_DISABLE, 0, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); assert_true(test_ctx->add_online_cb_called); assert_true(test_ctx->add_offline_cb_called); while (ptask->enabled && !test_ctx->done) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_false(ptask->enabled); assert_false(test_ctx->done); assert_null(ptask->timer); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_offline_execute(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; errno_t ret; mark_offline(test_ctx); ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_EXECUTE, 0, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); while (!test_ctx->done) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(ptask->enabled); assert_non_null(ptask->timer); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_reschedule_ok(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t next_execution; time_t now; errno_t ret; now = get_current_time(); ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); next_execution = ptask->next_execution; while (!test_ctx->done) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now <= ptask->last_execution); assert_true(now <= test_ctx->when); assert_true(ptask->last_execution <= test_ctx->when); assert_true(next_execution + PERIOD <= ptask->next_execution); assert_non_null(ptask->timer); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_reschedule_null(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t now = 0; errno_t ret; ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_null_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); while (!test_ctx->done) { now = get_current_time(); tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now + PERIOD <= ptask->next_execution); assert_non_null(ptask->timer); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_reschedule_error(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t now = 0; errno_t ret; ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_error_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); while (!test_ctx->done) { now = get_current_time(); tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now + PERIOD <= ptask->next_execution); assert_non_null(ptask->timer); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_reschedule_timeout(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t now = 0; errno_t ret; ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 1, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_timeout_send, test_be_ptask_error_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); /* first iterate until the task is executed */ while (!test_ctx->done && ptask->req == NULL) { tevent_loop_once(test_ctx->be_ctx->ev); } /* then iterate until the request is destroyed */ while (!test_ctx->done && ptask->req != NULL) { now = get_current_time(); tevent_loop_once(test_ctx->be_ctx->ev); } assert_false(test_ctx->done); assert_true(now + PERIOD <= ptask->next_execution); assert_non_null(ptask->timer); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_reschedule_backoff(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t next_execution; time_t now_first; time_t now_backoff = 0; errno_t ret; now_first = get_current_time(); ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, PERIOD*2, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); /* first run */ next_execution = ptask->next_execution; while (!test_ctx->done) { /* We need to acquire timestamp for the second test here, since this * is the closest value to the timestamp when the next event is * scheduled. */ now_backoff = get_current_time(); tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now_first <= ptask->last_execution); assert_true(now_first <= test_ctx->when); assert_true(ptask->last_execution <= test_ctx->when); assert_true(next_execution + PERIOD <= ptask->next_execution); assert_int_equal(PERIOD*2, ptask->period); assert_non_null(ptask->timer); test_ctx->done = false; /* second run */ next_execution = ptask->next_execution; while (!test_ctx->done) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now_backoff + PERIOD <= ptask->last_execution); assert_true(now_backoff + PERIOD <= test_ctx->when); assert_true(ptask->last_execution <= test_ctx->when); assert_true(next_execution + PERIOD*2 <= ptask->next_execution); assert_int_equal(PERIOD*2, ptask->period); assert_non_null(ptask->timer); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_get_period(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t out_period; errno_t ret; ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); out_period = be_ptask_get_period(ptask); assert_true(PERIOD == out_period); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_get_timeout(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t out_timeout; errno_t ret; ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, TIMEOUT, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, test_be_ptask_recv, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); out_timeout = be_ptask_get_timeout(ptask); assert_true(TIMEOUT == out_timeout); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_create_sync(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t now; errno_t ret; now = get_current_time(); ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_sync, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); while (!test_ctx->done) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now <= ptask->last_execution); assert_true(now <= test_ctx->when); assert_true(ptask->last_execution <= test_ctx->when); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_sync_reschedule_ok(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t next_execution; time_t now; errno_t ret; now = get_current_time(); ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_sync, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); next_execution = ptask->next_execution; while (!is_sync_ptask_finished(test_ctx, ptask)) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now <= ptask->last_execution); assert_true(now <= test_ctx->when); assert_true(ptask->last_execution <= test_ctx->when); assert_true(next_execution + PERIOD <= ptask->next_execution); assert_non_null(ptask->timer); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_sync_reschedule_error(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t now = 0; errno_t ret; ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_sync_error, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); while (!is_sync_ptask_finished(test_ctx, ptask)) { now = get_current_time(); tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now + PERIOD <= ptask->next_execution); assert_non_null(ptask->timer); be_ptask_destroy(&ptask); assert_null(ptask); } void test_be_ptask_sync_reschedule_backoff(void **state) { struct test_ctx *test_ctx = (struct test_ctx *)(*state); struct be_ptask *ptask = NULL; time_t next_execution; time_t now_first; time_t now_backoff = 0; errno_t ret; now_first = get_current_time(); ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, BE_PTASK_OFFLINE_SKIP, PERIOD*2, test_be_ptask_sync_error, test_ctx, "Test ptask", &ptask); assert_int_equal(ret, ERR_OK); assert_non_null(ptask); assert_non_null(ptask->timer); /* first run */ next_execution = ptask->next_execution; while (!is_sync_ptask_finished(test_ctx, ptask)) { /* We need to acquire timestamp for the second test here, since this * is the closest value to the timestamp when the next event is * scheduled. */ now_backoff = get_current_time(); tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now_first <= ptask->last_execution); assert_true(now_first <= test_ctx->when); assert_true(ptask->last_execution <= test_ctx->when); assert_true(next_execution + PERIOD <= ptask->next_execution); assert_int_equal(PERIOD*2, ptask->period); assert_non_null(ptask->timer); test_ctx->done = false; /* second run */ next_execution = ptask->next_execution; while (!is_sync_ptask_finished(test_ctx, ptask)) { tevent_loop_once(test_ctx->be_ctx->ev); } assert_true(now_backoff + PERIOD <= ptask->last_execution); assert_true(now_backoff + PERIOD <= test_ctx->when); assert_true(ptask->last_execution <= test_ctx->when); assert_true(next_execution + PERIOD*2 <= ptask->next_execution); assert_int_equal(PERIOD*2, ptask->period); assert_non_null(ptask->timer); be_ptask_destroy(&ptask); assert_null(ptask); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { new_test(be_ptask_create_einval_be), new_test(be_ptask_create_einval_period), new_test(be_ptask_create_einval_send), new_test(be_ptask_create_einval_recv), new_test(be_ptask_create_einval_name), new_test(be_ptask_create_no_delay), new_test(be_ptask_create_first_delay), new_test(be_ptask_disable), new_test(be_ptask_enable), new_test(be_ptask_enable_delay), new_test(be_ptask_offline_skip), new_test(be_ptask_offline_disable), new_test(be_ptask_offline_execute), new_test(be_ptask_reschedule_ok), new_test(be_ptask_reschedule_null), new_test(be_ptask_reschedule_error), new_test(be_ptask_reschedule_timeout), new_test(be_ptask_reschedule_backoff), new_test(be_ptask_get_period), new_test(be_ptask_get_timeout), new_test(be_ptask_create_sync), new_test(be_ptask_sync_reschedule_ok), new_test(be_ptask_sync_reschedule_error), new_test(be_ptask_sync_reschedule_backoff) }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_responder_common.c0000644000000000000000000000007412703456111022267 xustar0030 atime=1460561751.656715648 30 ctime=1460561774.959794663 sssd-1.13.4/src/tests/cmocka/test_responder_common.c0000644002412700241270000002745312703456111023751 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat SSSD tests: Common responder code tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_responder_conf.ldb" #define TEST_DOM_NAME "responder_test" #define TEST_ID_PROVIDER "ldap" #define NAME "username" static void mock_sss_dp_done(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt); errno_t sss_dp_issue_request(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, const char *strkey, struct sss_domain_info *dom, dbus_msg_constructor msg_create, void *pvt, struct tevent_req *nreq) { struct tevent_immediate *imm; imm = tevent_create_immediate(rctx->ev); if (imm == NULL) { return ENOMEM; } tevent_schedule_immediate(imm, rctx->ev, mock_sss_dp_done, nreq); return EOK; } static void mock_sss_dp_done(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt) { struct tevent_req *req; talloc_free(imm); req = talloc_get_type(pvt, struct tevent_req); tevent_req_done(req); } errno_t sss_dp_req_recv(TALLOC_CTX *mem_ctx, struct tevent_req *sidereq, dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret, char **err_msg) { return EOK; } struct parse_inp_test_ctx { struct sss_test_ctx *tctx; struct resp_ctx *rctx; }; static int parse_inp_test_setup(void **state) { struct parse_inp_test_ctx *parse_inp_ctx; int ret; assert_true(leak_check_setup()); parse_inp_ctx = talloc_zero(global_talloc_context, struct parse_inp_test_ctx); assert_non_null(parse_inp_ctx); parse_inp_ctx->tctx = create_dom_test_ctx(parse_inp_ctx, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, NULL); assert_non_null(parse_inp_ctx->tctx); parse_inp_ctx->rctx = mock_rctx(parse_inp_ctx, parse_inp_ctx->tctx->ev, parse_inp_ctx->tctx->dom, parse_inp_ctx); assert_non_null(parse_inp_ctx->rctx); /* Testing the request race condition should be a special case */ gettimeofday(&parse_inp_ctx->rctx->get_domains_last_call, NULL); /* sysdb_master_domain_update sets the view name, if we do not call it * here we get a leak check warning when sysdb_master_domain_update is * called later while processing the tests. */ ret = sysdb_master_domain_update(parse_inp_ctx->tctx->dom); assert_int_equal(ret, EOK); check_leaks_push(parse_inp_ctx); *state = parse_inp_ctx; return 0; } static int parse_inp_test_teardown(void **state) { struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, struct parse_inp_test_ctx); assert_true(check_leaks_pop(parse_inp_ctx) == true); talloc_free(parse_inp_ctx); assert_true(leak_check_teardown()); return 0; } int __real_sss_parse_name_for_domains(TALLOC_CTX *memctx, struct sss_domain_info *domains, const char *default_domain, const char *orig, char **domain, char **name); int __wrap_sss_parse_name_for_domains(TALLOC_CTX *memctx, struct sss_domain_info *domains, const char *default_domain, const char *orig, char **domain, char **name) { enum sss_test_wrapper_call wtype = sss_mock_type(enum sss_test_wrapper_call); errno_t ret; if (wtype == WRAP_CALL_REAL) { return __real_sss_parse_name_for_domains(memctx, domains, default_domain, orig, domain, name); } ret = sss_mock_type(errno_t); return ret; } void parse_inp_simple_done(struct tevent_req *req) { errno_t ret; struct parse_inp_test_ctx *parse_inp_ctx = tevent_req_callback_data(req, struct parse_inp_test_ctx); char *name = NULL; char *domname = NULL; ret = sss_parse_inp_recv(req, parse_inp_ctx, &name, &domname); assert_int_equal(ret, EOK); test_ev_done(parse_inp_ctx->tctx, EOK); talloc_free(req); assert_string_equal(name, NAME); assert_null(domname); talloc_free(name); } void parse_inp_simple(void **state) { struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, struct parse_inp_test_ctx); struct tevent_req *req; errno_t ret; will_return(__wrap_sss_parse_name_for_domains, WRAP_CALL_REAL); req = sss_parse_inp_send(parse_inp_ctx, parse_inp_ctx->rctx, NAME); assert_non_null(req); tevent_req_set_callback(req, parse_inp_simple_done, parse_inp_ctx); ret = test_ev_loop(parse_inp_ctx->tctx); assert_int_equal(ret, EOK); } void parse_inp_call_dp(void **state) { struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, struct parse_inp_test_ctx); struct tevent_req *req; errno_t ret; /* First call will indicate we need to go to DP */ will_return(__wrap_sss_parse_name_for_domains, WRAP_CALL_WRAPPER); will_return(__wrap_sss_parse_name_for_domains, EAGAIN); /* The second one will succeed as the domains are up-to-date */ will_return(__wrap_sss_parse_name_for_domains, WRAP_CALL_REAL); req = sss_parse_inp_send(parse_inp_ctx, parse_inp_ctx->rctx, NAME); assert_non_null(req); tevent_req_set_callback(req, parse_inp_simple_done, parse_inp_ctx); ret = test_ev_loop(parse_inp_ctx->tctx); assert_int_equal(ret, EOK); } void parse_inp_call_attach(void **state) { struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, struct parse_inp_test_ctx); struct tevent_req *req; errno_t ret; /* simulate responder startup */ parse_inp_ctx->rctx->get_domains_last_call.tv_sec = 0; /* The first parse wouldn't be called, the second one will succeed * as the domains are up-to-date */ will_return(__wrap_sss_parse_name_for_domains, WRAP_CALL_REAL); req = sss_parse_inp_send(parse_inp_ctx, parse_inp_ctx->rctx, NAME); assert_non_null(req); tevent_req_set_callback(req, parse_inp_simple_done, parse_inp_ctx); ret = test_ev_loop(parse_inp_ctx->tctx); assert_int_equal(ret, EOK); } void parse_inp_neg_done(struct tevent_req *req) { errno_t ret; struct parse_inp_test_ctx *parse_inp_ctx = tevent_req_callback_data(req, struct parse_inp_test_ctx); char *name = NULL; char *domname = NULL; ret = sss_parse_inp_recv(req, parse_inp_ctx, &name, &domname); assert_int_equal(ret, ERR_INPUT_PARSE); test_ev_done(parse_inp_ctx->tctx, EOK); talloc_free(req); assert_null(name); assert_null(domname); } void parse_inp_call_neg(void **state) { struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, struct parse_inp_test_ctx); struct tevent_req *req; errno_t ret; /* Simulate an error */ will_return(__wrap_sss_parse_name_for_domains, WRAP_CALL_WRAPPER); will_return(__wrap_sss_parse_name_for_domains, EINVAL); req = sss_parse_inp_send(parse_inp_ctx, parse_inp_ctx->rctx, NAME); assert_non_null(req); tevent_req_set_callback(req, parse_inp_neg_done, parse_inp_ctx); ret = test_ev_loop(parse_inp_ctx->tctx); assert_int_equal(ret, EOK); } struct sss_nc_ctx { struct parse_inp_test_ctx *pctx; }; errno_t sss_ncache_reset_repopulate_permanent(struct resp_ctx *rctx, struct sss_nc_ctx *dummy_ncache_ptr) { test_ev_done(dummy_ncache_ptr->pctx->tctx, EOK); return EOK; } void test_schedule_get_domains_task(void **state) { struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, struct parse_inp_test_ctx); errno_t ret; struct sss_nc_ctx *dummy_ncache_ptr; dummy_ncache_ptr = talloc(parse_inp_ctx, struct sss_nc_ctx); assert_non_null(dummy_ncache_ptr); dummy_ncache_ptr->pctx = parse_inp_ctx; ret = schedule_get_domains_task(dummy_ncache_ptr, parse_inp_ctx->rctx->ev, parse_inp_ctx->rctx, dummy_ncache_ptr); assert_int_equal(ret, EOK); ret = test_ev_loop(parse_inp_ctx->tctx); assert_int_equal(ret, EOK); talloc_free(dummy_ncache_ptr); } int main(int argc, const char *argv[]) { int rv; int no_cleanup = 0; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(parse_inp_simple, parse_inp_test_setup, parse_inp_test_teardown), cmocka_unit_test_setup_teardown(parse_inp_call_dp, parse_inp_test_setup, parse_inp_test_teardown), cmocka_unit_test_setup_teardown(parse_inp_call_attach, parse_inp_test_setup, parse_inp_test_teardown), cmocka_unit_test_setup_teardown(parse_inp_call_neg, parse_inp_test_setup, parse_inp_test_teardown), cmocka_unit_test_setup_teardown(test_schedule_get_domains_task, parse_inp_test_setup, parse_inp_test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0 && !no_cleanup) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); } return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_sdap.c0000644000000000000000000000007412703456111017645 xustar0030 atime=1460561751.656715648 30 ctime=1460561774.968794693 sssd-1.13.4/src/tests/cmocka/test_sdap.c0000644002412700241270000012154012703456111021317 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "tests/cmocka/common_mock.h" #include "providers/ldap/ldap_opts.h" #include "providers/ipa/ipa_opts.h" #include "util/crypto/sss_crypto.h" /* mock an LDAP entry */ struct mock_ldap_attr { const char *name; const char **values; }; struct mock_ldap_entry { const char *dn; struct mock_ldap_attr *attrs; }; struct mock_ldap_entry *global_ldap_entry; static int mock_ldap_entry_iter(void) { return sss_mock_type(int); } static struct mock_ldap_entry *mock_ldap_entry_get(void) { return sss_mock_ptr_type(struct mock_ldap_entry *); } void set_entry_parse(struct mock_ldap_entry *entry) { will_return_always(mock_ldap_entry_get, entry); } LDAPDerefRes *mock_deref_res(TALLOC_CTX *mem_ctx, struct mock_ldap_entry *entry) { LDAPDerefRes *dref; LDAPDerefVal *dval, *dvaltail = NULL; size_t nattr; size_t nval; dref = talloc_zero(mem_ctx, LDAPDerefRes); assert_non_null(dref); dref->derefVal.bv_val = talloc_strdup(dref, entry->dn); assert_non_null(dref->derefVal.bv_val); dref->derefVal.bv_len = strlen(entry->dn); if (entry->attrs == NULL) { /* no attributes, done */ return dref; } for (nattr = 0; entry->attrs[nattr].name; nattr++) { dval = talloc_zero(dref, LDAPDerefVal); assert_non_null(dval); dval->type = talloc_strdup(dval, entry->attrs[nattr].name); assert_non_null(dval->type); for (nval = 0; entry->attrs[nattr].values[nval]; nval++); dval->vals = talloc_zero_array(dval, struct berval, nval+1); assert_non_null(dval->vals); for (nval = 0; entry->attrs[nattr].values[nval]; nval++) { dval->vals[nval].bv_val = talloc_strdup(dval->vals, entry->attrs[nattr].values[nval]); assert_non_null(dval->vals[nval].bv_val); dval->vals[nval].bv_len = strlen(dval->vals[nval].bv_val); } if (dvaltail != NULL) { dvaltail->next = dval; dvaltail = dvaltail->next; } else { dvaltail = dval; dref->attrVals = dval; } } return dref; } /* libldap wrappers */ int __wrap_ldap_set_option(LDAP *ld, int option, void *invalue) { return LDAP_OPT_SUCCESS; } char *__wrap_ldap_get_dn(LDAP *ld, LDAPMessage *entry) { struct mock_ldap_entry *ldap_entry = mock_ldap_entry_get(); return discard_const(ldap_entry->dn); } void __wrap_ldap_memfree(void *p) { return; } struct berval **__wrap_ldap_get_values_len(LDAP *ld, LDAPMessage *entry, LDAP_CONST char *target) { size_t count, i; struct berval **vals; const char **attrvals; struct mock_ldap_entry *ldap_entry = mock_ldap_entry_get(); if (target == NULL) return NULL; if (ldap_entry == NULL) return NULL; /* Should we return empty array here? */ if (ldap_entry->attrs == NULL) return NULL; attrvals = NULL; for (i = 0; ldap_entry->attrs[i].name != NULL; i++) { if (strcmp(ldap_entry->attrs[i].name, target) == 0) { attrvals = ldap_entry->attrs[i].values; break; } } if (attrvals == NULL) { return NULL; } count = 0; for (i = 0; attrvals[i]; i++) { count++; } vals = talloc_zero_array(global_talloc_context, struct berval *, count + 1); assert_non_null(vals); for (i = 0; attrvals[i]; i++) { vals[i] = talloc_zero(vals, struct berval); assert_non_null(vals[i]); vals[i]->bv_val = talloc_strdup(vals[i], attrvals[i]); if (vals[i]->bv_val == NULL) { talloc_free(vals); return NULL; } vals[i]->bv_len = strlen(attrvals[i]); } return vals; } void __wrap_ldap_value_free_len(struct berval **vals) { talloc_free(vals); /* Allocated on global_talloc_context */ } char *__wrap_ldap_first_attribute(LDAP *ld, LDAPMessage *entry, BerElement **berout) { struct mock_ldap_entry *ldap_entry = mock_ldap_entry_get(); if (ldap_entry == NULL) return NULL; if (ldap_entry->attrs == NULL) return NULL; will_return(mock_ldap_entry_iter, 1); return discard_const(ldap_entry->attrs[0].name); } char *__wrap_ldap_next_attribute(LDAP *ld, LDAPMessage *entry, BerElement *ber) { struct mock_ldap_entry *ldap_entry = mock_ldap_entry_get(); int idx = mock_ldap_entry_iter(); char *val; val = discard_const(ldap_entry->attrs[idx].name); if (val != NULL) { will_return(mock_ldap_entry_iter, idx + 1); } return val; } /* Mock parsing search base without overlinking the test */ errno_t sdap_parse_search_base(TALLOC_CTX *mem_ctx, struct dp_option *opts, int class, struct sdap_search_base ***_search_bases) { return EOK; } /* Utility function */ void assert_entry_has_attr(struct sysdb_attrs *attrs, const char *attr, const char *value) { const char *v; int ret; ret = sysdb_attrs_get_string(attrs, attr, &v); assert_int_equal(ret, ERR_OK); assert_non_null(v); assert_string_equal(v, value); } void assert_entry_has_no_attr(struct sysdb_attrs *attrs, const char *attr) { int ret; const char *v; ret = sysdb_attrs_get_string(attrs, attr, &v); assert_int_equal(ret, ENOENT); } struct parse_test_ctx { struct sdap_handle sh; struct sdap_msg sm; }; static int parse_entry_test_setup(void **state) { struct parse_test_ctx *test_ctx; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct parse_test_ctx); assert_non_null(test_ctx); check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int parse_entry_test_teardown(void **state) { struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } void test_parse_with_map(void **state) { int ret; struct sysdb_attrs *attrs; struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); struct mock_ldap_entry test_ipa_user; struct sdap_attr_map *map; struct ldb_message_element *el; uint8_t *decoded_key; size_t key_len; const char *oc_values[] = { "posixAccount", NULL }; const char *uid_values[] = { "tuser1", NULL }; const char *extra_values[] = { "extra", NULL }; const char *multi_values[] = { "svc1", "svc2", NULL }; const char *ssh_values[] = { "1234", NULL }; struct mock_ldap_attr test_ipa_user_attrs[] = { { .name = "objectClass", .values = oc_values }, { .name = "uid", .values = uid_values }, { .name = "extra", .values = extra_values }, { .name = "authorizedService", .values = multi_values }, { .name = "ipaSshPubKey", .values = ssh_values }, { NULL, NULL } }; test_ipa_user.dn = "cn=testuser,dc=example,dc=com"; test_ipa_user.attrs = test_ipa_user_attrs; set_entry_parse(&test_ipa_user); ret = sdap_copy_map(test_ctx, ipa_user_map, SDAP_OPTS_USER, &map); assert_int_equal(ret, ERR_OK); ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm, map, SDAP_OPTS_USER, &attrs, false); assert_int_equal(ret, ERR_OK); assert_int_equal(attrs->num, 4); /* Every entry has a DN */ assert_entry_has_attr(attrs, SYSDB_ORIG_DN, "cn=testuser,dc=example,dc=com"); /* Test the single-valued attribute */ assert_entry_has_attr(attrs, SYSDB_NAME, "tuser1"); /* Multivalued attributes must return all values */ ret = sysdb_attrs_get_el_ext(attrs, SYSDB_AUTHORIZED_SERVICE, false, &el); assert_int_equal(ret, ERR_OK); assert_int_equal(el->num_values, 2); assert_true((strcmp((const char *) el->values[0].data, "svc1") == 0 && strcmp((const char *) el->values[1].data, "svc2") == 0) || (strcmp((const char *) el->values[1].data, "svc1") == 0 && strcmp((const char *) el->values[0].data, "svc2") == 0)); /* The SSH attribute must be base64 encoded */ ret = sysdb_attrs_get_el_ext(attrs, SYSDB_SSH_PUBKEY, false, &el); assert_int_equal(ret, ERR_OK); assert_int_equal(el->num_values, 1); decoded_key = sss_base64_decode(test_ctx, (const char *)el->values[0].data, &key_len); assert_non_null(decoded_key); assert_memory_equal(decoded_key, "1234", key_len); /* The extra attribute must not be downloaded, it's not present in map */ assert_entry_has_no_attr(attrs, "extra"); talloc_free(decoded_key); talloc_free(map); talloc_free(attrs); } /* Some searches, like rootDSE search do not use any map */ void test_parse_no_map(void **state) { int ret; struct sysdb_attrs *attrs; struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); struct mock_ldap_entry test_nomap_entry; struct ldb_message_element *el; const char *foo_values[] = { "fooval1", "fooval2", NULL }; const char *bar_values[] = { "barval1", NULL }; struct mock_ldap_attr test_nomap_entry_attrs[] = { { .name = "foo", .values = foo_values }, { .name = "bar", .values = bar_values }, { NULL, NULL } }; test_nomap_entry.dn = "cn=testentry,dc=example,dc=com"; test_nomap_entry.attrs = test_nomap_entry_attrs; set_entry_parse(&test_nomap_entry); ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm, NULL, 0, &attrs, false); assert_int_equal(ret, ERR_OK); assert_int_equal(attrs->num, 3); assert_entry_has_attr(attrs, SYSDB_ORIG_DN, "cn=testentry,dc=example,dc=com"); assert_entry_has_attr(attrs, "bar", "barval1"); /* Multivalued attributes must return all values */ ret = sysdb_attrs_get_el_ext(attrs, "foo", false, &el); assert_int_equal(ret, ERR_OK); assert_int_equal(el->num_values, 2); assert_true((strcmp((const char *) el->values[0].data, "fooval1") == 0 && strcmp((const char *) el->values[1].data, "fooval2") == 0) || (strcmp((const char *) el->values[1].data, "fooval1") == 0 && strcmp((const char *) el->values[0].data, "fooval2") == 0)); talloc_free(attrs); } /* Only DN and OC, no real attributes */ void test_parse_no_attrs(void **state) { int ret; struct sysdb_attrs *attrs; struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); struct mock_ldap_entry test_rfc2307_user; struct sdap_attr_map *map; const char *oc_values[] = { "posixAccount", NULL }; struct mock_ldap_attr test_rfc2307_user_attrs[] = { { .name = "objectClass", .values = oc_values }, { NULL, NULL } }; test_rfc2307_user.dn = "cn=testuser,dc=example,dc=com"; test_rfc2307_user.attrs = test_rfc2307_user_attrs; set_entry_parse(&test_rfc2307_user); ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &map); assert_int_equal(ret, ERR_OK); ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm, map, SDAP_OPTS_USER, &attrs, false); assert_int_equal(ret, ERR_OK); assert_int_equal(attrs->num, 1); assert_entry_has_attr(attrs, SYSDB_ORIG_DN, "cn=testuser,dc=example,dc=com"); talloc_free(map); talloc_free(attrs); } void test_parse_dups(void **state) { int ret; struct sysdb_attrs *attrs; struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); struct mock_ldap_entry test_dupattr_user; struct sdap_attr_map *map; int i; const char *oc_values[] = { "posixAccount", NULL }; const char *uid_values[] = { "1234", NULL }; struct mock_ldap_attr test_dupattr_attrs[] = { { .name = "objectClass", .values = oc_values }, { .name = "idNumber", .values = uid_values }, { NULL, NULL } }; test_dupattr_user.dn = "cn=dupuser,dc=example,dc=com"; test_dupattr_user.attrs = test_dupattr_attrs; set_entry_parse(&test_dupattr_user); ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &map); assert_int_equal(ret, ERR_OK); /* Set both uidNumber and gidNumber to idNumber */ for (i = 0; i < SDAP_OPTS_USER; i++) { if (map[i].name == NULL) continue; if (strcmp(map[i].name, "uidNumber") == 0 || strcmp(map[i].name, "gidNumber") == 0) { map[i].name = discard_const("idNumber"); } } ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm, map, SDAP_OPTS_USER, &attrs, false); assert_int_equal(ret, ERR_OK); assert_int_equal(attrs->num, 3); /* Every entry has a DN */ assert_entry_has_attr(attrs, SYSDB_ORIG_DN, "cn=dupuser,dc=example,dc=com"); /* Test the single-valued attribute */ assert_entry_has_attr(attrs, SYSDB_UIDNUM, "1234"); assert_entry_has_attr(attrs, SYSDB_GIDNUM, "1234"); talloc_free(map); talloc_free(attrs); } void test_parse_deref(void **state) { errno_t ret; struct sdap_attr_map_info minfo; struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); struct sdap_deref_attrs **res; LDAPDerefRes *dref; const char *oc_values[] = { "posixAccount", NULL }; const char *uid_values[] = { "tuser1", NULL }; const char *extra_values[] = { "extra", NULL }; struct mock_ldap_attr test_ipa_user_attrs[] = { { .name = "objectClass", .values = oc_values }, { .name = "uid", .values = uid_values }, { .name = "extra", .values = extra_values }, { NULL, NULL } }; struct mock_ldap_entry test_ipa_user; test_ipa_user.dn = "cn=testuser,dc=example,dc=com"; test_ipa_user.attrs = test_ipa_user_attrs; ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &minfo.map); minfo.num_attrs = SDAP_OPTS_USER; assert_int_equal(ret, ERR_OK); dref = mock_deref_res(test_ctx, &test_ipa_user); assert_non_null(dref); ret = sdap_parse_deref(test_ctx, &minfo, 1, dref, &res); talloc_free(dref); talloc_free(minfo.map); assert_int_equal(ret, ERR_OK); assert_non_null(res); /* The extra attribute must not be downloaded, it's not present in map */ assert_non_null(res[0]); assert_true(res[0]->map == minfo.map); assert_entry_has_attr(res[0]->attrs, SYSDB_ORIG_DN, "cn=testuser,dc=example,dc=com"); assert_entry_has_attr(res[0]->attrs, SYSDB_NAME, "tuser1"); assert_entry_has_no_attr(res[0]->attrs, "extra"); talloc_free(res); } void test_parse_deref_no_attrs(void **state) { errno_t ret; struct sdap_attr_map_info minfo; struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); struct sdap_deref_attrs **res; LDAPDerefRes *dref; struct mock_ldap_entry test_ipa_user; test_ipa_user.dn = "cn=testuser,dc=example,dc=com"; test_ipa_user.attrs = NULL; ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &minfo.map); minfo.num_attrs = SDAP_OPTS_USER; assert_int_equal(ret, ERR_OK); dref = mock_deref_res(test_ctx, &test_ipa_user); assert_non_null(dref); ret = sdap_parse_deref(test_ctx, &minfo, 1, dref, &res); talloc_free(dref); talloc_free(minfo.map); assert_int_equal(ret, ERR_OK); assert_null(res); /* res must be NULL on receiving no attributes */ } void test_parse_deref_map_mismatch(void **state) { errno_t ret; struct sdap_attr_map_info minfo; struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); struct sdap_deref_attrs **res; LDAPDerefRes *dref; const char *oc_values[] = { "posixAccount", NULL }; const char *uid_values[] = { "tuser1", NULL }; struct mock_ldap_attr test_ipa_user_attrs[] = { { .name = "objectClass", .values = oc_values }, { .name = "uid", .values = uid_values }, { NULL, NULL } }; struct mock_ldap_entry test_ipa_user; test_ipa_user.dn = "cn=testuser,dc=example,dc=com"; test_ipa_user.attrs = test_ipa_user_attrs; ret = sdap_copy_map(test_ctx, rfc2307_group_map, SDAP_OPTS_GROUP, &minfo.map); minfo.num_attrs = SDAP_OPTS_GROUP; assert_int_equal(ret, ERR_OK); dref = mock_deref_res(test_ctx, &test_ipa_user); assert_non_null(dref); ret = sdap_parse_deref(test_ctx, &minfo, 1, dref, &res); talloc_free(dref); talloc_free(minfo.map); assert_int_equal(ret, ERR_OK); assert_non_null(res); /* the group map didn't match, so no attrs will be parsed out of the map */ assert_null(res[0]->attrs); talloc_free(res); } void test_parse_secondary_oc(void **state) { int ret; struct sysdb_attrs *attrs; struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); struct mock_ldap_entry test_rfc2307_group; struct sdap_attr_map *map; const char *oc_values[] = { "secondaryOC", NULL }; const char *uid_values[] = { "tgroup1", NULL }; struct mock_ldap_attr test_rfc2307_group_attrs[] = { { .name = "objectClass", .values = oc_values }, { .name = "uid", .values = uid_values }, { NULL, NULL } }; test_rfc2307_group.dn = "cn=testgroup,dc=example,dc=com"; test_rfc2307_group.attrs = test_rfc2307_group_attrs; set_entry_parse(&test_rfc2307_group); ret = sdap_copy_map(test_ctx, rfc2307_group_map, SDAP_OPTS_GROUP, &map); assert_int_equal(ret, ERR_OK); map[SDAP_OC_GROUP_ALT].name = discard_const("secondaryOC"); ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm, map, SDAP_OPTS_GROUP, &attrs, false); assert_int_equal(ret, ERR_OK); talloc_free(map); talloc_free(attrs); } /* Negative test - objectclass doesn't match the map */ void test_parse_bad_oc(void **state) { int ret; struct sysdb_attrs *attrs; struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); struct mock_ldap_entry test_rfc2307_user; struct sdap_attr_map *map; const char *oc_values[] = { "someRandomValueWhoCaresItsAUnitTest", NULL }; const char *uid_values[] = { "tuser1", NULL }; struct mock_ldap_attr test_rfc2307_user_attrs[] = { { .name = "objectClass", .values = oc_values }, { .name = "uid", .values = uid_values }, { NULL, NULL } }; test_rfc2307_user.dn = "cn=testuser,dc=example,dc=com"; test_rfc2307_user.attrs = test_rfc2307_user_attrs; set_entry_parse(&test_rfc2307_user); ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &map); assert_int_equal(ret, ERR_OK); ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm, map, SDAP_OPTS_USER, &attrs, false); assert_int_not_equal(ret, ERR_OK); talloc_free(map); } /* Negative test - the entry has no objectClass. Just make sure * we don't crash */ void test_parse_no_oc(void **state) { int ret; struct sysdb_attrs *attrs; struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); struct mock_ldap_entry test_rfc2307_user; struct sdap_attr_map *map; const char *uid_values[] = { "tuser1", NULL }; struct mock_ldap_attr test_rfc2307_user_attrs[] = { { .name = "uid", .values = uid_values }, { NULL, NULL } }; test_rfc2307_user.dn = "cn=testuser,dc=example,dc=com"; test_rfc2307_user.attrs = test_rfc2307_user_attrs; set_entry_parse(&test_rfc2307_user); ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &map); assert_int_equal(ret, ERR_OK); ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm, map, SDAP_OPTS_USER, &attrs, false); assert_int_not_equal(ret, ERR_OK); talloc_free(map); } /* Negative test - the entry has no DN. Just make sure * we don't crash and detect the failure. */ void test_parse_no_dn(void **state) { int ret; struct sysdb_attrs *attrs; struct parse_test_ctx *test_ctx = talloc_get_type_abort(*state, struct parse_test_ctx); struct mock_ldap_entry test_rfc2307_user; struct sdap_attr_map *map; const char *oc_values[] = { "posixAccount", NULL }; const char *uid_values[] = { "tuser1", NULL }; struct mock_ldap_attr test_rfc2307_user_attrs[] = { { .name = "objectClass", .values = oc_values }, { .name = "uid", .values = uid_values }, { NULL, NULL } }; test_rfc2307_user.dn = NULL; /* Test */ test_rfc2307_user.attrs = test_rfc2307_user_attrs; set_entry_parse(&test_rfc2307_user); ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &map); assert_int_equal(ret, ERR_OK); ret = sdap_parse_entry(test_ctx, &test_ctx->sh, &test_ctx->sm, map, SDAP_OPTS_USER, &attrs, false); assert_int_not_equal(ret, ERR_OK); talloc_free(map); } struct copy_map_entry_test_ctx { struct sdap_attr_map *src_map; struct sdap_attr_map *dst_map; }; static int copy_map_entry_test_setup(void **state) { int ret; struct copy_map_entry_test_ctx *test_ctx; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct copy_map_entry_test_ctx); assert_non_null(test_ctx); ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &test_ctx->src_map); assert_int_equal(ret, ERR_OK); ret = sdap_copy_map(test_ctx, rfc2307_user_map, SDAP_OPTS_USER, &test_ctx->dst_map); assert_int_equal(ret, ERR_OK); check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int copy_map_entry_test_teardown(void **state) { struct copy_map_entry_test_ctx *test_ctx = talloc_get_type_abort(*state, struct copy_map_entry_test_ctx); assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } static const char *copy_uuid(struct copy_map_entry_test_ctx *test_ctx) { errno_t ret; assert_null(test_ctx->dst_map[SDAP_AT_USER_UUID].name); ret = sdap_copy_map_entry(test_ctx->src_map, test_ctx->dst_map, SDAP_AT_USER_UUID); assert_int_equal(ret, EOK); return test_ctx->dst_map[SDAP_AT_USER_UUID].name; } static void test_sdap_copy_map_entry(void **state) { struct copy_map_entry_test_ctx *test_ctx = talloc_get_type_abort(*state, struct copy_map_entry_test_ctx); const char *uuid_set_val = "test_uuid_val"; const char *uuid_val = NULL; test_ctx->src_map[SDAP_AT_USER_UUID].name = discard_const(uuid_set_val); uuid_val = copy_uuid(test_ctx); assert_non_null(uuid_val); assert_string_equal(uuid_val, uuid_set_val); talloc_free(test_ctx->dst_map[SDAP_AT_USER_UUID].name); } static void test_sdap_copy_map_entry_null_name(void **state) { struct copy_map_entry_test_ctx *test_ctx = talloc_get_type_abort(*state, struct copy_map_entry_test_ctx); const char *uuid_val = NULL; uuid_val = copy_uuid(test_ctx); assert_null(uuid_val); } struct test_sdap_inherit_ctx { struct sdap_options *parent_sdap_opts; struct sdap_options *child_sdap_opts; }; struct sdap_options *mock_sdap_opts(TALLOC_CTX *mem_ctx) { int ret; struct sdap_options *opts; opts = talloc_zero(mem_ctx, struct sdap_options); assert_non_null(opts); ret = sdap_copy_map(opts, rfc2307_user_map, SDAP_OPTS_USER, &opts->user_map); assert_int_equal(ret, ERR_OK); ret = dp_copy_defaults(opts, default_basic_opts, SDAP_OPTS_BASIC, &opts->basic); assert_int_equal(ret, ERR_OK); return opts; } static int test_sdap_inherit_option_setup(void **state) { int ret; struct test_sdap_inherit_ctx *test_ctx; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct test_sdap_inherit_ctx); assert_non_null(test_ctx); test_ctx->child_sdap_opts = talloc_zero(test_ctx, struct sdap_options); test_ctx->parent_sdap_opts = mock_sdap_opts(test_ctx); assert_non_null(test_ctx->parent_sdap_opts); test_ctx->child_sdap_opts = mock_sdap_opts(test_ctx); assert_non_null(test_ctx->child_sdap_opts); test_ctx->parent_sdap_opts->user_map[SDAP_AT_USER_PRINC].name = \ discard_const("test_princ"); ret = dp_opt_set_int(test_ctx->parent_sdap_opts->basic, SDAP_PURGE_CACHE_TIMEOUT, 123); assert_int_equal(ret, EOK); *state = test_ctx; return 0; } static int test_sdap_inherit_option_teardown(void **state) { struct test_sdap_inherit_ctx *test_ctx = \ talloc_get_type_abort(*state, struct test_sdap_inherit_ctx); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } static void test_sdap_inherit_option_null(void **state) { struct test_sdap_inherit_ctx *test_ctx = \ talloc_get_type_abort(*state, struct test_sdap_inherit_ctx); int val; val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, SDAP_PURGE_CACHE_TIMEOUT); assert_int_equal(val, 0); sdap_inherit_options(NULL, test_ctx->parent_sdap_opts, test_ctx->child_sdap_opts); val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, SDAP_PURGE_CACHE_TIMEOUT); assert_int_equal(val, 0); } static void test_sdap_inherit_option_notset(void **state) { struct test_sdap_inherit_ctx *test_ctx = \ talloc_get_type_abort(*state, struct test_sdap_inherit_ctx); int val; const char *inherit_options[] = { "ldap_use_tokengroups", NULL }; val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, SDAP_PURGE_CACHE_TIMEOUT); assert_int_equal(val, 0); /* parent has nondefault, but it's not supposed to be inherited */ sdap_inherit_options(discard_const(inherit_options), test_ctx->parent_sdap_opts, test_ctx->child_sdap_opts); val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, SDAP_PURGE_CACHE_TIMEOUT); assert_int_equal(val, 0); } static void test_sdap_inherit_option_basic(void **state) { struct test_sdap_inherit_ctx *test_ctx = \ talloc_get_type_abort(*state, struct test_sdap_inherit_ctx); int val; const char *inherit_options[] = { "ldap_purge_cache_timeout", NULL }; val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, SDAP_PURGE_CACHE_TIMEOUT); assert_int_equal(val, 0); /* parent has nondefault, but it's not supposed to be inherited */ sdap_inherit_options(discard_const(inherit_options), test_ctx->parent_sdap_opts, test_ctx->child_sdap_opts); val = dp_opt_get_int(test_ctx->child_sdap_opts->basic, SDAP_PURGE_CACHE_TIMEOUT); assert_int_equal(val, 123); } static void test_sdap_inherit_option_user(void **state) { struct test_sdap_inherit_ctx *test_ctx = \ talloc_get_type_abort(*state, struct test_sdap_inherit_ctx); const char *inherit_options[] = { "ldap_user_principal", NULL }; assert_string_equal( test_ctx->child_sdap_opts->user_map[SDAP_AT_USER_PRINC].name, "krbPrincipalName"); /* parent has nondefault, but it's not supposed to be inherited */ sdap_inherit_options(discard_const(inherit_options), test_ctx->parent_sdap_opts, test_ctx->child_sdap_opts); assert_string_equal( test_ctx->child_sdap_opts->user_map[SDAP_AT_USER_PRINC].name, "test_princ"); talloc_free(test_ctx->child_sdap_opts->user_map[SDAP_AT_USER_PRINC].name); } struct copy_dom_obj_test_ctx { struct sdap_options *opts; struct sss_domain_info *parent; struct sss_domain_info *child; struct sdap_domain *parent_sd; struct sdap_domain *child_sd; struct sysdb_attrs **ldap_objects; struct sysdb_attrs **dom_objects; }; static struct sysdb_attrs *test_obj(TALLOC_CTX *mem_ctx, const char *name, const char *basedn) { errno_t ret; const char *orig_dn; struct sysdb_attrs *obj; obj = sysdb_new_attrs(mem_ctx); assert_non_null(obj); orig_dn = talloc_asprintf(obj, "CN=%s,%s", name, basedn); assert_non_null(orig_dn); ret = sysdb_attrs_add_string(obj, SYSDB_ORIG_DN, orig_dn); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(obj, SYSDB_NAME, name); assert_int_equal(ret, EOK); return obj; } static struct sdap_domain *create_sdap_domain(struct sdap_options *opts, struct sss_domain_info *dom) { errno_t ret; struct sdap_domain *sdom; ret = sdap_domain_add(opts, dom, &sdom); assert_int_equal(ret, EOK); sdom->search_bases = talloc_array(sdom, struct sdap_search_base *, 2); assert_non_null(sdom->search_bases); sdom->search_bases[1] = NULL; ret = sdap_create_search_base(sdom, sdom->basedn, LDAP_SCOPE_SUBTREE, NULL, &sdom->search_bases[0]); assert_int_equal(ret, EOK); return sdom; } static int sdap_copy_objects_in_dom_setup(void **state) { struct copy_dom_obj_test_ctx *test_ctx; test_ctx = talloc_zero(NULL, struct copy_dom_obj_test_ctx); assert_non_null(test_ctx); test_ctx->opts = talloc_zero(test_ctx, struct sdap_options); assert_non_null(test_ctx->opts); test_ctx->parent = named_domain(test_ctx, "win.trust.test", NULL); assert_non_null(test_ctx->parent); test_ctx->child = named_domain(test_ctx, "child.win.trust.test", test_ctx->parent); assert_non_null(test_ctx->child); test_ctx->parent_sd = create_sdap_domain(test_ctx->opts, test_ctx->parent); assert_non_null(test_ctx->parent_sd); test_ctx->child_sd = create_sdap_domain(test_ctx->opts, test_ctx->child); assert_non_null(test_ctx->child_sd); /* These two objects were 'returned by LDAP' */ test_ctx->ldap_objects = talloc_zero_array(test_ctx, struct sysdb_attrs *, 2); assert_non_null(test_ctx->ldap_objects); test_ctx->ldap_objects[0] = test_obj(test_ctx->ldap_objects, "parent", test_ctx->parent_sd->basedn); assert_non_null(test_ctx->ldap_objects[0]); test_ctx->ldap_objects[1] = test_obj(test_ctx->ldap_objects, "child", test_ctx->child_sd->basedn); assert_non_null(test_ctx->ldap_objects[1]); /* This is the array we'll filter to */ test_ctx->dom_objects = talloc_zero_array(test_ctx, struct sysdb_attrs *, 2); assert_non_null(test_ctx->dom_objects); *state = test_ctx; return 0; } static int sdap_copy_objects_in_dom_teardown(void **state) { struct copy_dom_obj_test_ctx *test_ctx = talloc_get_type_abort(*state, struct copy_dom_obj_test_ctx); talloc_free(test_ctx); return 0; } static void test_sdap_copy_objects_in_dom(void **state) { struct copy_dom_obj_test_ctx *test_ctx = talloc_get_type_abort(*state, struct copy_dom_obj_test_ctx); size_t count; assert_ptr_equal(talloc_parent(test_ctx->ldap_objects[0]), test_ctx->ldap_objects); assert_ptr_equal(talloc_parent(test_ctx->ldap_objects[1]), test_ctx->ldap_objects); assert_null(test_ctx->dom_objects[0]); assert_null(test_ctx->dom_objects[1]); count = sdap_steal_objects_in_dom(test_ctx->opts, test_ctx->dom_objects, 0, test_ctx->parent, test_ctx->ldap_objects, 2, true); assert_int_equal(count, 1); assert_non_null(test_ctx->dom_objects[0]); assert_non_null(test_ctx->dom_objects[0] == test_ctx->ldap_objects[0]); assert_null(test_ctx->dom_objects[1]); assert_ptr_equal(talloc_parent(test_ctx->ldap_objects[0]), test_ctx->dom_objects); count = sdap_steal_objects_in_dom(test_ctx->opts, test_ctx->dom_objects, 1, test_ctx->child, test_ctx->ldap_objects, 2, true); assert_int_equal(count, 1); assert_non_null(test_ctx->dom_objects[1]); assert_non_null(test_ctx->dom_objects[1] == test_ctx->ldap_objects[1]); assert_ptr_equal(talloc_parent(test_ctx->ldap_objects[1]), test_ctx->dom_objects); } static void test_sdap_copy_objects_in_dom_nofilter(void **state) { struct copy_dom_obj_test_ctx *test_ctx = talloc_get_type_abort(*state, struct copy_dom_obj_test_ctx); size_t count; count = sdap_steal_objects_in_dom(test_ctx->opts, test_ctx->dom_objects, 0, test_ctx->parent, test_ctx->ldap_objects, 2, false); assert_int_equal(count, 2); assert_ptr_equal(talloc_parent(test_ctx->ldap_objects[0]), test_ctx->dom_objects); assert_ptr_equal(talloc_parent(test_ctx->ldap_objects[1]), test_ctx->dom_objects); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_parse_with_map, parse_entry_test_setup, parse_entry_test_teardown), cmocka_unit_test_setup_teardown(test_parse_no_map, parse_entry_test_setup, parse_entry_test_teardown), cmocka_unit_test_setup_teardown(test_parse_no_attrs, parse_entry_test_setup, parse_entry_test_teardown), cmocka_unit_test_setup_teardown(test_parse_dups, parse_entry_test_setup, parse_entry_test_teardown), cmocka_unit_test_setup_teardown(test_parse_deref, parse_entry_test_setup, parse_entry_test_teardown), cmocka_unit_test_setup_teardown(test_parse_deref_no_attrs, parse_entry_test_setup, parse_entry_test_teardown), cmocka_unit_test_setup_teardown(test_parse_secondary_oc, parse_entry_test_setup, parse_entry_test_teardown), /* Negative tests */ cmocka_unit_test_setup_teardown(test_parse_no_oc, parse_entry_test_setup, parse_entry_test_teardown), cmocka_unit_test_setup_teardown(test_parse_bad_oc, parse_entry_test_setup, parse_entry_test_teardown), cmocka_unit_test_setup_teardown(test_parse_no_dn, parse_entry_test_setup, parse_entry_test_teardown), cmocka_unit_test_setup_teardown(test_parse_deref_map_mismatch, parse_entry_test_setup, parse_entry_test_teardown), /* Map option tests */ cmocka_unit_test_setup_teardown(test_sdap_copy_map_entry, copy_map_entry_test_setup, copy_map_entry_test_teardown), cmocka_unit_test_setup_teardown(test_sdap_copy_map_entry_null_name, copy_map_entry_test_setup, copy_map_entry_test_teardown), /* Option inherit tests */ cmocka_unit_test_setup_teardown(test_sdap_inherit_option_null, test_sdap_inherit_option_setup, test_sdap_inherit_option_teardown), cmocka_unit_test_setup_teardown(test_sdap_inherit_option_notset, test_sdap_inherit_option_setup, test_sdap_inherit_option_teardown), cmocka_unit_test_setup_teardown(test_sdap_inherit_option_basic, test_sdap_inherit_option_setup, test_sdap_inherit_option_teardown), cmocka_unit_test_setup_teardown(test_sdap_inherit_option_user, test_sdap_inherit_option_setup, test_sdap_inherit_option_teardown), /* Per-domain object filter tests */ cmocka_unit_test_setup_teardown(test_sdap_copy_objects_in_dom, sdap_copy_objects_in_dom_setup, sdap_copy_objects_in_dom_teardown), cmocka_unit_test_setup_teardown(test_sdap_copy_objects_in_dom_nofilter, sdap_copy_objects_in_dom_setup, sdap_copy_objects_in_dom_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_sdap_access.c0000644000000000000000000000007412703456111021166 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.047794961 sssd-1.13.4/src/tests/cmocka/test_sdap_access.c0000644002412700241270000000442012703456111022635 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Reichl Copyright (C) 2015 Red Hat SSSD tests - sdap access This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "tests/common_check.h" #include "tests/cmocka/test_expire_common.h" /* linking against function from sdap_access.c module */ extern bool nds_check_expired(const char *exp_time_str); static void nds_check_expired_wrap(void *in, void *_out) { *(bool*)_out = nds_check_expired((const char*)in); } void test_nds_check_expire(void **state) { struct expire_test_ctx *tc; bool res; tc = talloc_get_type(*state, struct expire_test_ctx); assert_non_null(tc); assert_false(nds_check_expired(NULL)); assert_true(nds_check_expired(tc->invalid_longer_format)); assert_true(nds_check_expired(tc->invalid_format)); assert_true(nds_check_expired(tc->past_time)); assert_false(nds_check_expired(tc->future_time)); /* changing time zone has no effect as time of expiration is in UTC */ expire_test_tz("GST+2", nds_check_expired_wrap, (void*)tc->future_time, (void*)&res); assert_false(res); expire_test_tz("GST-2", nds_check_expired_wrap, (void*)tc->future_time, (void*)&res); assert_false(res); } int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_nds_check_expire, expire_test_setup, expire_test_teardown) }; return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/common_mock_sysdb_objects.c0000644000000000000000000000007412703456111023075 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.941794602 sssd-1.13.4/src/tests/cmocka/common_mock_sysdb_objects.c0000644002412700241270000001216212703456111024546 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "db/sysdb.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_sysdb_objects.h" enum sysdb_attr_type { SYSDB_ATTR_TYPE_BOOL, SYSDB_ATTR_TYPE_LONG, SYSDB_ATTR_TYPE_UINT32, SYSDB_ATTR_TYPE_TIME, SYSDB_ATTR_TYPE_STRING }; static enum sysdb_attr_type get_attr_type(const char *attr) { /* Most attributes in sysdb are strings. Since this is only for the purpose * of unit tests, we can safe ourselves some time and handle all attributes * that are not listed amongst other types as string instead of invalid * or unknown. */ static const char *table_bool[] = { SYSDB_POSIX, NULL }; static const char *table_long[] = { NULL }; static const char *table_uint32[] = { SYSDB_UIDNUM, SYSDB_GIDNUM, NULL }; static const char *table_time[] = { SYSDB_CACHE_EXPIRE, NULL }; static const char **tables[SYSDB_ATTR_TYPE_STRING] = { table_bool, table_long, table_uint32, table_time }; enum sysdb_attr_type type; int i; for (type = 0; type < SYSDB_ATTR_TYPE_STRING; type++) { for (i = 0; tables[type][i] != NULL; i++) { if (strcmp(attr, tables[type][i]) == 0) { return type; } } } /* we didn't find the attribute, consider it as string */ return SYSDB_ATTR_TYPE_STRING; } static errno_t fill_attrs(struct sysdb_attrs *attrs, va_list in_ap) { va_list ap; const char *attr = NULL; errno_t ret; va_copy(ap, in_ap); while ((attr = va_arg(ap, const char *)) != NULL) { switch (get_attr_type(attr)) { case SYSDB_ATTR_TYPE_STRING: ret = sysdb_attrs_add_string(attrs, attr, va_arg(ap, const char *)); break; case SYSDB_ATTR_TYPE_BOOL: /* _Bool is implicitly promoted to int in variadic functions */ ret = sysdb_attrs_add_bool(attrs, attr, va_arg(ap, int)); break; case SYSDB_ATTR_TYPE_LONG: ret = sysdb_attrs_add_long(attrs, attr, va_arg(ap, long int)); break; case SYSDB_ATTR_TYPE_UINT32: ret = sysdb_attrs_add_uint32(attrs, attr, va_arg(ap, uint32_t)); break; case SYSDB_ATTR_TYPE_TIME: ret = sysdb_attrs_add_time_t(attrs, attr, va_arg(ap, time_t)); break; } if (ret != EOK) { return ret; } } va_end(ap); return EOK; } struct sysdb_attrs * _mock_sysdb_object(TALLOC_CTX *mem_ctx, const char *base_dn, const char *name, ...) { va_list ap; struct sysdb_attrs *attrs = NULL; char *orig_dn = NULL; errno_t ret; attrs = sysdb_new_attrs(mem_ctx); if (attrs == NULL) { goto fail; } orig_dn = talloc_asprintf(attrs, "cn=%s,%s", name, base_dn); if (orig_dn == NULL) { goto fail; } ret = sysdb_attrs_add_string(attrs, SYSDB_ORIG_DN, orig_dn); if (ret != EOK) { goto fail; } ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name); if (ret != EOK) { goto fail; } va_start(ap, name); ret = fill_attrs(attrs, ap); va_end(ap); if (ret != EOK) { goto fail; } talloc_free(orig_dn); return attrs; fail: talloc_free(attrs); return NULL; } struct sysdb_attrs * mock_sysdb_group_rfc2307bis(TALLOC_CTX *mem_ctx, const char *base_dn, gid_t gid, const char *name, const char **members) { struct sysdb_attrs *attrs = NULL; errno_t ret; int i; attrs = mock_sysdb_object(mem_ctx, base_dn, name, SYSDB_GIDNUM, gid); if (attrs == NULL) { return NULL; } if (members != NULL) { for (i = 0; members[i] != NULL; i++) { ret = sysdb_attrs_add_string(attrs, SYSDB_MEMBER, members[i]); if (ret != EOK) { talloc_zfree(attrs); return NULL; } } } return attrs; } struct sysdb_attrs * mock_sysdb_user(TALLOC_CTX *mem_ctx, const char *base_dn, uid_t uid, const char *name) { return mock_sysdb_object(mem_ctx, base_dn, name, SYSDB_UIDNUM, uid); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/common_mock_krb5.h0000644000000000000000000000007412703456111021110 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.588793405 sssd-1.13.4/src/tests/cmocka/common_mock_krb5.h0000644002412700241270000000315612703456111022564 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Jakub Hrozek Copyright (C) 2015 Red Hat SSSD tests: Tests keytab utilities This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __COMMON_MOCK_KRB5_H_ #define __COMMON_MOCK_KRB5_H_ #include "util/sss_krb5.h" #include "tests/cmocka/common_mock.h" void mock_krb5_keytab_entry(krb5_keytab_entry *kent, krb5_principal principal, krb5_timestamp timestamp, krb5_kvno vno, krb5_enctype enctype, const char *key); int mock_keytab(krb5_context kctx, const char *kt_path, krb5_keytab_entry *kt_keys, size_t nkeys); /* Dummy keys with user-selected principal */ int mock_keytab_with_contents(TALLOC_CTX *mem_ctx, const char *keytab_path, const char *keytab_princ); #endif /* __COMMON_MOCK_KRB5_H_ */ sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_sysdb_utils.c0000644000000000000000000000007412703456111021262 xustar0030 atime=1460561751.657715651 30 ctime=1460561775.050794971 sssd-1.13.4/src/tests/cmocka/test_sysdb_utils.c0000644002412700241270000001055712703456111022741 0ustar00jhrozekjhrozek00000000000000/* SSSD sysdb_utils - Tests for various sysdb calls Authors: Sumit Bose Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "tests/cmocka/common_mock.h" #define IPA_UUID "bcae7c40-97eb-11e4-88ca-525400e96a6b" #define AD_GUID_BIN {0x8d, 0x0d, 0xa8, 0xfe, 0xd5, 0xdb, 0x84, 0x4f, \ 0x85, 0x74, 0x7d, 0xb0, 0x47, 0x7f, 0x96, 0x2e}; #define AD_GUID "fea80d8d-dbd5-4f84-8574-7db0477f962e" static void test_sysdb_handle_original_uuid(void **state) { int ret; struct sysdb_attrs *src_attrs; struct sysdb_attrs *dest_attrs; const char *guid; uint8_t bin_guid[] = AD_GUID_BIN; struct ldb_val guid_val = {bin_guid, 16}; ret = sysdb_handle_original_uuid(NULL, NULL, NULL, NULL, NULL); assert_int_equal(ret, ENOENT); src_attrs = sysdb_new_attrs(NULL); assert_non_null(src_attrs); dest_attrs = sysdb_new_attrs(NULL); assert_non_null(dest_attrs); ret = sysdb_handle_original_uuid("xyz", src_attrs, "abc", dest_attrs, "def"); assert_int_equal(ret, ENOENT); ret = sysdb_attrs_add_val(src_attrs, "GUID", &guid_val); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(src_attrs, "UUID", IPA_UUID); assert_int_equal(ret, EOK); ret = sysdb_handle_original_uuid(NULL, src_attrs, "GUID", dest_attrs, "def"); assert_int_equal(ret, ENOENT); ret = sysdb_handle_original_uuid("objectGUID", NULL, "GUID", dest_attrs, "def"); assert_int_equal(ret, EINVAL); ret = sysdb_handle_original_uuid("objectGUID", src_attrs, "GUID", dest_attrs, "def"); assert_int_equal(ret, EOK); ret = sysdb_attrs_get_string(dest_attrs, "def", &guid); assert_int_equal(ret, EOK); assert_string_equal(guid, AD_GUID); ret = sysdb_handle_original_uuid("ipaUniqueID", src_attrs, "UUID", dest_attrs, "ghi"); assert_int_equal(ret, EOK); ret = sysdb_attrs_get_string(dest_attrs, "ghi", &guid); assert_int_equal(ret, EOK); assert_string_equal(guid, IPA_UUID); talloc_free(src_attrs); src_attrs = sysdb_new_attrs(NULL); assert_non_null(src_attrs); /* check objectGUID with length other than 16 */ ret = sysdb_attrs_add_string(src_attrs, "GUID", IPA_UUID); assert_int_equal(ret, EOK); ret = sysdb_handle_original_uuid("objectGUID", src_attrs, "GUID", dest_attrs, "jkl"); assert_int_equal(ret, EOK); ret = sysdb_attrs_get_string(dest_attrs, "jkl", &guid); assert_int_equal(ret, EOK); assert_string_equal(guid, IPA_UUID); talloc_free(src_attrs); talloc_free(dest_attrs); } int main(int argc, const char *argv[]) { int rv; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test(test_sysdb_handle_original_uuid), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); rv = cmocka_run_group_tests(tests, NULL, NULL); return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_nested_groups.c0000644000000000000000000000007412703456111021577 xustar0030 atime=1460561751.656715648 30 ctime=1460561774.942794605 sssd-1.13.4/src/tests/cmocka/test_nested_groups.c0000644002412700241270000012565712703456111023266 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_sdap.h" #include "tests/cmocka/common_mock_be.h" #include "tests/cmocka/common_mock_sysdb_objects.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap.h" #include "providers/ldap/sdap_idmap.h" #include "providers/ldap/sdap_async_private.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_ldap_nested_groups_conf.ldb" #define TEST_DOM_NAME "ldap_nested_groups_test" #define TEST_ID_PROVIDER "ldap" #define TEST_EXT_MEMBER "extMember" #define new_test(test) \ cmocka_unit_test_setup_teardown(nested_groups_test_ ## test, \ nested_groups_test_setup, \ nested_groups_test_teardown) /* put users and groups under the same container so we can easily run the * same tests cases for several search base scenarios */ #define OBJECT_BASE_DN "cn=objects,dc=test,dc=com" #define GROUP_BASE_DN "cn=groups," OBJECT_BASE_DN #define USER_BASE_DN "cn=users," OBJECT_BASE_DN struct nested_groups_test_ctx { struct sss_test_ctx *tctx; struct be_ctx *be_ctx; struct sdap_options *sdap_opts; struct sdap_handle *sdap_handle; struct sdap_domain *sdap_domain; struct sdap_idmap_ctx *idmap_ctx; struct sdap_id_ctx *sdap_id_ctx; hash_table_t *missing_external; struct sysdb_attrs **users; struct sysdb_attrs **groups; unsigned long num_users; unsigned long num_groups; /* External members tests */ struct sdap_ext_member_ctx *ext_ctx; enum sysdb_member_type ext_member_type; struct sss_domain_info *ext_dom; struct sysdb_attrs *ext_member; }; errno_t krb5_try_kdcip(struct confdb_ctx *cdb, const char *conf_path, struct dp_option *opts, int opt_id) { return EOK; } /* Both arrays must have the same length! */ static void compare_sysdb_string_array_noorder(struct sysdb_attrs **sysdb_array, const char **string_array, size_t len) { int i, ii; errno_t ret; const char *name; /* Check the returned groups. The order is irrelevant. */ for (i = 0; i < len; i++) { ret = sysdb_attrs_get_string(sysdb_array[i], SYSDB_NAME, &name); assert_int_equal(ret, ERR_OK); for (ii = 0; ii < len; ii++) { if (string_array[ii] == NULL) { continue; } if (strcmp(name, string_array[ii]) == 0) { string_array[ii] = NULL; break; } } } for (i = 0; i < len; i++) { assert_null(string_array[i]); } } static void nested_groups_test_done(struct tevent_req *req) { struct nested_groups_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct nested_groups_test_ctx); ctx->tctx->error = sdap_nested_group_recv(ctx, req, &ctx->num_users, &ctx->users, &ctx->num_groups, &ctx->groups, &ctx->missing_external); talloc_zfree(req); ctx->tctx->done = true; } static void nested_groups_test_one_group_no_members(void **state) { struct nested_groups_test_ctx *test_ctx = NULL; struct sysdb_attrs *rootgroup = NULL; struct tevent_req *req = NULL; TALLOC_CTX *req_mem_ctx = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx); rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000, "rootgroup", NULL); /* mock return values */ sss_will_return_always(sdap_has_deref_support, false); /* run test, check for memory leaks */ req_mem_ctx = talloc_new(global_talloc_context); assert_non_null(req_mem_ctx); check_leaks_push(req_mem_ctx); req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->sdap_domain, test_ctx->sdap_opts, test_ctx->sdap_handle, rootgroup); assert_non_null(req); tevent_req_set_callback(req, nested_groups_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_true(check_leaks_pop(req_mem_ctx) == true); talloc_zfree(req_mem_ctx); /* check return code */ assert_int_equal(ret, ERR_OK); /* check generated values */ assert_int_equal(test_ctx->num_users, 0); assert_null(test_ctx->users); assert_int_equal(test_ctx->num_groups, 1); assert_non_null(test_ctx->groups); assert_true(rootgroup == test_ctx->groups[0]); } static void nested_groups_test_one_group_unique_members(void **state) { struct nested_groups_test_ctx *test_ctx = NULL; struct sysdb_attrs *rootgroup = NULL; struct tevent_req *req = NULL; TALLOC_CTX *req_mem_ctx = NULL; errno_t ret; const char *users[] = { "cn=user1,"USER_BASE_DN, "cn=user2,"USER_BASE_DN, NULL }; const struct sysdb_attrs *user1_reply[2] = { NULL }; const struct sysdb_attrs *user2_reply[2] = { NULL }; const char * expected[] = { "user1", "user2" }; test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx); /* mock return values */ rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000, "rootgroup", users); user1_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1"); assert_non_null(user1_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, user1_reply); will_return(sdap_get_generic_recv, ERR_OK); user2_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2002, "user2"); assert_non_null(user2_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, user2_reply); will_return(sdap_get_generic_recv, ERR_OK); sss_will_return_always(sdap_has_deref_support, false); /* run test, check for memory leaks */ req_mem_ctx = talloc_new(global_talloc_context); assert_non_null(req_mem_ctx); check_leaks_push(req_mem_ctx); req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->sdap_domain, test_ctx->sdap_opts, test_ctx->sdap_handle, rootgroup); assert_non_null(req); tevent_req_set_callback(req, nested_groups_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_true(check_leaks_pop(req_mem_ctx) == true); talloc_zfree(req_mem_ctx); /* check return code */ assert_int_equal(ret, ERR_OK); /* Check the users */ assert_int_equal(test_ctx->num_users, N_ELEMENTS(expected)); assert_int_equal(test_ctx->num_groups, 1); compare_sysdb_string_array_noorder(test_ctx->users, expected, N_ELEMENTS(expected)); } static void nested_groups_test_one_group_dup_users(void **state) { struct nested_groups_test_ctx *test_ctx = NULL; struct sysdb_attrs *rootgroup = NULL; struct tevent_req *req = NULL; TALLOC_CTX *req_mem_ctx = NULL; errno_t ret; const char *name; const char *users[] = { "cn=user1,"USER_BASE_DN, "cn=user1,"USER_BASE_DN, NULL }; const struct sysdb_attrs *user1_reply[2] = { NULL }; const struct sysdb_attrs *user2_reply[2] = { NULL }; test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx); /* mock return values */ rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000, "rootgroup", users); user1_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1"); assert_non_null(user1_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, user1_reply); will_return(sdap_get_generic_recv, ERR_OK); user2_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1"); assert_non_null(user2_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, user2_reply); will_return(sdap_get_generic_recv, ERR_OK); sss_will_return_always(sdap_has_deref_support, false); /* run test, check for memory leaks */ req_mem_ctx = talloc_new(global_talloc_context); assert_non_null(req_mem_ctx); check_leaks_push(req_mem_ctx); req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->sdap_domain, test_ctx->sdap_opts, test_ctx->sdap_handle, rootgroup); assert_non_null(req); tevent_req_set_callback(req, nested_groups_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_true(check_leaks_pop(req_mem_ctx) == true); talloc_zfree(req_mem_ctx); /* check return code */ assert_int_equal(ret, ERR_OK); /* Check the users */ assert_int_equal(test_ctx->num_users, 1); assert_int_equal(test_ctx->num_groups, 1); ret = sysdb_attrs_get_string(test_ctx->users[0], SYSDB_NAME, &name); assert_int_equal(ret, ERR_OK); assert_string_equal(name, "user1"); } static void nested_groups_test_one_group_unique_group_members(void **state) { struct nested_groups_test_ctx *test_ctx = NULL; struct sysdb_attrs *rootgroup = NULL; struct tevent_req *req = NULL; TALLOC_CTX *req_mem_ctx = NULL; errno_t ret; const char *groups[] = { "cn=emptygroup1,"GROUP_BASE_DN, "cn=emptygroup2,"GROUP_BASE_DN, NULL }; const struct sysdb_attrs *group1_reply[2] = { NULL }; const struct sysdb_attrs *group2_reply[2] = { NULL }; const char * expected[] = { "rootgroup", "emptygroup1", "emptygroup2" }; test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx); /* mock return values */ rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000, "rootgroup", groups); group1_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1001, "emptygroup1", NULL); assert_non_null(group1_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, group1_reply); will_return(sdap_get_generic_recv, ERR_OK); group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1002, "emptygroup2", NULL); assert_non_null(group2_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, group2_reply); will_return(sdap_get_generic_recv, ERR_OK); sss_will_return_always(sdap_has_deref_support, false); /* run test, check for memory leaks */ req_mem_ctx = talloc_new(global_talloc_context); assert_non_null(req_mem_ctx); check_leaks_push(req_mem_ctx); req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->sdap_domain, test_ctx->sdap_opts, test_ctx->sdap_handle, rootgroup); assert_non_null(req); tevent_req_set_callback(req, nested_groups_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_true(check_leaks_pop(req_mem_ctx) == true); talloc_zfree(req_mem_ctx); /* check return code */ assert_int_equal(ret, ERR_OK); /* Check the users */ assert_int_equal(test_ctx->num_users, 0); assert_int_equal(test_ctx->num_groups, N_ELEMENTS(expected)); compare_sysdb_string_array_noorder(test_ctx->groups, expected, N_ELEMENTS(expected)); } static void nested_groups_test_one_group_dup_group_members(void **state) { struct nested_groups_test_ctx *test_ctx = NULL; struct sysdb_attrs *rootgroup = NULL; struct tevent_req *req = NULL; TALLOC_CTX *req_mem_ctx = NULL; errno_t ret; const char *groups[] = { "cn=emptygroup1,"GROUP_BASE_DN, "cn=emptygroup1,"GROUP_BASE_DN, NULL }; const struct sysdb_attrs *group1_reply[2] = { NULL }; const struct sysdb_attrs *group2_reply[2] = { NULL }; const char * expected[] = { "rootgroup", "emptygroup1" }; test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx); /* mock return values */ rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000, "rootgroup", groups); group1_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1001, "emptygroup1", NULL); assert_non_null(group1_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, group1_reply); will_return(sdap_get_generic_recv, ERR_OK); group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1001, "emptygroup1", NULL); assert_non_null(group2_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, group2_reply); will_return(sdap_get_generic_recv, ERR_OK); sss_will_return_always(sdap_has_deref_support, false); /* run test, check for memory leaks */ req_mem_ctx = talloc_new(global_talloc_context); assert_non_null(req_mem_ctx); check_leaks_push(req_mem_ctx); req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->sdap_domain, test_ctx->sdap_opts, test_ctx->sdap_handle, rootgroup); assert_non_null(req); tevent_req_set_callback(req, nested_groups_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_true(check_leaks_pop(req_mem_ctx) == true); talloc_zfree(req_mem_ctx); /* check return code */ assert_int_equal(ret, ERR_OK); assert_int_equal(test_ctx->num_users, 0); assert_int_equal(test_ctx->num_groups, N_ELEMENTS(expected)); compare_sysdb_string_array_noorder(test_ctx->groups, expected, N_ELEMENTS(expected)); } static void nested_groups_test_nested_chain(void **state) { struct nested_groups_test_ctx *test_ctx = NULL; struct tevent_req *req = NULL; TALLOC_CTX *req_mem_ctx = NULL; errno_t ret; const char *rootgroup_members[] = { "cn=user1,"USER_BASE_DN, "cn=group1,"GROUP_BASE_DN, NULL }; const char *group1_members[] = { "cn=user2,"USER_BASE_DN, "cn=group2,"GROUP_BASE_DN, NULL }; const char *group2_members[] = { "cn=user3,"USER_BASE_DN, NULL }; struct sysdb_attrs *rootgroup; const struct sysdb_attrs *user1_reply[2] = { NULL }; const struct sysdb_attrs *group1_reply[2] = { NULL }; const struct sysdb_attrs *user2_reply[2] = { NULL }; const struct sysdb_attrs *group2_reply[2] = { NULL }; const struct sysdb_attrs *user3_reply[2] = { NULL }; const char *expected_groups[] = { "rootgroup", "group1", "group2" }; const char *expected_users[] = { "user1", "user2", "user3" }; test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx); /* mock return values */ rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000, "rootgroup", rootgroup_members); assert_non_null(rootgroup); user1_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1"); assert_non_null(user1_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, user1_reply); will_return(sdap_get_generic_recv, ERR_OK); group1_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1001, "group1", group1_members); assert_non_null(group1_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, group1_reply); will_return(sdap_get_generic_recv, ERR_OK); user2_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2002, "user2"); assert_non_null(user2_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, user2_reply); will_return(sdap_get_generic_recv, ERR_OK); group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1002, "group2", group2_members); assert_non_null(group2_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, group2_reply); will_return(sdap_get_generic_recv, ERR_OK); user3_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2003, "user3"); assert_non_null(user3_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, user3_reply); will_return(sdap_get_generic_recv, ERR_OK); sss_will_return_always(sdap_has_deref_support, false); /* run test, check for memory leaks */ req_mem_ctx = talloc_new(global_talloc_context); assert_non_null(req_mem_ctx); check_leaks_push(req_mem_ctx); req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->sdap_domain, test_ctx->sdap_opts, test_ctx->sdap_handle, rootgroup); assert_non_null(req); tevent_req_set_callback(req, nested_groups_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_true(check_leaks_pop(req_mem_ctx) == true); talloc_zfree(req_mem_ctx); /* check return code */ assert_int_equal(ret, ERR_OK); /* Check the users */ assert_int_equal(test_ctx->num_users, N_ELEMENTS(expected_users)); assert_int_equal(test_ctx->num_groups, N_ELEMENTS(expected_groups)); compare_sysdb_string_array_noorder(test_ctx->groups, expected_groups, N_ELEMENTS(expected_groups)); compare_sysdb_string_array_noorder(test_ctx->users, expected_users, N_ELEMENTS(expected_users)); } static void nested_groups_test_nested_chain_with_error(void **state) { struct nested_groups_test_ctx *test_ctx = NULL; struct tevent_req *req = NULL; TALLOC_CTX *req_mem_ctx = NULL; errno_t ret; const char *rootgroup_members[] = { "cn=group1,"GROUP_BASE_DN, NULL }; const char *group1_members[] = { "cn=group2,"GROUP_BASE_DN, NULL }; const char *group2_members[] = { "cn=user1,"USER_BASE_DN, NULL }; struct sysdb_attrs *rootgroup; const struct sysdb_attrs *user_reply[2] = { NULL }; const struct sysdb_attrs *group1_reply[2] = { NULL }; const struct sysdb_attrs *group2_reply[2] = { NULL }; test_ctx = talloc_get_type_abort(*state, struct nested_groups_test_ctx); /* mock return values */ rootgroup = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1000, "rootgroup", rootgroup_members); assert_non_null(rootgroup); group1_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1001, "group1", group1_members); assert_non_null(group1_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, group1_reply); will_return(sdap_get_generic_recv, ERR_OK); group2_reply[0] = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, 1002, "group2", group2_members); assert_non_null(group2_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, group2_reply); will_return(sdap_get_generic_recv, ERR_OK); user_reply[0] = mock_sysdb_user(test_ctx, USER_BASE_DN, 2001, "user1"); assert_non_null(user_reply[0]); will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, user_reply); will_return(sdap_get_generic_recv, EIO); sss_will_return_always(sdap_has_deref_support, false); /* run test, check for memory leaks */ req_mem_ctx = talloc_new(global_talloc_context); assert_non_null(req_mem_ctx); check_leaks_push(req_mem_ctx); req = sdap_nested_group_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->sdap_domain, test_ctx->sdap_opts, test_ctx->sdap_handle, rootgroup); assert_non_null(req); tevent_req_set_callback(req, nested_groups_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_true(check_leaks_pop(req_mem_ctx) == true); talloc_zfree(req_mem_ctx); /* check return code */ assert_int_equal(ret, EIO); } static int nested_groups_test_setup(void **state) { errno_t ret; struct nested_groups_test_ctx *test_ctx = NULL; static struct sss_test_conf_param params[] = { { "ldap_schema", "rfc2307bis" }, /* enable nested groups */ { "ldap_search_base", OBJECT_BASE_DN }, { "ldap_user_search_base", USER_BASE_DN }, { "ldap_group_search_base", GROUP_BASE_DN }, { NULL, NULL } }; test_ctx = talloc_zero(NULL, struct nested_groups_test_ctx); assert_non_null(test_ctx); *state = test_ctx; /* initialize domain */ test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, params); assert_non_null(test_ctx->tctx); /* mock SDAP */ test_ctx->sdap_opts = mock_sdap_options_ldap(test_ctx, test_ctx->tctx->dom, test_ctx->tctx->confdb, test_ctx->tctx->conf_dom_path); assert_non_null(test_ctx->sdap_opts); test_ctx->sdap_domain = test_ctx->sdap_opts->sdom; test_ctx->sdap_handle = mock_sdap_handle(test_ctx); assert_non_null(test_ctx->sdap_handle); test_ctx->be_ctx = mock_be_ctx(test_ctx, test_ctx->tctx); assert_non_null(test_ctx->be_ctx); test_ctx->sdap_id_ctx = mock_sdap_id_ctx(test_ctx, test_ctx->be_ctx, test_ctx->sdap_opts); assert_non_null(test_ctx->sdap_id_ctx); ret = sdap_idmap_init(test_ctx, test_ctx->sdap_id_ctx, &test_ctx->idmap_ctx); assert_int_equal(ret, EOK); test_ctx->sdap_opts->idmap_ctx = test_ctx->idmap_ctx; test_ctx->ext_ctx = talloc_zero(test_ctx, struct sdap_ext_member_ctx); assert_non_null(test_ctx->ext_ctx); return 0; } static int nested_groups_test_teardown(void **state) { talloc_zfree(*state); return 0; } struct test_ext_pvt { struct sss_domain_info *dom_head; }; struct test_ext_member { const char *sid; const char *name; id_t id; enum sysdb_member_type member_type; } test_ext_member_table[] = { { "S-1-5-21-3623811015-3361044348-30300820-10001", "ext_user10001", 10001, SYSDB_MEMBER_USER }, { "S-1-5-21-3623811015-3361044348-30300820-20001", "ext_group20001", 10001, SYSDB_MEMBER_GROUP }, { NULL, NULL, 0, 0 }, }; struct test_resolve_ext_state { struct sss_domain_info *dom; enum sysdb_member_type member_type; struct sysdb_attrs *member; }; static errno_t test_resolve_ext_save_obj(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *name, id_t id, enum sysdb_member_type member_type, struct sysdb_attrs **_member); struct tevent_req *test_resolve_ext_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *ext_member, void *pvt) { struct tevent_req *req; struct test_resolve_ext_state *state; errno_t ret; struct test_ext_pvt *test_pvt = talloc_get_type(pvt, struct test_ext_pvt); struct sysdb_attrs *member; req = tevent_req_create(mem_ctx, &state, struct test_resolve_ext_state); if (req == NULL) { return NULL; } for (size_t i = 0; test_ext_member_table[i].sid; i++) { if (strcmp(ext_member, test_ext_member_table[i].sid) == 0) { ret = test_resolve_ext_save_obj(state, test_pvt->dom_head, test_ext_member_table[i].name, test_ext_member_table[i].id, test_ext_member_table[i].member_type, &member); if (ret != EOK) { goto immediate; } state->dom = test_pvt->dom_head; state->member_type = test_ext_member_table[i].member_type; state->member = talloc_steal(state, member); ret = EOK; goto immediate; } } ret = ENOENT; immediate: if (ret != EOK) { tevent_req_error(req, ret); } else { tevent_req_done(req); } tevent_req_post(req, ev); return req; } static errno_t test_resolve_ext_save_obj(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, const char *name, id_t id, enum sysdb_member_type member_type, struct sysdb_attrs **_member) { errno_t ret; struct ldb_result *res; char *home; struct sysdb_attrs **members; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { return ENOMEM; } if (member_type == SYSDB_MEMBER_USER) { home = talloc_asprintf(tmp_ctx, "/home/%s", name); if (home == NULL) { ret = ENOMEM; goto done; } ret = sysdb_store_user(dom, name, "*", id, id, name, home, "/bin/bash", NULL, NULL, NULL, 1000, time(NULL)); if (ret != EOK) { goto done; } ret = sysdb_getpwnam(tmp_ctx, dom, name, &res); if (ret != EOK) { goto done; } } else if (member_type == SYSDB_MEMBER_GROUP) { ret = sysdb_store_group(dom, name, id, NULL, 1000, time(NULL)); if (ret != EOK) { goto done; } ret = sysdb_getgrnam(tmp_ctx, dom, name, &res); if (ret != EOK) { goto done; } } else { ret = EINVAL; goto done; } ret = sysdb_msg2attrs(tmp_ctx, 1, res->msgs, &members); if (ret != EOK) { goto done; } *_member = talloc_steal(mem_ctx, members[0]); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t test_resolve_ext_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, enum sysdb_member_type *_member_type, struct sss_domain_info **_dom, struct sysdb_attrs **_member) { struct test_resolve_ext_state *state = tevent_req_data(req, struct test_resolve_ext_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_member_type != NULL) { *_member_type = state->member_type; } if (_dom) { *_dom = state->dom; } if (_member != NULL) { *_member = talloc_steal(mem_ctx, state->member); } return EOK; } static int nested_group_external_member_setup(void **state) { struct nested_groups_test_ctx *test_ctx; struct test_ext_pvt *ext_pvt; int ret; ret = nested_groups_test_setup((void **) &test_ctx); assert_int_equal(ret, 0); ext_pvt = talloc_zero(test_ctx->ext_ctx, struct test_ext_pvt); assert_non_null(ext_pvt); ext_pvt->dom_head = test_ctx->tctx->dom; test_ctx->ext_ctx->ext_member_resolve_send = test_resolve_ext_send; test_ctx->ext_ctx->ext_member_resolve_recv = test_resolve_ext_recv; test_ctx->ext_ctx->pvt = ext_pvt; *state = test_ctx; return 0; } static int nested_group_external_member_teardown(void **state) { struct nested_groups_test_ctx *test_ctx = talloc_get_type(*state, struct nested_groups_test_ctx); errno_t ret; int i; ret = sysdb_delete_group(test_ctx->tctx->dom, "rootgroup", 0); if (ret != EOK && ret != ENOENT) { return 1; } for (i = 0; test_ext_member_table[i].sid != NULL; i++) { switch (test_ext_member_table[i].member_type) { case SYSDB_MEMBER_USER: ret = sysdb_delete_user(test_ctx->tctx->dom, test_ext_member_table[i].name, 0); break; case SYSDB_MEMBER_GROUP: ret = sysdb_delete_group(test_ctx->tctx->dom, test_ext_member_table[i].name, 0); break; default: continue; } if (ret != EOK && ret != ENOENT) { return 1; } } talloc_free(test_ctx->ext_ctx); return nested_groups_test_setup(*state); } static void nested_external_done(struct tevent_req *req) { struct nested_groups_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct nested_groups_test_ctx); ctx->tctx->error = sdap_nested_group_lookup_external_recv(ctx, req); talloc_zfree(req); ctx->tctx->done = true; } static struct sysdb_attrs * mock_group_with_ext_members(struct nested_groups_test_ctx *test_ctx, const char *name, gid_t gid, const char *ext_members[]) { struct sysdb_attrs *ext_group = NULL; const struct sysdb_attrs **ext_group_reply; int i; errno_t ret; ext_group_reply = talloc_zero_array(test_ctx, const struct sysdb_attrs *, 2); if (ext_group_reply == NULL) { return NULL; } ext_group = mock_sysdb_object(ext_group_reply, GROUP_BASE_DN, name, SYSDB_GIDNUM, gid); if (ext_group == NULL) { talloc_free(ext_group_reply); return NULL; } for (i = 0; ext_members[i] != NULL; i++) { ret = sysdb_attrs_add_string( ext_group, test_ctx->sdap_opts->group_map[SDAP_AT_GROUP_EXT_MEMBER].sys_name, ext_members[i]); if (ret != EOK) { talloc_free(ext_group_reply); return NULL; } } ext_group_reply[0] = ext_group; will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, ext_group_reply); will_return(sdap_get_generic_recv, ERR_OK); return ext_group; } static errno_t nested_group_test_save_group(struct nested_groups_test_ctx *test_ctx, struct sysdb_attrs *ldap_attrs, struct group *gr) { errno_t ret; struct sysdb_attrs *sysdb_grattrs = NULL; const char *s; sysdb_grattrs = sysdb_new_attrs(test_ctx); if (sysdb_grattrs == NULL) { return ENOMEM; } ret = sysdb_attrs_get_string(ldap_attrs, SYSDB_ORIG_DN, &s); if (ret != EOK) { return ret; } ret = sysdb_attrs_add_string(sysdb_grattrs, SYSDB_ORIG_DN, s); if (ret != EOK) { return ret; } ret = sysdb_store_group(test_ctx->tctx->dom, gr->gr_name, gr->gr_gid, sysdb_grattrs, 0, time(NULL)); talloc_free(sysdb_grattrs); if (ret != EOK) { return ret; } return EOK; } static void nested_group_external_member_test(void **state) { struct nested_groups_test_ctx *test_ctx = talloc_get_type(*state, struct nested_groups_test_ctx); struct tevent_req *req; errno_t ret; struct sysdb_attrs *rootgroup_ldap_attrs = NULL; struct sysdb_attrs *nested_group_ldap_attrs = NULL; struct sysdb_attrs *ext_group_ldap_attrs = NULL; struct sysdb_attrs *ext_group_nested_ldap_attrs = NULL; struct ldb_result *res; struct group rootgroup; struct group nested_group; struct group ext_group; struct group ext_group_nested; const char *s; const char *rootgroup_members[] = { "cn=nested_group,"GROUP_BASE_DN, "cn=extgroup,"GROUP_BASE_DN, NULL }; const char *nestedgroup_members[] = { "cn=extgroup_nested,"GROUP_BASE_DN, NULL }; const char *extgroup_members[] = { "S-1-5-21-3623811015-3361044348-30300820-10001", NULL }; const char *extgroup_nested_members[] = { "S-1-5-21-3623811015-3361044348-30300820-10001", "S-1-5-21-3623811015-3361044348-30300820-20001", NULL }; const struct sysdb_attrs *nested_group_reply[2] = { NULL }; struct ldb_message *msg; struct ldb_message_element *member; const char *sysdb_gr_attrs[] = { SYSDB_MEMBEROF, NULL }; TALLOC_CTX *req_mem_ctx = NULL; /* LDAP provider doesn't support external groups by default */ test_ctx->sdap_opts->group_map[SDAP_AT_GROUP_MEMBER].name = \ discard_const(TEST_EXT_MEMBER); test_ctx->sdap_opts->ext_ctx = test_ctx->ext_ctx; rootgroup.gr_name = discard_const("rootgroup"); rootgroup.gr_gid = 1000; rootgroup_ldap_attrs = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, rootgroup.gr_gid, rootgroup.gr_name, rootgroup_members); assert_non_null(rootgroup_ldap_attrs); nested_group.gr_name = discard_const("nested_group"); nested_group.gr_gid = 1001; nested_group_ldap_attrs = mock_sysdb_group_rfc2307bis(test_ctx, GROUP_BASE_DN, nested_group.gr_gid, nested_group.gr_name, nestedgroup_members); assert_non_null(nested_group_ldap_attrs); nested_group_reply[0] = nested_group_ldap_attrs; will_return(sdap_get_generic_recv, 1); will_return(sdap_get_generic_recv, nested_group_reply); will_return(sdap_get_generic_recv, ERR_OK); ext_group.gr_name = discard_const("extgroup"); ext_group.gr_gid = 2001; ext_group_ldap_attrs = mock_group_with_ext_members(test_ctx, ext_group.gr_name, ext_group.gr_gid, extgroup_members); assert_non_null(ext_group_ldap_attrs); ext_group_nested.gr_name = discard_const("extgroup_nested"); ext_group_nested.gr_gid = 2002; ext_group_nested_ldap_attrs = mock_group_with_ext_members(test_ctx, ext_group_nested.gr_name, ext_group_nested.gr_gid, extgroup_nested_members); assert_non_null(ext_group_nested_ldap_attrs); /* run test, check for memory leaks */ req_mem_ctx = talloc_new(global_talloc_context); assert_non_null(req_mem_ctx); check_leaks_push(req_mem_ctx); sss_will_return_always(sdap_has_deref_support, false); req = sdap_nested_group_send(test_ctx, test_ctx->tctx->ev, test_ctx->sdap_domain, test_ctx->sdap_opts, test_ctx->sdap_handle, rootgroup_ldap_attrs); assert_non_null(req); tevent_req_set_callback(req, nested_groups_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_true(check_leaks_pop(req_mem_ctx) == true); talloc_zfree(req_mem_ctx); assert_int_equal(ret, ERR_OK); /* Save the groups to sysdb so that external membership code can link * external members against this group */ ret = nested_group_test_save_group(test_ctx, rootgroup_ldap_attrs, &rootgroup); assert_int_equal(ret, EOK); ret = nested_group_test_save_group(test_ctx, ext_group_ldap_attrs, &ext_group); assert_int_equal(ret, EOK); ret = nested_group_test_save_group(test_ctx, nested_group_ldap_attrs, &nested_group); assert_int_equal(ret, EOK); ret = nested_group_test_save_group(test_ctx, ext_group_nested_ldap_attrs, &ext_group_nested); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(test_ctx->tctx->dom, rootgroup.gr_name, ext_group.gr_name, SYSDB_MEMBER_GROUP, false); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(test_ctx->tctx->dom, rootgroup.gr_name, nested_group.gr_name, SYSDB_MEMBER_GROUP, false); assert_int_equal(ret, EOK); ret = sysdb_add_group_member(test_ctx->tctx->dom, nested_group.gr_name, ext_group_nested.gr_name, SYSDB_MEMBER_GROUP, false); assert_int_equal(ret, EOK); /* Resolve external members */ req_mem_ctx = talloc_new(global_talloc_context); assert_non_null(req_mem_ctx); check_leaks_push(req_mem_ctx); req = sdap_nested_group_lookup_external_send(test_ctx, test_ctx->tctx->ev, test_ctx->tctx->dom, test_ctx->ext_ctx, test_ctx->missing_external); assert_non_null(req); tevent_req_set_callback(req, nested_external_done, test_ctx); test_ctx->tctx->done = false; ret = test_ev_loop(test_ctx->tctx); assert_true(check_leaks_pop(req_mem_ctx) == true); talloc_zfree(req_mem_ctx); assert_int_equal(ret, ERR_OK); /* Make sure that extuser1001 is a member of rootgroup now */ ret = sysdb_initgroups(test_ctx, test_ctx->tctx->dom, "ext_user10001", &res); assert_int_equal(ret, EOK); s = ldb_msg_find_attr_as_string(res->msgs[1], SYSDB_NAME, NULL); assert_string_equal(s, rootgroup.gr_name); s = ldb_msg_find_attr_as_string(res->msgs[2], SYSDB_NAME, NULL); assert_string_equal(s, nested_group.gr_name); ret = sysdb_getgrnam(test_ctx, test_ctx->tctx->dom, "ext_group20001", &res); ret = sysdb_search_group_by_name(test_ctx, test_ctx->tctx->dom, "ext_group20001", sysdb_gr_attrs, &msg); assert_int_equal(ret, EOK); member = ldb_msg_find_element(msg, SYSDB_MEMBEROF); assert_int_equal(member->num_values, 2); s = sysdb_group_strdn(test_ctx, test_ctx->tctx->dom->name, rootgroup.gr_name); assert_non_null(s); assert_string_equal(member->values[0].data, s); s = sysdb_group_strdn(test_ctx, test_ctx->tctx->dom->name, nested_group.gr_name); assert_non_null(s); assert_string_equal(member->values[1].data, s); } int main(int argc, const char *argv[]) { int rv; int no_cleanup = 0; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { new_test(one_group_no_members), new_test(one_group_unique_members), new_test(one_group_dup_users), new_test(one_group_unique_group_members), new_test(one_group_dup_group_members), new_test(nested_chain), new_test(nested_chain_with_error), cmocka_unit_test_setup_teardown(nested_group_external_member_test, nested_group_external_member_setup, nested_group_external_member_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0 && !no_cleanup) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); } return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_string_utils.c0000644000000000000000000000007412703456111021444 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.055794988 sssd-1.13.4/src/tests/cmocka/test_string_utils.c0000644002412700241270000001560012703456111023115 0ustar00jhrozekjhrozek00000000000000/* Authors: Lukas Slebodnik Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "tests/cmocka/common_mock.h" void test_replace_whitespaces(void **state) { TALLOC_CTX *mem_ctx; const char *input_str = "Lorem ipsum dolor sit amet"; const char *res; size_t i; struct { const char *input; const char *output; const char replace_char; } data_set[] = { { "", "", '-' }, { " ", "-", '-' }, { "abcd", "abcd", '-' }, { "a b c d", "a-b-c-d", '-' }, { " a b c d ", "-a-b-c-d-", '-' }, { " ", "^", '^' }, { "abcd", "abcd", '^' }, { "a b c d", "a^b^c^d", '^' }, { " a b c d ", "^a^b^c^d^", '^' }, { " ", "^", '^' }, { " ", " ", ' ' }, { " ", " ", ' ' }, { "abcd", "abcd", ' ' }, { "a b c d", "a b c d", ' ' }, { "a b^c d", "a b^c d", '^' }, { NULL, NULL, '\0' }, }; mem_ctx = talloc_new(NULL); assert_non_null(mem_ctx); check_leaks_push(mem_ctx); res = sss_replace_space(mem_ctx, input_str, '\0'); assert_string_equal(res, input_str); talloc_zfree(res); res = sss_replace_space(mem_ctx, input_str, '\0'); assert_string_equal(res, input_str); talloc_zfree(res); for (i=0; data_set[i].input != NULL; ++i) { res = sss_replace_space(mem_ctx, data_set[i].input, data_set[i].replace_char); assert_non_null(res); assert_string_equal(res, data_set[i].output); talloc_zfree(res); } assert_true(check_leaks_pop(mem_ctx) == true); talloc_free(mem_ctx); } void test_reverse_replace_whitespaces(void **state) { TALLOC_CTX *mem_ctx; char *input_str = discard_const_p(char, "Lorem ipsum dolor sit amet"); char *res; size_t i; struct { const char *input; const char *output; const char replace_char; } data_set[] = { { "", "", '-' }, { "-", " ", '-' }, { "----", " ", '-' }, { "abcd", "abcd", '-' }, { "a-b-c-d", "a b c d", '-' }, { "-a-b-c-d-", " a b c d ", '-' }, { "a b c d", "a b c d", '-' }, { " a b c d ", " a b c d ", '-' }, { "^", " ", '^' }, { "^^^^", " ", '^' }, { "abcd", "abcd", '^' }, { "a^b^c^d", "a b c d", '^' }, { "^a^b^c^d^", " a b c d ", '^' }, { " ", " ", ' ' }, { " ", " ", ' ' }, { "abcd", "abcd", ' ' }, { "a b c d", "a b c d", ' ' }, { " a b c d ", " a b c d ", ' ' }, { "a b^c d", "a b^c d", '^' }, { NULL, NULL, '\0' }, }; mem_ctx = talloc_new(NULL); assert_non_null(mem_ctx); check_leaks_push(mem_ctx); res = sss_reverse_replace_space(mem_ctx, input_str, '\0'); assert_string_equal(res, input_str); talloc_free(res); res = sss_reverse_replace_space(mem_ctx, input_str, '\0'); assert_string_equal(res, input_str); talloc_free(res); for (i=0; data_set[i].input != NULL; ++i) { input_str = discard_const_p(char, data_set[i].input); res = sss_reverse_replace_space(mem_ctx, input_str, data_set[i].replace_char); assert_non_null(res); assert_string_equal(res, data_set[i].output); talloc_zfree(res); } assert_true(check_leaks_pop(mem_ctx) == true); talloc_free(mem_ctx); } void test_guid_blob_to_string_buf(void **state) { int ret; char str_buf[GUID_STR_BUF_SIZE]; size_t c; /* How to get test data: * The objectGUID attribute contains a 16byte long binary value * representing the GUID of the object. This data can be converted * manually to the string representation but it might be easier to use * LDAP_SERVER_EXTENDED_DN_OID as described in [MS-ADST] section * 3.1.1.3.4.1.5. This is an LDAP extended control which adds the GUID and * the SID to the DN of an object. This can be activate with the -E * ldapsearch option like: * * ldapsearch -E 1.2.840.113556.1.4.529=::MAMCAQE= .... * * where 'MAMCAQE=' is the base64 encoded BER sequence with the integer * value 1 (see [MS-ADTS] for details about possible values). * * Btw, if you want to use the string representation of a GUID to search * for an object in AD you have to use the GUID as the search base in the * following form: * * ldapsearch b '' ... * * (please note that the '<' and '>' are really needed). */ struct test_data { uint8_t blob[16]; const char *guid_str; } test_data[] = { {{0x8d, 0x0d, 0xa8, 0xfe, 0xd5, 0xdb, 0x84, 0x4f, 0x85, 0x74, 0x7d, 0xb0, 0x47, 0x7f, 0x96, 0x2e}, "fea80d8d-dbd5-4f84-8574-7db0477f962e"}, {{0x91, 0x7e, 0x2e, 0xf8, 0x4e, 0x44, 0xfa, 0x4e, 0xb1, 0x13, 0x08, 0x98, 0x63, 0x49, 0x6c, 0xc6}, "f82e7e91-444e-4efa-b113-089863496cc6"}, {{0}, NULL} }; ret = guid_blob_to_string_buf(NULL, str_buf, GUID_STR_BUF_SIZE); assert_int_equal(ret, EINVAL); ret = guid_blob_to_string_buf((const uint8_t *) "1234567812345678", NULL, GUID_STR_BUF_SIZE); assert_int_equal(ret, EINVAL); ret = guid_blob_to_string_buf((const uint8_t *) "1234567812345678", str_buf, 0); assert_int_equal(ret, EINVAL); for (c = 0; test_data[c].guid_str != NULL; c++) { ret = guid_blob_to_string_buf(test_data[c].blob, str_buf, sizeof(str_buf)); assert_int_equal(ret, EOK); assert_string_equal(test_data[c].guid_str, str_buf); } } void test_get_last_x_chars(void **state) { const char *s; s = get_last_x_chars(NULL, 0); assert_null(s); s = get_last_x_chars("abc", 0); assert_non_null(s); assert_string_equal(s, ""); s = get_last_x_chars("abc", 1); assert_non_null(s); assert_string_equal(s, "c"); s = get_last_x_chars("abc", 2); assert_non_null(s); assert_string_equal(s, "bc"); s = get_last_x_chars("abc", 3); assert_non_null(s); assert_string_equal(s, "abc"); s = get_last_x_chars("abc", 4); assert_non_null(s); assert_string_equal(s, "abc"); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/common_mock_resp.c0000644000000000000000000000007412703456111021211 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.923794541 sssd-1.13.4/src/tests/cmocka/common_mock_resp.c0000644002412700241270000000343012703456111022660 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat SSSD tests: Common utilities for tests that exercise domains This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "tests/cmocka/common_mock_resp.h" /* Mock a responder context */ struct resp_ctx * mock_rctx(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sss_domain_info *domains, void *pvt_ctx) { struct resp_ctx *rctx; errno_t ret; rctx = talloc_zero(mem_ctx, struct resp_ctx); if (!rctx) return NULL; ret = sss_hash_create(rctx, 30, &rctx->dp_request_table); if (ret != EOK) { talloc_free(rctx); return NULL; } rctx->ev = ev; rctx->domains = domains; rctx->pvt_ctx = pvt_ctx; return rctx; } /* Mock a client context */ struct cli_ctx * mock_cctx(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx) { struct cli_ctx *cctx; cctx = talloc_zero(mem_ctx, struct cli_ctx); if (!cctx) return NULL; cctx->creq = talloc_zero(cctx, struct cli_request); if (cctx->creq == NULL) { talloc_free(cctx); return NULL; } cctx->rctx = rctx; return cctx; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_child_common.c0000644000000000000000000000007312703456111021350 xustar0030 atime=1460561751.655715644 29 ctime=1460561775.03279491 sssd-1.13.4/src/tests/cmocka/test_child_common.c0000644002412700241270000004001412703456111023017 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat SSSD tests: Child handlers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/child_common.h" #include "tests/cmocka/common_mock.h" #define TEST_BIN "dummy-child" #define ECHO_STR "Hello child" static int destructor_called; struct child_test_ctx { int pipefd_to_child[2]; int pipefd_from_child[2]; struct sss_test_ctx *test_ctx; }; static int child_test_setup(void **state) { struct child_test_ctx *child_tctx; errno_t ret; assert_true(leak_check_setup()); check_leaks_push(global_talloc_context); child_tctx = talloc(global_talloc_context, struct child_test_ctx); assert_non_null(child_tctx); child_tctx->test_ctx = create_ev_test_ctx(child_tctx); assert_non_null(child_tctx->test_ctx); ret = pipe(child_tctx->pipefd_from_child); assert_int_not_equal(ret, -1); DEBUG(SSSDBG_TRACE_LIBS, "from_child: %d:%d\n", child_tctx->pipefd_from_child[0], child_tctx->pipefd_from_child[1]); ret = pipe(child_tctx->pipefd_to_child); assert_int_not_equal(ret, -1); DEBUG(SSSDBG_TRACE_LIBS, "to_child: %d:%d\n", child_tctx->pipefd_to_child[0], child_tctx->pipefd_to_child[1]); *state = child_tctx; return 0; } static int child_test_teardown(void **state) { struct child_test_ctx *child_tctx = talloc_get_type(*state, struct child_test_ctx); talloc_free(child_tctx); assert_true(check_leaks_pop(global_talloc_context)); assert_true(leak_check_teardown()); return 0; } /* Just make sure the exec works. The child does nothing but exits */ void test_exec_child(void **state) { errno_t ret; pid_t child_pid; int status; struct child_test_ctx *child_tctx = talloc_get_type(*state, struct child_test_ctx); child_pid = fork(); assert_int_not_equal(child_pid, -1); if (child_pid == 0) { ret = exec_child(child_tctx, child_tctx->pipefd_to_child, child_tctx->pipefd_from_child, CHILD_DIR"/"TEST_BIN, 2); assert_int_equal(ret, EOK); } else { do { errno = 0; ret = waitpid(child_pid, &status, 0); } while (ret == -1 && errno == EINTR); if (ret > 0) { ret = EIO; if (WIFEXITED(status)) { ret = WEXITSTATUS(status); assert_int_equal(ret, 0); } } else { DEBUG(SSSDBG_FUNC_DATA, "Failed to wait for children %d\n", child_pid); ret = EIO; } } } /* Make sure extra arguments are passed correctly */ void test_exec_child_extra_args(void **state) { errno_t ret; pid_t child_pid; int status; struct child_test_ctx *child_tctx = talloc_get_type(*state, struct child_test_ctx); const char *extra_args[] = { "--guitar=george", "--drums=ringo", NULL }; setenv("TEST_CHILD_ACTION", "check_extra_args", 1); child_pid = fork(); assert_int_not_equal(child_pid, -1); if (child_pid == 0) { ret = exec_child_ex(child_tctx, child_tctx->pipefd_to_child, child_tctx->pipefd_from_child, CHILD_DIR"/"TEST_BIN, 2, extra_args, false, STDIN_FILENO, STDOUT_FILENO); assert_int_equal(ret, EOK); } else { do { errno = 0; ret = waitpid(child_pid, &status, 0); } while (ret == -1 && errno == EINTR); if (ret > 0) { ret = EIO; if (WIFEXITED(status)) { ret = WEXITSTATUS(status); assert_int_equal(ret, 0); } } else { DEBUG(SSSDBG_FUNC_DATA, "Failed to wait for children %d\n", child_pid); ret = EIO; } } } struct tevent_req *echo_child_write_send(TALLOC_CTX *mem_ctx, struct child_test_ctx *child_tctx, struct child_io_fds *io_fds, const char *input); static void echo_child_write_done(struct tevent_req *subreq); static void echo_child_read_done(struct tevent_req *subreq); int __real_child_io_destructor(void *ptr); int __wrap_child_io_destructor(void *ptr) { destructor_called = 1; return __real_child_io_destructor(ptr); } /* Test that writing to the pipes works as expected */ void test_exec_child_io_destruct(void **state) { struct child_test_ctx *child_tctx = talloc_get_type(*state, struct child_test_ctx); struct child_io_fds *io_fds; io_fds = talloc(child_tctx, struct child_io_fds); io_fds->read_from_child_fd = -1; io_fds->write_to_child_fd = -1; assert_non_null(io_fds); talloc_set_destructor((void *) io_fds, child_io_destructor); io_fds->read_from_child_fd = child_tctx->pipefd_from_child[0]; io_fds->write_to_child_fd = child_tctx->pipefd_to_child[1]; destructor_called = 0; talloc_free(io_fds); assert_int_equal(destructor_called, 1); errno = 0; close(child_tctx->pipefd_from_child[0]); assert_int_equal(errno, EBADF); errno = 0; close(child_tctx->pipefd_from_child[1]); assert_int_equal(errno, 0); errno = 0; close(child_tctx->pipefd_to_child[0]); assert_int_equal(errno, 0); errno = 0; close(child_tctx->pipefd_to_child[1]); assert_int_equal(errno, EBADF); } void test_child_cb(int child_status, struct tevent_signal *sige, void *pvt); /* Test that writing to the pipes works as expected */ void test_exec_child_handler(void **state) { errno_t ret; pid_t child_pid; struct child_test_ctx *child_tctx = talloc_get_type(*state, struct child_test_ctx); struct sss_child_ctx_old *child_old_ctx; ret = unsetenv("TEST_CHILD_ACTION"); assert_int_equal(ret, 0); child_pid = fork(); assert_int_not_equal(child_pid, -1); if (child_pid == 0) { ret = exec_child(child_tctx, child_tctx->pipefd_to_child, child_tctx->pipefd_from_child, CHILD_DIR"/"TEST_BIN, 2); assert_int_equal(ret, EOK); } ret = child_handler_setup(child_tctx->test_ctx->ev, child_pid, test_child_cb, child_tctx, &child_old_ctx); assert_int_equal(ret, EOK); ret = test_ev_loop(child_tctx->test_ctx); assert_int_equal(ret, EOK); assert_int_equal(child_tctx->test_ctx->error, 0); } void test_child_cb(int child_status, struct tevent_signal *sige, void *pvt) { struct child_test_ctx *child_ctx = talloc_get_type(pvt, struct child_test_ctx); child_ctx->test_ctx->error = EIO; if (WIFEXITED(child_status) && WEXITSTATUS(child_status) == 0) { child_ctx->test_ctx->error = 0; } child_ctx->test_ctx->done = true; } /* Test that writing to the pipes works as expected */ void test_exec_child_echo(void **state) { errno_t ret; pid_t child_pid; struct child_test_ctx *child_tctx = talloc_get_type(*state, struct child_test_ctx); struct tevent_req *req; struct child_io_fds *io_fds; setenv("TEST_CHILD_ACTION", "echo", 1); io_fds = talloc(child_tctx, struct child_io_fds); assert_non_null(io_fds); io_fds->read_from_child_fd = -1; io_fds->write_to_child_fd = -1; talloc_set_destructor((void *) io_fds, child_io_destructor); child_pid = fork(); assert_int_not_equal(child_pid, -1); if (child_pid == 0) { ret = exec_child_ex(child_tctx, child_tctx->pipefd_to_child, child_tctx->pipefd_from_child, CHILD_DIR"/"TEST_BIN, 2, NULL, false, STDIN_FILENO, 3); assert_int_equal(ret, EOK); } DEBUG(SSSDBG_FUNC_DATA, "Forked into %d\n", child_pid); io_fds->read_from_child_fd = child_tctx->pipefd_from_child[0]; close(child_tctx->pipefd_from_child[1]); io_fds->write_to_child_fd = child_tctx->pipefd_to_child[1]; close(child_tctx->pipefd_to_child[0]); sss_fd_nonblocking(io_fds->write_to_child_fd); sss_fd_nonblocking(io_fds->read_from_child_fd); ret = child_handler_setup(child_tctx->test_ctx->ev, child_pid, NULL, NULL, NULL); assert_int_equal(ret, EOK); req = echo_child_write_send(child_tctx, child_tctx, io_fds, ECHO_STR); assert_non_null(req); ret = test_ev_loop(child_tctx->test_ctx); talloc_free(io_fds); assert_int_equal(ret, EOK); } struct test_exec_echo_state { struct child_io_fds *io_fds; struct io_buffer buf; struct child_test_ctx *child_test_ctx; }; struct tevent_req *echo_child_write_send(TALLOC_CTX *mem_ctx, struct child_test_ctx *child_tctx, struct child_io_fds *io_fds, const char *input) { struct tevent_req *req; struct tevent_req *subreq; struct test_exec_echo_state *echo_state; req = tevent_req_create(mem_ctx, &echo_state, struct test_exec_echo_state); assert_non_null(req); echo_state->child_test_ctx = child_tctx; echo_state->buf.data = (unsigned char *) talloc_strdup(echo_state, input); assert_non_null(echo_state->buf.data); echo_state->buf.size = strlen(input) + 1; echo_state->io_fds = io_fds; DEBUG(SSSDBG_TRACE_INTERNAL, "Writing..\n"); subreq = write_pipe_send(child_tctx, child_tctx->test_ctx->ev, echo_state->buf.data, echo_state->buf.size, echo_state->io_fds->write_to_child_fd); assert_non_null(subreq); tevent_req_set_callback(subreq, echo_child_write_done, req); return req; } static void echo_child_write_done(struct tevent_req *subreq) { struct tevent_req *req; struct test_exec_echo_state *echo_state; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); echo_state = tevent_req_data(req, struct test_exec_echo_state); ret = write_pipe_recv(subreq); DEBUG(SSSDBG_TRACE_INTERNAL, "Writing OK\n"); talloc_zfree(subreq); assert_int_equal(ret, EOK); close(echo_state->io_fds->write_to_child_fd); echo_state->io_fds->write_to_child_fd = -1; DEBUG(SSSDBG_TRACE_INTERNAL, "Reading..\n"); subreq = read_pipe_send(echo_state, echo_state->child_test_ctx->test_ctx->ev, echo_state->io_fds->read_from_child_fd); assert_non_null(subreq); tevent_req_set_callback(subreq, echo_child_read_done, req); } static void echo_child_read_done(struct tevent_req *subreq) { struct tevent_req *req; struct test_exec_echo_state *echo_state; errno_t ret; ssize_t len; uint8_t *buf; req = tevent_req_callback_data(subreq, struct tevent_req); echo_state = tevent_req_data(req, struct test_exec_echo_state); ret = read_pipe_recv(subreq, echo_state, &buf, &len); talloc_zfree(subreq); DEBUG(SSSDBG_TRACE_INTERNAL, "Reading OK\n"); assert_int_equal(ret, EOK); close(echo_state->io_fds->read_from_child_fd); echo_state->io_fds->read_from_child_fd = -1; assert_string_equal(buf, echo_state->buf.data); echo_state->child_test_ctx->test_ctx->done = true; } void sss_child_cb(int pid, int wait_status, void *pvt); /* Just make sure the exec works. The child does nothing but exits */ void test_sss_child(void **state) { errno_t ret; pid_t child_pid; struct child_test_ctx *child_tctx = talloc_get_type(*state, struct child_test_ctx); struct sss_sigchild_ctx *sc_ctx; struct sss_child_ctx *sss_child; ret = unsetenv("TEST_CHILD_ACTION"); assert_int_equal(ret, 0); ret = sss_sigchld_init(child_tctx, child_tctx->test_ctx->ev, &sc_ctx); assert_int_equal(ret, EOK); child_pid = fork(); assert_int_not_equal(child_pid, -1); if (child_pid == 0) { ret = exec_child(child_tctx, child_tctx->pipefd_to_child, child_tctx->pipefd_from_child, CHILD_DIR"/"TEST_BIN, 2); assert_int_equal(ret, EOK); } ret = sss_child_register(child_tctx, sc_ctx, child_pid, sss_child_cb, child_tctx, &sss_child); assert_int_equal(ret, EOK); ret = test_ev_loop(child_tctx->test_ctx); assert_int_equal(ret, EOK); assert_int_equal(child_tctx->test_ctx->error, 0); } void sss_child_cb(int pid, int wait_status, void *pvt) { struct child_test_ctx *child_ctx = talloc_get_type(pvt, struct child_test_ctx); child_ctx->test_ctx->error = EIO; if (WIFEXITED(wait_status) && WEXITSTATUS(wait_status) == 0) { child_ctx->test_ctx->error = 0; } child_ctx->test_ctx->done = true; } int main(int argc, const char *argv[]) { int rv; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_exec_child, child_test_setup, child_test_teardown), cmocka_unit_test_setup_teardown(test_exec_child_extra_args, child_test_setup, child_test_teardown), cmocka_unit_test_setup_teardown(test_exec_child_io_destruct, child_test_setup, child_test_teardown), cmocka_unit_test_setup_teardown(test_exec_child_handler, child_test_setup, child_test_teardown), cmocka_unit_test_setup_teardown(test_exec_child_echo, child_test_setup, child_test_teardown), cmocka_unit_test_setup_teardown(test_sss_child, child_test_setup, child_test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); rv = cmocka_run_group_tests(tests, NULL, NULL); return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_dp_opts.c0000644000000000000000000000007412703456111020366 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.915794514 sssd-1.13.4/src/tests/cmocka/test_dp_opts.c0000644002412700241270000003700012703456111022035 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat SSSD tests: Data Provider Option Tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "providers/data_provider.h" #include "tests/cmocka/common_mock.h" #define STRING_DEFAULT "stringval" #define BLOB_DEFAULT "blobval" #define INT_DEFAULT 123 #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_opt_conf.ldb" #define TEST_DOM_NAME "opt_test" #define TEST_ID_PROVIDER "ldap" enum test_opts { OPT_STRING_NODEFAULT, OPT_STRING_DEFAULT, OPT_BLOB_NODEFAULT, OPT_BLOB_DEFAULT, OPT_INT_NODEFAULT, OPT_INT_DEFAULT, OPT_BOOL_TRUE, OPT_BOOL_FALSE, OPT_NUM_OPTS }; struct dp_option test_def_opts[] = { { "string_nodefault", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "string_default", DP_OPT_STRING, { STRING_DEFAULT }, NULL_STRING}, { "blob_nodefault", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB }, { "blob_default", DP_OPT_BLOB, { .blob = { discard_const(BLOB_DEFAULT), sizeof(BLOB_DEFAULT) - 1 } }, NULL_BLOB }, { "int_nodefault", DP_OPT_NUMBER, NULL_NUMBER, NULL_NUMBER }, { "int_default", DP_OPT_NUMBER, { .number = INT_DEFAULT }, NULL_NUMBER }, { "bool_true", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, { "bool_false", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, DP_OPTION_TERMINATOR }; static void assert_defaults(struct dp_option *opts) { char *s; struct dp_opt_blob b; int i; bool bo; s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT); assert_null(s); s = dp_opt_get_string(opts, OPT_STRING_DEFAULT); assert_non_null(s); assert_string_equal(s, STRING_DEFAULT); b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT); assert_null(b.data); assert_int_equal(b.length, 0); b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT); assert_non_null(b.data); assert_int_equal(b.length, strlen(BLOB_DEFAULT)); assert_memory_equal(b.data, BLOB_DEFAULT, strlen(BLOB_DEFAULT)); i = dp_opt_get_int(opts, OPT_INT_NODEFAULT); assert_int_equal(i, 0); i = dp_opt_get_int(opts, OPT_INT_DEFAULT); assert_int_equal(i, INT_DEFAULT); bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE); assert_true(bo == true); bo = dp_opt_get_bool(opts, OPT_BOOL_FALSE); assert_true(bo == false); } void opt_test_copy_default(void **state) { int ret; TALLOC_CTX *mem_ctx; struct dp_option *opts; struct dp_opt_blob b; mem_ctx = talloc_new(global_talloc_context); assert_non_null(mem_ctx); ret = dp_copy_defaults(mem_ctx, test_def_opts, OPT_NUM_OPTS, &opts); assert_int_equal(ret, EOK); assert_defaults(opts); /* Test that copy_defaults would still copy defaults even if we * change the values */ ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1"); assert_int_equal(ret, EOK); ret = dp_opt_set_string(opts, OPT_STRING_DEFAULT, "str2"); assert_int_equal(ret, EOK); b.data = discard_const_p(uint8_t, "blob1"); b.length = strlen("blob1"); ret = dp_opt_set_blob(opts, OPT_BLOB_NODEFAULT, b); assert_int_equal(ret, EOK); ret = dp_opt_set_blob(opts, OPT_BLOB_DEFAULT, b); b.data = discard_const_p(uint8_t, "blob2"); b.length = strlen("blob2"); assert_int_equal(ret, EOK); ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456); assert_int_equal(ret, EOK); ret = dp_opt_set_int(opts, OPT_INT_DEFAULT, 789); assert_int_equal(ret, EOK); ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false); assert_int_equal(ret, EOK); ret = dp_opt_set_bool(opts, OPT_BOOL_FALSE, true); assert_int_equal(ret, EOK); talloc_free(opts); ret = dp_copy_defaults(mem_ctx, test_def_opts, OPT_NUM_OPTS, &opts); assert_int_equal(ret, EOK); assert_defaults(opts); } void opt_test_copy_options(void **state) { int ret; TALLOC_CTX *mem_ctx; struct dp_option *opts; char *s; struct dp_opt_blob b; int i; bool bo; mem_ctx = talloc_new(global_talloc_context); assert_non_null(mem_ctx); ret = dp_copy_options(mem_ctx, test_def_opts, OPT_NUM_OPTS, &opts); assert_int_equal(ret, EOK); assert_int_equal(ret, EOK); ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1"); assert_int_equal(ret, EOK); b.data = discard_const_p(uint8_t, "blob1"); b.length = strlen("blob1"); ret = dp_opt_set_blob(opts, OPT_BLOB_NODEFAULT, b); assert_int_equal(ret, EOK); ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456); assert_int_equal(ret, EOK); ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false); assert_int_equal(ret, EOK); /* Test that options set to an explicit value retain * the value and even options with default value * do not return the default unless explicitly set */ s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT); assert_string_equal(s, "str1"); s = dp_opt_get_string(opts, OPT_STRING_DEFAULT); assert_null(s); b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT); assert_non_null(b.data); assert_int_equal(b.length, strlen("blob1")); assert_memory_equal(b.data, "blob1", strlen("blob1")); b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT); assert_null(b.data); assert_int_equal(b.length, 0); i = dp_opt_get_int(opts, OPT_INT_NODEFAULT); assert_int_equal(i, 456); i = dp_opt_get_int(opts, OPT_INT_DEFAULT); assert_int_equal(i, 0); bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE); assert_false(bo == true); } void opt_test_get(void **state) { int ret; struct sss_test_ctx *tctx; struct dp_option *opts; struct sss_test_conf_param params[] = { { "string_nodefault", "stringval2" }, { "blob_nodefault", "blobval2" }, { "int_nodefault", "456" }, { "bool_true", "false" }, { NULL, NULL }, /* Sentinel */ }; char *s; struct dp_opt_blob b; int i; bool bo; tctx = create_dom_test_ctx(global_talloc_context, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, params); assert_non_null(tctx); ret = dp_get_options(global_talloc_context, tctx->confdb, tctx->conf_dom_path, test_def_opts, OPT_NUM_OPTS, &opts); assert_int_equal(ret, EOK); /* Options that were not specified explicitly should only have the default * value, those that have been specified explicitly should carry that * value */ s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT); assert_non_null(s); assert_string_equal(s, "stringval2"); s = dp_opt_get_string(opts, OPT_STRING_DEFAULT); assert_non_null(s); assert_string_equal(s, STRING_DEFAULT); b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT); assert_non_null(b.data); assert_int_equal(b.length, strlen("blobval2")); assert_memory_equal(b.data, "blobval2", strlen("blobval2")); b = dp_opt_get_blob(opts, OPT_BLOB_DEFAULT); assert_non_null(b.data); assert_int_equal(b.length, strlen(BLOB_DEFAULT)); assert_memory_equal(b.data, BLOB_DEFAULT, strlen(BLOB_DEFAULT)); i = dp_opt_get_int(opts, OPT_INT_NODEFAULT); assert_int_equal(i, 456); i = dp_opt_get_int(opts, OPT_INT_DEFAULT); assert_int_equal(i, INT_DEFAULT); bo = dp_opt_get_bool(opts, OPT_BOOL_TRUE); assert_true(bo == false); bo = dp_opt_get_bool(opts, OPT_BOOL_FALSE); assert_true(bo == false); } static int opt_test_getset_setup(void **state) { int ret; struct dp_option *opts; ret = dp_copy_defaults(global_talloc_context, test_def_opts, OPT_NUM_OPTS, &opts); assert_int_equal(ret, EOK); assert_defaults(opts); *state = opts; return 0; } static int opt_test_getset_teardown(void **state) { struct dp_option *opts = talloc_get_type(*state, struct dp_option); talloc_free(opts); return 0; } static void assert_nondefault_string_empty(struct dp_option *opts) { char *s; s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT); assert_null(s); } static void set_nondefault_string(struct dp_option *opts) { int ret; ret = dp_opt_set_string(opts, OPT_STRING_NODEFAULT, "str1"); assert_int_equal(ret, EOK); } static void check_nondefault_string(struct dp_option *opts) { char *s; s = dp_opt_get_string(opts, OPT_STRING_NODEFAULT); assert_non_null(s); assert_string_equal(s, "str1"); } void opt_test_getset_string(void **state) { struct dp_option *opts = talloc_get_type(*state, struct dp_option); assert_nondefault_string_empty(opts); set_nondefault_string(opts); check_nondefault_string(opts); } static void assert_nondefault_blob_empty(struct dp_option *opts) { struct dp_opt_blob b; b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT); assert_null(b.data); assert_int_equal(b.length, 0); } static void set_nondefault_blob(struct dp_option *opts) { struct dp_opt_blob b; int ret; b.data = discard_const_p(uint8_t, "blob2"); b.length = strlen("blob2"); ret = dp_opt_set_blob(opts, OPT_BLOB_NODEFAULT, b); assert_int_equal(ret, EOK); } static void check_nondefault_blob(struct dp_option *opts) { struct dp_opt_blob b; b = dp_opt_get_blob(opts, OPT_BLOB_NODEFAULT); assert_non_null(b.data); assert_int_equal(b.length, strlen("blob2")); assert_memory_equal(b.data, "blob2", strlen("blob2")); } void opt_test_getset_blob(void **state) { struct dp_option *opts = talloc_get_type(*state, struct dp_option); assert_nondefault_blob_empty(opts); set_nondefault_blob(opts); check_nondefault_blob(opts); } static void assert_nondefault_int_notset(struct dp_option *opts) { int i; i = dp_opt_get_int(opts, OPT_INT_NODEFAULT); assert_int_equal(i, 0); } static void set_nondefault_int(struct dp_option *opts) { int ret; ret = dp_opt_set_int(opts, OPT_INT_NODEFAULT, 456); assert_int_equal(ret, EOK); } static void assert_nondefault_int_set(struct dp_option *opts) { int i; i = dp_opt_get_int(opts, OPT_INT_NODEFAULT); assert_int_equal(i, 456); } void opt_test_getset_int(void **state) { struct dp_option *opts = talloc_get_type(*state, struct dp_option); assert_nondefault_int_notset(opts); set_nondefault_int(opts); assert_nondefault_int_set(opts); } void opt_test_getset_bool(void **state) { struct dp_option *opts = talloc_get_type(*state, struct dp_option); int ret; bool b; b = dp_opt_get_bool(opts, OPT_BOOL_TRUE); assert_true(b == true); ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false); assert_int_equal(ret, EOK); b = dp_opt_get_bool(opts, OPT_BOOL_TRUE); assert_false(b == true); } void opt_test_inherit(void **state) { struct dp_option *opts = talloc_get_type(*state, struct dp_option); int ret; struct dp_option *opts_copy; const char *s; const char *sd_inherit_match[] = { "string_nodefault", "blob_nodefault", "int_nodefault", "bool_true", NULL }; ret = dp_copy_defaults(opts, test_def_opts, OPT_NUM_OPTS, &opts_copy); assert_int_equal(ret, EOK); assert_defaults(opts); dp_option_inherit(NULL, OPT_STRING_NODEFAULT, opts, opts_copy); s = dp_opt_get_string(opts_copy, OPT_STRING_NODEFAULT); assert_null(s); /* string */ assert_nondefault_string_empty(opts_copy); set_nondefault_string(opts); dp_option_inherit(discard_const(sd_inherit_match), OPT_STRING_NODEFAULT, opts, opts_copy); check_nondefault_string(opts_copy); /* blob */ assert_nondefault_blob_empty(opts_copy); set_nondefault_blob(opts); dp_option_inherit(discard_const(sd_inherit_match), OPT_BLOB_NODEFAULT, opts, opts_copy); check_nondefault_blob(opts_copy); /* number */ assert_nondefault_int_notset(opts_copy); set_nondefault_int(opts); dp_option_inherit(discard_const(sd_inherit_match), OPT_INT_NODEFAULT, opts, opts_copy); assert_nondefault_int_set(opts_copy); /* bool */ assert_true(dp_opt_get_bool(opts_copy, OPT_BOOL_TRUE)); ret = dp_opt_set_bool(opts, OPT_BOOL_TRUE, false); assert_int_equal(ret, EOK); dp_option_inherit(discard_const(sd_inherit_match), OPT_BOOL_TRUE, opts, opts_copy); assert_false(dp_opt_get_bool(opts_copy, OPT_BOOL_TRUE)); } int main(int argc, const char *argv[]) { int no_cleanup = 0; poptContext pc; int opt; int ret; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(opt_test_getset_string, opt_test_getset_setup, opt_test_getset_teardown), cmocka_unit_test_setup_teardown(opt_test_getset_int, opt_test_getset_setup, opt_test_getset_teardown), cmocka_unit_test_setup_teardown(opt_test_getset_bool, opt_test_getset_setup, opt_test_getset_teardown), cmocka_unit_test_setup_teardown(opt_test_getset_blob, opt_test_getset_setup, opt_test_getset_teardown), cmocka_unit_test_setup_teardown(opt_test_inherit, opt_test_getset_setup, opt_test_getset_teardown), cmocka_unit_test(opt_test_copy_default), cmocka_unit_test(opt_test_copy_options), cmocka_unit_test(opt_test_get) }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); test_dom_suite_setup(TESTS_PATH); ret = cmocka_run_group_tests(tests, NULL, NULL); if (ret == 0 && !no_cleanup) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); } return ret; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_ifp.c0000644000000000000000000000007412703456111017474 xustar0030 atime=1460561751.656715648 30 ctime=1460561774.929794561 sssd-1.13.4/src/tests/cmocka/test_ifp.c0000644002412700241270000003265612703456111021157 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat SSSD tests: InfoPipe responder This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "db/sysdb.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #include "responder/ifp/ifp_private.h" #include "sbus/sssd_dbus_private.h" /* dbus library checks for valid object paths when unit testing, we don't * want that */ #undef DBUS_TYPE_OBJECT_PATH #define DBUS_TYPE_OBJECT_PATH ((int) 's') static struct ifp_ctx * mock_ifp_ctx(TALLOC_CTX *mem_ctx) { struct ifp_ctx *ifp_ctx; ifp_ctx = talloc_zero(mem_ctx, struct ifp_ctx); assert_non_null(ifp_ctx); ifp_ctx->rctx = mock_rctx(ifp_ctx, NULL, NULL, NULL); assert_non_null(ifp_ctx->rctx); ifp_ctx->rctx->allowed_uids = talloc_array(ifp_ctx->rctx, uint32_t, 1); assert_non_null(ifp_ctx->rctx->allowed_uids); ifp_ctx->rctx->allowed_uids[0] = geteuid(); ifp_ctx->rctx->allowed_uids_count = 1; ifp_ctx->sysbus = talloc_zero(ifp_ctx, struct sysbus_ctx); assert_non_null(ifp_ctx->sysbus); ifp_ctx->sysbus->conn = talloc_zero(ifp_ctx, struct sbus_connection); assert_non_null(ifp_ctx->sysbus->conn); return ifp_ctx; } static struct sbus_request * mock_sbus_request(TALLOC_CTX *mem_ctx, uid_t client) { struct sbus_request *sr; sr = talloc_zero(mem_ctx, struct sbus_request); assert_non_null(sr); sr->conn = talloc_zero(sr, struct sbus_connection); assert_non_null(sr->conn); sr->message = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL); assert_non_null(sr->message); dbus_message_set_serial(sr->message, 1); sr->client = client; return sr; } void ifp_test_req_create(void **state) { struct ifp_req *ireq; struct sbus_request *sr; struct ifp_ctx *ifp_ctx; errno_t ret; assert_true(leak_check_setup()); ifp_ctx = mock_ifp_ctx(global_talloc_context); assert_non_null(ifp_ctx); check_leaks_push(ifp_ctx); sr = mock_sbus_request(ifp_ctx, geteuid()); assert_non_null(sr); check_leaks_push(sr); ret = ifp_req_create(sr, ifp_ctx, &ireq); assert_int_equal(ret, EOK); talloc_free(ireq); assert_true(check_leaks_pop(sr) == true); talloc_free(sr); assert_true(check_leaks_pop(ifp_ctx) == true); talloc_free(ifp_ctx); assert_true(leak_check_teardown()); } void ifp_test_req_wrong_uid(void **state) { struct ifp_req *ireq; struct sbus_request *sr; struct ifp_ctx *ifp_ctx; errno_t ret; assert_true(leak_check_setup()); ifp_ctx = mock_ifp_ctx(global_talloc_context); assert_non_null(ifp_ctx); check_leaks_push(ifp_ctx); sr = mock_sbus_request(ifp_ctx, geteuid()+1); assert_non_null(sr); ret = ifp_req_create(sr, ifp_ctx, &ireq); assert_int_equal(ret, EACCES); talloc_free(sr); assert_true(check_leaks_pop(ifp_ctx) == true); talloc_free(ifp_ctx); assert_true(leak_check_teardown()); } void test_el_to_dict(void **state) { static struct sbus_request *sr; dbus_bool_t dbret; DBusMessageIter iter; DBusMessageIter iter_dict; struct ldb_message_element *el; errno_t ret; char *attr_name; char *attr_val; sr = mock_sbus_request(global_talloc_context, geteuid()); assert_non_null(sr); el = talloc(sr, struct ldb_message_element); assert_non_null(el); el->name = "numbers"; el->values = talloc_array(el, struct ldb_val, 2); assert_non_null(el->values); el->num_values = 2; el->values[0].data = (uint8_t *) discard_const("one"); el->values[0].length = strlen("one") + 1; el->values[1].data = (uint8_t *) discard_const("two"); el->values[1].length = strlen("two") + 1; dbus_message_iter_init_append(sr->message, &iter); dbret = dbus_message_iter_open_container( &iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &iter_dict); assert_true(dbret == TRUE); ret = ifp_add_ldb_el_to_dict(&iter_dict, el); assert_int_equal(ret, EOK); dbret = dbus_message_iter_close_container(&iter, &iter_dict); assert_true(dbret == TRUE); /* Test the reply contains what we expect */ dbus_message_iter_init(sr->message, &iter); assert_int_equal(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_ARRAY); dbus_message_iter_recurse(&iter, &iter); assert_int_equal(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_DICT_ENTRY); dbus_message_iter_recurse(&iter, &iter_dict); dbus_message_iter_get_basic(&iter_dict, &attr_name); assert_string_equal(attr_name, "numbers"); dbus_message_iter_next(&iter_dict); assert_int_equal(dbus_message_iter_get_arg_type(&iter_dict), DBUS_TYPE_VARIANT); dbus_message_iter_recurse(&iter_dict, &iter_dict); assert_int_equal(dbus_message_iter_get_arg_type(&iter_dict), DBUS_TYPE_ARRAY); dbus_message_iter_recurse(&iter_dict, &iter_dict); dbus_message_iter_get_basic(&iter_dict, &attr_val); assert_string_equal(attr_val, "one"); assert_true(dbus_message_iter_next(&iter_dict)); dbus_message_iter_get_basic(&iter_dict, &attr_val); assert_string_equal(attr_val, "two"); assert_false(dbus_message_iter_next(&iter_dict)); talloc_free(sr); } static void assert_string_list_equal(const char **s1, const char **s2) { int i; for (i=0; s1[i]; i++) { assert_non_null(s2[i]); assert_string_equal(s1[i], s2[i]); } assert_null(s2[i]); } static void attr_parse_test(const char *expected[], const char *input) { const char **res; TALLOC_CTX *test_ctx; test_ctx = talloc_new(NULL); assert_non_null(test_ctx); res = ifp_parse_user_attr_list(test_ctx, input); if (expected) { /* Positive test */ assert_non_null(res); assert_string_list_equal(res, expected); } else { /* Negative test */ assert_null(res); } talloc_free(test_ctx); } static void attr_parse_test_ex(const char *expected[], const char *input, const char **defaults) { const char **res; TALLOC_CTX *test_ctx; test_ctx = talloc_new(NULL); assert_non_null(test_ctx); res = parse_attr_list_ex(test_ctx, input, defaults); if (expected) { /* Positive test */ assert_non_null(res); assert_string_list_equal(res, expected); } else { /* Negative test */ assert_null(res); } talloc_free(test_ctx); } void test_attr_acl(void **state) { /* Test defaults */ const char *exp_defaults[] = { SYSDB_NAME, SYSDB_UIDNUM, SYSDB_GIDNUM, SYSDB_GECOS, SYSDB_HOMEDIR, SYSDB_SHELL, "groups", NULL }; attr_parse_test(exp_defaults, NULL); /* Test adding some attributes to the defaults */ const char *exp_add[] = { "telephoneNumber", "streetAddress", SYSDB_NAME, SYSDB_UIDNUM, SYSDB_GIDNUM, SYSDB_GECOS, SYSDB_HOMEDIR, SYSDB_SHELL, "groups", NULL }; attr_parse_test(exp_add, "+telephoneNumber, +streetAddress"); /* Test removing some attributes to the defaults */ const char *exp_rm[] = { SYSDB_NAME, SYSDB_GIDNUM, SYSDB_GECOS, SYSDB_HOMEDIR, "groups", NULL }; attr_parse_test(exp_rm, "-"SYSDB_SHELL ",-"SYSDB_UIDNUM); /* Test both add and remove */ const char *exp_add_rm[] = { "telephoneNumber", SYSDB_NAME, SYSDB_UIDNUM, SYSDB_GIDNUM, SYSDB_GECOS, SYSDB_HOMEDIR, "groups", NULL }; attr_parse_test(exp_add_rm, "+telephoneNumber, -"SYSDB_SHELL); /* Test rm trumps add */ const char *exp_add_rm_override[] = { SYSDB_NAME, SYSDB_UIDNUM, SYSDB_GIDNUM, SYSDB_GECOS, SYSDB_HOMEDIR, SYSDB_SHELL, "groups", NULL }; attr_parse_test(exp_add_rm_override, "+telephoneNumber, -telephoneNumber, +telephoneNumber"); /* Remove all */ const char *rm_all[] = { NULL }; attr_parse_test(rm_all, "-"SYSDB_NAME ", -"SYSDB_UIDNUM ", -"SYSDB_GIDNUM ", -"SYSDB_GECOS ", -"SYSDB_HOMEDIR ", -"SYSDB_SHELL", -groups"); /* Malformed list */ attr_parse_test(NULL, "missing_plus_or_minus"); } void test_attr_acl_ex(void **state) { /* Test defaults */ const char *exp_defaults[] = { "abc", "123", "xyz", NULL }; attr_parse_test_ex(exp_defaults, NULL, exp_defaults); /* Test adding some attributes to the defaults */ const char *exp_add[] = { "telephoneNumber", "streetAddress", "abc", "123", "xyz", NULL }; attr_parse_test_ex(exp_add, "+telephoneNumber, +streetAddress", exp_defaults); /* Test removing some attributes to the defaults */ const char *exp_rm[] = { "123", NULL }; attr_parse_test_ex(exp_rm, "-abc, -xyz", exp_defaults); /* Test adding with empty defaults */ const char *exp_add_empty[] = { "telephoneNumber", "streetAddress", NULL }; attr_parse_test_ex(exp_add_empty, "+telephoneNumber, +streetAddress", NULL); /* Test removing with empty defaults */ const char *rm_all[] = { NULL }; attr_parse_test_ex(rm_all, "-telephoneNumber, -streetAddress", NULL); } void test_attr_allowed(void **state) { const char *whitelist[] = { "name", "gecos", NULL }; const char *emptylist[] = { NULL }; assert_true(ifp_attr_allowed(whitelist, "name")); assert_true(ifp_attr_allowed(whitelist, "gecos")); assert_false(ifp_attr_allowed(whitelist, "password")); assert_false(ifp_attr_allowed(emptylist, "name")); assert_false(ifp_attr_allowed(NULL, "name")); } struct ifp_test_req_ctx { struct ifp_req *ireq; struct sbus_request *sr; struct ifp_ctx *ifp_ctx; }; static int ifp_test_req_setup(void **state) { struct ifp_test_req_ctx *test_ctx; errno_t ret; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct ifp_test_req_ctx); assert_non_null(test_ctx); test_ctx->ifp_ctx = mock_ifp_ctx(test_ctx); assert_non_null(test_ctx->ifp_ctx); test_ctx->sr = mock_sbus_request(test_ctx, geteuid()); assert_non_null(test_ctx->sr); ret = ifp_req_create(test_ctx->sr, test_ctx->ifp_ctx, &test_ctx->ireq); assert_int_equal(ret, EOK); assert_non_null(test_ctx->ireq); check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int ifp_test_req_teardown(void **state) { struct ifp_test_req_ctx *test_ctx = talloc_get_type_abort(*state, struct ifp_test_req_ctx); assert_true(check_leaks_pop(test_ctx) == true); dbus_message_unref(test_ctx->sr->message); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test(ifp_test_req_create), cmocka_unit_test(ifp_test_req_wrong_uid), cmocka_unit_test_setup_teardown(test_el_to_dict, ifp_test_req_setup, ifp_test_req_teardown), cmocka_unit_test(test_attr_acl), cmocka_unit_test(test_attr_acl_ex), cmocka_unit_test(test_attr_allowed), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_ipa_idmap.c0000644000000000000000000000007412703456111020641 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.038794931 sssd-1.13.4/src/tests/cmocka/test_ipa_idmap.c0000644002412700241270000002117512703456111022316 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2014 Red Hat SSSD tests: Unit tests for id-mapping in the IPA provider This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "tests/cmocka/common_mock.h" #include "lib/idmap/sss_idmap.h" #include "providers/ipa/ipa_common.h" #include "providers/ldap/sdap_idmap.h" #define RANGE_NAME discard_const("range1") #define DOMAIN_SID discard_const("S-1-5-21-2-3-4") #define DOMAIN_NAME discard_const("dom.test") #define BASE_RID 111 #define SECONDARY_BASE_RID 11223344 #define BASE_ID 123456 #define RANGE_SIZE 222222 #define RANGE_MAX (BASE_ID + RANGE_SIZE - 1) void test_get_idmap_data_from_range(void **state) { char *dom_name; char *sid; uint32_t rid; struct sss_idmap_range range; bool external_mapping; size_t c; errno_t ret; struct test_data { struct range_info r; errno_t exp_ret; char *exp_dom_name; char *exp_sid; uint32_t exp_rid; struct sss_idmap_range exp_range; bool exp_external_mapping; } d[] = { /* working IPA_RANGE_LOCAL range */ {{RANGE_NAME, BASE_ID, RANGE_SIZE, BASE_RID, SECONDARY_BASE_RID, NULL, discard_const(IPA_RANGE_LOCAL)}, EOK, DOMAIN_NAME, NULL, 0, {BASE_ID, RANGE_MAX}, true}, /* working old-style IPA_RANGE_LOCAL range without range type */ {{RANGE_NAME, BASE_ID, RANGE_SIZE, BASE_RID, SECONDARY_BASE_RID, NULL, NULL}, EOK, DOMAIN_NAME, NULL, 0, {BASE_ID, RANGE_MAX}, true}, /* old-style IPA_RANGE_LOCAL without SID and secondary base rid */ {{RANGE_NAME, BASE_ID, RANGE_SIZE, BASE_RID, 0, NULL, NULL}, EINVAL, NULL, NULL, 0, {0, 0}, false}, /* old-style range with SID and secondary base rid */ {{RANGE_NAME, BASE_ID, RANGE_SIZE, BASE_RID, SECONDARY_BASE_RID, DOMAIN_SID, NULL}, EINVAL, NULL, NULL, 0, {0, 0}, false}, /* working IPA_RANGE_AD_TRUST range */ {{RANGE_NAME, BASE_ID, RANGE_SIZE, BASE_RID, 0, DOMAIN_SID, discard_const(IPA_RANGE_AD_TRUST)}, EOK, DOMAIN_SID, DOMAIN_SID, BASE_RID, {BASE_ID, RANGE_MAX}, false}, /* working old-style IPA_RANGE_AD_TRUST range without range type */ {{RANGE_NAME, BASE_ID, RANGE_SIZE, BASE_RID, 0, DOMAIN_SID, NULL}, EOK, DOMAIN_SID, DOMAIN_SID, BASE_RID, {BASE_ID, RANGE_MAX}, false}, /* working IPA_RANGE_AD_TRUST_POSIX range */ {{RANGE_NAME, BASE_ID, RANGE_SIZE, BASE_RID, 0, DOMAIN_SID, discard_const(IPA_RANGE_AD_TRUST_POSIX)}, EOK, DOMAIN_SID, DOMAIN_SID, 0, {BASE_ID, RANGE_MAX}, true}, {{0}, 0, NULL, NULL, 0, {0, 0}, false} }; for (c = 0; d[c].exp_dom_name != NULL; c++) { ret = get_idmap_data_from_range(&d[c].r, DOMAIN_NAME, &dom_name, &sid, &rid, &range, &external_mapping); assert_int_equal(ret, d[c].exp_ret); assert_string_equal(dom_name, d[c].exp_dom_name); if (d[c].exp_sid == NULL) { assert_null(sid); } else { assert_string_equal(sid, d[c].exp_sid); } assert_int_equal(rid, d[c].exp_rid); assert_int_equal(range.min, d[c].exp_range.min); assert_int_equal(range.max, d[c].exp_range.max); assert_true(external_mapping == d[c].exp_external_mapping); } } errno_t __wrap_sysdb_get_ranges(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, size_t *range_count, struct range_info ***range_list) { *range_count = sss_mock_type(size_t); *range_list = talloc_steal(mem_ctx, sss_mock_ptr_type(struct range_info **)); return EOK; } struct test_ctx { struct sdap_idmap_ctx *idmap_ctx; struct sdap_id_ctx *sdap_id_ctx; }; static struct range_info **get_range_list(TALLOC_CTX *mem_ctx) { struct range_info **range_list; range_list = talloc_array(mem_ctx, struct range_info *, 2); assert_non_null(range_list); range_list[0] = talloc_zero(range_list, struct range_info); assert_non_null(range_list[0]); range_list[0]->name = talloc_strdup(range_list[0], RANGE_NAME); assert_non_null( range_list[0]->name); range_list[0]->base_id = BASE_ID; range_list[0]->id_range_size = RANGE_SIZE; range_list[0]->base_rid = BASE_RID; range_list[0]->secondary_base_rid = 0; range_list[0]->trusted_dom_sid = talloc_strdup(range_list[0], DOMAIN_SID); assert_non_null(range_list[0]->trusted_dom_sid); range_list[0]->range_type = talloc_strdup(range_list[0], IPA_RANGE_AD_TRUST); assert_non_null(range_list[0]->range_type); return range_list; } static int setup_idmap_ctx(void **state) { int ret; struct test_ctx *test_ctx; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct test_ctx); assert_non_null(test_ctx); test_ctx->sdap_id_ctx = talloc_zero(test_ctx, struct sdap_id_ctx); assert_non_null(test_ctx->sdap_id_ctx); test_ctx->sdap_id_ctx->be = talloc_zero(test_ctx->sdap_id_ctx, struct be_ctx); assert_non_null(test_ctx->sdap_id_ctx->be); test_ctx->sdap_id_ctx->be->domain = talloc_zero(test_ctx->sdap_id_ctx->be, struct sss_domain_info); assert_non_null(test_ctx->sdap_id_ctx->be->domain); test_ctx->sdap_id_ctx->be->domain->name = talloc_strdup(test_ctx->sdap_id_ctx->be->domain, DOMAIN_NAME); assert_non_null(test_ctx->sdap_id_ctx->be->domain->name); will_return(__wrap_sysdb_get_ranges, 1); will_return(__wrap_sysdb_get_ranges, get_range_list(global_talloc_context)); ret = ipa_idmap_init(test_ctx, test_ctx->sdap_id_ctx, &test_ctx->idmap_ctx); assert_int_equal(ret, EOK); check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int teardown_idmap_ctx(void **state) { struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } void test_ipa_idmap_get_ranges_from_sysdb(void **state) { int ret; struct test_ctx *test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); will_return(__wrap_sysdb_get_ranges, 1); will_return(__wrap_sysdb_get_ranges, get_range_list(test_ctx->idmap_ctx)); ret = ipa_idmap_get_ranges_from_sysdb(test_ctx->idmap_ctx, DOMAIN_NAME, DOMAIN_SID, true); assert_int_equal(ret, EOK); will_return(__wrap_sysdb_get_ranges, 1); will_return(__wrap_sysdb_get_ranges, get_range_list(global_talloc_context)); ret = ipa_idmap_get_ranges_from_sysdb(test_ctx->idmap_ctx, DOMAIN_NAME, DOMAIN_SID, false); assert_int_equal(ret, EIO); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test(test_get_idmap_data_from_range), cmocka_unit_test_setup_teardown(test_ipa_idmap_get_ranges_from_sysdb, setup_idmap_ctx, teardown_idmap_ctx), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_pam_srv.c0000644000000000000000000000007412703456111020365 xustar0030 atime=1460561751.656715648 30 ctime=1460561774.949794629 sssd-1.13.4/src/tests/cmocka/test_pam_srv.c0000644002412700241270000015644112703456111022047 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2015 Red Hat SSSD tests: PAM responder tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #include "responder/common/responder_packet.h" #include "responder/common/negcache.h" #include "responder/pam/pamsrv.h" #include "responder/pam/pam_helpers.h" #include "sss_client/pam_message.h" #include "sss_client/sss_cli.h" #include "util/crypto/sss_crypto.h" #ifdef HAVE_NSS #include "util/crypto/nss/nss_util.h" #endif #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_pam_conf.ldb" #define TEST_DOM_NAME "pam_test" #define TEST_SUBDOM_NAME "test.subdomain" #define TEST_ID_PROVIDER "ldap" #define NSS_DB_PATH "./sssd_test_nssdb" #define NSS_DB "sql:"NSS_DB_PATH #define TEST_TOKEN_NAME "SSSD Test Token" #define TEST_TOKEN_CERT \ "MIIECTCCAvGgAwIBAgIBCDANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \ "REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA2MjMx" \ "NjMyMDdaFw0xNzA2MjMxNjMyMDdaMDIxEjAQBgNVBAoMCUlQQS5ERVZFTDEcMBoG" \ "A1UEAwwTaXBhLWRldmVsLmlwYS5kZXZlbDCCASIwDQYJKoZIhvcNAQEBBQADggEP" \ "ADCCAQoCggEBALXUq56VlY+Z0aWLLpFAjFfbElPBXGQsbZb85J3cGyPjaMHC9wS+" \ "wjB6Ve4HmQyPLx8hbINdDmbawMHYQvTScLYfsqLtj0Lqw20sUUmedk+Es5Oh9VHo" \ "nd8MavYx25Du2u+T0iSgNIDikXguiwCmtAj8VC49ebbgITcjJGzMmiiuJkV3o93Y" \ "vvYF0VjLGDQbQWOy7IxzYJeNVJnZWKo67CHdok6qOrm9rxQt81rzwV/mGLbCMUbr" \ "+N4M8URtd7EmzaYZQmNm//s2owFrCYMxpLiURPj+URZVuB72504/Ix7X0HCbA/AV" \ "26J27fPY5nc8DMwfhUDCbTqPH/JEjd3mvY8CAwEAAaOCASYwggEiMB8GA1UdIwQY" \ "MBaAFJOq+KAQmPEnNp8Wok23eGTdE7aDMDsGCCsGAQUFBwEBBC8wLTArBggrBgEF" \ "BQcwAYYfaHR0cDovL2lwYS1jYS5pcGEuZGV2ZWwvY2Evb2NzcDAOBgNVHQ8BAf8E" \ "BAMCBPAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHQGA1UdHwRtMGsw" \ "aaAxoC+GLWh0dHA6Ly9pcGEtY2EuaXBhLmRldmVsL2lwYS9jcmwvTWFzdGVyQ1JM" \ "LmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRpZmljYXRl" \ "IEF1dGhvcml0eTAdBgNVHQ4EFgQUFaDNd5a53QGpaw5m63hnwXicMQ8wDQYJKoZI" \ "hvcNAQELBQADggEBADH7Nj00qqGhGJeXJQAsepqSskz/wooqXh8vgVyb8SS4N0/c" \ "0aQtVmY81xamlXE12ZFpwDX43d+EufBkwCUKFX/+8JFDd2doAyeJxv1xM22kKRpc" \ "AqITPgMsa9ToGMWxjbVpc/X/5YfZixWPF0/eZUTotBj9oaR039UrhGfyN7OguF/G" \ "rzmxtB5y4ZrMpcD/Oe90mkd9HY7sA/fB8OWOUgeRfQoh97HNS0UiDWsPtfxmjQG5" \ "zotpoBIZmdH+ipYsu58HohHVlM9Wi5H4QmiiXl+Soldkq7eXYlafcmT7wv8+cKwz" \ "Nz0Tm3+eYpFqRo3skr6QzXi525Jkg3r6r+kkhxU=" \ static char CACHED_AUTH_TIMEOUT_STR[] = "2"; static const int CACHED_AUTH_TIMEOUT = 2; struct pam_test_ctx { struct sss_test_ctx *tctx; struct sss_domain_info *subdom; struct resp_ctx *rctx; struct cli_ctx *cctx; struct sss_cmd_table *pam_cmds; struct pam_ctx *pctx; int ncache_hits; int exp_pam_status; bool provider_contacted; }; /* Must be global because it is needed in some wrappers */ struct pam_test_ctx *pam_test_ctx; static errno_t setup_nss_db(void) { int ret; FILE *fp; int status; pid_t child_pid; ret = mkdir(NSS_DB_PATH, 0775); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to create " NSS_DB_PATH ".\n"); return ret; } child_pid = fork(); if (child_pid == 0) { /* child */ ret = execlp("certutil", "certutil", "-N", "--empty-password", "-d", NSS_DB, NULL); if (ret == -1) { DEBUG(SSSDBG_FATAL_FAILURE, "execl() failed.\n"); exit(-1); } } else if (child_pid > 0) { wait(&status); } else { ret = errno; DEBUG(SSSDBG_FATAL_FAILURE, "fork() failed\n"); return ret; } fp = fopen(NSS_DB_PATH"/pkcs11.txt", "w"); if (fp == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "fopen() failed.\n"); return ret; } ret = fprintf(fp, "library=libsoftokn3.so\nname=soft\n"); if (ret < 0) { DEBUG(SSSDBG_FATAL_FAILURE, "fprintf() failed.\n"); return ret; } ret = fprintf(fp, "parameters=configdir='sql:%s/src/tests/cmocka/p11_nssdb' dbSlotDescription='SSSD Test Slot' dbTokenDescription='SSSD Test Token' secmod='secmod.db' flags=readOnly \n\n", ABS_SRC_DIR); if (ret < 0) { DEBUG(SSSDBG_FATAL_FAILURE, "fprintf() failed.\n"); return ret; } ret = fclose(fp); if (ret != 0) { DEBUG(SSSDBG_FATAL_FAILURE, "fclose() failed.\n"); return ret; } return EOK; } static void cleanup_nss_db(void) { int ret; ret = unlink(NSS_DB_PATH"/cert9.db"); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to remove cert9.db.\n"); } ret = unlink(NSS_DB_PATH"/key4.db"); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to remove key4.db.\n"); } ret = unlink(NSS_DB_PATH"/pkcs11.txt"); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to remove pkcs11.db.\n"); } ret = rmdir(NSS_DB_PATH); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to remove " NSS_DB_PATH "\n"); } } struct pam_ctx *mock_pctx(TALLOC_CTX *mem_ctx) { struct pam_ctx *pctx; errno_t ret; pctx = talloc_zero(mem_ctx, struct pam_ctx); assert_non_null(pctx); ret = sss_ncache_init(pctx, &pctx->ncache); assert_int_equal(ret, EOK); pctx->neg_timeout = 10; ret = sss_hash_create(pctx, 10, &pctx->id_table); assert_int_equal(ret, EOK); return pctx; } static int add_confdb_params(struct sss_test_conf_param params[], struct confdb_ctx *cdb, const char *section) { const char *val[2]; int ret; val[1] = NULL; for (int i = 0; params[i].key; i++) { val[0] = params[i].value; ret = confdb_add_param(cdb, true, section, params[i].key, val); assert_int_equal(ret, EOK); } return EOK; } static int add_pam_params(struct sss_test_conf_param pam_params[], struct confdb_ctx *cdb) { return add_confdb_params(pam_params, cdb, CONFDB_PAM_CONF_ENTRY); } static int add_monitor_params(struct sss_test_conf_param monitor_params[], struct confdb_ctx *cdb) { return add_confdb_params(monitor_params, cdb, CONFDB_MONITOR_CONF_ENTRY); } void test_pam_setup(struct sss_test_conf_param dom_params[], struct sss_test_conf_param pam_params[], struct sss_test_conf_param monitor_params[], void **state) { errno_t ret; pam_test_ctx = talloc_zero(NULL, struct pam_test_ctx); assert_non_null(pam_test_ctx); pam_test_ctx->tctx = create_dom_test_ctx(pam_test_ctx, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, dom_params); assert_non_null(pam_test_ctx->tctx); pam_test_ctx->pam_cmds = get_pam_cmds(); assert_non_null(pam_test_ctx->pam_cmds); /* FIXME - perhaps this should be folded into sssd_domain_init or stricty * used together */ ret = sss_names_init(pam_test_ctx, pam_test_ctx->tctx->confdb, TEST_DOM_NAME, &pam_test_ctx->tctx->dom->names); assert_int_equal(ret, EOK); /* Initialize the PAM responder */ pam_test_ctx->pctx = mock_pctx(pam_test_ctx); assert_non_null(pam_test_ctx->pctx); pam_test_ctx->rctx = mock_rctx(pam_test_ctx, pam_test_ctx->tctx->ev, pam_test_ctx->tctx->dom, pam_test_ctx->pctx); assert_non_null(pam_test_ctx->rctx); pam_test_ctx->rctx->cdb = pam_test_ctx->tctx->confdb; pam_test_ctx->pctx->rctx = pam_test_ctx->rctx; ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); assert_int_equal(ret, EOK); ret = add_monitor_params(monitor_params, pam_test_ctx->rctx->cdb); assert_int_equal(ret, EOK); /* Create client context */ pam_test_ctx->cctx = mock_cctx(pam_test_ctx, pam_test_ctx->rctx); assert_non_null(pam_test_ctx->cctx); pam_test_ctx->cctx->cli_protocol_version = register_cli_protocol_version(); pam_test_ctx->cctx->ev = pam_test_ctx->tctx->ev; } static void pam_test_setup_common(void) { errno_t ret; /* Prime the cache with a valid user */ ret = sysdb_add_user(pam_test_ctx->tctx->dom, "pamuser", 123, 456, "pam user", "/home/pamuser", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); /* Add entry to the initgr cache to make sure no initgr request is sent to * the backend */ ret = pam_initgr_cache_set(pam_test_ctx->pctx->rctx->ev, pam_test_ctx->pctx->id_table, discard_const("pamuser"), pam_test_ctx->pctx->id_timeout); assert_int_equal(ret, EOK); /* Prime the cache with a user for wrong matches */ ret = sysdb_add_user(pam_test_ctx->tctx->dom, "wronguser", 321, 654, "wrong user", "/home/wringuser", "/bin/sh", NULL, NULL, 300, 0); assert_int_equal(ret, EOK); /* Add entry to the initgr cache to make sure no initgr request is sent to * the backend */ ret = pam_initgr_cache_set(pam_test_ctx->pctx->rctx->ev, pam_test_ctx->pctx->id_table, discard_const("wronguser"), pam_test_ctx->pctx->id_timeout); assert_int_equal(ret, EOK); } static int pam_test_setup(void **state) { struct sss_test_conf_param dom_params[] = { { "enumerate", "false" }, { "cache_credentials", "true" }, { NULL, NULL }, /* Sentinel */ }; struct sss_test_conf_param pam_params[] = { { "p11_child_timeout", "30" }, { NULL, NULL }, /* Sentinel */ }; struct sss_test_conf_param monitor_params[] = { { "certificate_verification", "no_ocsp"}, { NULL, NULL }, /* Sentinel */ }; test_pam_setup(dom_params, pam_params, monitor_params, state); pam_test_setup_common(); return 0; } static int pam_cached_test_setup(void **state) { struct sss_test_conf_param dom_params[] = { { "enumerate", "false" }, { "cache_credentials", "true" }, { "cached_auth_timeout", CACHED_AUTH_TIMEOUT_STR }, { NULL, NULL }, /* Sentinel */ }; struct sss_test_conf_param pam_params[] = { { "p11_child_timeout", "30" }, { NULL, NULL }, /* Sentinel */ }; struct sss_test_conf_param monitor_params[] = { { "certificate_verification", "no_ocsp"}, { NULL, NULL }, /* Sentinel */ }; test_pam_setup(dom_params, pam_params, monitor_params, state); pam_test_setup_common(); return 0; } static int pam_test_teardown(void **state) { int ret; ret = sysdb_delete_user(pam_test_ctx->tctx->dom, "pamuser", 0); assert_int_equal(ret, EOK); ret = sysdb_delete_user(pam_test_ctx->tctx->dom, "wronguser", 0); assert_int_equal(ret, EOK); talloc_free(pam_test_ctx); return 0; } typedef int (*cmd_cb_fn_t)(uint32_t, uint8_t *, size_t); int __real_read_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **buf, ssize_t *len); void __real_sss_packet_get_body(struct sss_packet *packet, uint8_t **body, size_t *blen); void __wrap_sss_packet_get_body(struct sss_packet *packet, uint8_t **body, size_t *blen) { enum sss_test_wrapper_call wtype = sss_mock_type(enum sss_test_wrapper_call); size_t len; if (wtype == WRAP_CALL_REAL) { return __real_sss_packet_get_body(packet, body, blen); } *body = sss_mock_ptr_type(uint8_t *); len = sss_mock_type(size_t); if (len == 0) { len = strlen((const char *) *body) + 1; } *blen = len; return; } void __real_sss_packet_get_body(struct sss_packet *packet, uint8_t **body, size_t *blen); void __wrap_sss_cmd_done(struct cli_ctx *cctx, void *freectx) { struct sss_packet *packet = cctx->creq->out; uint8_t *body; size_t blen; cmd_cb_fn_t check_cb; assert_non_null(packet); check_cb = sss_mock_ptr_type(cmd_cb_fn_t); __real_sss_packet_get_body(packet, &body, &blen); pam_test_ctx->tctx->error = check_cb(sss_packet_get_status(packet), body, blen); pam_test_ctx->tctx->done = true; } enum sss_cli_command __wrap_sss_packet_get_cmd(struct sss_packet *packet) { return sss_mock_type(enum sss_cli_command); } int __wrap_sss_cmd_send_empty(struct cli_ctx *cctx, TALLOC_CTX *freectx) { pam_test_ctx->tctx->done = true; pam_test_ctx->tctx->error = ENOENT; return EOK; } static void set_cmd_cb(cmd_cb_fn_t fn) { will_return(__wrap_sss_cmd_done, fn); } int __wrap_pam_dp_send_req(struct pam_auth_req *preq, int timeout) { pam_test_ctx->provider_contacted = true; /* Set expected status */ preq->pd->pam_status = pam_test_ctx->exp_pam_status; preq->callback(preq); return EOK; } static void mock_input_pam(TALLOC_CTX *mem_ctx, const char *name, const char *pwd, const char *fa2) { size_t buf_size; uint8_t *m_buf; uint8_t *buf; struct pam_items pi = { 0 }; int ret; size_t needed_size; uint8_t *authtok; if (name != NULL) { pi.pam_user = name; pi.pam_user_size = strlen(pi.pam_user) + 1; } else { pi.pam_user = ""; pi.pam_user_size = 0; } if (pwd != NULL) { if (fa2 != NULL) { ret = sss_auth_pack_2fa_blob(pwd, 0, fa2, 0, NULL, 0, &needed_size); assert_int_equal(ret, EAGAIN); authtok = talloc_size(mem_ctx, needed_size); assert_non_null(authtok); ret = sss_auth_pack_2fa_blob(pwd, 0, fa2, 0, authtok, needed_size, &needed_size); assert_int_equal(ret, EOK); pi.pam_authtok = (char *) authtok; pi.pam_authtok_size = needed_size; pi.pam_authtok_type = SSS_AUTHTOK_TYPE_2FA; } else { pi.pam_authtok = discard_const(pwd); pi.pam_authtok_size = strlen(pi.pam_authtok) + 1; pi.pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD; } } pi.pam_service = "ssh"; pi.pam_service_size = strlen(pi.pam_service) + 1; pi.pam_tty = "/dev/tty"; pi.pam_tty_size = strlen(pi.pam_tty) + 1; pi.pam_ruser = "remuser"; pi.pam_ruser_size = strlen(pi.pam_ruser) + 1; pi.pam_rhost = "remhost"; pi.pam_rhost_size = strlen(pi.pam_rhost) + 1; pi.requested_domains = ""; pi.cli_pid = 12345; ret = pack_message_v3(&pi, &buf_size, &m_buf); assert_int_equal(ret, 0); buf = talloc_memdup(mem_ctx, m_buf, buf_size); free(m_buf); assert_non_null(buf); will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, buf); will_return(__wrap_sss_packet_get_body, buf_size); } static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name, const char *pin) { size_t buf_size; uint8_t *m_buf; uint8_t *buf; struct pam_items pi = { 0 }; int ret; if (name != NULL) { pi.pam_user = name; pi.pam_user_size = strlen(pi.pam_user) + 1; } else { pi.pam_user = ""; pi.pam_user_size = 0; } if (pin != NULL) { pi.pam_authtok = discard_const(pin); pi.pam_authtok_size = strlen(pi.pam_authtok) + 1; pi.pam_authtok_type = SSS_AUTHTOK_TYPE_SC_PIN; } pi.pam_service = "login"; pi.pam_service_size = strlen(pi.pam_service) + 1; pi.pam_tty = "/dev/tty"; pi.pam_tty_size = strlen(pi.pam_tty) + 1; pi.pam_ruser = "remuser"; pi.pam_ruser_size = strlen(pi.pam_ruser) + 1; pi.pam_rhost = "remhost"; pi.pam_rhost_size = strlen(pi.pam_rhost) + 1; pi.requested_domains = ""; pi.cli_pid = 12345; ret = pack_message_v3(&pi, &buf_size, &m_buf); assert_int_equal(ret, 0); buf = talloc_memdup(mem_ctx, m_buf, buf_size); free(m_buf); assert_non_null(buf); will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); will_return(__wrap_sss_packet_get_body, buf); will_return(__wrap_sss_packet_get_body, buf_size); } static int test_pam_simple_check(uint32_t status, uint8_t *body, size_t blen) { size_t rp = 0; uint32_t val; assert_int_equal(status, 0); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, pam_test_ctx->exp_pam_status); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, 1); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, SSS_PAM_DOMAIN_NAME); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, 9); assert_int_equal(*(body + rp + val - 1), 0); assert_string_equal(body + rp, TEST_DOM_NAME); return EOK; } static int test_pam_cert_check(uint32_t status, uint8_t *body, size_t blen) { size_t rp = 0; uint32_t val; assert_int_equal(status, 0); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, pam_test_ctx->exp_pam_status); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, 2); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, SSS_PAM_DOMAIN_NAME); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, 9); assert_int_equal(*(body + rp + val - 1), 0); assert_string_equal(body + rp, TEST_DOM_NAME); rp += val; SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, SSS_PAM_CERT_INFO); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, (sizeof("pamuser") + sizeof(TEST_TOKEN_NAME))); assert_int_equal(*(body + rp + sizeof("pamuser") - 1), 0); assert_string_equal(body + rp, "pamuser"); rp += sizeof("pamuser"); assert_int_equal(*(body + rp + sizeof(TEST_TOKEN_NAME) - 1), 0); assert_string_equal(body + rp, TEST_TOKEN_NAME); return EOK; } static int test_pam_offline_chauthtok_check(uint32_t status, uint8_t *body, size_t blen) { size_t rp = 0; uint32_t val; pam_test_ctx->exp_pam_status = PAM_AUTHTOK_ERR; assert_int_equal(status, 0); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, pam_test_ctx->exp_pam_status); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, 2); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, SSS_PAM_DOMAIN_NAME); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, 9); assert_int_equal(*(body + rp + val - 1), 0); assert_string_equal(body + rp, TEST_DOM_NAME); rp += val; SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, SSS_PAM_USER_INFO); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, 4); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, SSS_PAM_USER_INFO_OFFLINE_CHPASS); return EOK; } static int test_pam_failed_offline_auth_check(uint32_t status, uint8_t *body, size_t blen) { pam_test_ctx->exp_pam_status = PAM_PERM_DENIED; return test_pam_simple_check(status, body, blen); } static int test_pam_successful_offline_auth_check(uint32_t status, uint8_t *body, size_t blen) { pam_test_ctx->exp_pam_status = PAM_SUCCESS; return test_pam_simple_check(status, body, blen); } static int test_pam_successful_cached_auth_check(uint32_t status, uint8_t *body, size_t blen) { pam_test_ctx->exp_pam_status = PAM_SUCCESS; return test_pam_simple_check(status, body, blen); } static int test_pam_wrong_pw_offline_auth_check(uint32_t status, uint8_t *body, size_t blen) { pam_test_ctx->exp_pam_status = PAM_AUTH_ERR; return test_pam_simple_check(status, body, blen); } static int test_pam_creds_insufficient_check(uint32_t status, uint8_t *body, size_t blen) { size_t rp = 0; uint32_t val; assert_int_equal(status, 0); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, PAM_CRED_INSUFFICIENT); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, 0); return EOK; } static int test_pam_user_unknown_check(uint32_t status, uint8_t *body, size_t blen) { size_t rp = 0; uint32_t val; assert_int_equal(status, 0); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, PAM_USER_UNKNOWN); SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); assert_int_equal(val, 0); return EOK; } void test_pam_authenticate(void **state) { int ret; mock_input_pam(pam_test_ctx, "pamuser", NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_setcreds(void **state) { int ret; mock_input_pam(pam_test_ctx, "pamuser", NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_SETCRED); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_SETCRED, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_acct_mgmt(void **state) { int ret; mock_input_pam(pam_test_ctx, "pamuser", NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_ACCT_MGMT); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_ACCT_MGMT, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_open_session(void **state) { int ret; mock_input_pam(pam_test_ctx, "pamuser", NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_OPEN_SESSION); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_NO_MODULE_DATA; set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_OPEN_SESSION, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_close_session(void **state) { int ret; mock_input_pam(pam_test_ctx, "pamuser", NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_CLOSE_SESSION); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_CLOSE_SESSION, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_chauthtok(void **state) { int ret; mock_input_pam(pam_test_ctx, "pamuser", NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_CHAUTHTOK); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_CHAUTHTOK, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_chauthtok_prelim(void **state) { int ret; mock_input_pam(pam_test_ctx, "pamuser", NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_CHAUTHTOK_PRELIM); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_CHAUTHTOK_PRELIM, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_preauth(void **state) { int ret; mock_input_pam(pam_test_ctx, "pamuser", NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } /* Cached on-line authentication */ static void common_test_pam_cached_auth(const char *pwd) { int ret; mock_input_pam(pam_test_ctx, "pamuser", pwd, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_SUCCESS; set_cmd_cb(test_pam_successful_cached_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_cached_auth_success(void **state) { int ret; common_test_pam_cached_auth("12345"); /* Back end should be contacted */ assert_true(pam_test_ctx->provider_contacted); ret = sysdb_cache_password(pam_test_ctx->tctx->dom, "pamuser", "12345"); assert_int_equal(ret, EOK); /* Reset before next call */ pam_test_ctx->provider_contacted = false; common_test_pam_cached_auth("12345"); /* Back end should not be contacted */ assert_false(pam_test_ctx->provider_contacted); } void test_pam_cached_auth_wrong_pw(void **state) { int ret; ret = sysdb_cache_password(pam_test_ctx->tctx->dom, "pamuser", "12345"); assert_int_equal(ret, EOK); ret = pam_set_last_online_auth_with_curr_token(pam_test_ctx->tctx->dom, "pamuser", time(NULL)); assert_int_equal(ret, EOK); common_test_pam_cached_auth("11111"); /* Back end should be contacted */ assert_true(pam_test_ctx->provider_contacted); } /* test cached_auth_timeout option */ void test_pam_cached_auth_opt_timeout(void **state) { int ret; uint64_t last_online; ret = sysdb_cache_password(pam_test_ctx->tctx->dom, "pamuser", "12345"); assert_int_equal(ret, EOK); last_online = time(NULL) - CACHED_AUTH_TIMEOUT - 1; ret = pam_set_last_online_auth_with_curr_token(pam_test_ctx->tctx->dom, "pamuser", last_online); assert_int_equal(ret, EOK); common_test_pam_cached_auth("12345"); /* Back end should be contacted */ assert_true(pam_test_ctx->provider_contacted); } /* too long since last on-line authentication */ void test_pam_cached_auth_timeout(void **state) { int ret; ret = sysdb_cache_password(pam_test_ctx->tctx->dom, "pamuser", "12345"); assert_int_equal(ret, EOK); ret = pam_set_last_online_auth_with_curr_token(pam_test_ctx->tctx->dom, "pamuser", 0); assert_int_equal(ret, EOK); common_test_pam_cached_auth("12345"); /* Back end should be contacted */ assert_true(pam_test_ctx->provider_contacted); } void test_pam_cached_auth_success_combined_pw_with_cached_2fa(void **state) { int ret; common_test_pam_cached_auth("12345678"); assert_true(pam_test_ctx->provider_contacted); ret = sysdb_cache_password_ex(pam_test_ctx->tctx->dom, "pamuser", "12345678", SSS_AUTHTOK_TYPE_2FA, 5); assert_int_equal(ret, EOK); /* Reset before next call */ pam_test_ctx->provider_contacted = false; common_test_pam_cached_auth("12345678"); assert_false(pam_test_ctx->provider_contacted); } void test_pam_cached_auth_failed_combined_pw_with_cached_2fa(void **state) { int ret; ret = sysdb_cache_password_ex(pam_test_ctx->tctx->dom, "pamuser", "12345678", SSS_AUTHTOK_TYPE_2FA, 5); assert_int_equal(ret, EOK); ret = pam_set_last_online_auth_with_curr_token(pam_test_ctx->tctx->dom, "pamuser", time(NULL)); assert_int_equal(ret, EOK); common_test_pam_cached_auth("1111abcde"); assert_true(pam_test_ctx->provider_contacted); } /* Off-line authentication */ void test_pam_offline_auth_no_hash(void **state) { int ret; mock_input_pam(pam_test_ctx, "pamuser", "12345", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_failed_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_auth_success(void **state) { int ret; ret = sysdb_cache_password(pam_test_ctx->tctx->dom, "pamuser", "12345"); assert_int_equal(ret, EOK); mock_input_pam(pam_test_ctx, "pamuser", "12345", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_successful_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_auth_wrong_pw(void **state) { int ret; ret = sysdb_cache_password(pam_test_ctx->tctx->dom, "pamuser", "12345"); assert_int_equal(ret, EOK); mock_input_pam(pam_test_ctx, "pamuser", "11111", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_wrong_pw_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_auth_success_2fa(void **state) { int ret; ret = sysdb_cache_password(pam_test_ctx->tctx->dom, "pamuser", "12345"); assert_int_equal(ret, EOK); mock_input_pam(pam_test_ctx, "pamuser", "12345", "abcde"); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_successful_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_auth_failed_2fa(void **state) { int ret; ret = sysdb_cache_password(pam_test_ctx->tctx->dom, "pamuser", "12345"); assert_int_equal(ret, EOK); mock_input_pam(pam_test_ctx, "pamuser", "11111", "abcde"); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_wrong_pw_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_auth_success_2fa_with_cached_2fa(void **state) { int ret; ret = sysdb_cache_password_ex(pam_test_ctx->tctx->dom, "pamuser", "12345", SSS_AUTHTOK_TYPE_2FA, 5); assert_int_equal(ret, EOK); mock_input_pam(pam_test_ctx, "pamuser", "12345", "abcde"); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_successful_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_auth_failed_2fa_with_cached_2fa(void **state) { int ret; ret = sysdb_cache_password_ex(pam_test_ctx->tctx->dom, "pamuser", "12345", SSS_AUTHTOK_TYPE_2FA, 5); assert_int_equal(ret, EOK); mock_input_pam(pam_test_ctx, "pamuser", "11111", "abcde"); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_wrong_pw_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_auth_success_pw_with_cached_2fa(void **state) { int ret; ret = sysdb_cache_password_ex(pam_test_ctx->tctx->dom, "pamuser", "12345", SSS_AUTHTOK_TYPE_2FA, 5); assert_int_equal(ret, EOK); mock_input_pam(pam_test_ctx, "pamuser", "12345", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_successful_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_auth_failed_pw_with_cached_2fa(void **state) { int ret; ret = sysdb_cache_password_ex(pam_test_ctx->tctx->dom, "pamuser", "12345", SSS_AUTHTOK_TYPE_2FA, 5); assert_int_equal(ret, EOK); mock_input_pam(pam_test_ctx, "pamuser", "11111", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_wrong_pw_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_auth_success_combined_pw_with_cached_2fa(void **state) { int ret; ret = sysdb_cache_password_ex(pam_test_ctx->tctx->dom, "pamuser", "12345678", SSS_AUTHTOK_TYPE_2FA, 5); assert_int_equal(ret, EOK); mock_input_pam(pam_test_ctx, "pamuser", "12345678abcde", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_successful_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_auth_failed_combined_pw_with_cached_2fa(void **state) { int ret; ret = sysdb_cache_password_ex(pam_test_ctx->tctx->dom, "pamuser", "12345678", SSS_AUTHTOK_TYPE_2FA, 5); assert_int_equal(ret, EOK); mock_input_pam(pam_test_ctx, "pamuser", "11111111abcde", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_wrong_pw_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_auth_failed_wrong_2fa_size_with_cached_2fa(void **state) { int ret; ret = sysdb_cache_password_ex(pam_test_ctx->tctx->dom, "pamuser", "12345678", SSS_AUTHTOK_TYPE_2FA, 5); assert_int_equal(ret, EOK); mock_input_pam(pam_test_ctx, "pamuser", "12345678abcd", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_wrong_pw_offline_auth_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_chauthtok_prelim(void **state) { int ret; mock_input_pam(pam_test_ctx, "pamuser", NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_CHAUTHTOK_PRELIM); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_offline_chauthtok_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_CHAUTHTOK_PRELIM, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_offline_chauthtok(void **state) { int ret; mock_input_pam(pam_test_ctx, "pamuser", NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_CHAUTHTOK); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); pam_test_ctx->exp_pam_status = PAM_AUTHINFO_UNAVAIL; set_cmd_cb(test_pam_offline_chauthtok_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_CHAUTHTOK, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_preauth_no_logon_name(void **state) { int ret; mock_input_pam_cert(pam_test_ctx, NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_pam_creds_insufficient_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } static void set_cert_auth_param(struct pam_ctx *pctx, const char *dbpath) { pam_test_ctx->pctx->cert_auth = true; pam_test_ctx->pctx->nss_db = discard_const(dbpath); } void test_pam_preauth_cert_nocert(void **state) { int ret; set_cert_auth_param(pam_test_ctx->pctx, "/no/path"); mock_input_pam_cert(pam_test_ctx, "pamuser", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } static int test_lookup_by_cert_cb(void *pvt) { int ret; struct sysdb_attrs *attrs; unsigned char *der = NULL; size_t der_size; if (pvt != NULL) { attrs = sysdb_new_attrs(pam_test_ctx); assert_non_null(attrs); der = sss_base64_decode(pam_test_ctx, pvt, &der_size); assert_non_null(der); ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_CERT, der, der_size); talloc_free(der); assert_int_equal(ret, EOK); ret = sysdb_set_user_attr(pam_test_ctx->tctx->dom, "pamuser", attrs, LDB_FLAG_MOD_ADD); assert_int_equal(ret, EOK); } return EOK; } static int test_lookup_by_cert_wrong_user_cb(void *pvt) { int ret; struct sysdb_attrs *attrs; unsigned char *der = NULL; size_t der_size; if (pvt != NULL) { attrs = sysdb_new_attrs(pam_test_ctx); assert_non_null(attrs); der = sss_base64_decode(pam_test_ctx, pvt, &der_size); assert_non_null(der); ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_CERT, der, der_size); talloc_free(der); assert_int_equal(ret, EOK); ret = sysdb_set_user_attr(pam_test_ctx->tctx->dom, "wronguser", attrs, LDB_FLAG_MOD_ADD); assert_int_equal(ret, EOK); } return EOK; } void test_pam_preauth_cert_nomatch(void **state) { int ret; set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); mock_input_pam_cert(pam_test_ctx, "pamuser", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); mock_account_recv(0, 0, NULL, test_lookup_by_cert_cb, NULL); set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_preauth_cert_match(void **state) { int ret; set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); mock_input_pam_cert(pam_test_ctx, "pamuser", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); mock_account_recv(0, 0, NULL, test_lookup_by_cert_cb, discard_const(TEST_TOKEN_CERT)); set_cmd_cb(test_pam_cert_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_preauth_cert_match_wrong_user(void **state) { int ret; set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); mock_input_pam_cert(pam_test_ctx, "pamuser", NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); mock_account_recv(0, 0, NULL, test_lookup_by_cert_wrong_user_cb, discard_const(TEST_TOKEN_CERT)); set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_preauth_cert_no_logon_name(void **state) { int ret; set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); mock_input_pam_cert(pam_test_ctx, NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); mock_account_recv(0, 0, NULL, test_lookup_by_cert_cb, discard_const(TEST_TOKEN_CERT)); set_cmd_cb(test_pam_cert_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_preauth_no_cert_no_logon_name(void **state) { int ret; set_cert_auth_param(pam_test_ctx->pctx, "/no/path"); mock_input_pam_cert(pam_test_ctx, NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); set_cmd_cb(test_pam_user_unknown_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_preauth_cert_no_logon_name_no_match(void **state) { int ret; set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); mock_input_pam_cert(pam_test_ctx, NULL, NULL); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); mock_account_recv(0, 0, NULL, test_lookup_by_cert_cb, NULL); set_cmd_cb(test_pam_user_unknown_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } void test_pam_cert_auth(void **state) { int ret; set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); mock_input_pam_cert(pam_test_ctx, "pamuser", "123456"); will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); mock_account_recv(0, 0, NULL, test_lookup_by_cert_cb, discard_const(TEST_TOKEN_CERT)); set_cmd_cb(test_pam_simple_check); ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, pam_test_ctx->pam_cmds); assert_int_equal(ret, EOK); /* Wait until the test finishes with EOK */ ret = test_ev_loop(pam_test_ctx->tctx); assert_int_equal(ret, EOK); } int main(int argc, const char *argv[]) { int rv; int no_cleanup = 0; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS { "no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_pam_authenticate, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_setcreds, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_acct_mgmt, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_open_session, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_close_session, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_chauthtok, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_chauthtok_prelim, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_preauth, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_offline_auth_no_hash, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_offline_auth_success, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_offline_auth_wrong_pw, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_offline_auth_success_2fa, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_offline_auth_failed_2fa, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown( test_pam_offline_auth_success_2fa_with_cached_2fa, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown( test_pam_offline_auth_failed_2fa_with_cached_2fa, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown( test_pam_offline_auth_success_pw_with_cached_2fa, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown( test_pam_offline_auth_failed_pw_with_cached_2fa, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown( test_pam_offline_auth_success_combined_pw_with_cached_2fa, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown( test_pam_offline_auth_failed_combined_pw_with_cached_2fa, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown( test_pam_offline_auth_failed_wrong_2fa_size_with_cached_2fa, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_offline_chauthtok_prelim, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_offline_chauthtok, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_preauth_no_logon_name, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_cached_auth_success, pam_cached_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_cached_auth_wrong_pw, pam_cached_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_cached_auth_opt_timeout, pam_cached_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_cached_auth_timeout, pam_cached_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_cached_auth_success_combined_pw_with_cached_2fa, pam_cached_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_cached_auth_failed_combined_pw_with_cached_2fa, pam_cached_test_setup, pam_test_teardown), /* p11_child is not built without NSS */ #ifdef HAVE_NSS cmocka_unit_test_setup_teardown(test_pam_preauth_cert_nocert, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_preauth_cert_nomatch, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_preauth_cert_match, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_preauth_cert_match_wrong_user, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_preauth_cert_no_logon_name, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_preauth_no_cert_no_logon_name, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown( test_pam_preauth_cert_no_logon_name_no_match, pam_test_setup, pam_test_teardown), cmocka_unit_test_setup_teardown(test_pam_cert_auth, pam_test_setup, pam_test_teardown), #endif /* HAVE_NSS */ }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); test_dom_suite_setup(TESTS_PATH); cleanup_nss_db(); rv = setup_nss_db(); if (rv != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "setup_nss_db failed.\n"); exit(-1); } rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0 && !no_cleanup) { cleanup_nss_db(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); } #ifdef HAVE_NSS /* Cleanup NSS and NSPR to make valgrund happy. */ nspr_nss_cleanup(); #endif return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_ipa_subdomains_server.c0000644000000000000000000000007412703456111023301 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.040794938 sssd-1.13.4/src/tests/cmocka/test_ipa_subdomains_server.c0000644002412700241270000007523412703456111024763 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2015 Red Hat SSSD tests: IPA subdomain server utils tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #define TESTS_PATH "tp_" BASE_FILE_STEM #include "providers/ipa/ipa_subdomains.h" #include "providers/ipa/ipa_opts.h" #include "providers/data_provider.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #include "tests/cmocka/common_mock_krb5.h" #include "tests/cmocka/common_mock_sdap.h" #include "tests/cmocka/common_mock_be.h" #define DOM_REALM "DOM.MAIN" #define HOSTNAME "ipaserver.dom.main" #define DOM_FLAT "DOM" #define TEST_AUTHID "host/"HOSTNAME #define KEYTAB_TEST_PRINC TEST_AUTHID"@"DOM_REALM #define KEYTAB_PATH TEST_DIR"/"TESTS_PATH"/keytab_test.keytab" #define SUBDOM_NAME "twoway.subdom.test" #define SUBDOM_REALM "TWOWAY.SUBDOM.TEST" #define SUBDOM_FLAT "TWOWAY" #define SUBDOM_SID "S-1-2-3" #define CHILD_NAME "child."SUBDOM_NAME #define CHILD_REALM "CHILD."SUBDOM_REALM #define CHILD_FLAT "CHILD" #define CHILD_SID "S-1-2-3-4" #define TEST_CONF_DB "test_ipa_subdom_server.ldb" #define TEST_DOM_NAME "ipa_subdom_server_test" #define TEST_ID_PROVIDER "ipa" #define ONEWAY_KEYTAB TEST_DIR"/"TESTS_PATH"/"SUBDOM_REALM".keytab" #define ONEWAY_PRINC DOM_FLAT"$" #define ONEWAY_AUTHID ONEWAY_PRINC"@"SUBDOM_REALM static bool global_rename_called; #ifdef HAVE_SELINUX /* Provide faster implementation of kerberos function * krb5int_labeled_[f]?open. Real functions take care also * about SELinux context which is very expensive operation * and cause failures due to timeout when executing with valgrind. * It's approximately 40 times slower with real function */ FILE * krb5int_labeled_fopen(const char *path, const char *mode) { return fopen(path, mode); } int krb5int_labeled_open(const char *path, int flags, mode_t mode) { return open(path, flags, mode); } #endif /* HAVE_SELINUX */ krb5_error_code __wrap_krb5_kt_default(krb5_context context, krb5_keytab *id) { return krb5_kt_resolve(context, KEYTAB_PATH, id); } static void create_dummy_keytab(const char *dummy_kt) { errno_t ret; assert_non_null(dummy_kt); mock_keytab_with_contents(global_talloc_context, dummy_kt, ONEWAY_AUTHID); ret = access(dummy_kt, R_OK); assert_int_equal(ret, 0); } static int wrap_exec(void) { const char *test_kt; const char *fail_creating_kt; test_kt = getenv("TEST_KT_ENV"); if (test_kt == NULL) { _exit(1); } unsetenv("TEST_KT_ENV"); fail_creating_kt = getenv("KT_CREATE_FAIL"); if (fail_creating_kt != NULL) { _exit(1); } create_dummy_keytab(test_kt); _exit(0); return 1; /* Should not happen */ } int __wrap_execle(const char *path, const char *arg, ...) { return wrap_exec(); } int __wrap_execve(const char *path, const char *arg, ...) { return wrap_exec(); } errno_t __real_sss_unique_filename(TALLOC_CTX *owner, char *path_tmpl); errno_t __wrap_sss_unique_filename(TALLOC_CTX *owner, char *path_tmpl) { int ret; int sret; ret = __real_sss_unique_filename(owner, path_tmpl); if (ret == EOK) { sret = setenv("TEST_KT_ENV", path_tmpl, 1); assert_int_equal(sret, 0); } return ret; } int __real_rename(const char *old, const char *new); int __wrap_rename(const char *old, const char *new) { global_rename_called = true; return __real_rename(old, new); } struct trust_test_ctx { struct sss_test_ctx *tctx; struct be_ctx *be_ctx; struct ipa_id_ctx *ipa_ctx; bool expect_rename; }; static struct ipa_id_ctx *mock_ipa_ctx(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct sss_test_ctx *tctx, const char *krb5_realm, const char *hostname) { struct ipa_id_ctx *ipa_ctx; errno_t ret; ipa_ctx = talloc_zero(mem_ctx, struct ipa_id_ctx); assert_non_null(ipa_ctx); ipa_ctx->ipa_options = talloc_zero(ipa_ctx, struct ipa_options); assert_non_null(ipa_ctx->ipa_options); ipa_ctx->ipa_options->id = talloc_zero(ipa_ctx->ipa_options, struct sdap_options); assert_non_null(ipa_ctx->ipa_options->id); ret = sdap_copy_map(ipa_ctx->ipa_options->id, ipa_user_map, SDAP_OPTS_USER, &ipa_ctx->ipa_options->id->user_map); assert_int_equal(ret, ERR_OK); ret = dp_get_options(ipa_ctx->ipa_options->id, tctx->confdb, tctx->conf_dom_path, ipa_def_ldap_opts, SDAP_OPTS_BASIC, &ipa_ctx->ipa_options->id->basic); assert_int_equal(ret, EOK); ret = dp_get_options(ipa_ctx->ipa_options->basic, tctx->confdb, tctx->conf_dom_path, ipa_basic_opts, IPA_OPTS_BASIC, &ipa_ctx->ipa_options->basic); assert_int_equal(ret, EOK); ret = dp_opt_set_string(ipa_ctx->ipa_options->basic, IPA_KRB5_REALM, krb5_realm); assert_int_equal(ret, EOK); ret = dp_opt_set_string(ipa_ctx->ipa_options->basic, IPA_HOSTNAME, hostname); assert_int_equal(ret, EOK); ret = dp_opt_set_bool(ipa_ctx->ipa_options->basic, IPA_SERVER_MODE, true); assert_int_equal(ret, EOK); ipa_ctx->sdap_id_ctx = mock_sdap_id_ctx(ipa_ctx, be_ctx, ipa_ctx->ipa_options->id); assert_non_null(ipa_ctx->sdap_id_ctx); return ipa_ctx; } static struct ipa_server_mode_ctx *mock_server_mode(TALLOC_CTX *mem_ctx) { struct ipa_server_mode_ctx *server_mode; server_mode = talloc_zero(mem_ctx, struct ipa_server_mode_ctx); assert_non_null(server_mode); server_mode->hostname = HOSTNAME; server_mode->realm = DOM_REALM; return server_mode; } static void add_test_subdomains(struct trust_test_ctx *test_ctx, uint32_t direction) { errno_t /* Add two subdomains */ ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, SUBDOM_NAME, SUBDOM_REALM, NULL, SUBDOM_SID, true, false, SUBDOM_REALM, direction); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, CHILD_NAME, CHILD_REALM, CHILD_FLAT, CHILD_SID, true, false, SUBDOM_REALM, direction); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom); assert_int_equal(ret, EOK); } static void add_test_2way_subdomains(struct trust_test_ctx *test_ctx) { return add_test_subdomains(test_ctx, 0x1 | 0x2); } static void add_test_1way_subdomains(struct trust_test_ctx *test_ctx) { return add_test_subdomains(test_ctx, 0x1); } static int test_ipa_server_create_trusts_setup(void **state) { errno_t ret; struct trust_test_ctx *test_ctx; struct sss_test_conf_param params[] = { { NULL, NULL }, /* Sentinel */ }; test_ctx = talloc_zero(NULL, struct trust_test_ctx); assert_non_null(test_ctx); test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, params); assert_non_null(test_ctx->tctx); test_ctx->tctx->dom->flat_name = discard_const(DOM_FLAT); test_ctx->tctx->dom->realm = discard_const(DOM_REALM); test_ctx->be_ctx = mock_be_ctx(test_ctx, test_ctx->tctx); assert_non_null(test_ctx->be_ctx); test_ctx->ipa_ctx = mock_ipa_ctx(test_ctx, test_ctx->be_ctx, test_ctx->tctx, DOM_REALM, HOSTNAME); assert_non_null(test_ctx->tctx); test_ctx->ipa_ctx->server_mode = mock_server_mode(test_ctx->ipa_ctx); assert_non_null(test_ctx->ipa_ctx->server_mode); ret = be_init_failover(test_ctx->be_ctx); assert_int_equal(ret, EOK); mock_keytab_with_contents(test_ctx, KEYTAB_PATH, KEYTAB_TEST_PRINC); global_rename_called = false; *state = test_ctx; return 0; } static int test_ipa_server_create_trusts_teardown(void **state) { struct trust_test_ctx *test_ctx = talloc_get_type(*state, struct trust_test_ctx); errno_t ret; ret = unlink(KEYTAB_PATH); assert_int_equal(ret, 0); unlink(ONEWAY_KEYTAB); /* Ignore failures */ /* If a test needs this variable, it should be set again in * each test */ unsetenv("KT_CREATE_FAIL"); talloc_free(test_ctx); return 0; } static void test_ipa_server_create_trusts_none(struct tevent_req *req); static void test_ipa_server_create_trusts_twoway(struct tevent_req *req); static void test_ipa_server_create_trusts(void **state) { struct trust_test_ctx *test_ctx = talloc_get_type(*state, struct trust_test_ctx); struct tevent_req *req; errno_t ret; req = ipa_server_create_trusts_send(test_ctx, test_ctx->tctx->ev, test_ctx->be_ctx, test_ctx->ipa_ctx, test_ctx->be_ctx->domain); assert_non_null(req); tevent_req_set_callback(req, test_ipa_server_create_trusts_none, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); } static void test_ipa_server_create_trusts_none(struct tevent_req *req) { struct trust_test_ctx *test_ctx = \ tevent_req_callback_data(req, struct trust_test_ctx); errno_t ret; ret = ipa_server_create_trusts_recv(req); talloc_zfree(req); assert_int_equal(ret, EOK); /* Add two subdomains */ add_test_2way_subdomains(test_ctx); req = ipa_server_create_trusts_send(test_ctx, test_ctx->tctx->ev, test_ctx->be_ctx, test_ctx->ipa_ctx, test_ctx->be_ctx->domain); assert_non_null(req); tevent_req_set_callback(req, test_ipa_server_create_trusts_twoway, test_ctx); } static void assert_trust_object(struct ipa_ad_server_ctx *trust, const char *dom_name, const char *dom_realm, const char *sid, const char *keytab, const char *authid, const char *sdap_realm) { const char *s; assert_non_null(trust); assert_non_null(trust->dom); assert_string_equal(trust->dom->name, dom_name); assert_string_equal(trust->dom->domain_id, sid); s = dp_opt_get_string(trust->ad_id_ctx->ad_options->basic, AD_KRB5_REALM); if (dom_realm != NULL) { assert_non_null(s); assert_string_equal(s, dom_realm); } else { assert_null(s); } s = dp_opt_get_string(trust->ad_id_ctx->ad_options->basic, AD_DOMAIN); if (dom_name != NULL) { assert_non_null(s); assert_string_equal(s, dom_name); } else { assert_null(s); } /* the system keytab is always used with two-way trusts */ s = dp_opt_get_string(trust->ad_id_ctx->ad_options->id->basic, SDAP_KRB5_KEYTAB); if (keytab != NULL) { assert_non_null(s); assert_string_equal(s, keytab); } else { assert_null(s); } s = dp_opt_get_string(trust->ad_id_ctx->ad_options->id->basic, SDAP_SASL_REALM); if (sdap_realm != NULL) { assert_non_null(s); assert_string_equal(s, sdap_realm); } else { assert_null(s); } s = dp_opt_get_string(trust->ad_id_ctx->ad_options->id->basic, SDAP_SASL_AUTHID); if (authid != NULL) { assert_non_null(s); assert_string_equal(s, authid); } else { assert_null(s); } } static void test_ipa_server_create_trusts_twoway(struct tevent_req *req) { struct trust_test_ctx *test_ctx = \ tevent_req_callback_data(req, struct trust_test_ctx); errno_t ret; struct sss_domain_info *child_dom; ret = ipa_server_create_trusts_recv(req); talloc_zfree(req); assert_int_equal(ret, EOK); /* Trust object should be around now */ assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); /* Two-way trusts should use the system realm */ assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts, CHILD_NAME, DOM_REALM, CHILD_SID, NULL, TEST_AUTHID, DOM_REALM); assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts->next, SUBDOM_NAME, DOM_REALM, SUBDOM_SID, NULL, TEST_AUTHID, DOM_REALM); /* No more trust objects */ assert_null(test_ctx->ipa_ctx->server_mode->trusts->next->next); ret = sysdb_subdomain_delete(test_ctx->tctx->sysdb, CHILD_NAME); assert_int_equal(ret, EOK); child_dom = find_domain_by_name(test_ctx->be_ctx->domain, CHILD_NAME, true); assert_non_null(child_dom); ipa_ad_subdom_remove(test_ctx->be_ctx, test_ctx->ipa_ctx, child_dom); assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts, SUBDOM_NAME, DOM_REALM, SUBDOM_SID, NULL, TEST_AUTHID, DOM_REALM); assert_null(test_ctx->ipa_ctx->server_mode->trusts->next); test_ev_done(test_ctx->tctx, EOK); } static void ipa_server_init_done(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct trust_test_ctx *test_ctx = talloc_get_type(pvt, struct trust_test_ctx); test_ctx->tctx->done = true; } static void test_ipa_server_trust_init(void **state) { struct trust_test_ctx *test_ctx = talloc_get_type(*state, struct trust_test_ctx); errno_t ret; struct tevent_timer *timeout_handler; struct timeval tv; add_test_2way_subdomains(test_ctx); ret = ipa_ad_subdom_init(test_ctx->be_ctx, test_ctx->ipa_ctx); assert_int_equal(ret, EOK); tv = tevent_timeval_current_ofs(1, 0); timeout_handler = tevent_add_timer(test_ctx->tctx->ev, test_ctx, tv, ipa_server_init_done, test_ctx); assert_non_null(timeout_handler); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); /* Trust object should be around now */ assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); /* Two-way trusts should use the system realm */ assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts, CHILD_NAME, DOM_REALM, CHILD_SID, NULL, TEST_AUTHID, DOM_REALM); assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts->next, SUBDOM_NAME, DOM_REALM, SUBDOM_SID, NULL, TEST_AUTHID, DOM_REALM); /* No more trust objects */ assert_null(test_ctx->ipa_ctx->server_mode->trusts->next->next); } struct dir_test_ctx { struct ldb_context *ldb; struct sysdb_attrs *tdo; }; static int test_get_trust_direction_setup(void **state) { struct dir_test_ctx *test_ctx; test_ctx = talloc_zero(global_talloc_context, struct dir_test_ctx); assert_non_null(test_ctx); test_ctx->ldb = ldb_init(test_ctx, NULL); assert_non_null(test_ctx->ldb); test_ctx->tdo = sysdb_new_attrs(test_ctx); assert_non_null(test_ctx->tdo); *state = test_ctx; return 0; } static int test_get_trust_direction_teardown(void **state) { struct dir_test_ctx *test_ctx = talloc_get_type(*state, struct dir_test_ctx); talloc_free(test_ctx); return 0; } /* These are stupid tests, but test real data */ static void test_trust_dir_getset(struct dir_test_ctx *test_ctx, uint32_t dir_in) { errno_t ret; uint32_t dir; ret = sysdb_attrs_add_uint32(test_ctx->tdo, IPA_TRUST_DIRECTION, dir_in); assert_int_equal(ret, EOK); ret = ipa_server_get_trust_direction(test_ctx->tdo, test_ctx->ldb, &dir); assert_int_equal(ret, EOK); assert_int_equal(dir, dir_in); } static void test_get_trust_direction_inbound(void **state) { struct dir_test_ctx *test_ctx = talloc_get_type(*state, struct dir_test_ctx); test_trust_dir_getset(test_ctx, 0x1); } static void test_get_trust_direction_outbound(void **state) { struct dir_test_ctx *test_ctx = talloc_get_type(*state, struct dir_test_ctx); test_trust_dir_getset(test_ctx, 0x2); } static void test_get_trust_direction_twoway(void **state) { struct dir_test_ctx *test_ctx = talloc_get_type(*state, struct dir_test_ctx); test_trust_dir_getset(test_ctx, 0x1 | 0x2); } static void test_get_trust_direction_notset_root(void **state) { errno_t ret; uint32_t dir; struct dir_test_ctx *test_ctx = talloc_get_type(*state, struct dir_test_ctx); ret = sysdb_attrs_add_string(test_ctx->tdo, SYSDB_ORIG_DN, "cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com"); assert_int_equal(ret, EOK); ret = ipa_server_get_trust_direction(test_ctx->tdo, test_ctx->ldb, &dir); assert_int_equal(ret, EOK); /* With root domains we assume two-way trust */ assert_int_equal(dir, 0x1 | 0x2); } static void test_get_trust_direction_notset_member(void **state) { errno_t ret; uint32_t dir; struct dir_test_ctx *test_ctx = talloc_get_type(*state, struct dir_test_ctx); ret = sysdb_attrs_add_string(test_ctx->tdo, SYSDB_ORIG_DN, "cn=SUB.AD.DOM,cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com"); assert_int_equal(ret, EOK); ret = ipa_server_get_trust_direction(test_ctx->tdo, test_ctx->ldb, &dir); assert_int_equal(ret, EOK); /* With members we set zero and take a look at the parent */ assert_int_equal(dir, 0); } static void test_ipa_server_create_trusts_oneway(struct tevent_req *req); static void test_ipa_server_create_oneway(void **state) { struct trust_test_ctx *test_ctx = talloc_get_type(*state, struct trust_test_ctx); struct tevent_req *req; errno_t ret; add_test_1way_subdomains(test_ctx); ret = access(ONEWAY_KEYTAB, R_OK); assert_int_not_equal(ret, 0); assert_null(test_ctx->ipa_ctx->server_mode->trusts); test_ctx->expect_rename = true; req = ipa_server_create_trusts_send(test_ctx, test_ctx->tctx->ev, test_ctx->be_ctx, test_ctx->ipa_ctx, test_ctx->be_ctx->domain); assert_non_null(req); tevent_req_set_callback(req, test_ipa_server_create_trusts_oneway, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); } static void test_ipa_server_create_trusts_oneway(struct tevent_req *req) { struct trust_test_ctx *test_ctx = \ tevent_req_callback_data(req, struct trust_test_ctx); errno_t ret; ret = ipa_server_create_trusts_recv(req); talloc_zfree(req); assert_int_equal(ret, EOK); assert_true(test_ctx->expect_rename == global_rename_called); ret = access(ONEWAY_KEYTAB, R_OK); assert_int_equal(ret, 0); /* Trust object should be around now */ assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); assert_trust_object( test_ctx->ipa_ctx->server_mode->trusts, CHILD_NAME, /* AD domain name */ CHILD_REALM, /* AD realm can be child if SDAP realm is parent's */ CHILD_SID, ONEWAY_KEYTAB, /* Keytab shared with parent AD dom */ ONEWAY_PRINC, /* Principal shared with parent AD dom */ SUBDOM_REALM); /* SDAP realm must be AD root domain */ assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); /* Here all properties point to the AD domain */ assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts->next, SUBDOM_NAME, SUBDOM_REALM, SUBDOM_SID, ONEWAY_KEYTAB, ONEWAY_PRINC, SUBDOM_REALM); assert_null(test_ctx->ipa_ctx->server_mode->trusts->next->next); test_ev_done(test_ctx->tctx, EOK); } static void test_ipa_server_create_oneway_kt_exists(void **state) { struct trust_test_ctx *test_ctx = talloc_get_type(*state, struct trust_test_ctx); struct tevent_req *req; errno_t ret; add_test_1way_subdomains(test_ctx); create_dummy_keytab(ONEWAY_KEYTAB); ret = access(ONEWAY_KEYTAB, R_OK); assert_int_equal(ret, 0); test_ctx->expect_rename = true; assert_null(test_ctx->ipa_ctx->server_mode->trusts); req = ipa_server_create_trusts_send(test_ctx, test_ctx->tctx->ev, test_ctx->be_ctx, test_ctx->ipa_ctx, test_ctx->be_ctx->domain); assert_non_null(req); tevent_req_set_callback(req, test_ipa_server_create_trusts_oneway, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); } /* Test scenario where a keytab already exists, but refresh fails. In this case, * sssd should attempt to reuse the previous keytab */ static void test_ipa_server_create_oneway_kt_refresh_fallback(void **state) { struct trust_test_ctx *test_ctx = talloc_get_type(*state, struct trust_test_ctx); struct tevent_req *req; errno_t ret; add_test_1way_subdomains(test_ctx); create_dummy_keytab(ONEWAY_KEYTAB); ret = access(ONEWAY_KEYTAB, R_OK); assert_int_equal(ret, 0); setenv("KT_CREATE_FAIL", "1", 1); test_ctx->expect_rename = false; assert_null(test_ctx->ipa_ctx->server_mode->trusts); req = ipa_server_create_trusts_send(test_ctx, test_ctx->tctx->ev, test_ctx->be_ctx, test_ctx->ipa_ctx, test_ctx->be_ctx->domain); assert_non_null(req); tevent_req_set_callback(req, test_ipa_server_create_trusts_oneway, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); } /* Tests case where there's no keytab and retrieving fails. Just fail the * request in that case */ static void test_ipa_server_create_trusts_oneway_fail(struct tevent_req *req); static void test_ipa_server_create_oneway_kt_refresh_fail(void **state) { struct trust_test_ctx *test_ctx = talloc_get_type(*state, struct trust_test_ctx); struct tevent_req *req; errno_t ret; add_test_1way_subdomains(test_ctx); setenv("KT_CREATE_FAIL", "1", 1); test_ctx->expect_rename = false; assert_null(test_ctx->ipa_ctx->server_mode->trusts); req = ipa_server_create_trusts_send(test_ctx, test_ctx->tctx->ev, test_ctx->be_ctx, test_ctx->ipa_ctx, test_ctx->be_ctx->domain); assert_non_null(req); tevent_req_set_callback(req, test_ipa_server_create_trusts_oneway_fail, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); } static void test_ipa_server_create_trusts_oneway_fail(struct tevent_req *req) { struct trust_test_ctx *test_ctx = \ tevent_req_callback_data(req, struct trust_test_ctx); errno_t ret; ret = ipa_server_create_trusts_recv(req); assert_int_not_equal(ret, EOK); assert_true(test_ctx->expect_rename == global_rename_called); test_ev_done(test_ctx->tctx, EOK); } static void test_ipa_server_trust_oneway_init(void **state) { struct trust_test_ctx *test_ctx = talloc_get_type(*state, struct trust_test_ctx); errno_t ret; struct tevent_timer *timeout_handler; struct timeval tv; add_test_1way_subdomains(test_ctx); ret = ipa_ad_subdom_init(test_ctx->be_ctx, test_ctx->ipa_ctx); assert_int_equal(ret, EOK); tv = tevent_timeval_current_ofs(1, 0); timeout_handler = tevent_add_timer(test_ctx->tctx->ev, test_ctx, tv, ipa_server_init_done, test_ctx); assert_non_null(timeout_handler); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); } static void test_ipa_trust_dir2str(void **state) { /* Just make sure the caller can rely on getting a valid string.. */ assert_non_null(ipa_trust_dir2str(0x00)); assert_non_null(ipa_trust_dir2str(0x01)); assert_non_null(ipa_trust_dir2str(0x02)); assert_non_null(ipa_trust_dir2str(0x80)); } int main(int argc, const char *argv[]) { int rv; int no_cleanup = 0; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS { "no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test(test_ipa_trust_dir2str), cmocka_unit_test_setup_teardown(test_ipa_server_create_oneway, test_ipa_server_create_trusts_setup, test_ipa_server_create_trusts_teardown), cmocka_unit_test_setup_teardown(test_ipa_server_create_oneway_kt_exists, test_ipa_server_create_trusts_setup, test_ipa_server_create_trusts_teardown), cmocka_unit_test_setup_teardown(test_ipa_server_create_oneway_kt_refresh_fallback, test_ipa_server_create_trusts_setup, test_ipa_server_create_trusts_teardown), cmocka_unit_test_setup_teardown(test_ipa_server_create_oneway_kt_refresh_fail, test_ipa_server_create_trusts_setup, test_ipa_server_create_trusts_teardown), cmocka_unit_test_setup_teardown(test_ipa_server_trust_oneway_init, test_ipa_server_create_trusts_setup, test_ipa_server_create_trusts_teardown), cmocka_unit_test_setup_teardown(test_ipa_server_trust_init, test_ipa_server_create_trusts_setup, test_ipa_server_create_trusts_teardown), cmocka_unit_test_setup_teardown(test_ipa_server_create_trusts, test_ipa_server_create_trusts_setup, test_ipa_server_create_trusts_teardown), cmocka_unit_test_setup_teardown(test_get_trust_direction_inbound, test_get_trust_direction_setup, test_get_trust_direction_teardown), cmocka_unit_test_setup_teardown(test_get_trust_direction_outbound, test_get_trust_direction_setup, test_get_trust_direction_teardown), cmocka_unit_test_setup_teardown(test_get_trust_direction_twoway, test_get_trust_direction_setup, test_get_trust_direction_teardown), cmocka_unit_test_setup_teardown(test_get_trust_direction_notset_root, test_get_trust_direction_setup, test_get_trust_direction_teardown), cmocka_unit_test_setup_teardown(test_get_trust_direction_notset_member, test_get_trust_direction_setup, test_get_trust_direction_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0 && !no_cleanup) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); } return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_dyndns.c0000644000000000000000000000007412703456111020215 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.917794521 sssd-1.13.4/src/tests/cmocka/test_dyndns.c0000644002412700241270000006361712703456111021701 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat SSSD tests: Dynamic DNS tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include /* In order to access opaque types */ #include "providers/dp_dyndns.c" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_be.h" #include "src/providers/dp_dyndns.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_dyndns_conf.ldb" #define TEST_DOM_NAME "dyndns_test" #define TEST_ID_PROVIDER "ldap" enum mock_nsupdate_states { MOCK_NSUPDATE_OK, MOCK_NSUPDATE_ERR, MOCK_NSUPDATE_TIMEOUT, }; static TALLOC_CTX *global_mock_context = NULL; struct dyndns_test_ctx { struct sss_test_ctx *tctx; struct be_ctx *be_ctx; struct be_nsupdate_ctx *update_ctx; enum mock_nsupdate_states state; int child_status; int child_retval; }; static struct dyndns_test_ctx *dyndns_test_ctx; void __wrap_execv(const char *path, char *const argv[]) { int err; switch (dyndns_test_ctx->state) { case MOCK_NSUPDATE_OK: DEBUG(SSSDBG_FUNC_DATA, "nsupdate success test case\n"); err = 0; usleep(50000); /* 50 miliseconds */ break; case MOCK_NSUPDATE_ERR: DEBUG(SSSDBG_FUNC_DATA, "nsupdate error test case\n"); err = 1; break; case MOCK_NSUPDATE_TIMEOUT: DEBUG(SSSDBG_FUNC_DATA, "nsupdate timeout test case\n"); err = 2; sleep(3); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "unknown test case\n"); err = 255; break; } DEBUG(SSSDBG_TRACE_LIBS, "Child exiting with status %d\n", err); _exit(err); } int __wrap_getifaddrs(struct ifaddrs **_ifap) { struct ifaddrs *ifap = NULL; struct ifaddrs *ifap_prev = NULL; struct ifaddrs *ifap_head = NULL; char *name; char *straddr; int ad_family; struct sockaddr_in *sa; void *dst; while ((name = sss_mock_ptr_type(char *)) != NULL) { straddr = sss_mock_ptr_type(char *); if (straddr == NULL) { errno = EINVAL; goto fail; } ad_family = sss_mock_type(int); ifap = talloc_zero(global_mock_context, struct ifaddrs); if (ifap == NULL) { errno = ENOMEM; /* getifaddrs sets errno, too */ goto fail; } if (ifap_prev) { ifap_prev->ifa_next = ifap; } else { ifap_head = ifap; } ifap_prev = ifap; ifap->ifa_name = talloc_strdup(ifap, name); if (ifap->ifa_name == NULL) { errno = ENOMEM; goto fail; } /* Do not alocate directly on ifap->ifa_addr to * avoid alignment warnings */ if (ad_family == AF_INET) { sa = talloc(ifap, struct sockaddr_in); } else if (ad_family == AF_INET6) { sa = (struct sockaddr_in *) talloc(ifap, struct sockaddr_in6); } else { errno = EINVAL; goto fail; } if (sa == NULL) { errno = ENOMEM; goto fail; } sa->sin_family = ad_family; if (ad_family == AF_INET) { dst = &sa->sin_addr; } else if (ad_family == AF_INET6) { dst = &((struct sockaddr_in6 *)sa)->sin6_addr; } else { errno = EINVAL; goto fail; } /* convert straddr into ifa_addr */ if (inet_pton(ad_family, straddr, dst) != 1) { goto fail; } ifap->ifa_addr = (struct sockaddr *) sa; } *_ifap = ifap_head; return 0; fail: talloc_free(ifap); return -1; } void __wrap_freeifaddrs(struct ifaddrs *ifap) { talloc_free(ifap); } static void dyndns_test_done(struct tevent_req *req) { struct dyndns_test_ctx *ctx = tevent_req_callback_data(req, struct dyndns_test_ctx); ctx->child_retval = -1; ctx->tctx->error = be_nsupdate_recv(req, &ctx->child_status); talloc_zfree(req); ctx->tctx->done = true; } void will_return_getifaddrs(const char *ifname, const char *straddr, int af_family) { will_return(__wrap_getifaddrs, ifname); if (ifname) { will_return(__wrap_getifaddrs, straddr); } if (straddr) { will_return(__wrap_getifaddrs, af_family); } } void dyndns_test_sss_iface_addr_get_misc(void **state) { struct sss_iface_addr addrs[3]; struct sockaddr_storage ss[3]; addrs[0].prev = NULL; addrs[0].next = &addrs[1]; addrs[0].addr = &ss[0]; addrs[1].prev = &addrs[0]; addrs[1].next = &addrs[2]; addrs[1].addr = &ss[1]; addrs[2].prev = &addrs[1]; addrs[2].next = NULL; addrs[2].addr = &ss[2]; assert_ptr_equal(sss_iface_addr_get_address(NULL), NULL); assert_ptr_equal(sss_iface_addr_get_address(&addrs[0]), &ss[0]); assert_ptr_equal(sss_iface_addr_get_address(&addrs[1]), &ss[1]); assert_ptr_equal(sss_iface_addr_get_address(&addrs[2]), &ss[2]); assert_ptr_equal(sss_iface_addr_get_next(NULL), NULL); assert_ptr_equal(sss_iface_addr_get_next(&addrs[0]), &addrs[1]); assert_ptr_equal(sss_iface_addr_get_next(&addrs[1]), &addrs[2]); assert_ptr_equal(sss_iface_addr_get_next(&addrs[2]), NULL); } void dyndns_test_get_ifaddr(void **state) { errno_t ret; struct sss_iface_addr *addrlist; char straddr[128]; check_leaks_push(dyndns_test_ctx); will_return_getifaddrs("eth0", "192.168.0.1", AF_INET); will_return_getifaddrs("eth1", "192.168.0.2", AF_INET); will_return_getifaddrs(NULL, NULL, 0); /* sentinel */ ret = sss_iface_addr_list_get(dyndns_test_ctx, "eth0", &addrlist); assert_int_equal(ret, EOK); /* There must be only one address with the correct value */ assert_non_null(addrlist); assert_non_null(addrlist->addr); assert_null(addrlist->next); assert_null(addrlist->prev); assert_non_null(inet_ntop(AF_INET, &((struct sockaddr_in *) addrlist->addr)->sin_addr, straddr, INET_ADDRSTRLEN)); assert_string_equal(straddr, "192.168.0.1"); talloc_free(addrlist); assert_true(check_leaks_pop(dyndns_test_ctx) == true); } void dyndns_test_get_multi_ifaddr(void **state) { errno_t ret; struct sss_iface_addr *addrlist; struct sss_iface_addr *sss_if_addr; char straddr[128]; check_leaks_push(dyndns_test_ctx); will_return_getifaddrs("eth0", "192.168.0.2", AF_INET); will_return_getifaddrs("eth0", "192.168.0.1", AF_INET); will_return_getifaddrs(NULL, NULL, 0); /* sentinel */ ret = sss_iface_addr_list_get(dyndns_test_ctx, "eth0", &addrlist); assert_int_equal(ret, EOK); sss_if_addr = addrlist; assert_non_null(sss_if_addr); assert_non_null(sss_if_addr->addr); assert_non_null(sss_if_addr->next); assert_null(sss_if_addr->prev); assert_non_null(inet_ntop(AF_INET, &((struct sockaddr_in *) sss_if_addr->addr)->sin_addr, straddr, INET_ADDRSTRLEN)); /* ip addresses are returned in different order */ assert_string_equal(straddr, "192.168.0.1"); sss_if_addr = addrlist->next; assert_non_null(sss_if_addr); assert_non_null(sss_if_addr->addr); assert_null(sss_if_addr->next); assert_non_null(sss_if_addr->prev); assert_non_null(inet_ntop(AF_INET, &((struct sockaddr_in *) sss_if_addr->addr)->sin_addr, straddr, INET_ADDRSTRLEN)); /* ip addresses are returned in different order */ assert_string_equal(straddr, "192.168.0.2"); talloc_free(addrlist); assert_true(check_leaks_pop(dyndns_test_ctx) == true); } void dyndns_test_get_ifaddr_enoent(void **state) { errno_t ret; struct sss_iface_addr *addrlist = NULL; check_leaks_push(dyndns_test_ctx); will_return_getifaddrs("eth0", "192.168.0.1", AF_INET); will_return_getifaddrs("eth1", "192.168.0.2", AF_INET); will_return_getifaddrs(NULL, NULL, 0); /* sentinel */ ret = sss_iface_addr_list_get(dyndns_test_ctx, "non_existing_interface", &addrlist); assert_int_equal(ret, ENOENT); talloc_free(addrlist); assert_true(check_leaks_pop(dyndns_test_ctx) == true); } void dyndns_test_addr_list_as_str_list(void **state) { int i; char **output; errno_t ret; struct sss_iface_addr *addrlist; struct { const char* addr; int af; } input[] = { {"2001:cdba::555", AF_INET6}, {"192.168.0.1", AF_INET}, {"192.168.0.2", AF_INET}, {"2001:cdba::444", AF_INET6} }; int size = 4; check_leaks_push(dyndns_test_ctx); for (i = 0; i < size; i++) { will_return_getifaddrs("eth0", input[i].addr, input[i].af); } will_return_getifaddrs(NULL, NULL, 0); /* sentinel */ ret = sss_iface_addr_list_get(dyndns_test_ctx, "eth0", &addrlist); assert_int_equal(ret, EOK); ret = sss_iface_addr_list_as_str_list(dyndns_test_ctx, addrlist, &output); assert_int_equal(ret, EOK); for (i = 0; i < size; i++) { /* addresses are returned in reversed order */ assert_int_equal(strcmp(input[i].addr, output[size - 1 - i]), 0); } talloc_free(addrlist); talloc_free(output); assert_true(check_leaks_pop(dyndns_test_ctx) == true); } void dyndns_test_dualstack(void **state) { errno_t ret; struct sss_iface_addr *addrlist; struct sss_iface_addr *sss_if_addrs; char straddr[128]; int i; check_leaks_push(dyndns_test_ctx); /* getifaddrs is called twice in sss_get_dualstack_addresses() */ for (i = 0; i < 2; i++) { will_return_getifaddrs("eth0", "192.168.0.2", AF_INET); will_return_getifaddrs("eth1", "192.168.0.1", AF_INET); will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6); will_return_getifaddrs("eth1", "2001:cdba::444", AF_INET6); will_return_getifaddrs(NULL, NULL, 0); /* sentinel */ } struct sockaddr_in sin; memset (&sin, 0, sizeof (sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr ("192.168.0.2"); ret = sss_get_dualstack_addresses(dyndns_test_ctx, (struct sockaddr *) &sin, &addrlist); assert_int_equal(ret, EOK); sss_if_addrs = addrlist; assert_non_null(sss_if_addrs); assert_non_null(sss_if_addrs->addr); assert_non_null(sss_if_addrs->next); assert_null(sss_if_addrs->prev); assert_non_null(inet_ntop(AF_INET6, &((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr, straddr, INET6_ADDRSTRLEN)); /* ip addresses are returned in different order */ assert_string_equal(straddr, "2001:cdba::555"); sss_if_addrs = addrlist->next; assert_non_null(sss_if_addrs); assert_non_null(sss_if_addrs->addr); assert_null(sss_if_addrs->next); assert_non_null(sss_if_addrs->prev); assert_non_null(inet_ntop(AF_INET, &((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr, straddr, INET_ADDRSTRLEN)); /* ip addresses are returned in different order */ assert_string_equal(straddr, "192.168.0.2"); talloc_free(addrlist); assert_true(check_leaks_pop(dyndns_test_ctx) == true); } void dyndns_test_dualstack_multiple_addresses(void **state) { errno_t ret; struct sss_iface_addr *addrlist; struct sss_iface_addr *sss_if_addrs; char straddr[128]; int i; check_leaks_push(dyndns_test_ctx); /* getifaddrs is called twice in sss_get_dualstack_addresses() */ for (i = 0; i < 2; i++) { will_return_getifaddrs("eth0", "192.168.0.2", AF_INET); will_return_getifaddrs("eth0", "192.168.0.1", AF_INET); /* loopback - invalid for dns (should be skipped) */ will_return_getifaddrs("eth0", "::1", AF_INET6); /* linklocal - invalid for dns (should be skipped) */ will_return_getifaddrs("eth0", "fe80::5054:ff:fe4a:65ae", AF_INET6); will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6); will_return_getifaddrs("eth0", "2001:cdba::444", AF_INET6); will_return_getifaddrs(NULL, NULL, 0); /* sentinel */ } struct sockaddr_in sin; memset (&sin, 0, sizeof (sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr ("192.168.0.2"); ret = sss_get_dualstack_addresses(dyndns_test_ctx, (struct sockaddr *) &sin, &addrlist); assert_int_equal(ret, EOK); sss_if_addrs = addrlist; assert_non_null(sss_if_addrs); assert_non_null(sss_if_addrs->addr); assert_non_null(sss_if_addrs->next); assert_null(sss_if_addrs->prev); assert_non_null(inet_ntop(AF_INET6, &((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr, straddr, INET6_ADDRSTRLEN)); /* ip addresses are returned in different order */ assert_string_equal(straddr, "2001:cdba::444"); sss_if_addrs = sss_if_addrs->next; assert_non_null(sss_if_addrs); assert_non_null(sss_if_addrs->addr); assert_non_null(sss_if_addrs->prev); assert_non_null(sss_if_addrs->next); assert_non_null(inet_ntop(AF_INET6, &((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr, straddr, INET6_ADDRSTRLEN)); /* ip addresses are returned in different order */ assert_string_equal(straddr, "2001:cdba::555"); sss_if_addrs = sss_if_addrs->next; assert_non_null(sss_if_addrs); assert_non_null(sss_if_addrs->addr); assert_non_null(sss_if_addrs->next); assert_non_null(sss_if_addrs->prev); assert_non_null(inet_ntop(AF_INET, &((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr, straddr, INET_ADDRSTRLEN)); /* ip addresses are returned in different order */ assert_string_equal(straddr, "192.168.0.1"); sss_if_addrs = sss_if_addrs->next; assert_non_null(sss_if_addrs); assert_non_null(sss_if_addrs->addr); assert_null(sss_if_addrs->next); assert_non_null(sss_if_addrs->prev); assert_non_null(inet_ntop(AF_INET, &((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr, straddr, INET_ADDRSTRLEN)); /* ip addresses are returned in different order */ assert_string_equal(straddr, "192.168.0.2"); talloc_free(addrlist); assert_true(check_leaks_pop(dyndns_test_ctx) == true); } void dyndns_test_dualstack_no_iface(void **state) { errno_t ret; struct sss_iface_addr *addrlist; check_leaks_push(dyndns_test_ctx); will_return_getifaddrs("eth0", "192.168.0.2", AF_INET); will_return_getifaddrs("eth1", "192.168.0.1", AF_INET); will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6); will_return_getifaddrs("eth1", "2001:cdba::444", AF_INET6); will_return_getifaddrs(NULL, NULL, 0); /* sentinel */ struct sockaddr_in sin; memset (&sin, 0, sizeof (sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr ("192.168.0.3"); ret = sss_get_dualstack_addresses(dyndns_test_ctx, (struct sockaddr *) &sin, &addrlist); assert_int_equal(ret, ENOENT); assert_true(check_leaks_pop(dyndns_test_ctx) == true); } void dyndns_test_ok(void **state) { struct tevent_req *req; errno_t ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); dyndns_test_ctx->state = MOCK_NSUPDATE_OK; req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev, BE_NSUPDATE_AUTH_GSS_TSIG, discard_const("test message"), false); assert_non_null(req); tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx); /* Wait until the test finishes with EOK */ ret = test_ev_loop(dyndns_test_ctx->tctx); DEBUG(SSSDBG_TRACE_LIBS, "Child request returned [%d]: %s\n", ret, strerror(ret)); assert_int_equal(ret, EOK); assert_true(WIFEXITED(dyndns_test_ctx->child_status)); assert_int_equal(WEXITSTATUS(dyndns_test_ctx->child_status), 0); assert_true(check_leaks_pop(tmp_ctx) == true); talloc_free(tmp_ctx); } void dyndns_test_error(void **state) { struct tevent_req *req; errno_t ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); dyndns_test_ctx->state = MOCK_NSUPDATE_ERR; req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev, BE_NSUPDATE_AUTH_GSS_TSIG, discard_const("test message"), false); assert_non_null(req); tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx); /* Wait until the test finishes with EIO (child error) */ ret = test_ev_loop(dyndns_test_ctx->tctx); DEBUG(SSSDBG_TRACE_LIBS, "Child request returned [%d]: %s\n", ret, strerror(ret)); assert_int_equal(ret, ERR_DYNDNS_FAILED); assert_true(WIFEXITED(dyndns_test_ctx->child_status)); assert_int_equal(WEXITSTATUS(dyndns_test_ctx->child_status), 1); assert_true(check_leaks_pop(tmp_ctx) == true); talloc_free(tmp_ctx); } void dyndns_test_timeout(void **state) { struct tevent_req *req; errno_t ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); dyndns_test_ctx->state = MOCK_NSUPDATE_TIMEOUT; req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev, BE_NSUPDATE_AUTH_GSS_TSIG, discard_const("test message"), false); assert_non_null(req); tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx); /* Wait until the test finishes with EIO (child error) */ ret = test_ev_loop(dyndns_test_ctx->tctx); /* The event queue may not be empty. We need to make sure that all events * are processed. Unfortunately, tevent_loop_wait() contains a bug that * prevents exiting the loop even if there are no remaining events, thus * we have to use tevent_loop_once(). * * FIXME: use tevent_loop_wait() when the bug is fixed * https://bugzilla.samba.org/show_bug.cgi?id=10012 */ tevent_loop_once(dyndns_test_ctx->tctx->ev); /* SIGCHLD handler */ tevent_loop_once(dyndns_test_ctx->tctx->ev); /* nsupdate_child_handler */ DEBUG(SSSDBG_TRACE_LIBS, "Child request returned [%d]: %s\n", ret, strerror(ret)); assert_int_equal(ret, ERR_DYNDNS_TIMEOUT); assert_true(check_leaks_pop(tmp_ctx) == true); talloc_free(tmp_ctx); } void dyndns_test_timer(void *pvt) { struct dyndns_test_ctx *ctx = talloc_get_type(pvt, struct dyndns_test_ctx); static int ncalls = 0; ncalls++; if (ncalls == 1) { be_nsupdate_timer_schedule(ctx->tctx->ev, ctx->update_ctx); } else if (ncalls == 2) { ctx->tctx->done = true; } ctx->tctx->error = ERR_OK; } void dyndns_test_interval(void **state) { errno_t ret; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); ret = be_nsupdate_init(tmp_ctx, dyndns_test_ctx->be_ctx, NULL, &dyndns_test_ctx->update_ctx); assert_int_equal(ret, EOK); ret = be_nsupdate_init_timer(dyndns_test_ctx->update_ctx, dyndns_test_ctx->be_ctx->ev, dyndns_test_timer, dyndns_test_ctx); assert_int_equal(ret, EOK); /* Wait until the timer hits */ ret = test_ev_loop(dyndns_test_ctx->tctx); DEBUG(SSSDBG_TRACE_LIBS, "Child request returned [%d]: %s\n", ret, strerror(ret)); assert_int_equal(ret, ERR_OK); talloc_free(dyndns_test_ctx->update_ctx); assert_true(check_leaks_pop(tmp_ctx) == true); talloc_free(tmp_ctx); } /* Testsuite setup and teardown */ static int dyndns_test_setup(void **state) { struct sss_test_conf_param params[] = { { "dyndns_update", "true" }, { "dyndns_refresh_interval", "2" }, { NULL, NULL }, /* Sentinel */ }; assert_true(leak_check_setup()); global_mock_context = talloc_new(global_talloc_context); assert_non_null(global_mock_context); dyndns_test_ctx = talloc_zero(global_talloc_context, struct dyndns_test_ctx); assert_non_null(dyndns_test_ctx); dyndns_test_ctx->tctx = create_dom_test_ctx(dyndns_test_ctx, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, params); assert_non_null(dyndns_test_ctx->tctx); dyndns_test_ctx->be_ctx = mock_be_ctx(dyndns_test_ctx, dyndns_test_ctx->tctx); assert_non_null(dyndns_test_ctx->be_ctx); return 0; } static int dyndns_test_simple_setup(void **state) { assert_true(leak_check_setup()); global_mock_context = talloc_new(global_talloc_context); assert_non_null(global_mock_context); dyndns_test_ctx = talloc_zero(global_talloc_context, struct dyndns_test_ctx); assert_non_null(dyndns_test_ctx); return 0; } static int dyndns_test_teardown(void **state) { talloc_free(dyndns_test_ctx); talloc_free(global_mock_context); assert_true(leak_check_teardown()); return 0; } int main(int argc, const char *argv[]) { int rv; int no_cleanup = 0; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { /* Utility functions unit test */ cmocka_unit_test_setup_teardown(dyndns_test_sss_iface_addr_get_misc, dyndns_test_simple_setup, dyndns_test_teardown), cmocka_unit_test_setup_teardown(dyndns_test_get_ifaddr, dyndns_test_simple_setup, dyndns_test_teardown), cmocka_unit_test_setup_teardown(dyndns_test_get_multi_ifaddr, dyndns_test_simple_setup, dyndns_test_teardown), cmocka_unit_test_setup_teardown(dyndns_test_get_ifaddr_enoent, dyndns_test_simple_setup, dyndns_test_teardown), cmocka_unit_test_setup_teardown(dyndns_test_addr_list_as_str_list, dyndns_test_simple_setup, dyndns_test_teardown), /* Dynamic DNS update unit tests*/ cmocka_unit_test_setup_teardown(dyndns_test_ok, dyndns_test_setup, dyndns_test_teardown), cmocka_unit_test_setup_teardown(dyndns_test_error, dyndns_test_setup, dyndns_test_teardown), cmocka_unit_test_setup_teardown(dyndns_test_timeout, dyndns_test_setup, dyndns_test_teardown), cmocka_unit_test_setup_teardown(dyndns_test_interval, dyndns_test_setup, dyndns_test_teardown), /* Dynamic DNS dualstack unit tests*/ cmocka_unit_test_setup_teardown(dyndns_test_dualstack, dyndns_test_simple_setup, dyndns_test_teardown), cmocka_unit_test_setup_teardown(dyndns_test_dualstack_multiple_addresses, dyndns_test_simple_setup, dyndns_test_teardown), cmocka_unit_test_setup_teardown(dyndns_test_dualstack_no_iface, dyndns_test_simple_setup, dyndns_test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0 && !no_cleanup) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); } return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_tools_colondb.c0000644000000000000000000000007412703456111021556 xustar0030 atime=1460561751.657715651 30 ctime=1460561775.052794978 sssd-1.13.4/src/tests/cmocka/test_tools_colondb.c0000644002412700241270000002666612703456111023245 0ustar00jhrozekjhrozek00000000000000/* Authors: Petr Čech Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "tests/cmocka/common_mock.h" #include "src/tools/common/sss_colondb.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TESTS_FILE "test_colondb.ldb" const char *TEST_STRING1 = "white"; const int TEST_INT1 = 12; const char *TEST_STRING2 = "black"; const int TEST_INT2 = 34; static void create_dir(const char *path) { errno_t ret; errno = 0; ret = mkdir(path, 0775); assert_return_code(ret, errno); } static void create_empty_file(TALLOC_CTX *test_ctx, const char *path, const char *name) { TALLOC_CTX *tmp_ctx = NULL; char *file_name = NULL; FILE *fp = NULL; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); create_dir(path); file_name = talloc_asprintf(tmp_ctx, "%s/%s", path, name); assert_non_null(file_name); fp = fopen(file_name, "w"); assert_non_null(fp); fclose(fp); talloc_free(tmp_ctx); } static void create_nonempty_file(TALLOC_CTX *test_ctx, const char *path, const char *name) { TALLOC_CTX *tmp_ctx = NULL; struct sss_colondb *db = NULL; errno_t ret; struct sss_colondb_write_field table[] = { { SSS_COLONDB_STRING, { .str = TEST_STRING2 } }, { SSS_COLONDB_UINT32, { .uint32 = TEST_INT2 } }, { SSS_COLONDB_SENTINEL, { 0 } } }; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); create_empty_file(test_ctx, TESTS_PATH, TESTS_FILE); db = sss_colondb_open(tmp_ctx, SSS_COLONDB_WRITE, TESTS_PATH "/" TESTS_FILE); assert_non_null(db); ret = sss_colondb_writeline(db, table); assert_int_equal(ret, EOK); talloc_free(db); talloc_free(tmp_ctx); } static int setup(void **state, int file_state) { TALLOC_CTX *test_ctx = NULL; assert_true(leak_check_setup()); check_leaks_push(global_talloc_context); test_ctx = talloc_new(global_talloc_context); assert_non_null(test_ctx); switch (file_state) { case 0: break; case 1: create_empty_file(test_ctx, TESTS_PATH, TESTS_FILE); break; case 2: create_nonempty_file(test_ctx, TESTS_PATH, TESTS_FILE); break; default: break; } check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int without_file_setup(void **state) { return setup(state, 0); } static int with_empty_file_setup(void **state) { return setup(state, 1); } static int with_nonempty_file_setup(void **state) { return setup(state, 2); } static int teardown(void **state) { errno_t ret; errno = 0; ret = unlink(TESTS_PATH "/" TESTS_FILE); if (ret != 0) { assert_int_equal(errno, ENOENT); } assert_true(check_leaks_pop(*state)); talloc_zfree(*state); test_dom_suite_cleanup(TESTS_PATH, NULL, NULL); assert_true(check_leaks_pop(global_talloc_context)); assert_true(leak_check_teardown()); return 0; } void test_open_nonexist_for_read(void **state) { TALLOC_CTX *test_ctx = *state; struct sss_colondb *db = NULL; db = sss_colondb_open(test_ctx, SSS_COLONDB_READ, TESTS_PATH "/" TESTS_FILE); assert_null(db); talloc_free(db); } void test_open_nonexist_for_write(void **state) { TALLOC_CTX *test_ctx = *state; struct sss_colondb *db = NULL; db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE, TESTS_PATH "/" TESTS_FILE); assert_null(db); talloc_free(db); } void test_open_exist_for_read(void **state) { TALLOC_CTX *test_ctx = *state; struct sss_colondb *db = NULL; db = sss_colondb_open(test_ctx, SSS_COLONDB_READ, TESTS_PATH "/" TESTS_FILE); assert_non_null(db); talloc_free(db); } void test_open_exist_for_write(void **state) { TALLOC_CTX *test_ctx = *state; struct sss_colondb *db = NULL; db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE, TESTS_PATH "/" TESTS_FILE); assert_non_null(db); talloc_free(db); } void test_open_nonempty_for_read(void **state) { TALLOC_CTX *test_ctx = *state; struct sss_colondb *db = NULL; db = sss_colondb_open(test_ctx, SSS_COLONDB_READ, TESTS_PATH "/" TESTS_FILE); assert_non_null(db); talloc_free(db); } void test_open_nonempty_for_write(void **state) { TALLOC_CTX *test_ctx = *state; struct sss_colondb *db = NULL; db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE, TESTS_PATH "/" TESTS_FILE); assert_non_null(db); talloc_free(db); } void test_write_to_empty(void **state) { TALLOC_CTX *test_ctx = *state; struct sss_colondb *db = NULL; struct sss_colondb_write_field table[] = { { SSS_COLONDB_STRING, { .str = TEST_STRING1 } }, { SSS_COLONDB_UINT32, { .uint32 = TEST_INT1 } }, { SSS_COLONDB_SENTINEL, { 0 } } }; errno_t ret; db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE, TESTS_PATH "/" TESTS_FILE); assert_non_null(db); ret = sss_colondb_writeline(db, table); assert_int_equal(ret, 0); talloc_free(db); } void test_write_to_nonempty(void **state) { TALLOC_CTX *test_ctx = *state; struct sss_colondb *db = NULL; struct sss_colondb_write_field table[] = { { SSS_COLONDB_STRING, { .str = TEST_STRING1 } }, { SSS_COLONDB_UINT32, { .uint32 = TEST_INT1 } }, { SSS_COLONDB_SENTINEL, { 0 } } }; errno_t ret; db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE, TESTS_PATH "/" TESTS_FILE); assert_non_null(db); ret = sss_colondb_writeline(db, table); assert_int_equal(ret, 0); talloc_free(db); } void test_read_from_nonempty(void **state) { TALLOC_CTX *test_ctx = *state; struct sss_colondb *db = NULL; errno_t ret; const char *string = NULL; uint32_t number; struct sss_colondb_read_field table[] = { { SSS_COLONDB_STRING, { .str = &string } }, { SSS_COLONDB_UINT32, { .uint32 = &number } }, { SSS_COLONDB_SENTINEL, { 0 } } }; db = sss_colondb_open(test_ctx, SSS_COLONDB_READ, TESTS_PATH "/" TESTS_FILE); assert_non_null(db); ret = sss_colondb_readline(test_ctx, db, table); assert_int_equal(ret, 0); assert_string_equal(string, TEST_STRING2); assert_int_equal(number, TEST_INT2); talloc_zfree(string); talloc_free(db); } void test_read_from_empty(void **state) { TALLOC_CTX *test_ctx = *state; struct sss_colondb *db = NULL; errno_t ret; const char *string; uint32_t number; struct sss_colondb_read_field table[] = { { SSS_COLONDB_STRING, { .str = &string } }, { SSS_COLONDB_UINT32, { .uint32 = &number } }, { SSS_COLONDB_SENTINEL, { 0 } } }; db = sss_colondb_open(test_ctx, SSS_COLONDB_READ, TESTS_PATH "/" TESTS_FILE); assert_non_null(db); ret = sss_colondb_readline(test_ctx, db, table); assert_int_equal(ret, EOF); talloc_free(db); } void test_write_read(void **state) { TALLOC_CTX *test_ctx = *state; struct sss_colondb *db = NULL; errno_t ret; const char *string = NULL; uint32_t number; struct sss_colondb_write_field table_in[] = { { SSS_COLONDB_STRING, { .str = TEST_STRING2 } }, { SSS_COLONDB_UINT32, { .uint32 = TEST_INT2 } }, { SSS_COLONDB_SENTINEL, { 0 } } }; struct sss_colondb_read_field table_out[] = { { SSS_COLONDB_STRING, { .str = &string } }, { SSS_COLONDB_UINT32, { .uint32 = &number } }, { SSS_COLONDB_SENTINEL, { 0 } } }; db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE, TESTS_PATH "/" TESTS_FILE); assert_non_null(db); ret = sss_colondb_writeline(db, table_in); assert_int_equal(ret, 0); talloc_free(db); db = sss_colondb_open(test_ctx, SSS_COLONDB_READ, TESTS_PATH "/" TESTS_FILE); assert_non_null(db); ret = sss_colondb_readline(test_ctx, db, table_out); assert_int_equal(ret, 0); assert_string_equal(string, TEST_STRING2); assert_int_equal(number, TEST_INT2); talloc_zfree(string); talloc_free(db); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_open_nonexist_for_read, without_file_setup, teardown), cmocka_unit_test_setup_teardown(test_open_nonexist_for_write, without_file_setup, teardown), cmocka_unit_test_setup_teardown(test_open_exist_for_read, with_empty_file_setup, teardown), cmocka_unit_test_setup_teardown(test_open_exist_for_write, with_empty_file_setup, teardown), cmocka_unit_test_setup_teardown(test_open_nonempty_for_read, with_nonempty_file_setup, teardown), cmocka_unit_test_setup_teardown(test_open_nonempty_for_write, with_nonempty_file_setup, teardown), cmocka_unit_test_setup_teardown(test_write_to_empty, with_empty_file_setup, teardown), cmocka_unit_test_setup_teardown(test_write_to_nonempty, with_nonempty_file_setup, teardown), cmocka_unit_test_setup_teardown(test_read_from_empty, with_empty_file_setup, teardown), cmocka_unit_test_setup_teardown(test_read_from_nonempty, with_nonempty_file_setup, teardown), cmocka_unit_test_setup_teardown(test_write_read, with_empty_file_setup, teardown), }; /* Set debug level to invalid value so we can decide if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, NULL, NULL); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/common_mock_krb5.c0000644000000000000000000000007312703456111021102 xustar0030 atime=1460561751.655715644 29 ctime=1460561774.90579448 sssd-1.13.4/src/tests/cmocka/common_mock_krb5.c0000644002412700241270000000606412703456111022560 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Jakub Hrozek Copyright (C) 2015 Red Hat SSSD tests: Tests keytab utilities This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/sss_krb5.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_krb5.h" int mock_keytab(krb5_context kctx, const char *kt_path, krb5_keytab_entry *kt_keys, size_t nkeys) { krb5_error_code kerr; krb5_keytab keytab; size_t n; kerr = krb5_kt_resolve(kctx, kt_path, &keytab); assert_int_equal(kerr, 0); for (n = 0; n < nkeys; n++) { kerr = krb5_kt_add_entry(kctx, keytab, &kt_keys[n]); assert_int_equal(kerr, 0); } kerr = krb5_kt_close(kctx, keytab); assert_int_equal(kerr, 0); return EOK; } void mock_krb5_keytab_entry(krb5_keytab_entry *kent, krb5_principal principal, krb5_timestamp timestamp, krb5_kvno vno, krb5_enctype enctype, const char *key) { memset(kent, 0, sizeof(krb5_keytab_entry)); kent->magic = KV5M_KEYTAB_ENTRY; kent->principal = principal; kent->timestamp = timestamp; kent->vno = vno; kent->key.magic = KV5M_KEYBLOCK; kent->key.enctype = enctype; kent->key.length = strlen(key) - 1; kent->key.contents = (krb5_octet *) discard_const(key); } int mock_keytab_with_contents(TALLOC_CTX *mem_ctx, const char *keytab_path, const char *keytab_princ) { krb5_context kctx; krb5_principal principal; krb5_error_code kerr; size_t nkeys = 2; krb5_keytab_entry keys[nkeys]; char *keytab_file_name; kerr = krb5_init_context(&kctx); assert_int_equal(kerr, 0); keytab_file_name = talloc_asprintf(mem_ctx, "FILE:%s", keytab_path); assert_non_null(keytab_file_name); kerr = krb5_parse_name(kctx, keytab_princ, &principal); assert_int_equal(kerr, 0); memset(&keys, nkeys, nkeys * sizeof(krb5_keytab_entry)); mock_krb5_keytab_entry(&keys[0], principal, 12345, 1, 1, "11"); mock_krb5_keytab_entry(&keys[1], principal, 12345, 1, 2, "12"); kerr = mock_keytab(kctx, keytab_file_name, keys, nkeys); assert_int_equal(kerr, 0); krb5_free_principal(kctx, principal); krb5_free_context(kctx); talloc_free(keytab_file_name); return 0; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_sysdb_views.c0000644000000000000000000000007412703456111021257 xustar0030 atime=1460561751.657715651 30 ctime=1460561775.051794975 sssd-1.13.4/src/tests/cmocka/test_sysdb_views.c0000644002412700241270000010756012703456111022737 0ustar00jhrozekjhrozek00000000000000/* SSSD sysdb_views - Tests for view and override related sysdb calls Authors: Sumit Bose Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "tests/cmocka/common_mock.h" #include "providers/ipa/ipa_id.h" #include "db/sysdb_private.h" /* for sysdb->ldb member */ #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_FILE "tests_conf.ldb" #define TEST_ANCHOR_PREFIX ":ANCHOR:" #define TEST_VIEW_NAME "test view" #define TEST_VIEW_CONTAINER "cn=" TEST_VIEW_NAME ",cn=views,cn=sysdb" #define TEST_USER_NAME "test_user" #define TEST_USER_UID 1234 #define TEST_USER_GID 5678 #define TEST_USER_GECOS "Gecos field" #define TEST_USER_HOMEDIR "/home/home" #define TEST_USER_SHELL "/bin/shell" #define TEST_USER_SID "S-1-2-3-4" #define TEST_GID_OVERRIDE_BASE 100 struct sysdb_test_ctx { struct sysdb_ctx *sysdb; struct confdb_ctx *confdb; struct tevent_context *ev; struct sss_domain_info *domain; }; static int _setup_sysdb_tests(struct sysdb_test_ctx **ctx, bool enumerate) { struct sysdb_test_ctx *test_ctx; char *conf_db; int ret; const char *val[2]; val[1] = NULL; /* Create tests directory if it doesn't exist */ /* (relative to current dir) */ ret = mkdir(TESTS_PATH, 0775); assert_true(ret == 0 || errno == EEXIST); test_ctx = talloc_zero(global_talloc_context, struct sysdb_test_ctx); assert_non_null(test_ctx); /* Create an event context * It will not be used except in confdb_init and sysdb_init */ test_ctx->ev = tevent_context_init(test_ctx); assert_non_null(test_ctx->ev); conf_db = talloc_asprintf(test_ctx, "%s/%s", TESTS_PATH, TEST_CONF_FILE); assert_non_null(conf_db); DEBUG(SSSDBG_MINOR_FAILURE, "CONFDB: %s\n", conf_db); /* Connect to the conf db */ ret = confdb_init(test_ctx, &test_ctx->confdb, conf_db); assert_int_equal(ret, EOK); val[0] = "LOCAL"; ret = confdb_add_param(test_ctx->confdb, true, "config/sssd", "domains", val); assert_int_equal(ret, EOK); val[0] = "local"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "id_provider", val); assert_int_equal(ret, EOK); val[0] = enumerate ? "TRUE" : "FALSE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "enumerate", val); assert_int_equal(ret, EOK); val[0] = "TRUE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "cache_credentials", val); assert_int_equal(ret, EOK); ret = sssd_domain_init(test_ctx, test_ctx->confdb, "local", TESTS_PATH, &test_ctx->domain); assert_int_equal(ret, EOK); test_ctx->domain->has_views = true; test_ctx->sysdb = test_ctx->domain->sysdb; *ctx = test_ctx; return EOK; } #define setup_sysdb_tests(ctx) _setup_sysdb_tests((ctx), false) #define setup_sysdb_enum_tests(ctx) _setup_sysdb_tests((ctx), true) static int test_sysdb_setup(void **state) { int ret; struct sysdb_test_ctx *test_ctx; assert_true(leak_check_setup()); ret = setup_sysdb_tests(&test_ctx); assert_int_equal(ret, EOK); *state = (void *) test_ctx; return 0; } static int test_sysdb_teardown(void **state) { struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } static void test_sysdb_store_override(void **state) { int ret; struct ldb_message *msg; struct ldb_message **msgs; struct sysdb_attrs *attrs; size_t count; const char override_dn_str[] = SYSDB_OVERRIDE_ANCHOR_UUID "=" \ TEST_ANCHOR_PREFIX TEST_USER_SID "," TEST_VIEW_CONTAINER; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); test_ctx->domain->mpg = false; ret = sysdb_store_user(test_ctx->domain, TEST_USER_NAME, NULL, TEST_USER_UID, TEST_USER_GID, TEST_USER_GECOS, TEST_USER_HOMEDIR, TEST_USER_SHELL, NULL, NULL, NULL, 0,0); assert_int_equal(ret, EOK); ret = sysdb_search_user_by_name(test_ctx, test_ctx->domain, TEST_USER_NAME, NULL, &msg); assert_int_equal(ret, EOK); assert_non_null(msg); /* No override exists */ ret = sysdb_store_override(test_ctx->domain, TEST_VIEW_NAME, SYSDB_MEMBER_USER, NULL, msg->dn); assert_int_equal(ret, EOK); ret = sysdb_search_entry(test_ctx, test_ctx->domain->sysdb,msg->dn, LDB_SCOPE_BASE, NULL, NULL, &count, &msgs); assert_int_equal(ret, EOK); assert_int_equal(count, 1); assert_string_equal(ldb_dn_get_linearized(msg->dn), ldb_msg_find_attr_as_string(msgs[0], SYSDB_OVERRIDE_DN, NULL)); ret = sysdb_invalidate_overrides(test_ctx->domain->sysdb); assert_int_equal(ret, EOK); attrs = sysdb_new_attrs(test_ctx); assert_non_null(attrs); /* Missing anchor attribute */ ret = sysdb_store_override(test_ctx->domain, TEST_VIEW_NAME, SYSDB_MEMBER_USER, attrs, msg->dn); assert_int_equal(ret, EINVAL); /* With anchor */ ret = sysdb_attrs_add_string(attrs, SYSDB_OVERRIDE_ANCHOR_UUID, TEST_ANCHOR_PREFIX TEST_USER_SID); assert_int_equal(ret, EOK); ret = sysdb_store_override(test_ctx->domain, TEST_VIEW_NAME, SYSDB_MEMBER_USER, attrs, msg->dn); assert_int_equal(ret, EOK); ret = sysdb_search_entry(test_ctx, test_ctx->domain->sysdb,msg->dn, LDB_SCOPE_BASE, NULL, NULL, &count, &msgs); assert_int_equal(ret, EOK); assert_int_equal(count, 1); assert_string_equal(override_dn_str, ldb_msg_find_attr_as_string(msgs[0], SYSDB_OVERRIDE_DN, NULL)); } void test_sysdb_add_overrides_to_object(void **state) { int ret; struct ldb_message *orig; struct ldb_message *override; struct ldb_message_element *el; char *tmp_str; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); orig = ldb_msg_new(test_ctx); assert_non_null(orig); tmp_str = talloc_strdup(orig, "ORIGNAME"); assert_non_null(tmp_str); ret = ldb_msg_add_string(orig, SYSDB_NAME, tmp_str); assert_int_equal(ret, EOK); tmp_str = talloc_strdup(orig, "ORIGGECOS"); assert_non_null(tmp_str); ret = ldb_msg_add_string(orig, SYSDB_GECOS, tmp_str); assert_int_equal(ret, EOK); override = ldb_msg_new(test_ctx); assert_non_null(override); tmp_str = talloc_strdup(override, "OVERRIDENAME"); assert_non_null(tmp_str); ret = ldb_msg_add_string(override, SYSDB_NAME, tmp_str); assert_int_equal(ret, EOK); tmp_str = talloc_strdup(override, "OVERRIDEGECOS"); assert_non_null(tmp_str); ret = ldb_msg_add_string(override, SYSDB_GECOS, tmp_str); assert_int_equal(ret, EOK); tmp_str = talloc_strdup(override, "OVERRIDEKEY1"); assert_non_null(tmp_str); ret = ldb_msg_add_string(override, SYSDB_SSH_PUBKEY, tmp_str); assert_int_equal(ret, EOK); tmp_str = talloc_strdup(override, "OVERRIDEKEY2"); assert_non_null(tmp_str); ret = ldb_msg_add_string(override, SYSDB_SSH_PUBKEY, tmp_str); assert_int_equal(ret, EOK); ret = sysdb_add_overrides_to_object(test_ctx->domain, orig, override, NULL); assert_int_equal(ret, EOK); assert_string_equal(ldb_msg_find_attr_as_string(orig, SYSDB_NAME, NULL), "ORIGNAME"); assert_string_equal(ldb_msg_find_attr_as_string(orig, SYSDB_GECOS, NULL), "ORIGGECOS"); assert_string_equal(ldb_msg_find_attr_as_string(orig, OVERRIDE_PREFIX SYSDB_NAME, NULL), "OVERRIDENAME"); assert_string_equal(ldb_msg_find_attr_as_string(orig, OVERRIDE_PREFIX SYSDB_GECOS, NULL), "OVERRIDEGECOS"); el = ldb_msg_find_element(orig, OVERRIDE_PREFIX SYSDB_SSH_PUBKEY); assert_non_null(el); assert_int_equal(el->num_values, 2); assert_int_equal(ldb_val_string_cmp(&el->values[0], "OVERRIDEKEY1"), 0); assert_int_equal(ldb_val_string_cmp(&el->values[1], "OVERRIDEKEY2"), 0); } void test_sysdb_add_overrides_to_object_local(void **state) { int ret; struct ldb_message *orig; char *tmp_str; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); orig = ldb_msg_new(test_ctx); assert_non_null(orig); tmp_str = talloc_strdup(orig, "ORIGNAME"); assert_non_null(tmp_str); ret = ldb_msg_add_string(orig, SYSDB_NAME, tmp_str); assert_int_equal(ret, EOK); tmp_str = talloc_strdup(orig, "ORIGGECOS"); assert_non_null(tmp_str); ret = ldb_msg_add_string(orig, SYSDB_GECOS, tmp_str); assert_int_equal(ret, EOK); test_ctx->domain->has_views = true; test_ctx->domain->view_name = "LOCAL"; ret = sysdb_add_overrides_to_object(test_ctx->domain, orig, NULL, NULL); assert_int_equal(ret, EOK); } void test_sysdb_add_overrides_to_object_missing_overridedn(void **state) { int ret; struct ldb_message *orig; char *tmp_str; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); orig = ldb_msg_new(test_ctx); assert_non_null(orig); orig->dn = ldb_dn_new(orig, test_ctx->domain->sysdb->ldb, "cn=somedn,dc=example,dc=com"); assert_non_null(orig->dn); tmp_str = talloc_strdup(orig, "ORIGNAME"); assert_non_null(tmp_str); ret = ldb_msg_add_string(orig, SYSDB_NAME, tmp_str); assert_int_equal(ret, EOK); tmp_str = talloc_strdup(orig, "ORIGGECOS"); assert_non_null(tmp_str); ret = ldb_msg_add_string(orig, SYSDB_GECOS, tmp_str); assert_int_equal(ret, EOK); test_ctx->domain->has_views = true; test_ctx->domain->view_name = "NON-LOCAL"; ret = sysdb_add_overrides_to_object(test_ctx->domain, orig, NULL, NULL); assert_int_equal(ret, ENOENT); } void test_split_ipa_anchor(void **state) { int ret; char *dom; char *uuid; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); ret = split_ipa_anchor(test_ctx, NULL, &dom, &uuid); assert_int_equal(ret, EINVAL); ret = split_ipa_anchor(test_ctx, "fwfkwjfkw", &dom, &uuid); assert_int_equal(ret, ENOMSG); ret = split_ipa_anchor(test_ctx, ":IPA:", &dom, &uuid); assert_int_equal(ret, EINVAL); ret = split_ipa_anchor(test_ctx, ":IPA:abc", &dom, &uuid); assert_int_equal(ret, EINVAL); ret = split_ipa_anchor(test_ctx, ":IPA:abc:", &dom, &uuid); assert_int_equal(ret, EINVAL); ret = split_ipa_anchor(test_ctx, ":IPA:abc:def", &dom, &uuid); assert_int_equal(ret, EOK); assert_string_equal(dom, "abc"); assert_string_equal(uuid, "def"); } void test_sysdb_delete_view_tree(void **state) { int ret; struct ldb_message *msg; struct ldb_message **msgs = NULL; struct sysdb_attrs *attrs; size_t count; struct ldb_dn *views_dn; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); test_ctx->domain->mpg = false; ret = sysdb_update_view_name(test_ctx->domain->sysdb, TEST_VIEW_NAME); assert_int_equal(ret, EOK); ret = sysdb_store_user(test_ctx->domain, TEST_USER_NAME, NULL, TEST_USER_UID, TEST_USER_GID, TEST_USER_GECOS, TEST_USER_HOMEDIR, TEST_USER_SHELL, NULL, NULL, NULL, 0,0); assert_int_equal(ret, EOK); ret = sysdb_search_user_by_name(test_ctx, test_ctx->domain, TEST_USER_NAME, NULL, &msg); assert_int_equal(ret, EOK); assert_non_null(msg); attrs = sysdb_new_attrs(test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_string(attrs, SYSDB_OVERRIDE_ANCHOR_UUID, TEST_ANCHOR_PREFIX TEST_USER_SID); assert_int_equal(ret, EOK); ret = sysdb_store_override(test_ctx->domain, TEST_VIEW_NAME, SYSDB_MEMBER_USER, attrs, msg->dn); assert_int_equal(ret, EOK); views_dn = ldb_dn_new(test_ctx, test_ctx->domain->sysdb->ldb, SYSDB_TMPL_VIEW_BASE); assert_non_null(views_dn); ret = sysdb_search_entry(test_ctx, test_ctx->domain->sysdb, views_dn, LDB_SCOPE_SUBTREE, NULL, NULL, &count, &msgs); assert_int_equal(ret, EOK); assert_true(count > 1); assert_non_null(msgs); ret = sysdb_delete_view_tree(test_ctx->domain->sysdb, TEST_VIEW_NAME); assert_int_equal(ret, EOK); ret = sysdb_search_entry(test_ctx, test_ctx->domain->sysdb, views_dn, LDB_SCOPE_SUBTREE, NULL, NULL, &count, &msgs); assert_int_equal(ret, EOK); assert_int_equal(count, 1); assert_true(ldb_dn_compare(views_dn, msgs[0]->dn) == 0); } void test_sysdb_invalidate_overrides(void **state) { int ret; struct ldb_message *msg; struct sysdb_attrs *attrs; struct ldb_dn *views_dn; const char *user_attrs[] = { SYSDB_NAME, SYSDB_CACHE_EXPIRE, SYSDB_OVERRIDE_DN, NULL}; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); test_ctx->domain->mpg = false; ret = sysdb_update_view_name(test_ctx->domain->sysdb, TEST_VIEW_NAME); assert_int_equal(ret, EOK); ret = sysdb_store_user(test_ctx->domain, TEST_USER_NAME, NULL, TEST_USER_UID, TEST_USER_GID, TEST_USER_GECOS, TEST_USER_HOMEDIR, TEST_USER_SHELL, NULL, NULL, NULL, 10,0); assert_int_equal(ret, EOK); ret = sysdb_search_user_by_name(test_ctx, test_ctx->domain, TEST_USER_NAME, NULL, &msg); assert_int_equal(ret, EOK); assert_non_null(msg); attrs = sysdb_new_attrs(test_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_string(attrs, SYSDB_OVERRIDE_ANCHOR_UUID, TEST_ANCHOR_PREFIX TEST_USER_SID); assert_int_equal(ret, EOK); ret = sysdb_store_override(test_ctx->domain, TEST_VIEW_NAME, SYSDB_MEMBER_USER, attrs, msg->dn); assert_int_equal(ret, EOK); views_dn = ldb_dn_new(test_ctx, test_ctx->domain->sysdb->ldb, SYSDB_TMPL_VIEW_BASE); assert_non_null(views_dn); ret = sysdb_delete_view_tree(test_ctx->domain->sysdb, TEST_VIEW_NAME); assert_int_equal(ret, EOK); ret = sysdb_search_user_by_name(test_ctx, test_ctx->domain, TEST_USER_NAME, user_attrs, &msg); assert_int_equal(ret, EOK); assert_non_null(msg); assert_true(ldb_msg_find_attr_as_uint64(msg, SYSDB_CACHE_EXPIRE, 0) > 1); assert_non_null(ldb_msg_find_attr_as_string(msg, SYSDB_OVERRIDE_DN, NULL)); ret = sysdb_invalidate_overrides(test_ctx->domain->sysdb); assert_int_equal(ret, EOK); ret = sysdb_search_user_by_name(test_ctx, test_ctx->domain, TEST_USER_NAME, user_attrs, &msg); assert_int_equal(ret, EOK); assert_non_null(msg); assert_int_equal(ldb_msg_find_attr_as_uint64(msg, SYSDB_CACHE_EXPIRE, 0), 1); assert_null(ldb_msg_find_attr_as_string(msg, SYSDB_OVERRIDE_DN, NULL)); ret = sysdb_delete_user(test_ctx->domain, TEST_USER_NAME, 0); assert_int_equal(ret, EOK); } static const char *users[] = { "alice", "bob", "barney", NULL }; static void enum_test_user_override(struct sysdb_test_ctx *test_ctx, const char *name) { int ret; struct sysdb_attrs *attrs; struct ldb_dn *dn; TALLOC_CTX *tmp_ctx; const char *anchor; const char *override_gecos; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); attrs = sysdb_new_attrs(tmp_ctx); assert_non_null(attrs); dn = sysdb_user_dn(tmp_ctx, test_ctx->domain, name); assert_non_null(dn); anchor = talloc_asprintf(tmp_ctx, "%s%s", TEST_ANCHOR_PREFIX, name); ret = sysdb_attrs_add_string(attrs, SYSDB_OVERRIDE_ANCHOR_UUID, anchor); assert_int_equal(ret, EOK); override_gecos = talloc_asprintf(attrs, "%s_GECOS_OVERRIDE", name); ret = sysdb_attrs_add_string(attrs, SYSDB_GECOS, override_gecos); assert_int_equal(ret, EOK); ret = sysdb_store_override(test_ctx->domain, TEST_VIEW_NAME, SYSDB_MEMBER_USER, attrs, dn); assert_int_equal(ret, EOK); talloc_free(tmp_ctx); } static void enum_test_add_users(struct sysdb_test_ctx *test_ctx, const char *usernames[]) { int i; int ret; struct sysdb_attrs *attrs; for (i = 0; usernames[i] != NULL; i++) { attrs = talloc(test_ctx, struct sysdb_attrs); assert_non_null(attrs); ret = sysdb_store_user(test_ctx->domain, usernames[i], NULL, 0, 0, usernames[i], "/", "/bin/sh", NULL, NULL, NULL, 1, 1234 + i); assert_int_equal(ret, EOK); enum_test_user_override(test_ctx, usernames[i]); talloc_free(attrs); } } static void enum_test_del_users(struct sss_domain_info *dom, const char *usernames[]) { int i; int ret; for (i = 0; usernames[i] != NULL; i++) { ret = sysdb_delete_user(dom, usernames[i], 0); if (ret != EOK && ret != ENOENT) { fail(); } } } static int test_enum_users_setup(void **state) { int ret; struct sysdb_test_ctx *test_ctx; assert_true(leak_check_setup()); ret = setup_sysdb_enum_tests(&test_ctx); assert_int_equal(ret, EOK); enum_test_add_users(test_ctx, users); *state = (void *) test_ctx; return 0; } static void assert_user_attrs(struct ldb_message *msg, const char *name, bool has_views) { const char *str; str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); assert_string_equal(str, name); str = ldb_msg_find_attr_as_string(msg, SYSDB_GECOS, NULL); assert_string_equal(str, name); str = ldb_msg_find_attr_as_string(msg, OVERRIDE_PREFIX SYSDB_GECOS, NULL); if (has_views) { char *override; assert_non_null(str); override = talloc_asprintf(msg, "%s_GECOS_OVERRIDE", name); assert_non_null(override); assert_string_equal(str, override); talloc_free(override); } else { assert_null(str); } } static int test_enum_users_teardown(void **state) { struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); enum_test_del_users(test_ctx->domain, users); return test_sysdb_teardown(state); } static void check_enumpwent(int ret, struct ldb_result *res, bool views) { assert_int_equal(ret, EOK); assert_int_equal(res->count, N_ELEMENTS(users)-1); assert_user_attrs(res->msgs[0], "barney", views); assert_user_attrs(res->msgs[1], "alice", views); assert_user_attrs(res->msgs[2], "bob", views); } static void test_sysdb_enumpwent(void **state) { int ret; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); struct ldb_result *res; ret = sysdb_enumpwent(test_ctx, test_ctx->domain, &res); check_enumpwent(ret, res, false); } static void test_sysdb_enumpwent_views(void **state) { int ret; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); struct ldb_result *res; ret = sysdb_enumpwent_with_views(test_ctx, test_ctx->domain, &res); check_enumpwent(ret, res, true); } static void test_sysdb_enumpwent_filter(void **state) { int ret; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); struct ldb_result *res; char *addtl_filter; ret = sysdb_enumpwent_filter(test_ctx, test_ctx->domain, "a*", 0, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); assert_user_attrs(res->msgs[0], "alice", false); ret = sysdb_enumpwent_filter(test_ctx, test_ctx->domain, "b*", 0, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 2); assert_user_attrs(res->msgs[0], "barney", false); assert_user_attrs(res->msgs[1], "bob", false); ret = sysdb_enumpwent_filter(test_ctx, test_ctx->domain, "c*", 0, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); ret = sysdb_enumpwent_filter(test_ctx, test_ctx->domain, "*", 0, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, N_ELEMENTS(users)-1); /* Test searching based on time as well */ addtl_filter = talloc_asprintf(test_ctx, "(%s<=%d)", SYSDB_LAST_UPDATE, 1233); ret = sysdb_enumpwent_filter(test_ctx, test_ctx->domain, "a*", addtl_filter, &res); talloc_free(addtl_filter); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); addtl_filter = talloc_asprintf(test_ctx, "(%s<=%d)", SYSDB_LAST_UPDATE, 1234); ret = sysdb_enumpwent_filter(test_ctx, test_ctx->domain, "a*", addtl_filter, &res); talloc_free(addtl_filter); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); assert_user_attrs(res->msgs[0], "alice", false); } static void test_sysdb_enumpwent_filter_views(void **state) { int ret; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); struct ldb_result *res; char *addtl_filter; ret = sysdb_enumpwent_filter_with_views(test_ctx, test_ctx->domain, "a*", NULL, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); assert_user_attrs(res->msgs[0], "alice", true); ret = sysdb_enumpwent_filter_with_views(test_ctx, test_ctx->domain, "b*", NULL, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 2); assert_user_attrs(res->msgs[0], "barney", true); assert_user_attrs(res->msgs[1], "bob", true); addtl_filter = talloc_asprintf(test_ctx, "(%s<=%d)", SYSDB_LAST_UPDATE, 1235); ret = sysdb_enumpwent_filter_with_views(test_ctx, test_ctx->domain, "b*", addtl_filter, &res); talloc_free(addtl_filter); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); assert_user_attrs(res->msgs[0], "bob", true); ret = sysdb_enumpwent_filter_with_views(test_ctx, test_ctx->domain, "c*", NULL, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); ret = sysdb_enumpwent_filter_with_views(test_ctx, test_ctx->domain, "*", NULL, &res); check_enumpwent(ret, res, true); } static const char *groups[] = { "one", "two", "three", NULL }; static void enum_test_group_override(struct sysdb_test_ctx *test_ctx, const char *name, unsigned override_gid) { int ret; struct sysdb_attrs *attrs; struct ldb_dn *dn; TALLOC_CTX *tmp_ctx; const char *anchor; tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); attrs = sysdb_new_attrs(tmp_ctx); assert_non_null(attrs); dn = sysdb_group_dn(tmp_ctx, test_ctx->domain, name); assert_non_null(dn); anchor = talloc_asprintf(tmp_ctx, "%s%s", TEST_ANCHOR_PREFIX, name); ret = sysdb_attrs_add_string(attrs, SYSDB_OVERRIDE_ANCHOR_UUID, anchor); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, override_gid); assert_int_equal(ret, EOK); ret = sysdb_store_override(test_ctx->domain, TEST_VIEW_NAME, SYSDB_MEMBER_GROUP, attrs, dn); assert_int_equal(ret, EOK); talloc_free(tmp_ctx); } static void enum_test_add_groups(struct sysdb_test_ctx *test_ctx, const char *groupnames[]) { int i; int ret; struct sysdb_attrs *attrs; for (i = 0; groupnames[i] != NULL; i++) { attrs = talloc(test_ctx, struct sysdb_attrs); assert_non_null(attrs); ret = sysdb_store_group(test_ctx->domain, groupnames[i], 0, NULL, 1, 1234 + i); assert_int_equal(ret, EOK); enum_test_group_override(test_ctx, groupnames[i], TEST_GID_OVERRIDE_BASE + i); talloc_free(attrs); } } static void enum_test_del_groups(struct sss_domain_info *dom, const char *groupnames[]) { int i; int ret; for (i = 0; groupnames[i] != NULL; i++) { ret = sysdb_delete_group(dom, groupnames[i], 0); if (ret != EOK && ret != ENOENT) { fail(); } } } static int test_enum_groups_setup(void **state) { int ret; struct sysdb_test_ctx *test_ctx; assert_true(leak_check_setup()); ret = setup_sysdb_enum_tests(&test_ctx); assert_int_equal(ret, EOK); enum_test_add_groups(test_ctx, groups); *state = (void *) test_ctx; return 0; } static int test_enum_groups_teardown(void **state) { struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); enum_test_del_groups(test_ctx->domain, groups); return test_sysdb_teardown(state); } static void assert_group_attrs(struct ldb_message *msg, const char *name, unsigned expected_override_gid) { const char *str; unsigned gid; str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); assert_string_equal(str, name); if (expected_override_gid) { gid = ldb_msg_find_attr_as_uint64(msg, OVERRIDE_PREFIX SYSDB_GIDNUM, 0); assert_int_equal(gid, expected_override_gid); } } static void check_enumgrent(int ret, struct ldb_result *res, bool views) { assert_int_equal(ret, EOK); assert_int_equal(res->count, N_ELEMENTS(groups)-1); assert_group_attrs(res->msgs[0], "three", views ? TEST_GID_OVERRIDE_BASE + 2 : 0); assert_group_attrs(res->msgs[1], "one", views ? TEST_GID_OVERRIDE_BASE : 0); assert_group_attrs(res->msgs[2], "two", views ? TEST_GID_OVERRIDE_BASE + 1 : 0); } static void test_sysdb_enumgrent(void **state) { int ret; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); struct ldb_result *res; ret = sysdb_enumgrent(test_ctx, test_ctx->domain, &res); check_enumgrent(ret, res, false); } static void test_sysdb_enumgrent_views(void **state) { int ret; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); struct ldb_result *res; ret = sysdb_enumgrent_with_views(test_ctx, test_ctx->domain, &res); check_enumgrent(ret, res, true); } static void test_sysdb_enumgrent_filter(void **state) { int ret; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); struct ldb_result *res; char *addtl_filter; ret = sysdb_enumgrent_filter(test_ctx, test_ctx->domain, "o*", 0, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); assert_group_attrs(res->msgs[0], "one", 0); ret = sysdb_enumgrent_filter(test_ctx, test_ctx->domain, "t*", 0, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 2); assert_group_attrs(res->msgs[0], "three", 0); assert_group_attrs(res->msgs[1], "two", 0); ret = sysdb_enumgrent_filter(test_ctx, test_ctx->domain, "x*", 0, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); ret = sysdb_enumgrent_filter(test_ctx, test_ctx->domain, "*", 0, &res); check_enumgrent(ret, res, false); addtl_filter = talloc_asprintf(test_ctx, "(%s<=%d)", SYSDB_LAST_UPDATE, 1233); ret = sysdb_enumgrent_filter(test_ctx, test_ctx->domain, "o*", addtl_filter, &res); talloc_free(addtl_filter); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); addtl_filter = talloc_asprintf(test_ctx, "(%s<=%d)", SYSDB_LAST_UPDATE, 1234); ret = sysdb_enumgrent_filter(test_ctx, test_ctx->domain, "o*", addtl_filter, &res); talloc_free(addtl_filter); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); assert_group_attrs(res->msgs[0], "one", 0); } static void test_sysdb_enumgrent_filter_views(void **state) { int ret; struct sysdb_test_ctx *test_ctx = talloc_get_type_abort(*state, struct sysdb_test_ctx); struct ldb_result *res; char *addtl_filter; ret = sysdb_enumgrent_filter_with_views(test_ctx, test_ctx->domain, "o*", NULL, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); assert_group_attrs(res->msgs[0], "one", TEST_GID_OVERRIDE_BASE); ret = sysdb_enumgrent_filter_with_views(test_ctx, test_ctx->domain, "t*", NULL, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 2); assert_group_attrs(res->msgs[0], "three", TEST_GID_OVERRIDE_BASE + 2); assert_group_attrs(res->msgs[1], "two", TEST_GID_OVERRIDE_BASE + 1); addtl_filter = talloc_asprintf(test_ctx, "(%s<=%d)", SYSDB_LAST_UPDATE, 1235); ret = sysdb_enumgrent_filter_with_views(test_ctx, test_ctx->domain, "t*", addtl_filter, &res); talloc_free(addtl_filter); assert_int_equal(ret, EOK); assert_int_equal(res->count, 1); assert_group_attrs(res->msgs[0], "two", TEST_GID_OVERRIDE_BASE + 1); ret = sysdb_enumgrent_filter_with_views(test_ctx, test_ctx->domain, "x*", NULL, &res); assert_int_equal(ret, EOK); assert_int_equal(res->count, 0); ret = sysdb_enumgrent_filter_with_views(test_ctx, test_ctx->domain, "*", NULL, &res); check_enumgrent(ret, res, true); } int main(int argc, const char *argv[]) { int rv; int no_cleanup = 0; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_sysdb_store_override, test_sysdb_setup, test_sysdb_teardown), cmocka_unit_test_setup_teardown(test_sysdb_add_overrides_to_object, test_sysdb_setup, test_sysdb_teardown), cmocka_unit_test_setup_teardown(test_sysdb_add_overrides_to_object_local, test_sysdb_setup, test_sysdb_teardown), cmocka_unit_test_setup_teardown(test_sysdb_add_overrides_to_object_missing_overridedn, test_sysdb_setup, test_sysdb_teardown), cmocka_unit_test_setup_teardown(test_split_ipa_anchor, test_sysdb_setup, test_sysdb_teardown), cmocka_unit_test_setup_teardown(test_sysdb_delete_view_tree, test_sysdb_setup, test_sysdb_teardown), cmocka_unit_test_setup_teardown(test_sysdb_invalidate_overrides, test_sysdb_setup, test_sysdb_teardown), cmocka_unit_test_setup_teardown(test_sysdb_enumpwent, test_enum_users_setup, test_enum_users_teardown), cmocka_unit_test_setup_teardown(test_sysdb_enumpwent_views, test_enum_users_setup, test_enum_users_teardown), cmocka_unit_test_setup_teardown(test_sysdb_enumpwent_filter, test_enum_users_setup, test_enum_users_teardown), cmocka_unit_test_setup_teardown(test_sysdb_enumpwent_filter_views, test_enum_users_setup, test_enum_users_teardown), cmocka_unit_test_setup_teardown(test_sysdb_enumgrent, test_enum_groups_setup, test_enum_groups_teardown), cmocka_unit_test_setup_teardown(test_sysdb_enumgrent_views, test_enum_groups_setup, test_enum_groups_teardown), cmocka_unit_test_setup_teardown(test_sysdb_enumgrent_filter, test_enum_groups_setup, test_enum_groups_teardown), cmocka_unit_test_setup_teardown(test_sysdb_enumgrent_filter_views, test_enum_groups_setup, test_enum_groups_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_FILE, LOCAL_SYSDB_FILE); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0 && no_cleanup == 0) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_FILE, LOCAL_SYSDB_FILE); } return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/p11_nssdb0000644000000000000000000000013212703463556017236 xustar0030 mtime=1460561774.369792662 30 atime=1460561776.119798596 30 ctime=1460561774.369792662 sssd-1.13.4/src/tests/cmocka/p11_nssdb/0000755002412700241270000000000012703463556020767 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/tests/cmocka/p11_nssdb/PaxHeaders.16287/cert9.db0000644000000000000000000000007412703456111020642 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.368792659 sssd-1.13.4/src/tests/cmocka/p11_nssdb/cert9.db0000644002412700241270000003200012703456111022304 0ustar00jhrozekjhrozek00000000000000SQLite format 3@  -   3%Ϥ%ϣ %Ϣ 35tablenssPublicnssPublicCREATE TABLE nssPublic (id PRIMARY KEY UNIQUE ON CONFLICT ABORT, a0, a1, a2, a3, a10, a11, a12, a80, a81, a82, a83, a84, a85, a86, a87, a88, a89, a8a, a8b, a90, a100, a101, a102, a103, a104, a105, a106, a107, a108, a109, a10a, a10b, a10c, a110, a111, a120, a121, a122, a123, a124, a125, a126, a127, a128, a130, a131, a132, a133, a134, a160, a161, a162, a163, a164, a165, a166, a170, a180, a181, a200, a201, a202, a210, a40000211, a40000212, a300, a301, a302, a400, a401, a402, a403, a404, a405, a406, a480, a481, a482, a500, a501, a502, a503, ace534351, ace534352, ace534353, ace534354, ace534355, ace534356, ace534357, ace534358, ace534364, ace534365, ace534366, ace534367, ace534368, ace536351, ace536352, ace536353, ace536354, ace536355, ace536356, ace536357, ace536358, ace536359, ace53635a, ace53635b, ace53635c, ace53635d, ace53635e, ace53635f, ace536360, ace5363b4, ace5363b5, ad5a0db00, a80000001, ace534369)7 KK:x0410U IPA.DEVEL10U Certificate Authority:x0410U IPA.DEVEL10U Certificate Authority:x0410U IPA.DEVEL10U Certificate Authority D@YindexckaidnssPublic CREATE INDEX ckaid ON nssPublic (a102)>UindexlabelnssPublicCREATE INDEX label ON nssPublic (a3)D]indexsubjectnssPublicCREATE INDEX subject ON nssPublic (a101)AYindexissuernssPublicCREATE INDEX issuer ON nssPublic (a81)1Eindexsqlite_autoindex_nssPublic_1nssPublic :x0410U IPA.DEVEL10U Certificate Authority8t0210U IPA.DEVEL10U ipa-devel.ipa.devel Z Z,IPA.DEVEL IPA CA"Server-Cert Z Z4h"#7!=4 h"#7!=pa-devel.ipa.devel0"0  *H 0 ԫѥ.@WS\d,m#h0zU /!l]fBpBm,QIvOQ j1ې$4x.T.=y!7#$l̚(&EwؾX4Acs`TX:!ݢN:-Z_1F Dmw&ͦBcf6k 1DQUN?#pۢvw< @m:D潏&0"0U#0'6Mxd0;+/0-0++0http://ipa-ca.ipa.devel/ca/ocsp0U0U%0++0tUm0k0i1/-http://ipa-ca.ipa.devel/ipa/crl/MasterCRL.bin420010 U ipaca10U Certificate Authority0Uwkfxgx10  *H  16=4%,zLŠ*^/\$7OѤ-Vf<q5ّi5߄d% Cwgh'q3m)\>,kűisًOeDt+g7_Ư9r̥9tG}R} !KE" kf΋i,ՔVBh^_WdbVrd>p37=bjF쒾xےdz$0410U IPA.DEVEL10U Certificate Authority0210U IPA.DEVEL10U ipa-devel.ipa.develh"#7!=0  *H  0410U IPA.DEVEL10U Certificate Authority0 150623163113Z 350623163113Z0410U IPA.DEVEL10U Certificate Authority0"0  *H 0 v.꩝ ,bgYU赽Py it)~8ze/ά4'}BXR04’!PqjfF?Mt?ÁyYL:y׷3TW$ö`3`;$>pRy(S9K>FdeS*{E᱾߼>Yi)N ޿d0\H{iO_$݂JP<8Fۃ ftxl`*|_e00U#0'6Mxd0U00U0U'6Mxd0A+50301+0%http://ipa-devel.ipa.devel:80/ca/ocsp0  *H  4 @c"C-p/QC)Xk((pî$U<”ۍl Nrk)$hB'}Wo;W* r1wt=.L̚wSkz^Uh.Ԥ:v!7dмͥuz|:%iu\^w҂pǵH 8˖ҁ) A0410U IPA.DEVEL10U Certificate Authority0410U IPA.DEVEL10U Certificate AuthorityZ N$w,*xx%ϤIPA.DEVEL IPA CA00s w"&xt4%ϣServer-Cert0 00  *H  0410U IPA.DEVEL10U Certificate Authority0 150623163207Z 170623163207Z0210U IPA.DEVEL10U i /w4 %ϢZZh"#7!=ZZԫѥ.@WS\d,m#h0zU /!l]fBpBm,QIvOQ j1ې$4x.T.=y!7#$l̚(&EwؾX4Acs`TX:!ݢN:-Z_1F Dmw&ͦBcf6k 1DQUN?#pۢvw< @m:D潏   rvx4,3SCSZ0410U IPA.DEVEL10U Certificate AuthoritySC[SCRSC[SC[<4Y)O;Ola}l̡H4Q8sssd-1.13.4/src/tests/cmocka/p11_nssdb/PaxHeaders.16287/key4.db0000644000000000000000000000007412703456111020470 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.369792662 sssd-1.13.4/src/tests/cmocka/p11_nssdb/key4.db0000644002412700241270000003400012703456111022134 0ustar00jhrozekjhrozek00000000000000SQLite format 3@ - 00E~"t4 ||||| %ϡServer-Cert0210U IPA.DEVEL10U ipa-devel.ipa.develh"#7!=ZZԫѥ.@WS\d,m#h0zU /!l]fBpBm,QIvOQ j1ې$4x.T.=y!7#$l̚(&EwؾX4Acs`TX:!ݢN:-Z_1F Dmw&ͦBcf6k 1DQUN?#pۢvw< @m:D潏060( *H  0%ܐꌈ[SQs| !k+%MWO*/[Q囡ɭ.fl+tablemetaDatametaData CREATE TABLE metaData (id PRIMARY KEY UNIQUE ON CONFLICT REPLACE, item1, item2)/Cindexsqlite_autoindex_metaData_1metaData B![indexckaidnssPrivate CREATE INDEX ckaid ON nssPrivate (a102)@!WindexlabelnssPrivateCREATE INDEX label ON nssPrivate (a3)F!_indexsubjectnssPrivateCREATE INDEX subject ON nssPrivate (a101)C![indexissuernssPrivateCREATE INDEX issuer ON nssPrivate (a81)3G!indexsqlite_autoindex_nssPrivate_1nssPrivate 7t 0210U IPA.DEVEL10U ipa-devel.ipa.devel " Server-Cert 4 h"#7!=  z<[Asig_cert_338ad5f7_ce536359 Asig_cert_338ad5f7_ce536358 Asig_cert_338ad5f7_ce5363b5 Asig_cert_338ad5f7_ce53635b Asig_cert_338ad5f7_ce5363b4Asig_cert_338ad5f7_ce53635aAsig_cert_338ad5f7_ce536360Asig_cert_25d1cfa2_00000122Asig_cert_25d1cfa2_00000120?sig_key_25d1cfa1_00000122?sig_key_25d1cfa1_00000120  password hW h"Asig_cert_338ad5f7_ce53636000\ *H 0O0A *H  04 "HQ"/K$BJPZcU 0 *H  0 *H   |qb!֔Ve<g?"Asig_cert_25d1cfa2_0000012200\ *H 0O0A *H  04 nܫ橙ٲ"u#[ 0 *H  0 *H   munw@Znwr%C[+)"Asig_cert_25d1cfa2_0000012000\ *H 0O0A *H  04 ]]ﲞ%r%k/-E3up 0 *H  0 *H   dvhgwm|UN!?sig_key_25d1cfa1_0000012200\ *H 0O0A *H  04 f" djPM[7h 0 *H  0 *H   4%m7-JmMXZϊNlptP !?sig_key_25d1cfa1_0000012000\ *H 0O0A *H  04 24zn=T&:(՚J,atF[j!~=rzwB:4"SiHE0lP=00( *H  0ZĤ9Ӓ҆䛭JW5LRȇ7 ~`3G&%uܒ2Kmz4c]I5VPX  0 *H  0 *H   yCEN| XqXV:~L" Asig_cert_338ad5f7_ce53635800\ *H 0O0A *H  04 #2aRr)lK!3@].o˼ɩxe 0 *H  0 *H   \RXn.*r;Ypzi" Asig_cert_338ad5f7_ce5363b500\ *H 0O0A *H  04 b;hޏ68'|/`M0o 0 *H  0 *H   L44{H_Ŀ[ ɼ" Asig_cert_338ad5f7_ce53635b00\ *H 0O0A *H  04 VBb06:n=s֒Ċ 0 *H  0 *H   0@LpNG, lfiH""Asig_cert_338ad5f7_ce5363b400\ *H 0O0A *H  04 (QM3AqWg)2quy 0 *H  0 *H   bSy~1Gx*IN2Ygh"Asig_cert_338ad5f7_ce53635a00\ *H 0O0A *H  04 y2ǻ$F.>5d9| Copyright (C) 2013 Red Hat SSSD tests: Common utilities for tests that exercise domains This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __COMMON_MOCK_H_ #define __COMMON_MOCK_H_ /* * from cmocka.c: * These headers or their equivalents should be included prior to * including * this header file. * * #include * #include * #include * * This allows test applications to use custom definitions of C standard * library functions and types. */ #include #include #include #include #include "tests/common.h" #define sss_mock_type(type) ((type) mock()) #define sss_mock_ptr_type(type) ((type) (uintptr_t) mock()) #define sss_will_return_always(fn, value) will_return_count(fn, (value), -1) enum sss_test_wrapper_call { WRAP_CALL_WRAPPER, WRAP_CALL_REAL }; #endif /* __COMMON_MOCK_H_ */ sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_sss_sifp.c0000644000000000000000000000007412703456111020547 xustar0030 atime=1460561751.656715648 30 ctime=1460561774.984794748 sssd-1.13.4/src/tests/cmocka/test_sss_sifp.c0000644002412700241270000022336612703456111022232 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "tests/cmocka/common_mock.h" #include "lib/sifp/sss_sifp.h" #include "lib/sifp/sss_sifp_dbus.h" #include "lib/sifp/sss_sifp_private.h" struct { sss_sifp_ctx *dbus_ctx; DBusMessage *reply; } test_ctx; DBusConnection * __wrap_dbus_bus_get(DBusBusType type, DBusError *error) { /* we won't use the connection anywhere, so we can just return NULL */ return NULL; } DBusMessage * __wrap_dbus_connection_send_with_reply_and_block(DBusConnection *connection, DBusMessage *message, int timeout_milliseconds, DBusError *error) { if (message == NULL || error == NULL) { return NULL; } return sss_mock_ptr_type(DBusMessage *); } static void reply_variant_basic(DBusMessage *reply, const char *type, const void *val) { DBusMessageIter iter; DBusMessageIter variant_iter; dbus_bool_t bret; dbus_message_iter_init_append(reply, &iter); bret = dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, type, &variant_iter); assert_true(bret); /* Now add the value */ bret = dbus_message_iter_append_basic(&variant_iter, type[0], val); assert_true(bret); bret = dbus_message_iter_close_container(&iter, &variant_iter); assert_true(bret); } static void reply_variant_array(DBusMessage *reply, const char *type, int num_vals, uint8_t *vals, unsigned int item_size) { DBusMessageIter iter; DBusMessageIter variant_iter; DBusMessageIter array_iter; dbus_bool_t bret; char array_type[3]; int i; void *addr; array_type[0] = DBUS_TYPE_ARRAY; array_type[1] = type[0]; array_type[2] = '\0'; dbus_message_iter_init_append(reply, &iter); bret = dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, array_type, &variant_iter); assert_true(bret); bret = dbus_message_iter_open_container(&variant_iter, DBUS_TYPE_ARRAY, type, &array_iter); assert_true(bret); for (i = 0; i < num_vals; i++) { addr = vals + i*item_size; bret = dbus_message_iter_append_basic(&array_iter, type[0], addr); assert_true(bret); } bret = dbus_message_iter_close_container(&iter, &array_iter); assert_true(bret); bret = dbus_message_iter_close_container(&iter, &variant_iter); assert_true(bret); } static int test_setup(void **state) { sss_sifp_error ret; ret = sss_sifp_init(&test_ctx.dbus_ctx); assert_int_equal(ret, SSS_SIFP_OK); test_ctx.reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); assert_non_null(test_ctx.reply); return 0; } static int test_teardown_parser(void **state) { sss_sifp_free(&test_ctx.dbus_ctx); assert_null(test_ctx.dbus_ctx); dbus_message_unref(test_ctx.reply); test_ctx.reply = NULL; return 0; } static int test_teardown_api(void **state) { sss_sifp_free(&test_ctx.dbus_ctx); assert_null(test_ctx.dbus_ctx); /* sss_sifp is responsible for freeing the reply */ return 0; } void test_sss_sifp_strdup_valid(void **state) { const char *str = "test_string"; char *dup_str = sss_sifp_strdup(test_ctx.dbus_ctx, str); assert_non_null(dup_str); assert_string_equal(str, dup_str); sss_sifp_free_string(test_ctx.dbus_ctx, &dup_str); assert_null(dup_str); } void test_sss_sifp_strdup_null(void **state) { char *dup_str = sss_sifp_strdup(test_ctx.dbus_ctx, NULL); assert_null(dup_str); } void test_sss_sifp_strcat_valid(void **state) { char *cat = sss_sifp_strcat(test_ctx.dbus_ctx, "hello ", "world"); assert_non_null(cat); assert_string_equal("hello world", cat); sss_sifp_free_string(test_ctx.dbus_ctx, &cat); assert_null(cat); } void test_sss_sifp_strcat_left_null(void **state) { char *cat = sss_sifp_strcat(test_ctx.dbus_ctx, NULL, "world"); assert_non_null(cat); assert_string_equal("world", cat); sss_sifp_free_string(test_ctx.dbus_ctx, &cat); assert_null(cat); } void test_sss_sifp_strcat_right_null(void **state) { char *cat = sss_sifp_strcat(test_ctx.dbus_ctx, "hello ", NULL); assert_non_null(cat); assert_string_equal("hello ", cat); sss_sifp_free_string(test_ctx.dbus_ctx, &cat); assert_null(cat); } void test_sss_sifp_strcat_both_null(void **state) { char *cat = sss_sifp_strcat(test_ctx.dbus_ctx, NULL, NULL); assert_null(cat); } void test_sss_sifp_parse_object_path_valid(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; dbus_bool_t bret; sss_sifp_error ret; const char *path_in = "/object/path"; char *path_out = NULL; /* prepare message */ bret = dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path_in, DBUS_TYPE_INVALID); assert_true(bret); /* test */ ret = sss_sifp_parse_object_path(ctx, reply, &path_out); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(path_out); assert_string_equal(path_in, path_out); sss_sifp_free_string(ctx, &path_out); assert_null(path_out); } void test_sss_sifp_parse_object_path_invalid(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; dbus_bool_t bret; sss_sifp_error ret; uint16_t path_in = 10; char *path_out = NULL; /* prepare message */ bret = dbus_message_append_args(reply, DBUS_TYPE_UINT16, &path_in, DBUS_TYPE_INVALID); assert_true(bret); /* test */ ret = sss_sifp_parse_object_path(ctx, reply, &path_out); assert_int_not_equal(ret, SSS_SIFP_OK); assert_null(path_out); } void test_sss_sifp_parse_object_path_list_valid(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; dbus_bool_t bret; sss_sifp_error ret; char **path_out = NULL; const char *path_in[] = {"/object/path1", "/object/path2"}; const char **paths = path_in; int path_in_len = 2; int i; /* prepare message */ bret = dbus_message_append_args(reply, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, path_in_len, DBUS_TYPE_INVALID); assert_true(bret); /* test */ ret = sss_sifp_parse_object_path_list(ctx, reply, &path_out); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(path_out); for (i = 0; path_out[i] != NULL; i++) { assert_true(i < path_in_len); assert_non_null(path_out[i]); assert_string_equal(path_in[i], path_out[i]); } sss_sifp_free_string_array(ctx, &path_out); assert_null(path_out); } void test_sss_sifp_parse_object_path_list_invalid(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; dbus_bool_t bret; sss_sifp_error ret; char **path_out = NULL; const char *path_in = "/object/path"; /* prepare message */ bret = dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path_in, DBUS_TYPE_INVALID); assert_true(bret); /* test */ ret = sss_sifp_parse_object_path_list(ctx, reply, &path_out); assert_int_not_equal(ret, SSS_SIFP_OK); assert_null(path_out); } void test_sss_sifp_parse_attr_bool(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; dbus_bool_t in = 1; bool out; /* prepare message */ reply_variant_basic(reply, DBUS_TYPE_BOOLEAN_AS_STRING, &in); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_BOOL); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_bool(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_true(in == out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_int16(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; int16_t in = INT16_MIN; int16_t out; /* prepare message */ reply_variant_basic(reply, DBUS_TYPE_INT16_AS_STRING, &in); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT16); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_int16(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(in, out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_uint16(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; uint16_t in = UINT16_MAX; uint16_t out; /* prepare message */ reply_variant_basic(reply, DBUS_TYPE_UINT16_AS_STRING, &in); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT16); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_uint16(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(in, out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_int32(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; int32_t in = INT32_MIN; int32_t out; /* prepare message */ reply_variant_basic(reply, DBUS_TYPE_INT32_AS_STRING, &in); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT32); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_int32(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(in, out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_uint32(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; uint32_t in = UINT32_MAX; uint32_t out; /* prepare message */ reply_variant_basic(reply, DBUS_TYPE_UINT32_AS_STRING, &in); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT32); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_uint32(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(in, out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_int64(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; int64_t in = INT64_MIN; int64_t out; /* prepare message */ reply_variant_basic(reply, DBUS_TYPE_INT64_AS_STRING, &in); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT64); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_int64(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(in, out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_uint64(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; uint64_t in = UINT64_MAX; uint64_t out; /* prepare message */ reply_variant_basic(reply, DBUS_TYPE_UINT64_AS_STRING, &in); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT64); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_uint64(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(in, out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_string(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; const char *in = "test value"; const char *out; /* prepare message */ reply_variant_basic(reply, DBUS_TYPE_STRING_AS_STRING, &in); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_STRING); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_string(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_string_equal(in, out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_object_path(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; const char *in = "/object/path"; const char *out; /* prepare message */ reply_variant_basic(reply, DBUS_TYPE_OBJECT_PATH_AS_STRING, &in); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_STRING); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_string(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_string_equal(in, out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_string_dict(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; DBusMessageIter iter; DBusMessageIter var_iter; DBusMessageIter array_iter; DBusMessageIter dict_iter; dbus_bool_t bret; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; struct { const char *key; const char *value; } data = {"key", "value"}; hash_table_t *out; hash_key_t key; hash_value_t value; char **values; int hret; /* prepare message */ dbus_message_iter_init_append(reply, &iter); bret = dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &var_iter); assert_true(bret); bret = dbus_message_iter_open_container(&var_iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array_iter); assert_true(bret); bret = dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter); assert_true(bret); bret = dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &data.key); assert_true(bret); bret = dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &data.value); assert_true(bret); bret = dbus_message_iter_close_container(&array_iter, &dict_iter); assert_true(bret); bret = dbus_message_iter_close_container(&var_iter, &array_iter); assert_true(bret); bret = dbus_message_iter_close_container(&iter, &var_iter); assert_true(bret); ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_STRING_DICT); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_string_dict(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(hash_count(out), 1); key.type = HASH_KEY_STRING; key.str = discard_const(data.key); hret = hash_lookup(out, &key, &value); assert_int_equal(hret, HASH_SUCCESS); assert_int_equal(value.type, HASH_VALUE_PTR); assert_non_null(value.ptr); values = value.ptr; assert_non_null(values[0]); assert_string_equal(values[0], data.value); assert_null(values[1]); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_bool_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 5; dbus_bool_t in_array[] = {1, 1, 0, 0, 1}; dbus_bool_t *in = in_array; unsigned int out_num; bool *out; unsigned int i; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_BOOLEAN_AS_STRING, num_values, (uint8_t*)in, sizeof(dbus_bool_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_BOOL); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_bool_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(num_values, out_num); for (i = 0; i < num_values; i++) { assert_true(in[i] == out[i]); } sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_bool_array_empty(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 0; unsigned int out_num; bool *out; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_BOOLEAN_AS_STRING, num_values, NULL, sizeof(dbus_bool_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_BOOL); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_bool_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_ATTR_NULL); assert_int_equal(num_values, out_num); assert_null(out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_int16_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 5; int16_t in_array[] = {10, 15, -10, -15, 5559}; int16_t *in = in_array; unsigned int out_num; int16_t *out; unsigned int i; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_INT16_AS_STRING, num_values, (uint8_t*)in, sizeof(int16_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT16); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_int16_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(num_values, out_num); for (i = 0; i < num_values; i++) { assert_int_equal(in[i], out[i]); } sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_int16_array_empty(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 0; unsigned int out_num; int16_t *out; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_INT16_AS_STRING, num_values, NULL, sizeof(int16_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT16); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_int16_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_ATTR_NULL); assert_int_equal(num_values, out_num); assert_null(out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_uint16_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 5; uint16_t in_array[] = {10, 15, 8885, 3224, 5559}; uint16_t *in = in_array; unsigned int out_num; uint16_t *out; unsigned int i; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_UINT16_AS_STRING, num_values, (uint8_t*)in, sizeof(uint16_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT16); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_uint16_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(num_values, out_num); for (i = 0; i < num_values; i++) { assert_int_equal(in[i], out[i]); } sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_uint16_array_empty(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 0; unsigned int out_num; uint16_t *out; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_UINT16_AS_STRING, num_values, NULL, sizeof(uint16_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT16); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_uint16_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_ATTR_NULL); assert_int_equal(num_values, out_num); assert_null(out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_int32_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 5; int32_t in_array[] = {10, 15, -10, -15, 5559}; int32_t *in = in_array; unsigned int out_num; int32_t *out; unsigned int i; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_INT32_AS_STRING, num_values, (uint8_t*)in, sizeof(int32_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT32); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_int32_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(num_values, out_num); for (i = 0; i < num_values; i++) { assert_int_equal(in[i], out[i]); } sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_int32_array_empty(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 0; unsigned int out_num; int32_t *out; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_INT32_AS_STRING, num_values, NULL, sizeof(int32_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT32); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_int32_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_ATTR_NULL); assert_int_equal(num_values, out_num); assert_null(out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_uint32_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 5; uint32_t in_array[] = {10, 15, 8885, 3224, 5559}; uint32_t *in = in_array; unsigned int out_num; uint32_t *out; unsigned int i; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_UINT32_AS_STRING, num_values, (uint8_t*)in, sizeof(uint32_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT32); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_uint32_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(num_values, out_num); for (i = 0; i < num_values; i++) { assert_int_equal(in[i], out[i]); } sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_uint32_array_empty(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 0; unsigned int out_num; uint32_t *out; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_UINT32_AS_STRING, num_values, NULL, sizeof(uint32_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT32); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_uint32_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_ATTR_NULL); assert_int_equal(num_values, out_num); assert_null(out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_int64_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 5; int64_t in_array[] = {10, 15, -10, -15, 5559}; int64_t *in = in_array; unsigned int out_num; int64_t *out; unsigned int i; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_INT64_AS_STRING, num_values, (uint8_t*)in, sizeof(int64_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT64); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_int64_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(num_values, out_num); for (i = 0; i < num_values; i++) { assert_int_equal(in[i], out[i]); } sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_int64_array_empty(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 0; unsigned int out_num; int64_t *out; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_INT64_AS_STRING, num_values, NULL, sizeof(int64_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_INT64); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_int64_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_ATTR_NULL); assert_int_equal(num_values, out_num); assert_null(out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_uint64_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 5; uint64_t in_array[] = {10, 15, 8885, 3224, 5559}; uint64_t *in = in_array; unsigned int out_num; uint64_t *out; unsigned int i; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_UINT64_AS_STRING, num_values, (uint8_t*)in, sizeof(uint64_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT64); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_uint64_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(num_values, out_num); for (i = 0; i < num_values; i++) { assert_int_equal(in[i], out[i]); } sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_uint64_array_empty(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 0; unsigned int out_num; uint64_t *out; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_UINT64_AS_STRING, num_values, NULL, sizeof(uint64_t)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT64); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_uint64_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_ATTR_NULL); assert_int_equal(num_values, out_num); assert_null(out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_string_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 6; const char *in_array[] = {"I", "don't", "like", "writing", "unit", "tests"}; const char **in = in_array; unsigned int out_num; const char * const *out; unsigned int i; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_STRING_AS_STRING, num_values, (uint8_t*)in, sizeof(const char*)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_STRING); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_string_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(num_values, out_num); for (i = 0; i < num_values; i++) { assert_string_equal(in[i], out[i]); } sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_string_array_empty(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 0; unsigned int out_num; const char * const *out; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_STRING_AS_STRING, num_values, NULL, sizeof(const char*)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_STRING); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_string_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_ATTR_NULL); assert_int_equal(num_values, out_num); assert_null(out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_object_path_array(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 2; const char *in_array[] = {"/object/path1", "/object/path2"}; const char **in = in_array; unsigned int out_num; const char * const *out; unsigned int i; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_OBJECT_PATH_AS_STRING, num_values, (uint8_t*)in, sizeof(const char*)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_STRING); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_string_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(num_values, out_num); for (i = 0; i < num_values; i++) { assert_string_equal(in[i], out[i]); } sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_object_path_array_empty(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; unsigned int num_values = 0; unsigned int out_num; const char * const *out; /* prepare message */ reply_variant_array(reply, DBUS_TYPE_OBJECT_PATH_AS_STRING, num_values, NULL, sizeof(const char*)); /* test */ ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, num_values); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_STRING); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_string_array(attrs, name, &out_num, &out); assert_int_equal(ret, SSS_SIFP_ATTR_NULL); assert_int_equal(num_values, out_num); assert_null(out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_string_dict_array(void **state) { return; sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; DBusMessageIter iter; DBusMessageIter var_iter; DBusMessageIter array_iter; DBusMessageIter dict_iter; DBusMessageIter val_iter; dbus_bool_t bret; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; static struct { const char *key; const char *values[]; } data = {"key", {"value1", "value2", "value3"}}; unsigned int num_values = 3; hash_table_t *out; hash_key_t key; hash_value_t value; char **values; unsigned int i; int hret; /* prepare message */ dbus_message_iter_init_append(reply, &iter); bret = dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &var_iter); assert_true(bret); bret = dbus_message_iter_open_container(&var_iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array_iter); assert_true(bret); bret = dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter); assert_true(bret); bret = dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &data.key); assert_true(bret); bret = dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &val_iter); assert_true(bret); for (i = 0; i < num_values; i++) { bret = dbus_message_iter_append_basic(&val_iter, DBUS_TYPE_STRING, &data.values[i]); assert_true(bret); } bret = dbus_message_iter_close_container(&dict_iter, &val_iter); assert_true(bret); bret = dbus_message_iter_close_container(&array_iter, &dict_iter); assert_true(bret); bret = dbus_message_iter_close_container(&var_iter, &array_iter); assert_true(bret); bret = dbus_message_iter_close_container(&iter, &var_iter); assert_true(bret); ret = sss_sifp_parse_attr(ctx, name, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_STRING_DICT); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_string_dict(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(hash_count(out), 1); key.type = HASH_KEY_STRING; key.str = discard_const(data.key); hret = hash_lookup(out, &key, &value); assert_int_equal(hret, HASH_SUCCESS); assert_int_equal(value.type, HASH_VALUE_PTR); assert_non_null(value.ptr); values = value.ptr; for (i = 0; i < num_values; i++) { assert_non_null(values[i]); assert_string_equal(values[i], data.values[i]); } assert_null(values[i]); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_list(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; DBusMessageIter iter; DBusMessageIter array_iter; DBusMessageIter dict_iter; DBusMessageIter var_iter; dbus_bool_t bret; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; struct { const char *name; uint32_t value; } data[] = {{"attr1", 1}, {"attr2", 2}, {"attr3", 3}, {NULL, 0}}; uint32_t out; int i; /* prepare message */ dbus_message_iter_init_append(reply, &iter); bret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array_iter); assert_true(bret); for (i = 0; data[i].name != NULL; i++) { bret = dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter); assert_true(bret); bret = dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &data[i].name); assert_true(bret); bret = dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, DBUS_TYPE_UINT32_AS_STRING, &var_iter); assert_true(bret); bret = dbus_message_iter_append_basic(&var_iter, DBUS_TYPE_UINT32, &data[i].value); assert_true(bret); bret = dbus_message_iter_close_container(&dict_iter, &var_iter); assert_true(bret); bret = dbus_message_iter_close_container(&array_iter, &dict_iter); assert_true(bret); } bret = dbus_message_iter_close_container(&iter, &array_iter); assert_true(bret); ret = sss_sifp_parse_attr_list(ctx, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); for (i = 0; data[i].name != NULL; i++) { assert_non_null(attrs[i]); assert_int_equal(attrs[i]->num_values, 1); assert_int_equal(attrs[i]->type, SSS_SIFP_ATTR_TYPE_UINT32); assert_string_equal(attrs[i]->name, data[i].name); ret = sss_sifp_find_attr_as_uint32(attrs, data[i].name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(data[i].value, out); } assert_null(attrs[i]); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_parse_attr_list_empty(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; DBusMessageIter iter; DBusMessageIter array_iter; dbus_bool_t bret; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; /* prepare message */ dbus_message_iter_init_append(reply, &iter); bret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array_iter); assert_true(bret); bret = dbus_message_iter_close_container(&iter, &array_iter); assert_true(bret); ret = sss_sifp_parse_attr_list(ctx, reply, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_null(attrs[0]); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_get_iface_for_object(void **state) { int i; const char *iface = NULL; static struct { const char *path; const char *iface; } data[] = {{SSS_SIFP_PATH_IFP "/Components/Monitor", SSS_SIFP_IFACE_COMPONENTS}, {SSS_SIFP_PATH_IFP "/Domains/LDAP", SSS_SIFP_IFACE_DOMAINS}, {SSS_SIFP_PATH_IFP "/Services/NSS", SSS_SIFP_IFACE_SERVICES}, {SSS_SIFP_PATH_IFP "/Users/2154", SSS_SIFP_IFACE_USERS}, {SSS_SIFP_PATH_IFP "/Groups/3441", SSS_SIFP_IFACE_GROUPS}, {NULL, NULL}}; for (i = 0; data[i].path != NULL; i++) { iface = sss_sifp_get_iface_for_object(data[i].path); assert_non_null(iface); assert_string_equal(data[i].iface, iface); } } void test_sss_sifp_fetch_attr(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; const char *name = "test-attr"; uint32_t in = UINT32_MAX; uint32_t out; /* prepare message */ reply_variant_basic(reply, DBUS_TYPE_UINT32_AS_STRING, &in); will_return(__wrap_dbus_connection_send_with_reply_and_block, reply); /* test */ ret = sss_sifp_fetch_attr(ctx, "/test/object", "test.com", name, &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); assert_non_null(attrs[0]); assert_null(attrs[1]); assert_int_equal(attrs[0]->num_values, 1); assert_int_equal(attrs[0]->type, SSS_SIFP_ATTR_TYPE_UINT32); assert_string_equal(attrs[0]->name, name); ret = sss_sifp_find_attr_as_uint32(attrs, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(in, out); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_fetch_all_attrs(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; DBusMessageIter iter; DBusMessageIter array_iter; DBusMessageIter dict_iter; DBusMessageIter var_iter; dbus_bool_t bret; sss_sifp_error ret; sss_sifp_attr **attrs = NULL; struct { const char *name; uint32_t value; } data[] = {{"attr1", 1}, {"attr2", 2}, {"attr3", 3}, {NULL, 0}}; uint32_t out; int i; /* prepare message */ dbus_message_iter_init_append(reply, &iter); bret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array_iter); assert_true(bret); for (i = 0; data[i].name != NULL; i++) { bret = dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter); assert_true(bret); bret = dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &data[i].name); assert_true(bret); bret = dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, DBUS_TYPE_UINT32_AS_STRING, &var_iter); assert_true(bret); bret = dbus_message_iter_append_basic(&var_iter, DBUS_TYPE_UINT32, &data[i].value); assert_true(bret); bret = dbus_message_iter_close_container(&dict_iter, &var_iter); assert_true(bret); bret = dbus_message_iter_close_container(&array_iter, &dict_iter); assert_true(bret); } bret = dbus_message_iter_close_container(&iter, &array_iter); assert_true(bret); will_return(__wrap_dbus_connection_send_with_reply_and_block, reply); ret = sss_sifp_fetch_all_attrs(ctx, "/test/object", "test.com", &attrs); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(attrs); for (i = 0; data[i].name != NULL; i++) { assert_non_null(attrs[i]); assert_int_equal(attrs[i]->num_values, 1); assert_int_equal(attrs[i]->type, SSS_SIFP_ATTR_TYPE_UINT32); assert_string_equal(attrs[i]->name, data[i].name); ret = sss_sifp_find_attr_as_uint32(attrs, data[i].name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_int_equal(data[i].value, out); } assert_null(attrs[i]); sss_sifp_free_attrs(ctx, &attrs); assert_null(attrs); } void test_sss_sifp_fetch_object(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; DBusMessageIter iter; DBusMessageIter array_iter; DBusMessageIter dict_iter; DBusMessageIter var_iter; const char *path = "/test/object"; const char *iface = "test.com"; dbus_bool_t bret; sss_sifp_error ret; sss_sifp_object *object = NULL; struct { const char *name; const char *value; } data[] = {{"name", "test-object"}, {"a1", "a"}, {"a2", "b"}, {NULL, 0}}; const char *out; int i; /* prepare message */ dbus_message_iter_init_append(reply, &iter); bret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array_iter); assert_true(bret); for (i = 0; data[i].name != NULL; i++) { bret = dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter); assert_true(bret); bret = dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &data[i].name); assert_true(bret); bret = dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &var_iter); assert_true(bret); bret = dbus_message_iter_append_basic(&var_iter, DBUS_TYPE_STRING, &data[i].value); assert_true(bret); bret = dbus_message_iter_close_container(&dict_iter, &var_iter); assert_true(bret); bret = dbus_message_iter_close_container(&array_iter, &dict_iter); assert_true(bret); } bret = dbus_message_iter_close_container(&iter, &array_iter); assert_true(bret); will_return(__wrap_dbus_connection_send_with_reply_and_block, reply); ret = sss_sifp_fetch_object(ctx, path, iface, &object); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(object); assert_non_null(object->attrs); assert_non_null(object->name); assert_non_null(object->object_path); assert_non_null(object->interface); assert_string_equal(object->name, "test-object"); assert_string_equal(object->object_path, path); assert_string_equal(object->interface, iface); for (i = 0; data[i].name != NULL; i++) { assert_non_null(object->attrs[i]); assert_int_equal(object->attrs[i]->num_values, 1); assert_int_equal(object->attrs[i]->type, SSS_SIFP_ATTR_TYPE_STRING); assert_string_equal(object->attrs[i]->name, data[i].name); ret = sss_sifp_find_attr_as_string(object->attrs, data[i].name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_string_equal(data[i].value, out); } assert_null(object->attrs[i]); sss_sifp_free_object(ctx, &object); assert_null(object); } void test_sss_sifp_invoke_list_zeroargs(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; dbus_bool_t bret; sss_sifp_error ret; char **path_out = NULL; const char *path_in[] = {"/object/path1", "/object/path2"}; const char **paths = path_in; int path_in_len = 2; int i; /* prepare message */ bret = dbus_message_append_args(reply, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, path_in_len, DBUS_TYPE_INVALID); assert_true(bret); will_return(__wrap_dbus_connection_send_with_reply_and_block, reply); /* test */ ret = sss_sifp_invoke_list(ctx, "MyMethod", &path_out, DBUS_TYPE_INVALID); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(path_out); for (i = 0; path_out[i] != NULL; i++) { assert_true(i < path_in_len); assert_non_null(path_out[i]); assert_string_equal(path_in[i], path_out[i]); } sss_sifp_free_string_array(ctx, &path_out); assert_null(path_out); } void test_sss_sifp_invoke_list_withargs(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; dbus_bool_t bret; sss_sifp_error ret; char **path_out = NULL; const char *path_in[] = {"/object/path1", "/object/path2"}; const char **paths = path_in; const char *arg = "first-arg"; int path_in_len = 2; int i; /* prepare message */ bret = dbus_message_append_args(reply, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, path_in_len, DBUS_TYPE_INVALID); assert_true(bret); will_return(__wrap_dbus_connection_send_with_reply_and_block, reply); /* test */ ret = sss_sifp_invoke_list(ctx, "MyMethod", &path_out, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(path_out); for (i = 0; path_out[i] != NULL; i++) { assert_true(i < path_in_len); assert_non_null(path_out[i]); assert_string_equal(path_in[i], path_out[i]); } sss_sifp_free_string_array(ctx, &path_out); assert_null(path_out); } void test_sss_sifp_invoke_find_zeroargs(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; dbus_bool_t bret; sss_sifp_error ret; const char *path_in = "/object/path"; char *path_out = NULL; /* prepare message */ bret = dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path_in, DBUS_TYPE_INVALID); assert_true(bret); will_return(__wrap_dbus_connection_send_with_reply_and_block, reply); /* test */ ret = sss_sifp_invoke_find(ctx, "MyMethod", &path_out, DBUS_TYPE_INVALID); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(path_out); assert_string_equal(path_in, path_out); sss_sifp_free_string(ctx, &path_out); assert_null(path_out); } void test_sss_sifp_invoke_find_withargs(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *reply = test_ctx.reply; dbus_bool_t bret; sss_sifp_error ret; const char *path_in = "/object/path"; char *path_out = NULL; const char *arg = "first-arg"; /* prepare message */ bret = dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path_in, DBUS_TYPE_INVALID); assert_true(bret); will_return(__wrap_dbus_connection_send_with_reply_and_block, reply); /* test */ ret = sss_sifp_invoke_find(ctx, "MyMethod", &path_out, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(path_out); assert_string_equal(path_in, path_out); sss_sifp_free_string(ctx, &path_out); assert_null(path_out); } void test_sss_sifp_list_domains(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *msg_paths = NULL; DBusMessage *msg_ldap = NULL; DBusMessage *msg_ipa = NULL; dbus_bool_t bret; sss_sifp_error ret; const char *in[] = {SSS_SIFP_PATH_IFP "/Domains/LDAP", SSS_SIFP_PATH_IFP "/Domains/IPA"}; const char **paths = in; const char *names[] = {"LDAP", "IPA"}; char **out = NULL; int in_len = 2; int i; msg_paths = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); assert_non_null(msg_paths); msg_ldap = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); assert_non_null(msg_ldap); msg_ipa = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); assert_non_null(msg_ipa); /* prepare message */ bret = dbus_message_append_args(msg_paths, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, in_len, DBUS_TYPE_INVALID); assert_true(bret); reply_variant_basic(msg_ldap, DBUS_TYPE_STRING_AS_STRING, &names[0]); reply_variant_basic(msg_ipa, DBUS_TYPE_STRING_AS_STRING, &names[1]); will_return(__wrap_dbus_connection_send_with_reply_and_block, msg_paths); will_return(__wrap_dbus_connection_send_with_reply_and_block, msg_ldap); will_return(__wrap_dbus_connection_send_with_reply_and_block, msg_ipa); /* test */ ret = sss_sifp_list_domains(ctx, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(out); for (i = 0; i < in_len; i++) { assert_non_null(out[i]); assert_string_equal(out[i], names[i]); } assert_null(out[i]); sss_sifp_free_string_array(ctx, &out); assert_null(out); /* messages are unrefed in the library */ } void test_sss_sifp_fetch_domain_by_name(void **state) { sss_sifp_ctx *ctx = test_ctx.dbus_ctx; DBusMessage *msg_path = NULL; DBusMessage *msg_props = NULL; DBusMessageIter iter; DBusMessageIter array_iter; DBusMessageIter dict_iter; DBusMessageIter var_iter; dbus_bool_t bret; sss_sifp_error ret; const char *in =SSS_SIFP_PATH_IFP "/Domains/LDAP"; const char *name = "LDAP"; const char *prop = NULL; sss_sifp_object *out = NULL; struct { const char *name; const char *value; } props[] = {{"name", name}, {"a1", "a"}, {"a2", "b"}, {NULL, 0}}; int i; msg_path = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); assert_non_null(msg_path); msg_props = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); assert_non_null(msg_props); /* prepare message */ bret = dbus_message_append_args(msg_path, DBUS_TYPE_OBJECT_PATH, &in, DBUS_TYPE_INVALID); assert_true(bret); dbus_message_iter_init_append(msg_props, &iter); bret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array_iter); assert_true(bret); for (i = 0; props[i].name != NULL; i++) { bret = dbus_message_iter_open_container(&array_iter, DBUS_TYPE_DICT_ENTRY, NULL, &dict_iter); assert_true(bret); bret = dbus_message_iter_append_basic(&dict_iter, DBUS_TYPE_STRING, &props[i].name); assert_true(bret); bret = dbus_message_iter_open_container(&dict_iter, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &var_iter); assert_true(bret); bret = dbus_message_iter_append_basic(&var_iter, DBUS_TYPE_STRING, &props[i].value); assert_true(bret); bret = dbus_message_iter_close_container(&dict_iter, &var_iter); assert_true(bret); bret = dbus_message_iter_close_container(&array_iter, &dict_iter); assert_true(bret); } bret = dbus_message_iter_close_container(&iter, &array_iter); assert_true(bret); will_return(__wrap_dbus_connection_send_with_reply_and_block, msg_path); will_return(__wrap_dbus_connection_send_with_reply_and_block, msg_props); /* test */ ret = sss_sifp_fetch_domain_by_name(ctx, name, &out); assert_int_equal(ret, SSS_SIFP_OK); assert_non_null(out); assert_non_null(out->attrs); assert_non_null(out->name); assert_non_null(out->object_path); assert_non_null(out->interface); assert_string_equal(out->name, name); assert_string_equal(out->object_path, in); assert_string_equal(out->interface, SSS_SIFP_IFACE_DOMAINS); for (i = 0; props[i].name != NULL; i++) { assert_non_null(out->attrs[i]); assert_int_equal(out->attrs[i]->num_values, 1); assert_int_equal(out->attrs[i]->type, SSS_SIFP_ATTR_TYPE_STRING); assert_string_equal(out->attrs[i]->name, props[i].name); ret = sss_sifp_find_attr_as_string(out->attrs, props[i].name, &prop); assert_int_equal(ret, SSS_SIFP_OK); assert_string_equal(props[i].value, prop); } assert_null(out->attrs[i]); sss_sifp_free_object(ctx, &out); assert_null(out); /* messages are unrefed in the library */ } int main(int argc, const char *argv[]) { int rv; int no_cleanup = 0; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_sss_sifp_strdup_valid, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_strdup_null, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_strcat_valid, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_strcat_left_null, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_strcat_right_null, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_strcat_both_null, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_object_path_valid, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_object_path_invalid, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_object_path_list_valid, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_object_path_list_invalid, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_bool, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int16, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint16, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int32, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint32, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int64, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint64, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_string, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_object_path, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_string_dict, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_bool_array, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_bool_array_empty, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int32_array, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int32_array_empty, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint32_array, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint32_array_empty, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int64_array, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_int64_array_empty, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint64_array, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_uint64_array_empty, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_string_array, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_string_array_empty, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_object_path_array, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_object_path_array_empty, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_string_dict_array, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_list, test_setup, test_teardown_parser), cmocka_unit_test_setup_teardown(test_sss_sifp_parse_attr_list_empty, test_setup, test_teardown_parser), cmocka_unit_test(test_sss_sifp_get_iface_for_object), cmocka_unit_test_setup_teardown(test_sss_sifp_fetch_attr, test_setup, test_teardown_api), cmocka_unit_test_setup_teardown(test_sss_sifp_fetch_all_attrs, test_setup, test_teardown_api), cmocka_unit_test_setup_teardown(test_sss_sifp_fetch_object, test_setup, test_teardown_api), cmocka_unit_test_setup_teardown(test_sss_sifp_invoke_list_zeroargs, test_setup, test_teardown_api), cmocka_unit_test_setup_teardown(test_sss_sifp_invoke_list_withargs, test_setup, test_teardown_api), cmocka_unit_test_setup_teardown(test_sss_sifp_invoke_find_zeroargs, test_setup, test_teardown_api), cmocka_unit_test_setup_teardown(test_sss_sifp_invoke_find_withargs, test_setup, test_teardown_api), cmocka_unit_test_setup_teardown(test_sss_sifp_list_domains, test_setup, test_teardown_api), cmocka_unit_test_setup_teardown(test_sss_sifp_fetch_domain_by_name, test_setup, test_teardown_api), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); rv = cmocka_run_group_tests(tests, NULL, NULL); return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/sbus_internal_tests.c0000644000000000000000000000007412703456111021751 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.962794673 sssd-1.13.4/src/tests/cmocka/sbus_internal_tests.c0000644002412700241270000001746712703456111023437 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat SSSD tests: SBUS internals This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/util.h" #include "responder/common/responder.h" #include "tests/cmocka/common_mock.h" #include "sbus/sssd_dbus_private.h" struct sbus_get_id_ctx { struct sss_test_ctx *stc; struct sbus_connection *conn; DBusPendingCallNotifyFunction reply_handler; void *reply_pvt; int last_hash_lookup; int64_t expected; }; struct sbus_get_id_ctx *global_test_ctx; DBusConnection * __wrap_dbus_bus_get(DBusBusType type, DBusError *error) { /* just don't return NULL */ return (DBusConnection *) 0x42; } void __wrap_dbus_connection_set_exit_on_disconnect(DBusConnection *connection, dbus_bool_t exit_on_disconnect) { return; } void __wrap_dbus_pending_call_unref(DBusPendingCall *pending) { return; } void __wrap_dbus_message_unref(DBusMessage *message) { return; } void __wrap_dbus_connection_unref(DBusConnection *connection) { return; } DBusMessage* __wrap_dbus_pending_call_steal_reply(DBusPendingCall *pending) { return sss_mock_ptr_type(DBusMessage *); } int __real_hash_lookup(hash_table_t *table, hash_key_t *key, hash_value_t *value); int __wrap_hash_lookup(hash_table_t *table, hash_key_t *key, hash_value_t *value) { global_test_ctx->last_hash_lookup = __real_hash_lookup(table, key, value); return global_test_ctx->last_hash_lookup; } static void fake_sbus_msg_done(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt) { struct sbus_get_id_ctx *test_ctx = talloc_get_type(pvt, struct sbus_get_id_ctx); talloc_free(imm); test_ctx->reply_handler(NULL, test_ctx->reply_pvt); } int sss_dbus_conn_send(DBusConnection *dbus_conn, DBusMessage *msg, int timeout_ms, DBusPendingCallNotifyFunction reply_handler, void *pvt, DBusPendingCall **pending) { struct tevent_immediate *imm; global_test_ctx->reply_pvt = pvt; global_test_ctx->reply_handler = reply_handler; imm = tevent_create_immediate(global_test_ctx->stc->ev); assert_non_null(imm); tevent_schedule_immediate(imm, global_test_ctx->stc->ev, fake_sbus_msg_done, global_test_ctx); return EOK; } int sbus_get_id_test_setup(void **state) { struct sbus_get_id_ctx *test_ctx; int ret; test_ctx = talloc(global_talloc_context, struct sbus_get_id_ctx); assert_non_null(test_ctx); test_ctx->conn = talloc(test_ctx, struct sbus_connection); assert_non_null(test_ctx->conn); test_ctx->conn->connection_type = SBUS_CONN_TYPE_SYSBUS; ret = sss_hash_create(test_ctx->conn, 32, &test_ctx->conn->clients); assert_int_equal(ret, EOK); test_ctx->stc = create_ev_test_ctx(test_ctx); assert_non_null(test_ctx->stc); *state = test_ctx; global_test_ctx = test_ctx; return 0; } void sbus_int_test_get_uid_done(struct tevent_req *req) { errno_t ret; int64_t uid; struct sbus_get_id_ctx *test_ctx = tevent_req_callback_data(req, struct sbus_get_id_ctx); ret = sbus_get_sender_id_recv(req, &uid); talloc_free(req); assert_int_equal(ret, EOK); test_ctx->stc->done = true; assert_int_equal(uid, test_ctx->expected); } void sbus_int_test_get_uid(void **state) { errno_t ret; struct tevent_req *req; DBusMessage *reply; struct sbus_get_id_ctx *test_ctx = talloc_get_type(*state, struct sbus_get_id_ctx); uint32_t uid; test_ctx->expected = 42; uid = test_ctx->expected; reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL); assert_non_null(reply); dbus_message_append_args(reply, DBUS_TYPE_UINT32, &uid, DBUS_TYPE_INVALID); will_return(__wrap_dbus_pending_call_steal_reply, reply); req = sbus_get_sender_id_send(test_ctx, test_ctx->stc->ev, test_ctx->conn, __FILE__); tevent_req_set_callback(req, sbus_int_test_get_uid_done, test_ctx); ret = test_ev_loop(test_ctx->stc); assert_int_equal(ret, EOK); assert_int_equal(test_ctx->last_hash_lookup, HASH_ERROR_KEY_NOT_FOUND); /* Now do the same lookup again, just make sure the result was cached */ req = sbus_get_sender_id_send(test_ctx, test_ctx->stc->ev, test_ctx->conn, __FILE__); tevent_req_set_callback(req, sbus_int_test_get_uid_done, test_ctx); ret = test_ev_loop(test_ctx->stc); assert_int_equal(ret, EOK); assert_int_equal(test_ctx->last_hash_lookup, HASH_SUCCESS); } void sbus_int_test_get_uid_no_sender_done(struct tevent_req *req) { errno_t ret; int64_t uid; struct sbus_get_id_ctx *test_ctx = tevent_req_callback_data(req, struct sbus_get_id_ctx); ret = sbus_get_sender_id_recv(req, &uid); talloc_free(req); assert_int_equal(ret, ERR_SBUS_NO_SENDER); test_ctx->stc->done = true; } void sbus_int_test_get_uid_no_sender(void **state) { errno_t ret; struct tevent_req *req; struct sbus_get_id_ctx *test_ctx = talloc_get_type(*state, struct sbus_get_id_ctx); test_ctx->expected = -1; req = sbus_get_sender_id_send(test_ctx, test_ctx->stc->ev, test_ctx->conn, NULL); tevent_req_set_callback(req, sbus_int_test_get_uid_no_sender_done, test_ctx); ret = test_ev_loop(test_ctx->stc); assert_int_equal(ret, EOK); } int sbus_get_id_test_teardown(void **state) { struct sbus_get_id_ctx *test_ctx = talloc_get_type(*state, struct sbus_get_id_ctx); talloc_free(test_ctx); return 0; } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(sbus_int_test_get_uid, sbus_get_id_test_setup, sbus_get_id_test_teardown), cmocka_unit_test_setup_teardown(sbus_int_test_get_uid_no_sender, sbus_get_id_test_setup, sbus_get_id_test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/common_mock_sdap.c0000644000000000000000000000007412703456111021167 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.941794602 sssd-1.13.4/src/tests/cmocka/common_mock_sdap.c0000644002412700241270000001134612703456111022643 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap.h" #include "tests/cmocka/common_mock.h" struct sdap_id_ctx *mock_sdap_id_ctx(TALLOC_CTX *mem_ctx, struct be_ctx *be_ctx, struct sdap_options *sdap_opts) { struct sdap_id_ctx *sdap_id_ctx; sdap_id_ctx = talloc_zero(mem_ctx, struct sdap_id_ctx); assert_non_null(sdap_id_ctx); sdap_id_ctx->be = be_ctx; sdap_id_ctx->opts = sdap_opts; return sdap_id_ctx; } struct sdap_options *mock_sdap_options_ldap(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct confdb_ctx *confdb_ctx, const char *conf_path) { struct sdap_options *opts = NULL; errno_t ret; ret = ldap_get_options(mem_ctx, domain, confdb_ctx, conf_path, &opts); if (ret != EOK) { return NULL; } return opts; } struct sdap_handle *mock_sdap_handle(TALLOC_CTX *mem_ctx) { struct sdap_handle *handle = talloc_zero(mem_ctx, struct sdap_handle); /* we will never connect to any LDAP server and any sdap API that * access sdap_handle should be mocked, thus returning empty structure * is enough */ return handle; } /* * Mock sdap_async.c * * Every function that is placed in sdap_async.c module has to be mocked, * to avoid any attempt to communicate with remote servers. Therefore no test * can be compiled with sdap_async.c. If any of these functions is needed, * their mock equivalent shall be used. */ bool sdap_has_deref_support(struct sdap_handle *sh, struct sdap_options *opts) { return sss_mock_type(bool); } struct tevent_req *sdap_get_generic_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *search_base, int scope, const char *filter, const char **attrs, struct sdap_attr_map *map, int map_num_attrs, int timeout, bool allow_paging) { return test_req_succeed_send(mem_ctx, ev); } int sdap_get_generic_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sysdb_attrs ***reply) { TEVENT_REQ_RETURN_ON_ERROR(req); *reply_count = sss_mock_type(size_t); *reply = sss_mock_ptr_type(struct sysdb_attrs **); return sss_mock_type(int); } struct tevent_req * sdap_deref_search_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sdap_options *opts, struct sdap_handle *sh, const char *base_dn, const char *deref_attr, const char **attrs, int num_maps, struct sdap_attr_map_info *maps, int timeout) { return test_req_succeed_send(mem_ctx, ev); } int sdap_deref_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sdap_deref_attrs ***reply) { TEVENT_REQ_RETURN_ON_ERROR(req); *reply_count = sss_mock_type(size_t); *reply = talloc_steal(mem_ctx, sss_mock_ptr_type(struct sdap_deref_attrs **)); return EOK; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/common_mock_be.c0000644000000000000000000000007412703456111020626 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.916794517 sssd-1.13.4/src/tests/cmocka/common_mock_be.c0000644002412700241270000000224612703456111022301 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2015 Red Hat SSSD tests: Fake back end This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "tests/cmocka/common_mock_resp.h" struct be_ctx *mock_be_ctx(TALLOC_CTX *mem_ctx, struct sss_test_ctx *tctx) { struct be_ctx *be_ctx; be_ctx = talloc_zero(mem_ctx, struct be_ctx); assert_non_null(be_ctx); be_ctx->cdb = tctx->confdb; be_ctx->ev = tctx->ev; be_ctx->domain = tctx->dom; be_ctx->conf_path = tctx->conf_dom_path; return be_ctx; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_ipa_subdomains_utils.c0000644000000000000000000000007412703456111023133 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.041794941 sssd-1.13.4/src/tests/cmocka/test_ipa_subdomains_utils.c0000644002412700241270000001446512703456111024614 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2015 Red Hat SSSD tests: IPA subdomain util tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include "providers/ipa/ipa_subdomains.h" #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" struct test_ipa_subdom_ctx { struct ldb_context *ldb; }; static int test_ipa_subdom_setup(void **state) { struct test_ipa_subdom_ctx *test_ctx; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct test_ipa_subdom_ctx); assert_non_null(test_ctx); test_ctx->ldb = ldb_init(test_ctx, NULL); assert_non_null(test_ctx->ldb); check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int test_ipa_subdom_teardown(void **state) { struct test_ipa_subdom_ctx *test_ctx; test_ctx = talloc_get_type(*state, struct test_ipa_subdom_ctx); assert_non_null(test_ctx); assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } static struct sysdb_attrs *dn_attrs(TALLOC_CTX *mem_ctx, const char *dn) { struct sysdb_attrs *attrs; int rv; attrs = sysdb_new_attrs(mem_ctx); assert_non_null(attrs); rv = sysdb_attrs_add_string(attrs, SYSDB_ORIG_DN, dn); assert_int_equal(rv, EOK); return attrs; } static void test_ipa_subdom_ldb_dn(void **state) { struct ldb_dn *dn; struct sysdb_attrs *attrs; struct test_ipa_subdom_ctx *test_ctx; test_ctx = talloc_get_type(*state, struct test_ipa_subdom_ctx); assert_non_null(test_ctx); attrs = dn_attrs(test_ctx, "dc=foo,dc=bar"); assert_non_null(attrs); dn = ipa_subdom_ldb_dn(test_ctx, test_ctx->ldb, attrs); assert_non_null(dn); assert_string_equal(ldb_dn_get_linearized(dn), "dc=foo,dc=bar"); talloc_free(dn); talloc_free(attrs); } static void test_ipa_subdom_ldb_dn_fail(void **state) { struct ldb_dn *dn; struct sysdb_attrs *attrs; struct test_ipa_subdom_ctx *test_ctx; test_ctx = talloc_get_type(*state, struct test_ipa_subdom_ctx); assert_non_null(test_ctx); attrs = dn_attrs(test_ctx, "notadn"); assert_non_null(attrs); dn = ipa_subdom_ldb_dn(test_ctx, NULL, NULL); assert_null(dn); dn = ipa_subdom_ldb_dn(test_ctx, test_ctx->ldb, attrs); assert_null(dn); talloc_free(attrs); attrs = sysdb_new_attrs(test_ctx); assert_non_null(attrs); dn = ipa_subdom_ldb_dn(test_ctx, test_ctx->ldb, attrs); assert_null(dn); talloc_free(attrs); } static struct ldb_dn *get_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const char *strdn) { struct ldb_dn *dn; struct sysdb_attrs *attrs; attrs = dn_attrs(mem_ctx, strdn); assert_non_null(attrs); dn = ipa_subdom_ldb_dn(mem_ctx, ldb, attrs); talloc_free(attrs); assert_non_null(dn); return dn; } static void test_ipa_subdom_is_member_dom(void **state) { struct ldb_dn *dn; struct test_ipa_subdom_ctx *test_ctx; bool is_member; test_ctx = talloc_get_type(*state, struct test_ipa_subdom_ctx); dn = get_dn(test_ctx, test_ctx->ldb, "cn=SUB.AD.DOM,cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com"); is_member = ipa_subdom_is_member_dom(dn); talloc_free(dn); assert_true(is_member); dn = get_dn(test_ctx, test_ctx->ldb, "cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com"); is_member = ipa_subdom_is_member_dom(dn); talloc_free(dn); assert_false(is_member); dn = get_dn(test_ctx, test_ctx->ldb, "cn=SUB.AD.DOM,cn=AD.DOM,cn=ad,cn=XXX,dc=example,dc=com"); is_member = ipa_subdom_is_member_dom(dn); talloc_free(dn); assert_false(is_member); dn = get_dn(test_ctx, test_ctx->ldb, "cn=SUB.AD.DOM,cn=AD.DOM,cn=YYY,cn=trusts,dc=example,dc=com"); is_member = ipa_subdom_is_member_dom(dn); talloc_free(dn); assert_false(is_member); } int main(int argc, const char *argv[]) { int rv; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_ipa_subdom_ldb_dn, test_ipa_subdom_setup, test_ipa_subdom_teardown), cmocka_unit_test_setup_teardown(test_ipa_subdom_ldb_dn_fail, test_ipa_subdom_setup, test_ipa_subdom_teardown), cmocka_unit_test_setup_teardown(test_ipa_subdom_is_member_dom, test_ipa_subdom_setup, test_ipa_subdom_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); rv = cmocka_run_group_tests(tests, NULL, NULL); return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_utils.h0000644000000000000000000000007412703456111020063 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.599793442 sssd-1.13.4/src/tests/cmocka/test_utils.h0000644002412700241270000000234012703456111021531 0ustar00jhrozekjhrozek00000000000000/* Authors: Lukas Slebodnik Copyright (C) 2014 Red Hat SSSD tests: Tests for utility functions This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __TESTS__CMOCKA__TEST_UTILS_H__ #define __TESTS__CMOCKA__TEST_UTILS_H__ /* from src/tests/cmocka/test_sss_ssh.c */ void test_textual_public_key(void **state); /* from src/tests/cmocka/test_string_utils.c */ void test_replace_whitespaces(void **state); void test_reverse_replace_whitespaces(void **state); void test_guid_blob_to_string_buf(void **state); void test_get_last_x_chars(void **state); #endif /* __TESTS__CMOCKA__TEST_UTILS_H__ */ sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_ad_access_filter.c0000644000000000000000000000007412703456111022170 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.904794477 sssd-1.13.4/src/tests/cmocka/test_ad_access_filter.c0000644002412700241270000002326712703456111023651 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat SSSD tests: AD access control filter tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include /* In order to access opaque types */ #include "providers/ad/ad_access.c" #include "tests/cmocka/common_mock.h" #define DOM_NAME "parent_dom" struct ad_access_test_ctx { struct sss_domain_info *dom; }; static struct ad_access_test_ctx *test_ctx; int ad_access_filter_test_setup(void **state) { assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct ad_access_test_ctx); assert_non_null(test_ctx); test_ctx->dom = talloc_zero(test_ctx, struct sss_domain_info); assert_non_null(test_ctx->dom); test_ctx->dom->name = talloc_strdup(test_ctx->dom, DOM_NAME); assert_non_null(test_ctx->dom->name); return 0; } int ad_access_filter_test_teardown(void **state) { talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } struct filter_parse_result { const int result; const char *best_match; }; static void test_parse_filter_generic(const char *filter_in, struct filter_parse_result *expected) { errno_t ret; TALLOC_CTX *tmp_ctx; char *best_match; assert_non_null(expected); tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); ret = ad_parse_access_filter(tmp_ctx, test_ctx->dom, filter_in, &best_match); assert_int_equal(ret, expected->result); if (expected->result != EOK) { goto done; } if (expected->best_match != NULL) { assert_string_equal(best_match, expected->best_match); } else { assert_true(best_match == NULL); } talloc_free(best_match); done: assert_true(check_leaks_pop(tmp_ctx) == true); talloc_free(tmp_ctx); } /* Test that setting no filter lets all access through */ void test_no_filter(void **state) { struct filter_parse_result expected = { .result = EOK, .best_match = NULL }; test_parse_filter_generic(NULL, &expected); } /* Test that if one filter is provided, it is returned as-is */ void test_single_filter(void **state) { struct filter_parse_result expected = { .result = EOK, .best_match = "(name=foo)" }; test_parse_filter_generic("name=foo", &expected); test_parse_filter_generic("(name=foo)", &expected); test_parse_filter_generic(DOM_NAME":(name=foo)", &expected); test_parse_filter_generic("DOM:"DOM_NAME":(name=foo)", &expected); } /* Test that if more filters are provided, the best match is returned */ void test_filter_order(void **state) { struct filter_parse_result expected = { .result = EOK, .best_match = "(name=foo)" }; test_parse_filter_generic("name=foo?name=bar", &expected); test_parse_filter_generic(DOM_NAME":(name=foo)?name=bar", &expected); test_parse_filter_generic("name=bla?"DOM_NAME":(name=foo)?name=bar", &expected); /* Test that another foreign domain wouldn't match */ test_parse_filter_generic("anotherdom:(name=bla)?"DOM_NAME":(name=foo)", &expected); test_parse_filter_generic("anotherdom:(name=bla)?(name=foo)", &expected); } void test_filter_no_match(void **state) { struct filter_parse_result expected = { .result = EOK, .best_match = NULL }; test_parse_filter_generic("anotherdom:(name=bla)?yetanother:(name=foo)", &expected); } int parse_test_setup(void **state) { assert_true(leak_check_setup()); return 0; } int parse_test_teardown(void **state) { assert_true(leak_check_teardown()); return 0; } struct parse_result { const int result; const char *filter; const char *spec; const int flags; }; static void test_parse_generic(const char *filter_in, struct parse_result *expected) { errno_t ret; TALLOC_CTX *tmp_ctx; char *filter; char *spec; int flags; assert_non_null(expected); tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); ret = parse_filter(tmp_ctx, filter_in, &filter, &spec, &flags); assert_int_equal(ret, expected->result); if (expected->result != EOK) { goto done; } if (expected->filter != NULL) { assert_string_equal(filter, expected->filter); } else { assert_true(filter == NULL); } talloc_free(filter); if (expected->spec != NULL) { assert_string_equal(spec, expected->spec); } else { assert_true(spec == NULL); } talloc_free(spec); assert_int_equal(flags, expected->flags); done: assert_true(check_leaks_pop(tmp_ctx) == true); talloc_free(tmp_ctx); } void test_parse_plain(void **state) { struct parse_result expected = { .result = EOK, .filter = "name=foo", .spec = NULL, .flags = AD_FILTER_GENERIC }; test_parse_generic("name=foo", &expected); } void test_parse_dom_without_kw(void **state) { struct parse_result expected = { .result = EOK, .filter = "(name=foo)", .spec = "mydom", .flags = AD_FILTER_DOMAIN }; test_parse_generic("mydom:(name=foo)", &expected); /* Check we can handle domain called DOM */ struct parse_result expected2 = { .result = EOK, .filter = "(name=foo)", .spec = "DOM", .flags = AD_FILTER_DOMAIN }; test_parse_generic("DOM:(name=foo)", &expected2); } void test_parse_dom_kw(void **state) { struct parse_result expected = { .result = EOK, .filter = "(name=foo)", .spec = "mydom", .flags = AD_FILTER_DOMAIN }; test_parse_generic("DOM:mydom:(name=foo)", &expected); } void test_parse_forest_kw(void **state) { struct parse_result expected = { .result = EOK, .filter = "(name=foo)", .spec = "myforest", .flags = AD_FILTER_FOREST }; test_parse_generic("FOREST:myforest:(name=foo)", &expected); } void test_parse_malformed(void **state) { struct parse_result expected = { .result = EINVAL, }; test_parse_generic("DOM:", &expected); test_parse_generic("DOM::", &expected); test_parse_generic("DOM:mydom:", &expected); test_parse_generic("DOM:mydom:name=foo", &expected); test_parse_generic("DOM::(name=foo)", &expected); test_parse_generic("BLABLABLA:mydom:name=foo", &expected); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_parse_plain, parse_test_setup, parse_test_teardown), cmocka_unit_test_setup_teardown(test_parse_dom_without_kw, parse_test_setup, parse_test_teardown), cmocka_unit_test_setup_teardown(test_parse_dom_kw, parse_test_setup, parse_test_teardown), cmocka_unit_test_setup_teardown(test_parse_forest_kw, parse_test_setup, parse_test_teardown), cmocka_unit_test_setup_teardown(test_parse_malformed, parse_test_setup, parse_test_teardown), cmocka_unit_test_setup_teardown(test_no_filter, ad_access_filter_test_setup, ad_access_filter_test_teardown), cmocka_unit_test_setup_teardown(test_single_filter, ad_access_filter_test_setup, ad_access_filter_test_teardown), cmocka_unit_test_setup_teardown(test_filter_order, ad_access_filter_test_setup, ad_access_filter_test_teardown), cmocka_unit_test_setup_teardown(test_filter_no_match, ad_access_filter_test_setup, ad_access_filter_test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_expire_common.c0000644000000000000000000000007412703456111021562 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.043794948 sssd-1.13.4/src/tests/cmocka/test_expire_common.c0000644002412700241270000000623512703456111023237 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Reichl Copyright (C) 2015 Red Hat SSSD tests - common code for password expiration tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "tests/common_check.h" #include "tests/cmocka/test_expire_common.h" #define MAX 100 static char *now_str(TALLOC_CTX *mem_ctx, const char* format, int s) { time_t t = time(NULL) + s; struct tm *tm; size_t len; char *timestr; timestr = talloc_array(mem_ctx, char, MAX); tm = gmtime(&t); len = strftime(timestr, MAX, format, tm); if (len == 0) { return NULL; } return timestr; } int expire_test_setup(void **state) { struct expire_test_ctx *exp_state; TALLOC_CTX *mem_ctx; char *past_time; char *future_time; char *invalid_format; char *invalid_longer_format; mem_ctx = talloc_new(NULL); assert_non_null(mem_ctx); exp_state = talloc(mem_ctx, struct expire_test_ctx); assert_non_null(exp_state); *state = exp_state; /* testing data */ invalid_format = now_str(exp_state, "%Y%m%d%H%M%S", -20); assert_non_null(invalid_format); invalid_longer_format = (void*)now_str(exp_state, "%Y%m%d%H%M%SZA", -20); assert_non_null(invalid_longer_format); past_time = (void*)now_str(exp_state, "%Y%m%d%H%M%SZ", -20); assert_non_null(past_time); future_time = (void*)now_str(exp_state, "%Y%m%d%H%M%SZ", 20); assert_non_null(future_time); exp_state->past_time = past_time; exp_state->future_time = future_time; exp_state->invalid_format = invalid_format; exp_state->invalid_longer_format = invalid_longer_format; return 0; } int expire_test_teardown(void **state) { struct expire_test_ctx *test_ctx; test_ctx = talloc_get_type(*state, struct expire_test_ctx); assert_non_null(test_ctx); talloc_free(test_ctx); return 0; } void expire_test_tz(const char* tz, void (*test_func)(void*, void*), void *test_in, void *_test_out) { errno_t ret; const char *orig_tz = NULL; orig_tz = getenv("TZ"); if (orig_tz == NULL) { orig_tz = ""; } if (tz) { ret = setenv("TZ", tz, 1); assert_return_code(ret, errno); } test_func(test_in, _test_out); /* restore */ if (orig_tz != NULL) { ret = setenv("TZ", orig_tz, 1); assert_return_code(ret, errno); } } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_sss_idmap.c0000644000000000000000000000007412703456111020700 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.049794968 sssd-1.13.4/src/tests/cmocka/test_sss_idmap.c0000644002412700241270000006410112703456111022351 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2013 Red Hat SSSD tests: Unit tests for libsss_idmap This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "tests/cmocka/common_mock.h" #include "lib/idmap/sss_idmap.h" #define TEST_RANGE_MIN 200000 #define TEST_RANGE_MAX 399999 #define TEST_DOM_NAME "test.dom" #define TEST_DOM_SID "S-1-5-21-123-456-789" #define TEST_FIRST_RID 0 #define TEST_EXT_MAPPING true #define TEST_2_RANGE_MIN 600000 #define TEST_2_RANGE_MAX 799999 #define TEST_2_DOM_NAME "test2.dom" #define TEST_2_DOM_SID "S-1-5-21-987-654-321" #define TEST_2_FIRST_RID 1000000 #define TEST_2_EXT_MAPPING true #define TEST_OFFSET 1000000 #define TEST_OFFSET_STR "1000000" const int TEST_2922_MIN_ID = 1842600000; const int TEST_2922_MAX_ID = 1842799999; struct test_ctx { TALLOC_CTX *mem_idmap; struct sss_idmap_ctx *idmap_ctx; }; static void *idmap_talloc(size_t size, void *pvt) { return talloc_size(pvt, size); } static void idmap_free(void *ptr, void *pvt) { talloc_free(ptr); } static int test_sss_idmap_setup(void **state) { struct test_ctx *test_ctx; enum idmap_error_code err; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct test_ctx); assert_non_null(test_ctx); check_leaks_push(test_ctx); test_ctx->mem_idmap = talloc_new(test_ctx); assert_non_null(test_ctx->mem_idmap); err = sss_idmap_init(idmap_talloc, test_ctx->mem_idmap, idmap_free, &test_ctx->idmap_ctx); assert_int_equal(err, IDMAP_SUCCESS); *state = test_ctx; return 0; } static int setup_ranges(struct test_ctx *test_ctx, bool external_mapping, bool second_domain, bool sec_slices) { struct sss_idmap_range range; enum idmap_error_code err; const char *name; const char *sid; assert_non_null(test_ctx); if (second_domain) { range.min = TEST_2_RANGE_MIN; range.max = TEST_2_RANGE_MAX; name = TEST_2_DOM_NAME; sid = TEST_2_DOM_SID; } else { range.min = TEST_RANGE_MIN; range.max = TEST_RANGE_MAX; name = TEST_DOM_NAME; sid = TEST_DOM_SID; } if (sec_slices) { err = sss_idmap_add_auto_domain_ex(test_ctx->idmap_ctx, name, sid, &range, NULL, 0, external_mapping, NULL, NULL); } else { err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range, NULL, 0, external_mapping); } assert_int_equal(err, IDMAP_SUCCESS); range.min += TEST_OFFSET; range.max += TEST_OFFSET; if (sec_slices) { err = sss_idmap_add_auto_domain_ex(test_ctx->idmap_ctx, name, sid, &range, NULL, TEST_OFFSET, external_mapping, NULL, NULL); } else { err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range, NULL, TEST_OFFSET, external_mapping); } assert_int_equal(err, IDMAP_SUCCESS); return 0; } static int setup_ranges_2922(struct test_ctx *test_ctx) { const int TEST_2922_DFL_SLIDE = 9212; struct sss_idmap_range range; enum idmap_error_code err; const char *name; const char *sid; /* Pick a new slice. */ id_t slice_num = -1; assert_non_null(test_ctx); name = TEST_DOM_NAME; sid = TEST_DOM_SID; err = sss_idmap_calculate_range(test_ctx->idmap_ctx, sid, &slice_num, &range); assert_int_equal(err, IDMAP_SUCCESS); /* Range computation should be deterministic. Lets validate that. */ assert_int_equal(range.min, TEST_2922_MIN_ID); assert_int_equal(range.max, TEST_2922_MAX_ID); assert_int_equal(slice_num, TEST_2922_DFL_SLIDE); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range, NULL, 0, false /* No external mapping */); assert_int_equal(err, IDMAP_SUCCESS); return 0; } static int test_sss_idmap_setup_with_domains(void **state) { struct test_ctx *test_ctx; test_sss_idmap_setup(state); test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); setup_ranges(test_ctx, false, false, false); return 0; } static int test_sss_idmap_setup_with_domains_2922(void **state) { struct test_ctx *test_ctx; test_sss_idmap_setup(state); test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); setup_ranges_2922(test_ctx); return 0; } static int test_sss_idmap_setup_with_domains_sec_slices(void **state) { struct test_ctx *test_ctx; test_sss_idmap_setup(state); test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); setup_ranges(test_ctx, false, false, true); return 0; } static int test_sss_idmap_setup_with_external_mappings(void **state) { struct test_ctx *test_ctx; test_sss_idmap_setup(state); test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); setup_ranges(test_ctx, true, false, false); return 0; } static int test_sss_idmap_setup_with_both(void **state) { struct test_ctx *test_ctx; test_sss_idmap_setup(state); test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); setup_ranges(test_ctx, false, false, false); setup_ranges(test_ctx, true, true, false); return 0; } static int test_sss_idmap_teardown(void **state) { struct test_ctx *test_ctx; test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); talloc_free(test_ctx->idmap_ctx); talloc_free(test_ctx->mem_idmap); assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } void test_add_domain(void **state) { struct test_ctx *test_ctx; enum idmap_error_code err; struct sss_idmap_range range; test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); range.min = TEST_RANGE_MIN; range.max = TEST_RANGE_MAX; err = sss_idmap_add_domain(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range); assert_int_equal(err, IDMAP_SUCCESS); err = sss_idmap_add_domain(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range); assert_int_equal(err, IDMAP_COLLISION); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range, NULL, 0, false); assert_int_equal(err, IDMAP_COLLISION); range.min = TEST_RANGE_MIN + TEST_OFFSET; range.max = TEST_RANGE_MAX + TEST_OFFSET; err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range, NULL, 0, false); assert_int_equal(err, IDMAP_COLLISION); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME"X", TEST_DOM_SID, &range, NULL, TEST_OFFSET, false); assert_int_equal(err, IDMAP_COLLISION); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID"1", &range, NULL, TEST_OFFSET, false); assert_int_equal(err, IDMAP_COLLISION); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range, NULL, TEST_OFFSET, true); assert_int_equal(err, IDMAP_COLLISION); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME, TEST_DOM_SID, &range, NULL, TEST_OFFSET, false); assert_int_equal(err, IDMAP_SUCCESS); range.min = TEST_RANGE_MIN + 2 * TEST_OFFSET; range.max = TEST_RANGE_MAX + 2 * TEST_OFFSET; err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME"-nosid", NULL, &range, NULL, TEST_OFFSET, false); assert_int_equal(err, IDMAP_SID_INVALID); err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, TEST_DOM_NAME"-nosid", NULL, &range, NULL, TEST_OFFSET, true); assert_int_equal(err, IDMAP_SUCCESS); } void test_map_id(void **state) { struct test_ctx *test_ctx; enum idmap_error_code err; uint32_t id; char *sid = NULL; test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"1-1", &id); assert_int_equal(err, IDMAP_NO_DOMAIN); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-400000", &id); assert_int_equal(err, IDMAP_NO_RANGE); err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_OFFSET - 1, &sid); assert_int_equal(err, IDMAP_NO_DOMAIN); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-0", &id); assert_int_equal(err, IDMAP_SUCCESS); assert_int_equal(id, TEST_RANGE_MIN); err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, id, &sid); assert_int_equal(err, IDMAP_SUCCESS); assert_string_equal(sid, TEST_DOM_SID"-0"); sss_idmap_free_sid(test_ctx->idmap_ctx, sid); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-"TEST_OFFSET_STR, &id); assert_int_equal(err, IDMAP_SUCCESS); assert_int_equal(id, TEST_RANGE_MIN+TEST_OFFSET); err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, id, &sid); assert_int_equal(err, IDMAP_SUCCESS); assert_string_equal(sid, TEST_DOM_SID"-"TEST_OFFSET_STR); sss_idmap_free_sid(test_ctx->idmap_ctx, sid); } /* https://fedorahosted.org/sssd/ticket/2922 */ /* ID mapping - bug in computing max id for slice range */ void test_map_id_2922(void **state) { const char* TEST_2922_FIRST_SID = TEST_DOM_SID"-0"; /* Last SID = first SID + (default) rangesize -1 */ const char* TEST_2922_LAST_SID = TEST_DOM_SID"-199999"; /* Last SID = first SID + rangesize */ const char* TEST_2922_LAST_SID_PLUS_ONE = TEST_DOM_SID"-200000"; struct test_ctx *test_ctx; enum idmap_error_code err; uint32_t id; char *sid = NULL; test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); /* Min UNIX ID to SID */ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_2922_MIN_ID, &sid); assert_int_equal(err, IDMAP_SUCCESS); assert_string_equal(sid, TEST_2922_FIRST_SID); sss_idmap_free_sid(test_ctx->idmap_ctx, sid); /* First SID to UNIX ID */ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_2922_FIRST_SID, &id); assert_int_equal(err, IDMAP_SUCCESS); assert_int_equal(id, TEST_2922_MIN_ID); /* Max UNIX ID to SID */ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_2922_MAX_ID, &sid); assert_int_equal(err, IDMAP_SUCCESS); assert_string_equal(sid, TEST_2922_LAST_SID); sss_idmap_free_sid(test_ctx->idmap_ctx, sid); /* Last SID to UNIX ID */ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_2922_LAST_SID, &id); assert_int_equal(err, IDMAP_SUCCESS); assert_int_equal(id, TEST_2922_MAX_ID); /* Max UNIX ID + 1 to SID */ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_2922_MAX_ID + 1, &sid); assert_int_equal(err, IDMAP_NO_DOMAIN); /* Last SID + 1 to UNIX ID */ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_2922_LAST_SID_PLUS_ONE, &id); /* Auto adding new ranges is disable in this test. */ assert_int_equal(err, IDMAP_NO_RANGE); } void test_map_id_sec_slices(void **state) { struct test_ctx *test_ctx; enum idmap_error_code err; uint32_t id; char *sid = NULL; test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"1-1", &id); assert_int_equal(err, IDMAP_NO_DOMAIN); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-4000000", &id); assert_int_equal(err, IDMAP_SUCCESS); assert_int_equal(id, 575600000); err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_OFFSET - 1, &sid); assert_int_equal(err, IDMAP_NO_DOMAIN); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-0", &id); assert_int_equal(err, IDMAP_SUCCESS); assert_int_equal(id, TEST_RANGE_MIN); err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, id, &sid); assert_int_equal(err, IDMAP_SUCCESS); assert_string_equal(sid, TEST_DOM_SID"-0"); sss_idmap_free_sid(test_ctx->idmap_ctx, sid); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-"TEST_OFFSET_STR, &id); assert_int_equal(err, IDMAP_SUCCESS); assert_int_equal(id, TEST_RANGE_MIN+TEST_OFFSET); err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, id, &sid); assert_int_equal(err, IDMAP_SUCCESS); assert_string_equal(sid, TEST_DOM_SID"-"TEST_OFFSET_STR); sss_idmap_free_sid(test_ctx->idmap_ctx, sid); } void test_map_id_external(void **state) { struct test_ctx *test_ctx; enum idmap_error_code err; uint32_t id; char *sid = NULL; test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"1-1", &id); assert_int_equal(err, IDMAP_NO_DOMAIN); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-400000", &id); assert_int_equal(err, IDMAP_EXTERNAL); err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_OFFSET - 1, &sid); assert_int_equal(err, IDMAP_NO_DOMAIN); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-0", &id); assert_int_equal(err, IDMAP_EXTERNAL); err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_RANGE_MIN, &sid); assert_int_equal(err, IDMAP_EXTERNAL); err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-"TEST_OFFSET_STR, &id); assert_int_equal(err, IDMAP_EXTERNAL); err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_RANGE_MIN + TEST_OFFSET, &sid); assert_int_equal(err, IDMAP_EXTERNAL); } void test_check_sid_id(void **state) { struct test_ctx *test_ctx; enum idmap_error_code err; test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); err = sss_idmap_check_sid_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-400000", TEST_RANGE_MIN-1); assert_int_equal(err, IDMAP_NO_RANGE); err = sss_idmap_check_sid_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-400000", TEST_RANGE_MIN); assert_int_equal(err, IDMAP_SUCCESS); err = sss_idmap_check_sid_unix(test_ctx->idmap_ctx, TEST_DOM_SID"1-400000", TEST_RANGE_MIN); assert_int_equal(err, IDMAP_SID_UNKNOWN); err = sss_idmap_check_sid_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-400000", TEST_RANGE_MAX + TEST_OFFSET); assert_int_equal(err, IDMAP_SUCCESS); err = sss_idmap_check_sid_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-400000", TEST_RANGE_MAX + TEST_OFFSET + 1); assert_int_equal(err, IDMAP_NO_RANGE); } void test_has_algorithmic(void **state) { struct test_ctx *test_ctx; bool use_id_mapping; enum idmap_error_code err; test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); err = sss_idmap_domain_has_algorithmic_mapping(NULL, NULL, &use_id_mapping); assert_int_equal(err, IDMAP_SID_INVALID); err = sss_idmap_domain_has_algorithmic_mapping(NULL, TEST_DOM_SID, &use_id_mapping); assert_int_equal(err, IDMAP_CONTEXT_INVALID); err = sss_idmap_domain_has_algorithmic_mapping(test_ctx->idmap_ctx, NULL, &use_id_mapping); assert_int_equal(err, IDMAP_SID_INVALID); err = sss_idmap_domain_has_algorithmic_mapping(test_ctx->idmap_ctx, TEST_DOM_SID"1", &use_id_mapping); assert_int_equal(err, IDMAP_SID_UNKNOWN); err = sss_idmap_domain_has_algorithmic_mapping(test_ctx->idmap_ctx, TEST_DOM_SID, &use_id_mapping); assert_int_equal(err, IDMAP_SUCCESS); assert_true(use_id_mapping); err = sss_idmap_domain_has_algorithmic_mapping(test_ctx->idmap_ctx, TEST_2_DOM_SID, &use_id_mapping); assert_int_equal(err, IDMAP_SUCCESS); assert_false(use_id_mapping); } void test_has_algorithmic_by_name(void **state) { struct test_ctx *test_ctx; bool use_id_mapping; enum idmap_error_code err; test_ctx = talloc_get_type(*state, struct test_ctx); assert_non_null(test_ctx); err = sss_idmap_domain_by_name_has_algorithmic_mapping(NULL, NULL, &use_id_mapping); assert_int_equal(err, IDMAP_ERROR); err = sss_idmap_domain_by_name_has_algorithmic_mapping(NULL, TEST_DOM_SID, &use_id_mapping); assert_int_equal(err, IDMAP_CONTEXT_INVALID); err = sss_idmap_domain_by_name_has_algorithmic_mapping(test_ctx->idmap_ctx, NULL, &use_id_mapping); assert_int_equal(err, IDMAP_ERROR); err = sss_idmap_domain_by_name_has_algorithmic_mapping(test_ctx->idmap_ctx, TEST_DOM_NAME"1", &use_id_mapping); assert_int_equal(err, IDMAP_NAME_UNKNOWN); err = sss_idmap_domain_by_name_has_algorithmic_mapping(test_ctx->idmap_ctx, TEST_DOM_NAME, &use_id_mapping); assert_int_equal(err, IDMAP_SUCCESS); assert_true(use_id_mapping); err = sss_idmap_domain_by_name_has_algorithmic_mapping(test_ctx->idmap_ctx, TEST_2_DOM_NAME, &use_id_mapping); assert_int_equal(err, IDMAP_SUCCESS); assert_false(use_id_mapping); } void test_sss_idmap_check_collision_ex(void **state) { enum idmap_error_code err; struct sss_idmap_range r1 = {TEST_RANGE_MIN, TEST_RANGE_MAX}; struct sss_idmap_range r2 = {TEST_2_RANGE_MIN, TEST_2_RANGE_MAX}; err = sss_idmap_check_collision_ex(TEST_DOM_NAME, TEST_DOM_SID, &r1, TEST_FIRST_RID, NULL, TEST_EXT_MAPPING, TEST_2_DOM_NAME, TEST_2_DOM_SID, &r2, TEST_2_FIRST_RID, NULL, TEST_2_EXT_MAPPING); assert_int_equal(err, IDMAP_SUCCESS); /* Same name, different SID */ err = sss_idmap_check_collision_ex(TEST_DOM_NAME, TEST_DOM_SID, &r1, TEST_FIRST_RID, NULL, TEST_EXT_MAPPING, TEST_DOM_NAME, TEST_2_DOM_SID, &r2, TEST_2_FIRST_RID, NULL, TEST_2_EXT_MAPPING); assert_int_equal(err, IDMAP_COLLISION); /* Same SID, different name */ err = sss_idmap_check_collision_ex(TEST_DOM_NAME, TEST_DOM_SID, &r1, TEST_FIRST_RID, NULL, TEST_EXT_MAPPING, TEST_2_DOM_NAME, TEST_DOM_SID, &r2, TEST_2_FIRST_RID, NULL, TEST_2_EXT_MAPPING); assert_int_equal(err, IDMAP_COLLISION); /* Same SID and name, no overlaps */ err = sss_idmap_check_collision_ex(TEST_DOM_NAME, TEST_DOM_SID, &r1, TEST_FIRST_RID, NULL, TEST_EXT_MAPPING, TEST_DOM_NAME, TEST_DOM_SID, &r2, TEST_2_FIRST_RID, NULL, TEST_2_EXT_MAPPING); assert_int_equal(err, IDMAP_SUCCESS); /* Same SID and name, different mappings */ err = sss_idmap_check_collision_ex(TEST_DOM_NAME, TEST_DOM_SID, &r1, TEST_FIRST_RID, NULL, TEST_EXT_MAPPING, TEST_DOM_NAME, TEST_DOM_SID, &r2, TEST_2_FIRST_RID, NULL, !TEST_EXT_MAPPING); assert_int_equal(err, IDMAP_COLLISION); /* Same SID and name, Overlapping RID range */ err = sss_idmap_check_collision_ex(TEST_DOM_NAME, TEST_DOM_SID, &r1, TEST_FIRST_RID, NULL, false, TEST_DOM_NAME, TEST_DOM_SID, &r2, TEST_FIRST_RID, NULL, false); assert_int_equal(err, IDMAP_COLLISION); /* Different SID and name, Overlapping RID range */ err = sss_idmap_check_collision_ex(TEST_DOM_NAME, TEST_DOM_SID, &r1, TEST_FIRST_RID, NULL, false, TEST_2_DOM_NAME, TEST_2_DOM_SID, &r2, TEST_FIRST_RID, NULL, false); assert_int_equal(err, IDMAP_SUCCESS); /* Overlapping ranges with no external mapping */ err = sss_idmap_check_collision_ex(TEST_DOM_NAME, TEST_DOM_SID, &r1, TEST_FIRST_RID, NULL, false, TEST_2_DOM_NAME, TEST_2_DOM_SID, &r1, TEST_2_FIRST_RID, NULL, false); assert_int_equal(err, IDMAP_COLLISION); /* Overlapping ranges with external mapping */ err = sss_idmap_check_collision_ex(TEST_DOM_NAME, TEST_DOM_SID, &r1, TEST_FIRST_RID, NULL, true, TEST_2_DOM_NAME, TEST_2_DOM_SID, &r1, TEST_2_FIRST_RID, NULL, true); assert_int_equal(err, IDMAP_SUCCESS); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_add_domain, test_sss_idmap_setup, test_sss_idmap_teardown), cmocka_unit_test_setup_teardown(test_map_id, test_sss_idmap_setup_with_domains, test_sss_idmap_teardown), cmocka_unit_test_setup_teardown(test_map_id_2922, test_sss_idmap_setup_with_domains_2922, test_sss_idmap_teardown), cmocka_unit_test_setup_teardown(test_map_id_sec_slices, test_sss_idmap_setup_with_domains_sec_slices, test_sss_idmap_teardown), cmocka_unit_test_setup_teardown(test_map_id_external, test_sss_idmap_setup_with_external_mappings, test_sss_idmap_teardown), cmocka_unit_test_setup_teardown(test_check_sid_id, test_sss_idmap_setup_with_domains, test_sss_idmap_teardown), cmocka_unit_test_setup_teardown(test_check_sid_id, test_sss_idmap_setup_with_external_mappings, test_sss_idmap_teardown), cmocka_unit_test_setup_teardown(test_has_algorithmic, test_sss_idmap_setup_with_both, test_sss_idmap_teardown), cmocka_unit_test_setup_teardown(test_has_algorithmic_by_name, test_sss_idmap_setup_with_both, test_sss_idmap_teardown), cmocka_unit_test(test_sss_idmap_check_collision_ex), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_sysdb_subdomains.c0000644000000000000000000000007412703456111022266 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.050794971 sssd-1.13.4/src/tests/cmocka/test_sysdb_subdomains.c0000644002412700241270000006104112703456111023737 0ustar00jhrozekjhrozek00000000000000/* SSSD sysdb_subdomains - Tests for subdomains and related calls Authors: Jakub Hrozek Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "tests/cmocka/common_mock.h" #include "tests/common.h" #include "db/sysdb_private.h" /* for sysdb->ldb member */ #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_sysdb_subdomains.ldb" #define TEST_DOM1_NAME "test_sysdb_subdomains_1" #define TEST_FLAT_NAME "TEST_1" #define TEST_SID "S-1" #define TEST_REALM "TEST_SYSDB_SUBDOMAINS" #define TEST_FOREST TEST_REALM #define TEST_ID_PROVIDER "ldap" #define TEST_DOM2_NAME "child2.test_sysdb_subdomains_2" #define TEST_FLAT_NAME2 "CHILD2" #define TEST_SID2 "S-2" #define TEST_REALM2 "TEST_SYSDB_SUBDOMAINS2" #define TEST_FOREST2 TEST_REALM2 const char *domains[] = { TEST_DOM1_NAME, TEST_DOM2_NAME, NULL }; struct subdom_test_ctx { struct sss_test_ctx *tctx; }; static int test_sysdb_subdom_setup(void **state) { struct subdom_test_ctx *test_ctx; struct sss_test_conf_param params[] = { { NULL, NULL }, /* Sentinel */ }; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct subdom_test_ctx); assert_non_null(test_ctx); test_dom_suite_setup(TESTS_PATH); test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, domains, TEST_ID_PROVIDER, params); assert_non_null(test_ctx->tctx); *state = test_ctx; return 0; } static int test_sysdb_subdom_teardown(void **state) { struct subdom_test_ctx *test_ctx = talloc_get_type(*state, struct subdom_test_ctx); test_multidom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, domains); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } static void test_sysdb_subdomain_create(void **state) { errno_t ret; struct subdom_test_ctx *test_ctx = talloc_get_type(*state, struct subdom_test_ctx); const char *const dom1[4] = { "dom1.sub", "DOM1.SUB", "dom1", "S-1" }; const char *const dom2[4] = { "dom2.sub", "DOM2.SUB", "dom2", "S-2" }; ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom1[0], dom1[1], dom1[2], dom1[3], false, false, NULL, 0); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom); assert_int_equal(ret, EOK); assert_non_null(test_ctx->tctx->dom->subdomains); assert_string_equal(test_ctx->tctx->dom->subdomains->name, dom1[0]); assert_int_equal(test_ctx->tctx->dom->subdomains->trust_direction, 0); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom2[0], dom2[1], dom2[2], dom2[3], false, false, NULL, 1); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom); assert_int_equal(ret, EOK); assert_non_null(test_ctx->tctx->dom->subdomains->next); assert_string_equal(test_ctx->tctx->dom->subdomains->next->name, dom2[0]); assert_int_equal(test_ctx->tctx->dom->subdomains->next->trust_direction, 1); /* Reverse the trust directions */ ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom1[0], dom1[1], dom1[2], dom1[3], false, false, NULL, 1); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom2[0], dom2[1], dom2[2], dom2[3], false, false, NULL, 0); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom); assert_int_equal(ret, EOK); assert_int_equal(test_ctx->tctx->dom->subdomains->trust_direction, 1); assert_int_equal(test_ctx->tctx->dom->subdomains->next->trust_direction, 0); ret = sysdb_subdomain_delete(test_ctx->tctx->sysdb, dom2[0]); assert_int_equal(ret, EOK); ret = sysdb_subdomain_delete(test_ctx->tctx->sysdb, dom1[0]); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom); assert_int_equal(ret, EOK); assert_int_equal(sss_domain_get_state(test_ctx->tctx->dom->subdomains), DOM_DISABLED); assert_int_equal( sss_domain_get_state(test_ctx->tctx->dom->subdomains->next), DOM_DISABLED); } static void test_sysdb_master_domain_ops(void **state) { errno_t ret; struct subdom_test_ctx *test_ctx = talloc_get_type(*state, struct subdom_test_ctx); ret = sysdb_master_domain_add_info(test_ctx->tctx->dom, "realm1", "flat1", "id1", "forest1"); assert_int_equal(ret, EOK); ret = sysdb_master_domain_update(test_ctx->tctx->dom); assert_int_equal(ret, EOK); assert_string_equal(test_ctx->tctx->dom->realm, "realm1"); assert_string_equal(test_ctx->tctx->dom->flat_name, "flat1"); assert_string_equal(test_ctx->tctx->dom->domain_id, "id1"); assert_string_equal(test_ctx->tctx->dom->forest, "forest1"); ret = sysdb_master_domain_add_info(test_ctx->tctx->dom, "realm2", "flat2", "id2", "forest2"); assert_int_equal(ret, EOK); ret = sysdb_master_domain_update(test_ctx->tctx->dom); assert_int_equal(ret, EOK); assert_string_equal(test_ctx->tctx->dom->realm, "realm2"); assert_string_equal(test_ctx->tctx->dom->flat_name, "flat2"); assert_string_equal(test_ctx->tctx->dom->domain_id, "id2"); assert_string_equal(test_ctx->tctx->dom->forest, "forest2"); } /* Parent domain totally separate from subdomains that imitate * IPA domain and two forests */ static void test_sysdb_link_forest_root_ipa(void **state) { errno_t ret; struct subdom_test_ctx *test_ctx = talloc_get_type(*state, struct subdom_test_ctx); struct sss_domain_info *main_dom; struct sss_domain_info *sub; struct sss_domain_info *child; /* name, realm, flat, SID, forest */ const char *const dom1[5] = { "dom1.sub", "DOM1.SUB", "DOM1", "S-1", "DOM1.SUB" }; const char *const child_dom1[5] = { "child1.dom1.sub", "CHILD1.DOM1.SUB", "CHILD1.DOM1", "S-1-2", "DOM1.SUB" }; const char *const dom2[5] = { "dom2.sub", "DOM2.SUB", "DOM2", "S-2", "DOM2.SUB" }; const char *const child_dom2[5] = { "child2.dom2.sub", "CHILD2.DOM1.SUB", "CHILD2.DOM1", "S-2-2", "DOM2.SUB" }; ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom1[0], dom1[1], dom1[2], dom1[3], false, false, dom1[4], 0); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, child_dom1[0], child_dom1[1], child_dom1[2], child_dom1[3], false, false, child_dom1[4], 0); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, dom2[0], dom2[1], dom2[2], dom2[3], false, false, dom2[4], 0); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, child_dom2[0], child_dom2[1], child_dom2[2], child_dom2[3], false, false, child_dom2[4], 0); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom); assert_int_equal(ret, EOK); /* Also update dom2 */ ret = sysdb_update_subdomains(test_ctx->tctx->dom->next); assert_int_equal(ret, EOK); sub = find_domain_by_name(test_ctx->tctx->dom, dom1[0], true); assert_non_null(sub->forest_root); assert_ptr_equal(sub->forest_root, sub); child = find_domain_by_name(test_ctx->tctx->dom, child_dom1[0], true); assert_non_null(child->forest_root); assert_ptr_equal(child->forest_root, sub); sub = find_domain_by_name(test_ctx->tctx->dom, dom2[0], true); assert_non_null(sub->forest_root); assert_ptr_equal(sub->forest_root, sub); child = find_domain_by_name(test_ctx->tctx->dom, child_dom2[0], true); assert_non_null(child->forest_root); assert_ptr_equal(child->forest_root, sub); main_dom = find_domain_by_name(test_ctx->tctx->dom, TEST_DOM1_NAME, true); assert_non_null(main_dom); assert_non_null(main_dom->forest_root); assert_true(main_dom->forest_root == main_dom); main_dom = find_domain_by_name(test_ctx->tctx->dom, TEST_DOM2_NAME, true); assert_non_null(main_dom); assert_non_null(main_dom->forest_root); assert_true(main_dom->forest_root == main_dom); } /* Parent domain is an AD forest root and there are two subdomains * child and parallel */ static void test_sysdb_link_forest_root_ad(void **state) { errno_t ret; struct subdom_test_ctx *test_ctx = talloc_get_type(*state, struct subdom_test_ctx); struct sss_domain_info *main_dom; struct sss_domain_info *sub; struct sss_domain_info *child; const char *const child_dom[5] = { "child.test_sysdb_subdomains",/* name */ "CHILD.TEST_SYSDB_SUBDOMAINS",/* realm */ "CHILD", /* flat */ "S-1-2", /* sid */ TEST_FOREST }; /* forest */ const char *const sub_dom[5] = { "another.subdomain", /* name */ "ANOTHER.SUBDOMAIN", /* realm */ "ANOTHER", /* flat */ "S-1-3", /* sid */ TEST_FOREST }; /* forest */ ret = sysdb_master_domain_add_info(test_ctx->tctx->dom, TEST_REALM, TEST_FLAT_NAME, TEST_SID, TEST_FOREST); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, child_dom[0], child_dom[1], child_dom[2], child_dom[3], false, false, child_dom[4], 0); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, sub_dom[0], sub_dom[1], sub_dom[2], sub_dom[3], false, false, sub_dom[4], 0); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom); assert_int_equal(ret, EOK); /* Also update dom2 */ ret = sysdb_update_subdomains(test_ctx->tctx->dom->next); assert_int_equal(ret, EOK); assert_non_null(test_ctx->tctx->dom->forest_root); assert_true(test_ctx->tctx->dom->forest_root == test_ctx->tctx->dom); assert_string_equal(test_ctx->tctx->dom->name, TEST_DOM1_NAME); child = find_domain_by_name(test_ctx->tctx->dom, child_dom[0], true); assert_non_null(child->forest_root); assert_ptr_equal(child->forest_root, test_ctx->tctx->dom); sub = find_domain_by_name(test_ctx->tctx->dom, sub_dom[0], true); assert_non_null(sub->forest_root); assert_ptr_equal(sub->forest_root, test_ctx->tctx->dom); /* Another separate domain is a forest of its own */ main_dom = find_domain_by_name(test_ctx->tctx->dom, TEST_DOM2_NAME, true); assert_non_null(main_dom); assert_non_null(main_dom->forest_root); assert_true(main_dom->forest_root == main_dom); } /* Parent domain is an AD member domain connected to a root domain */ static void test_sysdb_link_forest_member_ad(void **state) { errno_t ret; struct subdom_test_ctx *test_ctx = talloc_get_type(*state, struct subdom_test_ctx); struct sss_domain_info *main_dom; struct sss_domain_info *sub; struct sss_domain_info *root; const char *const forest_root[5] = { test_ctx->tctx->dom->name, /* name */ TEST_FOREST, /* realm */ TEST_FLAT_NAME, /* flat */ TEST_SID, /* sid */ TEST_FOREST }; /* forest */ const char *const child_dom[5] = { "child.test_sysdb_subdomains",/* name */ "CHILD.TEST_SYSDB_SUBDOMAINS",/* realm */ "CHILD", /* flat */ "S-1-2", /* sid */ TEST_FOREST }; /* forest */ const char *const sub_dom[5] = { "another.subdomain", /* name */ "ANOTHER.SUBDOMAIN", /* realm */ "ANOTHER", /* flat */ "S-1-3", /* sid */ TEST_FOREST }; /* forest */ ret = sysdb_master_domain_add_info(test_ctx->tctx->dom, child_dom[1], child_dom[2], child_dom[3], TEST_FOREST); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, sub_dom[0], sub_dom[1], sub_dom[2], sub_dom[3], false, false, sub_dom[4], 0); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, forest_root[0], forest_root[1], forest_root[2], forest_root[3], false, false, forest_root[4], 0); assert_int_equal(ret, EOK); ret = sysdb_master_domain_update(test_ctx->tctx->dom); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom); assert_int_equal(ret, EOK); /* Also update dom2 */ ret = sysdb_master_domain_update(test_ctx->tctx->dom->next); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom->next); assert_int_equal(ret, EOK); /* Checks */ root = find_domain_by_name(test_ctx->tctx->dom, forest_root[0], true); assert_non_null(root->forest_root); assert_ptr_equal(root->forest_root, root); assert_non_null(test_ctx->tctx->dom->forest_root); assert_true(test_ctx->tctx->dom->forest_root == root); sub = find_domain_by_name(test_ctx->tctx->dom, sub_dom[0], true); assert_non_null(sub->forest_root); assert_ptr_equal(sub->forest_root, root); /* Another separate domain is a forest of its own */ main_dom = find_domain_by_name(test_ctx->tctx->dom, TEST_DOM2_NAME, true); assert_non_null(main_dom); assert_non_null(main_dom->forest_root); assert_true(main_dom->forest_root == main_dom); } /* Each parent domain has a subdomain. One parent domain is a root domain, * the other is not. */ static void test_sysdb_link_ad_multidom(void **state) { errno_t ret; struct subdom_test_ctx *test_ctx = talloc_get_type(*state, struct subdom_test_ctx); struct sss_domain_info *main_dom1; struct sss_domain_info *main_dom2; struct sss_domain_info *root; const char *const child_dom[5] = { "child.test_sysdb_subdomains",/* name */ "CHILD.TEST_SYSDB_SUBDOMAINS",/* realm */ "CHILD", /* flat */ "S-1-2", /* sid */ TEST_FOREST }; /* forest */ const char *const dom2_forest_root[5] = \ { "test_sysdb_subdomains_2", /* name */ TEST_FOREST2, /* realm */ "TEST2", /* flat */ TEST_SID2, /* sid */ TEST_FOREST2 }; /* forest */ main_dom1 = find_domain_by_name(test_ctx->tctx->dom, TEST_DOM1_NAME, true); main_dom2 = find_domain_by_name(test_ctx->tctx->dom, TEST_DOM2_NAME, true); ret = sysdb_master_domain_add_info(main_dom1, TEST_REALM, TEST_FLAT_NAME, TEST_SID, TEST_FOREST); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(main_dom1->sysdb, child_dom[0], child_dom[1], child_dom[2], child_dom[3], false, false, child_dom[4], 0); assert_int_equal(ret, EOK); ret = sysdb_master_domain_update(main_dom1); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(main_dom1); assert_int_equal(ret, EOK); ret = sysdb_master_domain_add_info(main_dom2, TEST_REALM2, TEST_FLAT_NAME2, TEST_SID2, TEST_FOREST2); assert_int_equal(ret, EOK); ret = sysdb_subdomain_store(main_dom2->sysdb, dom2_forest_root[0], dom2_forest_root[1], dom2_forest_root[2], dom2_forest_root[3], false, false, dom2_forest_root[4], 0); assert_int_equal(ret, EOK); ret = sysdb_master_domain_update(main_dom2); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(main_dom2); assert_int_equal(ret, EOK); main_dom1 = find_domain_by_name(test_ctx->tctx->dom, TEST_DOM1_NAME, true); assert_non_null(main_dom1); assert_non_null(main_dom1->forest_root); assert_true(main_dom1->forest_root == main_dom1); main_dom2 = find_domain_by_name(test_ctx->tctx->dom, TEST_DOM2_NAME, true); assert_non_null(main_dom1); assert_non_null(main_dom1->forest_root); assert_true(main_dom1->forest_root == main_dom1); root = find_domain_by_name(test_ctx->tctx->dom, dom2_forest_root[0], true); assert_non_null(root); assert_non_null(root->forest_root); assert_ptr_equal(root->forest_root, main_dom2); } static void test_try_to_find_expected_dn(void **state) { int ret; struct sysdb_attrs *result; struct sysdb_attrs *usr_attrs[10] = { NULL }; struct sss_domain_info *dom; struct subdom_test_ctx *test_ctx = talloc_get_type(*state, struct subdom_test_ctx); dom = find_domain_by_name(test_ctx->tctx->dom, "child2.test_sysdb_subdomains_2", true); assert_non_null(dom); usr_attrs[0] = sysdb_new_attrs(test_ctx); assert_non_null(usr_attrs[0]); ret = sysdb_attrs_add_string(usr_attrs[0], SYSDB_ORIG_DN, "uid=user,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2"); assert_int_equal(ret, EOK); ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, 0, NULL); assert_int_equal(ret, EINVAL); ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 1, &result); assert_int_equal(ret, ENOENT); ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 1, &result); assert_int_equal(ret, EOK); assert_ptr_equal(result, usr_attrs[0]); usr_attrs[1] = sysdb_new_attrs(test_ctx); assert_non_null(usr_attrs[1]); ret = sysdb_attrs_add_string(usr_attrs[1], SYSDB_ORIG_DN, "uid=user1,cn=abc,dc=child2,dc=test_sysdb_subdomains_2"); assert_int_equal(ret, EOK); usr_attrs[2] = sysdb_new_attrs(test_ctx); assert_non_null(usr_attrs[2]); ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN, "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2"); assert_int_equal(ret, EOK); ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result); assert_int_equal(ret, EOK); assert_ptr_equal(result, usr_attrs[1]); ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 3, &result); assert_int_equal(ret, EINVAL); /* Make sure cn=users match is preferred */ talloc_free(usr_attrs[2]); usr_attrs[2] = sysdb_new_attrs(test_ctx); assert_non_null(usr_attrs[2]); ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN, "uid=user2,cn=abc,cn=users,dc=child2,dc=test_sysdb_subdomains_2"); assert_int_equal(ret, EOK); ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result); assert_int_equal(ret, EOK); assert_ptr_equal(result, usr_attrs[2]); talloc_free(usr_attrs[0]); talloc_free(usr_attrs[1]); talloc_free(usr_attrs[2]); } int main(int argc, const char *argv[]) { int rv; int no_cleanup = 0; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0, _("Do not delete the test database after a test run"), NULL }, POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_sysdb_master_domain_ops, test_sysdb_subdom_setup, test_sysdb_subdom_teardown), cmocka_unit_test_setup_teardown(test_sysdb_subdomain_create, test_sysdb_subdom_setup, test_sysdb_subdom_teardown), cmocka_unit_test_setup_teardown(test_sysdb_link_forest_root_ipa, test_sysdb_subdom_setup, test_sysdb_subdom_teardown), cmocka_unit_test_setup_teardown(test_sysdb_link_forest_root_ad, test_sysdb_subdom_setup, test_sysdb_subdom_teardown), cmocka_unit_test_setup_teardown(test_sysdb_link_forest_member_ad, test_sysdb_subdom_setup, test_sysdb_subdom_teardown), cmocka_unit_test_setup_teardown(test_sysdb_link_ad_multidom, test_sysdb_subdom_setup, test_sysdb_subdom_teardown), cmocka_unit_test_setup_teardown(test_try_to_find_expected_dn, test_sysdb_subdom_setup, test_sysdb_subdom_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, LOCAL_SYSDB_FILE); test_dom_suite_setup(TESTS_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv == 0 && no_cleanup == 0) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, LOCAL_SYSDB_FILE); } return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_responder_cache_req.c0000644000000000000000000000007412703456111022711 xustar0030 atime=1460561751.656715648 30 ctime=1460561774.960794666 sssd-1.13.4/src/tests/cmocka/test_responder_cache_req.c0000644002412700241270000016320312703456111024365 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #include "db/sysdb.h" #include "responder/common/responder_cache_req.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_responder_cache_req_conf.ldb" #define TEST_DOM_NAME "responder_cache_req_test" #define TEST_ID_PROVIDER "ldap" #define TEST_USER_NAME "test-user" #define TEST_UPN "upn@upndomain.com" #define TEST_USER_ID 1000 #define TEST_GROUP_NAME "test-group" #define TEST_GROUP_ID 1000 #define TEST_USER_ID2 1001 #define TEST_USER_NAME2 "test_user2" #define TEST_GROUP_NAME2 "test_group2" #define TEST_GROUP_ID2 1001 #define TEST_USER_ID3 1002 #define TEST_USER_NAME3 "test_user3" #define TEST_GROUP_NAME3 "test_group3" #define TEST_GROUP_ID3 1002 #define TEST_USER_PREFIX "test*" #define new_single_domain_test(test) \ cmocka_unit_test_setup_teardown(test_ ## test, \ test_single_domain_setup, \ test_single_domain_teardown) #define new_multi_domain_test(test) \ cmocka_unit_test_setup_teardown(test_ ## test, \ test_multi_domain_setup, \ test_multi_domain_teardown) #define run_cache_req(ctx, send_fn, done_fn, dom, crp, lookup, expret) do { \ TALLOC_CTX *req_mem_ctx; \ struct tevent_req *req; \ errno_t ret; \ \ req_mem_ctx = talloc_new(global_talloc_context); \ check_leaks_push(req_mem_ctx); \ \ req = send_fn(req_mem_ctx, ctx->tctx->ev, ctx->rctx, \ ctx->ncache, 10, crp, \ (dom == NULL ? NULL : dom->name), lookup); \ assert_non_null(req); \ tevent_req_set_callback(req, done_fn, ctx); \ \ ret = test_ev_loop(ctx->tctx); \ assert_int_equal(ret, expret); \ assert_true(check_leaks_pop(req_mem_ctx)); \ \ talloc_free(req_mem_ctx); \ } while (0) struct cache_req_test_ctx { struct sss_test_ctx *tctx; struct resp_ctx *rctx; struct sss_nc_ctx *ncache; struct ldb_result *result; struct sss_domain_info *domain; char *name; bool dp_called; /* NOTE: Please, instead of adding new create_[user|group] bool, * use bitshift. */ bool create_user1; bool create_user2; bool create_group1; bool create_group2; }; const char *domains[] = {"responder_cache_req_test_a", "responder_cache_req_test_b", "responder_cache_req_test_c", "responder_cache_req_test_d", NULL}; struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version version[] = { { 0, NULL, NULL } }; return version; } static void cache_req_user_by_name_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_user_by_name_recv(ctx, req, &ctx->result, &ctx->domain, &ctx->name); talloc_zfree(req); ctx->tctx->done = true; } static void cache_req_user_by_id_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_user_by_id_recv(ctx, req, &ctx->result, &ctx->domain); talloc_zfree(req); ctx->tctx->done = true; } static void cache_req_group_by_name_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_group_by_name_recv(ctx, req, &ctx->result, &ctx->domain, &ctx->name); talloc_zfree(req); ctx->tctx->done = true; } static void cache_req_group_by_id_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_group_by_id_recv(ctx, req, &ctx->result, &ctx->domain); talloc_zfree(req); ctx->tctx->done = true; } static void prepare_concrete_user(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char* user_name, int user_id, int group_id, uint64_t timeout, time_t transaction_time) { struct sysdb_attrs *attrs; errno_t ret; attrs = sysdb_new_attrs(mem_ctx); assert_non_null(attrs); ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, TEST_UPN); assert_int_equal(ret, EOK); ret = sysdb_store_user(domain, user_name, "pwd", user_id, group_id, NULL, NULL, NULL, "cn=test-user,dc=test", attrs, NULL, timeout, transaction_time); assert_int_equal(ret, EOK); } static void prepare_user(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, uint64_t timeout, time_t transaction_time) { prepare_concrete_user(mem_ctx, domain, TEST_USER_NAME, TEST_USER_ID, TEST_GROUP_ID, timeout, transaction_time); } static void run_user_by_name(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, int cache_refresh_percent, errno_t exp_ret) { run_cache_req(test_ctx, cache_req_user_by_name_send, cache_req_user_by_name_test_done, domain, cache_refresh_percent, TEST_USER_NAME, exp_ret); } static void run_user_by_upn(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, int cache_refresh_percent, errno_t exp_ret) { run_cache_req(test_ctx, cache_req_user_by_name_send, cache_req_user_by_name_test_done, domain, cache_refresh_percent, TEST_UPN, exp_ret); } static void run_user_by_id(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, int cache_refresh_percent, errno_t exp_ret) { run_cache_req(test_ctx, cache_req_user_by_id_send, cache_req_user_by_id_test_done, domain, cache_refresh_percent, TEST_USER_ID, exp_ret); } static void check_user(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *exp_dom) { const char *ldbname; const char *ldbupn; uid_t ldbuid; assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); assert_non_null(test_ctx->result->msgs); assert_non_null(test_ctx->result->msgs[0]); ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0], SYSDB_NAME, NULL); assert_non_null(ldbname); assert_string_equal(ldbname, TEST_USER_NAME); ldbupn = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0], SYSDB_UPN, NULL); assert_non_null(ldbupn); assert_string_equal(ldbupn, TEST_UPN); ldbuid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0], SYSDB_UIDNUM, 0); assert_int_equal(ldbuid, TEST_USER_ID); assert_non_null(test_ctx->domain); assert_string_equal(exp_dom->name, test_ctx->domain->name); } static void prepare_group(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, uint64_t timeout, time_t transaction_time) { errno_t ret; ret = sysdb_store_group(domain, TEST_GROUP_NAME, TEST_GROUP_ID, NULL, timeout, transaction_time); assert_int_equal(ret, EOK); } static void run_group_by_name(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, int cache_refresh_percent, errno_t exp_ret) { run_cache_req(test_ctx, cache_req_group_by_name_send, cache_req_group_by_name_test_done, domain, cache_refresh_percent, TEST_GROUP_NAME, exp_ret); } static void run_group_by_id(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, int cache_refresh_percent, errno_t exp_ret) { run_cache_req(test_ctx, cache_req_group_by_id_send, cache_req_group_by_id_test_done, domain, cache_refresh_percent, TEST_GROUP_ID, exp_ret); } static void check_group(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *exp_dom) { const char *ldbname; gid_t ldbgid; assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); assert_non_null(test_ctx->result->msgs); assert_non_null(test_ctx->result->msgs[0]); ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0], SYSDB_NAME, NULL); assert_non_null(ldbname); assert_string_equal(ldbname, TEST_GROUP_NAME); ldbgid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0], SYSDB_GIDNUM, 0); assert_int_equal(ldbgid, TEST_USER_ID); assert_non_null(test_ctx->domain); assert_string_equal(exp_dom->name, test_ctx->domain->name); } struct tevent_req * __wrap_sss_dp_get_account_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, bool fast_reply, enum sss_dp_acct_type type, const char *opt_name, uint32_t opt_id, const char *extra) { struct cache_req_test_ctx *ctx = NULL; errno_t ret; ctx = sss_mock_ptr_type(struct cache_req_test_ctx*); ctx->dp_called = true; if (ctx->create_user1) { prepare_user(ctx, ctx->tctx->dom, 1000, time(NULL)); } if (ctx->create_user2) { prepare_concrete_user(mem_ctx, ctx->tctx->dom, TEST_USER_NAME2, TEST_USER_ID2, TEST_GROUP_ID2, 1000, time(NULL)); } if (ctx->create_group1) { ret = sysdb_store_group(ctx->tctx->dom, TEST_GROUP_NAME, TEST_GROUP_ID, NULL, 1000, time(NULL)); assert_int_equal(ret, EOK); } if (ctx->create_group2) { ret = sysdb_store_group(ctx->tctx->dom, TEST_GROUP_NAME2, TEST_GROUP_ID2, NULL, 1000, time(NULL)); assert_int_equal(ret, EOK); } return test_req_succeed_send(mem_ctx, rctx->ev); } static int test_single_domain_setup(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; test_dom_suite_setup(TESTS_PATH); test_ctx = talloc_zero(NULL, struct cache_req_test_ctx); assert_non_null(test_ctx); *state = test_ctx; test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, TEST_ID_PROVIDER, NULL); assert_non_null(test_ctx->tctx); test_ctx->rctx = mock_rctx(test_ctx, test_ctx->tctx->ev, test_ctx->tctx->dom, NULL); assert_non_null(test_ctx->rctx); ret = sss_ncache_init(test_ctx, &test_ctx->ncache); assert_int_equal(ret, EOK); return 0; } static int test_single_domain_teardown(void **state) { talloc_zfree(*state); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); return 0; } static int test_multi_domain_setup(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; test_dom_suite_setup(TESTS_PATH); test_ctx = talloc_zero(NULL, struct cache_req_test_ctx); assert_non_null(test_ctx); *state = test_ctx; test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, domains, TEST_ID_PROVIDER, NULL); assert_non_null(test_ctx->tctx); test_ctx->rctx = mock_rctx(test_ctx, test_ctx->tctx->ev, test_ctx->tctx->dom, NULL); assert_non_null(test_ctx->rctx); ret = sss_ncache_init(test_ctx, &test_ctx->ncache); assert_int_equal(ret, EOK); return 0; } static int test_multi_domain_teardown(void **state) { talloc_zfree(*state); test_multidom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, domains); return 0; } void test_user_by_name_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(test_ctx, domain, 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(TEST_USER_NAME, NULL, ERR_OK); /* Test. */ run_user_by_name(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, domain); } void test_user_by_name_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(TEST_USER_NAME, NULL, ERR_OK); /* Test. */ run_user_by_name(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_name_multiple_domains_parse(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; const char *name = TEST_USER_NAME; const char *fqn = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Add user to the first domain with different uid then test user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_a", true); assert_non_null(domain); ret = sysdb_store_user(domain, name, "pwd", 2000, 1000, NULL, NULL, NULL, "cn=test-user,dc=test", NULL, NULL, 1000, time(NULL)); assert_int_equal(ret, EOK); /* Add test user to the last domain. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(test_ctx, domain, 1000, time(NULL)); /* Append domain name to the username. */ fqn = talloc_asprintf(test_ctx, "%s@%s", name, "responder_cache_req_test_d"); assert_non_null(fqn); /* Mock values. */ mock_parse_inp(name, "responder_cache_req_test_d", ERR_OK); /* Test. */ req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->ncache, 10, 0, NULL, fqn); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_false(test_ctx->dp_called); check_user(test_ctx, domain); assert_non_null(test_ctx->name); assert_string_equal(name, test_ctx->name); } void test_user_by_name_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx, test_ctx->tctx->dom, 1000, time(NULL)); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_name_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx, test_ctx->tctx->dom, -1000, time(NULL)); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_name_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx, test_ctx->tctx->dom, 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 50, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_name_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ ret = sss_ncache_set_user(test_ctx->ncache, false, test_ctx->tctx->dom, TEST_USER_NAME); assert_int_equal(ret, EOK); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_user_by_name_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); test_ctx->create_user1 = true; test_ctx->create_user2 = false; /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_name_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_upn_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(test_ctx, domain, 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, domain); } void test_user_by_upn_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_upn_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx, test_ctx->tctx->dom, 1000, time(NULL)); /* Mock values. */ mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ERR_OK); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_upn_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx, test_ctx->tctx->dom, -1000, time(NULL)); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_upn_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx, test_ctx->tctx->dom, 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 50, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_upn_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ ret = sss_ncache_set_user(test_ctx->ncache, false, test_ctx->tctx->dom, TEST_UPN); assert_int_equal(ret, EOK); /* Mock values. */ mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_user_by_upn_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); test_ctx->create_user1 = true; test_ctx->create_user2 = false; /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_upn_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_id_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(test_ctx, domain, 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); /* Test. */ run_user_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, domain); } void test_user_by_id_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); /* Test. */ run_user_by_id(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_id_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx, test_ctx->tctx->dom, 1000, time(NULL)); /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_id_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx, test_ctx->tctx->dom, -1000, time(NULL)); /* Mock values. */ /* DP should be contacted. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_id_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx, test_ctx->tctx->dom, 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 50, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_id_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ ret = sss_ncache_set_uid(test_ctx->ncache, false, NULL, TEST_USER_ID); assert_int_equal(ret, EOK); /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_user_by_id_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); test_ctx->create_user1 = true; test_ctx->create_user2 = false; /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, test_ctx->tctx->dom); } void test_user_by_id_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_group_by_name_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_group(test_ctx, domain, 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(TEST_GROUP_NAME, NULL, ERR_OK); /* Test. */ run_group_by_name(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, domain); } void test_group_by_name_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(TEST_GROUP_NAME, NULL, ERR_OK); /* Test. */ run_group_by_name(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_group_by_name_multiple_domains_parse(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; const char *name = TEST_GROUP_NAME; const char *fqn = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Add group to the first domain. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_a", true); assert_non_null(domain); ret = sysdb_store_group(domain, name, 2000, NULL, 1000, time(NULL)); assert_int_equal(ret, EOK); /* Add group to the last domain, with different gid. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_group(test_ctx, domain, 1000, time(NULL)); /* Append domain name to the username. */ fqn = talloc_asprintf(test_ctx, "%s@%s", name, "responder_cache_req_test_d"); assert_non_null(fqn); /* Test. */ req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); mock_parse_inp(name, "responder_cache_req_test_d", ERR_OK); req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->ncache, 10, 0, NULL, fqn); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_name_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_false(test_ctx->dp_called); check_group(test_ctx, domain); assert_non_null(test_ctx->name); assert_string_equal(name, test_ctx->name); } void test_group_by_name_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx, test_ctx->tctx->dom, 1000, time(NULL)); /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); check_group(test_ctx, test_ctx->tctx->dom); } void test_group_by_name_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx, test_ctx->tctx->dom, -1000, time(NULL)); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, test_ctx->tctx->dom); } void test_group_by_name_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx, test_ctx->tctx->dom, 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 50, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, test_ctx->tctx->dom); } void test_group_by_name_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ ret = sss_ncache_set_group(test_ctx->ncache, false, test_ctx->tctx->dom, TEST_GROUP_NAME); assert_int_equal(ret, EOK); /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_group_by_name_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); test_ctx->create_group1 = true; test_ctx->create_group2 = false; /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, test_ctx->tctx->dom); } void test_group_by_name_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_group_by_id_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_group(test_ctx, domain, 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); /* Test. */ run_group_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, domain); } void test_group_by_id_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); /* Test. */ run_group_by_id(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_group_by_id_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx, test_ctx->tctx->dom, 1000, time(NULL)); /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); check_group(test_ctx, test_ctx->tctx->dom); } void test_group_by_id_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx, test_ctx->tctx->dom, -1000, time(NULL)); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, test_ctx->tctx->dom); } void test_group_by_id_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx, test_ctx->tctx->dom, 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 50, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, test_ctx->tctx->dom); } void test_group_by_id_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ ret = sss_ncache_set_gid(test_ctx->ncache, false, NULL, TEST_GROUP_ID); assert_int_equal(ret, EOK); /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_group_by_id_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); test_ctx->create_group1 = true; test_ctx->create_group2 = false; /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, test_ctx->tctx->dom); } void test_group_by_id_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_true(test_ctx->dp_called); } static void cache_req_user_by_filter_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_user_by_filter_recv(ctx, req, &ctx->result, &ctx->domain); talloc_zfree(req); ctx->tctx->done = true; } void test_user_by_recent_filter_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; const char *ldbname = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_user1 = true; test_ctx->create_user2 = false; ret = sysdb_store_user(test_ctx->tctx->dom, TEST_USER_NAME2, "pwd", 1001, 1001, NULL, NULL, NULL, "cn="TEST_USER_NAME2",dc=test", NULL, NULL, 1000, time(NULL)-1); assert_int_equal(ret, EOK); req_mem_ctx = talloc_new(test_ctx->tctx); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* User TEST_USER is created with a DP callback. */ req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->tctx->dom->name, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0], SYSDB_NAME, NULL); assert_non_null(ldbname); assert_string_equal(ldbname, TEST_USER_NAME); } void test_users_by_recent_filter_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; const char **user_names = NULL; const char **ldb_results = NULL; const char *ldbname = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_user1 = true; test_ctx->create_user2 = true; ret = sysdb_store_user(test_ctx->tctx->dom, TEST_USER_NAME3, "pwd", 1002, 1002, NULL, NULL, NULL, "cn="TEST_USER_NAME3",dc=test", NULL, NULL, 1000, time(NULL)-1); assert_int_equal(ret, EOK); req_mem_ctx = talloc_new(test_ctx->tctx); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* User TEST_USER1 and TEST_USER2 are created with a DP callback. */ req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->tctx->dom->name, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 2); user_names = talloc_array(test_ctx, const char *, 2); assert_non_null(user_names); user_names[0] = TEST_USER_NAME; user_names[1] = TEST_USER_NAME2; ldb_results = talloc_array(test_ctx, const char *, 2); assert_non_null(ldb_results); for (int i = 0; i < 2; ++i) { ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[i], SYSDB_NAME, NULL); assert_non_null(ldbname); ldb_results[i] = ldbname; } assert_string_not_equal(ldb_results[0], ldb_results[1]); assert_true(tc_are_values_in_array(user_names, ldb_results)); } void test_users_by_filter_filter_old(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; const char *ldbname = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_user1 = true; test_ctx->create_user2 = false; /* This user was updated in distant past, so it wont't be reported by * the filter search */ ret = sysdb_store_user(test_ctx->tctx->dom, TEST_USER_NAME2, "pwd", 1001, 1001, NULL, NULL, NULL, "cn="TEST_USER_NAME2",dc=test", NULL, NULL, 1000, 1); assert_int_equal(ret, EOK); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->tctx->dom->name, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0], SYSDB_NAME, NULL); assert_non_null(ldbname); assert_string_equal(ldbname, TEST_USER_NAME); } void test_users_by_filter_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->tctx->dom->name, "nosuchuser*"); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_true(check_leaks_pop(req_mem_ctx)); } static void test_users_by_filter_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, domain->name, "nosuchuser*"); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_true(check_leaks_pop(req_mem_ctx)); } static void cache_req_group_by_filter_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_group_by_filter_recv(ctx, req, &ctx->result, &ctx->domain); talloc_zfree(req); ctx->tctx->done = true; } void test_group_by_recent_filter_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; const char *ldbname = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_group1 = true; test_ctx->create_group2 = false; ret = sysdb_store_group(test_ctx->tctx->dom, TEST_GROUP_NAME2, 1001, NULL, 1001, time(NULL)-1); assert_int_equal(ret, EOK); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Group TEST_GROUP is created with a DP callback. */ req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->tctx->dom->name, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0], SYSDB_NAME, NULL); assert_non_null(ldbname); assert_string_equal(ldbname, TEST_GROUP_NAME); } void test_groups_by_recent_filter_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; TALLOC_CTX *tmp_ctx = NULL; struct tevent_req *req = NULL; const char **group_names = NULL; const char **ldb_results = NULL; const char *ldbname = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_group1 = true; test_ctx->create_group2 = true; ret = sysdb_store_group(test_ctx->tctx->dom, TEST_GROUP_NAME2, 1001, NULL, 1001, time(NULL)-1); assert_int_equal(ret, EOK); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Group TEST_GROUP1 and TEST_GROUP2 are created with a DP callback. */ req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->tctx->dom->name, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 2); tmp_ctx = talloc_new(req_mem_ctx); group_names = talloc_array(tmp_ctx, const char *, 2); assert_non_null(group_names); group_names[0] = TEST_GROUP_NAME; group_names[1] = TEST_GROUP_NAME2; ldb_results = talloc_array(tmp_ctx, const char *, 2); assert_non_null(ldb_results); for (int i = 0; i < 2; ++i) { ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[i], SYSDB_NAME, NULL); assert_non_null(ldbname); ldb_results[i] = ldbname; } assert_string_not_equal(ldb_results[0], ldb_results[1]); assert_true(tc_are_values_in_array(group_names, ldb_results)); talloc_zfree(tmp_ctx); } void test_groups_by_filter_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->tctx->dom->name, "nosuchgroup*"); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_true(check_leaks_pop(req_mem_ctx)); } void test_groups_by_filter_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, domain->name, "nosuchgroup*"); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_true(check_leaks_pop(req_mem_ctx)); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { new_single_domain_test(user_by_name_cache_valid), new_single_domain_test(user_by_name_cache_expired), new_single_domain_test(user_by_name_cache_midpoint), new_single_domain_test(user_by_name_ncache), new_single_domain_test(user_by_name_missing_found), new_single_domain_test(user_by_name_missing_notfound), new_multi_domain_test(user_by_name_multiple_domains_found), new_multi_domain_test(user_by_name_multiple_domains_notfound), new_multi_domain_test(user_by_name_multiple_domains_parse), new_single_domain_test(user_by_upn_cache_valid), new_single_domain_test(user_by_upn_cache_expired), new_single_domain_test(user_by_upn_cache_midpoint), new_single_domain_test(user_by_upn_ncache), new_single_domain_test(user_by_upn_missing_found), new_single_domain_test(user_by_upn_missing_notfound), new_multi_domain_test(user_by_upn_multiple_domains_found), new_multi_domain_test(user_by_upn_multiple_domains_notfound), new_single_domain_test(user_by_id_cache_valid), new_single_domain_test(user_by_id_cache_expired), new_single_domain_test(user_by_id_cache_midpoint), new_single_domain_test(user_by_id_ncache), new_single_domain_test(user_by_id_missing_found), new_single_domain_test(user_by_id_missing_notfound), new_multi_domain_test(user_by_id_multiple_domains_found), new_multi_domain_test(user_by_id_multiple_domains_notfound), new_single_domain_test(group_by_name_cache_valid), new_single_domain_test(group_by_name_cache_expired), new_single_domain_test(group_by_name_cache_midpoint), new_single_domain_test(group_by_name_ncache), new_single_domain_test(group_by_name_missing_found), new_single_domain_test(group_by_name_missing_notfound), new_multi_domain_test(group_by_name_multiple_domains_found), new_multi_domain_test(group_by_name_multiple_domains_notfound), new_multi_domain_test(group_by_name_multiple_domains_parse), new_single_domain_test(group_by_id_cache_valid), new_single_domain_test(group_by_id_cache_expired), new_single_domain_test(group_by_id_cache_midpoint), new_single_domain_test(group_by_id_ncache), new_single_domain_test(group_by_id_missing_found), new_single_domain_test(group_by_id_missing_notfound), new_multi_domain_test(group_by_id_multiple_domains_found), new_multi_domain_test(group_by_id_multiple_domains_notfound), new_single_domain_test(user_by_recent_filter_valid), new_single_domain_test(users_by_recent_filter_valid), new_single_domain_test(group_by_recent_filter_valid), new_single_domain_test(groups_by_recent_filter_valid), new_single_domain_test(users_by_filter_filter_old), new_single_domain_test(users_by_filter_notfound), new_multi_domain_test(users_by_filter_multiple_domains_notfound), new_single_domain_test(groups_by_filter_notfound), new_multi_domain_test(groups_by_filter_multiple_domains_notfound), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_multidom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, domains); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_fqnames.c0000644000000000000000000000007412703456111020350 xustar0030 atime=1460561751.656715648 30 ctime=1460561774.921794534 sssd-1.13.4/src/tests/cmocka/test_fqnames.c0000644002412700241270000004621412703456111022026 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat SSSD tests: Fully Qualified Names Tests This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "db/sysdb_private.h" #include "tests/cmocka/common_mock.h" #define NAME "name" #define DOMNAME "domname" #define FLATNAME "flatname" #define SPECIALNAME "[]{}();:'|\",<.>/?!#$%^&*_+~`" #define PROVIDER "local" #define CONNNAME "conn" #define DOMNAME2 "domname2" #define FLATNAME2 "flatname2" #define SUBDOMNAME "subdomname" #define SUBFLATNAME "subflatname" static struct sss_domain_info *create_test_domain(TALLOC_CTX *mem_ctx, const char *name, const char *flatname, struct sss_domain_info *parent, struct sss_names_ctx *nctx) { struct sss_domain_info *dom; dom = talloc_zero(mem_ctx, struct sss_domain_info); assert_non_null(dom); /* just to make new_subdomain happy */ dom->sysdb = talloc_zero(dom, struct sysdb_ctx); assert_non_null(dom->sysdb); dom->name = discard_const(name); dom->flat_name = discard_const(flatname); dom->parent = parent; dom->names = nctx; dom->provider = discard_const(PROVIDER); dom->conn_name = discard_const(CONNNAME); return dom; } struct fqdn_test_ctx { struct sss_domain_info *dom; struct sss_names_ctx *nctx; }; static int fqdn_test_setup(void **state) { struct fqdn_test_ctx *test_ctx; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct fqdn_test_ctx); assert_non_null(test_ctx); test_ctx->dom = create_test_domain(test_ctx, DOMNAME, FLATNAME, NULL, NULL); check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int fqdn_test_teardown(void **state) { struct fqdn_test_ctx *test_ctx = talloc_get_type(*state, struct fqdn_test_ctx); if (test_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); return 1; } assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } void test_default(void **state) { struct fqdn_test_ctx *test_ctx = talloc_get_type(*state, struct fqdn_test_ctx); errno_t ret; char *fqdn; const int fqdn_size = 255; char fqdn_s[fqdn_size]; if (test_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); return; } ret = sss_names_init_from_args(test_ctx, "(?P[^@]+)@?(?P[^@]*$)", "%1$s@%2$s", &test_ctx->nctx); assert_int_equal(ret, EOK); fqdn = sss_tc_fqname(test_ctx, test_ctx->nctx, test_ctx->dom, NAME); assert_non_null(fqdn); assert_string_equal(fqdn, NAME"@"DOMNAME); talloc_free(fqdn); ret = sss_fqname(fqdn_s, fqdn_size, test_ctx->nctx, test_ctx->dom, NAME); assert_int_equal(ret + 1, sizeof(NAME"@"DOMNAME)); assert_string_equal(fqdn_s, NAME"@"DOMNAME); talloc_free(test_ctx->nctx); } void test_all(void **state) { struct fqdn_test_ctx *test_ctx = talloc_get_type(*state, struct fqdn_test_ctx); errno_t ret; char *fqdn; const int fqdn_size = 255; char fqdn_s[fqdn_size]; if (test_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); return; } ret = sss_names_init_from_args(test_ctx, "(?P[^@]+)@?(?P[^@]*$)", "%1$s@%2$s@%3$s", &test_ctx->nctx); assert_int_equal(ret, EOK); fqdn = sss_tc_fqname(test_ctx, test_ctx->nctx, test_ctx->dom, NAME); assert_non_null(fqdn); assert_string_equal(fqdn, NAME"@"DOMNAME"@"FLATNAME); talloc_free(fqdn); ret = sss_fqname(fqdn_s, fqdn_size, test_ctx->nctx, test_ctx->dom, NAME); assert_int_equal(ret + 1, sizeof(NAME"@"DOMNAME"@"FLATNAME)); assert_string_equal(fqdn_s, NAME"@"DOMNAME"@"FLATNAME); talloc_free(test_ctx->nctx); } void test_flat(void **state) { struct fqdn_test_ctx *test_ctx = talloc_get_type(*state, struct fqdn_test_ctx); errno_t ret; char *fqdn; const int fqdn_size = 255; char fqdn_s[fqdn_size]; if (test_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); return; } ret = sss_names_init_from_args(test_ctx, "(?P[^@]+)@?(?P[^@]*$)", "%1$s@%3$s", &test_ctx->nctx); assert_int_equal(ret, EOK); fqdn = sss_tc_fqname(test_ctx, test_ctx->nctx, test_ctx->dom, NAME); assert_non_null(fqdn); assert_string_equal(fqdn, NAME"@"FLATNAME); talloc_free(fqdn); ret = sss_fqname(fqdn_s, fqdn_size, test_ctx->nctx, test_ctx->dom, NAME); assert_int_equal(ret + 1, sizeof(NAME"@"FLATNAME)); assert_string_equal(fqdn_s, NAME"@"FLATNAME); talloc_free(test_ctx->nctx); } void test_flat_fallback(void **state) { struct fqdn_test_ctx *test_ctx = talloc_get_type(*state, struct fqdn_test_ctx); errno_t ret; char *fqdn; const int fqdn_size = 255; char fqdn_s[fqdn_size]; if (test_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); return; } ret = sss_names_init_from_args(test_ctx, "(?P[^@]+)@?(?P[^@]*$)", "%1$s@%3$s", &test_ctx->nctx); assert_int_equal(ret, EOK); test_ctx->dom->flat_name = NULL; /* If flat name is requested but does not exist, the code falls back to domain * name */ fqdn = sss_tc_fqname(test_ctx, test_ctx->nctx, test_ctx->dom, NAME); assert_non_null(fqdn); assert_string_equal(fqdn, NAME"@"DOMNAME); talloc_free(fqdn); ret = sss_fqname(fqdn_s, fqdn_size, test_ctx->nctx, test_ctx->dom, NAME); assert_int_equal(ret + 1, sizeof(NAME"@"DOMNAME)); assert_string_equal(fqdn_s, NAME"@"DOMNAME); talloc_free(test_ctx->nctx); } struct parse_name_test_ctx { struct sss_domain_info *dom; struct sss_domain_info *subdom; struct sss_names_ctx *nctx; }; void parse_name_check(struct parse_name_test_ctx *test_ctx, const char *full_name, const char *default_domain, const char exp_ret, const char *exp_name, const char *exp_domain) { errno_t ret; char *domain = NULL; char *name = NULL; check_leaks_push(test_ctx); ret = sss_parse_name_for_domains(test_ctx, test_ctx->dom, default_domain, full_name, &domain, &name); assert_int_equal(ret, exp_ret); if (exp_name) { assert_non_null(name); assert_string_equal(name, exp_name); } if (exp_domain) { assert_non_null(domain); assert_string_equal(domain, exp_domain); } talloc_free(name); talloc_free(domain); assert_true(check_leaks_pop(test_ctx) == true); } static int parse_name_test_setup(void **state) { struct parse_name_test_ctx *test_ctx; struct sss_domain_info *dom; errno_t ret; assert_true(leak_check_setup()); test_ctx = talloc_zero(global_talloc_context, struct parse_name_test_ctx); assert_non_null(test_ctx); /* Init with an AD-style regex to be able to test flat name */ ret = sss_names_init_from_args(test_ctx, "(((?P[^\\\\]+)\\\\(?P.+$))|" \ "((?P[^@]+)@(?P.+$))|" \ "(^(?P[^@\\\\]+)$))", "%1$s@%2$s", &test_ctx->nctx); assert_int_equal(ret, EOK); /* The setup is two domains, first one with no subdomains, * second one with a single subdomain */ dom = create_test_domain(test_ctx, DOMNAME, FLATNAME, NULL, test_ctx->nctx); assert_non_null(dom); DLIST_ADD_END(test_ctx->dom, dom, struct sss_domain_info *); dom = create_test_domain(test_ctx, DOMNAME2, FLATNAME2, NULL, test_ctx->nctx); assert_non_null(dom); DLIST_ADD_END(test_ctx->dom, dom, struct sss_domain_info *); /* Create the subdomain, but don't add it yet, we want to be able to * test sss_parse_name_for_domains() signaling that domains must be * discovered */ test_ctx->subdom = new_subdomain(dom, dom, SUBDOMNAME, NULL, SUBFLATNAME, NULL, false, false, NULL, 0); assert_non_null(test_ctx->subdom); check_leaks_push(test_ctx); *state = test_ctx; return 0; } static int parse_name_test_teardown(void **state) { struct parse_name_test_ctx *test_ctx = talloc_get_type(*state, struct parse_name_test_ctx); assert_true(check_leaks_pop(test_ctx) == true); talloc_free(test_ctx); assert_true(leak_check_teardown()); return 0; } void sss_parse_name_check(struct parse_name_test_ctx *test_ctx, const char *input_name, const int exp_ret, const char *exp_name, const char *exp_domain) { errno_t ret; char *domain = NULL; char *name = NULL; const char *domain_const = NULL; const char *name_const = NULL; check_leaks_push(test_ctx); ret = sss_parse_name(test_ctx, test_ctx->nctx, input_name, &domain, &name); assert_int_equal(ret, exp_ret); if (exp_name) { assert_non_null(name); assert_string_equal(name, exp_name); } if (exp_domain) { assert_non_null(domain); assert_string_equal(domain, exp_domain); } talloc_zfree(name); talloc_zfree(domain); ret = sss_parse_name_const(test_ctx, test_ctx->nctx, input_name, &domain_const, &name_const); assert_int_equal(ret, exp_ret); if (exp_name) { assert_non_null(name_const); assert_string_equal(name_const, exp_name); } if (exp_domain) { assert_non_null(domain_const); assert_string_equal(domain_const, exp_domain); } talloc_free(discard_const(name_const)); talloc_free(discard_const(domain_const)); assert_true(check_leaks_pop(test_ctx) == true); } void parse_name_plain(void **state) { struct parse_name_test_ctx *test_ctx = talloc_get_type(*state, struct parse_name_test_ctx); int ret; parse_name_check(test_ctx, NAME, NULL, EOK, NAME, NULL); ret = sss_parse_name(test_ctx, test_ctx->nctx, NAME, NULL, NULL); assert_int_equal(ret, EOK); ret = sss_parse_name_const(test_ctx, test_ctx->nctx, NAME, NULL, NULL); assert_int_equal(ret, EOK); sss_parse_name_check(test_ctx, NAME, EOK, NAME, NULL); sss_parse_name_check(test_ctx, SPECIALNAME, EOK, SPECIALNAME, NULL); } void parse_name_fqdn(void **state) { struct parse_name_test_ctx *test_ctx = talloc_get_type(*state, struct parse_name_test_ctx); parse_name_check(test_ctx, NAME"@"DOMNAME, NULL, EOK, NAME, DOMNAME); parse_name_check(test_ctx, NAME"@"DOMNAME2, NULL, EOK, NAME, DOMNAME2); sss_parse_name_check(test_ctx, NAME"@"DOMNAME, EOK, NAME, DOMNAME); sss_parse_name_check(test_ctx, NAME"@"DOMNAME2, EOK, NAME, DOMNAME2); sss_parse_name_check(test_ctx, DOMNAME"\\"NAME, EOK, NAME, DOMNAME); sss_parse_name_check(test_ctx, DOMNAME2"\\"NAME, EOK, NAME, DOMNAME2); } void parse_name_sub(void **state) { struct parse_name_test_ctx *test_ctx = talloc_get_type(*state, struct parse_name_test_ctx); /* The subdomain name is valid, but not known */ parse_name_check(test_ctx, NAME"@"SUBDOMNAME, NULL, EAGAIN, NULL, NULL); /* Link the subdomain (simulating subdom handler) and retry */ test_ctx->dom->subdomains = test_ctx->subdom; parse_name_check(test_ctx, NAME"@"SUBDOMNAME, NULL, EOK, NAME, SUBDOMNAME); } void parse_name_flat(void **state) { struct parse_name_test_ctx *test_ctx = talloc_get_type(*state, struct parse_name_test_ctx); /* Link the subdomain (simulating subdom handler) */ parse_name_check(test_ctx, FLATNAME"\\"NAME, NULL, EOK, NAME, DOMNAME); parse_name_check(test_ctx, FLATNAME2"\\"NAME, NULL, EOK, NAME, DOMNAME2); /* The subdomain name is valid, but not known */ parse_name_check(test_ctx, SUBFLATNAME"\\"NAME, NULL, EAGAIN, NULL, NULL); test_ctx->dom->subdomains = test_ctx->subdom; parse_name_check(test_ctx, SUBFLATNAME"\\"NAME, NULL, EOK, NAME, SUBDOMNAME); } void parse_name_default(void **state) { struct parse_name_test_ctx *test_ctx = talloc_get_type(*state, struct parse_name_test_ctx); struct sss_domain_info *dom2; parse_name_check(test_ctx, NAME, DOMNAME2, EOK, NAME, DOMNAME2); dom2 = test_ctx->dom->next; /* Simulate uknown default domain */ DLIST_REMOVE(test_ctx->dom, dom2); parse_name_check(test_ctx, NAME, DOMNAME2, EAGAIN, NULL, NULL); } void test_init_nouser(void **state) { struct fqdn_test_ctx *test_ctx = talloc_get_type(*state, struct fqdn_test_ctx); errno_t ret; if (test_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Type mismatch\n"); return; } ret = sss_names_init_from_args(test_ctx, "(?P[^@]+)@?(?P[^@]*$)", "%2$s@%3$s", &test_ctx->nctx); /* Initialization with no user name must fail */ assert_int_not_equal(ret, EOK); } void sss_parse_name_fail(void **state) { struct parse_name_test_ctx *test_ctx = talloc_get_type(*state, struct parse_name_test_ctx); sss_parse_name_check(test_ctx, "", ERR_REGEX_NOMATCH, NULL, NULL); sss_parse_name_check(test_ctx, "@", ERR_REGEX_NOMATCH, NULL, NULL); sss_parse_name_check(test_ctx, "\\", ERR_REGEX_NOMATCH, NULL, NULL); sss_parse_name_check(test_ctx, "\\"NAME, ERR_REGEX_NOMATCH, NULL, NULL); sss_parse_name_check(test_ctx, "@"NAME, ERR_REGEX_NOMATCH, NULL, NULL); sss_parse_name_check(test_ctx, NAME"@", ERR_REGEX_NOMATCH, NULL, NULL); sss_parse_name_check(test_ctx, NAME"\\", ERR_REGEX_NOMATCH, NULL, NULL); } void test_sss_get_domain_name(void **state) { struct parse_name_test_ctx *test_ctx = talloc_get_type(*state, struct parse_name_test_ctx); struct { const char *input; struct sss_domain_info *domain; const char *expected; } data[] = {{"user", test_ctx->dom, "user"}, {"user", test_ctx->subdom, "user@" SUBDOMNAME}, {"user@" SUBDOMNAME, test_ctx->subdom, "user@" SUBDOMNAME}, {NULL, NULL, NULL}}; char *name; int i; for (i = 0; data[i].input != NULL; i++) { name = sss_get_domain_name(test_ctx, data[i].input, data[i].domain); assert_non_null(name); assert_string_equal(name, data[i].expected); talloc_free(name); } } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_default, fqdn_test_setup, fqdn_test_teardown), cmocka_unit_test_setup_teardown(test_all, fqdn_test_setup, fqdn_test_teardown), cmocka_unit_test_setup_teardown(test_flat, fqdn_test_setup, fqdn_test_teardown), cmocka_unit_test_setup_teardown(test_flat_fallback, fqdn_test_setup, fqdn_test_teardown), cmocka_unit_test_setup_teardown(test_init_nouser, fqdn_test_setup, fqdn_test_teardown), cmocka_unit_test_setup_teardown(parse_name_plain, parse_name_test_setup, parse_name_test_teardown), cmocka_unit_test_setup_teardown(parse_name_fqdn, parse_name_test_setup, parse_name_test_teardown), cmocka_unit_test_setup_teardown(parse_name_sub, parse_name_test_setup, parse_name_test_teardown), cmocka_unit_test_setup_teardown(parse_name_flat, parse_name_test_setup, parse_name_test_teardown), cmocka_unit_test_setup_teardown(parse_name_default, parse_name_test_setup, parse_name_test_teardown), cmocka_unit_test_setup_teardown(sss_parse_name_fail, parse_name_test_setup, parse_name_test_teardown), cmocka_unit_test_setup_teardown(test_sss_get_domain_name, parse_name_test_setup, parse_name_test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_resolv_fake.c0000644000000000000000000000007412703456111021216 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.045794955 sssd-1.13.4/src/tests/cmocka/test_resolv_fake.c0000644002412700241270000002421412703456111022670 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat SSSD tests: Resolver tests using a fake resolver library This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #define TEST_BUFSIZE 1024 #define TEST_DEFAULT_TIMEOUT 5 #define TEST_SRV_QUERY "_ldap._tcp.sssd.com" static TALLOC_CTX *global_mock_context = NULL; struct srv_rrdata { uint16_t port; uint16_t prio; uint16_t weight; uint32_t ttl; const char *hostname; }; static ssize_t dns_header(unsigned char **buf, size_t ancount) { uint8_t *hb; HEADER h; hb = *buf; memset(hb, 0, NS_HFIXEDSZ); memset(&h, 0, sizeof(h)); h.id = res_randomid(); /* random query ID */ h.qr = 1; /* response flag */ h.rd = 1; /* recursion desired */ h.ra = 1; /* resursion available */ h.qdcount = htons(1); /* no. of questions */ h.ancount = htons(ancount); /* no. of answers */ h.arcount = htons(0); /* no. of add'tl records */ memcpy(hb, &h, sizeof(h)); hb += NS_HFIXEDSZ; /* move past the header */ *buf = hb; return NS_HFIXEDSZ; } static ssize_t dns_question(const char *question, uint16_t type, uint8_t **question_ptr, size_t remaining) { unsigned char *qb = *question_ptr; int n; n = ns_name_compress(question, qb, remaining, NULL, NULL); assert_true(n > 0); qb += n; remaining -= n; NS_PUT16(type, qb); NS_PUT16(ns_c_in, qb); *question_ptr = qb; return n + 2 * sizeof(uint16_t); } static ssize_t add_rr_common(uint16_t type, uint32_t ttl, size_t rdata_size, const char *key, size_t remaining, uint8_t **rdata_ptr) { uint8_t *rd = *rdata_ptr; ssize_t written = 0; written = ns_name_compress(key, rd, remaining, NULL, NULL); assert_int_not_equal(written, -1); rd += written; remaining -= written; assert_true(remaining > 3 * sizeof(uint16_t) + sizeof(uint32_t)); NS_PUT16(type, rd); NS_PUT16(ns_c_in, rd); NS_PUT32(ttl, rd); NS_PUT16(rdata_size, rd); assert_true(remaining > rdata_size); *rdata_ptr = rd; return written + 3 * sizeof(uint16_t) + sizeof(uint32_t) + rdata_size; } static ssize_t add_srv_rr(struct srv_rrdata *rr, const char *question, uint8_t *answer, size_t anslen) { uint8_t *a = answer; ssize_t resp_size; size_t rdata_size; unsigned char hostname_compressed[MAXDNAME]; ssize_t compressed_len; rdata_size = 3 * sizeof(uint16_t); /* Prepare the data to write */ compressed_len = ns_name_compress(rr->hostname, hostname_compressed, MAXDNAME, NULL, NULL); assert_int_not_equal(compressed_len, -1); rdata_size += compressed_len; resp_size = add_rr_common(ns_t_srv, rr->ttl, rdata_size, question, anslen, &a); NS_PUT16(rr->prio, a); NS_PUT16(rr->weight, a); NS_PUT16(rr->port, a); memcpy(a, hostname_compressed, compressed_len); return resp_size; } unsigned char *create_srv_buffer(TALLOC_CTX *mem_ctx, const char *question, struct srv_rrdata *rrs, size_t n_rrs, size_t *_buflen) { unsigned char *buf; unsigned char *buf_head; ssize_t len; ssize_t i; ssize_t total = 0; buf = talloc_zero_array(mem_ctx, unsigned char, TEST_BUFSIZE); assert_non_null(buf); buf_head = buf; len = dns_header(&buf, n_rrs); assert_true(len > 0); total += len; len = dns_question(question, ns_t_srv, &buf, TEST_BUFSIZE - total); assert_true(len > 0); total += len; /* answer */ for (i = 0; i < n_rrs; i++) { len = add_srv_rr(&rrs[i], question, buf, TEST_BUFSIZE - total); assert_true(len > 0); total += len; buf += len; } *_buflen = total; return buf_head; } struct fake_ares_query { int status; int timeouts; unsigned char *abuf; int alen; }; void mock_ares_query(int status, int timeouts, unsigned char *abuf, int alen) { will_return(__wrap_ares_query, status); will_return(__wrap_ares_query, timeouts); will_return(__wrap_ares_query, abuf); will_return(__wrap_ares_query, alen); } void __wrap_ares_query(ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg) { struct fake_ares_query query; query.status = sss_mock_type(int); query.timeouts = sss_mock_type(int); query.abuf = sss_mock_ptr_type(unsigned char *); query.alen = sss_mock_type(int); callback(arg, query.status, query.timeouts, query.abuf, query.alen); } /* The unit test */ struct resolv_fake_ctx { struct resolv_ctx *resolv; struct sss_test_ctx *ctx; }; static int test_resolv_fake_setup(void **state) { struct resolv_fake_ctx *test_ctx; int ret; assert_true(leak_check_setup()); global_mock_context = talloc_new(global_talloc_context); assert_non_null(global_mock_context); test_ctx = talloc_zero(global_mock_context, struct resolv_fake_ctx); assert_non_null(test_ctx); test_ctx->ctx = create_ev_test_ctx(test_ctx); assert_non_null(test_ctx->ctx); ret = resolv_init(test_ctx, test_ctx->ctx->ev, TEST_DEFAULT_TIMEOUT, &test_ctx->resolv); assert_int_equal(ret, EOK); *state = test_ctx; return 0; } static int test_resolv_fake_teardown(void **state) { struct resolv_fake_ctx *test_ctx = talloc_get_type(*state, struct resolv_fake_ctx); talloc_free(test_ctx); talloc_free(global_mock_context); assert_true(leak_check_teardown()); return 0; } void test_resolv_fake_srv_done(struct tevent_req *req) { errno_t ret; TALLOC_CTX *tmp_ctx; int status; uint32_t ttl; struct ares_srv_reply *srv_replies = NULL; struct resolv_fake_ctx *test_ctx = tevent_req_callback_data(req, struct resolv_fake_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); ret = resolv_getsrv_recv(tmp_ctx, req, &status, NULL, &srv_replies, &ttl); assert_int_equal(ret, EOK); assert_non_null(srv_replies); assert_int_equal(srv_replies->priority, 1); assert_int_equal(srv_replies->weight, 40); assert_int_equal(srv_replies->port, 389); assert_string_equal(srv_replies->host, "ldap.sssd.com"); srv_replies = srv_replies->next; assert_non_null(srv_replies); assert_int_equal(srv_replies->priority, 1); assert_int_equal(srv_replies->weight, 60); assert_int_equal(srv_replies->port, 389); assert_string_equal(srv_replies->host, "ldap2.sssd.com"); srv_replies = srv_replies->next; assert_null(srv_replies); assert_int_equal(ttl, 500); talloc_free(tmp_ctx); test_ev_done(test_ctx->ctx, EOK); } void test_resolv_fake_srv(void **state) { int ret; struct tevent_req *req; struct resolv_fake_ctx *test_ctx = talloc_get_type(*state, struct resolv_fake_ctx); unsigned char *buf; size_t buflen; struct srv_rrdata rr[2]; rr[0].prio = 1; rr[0].port = 389; rr[0].weight = 40; rr[0].ttl = 600; rr[0].hostname = "ldap.sssd.com"; rr[1].prio = 1; rr[1].port = 389; rr[1].weight = 60; rr[1].ttl = 500; rr[1].hostname = "ldap2.sssd.com"; buf = create_srv_buffer(test_ctx, TEST_SRV_QUERY, rr, 2, &buflen); assert_non_null(buf); mock_ares_query(0, 0, buf, buflen); req = resolv_getsrv_send(test_ctx, test_ctx->ctx->ev, test_ctx->resolv, TEST_SRV_QUERY); assert_non_null(req); tevent_req_set_callback(req, test_resolv_fake_srv_done, test_ctx); ret = test_ev_loop(test_ctx->ctx); assert_int_equal(ret, ERR_OK); } int main(int argc, const char *argv[]) { int rv; poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test_setup_teardown(test_resolv_fake_srv, test_resolv_fake_setup, test_resolv_fake_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); rv = cmocka_run_group_tests(tests, NULL, NULL); return rv; } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/common_mock_be.h0000644000000000000000000000007412703456111020633 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.589793408 sssd-1.13.4/src/tests/cmocka/common_mock_be.h0000644002412700241270000000173012703456111022303 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2015 Red Hat SSSD tests: Fake back end This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __COMMON_MOCK_BE_H_ #define __COMMON_MOCK_BE_H_ #include "tests/cmocka/common_mock.h" struct be_ctx *mock_be_ctx(TALLOC_CTX *mem_ctx, struct sss_test_ctx *tctx); #endif /* __COMMON_MOCK_BE_H_ */ sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/sss_nss_idmap-tests.c0000644000000000000000000000007412703456111021664 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.979794731 sssd-1.13.4/src/tests/cmocka/sss_nss_idmap-tests.c0000644002412700241270000001216312703456111023336 0ustar00jhrozekjhrozek00000000000000/* Authors: Sumit Bose Copyright (C) 2013 Red Hat Test for the NSS Responder ID-SID mapping interface This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "util/sss_endian.h" #include "sss_client/idmap/sss_nss_idmap.h" #include "tests/cmocka/common_mock.h" #include #include "sss_client/sss_cli.h" struct sss_nss_make_request_test_data { uint8_t *repbuf; size_t replen; int errnop; enum nss_status nss_status; }; #if (__BYTE_ORDER == __LITTLE_ENDIAN) uint8_t buf1[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; uint8_t buf2[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; uint8_t buf3[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; uint8_t buf4[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 'x'}; uint8_t buf_orig1[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 'k', 'e', 'y', 0x00, 'v', 'a', 'l', 'u', 'e', 0x00}; #elif (__BYTE_ORDER == __BIG_ENDIAN) uint8_t buf1[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; uint8_t buf2[] = {0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; uint8_t buf3[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 0x00}; uint8_t buf4[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 't', 'e', 's', 't', 'x'}; uint8_t buf_orig1[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 'k', 'e', 'y', 0x00, 'v', 'a', 'l', 'u', 'e', 0x00}; #else #error "unknow endianess" #endif enum nss_status sss_nss_make_request(enum sss_cli_command cmd, struct sss_cli_req_data *rd, uint8_t **repbuf, size_t *replen, int *errnop) { struct sss_nss_make_request_test_data *d; d = sss_mock_ptr_type(struct sss_nss_make_request_test_data *); *replen = d->replen; *errnop = d->errnop; /* the caller must be able to free repbuf. */ if (*replen != 0 && d->repbuf != NULL) { *repbuf = malloc(*replen); assert_non_null(*repbuf); memcpy(*repbuf, d->repbuf, *replen); } return d->nss_status; } void test_getsidbyname(void **state) { int ret; char *sid = NULL; size_t c; enum sss_id_type type; struct test_data { struct sss_nss_make_request_test_data d; int ret; const char *str; } d[] = { {{buf1, sizeof(buf1), 0, NSS_STATUS_SUCCESS}, EOK, "test"}, {{buf2, sizeof(buf2), 0, NSS_STATUS_SUCCESS}, EBADMSG, NULL}, {{buf3, sizeof(buf3), 0, NSS_STATUS_SUCCESS}, ENOENT, NULL}, {{buf4, sizeof(buf4), 0, NSS_STATUS_SUCCESS}, EBADMSG, NULL}, {{NULL, 0, 0, 0}, 0, NULL} }; ret = sss_nss_getsidbyname(NULL, NULL, NULL); assert_int_equal(ret, EINVAL); ret = sss_nss_getsidbyname("", NULL, NULL); assert_int_equal(ret, EINVAL); ret = sss_nss_getsidbyname("", &sid, NULL); assert_int_equal(ret, EINVAL); free(sid); sid = NULL; for (c = 0; d[c].d.repbuf != NULL; c++) { will_return(sss_nss_make_request, &d[0].d); ret = sss_nss_getsidbyname("test", &sid, &type); assert_int_equal(ret, d[0].ret); if (ret == EOK) { assert_string_equal(sid, d[0].str); assert_int_equal(type, 0); } free(sid); sid = NULL; } } void test_getorigbyname(void **state) { int ret; struct sss_nss_kv *kv_list; enum sss_id_type type; struct sss_nss_make_request_test_data d = {buf_orig1, sizeof(buf_orig1), 0, NSS_STATUS_SUCCESS}; will_return(sss_nss_make_request, &d); ret = sss_nss_getorigbyname("test", &kv_list, &type); assert_int_equal(ret, EOK); assert_int_equal(type, SSS_ID_TYPE_UID); assert_string_equal(kv_list[0].key, "key"); assert_string_equal(kv_list[0].value, "value"); assert_null(kv_list[1].key); assert_null(kv_list[1].value); sss_nss_free_kv(kv_list); } int main(int argc, const char *argv[]) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_getsidbyname), cmocka_unit_test(test_getorigbyname), }; return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cmocka/PaxHeaders.16287/test_find_uid.c0000644000000000000000000000007412703456111020477 xustar0030 atime=1460561751.656715648 30 ctime=1460561775.027794894 sssd-1.13.4/src/tests/cmocka/test_find_uid.c0000644002412700241270000000471712703456111022157 0ustar00jhrozekjhrozek00000000000000/* SSSD find_uid - Utilities tests Authors: Abhishek Singh Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "util/find_uid.h" #include "tests/common.h" void test_check_if_uid_is_active_success(void **state) { int ret; uid_t uid; bool result; uid = getuid(); ret = check_if_uid_is_active(uid, &result); assert_true(ret == EOK); assert_true(result); } void test_check_if_uid_is_active_fail(void **state) { int ret; uid_t uid; bool result; uid = (uid_t) -7; ret = check_if_uid_is_active(uid, &result); assert_true(ret == EOK); assert_true(!result); } void test_get_uid_table(void **state) { int ret; uid_t uid; TALLOC_CTX *tmp_ctx; hash_table_t *table; hash_key_t key; hash_value_t value; tmp_ctx = talloc_new(NULL); assert_true(tmp_ctx != NULL); ret = get_uid_table(tmp_ctx, &table); assert_true(ret == EOK); uid = getuid(); key.type = HASH_KEY_ULONG; key.ul = (unsigned long) uid; ret = hash_lookup(table, &key, &value); assert_true(ret == HASH_SUCCESS); assert_true(hash_delete(table, &key) == HASH_SUCCESS); uid = (uid_t) -7; key.type = HASH_KEY_ULONG; key.ul = (unsigned long) uid; ret = hash_lookup(table, &key, &value); assert_true(ret == HASH_ERROR_KEY_NOT_FOUND); talloc_free(tmp_ctx); } int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(test_check_if_uid_is_active_success), cmocka_unit_test(test_check_if_uid_is_active_fail), cmocka_unit_test(test_get_uid_table) }; return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/PaxHeaders.16287/intg0000644000000000000000000000013212703463560015143 xustar0030 mtime=1460561776.114798579 30 atime=1460561776.119798596 30 ctime=1460561776.114798579 sssd-1.13.4/src/tests/intg/0000755002412700241270000000000012703463560016674 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/tests/intg/PaxHeaders.16287/Makefile.in0000644000000000000000000000013212703463544017267 xustar0030 mtime=1460561764.675759792 30 atime=1460561772.689786966 30 ctime=1460561776.114798579 sssd-1.13.4/src/tests/intg/Makefile.in0000644002412700241270000005157012703463544020753 0ustar00jhrozekjhrozek00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/tests/intg ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ $(top_srcdir)/version.m4 $(top_srcdir)/src/build_macros.m4 \ $(top_srcdir)/src/external/platform.m4 \ $(top_srcdir)/src/conf_macros.m4 \ $(top_srcdir)/src/external/pkg.m4 \ $(top_srcdir)/src/external/libpopt.m4 \ $(top_srcdir)/src/external/libtalloc.m4 \ $(top_srcdir)/src/external/libtdb.m4 \ $(top_srcdir)/src/external/libtevent.m4 \ $(top_srcdir)/src/external/libldb.m4 \ $(top_srcdir)/src/external/libdhash.m4 \ $(top_srcdir)/src/external/libcollection.m4 \ $(top_srcdir)/src/external/libini_config.m4 \ $(top_srcdir)/src/external/pam.m4 \ $(top_srcdir)/src/external/ldap.m4 \ $(top_srcdir)/src/external/libpcre.m4 \ $(top_srcdir)/src/external/krb5.m4 \ $(top_srcdir)/src/external/libcares.m4 \ $(top_srcdir)/src/external/libcmocka.m4 \ $(top_srcdir)/src/external/docbook.m4 \ $(top_srcdir)/src/external/sizes.m4 \ $(top_srcdir)/src/external/python.m4 \ $(top_srcdir)/src/external/selinux.m4 \ $(top_srcdir)/src/external/crypto.m4 \ $(top_srcdir)/src/external/nscd.m4 \ $(top_srcdir)/src/external/nsupdate.m4 \ $(top_srcdir)/src/external/libkeyutils.m4 \ $(top_srcdir)/src/external/libnl.m4 \ $(top_srcdir)/src/external/systemd.m4 \ $(top_srcdir)/src/external/pac_responder.m4 \ $(top_srcdir)/src/external/cifsidmap.m4 \ $(top_srcdir)/src/external/signal.m4 \ $(top_srcdir)/src/external/inotify.m4 \ $(top_srcdir)/src/external/samba.m4 \ $(top_srcdir)/src/external/sasl.m4 \ $(top_srcdir)/src/external/configlib.m4 \ $(top_srcdir)/src/external/libnfsidmap.m4 \ $(top_srcdir)/src/external/cwrap.m4 \ $(top_srcdir)/src/external/libresolv.m4 \ $(top_srcdir)/src/external/intgcheck.m4 \ $(top_srcdir)/src/external/libaugeas.m4 \ $(top_srcdir)/src/external/libunistring.m4 \ $(top_srcdir)/src/external/glib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(dist_noinst_DATA) \ $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(dist_noinst_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in \ $(top_srcdir)/build/mkinstalldirs DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUGEAS_CFLAGS = @AUGEAS_CFLAGS@ AUGEAS_LIBS = @AUGEAS_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CARES_CFLAGS = @CARES_CFLAGS@ CARES_LIBS = @CARES_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CMOCKA_CFLAGS = @CMOCKA_CFLAGS@ CMOCKA_LIBS = @CMOCKA_LIBS@ COLLECTION_CFLAGS = @COLLECTION_CFLAGS@ COLLECTION_LIBS = @COLLECTION_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPTO_CFLAGS = @CRYPTO_CFLAGS@ CRYPTO_LIBS = @CRYPTO_LIBS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHASH_CFLAGS = @DHASH_CFLAGS@ DHASH_LIBS = @DHASH_LIBS@ DLLTOOL = @DLLTOOL@ DOCBOOK_XSLT = @DOCBOOK_XSLT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB2_CFLAGS = @GLIB2_CFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMSGFMT = @GMSGFMT@ GPO_DEFAULT = @GPO_DEFAULT@ GREP = @GREP@ HAVE_FAKEROOT = @HAVE_FAKEROOT@ HAVE_LDAPMODIFY = @HAVE_LDAPMODIFY@ HAVE_MANPAGES = @HAVE_MANPAGES@ HAVE_NSS_WRAPPER = @HAVE_NSS_WRAPPER@ HAVE_PYTHON2 = @HAVE_PYTHON2@ HAVE_PYTHON2_BINDINGS = @HAVE_PYTHON2_BINDINGS@ HAVE_PYTHON3 = @HAVE_PYTHON3@ HAVE_PYTHON3_BINDINGS = @HAVE_PYTHON3_BINDINGS@ HAVE_SELINUX = @HAVE_SELINUX@ HAVE_SEMANAGE = @HAVE_SEMANAGE@ HAVE_SYSTEMD = @HAVE_SYSTEMD@ HAVE_UID_WRAPPER = @HAVE_UID_WRAPPER@ INI_CONFIG_CFLAGS = @INI_CONFIG_CFLAGS@ INI_CONFIG_LIBS = @INI_CONFIG_LIBS@ INI_CONFIG_V0_CFLAGS = @INI_CONFIG_V0_CFLAGS@ INI_CONFIG_V0_LIBS = @INI_CONFIG_V0_LIBS@ INI_CONFIG_V1_1_CFLAGS = @INI_CONFIG_V1_1_CFLAGS@ INI_CONFIG_V1_1_LIBS = @INI_CONFIG_V1_1_LIBS@ INI_CONFIG_V1_CFLAGS = @INI_CONFIG_V1_CFLAGS@ INI_CONFIG_V1_LIBS = @INI_CONFIG_V1_LIBS@ INOTIFY_LIBS = @INOTIFY_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ JOURNALD_CFLAGS = @JOURNALD_CFLAGS@ JOURNALD_LIBS = @JOURNALD_LIBS@ KEYUTILS_LIBS = @KEYUTILS_LIBS@ KRB5_CFLAGS = @KRB5_CFLAGS@ KRB5_CONFIG = @KRB5_CONFIG@ KRB5_LIBS = @KRB5_LIBS@ LD = @LD@ LDB_CFLAGS = @LDB_CFLAGS@ LDB_LIBS = @LDB_LIBS@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ LIBADD_DLOPEN = @LIBADD_DLOPEN@ LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ LIBNL1_LIBS = @LIBNL1_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ NDR_KRB5PAC_CFLAGS = @NDR_KRB5PAC_CFLAGS@ NDR_KRB5PAC_LIBS = @NDR_KRB5PAC_LIBS@ NDR_NBT_CFLAGS = @NDR_NBT_CFLAGS@ NDR_NBT_LIBS = @NDR_NBT_LIBS@ NFSIDMAP_CFLAGS = @NFSIDMAP_CFLAGS@ NFSIDMAP_LIBS = @NFSIDMAP_LIBS@ NFSIDMAP_OBJ = @NFSIDMAP_OBJ@ NM = @NM@ NMEDIT = @NMEDIT@ NSCD = @NSCD@ NSCD_PATH = @NSCD_PATH@ NSS_CFLAGS = @NSS_CFLAGS@ NSS_LIBS = @NSS_LIBS@ NSUPDATE = @NSUPDATE@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENLDAP_CFLAGS = @OPENLDAP_CFLAGS@ OPENLDAP_LIBS = @OPENLDAP_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_LIBS = @PAM_LIBS@ PAM_MISC_LIBS = @PAM_MISC_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PO4A = @PO4A@ POPT_CFLAGS = @POPT_CFLAGS@ POPT_LIBS = @POPT_LIBS@ POSUB = @POSUB@ PRERELEASE_VERSION = @PRERELEASE_VERSION@ PYTEST = @PYTEST@ PYTHON = @PYTHON@ PYTHON2 = @PYTHON2@ PYTHON2_CFLAGS = @PYTHON2_CFLAGS@ PYTHON2_EXEC_PREFIX = @PYTHON2_EXEC_PREFIX@ PYTHON2_INCLUDES = @PYTHON2_INCLUDES@ PYTHON2_LIBS = @PYTHON2_LIBS@ PYTHON2_PREFIX = @PYTHON2_PREFIX@ PYTHON2_VERSION = @PYTHON2_VERSION@ PYTHON3 = @PYTHON3@ PYTHON3_CFLAGS = @PYTHON3_CFLAGS@ PYTHON3_EXEC_PREFIX = @PYTHON3_EXEC_PREFIX@ PYTHON3_INCLUDES = @PYTHON3_INCLUDES@ PYTHON3_LIBS = @PYTHON3_LIBS@ PYTHON3_PREFIX = @PYTHON3_PREFIX@ PYTHON3_VERSION = @PYTHON3_VERSION@ PYTHON_CONFIG = @PYTHON_CONFIG@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RESOLV_CFLAGS = @RESOLV_CFLAGS@ RESOLV_LIBS = @RESOLV_LIBS@ SASL_CFLAGS = @SASL_CFLAGS@ SASL_LIBS = @SASL_LIBS@ SED = @SED@ SELINUX_LIBS = @SELINUX_LIBS@ SEMANAGE_LIBS = @SEMANAGE_LIBS@ SET_MAKE = @SET_MAKE@ SGML_CATALOG_FILES = @SGML_CATALOG_FILES@ SHELL = @SHELL@ SLAPD = @SLAPD@ SMBCLIENT_CFLAGS = @SMBCLIENT_CFLAGS@ SMBCLIENT_LIBS = @SMBCLIENT_LIBS@ SSSD_USER = @SSSD_USER@ STRIP = @STRIP@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ TALLOC_CFLAGS = @TALLOC_CFLAGS@ TALLOC_LIBS = @TALLOC_LIBS@ TDB_CFLAGS = @TDB_CFLAGS@ TDB_LIBS = @TDB_LIBS@ TEST_DIR = @TEST_DIR@ TEVENT_CFLAGS = @TEVENT_CFLAGS@ TEVENT_LIBS = @TEVENT_LIBS@ UNICODE_LIBS = @UNICODE_LIBS@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ XMLLINT = @XMLLINT@ XSLTPROC = @XSLTPROC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appmodpath = @appmodpath@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cifspluginpath = @cifspluginpath@ config_def_ccache_dir = @config_def_ccache_dir@ config_def_ccname_template = @config_def_ccname_template@ datadir = @datadir@ datarootdir = @datarootdir@ dbpath = @dbpath@ docdir = @docdir@ dvidir = @dvidir@ environment_file = @environment_file@ exec_prefix = @exec_prefix@ gpocachepath = @gpocachepath@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ krb5authdatapluginpath = @krb5authdatapluginpath@ krb5pluginpath = @krb5pluginpath@ krb5rcachedir = @krb5rcachedir@ ldblibdir = @ldblibdir@ libdir = @libdir@ libexecdir = @libexecdir@ libwbclient_version = @libwbclient_version@ libwbclient_version_info = @libwbclient_version_info@ localedir = @localedir@ localstatedir = @localstatedir@ logpath = @logpath@ mandir = @mandir@ mcpath = @mcpath@ mkdir_p = @mkdir_p@ nfsidmaplibdir = @nfsidmaplibdir@ nfslibpath = @nfslibpath@ nsslibdir = @nsslibdir@ oldincludedir = @oldincludedir@ pammoddir = @pammoddir@ pdfdir = @pdfdir@ pidpath = @pidpath@ pipepath = @pipepath@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ pluginpath = @pluginpath@ polkitdir = @polkitdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pubconfpath = @pubconfpath@ py2execdir = @py2execdir@ py3execdir = @py3execdir@ pyexecdir = @pyexecdir@ python2dir = @python2dir@ python3dir = @python3dir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedbuilddir = @sharedbuilddir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sudolibpath = @sudolibpath@ sysconfdir = @sysconfdir@ systemdconfdir = @systemdconfdir@ systemdunitdir = @systemdunitdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ dist_noinst_DATA = \ config.py.m4 \ sssd_id.py \ ds.py \ ds_openldap.py \ ent.py \ ent_test.py \ ldap_ent.py \ ldap_local_override_test.py \ ldap_test.py \ test_local_domain.py \ util.py \ test_memory_cache.py \ $(NULL) CLEANFILES = config.py config.pyc passwd group all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tests/intg/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/tests/intg/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local cscopelist-am ctags-am distclean distclean-generic \ distclean-libtool distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags-am uninstall uninstall-am .PRECIOUS: Makefile config.py: config.py.m4 m4 -D "prefix=\`$(prefix)'" \ -D "sysconfdir=\`$(sysconfdir)'" \ -D "dbpath=\`$(dbpath)'" \ -D "pidpath=\`$(pidpath)'" \ -D "logpath=\`$(logpath)'" \ -D "mcpath=\`$(mcpath)'" \ $< > $@ root: : "Create directory for emulated root's D-Bus cookies." : "See http://dbus.freedesktop.org/doc/dbus-specification.html#auth-mechanisms" $(MKDIR_P) -m 0700 root/.dbus-keyrings passwd: root echo "root:x:0:0:root:$(abs_builddir)/root:/bin/bash" > $@ group: echo "root:x:0:" > $@ clean-local: rm -Rf root intgcheck-installed: config.py passwd group pipepath="$(DESTDIR)$(pipepath)"; \ if test $${#pipepath} -gt 80; then \ echo "error: Pipe directory path too long," \ "D-Bus won't be able to open sockets" >&2; \ exit 1; \ fi set -e; \ cd "$(abs_srcdir)"; \ nss_wrapper=$$(pkg-config --libs nss_wrapper); \ uid_wrapper=$$(pkg-config --libs uid_wrapper); \ PATH="$$(dirname -- $(SLAPD)):$$PATH" \ PATH="$(DESTDIR)$(sbindir):$(DESTDIR)$(bindir):$$PATH" \ PATH="$(abs_builddir):$(abs_srcdir):$$PATH" \ PYTHONPATH="$(abs_builddir):$(abs_srcdir)" \ LDB_MODULES_PATH="$(DESTDIR)$(ldblibdir)" \ LD_PRELOAD="$$nss_wrapper $$uid_wrapper" \ NSS_WRAPPER_PASSWD="$(abs_builddir)/passwd" \ NSS_WRAPPER_GROUP="$(abs_builddir)/group" \ NSS_WRAPPER_MODULE_SO_PATH="$(DESTDIR)$(nsslibdir)/libnss_sss.so.2" \ NSS_WRAPPER_MODULE_FN_PREFIX="sss" \ UID_WRAPPER=1 \ UID_WRAPPER_ROOT=1 \ fakeroot $(PYTHON2) $(PYTEST) -v --tb=native $(INTGCHECK_PYTEST_ARGS) . rm -f $(DESTDIR)$(logpath)/* # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: sssd-1.13.4/src/tests/intg/PaxHeaders.16287/ent_test.py0000644000000000000000000000007412703456111017416 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.108798559 sssd-1.13.4/src/tests/intg/ent_test.py0000644002412700241270000003707212703456111021076 0ustar00jhrozekjhrozek00000000000000# # ent.py module tests # # Copyright (c) 2015 Red Hat, Inc. # Author: Nikolai Kondrashov # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import re import os import io import shutil import pytest import ent from util import * def backup_envvar_file(name): path = os.environ[name] backup_path = path + ".bak" shutil.copyfile(path, backup_path) return path def restore_envvar_file(name): path = os.environ[name] backup_path = path + ".bak" os.rename(backup_path, path) @pytest.fixture(scope="module") def passwd_path(request): name = "NSS_WRAPPER_PASSWD" request.addfinalizer(lambda: restore_envvar_file(name)) return backup_envvar_file(name) @pytest.fixture(scope="module") def group_path(request): name = "NSS_WRAPPER_GROUP" request.addfinalizer(lambda: restore_envvar_file(name)) return backup_envvar_file(name) USER1 = dict(name="user1", passwd="x", uid=1001, gid=2001, gecos="User 1", dir="/home/user1", shell="/bin/bash") USER2 = dict(name="user2", passwd="x", uid=1002, gid=2002, gecos="User 2", dir="/home/user2", shell="/bin/bash") USER_LIST = [USER1, USER2] USER_NAME_DICT = dict((u["name"], u) for u in USER_LIST) USER_UID_DICT = dict((u["uid"], u) for u in USER_LIST) EMPTY_GROUP = dict(name="empty_group", passwd="x", gid=2000, mem=ent.contains_only()) GROUP1 = dict(name="group1", passwd="x", gid=2001, mem=ent.contains_only()) GROUP2 = dict(name="group2", passwd="x", gid=2002, mem=ent.contains_only()) ONE_USER_GROUP1 = dict(name="one_user_group1", passwd="x", gid=2011, mem=ent.contains_only("user1")) ONE_USER_GROUP2 = dict(name="one_user_group2", passwd="x", gid=2012, mem=ent.contains_only("user2")) TWO_USER_GROUP = dict(name="two_user_group", passwd="x", gid=2020, mem=ent.contains_only("user1", "user2")) GROUP_LIST = [EMPTY_GROUP, GROUP1, GROUP2, ONE_USER_GROUP1, ONE_USER_GROUP2, TWO_USER_GROUP] GROUP_NAME_DICT = dict((g["name"], g) for g in GROUP_LIST) GROUP_GID_DICT = dict((g["gid"], g) for g in GROUP_LIST) @pytest.fixture(scope="module") def users_and_groups(request, passwd_path, group_path): passwd_contents = "".join([ "{name}:{passwd}:{uid}:{gid}:{gecos}:{dir}:{shell}\n".format(**u) for u in USER_LIST ]) group_contents = "".join([ "%s:%s:%s:%s\n" % (g["name"], g["passwd"], g["gid"], ",".join(g["mem"])) for g in GROUP_LIST ]) with open(passwd_path, "a") as f: f.write(passwd_contents) with open(group_path, "a") as f: f.write(group_contents) def test_assert_passwd_by_name(users_and_groups): ent.assert_passwd_by_name("user1", {}) ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001)) ent.assert_passwd_by_name("user1", USER1) try: ent.assert_passwd_by_name("user3", {}) assert False except AssertionError as e: assert str(e) == "'getpwnam(): name not found: user3'" try: ent.assert_passwd_by_name("user2", dict(name="user1")) assert False except AssertionError as e: assert str(e) == "'name' mismatch: 'user1' != 'user2'" def test_assert_passwd_by_uid(users_and_groups): ent.assert_passwd_by_uid(1001, {}) ent.assert_passwd_by_uid(1001, dict(name="user1", uid=1001)) ent.assert_passwd_by_uid(1001, USER1) try: ent.assert_passwd_by_uid(1003, {}) assert False except AssertionError as e: assert str(e) == "'getpwuid(): uid not found: 1003'" try: ent.assert_passwd_by_uid(1002, dict(name="user1")) assert False except AssertionError as e: assert str(e) == "'name' mismatch: 'user1' != 'user2'" def test_assert_passwd_list(users_and_groups): ent.assert_passwd_list(ent.contains()) ent.assert_passwd_list(ent.contains(USER1)) ent.assert_passwd_list(ent.contains_only(*USER_LIST)) try: ent.assert_passwd_list(ent.contains_only()) assert False except AssertionError as e: assert not re.search("expected users not found:", str(e)) assert re.search("unexpected users found:", str(e)) try: ent.assert_passwd_list(ent.contains(dict(name="non_existent"))) assert False except AssertionError as e: assert re.search("expected users not found:", str(e)) assert not re.search("unexpected users found:", str(e)) def test_assert_each_passwd_by_name(users_and_groups): ent.assert_each_passwd_by_name({}) ent.assert_each_passwd_by_name(dict(user1=USER1)) ent.assert_each_passwd_by_name(USER_NAME_DICT) try: ent.assert_each_passwd_by_name(dict(user3={})) assert False except AssertionError as e: assert str(e) == "'getpwnam(): name not found: user3'" try: ent.assert_each_passwd_by_name(dict(user1=dict(name="user2"))) assert False except AssertionError as e: assert str(e) == \ "user 'user1' mismatch: 'name' mismatch: 'user2' != 'user1'" def test_assert_each_passwd_by_uid(users_and_groups): ent.assert_each_passwd_by_uid({}) ent.assert_each_passwd_by_uid({1001: USER1}) ent.assert_each_passwd_by_uid(USER_UID_DICT) try: ent.assert_each_passwd_by_uid({1003: {}}) assert False except AssertionError as e: assert str(e) == "'getpwuid(): uid not found: 1003'" try: ent.assert_each_passwd_by_uid({1001: dict(uid=1002)}) assert False except AssertionError as e: assert str(e) == \ "user 1001 mismatch: 'uid' mismatch: 1002 != 1001" def test_assert_each_passwd_with_name(users_and_groups): ent.assert_each_passwd_with_name([]) ent.assert_each_passwd_with_name([USER1]) ent.assert_each_passwd_with_name(USER_LIST) try: ent.assert_each_passwd_with_name([dict(name="user3")]) assert False except AssertionError as e: assert str(e) == "'getpwnam(): name not found: user3'" try: ent.assert_each_passwd_with_name([dict(name="user1", uid=1002)]) assert False except AssertionError as e: assert str(e) == \ "user 'user1' mismatch: 'uid' mismatch: 1002 != 1001" def test_assert_each_passwd_with_uid(users_and_groups): ent.assert_each_passwd_with_uid([]) ent.assert_each_passwd_with_uid([USER1]) ent.assert_each_passwd_with_uid(USER_LIST) try: ent.assert_each_passwd_with_uid([dict(uid=1003)]) assert False except AssertionError as e: assert str(e) == "'getpwuid(): uid not found: 1003'" try: ent.assert_each_passwd_with_uid([dict(name="user2", uid=1001)]) assert False except AssertionError as e: assert str(e) == \ "user 1001 mismatch: 'name' mismatch: 'user2' != 'user1'" def test_assert_passwd(users_and_groups): ent.assert_passwd(ent.contains()) ent.assert_passwd(ent.contains(USER1)) ent.assert_passwd(ent.contains_only(*USER_LIST)) try: ent.assert_passwd(ent.contains(dict(name="user3", uid=1003))) assert False except AssertionError as e: assert re.search("list mismatch:", str(e)) assert re.search("expected users not found:", str(e)) assert not re.search("unexpected users found:", str(e)) try: ent.assert_passwd(ent.contains_only(USER1)) assert False except AssertionError as e: assert re.search("list mismatch:", str(e)) assert not re.search("expected users not found:", str(e)) assert re.search("unexpected users found:", str(e)) def test_group_member_matching(users_and_groups): ent.assert_group_by_name("empty_group", dict(mem=ent.contains())) ent.assert_group_by_name("empty_group", dict(mem=ent.contains_only())) try: ent.assert_group_by_name("empty_group", dict(mem=ent.contains("user1"))) except AssertionError as e: assert re.search("member list mismatch:", str(e)) assert re.search("expected members not found:", str(e)) ent.assert_group_by_name("one_user_group1", dict(mem=ent.contains())) ent.assert_group_by_name("one_user_group1", dict(mem=ent.contains("user1"))) ent.assert_group_by_name("one_user_group1", dict(mem=ent.contains_only("user1"))) try: ent.assert_group_by_name("one_user_group1", dict(mem=ent.contains_only())) except AssertionError as e: assert re.search("member list mismatch:", str(e)) assert re.search("unexpected members found:", str(e)) assert not re.search("expected members not found:", str(e)) try: ent.assert_group_by_name("one_user_group1", dict(mem=ent.contains_only("user3"))) except AssertionError as e: assert re.search("member list mismatch:", str(e)) assert re.search("unexpected members found:", str(e)) assert re.search("expected members not found:", str(e)) try: ent.assert_group_by_name("one_user_group1", dict(mem=ent.contains("user3"))) except AssertionError as e: assert re.search("member list mismatch:", str(e)) assert not re.search("unexpected members found:", str(e)) assert re.search("expected members not found:", str(e)) ent.assert_group_by_name("two_user_group", dict(mem=ent.contains())) ent.assert_group_by_name("two_user_group", dict(mem=ent.contains("user1"))) ent.assert_group_by_name("two_user_group", dict(mem=ent.contains("user1", "user2"))) ent.assert_group_by_name("two_user_group", dict(mem=ent.contains_only("user1", "user2"))) try: ent.assert_group_by_name("two_user_group", dict(mem=ent.contains_only("user1"))) except AssertionError as e: assert re.search("member list mismatch:", str(e)) assert re.search("unexpected members found:", str(e)) assert not re.search("expected members not found:", str(e)) def test_assert_group_by_name(users_and_groups): ent.assert_group_by_name("group1", {}) ent.assert_group_by_name("group1", dict(name="group1", gid=2001)) ent.assert_group_by_name("group1", GROUP1) try: ent.assert_group_by_name("group3", {}) assert False except AssertionError as e: assert str(e) == "'getgrnam(): name not found: group3'" try: ent.assert_group_by_name("group2", dict(name="group1")) assert False except AssertionError as e: assert str(e) == "'name' mismatch: 'group1' != 'group2'" def test_assert_group_by_gid(users_and_groups): ent.assert_group_by_gid(2001, {}) ent.assert_group_by_gid(2001, dict(name="group1", gid=2001)) ent.assert_group_by_gid(2001, GROUP1) try: ent.assert_group_by_gid(2003, {}) assert False except AssertionError as e: assert str(e) == "'getgrgid(): gid not found: 2003'" try: ent.assert_group_by_gid(2002, dict(name="group1")) assert False except AssertionError as e: assert str(e) == "'name' mismatch: 'group1' != 'group2'" def test_assert_group_list(users_and_groups): ent.assert_group_list(ent.contains()) ent.assert_group_list(ent.contains(GROUP1)) ent.assert_group_list(ent.contains_only(*GROUP_LIST)) try: ent.assert_group_list(ent.contains_only()) assert False except AssertionError as e: assert not re.search("expected groups not found:", str(e)) assert re.search("unexpected groups found:", str(e)) try: ent.assert_group_list(ent.contains(dict(name="non_existent"))) assert False except AssertionError as e: assert re.search("expected groups not found:", str(e)) assert not re.search("unexpected groups found:", str(e)) def test_assert_each_group_by_name(users_and_groups): ent.assert_each_group_by_name({}) ent.assert_each_group_by_name(dict(group1=GROUP1)) ent.assert_each_group_by_name(GROUP_NAME_DICT) try: ent.assert_each_group_by_name(dict(group3={})) assert False except AssertionError as e: assert str(e) == "'getgrnam(): name not found: group3'" try: ent.assert_each_group_by_name(dict(group1=dict(name="group2"))) assert False except AssertionError as e: assert str(e) == "group 'group1' mismatch: " + \ "'name' mismatch: 'group2' != 'group1'" def test_assert_each_group_by_gid(users_and_groups): ent.assert_each_group_by_gid({}) ent.assert_each_group_by_gid({2001: GROUP1}) ent.assert_each_group_by_gid(GROUP_GID_DICT) try: ent.assert_each_group_by_gid({2003: {}}) assert False except AssertionError as e: assert str(e) == "'getgrgid(): gid not found: 2003'" try: ent.assert_each_group_by_gid({2001: dict(gid=2002)}) assert False except AssertionError as e: assert str(e) == \ "group 2001 mismatch: 'gid' mismatch: 2002 != 2001" def test_assert_each_group_with_name(users_and_groups): ent.assert_each_group_with_name([]) ent.assert_each_group_with_name([GROUP1]) ent.assert_each_group_with_name(GROUP_LIST) try: ent.assert_each_group_with_name([dict(name="group3")]) assert False except AssertionError as e: assert str(e) == "'getgrnam(): name not found: group3'" try: ent.assert_each_group_with_name([dict(name="group1", gid=2002)]) assert False except AssertionError as e: assert str(e) == \ "group 'group1' mismatch: 'gid' mismatch: 2002 != 2001" def test_assert_each_group_with_gid(users_and_groups): ent.assert_each_group_with_gid([]) ent.assert_each_group_with_gid([GROUP1]) ent.assert_each_group_with_gid(GROUP_LIST) try: ent.assert_each_group_with_gid([dict(gid=2003)]) assert False except AssertionError as e: assert str(e) == "'getgrgid(): gid not found: 2003'" try: ent.assert_each_group_with_gid([dict(name="group2", gid=2001)]) assert False except AssertionError as e: assert str(e) == \ "group 2001 mismatch: 'name' mismatch: 'group2' != 'group1'" def test_assert_group(users_and_groups): ent.assert_group(ent.contains()) ent.assert_group(ent.contains(GROUP1)) ent.assert_group(ent.contains_only(*GROUP_LIST)) try: ent.assert_group(ent.contains(dict(name="group3", gid=2003))) assert False except AssertionError as e: assert re.search("list mismatch:", str(e)) assert re.search("expected groups not found:", str(e)) assert not re.search("unexpected groups found:", str(e)) try: ent.assert_group(ent.contains_only(GROUP1)) assert False except AssertionError as e: assert re.search("list mismatch:", str(e)) assert not re.search("expected groups not found:", str(e)) assert re.search("unexpected groups found:", str(e)) sssd-1.13.4/src/tests/intg/PaxHeaders.16287/ldap_ent.py0000644000000000000000000000007412703456111017357 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.109798562 sssd-1.13.4/src/tests/intg/ldap_ent.py0000644002412700241270000001044112703456111021026 0ustar00jhrozekjhrozek00000000000000# # LDAP modlist generation # # Copyright (c) 2015 Red Hat, Inc. # Author: Nikolai Kondrashov # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # def user(base_dn, uid, uidNumber, gidNumber, userPassword=None, gecos=None, homeDirectory=None, loginShell=None, cn=None, sn=None): """ Generate an RFC2307(bis) user add-modlist for passing to ldap.add* """ uidNumber = str(uidNumber) gidNumber = str(gidNumber) user = ( "uid=" + uid + ",ou=Users," + base_dn, [ ('objectClass', ['top', 'inetOrgPerson', 'posixAccount']), ('cn', [uidNumber if cn is None else cn]), ('sn', ['User' if sn is None else sn]), ('uidNumber', [uidNumber]), ('gidNumber', [gidNumber]), ('userPassword', ['Password' + uidNumber if userPassword is None else userPassword]), ('homeDirectory', ['/home/' + uid if homeDirectory is None else homeDirectory]), ('loginShell', ['/bin/bash' if loginShell is None else loginShell]), ] ) if gecos is not None: user[1].append(('gecos', [gecos])) return user def group(base_dn, cn, gidNumber, member_uids=[]): """ Generate an RFC2307 group add-modlist for passing to ldap.add*. """ gidNumber = str(gidNumber) attr_list = [ ('objectClass', ['top', 'posixGroup']), ('gidNumber', [gidNumber]) ] if len(member_uids) > 0: attr_list.append(('memberUid', member_uids)) return ("cn=" + cn + ",ou=Groups," + base_dn, attr_list) def group_bis(base_dn, cn, gidNumber, member_uids=[], member_gids=[]): """ Generate an RFC2307bis group add-modlist for passing to ldap.add*. """ gidNumber = str(gidNumber) attr_list = [ ('objectClass', ['top', 'extensibleObject', 'groupOfNames']), ('gidNumber', [gidNumber]) ] member_list = [] for uid in member_uids: member_list.append("uid=" + uid + ",ou=Users," + base_dn) for gid in member_gids: member_list.append("cn=" + gid + ",ou=Groups," + base_dn) if len(member_list) > 0: attr_list.append(('member', member_list)) return ("cn=" + cn + ",ou=Groups," + base_dn, attr_list) class List(list): """LDAP add-modlist list""" def __init__(self, base_dn): self.base_dn = base_dn def add_user(self, uid, uidNumber, gidNumber, base_dn=None, userPassword=None, gecos=None, homeDirectory=None, loginShell=None, cn=None, sn=None): """Add an RFC2307(bis) user add-modlist.""" self.append(user(base_dn or self.base_dn, uid, uidNumber, gidNumber, userPassword=userPassword, gecos=gecos, homeDirectory=homeDirectory, loginShell=loginShell, cn=cn, sn=sn)) def add_group(self, cn, gidNumber, member_uids=[], base_dn=None): """Add an RFC2307 group add-modlist.""" self.append(group(base_dn or self.base_dn, cn, gidNumber, member_uids)) def add_group_bis(self, cn, gidNumber, member_uids=[], member_gids=[], base_dn=None): """Add an RFC2307bis group add-modlist.""" self.append(group_bis(base_dn or self.base_dn, cn, gidNumber, member_uids, member_gids)) sssd-1.13.4/src/tests/intg/PaxHeaders.16287/sssd_id.py0000644000000000000000000000007412703456111017221 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.104798545 sssd-1.13.4/src/tests/intg/sssd_id.py0000644002412700241270000000736412703456111020702 0ustar00jhrozekjhrozek00000000000000# # Module for simulation of utility "id" from coreutils # # Copyright (c) 2015 Red Hat, Inc. # Author: Lukas Slebodnik # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import config import pwd import grp from ctypes import (cdll, c_int, c_char, c_uint32, c_long, c_char_p, POINTER, pointer) class NssReturnCode(object): """ 'enum' class for name service switch retrn code """ TRYAGAIN = -2, UNAVAIL = -1 NOTFOUND = 0 SUCCESS = 1 RETURN = 2 def call_sssd_initgroups(user, gid): """ Function will initialize the supplementary group access list for given user. It will gather groups only provided by sssd. Arguments are the same as for C function initgroups @param string user name of user @param int gid the additional gid will be also added to the list. @return (int, int, List[int]) (err, errno, gids) gids shoudl contain user group IDs if err is NssReturnCode.SUCCESS otherwise errno will contain non-zero vlaue. """ libnss_sss_path = config.PREFIX + "/lib/libnss_sss.so.2" libnss_sss = cdll.LoadLibrary(libnss_sss_path) func = libnss_sss._nss_sss_initgroups_dyn func.restype = c_int func.argtypes = [POINTER(c_char), c_uint32, POINTER(c_long), POINTER(c_long), POINTER(POINTER(c_uint32)), c_long, POINTER(c_int)] start = POINTER(c_long)(c_long(0)) size = POINTER(c_long)(c_long(0)) groups = POINTER(c_uint32)() p_groups = pointer(groups) limit = c_long(-1) errno = POINTER(c_int)(c_int(0)) res = func(c_char_p(user), c_uint32(gid), start, size, p_groups, limit, errno) gids = [] if res == NssReturnCode.SUCCESS: gids_count = size[0] assert gids_count > 0, "_nss_sss_initgroups_dyn shoulld return " \ "one gid" for i in range(0, gids_count): gids.append(int(p_groups.contents[i])) return (int(res), errno[0], gids) def get_user_gids(user): """ Function will initialize the supplementary group access list for given user. It will gather groups only provided by sssd. Arguments are the same as for C function initgroups @param string user name of user @return (int, int, List[int]) (err, errno, gids) gids shoudl contain user group IDs if err is NssReturnCode.SUCCESS otherwise errno will contain non-zero vlaue. """ pwd_user = pwd.getpwnam(user) uid = pwd_user.pw_uid gid = pwd_user.pw_gid user = pwd.getpwuid(uid).pw_name return call_sssd_initgroups(user, gid) def get_user_groups(user): """ Function will initialize the supplementary group access list for given user. It will gather groups only provided by sssd. Arguments are the same as for C function initgroups @param string user name of user @return (int, int, List[string]) (err, errno, groups) roups shoudl contain names of user groups if err is NssReturnCode.SUCCESS otherwise errno will contain non-zero vlaue. """ (res, errno, gids) = get_user_gids(user) groups = [] if res == NssReturnCode.SUCCESS: groups = [grp.getgrgid(gid).gr_name for gid in gids] return (res, errno, groups) sssd-1.13.4/src/tests/intg/PaxHeaders.16287/ds_openldap.py0000644000000000000000000000007412703456111020061 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.106798552 sssd-1.13.4/src/tests/intg/ds_openldap.py0000644002412700241270000002357412703456111021543 0ustar00jhrozekjhrozek00000000000000# # OpenLDAP directory server instance class # # Copyright (c) 2015 Red Hat, Inc. # Author: Nikolai Kondrashov # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import hashlib import base64 import urllib import time import ldap import os import errno import signal import shutil import sys from util import * from ds import DS def hash_password(password): """Generate userPassword value for a password.""" salt = os.urandom(4) hash = hashlib.sha1(password) hash.update(salt) return "{SSHA}" + base64.standard_b64encode(hash.digest() + salt) class DSOpenLDAP(DS): """OpenLDAP directory server instance.""" def __init__(self, dir, port, base_dn, admin_rdn, admin_pw): """ Initialize the instance. Arguments: dir Path to the root of the filesystem hierarchy to create the instance under. port TCP port on localhost to bind the server to. base_dn Base DN. admin_rdn Administrator DN, relative to BASE_DN. admin_pw Administrator password. """ DS.__init__(self, dir, port, base_dn, admin_rdn, admin_pw) self.run_dir = self.dir + "/var/run/ldap" self.pid_path = self.run_dir + "/slapd.pid" self.conf_dir = self.dir + "/etc/ldap" self.conf_slapd_d_dir = self.conf_dir + "/slapd.d" self.data_dir = self.dir + "/var/lib/ldap" def _setup_config(self): """Setup the instance initial configuration.""" dist_lib_dir = first_dir("/usr/lib/openldap", "/usr/lib64/openldap", "/usr/lib/ldap") dist_conf_dir = first_dir("/etc/ldap", "/etc/openldap") args_file = self.run_dir + "/slapd.args" admin_pw_hash = hash_password(self.admin_pw) uid = os.geteuid() gid = os.getegid() # # Add configuration # config = unindent(""" dn: cn=config objectClass: olcGlobal cn: config olcPidFile: {self.pid_path} olcArgsFile: {args_file} # Read slapd.conf(5) for possible values olcLogLevel: none # Frontend settings dn: olcDatabase={{-1}}frontend,cn=config objectClass: olcDatabaseConfig objectClass: olcFrontendConfig olcDatabase: {{-1}}frontend # The maximum number of entries that is returned for # a search operation olcSizeLimit: 500 # Allow unlimited access to local connection from the local root olcAccess: {{0}}to * by dn.exact=gidNumber={gid}+uidNumber={uid}, cn=peercred,cn=external,cn=auth manage by * break # Allow unauthenticated read access for schema and # base DN autodiscovery olcAccess: {{1}}to dn.exact="" by * read olcAccess: {{2}}to dn.base="cn=Subschema" by * read # Config db settings dn: olcDatabase=config,cn=config objectClass: olcDatabaseConfig olcDatabase: config # Allow unlimited access to local connection from the local root olcAccess: to * by dn.exact=gidNumber={gid}+uidNumber={uid}, cn=peercred,cn=external,cn=auth manage by * break olcRootDN: {self.admin_rdn},cn=config olcRootPW: {admin_pw_hash} # Load schemas dn: cn=schema,cn=config objectClass: olcSchemaConfig cn: schema include: file://{dist_conf_dir}/schema/core.ldif include: file://{dist_conf_dir}/schema/cosine.ldif include: file://{dist_conf_dir}/schema/nis.ldif include: file://{dist_conf_dir}/schema/inetorgperson.ldif # Load module dn: cn=module{{0}},cn=config objectClass: olcModuleList cn: module{{0}} olcModulePath: {dist_lib_dir} olcModuleLoad: back_hdb # Set defaults for the backend dn: olcBackend=hdb,cn=config objectClass: olcBackendConfig olcBackend: hdb # The database definition. dn: olcDatabase=hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: hdb olcDbCheckpoint: 512 30 olcLastMod: TRUE olcSuffix: {self.base_dn} olcDbDirectory: {self.data_dir} olcRootDN: {self.admin_dn} olcRootPW: {admin_pw_hash} olcDbIndex: objectClass eq olcDbIndex: cn,uid eq olcDbIndex: uidNumber,gidNumber eq olcDbIndex: member,memberUid eq olcAccess: to attrs=userPassword,shadowLastChange by self write by anonymous auth by * none olcAccess: to dn.base="" by * read olcAccess: to * by * read """).format(**locals()) slapadd = subprocess.Popen( ["slapadd", "-F", self.conf_slapd_d_dir, "-b", "cn=config"], stdin=subprocess.PIPE, close_fds=True ) slapadd.communicate(config) if slapadd.returncode != 0: raise Exception("Failed to add configuration with slapadd") # # Add database config (example from distribution) # db_config = unindent(""" # One 0.25 GB cache set_cachesize 0 268435456 1 # Transaction Log settings set_lg_regionmax 262144 set_lg_bsize 2097152 """) db_config_file = open(self.data_dir + "/DB_CONFIG", "w") db_config_file.write(db_config) db_config_file.close() def setup(self): """Setup the instance.""" ldapi_socket = self.run_dir + "/ldapi" ldapi_url = "ldapi://" + urllib.quote(ldapi_socket, "") url_list = ldapi_url + " " + self.ldap_url os.makedirs(self.conf_slapd_d_dir) os.makedirs(self.run_dir) os.makedirs(self.data_dir) # # Setup initial configuration # self._setup_config() # # Start the daemon # if subprocess.call(["slapd", "-F", self.conf_slapd_d_dir, "-h", url_list]) != 0: raise Exception("Failed to start slapd") # # Wait until it is available # attempt = 0 while True: try: ldap_conn = ldap.initialize(ldapi_url) ldap_conn.simple_bind_s(self.admin_rdn + ",cn=config", self.admin_pw) ldap_conn.unbind_s() ldap_conn = ldap.initialize(self.ldap_url) ldap_conn.simple_bind_s(self.admin_dn, self.admin_pw) ldap_conn.unbind_s() break except ldap.SERVER_DOWN: pass attempt = attempt + 1 if attempt > 30: raise Exception("Failed to start slapd") time.sleep(1) # # Relax requirement of member attribute presence in groupOfNames # modlist = [ (ldap.MOD_DELETE, "olcObjectClasses", "{7}( 2.5.6.9 NAME 'groupOfNames' " "DESC 'RFC2256: a group of names (DNs)' SUP top " "STRUCTURAL MUST ( member $ cn ) MAY ( businessCategory $ " "seeAlso $ owner $ ou $ o $ description ) )"), (ldap.MOD_ADD, "olcObjectClasses", "{7}( 2.5.6.9 NAME 'groupOfNames' " "DESC 'RFC2256: a group of names (DNs)' SUP top " "STRUCTURAL MUST ( cn ) MAY ( member $ businessCategory $ " "seeAlso $ owner $ ou $ o $ description ) )"), ] ldap_conn = ldap.initialize(ldapi_url) ldap_conn.simple_bind_s(self.admin_rdn + ",cn=config", self.admin_pw) ldap_conn.modify_s("cn={0}core,cn=schema,cn=config", modlist) ldap_conn.unbind_s() # # Add data # ldap_conn = ldap.initialize(self.ldap_url) ldap_conn.simple_bind_s(self.admin_dn, self.admin_pw) ldap_conn.add_s(self.base_dn, [ ("objectClass", ["dcObject", "organization"]), ("o", "Example Company"), ]) ldap_conn.add_s("cn=Manager," + self.base_dn, [ ("objectClass", "organizationalRole"), ]) for ou in ("Users", "Groups", "Netgroups", "Services", "Policies"): ldap_conn.add_s("ou=" + ou + "," + self.base_dn, [ ("objectClass", ["top", "organizationalUnit"]), ]) ldap_conn.unbind_s() def teardown(self): """Teardown the instance.""" # Wait for slapd to stop try: pid_file = open(self.pid_path, "r") try: os.kill(int(pid_file.read()), signal.SIGTERM) finally: pid_file.close() attempt = 0 while os.path.isfile(self.pid_path): attempt = attempt + 1 if attempt > 30: raise Exception("Failed to stop slapd") time.sleep(1) except IOError as e: if e.errno != errno.ENOENT: raise for path in (self.conf_slapd_d_dir, self.run_dir, self.data_dir): shutil.rmtree(path, True) sssd-1.13.4/src/tests/intg/PaxHeaders.16287/ldap_test.py0000644000000000000000000000007412703456111017550 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.110798566 sssd-1.13.4/src/tests/intg/ldap_test.py0000644002412700241270000006410312703456111021223 0ustar00jhrozekjhrozek00000000000000# # LDAP integration test # # Copyright (c) 2015 Red Hat, Inc. # Author: Nikolai Kondrashov # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os import sys import stat import pwd import grp import ent import config import signal import subprocess import time import ldap import pytest import ds_openldap import ldap_ent from util import * LDAP_BASE_DN = "dc=example,dc=com" INTERACTIVE_TIMEOUT = 4 @pytest.fixture(scope="module") def ds_inst(request): """LDAP server instance fixture""" ds_inst = ds_openldap.DSOpenLDAP( config.PREFIX, 10389, LDAP_BASE_DN, "cn=admin", "Secret123" ) try: ds_inst.setup() except: ds_inst.teardown() raise request.addfinalizer(lambda: ds_inst.teardown()) return ds_inst @pytest.fixture(scope="module") def ldap_conn(request, ds_inst): """LDAP server connection fixture""" ldap_conn = ds_inst.bind() ldap_conn.ds_inst = ds_inst request.addfinalizer(lambda: ldap_conn.unbind_s()) return ldap_conn def create_ldap_entries(ldap_conn, ent_list=None): """Add LDAP entries from ent_list""" if ent_list is not None: for entry in ent_list: ldap_conn.add_s(entry[0], entry[1]) def cleanup_ldap_entries(ldap_conn, ent_list=None): """Remove LDAP entries added by create_ldap_entries""" if ent_list is None: for ou in ("Users", "Groups", "Netgroups", "Services", "Policies"): for entry in ldap_conn.search_s("ou=" + ou + "," + ldap_conn.ds_inst.base_dn, ldap.SCOPE_ONELEVEL, attrlist=[]): ldap_conn.delete_s(entry[0]) else: for entry in ent_list: ldap_conn.delete_s(entry[0]) def create_ldap_cleanup(request, ldap_conn, ent_list=None): """Add teardown for removing all user/group LDAP entries""" request.addfinalizer(lambda: cleanup_ldap_entries(ldap_conn, ent_list)) def create_ldap_fixture(request, ldap_conn, ent_list=None): """Add LDAP entries and add teardown for removing them""" create_ldap_entries(ldap_conn, ent_list) create_ldap_cleanup(request, ldap_conn, ent_list) SCHEMA_RFC2307 = "rfc2307" SCHEMA_RFC2307_BIS = "rfc2307bis" def format_basic_conf(ldap_conn, schema, enum): """Format a basic SSSD configuration""" schema_conf = "ldap_schema = " + schema + "\n" if schema == SCHEMA_RFC2307_BIS: schema_conf += "ldap_group_object_class = groupOfNames\n" return unindent("""\ [sssd] debug_level = 0xffff domains = LDAP services = nss, pam [nss] debug_level = 0xffff memcache_timeout = 0 [pam] debug_level = 0xffff [domain/LDAP] ldap_auth_disable_tls_never_use_in_production = true debug_level = 0xffff enumerate = {enum} {schema_conf} id_provider = ldap auth_provider = ldap ldap_uri = {ldap_conn.ds_inst.ldap_url} ldap_search_base = {ldap_conn.ds_inst.base_dn} """).format(**locals()) def format_interactive_conf(ldap_conn, schema): """Format an SSSD configuration with all caches refreshing in 4 seconds""" return \ format_basic_conf(ldap_conn, schema, enum=True) + \ unindent(""" [nss] memcache_timeout = 0 enum_cache_timeout = {0} entry_negative_timeout = 0 [domain/LDAP] ldap_enumeration_refresh_timeout = {0} ldap_purge_cache_timeout = 1 entry_cache_timeout = {0} """).format(INTERACTIVE_TIMEOUT) def create_conf_file(contents): """Create sssd.conf with specified contents""" conf = open(config.CONF_PATH, "w") conf.write(contents) conf.close() os.chmod(config.CONF_PATH, stat.S_IRUSR | stat.S_IWUSR) def cleanup_conf_file(): """Remove sssd.conf, if it exists""" if os.path.lexists(config.CONF_PATH): os.unlink(config.CONF_PATH) def create_conf_cleanup(request): """Add teardown for removing sssd.conf""" request.addfinalizer(cleanup_conf_file) def create_conf_fixture(request, contents): """ Create sssd.conf with specified contents and add teardown for removing it """ create_conf_file(contents) create_conf_cleanup(request) def create_sssd_process(): """Start the SSSD process""" if subprocess.call(["sssd", "-D", "-f"]) != 0: raise Exception("sssd start failed") def cleanup_sssd_process(): """Stop the SSSD process and remove its state""" try: pid_file = open(config.PIDFILE_PATH, "r") pid = int(pid_file.read()) os.kill(pid, signal.SIGTERM) while True: try: os.kill(pid, signal.SIGCONT) except: break time.sleep(1) except: pass for path in os.listdir(config.DB_PATH): os.unlink(config.DB_PATH + "/" + path) for path in os.listdir(config.MCACHE_PATH): os.unlink(config.MCACHE_PATH + "/" + path) def create_sssd_cleanup(request): """Add teardown for stopping SSSD and removing its state""" request.addfinalizer(cleanup_sssd_process) def create_sssd_fixture(request): """Start SSSD and add teardown for stopping it and removing its state""" create_sssd_process() create_sssd_cleanup(request) @pytest.fixture def sanity_rfc2307(request, ldap_conn): ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user1", 1001, 2001) ent_list.add_user("user2", 1002, 2002) ent_list.add_user("user3", 1003, 2003) ent_list.add_group("group1", 2001) ent_list.add_group("group2", 2002) ent_list.add_group("group3", 2003) ent_list.add_group("empty_group", 2010) ent_list.add_group("two_user_group", 2012, ["user1", "user2"]) create_ldap_fixture(request, ldap_conn, ent_list) conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307, enum=True) create_conf_fixture(request, conf) create_sssd_fixture(request) return None @pytest.fixture def simple_rfc2307(request, ldap_conn): ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user('usr\\\\001', 181818, 181818) ent_list.add_group("group1", 181818) create_ldap_fixture(request, ldap_conn, ent_list) conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307, enum=False) create_conf_fixture(request, conf) create_sssd_fixture(request) return None @pytest.fixture def sanity_rfc2307_bis(request, ldap_conn): ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user1", 1001, 2001) ent_list.add_user("user2", 1002, 2002) ent_list.add_user("user3", 1003, 2003) ent_list.add_group_bis("group1", 2001) ent_list.add_group_bis("group2", 2002) ent_list.add_group_bis("group3", 2003) ent_list.add_group_bis("empty_group1", 2010) ent_list.add_group_bis("empty_group2", 2011) ent_list.add_group_bis("two_user_group", 2012, ["user1", "user2"]) ent_list.add_group_bis("group_empty_group", 2013, [], ["empty_group1"]) ent_list.add_group_bis("group_two_empty_groups", 2014, [], ["empty_group1", "empty_group2"]) ent_list.add_group_bis("one_user_group1", 2015, ["user1"]) ent_list.add_group_bis("one_user_group2", 2016, ["user2"]) ent_list.add_group_bis("group_one_user_group", 2017, [], ["one_user_group1"]) ent_list.add_group_bis("group_two_user_group", 2018, [], ["two_user_group"]) ent_list.add_group_bis("group_two_one_user_groups", 2019, [], ["one_user_group1", "one_user_group2"]) create_ldap_fixture(request, ldap_conn, ent_list) conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS, enum=True) create_conf_fixture(request, conf) create_sssd_fixture(request) return None def test_regression_ticket2163(ldap_conn, simple_rfc2307): ent.assert_passwd_by_name( 'usr\\001', dict(name='usr\\001', passwd='*', uid=181818, gid=181818, gecos='181818', shell='/bin/bash')) def test_sanity_rfc2307(ldap_conn, sanity_rfc2307): passwd_pattern = ent.contains_only( dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', dir='/home/user1', shell='/bin/bash'), dict(name='user2', passwd='*', uid=1002, gid=2002, gecos='1002', dir='/home/user2', shell='/bin/bash'), dict(name='user3', passwd='*', uid=1003, gid=2003, gecos='1003', dir='/home/user3', shell='/bin/bash') ) ent.assert_passwd(passwd_pattern) group_pattern = ent.contains_only( dict(name='group1', passwd='*', gid=2001, mem=ent.contains_only()), dict(name='group2', passwd='*', gid=2002, mem=ent.contains_only()), dict(name='group3', passwd='*', gid=2003, mem=ent.contains_only()), dict(name='empty_group', passwd='*', gid=2010, mem=ent.contains_only()), dict(name='two_user_group', passwd='*', gid=2012, mem=ent.contains_only("user1", "user2")) ) ent.assert_group(group_pattern) with pytest.raises(KeyError): pwd.getpwnam("non_existent_user") with pytest.raises(KeyError): pwd.getpwuid(1) with pytest.raises(KeyError): grp.getgrnam("non_existent_group") with pytest.raises(KeyError): grp.getgrgid(1) def test_sanity_rfc2307_bis(ldap_conn, sanity_rfc2307_bis): passwd_pattern = ent.contains_only( dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', dir='/home/user1', shell='/bin/bash'), dict(name='user2', passwd='*', uid=1002, gid=2002, gecos='1002', dir='/home/user2', shell='/bin/bash'), dict(name='user3', passwd='*', uid=1003, gid=2003, gecos='1003', dir='/home/user3', shell='/bin/bash') ) ent.assert_passwd(passwd_pattern) group_pattern = ent.contains_only( dict(name='group1', passwd='*', gid=2001, mem=ent.contains_only()), dict(name='group2', passwd='*', gid=2002, mem=ent.contains_only()), dict(name='group3', passwd='*', gid=2003, mem=ent.contains_only()), dict(name='empty_group1', passwd='*', gid=2010, mem=ent.contains_only()), dict(name='empty_group2', passwd='*', gid=2011, mem=ent.contains_only()), dict(name='two_user_group', passwd='*', gid=2012, mem=ent.contains_only("user1", "user2")), dict(name='group_empty_group', passwd='*', gid=2013, mem=ent.contains_only()), dict(name='group_two_empty_groups', passwd='*', gid=2014, mem=ent.contains_only()), dict(name='one_user_group1', passwd='*', gid=2015, mem=ent.contains_only("user1")), dict(name='one_user_group2', passwd='*', gid=2016, mem=ent.contains_only("user2")), dict(name='group_one_user_group', passwd='*', gid=2017, mem=ent.contains_only("user1")), dict(name='group_two_user_group', passwd='*', gid=2018, mem=ent.contains_only("user1", "user2")), dict(name='group_two_one_user_groups', passwd='*', gid=2019, mem=ent.contains_only("user1", "user2")) ) ent.assert_group(group_pattern) with pytest.raises(KeyError): pwd.getpwnam("non_existent_user") with pytest.raises(KeyError): pwd.getpwuid(1) with pytest.raises(KeyError): grp.getgrnam("non_existent_group") with pytest.raises(KeyError): grp.getgrgid(1) @pytest.fixture def refresh_after_cleanup_task(request, ldap_conn): ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user1", 1001, 2001) ent_list.add_group_bis("group1", 2001, ["user1"]) ent_list.add_group_bis("group2", 2002, [], ["group1"]) create_ldap_fixture(request, ldap_conn, ent_list) conf = \ format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS, enum=False) + \ unindent(""" [domain/LDAP] entry_cache_user_timeout = 1 entry_cache_group_timeout = 5000 ldap_purge_cache_timeout = 3 """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) return None def test_refresh_after_cleanup_task(ldap_conn, refresh_after_cleanup_task): """ Regression test for ticket: https://fedorahosted.org/sssd/ticket/2676 """ ent.assert_group_by_name( "group2", dict(mem=ent.contains_only("user1"))) ent.assert_passwd_by_name( 'user1', dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', shell='/bin/bash')) time.sleep(15) ent.assert_group_by_name( "group2", dict(mem=ent.contains_only("user1"))) @pytest.fixture def blank_rfc2307(request, ldap_conn): """Create blank RFC2307 directory fixture with interactive SSSD conf""" create_ldap_cleanup(request, ldap_conn) create_conf_fixture(request, format_interactive_conf(ldap_conn, SCHEMA_RFC2307)) create_sssd_fixture(request) @pytest.fixture def blank_rfc2307_bis(request, ldap_conn): """Create blank RFC2307bis directory fixture with interactive SSSD conf""" create_ldap_cleanup(request, ldap_conn) create_conf_fixture(request, format_interactive_conf(ldap_conn, SCHEMA_RFC2307_BIS)) create_sssd_fixture(request) @pytest.fixture def user_and_group_rfc2307(request, ldap_conn): """ Create an RFC2307 directory fixture with interactive SSSD conf, one user and one group """ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user", 1001, 2000) ent_list.add_group("group", 2001) create_ldap_fixture(request, ldap_conn, ent_list) create_conf_fixture(request, format_interactive_conf(ldap_conn, SCHEMA_RFC2307)) create_sssd_fixture(request) return None @pytest.fixture def user_and_groups_rfc2307_bis(request, ldap_conn): """ Create an RFC2307bis directory fixture with interactive SSSD conf, one user and two groups """ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user", 1001, 2000) ent_list.add_group_bis("group1", 2001) ent_list.add_group_bis("group2", 2002) create_ldap_fixture(request, ldap_conn, ent_list) create_conf_fixture(request, format_interactive_conf(ldap_conn, SCHEMA_RFC2307_BIS)) create_sssd_fixture(request) return None def test_add_remove_user(ldap_conn, blank_rfc2307): """Test user addition and removal are reflected by SSSD""" e = ldap_ent.user(ldap_conn.ds_inst.base_dn, "user", 1001, 2000) time.sleep(INTERACTIVE_TIMEOUT/2) # Add the user ent.assert_passwd(ent.contains_only()) ldap_conn.add_s(*e) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_passwd(ent.contains_only(dict(name="user", uid=1001))) # Remove the user ldap_conn.delete_s(e[0]) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_passwd(ent.contains_only()) def test_add_remove_group_rfc2307(ldap_conn, blank_rfc2307): """Test RFC2307 group addition and removal are reflected by SSSD""" e = ldap_ent.group(ldap_conn.ds_inst.base_dn, "group", 2001) time.sleep(INTERACTIVE_TIMEOUT/2) # Add the group ent.assert_group(ent.contains_only()) ldap_conn.add_s(*e) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_group(ent.contains_only(dict(name="group", gid=2001))) # Remove the group ldap_conn.delete_s(e[0]) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_group(ent.contains_only()) def test_add_remove_group_rfc2307_bis(ldap_conn, blank_rfc2307_bis): """Test RFC2307bis group addition and removal are reflected by SSSD""" e = ldap_ent.group_bis(ldap_conn.ds_inst.base_dn, "group", 2001) time.sleep(INTERACTIVE_TIMEOUT/2) # Add the group ent.assert_group(ent.contains_only()) ldap_conn.add_s(*e) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_group(ent.contains_only(dict(name="group", gid=2001))) # Remove the group ldap_conn.delete_s(e[0]) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_group(ent.contains_only()) def test_add_remove_membership_rfc2307(ldap_conn, user_and_group_rfc2307): """Test user membership addition and removal are reflected by SSSD""" time.sleep(INTERACTIVE_TIMEOUT/2) # Add user to group ent.assert_group_by_name("group", dict(mem=ent.contains_only())) ldap_conn.modify_s("cn=group,ou=Groups," + ldap_conn.ds_inst.base_dn, [(ldap.MOD_REPLACE, "memberUid", "user")]) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_group_by_name("group", dict(mem=ent.contains_only("user"))) # Remove user from group ldap_conn.modify_s("cn=group,ou=Groups," + ldap_conn.ds_inst.base_dn, [(ldap.MOD_DELETE, "memberUid", None)]) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_group_by_name("group", dict(mem=ent.contains_only())) def test_add_remove_membership_rfc2307_bis(ldap_conn, user_and_groups_rfc2307_bis): """ Test user and group membership addition and removal are reflected by SSSD, with RFC2307bis schema """ time.sleep(INTERACTIVE_TIMEOUT/2) # Add user to group1 ent.assert_group_by_name("group1", dict(mem=ent.contains_only())) ldap_conn.modify_s("cn=group1,ou=Groups," + ldap_conn.ds_inst.base_dn, [(ldap.MOD_REPLACE, "member", "uid=user,ou=Users," + ldap_conn.ds_inst.base_dn)]) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_group_by_name("group1", dict(mem=ent.contains_only("user"))) # Add group1 to group2 ldap_conn.modify_s("cn=group2,ou=Groups," + ldap_conn.ds_inst.base_dn, [(ldap.MOD_REPLACE, "member", "cn=group1,ou=Groups," + ldap_conn.ds_inst.base_dn)]) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_group_by_name("group2", dict(mem=ent.contains_only("user"))) # Remove group1 from group2 ldap_conn.modify_s("cn=group2,ou=Groups," + ldap_conn.ds_inst.base_dn, [(ldap.MOD_DELETE, "member", None)]) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_group_by_name("group2", dict(mem=ent.contains_only())) # Remove user from group1 ldap_conn.modify_s("cn=group1,ou=Groups," + ldap_conn.ds_inst.base_dn, [(ldap.MOD_DELETE, "member", None)]) time.sleep(INTERACTIVE_TIMEOUT) ent.assert_group_by_name("group1", dict(mem=ent.contains_only())) @pytest.fixture def override_homedir(request, ldap_conn): ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user_with_homedir_A", 1001, 2001, homeDirectory="/home/A") ent_list.add_user("user_with_homedir_B", 1002, 2002, homeDirectory="/home/B") ent_list.add_user("user_with_empty_homedir", 1003, 2003, homeDirectory="") create_ldap_fixture(request, ldap_conn, ent_list) conf = \ format_basic_conf(ldap_conn, SCHEMA_RFC2307, enum=True) + \ unindent("""\ [nss] override_homedir = /home/B """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) def test_override_homedir(override_homedir): """Test the effect of the "override_homedir" option""" ent.assert_passwd( ent.contains_only( dict(name="user_with_homedir_A", uid=1001, dir="/home/B"), dict(name="user_with_homedir_B", uid=1002, dir="/home/B"), dict(name="user_with_empty_homedir", uid=1003, dir="/home/B") ) ) @pytest.fixture def fallback_homedir(request, ldap_conn): ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user_with_homedir_A", 1001, 2001, homeDirectory="/home/A") ent_list.add_user("user_with_homedir_B", 1002, 2002, homeDirectory="/home/B") ent_list.add_user("user_with_empty_homedir", 1003, 2003, homeDirectory="") create_ldap_fixture(request, ldap_conn, ent_list) conf = \ format_basic_conf(ldap_conn, SCHEMA_RFC2307, enum=True) + \ unindent("""\ [nss] fallback_homedir = /home/B """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) def test_fallback_homedir(fallback_homedir): """Test the effect of the "fallback_homedir" option""" ent.assert_passwd( ent.contains_only( dict(name="user_with_homedir_A", uid=1001, dir="/home/A"), dict(name="user_with_homedir_B", uid=1002, dir="/home/B"), dict(name="user_with_empty_homedir", uid=1003, dir="/home/B") ) ) @pytest.fixture def override_shell(request, ldap_conn): ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user_with_shell_A", 1001, 2001, loginShell="/bin/A") ent_list.add_user("user_with_shell_B", 1002, 2002, loginShell="/bin/B") ent_list.add_user("user_with_empty_shell", 1003, 2003, loginShell="") create_ldap_fixture(request, ldap_conn, ent_list) conf = \ format_basic_conf(ldap_conn, SCHEMA_RFC2307, enum=True) + \ unindent("""\ [nss] override_shell = /bin/B """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) def test_override_shell(override_shell): """Test the effect of the "override_shell" option""" ent.assert_passwd( ent.contains_only( dict(name="user_with_shell_A", uid=1001, shell="/bin/B"), dict(name="user_with_shell_B", uid=1002, shell="/bin/B"), dict(name="user_with_empty_shell", uid=1003, shell="/bin/B") ) ) @pytest.fixture def shell_fallback(request, ldap_conn): ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user_with_sh_shell", 1001, 2001, loginShell="/bin/sh") ent_list.add_user("user_with_not_installed_shell", 1002, 2002, loginShell="/bin/not_installed") ent_list.add_user("user_with_empty_shell", 1003, 2003, loginShell="") create_ldap_fixture(request, ldap_conn, ent_list) conf = \ format_basic_conf(ldap_conn, SCHEMA_RFC2307, enum=True) + \ unindent("""\ [nss] shell_fallback = /bin/fallback allowed_shells = /bin/not_installed """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) def test_shell_fallback(shell_fallback): """Test the effect of the "shell_fallback" option""" ent.assert_passwd( ent.contains_only( dict(name="user_with_sh_shell", uid=1001, shell="/bin/sh"), dict(name="user_with_not_installed_shell", uid=1002, shell="/bin/fallback"), dict(name="user_with_empty_shell", uid=1003, shell="") ) ) @pytest.fixture def default_shell(request, ldap_conn): ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user_with_sh_shell", 1001, 2001, loginShell="/bin/sh") ent_list.add_user("user_with_not_installed_shell", 1002, 2002, loginShell="/bin/not_installed") ent_list.add_user("user_with_empty_shell", 1003, 2003, loginShell="") create_ldap_fixture(request, ldap_conn, ent_list) conf = \ format_basic_conf(ldap_conn, SCHEMA_RFC2307, enum=True) + \ unindent("""\ [nss] default_shell = /bin/default allowed_shells = /bin/default, /bin/not_installed shell_fallback = /bin/fallback """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) def test_default_shell(default_shell): """Test the effect of the "default_shell" option""" ent.assert_passwd( ent.contains_only( dict(name="user_with_sh_shell", uid=1001, shell="/bin/sh"), dict(name="user_with_not_installed_shell", uid=1002, shell="/bin/fallback"), dict(name="user_with_empty_shell", uid=1003, shell="/bin/default") ) ) @pytest.fixture def vetoed_shells(request, ldap_conn): ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user_with_sh_shell", 1001, 2001, loginShell="/bin/sh") ent_list.add_user("user_with_vetoed_shell", 1002, 2002, loginShell="/bin/vetoed") ent_list.add_user("user_with_empty_shell", 1003, 2003, loginShell="") create_ldap_fixture(request, ldap_conn, ent_list) conf = \ format_basic_conf(ldap_conn, SCHEMA_RFC2307, enum=True) + \ unindent("""\ [nss] default_shell = /bin/default vetoed_shells = /bin/vetoed shell_fallback = /bin/fallback """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) def test_vetoed_shells(vetoed_shells): """Test the effect of the "vetoed_shells" option""" ent.assert_passwd( ent.contains_only( dict(name="user_with_sh_shell", uid=1001, shell="/bin/sh"), dict(name="user_with_vetoed_shell", uid=1002, shell="/bin/fallback"), dict(name="user_with_empty_shell", uid=1003, shell="/bin/default") ) ) sssd-1.13.4/src/tests/intg/PaxHeaders.16287/ds.py0000644000000000000000000000007412703456111016177 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.105798549 sssd-1.13.4/src/tests/intg/ds.py0000644002412700241270000000374412703456111017656 0ustar00jhrozekjhrozek00000000000000# # Abstract directory server instance class # # Copyright (c) 2015 Red Hat, Inc. # Author: Nikolai Kondrashov # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import ldap class DS: """Abstract directory server instance.""" def __init__(self, dir, port, base_dn, admin_rdn, admin_pw): """ Initialize the instance. Arguments: dir Path to the root of the filesystem hierarchy to create the instance under. port TCP port on localhost to bind the server to. base_dn Base DN. admin_rdn Administrator DN, relative to BASE_DN. admin_pw Administrator password. """ self.dir = dir self.port = port self.ldap_url = "ldap://localhost:" + str(self.port) self.base_dn = base_dn self.admin_rdn = admin_rdn self.admin_dn = admin_rdn + "," + base_dn self.admin_pw = admin_pw def setup(self): """Setup the instance""" raise NotImplementedError() def teardown(self): """Teardown the instance""" raise NotImplementedError() def bind(self): """Connect to the server and bind as admin, return connection.""" conn = ldap.initialize(self.ldap_url) conn.simple_bind_s(self.admin_dn, self.admin_pw) return conn def __del__(self): """Destroy the instance.""" self.teardown() sssd-1.13.4/src/tests/intg/PaxHeaders.16287/test_local_domain.py0000644000000000000000000000007412703456111021251 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.111798569 sssd-1.13.4/src/tests/intg/test_local_domain.py0000644002412700241270000000612212703456111022721 0ustar00jhrozekjhrozek00000000000000# # SSSD LOCAL domain tests # # Copyright (c) 2015 Red Hat, Inc. # Author: Michal Zidek # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os import stat import pwd import time import config import signal import subprocess import pytest from util import unindent def stop_sssd(): pid_file = open(config.PIDFILE_PATH, "r") pid = int(pid_file.read()) os.kill(pid, signal.SIGTERM) while True: try: os.kill(pid, signal.SIGCONT) except: break time.sleep(1) def create_conf_fixture(request, contents): """Generate sssd.conf and add teardown for removing it""" conf = open(config.CONF_PATH, "w") conf.write(contents) conf.close() os.chmod(config.CONF_PATH, stat.S_IRUSR | stat.S_IWUSR) request.addfinalizer(lambda: os.unlink(config.CONF_PATH)) def create_sssd_fixture(request): """Start sssd and add teardown for stopping it and removing state""" if subprocess.call(["sssd", "-D", "-f"]) != 0: raise Exception("sssd start failed") def teardown(): try: stop_sssd() except: pass subprocess.call(["sss_cache", "-E"]) for path in os.listdir(config.DB_PATH): os.unlink(config.DB_PATH + "/" + path) # FIXME: Uncomment this when ticket #2726 is solved # https://fedorahosted.org/sssd/ticket/2726 # for path in os.listdir(config.MCACHE_PATH): # os.unlink(config.MCACHE_PATH + "/" + path) request.addfinalizer(teardown) @pytest.fixture def local_domain_only(request): conf = unindent("""\ [sssd] domains = LOCAL services = nss [nss] memcache_timeout = 0 [domain/LOCAL] id_provider = local min_id = 10000 max_id = 20000 """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) return None def assert_nonexistent_user(name): with pytest.raises(KeyError): pwd.getpwnam(name) def test_wrong_LC_ALL(local_domain_only): """ Regression test for ticket https://fedorahosted.org/sssd/ticket/2785 """ subprocess.check_call(["sss_useradd", "foo", "-M"]) pwd.getpwnam("foo") # Change the LC_ALL variable to nonexistent locale oldvalue = os.environ.get("LC_ALL", "") os.environ["LC_ALL"] = "nonexistent_locale" # sss_userdel must remove the user despite wrong LC_ALL subprocess.check_call(["sss_userdel", "foo", "-R"]) assert_nonexistent_user("foo") os.environ["LC_LOCAL"] = oldvalue sssd-1.13.4/src/tests/intg/PaxHeaders.16287/util.py0000644000000000000000000000007412703456111016546 xustar0030 atime=1460561751.658715654 30 ctime=1460561776.112798572 sssd-1.13.4/src/tests/intg/util.py0000644002412700241270000000362312703456111020221 0ustar00jhrozekjhrozek00000000000000# # Various functions # # Copyright (c) 2015 Red Hat, Inc. # Author: Nikolai Kondrashov # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import re import os import subprocess import config UNINDENT_RE = re.compile("^ +", re.MULTILINE) def unindent(text): """ Unindent text by removing at most the number of spaces present in the first non-empty line from the beginning of every line. """ indent_ref = [0] def replace(match): if indent_ref[0] == 0: indent_ref[0] = len(match.group()) return match.group()[indent_ref[0]:] return UNINDENT_RE.sub(replace, text) def run_shell(): """ Execute an interactive shell under "screen", preserving environment. For use as a breakpoint for debugging. """ my_env = os.environ.copy() my_env["ROOT_DIR"] = config.PREFIX # screen filter out LD_* evniroment varibles. # Back-up them and set them later in screenrc my_env["_LD_LIBRARY_PATH"] = os.getenv("LD_LIBRARY_PATH", "") my_env["_LD_PRELOAD"] = os.getenv("LD_PRELOAD", "") subprocess.call([ "screen", "-DAm", "-S", "sssd_cwrap_session", "-c", ".config/screenrc"], env=my_env ) def first_dir(*args): """Return first argument that points to an existing directory.""" for arg in args: if os.path.isdir(arg): return arg sssd-1.13.4/src/tests/intg/PaxHeaders.16287/ldap_local_override_test.py0000644000000000000000000000007412703456111022621 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.110798566 sssd-1.13.4/src/tests/intg/ldap_local_override_test.py0000644002412700241270000007275612703456111024311 0ustar00jhrozekjhrozek00000000000000# # integration test for sss_override tool # # Copyright (c) 2015 Red Hat, Inc. # Author: Pavel Reichl # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os import stat import ent import grp import pwd import config import signal import subprocess import time import pytest import ds_openldap import ldap_ent import sssd_id from util import unindent try: from subprocess import check_output except ImportError: # In python 2.6 , the module subprocess does not have the function # check_output. This is a falback implementation def check_output(*popenargs, **kwargs): if 'stdout' in kwargs: raise ValueError('stdout argument not allowed, it will be ' 'overridden.') process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs) output, _ = process.communicate() retcode = process.poll() if retcode: cmd = kwargs.get("args") if cmd is None: cmd = popenargs[0] raise subprocess.CalledProcessError(retcode, cmd, output=output) return output @pytest.fixture(scope="module") def ds_inst(request): """LDAP server instance fixture""" ds_inst = ds_openldap.DSOpenLDAP( config.PREFIX, 10389, 'dc=example,dc=com', "cn=admin", "Secret123") try: ds_inst.setup() except: ds_inst.teardown() raise request.addfinalizer(lambda: ds_inst.teardown()) return ds_inst @pytest.fixture(scope="module") def ldap_conn(request, ds_inst): """LDAP server connection fixture""" ldap_conn = ds_inst.bind() ldap_conn.ds_inst = ds_inst request.addfinalizer(lambda: ldap_conn.unbind_s()) return ldap_conn def create_ldap_fixture(request, ldap_conn, ent_list): """Add LDAP entries and add teardown for removing them""" for entry in ent_list: ldap_conn.add_s(entry[0], entry[1]) def teardown(): for entry in ent_list: ldap_conn.delete_s(entry[0]) request.addfinalizer(teardown) def create_conf_fixture(request, contents): """Generate sssd.conf and add teardown for removing it""" conf = open(config.CONF_PATH, "w") conf.write(contents) conf.close() os.chmod(config.CONF_PATH, stat.S_IRUSR | stat.S_IWUSR) request.addfinalizer(lambda: os.unlink(config.CONF_PATH)) def stop_sssd(): pid_file = open(config.PIDFILE_PATH, "r") pid = int(pid_file.read()) os.kill(pid, signal.SIGTERM) while True: try: os.kill(pid, signal.SIGCONT) except: break time.sleep(1) def start_sssd(): """Start sssd""" if subprocess.call(["sssd", "-D", "-f"]) != 0: raise Exception("sssd start failed") def restart_sssd(): stop_sssd() start_sssd() def create_sssd_fixture(request): """Start sssd and add teardown for stopping it and removing state""" if subprocess.call(["sssd", "-D", "-f"]) != 0: raise Exception("sssd start failed") def teardown(): try: stop_sssd() except: pass for path in os.listdir(config.DB_PATH): os.unlink(config.DB_PATH + "/" + path) for path in os.listdir(config.MCACHE_PATH): os.unlink(config.MCACHE_PATH + "/" + path) request.addfinalizer(teardown) OVERRIDE_FILENAME = "export_file" def prepare_sssd(request, ldap_conn, use_fully_qualified_names=False, case_sensitive=True): """Prepare SSSD with defaults""" conf = unindent("""\ [sssd] domains = LDAP services = nss [nss] memcache_timeout = 1 [domain/LDAP] ldap_auth_disable_tls_never_use_in_production = true ldap_schema = rfc2307 id_provider = ldap auth_provider = ldap sudo_provider = ldap ldap_uri = {ldap_conn.ds_inst.ldap_url} ldap_search_base = {ldap_conn.ds_inst.base_dn} use_fully_qualified_names = {use_fully_qualified_names} case_sensitive = {case_sensitive} """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) def teardown(): # remove user export file try: os.unlink(OVERRIDE_FILENAME) except: pass request.addfinalizer(teardown) # # Common asserts for users # def assert_user_default(): # Assert entries are not overriden with pytest.raises(KeyError): pwd.getpwnam('ov_user1') with pytest.raises(KeyError): pwd.getpwnam('ov_user1@LDAP') with pytest.raises(KeyError): pwd.getpwnam('ov_user2') with pytest.raises(KeyError): pwd.getpwnam('ov_user2@LDAP') user1 = dict(name='user1', passwd='*', uid=10001, gid=20001, gecos='User Number 1', dir='/home/user1', shell='/bin/user1_shell') user2 = dict(name='user2', passwd='*', uid=10002, gid=20001, gecos='User Number 2', dir='/home/user2', shell='/bin/user2_shell') ent.assert_passwd_by_name('user1', user1) ent.assert_passwd_by_name('user1@LDAP', user1) ent.assert_passwd_by_name('user2', user2) ent.assert_passwd_by_name('user2@LDAP', user2) def assert_user_overriden(): user1 = dict(name='ov_user1', passwd='*', uid=10010, gid=20010, gecos='Overriden User 1', dir='/home/ov/user1', shell='/bin/ov_user1_shell') user2 = dict(name='ov_user2', passwd='*', uid=10020, gid=20020, gecos='Overriden User 2', dir='/home/ov/user2', shell='/bin/ov_user2_shell') ent.assert_passwd_by_name('user1', user1) ent.assert_passwd_by_name('user1@LDAP', user1) ent.assert_passwd_by_name('ov_user1', user1) ent.assert_passwd_by_name('ov_user1@LDAP', user1) ent.assert_passwd_by_name('user2', user2) ent.assert_passwd_by_name('user2@LDAP', user2) ent.assert_passwd_by_name('ov_user2', user2) ent.assert_passwd_by_name('ov_user2@LDAP', user2) # # Common fixtures for users # @pytest.fixture def env_two_users_and_group(request, ldap_conn): prepare_sssd(request, ldap_conn) # Add entries ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user1", 10001, 20001, gecos='User Number 1', loginShell='/bin/user1_shell', homeDirectory='/home/user1') ent_list.add_user("user2", 10002, 20001, gecos='User Number 2', loginShell='/bin/user2_shell', homeDirectory='/home/user2') ent_list.add_group("group", 2001, ["user2", "user1"]) create_ldap_fixture(request, ldap_conn, ent_list) # Assert entries are not overriden assert_user_default() @pytest.fixture def env_two_users_and_group_overriden(request, ldap_conn, env_two_users_and_group): # Override subprocess.check_call(["sss_override", "user-add", "user1", "-u", "10010", "-g", "20010", "-n", "ov_user1", "-c", "Overriden User 1", "-h", "/home/ov/user1", "-s", "/bin/ov_user1_shell"]) subprocess.check_call(["sss_override", "user-add", "user2@LDAP", "-u", "10020", "-g", "20020", "-n", "ov_user2", "-c", "Overriden User 2", "-h", "/home/ov/user2", "-s", "/bin/ov_user2_shell"]) # Restart SSSD so the override might take effect restart_sssd() # Assert entries are overriden assert_user_overriden() # # Simple user override # @pytest.fixture def env_simple_user_override(request, ldap_conn, env_two_users_and_group): # Override subprocess.check_call(["sss_override", "user-add", "user1", "-u", "10010", "-g", "20010", "-n", "ov_user1", "-c", "Overriden User 1", "-h", "/home/ov/user1", "-s", "/bin/ov_user1_shell"]) subprocess.check_call(["sss_override", "user-add", "user2@LDAP", "-u", "10020", "-g", "20020", "-n", "ov_user2", "-c", "Overriden User 2", "-h", "/home/ov/user2", "-s", "/bin/ov_user2_shell"]) # Restart SSSD so the override might take effect restart_sssd() def test_simple_user_override(ldap_conn, env_simple_user_override): """Test entries are overriden""" assert_user_overriden() # # Root user override # @pytest.fixture def env_root_user_override(request, ldap_conn, env_two_users_and_group): # Assert entries are not overriden ent.assert_passwd_by_name( 'root', dict(name='root', uid=0, gid=0)) ent.assert_passwd_by_uid(0, dict(name="root")) # Override subprocess.check_call(["sss_override", "user-add", "user1", "-u", "0", "-g", "0", "-n", "ov_user1", "-c", "Overriden User 1", "-h", "/home/ov/user1", "-s", "/bin/ov_user1_shell"]) subprocess.check_call(["sss_override", "user-add", "user2", "-u", "10020", "-g", "20020", "-n", "root", "-c", "Overriden User 2", "-h", "/home/ov/user2", "-s", "/bin/ov_user2_shell"]) # Restart SSSD so the override might take effect restart_sssd() def test_root_user_override(ldap_conn, env_root_user_override): """Test entries are not overriden to root""" # Override does not have to happen completly, trying to set uid or gid # to 0 is simply ignored. ent.assert_passwd_by_name( 'ov_user1', dict(name='ov_user1', passwd='*', uid=10001, gid=20001, gecos='Overriden User 1', dir='/home/ov/user1', shell='/bin/ov_user1_shell')) # We can create override with name root. This test is just for tracking # that this particular behavior won't change. ent.assert_passwd_by_name( 'user2', dict(name='root', passwd='*', uid=10020, gid=20020, gecos='Overriden User 2', dir='/home/ov/user2', shell='/bin/ov_user2_shell')) ent.assert_passwd_by_uid(0, dict(name="root")) # # Override replaces previous override # @pytest.fixture def env_replace_user_override(request, ldap_conn): prepare_sssd(request, ldap_conn) # Add entries ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user1", 10001, 20001, gecos='User Number 1', loginShell='/bin/user1_shell', homeDirectory='/home/user1') create_ldap_fixture(request, ldap_conn, ent_list) # Assert entries are not overriden ent.assert_passwd_by_name( 'user1', dict(name='user1', passwd='*', uid=10001, gid=20001, gecos='User Number 1', dir='/home/user1', shell='/bin/user1_shell')) # Override subprocess.check_call(["sss_override", "user-add", "user1", "-u", "10010", "-g", "20010", "-n", "ov_user1", "-c", "Overriden User 1", "-h", "/home/ov/user1", "-s", "/bin/ov_user1_shell"]) # Restart SSSD so the override might take effect restart_sssd() # Assert entries are overriden ent.assert_passwd_by_name( 'user1', dict(name='ov_user1', passwd='*', uid=10010, gid=20010, gecos='Overriden User 1', dir='/home/ov/user1', shell='/bin/ov_user1_shell')) # Override of override subprocess.check_call(["sss_override", "user-add", "user1", "-u", "10100", "-g", "20100", "-n", "ov2_user1", "-c", "Overriden2 User 1", "-h", "/home/ov2/user1", "-s", "/bin/ov2_user1_shell"]) # Restart SSSD so the override might take effect restart_sssd() def test_replace_user_override(ldap_conn, env_replace_user_override): user = dict(name='ov2_user1', passwd='*', uid=10100, gid=20100, gecos='Overriden2 User 1', dir='/home/ov2/user1', shell='/bin/ov2_user1_shell') ent.assert_passwd_by_name('ov2_user1', user) ent.assert_passwd_by_name('ov2_user1@LDAP', user) with pytest.raises(KeyError): pwd.getpwnam('ov_user1') with pytest.raises(KeyError): pwd.getpwnam('ov_user1@LDAP') # # Override removal # @pytest.fixture def env_remove_user_override(request, ldap_conn, env_two_users_and_group_overriden): # Drop all overrides subprocess.check_call(["sss_override", "user-del", "user1"]) subprocess.check_call(["sss_override", "user-del", "user2@LDAP"]) # Avoid hitting memory cache time.sleep(2) def test_remove_user_override(ldap_conn, env_remove_user_override): # Test entries are not overriden assert_user_default() # # Override import/export # @pytest.fixture def env_imp_exp_user_override(request, ldap_conn, env_two_users_and_group_overriden): # Export overrides subprocess.check_call(["sss_override", "user-export", OVERRIDE_FILENAME]) # Drop all overrides subprocess.check_call(["sss_override", "user-del", "user1"]) subprocess.check_call(["sss_override", "user-del", "user2@LDAP"]) # Avoid hitting memory cache time.sleep(2) # Assert entries are not overridden assert_user_default() # Import overrides subprocess.check_call(["sss_override", "user-import", OVERRIDE_FILENAME]) restart_sssd() def test_imp_exp_user_override(ldap_conn, env_imp_exp_user_override): assert_user_overriden() # # Override user-show # @pytest.fixture def env_show_user_override(request, ldap_conn, env_two_users_and_group_overriden): pass def test_show_user_override(ldap_conn, env_show_user_override): out = check_output(['sss_override', 'user-show', 'user1']) assert out == "user1@LDAP:ov_user1:10010:20010:Overriden User 1:"\ "/home/ov/user1:/bin/ov_user1_shell\n" out = check_output(['sss_override', 'user-show', 'user2@LDAP']) assert out == "user2@LDAP:ov_user2:10020:20020:Overriden User 2:"\ "/home/ov/user2:/bin/ov_user2_shell\n" # Return error on non-existing user ret = subprocess.call(['sss_override', 'user-show', 'nonexisting_user']) assert ret == 1 # # Override user-find # @pytest.fixture def env_find_user_override(request, ldap_conn, env_two_users_and_group_overriden): pass def test_find_user_override(ldap_conn, env_find_user_override): out = check_output(['sss_override', 'user-find']) # Expected override of users exp_usr_ovrd = ['user1@LDAP:ov_user1:10010:20010:Overriden User 1:' '/home/ov/user1:/bin/ov_user1_shell', 'user2@LDAP:ov_user2:10020:20020:Overriden User 2:' '/home/ov/user2:/bin/ov_user2_shell'] assert set(out.splitlines()) == set(exp_usr_ovrd) out = check_output(['sss_override', 'user-find', '--domain=LDAP']) assert set(out.splitlines()) == set(exp_usr_ovrd) # Unexpected parameter is reported ret = subprocess.call(['sss_override', 'user-find', 'PARAM']) assert ret == 1 # # Group tests # # # Common group asserts # def assert_group_overriden(): # Assert entries are overridden empty_group = dict(gid=3002, mem=ent.contains_only()) group = dict(gid=3001, mem=ent.contains_only("user1", "user2")) ent.assert_group_by_name("group", group) ent.assert_group_by_name("group@LDAP", group) ent.assert_group_by_name("ov_group", group) ent.assert_group_by_name("ov_group@LDAP", group) ent.assert_group_by_name("empty_group", empty_group) ent.assert_group_by_name("empty_group@LDAP", empty_group) ent.assert_group_by_name("ov_empty_group", empty_group) ent.assert_group_by_name("ov_empty_group@LDAP", empty_group) def assert_group_default(): # Assert entries are not overridden with pytest.raises(KeyError): pwd.getpwnam('ov_group') with pytest.raises(KeyError): pwd.getpwnam('ov_group@LDAP') with pytest.raises(KeyError): pwd.getpwnam('ov_empty_group') with pytest.raises(KeyError): pwd.getpwnam('ov_empty_group@LDAP') empty_group = dict(gid=2002, mem=ent.contains_only()) group = dict(gid=2001, mem=ent.contains_only("user1", "user2")) ent.assert_group_by_name("group", group) ent.assert_group_by_name("group@LDAP", group) ent.assert_group_by_name("empty_group", empty_group) ent.assert_group_by_name("empty_group@LDAP", empty_group) # # Common fixtures for groups # @pytest.fixture def env_group_basic(request, ldap_conn): prepare_sssd(request, ldap_conn) # Add entries ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user1", 10001, 20001, gecos='User Number 1', loginShell='/bin/user1_shell', homeDirectory='/home/user1') ent_list.add_user("user2", 10002, 20001, gecos='User Number 2', loginShell='/bin/user2_shell', homeDirectory='/home/user2') ent_list.add_group("group", 2001, ["user2", "user1"]) ent_list.add_group("empty_group", 2002, []) create_ldap_fixture(request, ldap_conn, ent_list) # Assert entries are not overriden with pytest.raises(KeyError): pwd.getpwnam('ov_group') with pytest.raises(KeyError): pwd.getpwnam('ov_group@LDAP') with pytest.raises(KeyError): pwd.getpwnam('ov_empty_group') with pytest.raises(KeyError): pwd.getpwnam('ov_empty_group@LDAP') @pytest.fixture def env_group_override(request, ldap_conn, env_group_basic): # Override subprocess.check_call(["sss_override", "group-add", "group", "-n", "ov_group", "-g", "3001"]) subprocess.check_call(["sss_override", "group-add", "empty_group@LDAP", "--name", "ov_empty_group", "--gid", "3002"]) # Restart SSSD so the override might take effect restart_sssd() # Assert entries are overridden assert_group_overriden() # # Simple group override # @pytest.fixture def env_simple_group_override(request, ldap_conn, env_group_basic): # Override subprocess.check_call(["sss_override", "group-add", "group", "-n", "ov_group", "-g", "3001"]) subprocess.check_call(["sss_override", "group-add", "empty_group@LDAP", "--name", "ov_empty_group", "--gid", "3002"]) # Restart SSSD so the override might take effect restart_sssd() def test_simple_group_override(ldap_conn, env_simple_group_override): """Test entries are overriden""" assert_group_overriden() # # Root group override # @pytest.fixture def env_root_group_override(request, ldap_conn, env_group_basic): # Override subprocess.check_call(["sss_override", "group-add", "group", "-n", "ov_group", "-g", "0"]) subprocess.check_call(["sss_override", "group-add", "empty_group@LDAP", "--name", "ov_empty_group", "--gid", "0"]) # Restart SSSD so the override might take effect restart_sssd() def test_root_group_override(ldap_conn, env_root_group_override): """Test entries are overriden""" group = dict(gid=2001, mem=ent.contains_only("user1", "user2")) empty_group = dict(gid=2002, mem=ent.contains_only()) ent.assert_group_by_name("group", group) ent.assert_group_by_name("ov_group", group) ent.assert_group_by_name("group@LDAP", group) ent.assert_group_by_name("ov_group@LDAP", group) ent.assert_group_by_name("empty_group", empty_group) ent.assert_group_by_name("ov_empty_group", empty_group) ent.assert_group_by_name("empty_group@LDAP", empty_group) ent.assert_group_by_name("ov_empty_group@LDAP", empty_group) # # Replace group override # @pytest.fixture def env_replace_group_override(request, ldap_conn, env_group_override): # Override of override subprocess.check_call(["sss_override", "group-add", "group", "-n", "ov2_group", "-g", "4001"]) subprocess.check_call(["sss_override", "group-add", "empty_group@LDAP", "--name", "ov2_empty_group", "--gid", "4002"]) # Restart SSSD so the override might take effect restart_sssd() def test_replace_group_override(ldap_conn, env_replace_group_override): # Test overrides are overridden with pytest.raises(KeyError): pwd.getpwnam('ov_group') with pytest.raises(KeyError): pwd.getpwnam('ov_group@LDAP') with pytest.raises(KeyError): pwd.getpwnam('ov_empty_group') with pytest.raises(KeyError): pwd.getpwnam('ov_empty_group@LDAP') group = dict(gid=4001, mem=ent.contains_only("user1", "user2")) empty_group = dict(gid=4002, mem=ent.contains_only()) ent.assert_group_by_name("group", group) ent.assert_group_by_name("ov2_group", group) ent.assert_group_by_name("group@LDAP", group) ent.assert_group_by_name("ov2_group@LDAP", group) ent.assert_group_by_name("empty_group", empty_group) ent.assert_group_by_name("empty_group@LDAP", empty_group) ent.assert_group_by_name("ov2_empty_group", empty_group) ent.assert_group_by_name("ov2_empty_group@LDAP", empty_group) # # Remove group override # @pytest.fixture def env_remove_group_override(request, ldap_conn, env_group_override): # Drop all overrides subprocess.check_call(["sss_override", "group-del", "group"]) subprocess.check_call(["sss_override", "group-del", "empty_group@LDAP"]) # Avoid hitting memory cache time.sleep(2) def test_remove_group_override(ldap_conn, env_remove_group_override): # Test overrides were dropped assert_group_default() # # Overridde group import/export # @pytest.fixture def env_imp_exp_group_override(request, ldap_conn, env_group_override): # Export overrides subprocess.check_call(["sss_override", "group-export", OVERRIDE_FILENAME]) # Drop all overrides subprocess.check_call(["sss_override", "group-del", "group"]) subprocess.check_call(["sss_override", "group-del", "empty_group@LDAP"]) # Avoid hitting memory cache time.sleep(2) assert_group_default() # Import overrides subprocess.check_call(["sss_override", "group-import", OVERRIDE_FILENAME]) restart_sssd() def test_imp_exp_group_override(ldap_conn, env_imp_exp_group_override): assert_group_overriden() # Regression test for bug #2802 # sss_override segfaults when accidentally adding --help flag to some commands @pytest.fixture def env_regr_2802_override(request, ldap_conn): prepare_sssd(request, ldap_conn) def test_regr_2802_override(ldap_conn, env_regr_2802_override): subprocess.check_call(["sss_override", "user-del", "--help"]) # Regression test for bug #2757 # sss_override does not work correctly when 'use_fully_qualified_names = True' @pytest.fixture def env_regr_2757_override(request, ldap_conn): prepare_sssd(request, ldap_conn, use_fully_qualified_names=True) # Add entries ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user1", 10001, 20001) create_ldap_fixture(request, ldap_conn, ent_list) # Assert entries are not overridden ent.assert_passwd_by_name( 'user1@LDAP', dict(name='user1@LDAP', passwd='*', uid=10001, gid=20001)) with pytest.raises(KeyError): pwd.getpwnam('alias1') with pytest.raises(KeyError): pwd.getpwnam('alias1@LDAP') # Override subprocess.check_call(["sss_override", "user-add", "user1@LDAP", "-n", "alias1"]) restart_sssd() def test_regr_2757_override(ldap_conn, env_regr_2757_override): # Assert entries are overridden ent.assert_passwd_by_name( 'user1@LDAP', dict(name='alias1@LDAP', passwd='*', uid=10001, gid=20001)) ent.assert_passwd_by_name( 'alias1@LDAP', dict(name='alias1@LDAP', passwd='*', uid=10001, gid=20001)) with pytest.raises(KeyError): pwd.getpwnam('user1') with pytest.raises(KeyError): pwd.getpwnam('alias1') # Regression test for bug #2790 # sss_override --name doesn't work with RFC2307 and ghost users @pytest.fixture def env_regr_2790_override(request, ldap_conn): prepare_sssd(request, ldap_conn) # Add entries ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user1", 10001, 20001) ent_list.add_user("user2", 10002, 20002) ent_list.add_group("group1", 2001, ["user1", "user2"]) ent_list.add_group("group2", 2002, ["user2"]) create_ldap_fixture(request, ldap_conn, ent_list) # Assert entries are not overridden with pytest.raises(KeyError): pwd.getpwnam('alias1') with pytest.raises(KeyError): pwd.getpwnam('alias1@LDAP') with pytest.raises(KeyError): pwd.getpwnam('alias2') with pytest.raises(KeyError): pwd.getpwnam('alias2@LDAP') # Override subprocess.check_call(["sss_override", "user-add", "user1", "-n", "alias1"]) subprocess.check_call(["sss_override", "user-add", "user2", "-n", "alias2"]) restart_sssd() def test_regr_2790_override(ldap_conn, env_regr_2790_override): # Assert entries are overridden (res, errno, grp_list) = sssd_id.get_user_groups("alias1") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user1 %d" % errno assert grp_list == ["group1"] (res, errno, grp_list) = sssd_id.get_user_groups("alias2") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user2 %d" % errno assert sorted(grp_list) == sorted(["group1", "group2"]) # Test fully qualified and case-insensitive names @pytest.fixture def env_mix_cased_name_override(request, ldap_conn): """Setup test for mixed case names""" prepare_sssd(request, ldap_conn, True, False) # Add entries ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user1", 10001, 20001) ent_list.add_user("uSeR2", 10002, 20002) create_ldap_fixture(request, ldap_conn, ent_list) pwd.getpwnam('user1@LDAP') pwd.getpwnam('user2@LDAP') with pytest.raises(KeyError): pwd.getpwnam('ov_user1@LDAP') with pytest.raises(KeyError): pwd.getpwnam('ov_user2@LDAP') # Override subprocess.check_call(["sss_override", "user-add", "user1@LDAP", "-u", "10010", "-g", "20010", "-n", "ov_user1", "-c", "Overriden User 1", "-h", "/home/ov/user1", "-s", "/bin/ov_user1_shell"]) subprocess.check_call(["sss_override", "user-add", "user2@LDAP", "-u", "10020", "-g", "20020", "-n", "ov_user2", "-c", "Overriden User 2", "-h", "/home/ov/user2", "-s", "/bin/ov_user2_shell"]) restart_sssd() def test_mix_cased_name_override(ldap_conn, env_mix_cased_name_override): """Test if names with upper and lower case letter are overridden""" # Assert entries are overridden user1 = dict(name='ov_user1@LDAP', passwd='*', uid=10010, gid=20010, gecos='Overriden User 1', dir='/home/ov/user1', shell='/bin/ov_user1_shell') user2 = dict(name='ov_user2@LDAP', passwd='*', uid=10020, gid=20020, gecos='Overriden User 2', dir='/home/ov/user2', shell='/bin/ov_user2_shell') ent.assert_passwd_by_name('user1@LDAP', user1) ent.assert_passwd_by_name('ov_user1@LDAP', user1) ent.assert_passwd_by_name('user2@LDAP', user2) ent.assert_passwd_by_name('ov_user2@LDAP', user2) sssd-1.13.4/src/tests/intg/PaxHeaders.16287/Makefile.am0000644000000000000000000000007212703456111017251 xustar0028 atime=1460561764.6487597 30 ctime=1460561776.103798542 sssd-1.13.4/src/tests/intg/Makefile.am0000644002412700241270000000352512703456111020727 0ustar00jhrozekjhrozek00000000000000dist_noinst_DATA = \ config.py.m4 \ sssd_id.py \ ds.py \ ds_openldap.py \ ent.py \ ent_test.py \ ldap_ent.py \ ldap_local_override_test.py \ ldap_test.py \ test_local_domain.py \ util.py \ test_memory_cache.py \ $(NULL) config.py: config.py.m4 m4 -D "prefix=\`$(prefix)'" \ -D "sysconfdir=\`$(sysconfdir)'" \ -D "dbpath=\`$(dbpath)'" \ -D "pidpath=\`$(pidpath)'" \ -D "logpath=\`$(logpath)'" \ -D "mcpath=\`$(mcpath)'" \ $< > $@ root: : "Create directory for emulated root's D-Bus cookies." : "See http://dbus.freedesktop.org/doc/dbus-specification.html#auth-mechanisms" $(MKDIR_P) -m 0700 root/.dbus-keyrings passwd: root echo "root:x:0:0:root:$(abs_builddir)/root:/bin/bash" > $@ group: echo "root:x:0:" > $@ CLEANFILES=config.py config.pyc passwd group clean-local: rm -Rf root intgcheck-installed: config.py passwd group pipepath="$(DESTDIR)$(pipepath)"; \ if test $${#pipepath} -gt 80; then \ echo "error: Pipe directory path too long," \ "D-Bus won't be able to open sockets" >&2; \ exit 1; \ fi set -e; \ cd "$(abs_srcdir)"; \ nss_wrapper=$$(pkg-config --libs nss_wrapper); \ uid_wrapper=$$(pkg-config --libs uid_wrapper); \ PATH="$$(dirname -- $(SLAPD)):$$PATH" \ PATH="$(DESTDIR)$(sbindir):$(DESTDIR)$(bindir):$$PATH" \ PATH="$(abs_builddir):$(abs_srcdir):$$PATH" \ PYTHONPATH="$(abs_builddir):$(abs_srcdir)" \ LDB_MODULES_PATH="$(DESTDIR)$(ldblibdir)" \ LD_PRELOAD="$$nss_wrapper $$uid_wrapper" \ NSS_WRAPPER_PASSWD="$(abs_builddir)/passwd" \ NSS_WRAPPER_GROUP="$(abs_builddir)/group" \ NSS_WRAPPER_MODULE_SO_PATH="$(DESTDIR)$(nsslibdir)/libnss_sss.so.2" \ NSS_WRAPPER_MODULE_FN_PREFIX="sss" \ UID_WRAPPER=1 \ UID_WRAPPER_ROOT=1 \ fakeroot $(PYTHON2) $(PYTEST) -v --tb=native $(INTGCHECK_PYTEST_ARGS) . rm -f $(DESTDIR)$(logpath)/* sssd-1.13.4/src/tests/intg/PaxHeaders.16287/test_memory_cache.py0000644000000000000000000000007412703456111021263 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.113798576 sssd-1.13.4/src/tests/intg/test_memory_cache.py0000644002412700241270000006125712703456111022745 0ustar00jhrozekjhrozek00000000000000# # LDAP integration test # # Copyright (c) 2015 Red Hat, Inc. # Author: Lukas Slebodnik # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os import stat import ent import grp import pwd import config import signal import subprocess import time import pytest import ds_openldap import ldap_ent import sssd_id from util import unindent LDAP_BASE_DN = "dc=example,dc=com" @pytest.fixture(scope="module") def ds_inst(request): """LDAP server instance fixture""" ds_inst = ds_openldap.DSOpenLDAP( config.PREFIX, 10389, LDAP_BASE_DN, "cn=admin", "Secret123") try: ds_inst.setup() except: ds_inst.teardown() raise request.addfinalizer(lambda: ds_inst.teardown()) return ds_inst @pytest.fixture(scope="module") def ldap_conn(request, ds_inst): """LDAP server connection fixture""" ldap_conn = ds_inst.bind() ldap_conn.ds_inst = ds_inst request.addfinalizer(lambda: ldap_conn.unbind_s()) return ldap_conn def create_ldap_fixture(request, ldap_conn, ent_list): """Add LDAP entries and add teardown for removing them""" for entry in ent_list: ldap_conn.add_s(entry[0], entry[1]) def teardown(): for entry in ent_list: ldap_conn.delete_s(entry[0]) request.addfinalizer(teardown) def create_conf_fixture(request, contents): """Generate sssd.conf and add teardown for removing it""" conf = open(config.CONF_PATH, "w") conf.write(contents) conf.close() os.chmod(config.CONF_PATH, stat.S_IRUSR | stat.S_IWUSR) request.addfinalizer(lambda: os.unlink(config.CONF_PATH)) def stop_sssd(): pid_file = open(config.PIDFILE_PATH, "r") pid = int(pid_file.read()) os.kill(pid, signal.SIGTERM) while True: try: os.kill(pid, signal.SIGCONT) except: break time.sleep(1) def create_sssd_fixture(request): """Start sssd and add teardown for stopping it and removing state""" if subprocess.call(["sssd", "-D", "-f"]) != 0: raise Exception("sssd start failed") def teardown(): try: stop_sssd() except: pass for path in os.listdir(config.DB_PATH): os.unlink(config.DB_PATH + "/" + path) for path in os.listdir(config.MCACHE_PATH): os.unlink(config.MCACHE_PATH + "/" + path) request.addfinalizer(teardown) def load_data_to_ldap(request, ldap_conn): ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ent_list.add_user("user1", 1001, 2001) ent_list.add_user("user2", 1002, 2002) ent_list.add_user("user3", 1003, 2003) ent_list.add_user("user11", 1011, 2001) ent_list.add_user("user12", 1012, 2002) ent_list.add_user("user13", 1013, 2003) ent_list.add_user("user21", 1021, 2001) ent_list.add_user("user22", 1022, 2002) ent_list.add_user("user23", 1023, 2003) ent_list.add_group("group1", 2001, ["user1", "user11", "user21"]) ent_list.add_group("group2", 2002, ["user2", "user12", "user22"]) ent_list.add_group("group3", 2003, ["user3", "user13", "user23"]) ent_list.add_group("group0x", 2000, ["user1", "user2", "user3"]) ent_list.add_group("group1x", 2010, ["user11", "user12", "user13"]) ent_list.add_group("group2x", 2020, ["user21", "user22", "user23"]) create_ldap_fixture(request, ldap_conn, ent_list) @pytest.fixture def sanity_rfc2307(request, ldap_conn): load_data_to_ldap(request, ldap_conn) conf = unindent("""\ [sssd] domains = LDAP services = nss [nss] [domain/LDAP] ldap_auth_disable_tls_never_use_in_production = true ldap_schema = rfc2307 id_provider = ldap auth_provider = ldap sudo_provider = ldap ldap_uri = {ldap_conn.ds_inst.ldap_url} ldap_search_base = {ldap_conn.ds_inst.base_dn} """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) return None @pytest.fixture def fqname_rfc2307(request, ldap_conn): load_data_to_ldap(request, ldap_conn) conf = unindent("""\ [sssd] domains = LDAP services = nss [nss] [domain/LDAP] ldap_auth_disable_tls_never_use_in_production = true ldap_schema = rfc2307 id_provider = ldap auth_provider = ldap sudo_provider = ldap ldap_uri = {ldap_conn.ds_inst.ldap_url} ldap_search_base = {ldap_conn.ds_inst.base_dn} use_fully_qualified_names = true """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) return None @pytest.fixture def fqname_case_insensitive_rfc2307(request, ldap_conn): load_data_to_ldap(request, ldap_conn) conf = unindent("""\ [sssd] domains = LDAP services = nss [nss] [domain/LDAP] ldap_auth_disable_tls_never_use_in_production = true ldap_schema = rfc2307 id_provider = ldap auth_provider = ldap sudo_provider = ldap ldap_uri = {ldap_conn.ds_inst.ldap_url} ldap_search_base = {ldap_conn.ds_inst.base_dn} use_fully_qualified_names = true case_sensitive = false """).format(**locals()) create_conf_fixture(request, conf) create_sssd_fixture(request) return None def test_getpwnam(ldap_conn, sanity_rfc2307): ent.assert_passwd_by_name( 'user1', dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', shell='/bin/bash')) ent.assert_passwd_by_uid( 1001, dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', shell='/bin/bash')) ent.assert_passwd_by_name( 'user2', dict(name='user2', passwd='*', uid=1002, gid=2002, gecos='1002', shell='/bin/bash')) ent.assert_passwd_by_uid( 1002, dict(name='user2', passwd='*', uid=1002, gid=2002, gecos='1002', shell='/bin/bash')) ent.assert_passwd_by_name( 'user3', dict(name='user3', passwd='*', uid=1003, gid=2003, gecos='1003', shell='/bin/bash')) ent.assert_passwd_by_uid( 1003, dict(name='user3', passwd='*', uid=1003, gid=2003, gecos='1003', shell='/bin/bash')) ent.assert_passwd_by_name( 'user11', dict(name='user11', passwd='*', uid=1011, gid=2001, gecos='1011', shell='/bin/bash')) ent.assert_passwd_by_uid( 1011, dict(name='user11', passwd='*', uid=1011, gid=2001, gecos='1011', shell='/bin/bash')) ent.assert_passwd_by_name( 'user12', dict(name='user12', passwd='*', uid=1012, gid=2002, gecos='1012', shell='/bin/bash')) ent.assert_passwd_by_uid( 1012, dict(name='user12', passwd='*', uid=1012, gid=2002, gecos='1012', shell='/bin/bash')) ent.assert_passwd_by_name( 'user13', dict(name='user13', passwd='*', uid=1013, gid=2003, gecos='1013', shell='/bin/bash')) ent.assert_passwd_by_uid( 1013, dict(name='user13', passwd='*', uid=1013, gid=2003, gecos='1013', shell='/bin/bash')) ent.assert_passwd_by_name( 'user21', dict(name='user21', passwd='*', uid=1021, gid=2001, gecos='1021', shell='/bin/bash')) ent.assert_passwd_by_uid( 1021, dict(name='user21', passwd='*', uid=1021, gid=2001, gecos='1021', shell='/bin/bash')) ent.assert_passwd_by_name( 'user22', dict(name='user22', passwd='*', uid=1022, gid=2002, gecos='1022', shell='/bin/bash')) ent.assert_passwd_by_uid( 1022, dict(name='user22', passwd='*', uid=1022, gid=2002, gecos='1022', shell='/bin/bash')) ent.assert_passwd_by_name( 'user23', dict(name='user23', passwd='*', uid=1023, gid=2003, gecos='1023', shell='/bin/bash')) ent.assert_passwd_by_uid( 1023, dict(name='user23', passwd='*', uid=1023, gid=2003, gecos='1023', shell='/bin/bash')) def test_getpwnam_with_mc(ldap_conn, sanity_rfc2307): test_getpwnam(ldap_conn, sanity_rfc2307) stop_sssd() test_getpwnam(ldap_conn, sanity_rfc2307) def test_getgrnam_simple(ldap_conn, sanity_rfc2307): ent.assert_group_by_name("group1", dict(name="group1", gid=2001)) ent.assert_group_by_gid(2001, dict(name="group1", gid=2001)) ent.assert_group_by_name("group2", dict(name="group2", gid=2002)) ent.assert_group_by_gid(2002, dict(name="group2", gid=2002)) ent.assert_group_by_name("group3", dict(name="group3", gid=2003)) ent.assert_group_by_gid(2003, dict(name="group3", gid=2003)) ent.assert_group_by_name("group0x", dict(name="group0x", gid=2000)) ent.assert_group_by_gid(2000, dict(name="group0x", gid=2000)) ent.assert_group_by_name("group1x", dict(name="group1x", gid=2010)) ent.assert_group_by_gid(2010, dict(name="group1x", gid=2010)) ent.assert_group_by_name("group2x", dict(name="group2x", gid=2020)) ent.assert_group_by_gid(2020, dict(name="group2x", gid=2020)) def test_getgrnam_simple_with_mc(ldap_conn, sanity_rfc2307): test_getgrnam_simple(ldap_conn, sanity_rfc2307) stop_sssd() test_getgrnam_simple(ldap_conn, sanity_rfc2307) def test_getgrnam_membership(ldap_conn, sanity_rfc2307): ent.assert_group_by_name( "group1", dict(mem=ent.contains_only("user1", "user11", "user21"))) ent.assert_group_by_gid( 2001, dict(mem=ent.contains_only("user1", "user11", "user21"))) ent.assert_group_by_name( "group2", dict(mem=ent.contains_only("user2", "user12", "user22"))) ent.assert_group_by_gid( 2002, dict(mem=ent.contains_only("user2", "user12", "user22"))) ent.assert_group_by_name( "group3", dict(mem=ent.contains_only("user3", "user13", "user23"))) ent.assert_group_by_gid( 2003, dict(mem=ent.contains_only("user3", "user13", "user23"))) ent.assert_group_by_name( "group0x", dict(mem=ent.contains_only("user1", "user2", "user3"))) ent.assert_group_by_gid( 2000, dict(mem=ent.contains_only("user1", "user2", "user3"))) ent.assert_group_by_name( "group1x", dict(mem=ent.contains_only("user11", "user12", "user13"))) ent.assert_group_by_gid( 2010, dict(mem=ent.contains_only("user11", "user12", "user13"))) ent.assert_group_by_name( "group2x", dict(mem=ent.contains_only("user21", "user22", "user23"))) ent.assert_group_by_gid( 2020, dict(mem=ent.contains_only("user21", "user22", "user23"))) def test_getgrnam_membership_with_mc(ldap_conn, sanity_rfc2307): test_getgrnam_membership(ldap_conn, sanity_rfc2307) stop_sssd() test_getgrnam_membership(ldap_conn, sanity_rfc2307) def assert_user_gids_equal(user, expected_gids): (res, errno, gids) = sssd_id.get_user_gids(user) assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user %s, %d" % (user, errno) assert sorted(gids) == sorted(expected_gids), \ "result: %s\n expected %s" % ( ", ".join(["%s" % s for s in sorted(gids)]), ", ".join(["%s" % s for s in sorted(expected_gids)]) ) def test_initgroups(ldap_conn, sanity_rfc2307): assert_user_gids_equal('user1', [2000, 2001]) assert_user_gids_equal('user2', [2000, 2002]) assert_user_gids_equal('user3', [2000, 2003]) assert_user_gids_equal('user11', [2010, 2001]) assert_user_gids_equal('user12', [2010, 2002]) assert_user_gids_equal('user13', [2010, 2003]) assert_user_gids_equal('user21', [2020, 2001]) assert_user_gids_equal('user22', [2020, 2002]) assert_user_gids_equal('user23', [2020, 2003]) def test_initgroups_with_mc(ldap_conn, sanity_rfc2307): test_initgroups(ldap_conn, sanity_rfc2307) stop_sssd() test_initgroups(ldap_conn, sanity_rfc2307) def test_initgroups_fqname_with_mc(ldap_conn, fqname_rfc2307): assert_user_gids_equal('user1@LDAP', [2000, 2001]) stop_sssd() assert_user_gids_equal('user1@LDAP', [2000, 2001]) def assert_initgroups_equal(user, primary_gid, expected_gids): (res, errno, gids) = sssd_id.call_sssd_initgroups(user, primary_gid) assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user %s, %d" % (user, errno) assert sorted(gids) == sorted(expected_gids), \ "result: %s\n expected %s" % ( ", ".join(["%s" % s for s in sorted(gids)]), ", ".join(["%s" % s for s in sorted(expected_gids)]) ) def assert_stored_last_initgroups(user1_case1, user1_case2, user1_case_last, primary_gid, expected_gids): assert_initgroups_equal(user1_case1, primary_gid, expected_gids) assert_initgroups_equal(user1_case2, primary_gid, expected_gids) assert_initgroups_equal(user1_case_last, primary_gid, expected_gids) stop_sssd() user = user1_case1 (res, errno, _) = sssd_id.call_sssd_initgroups(user, primary_gid) assert res == sssd_id.NssReturnCode.UNAVAIL, \ "Initgroups for user shoudl fail user %s, %d, %d" % (user, res, errno) user = user1_case2 (res, errno, _) = sssd_id.call_sssd_initgroups(user, primary_gid) assert res == sssd_id.NssReturnCode.UNAVAIL, \ "Initgroups for user shoudl fail user %s, %d, %d" % (user, res, errno) # Just last invocation of initgroups shoudl PASS # Otherwise, we would not be able to invalidate it assert_initgroups_equal(user1_case_last, primary_gid, expected_gids) def test_initgroups_case_insensitive_with_mc1(ldap_conn, fqname_case_insensitive_rfc2307): user1_case1 = 'User1@LDAP' user1_case2 = 'uSer1@LDAP' user1_case_last = 'usEr1@LDAP' primary_gid = 2001 expected_gids = [2000, 2001] assert_stored_last_initgroups(user1_case1, user1_case2, user1_case_last, primary_gid, expected_gids) def test_initgroups_case_insensitive_with_mc2(ldap_conn, fqname_case_insensitive_rfc2307): user1_case1 = 'usEr1@LDAP' user1_case2 = 'User1@LDAP' user1_case_last = 'uSer1@LDAP' primary_gid = 2001 expected_gids = [2000, 2001] assert_stored_last_initgroups(user1_case1, user1_case2, user1_case_last, primary_gid, expected_gids) def test_initgroups_case_insensitive_with_mc3(ldap_conn, fqname_case_insensitive_rfc2307): user1_case1 = 'uSer1@LDAP' user1_case2 = 'usEr1@LDAP' user1_case_last = 'User1@LDAP' primary_gid = 2001 expected_gids = [2000, 2001] assert_stored_last_initgroups(user1_case1, user1_case2, user1_case_last, primary_gid, expected_gids) def run_simple_test_with_initgroups(): ent.assert_passwd_by_name( 'user1', dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', shell='/bin/bash')) ent.assert_passwd_by_uid( 1001, dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', shell='/bin/bash')) ent.assert_group_by_name( "group1", dict(mem=ent.contains_only("user1", "user11", "user21"))) ent.assert_group_by_gid( 2001, dict(mem=ent.contains_only("user1", "user11", "user21"))) # unrelated group to user1 ent.assert_group_by_name( "group2", dict(mem=ent.contains_only("user2", "user12", "user22"))) ent.assert_group_by_gid( 2002, dict(mem=ent.contains_only("user2", "user12", "user22"))) assert_initgroups_equal("user1", 2001, [2000, 2001]) def test_invalidation_of_gids_after_initgroups(ldap_conn, sanity_rfc2307): # the sssd cache was empty and not all user's group were # resolved with getgr{nm,gid}. Therefore there is a change in # group membership => user groups should be invalidated run_simple_test_with_initgroups() assert_initgroups_equal("user1", 2001, [2000, 2001]) stop_sssd() ent.assert_passwd_by_name( 'user1', dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', shell='/bin/bash')) ent.assert_passwd_by_uid( 1001, dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', shell='/bin/bash')) # unrelated group to user1 must be returned ent.assert_group_by_name( "group2", dict(mem=ent.contains_only("user2", "user12", "user22"))) ent.assert_group_by_gid( 2002, dict(mem=ent.contains_only("user2", "user12", "user22"))) assert_initgroups_equal("user1", 2001, [2000, 2001]) # user groups must be invalidated for group in ["group1", "group0x"]: with pytest.raises(KeyError): grp.getgrnam(group) for gid in [2000, 2001]: with pytest.raises(KeyError): grp.getgrgid(gid) def test_initgroups_without_change_in_membership(ldap_conn, sanity_rfc2307): # the sssd cache was empty and not all user's group were # resolved with getgr{nm,gid}. Therefore there is a change in # group membership => user groups should be invalidated run_simple_test_with_initgroups() # invalidate cache subprocess.call(["sss_cache", "-E"]) # all users and groups will be just refreshed from LDAP # but there will not be a change in group membership # user groups should not be invlaidated run_simple_test_with_initgroups() stop_sssd() # everything should be in memory cache run_simple_test_with_initgroups() def assert_mc_records_for_user1(): ent.assert_passwd_by_name( 'user1', dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', shell='/bin/bash')) ent.assert_passwd_by_uid( 1001, dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', shell='/bin/bash')) ent.assert_group_by_name( "group1", dict(mem=ent.contains_only("user1", "user11", "user21"))) ent.assert_group_by_gid( 2001, dict(mem=ent.contains_only("user1", "user11", "user21"))) ent.assert_group_by_name( "group0x", dict(mem=ent.contains_only("user1", "user2", "user3"))) ent.assert_group_by_gid( 2000, dict(mem=ent.contains_only("user1", "user2", "user3"))) assert_initgroups_equal("user1", 2001, [2000, 2001]) def assert_missing_mc_records_for_user1(): with pytest.raises(KeyError): pwd.getpwnam("user1") with pytest.raises(KeyError): pwd.getpwuid(1001) for gid in [2000, 2001]: with pytest.raises(KeyError): grp.getgrgid(gid) for group in ["group0x", "group1"]: with pytest.raises(KeyError): grp.getgrnam(group) (res, err, _) = sssd_id.call_sssd_initgroups("user1", 2001) assert res == sssd_id.NssReturnCode.UNAVAIL, \ "Initgroups should not find anything after invalidation of mc.\n" \ "User user1, errno:%d" % err def test_invalidate_user_before_stop(ldap_conn, sanity_rfc2307): # initialize cache with full ID (res, errno, _) = sssd_id.get_user_groups("user1") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user1 %s, %d" % errno assert_mc_records_for_user1() subprocess.call(["sss_cache", "-u", "user1"]) stop_sssd() assert_missing_mc_records_for_user1() def test_invalidate_user_after_stop(ldap_conn, sanity_rfc2307): # initialize cache with full ID (res, errno, _) = sssd_id.get_user_groups("user1") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user1 %s, %d" % errno assert_mc_records_for_user1() stop_sssd() subprocess.call(["sss_cache", "-u", "user1"]) assert_missing_mc_records_for_user1() def test_invalidate_users_before_stop(ldap_conn, sanity_rfc2307): # initialize cache with full ID (res, errno, _) = sssd_id.get_user_groups("user1") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user1 %s, %d" % errno assert_mc_records_for_user1() subprocess.call(["sss_cache", "-U"]) stop_sssd() assert_missing_mc_records_for_user1() def test_invalidate_users_after_stop(ldap_conn, sanity_rfc2307): # initialize cache with full ID (res, errno, _) = sssd_id.get_user_groups("user1") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user1 %s, %d" % errno assert_mc_records_for_user1() stop_sssd() subprocess.call(["sss_cache", "-U"]) assert_missing_mc_records_for_user1() def test_invalidate_group_before_stop(ldap_conn, sanity_rfc2307): # initialize cache with full ID (res, errno, _) = sssd_id.get_user_groups("user1") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user1 %s, %d" % errno assert_mc_records_for_user1() subprocess.call(["sss_cache", "-g", "group1"]) stop_sssd() assert_missing_mc_records_for_user1() def test_invalidate_group_after_stop(ldap_conn, sanity_rfc2307): # initialize cache with full ID (res, errno, _) = sssd_id.get_user_groups("user1") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user1 %s, %d" % errno assert_mc_records_for_user1() stop_sssd() subprocess.call(["sss_cache", "-g", "group1"]) assert_missing_mc_records_for_user1() def test_invalidate_groups_before_stop(ldap_conn, sanity_rfc2307): # initialize cache with full ID (res, errno, _) = sssd_id.get_user_groups("user1") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user1 %s, %d" % errno assert_mc_records_for_user1() subprocess.call(["sss_cache", "-G"]) stop_sssd() assert_missing_mc_records_for_user1() def test_invalidate_groups_after_stop(ldap_conn, sanity_rfc2307): # initialize cache with full ID (res, errno, _) = sssd_id.get_user_groups("user1") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user1 %s, %d" % errno assert_mc_records_for_user1() stop_sssd() subprocess.call(["sss_cache", "-G"]) assert_missing_mc_records_for_user1() def test_invalidate_everything_before_stop(ldap_conn, sanity_rfc2307): # initialize cache with full ID (res, errno, _) = sssd_id.get_user_groups("user1") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user1 %s, %d" % errno assert_mc_records_for_user1() subprocess.call(["sss_cache", "-E"]) stop_sssd() assert_missing_mc_records_for_user1() def test_invalidate_everything_after_stop(ldap_conn, sanity_rfc2307): # initialize cache with full ID (res, errno, _) = sssd_id.get_user_groups("user1") assert res == sssd_id.NssReturnCode.SUCCESS, \ "Could not find groups for user1 %s, %d" % errno assert_mc_records_for_user1() stop_sssd() subprocess.call(["sss_cache", "-E"]) assert_missing_mc_records_for_user1() def test_removed_mc(ldap_conn, sanity_rfc2307): """ Regression test for ticket: https://fedorahosted.org/sssd/ticket/2726 """ ent.assert_passwd_by_name( 'user1', dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', shell='/bin/bash')) ent.assert_passwd_by_uid( 1001, dict(name='user1', passwd='*', uid=1001, gid=2001, gecos='1001', shell='/bin/bash')) ent.assert_group_by_name("group1", dict(name="group1", gid=2001)) ent.assert_group_by_gid(2001, dict(name="group1", gid=2001)) stop_sssd() # remove cache without invalidation for path in os.listdir(config.MCACHE_PATH): os.unlink(config.MCACHE_PATH + "/" + path) # sssd is stopped; so the memory cache should not be used # in long living clients (py.test in this case) with pytest.raises(KeyError): pwd.getpwnam('user1') with pytest.raises(KeyError): pwd.getpwuid(1001) with pytest.raises(KeyError): grp.getgrnam('group1') with pytest.raises(KeyError): grp.getgrgid(2001) sssd-1.13.4/src/tests/intg/PaxHeaders.16287/config.py.m40000644000000000000000000000007412703456111017355 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.104798545 sssd-1.13.4/src/tests/intg/config.py.m40000644002412700241270000000056112703456111021026 0ustar00jhrozekjhrozek00000000000000""" Build configuration variables. """ PREFIX = "prefix" SYSCONFDIR = "sysconfdir" SSSDCONFDIR = SYSCONFDIR + "/sssd" CONF_PATH = SSSDCONFDIR + "/sssd.conf" DB_PATH = "dbpath" PID_PATH = "pidpath" PIDFILE_PATH = PID_PATH + "/sssd.pid" LOG_PATH = "logpath" MCACHE_PATH = "mcpath" sssd-1.13.4/src/tests/intg/PaxHeaders.16287/ent.py0000644000000000000000000000007412703456111016357 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.107798556 sssd-1.13.4/src/tests/intg/ent.py0000644002412700241270000003636412703456111020042 0ustar00jhrozekjhrozek00000000000000# # Abstract passwd/group entry management # # Copyright (c) 2015 Red Hat, Inc. # Author: Nikolai Kondrashov # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # from pprint import pformat import pwd import grp _PASSWD_LIST_DESC = {None: ("user", {})} _GROUP_DESC = {"mem": ("member list", {None: ("member", {})})} _GROUP_LIST_DESC = {None: ("group", _GROUP_DESC)} def _get_desc(desc_map, key): """ Get an item description from a container description map. Arguments: desc_map Container description map. key Item key, None for wildcard description. """ assert isinstance(desc_map, dict) if key in desc_map: return desc_map[key] if None in desc_map: desc = desc_map[None] if key is not None: desc = (desc[0] + " " + pformat(key), desc[1]) return desc elif key is None: return ("item", {}) else: return (pformat(key), {}) def _diff(ent, pattern, desc_map={}): """ Describe difference between an entry and a pattern. Return None, if none. Arguments: ent Entry. pattern Pattern. desc_map Container pattern description map. An entry is a value, a list of entries, or a dictionary of entries. Entries are used to store passwd and group database entries as dictionaries, in lists and dictionaries. A pattern is a value, a tuple, a list, or a dictionary of patterns. E.g. 123, "abc", [ 123, "abc" ], { "abc": 123 }, { "abc": ( 123 ) } A pattern can be matched against a value, a list, or a dictionary entry. A value is considered matching, if it's equal to the pattern. E.g. 123 == 123, 123 != 456, "abc" == "abc", "abc" != "def", 123 != "abc" A list is considered matching a pattern, if the pattern is a list or a tuple, where each of pattern list items matches an entry list item and vice versa, or where each pattern tuple item matches an entry list item, but not necessarily the other way around. E.g. [] != "abc", [] == [], [ "abc", 123 ] == [ 123, "abc" ], [ "abc" ] != [ 123 ], [ 123 ] != [], [] == (), [ "abc", 123 ] == ( 123, "abc" ), [ "abc" ] != ( 123 ), [ 123 ] == (), [ 123, "abc" ] == ( 123 ) NOTE: For the sake of readability, it is recommended to use "contains_only" function to create patterns matching all entry list items (list patterns), and "contains" function to create patterns matching a subset of entry list items (tuple patterns). A dictionary is considered matching a pattern, if it is also a dictionary, and all of pattern values match identically-keyed values of the dictionary. E.g. {} == {}, {} != "abc", { "abc": 123, "def": 456 } == { "abc": 123 }, { "abc": 123 } == {} Container pattern description map is a dictionary with keys being item keys/indices and values being (name, description map) tuples. None key points to a wildcard description, others to specific item descriptions. The description map argument is optional, and is used to generate more readable difference explanations. """ assert isinstance(desc_map, dict) if isinstance(pattern, dict): if not isinstance(ent, dict): return "not a dict, " + str(type(ent)) for key, value in pattern.iteritems(): item_name, item_map = _get_desc(desc_map, key) d = _diff(ent[key], value, item_map) if d: return item_name + " mismatch: " + d elif isinstance(pattern, tuple): if not isinstance(ent, list): return "not a list, " + str(type(ent)) pattern_matches = [0 for pv in pattern] for ei, ev in enumerate(ent): for pi, pv in enumerate(pattern): d = _diff(ev, pv) if not d: pattern_matches[pi] += 1 unmatched_pattern = [pattern[pi] for pi in xrange(0, len(pattern)) if pattern_matches[pi] == 0] items = _get_desc(desc_map, None)[0] + "s" if len(unmatched_pattern) > 0: return "\nexpected " + items + " not found:\n" + \ pformat(unmatched_pattern) elif isinstance(pattern, list): if not isinstance(ent, list): return "not a list, " + str(type(ent)) pattern_matches = [0 for pv in pattern] ent_matches = [0 for ev in ent] for ei, ev in enumerate(ent): for pi, pv in enumerate(pattern): d = _diff(ev, pv) if not d: pattern_matches[pi] += 1 ent_matches[ei] += 1 unmatched_pattern = [pattern[pi] for pi in xrange(0, len(pattern)) if pattern_matches[pi] == 0] unmatched_ent = [ent[pi] for pi in xrange(0, len(ent)) if ent_matches[pi] == 0] items = _get_desc(desc_map, None)[0] + "s" d = "" if len(unmatched_pattern) > 0: d += "\nexpected " + items + " not found:\n" + \ pformat(unmatched_pattern) if len(unmatched_ent) != 0: d += "\nunexpected " + items + " found:\n" + \ pformat(unmatched_ent) if len(d) > 0: return d else: if pattern != ent: return pformat(pattern) + " != " + pformat(ent) return None def contains_only(*args): """ Produce a pattern matching all list items against arguments. Use this function instead of constructing bare lists, for readability. """ return list(args) def contains(*args): """ Produce a pattern matching a subset of list items against arguments. Use this function instead of constructing bare tuples, for readability. """ return args def _convert_passwd(passwd): """ Convert a passwd entry returned by pwd module to an entry dictionary. """ return dict( name=passwd.pw_name, passwd=passwd.pw_passwd, uid=passwd.pw_uid, gid=passwd.pw_gid, gecos=passwd.pw_gecos, dir=passwd.pw_dir, shell=passwd.pw_shell ) def get_passwd_by_name(name): """Get a passwd database entry by name.""" return _convert_passwd(pwd.getpwnam(name)) def get_passwd_by_uid(uid): """Get a passwd database entry by UID.""" return _convert_passwd(pwd.getpwuid(uid)) def assert_passwd_by_name(name, pattern): """Assert a passwd entry, retrieved by name, matches a pattern.""" try: ent = get_passwd_by_name(name) except KeyError as err: assert False, err d = _diff(ent, pattern) assert not d, d def assert_passwd_by_uid(uid, pattern): """Assert a passwd entry, retrieved by UID, matches a pattern.""" try: ent = get_passwd_by_uid(uid) except KeyError as err: assert False, err d = _diff(ent, pattern) assert not d, d def get_passwd_list(): """Get passwd database entry list with root user removed.""" passwd_list = pwd.getpwall() for i, v in enumerate(passwd_list): if v.pw_name == "root" and v.pw_uid == 0 and v.pw_gid == 0: del passwd_list[i] return map(_convert_passwd, passwd_list) raise Exception("no root user found") def assert_passwd_list(pattern): """Assert retrieved passwd list matches a pattern.""" d = _diff(get_passwd_list(), pattern, _PASSWD_LIST_DESC) assert not d, d def _diff_each_passwd_by_name(pattern_dict): """ Describe difference between each pattern_dict value and a passwd entry retrieved by name being the corresponding key. """ try: ent = dict((k, get_passwd_by_name(k)) for k in pattern_dict.keys()) except KeyError as err: return str(err) return _diff(ent, pattern_dict, _PASSWD_LIST_DESC) def _diff_each_passwd_by_uid(pattern_dict): """ Describe difference between each pattern_dict value and a passwd entry retrieved by UID being the corresponding key. """ try: ent = dict((k, get_passwd_by_uid(k)) for k in pattern_dict.keys()) except KeyError as err: return str(err) return _diff(ent, pattern_dict, _PASSWD_LIST_DESC) def _diff_each_passwd_with_name(pattern_seq): """ Describe difference between each pattern in pattern_seq sequence and a passwd entry retrieved by name being the pattern's "name" value. """ return _diff_each_passwd_by_name(dict((p["name"], p) for p in pattern_seq)) def _diff_each_passwd_with_uid(pattern_seq): """ Describe difference between each pattern in pattern_seq sequence and a passwd entry retrieved by UID being the pattern's "uid" value. """ return _diff_each_passwd_by_uid(dict((p["uid"], p) for p in pattern_seq)) def assert_each_passwd_by_name(pattern_dict): """ Assert each pattern_dict value matches a passwd entry retrieved by name being the corresponding key. """ d = _diff_each_passwd_by_name(pattern_dict) assert not d, d def assert_each_passwd_by_uid(pattern_dict): """ Assert each pattern_dict value matches a passwd entry retrieved by UID being the corresponding key. """ d = _diff_each_passwd_by_uid(pattern_dict) assert not d, d def assert_each_passwd_with_name(pattern_seq): """ Assert each pattern in pattern_seq sequence matches a passwd entry retrieved by name being the pattern's "name" value. """ d = _diff_each_passwd_with_name(pattern_seq) assert not d, d def assert_each_passwd_with_uid(pattern_seq): """ Assert each pattern in pattern_seq sequence matches a passwd entry retrieved by UID being the pattern's "uid" value. """ d = _diff_each_passwd_with_uid(pattern_seq) assert not d, d def _diff_passwd(pattern): """ Describe difference between passwd database and a pattern. Each pattern entry must have "name" and "uid" attribute. """ d = _diff(get_passwd_list(), pattern, _PASSWD_LIST_DESC) if d: return "list mismatch: " + d d = _diff_each_passwd_with_name(pattern) if d: return "name retrieval mismatch: " + d d = _diff_each_passwd_with_uid(pattern) if d: return "UID retrieval mismatch: " + d return None def assert_passwd(pattern): """ Assert passwd database matches a pattern. Each pattern entry must have "name" and "uid" attribute. """ d = _diff_passwd(pattern) assert not d, d def _convert_group(group): """ Convert a group entry returned by grp module to an entry dictionary. """ return dict( name=group.gr_name, passwd=group.gr_passwd, gid=group.gr_gid, mem=group.gr_mem ) def get_group_by_name(name): """Get a group database entry by name.""" return _convert_group(grp.getgrnam(name)) def get_group_by_gid(gid): """Get a group database entry by GID.""" return _convert_group(grp.getgrgid(gid)) def assert_group_by_name(name, pattern): """Assert a group entry, retrieved by name, matches a pattern.""" try: ent = get_group_by_name(name) except KeyError as err: assert False, err d = _diff(ent, pattern, _GROUP_DESC) assert not d, d def assert_group_by_gid(gid, pattern): """Assert a group entry, retrieved by GID, matches a pattern.""" try: ent = get_group_by_gid(gid) except KeyError as err: assert False, err d = _diff(ent, pattern, _GROUP_DESC) assert not d, d def get_group_list(): """Get group database entry list with root group removed.""" group_list = grp.getgrall() for i, v in enumerate(group_list): if v.gr_name == "root" and v.gr_gid == 0: del group_list[i] return map(_convert_group, group_list) raise Exception("no root group found") def assert_group_list(pattern): """Assert retrieved group list matches a pattern.""" d = _diff(get_group_list(), pattern, _GROUP_LIST_DESC) assert not d, d def _diff_each_group_by_name(pattern_dict): """ Describe difference between each pattern_dict value and a group entry retrieved by name being the corresponding key. """ try: ent = dict((k, get_group_by_name(k)) for k in pattern_dict.keys()) except KeyError as err: return str(err) return _diff(ent, pattern_dict, _GROUP_LIST_DESC) def _diff_each_group_by_gid(pattern_dict): """ Describe difference between each pattern_dict value and a group entry retrieved by GID being the corresponding key. """ try: ent = dict((k, get_group_by_gid(k)) for k in pattern_dict.keys()) except KeyError as err: return str(err) return _diff(ent, pattern_dict, _GROUP_LIST_DESC) def _diff_each_group_with_name(pattern_seq): """ Describe difference between each pattern in pattern_seq sequence and a group entry retrieved name being the pattern's "name" value. """ return _diff_each_group_by_name(dict((p["name"], p) for p in pattern_seq)) def _diff_each_group_with_gid(pattern_seq): """ Describe difference between each pattern in pattern_seq sequence and a group entry retrieved by GID being the pattern's "gid" value. """ return _diff_each_group_by_gid(dict((p["gid"], p) for p in pattern_seq)) def assert_each_group_by_name(pattern_dict): """ Assert each pattern_dict value matches a group entry retrieved by name being the corresponding key. """ d = _diff_each_group_by_name(pattern_dict) assert not d, d def assert_each_group_by_gid(pattern_dict): """ Assert each pattern_dict value matches a group entry retrieved by GID being the corresponding key. """ d = _diff_each_group_by_gid(pattern_dict) assert not d, d def assert_each_group_with_name(pattern_seq): """ Assert each pattern in pattern_seq sequence matches a group entry retrieved by name being the pattern's "name" value. """ d = _diff_each_group_with_name(pattern_seq) assert not d, d def assert_each_group_with_gid(pattern_seq): """ Assert each pattern in pattern_seq sequence matches a group entry retrieved by GID being the pattern's "gid" value. """ d = _diff_each_group_with_gid(pattern_seq) assert not d, d def _diff_group(pattern): """ Describe difference between group database and a pattern. Each pattern entry must have "name" and "gid" attribute. """ d = _diff(get_group_list(), pattern, _GROUP_LIST_DESC) if d: return "list mismatch: " + d d = _diff_each_group_with_name(pattern) if d: return "name retrieval mismatch: " + d d = _diff_each_group_with_gid(pattern) if d: return "GID retrieval mismatch: " + d return None def assert_group(pattern): """ Assert group database matches a pattern. Each pattern entry must have "name" and "gid" attribute. """ d = _diff_group(pattern) assert not d, d sssd-1.13.4/src/tests/PaxHeaders.16287/refcount-tests.c0000644000000000000000000000007412703456111017407 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.956794653 sssd-1.13.4/src/tests/refcount-tests.c0000644002412700241270000001444012703456111021061 0ustar00jhrozekjhrozek00000000000000/* SSSD Reference counting tests. Authors: Martin Nagy Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "tests/common_check.h" #include "util/util.h" /* Interface under test */ #include "util/refcount.h" /* Fail the test if object 'obj' does not have 'num' references. */ #define REF_ASSERT(obj, num) \ fail_unless(((obj)->DO_NOT_TOUCH_THIS_MEMBER_refcount == (num)), \ "Reference count of " #obj " should be %d but is %d", \ (num), (obj)->DO_NOT_TOUCH_THIS_MEMBER_refcount) #define FILLER_SIZE 32 struct foo { REFCOUNT_COMMON; char a[FILLER_SIZE]; char b[FILLER_SIZE]; }; struct bar { char a[FILLER_SIZE]; REFCOUNT_COMMON; char b[FILLER_SIZE]; }; struct baz { char a[FILLER_SIZE]; char b[FILLER_SIZE]; REFCOUNT_COMMON; }; #define SET_FILLER(target) do { \ memset((target)->a, 'a', FILLER_SIZE); \ memset((target)->b, 'b', FILLER_SIZE); \ } while (0) #define CHECK_FILLER(target) do { \ int _counter; \ for (_counter = 0; _counter < FILLER_SIZE; _counter++) { \ fail_unless((target)->a[_counter] == 'a', "Corrupted memory in " \ #target "->a[%d] of size %d", _counter, FILLER_SIZE); \ fail_unless((target)->b[_counter] == 'b', "Corrupted memory in " \ #target "->b[%d] of size %d", _counter, FILLER_SIZE); \ } \ } while (0) struct container { struct foo *foo; struct bar *bar; struct baz *baz; }; static struct container *global; START_TEST(test_refcount_basic) { struct container *containers; int i; /* First allocate our global storage place. */ global = talloc(NULL, struct container); fail_if(global == NULL); /* Allocate foo. */ global->foo = rc_alloc(global, struct foo); fail_if(global->foo == NULL); SET_FILLER(global->foo); REF_ASSERT(global->foo, 1); /* Allocate bar. */ global->bar = rc_alloc(global, struct bar); fail_if(global->bar == NULL); SET_FILLER(global->bar); REF_ASSERT(global->bar, 1); /* Allocate baz. */ global->baz = rc_alloc(global, struct baz); fail_if(global->baz == NULL); SET_FILLER(global->baz); REF_ASSERT(global->baz, 1); /* Try multiple attaches. */ containers = talloc_array(NULL, struct container, 100); fail_if(containers == NULL); for (i = 0; i < 100; i++) { containers[i].foo = rc_reference(containers, struct foo, global->foo); containers[i].bar = rc_reference(containers, struct bar, global->bar); containers[i].baz = rc_reference(containers, struct baz, global->baz); REF_ASSERT(containers[i].foo, i + 2); REF_ASSERT(global->foo, i + 2); REF_ASSERT(containers[i].bar, i + 2); REF_ASSERT(global->bar, i + 2); REF_ASSERT(containers[i].baz, i + 2); REF_ASSERT(global->baz, i + 2); } talloc_free(containers); CHECK_FILLER(global->foo); CHECK_FILLER(global->bar); CHECK_FILLER(global->baz); REF_ASSERT(global->foo, 1); REF_ASSERT(global->bar, 1); REF_ASSERT(global->baz, 1); talloc_free(global); } END_TEST START_TEST(test_refcount_swap) { void *tmp_ctx; struct container *container1; struct container *container2; tmp_ctx = talloc_new(NULL); ck_leaks_push(tmp_ctx); container1 = talloc(tmp_ctx, struct container); container2 = talloc(tmp_ctx, struct container); /* Allocate. */ container1->foo = rc_alloc(container1, struct foo); fail_if(container1->foo == NULL); SET_FILLER(container1->foo); /* Reference. */ container2->foo = rc_reference(container2, struct foo, container1->foo); fail_if(container2->foo == NULL); /* Make sure everything is as it should be. */ fail_unless(container1->foo == container2->foo); REF_ASSERT(container1->foo, 2); /* Free in reverse order. */ talloc_free(container1); REF_ASSERT(container2->foo, 1); CHECK_FILLER(container2->foo); talloc_free(container2); ck_leaks_pop(tmp_ctx); talloc_free(tmp_ctx); } END_TEST Suite *create_suite(void) { Suite *s = suite_create("refcount"); TCase *tc = tcase_create("REFCOUNT Tests"); /* Do some testing */ tcase_add_checked_fixture(tc, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_test(tc, test_refcount_basic); tcase_add_test(tc, test_refcount_swap); /* Add all test cases to the test suite */ suite_add_tcase(s, tc); return s; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int failure_count; Suite *suite; SRunner *sr; int debug = 0; struct poptOption long_options[] = { POPT_AUTOHELP { "debug-level", 'd', POPT_ARG_INT, &debug, 0, "Set debug level", NULL }, POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug); tests_set_cwd(); suite = create_suite(); sr = srunner_create(suite); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); failure_count = srunner_ntests_failed(sr); srunner_free(sr); return (failure_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } sssd-1.13.4/src/tests/PaxHeaders.16287/pysss_murmur-test.py3.sh0000644000000000000000000000007412703456111021071 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.351792601 sssd-1.13.4/src/tests/pysss_murmur-test.py3.sh0000755002412700241270000000016612703456111022546 0ustar00jhrozekjhrozek00000000000000#!/bin/sh SCRIPT=$(readlink -f "$0") SCRIPT_PATH=$(dirname "$SCRIPT") exec python3 $SCRIPT_PATH/pysss_murmur-test.py sssd-1.13.4/src/tests/PaxHeaders.16287/sbus_codegen_tests.c0000644000000000000000000000007312703456111020303 xustar0030 atime=1460561751.658715654 29 ctime=1460561774.96479468 sssd-1.13.4/src/tests/sbus_codegen_tests.c0000644002412700241270000015757112703456111021773 0ustar00jhrozekjhrozek00000000000000/* SSSD sbus_codegen tests. Authors: Stef Walter Copyright (C) Red Hat, Inc 2014 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "sbus/sssd_dbus_meta.h" #include "tests/common.h" #include "tests/sbus_codegen_tests_generated.h" #include "util/util_errors.h" /* The following 2 macros were taken from check's project source files (0.9.10) * http://check.sourceforge.net/ */ #ifndef _ck_assert_uint #define _ck_assert_uint(X, OP, Y) do { \ uintmax_t _ck_x = (X); \ uintmax_t _ck_y = (Y); \ ck_assert_msg(_ck_x OP _ck_y, "Assertion '"#X#OP#Y"' failed: "#X"==%ju, "#Y"==%ju", _ck_x, _ck_y); \ } while (0) #endif /* _ck_assert_uint */ #ifndef ck_assert_uint_eq #define ck_assert_uint_eq(X, Y) _ck_assert_uint(X, ==, Y) #endif /* ck_assert_uint_eq */ static const struct sbus_arg_meta * find_arg(const struct sbus_arg_meta *args, const char *name) { const struct sbus_arg_meta *arg; for (arg = args; arg->name != NULL; arg++) { if (strcmp (arg->name, name) == 0) return arg; } return NULL; } START_TEST(test_interfaces) { ck_assert_str_eq(com_planetexpress_Ship_meta.name, "com.planetexpress.Ship"); ck_assert(com_planetexpress_Ship_meta.methods != NULL); ck_assert(com_planetexpress_Ship_meta.signals != NULL); ck_assert(com_planetexpress_Ship_meta.properties != NULL); /* Explicit C Symbol */ ck_assert_str_eq(test_pilot_meta.name, "com.planetexpress.Pilot"); ck_assert(test_pilot_meta.methods != NULL); ck_assert(test_pilot_meta.signals == NULL); /* no signals */ ck_assert(test_pilot_meta.properties != NULL); } END_TEST START_TEST(test_methods) { const struct sbus_method_meta *method; const struct sbus_arg_meta *arg; method = sbus_meta_find_method(&com_planetexpress_Ship_meta, "MoveUniverse"); ck_assert(method != NULL); ck_assert_str_eq(method->name, "MoveUniverse"); ck_assert(method->in_args != NULL); ck_assert(method->out_args != NULL); arg = find_arg(method->in_args, "smoothly"); ck_assert(arg != NULL); ck_assert_str_eq(arg->name, "smoothly"); ck_assert_str_eq(arg->type, "b"); arg = find_arg(method->out_args, "where_we_crashed"); ck_assert(arg != NULL); ck_assert_str_eq(arg->name, "where_we_crashed"); ck_assert_str_eq(arg->type, "s"); } END_TEST START_TEST(test_properties) { const struct sbus_property_meta *prop; prop = sbus_meta_find_property(&com_planetexpress_Ship_meta, "Color"); ck_assert(prop != NULL); ck_assert_str_eq(prop->name, "Color"); ck_assert_str_eq(prop->type, "s"); ck_assert_int_eq(prop->flags, SBUS_PROPERTY_READABLE); } END_TEST START_TEST(test_signals) { const struct sbus_signal_meta *signal; const struct sbus_arg_meta *arg; signal = sbus_meta_find_signal(&com_planetexpress_Ship_meta, "BecameSentient"); ck_assert(signal != NULL); ck_assert_str_eq(signal->name, "BecameSentient"); ck_assert(signal->args != NULL); arg = find_arg(signal->args, "gender"); ck_assert(arg != NULL); ck_assert_str_eq(arg->name, "gender"); ck_assert_str_eq(arg->type, "s"); } END_TEST static int mock_move_universe(struct sbus_request *dbus_req, void *data, bool arg_smoothly, uint32_t arg_speed_factor) { /* * The above arguments should match the handler signature, * and the below finish function should have the right signature. * * Not called, just testing compilation */ ck_assert(FALSE); return com_planetexpress_Ship_MoveUniverse_finish(dbus_req, "here"); } static int mock_crash_now(struct sbus_request *dbus_req, void *data, const char *where) { /* * One argument, no return value, yet a finish function should * have been generated. * * Not called, just testing compilation */ ck_assert(FALSE); return com_planetexpress_Ship_crash_now_finish(dbus_req); } static int mock_land(struct sbus_request *req, void *data) { /* * Raw handler, no finish function, no special arguments. * * Not called, just testing compilation */ ck_assert(FALSE); return 0; } START_TEST(test_vtable) { struct com_planetexpress_Ship vtable = { { &com_planetexpress_Ship_meta, 0 }, mock_move_universe, mock_crash_now, mock_land, NULL, }; /* * These are not silly tests: * - Will fail compilation if c-symbol name was not respected * - Will fail if method order was not respected */ ck_assert(vtable.crash_now == mock_crash_now); ck_assert(vtable.MoveUniverse == mock_move_universe); ck_assert(vtable.Land == mock_land); } END_TEST START_TEST(test_constants) { ck_assert_str_eq(COM_PLANETEXPRESS_SHIP, "com.planetexpress.Ship"); ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_MOVEUNIVERSE, "MoveUniverse"); ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_CRASH_NOW, "Crash"); ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_BECAMESENTIENT, "BecameSentient"); ck_assert_str_eq(COM_PLANETEXPRESS_SHIP_COLOR, "Color"); /* constants for com.planetexpress.Pilot */ ck_assert_str_eq(TEST_PILOT, "com.planetexpress.Pilot"); ck_assert_str_eq(TEST_PILOT_FULLNAME, "FullName"); } END_TEST TCase *create_defs_tests(void) { TCase *tc = tcase_create("defs"); /* Do some testing */ tcase_add_test(tc, test_interfaces); tcase_add_test(tc, test_methods); tcase_add_test(tc, test_properties); tcase_add_test(tc, test_signals); tcase_add_test(tc, test_vtable); tcase_add_test(tc, test_constants); return tc; } /* This is a handler which has all the basic arguments types */ static int eject_handler(struct sbus_request *req, void *instance_data, uint8_t arg_byte, bool arg_boolean, int16_t arg_int16, uint16_t arg_uint16, int32_t arg_int32, uint32_t arg_uint32, int64_t arg_int64, uint64_t arg_uint64, double arg_double, const char *arg_string, const char *arg_object_path, uint8_t arg_byte_array[], int len_byte_array, int16_t arg_int16_array[], int len_int16_array, uint16_t arg_uint16_array[], int len_uint16_array, int32_t arg_int32_array[], int len_int32_array, uint32_t arg_uint32_array[], int len_uint32_array, int64_t arg_int64_array[], int len_int64_array, uint64_t arg_uint64_array[], int len_uint64_array, double arg_double_array[], int len_double_array, const char *arg_string_array[], int len_string_array, const char *arg_object_path_array[], int len_object_path_array) { int i; /* Only called for leela, so double check here */ ck_assert_str_eq(instance_data, "Crash into the billboard"); /* Murge the various values for test case */ ck_assert_uint_eq(arg_byte, 11); arg_byte++; ck_assert(arg_boolean == TRUE); arg_boolean = !arg_boolean; ck_assert_int_eq(arg_int16, -2222); arg_int16++; ck_assert_uint_eq(arg_uint16, 3333); arg_uint16++; ck_assert_int_eq(arg_int32, -44444444); arg_int32++; ck_assert_uint_eq(arg_uint32, 55555555); arg_uint32++; ck_assert(arg_int64 == INT64_C(-6666666666666666)); arg_int64++; ck_assert(arg_uint64 == UINT64_C(7777777777777777)); arg_uint64++; ck_assert(arg_double == 1.1); arg_double++; ck_assert_str_eq(arg_string, "hello"); arg_string = "bears, beets, battlestar galactica"; ck_assert_str_eq(arg_object_path, "/original/object/path"); arg_object_path = "/another/object/path"; arg_byte_array = talloc_memdup(req, arg_byte_array, sizeof(uint8_t) * len_byte_array); for (i = 0; i < len_byte_array; i++) arg_byte_array[i]++; arg_int16_array = talloc_memdup(req, arg_int16_array, sizeof(int16_t) * len_int16_array); for (i = 0; i < len_int16_array; i++) arg_int16_array[i]++; len_int16_array--; arg_uint16_array = talloc_memdup(req, arg_uint16_array, sizeof(uint16_t) * len_uint16_array); for (i = 0; i < len_uint16_array; i++) arg_uint16_array[i]++; arg_int32_array = talloc_memdup(req, arg_int32_array, sizeof(int32_t) * len_int32_array); for (i = 0; i < len_int32_array; i++) arg_int32_array[i]++; len_int32_array--; arg_uint32_array = talloc_memdup(req, arg_uint32_array, sizeof(uint32_t) * len_uint32_array); for (i = 0; i < len_uint32_array; i++) arg_uint32_array[i]++; arg_int64_array = talloc_memdup(req, arg_int64_array, sizeof(int64_t) * len_int64_array); for (i = 0; i < len_int64_array; i++) arg_int64_array[i]++; arg_uint64_array = talloc_memdup(req, arg_uint64_array, sizeof(uint64_t) * len_uint64_array); for (i = 0; i < len_uint64_array; i++) arg_uint64_array[i]++; arg_double_array = talloc_memdup(req, arg_double_array, sizeof(double) * len_double_array); for (i = 0; i < len_double_array; i++) arg_double_array[i]++; arg_string_array = talloc_memdup(req, arg_string_array, sizeof(char *) * len_string_array); for (i = 0; i < len_double_array; i++) { ck_assert_str_eq(arg_string_array[i], "bears"); arg_string_array[i] = "beets"; } len_string_array--; arg_object_path_array = talloc_memdup(req, arg_object_path_array, sizeof(char *) * len_object_path_array); for (i = 0; i < len_object_path_array; i++) { ck_assert_str_eq(arg_object_path_array[i], "/original"); arg_object_path_array[i] = "/changed"; } /* And reply with those values */ return test_pilot_Eject_finish(req, arg_byte, arg_boolean, arg_int16, arg_uint16, arg_int32, arg_uint32, arg_int64, arg_uint64, arg_double, arg_string, arg_object_path, arg_byte_array, len_byte_array, arg_int16_array, len_int16_array, arg_uint16_array, len_uint16_array, arg_int32_array, len_int32_array, arg_uint32_array, len_uint32_array, arg_int64_array, len_int64_array, arg_uint64_array, len_uint64_array, arg_double_array, len_double_array, arg_string_array, len_string_array, arg_object_path_array, len_object_path_array); } #define getter_body(in, out) do { \ ck_assert(dbus_req != NULL); \ ck_assert(out != NULL); \ *out = in; \ } while(0); static const bool pilot_bool = true; void pilot_get_boolean_handler(struct sbus_request *dbus_req, void *instance_data, bool *val) { getter_body(pilot_bool, val); } static const char *pilot_full_name = "Turanga Leela"; void pilot_get_full_name_handler(struct sbus_request *dbus_req, void *instance_data, const char **name) { getter_body(pilot_full_name, name); } static const uint8_t pilot_byte = 42; void pilot_get_byte_handler(struct sbus_request *dbus_req, void *instance_data, uint8_t *byte) { getter_body(pilot_byte, byte); } static const int16_t pilot_int16 = -123; void pilot_get_int16_handler(struct sbus_request *dbus_req, void *instance_data, int16_t *int16) { getter_body(pilot_int16, int16); } static const uint16_t pilot_uint16 = 123; void pilot_get_uint16_handler(struct sbus_request *dbus_req, void *instance_data, uint16_t *uint16) { getter_body(pilot_uint16, uint16); } static const int32_t pilot_int32 = -456; void pilot_get_int32_handler(struct sbus_request *dbus_req, void *instance_data, int32_t *int32) { getter_body(pilot_int32, int32); } static const uint32_t pilot_uint32 = 456; void pilot_get_uint32_handler(struct sbus_request *dbus_req, void *instance_data, uint32_t *uint32) { getter_body(pilot_uint32, uint32); } static const int64_t pilot_int64 = -456; void pilot_get_int64_handler(struct sbus_request *dbus_req, void *instance_data, int64_t *int64) { getter_body(pilot_int64, int64); } static const uint64_t pilot_uint64 = 456; void pilot_get_uint64_handler(struct sbus_request *dbus_req, void *instance_data, uint64_t *uint64) { getter_body(pilot_uint64, uint64); } static const double pilot_double = 3.14; void pilot_get_double_handler(struct sbus_request *dbus_req, void *instance_data, double *double_val) { getter_body(pilot_double, double_val); } static const char *pilot_string = "leela"; void pilot_get_string_handler(struct sbus_request *dbus_req, void *instance_data, const char **string_val) { *string_val = pilot_string; } static const char *pilot_path = "/path/leela"; void pilot_get_objpath_handler(struct sbus_request *dbus_req, void *instance_data, const char **path_val) { *path_val = pilot_path; } void pilot_get_null_string_handler(struct sbus_request *dbus_req, void *instance_data, const char **string_val) { *string_val = NULL; } void pilot_get_null_path_handler(struct sbus_request *dbus_req, void *instance_data, const char **path_val) { *path_val = NULL; } #define array_getter_body(in, out, outlen) do { \ ck_assert(dbus_req != NULL); \ ck_assert(out != NULL); \ ck_assert(outlen != NULL); \ *out = in; \ *outlen = N_ELEMENTS(in); \ } while(0); static uint8_t pilot_byte_array[] = { 42, 0 }; void pilot_get_byte_array_handler(struct sbus_request *dbus_req, void *instance_data, uint8_t **arr_out, int *arr_len) { array_getter_body(pilot_byte_array, arr_out, arr_len); } static int16_t pilot_int16_array[] = { -123, 0 }; void pilot_get_int16_array_handler(struct sbus_request *dbus_req, void *instance_data, int16_t **arr_out, int *arr_len) { array_getter_body(pilot_int16_array, arr_out, arr_len); } static uint16_t pilot_uint16_array[] = { 123, 0 }; void pilot_get_uint16_array_handler(struct sbus_request *dbus_req, void *instance_data, uint16_t **arr_out, int *arr_len) { array_getter_body(pilot_uint16_array, arr_out, arr_len); } static int32_t pilot_int32_array[] = { -456, 0 }; void pilot_get_int32_array_handler(struct sbus_request *dbus_req, void *instance_data, int32_t **arr_out, int *arr_len) { array_getter_body(pilot_int32_array, arr_out, arr_len); } static uint32_t pilot_uint32_array[] = { 456, 0 }; void pilot_get_uint32_array_handler(struct sbus_request *dbus_req, void *instance_data, uint32_t **arr_out, int *arr_len) { array_getter_body(pilot_uint32_array, arr_out, arr_len); } static int64_t pilot_int64_array[] = { -789, 0 }; void pilot_get_int64_array_handler(struct sbus_request *dbus_req, void *instance_data, int64_t **arr_out, int *arr_len) { array_getter_body(pilot_int64_array, arr_out, arr_len); } static uint64_t pilot_uint64_array[] = { 789, 0 }; void pilot_get_uint64_array_handler(struct sbus_request *dbus_req, void *instance_data, uint64_t **arr_out, int *arr_len) { array_getter_body(pilot_uint64_array, arr_out, arr_len); } static double pilot_double_array[] = { 3.14, 0 }; void pilot_get_double_array_handler(struct sbus_request *dbus_req, void *instance_data, double **arr_out, int *arr_len) { array_getter_body(pilot_double_array, arr_out, arr_len); } static const char *pilot_string_array[] = { "Turanga", "Leela" }; void pilot_get_string_array_handler(struct sbus_request *dbus_req, void *data, const char ***arr_out, int *arr_len) { array_getter_body(pilot_string_array, arr_out, arr_len); } static const char *pilot_path_array[] = { "/some/path", "/another/path" }; void pilot_get_path_array_handler(struct sbus_request *dbus_req, void *data, const char ***arr_out, int *arr_len) { array_getter_body(pilot_path_array, arr_out, arr_len); } void special_get_array_dict_sas(struct sbus_request *sbus_req, void *data, hash_table_t **_out) { hash_table_t *table; hash_key_t key; hash_value_t value; char **values; errno_t ret; int hret; *_out = NULL; ret = sss_hash_create(sbus_req, 10, &table); ck_assert_int_eq(ret, EOK); values = talloc_zero_array(table, char *, 3); ck_assert(values != NULL); values[0] = talloc_strdup(values, "hello1"); values[1] = talloc_strdup(values, "world1"); ck_assert(values[0] != NULL); ck_assert(values[1] != NULL); key.type = HASH_KEY_STRING; key.str = talloc_strdup(table, "key1"); value.type = HASH_VALUE_PTR; value.ptr = values; hret = hash_enter(table, &key, &value); ck_assert_int_eq(hret, HASH_SUCCESS); values = talloc_zero_array(table, char *, 3); ck_assert(values != NULL); values[0] = talloc_strdup(values, "hello2"); values[1] = talloc_strdup(values, "world2"); ck_assert(values[0] != NULL); ck_assert(values[1] != NULL); key.type = HASH_KEY_STRING; key.str = talloc_strdup(table, "key2"); ck_assert(key.str != NULL); value.type = HASH_VALUE_PTR; value.ptr = values; hash_enter(table, &key, &value); ck_assert_int_eq(hret, HASH_SUCCESS); *_out = table; } struct test_pilot pilot_iface = { { &test_pilot_meta, 0 }, .Eject = eject_handler, .get_FullName = pilot_get_full_name_handler, .get_byte = pilot_get_byte_handler, .get_boolean = pilot_get_boolean_handler, .get_int16 = pilot_get_int16_handler, .get_uint16 = pilot_get_uint16_handler, .get_int32 = pilot_get_int32_handler, .get_uint32 = pilot_get_uint32_handler, .get_int64 = pilot_get_int64_handler, .get_uint64 = pilot_get_uint64_handler, .get_double = pilot_get_double_handler, .get_string = pilot_get_string_handler, .get_object_path = pilot_get_objpath_handler, .get_null_string = pilot_get_null_string_handler, .get_null_path = pilot_get_null_path_handler, .get_byte_array = pilot_get_byte_array_handler, .get_int16_array = pilot_get_int16_array_handler, .get_uint16_array = pilot_get_uint16_array_handler, .get_int32_array = pilot_get_int32_array_handler, .get_uint32_array = pilot_get_uint32_array_handler, .get_int64_array = pilot_get_int64_array_handler, .get_uint64_array = pilot_get_uint64_array_handler, .get_double_array = pilot_get_double_array_handler, .get_string_array = pilot_get_string_array_handler, .get_object_path_array = pilot_get_path_array_handler, }; struct test_special special_iface = { { &test_special_meta, 0}, .get_array_dict_sas = special_get_array_dict_sas }; static int pilot_test_server_init(struct sbus_connection *server, void *unused) { int ret; ret = sbus_conn_register_iface(server, &pilot_iface.vtable, "/test/leela", "Crash into the billboard"); ck_assert_int_eq(ret, EOK); return EOK; } static int special_test_server_init(struct sbus_connection *server, void *unused) { int ret; ret = sbus_conn_register_iface(server, &special_iface.vtable, "/test/special", "Crash into the billboard"); ck_assert_int_eq(ret, EOK); return EOK; } START_TEST(test_marshal_basic_types) { unsigned char arg_byte = 11; dbus_bool_t arg_boolean = TRUE; dbus_int16_t arg_int16 = -2222; dbus_uint16_t arg_uint16 = 3333; dbus_int32_t arg_int32 = -44444444; dbus_uint32_t arg_uint32 = 55555555; dbus_int64_t arg_int64 = INT64_C(-6666666666666666); dbus_uint64_t arg_uint64 = UINT64_C(7777777777777777); double arg_double = 1.1; const char *arg_string = "hello"; const char *arg_object_path = "/original/object/path"; unsigned char v_byte[] = { 11, 12 }; dbus_int16_t v_int16[] = { 1, -22, 333, -4444 }; dbus_uint16_t v_uint16[] = { 1, 2, 3, 4, 5 }; dbus_int32_t v_int32[] = { -1, -23, 34, -56, -90000000, 78 }; dbus_uint32_t v_uint32[] = { 11111111, 22222222, 33333333 }; dbus_int64_t v_int64[] = { INT64_C(-6666666666666666), INT64_C(7777777777777777) }; dbus_uint64_t v_uint64[] = { UINT64_C(7777777777777777), INT64_C(888888888888888888) }; double v_double[] = { 1.1, 2.2, 3.3 }; char *v_string[] = { "bears", "bears", "bears" }; char *v_object_path[] = { "/original", "/original" }; unsigned char *arr_byte = v_byte; dbus_int16_t *arr_int16 = v_int16; dbus_uint16_t *arr_uint16 = v_uint16; dbus_int32_t *arr_int32 = v_int32; dbus_uint32_t *arr_uint32 = v_uint32; dbus_int64_t *arr_int64 = v_int64; dbus_uint64_t *arr_uint64 = v_uint64; double *arr_double = v_double; char **arr_string = v_string; char **arr_object_path = v_object_path; int len_byte = N_ELEMENTS(v_byte); int len_int16 = N_ELEMENTS(v_int16); int len_uint16 = N_ELEMENTS(v_uint16); int len_int32 = N_ELEMENTS(v_int32); int len_uint32 = N_ELEMENTS(v_uint32); int len_int64 = N_ELEMENTS(v_int64); int len_uint64 = N_ELEMENTS(v_uint64); int len_double = N_ELEMENTS(v_double); int len_string = N_ELEMENTS(v_string); int len_object_path = N_ELEMENTS(v_object_path); TALLOC_CTX *ctx; DBusConnection *client; DBusError error = DBUS_ERROR_INIT; DBusMessage *reply; ctx = talloc_new(NULL); ck_assert(ctx != NULL); client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); ck_assert(client != NULL); reply = test_dbus_call_sync(client, "/test/leela", TEST_PILOT, TEST_PILOT_EJECT, &error, DBUS_TYPE_BYTE, &arg_byte, DBUS_TYPE_BOOLEAN, &arg_boolean, DBUS_TYPE_INT16, &arg_int16, DBUS_TYPE_UINT16, &arg_uint16, DBUS_TYPE_INT32, &arg_int32, DBUS_TYPE_UINT32, &arg_uint32, DBUS_TYPE_INT64, &arg_int64, DBUS_TYPE_UINT64, &arg_uint64, DBUS_TYPE_DOUBLE, &arg_double, DBUS_TYPE_STRING, &arg_string, DBUS_TYPE_OBJECT_PATH, &arg_object_path, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &arr_byte, len_byte, DBUS_TYPE_ARRAY, DBUS_TYPE_INT16, &arr_int16, len_int16, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT16, &arr_uint16, len_uint16, DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &arr_int32, len_int32, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &arr_uint32, len_uint32, DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &arr_int64, len_int64, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &arr_uint64, len_uint64, DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &arr_double, len_double, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &arr_string, len_string, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arr_object_path, len_object_path, DBUS_TYPE_INVALID); ck_assert(reply != NULL); ck_assert(!dbus_error_is_set(&error)); ck_assert(dbus_message_get_args(reply, NULL, DBUS_TYPE_BYTE, &arg_byte, DBUS_TYPE_BOOLEAN, &arg_boolean, DBUS_TYPE_INT16, &arg_int16, DBUS_TYPE_UINT16, &arg_uint16, DBUS_TYPE_INT32, &arg_int32, DBUS_TYPE_UINT32, &arg_uint32, DBUS_TYPE_INT64, &arg_int64, DBUS_TYPE_UINT64, &arg_uint64, DBUS_TYPE_DOUBLE, &arg_double, DBUS_TYPE_STRING, &arg_string, DBUS_TYPE_OBJECT_PATH, &arg_object_path, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &arr_byte, &len_byte, DBUS_TYPE_ARRAY, DBUS_TYPE_INT16, &arr_int16, &len_int16, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT16, &arr_uint16, &len_uint16, DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &arr_int32, &len_int32, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &arr_uint32, &len_uint32, DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &arr_int64, &len_int64, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &arr_uint64, &len_uint64, DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &arr_double, &len_double, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &arr_string, &len_string, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arr_object_path, &len_object_path, DBUS_TYPE_INVALID)); ck_assert_uint_eq(arg_byte, 12); ck_assert(arg_boolean == FALSE); ck_assert_int_eq(arg_int16, -2221); ck_assert_uint_eq(arg_uint16, 3334); ck_assert_int_eq(arg_int32, -44444443); ck_assert_uint_eq(arg_uint32, 55555556); ck_assert(arg_int64 == INT64_C(-6666666666666665)); ck_assert(arg_uint64 == UINT64_C(7777777777777778)); ck_assert(arg_double == 2.1); ck_assert_str_eq(arg_string, "bears, beets, battlestar galactica"); ck_assert_str_eq(arg_object_path, "/another/object/path"); ck_assert_int_eq(len_byte, 2); ck_assert_int_eq(arr_byte[0], 12); ck_assert_int_eq(arr_byte[1], 13); ck_assert_int_eq(len_int16, 3); ck_assert_int_eq(arr_int16[0], 2); ck_assert_int_eq(arr_int16[1], -21); ck_assert_int_eq(arr_int16[2], 334); ck_assert_int_eq(len_uint16, 5); ck_assert_uint_eq(arr_uint16[0], 2); ck_assert_uint_eq(arr_uint16[1], 3); ck_assert_uint_eq(arr_uint16[2], 4); ck_assert_uint_eq(arr_uint16[3], 5); ck_assert_uint_eq(arr_uint16[4], 6); ck_assert_int_eq(len_int32, 5); ck_assert_int_eq(arr_int32[0], 0); ck_assert_int_eq(arr_int32[1], -22); ck_assert_int_eq(arr_int32[2], 35); ck_assert_int_eq(arr_int32[3], -55); ck_assert_int_eq(arr_int32[4], -89999999); ck_assert_int_eq(len_uint32, 3); ck_assert_uint_eq(arr_uint32[0], 11111112); ck_assert_uint_eq(arr_uint32[1], 22222223); ck_assert_uint_eq(arr_uint32[2], 33333334); ck_assert_int_eq(len_int64, 2); ck_assert(arr_int64[0] == INT64_C(-6666666666666665)); ck_assert(arr_int64[1] == INT64_C(7777777777777778)); ck_assert_int_eq(len_uint64, 2); ck_assert(arr_uint64[0] == UINT64_C(7777777777777778)); ck_assert(arr_uint64[1] == UINT64_C(888888888888888889)); ck_assert_int_eq(len_double, 3); ck_assert(arr_double[0] == 2.1); ck_assert(arr_double[1] == 3.2); ck_assert(arr_double[2] == 4.3); ck_assert_int_eq(len_string, 2); ck_assert_str_eq(arr_string[0], "beets"); ck_assert_str_eq(arr_string[1], "beets"); dbus_free_string_array(arr_string); ck_assert_int_eq(len_object_path, 2); ck_assert_str_eq(arr_object_path[0], "/changed"); ck_assert_str_eq(arr_object_path[1], "/changed"); dbus_free_string_array(arr_object_path); dbus_message_unref (reply); talloc_free(ctx); } END_TEST static void parse_get_reply(DBusMessage *reply, const int type, void *val) { DBusMessageIter iter; DBusMessageIter variter; dbus_bool_t dbret; dbret = dbus_message_iter_init(reply, &iter); ck_assert(dbret == TRUE); ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_VARIANT); dbus_message_iter_recurse(&iter, &variter); ck_assert_int_eq(dbus_message_iter_get_arg_type(&variter), type); dbus_message_iter_get_basic(&variter, val); } static void call_get(DBusConnection *client, const char *object_path, const char *iface, const char *prop, int type, void *val) { DBusMessage *reply; DBusError error = DBUS_ERROR_INIT; reply = test_dbus_call_sync(client, object_path, DBUS_PROPERTIES_INTERFACE, "Get", &error, DBUS_TYPE_STRING, &iface, DBUS_TYPE_STRING, &prop, DBUS_TYPE_INVALID); ck_assert(reply != NULL); parse_get_reply(reply, type, val); } START_TEST(test_get_basic_types) { TALLOC_CTX *ctx; DBusConnection *client; dbus_bool_t bool_val; const char *string_val; const char *path_val; uint8_t byte_val; int16_t int16_val; uint16_t uint16_val; int32_t int32_val; uint32_t uint32_val; int64_t int64_val; uint64_t uint64_val; double double_val; ctx = talloc_new(NULL); ck_assert(ctx != NULL); client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); ck_assert(client != NULL); call_get(client, "/test/leela", test_pilot_meta.name, "boolean", DBUS_TYPE_BOOLEAN, &bool_val); ck_assert(bool_val == pilot_bool); call_get(client, "/test/leela", test_pilot_meta.name, "FullName", DBUS_TYPE_STRING, &string_val); ck_assert_str_eq(string_val, pilot_full_name); call_get(client, "/test/leela", test_pilot_meta.name, "byte", DBUS_TYPE_BYTE, &byte_val); ck_assert_int_eq(byte_val, pilot_byte); call_get(client, "/test/leela", test_pilot_meta.name, "int16", DBUS_TYPE_INT16, &int16_val); ck_assert_int_eq(int16_val, pilot_int16); call_get(client, "/test/leela", test_pilot_meta.name, "uint16", DBUS_TYPE_UINT16, &uint16_val); ck_assert_int_eq(uint16_val, pilot_uint16); call_get(client, "/test/leela", test_pilot_meta.name, "int32", DBUS_TYPE_INT32, &int32_val); ck_assert_int_eq(int32_val, pilot_int32); call_get(client, "/test/leela", test_pilot_meta.name, "uint32", DBUS_TYPE_UINT32, &uint32_val); ck_assert_int_eq(uint32_val, pilot_uint32); call_get(client, "/test/leela", test_pilot_meta.name, "int64", DBUS_TYPE_INT64, &int64_val); ck_assert_int_eq(int64_val, pilot_int64); call_get(client, "/test/leela", test_pilot_meta.name, "uint64", DBUS_TYPE_UINT64, &uint64_val); ck_assert_int_eq(uint64_val, pilot_uint64); call_get(client, "/test/leela", test_pilot_meta.name, "double", DBUS_TYPE_DOUBLE, &double_val); ck_assert_int_eq(double_val, pilot_double); call_get(client, "/test/leela", test_pilot_meta.name, "string", DBUS_TYPE_STRING, &string_val); ck_assert_str_eq(string_val, pilot_string); call_get(client, "/test/leela", test_pilot_meta.name, "object_path", DBUS_TYPE_OBJECT_PATH, &path_val); ck_assert_str_eq(path_val, pilot_path); /* If a string getter returns NULL, the caller should receive "" */ call_get(client, "/test/leela", test_pilot_meta.name, "null_string", DBUS_TYPE_STRING, &string_val); ck_assert_str_eq(string_val, ""); /* If a string getter returns NULL, the caller should receive "/" */ call_get(client, "/test/leela", test_pilot_meta.name, "null_path", DBUS_TYPE_OBJECT_PATH, &path_val); ck_assert_str_eq(path_val, "/"); talloc_free(ctx); } END_TEST static void parse_get_array_reply(DBusMessage *reply, const int type, void **values, int *nels) { DBusMessageIter iter; DBusMessageIter variter; DBusMessageIter arriter; dbus_bool_t dbret; dbret = dbus_message_iter_init(reply, &iter); ck_assert(dbret == TRUE); ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_VARIANT); dbus_message_iter_recurse(&iter, &variter); ck_assert_int_eq(dbus_message_iter_get_arg_type(&variter), DBUS_TYPE_ARRAY); ck_assert_int_eq(dbus_message_iter_get_element_type(&variter), type); dbus_message_iter_recurse(&variter, &arriter); if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) { int n = 0, i = 0;; const char **strings; const char *s; do { n++; } while (dbus_message_iter_next(&arriter)); /* Allocating on NULL is bad, but this is unit test */ strings = talloc_array(NULL, const char *, n); ck_assert(strings != NULL); dbus_message_iter_recurse(&variter, &arriter); do { dbus_message_iter_get_basic(&arriter, &s); strings[i] = talloc_strdup(strings, s); ck_assert(strings[i] != NULL); i++; } while (dbus_message_iter_next(&arriter)); *nels = n; *values = strings; } else { /* Fixed types are easy */ dbus_message_iter_get_fixed_array(&arriter, values, nels); } } static void call_get_array(DBusConnection *client, const char *object_path, const char *iface, const char *prop, int type, void **values, int *nels) { DBusMessage *reply; DBusError error = DBUS_ERROR_INIT; reply = test_dbus_call_sync(client, object_path, DBUS_PROPERTIES_INTERFACE, "Get", &error, DBUS_TYPE_STRING, &iface, DBUS_TYPE_STRING, &prop, DBUS_TYPE_INVALID); ck_assert(reply != NULL); parse_get_array_reply(reply, type, values, nels); } #define _check_array(reply, len, known, fn) do { \ fn(len, 2); \ fn(reply[0], known[0]); \ fn(reply[1], known[1]); \ } while(0); \ #define check_int_array(reply, len, known) \ _check_array(reply, len, known, ck_assert_int_eq) #define check_uint_array(reply, len, known) \ _check_array(reply, len, known, ck_assert_uint_eq) START_TEST(test_get_basic_array_types) { TALLOC_CTX *ctx; DBusConnection *client; const char **string_arr_val; int string_arr_len; const char **path_arr_val; int path_arr_len; uint8_t *byte_arr_val; int byte_arr_len; int16_t *int16_arr_val; int int16_arr_len; uint16_t *uint16_arr_val; int uint16_arr_len; int32_t *int32_arr_val; int int32_arr_len; uint32_t *uint32_arr_val; int uint32_arr_len; int64_t *int64_arr_val; int int64_arr_len; uint64_t *uint64_arr_val; int uint64_arr_len; double *double_arr_val; int double_arr_len; ctx = talloc_new(NULL); ck_assert(ctx != NULL); client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); ck_assert(client != NULL); call_get_array(client, "/test/leela", test_pilot_meta.name, "byte_array", DBUS_TYPE_BYTE, (void **) &byte_arr_val, &byte_arr_len); check_uint_array(byte_arr_val, byte_arr_len, pilot_byte_array); call_get_array(client, "/test/leela", test_pilot_meta.name, "int16_array", DBUS_TYPE_INT16, (void **) &int16_arr_val, &int16_arr_len); check_int_array(int16_arr_val, int16_arr_len, pilot_int16_array); call_get_array(client, "/test/leela", test_pilot_meta.name, "uint16_array", DBUS_TYPE_UINT16, (void **) &uint16_arr_val, &uint16_arr_len); check_uint_array(uint16_arr_val, uint16_arr_len, pilot_uint16_array); call_get_array(client, "/test/leela", test_pilot_meta.name, "int32_array", DBUS_TYPE_INT32, (void **) &int32_arr_val, &int32_arr_len); check_int_array(int32_arr_val, int32_arr_len, pilot_int32_array); call_get_array(client, "/test/leela", test_pilot_meta.name, "uint32_array", DBUS_TYPE_UINT32, (void **) &uint32_arr_val, &uint32_arr_len); check_uint_array(uint32_arr_val, uint32_arr_len, pilot_uint32_array); call_get_array(client, "/test/leela", test_pilot_meta.name, "int64_array", DBUS_TYPE_INT64, (void **) &int64_arr_val, &int64_arr_len); check_int_array(int64_arr_val, int64_arr_len, pilot_int64_array); call_get_array(client, "/test/leela", test_pilot_meta.name, "uint64_array", DBUS_TYPE_UINT64, (void **) &uint64_arr_val, &uint64_arr_len); check_uint_array(uint64_arr_val, uint64_arr_len, pilot_uint64_array); call_get_array(client, "/test/leela", test_pilot_meta.name, "double_array", DBUS_TYPE_DOUBLE, (void **) &double_arr_val, &double_arr_len); check_int_array(double_arr_val, double_arr_len, pilot_double_array); call_get_array(client, "/test/leela", test_pilot_meta.name, "string_array", DBUS_TYPE_STRING, (void **) &string_arr_val, &string_arr_len); ck_assert_int_eq(string_arr_len, 2); ck_assert_str_eq(string_arr_val[0], pilot_string_array[0]); ck_assert_str_eq(string_arr_val[1], pilot_string_array[1]); call_get_array(client, "/test/leela", test_pilot_meta.name, "string_array", DBUS_TYPE_STRING, (void **) &string_arr_val, &string_arr_len); ck_assert_int_eq(string_arr_len, 2); ck_assert_str_eq(string_arr_val[0], pilot_string_array[0]); ck_assert_str_eq(string_arr_val[1], pilot_string_array[1]); call_get_array(client, "/test/leela", test_pilot_meta.name, "object_path_array", DBUS_TYPE_OBJECT_PATH, (void **) &path_arr_val, &path_arr_len); ck_assert_int_eq(path_arr_len, 2); ck_assert_str_eq(path_arr_val[0], pilot_path_array[0]); ck_assert_str_eq(path_arr_val[1], pilot_path_array[1]); talloc_free(ctx); } END_TEST START_TEST(test_get_array_dict_sas) { TALLOC_CTX *ctx; DBusConnection *client; DBusMessage *reply; DBusMessageIter it_variant; DBusMessageIter it_array; DBusMessageIter it_dict; DBusMessageIter it_dict_entry; DBusMessageIter it_values; DBusError error = DBUS_ERROR_INIT; const char *prop = "array_dict_sas"; dbus_bool_t dbret; const char *value; const char *hash_content[2][2] = {{"hello1", "world1"}, {"hello2", "world2"}}; const char **exp_values = NULL; int i; ctx = talloc_new(NULL); ck_assert(ctx != NULL); client = test_dbus_setup_mock(ctx, NULL, special_test_server_init, NULL); ck_assert(client != NULL); reply = test_dbus_call_sync(client, "/test/special", DBUS_PROPERTIES_INTERFACE, "Get", &error, DBUS_TYPE_STRING, &test_special_meta.name, DBUS_TYPE_STRING, &prop, DBUS_TYPE_INVALID); ck_assert(reply != NULL); dbret = dbus_message_iter_init(reply, &it_variant); ck_assert(dbret == TRUE); ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_variant), DBUS_TYPE_VARIANT); dbus_message_iter_recurse(&it_variant, &it_array); /* array */ ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_array), DBUS_TYPE_ARRAY); ck_assert_int_eq(dbus_message_iter_get_element_type(&it_array), DBUS_TYPE_DICT_ENTRY); /* dict entry */ /* first item */ dbus_message_iter_recurse(&it_array, &it_dict); for (i = 0; i < 2; i++) { dbus_message_iter_recurse(&it_dict, &it_dict_entry); ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_dict_entry), DBUS_TYPE_STRING); dbus_message_iter_get_basic(&it_dict_entry, &value); ck_assert(value != NULL); if (strcmp(value, "key1") == 0) { exp_values = hash_content[0]; } else if (strcmp(value, "key2") == 0) { exp_values = hash_content[1]; } else { ck_abort_msg("Invalid key! %s", value); } dbret = dbus_message_iter_next(&it_dict_entry); ck_assert(dbret == TRUE); ck_assert_int_eq(dbus_message_iter_get_arg_type(&it_dict_entry), DBUS_TYPE_ARRAY); ck_assert_int_eq(dbus_message_iter_get_element_type(&it_dict_entry), DBUS_TYPE_STRING); dbus_message_iter_recurse(&it_dict_entry, &it_values); dbus_message_iter_get_basic(&it_values, &value); ck_assert(value != NULL); ck_assert_str_eq(value, exp_values[0]); dbret = dbus_message_iter_next(&it_values); dbus_message_iter_get_basic(&it_values, &value); ck_assert(value != NULL); ck_assert_str_eq(value, exp_values[1]); dbus_message_iter_next(&it_dict); } talloc_free(ctx); } END_TEST struct prop_test { const char *name; bool handled; int length; int type; union prop_value { bool bool_val; const char *string_val; const char *path_val; uint8_t byte_val; int16_t int16_val; uint16_t uint16_val; int32_t int32_val; uint32_t uint32_val; int64_t int64_val; uint64_t uint64_val; double double_val; const char **string_arr_val; const char **path_arr_val; uint8_t *byte_arr_val; int16_t *int16_arr_val; uint16_t *uint16_arr_val; int32_t *int32_arr_val; uint32_t *uint32_arr_val; int64_t *int64_arr_val; uint64_t *uint64_arr_val; double *double_arr_val; } value; }; void check_prop(DBusMessageIter *variter, struct prop_test *p) { dbus_bool_t bool_val; const char *string_val; const char *path_val; uint8_t byte_val; int16_t int16_val; uint16_t uint16_val; int32_t int32_val; uint32_t uint32_val; int64_t int64_val; uint64_t uint64_val; double double_val; int type; type = dbus_message_iter_get_arg_type(variter); /* No property should be returned twice */ ck_assert(p->handled == false); ck_assert(p->type == type); switch (p->type) { case DBUS_TYPE_BOOLEAN: dbus_message_iter_get_basic(variter, &bool_val); ck_assert(bool_val == p->value.bool_val); break; case DBUS_TYPE_STRING: dbus_message_iter_get_basic(variter, &string_val); ck_assert_str_eq(string_val, p->value.string_val); break; case DBUS_TYPE_BYTE: dbus_message_iter_get_basic(variter, &byte_val); ck_assert_int_eq(byte_val, p->value.byte_val); break; case DBUS_TYPE_INT16: dbus_message_iter_get_basic(variter, &int16_val); ck_assert_int_eq(int16_val, p->value.int16_val); break; case DBUS_TYPE_UINT16: dbus_message_iter_get_basic(variter, &uint16_val); ck_assert_int_eq(uint16_val, p->value.uint16_val); break; case DBUS_TYPE_INT32: dbus_message_iter_get_basic(variter, &int32_val); ck_assert_int_eq(int32_val, p->value.int32_val); break; case DBUS_TYPE_UINT32: dbus_message_iter_get_basic(variter, &uint32_val); ck_assert_int_eq(uint32_val, p->value.uint32_val); break; case DBUS_TYPE_INT64: dbus_message_iter_get_basic(variter, &int64_val); ck_assert_int_eq(int64_val, p->value.int64_val); break; case DBUS_TYPE_UINT64: dbus_message_iter_get_basic(variter, &uint64_val); ck_assert_int_eq(uint64_val, p->value.uint64_val); break; case DBUS_TYPE_DOUBLE: dbus_message_iter_get_basic(variter, &double_val); ck_assert_int_eq(double_val, p->value.double_val); break; case DBUS_TYPE_OBJECT_PATH: dbus_message_iter_get_basic(variter, &path_val); ck_assert_str_eq(path_val, p->value.path_val); break; default: /* Not handled */ return; } /* This attribute was handled, get the next one */ p->handled = true; } void check_arr_prop(DBusMessageIter *variter, struct prop_test *p) { DBusMessageIter arriter; const char **strings = NULL; uint8_t *byte_arr_val; int16_t *int16_arr_val; uint16_t *uint16_arr_val; int32_t *int32_arr_val; uint32_t *uint32_arr_val; int64_t *int64_arr_val; uint64_t *uint64_arr_val; double *double_arr_val; int len; int type; ck_assert_int_eq(dbus_message_iter_get_arg_type(variter), DBUS_TYPE_ARRAY); type = dbus_message_iter_get_element_type(variter); ck_assert_int_eq(type, p->type); dbus_message_iter_recurse(variter, &arriter); if (type == DBUS_TYPE_STRING || type == DBUS_TYPE_OBJECT_PATH) { int n = 0, i = 0;; const char *s; do { n++; } while (dbus_message_iter_next(&arriter)); /* Allocating on NULL is bad, but this is unit test */ strings = talloc_array(NULL, const char *, n); ck_assert(strings != NULL); dbus_message_iter_recurse(variter, &arriter); do { dbus_message_iter_get_basic(&arriter, &s); strings[i] = talloc_strdup(strings, s); ck_assert(strings[i] != NULL); i++; } while (dbus_message_iter_next(&arriter)); len = n; } switch (p->type) { case DBUS_TYPE_STRING: ck_assert_int_eq(len, 2); ck_assert(strings != NULL); ck_assert_str_eq(strings[0], pilot_string_array[0]); ck_assert_str_eq(strings[1], pilot_string_array[1]); break; case DBUS_TYPE_BYTE: dbus_message_iter_get_fixed_array(&arriter, &byte_arr_val, &len); check_uint_array(byte_arr_val, len, p->value.byte_arr_val); break; case DBUS_TYPE_INT16: dbus_message_iter_get_fixed_array(&arriter, &int16_arr_val, &len); check_int_array(int16_arr_val, len, p->value.int16_arr_val); break; case DBUS_TYPE_UINT16: dbus_message_iter_get_fixed_array(&arriter, &uint16_arr_val, &len); check_uint_array(uint16_arr_val, len, p->value.uint16_arr_val); break; case DBUS_TYPE_INT32: dbus_message_iter_get_fixed_array(&arriter, &int32_arr_val, &len); check_int_array(int32_arr_val, len, p->value.int32_arr_val); break; case DBUS_TYPE_UINT32: dbus_message_iter_get_fixed_array(&arriter, &uint32_arr_val, &len); check_uint_array(uint32_arr_val, len, p->value.uint32_arr_val); break; case DBUS_TYPE_INT64: dbus_message_iter_get_fixed_array(&arriter, &int64_arr_val, &len); check_int_array(int64_arr_val, len, p->value.int64_arr_val); break; case DBUS_TYPE_UINT64: dbus_message_iter_get_fixed_array(&arriter, &uint64_arr_val, &len); check_uint_array(uint64_arr_val, len, p->value.uint64_arr_val); break; case DBUS_TYPE_DOUBLE: dbus_message_iter_get_fixed_array(&arriter, &double_arr_val, &len); check_int_array(double_arr_val, len, p->value.double_arr_val); break; case DBUS_TYPE_OBJECT_PATH: ck_assert_int_eq(len, 2); ck_assert(strings != NULL); ck_assert_str_eq(strings[0], pilot_path_array[0]); ck_assert_str_eq(strings[1], pilot_path_array[1]); break; default: /* Not handled */ return; } p->handled = true; } START_TEST(test_getall_basic_types) { DBusMessage *reply; DBusMessageIter iter; DBusMessageIter arriter; DBusMessageIter dictiter; DBusMessageIter variter; dbus_bool_t dbret; DBusError error = DBUS_ERROR_INIT; TALLOC_CTX *ctx; DBusConnection *client; char *attr_name; int i; int num_prop; struct prop_test pilot_properties[] = { { "boolean", false, 0, DBUS_TYPE_BOOLEAN, { .bool_val = pilot_bool } }, { "FullName", false, 0, DBUS_TYPE_STRING, { .string_val = pilot_full_name } }, { "byte", false, 0, DBUS_TYPE_BYTE, { .byte_val = pilot_byte } }, { "int16", false, 0, DBUS_TYPE_INT16, { .int16_val = pilot_int16 } }, { "uint16", false, 0, DBUS_TYPE_UINT16, { .uint16_val = pilot_uint16 } }, { "int32", false, 0, DBUS_TYPE_INT32, { .int32_val = pilot_int32 } }, { "uint32", false, 0, DBUS_TYPE_UINT32, { .uint32_val = pilot_uint32 } }, { "int64", false, 0, DBUS_TYPE_INT64, { .int64_val = pilot_int64 } }, { "uint64", false, 0, DBUS_TYPE_UINT64, { .uint64_val = pilot_uint64 } }, { "double", false, 0, DBUS_TYPE_DOUBLE, { .double_val = pilot_double } }, { "string", false, 0, DBUS_TYPE_STRING, { .string_val = pilot_string } }, { "object_path", false, 0, DBUS_TYPE_OBJECT_PATH, { .path_val = pilot_path } }, { "null_string", false, 0, DBUS_TYPE_STRING, { .string_val = "" } }, { "null_path", false, 0, DBUS_TYPE_OBJECT_PATH, { .path_val = "/" } }, { "byte_array", false, N_ELEMENTS(pilot_byte_array), DBUS_TYPE_BYTE, { .byte_arr_val = pilot_byte_array } }, { "int16_array", false, N_ELEMENTS(pilot_int16_array), DBUS_TYPE_INT16, { .int16_arr_val = pilot_int16_array } }, { "uint16_array", false, N_ELEMENTS(pilot_uint16_array), DBUS_TYPE_UINT16, { .uint16_arr_val = pilot_uint16_array } }, { "int32_array", false, N_ELEMENTS(pilot_int32_array), DBUS_TYPE_INT32, { .int32_arr_val = pilot_int32_array } }, { "uint32_array", false, N_ELEMENTS(pilot_uint32_array), DBUS_TYPE_UINT32, { .uint32_arr_val = pilot_uint32_array } }, { "int64_array", false, N_ELEMENTS(pilot_int64_array), DBUS_TYPE_INT64, { .int64_arr_val = pilot_int64_array } }, { "uint64_array", false, N_ELEMENTS(pilot_uint64_array), DBUS_TYPE_UINT64, { .uint64_arr_val = pilot_uint64_array } }, { "double_array", false, N_ELEMENTS(pilot_double_array), DBUS_TYPE_DOUBLE, { .double_arr_val = pilot_double_array } }, { "string_array", false, N_ELEMENTS(pilot_string_array), DBUS_TYPE_STRING, { .string_arr_val = pilot_string_array } }, { "object_path_array", false, N_ELEMENTS(pilot_path_array), DBUS_TYPE_OBJECT_PATH, { .path_arr_val = pilot_path_array } }, { NULL, false, 0, 0, { .bool_val = false } }}; ctx = talloc_new(NULL); ck_assert(ctx != NULL); client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); ck_assert(client != NULL); reply = test_dbus_call_sync(client, "/test/leela", DBUS_PROPERTIES_INTERFACE, "GetAll", &error, DBUS_TYPE_STRING, &test_pilot_meta.name, DBUS_TYPE_INVALID); ck_assert(reply != NULL); /* GetAll reply is an array of dictionaries */ dbret = dbus_message_iter_init(reply, &iter); ck_assert(dbret == TRUE); ck_assert_int_eq(dbus_message_iter_get_arg_type(&iter), DBUS_TYPE_ARRAY); dbus_message_iter_recurse(&iter, &arriter); num_prop = 0; do { ck_assert_int_eq(dbus_message_iter_get_arg_type(&arriter), DBUS_TYPE_DICT_ENTRY); dbus_message_iter_recurse(&arriter, &dictiter); dbus_message_iter_get_basic(&dictiter, &attr_name); ck_assert(dbus_message_iter_next(&dictiter) == TRUE); ck_assert_int_eq(dbus_message_iter_get_arg_type(&dictiter), DBUS_TYPE_VARIANT); dbus_message_iter_recurse(&dictiter, &variter); for (i=0; pilot_properties[i].name; i++) { if (strcmp(attr_name, pilot_properties[i].name) == 0) { if (dbus_message_iter_get_arg_type(&variter) == DBUS_TYPE_ARRAY) { check_arr_prop(&variter, &pilot_properties[i]); } else { check_prop(&variter, &pilot_properties[i]); } break; } } num_prop++; } while(dbus_message_iter_next(&arriter)); /* All known properties must be handled now */ for (i=0; pilot_properties[i].name; i++) { ck_assert(pilot_properties[i].handled == true); } /* Also all properties returned from the bus must be accounted for */ ck_assert_uint_eq(num_prop, N_ELEMENTS(pilot_properties)-1); talloc_free(ctx); } END_TEST TCase *create_handler_tests(void) { TCase *tc = tcase_create("handler"); tcase_add_test(tc, test_marshal_basic_types); tcase_add_test(tc, test_get_basic_types); tcase_add_test(tc, test_getall_basic_types); tcase_add_test(tc, test_get_basic_array_types); tcase_add_test(tc, test_get_array_dict_sas); return tc; } Suite *create_suite(void) { Suite *s = suite_create("sbus_codegen"); suite_add_tcase(s, create_defs_tests ()); suite_add_tcase(s, create_handler_tests ()); return s; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int failure_count; Suite *suite; SRunner *sr; struct poptOption long_options[] = { POPT_AUTOHELP POPT_TABLEEND }; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); suite = create_suite(); sr = srunner_create(suite); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); failure_count = srunner_ntests_failed(sr); srunner_free(sr); return (failure_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } sssd-1.13.4/src/tests/PaxHeaders.16287/sbus_tests.c0000644000000000000000000000007312703456111016617 xustar0030 atime=1460561751.658715654 29 ctime=1460561774.96779469 sssd-1.13.4/src/tests/sbus_tests.c0000644002412700241270000003445512703456111020302 0ustar00jhrozekjhrozek00000000000000/* SSSD sbus_codegen tests. Authors: Stef Walter Copyright (C) Red Hat, Inc 2014 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "common.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_meta.h" #include "util/util_errors.h" /* * Although one would normally rely on the codegen to generate these * structures, we want to test this functionality *before* we test * the codegen in sbus_codegen_tests ... so these are hand rolled. */ #define PILOT_IFACE "test.Pilot" #define PILOT_BLINK "Blink" #define PILOT_EAT "Eat" #define PILOT_CRASH "Crash" #define PILOT_IFACE_INTROSPECT \ "\n" \ "\n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ " \n" \ "\n" /* our vtable */ struct pilot_vtable { struct sbus_vtable vtable; sbus_msg_handler_fn Blink; sbus_msg_handler_fn Eat; sbus_msg_handler_fn Crash; }; const struct sbus_method_meta pilot_methods[] = { { PILOT_BLINK, /* method name */ NULL, /* in args: manually parsed */ NULL, /* out args: manually parsed */ offsetof(struct pilot_vtable, Blink), NULL }, { PILOT_EAT, /* method name */ NULL, /* in args: manually parsed */ NULL, /* out args: manually parsed */ offsetof(struct pilot_vtable, Eat), NULL }, { PILOT_CRASH, /* method name */ NULL, /* in args: manually parsed */ NULL, /* out args: manually parsed */ offsetof(struct pilot_vtable, Crash), NULL }, { NULL, } }; const struct sbus_interface_meta pilot_meta = { PILOT_IFACE, /* name */ pilot_methods, NULL, /* no signals */ NULL, /* no properties */ NULL, /* no GetAll invoker */ }; static int blink_handler(struct sbus_request *req, void *data) { DBusError error = DBUS_ERROR_INIT; dbus_int32_t duration = 0; dbus_bool_t crashed; ck_assert(req->intf->vtable->meta == &pilot_meta); ck_assert(data != NULL); ck_assert(data == req->intf->handler_data); ck_assert_str_eq(req->intf->path, req->path); if (strcmp(req->path, "/test/fry") == 0) { ck_assert_str_eq(data, "Don't crash"); } else if (strcmp(req->path, "/test/leela") == 0) { ck_assert_str_eq(data, "Crash into the billboard"); } else { ck_abort(); } if (!dbus_message_get_args (req->message, &error, DBUS_TYPE_INT32, &duration, DBUS_TYPE_INVALID)) { sbus_request_fail_and_finish(req, &error); dbus_error_free(&error); return EOK; } /* Pilot crashes when eyes closed too long */ crashed = (duration > 5); return sbus_request_return_and_finish(req, DBUS_TYPE_BOOLEAN, &crashed, DBUS_TYPE_INVALID); } static int eat_handler(struct sbus_request *req, void *data) { dbus_int32_t integer; dbus_bool_t boolean; const char **array; int count; if (!sbus_request_parse_or_finish (req, DBUS_TYPE_INT32, &integer, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &array, &count, DBUS_TYPE_BOOLEAN, &boolean, DBUS_TYPE_INVALID)) { return EOK; /* handled */ } ck_assert_int_eq(integer, 5); ck_assert(boolean == TRUE); ck_assert_int_eq(count, 3); ck_assert_str_eq(array[0], "one"); ck_assert_str_eq(array[1], "two"); ck_assert_str_eq(array[2], "three"); return sbus_request_return_and_finish(req, DBUS_TYPE_INVALID); } static int crash_handler(struct sbus_request *req, void *data) { /* Pilot crashes by returning a malformed UTF-8 string */ const char *invalid = "ad\351la\357d"; return sbus_request_return_and_finish(req, DBUS_TYPE_STRING, &invalid, DBUS_TYPE_INVALID); } struct pilot_vtable pilot_impl = { { &pilot_meta, 0 }, .Blink = blink_handler, .Eat = eat_handler, .Crash = crash_handler, }; static int pilot_test_server_init(struct sbus_connection *server, void *unused) { int ret; ret = sbus_conn_register_iface(server, &pilot_impl.vtable, "/test/leela", "Crash into the billboard"); ck_assert_int_eq(ret, EOK); ret = sbus_conn_register_iface(server, &pilot_impl.vtable, "/test/fry", "Don't crash"); ck_assert_int_eq(ret, EOK); return EOK; } START_TEST(test_raw_handler) { TALLOC_CTX *ctx; DBusConnection *client; DBusError error = DBUS_ERROR_INIT; DBusMessage *reply; dbus_bool_t crashed; dbus_int32_t duration; ctx = talloc_new(NULL); client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); /* Leela crashes with a duration higher than 5 */ duration = 10; reply = test_dbus_call_sync(client, "/test/leela", PILOT_IFACE, PILOT_BLINK, &error, DBUS_TYPE_INT32, &duration, DBUS_TYPE_INVALID); ck_assert(reply != NULL); ck_assert(!dbus_error_is_set(&error)); ck_assert(dbus_message_get_args(reply, NULL, DBUS_TYPE_BOOLEAN, &crashed, DBUS_TYPE_INVALID)); dbus_message_unref (reply); ck_assert(crashed == true); /* Fry daesn't crash with a duration lower than 5 */ duration = 1; reply = test_dbus_call_sync(client, "/test/fry", PILOT_IFACE, PILOT_BLINK, &error, DBUS_TYPE_INT32, &duration, DBUS_TYPE_INVALID); ck_assert(reply != NULL); ck_assert(!dbus_error_is_set(&error)); ck_assert(dbus_message_get_args(reply, NULL, DBUS_TYPE_BOOLEAN, &crashed, DBUS_TYPE_INVALID)); dbus_message_unref (reply); ck_assert(crashed == FALSE); talloc_free(ctx); } END_TEST START_TEST(test_request_parse_ok) { const char *args[] = { "one", "two", "three" }; const char **array; TALLOC_CTX *ctx; DBusConnection *client; DBusError error = DBUS_ERROR_INIT; DBusMessage *reply; dbus_bool_t boolean; dbus_int32_t integer; int count; ctx = talloc_new(NULL); client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); boolean = TRUE; integer = 5; count = 3; array = args; reply = test_dbus_call_sync(client, "/test/leela", PILOT_IFACE, PILOT_EAT, &error, DBUS_TYPE_INT32, &integer, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &array, count, DBUS_TYPE_BOOLEAN, &boolean, DBUS_TYPE_INVALID); ck_assert(reply != NULL); ck_assert(!dbus_error_is_set(&error)); ck_assert(dbus_message_get_args(reply, NULL, DBUS_TYPE_INVALID)); dbus_message_unref (reply); talloc_free(ctx); } END_TEST START_TEST(test_request_parse_bad_args) { TALLOC_CTX *ctx; DBusConnection *client; DBusError error = DBUS_ERROR_INIT; DBusMessage *reply; ctx = talloc_new(NULL); client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); reply = test_dbus_call_sync(client, "/test/leela", PILOT_IFACE, PILOT_EAT, &error, DBUS_TYPE_INVALID); /* bad agruments */ ck_assert(reply == NULL); ck_assert(dbus_error_is_set(&error)); ck_assert(dbus_error_has_name(&error, DBUS_ERROR_INVALID_ARGS)); dbus_error_free(&error); talloc_free(ctx); } END_TEST START_TEST(test_request_dontcrash) { #ifdef HAVE_DBUSBASICVALUE TALLOC_CTX *ctx; DBusConnection *client; DBusError error = DBUS_ERROR_INIT; DBusMessage *reply; ctx = talloc_new(NULL); client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); reply = test_dbus_call_sync(client, "/test/leela", PILOT_IFACE, PILOT_CRASH, &error, DBUS_TYPE_INVALID); /* bad agruments */ ck_assert(reply == NULL); ck_assert(dbus_error_is_set(&error)); ck_assert(dbus_error_has_name(&error, DBUS_ERROR_INVALID_ARGS)); dbus_error_free(&error); talloc_free(ctx); #endif /* HAVE_DBUSBASICVALUE */ } END_TEST START_TEST(test_introspection) { TALLOC_CTX *ctx; DBusConnection *client; DBusError error = DBUS_ERROR_INIT; DBusMessage *reply; char *xml; ctx = talloc_new(NULL); client = test_dbus_setup_mock(ctx, NULL, pilot_test_server_init, NULL); reply = test_dbus_call_sync(client, "/test/leela", DBUS_INTROSPECT_INTERFACE, DBUS_INTROSPECT_METHOD, &error, DBUS_TYPE_INVALID); /* bad agruments */ ck_assert(reply != NULL); ck_assert(!dbus_error_is_set(&error)); ck_assert(dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID)); ck_assert_str_eq(PILOT_IFACE_INTROSPECT, xml); dbus_message_unref(reply); talloc_free(ctx); } END_TEST START_TEST(test_sbus_new_error) { TALLOC_CTX *ctx; DBusError *error; ctx = talloc_new(NULL); error = sbus_error_new(ctx, DBUS_ERROR_IO_ERROR, "Input-output error"); ck_assert(error != NULL); ck_assert(dbus_error_is_set(error)); ck_assert(dbus_error_has_name(error, DBUS_ERROR_IO_ERROR)); talloc_free(error); error = sbus_error_new(ctx, DBUS_ERROR_IO_ERROR, "The answer should have been %d", 42); ck_assert(error != NULL); ck_assert(dbus_error_is_set(error)); ck_assert(dbus_error_has_name(error, DBUS_ERROR_IO_ERROR)); talloc_free(error); /* NULL message must also work */ error = sbus_error_new(ctx, DBUS_ERROR_IO_ERROR, NULL); ck_assert(error != NULL); ck_assert(dbus_error_is_set(error)); ck_assert(dbus_error_has_name(error, DBUS_ERROR_IO_ERROR)); talloc_free(error); talloc_free(ctx); } END_TEST TCase *create_sbus_tests(void) { TCase *tc = tcase_create("tests"); tcase_add_test(tc, test_raw_handler); tcase_add_test(tc, test_request_parse_ok); tcase_add_test(tc, test_request_parse_bad_args); tcase_add_test(tc, test_request_dontcrash); tcase_add_test(tc, test_introspection); tcase_add_test(tc, test_sbus_new_error); return tc; } Suite *create_suite(void) { Suite *s = suite_create("sbus"); suite_add_tcase(s, create_sbus_tests()); return s; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int failure_count; Suite *suite; SRunner *sr; struct poptOption long_options[] = { POPT_AUTOHELP POPT_TABLEEND }; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); suite = create_suite(); sr = srunner_create(suite); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); failure_count = srunner_ntests_failed(sr); srunner_free(sr); return (failure_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } sssd-1.13.4/src/tests/PaxHeaders.16287/sysdb_ssh-tests.c0000644000000000000000000000007412703456111017563 xustar0030 atime=1460561751.658715654 30 ctime=1460561775.025794887 sssd-1.13.4/src/tests/sysdb_ssh-tests.c0000644002412700241270000002507012703456111021236 0ustar00jhrozekjhrozek00000000000000/* Authors: Michal Zidek Stephen Gallagher This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "config.h" #include "tests/common.h" #include "util/util.h" #include "confdb/confdb.h" #include "confdb/confdb_setup.h" #include "db/sysdb.h" #include "db/sysdb_services.h" #include "db/sysdb_ssh.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_FILE "tests_conf.ldb" #define TEST_HOSTNAME "testhost" struct sysdb_test_ctx { struct sysdb_ctx *sysdb; struct confdb_ctx *confdb; struct tevent_context *ev; struct sss_domain_info *domain; }; static int setup_sysdb_tests(struct sysdb_test_ctx **ctx) { struct sysdb_test_ctx *test_ctx; char *conf_db; int ret; const char *val[2]; val[1] = NULL; /* Create tests directory if it doesn't exist */ /* (relative to current dir) */ ret = mkdir(TESTS_PATH, 0775); if (ret == -1 && errno != EEXIST) { fail("Could not create %s directory", TESTS_PATH); return EFAULT; } test_ctx = talloc_zero(NULL, struct sysdb_test_ctx); if (test_ctx == NULL) { fail("Could not allocate memory for test context"); return ENOMEM; } /* Create an event context * It will not be used except in confdb_init and sysdb_init */ test_ctx->ev = tevent_context_init(test_ctx); if (test_ctx->ev == NULL) { fail("Could not create event context"); talloc_free(test_ctx); return EIO; } conf_db = talloc_asprintf(test_ctx, "%s/%s", TESTS_PATH, TEST_CONF_FILE); if (conf_db == NULL) { fail("Out of memory, aborting!"); talloc_free(test_ctx); return ENOMEM; } DEBUG(SSSDBG_MINOR_FAILURE, "CONFDB: %s\n", conf_db); /* Connect to the conf db */ ret = confdb_init(test_ctx, &test_ctx->confdb, conf_db); if (ret != EOK) { fail("Could not initialize connection to the confdb"); talloc_free(test_ctx); return ret; } val[0] = "LOCAL"; ret = confdb_add_param(test_ctx->confdb, true, "config/sssd", "domains", val); if (ret != EOK) { fail("Could not initialize domains placeholder"); talloc_free(test_ctx); return ret; } val[0] = "local"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "id_provider", val); if (ret != EOK) { fail("Could not initialize provider"); talloc_free(test_ctx); return ret; } val[0] = "TRUE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "enumerate", val); if (ret != EOK) { fail("Could not initialize LOCAL domain"); talloc_free(test_ctx); return ret; } val[0] = "TRUE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "cache_credentials", val); if (ret != EOK) { fail("Could not initialize LOCAL domain"); talloc_free(test_ctx); return ret; } ret = sssd_domain_init(test_ctx, test_ctx->confdb, "local", TESTS_PATH, &test_ctx->domain); if (ret != EOK) { fail("Could not initialize connection to the sysdb (%d)", ret); talloc_free(test_ctx); return ret; } test_ctx->sysdb = test_ctx->domain->sysdb; *ctx = test_ctx; return EOK; } static void clean_up(void) { int ret = 0; ret += unlink(TESTS_PATH"/"TEST_CONF_FILE); ret += unlink(TESTS_PATH"/sssd.ldb"); ret += rmdir(TESTS_PATH); if (ret != 0) { fprintf(stderr, "Unable to remove all test files from %s\n",TESTS_PATH); } } struct test_data { struct tevent_context *ev; struct sysdb_test_ctx *ctx; const char *hostname; const char *alias; struct ldb_message *host; struct sysdb_attrs *attrs; }; static int test_sysdb_store_ssh_host(struct test_data *data) { int ret; time_t now = time(NULL); ret = sysdb_store_ssh_host(data->ctx->domain, data->hostname, data->alias, data->ctx->domain->ssh_host_timeout, now, data->attrs); return ret; } static int test_sysdb_delete_ssh_host(struct test_data *data) { int ret; ret = sysdb_delete_ssh_host(data->ctx->domain, data->hostname); return ret; } static int test_sysdb_get_ssh_host(struct test_data *data) { int ret; const char *attrs[] = { SYSDB_NAME, NULL }; ret = sysdb_get_ssh_host(data->ctx, data->ctx->domain, data->hostname, attrs, &data->host); return ret; } START_TEST (store_one_host_test) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); if (data == NULL) { fail("Out of memory!"); talloc_free(test_ctx); return; } data->ctx = test_ctx; data->ev = test_ctx->ev; data->hostname = talloc_strdup(test_ctx, TEST_HOSTNAME); if (data->hostname == NULL) { fail("Out of memory!"); talloc_free(test_ctx); return; } data->attrs = sysdb_new_attrs(test_ctx); if (data->attrs == NULL) { fail("Out of memory!"); talloc_free(test_ctx); return; } ret = test_sysdb_store_ssh_host(data); fail_if(ret != EOK, "Could not store host into database"); talloc_free(test_ctx); } END_TEST START_TEST (delete_existing_host_test) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); if (data == NULL) { fail("Out of memory!"); return; } data->ctx = test_ctx; data->ev = test_ctx->ev; data->hostname = talloc_strdup(test_ctx, TEST_HOSTNAME); if (data->hostname == NULL) { fail("Out of memory!"); talloc_free(test_ctx); return; } ret = test_sysdb_delete_ssh_host(data); fail_if(ret != EOK, "Could not delete host from database"); talloc_free(test_ctx); } END_TEST START_TEST (delete_nonexistent_host_test) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up the test"); return; } data = talloc_zero(test_ctx, struct test_data); if (data == NULL) { fail("Out of memory!"); talloc_free(test_ctx); return; } data->ctx = test_ctx; data->ev = test_ctx->ev; data->hostname = talloc_strdup(test_ctx, "nonexistent_host"); if (data->hostname == NULL) { fail("Out of memory!"); talloc_free(test_ctx); return; } ret = test_sysdb_delete_ssh_host(data); fail_if(ret != EOK, "Deletion of nonexistent host returned code %d", ret); talloc_free(test_ctx); } END_TEST START_TEST (sysdb_get_ssh_host_test) { struct sysdb_test_ctx *test_ctx; struct test_data *data; int ret; ret = setup_sysdb_tests(&test_ctx); if (ret != EOK) { fail("Could not set up test"); return; } data = talloc_zero(test_ctx, struct test_data); if (data == NULL) { fail("Out of memory!"); talloc_free(test_ctx); return; } data->ctx = test_ctx; data->ev = test_ctx->ev; data->hostname = talloc_strdup(test_ctx, TEST_HOSTNAME); if (data->hostname == NULL) { fail("Out of memory!"); talloc_free(test_ctx); return; } data->attrs = sysdb_new_attrs(test_ctx); if (data->attrs == NULL) { fail("Out of memory!"); talloc_free(test_ctx); return; } ret = test_sysdb_store_ssh_host(data); if (ret != EOK) { fail("Could not store host '%s' to database", TEST_HOSTNAME); talloc_free(test_ctx); return; } ret = test_sysdb_get_ssh_host(data); fail_if(ret != EOK, "Could not find host '%s'",TEST_HOSTNAME); talloc_free(test_ctx); } END_TEST Suite *create_sysdb_ssh_suite(void) { Suite *s = suite_create("sysdb_ssh"); TCase *tc_sysdb_ssh = tcase_create("SYSDB_SSH Tests"); tcase_add_test(tc_sysdb_ssh, store_one_host_test); tcase_add_test(tc_sysdb_ssh, delete_existing_host_test); tcase_add_test(tc_sysdb_ssh, delete_nonexistent_host_test); tcase_add_test(tc_sysdb_ssh, sysdb_get_ssh_host_test); suite_add_tcase(s, tc_sysdb_ssh); return s; } int main(int argc, const char *argv[]) { int failcount; int opt; poptContext pc; Suite* s; SRunner *sr; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, (const char **) argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); if (!ldb_modules_path_is_set()) { fprintf(stderr, "Warning: LDB_MODULES_PATH is not set, " "will use LDB plugins installed in system paths.\n"); } tests_set_cwd(); s = create_sysdb_ssh_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_ENV); failcount = srunner_ntests_failed(sr); srunner_free(sr); clean_up(); if (failcount != 0) { return EXIT_FAILURE; } return EXIT_SUCCESS; } sssd-1.13.4/src/tests/PaxHeaders.16287/common_check.h0000644000000000000000000000007412703456111017054 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.584793391 sssd-1.13.4/src/tests/common_check.h0000644002412700241270000000220112703456111020516 0ustar00jhrozekjhrozek00000000000000/* SSSD Memory leak/growth checks for check-based tests using talloc. Authors: Martin Nagy Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __TESTS_COMMON_CHECK_H__ #define __TESTS_COMMON_CHECK_H__ #include "tests/common.h" void ck_leak_check_setup(void); void ck_leak_check_teardown(void); #define ck_leaks_push(ctx) check_leaks_push(ctx) #define ck_leaks_pop(ctx) fail_unless(check_leaks_pop(ctx) == true, check_leaks_err_msg()) #endif /* __TESTS_COMMON_CHECK_H__ */ sssd-1.13.4/src/tests/PaxHeaders.16287/sss_idmap-tests.c0000644000000000000000000000007412703456111017544 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.978794727 sssd-1.13.4/src/tests/sss_idmap-tests.c0000644002412700241270000010311512703456111021214 0ustar00jhrozekjhrozek00000000000000/* SSSD - Test for idmap library Authors: Sumit Bose Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "lib/idmap/sss_idmap.h" #include "lib/idmap/sss_idmap_private.h" #include "tests/common_check.h" #define IDMAP_RANGE_MIN 1234 #define IDMAP_RANGE_MAX 9876 #define IDMAP_RANGE_MIN2 11234 #define IDMAP_RANGE_MAX2 19876 const char test_sid[] = "S-1-5-21-2127521184-1604012920-1887927527-72713"; uint8_t test_bin_sid[] = {0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x00, 0xA0, 0x65, 0xCF, 0x7E, 0x78, 0x4B, 0x9B, 0x5F, 0xE7, 0x7C, 0x87, 0x70, 0x09, 0x1C, 0x01, 0x00}; size_t test_bin_sid_length = sizeof(test_bin_sid); struct dom_sid test_smb_sid = {1, 5, {0, 0, 0, 0, 0, 5}, {21, 2127521184, 1604012920, 1887927527, 72713, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; const char large_sid[] = "S-1-5-21-1-2-4294967295-1000"; const char too_large_sid[] = "S-1-5-21-1-2-4294967296-1000"; struct sss_idmap_ctx *idmap_ctx; static void *idmap_talloc(size_t size, void *pvt) { return talloc_size(pvt, size); } static void idmap_talloc_free(void *ptr, void *pvt) { talloc_free(ptr); } void idmap_ctx_setup(void) { enum idmap_error_code err; err = sss_idmap_init(idmap_talloc, global_talloc_context, idmap_talloc_free, &idmap_ctx); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_init failed."); fail_unless(idmap_ctx != NULL, "sss_idmap_init returned NULL."); } void idmap_ctx_setup_additional_seconary_slices(void) { enum idmap_error_code err; err = sss_idmap_init(idmap_talloc, global_talloc_context, idmap_talloc_free, &idmap_ctx); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_init failed."); fail_unless(idmap_ctx != NULL, "sss_idmap_init returned NULL."); idmap_ctx->idmap_opts.rangesize = 10; idmap_ctx->idmap_opts.extra_slice_init = 5; } void idmap_ctx_teardown(void) { enum idmap_error_code err; err = sss_idmap_free(idmap_ctx); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_free failed."); } void idmap_add_domain_setup(void) { enum idmap_error_code err; struct sss_idmap_range range = {IDMAP_RANGE_MIN, IDMAP_RANGE_MAX}; err = sss_idmap_add_domain(idmap_ctx, "test.dom", "S-1-5-21-1-2-3", &range); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_domain failed."); } void idmap_add_domain_with_sec_slices_setup(void) { enum idmap_error_code err; struct sss_idmap_range range = { IDMAP_RANGE_MIN, IDMAP_RANGE_MIN + idmap_ctx->idmap_opts.rangesize - 1, }; err = sss_idmap_add_auto_domain_ex(idmap_ctx, "test.dom", "S-1-5-21-1-2-3", &range, NULL, 0, false, NULL, NULL); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_auto_domain_ex failed."); } enum idmap_error_code cb(const char *dom_name, const char *dom_sid, const char *range_id, uint32_t min_id, uint32_t max_id, uint32_t first_rid, void *pvt) { return IDMAP_ERROR; } void idmap_add_domain_with_sec_slices_setup_cb_fail(void) { enum idmap_error_code err; struct sss_idmap_range range = { IDMAP_RANGE_MIN, IDMAP_RANGE_MIN + idmap_ctx->idmap_opts.rangesize - 1, }; err = sss_idmap_add_auto_domain_ex(idmap_ctx, "test.dom", "S-1-5-21-1-2-3", &range, NULL, 0, false, cb, NULL); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_auto_domain_ex failed."); } #define MAX 1000 char data[MAX]; enum idmap_error_code cb2(const char *dom_name, const char *dom_sid, const char *range_id, uint32_t min_id, uint32_t max_id, uint32_t first_rid, void *pvt) { char *p = (char*)pvt; size_t len; len = snprintf(p, MAX, "%s, %s %s, %"PRIu32", %"PRIu32", %" PRIu32, dom_name, dom_sid, range_id, min_id, max_id, first_rid); if (len >= MAX) { return IDMAP_OUT_OF_MEMORY; } return IDMAP_SUCCESS; } void idmap_add_domain_with_sec_slices_setup_cb_ok(void) { enum idmap_error_code err; struct sss_idmap_range range = { IDMAP_RANGE_MIN, IDMAP_RANGE_MIN + idmap_ctx->idmap_opts.rangesize - 1, }; void *pvt = (void*) data; err = sss_idmap_add_auto_domain_ex(idmap_ctx, "test.dom", "S-1-5-21-1-2-3", &range, NULL, 0, false, cb2, pvt); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_auto_domain_ex failed."); } START_TEST(idmap_test_is_domain_sid) { size_t c; const char *invalid[] = { "abc", "S-1-2-3-4-5-6", "S-1-5-21-1", "S-1-5-21-1-2-123456789012345678", "S-1-5-21-1+2+3", "S-1-5-21-a-b-c", "S-1-5-21-1-2-3-4", NULL }; fail_if(is_domain_sid(NULL), "is_domain_sid() returned true for [NULL]"); for (c = 0; invalid[c] != NULL; c++) { fail_if(is_domain_sid(invalid[c]), "is_domain_sid() returned true for [%s]", invalid[c]); } fail_unless(is_domain_sid("S-1-5-21-1-2-3"), "is_domain_sid() returned true for [S-1-5-21-1-2-3]"); } END_TEST START_TEST(idmap_test_init_malloc) { enum idmap_error_code err; struct sss_idmap_ctx *ctx = NULL; err = sss_idmap_init(NULL, NULL, NULL, &ctx); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_init failed."); fail_unless(ctx != NULL, "sss_idmap_init returned NULL."); err = sss_idmap_free(ctx); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_free failed."); } END_TEST START_TEST(idmap_test_init_talloc) { enum idmap_error_code err; struct sss_idmap_ctx *ctx = NULL; err = sss_idmap_init(idmap_talloc, global_talloc_context, idmap_talloc_free, &ctx); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_init failed."); fail_unless(ctx != NULL, "sss_idmap_init returned NULL."); err = sss_idmap_free(ctx); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_free failed."); } END_TEST START_TEST(idmap_test_add_domain) { idmap_add_domain_setup(); } END_TEST START_TEST(idmap_test_add_domain_collisions) { enum idmap_error_code err; struct sss_idmap_range range = {IDMAP_RANGE_MIN, IDMAP_RANGE_MAX}; struct sss_idmap_range range2 = {IDMAP_RANGE_MIN2, IDMAP_RANGE_MAX2}; err = sss_idmap_add_domain(idmap_ctx, "test.dom", "S-1-5-21-1-2-3", &range); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_domain failed."); err = sss_idmap_add_domain(idmap_ctx, "test.dom", "S-1-5-21-1-2-4", &range2); fail_unless(err == IDMAP_COLLISION, "sss_idmap_add_domain added domain with the same name."); err = sss_idmap_add_domain(idmap_ctx, "test.dom2", "S-1-5-21-1-2-3", &range2); fail_unless(err == IDMAP_COLLISION, "sss_idmap_add_domain added domain with the same SID."); err = sss_idmap_add_domain(idmap_ctx, "test.dom2", "S-1-5-21-1-2-4", &range); fail_unless(err == IDMAP_COLLISION, "sss_idmap_add_domain added domain with the same range."); err = sss_idmap_add_domain(idmap_ctx, "test.dom2", "S-1-5-21-1-2-4", &range2); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_domain failed to add second domain."); } END_TEST START_TEST(idmap_test_add_domain_collisions_ext_mapping) { enum idmap_error_code err; struct sss_idmap_range range = {IDMAP_RANGE_MIN, IDMAP_RANGE_MAX}; struct sss_idmap_range range2 = {IDMAP_RANGE_MIN2, IDMAP_RANGE_MAX2}; err = sss_idmap_add_domain_ex(idmap_ctx, "test.dom", "S-1-5-21-1-2-3", &range, NULL, 0, true); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_domain failed."); err = sss_idmap_add_domain_ex(idmap_ctx, "test.dom", "S-1-5-21-1-2-4", &range2, NULL, 0, true); fail_unless(err == IDMAP_COLLISION, "sss_idmap_add_domain added domain with the same name."); err = sss_idmap_add_domain_ex(idmap_ctx, "test.dom2", "S-1-5-21-1-2-3", &range2, NULL, 0, true); fail_unless(err == IDMAP_COLLISION, "sss_idmap_add_domain added domain with the same SID."); err = sss_idmap_add_domain_ex(idmap_ctx, "test.dom2", "S-1-5-21-1-2-4", &range, NULL, 0, true); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_add_domain failed to add second domain with " \ "external mapping and the same range."); } END_TEST START_TEST(idmap_test_sid2uid) { enum idmap_error_code err; uint32_t id; err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3333-1000", &id); fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_sid_to_unix did not detect " "unknown domain"); err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-10000", &id); fail_unless(err == IDMAP_NO_RANGE, "sss_idmap_sid_to_unix did not detect " "RID out of range"); err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-1000", &id); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed."); fail_unless(id == (1000 + IDMAP_RANGE_MIN), "sss_idmap_sid_to_unix returned wrong id, " "got [%d], expected [%d].", id, 1000 + IDMAP_RANGE_MIN); } END_TEST START_TEST(idmap_test_sid2uid_ss) { enum idmap_error_code err; uint32_t id; const uint32_t exp_id = 351800000; const uint32_t exp_id2 = 832610000; err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3333-1000", &id); fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_sid_to_unix did not detect " "unknown domain"); /* RID out of primary and secondary range */ err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-4000000", &id); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed."); fail_unless(id == exp_id, "sss_idmap_sid_to_unix returned wrong id, " "got [%d], expected [%d].", id, exp_id); err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-1000", &id); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed."); fail_unless(id == (1000 + IDMAP_RANGE_MIN), "sss_idmap_sid_to_unix returned wrong id, " "got [%d], expected [%d].", id, 1000 + IDMAP_RANGE_MIN); err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-210000", &id); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed."); fail_unless(id == exp_id2, "sss_idmap_sid_to_unix returned wrong id, " "got [%d], expected [%d].", id, exp_id2); } END_TEST START_TEST(idmap_test_sid2uid_ext_sec_slices) { enum idmap_error_code err; uint32_t id; char *sid; const uint32_t exp_id = 351800000; err = sss_idmap_unix_to_sid(idmap_ctx, exp_id, &sid); fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_sid did not detect " "id out of range"); /* RID out of primary and secondary range */ err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-4000000", &id); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed."); fail_unless(id == exp_id, "sss_idmap_sid_to_unix returned wrong id, " "got [%d], expected [%d].", id, exp_id); /* Secondary ranges were expanded by sid_to_unix call */ err = sss_idmap_unix_to_sid(idmap_ctx, exp_id, &sid); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_sid failed."); fail_unless(strcmp(sid, "S-1-5-21-1-2-3-4000000") == 0, "sss_idmap_unix_to_sid returned wrong SID, " "expected [%s], got [%s].", "S-1-5-21-1-2-3-4000000", sid); sss_idmap_free_sid(idmap_ctx, sid); } END_TEST START_TEST(idmap_test_dyn_dom_store_cb_fail) { enum idmap_error_code err; uint32_t id; char *sid; const uint32_t exp_id = 351800000; err = sss_idmap_unix_to_sid(idmap_ctx, exp_id, &sid); fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_sid did not detect " "id out of range"); /* RID out of primary and secondary range */ err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-4000000", &id); fail_unless(err == IDMAP_ERROR, "sss_idmap_sid_to_unix failed."); } END_TEST START_TEST(idmap_test_dyn_dom_store_cb_ok) { enum idmap_error_code err; uint32_t id; char *sid; const uint32_t exp_id = 351800000; const char *exp_stored_data = "test.dom, S-1-5-21-1-2-3 S-1-5-21-1-2-3-4000000, 351800000, 351999999, 4000000"; err = sss_idmap_unix_to_sid(idmap_ctx, exp_id, &sid); fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_sid did not detect " "id out of range"); /* RID out of primary and secondary range */ err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-4000000", &id); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed."); fail_unless(strcmp(data, exp_stored_data) == 0, "Storing dynamic domains idmapping failed: " "expected [%s] but got [%s].", exp_stored_data, data); } END_TEST START_TEST(idmap_test_sid2uid_additional_secondary_slices) { enum idmap_error_code err; struct TALLOC_CTX *tmp_ctx; const char *dom_prefix = "S-1-5-21-1-2-3"; const int max_rid = 80; const char *sids[max_rid + 1]; unsigned int ids[max_rid + 1]; tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "Out of memory."); for (unsigned int i = 0; i < max_rid + 1; i++) { sids[i] = talloc_asprintf(tmp_ctx, "%s-%u", dom_prefix, i); fail_unless(sids[i] != NULL, "Out of memory"); err = sss_idmap_sid_to_unix(idmap_ctx, sids[i], &ids[i]); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed."); } for (unsigned int i = 0; i < max_rid + 1; i++) { char *sid; err = sss_idmap_unix_to_sid(idmap_ctx, ids[i], &sid); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed."); fail_unless(strcmp(sid, sids[i]) == 0, "sss_idmap_unix_to_sid returned wrong sid, " "got [%s], expected [%s].", sid, sids[i]); talloc_free(sid); } talloc_free(tmp_ctx); } END_TEST START_TEST(idmap_test_bin_sid2uid) { enum idmap_error_code err; uint32_t id; uint8_t *bin_sid = NULL; size_t length; err = sss_idmap_sid_to_bin_sid(idmap_ctx, "S-1-5-21-1-2-3-1000", &bin_sid, &length); fail_unless(err == IDMAP_SUCCESS, "Failed to convert SID to binary SID"); err = sss_idmap_bin_sid_to_unix(idmap_ctx, bin_sid, length , &id); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_bin_sid_to_unix failed."); fail_unless(id == (1000 + IDMAP_RANGE_MIN), "sss_idmap_bin_sid_to_unix returned wrong id, " "got [%d], expected [%d].", id, 1000 + IDMAP_RANGE_MIN); sss_idmap_free_bin_sid(idmap_ctx, bin_sid); } END_TEST START_TEST(idmap_test_dom_sid2uid) { enum idmap_error_code err; uint32_t id; struct sss_dom_sid *dom_sid = NULL; err = sss_idmap_sid_to_dom_sid(idmap_ctx, "S-1-5-21-1-2-3-1000", &dom_sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert SID to SID structure"); err = sss_idmap_dom_sid_to_unix(idmap_ctx, dom_sid, &id); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_dom_sid_to_unix failed."); fail_unless(id == (1000 + IDMAP_RANGE_MIN), "sss_idmap_dom_sid_to_unix returned wrong id, " "got [%d], expected [%d].", id, 1000 + IDMAP_RANGE_MIN); sss_idmap_free_dom_sid(idmap_ctx, dom_sid); } END_TEST START_TEST(idmap_test_uid2sid) { enum idmap_error_code err; char *sid; err = sss_idmap_unix_to_sid(idmap_ctx, 10000, &sid); fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_sid did not detect " "id out of range"); err = sss_idmap_unix_to_sid(idmap_ctx, 2234, &sid); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_sid failed."); fail_unless(strcmp(sid, "S-1-5-21-1-2-3-1000") == 0, "sss_idmap_unix_to_sid returned wrong SID, " "expected [%s], got [%s].", "S-1-5-21-1-2-3-1000", sid); sss_idmap_free_sid(idmap_ctx, sid); } END_TEST START_TEST(idmap_test_uid2sid_ss) { enum idmap_error_code err; char *sid; err = sss_idmap_unix_to_sid(idmap_ctx, IDMAP_RANGE_MIN + idmap_ctx->idmap_opts.rangesize + 1, &sid); fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_sid did not detect " "id out of range"); err = sss_idmap_unix_to_sid(idmap_ctx, 2234, &sid); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_sid failed."); fail_unless(strcmp(sid, "S-1-5-21-1-2-3-1000") == 0, "sss_idmap_unix_to_sid returned wrong SID, " "expected [%s], got [%s].", "S-1-5-21-1-2-3-1000", sid); sss_idmap_free_sid(idmap_ctx, sid); /* Secondary ranges */ err = sss_idmap_unix_to_sid(idmap_ctx, 313800000, &sid); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_sid failed."); fail_unless(strcmp(sid, "S-1-5-21-1-2-3-400000") == 0, "sss_idmap_unix_to_sid returned wrong SID, " "expected [%s], got [%s].", "S-1-5-21-1-2-3-400000", sid); sss_idmap_free_sid(idmap_ctx, sid); } END_TEST START_TEST(idmap_test_uid2dom_sid) { enum idmap_error_code err; struct sss_dom_sid *dom_sid = NULL; char *sid = NULL; err = sss_idmap_unix_to_dom_sid(idmap_ctx, 10000, &dom_sid); fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_dom_sid did not detect " "id out of range"); err = sss_idmap_unix_to_dom_sid(idmap_ctx, 2234, &dom_sid); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_dom_sid failed."); err = sss_idmap_dom_sid_to_sid(idmap_ctx, dom_sid, &sid); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_dom_sid_to_sid failed."); fail_unless(strcmp(sid, "S-1-5-21-1-2-3-1000") == 0, "sss_idmap_unix_to_dom_sid returned wrong SID, " "expected [%s], got [%s].", "S-1-5-21-1-2-3-1000", sid); sss_idmap_free_sid(idmap_ctx, sid); sss_idmap_free_dom_sid(idmap_ctx, dom_sid); } END_TEST START_TEST(idmap_test_uid2bin_sid) { enum idmap_error_code err; uint8_t *bin_sid = NULL; size_t length; char *sid = NULL; err = sss_idmap_unix_to_bin_sid(idmap_ctx, 10000, &bin_sid, &length); fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_bin_sid did not detect " "id out of range"); err = sss_idmap_unix_to_bin_sid(idmap_ctx, 2234, &bin_sid, &length); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_bin_sid failed."); err = sss_idmap_bin_sid_to_sid(idmap_ctx, bin_sid, length, &sid); fail_unless(err == IDMAP_SUCCESS, "sss_idmap_bin_sid_to_sid failed."); fail_unless(strcmp(sid, "S-1-5-21-1-2-3-1000") == 0, "sss_idmap_unix_to_bin_sid returned wrong SID, " "expected [%s], got [%s].", "S-1-5-21-1-2-3-1000", sid); sss_idmap_free_sid(idmap_ctx, sid); sss_idmap_free_bin_sid(idmap_ctx, bin_sid); } END_TEST START_TEST(idmap_test_bin_sid2dom_sid) { struct sss_dom_sid *dom_sid = NULL; enum idmap_error_code err; uint8_t *new_bin_sid = NULL; size_t new_bin_sid_length; err = sss_idmap_bin_sid_to_dom_sid(idmap_ctx, test_bin_sid, test_bin_sid_length, &dom_sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert binary SID to struct sss_dom_sid."); err = sss_idmap_dom_sid_to_bin_sid(idmap_ctx, dom_sid, &new_bin_sid, &new_bin_sid_length); fail_unless(err == IDMAP_SUCCESS, "Failed to convert struct sss_dom_sid to binary SID."); fail_unless(new_bin_sid_length == test_bin_sid_length, "Length of binary SIDs do not match."); fail_unless(memcmp(test_bin_sid, new_bin_sid, test_bin_sid_length) == 0, "Binary SIDs do not match."); sss_idmap_free_dom_sid(idmap_ctx, dom_sid); sss_idmap_free_bin_sid(idmap_ctx, new_bin_sid); } END_TEST START_TEST(idmap_test_sid2dom_sid) { struct sss_dom_sid *dom_sid = NULL; enum idmap_error_code err; char *new_sid = NULL; err = sss_idmap_sid_to_dom_sid(idmap_ctx, "S-1-5-21-1-2-3-1000", &dom_sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert SID string to struct sss_dom_sid."); err = sss_idmap_dom_sid_to_sid(idmap_ctx, dom_sid, &new_sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert struct sss_dom_sid to SID string."); fail_unless(new_sid != NULL, "SID string not set"); fail_unless(strlen("S-1-5-21-1-2-3-1000") == strlen(new_sid), "Length of SID strings do not match."); fail_unless(strcmp("S-1-5-21-1-2-3-1000", new_sid) == 0, "SID strings do not match."); sss_idmap_free_dom_sid(idmap_ctx, dom_sid); sss_idmap_free_sid(idmap_ctx, new_sid); } END_TEST START_TEST(idmap_test_large_and_too_large_sid) { struct sss_dom_sid *dom_sid = NULL; enum idmap_error_code err; char *new_sid = NULL; err = sss_idmap_sid_to_dom_sid(idmap_ctx, large_sid, &dom_sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert SID string with a UINT32_MAX component " "to struct sss_dom_sid."); err = sss_idmap_dom_sid_to_sid(idmap_ctx, dom_sid, &new_sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert struct sss_dom_sid to SID string."); fail_unless(new_sid != NULL, "SID string not set"); fail_unless(strlen(large_sid) == strlen(new_sid), "Length of SID strings do not match."); fail_unless(strcmp(large_sid, new_sid) == 0, "SID strings do not match, expected [%s], got [%s]", large_sid, new_sid); err = sss_idmap_sid_to_dom_sid(idmap_ctx, too_large_sid, &dom_sid); fail_unless(err == IDMAP_SID_INVALID, "Trying to convert a SID with a too large component " "did not return IDMAP_SID_INVALID"); sss_idmap_free_dom_sid(idmap_ctx, dom_sid); sss_idmap_free_sid(idmap_ctx, new_sid); } END_TEST START_TEST(idmap_test_sid2bin_sid) { enum idmap_error_code err; size_t length; uint8_t *bin_sid = NULL; err = sss_idmap_sid_to_bin_sid(idmap_ctx, test_sid, &bin_sid, &length); fail_unless(err == IDMAP_SUCCESS, "Failed to convert SID string to binary sid."); fail_unless(length == test_bin_sid_length, "Size of binary SIDs do not match, got [%d], expected [%d]", length, test_bin_sid_length); fail_unless(memcmp(bin_sid, test_bin_sid, test_bin_sid_length) == 0, "Binary SIDs do not match"); sss_idmap_free_bin_sid(idmap_ctx, bin_sid); } END_TEST START_TEST(idmap_test_bin_sid2sid) { enum idmap_error_code err; char *sid = NULL; err = sss_idmap_bin_sid_to_sid(idmap_ctx, test_bin_sid, test_bin_sid_length, &sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert binary SID to SID string."); fail_unless(strcmp(sid, test_sid) == 0, "SID strings do not match, " "expected [%s], get [%s]", test_sid, sid); sss_idmap_free_sid(idmap_ctx, sid); } END_TEST START_TEST(idmap_test_smb_sid2dom_sid) { struct sss_dom_sid *dom_sid = NULL; enum idmap_error_code err; struct dom_sid *new_smb_sid = NULL; err = sss_idmap_smb_sid_to_dom_sid(idmap_ctx, &test_smb_sid, &dom_sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert samba dom_sid to struct sss_dom_sid."); err = sss_idmap_dom_sid_to_smb_sid(idmap_ctx, dom_sid, &new_smb_sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert struct sss_dom_sid to samba dom_sid."); fail_unless(memcmp(&test_smb_sid, new_smb_sid, sizeof(struct dom_sid)) == 0, "Samba dom_sid-s do not match."); sss_idmap_free_dom_sid(idmap_ctx, dom_sid); sss_idmap_free_smb_sid(idmap_ctx, new_smb_sid); } END_TEST START_TEST(idmap_test_smb_sid2bin_sid) { enum idmap_error_code err; size_t length; uint8_t *bin_sid = NULL; err = sss_idmap_smb_sid_to_bin_sid(idmap_ctx, &test_smb_sid, &bin_sid, &length); fail_unless(err == IDMAP_SUCCESS, "Failed to convert samba dom_sid to binary sid."); fail_unless(length == test_bin_sid_length, "Size of binary SIDs do not match, got [%d], expected [%d]", length, test_bin_sid_length); fail_unless(memcmp(bin_sid, test_bin_sid, test_bin_sid_length) == 0, "Binary SIDs do not match."); sss_idmap_free_bin_sid(idmap_ctx, bin_sid); } END_TEST START_TEST(idmap_test_bin_sid2smb_sid) { enum idmap_error_code err; struct dom_sid *smb_sid = NULL; err = sss_idmap_bin_sid_to_smb_sid(idmap_ctx, test_bin_sid, test_bin_sid_length, &smb_sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert binary sid to samba dom_sid."); fail_unless(memcmp(&test_smb_sid, smb_sid, sizeof(struct dom_sid)) == 0, "Samba dom_sid structs do not match."); sss_idmap_free_smb_sid(idmap_ctx, smb_sid); } END_TEST START_TEST(idmap_test_smb_sid2sid) { enum idmap_error_code err; char *sid = NULL; err = sss_idmap_smb_sid_to_sid(idmap_ctx, &test_smb_sid, &sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert samba dom_sid to sid string."); fail_unless(strcmp(sid, test_sid) == 0, "SID strings do not match, " "expected [%s], get [%s]", test_sid, sid); sss_idmap_free_sid(idmap_ctx, sid); } END_TEST START_TEST(idmap_test_sid2smb_sid) { enum idmap_error_code err; struct dom_sid *smb_sid = NULL; err = sss_idmap_sid_to_smb_sid(idmap_ctx, test_sid, &smb_sid); fail_unless(err == IDMAP_SUCCESS, "Failed to convert binary sid to samba dom_sid."); fail_unless(memcmp(&test_smb_sid, smb_sid, sizeof(struct dom_sid)) == 0, "Samba dom_sid structs do not match."); sss_idmap_free_smb_sid(idmap_ctx, smb_sid); } END_TEST Suite *idmap_test_suite (void) { Suite *s = suite_create ("IDMAP"); TCase *tc_init = tcase_create("IDMAP init tests"); tcase_add_checked_fixture(tc_init, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_test(tc_init, idmap_test_init_malloc); tcase_add_test(tc_init, idmap_test_init_talloc); tcase_add_test(tc_init, idmap_test_is_domain_sid); suite_add_tcase(s, tc_init); TCase *tc_dom = tcase_create("IDMAP domain tests"); tcase_add_checked_fixture(tc_dom, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_checked_fixture(tc_dom, idmap_ctx_setup, idmap_ctx_teardown); tcase_add_test(tc_dom, idmap_test_add_domain); tcase_add_test(tc_dom, idmap_test_add_domain_collisions); tcase_add_test(tc_dom, idmap_test_add_domain_collisions_ext_mapping); suite_add_tcase(s, tc_dom); TCase *tc_conv = tcase_create("IDMAP SID conversion tests"); tcase_add_checked_fixture(tc_conv, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_checked_fixture(tc_conv, idmap_ctx_setup, idmap_ctx_teardown); tcase_add_test(tc_conv, idmap_test_bin_sid2dom_sid); tcase_add_test(tc_conv, idmap_test_sid2dom_sid); tcase_add_test(tc_conv, idmap_test_sid2bin_sid); tcase_add_test(tc_conv, idmap_test_bin_sid2sid); tcase_add_test(tc_conv, idmap_test_smb_sid2dom_sid); tcase_add_test(tc_conv, idmap_test_smb_sid2bin_sid); tcase_add_test(tc_conv, idmap_test_bin_sid2smb_sid); tcase_add_test(tc_conv, idmap_test_smb_sid2sid); tcase_add_test(tc_conv, idmap_test_sid2smb_sid); tcase_add_test(tc_conv, idmap_test_large_and_too_large_sid); suite_add_tcase(s, tc_conv); TCase *tc_map = tcase_create("IDMAP mapping tests"); tcase_add_checked_fixture(tc_map, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_checked_fixture(tc_map, idmap_ctx_setup, idmap_ctx_teardown); tcase_add_checked_fixture(tc_map, idmap_add_domain_setup, NULL); tcase_add_test(tc_map, idmap_test_sid2uid); tcase_add_test(tc_map, idmap_test_bin_sid2uid); tcase_add_test(tc_map, idmap_test_dom_sid2uid); tcase_add_test(tc_map, idmap_test_uid2sid); tcase_add_test(tc_map, idmap_test_uid2dom_sid); tcase_add_test(tc_map, idmap_test_uid2bin_sid); suite_add_tcase(s, tc_map); /* Test secondary slices */ TCase *tc_map_ss = tcase_create("IDMAP mapping tests"); tcase_add_checked_fixture(tc_map_ss, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_checked_fixture(tc_map_ss, idmap_ctx_setup, idmap_ctx_teardown); tcase_add_checked_fixture(tc_map_ss, idmap_add_domain_with_sec_slices_setup, NULL); tcase_add_test(tc_map_ss, idmap_test_sid2uid_ss); tcase_add_test(tc_map_ss, idmap_test_uid2sid_ss); tcase_add_test(tc_map_ss, idmap_test_sid2uid_ext_sec_slices); suite_add_tcase(s, tc_map_ss); /* Test secondary slices - callback to store failed. */ TCase *tc_map_cb_fail = tcase_create("IDMAP mapping tests - store fail"); tcase_add_checked_fixture(tc_map_cb_fail, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_checked_fixture(tc_map_cb_fail, idmap_ctx_setup, idmap_ctx_teardown); tcase_add_checked_fixture(tc_map_cb_fail, idmap_add_domain_with_sec_slices_setup_cb_fail, NULL); tcase_add_test(tc_map_cb_fail, idmap_test_dyn_dom_store_cb_fail); suite_add_tcase(s, tc_map_cb_fail); /* Test secondary slices - callback to store passed. */ TCase *tc_map_cb_ok = tcase_create("IDMAP mapping tests"); tcase_add_checked_fixture(tc_map_cb_ok, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_checked_fixture(tc_map_cb_ok, idmap_ctx_setup, idmap_ctx_teardown); tcase_add_checked_fixture(tc_map_cb_ok, idmap_add_domain_with_sec_slices_setup_cb_ok, NULL); tcase_add_test(tc_map_cb_ok, idmap_test_dyn_dom_store_cb_ok); suite_add_tcase(s, tc_map_cb_ok); /* Test additional secondary slices */ TCase *tc_map_additional_secondary_slices = \ tcase_create("IDMAP additional secondary slices"); tcase_add_checked_fixture(tc_map_additional_secondary_slices, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_checked_fixture(tc_map_additional_secondary_slices, idmap_ctx_setup_additional_seconary_slices, idmap_ctx_teardown); tcase_add_checked_fixture(tc_map_additional_secondary_slices, idmap_add_domain_with_sec_slices_setup, NULL); tcase_add_test(tc_map_additional_secondary_slices, idmap_test_sid2uid_additional_secondary_slices); suite_add_tcase(s, tc_map_additional_secondary_slices); return s; } int main(int argc, const char *argv[]) { int number_failed; tests_set_cwd(); Suite *s = idmap_test_suite(); SRunner *sr = srunner_create(s); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed (sr); srunner_free (sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/krb5_proxy_check_test_data.conf0000644000000000000000000000007412703456111022416 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.353792608 sssd-1.13.4/src/tests/krb5_proxy_check_test_data.conf0000644002412700241270000000013012703456111024057 0ustar00jhrozekjhrozek00000000000000[realms] REALM = { kdc = hello } REALM_PROXY = { kdc = https://hello } sssd-1.13.4/src/tests/PaxHeaders.16287/check_and_open-tests.c0000644000000000000000000000007212703456111020500 xustar0030 atime=1460561751.655715644 28 ctime=1460561774.9117945 sssd-1.13.4/src/tests/check_and_open-tests.c0000644002412700241270000001655312703456111022163 0ustar00jhrozekjhrozek00000000000000/* SSSD Utilities tests check_and_open Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "tests/common.h" #define SUFFIX ".symlink" #define FILENAME_TEMPLATE "check_and_open-tests-XXXXXX" char *filename; uid_t uid; gid_t gid; mode_t mode; int fd; void setup_check_and_open(void) { int ret; mode_t old_umask; filename = strdup(FILENAME_TEMPLATE); fail_unless(filename != NULL, "strdup failed"); old_umask = umask(SSS_DFL_X_UMASK); ret = mkstemp(filename); umask(old_umask); fail_unless(ret != -1, "mkstemp failed [%d][%s]", errno, strerror(errno)); close(ret); uid = getuid(); gid = getgid(); mode = (S_IRUSR | S_IWUSR); fd = -1; } void teardown_check_and_open(void) { int ret; if (fd != -1) { ret = close(fd); fail_unless(ret == 0, "close failed [%d][%s]", errno, strerror(errno)); } fail_unless(filename != NULL, "unknown filename"); ret = unlink(filename); free(filename); fail_unless(ret == 0, "unlink failed [%d][%s]", errno, strerror(errno)); } START_TEST(test_wrong_filename) { int ret; ret = check_and_open_readonly("/bla/bla/bla", &fd, uid, gid, S_IFREG|mode, 0); fail_unless(ret == ENOENT, "check_and_open_readonly succeeded on non-existing file"); fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1"); } END_TEST START_TEST(test_symlink) { int ret; char *newpath; size_t newpath_length; newpath_length = strlen(filename) + strlen(SUFFIX) + 1; newpath = malloc((newpath_length) * sizeof(char)); fail_unless(newpath != NULL, "malloc failed"); ret = snprintf(newpath, newpath_length, "%s%s", filename, SUFFIX); fail_unless(ret == newpath_length - 1, "snprintf failed: expected [%d] got [%d]", newpath_length -1, ret); ret = symlink(filename, newpath); fail_unless(ret == 0, "symlink failed [%d][%s]", ret, strerror(errno)); ret = check_file(newpath, uid, gid, S_IFREG|mode, 0, NULL, false); unlink(newpath); fail_unless(ret == EINVAL, "check_and_open_readonly succeeded on symlink"); free(newpath); } END_TEST START_TEST(test_follow_symlink) { int ret; char *newpath; size_t newpath_length; newpath_length = strlen(filename) + strlen(SUFFIX) + 1; newpath = malloc((newpath_length) * sizeof(char)); fail_unless(newpath != NULL, "malloc failed"); ret = snprintf(newpath, newpath_length, "%s%s", filename, SUFFIX); fail_unless(ret == newpath_length - 1, "snprintf failed: expected [%d] got [%d]", newpath_length -1, ret); ret = symlink(filename, newpath); fail_unless(ret == 0, "symlink failed [%d][%s]", ret, strerror(errno)); ret = check_file(newpath, uid, gid, S_IFREG|mode, 0, NULL, true); unlink(newpath); fail_unless(ret == EOK, "check_and_open_readonly failed on symlink with follow=true"); free(newpath); } END_TEST START_TEST(test_not_regular_file) { int ret; ret = check_and_open_readonly("/dev/null", &fd, uid, gid, S_IFREG|mode, 0); fail_unless(ret == EINVAL, "check_and_open_readonly succeeded on non-regular file"); fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1"); } END_TEST START_TEST(test_wrong_uid) { int ret; ret = check_and_open_readonly(filename, &fd, uid+1, gid, S_IFREG|mode, 0); fail_unless(ret == EINVAL, "check_and_open_readonly succeeded with wrong uid"); fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1"); } END_TEST START_TEST(test_wrong_gid) { int ret; ret = check_and_open_readonly(filename, &fd, uid, gid+1, S_IFREG|mode, 0); fail_unless(ret == EINVAL, "check_and_open_readonly succeeded with wrong gid"); fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1"); } END_TEST START_TEST(test_wrong_permission) { int ret; ret = check_and_open_readonly(filename, &fd, uid, gid, S_IFREG|mode|S_IWOTH, 0); fail_unless(ret == EINVAL, "check_and_open_readonly succeeded with wrong mode"); fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1"); } END_TEST START_TEST(test_ok) { int ret; ret = check_and_open_readonly(filename, &fd, uid, gid, S_IFREG|mode, 0); fail_unless(ret == EOK, "check_and_open_readonly failed"); fail_unless(fd >= 0, "check_and_open_readonly returned illegal file descriptor"); } END_TEST START_TEST(test_write) { int ret; ssize_t size; errno_t my_errno; ret = check_and_open_readonly(filename, &fd, uid, gid, S_IFREG|mode, 0); fail_unless(ret == EOK, "check_and_open_readonly failed"); fail_unless(fd >= 0, "check_and_open_readonly returned illegal file descriptor"); size = write(fd, "abc", 3); my_errno = errno; fail_unless(size == -1, "check_and_open_readonly file is not readonly"); fail_unless(my_errno == EBADF, "write failed for other reason than readonly"); } END_TEST Suite *check_and_open_suite (void) { Suite *s = suite_create ("check_and_open"); TCase *tc_check_and_open_readonly = tcase_create ("check_and_open_readonly"); tcase_add_checked_fixture (tc_check_and_open_readonly, setup_check_and_open, teardown_check_and_open); tcase_add_test (tc_check_and_open_readonly, test_wrong_filename); tcase_add_test (tc_check_and_open_readonly, test_not_regular_file); tcase_add_test (tc_check_and_open_readonly, test_symlink); tcase_add_test (tc_check_and_open_readonly, test_follow_symlink); tcase_add_test (tc_check_and_open_readonly, test_wrong_uid); tcase_add_test (tc_check_and_open_readonly, test_wrong_gid); tcase_add_test (tc_check_and_open_readonly, test_wrong_permission); tcase_add_test (tc_check_and_open_readonly, test_ok); tcase_add_test (tc_check_and_open_readonly, test_write); suite_add_tcase (s, tc_check_and_open_readonly); return s; } int main(void) { int number_failed; tests_set_cwd(); Suite *s = check_and_open_suite (); SRunner *sr = srunner_create (s); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed (sr); srunner_free (sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/sbus_codegen_tests.xml0000644000000000000000000000007412703456111020662 xustar0030 atime=1460561751.658715654 30 ctime=1460561775.057794995 sssd-1.13.4/src/tests/sbus_codegen_tests.xml0000755002412700241270000001542012703456111022336 0ustar00jhrozekjhrozek00000000000000 sssd-1.13.4/src/tests/PaxHeaders.16287/pysss_murmur-test.py2.sh0000644000000000000000000000007412703456111021070 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.350792598 sssd-1.13.4/src/tests/pysss_murmur-test.py2.sh0000755002412700241270000000016612703456111022545 0ustar00jhrozekjhrozek00000000000000#!/bin/sh SCRIPT=$(readlink -f "$0") SCRIPT_PATH=$(dirname "$SCRIPT") exec python2 $SCRIPT_PATH/pysss_murmur-test.py sssd-1.13.4/src/tests/PaxHeaders.16287/ipa_hbac-tests.c0000644000000000000000000000007412703456111017310 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.933794575 sssd-1.13.4/src/tests/ipa_hbac-tests.c0000644002412700241270000006773712703456111021003 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "tests/common_check.h" #include "providers/ipa/ipa_hbac.h" #define HBAC_TEST_USER "testuser" #define HBAC_TEST_INVALID_USER "nosuchuser" #define HBAC_TEST_GROUP1 "testgroup1" #define HBAC_TEST_GROUP2 "testgroup2" #define HBAC_TEST_INVALID_GROUP "nosuchgroup" #define HBAC_TEST_SERVICE "testservice" #define HBAC_TEST_INVALID_SERVICE "nosuchservice" #define HBAC_TEST_SERVICEGROUP1 "login_services" #define HBAC_TEST_SERVICEGROUP2 "all_services" #define HBAC_TEST_INVALID_SERVICEGROUP "nosuchservicegroup" #define HBAC_TEST_SRCHOST "client.example.com" #define HBAC_TEST_INVALID_SRCHOST "nosuchsrchost" #define HBAC_TEST_SRCHOSTGROUP1 "site_hosts" #define HBAC_TEST_SRCHOSTGROUP2 "corp_hosts" #define HBAC_TEST_INVALID_SRCHOSTGROUP "nosuchsrchostgroup" /* These don't make sense for a user/group/service but they do the job and * every one is from a different codepage */ /* Latin Extended A - "Czech" */ const uint8_t user_utf8_lowcase[] = { 0xC4, 0x8D, 'e', 'c', 'h', 0x0 }; const uint8_t user_utf8_upcase[] = { 0xC4, 0x8C, 'e', 'c', 'h', 0x0 }; const uint8_t user_utf8_lowcase_neg[] = { 0xC4, 0x8E, 'e', 'c', 'h', 0x0 }; /* Latin 1 Supplement - "Munchen" */ const uint8_t service_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 }; const uint8_t service_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 }; /* Greek - "AlphaBetaGamma" */ const uint8_t srchost_utf8_lowcase[] = { 0xCE, 0xB1, 0xCE, 0xB2, 0xCE, 0xB3, 0x0 }; const uint8_t srchost_utf8_upcase[] = { 0xCE, 0x91, 0xCE, 0x92, 0xCE, 0x93, 0x0 }; /* Turkish "capital I" and "dotless i" */ const uint8_t user_lowcase_tr[] = { 0xC4, 0xB1, 0x0 }; const uint8_t user_upcase_tr[] = { 0x49, 0x0 }; static void get_allow_all_rule(TALLOC_CTX *mem_ctx, struct hbac_rule **allow_rule) { struct hbac_rule *rule; /* Create a rule that ALLOWs all services, users and * remote hosts. */ rule = talloc_zero(mem_ctx, struct hbac_rule); fail_if (rule == NULL); rule->enabled = true; rule->services = talloc_zero(rule, struct hbac_rule_element); fail_if (rule->services == NULL); rule->services->category = HBAC_CATEGORY_ALL; rule->services->names = NULL; rule->services->groups = NULL; rule->users = talloc_zero(rule, struct hbac_rule_element); fail_if (rule->users == NULL); rule->users->category = HBAC_CATEGORY_ALL; rule->users->names = NULL; rule->users->groups = NULL; rule->targethosts = talloc_zero(rule, struct hbac_rule_element); fail_if (rule->targethosts == NULL); rule->targethosts->category = HBAC_CATEGORY_ALL; rule->targethosts->names = NULL; rule->targethosts->groups = NULL; rule->srchosts = talloc_zero(rule, struct hbac_rule_element); fail_if (rule->srchosts == NULL); rule->srchosts->category = HBAC_CATEGORY_ALL; rule->srchosts->names = NULL; rule->srchosts->groups = NULL; *allow_rule = rule; } static void get_test_user(TALLOC_CTX *mem_ctx, struct hbac_request_element **user) { struct hbac_request_element *new_user; new_user = talloc_zero(mem_ctx, struct hbac_request_element); fail_if (new_user == NULL); new_user->name = talloc_strdup(new_user, HBAC_TEST_USER); fail_if(new_user->name == NULL); new_user->groups = talloc_array(new_user, const char *, 3); fail_if(new_user->groups == NULL); new_user->groups[0] = talloc_strdup(new_user->groups, HBAC_TEST_GROUP1); fail_if(new_user->groups[0] == NULL); new_user->groups[1] = talloc_strdup(new_user->groups, HBAC_TEST_GROUP2); fail_if(new_user->groups[1] == NULL); new_user->groups[2] = NULL; *user = new_user; } static void get_test_service(TALLOC_CTX *mem_ctx, struct hbac_request_element **service) { struct hbac_request_element *new_service; new_service = talloc_zero(mem_ctx, struct hbac_request_element); fail_if (new_service == NULL); new_service->name = talloc_strdup(new_service, HBAC_TEST_SERVICE); fail_if(new_service->name == NULL); new_service->groups = talloc_array(new_service, const char *, 3); fail_if(new_service->groups == NULL); new_service->groups[0] = talloc_strdup(new_service->groups, HBAC_TEST_SERVICEGROUP1); fail_if(new_service->groups[0] == NULL); new_service->groups[1] = talloc_strdup(new_service->groups, HBAC_TEST_SERVICEGROUP2); fail_if(new_service->groups[1] == NULL); new_service->groups[2] = NULL; *service = new_service; } static void get_test_srchost(TALLOC_CTX *mem_ctx, struct hbac_request_element **srchost) { struct hbac_request_element *new_srchost; new_srchost = talloc_zero(mem_ctx, struct hbac_request_element); fail_if (new_srchost == NULL); new_srchost->name = talloc_strdup(new_srchost, HBAC_TEST_SRCHOST); fail_if(new_srchost->name == NULL); new_srchost->groups = talloc_array(new_srchost, const char *, 3); fail_if(new_srchost->groups == NULL); new_srchost->groups[0] = talloc_strdup(new_srchost->groups, HBAC_TEST_SRCHOSTGROUP1); fail_if(new_srchost->groups[0] == NULL); new_srchost->groups[1] = talloc_strdup(new_srchost->groups, HBAC_TEST_SRCHOSTGROUP2); fail_if(new_srchost->groups[1] == NULL); new_srchost->groups[2] = NULL; *srchost = new_srchost; } START_TEST(ipa_hbac_test_allow_all) { enum hbac_eval_result result; TALLOC_CTX *test_ctx; struct hbac_rule **rules; struct hbac_eval_req *eval_req; struct hbac_info *info = NULL; bool is_valid; uint32_t missing_attrs; test_ctx = talloc_new(global_talloc_context); /* Create a request */ eval_req = talloc_zero(test_ctx, struct hbac_eval_req); fail_if (eval_req == NULL); get_test_user(eval_req, &eval_req->user); get_test_service(eval_req, &eval_req->service); get_test_srchost(eval_req, &eval_req->srchost); /* Create the rules to evaluate against */ rules = talloc_array(test_ctx, struct hbac_rule *, 2); fail_if (rules == NULL); get_allow_all_rule(rules, &rules[0]); rules[0]->name = talloc_strdup(rules[0], "Allow All"); fail_if(rules[0]->name == NULL); rules[1] = NULL; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_ALLOW, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_ALLOW), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; talloc_free(test_ctx); } END_TEST START_TEST(ipa_hbac_test_allow_user) { enum hbac_eval_result result; TALLOC_CTX *test_ctx; struct hbac_rule **rules; struct hbac_eval_req *eval_req; struct hbac_info *info = NULL; bool is_valid; uint32_t missing_attrs; test_ctx = talloc_new(global_talloc_context); /* Create a request */ eval_req = talloc_zero(test_ctx, struct hbac_eval_req); fail_if (eval_req == NULL); get_test_user(eval_req, &eval_req->user); get_test_service(eval_req, &eval_req->service); get_test_srchost(eval_req, &eval_req->srchost); /* Create the rules to evaluate against */ rules = talloc_array(test_ctx, struct hbac_rule *, 2); fail_if (rules == NULL); get_allow_all_rule(rules, &rules[0]); /* Modify the rule to allow only a specific user */ rules[0]->name = talloc_strdup(rules[0], "Allow user"); fail_if(rules[0]->name == NULL); rules[0]->users->category = HBAC_CATEGORY_NULL; rules[0]->users->names = talloc_array(rules[0], const char *, 2); fail_if(rules[0]->users->names == NULL); rules[0]->users->names[0] = HBAC_TEST_USER; rules[0]->users->names[1] = NULL; rules[1] = NULL; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_ALLOW, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_ALLOW), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; /* Negative test */ rules[0]->users->names[0] = HBAC_TEST_INVALID_USER; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_DENY, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_DENY), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; talloc_free(test_ctx); } END_TEST START_TEST(ipa_hbac_test_allow_utf8) { enum hbac_eval_result result; TALLOC_CTX *test_ctx; struct hbac_rule **rules; struct hbac_eval_req *eval_req; struct hbac_info *info = NULL; bool is_valid; uint32_t missing_attrs; test_ctx = talloc_new(global_talloc_context); /* Create a request */ eval_req = talloc_zero(test_ctx, struct hbac_eval_req); fail_if (eval_req == NULL); get_test_user(eval_req, &eval_req->user); get_test_service(eval_req, &eval_req->service); get_test_srchost(eval_req, &eval_req->srchost); /* Override the with UTF8 values */ eval_req->user->name = (const char *) &user_utf8_lowcase; eval_req->srchost->name = (const char *) &srchost_utf8_lowcase; eval_req->service->name = (const char *) &service_utf8_lowcase; /* Create the rules to evaluate against */ rules = talloc_array(test_ctx, struct hbac_rule *, 2); fail_if (rules == NULL); get_allow_all_rule(rules, &rules[0]); rules[0]->name = talloc_strdup(rules[0], "Allow user"); fail_if(rules[0]->name == NULL); rules[0]->users->category = HBAC_CATEGORY_NULL; /* Modify the rule to allow only a specific user */ rules[0]->users->names = talloc_array(rules[0], const char *, 2); fail_if(rules[0]->users->names == NULL); rules[0]->users->names[0] = (const char *) &user_utf8_upcase; rules[0]->users->names[1] = NULL; /* Modify the rule to allow only a specific service */ rules[0]->services->category = HBAC_CATEGORY_NULL; rules[0]->services->names = talloc_array(rules[0], const char *, 2); fail_if(rules[0]->services->names == NULL); rules[0]->services->names[0] = (const char *) &service_utf8_upcase; rules[0]->services->names[1] = NULL; /* Modify the rule to allow only a specific service */ rules[0]->srchosts->category = HBAC_CATEGORY_NULL; rules[0]->srchosts->names = talloc_array(rules[0], const char *, 2); fail_if(rules[0]->services->names == NULL); rules[0]->srchosts->names[0] = (const char *) &srchost_utf8_upcase; rules[0]->services->names[1] = NULL; rules[1] = NULL; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_ALLOW, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_ALLOW), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; /* Negative test - a different letter */ rules[0]->users->names[0] = (const char *) &user_utf8_lowcase_neg; /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_DENY, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_DENY), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; /* Negative test - Turkish dotless i. We cannot know that capital I * casefolds into dotless i unless we know the language is Turkish */ eval_req->user->name = (const char *) &user_lowcase_tr; rules[0]->users->names[0] = (const char *) &user_upcase_tr; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_DENY, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_DENY), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; talloc_free(test_ctx); } END_TEST START_TEST(ipa_hbac_test_allow_group) { enum hbac_eval_result result; TALLOC_CTX *test_ctx; struct hbac_rule **rules; struct hbac_eval_req *eval_req; struct hbac_info *info = NULL; bool is_valid; uint32_t missing_attrs; test_ctx = talloc_new(global_talloc_context); /* Create a request */ eval_req = talloc_zero(test_ctx, struct hbac_eval_req); fail_if (eval_req == NULL); get_test_user(eval_req, &eval_req->user); get_test_service(eval_req, &eval_req->service); get_test_srchost(eval_req, &eval_req->srchost); /* Create the rules to evaluate against */ rules = talloc_array(test_ctx, struct hbac_rule *, 2); fail_if (rules == NULL); get_allow_all_rule(rules, &rules[0]); /* Modify the rule to allow only a group of users */ rules[0]->name = talloc_strdup(rules[0], "Allow group"); fail_if(rules[0]->name == NULL); rules[0]->users->category = HBAC_CATEGORY_NULL; rules[0]->users->names = NULL; rules[0]->users->groups = talloc_array(rules[0], const char *, 2); fail_if(rules[0]->users->groups == NULL); rules[0]->users->groups[0] = HBAC_TEST_GROUP1; rules[0]->users->groups[1] = NULL; rules[1] = NULL; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_ALLOW, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_ALLOW), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; /* Negative test */ rules[0]->users->groups[0] = HBAC_TEST_INVALID_GROUP; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_DENY, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_DENY), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; talloc_free(test_ctx); } END_TEST START_TEST(ipa_hbac_test_allow_svc) { enum hbac_eval_result result; TALLOC_CTX *test_ctx; struct hbac_rule **rules; struct hbac_eval_req *eval_req; struct hbac_info *info = NULL; bool is_valid; uint32_t missing_attrs; test_ctx = talloc_new(global_talloc_context); /* Create a request */ eval_req = talloc_zero(test_ctx, struct hbac_eval_req); fail_if (eval_req == NULL); get_test_user(eval_req, &eval_req->user); get_test_service(eval_req, &eval_req->service); get_test_srchost(eval_req, &eval_req->srchost); /* Create the rules to evaluate against */ rules = talloc_array(test_ctx, struct hbac_rule *, 2); fail_if (rules == NULL); get_allow_all_rule(rules, &rules[0]); /* Modify the rule to allow only a specific service */ rules[0]->name = talloc_strdup(rules[0], "Allow service"); fail_if(rules[0]->name == NULL); rules[0]->services->category = HBAC_CATEGORY_NULL; rules[0]->services->names = talloc_array(rules[0], const char *, 2); fail_if(rules[0]->services->names == NULL); rules[0]->services->names[0] = HBAC_TEST_SERVICE; rules[0]->services->names[1] = NULL; rules[1] = NULL; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_ALLOW, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_ALLOW), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; /* Negative test */ rules[0]->services->names[0] = HBAC_TEST_INVALID_SERVICE; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_DENY, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_DENY), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; talloc_free(test_ctx); } END_TEST START_TEST(ipa_hbac_test_allow_svcgroup) { enum hbac_eval_result result; TALLOC_CTX *test_ctx; struct hbac_rule **rules; struct hbac_eval_req *eval_req; struct hbac_info *info = NULL; bool is_valid; uint32_t missing_attrs; test_ctx = talloc_new(global_talloc_context); /* Create a request */ eval_req = talloc_zero(test_ctx, struct hbac_eval_req); fail_if (eval_req == NULL); get_test_user(eval_req, &eval_req->user); get_test_service(eval_req, &eval_req->service); get_test_srchost(eval_req, &eval_req->srchost); /* Create the rules to evaluate against */ rules = talloc_array(test_ctx, struct hbac_rule *, 2); fail_if (rules == NULL); get_allow_all_rule(rules, &rules[0]); /* Modify the rule to allow only a group of users */ rules[0]->name = talloc_strdup(rules[0], "Allow servicegroup"); fail_if(rules[0]->name == NULL); rules[0]->services->category = HBAC_CATEGORY_NULL; rules[0]->services->names = NULL; rules[0]->services->groups = talloc_array(rules[0], const char *, 2); fail_if(rules[0]->services->groups == NULL); rules[0]->services->groups[0] = HBAC_TEST_SERVICEGROUP1; rules[0]->services->groups[1] = NULL; rules[1] = NULL; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_ALLOW, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_ALLOW), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; /* Negative test */ rules[0]->services->groups[0] = HBAC_TEST_INVALID_SERVICEGROUP; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_DENY, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_DENY), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; talloc_free(test_ctx); } END_TEST START_TEST(ipa_hbac_test_allow_srchost) { enum hbac_eval_result result; TALLOC_CTX *test_ctx; struct hbac_rule **rules; struct hbac_eval_req *eval_req; struct hbac_info *info = NULL; bool is_valid; uint32_t missing_attrs; test_ctx = talloc_new(global_talloc_context); /* Create a request */ eval_req = talloc_zero(test_ctx, struct hbac_eval_req); fail_if (eval_req == NULL); get_test_user(eval_req, &eval_req->user); get_test_service(eval_req, &eval_req->service); get_test_srchost(eval_req, &eval_req->srchost); /* Create the rules to evaluate against */ rules = talloc_array(test_ctx, struct hbac_rule *, 2); fail_if (rules == NULL); get_allow_all_rule(rules, &rules[0]); /* Modify the rule to allow only a specific service */ rules[0]->name = talloc_strdup(rules[0], "Allow srchost"); fail_if(rules[0]->name == NULL); rules[0]->srchosts->category = HBAC_CATEGORY_NULL; rules[0]->srchosts->names = talloc_array(rules[0], const char *, 2); fail_if(rules[0]->srchosts->names == NULL); rules[0]->srchosts->names[0] = HBAC_TEST_SRCHOST; rules[0]->srchosts->names[1] = NULL; rules[1] = NULL; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_ALLOW, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_ALLOW), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; /* Negative test */ rules[0]->srchosts->names[0] = HBAC_TEST_INVALID_SRCHOST; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_DENY, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_DENY), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; talloc_free(test_ctx); } END_TEST START_TEST(ipa_hbac_test_allow_srchostgroup) { enum hbac_eval_result result; TALLOC_CTX *test_ctx; struct hbac_rule **rules; struct hbac_eval_req *eval_req; struct hbac_info *info = NULL; bool is_valid; uint32_t missing_attrs; test_ctx = talloc_new(global_talloc_context); /* Create a request */ eval_req = talloc_zero(test_ctx, struct hbac_eval_req); fail_if (eval_req == NULL); get_test_user(eval_req, &eval_req->user); get_test_service(eval_req, &eval_req->service); get_test_srchost(eval_req, &eval_req->srchost); /* Create the rules to evaluate against */ rules = talloc_array(test_ctx, struct hbac_rule *, 2); fail_if (rules == NULL); get_allow_all_rule(rules, &rules[0]); /* Modify the rule to allow only a group of users */ rules[0]->name = talloc_strdup(rules[0], "Allow srchostgroup"); fail_if(rules[0]->name == NULL); rules[0]->srchosts->category = HBAC_CATEGORY_NULL; rules[0]->srchosts->names = NULL; rules[0]->srchosts->groups = talloc_array(rules[0], const char *, 2); fail_if(rules[0]->srchosts->groups == NULL); rules[0]->srchosts->groups[0] = HBAC_TEST_SRCHOSTGROUP1; rules[0]->srchosts->groups[1] = NULL; rules[1] = NULL; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_ALLOW, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_ALLOW), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; /* Negative test */ rules[0]->srchosts->groups[0] = HBAC_TEST_INVALID_SRCHOSTGROUP; /* Validate this rule */ is_valid = hbac_rule_is_complete(rules[0], &missing_attrs); fail_unless(is_valid); fail_unless(missing_attrs == 0); /* Evaluate the rules */ result = hbac_evaluate(rules, eval_req, &info); fail_unless(result == HBAC_EVAL_DENY, "Expected [%s], got [%s]; " "Error: [%s]", hbac_result_string(HBAC_EVAL_DENY), hbac_result_string(result), info ? hbac_error_string(info->code):"Unknown"); hbac_free_info(info); info = NULL; talloc_free(test_ctx); } END_TEST START_TEST(ipa_hbac_test_incomplete) { TALLOC_CTX *test_ctx; struct hbac_rule *rule; bool is_valid; uint32_t missing_attrs; test_ctx = talloc_new(global_talloc_context); rule = talloc_zero(test_ctx, struct hbac_rule); /* Validate this rule */ is_valid = hbac_rule_is_complete(rule, &missing_attrs); fail_if(is_valid); fail_unless(missing_attrs | HBAC_RULE_ELEMENT_USERS); fail_unless(missing_attrs | HBAC_RULE_ELEMENT_SERVICES); fail_unless(missing_attrs | HBAC_RULE_ELEMENT_TARGETHOSTS); fail_unless(missing_attrs | HBAC_RULE_ELEMENT_SOURCEHOSTS); talloc_free(test_ctx); } END_TEST Suite *hbac_test_suite (void) { Suite *s = suite_create ("HBAC"); TCase *tc_hbac = tcase_create("HBAC_rules"); tcase_add_checked_fixture(tc_hbac, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_test(tc_hbac, ipa_hbac_test_allow_all); tcase_add_test(tc_hbac, ipa_hbac_test_allow_user); tcase_add_test(tc_hbac, ipa_hbac_test_allow_group); tcase_add_test(tc_hbac, ipa_hbac_test_allow_svc); tcase_add_test(tc_hbac, ipa_hbac_test_allow_svcgroup); tcase_add_test(tc_hbac, ipa_hbac_test_allow_srchost); tcase_add_test(tc_hbac, ipa_hbac_test_allow_srchostgroup); tcase_add_test(tc_hbac, ipa_hbac_test_allow_utf8); tcase_add_test(tc_hbac, ipa_hbac_test_incomplete); suite_add_tcase(s, tc_hbac); return s; } int main(int argc, const char *argv[]) { int number_failed; tests_set_cwd(); Suite *s = hbac_test_suite(); SRunner *sr = srunner_create(s); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed (sr); srunner_free (sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/krb5_utils-tests.c0000644000000000000000000000007412703456111017645 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.936794585 sssd-1.13.4/src/tests/krb5_utils-tests.c0000644002412700241270000006501312703456111021321 0ustar00jhrozekjhrozek00000000000000/* SSSD Kerberos 5 Backend Module -- Utilities tests Authors: Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "providers/krb5/krb5_utils.h" #include "providers/krb5/krb5_ccache.h" #include "providers/krb5/krb5_auth.h" #include "util/sss_utf8.h" #include "tests/common.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define BASE "/abc/def" #define FILENAME "ghi" #define USERNAME "testuser" #define UID "12345" #define PRINCIPAL_NAME "testuser@EXAMPLE.COM" #define REALM "REALM.ORG" #define HOME_DIRECTORY "/home/testuser" #define CCACHE_DIR "/var/tmp" #define PID "4321" extern struct dp_option default_krb5_opts[]; TALLOC_CTX *tmp_ctx = NULL; struct krb5child_req *kr; #define RMDIR(__dir__) do { \ ret = rmdir(__dir__); \ fail_unless(ret == EOK, "rmdir [%s] failed, [%d][%s].", __dir__, \ errno, strerror(errno)); \ } while(0) void setup_create_dir(void) { fail_unless(tmp_ctx == NULL, "Talloc context already initialized."); tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "Cannot create talloc context."); } void teardown_create_dir(void) { int ret; fail_unless(tmp_ctx != NULL, "Talloc context already freed."); ret = talloc_free(tmp_ctx); tmp_ctx = NULL; fail_unless(ret == 0, "Cannot free talloc context."); } static void check_dir(const char *dirname, uid_t uid, gid_t gid, mode_t mode) { struct stat stat_buf; int ret; ret = stat(dirname, &stat_buf); fail_unless(ret == EOK, "stat failed [%d][%s].", errno, strerror(errno)); fail_unless(S_ISDIR(stat_buf.st_mode), "[%s] is not a directory.", dirname); fail_unless(stat_buf.st_uid == uid, "uid does not match, " "expected [%d], got [%d].", uid, stat_buf.st_uid); fail_unless(stat_buf.st_gid == gid, "gid does not match, " "expected [%d], got [%d].", gid, stat_buf.st_gid); fail_unless((stat_buf.st_mode & ~S_IFMT) == mode, "mode of [%s] does not match, " "expected [%o], got [%o].", dirname, mode, (stat_buf.st_mode & ~S_IFMT)); } START_TEST(test_private_ccache_dir_in_user_dir) { int ret; char *cwd; char *user_dir; char *dn1; char *dn2; char *dn3; char *filename; uid_t uid = getuid(); gid_t gid = getgid(); if (uid == 0) { uid = 12345; gid = 12345; } cwd = getcwd(NULL, 0); fail_unless(cwd != NULL, "getcwd failed."); user_dir = talloc_asprintf(tmp_ctx, "%s/%s/user", cwd, TESTS_PATH); free(cwd); fail_unless(user_dir != NULL, "talloc_asprintf failed."); ret = mkdir(user_dir, 0700); fail_unless(ret == EOK, "mkdir failed."); ret = chown(user_dir, uid, gid); fail_unless(ret == EOK, "chown failed."); dn1 = talloc_asprintf(tmp_ctx, "%s/a", user_dir); fail_unless(dn1 != NULL, "talloc_asprintf failed."); dn2 = talloc_asprintf(tmp_ctx, "%s/b", dn1); fail_unless(dn2 != NULL, "talloc_asprintf failed."); dn3 = talloc_asprintf(tmp_ctx, "%s/c", dn2); fail_unless(dn3 != NULL, "talloc_asprintf failed."); filename = talloc_asprintf(tmp_ctx, "%s/ccfile", dn3); fail_unless(filename != NULL, "talloc_asprintf failed."); ret = chmod(user_dir, 0600); fail_unless(ret == EOK, "chmod failed."); ret = sss_krb5_precreate_ccache(filename, uid, gid); fail_unless(ret == EINVAL, "sss_krb5_precreate_ccache does not return EINVAL " "while x-bit is missing."); ret = chmod(user_dir, 0700); fail_unless(ret == EOK, "chmod failed."); ret = sss_krb5_precreate_ccache(filename, uid, gid); fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed."); check_dir(dn3, uid, gid, 0700); RMDIR(dn3); check_dir(dn2, uid, gid, 0700); RMDIR(dn2); check_dir(dn1, uid, gid, 0700); RMDIR(dn1); RMDIR(user_dir); } END_TEST START_TEST(test_private_ccache_dir_in_wrong_user_dir) { int ret; char *cwd; char *dirname; char *subdirname; char *filename; fail_unless(getuid() == 0, "This test must be run as root."); cwd = getcwd(NULL, 0); fail_unless(cwd != NULL, "getcwd failed."); dirname = talloc_asprintf(tmp_ctx, "%s/%s/priv_ccdir", cwd, TESTS_PATH); free(cwd); fail_unless(dirname != NULL, "talloc_asprintf failed."); ret = mkdir(dirname, 0700); fail_unless(ret == EOK, "mkdir failed.\n"); ret = chown(dirname, 12346, 12346); fail_unless(ret == EOK, "chown failed.\n"); subdirname = talloc_asprintf(tmp_ctx, "%s/subdir", dirname); fail_unless(subdirname != NULL, "talloc_asprintf failed."); filename = talloc_asprintf(tmp_ctx, "%s/ccfile", subdirname); fail_unless(filename != NULL, "talloc_asprintf failed."); ret = sss_krb5_precreate_ccache(filename, 12345, 12345); fail_unless(ret == EINVAL, "Creating private ccache dir in wrong user " "dir does not failed with EINVAL."); RMDIR(dirname); } END_TEST START_TEST(test_illegal_patterns) { char *cwd; char *dirname; char *filename; pcre *illegal_re; const char *errstr; int errval; int errpos; char *result = NULL; illegal_re = pcre_compile2(ILLEGAL_PATH_PATTERN, 0, &errval, &errstr, &errpos, NULL); fail_unless(illegal_re != NULL, "Invalid Regular Expression pattern at " " position %d. (Error: %d [%s])\n", errpos, errval, errstr); cwd = getcwd(NULL, 0); fail_unless(cwd != NULL, "getcwd failed."); dirname = talloc_asprintf(tmp_ctx, "%s/%s/priv_ccdir", cwd, TESTS_PATH); free(cwd); fail_unless(dirname != NULL, "talloc_asprintf failed."); result = expand_ccname_template(tmp_ctx, kr, "abc/./ccfile", illegal_re, true, true); fail_unless(result == NULL, "expand_ccname_template allowed relative path\n"); filename = talloc_asprintf(tmp_ctx, "%s/abc/./ccfile", dirname); fail_unless(filename != NULL, "talloc_asprintf failed."); result = expand_ccname_template(tmp_ctx, kr, filename, illegal_re, true, true); fail_unless(result == NULL, "expand_ccname_template allowed " "illegal pattern '/./'\n"); filename = talloc_asprintf(tmp_ctx, "%s/abc/../ccfile", dirname); fail_unless(filename != NULL, "talloc_asprintf failed."); result = expand_ccname_template(tmp_ctx, kr, filename, illegal_re, true, true); fail_unless(result == NULL, "expand_ccname_template allowed " "illegal pattern '/../' in filename [%s].", filename); filename = talloc_asprintf(tmp_ctx, "%s/abc//ccfile", dirname); fail_unless(filename != NULL, "talloc_asprintf failed."); result = expand_ccname_template(tmp_ctx, kr, filename, illegal_re, true, true); fail_unless(result == NULL, "expand_ccname_template allowed " "illegal pattern '//' in filename [%s].", filename); pcre_free(illegal_re); } END_TEST START_TEST(test_cc_dir_create) { char *residual; char *dirname; char *cwd; uid_t uid = getuid(); gid_t gid = getgid(); errno_t ret; cwd = getcwd(NULL, 0); fail_unless(cwd != NULL, "getcwd failed."); dirname = talloc_asprintf(tmp_ctx, "%s/%s/user_dir", cwd, TESTS_PATH); fail_unless(dirname != NULL, "talloc_asprintf failed."); residual = talloc_asprintf(tmp_ctx, "DIR:%s/%s", dirname, "ccdir"); fail_unless(residual != NULL, "talloc_asprintf failed."); ret = sss_krb5_precreate_ccache(residual, uid, gid); fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed\n"); ret = rmdir(dirname); if (ret < 0) ret = errno; fail_unless(ret == 0, "Cannot remove %s: %s\n", dirname, strerror(ret)); talloc_free(residual); dirname = talloc_asprintf(tmp_ctx, "%s/%s/user_dir2", cwd, TESTS_PATH); fail_unless(dirname != NULL, "talloc_asprintf failed."); residual = talloc_asprintf(tmp_ctx, "DIR:%s/%s", dirname, "ccdir/"); fail_unless(residual != NULL, "talloc_asprintf failed."); ret = sss_krb5_precreate_ccache(residual, uid, gid); fail_unless(ret == EOK, "sss_krb5_precreate_ccache failed\n"); ret = rmdir(dirname); if (ret < 0) ret = errno; fail_unless(ret == 0, "Cannot remove %s: %s\n", dirname, strerror(ret)); talloc_free(residual); free(cwd); } END_TEST void setup_talloc_context(void) { int ret; int i; struct pam_data *pd; struct krb5_ctx *krb5_ctx; fail_unless(tmp_ctx == NULL, "Talloc context already initialized."); tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "Cannot create talloc context."); kr = talloc_zero(tmp_ctx, struct krb5child_req); fail_unless(kr != NULL, "Cannot create krb5child_req structure."); pd = create_pam_data(tmp_ctx); fail_unless(pd != NULL, "Cannot create pam_data structure."); krb5_ctx = talloc_zero(tmp_ctx, struct krb5_ctx); fail_unless(pd != NULL, "Cannot create krb5_ctx structure."); pd->user = discard_const(USERNAME); kr->uid = atoi(UID); kr->upn = discard_const(PRINCIPAL_NAME); pd->cli_pid = atoi(PID); krb5_ctx->opts = talloc_zero_array(tmp_ctx, struct dp_option, KRB5_OPTS); fail_unless(krb5_ctx->opts != NULL, "Cannot created options."); for (i = 0; i < KRB5_OPTS; i++) { krb5_ctx->opts[i].opt_name = default_krb5_opts[i].opt_name; krb5_ctx->opts[i].type = default_krb5_opts[i].type; krb5_ctx->opts[i].def_val = default_krb5_opts[i].def_val; } ret = dp_opt_set_string(krb5_ctx->opts, KRB5_REALM, REALM); fail_unless(ret == EOK, "Failed to set Realm"); ret = dp_opt_set_string(krb5_ctx->opts, KRB5_CCACHEDIR, CCACHE_DIR); fail_unless(ret == EOK, "Failed to set Ccache dir"); kr->homedir = HOME_DIRECTORY; kr->pd = pd; kr->krb5_ctx = krb5_ctx; } void free_talloc_context(void) { int ret; fail_unless(tmp_ctx != NULL, "Talloc context already freed."); ret = talloc_free(tmp_ctx); tmp_ctx = NULL; fail_unless(ret == 0, "Cannot free talloc context."); } static void do_test(const char *file_template, const char *dir_template, const char *expected) { char *result; int ret; ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR, dir_template); fail_unless(ret == EOK, "Failed to set Ccache dir"); result = expand_ccname_template(tmp_ctx, kr, file_template, NULL, true, true); fail_unless(result != NULL, "Cannot expand template [%s].", file_template); fail_unless(strcmp(result, expected) == 0, "Expansion failed, result [%s], expected [%s].", result, expected); } START_TEST(test_multiple_substitutions) { do_test(BASE"_%u_%U_%u", CCACHE_DIR, BASE"_"USERNAME"_"UID"_"USERNAME); do_test("%d/"FILENAME, BASE"_%u_%U_%u", BASE"_"USERNAME"_"UID"_"USERNAME"/"FILENAME); } END_TEST START_TEST(test_username) { do_test(BASE"_%u", CCACHE_DIR, BASE"_"USERNAME); do_test("%d/"FILENAME, BASE"_%u", BASE"_"USERNAME"/"FILENAME); } END_TEST START_TEST(test_case_sensitive) { char *result; int ret; const char *file_template = BASE"_%u"; const char *expected_cs = BASE"_TestUser"; const char *expected_ci = BASE"_testuser"; kr->pd->user = discard_const("TestUser"); ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR, CCACHE_DIR); fail_unless(ret == EOK, "Failed to set Ccache dir"); result = expand_ccname_template(tmp_ctx, kr, file_template, NULL, true, true); fail_unless(result != NULL, "Cannot expand template [%s].", file_template); fail_unless(strcmp(result, expected_cs) == 0, "Expansion failed, result [%s], expected [%s].", result, expected_cs); result = expand_ccname_template(tmp_ctx, kr, file_template, NULL, true, false); fail_unless(result != NULL, "Cannot expand template [%s].", file_template); fail_unless(strcmp(result, expected_ci) == 0, "Expansion failed, result [%s], expected [%s].", result, expected_ci); } END_TEST START_TEST(test_uid) { do_test(BASE"_%U", CCACHE_DIR, BASE"_"UID); do_test("%d/"FILENAME, BASE"_%U", BASE"_"UID"/"FILENAME); } END_TEST START_TEST(test_upn) { do_test(BASE"_%p", CCACHE_DIR, BASE"_"PRINCIPAL_NAME); do_test("%d/"FILENAME, BASE"_%p", BASE"_"PRINCIPAL_NAME"/"FILENAME); } END_TEST START_TEST(test_realm) { do_test(BASE"_%r", CCACHE_DIR, BASE"_"REALM); do_test("%d/"FILENAME, BASE"_%r", BASE"_"REALM"/"FILENAME); } END_TEST START_TEST(test_home) { do_test(BASE"_%h", CCACHE_DIR, BASE"_"HOME_DIRECTORY); do_test("%d/"FILENAME, BASE"_%h", BASE"_"HOME_DIRECTORY"/"FILENAME); } END_TEST START_TEST(test_ccache_dir) { char *result; int ret; do_test(BASE"_%d", CCACHE_DIR, BASE"_"CCACHE_DIR); ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR, BASE"_%d"); fail_unless(ret == EOK, "Failed to set Ccache dir"); result = expand_ccname_template(tmp_ctx, kr, "%d/"FILENAME, NULL, true, true); fail_unless(result == NULL, "Using %%d in ccache dir should fail."); } END_TEST START_TEST(test_pid) { char *result; int ret; do_test(BASE"_%P", CCACHE_DIR, BASE"_"PID); ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR, BASE"_%P"); fail_unless(ret == EOK, "Failed to set Ccache dir"); result = expand_ccname_template(tmp_ctx, kr, "%d/"FILENAME, NULL, true, true); fail_unless(result == NULL, "Using %%P in ccache dir should fail."); } END_TEST START_TEST(test_percent) { do_test(BASE"_%%", CCACHE_DIR, BASE"_%"); do_test("%d/"FILENAME, BASE"_%%", BASE"_%/"FILENAME); } END_TEST START_TEST(test_unknown_template) { const char *test_template = BASE"_%X"; char *result; int ret; result = expand_ccname_template(tmp_ctx, kr, test_template, NULL, true, true); fail_unless(result == NULL, "Unknown template [%s] should fail.", test_template); ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR, BASE"_%X"); fail_unless(ret == EOK, "Failed to set Ccache dir"); test_template = "%d/"FILENAME; result = expand_ccname_template(tmp_ctx, kr, test_template, NULL, true, true); fail_unless(result == NULL, "Unknown template [%s] should fail.", test_template); } END_TEST START_TEST(test_NULL) { char *test_template = NULL; char *result; result = expand_ccname_template(tmp_ctx, kr, test_template, NULL, true, true); fail_unless(result == NULL, "Expected NULL as a result for an empty input.", test_template); } END_TEST START_TEST(test_no_substitution) { const char *test_template = BASE; char *result; result = expand_ccname_template(tmp_ctx, kr, test_template, NULL, true, true); fail_unless(result != NULL, "Cannot expand template [%s].", test_template); fail_unless(strcmp(result, test_template) == 0, "Expansion failed, result [%s], expected [%s].", result, test_template); } END_TEST START_TEST(test_krb5_style_expansion) { char *result; const char *file_template; const char *expected; file_template = BASE"/%{uid}/%{USERID}/%{euid}/%{username}"; expected = BASE"/"UID"/"UID"/"UID"/"USERNAME; result = expand_ccname_template(tmp_ctx, kr, file_template, NULL, true, true); fail_unless(result != NULL, "Cannot expand template [%s].", file_template); fail_unless(strcmp(result, expected) == 0, "Expansion failed, result [%s], expected [%s].", result, expected); file_template = BASE"/%{unknown}"; expected = BASE"/%{unknown}"; result = expand_ccname_template(tmp_ctx, kr, file_template, NULL, true, true); fail_unless(result != NULL, "Cannot expand template [%s].", file_template); fail_unless(strcmp(result, expected) == 0, "Expansion failed, result [%s], expected [%s].", result, expected); } END_TEST START_TEST(test_compare_principal_realm) { int ret; bool different_realm; ret = compare_principal_realm(NULL, "a", &different_realm); fail_unless(ret == EINVAL, "NULL upn does not cause EINVAL."); ret = compare_principal_realm("a", NULL, &different_realm); fail_unless(ret == EINVAL, "NULL realm does not cause EINVAL."); ret = compare_principal_realm("a", "b", NULL); fail_unless(ret == EINVAL, "NULL different_realmbool " \ "does not cause EINVAL."); ret = compare_principal_realm("", "a", &different_realm); fail_unless(ret == EINVAL, "Empty upn does not cause EINVAL."); ret = compare_principal_realm("a", "", &different_realm); fail_unless(ret == EINVAL, "Empty realm does not cause EINVAL."); ret = compare_principal_realm("ABC", "ABC", &different_realm); fail_unless(ret == EINVAL, "Short UPN does not cause EINVAL."); ret = compare_principal_realm("userABC", "ABC", &different_realm); fail_unless(ret == EINVAL, "Missing '@' does not cause EINVAL."); ret = compare_principal_realm("user@ABC", "ABC", &different_realm); fail_unless(ret == EOK, "Failure with same realm"); fail_unless(different_realm == false, "Same realm but " \ "different_realm is not false."); ret = compare_principal_realm("user@ABC", "DEF", &different_realm); fail_unless(ret == EOK, "Failure with different realm"); fail_unless(different_realm == true, "Different realm but " \ "different_realm is not true."); ret = compare_principal_realm("user@ABC", "REALMNAMELONGERTHANUPN", &different_realm); fail_unless(ret == EOK, "Failure with long realm name."); fail_unless(different_realm == true, "Realm name longer than UPN but " "different_realm is not true."); } END_TEST static void compare_map_id_name_to_krb_primary(struct map_id_name_to_krb_primary *a, const char **str, size_t len) { int i = 0; errno_t ret; while (a[i].id_name != NULL && a[i].krb_primary != NULL) { fail_unless(i < len); ret = sss_utf8_case_eq((const uint8_t*)a[i].id_name, (const uint8_t*)str[i*2]); fail_unless(ret == EOK, "%s does not match %s", a[i].id_name, str[i*2]); ret = sss_utf8_case_eq((const uint8_t*)a[i].krb_primary, (const uint8_t*)str[i*2+1]); fail_unless(ret == EOK, "%s does not match %s", a[i].krb_primary, str[i*2+1]); i++; } fail_unless(len == i, "%u != %u", len, i); } START_TEST(test_parse_krb5_map_user) { errno_t ret; TALLOC_CTX *mem_ctx; struct map_id_name_to_krb_primary *name_to_primary; mem_ctx = talloc_new(NULL); /* empty input */ { check_leaks_push(mem_ctx); ret = parse_krb5_map_user(mem_ctx, NULL, &name_to_primary); fail_unless(ret == EOK); fail_unless(name_to_primary[0].id_name == NULL && name_to_primary[0].krb_primary == NULL); talloc_free(name_to_primary); ret = parse_krb5_map_user(mem_ctx, "", &name_to_primary); fail_unless(ret == EOK); fail_unless(name_to_primary[0].id_name == NULL && name_to_primary[0].krb_primary == NULL); talloc_free(name_to_primary); ret = parse_krb5_map_user(mem_ctx, ",", &name_to_primary); fail_unless(ret == EOK); fail_unless(name_to_primary[0].id_name == NULL && name_to_primary[0].krb_primary == NULL); talloc_free(name_to_primary); ret = parse_krb5_map_user(mem_ctx, ",,", &name_to_primary); fail_unless(ret == EOK); fail_unless(name_to_primary[0].id_name == NULL && name_to_primary[0].krb_primary == NULL); talloc_free(name_to_primary); fail_unless(check_leaks_pop(mem_ctx)); } /* valid input */ { check_leaks_push(mem_ctx); const char *p = "pája:preichl,joe:juser,jdoe:ßlack"; const char *p2 = " pája : preichl , joe:\njuser,jdoe\t: ßlack "; const char *expected[] = {"pája", "preichl", "joe", "juser", "jdoe", "ßlack"}; ret = parse_krb5_map_user(mem_ctx, p, &name_to_primary); fail_unless(ret == EOK); compare_map_id_name_to_krb_primary(name_to_primary, expected, sizeof(expected)/sizeof(const char*)/2); talloc_free(name_to_primary); ret = parse_krb5_map_user(mem_ctx, p2, &name_to_primary); fail_unless(ret == EOK); compare_map_id_name_to_krb_primary(name_to_primary, expected, sizeof(expected)/sizeof(const char*)/2); talloc_free(name_to_primary); fail_unless(check_leaks_pop(mem_ctx)); } /* invalid input */ { check_leaks_push(mem_ctx); ret = parse_krb5_map_user(mem_ctx, ":", &name_to_primary); fail_unless(ret == EINVAL); ret = parse_krb5_map_user(mem_ctx, "joe:", &name_to_primary); fail_unless(ret == EINVAL); ret = parse_krb5_map_user(mem_ctx, ":joe", &name_to_primary); fail_unless(ret == EINVAL); ret = parse_krb5_map_user(mem_ctx, "joe:,", &name_to_primary); fail_unless(ret == EINVAL); ret = parse_krb5_map_user(mem_ctx, ",joe", &name_to_primary); fail_unless(ret == EINVAL); ret = parse_krb5_map_user(mem_ctx, "joe:j:user", &name_to_primary); fail_unless(ret == EINVAL); fail_unless(check_leaks_pop(mem_ctx)); } talloc_free(mem_ctx); } END_TEST START_TEST(test_sss_krb5_realm_has_proxy) { fail_unless(sss_krb5_realm_has_proxy(NULL) == false); setenv("KRB5_CONFIG", "/dev/null", 1); fail_unless(sss_krb5_realm_has_proxy("REALM") == false); setenv("KRB5_CONFIG", ABS_SRC_DIR"/src/tests/krb5_proxy_check_test_data.conf", 1); fail_unless(sss_krb5_realm_has_proxy("REALM") == false); fail_unless(sss_krb5_realm_has_proxy("REALM_PROXY") == true); } END_TEST Suite *krb5_utils_suite (void) { Suite *s = suite_create ("krb5_utils"); TCase *tc_ccname_template = tcase_create ("ccname_template"); tcase_add_checked_fixture (tc_ccname_template, setup_talloc_context, free_talloc_context); tcase_add_test (tc_ccname_template, test_no_substitution); tcase_add_test (tc_ccname_template, test_NULL); tcase_add_test (tc_ccname_template, test_unknown_template); tcase_add_test (tc_ccname_template, test_username); tcase_add_test (tc_ccname_template, test_case_sensitive); tcase_add_test (tc_ccname_template, test_uid); tcase_add_test (tc_ccname_template, test_upn); tcase_add_test (tc_ccname_template, test_realm); tcase_add_test (tc_ccname_template, test_home); tcase_add_test (tc_ccname_template, test_ccache_dir); tcase_add_test (tc_ccname_template, test_pid); tcase_add_test (tc_ccname_template, test_percent); tcase_add_test (tc_ccname_template, test_multiple_substitutions); tcase_add_test (tc_ccname_template, test_krb5_style_expansion); suite_add_tcase (s, tc_ccname_template); TCase *tc_create_dir = tcase_create("create_dir"); tcase_add_checked_fixture (tc_create_dir, setup_create_dir, teardown_create_dir); tcase_add_test (tc_create_dir, test_illegal_patterns); tcase_add_test (tc_create_dir, test_cc_dir_create); if (getuid() == 0) { tcase_add_test (tc_create_dir, test_private_ccache_dir_in_user_dir); tcase_add_test (tc_create_dir, test_private_ccache_dir_in_wrong_user_dir); } else { printf("Run as root to enable more tests.\n"); } suite_add_tcase (s, tc_create_dir); TCase *tc_krb5_helpers = tcase_create("Helper functions"); tcase_add_test(tc_krb5_helpers, test_compare_principal_realm); tcase_add_test(tc_krb5_helpers, test_parse_krb5_map_user); tcase_add_test(tc_krb5_helpers, test_sss_krb5_realm_has_proxy); suite_add_tcase(s, tc_krb5_helpers); return s; } int main(int argc, const char *argv[]) { int ret; int opt; poptContext pc; int number_failed; tests_set_cwd(); struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); ret = mkdir(TESTS_PATH, 0775); if (ret != EOK) { fprintf(stderr, "Could not create empty directory [%s]. ", TESTS_PATH); if (errno == EEXIST) { fprintf(stderr, "Please remove [%s].\n", TESTS_PATH); } else { fprintf(stderr, "[%d][%s].\n", errno, strerror(errno)); } return 1; } Suite *s = krb5_utils_suite (); SRunner *sr = srunner_create (s); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed (sr); srunner_free (sr); if (number_failed == 0) { ret = rmdir(TESTS_PATH); if (ret != EOK) { fprintf(stderr, "Cannot remove [%s]: [%d][%s].\n", TESTS_PATH, errno, strerror(errno)); return EXIT_FAILURE; } return EXIT_SUCCESS; } return EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/debug-tests.c0000644000000000000000000000007412703456111016650 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.913794507 sssd-1.13.4/src/tests/debug-tests.c0000644002412700241270000004400612703456111020323 0ustar00jhrozekjhrozek00000000000000/* SSSD debug-tests.c Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "tests/common.h" #define DEBUG_TEST_ERROR -1 #define DEBUG_TEST_NOK 1 #define DEBUG_TEST_NOK_TS 2 START_TEST(test_debug_convert_old_level_old_format) { int expected_level = 0x0000; int old_level; int levels[] = { SSSDBG_FATAL_FAILURE, SSSDBG_CRIT_FAILURE, SSSDBG_OP_FAILURE, SSSDBG_MINOR_FAILURE, SSSDBG_CONF_SETTINGS, SSSDBG_FUNC_DATA, SSSDBG_TRACE_FUNC, SSSDBG_TRACE_LIBS, SSSDBG_TRACE_INTERNAL, SSSDBG_TRACE_ALL | SSSDBG_BE_FO }; for (old_level = 0; old_level <= 9; old_level++) { expected_level |= levels[old_level]; char *msg = NULL; msg = talloc_asprintf(NULL, "Invalid conversion of %d", old_level); fail_unless(debug_convert_old_level(old_level) == expected_level, msg); talloc_free(msg); } } END_TEST START_TEST(test_debug_convert_old_level_new_format) { fail_unless( debug_convert_old_level(SSSDBG_UNRESOLVED) == SSSDBG_FATAL_FAILURE, "Invalid conversion of SSSDBG_UNRESOLVED" ); fail_unless( debug_convert_old_level(SSSDBG_FATAL_FAILURE) == SSSDBG_FATAL_FAILURE, "Invalid conversion of SSSDBG_FATAL_FAILURE" ); fail_unless( debug_convert_old_level(SSSDBG_CRIT_FAILURE) == SSSDBG_CRIT_FAILURE, "Invalid conversion of SSSDBG_CRIT_FAILURE" ); fail_unless( debug_convert_old_level(SSSDBG_OP_FAILURE) == SSSDBG_OP_FAILURE, "Invalid conversion of SSSDBG_OP_FAILURE" ); fail_unless( debug_convert_old_level(SSSDBG_MINOR_FAILURE) == SSSDBG_MINOR_FAILURE, "Invalid conversion of SSSDBG_MINOR_FAILURE" ); fail_unless( debug_convert_old_level(SSSDBG_CONF_SETTINGS) == SSSDBG_CONF_SETTINGS, "Invalid conversion of SSSDBG_CONF_SETTINGS" ); fail_unless( debug_convert_old_level(SSSDBG_FUNC_DATA) == SSSDBG_FUNC_DATA, "Invalid conversion of SSSDBG_FUNC_DATA" ); fail_unless( debug_convert_old_level(SSSDBG_TRACE_FUNC) == SSSDBG_TRACE_FUNC, "Invalid conversion of SSSDBG_TRACE_FUNC" ); fail_unless( debug_convert_old_level(SSSDBG_TRACE_LIBS) == SSSDBG_TRACE_LIBS, "Invalid conversion of SSSDBG_TRACE_LIBS" ); fail_unless( debug_convert_old_level(SSSDBG_TRACE_INTERNAL) == SSSDBG_TRACE_INTERNAL, "Invalid conversion of SSSDBG_TRACE_INTERNAL" ); fail_unless( debug_convert_old_level(SSSDBG_TRACE_ALL) == SSSDBG_TRACE_ALL, "Invalid conversion of SSSDBG_TRACE_ALL" ); fail_unless( debug_convert_old_level(SSSDBG_MASK_ALL) == SSSDBG_MASK_ALL, "Invalid conversion of SSSDBG_MASK_ALL" ); } END_TEST int test_helper_debug_check_message(int level) { TALLOC_CTX *ctx = talloc_new(NULL); char filename[24] = {'\0'}; char *msg = NULL; char *compare_to = NULL; const char *function = __FUNCTION__; const char *body = "some error"; int filesize; int fsize; int fd; int ret; int _errno = 0; mode_t old_umask; FILE *file = NULL; strncpy(filename, "sssd_debug_tests.XXXXXX", 24); old_umask = umask(SSS_DFL_X_UMASK); fd = mkstemp(filename); umask(old_umask); if (fd == -1) { _errno = errno; talloc_free(ctx); errno = _errno; return DEBUG_TEST_ERROR; } file = fdopen(fd, "r"); if (file == NULL) { _errno = errno; ret = DEBUG_TEST_ERROR; goto done; } ret = set_debug_file_from_fd(fd); if (ret != EOK) { _errno = ret; ret = DEBUG_TEST_ERROR; goto done; } DEBUG(level, "%s\n", body); ret = fseek(file, 0, SEEK_END); if (ret == -1) { _errno = errno; ret = DEBUG_TEST_ERROR; goto done; } filesize = ftell(file); if (filesize == -1) { _errno = errno; ret = DEBUG_TEST_ERROR; goto done; } rewind(file); msg = talloc_array(ctx, char, filesize+1); if (msg == NULL) { _errno = ENOMEM; ret = DEBUG_TEST_ERROR; goto done; } fsize = fread(msg, sizeof(char), filesize, file); if (fsize != filesize) { _errno = EIO; ret = DEBUG_TEST_ERROR; goto done; } msg[fsize] = '\0'; if (debug_timestamps == 1) { char time_day[4] = {'\0', '\0', '\0', '\0'}; char time_month[4] = {'\0', '\0', '\0', '\0'}; int time_day_num = 0; int time_hour = 0; int time_min = 0; int time_sec = 0; int time_usec = 0; int time_year = 0; int scan_return = 0; if (debug_microseconds == 0) { scan_return = sscanf(msg, "(%s %s %d %d:%d:%d %d)", time_day, time_month, &time_day_num, &time_hour, &time_min, &time_sec, &time_year); if (scan_return != 7) { ret = DEBUG_TEST_NOK_TS; goto done; } compare_to = talloc_asprintf(ctx, "(%s %s %2d %.2d:%.2d:%.2d %.4d) " "[%s] [%s] (%#.4x): %s\n", time_day, time_month, time_day_num, time_hour, time_min, time_sec, time_year, debug_prg_name, function, level, body); if (compare_to == NULL) { _errno = ENOMEM; ret = DEBUG_TEST_ERROR; goto done; } } else { scan_return = sscanf(msg, "(%s %s %d %d:%d:%d:%d %d)", time_day, time_month, &time_day_num, &time_hour, &time_min, &time_sec, &time_usec, &time_year); if (scan_return != 8) { ret = DEBUG_TEST_NOK_TS; goto done; } compare_to = talloc_asprintf(ctx, "(%s %s %2d %.2d:%.2d:%.2d:%.6d %.4d) " "[%s] [%s] (%#.4x): %s\n", time_day, time_month, time_day_num, time_hour, time_min, time_sec, time_usec, time_year, debug_prg_name, function, level, body); if (compare_to == NULL) { _errno = ENOMEM; ret = DEBUG_TEST_ERROR; goto done; } } } else { compare_to = talloc_asprintf(ctx, "[%s] [%s] (%#.4x): %s\n", debug_prg_name, function, level, body); if (compare_to == NULL) { _errno = ENOMEM; ret = DEBUG_TEST_ERROR; goto done; } } ret = strncmp(msg, compare_to, filesize) == 0 ? EOK : DEBUG_TEST_NOK; done: talloc_free(ctx); if (file != NULL) { fclose(file); } remove(filename); errno = _errno; return ret; } int test_helper_debug_is_empty_message(int level) { char filename[24] = {'\0'}; int fd; int filesize; int ret; int _errno = 0; mode_t old_umask; FILE *file; strncpy(filename, "sssd_debug_tests.XXXXXX", 24); old_umask = umask(SSS_DFL_X_UMASK); fd = mkstemp(filename); umask(old_umask); if (fd == -1) { return DEBUG_TEST_ERROR; } file = fdopen(fd, "r"); if (file == NULL) { _errno = errno; ret = DEBUG_TEST_ERROR; goto done; } ret = set_debug_file_from_fd(fd); if (ret != EOK) { _errno = ret; ret = DEBUG_TEST_ERROR; goto done; } DEBUG(level, "some error\n"); ret = fseek(file, 0, SEEK_END); if (ret == -1) { _errno = errno; ret = DEBUG_TEST_ERROR; goto done; } filesize = ftell(file); if (filesize == -1) { _errno = errno; ret = DEBUG_TEST_ERROR; goto done; } ret = filesize == 0 ? EOK : DEBUG_TEST_NOK; done: if (file != NULL) { fclose(file); } remove(filename); errno = _errno; return ret; } START_TEST(test_debug_is_set_single_no_timestamp) { int i; int result; int levels[] = { SSSDBG_FATAL_FAILURE, SSSDBG_CRIT_FAILURE, SSSDBG_OP_FAILURE, SSSDBG_MINOR_FAILURE, SSSDBG_CONF_SETTINGS, SSSDBG_FUNC_DATA, SSSDBG_TRACE_FUNC, SSSDBG_TRACE_LIBS, SSSDBG_TRACE_INTERNAL, SSSDBG_TRACE_ALL }; char *error_msg; debug_timestamps = 0; debug_microseconds = 0; debug_to_file = 1; debug_prg_name = "sssd"; for (i = 0; i <= 9; i++) { debug_level = levels[i]; errno = 0; result = test_helper_debug_check_message(levels[i]); if (result == DEBUG_TEST_ERROR) { error_msg = strerror(errno); fail(error_msg); } char *msg = NULL; msg = talloc_asprintf(NULL, "Test of level %#.4x failed - message don't match", levels[i]); fail_unless(result == EOK, msg); talloc_free(msg); } } END_TEST START_TEST(test_debug_is_set_single_timestamp) { int i; int result; int levels[] = { SSSDBG_FATAL_FAILURE, SSSDBG_CRIT_FAILURE, SSSDBG_OP_FAILURE, SSSDBG_MINOR_FAILURE, SSSDBG_CONF_SETTINGS, SSSDBG_FUNC_DATA, SSSDBG_TRACE_FUNC, SSSDBG_TRACE_LIBS, SSSDBG_TRACE_INTERNAL, SSSDBG_TRACE_ALL }; char *error_msg; debug_timestamps = 1; debug_microseconds = 0; debug_to_file = 1; debug_prg_name = "sssd"; for (i = 0; i <= 9; i++) { debug_level = levels[i]; errno = 0; result = test_helper_debug_check_message(levels[i]); if (result == DEBUG_TEST_ERROR) { error_msg = strerror(errno); fail(error_msg); } char *msg = NULL; msg = talloc_asprintf(NULL, "Test of level %#.4x failed - invalid timestamp", levels[i]); fail_if(result == DEBUG_TEST_NOK_TS, msg); talloc_free(msg); msg = talloc_asprintf(NULL, "Test of level %#.4x failed - message don't match", levels[i]); fail_unless(result == EOK, msg); talloc_free(msg); } } END_TEST START_TEST(test_debug_is_set_single_timestamp_microseconds) { int i; int result; int levels[] = { SSSDBG_FATAL_FAILURE, SSSDBG_CRIT_FAILURE, SSSDBG_OP_FAILURE, SSSDBG_MINOR_FAILURE, SSSDBG_CONF_SETTINGS, SSSDBG_FUNC_DATA, SSSDBG_TRACE_FUNC, SSSDBG_TRACE_LIBS, SSSDBG_TRACE_INTERNAL, SSSDBG_TRACE_ALL }; char *error_msg; debug_timestamps = 1; debug_microseconds = 1; debug_to_file = 1; debug_prg_name = "sssd"; for (i = 0; i <= 9; i++) { debug_level = levels[i]; errno = 0; result = test_helper_debug_check_message(levels[i]); if (result == DEBUG_TEST_ERROR) { error_msg = strerror(errno); fail(error_msg); } char *msg = NULL; msg = talloc_asprintf(NULL, "Test of level %#.4x failed - invalid timestamp", levels[i]); fail_if(result == DEBUG_TEST_NOK_TS, msg); talloc_free(msg); msg = talloc_asprintf(NULL, "Test of level %#.4x failed - message don't match", levels[i]); fail_unless(result == EOK, msg); talloc_free(msg); } } END_TEST START_TEST(test_debug_is_notset_no_timestamp) { int i; int result; int all_set = SSSDBG_MASK_ALL; int levels[] = { SSSDBG_FATAL_FAILURE, SSSDBG_CRIT_FAILURE, SSSDBG_OP_FAILURE, SSSDBG_MINOR_FAILURE, SSSDBG_CONF_SETTINGS, SSSDBG_FUNC_DATA, SSSDBG_TRACE_FUNC, SSSDBG_TRACE_LIBS, SSSDBG_TRACE_INTERNAL, SSSDBG_TRACE_ALL }; char *error_msg; debug_timestamps = 0; debug_microseconds = 0; debug_to_file = 1; debug_prg_name = "sssd"; for (i = 0; i <= 9; i++) { debug_level = all_set & ~levels[i]; errno = 0; result = test_helper_debug_is_empty_message(levels[i]); if (result == DEBUG_TEST_ERROR) { error_msg = strerror(errno); fail(error_msg); } char *msg = NULL; msg = talloc_asprintf(NULL, "Test of level %#.4x failed - message has been written", levels[i]); fail_unless(result == EOK, msg); talloc_free(msg); } } END_TEST START_TEST(test_debug_is_notset_timestamp) { int i; int result; int all_set = SSSDBG_MASK_ALL; int levels[] = { SSSDBG_FATAL_FAILURE, SSSDBG_CRIT_FAILURE, SSSDBG_OP_FAILURE, SSSDBG_MINOR_FAILURE, SSSDBG_CONF_SETTINGS, SSSDBG_FUNC_DATA, SSSDBG_TRACE_FUNC, SSSDBG_TRACE_LIBS, SSSDBG_TRACE_INTERNAL, SSSDBG_TRACE_ALL }; char *error_msg; debug_timestamps = 0; debug_microseconds = 0; debug_to_file = 1; debug_prg_name = "sssd"; for (i = 0; i <= 9; i++) { debug_level = all_set & ~levels[i]; errno = 0; result = test_helper_debug_is_empty_message(levels[i]); if (result == DEBUG_TEST_ERROR) { error_msg = strerror(errno); fail(error_msg); } char *msg = NULL; msg = talloc_asprintf(NULL, "Test of level %#.4x failed - message has been written", levels[i]); fail_unless(result == EOK, msg); talloc_free(msg); } } END_TEST START_TEST(test_debug_is_notset_timestamp_microseconds) { int i; int result; int all_set = SSSDBG_MASK_ALL; int levels[] = { SSSDBG_FATAL_FAILURE, SSSDBG_CRIT_FAILURE, SSSDBG_OP_FAILURE, SSSDBG_MINOR_FAILURE, SSSDBG_CONF_SETTINGS, SSSDBG_FUNC_DATA, SSSDBG_TRACE_FUNC, SSSDBG_TRACE_LIBS, SSSDBG_TRACE_INTERNAL, SSSDBG_TRACE_ALL }; char *error_msg; debug_timestamps = 0; debug_microseconds = 1; debug_to_file = 1; debug_prg_name = "sssd"; for (i = 0; i <= 9; i++) { debug_level = all_set & ~levels[i]; errno = 0; result = test_helper_debug_is_empty_message(levels[i]); if (result == DEBUG_TEST_ERROR) { error_msg = strerror(errno); fail(error_msg); } char *msg = NULL; msg = talloc_asprintf(NULL, "Test of level %#.4x failed - message has been written", levels[i]); fail_unless(result == EOK, msg); talloc_free(msg); } } END_TEST START_TEST(test_debug_is_set_true) { int i; int result; int levels[] = { SSSDBG_FATAL_FAILURE, SSSDBG_CRIT_FAILURE, SSSDBG_OP_FAILURE, SSSDBG_MINOR_FAILURE, SSSDBG_CONF_SETTINGS, SSSDBG_FUNC_DATA, SSSDBG_TRACE_FUNC, SSSDBG_TRACE_LIBS, SSSDBG_TRACE_INTERNAL, SSSDBG_TRACE_ALL }; debug_level = SSSDBG_MASK_ALL; for (i = 0; i <= 9; i++) { result = DEBUG_IS_SET(levels[i]); char *msg = NULL; msg = talloc_asprintf(NULL, "Test of level %#.4x failed - result is 0x%.4x", levels[i], result); fail_unless(result > 0, msg); talloc_free(msg); } } END_TEST START_TEST(test_debug_is_set_false) { int i; int result; int all_set = SSSDBG_MASK_ALL; int levels[] = { SSSDBG_FATAL_FAILURE, SSSDBG_CRIT_FAILURE, SSSDBG_OP_FAILURE, SSSDBG_MINOR_FAILURE, SSSDBG_CONF_SETTINGS, SSSDBG_FUNC_DATA, SSSDBG_TRACE_FUNC, SSSDBG_TRACE_LIBS, SSSDBG_TRACE_INTERNAL, SSSDBG_TRACE_ALL }; for (i = 0; i <= 9; i++) { debug_level = all_set & ~levels[i]; result = DEBUG_IS_SET(levels[i]); char *msg = NULL; msg = talloc_asprintf(NULL, "Test of level %#.4x failed - result is 0x%.4x", levels[i], result); fail_unless(result == 0, msg); talloc_free(msg); } } END_TEST Suite *debug_suite(void) { Suite *s = suite_create("debug"); TCase *tc_debug = tcase_create("debug"); tcase_add_test(tc_debug, test_debug_convert_old_level_old_format); tcase_add_test(tc_debug, test_debug_convert_old_level_new_format); tcase_add_test(tc_debug, test_debug_is_set_single_no_timestamp); tcase_add_test(tc_debug, test_debug_is_set_single_timestamp); tcase_add_test(tc_debug, test_debug_is_set_single_timestamp_microseconds); tcase_add_test(tc_debug, test_debug_is_notset_no_timestamp); tcase_add_test(tc_debug, test_debug_is_notset_timestamp); tcase_add_test(tc_debug, test_debug_is_notset_timestamp_microseconds); tcase_add_test(tc_debug, test_debug_is_set_true); tcase_add_test(tc_debug, test_debug_is_set_false); tcase_set_timeout(tc_debug, 60); suite_add_tcase(s, tc_debug); return s; } int main(int argc, const char *argv[]) { int number_failed; tests_set_cwd(); Suite *s = debug_suite(); SRunner *sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); if (number_failed == 0) return EXIT_SUCCESS; return EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/pyhbac-test.py0000644000000000000000000000007412703456111017053 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.346792584 sssd-1.13.4/src/tests/pyhbac-test.py0000755002412700241270000004664712703456111020546 0ustar00jhrozekjhrozek00000000000000#!/usr/bin/env python from __future__ import print_function import unittest import sys import os import copy import tempfile BUILD_DIR = os.getenv('builddir') or "." TEST_DIR = os.getenv('SSS_TEST_DIR') or "." MODPATH = tempfile.mkdtemp(prefix="tp_pyhbac_", dir=TEST_DIR) if sys.version_info[0] > 2: unicode = str def compat_assertItemsEqual(this, expected_seq, actual_seq, msg=None): return this.assertEqual(sorted(expected_seq), sorted(actual_seq)) def compat_assertIsInstance(this, obj, cls, msg=None): return this.assertTrue(isinstance(obj, cls)) # add compat methods for old unittest.TestCase versions # (python < 2.7, RHEL5 for instance) if not hasattr(unittest.TestCase, "assertItemsEqual"): setattr(unittest.TestCase, "assertItemsEqual", compat_assertItemsEqual) if not hasattr(unittest.TestCase, "assertIsInstance"): setattr(unittest.TestCase, "assertIsInstance", compat_assertIsInstance) class PyHbacImport(unittest.TestCase): def setUp(self): " Make sure we load the in-tree module " self.system_path = sys.path[:] sys.path = [ MODPATH ] def tearDown(self): " Restore the system path " sys.path = self.system_path def testImport(self): " Import the module and assert it comes from tree " try: dest_module_path = MODPATH + "/pyhbac.so" if sys.version_info[0] > 2: src_module_path = BUILD_DIR + "/.libs/_py3hbac.so" else: src_module_path = BUILD_DIR + "/.libs/_py2hbac.so" src_module_path = os.path.abspath(src_module_path) os.symlink(src_module_path, dest_module_path) import pyhbac except ImportError as e: print("Could not load the pyhbac module. Please check if it is compiled", file=sys.stderr) raise e self.assertEqual(pyhbac.__file__, MODPATH + "/pyhbac.so") class PyHbacRuleElementTest(unittest.TestCase): def testInstantiateEmpty(self): el = pyhbac.HbacRuleElement() self.assertItemsEqual(el.names, []) self.assertItemsEqual(el.groups, []) self.assertItemsEqual(el.category, set([pyhbac.HBAC_CATEGORY_NULL])) def testInit(self): names = [ "foo", "bar" ] el = pyhbac.HbacRuleElement(names=names) self.assertItemsEqual(el.names, names) groups = [ "abc", "def" ] el = pyhbac.HbacRuleElement(groups=groups) self.assertItemsEqual(el.groups, groups) def testGetSet(self): names = [ "foo", "bar" ] el = pyhbac.HbacRuleElement() self.assertItemsEqual(el.names, []) el.names = names self.assertItemsEqual(el.names, names) groups = [ "abc", "def" ] el = pyhbac.HbacRuleElement() self.assertItemsEqual(el.groups, []) el.groups = groups self.assertItemsEqual(el.groups, groups) # Test other iterables than list groups = ( "abc", "def" ) el = pyhbac.HbacRuleElement() self.assertItemsEqual(el.groups, []) el.groups = groups self.assertItemsEqual(el.groups, groups) def testCategory(self): el = pyhbac.HbacRuleElement() assert pyhbac.HBAC_CATEGORY_NULL in el.category assert pyhbac.HBAC_CATEGORY_ALL not in el.category el.category.add(pyhbac.HBAC_CATEGORY_ALL) assert pyhbac.HBAC_CATEGORY_ALL in el.category el.category = set([pyhbac.HBAC_CATEGORY_ALL]) assert pyhbac.HBAC_CATEGORY_ALL in el.category # negative tests self.assertRaises(TypeError, el.__setattr__, "category", [pyhbac.HBAC_CATEGORY_ALL]) self.assertRaises(TypeError, el.__setattr__, "category", None) self.assertRaises(TypeError, el.__setattr__, "category", 1) def testNotIterable(self): self.assertRaises(TypeError, pyhbac.HbacRuleElement, names=123) self.assertRaises(TypeError, pyhbac.HbacRuleElement, names=None) def testRuleElementReference(self): def _get_rule(): users = [ "foo", "bar" ] user_groups = [ "abc", "def" ] return pyhbac.HbacRuleElement(names=users, groups=user_groups) el = _get_rule() self.assertItemsEqual(el.names, [ "foo", "bar" ]) self.assertItemsEqual(el.groups, [ "abc", "def" ]) def testRepr(self): el = pyhbac.HbacRuleElement() self.assertEquals(el.__repr__(), u'') el.category.add(pyhbac.HBAC_CATEGORY_ALL) el.names = ['foo'] el.groups = ['bar, baz'] self.assertEquals(el.__repr__(), u'') class PyHbacRuleTest(unittest.TestCase): def testRuleGetSetName(self): name = "testGetRule" new_name = "testGetNewRule" rule = pyhbac.HbacRule(name) self.assertEqual(rule.name, unicode(name)) rule.name = new_name self.assertEqual(rule.name, unicode(new_name)) def testRuleGetSetEnabled(self): rule = pyhbac.HbacRule("testRuleGetSetEnabled") rule.enabled = True self.assertEqual(rule.enabled, True) rule.enabled = False self.assertEqual(rule.enabled, False) rule.enabled = "TRUE" self.assertEqual(rule.enabled, True) rule.enabled = "FALSE" self.assertEqual(rule.enabled, False) rule.enabled = "true" self.assertEqual(rule.enabled, True) rule.enabled = "false" self.assertEqual(rule.enabled, False) rule.enabled = "True" self.assertEqual(rule.enabled, True) rule.enabled = "False" self.assertEqual(rule.enabled, False) rule.enabled = 1 self.assertEqual(rule.enabled, True) rule.enabled = 0 self.assertEqual(rule.enabled, False) # negative test self.assertRaises(TypeError, rule.__setattr__, "enabled", None) self.assertRaises(TypeError, rule.__setattr__, "enabled", []) self.assertRaises(ValueError, rule.__setattr__, "enabled", "foo") self.assertRaises(ValueError, rule.__setattr__, "enabled", 5) def testRuleElementInRule(self): users = [ "foo", "bar" ] user_groups = [ "abc", "def" ] # rule should contain empty elements after instantiation rule = pyhbac.HbacRule("testRuleElement") self.assertIsInstance(rule.users, pyhbac.HbacRuleElement) self.assertIsInstance(rule.services, pyhbac.HbacRuleElement) self.assertIsInstance(rule.targethosts, pyhbac.HbacRuleElement) self.assertIsInstance(rule.srchosts, pyhbac.HbacRuleElement) self.assertIsInstance(rule.users.names, list) self.assertIsInstance(rule.users.groups, list) self.assertItemsEqual(rule.users.names, []) self.assertItemsEqual(rule.users.groups, []) # Assign by copying a HbacRuleElement user_el = pyhbac.HbacRuleElement(names=users, groups=user_groups) rule = pyhbac.HbacRule("testRuleElement") rule.users = user_el self.assertItemsEqual(rule.users.names, users) self.assertItemsEqual(rule.users.groups, user_groups) # Assign directly rule = pyhbac.HbacRule("testRuleElement") rule.users.names = users rule.users.groups = user_groups self.assertItemsEqual(rule.users.names, users) self.assertItemsEqual(rule.users.groups, user_groups) def testRuleElementInRuleReference(self): " Test that references to RuleElement are kept even if element goes out of scope " def _get_rule(): users = [ "foo", "bar" ] user_groups = [ "abc", "def" ] el = pyhbac.HbacRuleElement(names=users, groups=user_groups) rule = pyhbac.HbacRule("testRuleElement") rule.users = el return rule rule = _get_rule() self.assertItemsEqual(rule.users.names, [ "foo", "bar" ]) self.assertItemsEqual(rule.users.groups, [ "abc", "def" ]) def testRepr(self): r = pyhbac.HbacRule('foo') self.assertEqual(r.__repr__(), u" " "services " "targethosts " "srchosts >") name = "someuser" service = "ssh" srchost = "host1" targethost = "host2" r.users.names = [ name ] r.services.names = [ service ] r.srchosts.names = [ srchost ] r.targethosts.names = [ targethost ] self.assertEqual(r.__repr__(), u" " "services " "targethosts " "srchosts >" % (name, service, targethost, srchost)) def testValidate(self): r = pyhbac.HbacRule('valid_rule') valid, missing = r.validate() self.assertEqual(valid, False) self.assertItemsEqual(missing, ( pyhbac.HBAC_RULE_ELEMENT_USERS, pyhbac.HBAC_RULE_ELEMENT_SERVICES, pyhbac.HBAC_RULE_ELEMENT_TARGETHOSTS, pyhbac.HBAC_RULE_ELEMENT_SOURCEHOSTS )) r.users.names = [ "someuser" ] r.services.names = [ "ssh" ] valid, missing = r.validate() self.assertEqual(valid, False) self.assertItemsEqual(missing, ( pyhbac.HBAC_RULE_ELEMENT_TARGETHOSTS, pyhbac.HBAC_RULE_ELEMENT_SOURCEHOSTS )) r.srchosts.names = [ "host1" ] r.targethosts.names = [ "host2" ] valid, missing = r.validate() self.assertEqual(valid, True) class PyHbacRequestElementTest(unittest.TestCase): def testInstantiateEmpty(self): el = pyhbac.HbacRequestElement() self.assertItemsEqual(el.name, "") self.assertItemsEqual(el.groups, []) def testInit(self): name = "foo" el = pyhbac.HbacRequestElement(name=name) self.assertItemsEqual(el.name, name) groups = [ "abc", "def" ] el = pyhbac.HbacRequestElement(groups=groups) self.assertItemsEqual(el.groups, groups) def testGetSet(self): name = "foo" el = pyhbac.HbacRequestElement() self.assertItemsEqual(el.name, "") el.name = name self.assertItemsEqual(el.name, name) groups = [ "abc", "def" ] el = pyhbac.HbacRequestElement() self.assertItemsEqual(el.groups, []) el.groups = groups self.assertItemsEqual(el.groups, groups) # Test other iterables than list groups = ( "abc", "def" ) el = pyhbac.HbacRequestElement() self.assertItemsEqual(el.groups, []) el.groups = groups self.assertItemsEqual(el.groups, groups) def testGroupsNotIterable(self): self.assertRaises(TypeError, pyhbac.HbacRequestElement, groups=None) self.assertRaises(TypeError, pyhbac.HbacRequestElement, groups=123) def testRepr(self): r = pyhbac.HbacRequestElement() self.assertEqual(r.__repr__(), u"") r.name = 'foo' r.groups = ['bar', 'baz'] self.assertEqual(r.__repr__(), u"") class PyHbacRequestTest(unittest.TestCase): def testRequestElementHandling(self): name = "req_name" groups = [ "g1", "g2" ] # The request should be empty after instantiation req = pyhbac.HbacRequest() self.assertIsInstance(req.user, pyhbac.HbacRequestElement) self.assertIsInstance(req.service, pyhbac.HbacRequestElement) self.assertIsInstance(req.targethost, pyhbac.HbacRequestElement) self.assertIsInstance(req.srchost, pyhbac.HbacRequestElement) self.assertEqual(req.user.name, "") self.assertIsInstance(req.user.groups, list) self.assertItemsEqual(req.user.groups, []) # Assign by copying a HbacRequestElement user_el = pyhbac.HbacRequestElement(name=name, groups=groups) req = pyhbac.HbacRequest() req.user = user_el self.assertItemsEqual(req.user.name, name) self.assertItemsEqual(req.user.groups, groups) # Assign directly req = pyhbac.HbacRequest() req.user.name = name req.user.groups = groups self.assertItemsEqual(req.user.name, name) self.assertItemsEqual(req.user.groups, groups) def testRuleName(self): req = pyhbac.HbacRequest() self.assertEqual(req.rule_name, None) # python 2.4 raises TypError, 2.7 raises AttributeError self.assertRaises((TypeError, AttributeError), req.__setattr__, "rule_name", "foo") def testEvaluate(self): name = "someuser" service = "ssh" srchost = "host1" targethost = "host2" allow_rule = pyhbac.HbacRule("allowRule", enabled=True) allow_rule.users.names = [ name ] allow_rule.services.names = [ service ] allow_rule.srchosts.names = [ srchost ] allow_rule.targethosts.names = [ targethost ] req = pyhbac.HbacRequest() req.user.name = name req.service.name = service req.srchost.name = srchost req.targethost.name = targethost # Test that an allow rule on its own allows access res = req.evaluate((allow_rule,)) self.assertEqual(res, pyhbac.HBAC_EVAL_ALLOW) self.assertEqual(req.rule_name, "allowRule") # Test that a user not in the rule is not allowed savename = req.user.name req.user.name = "someotheruser" res = req.evaluate((allow_rule, )) self.assertEqual(res, pyhbac.HBAC_EVAL_DENY) self.assertEqual(req.rule_name, None) # But allows if the rule is an ALL rule allow_rule.users.category.add(pyhbac.HBAC_CATEGORY_ALL) res = req.evaluate((allow_rule, )) self.assertEqual(res, pyhbac.HBAC_EVAL_ALLOW) def testRepr(self): name = "someuser" service = "ssh" srchost = "host1" targethost = "host2" req = pyhbac.HbacRequest() self.assertEqual(req.__repr__(), " " "service " "targethost " "srchost >") req.user.name = name req.service.name = service req.srchost.name = srchost req.targethost.name = targethost self.assertEqual(req.__repr__(), " " "service " "targethost " "srchost >" % (name, service, targethost, srchost)) def testEvaluateNegative(self): name = "someuser" service = "ssh" srchost = "host1" targethost = "host2" allow_rule = pyhbac.HbacRule("allowRule", enabled=True) allow_rule.users.names = [ name ] allow_rule.services.names = [ service ] allow_rule.srchosts.names = [ srchost ] allow_rule.targethosts.names = [ targethost ] req = pyhbac.HbacRequest() req.service.name = service req.srchost.name = srchost req.targethost.name = targethost req.user.name = name saveuser = req.user req.user = None # need to catch this # catch invalid category value savecat = copy.copy(allow_rule.users.category) allow_rule.users.category.add(pyhbac.HBAC_EVAL_ERROR) self.assertRaises(ValueError, req.evaluate, (allow_rule,)) allow_rule.users.category = savecat # Test that invalid type is raised self.assertRaises(TypeError, req.evaluate, (allow_rule,)) req.user = saveuser allow_rule.users = None # need to catch this self.assertRaises(TypeError, req.evaluate, (allow_rule,)) # catch invalid rule type self.assertRaises(TypeError, req.evaluate, (allow_rule, None)) class PyHbacModuleTest(unittest.TestCase): @classmethod def tearDownClass(cls): os.unlink(MODPATH + "/pyhbac.so") os.rmdir(MODPATH) def testHasResultTypes(self): assert hasattr(pyhbac, "HBAC_EVAL_ALLOW") assert hasattr(pyhbac, "HBAC_EVAL_DENY") assert hasattr(pyhbac, "HBAC_EVAL_ERROR") def testHasErrorTypes(self): assert hasattr(pyhbac, "HBAC_ERROR_UNKNOWN") assert hasattr(pyhbac, "HBAC_SUCCESS") assert hasattr(pyhbac, "HBAC_ERROR_NOT_IMPLEMENTED") assert hasattr(pyhbac, "HBAC_ERROR_OUT_OF_MEMORY") assert hasattr(pyhbac, "HBAC_ERROR_UNPARSEABLE_RULE") def testHasCategories(self): assert hasattr(pyhbac, "HBAC_CATEGORY_NULL") assert hasattr(pyhbac, "HBAC_CATEGORY_ALL") def testHasRuleElementTypes(self): assert hasattr(pyhbac, "HBAC_RULE_ELEMENT_USERS") assert hasattr(pyhbac, "HBAC_RULE_ELEMENT_SERVICES") assert hasattr(pyhbac, "HBAC_RULE_ELEMENT_TARGETHOSTS") assert hasattr(pyhbac, "HBAC_RULE_ELEMENT_SOURCEHOSTS") def testHbacResultString(self): results = [ pyhbac.HBAC_EVAL_ALLOW, pyhbac.HBAC_EVAL_DENY, pyhbac.HBAC_EVAL_ERROR ] for r in results: s = pyhbac.hbac_result_string(r) self.assertIsInstance(s, unicode) assert len(s) > 0 def testHbacErrorString(self): errors = [ pyhbac.HBAC_ERROR_UNKNOWN, pyhbac.HBAC_SUCCESS, pyhbac.HBAC_ERROR_NOT_IMPLEMENTED, pyhbac.HBAC_ERROR_OUT_OF_MEMORY, pyhbac.HBAC_ERROR_UNPARSEABLE_RULE ] for e in errors: s = pyhbac.hbac_error_string(e) self.assertIsInstance(s, unicode) assert len(s) > 0 if __name__ == "__main__": error = 0 suite = unittest.TestLoader().loadTestsFromTestCase(PyHbacImport) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x1 # need to bail out here because pyhbac could not be imported sys.exit(error) # import the pyhbac module into the global namespace, but make sure it's # the one in tree sys.path.insert(0, MODPATH) import pyhbac suite = unittest.TestLoader().loadTestsFromTestCase(PyHbacRuleElementTest) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x2 suite = unittest.TestLoader().loadTestsFromTestCase(PyHbacRuleTest) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x3 suite = unittest.TestLoader().loadTestsFromTestCase(PyHbacRequestElementTest) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x4 suite = unittest.TestLoader().loadTestsFromTestCase(PyHbacRequestTest) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x5 suite = unittest.TestLoader().loadTestsFromTestCase(PyHbacModuleTest) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x6 sys.exit(error) sssd-1.13.4/src/tests/PaxHeaders.16287/pysss_murmur-test.py0000644000000000000000000000007412703456111020375 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.349792595 sssd-1.13.4/src/tests/pysss_murmur-test.py0000755002412700241270000001040312703456111022045 0ustar00jhrozekjhrozek00000000000000#!/usr/bin/env python # SSSD # # Unit tests for pysss_murmur # # Copyright (C) Sumit Bose 2012 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from __future__ import print_function import unittest import sys import os import tempfile BUILD_DIR = os.getenv('builddir') or "." TEST_DIR = os.getenv('SSS_TEST_DIR') or "." MODPATH = tempfile.mkdtemp(prefix="tp_pysss_murmur_", dir=TEST_DIR) def compat_assertItemsEqual(this, expected_seq, actual_seq, msg=None): return this.assertEqual(sorted(expected_seq), sorted(actual_seq)) def compat_assertIsInstance(this, obj, cls, msg=None): return this.assertTrue(isinstance(obj, cls)) # add compat methods for old unittest.TestCase versions # (python < 2.7, RHEL5 for instance) if not hasattr(unittest.TestCase, "assertItemsEqual"): setattr(unittest.TestCase, "assertItemsEqual", compat_assertItemsEqual) if not hasattr(unittest.TestCase, "assertIsInstance"): setattr(unittest.TestCase, "assertIsInstance", compat_assertIsInstance) class PySssMurmurImport(unittest.TestCase): def setUp(self): " Make sure we load the in-tree module " self.system_path = sys.path[:] sys.path = [ MODPATH ] print (os.getcwd()) print(MODPATH) def tearDown(self): " Restore the system path " sys.path = self.system_path def testImport(self): " Import the module and assert it comes from tree " try: dest_module_path = MODPATH + "/pysss_murmur.so" if sys.version_info[0] > 2: src_module_path = BUILD_DIR + "/.libs/_py3sss_murmur.so" else: src_module_path = BUILD_DIR + "/.libs/_py2sss_murmur.so" src_module_path = os.path.abspath(src_module_path) os.symlink(src_module_path, dest_module_path) import pysss_murmur except ImportError as e: print("Could not load the pysss_murmur module. Please check if it is compiled", file=sys.stderr) raise e self.assertEqual(pysss_murmur.__file__, MODPATH + "/pysss_murmur.so") class PySssMurmurTest(unittest.TestCase): @classmethod def tearDownClass(cls): os.unlink(MODPATH + "/pysss_murmur.so") os.rmdir(MODPATH) def testExpectedHash(self): hash = pysss_murmur.murmurhash3("S-1-5-21-2153326666-2176343378-3404031434", 41, 0xdeadbeef) self.assertEqual(hash, 93103853) def testInvalidArguments(self): self.assertRaises(ValueError, pysss_murmur.murmurhash3, 1, 2, 3) self.assertRaises(ValueError, pysss_murmur.murmurhash3, "test", 2) self.assertRaises(ValueError, pysss_murmur.murmurhash3, "test") self.assertRaises(ValueError, pysss_murmur.murmurhash3) self.assertRaises(ValueError, pysss_murmur.murmurhash3, "test", -1, 3) self.assertRaises(ValueError, pysss_murmur.murmurhash3, "test", 2, 0xffffffffff) self.assertRaises(ValueError, pysss_murmur.murmurhash3, "test", 0xffffffffff, 3) if __name__ == "__main__": error = 0 suite = unittest.TestLoader().loadTestsFromTestCase(PySssMurmurImport) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x1 # need to bail out here because pysss_murmur could not be imported sys.exit(error) # import the pysss_murmur module into the global namespace, but make sure # it's the one in tree sys.path.insert(0, MODPATH) import pysss_murmur suite = unittest.TestLoader().loadTestsFromTestCase(PySssMurmurTest) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x2 sys.exit(error) sssd-1.13.4/src/tests/PaxHeaders.16287/fail_over-tests.c0000644000000000000000000000007412703456111017530 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.918794524 sssd-1.13.4/src/tests/fail_over-tests.c0000644002412700241270000002243012703456111021200 0ustar00jhrozekjhrozek00000000000000/* SSSD Fail over tests. Authors: Martin Nagy Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "resolv/async_resolv.h" #include "tests/common_check.h" #include "util/util.h" /* Interface under test */ #include "providers/fail_over.h" int use_net_test; struct test_ctx { struct tevent_context *ev; struct resolv_ctx *resolv; struct fo_ctx *fo_ctx; int tasks; }; struct task { struct test_ctx *test_ctx; const char *location; struct fo_service *service; int recv; int port; int new_server_status; int new_port_status; }; static struct test_ctx * setup_test(void) { struct test_ctx *ctx; struct fo_options fopts; int ret; ctx = talloc_zero(global_talloc_context, struct test_ctx); fail_if(ctx == NULL, "Could not allocate memory for test context"); ctx->ev = tevent_context_init(ctx); if (ctx->ev == NULL) { talloc_free(ctx); fail("Could not init tevent context"); } ret = resolv_init(ctx, ctx->ev, 5, &ctx->resolv); if (ret != EOK) { talloc_free(ctx); fail("Could not init resolv context"); } memset(&fopts, 0, sizeof(fopts)); fopts.retry_timeout = 30; fopts.family_order = IPV4_FIRST; ctx->fo_ctx = fo_context_init(ctx, &fopts); if (ctx->fo_ctx == NULL) { talloc_free(ctx); fail("Could not init fail over context"); } return ctx; } static void test_loop(struct test_ctx *data) { while (data->tasks != 0) tevent_loop_once(data->ev); } START_TEST(test_fo_new_service) { int i; int ret; struct test_ctx *ctx; struct fo_service *service; struct fo_service *services[10]; ctx = setup_test(); ck_leaks_push(ctx); for (i = 0; i < 10; i++) { char buf[16]; sprintf(buf, "service_%d", i); ck_leaks_push(ctx); ret = fo_new_service(ctx->fo_ctx, buf, NULL, &services[i]); fail_if(ret != EOK); } ret = fo_new_service(ctx->fo_ctx, "service_3", NULL, &service); fail_if(ret != EEXIST); for (i = 9; i >= 0; i--) { char buf[16]; sprintf(buf, "service_%d", i); ret = fo_get_service(ctx->fo_ctx, buf, &service); fail_if(ret != EOK); fail_if(service != services[i]); talloc_free(service); ck_leaks_pop(ctx); ret = fo_get_service(ctx->fo_ctx, buf, &service); fail_if(ret != ENOENT); } ck_leaks_pop(ctx); talloc_free(ctx); } END_TEST static void test_resolve_service_callback(struct tevent_req *req) { uint64_t recv_status; int port; struct task *task; struct fo_server *server = NULL; struct fo_server *active_server = NULL; struct resolv_hostent *he; int i; task = tevent_req_callback_data(req, struct task); task->test_ctx->tasks--; recv_status = fo_resolve_service_recv(req, req, &server); talloc_free(req); fail_if(recv_status != task->recv, "%s: Expected return of %d, got %d", task->location, task->recv, recv_status); if (recv_status != EOK) return; fail_if(server == NULL); port = fo_get_server_port(server); fail_if(port != task->port, "%s: Expected port %d, got %d", task->location, task->port, port); if (task->new_port_status >= 0) fo_set_port_status(server, task->new_port_status); if (task->new_server_status >= 0) fo_set_server_status(server, task->new_server_status); if (fo_get_server_name(server) != NULL) { he = fo_get_server_hostent(server); fail_if(he == NULL, "fo_get_server_hostent() returned NULL"); for (i = 0; he->addr_list[i]; i++) { char buf[256]; inet_ntop(he->family, he->addr_list[i]->ipaddr, buf, sizeof(buf)); fail_if(strcmp(buf, "127.0.0.1") != 0 && strcmp(buf, "::1") != 0); } } if (task->new_port_status == PORT_WORKING && task->new_server_status == SERVER_WORKING) { active_server = fo_get_active_server(task->service); fail_if(active_server == NULL, "Missing active server"); fail_if(server != active_server, "Current server is not active server"); } } #define get_request(a, b, c, d, e, f) \ _get_request(a, b, c, d, e, f, __location__) static void _get_request(struct test_ctx *test_ctx, struct fo_service *service, int expected_recv, int expected_port, int new_port_status, int new_server_status, const char *location) { struct tevent_req *req; struct task *task; task = talloc(test_ctx, struct task); fail_if(task == NULL); task->test_ctx = test_ctx; task->recv = expected_recv; task->port = expected_port; task->new_port_status = new_port_status; task->new_server_status = new_server_status; task->location = location; task->service = service; test_ctx->tasks++; req = fo_resolve_service_send(test_ctx, test_ctx->ev, test_ctx->resolv, test_ctx->fo_ctx, service); fail_if(req == NULL, "%s: fo_resolve_service_send() failed", location); tevent_req_set_callback(req, test_resolve_service_callback, task); test_loop(test_ctx); } START_TEST(test_fo_resolve_service) { struct test_ctx *ctx; struct fo_service *service[3]; ctx = setup_test(); fail_if(ctx == NULL); /* Add service. */ fail_if(fo_new_service(ctx->fo_ctx, "http", NULL, &service[0]) != EOK); fail_if(fo_new_service(ctx->fo_ctx, "ldap", NULL, &service[1]) != EOK); fail_if(fo_new_service(ctx->fo_ctx, "ntp", NULL, &service[2]) != EOK); /* Add servers. */ fail_if(fo_add_server(service[0], "localhost", 20, NULL, true) != EOK); fail_if(fo_add_server(service[0], "127.0.0.1", 80, NULL, false) != EOK); fail_if(fo_add_server(service[1], "localhost", 30, NULL, false) != EOK); fail_if(fo_add_server(service[1], "127.0.0.1", 389, NULL, true) != EOK); fail_if(fo_add_server(service[1], "127.0.0.1", 389, NULL, true) != EEXIST); fail_if(fo_add_server(service[1], "127.0.0.1", 389, NULL, false) != EEXIST); fail_if(fo_add_server(service[2], NULL, 123, NULL, true) != EOK); /* Make requests. */ get_request(ctx, service[0], EOK, 20, PORT_WORKING, -1); get_request(ctx, service[0], EOK, 20, PORT_WORKING, SERVER_WORKING); get_request(ctx, service[0], EOK, 20, -1, SERVER_NOT_WORKING); get_request(ctx, service[0], EOK, 80, PORT_WORKING, -1); get_request(ctx, service[0], EOK, 80, PORT_NOT_WORKING, -1); get_request(ctx, service[0], ENOENT, 0, -1, -1); get_request(ctx, service[1], EOK, 389, PORT_WORKING, -1); get_request(ctx, service[1], EOK, 389, -1, SERVER_NOT_WORKING); get_request(ctx, service[1], ENOENT, 0, -1, -1); get_request(ctx, service[2], EOK, 123, -1, -1); talloc_free(ctx); } END_TEST Suite * create_suite(void) { Suite *s = suite_create("fail_over"); TCase *tc = tcase_create("FAIL_OVER Tests"); tcase_add_checked_fixture(tc, ck_leak_check_setup, ck_leak_check_teardown); /* Do some testing */ tcase_add_test(tc, test_fo_new_service); tcase_add_test(tc, test_fo_resolve_service); if (use_net_test) { } /* Add all test cases to the test suite */ suite_add_tcase(s, tc); return s; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int failure_count; Suite *suite; SRunner *sr; struct poptOption long_options[] = { POPT_AUTOHELP { "debug-level", 'd', POPT_ARG_INT, &debug_level, 0, "Set debug level", NULL }, { "use-net-test", 'n', POPT_ARG_NONE, 0, 'n', "Run tests that need an active internet connection", NULL }, POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { case 'n': use_net_test = 1; break; default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); suite = create_suite(); sr = srunner_create(suite); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); failure_count = srunner_ntests_failed(sr); srunner_free(sr); return (failure_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } sssd-1.13.4/src/tests/PaxHeaders.16287/common.c0000644000000000000000000000007412703456111015712 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.826794212 sssd-1.13.4/src/tests/common.c0000644002412700241270000000751312703456111017367 0ustar00jhrozekjhrozek00000000000000/* SSSD Common utilities for check-based tests using talloc. Authors: Martin Nagy Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "tests/common.h" #include "util/util.h" void tests_set_cwd(void) { int ret; ret = chdir(TEST_DIR); if (ret == -1) { fprintf(stderr, "Could not chdir to [%s].\n" "Attempting to continue with current dir\n", TEST_DIR); } } void test_dom_suite_setup(const char *tests_path) { errno_t ret; /* Create tests directory if it doesn't exist */ /* (relative to current dir) */ ret = mkdir(tests_path, 0775); if (ret != 0 && errno != EEXIST) { fprintf(stderr, "Could not create test directory\n"); } } /* Check that the option names of the two maps are the same * and appear in the same order. */ errno_t compare_dp_options(struct dp_option *map1, size_t size1, struct dp_option *map2) { size_t i; for (i = 0; i < size1; i++) { /* Check for a valid option */ if (map1[i].opt_name == NULL) return EINVAL; /* Check whether we've gone past the end of map2 */ if (map2[i].opt_name == NULL) return ERANGE; /* Ensure that the option names are the same */ if(strcmp(map1[i].opt_name, map2[i].opt_name) != 0) { fprintf(stderr, "Expected [%s], got [%s]\n", map1[i].opt_name, map2[i].opt_name); return EINVAL; } } /* Leftover options in map2 */ if (map2[i].opt_name != NULL) return ERANGE; return EOK; } /* Check that the option names of the two maps are the same * and appear in the same order. */ errno_t compare_sdap_attr_maps(struct sdap_attr_map *map1, size_t size1, struct sdap_attr_map *map2) { size_t i; for (i = 0; i < size1; i++) { /* Check for a valid option */ if (map1[i].opt_name == NULL) return EINVAL; /* Check whether we've gone past the end of map2 */ if (map2[i].opt_name == NULL) return ERANGE; /* Ensure that the option names are the same */ if(strcmp(map1[i].opt_name, map2[i].opt_name) != 0) { fprintf(stderr, "Expected [%s], got [%s]\n", map1[i].opt_name, map2[i].opt_name); return EINVAL; } } /* Leftover options in map2 */ if (map2[i].opt_name != NULL) return ERANGE; return EOK; } bool ldb_modules_path_is_set(void) { if (getenv("LDB_MODULES_PATH")) { return true; } return false; } /* Returns true if all values are in array (else returns false) */ bool are_values_in_array(const char **values, size_t values_len, const char **array, size_t array_len) { bool is_value_in_element = false; bool is_value_in_array = false; bool ret = true; for (size_t i = 0; i < values_len; i++) { is_value_in_array = false; for (size_t j = 0; j < array_len; j++) { is_value_in_element = strcmp(values[i], array[j]) == 0 ? \ true : false; is_value_in_array = is_value_in_array || is_value_in_element; } ret = ret && is_value_in_array; } return ret; } sssd-1.13.4/src/tests/PaxHeaders.16287/cwrap0000644000000000000000000000013212703463560015316 xustar0030 mtime=1460561776.055798379 30 atime=1460561776.119798596 30 ctime=1460561776.055798379 sssd-1.13.4/src/tests/cwrap/0000755002412700241270000000000012703463560017047 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/tests/cwrap/PaxHeaders.16287/test_usertools.c0000644000000000000000000000007412703456111020634 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.055798379 sssd-1.13.4/src/tests/cwrap/test_usertools.c0000644002412700241270000000523712703456111022312 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat SSSD tests: User utilities This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "tests/cmocka/common_mock.h" void test_get_user_num(void **state) { uid_t uid; gid_t gid; errno_t ret; ret = sss_user_by_name_or_uid("123", &uid, &gid); assert_int_equal(ret, EOK); assert_int_equal(uid, 123); assert_int_equal(gid, 456); } void test_get_user_str(void **state) { uid_t uid; gid_t gid; errno_t ret; ret = sss_user_by_name_or_uid("sssd", &uid, &gid); assert_int_equal(ret, EOK); assert_int_equal(uid, 123); assert_int_equal(gid, 456); } void test_get_user_nullparm(void **state) { uid_t uid; gid_t gid; errno_t ret; ret = sss_user_by_name_or_uid("sssd", &uid, NULL); assert_int_equal(ret, EOK); assert_int_equal(uid, 123); ret = sss_user_by_name_or_uid("sssd", NULL, &gid); assert_int_equal(ret, EOK); assert_int_equal(gid, 456); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test(test_get_user_num), cmocka_unit_test(test_get_user_str), cmocka_unit_test(test_get_user_nullparm), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cwrap/PaxHeaders.16287/Makefile.in0000644000000000000000000000013112703463544017441 xustar0029 mtime=1460561764.63675966 30 atime=1460561772.674786915 30 ctime=1460561776.051798366 sssd-1.13.4/src/tests/cwrap/Makefile.in0000644002412700241270000055333312703463544021132 0ustar00jhrozekjhrozek00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ check_PROGRAMS = $(am__EXEEXT_1) @HAVE_CMOCKA_TRUE@@HAVE_NSS_WRAPPER_TRUE@@HAVE_UID_WRAPPER_TRUE@am__append_1 = \ @HAVE_CMOCKA_TRUE@@HAVE_NSS_WRAPPER_TRUE@@HAVE_UID_WRAPPER_TRUE@ become_user-tests \ @HAVE_CMOCKA_TRUE@@HAVE_NSS_WRAPPER_TRUE@@HAVE_UID_WRAPPER_TRUE@ server-tests \ @HAVE_CMOCKA_TRUE@@HAVE_NSS_WRAPPER_TRUE@@HAVE_UID_WRAPPER_TRUE@ usertools-tests \ @HAVE_CMOCKA_TRUE@@HAVE_NSS_WRAPPER_TRUE@@HAVE_UID_WRAPPER_TRUE@ responder_common-tests \ @HAVE_CMOCKA_TRUE@@HAVE_NSS_WRAPPER_TRUE@@HAVE_UID_WRAPPER_TRUE@ $(NULL) subdir = src/tests/cwrap ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ $(top_srcdir)/version.m4 $(top_srcdir)/src/build_macros.m4 \ $(top_srcdir)/src/external/platform.m4 \ $(top_srcdir)/src/conf_macros.m4 \ $(top_srcdir)/src/external/pkg.m4 \ $(top_srcdir)/src/external/libpopt.m4 \ $(top_srcdir)/src/external/libtalloc.m4 \ $(top_srcdir)/src/external/libtdb.m4 \ $(top_srcdir)/src/external/libtevent.m4 \ $(top_srcdir)/src/external/libldb.m4 \ $(top_srcdir)/src/external/libdhash.m4 \ $(top_srcdir)/src/external/libcollection.m4 \ $(top_srcdir)/src/external/libini_config.m4 \ $(top_srcdir)/src/external/pam.m4 \ $(top_srcdir)/src/external/ldap.m4 \ $(top_srcdir)/src/external/libpcre.m4 \ $(top_srcdir)/src/external/krb5.m4 \ $(top_srcdir)/src/external/libcares.m4 \ $(top_srcdir)/src/external/libcmocka.m4 \ $(top_srcdir)/src/external/docbook.m4 \ $(top_srcdir)/src/external/sizes.m4 \ $(top_srcdir)/src/external/python.m4 \ $(top_srcdir)/src/external/selinux.m4 \ $(top_srcdir)/src/external/crypto.m4 \ $(top_srcdir)/src/external/nscd.m4 \ $(top_srcdir)/src/external/nsupdate.m4 \ $(top_srcdir)/src/external/libkeyutils.m4 \ $(top_srcdir)/src/external/libnl.m4 \ $(top_srcdir)/src/external/systemd.m4 \ $(top_srcdir)/src/external/pac_responder.m4 \ $(top_srcdir)/src/external/cifsidmap.m4 \ $(top_srcdir)/src/external/signal.m4 \ $(top_srcdir)/src/external/inotify.m4 \ $(top_srcdir)/src/external/samba.m4 \ $(top_srcdir)/src/external/sasl.m4 \ $(top_srcdir)/src/external/configlib.m4 \ $(top_srcdir)/src/external/libnfsidmap.m4 \ $(top_srcdir)/src/external/cwrap.m4 \ $(top_srcdir)/src/external/libresolv.m4 \ $(top_srcdir)/src/external/intgcheck.m4 \ $(top_srcdir)/src/external/libaugeas.m4 \ $(top_srcdir)/src/external/libunistring.m4 \ $(top_srcdir)/src/external/glib.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(dist_noinst_SCRIPTS) \ $(dist_noinst_DATA) $(am__DIST_COMMON) mkinstalldirs = $(SHELL) $(top_srcdir)/build/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = @HAVE_CMOCKA_TRUE@@HAVE_NSS_WRAPPER_TRUE@@HAVE_UID_WRAPPER_TRUE@am__EXEEXT_1 = become_user-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@@HAVE_NSS_WRAPPER_TRUE@@HAVE_UID_WRAPPER_TRUE@ server-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@@HAVE_NSS_WRAPPER_TRUE@@HAVE_UID_WRAPPER_TRUE@ usertools-tests$(EXEEXT) \ @HAVE_CMOCKA_TRUE@@HAVE_NSS_WRAPPER_TRUE@@HAVE_UID_WRAPPER_TRUE@ responder_common-tests$(EXEEXT) am_become_user_tests_OBJECTS = \ become_user_tests-test_become_user.$(OBJEXT) become_user_tests_OBJECTS = $(am_become_user_tests_OBJECTS) am__DEPENDENCIES_1 = become_user_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_test_common.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = become_user_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(become_user_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ am__dirstamp = $(am__leading_dot)dirstamp am_responder_common_tests_OBJECTS = \ responder_common_tests-test_responder_common.$(OBJEXT) \ ../../../src/responder/common/responder_common_tests-responder_common.$(OBJEXT) \ ../../../src/responder/common/responder_common_tests-responder_packet.$(OBJEXT) \ ../../../src/responder/common/responder_common_tests-responder_cmd.$(OBJEXT) responder_common_tests_OBJECTS = $(am_responder_common_tests_OBJECTS) am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) responder_common_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(abs_top_builddir)/libsss_util.la \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_crypt.la \ $(abs_top_builddir)/libsss_test_common.la responder_common_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(responder_common_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ am_server_tests_OBJECTS = server_tests-test_server.$(OBJEXT) \ ../../../src/util/server_tests-server.$(OBJEXT) \ ../../../src/util/server_tests-become_user.$(OBJEXT) \ ../../../src/util/server_tests-backup_file.$(OBJEXT) \ ../../../src/util/server_tests-domain_info_utils.$(OBJEXT) \ ../../../src/util/server_tests-atomic_io.$(OBJEXT) \ ../../../src/util/server_tests-signal.$(OBJEXT) \ ../../../src/util/server_tests-util.$(OBJEXT) \ ../../../src/util/server_tests-string_utils.$(OBJEXT) \ ../../../src/util/server_tests-strtonum.$(OBJEXT) \ ../../../src/util/server_tests-util_errors.$(OBJEXT) \ ../../../src/util/server_tests-safe-format-string.$(OBJEXT) \ ../../../src/util/server_tests-sss_tc_utf8.$(OBJEXT) \ ../../../src/util/server_tests-sss_utf8.$(OBJEXT) \ ../../../src/util/server_tests-usertools.$(OBJEXT) \ ../../../src/confdb/server_tests-confdb.$(OBJEXT) \ ../../../src/db/server_tests-sysdb.$(OBJEXT) \ ../../../src/db/server_tests-sysdb_upgrade.$(OBJEXT) \ ../../../src/db/server_tests-sysdb_ops.$(OBJEXT) \ ../../../src/db/server_tests-sysdb_search.$(OBJEXT) \ ../../../src/db/server_tests-sysdb_autofs.$(OBJEXT) \ ../../../src/db/server_tests-sysdb_services.$(OBJEXT) \ ../../../src/db/server_tests-sysdb_views.$(OBJEXT) server_tests_OBJECTS = $(am_server_tests_OBJECTS) server_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_crypt.la \ $(abs_top_builddir)/libsss_test_common.la \ $(abs_top_builddir)/libsss_cert.la server_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(server_tests_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_usertools_tests_OBJECTS = usertools_tests-test_usertools.$(OBJEXT) \ ../../../src/util/usertools_tests-domain_info_utils.$(OBJEXT) \ ../../../src/util/usertools_tests-safe-format-string.$(OBJEXT) \ ../../../src/util/usertools_tests-usertools.$(OBJEXT) \ ../../../src/util/usertools_tests-string_utils.$(OBJEXT) \ ../../../src/util/usertools_tests-strtonum.$(OBJEXT) \ ../../../src/util/usertools_tests-backup_file.$(OBJEXT) \ ../../../src/util/usertools_tests-atomic_io.$(OBJEXT) \ ../../../src/util/usertools_tests-util.$(OBJEXT) \ ../../../src/util/usertools_tests-util_errors.$(OBJEXT) \ ../../../src/util/usertools_tests-sss_tc_utf8.$(OBJEXT) \ ../../../src/util/usertools_tests-sss_utf8.$(OBJEXT) \ ../../../src/confdb/usertools_tests-confdb.$(OBJEXT) \ ../../../src/db/usertools_tests-sysdb.$(OBJEXT) \ ../../../src/db/usertools_tests-sysdb_upgrade.$(OBJEXT) \ ../../../src/db/usertools_tests-sysdb_autofs.$(OBJEXT) \ ../../../src/db/usertools_tests-sysdb_search.$(OBJEXT) \ ../../../src/db/usertools_tests-sysdb_services.$(OBJEXT) \ ../../../src/db/usertools_tests-sysdb_ops.$(OBJEXT) \ ../../../src/db/usertools_tests-sysdb_views.$(OBJEXT) usertools_tests_OBJECTS = $(am_usertools_tests_OBJECTS) usertools_tests_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_crypt.la \ $(abs_top_builddir)/libsss_test_common.la \ $(abs_top_builddir)/libsss_cert.la usertools_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(usertools_tests_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ SCRIPTS = $(dist_noinst_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/build/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(become_user_tests_SOURCES) \ $(responder_common_tests_SOURCES) $(server_tests_SOURCES) \ $(usertools_tests_SOURCES) DIST_SOURCES = $(become_user_tests_SOURCES) \ $(responder_common_tests_SOURCES) $(server_tests_SOURCES) \ $(usertools_tests_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac DATA = $(dist_noinst_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) AM_RECURSIVE_TARGETS = check recheck TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/build/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/build/depcomp \ $(top_srcdir)/build/mkinstalldirs \ $(top_srcdir)/build/test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AUGEAS_CFLAGS = @AUGEAS_CFLAGS@ AUGEAS_LIBS = @AUGEAS_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CARES_CFLAGS = @CARES_CFLAGS@ CARES_LIBS = @CARES_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHECK_CFLAGS = @CHECK_CFLAGS@ CHECK_LIBS = @CHECK_LIBS@ CMOCKA_CFLAGS = @CMOCKA_CFLAGS@ CMOCKA_LIBS = @CMOCKA_LIBS@ COLLECTION_CFLAGS = @COLLECTION_CFLAGS@ COLLECTION_LIBS = @COLLECTION_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CRYPTO_CFLAGS = @CRYPTO_CFLAGS@ CRYPTO_LIBS = @CRYPTO_LIBS@ CYGPATH_W = @CYGPATH_W@ DBUS_CFLAGS = @DBUS_CFLAGS@ DBUS_LIBS = @DBUS_LIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DHASH_CFLAGS = @DHASH_CFLAGS@ DHASH_LIBS = @DHASH_LIBS@ DLLTOOL = @DLLTOOL@ DOCBOOK_XSLT = @DOCBOOK_XSLT@ DOXYGEN = @DOXYGEN@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GLIB2_CFLAGS = @GLIB2_CFLAGS@ GLIB2_LIBS = @GLIB2_LIBS@ GMSGFMT = @GMSGFMT@ GPO_DEFAULT = @GPO_DEFAULT@ GREP = @GREP@ HAVE_FAKEROOT = @HAVE_FAKEROOT@ HAVE_LDAPMODIFY = @HAVE_LDAPMODIFY@ HAVE_MANPAGES = @HAVE_MANPAGES@ HAVE_NSS_WRAPPER = @HAVE_NSS_WRAPPER@ HAVE_PYTHON2 = @HAVE_PYTHON2@ HAVE_PYTHON2_BINDINGS = @HAVE_PYTHON2_BINDINGS@ HAVE_PYTHON3 = @HAVE_PYTHON3@ HAVE_PYTHON3_BINDINGS = @HAVE_PYTHON3_BINDINGS@ HAVE_SELINUX = @HAVE_SELINUX@ HAVE_SEMANAGE = @HAVE_SEMANAGE@ HAVE_SYSTEMD = @HAVE_SYSTEMD@ HAVE_UID_WRAPPER = @HAVE_UID_WRAPPER@ INI_CONFIG_CFLAGS = @INI_CONFIG_CFLAGS@ INI_CONFIG_LIBS = @INI_CONFIG_LIBS@ INI_CONFIG_V0_CFLAGS = @INI_CONFIG_V0_CFLAGS@ INI_CONFIG_V0_LIBS = @INI_CONFIG_V0_LIBS@ INI_CONFIG_V1_1_CFLAGS = @INI_CONFIG_V1_1_CFLAGS@ INI_CONFIG_V1_1_LIBS = @INI_CONFIG_V1_1_LIBS@ INI_CONFIG_V1_CFLAGS = @INI_CONFIG_V1_CFLAGS@ INI_CONFIG_V1_LIBS = @INI_CONFIG_V1_LIBS@ INOTIFY_LIBS = @INOTIFY_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ JOURNALD_CFLAGS = @JOURNALD_CFLAGS@ JOURNALD_LIBS = @JOURNALD_LIBS@ KEYUTILS_LIBS = @KEYUTILS_LIBS@ KRB5_CFLAGS = @KRB5_CFLAGS@ KRB5_CONFIG = @KRB5_CONFIG@ KRB5_LIBS = @KRB5_LIBS@ LD = @LD@ LDB_CFLAGS = @LDB_CFLAGS@ LDB_LIBS = @LDB_LIBS@ LDFLAGS = @LDFLAGS@ LIBADD_DL = @LIBADD_DL@ LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ LIBADD_DLOPEN = @LIBADD_DLOPEN@ LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ LIBICONV = @LIBICONV@ LIBINTL = @LIBINTL@ LIBNL1_CFLAGS = @LIBNL1_CFLAGS@ LIBNL1_LIBS = @LIBNL1_LIBS@ LIBNL3_CFLAGS = @LIBNL3_CFLAGS@ LIBNL3_LIBS = @LIBNL3_LIBS@ LIBNL_CFLAGS = @LIBNL_CFLAGS@ LIBNL_LIBS = @LIBNL_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MKINSTALLDIRS = @MKINSTALLDIRS@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ NDR_KRB5PAC_CFLAGS = @NDR_KRB5PAC_CFLAGS@ NDR_KRB5PAC_LIBS = @NDR_KRB5PAC_LIBS@ NDR_NBT_CFLAGS = @NDR_NBT_CFLAGS@ NDR_NBT_LIBS = @NDR_NBT_LIBS@ NFSIDMAP_CFLAGS = @NFSIDMAP_CFLAGS@ NFSIDMAP_LIBS = @NFSIDMAP_LIBS@ NFSIDMAP_OBJ = @NFSIDMAP_OBJ@ NM = @NM@ NMEDIT = @NMEDIT@ NSCD = @NSCD@ NSCD_PATH = @NSCD_PATH@ NSS_CFLAGS = @NSS_CFLAGS@ NSS_LIBS = @NSS_LIBS@ NSUPDATE = @NSUPDATE@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENLDAP_CFLAGS = @OPENLDAP_CFLAGS@ OPENLDAP_LIBS = @OPENLDAP_LIBS@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAM_LIBS = @PAM_LIBS@ PAM_MISC_LIBS = @PAM_MISC_LIBS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PCRE_CFLAGS = @PCRE_CFLAGS@ PCRE_LIBS = @PCRE_LIBS@ PKG_CONFIG = @PKG_CONFIG@ PO4A = @PO4A@ POPT_CFLAGS = @POPT_CFLAGS@ POPT_LIBS = @POPT_LIBS@ POSUB = @POSUB@ PRERELEASE_VERSION = @PRERELEASE_VERSION@ PYTEST = @PYTEST@ PYTHON = @PYTHON@ PYTHON2 = @PYTHON2@ PYTHON2_CFLAGS = @PYTHON2_CFLAGS@ PYTHON2_EXEC_PREFIX = @PYTHON2_EXEC_PREFIX@ PYTHON2_INCLUDES = @PYTHON2_INCLUDES@ PYTHON2_LIBS = @PYTHON2_LIBS@ PYTHON2_PREFIX = @PYTHON2_PREFIX@ PYTHON2_VERSION = @PYTHON2_VERSION@ PYTHON3 = @PYTHON3@ PYTHON3_CFLAGS = @PYTHON3_CFLAGS@ PYTHON3_EXEC_PREFIX = @PYTHON3_EXEC_PREFIX@ PYTHON3_INCLUDES = @PYTHON3_INCLUDES@ PYTHON3_LIBS = @PYTHON3_LIBS@ PYTHON3_PREFIX = @PYTHON3_PREFIX@ PYTHON3_VERSION = @PYTHON3_VERSION@ PYTHON_CONFIG = @PYTHON_CONFIG@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ RANLIB = @RANLIB@ RESOLV_CFLAGS = @RESOLV_CFLAGS@ RESOLV_LIBS = @RESOLV_LIBS@ SASL_CFLAGS = @SASL_CFLAGS@ SASL_LIBS = @SASL_LIBS@ SED = @SED@ SELINUX_LIBS = @SELINUX_LIBS@ SEMANAGE_LIBS = @SEMANAGE_LIBS@ SET_MAKE = @SET_MAKE@ SGML_CATALOG_FILES = @SGML_CATALOG_FILES@ SHELL = @SHELL@ SLAPD = @SLAPD@ SMBCLIENT_CFLAGS = @SMBCLIENT_CFLAGS@ SMBCLIENT_LIBS = @SMBCLIENT_LIBS@ SSSD_USER = @SSSD_USER@ STRIP = @STRIP@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ TALLOC_CFLAGS = @TALLOC_CFLAGS@ TALLOC_LIBS = @TALLOC_LIBS@ TDB_CFLAGS = @TDB_CFLAGS@ TDB_LIBS = @TDB_LIBS@ TEST_DIR = @TEST_DIR@ TEVENT_CFLAGS = @TEVENT_CFLAGS@ TEVENT_LIBS = @TEVENT_LIBS@ UNICODE_LIBS = @UNICODE_LIBS@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ XMLLINT = @XMLLINT@ XSLTPROC = @XSLTPROC@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ appmodpath = @appmodpath@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ cifspluginpath = @cifspluginpath@ config_def_ccache_dir = @config_def_ccache_dir@ config_def_ccname_template = @config_def_ccname_template@ datadir = @datadir@ datarootdir = @datarootdir@ dbpath = @dbpath@ docdir = @docdir@ dvidir = @dvidir@ environment_file = @environment_file@ exec_prefix = @exec_prefix@ gpocachepath = @gpocachepath@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ initdir = @initdir@ install_sh = @install_sh@ krb5authdatapluginpath = @krb5authdatapluginpath@ krb5pluginpath = @krb5pluginpath@ krb5rcachedir = @krb5rcachedir@ ldblibdir = @ldblibdir@ libdir = @libdir@ libexecdir = @libexecdir@ libwbclient_version = @libwbclient_version@ libwbclient_version_info = @libwbclient_version_info@ localedir = @localedir@ localstatedir = @localstatedir@ logpath = @logpath@ mandir = @mandir@ mcpath = @mcpath@ mkdir_p = @mkdir_p@ nfsidmaplibdir = @nfsidmaplibdir@ nfslibpath = @nfslibpath@ nsslibdir = @nsslibdir@ oldincludedir = @oldincludedir@ pammoddir = @pammoddir@ pdfdir = @pdfdir@ pidpath = @pidpath@ pipepath = @pipepath@ pkgpyexecdir = @pkgpyexecdir@ pkgpythondir = @pkgpythondir@ pluginpath = @pluginpath@ polkitdir = @polkitdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pubconfpath = @pubconfpath@ py2execdir = @py2execdir@ py3execdir = @py3execdir@ pyexecdir = @pyexecdir@ python2dir = @python2dir@ python3dir = @python3dir@ pythondir = @pythondir@ sbindir = @sbindir@ sharedbuilddir = @sharedbuilddir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sudolibpath = @sudolibpath@ sysconfdir = @sysconfdir@ systemdconfdir = @systemdconfdir@ systemdunitdir = @systemdunitdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = \ -std=gnu99 \ -Wall \ -I$(top_srcdir)/src \ -I. \ -DLOCALEDIR=\"$(localedir)\" \ -DLIBDIR=\"$(libdir)\" \ -DVARDIR=\"$(localstatedir)\" \ -DSSS_STATEDIR=\"$(localstatedir)/lib/sss\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \ $(DBUS_CFLAGS) \ $(GLIB2_CFLAGS) \ $(NULL) TESTS_ENVIRONMENT = \ CWRAP_TEST_SRCDIR=$(abs_srcdir) \ . $(srcdir)/cwrap_test_setup.sh; \ $(AUX_TESTS_ENVIRONMENT) \ $(NULL) dist_noinst_SCRIPTS = \ cwrap_test_setup.sh \ $(NULL) SSSD_LIBS = \ $(TALLOC_LIBS) \ $(TEVENT_LIBS) \ $(POPT_LIBS) \ $(LDB_LIBS) \ $(DBUS_LIBS) \ $(PCRE_LIBS) \ $(INI_CONFIG_LIBS) \ $(COLLECTION_LIBS) \ $(DHASH_LIBS) \ $(SSS_CRYPT_LIBS) \ $(OPENLDAP_LIBS) \ $(TDB_LIBS) dist_noinst_DATA = \ group \ passwd \ $(NULL) TESTS = $(check_PROGRAMS) become_user_tests_SOURCES = \ test_become_user.c \ $(NULL) become_user_tests_CFLAGS = \ $(AM_CFLAGS) \ $(NULL) become_user_tests_LDADD = \ $(POPT_LIBS) \ $(CMOCKA_LIBS) \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_test_common.la \ $(NULL) server_tests_SOURCES = \ test_server.c \ ../../../src/util/server.c \ ../../../src/util/become_user.c \ ../../../src/util/backup_file.c \ ../../../src/util/domain_info_utils.c \ ../../../src/util/atomic_io.c \ ../../../src/util/signal.c \ ../../../src/util/util.c \ ../../../src/util/string_utils.c \ ../../../src/util/strtonum.c \ ../../../src/util/util_errors.c \ ../../../src/util/safe-format-string.c \ ../../../src/util/sss_tc_utf8.c \ ../../../src/util/sss_utf8.c \ ../../../src/util/usertools.c \ ../../../src/confdb/confdb.c \ ../../../src/db/sysdb.c \ ../../../src/db/sysdb_upgrade.c \ ../../../src/db/sysdb_ops.c \ ../../../src/db/sysdb_search.c \ ../../../src/db/sysdb_autofs.c \ ../../../src/db/sysdb_services.c \ ../../../src/db/sysdb_views.c \ $(NULL) server_tests_CFLAGS = \ $(AM_CFLAGS) \ $(LIBCAPNG_CFLAGS) \ -DTEST_DB_PATH=\"server_tests\" \ -DTEST_PID_PATH=\"server_tests\" \ -DUNIT_TESTING \ $(NULL) server_tests_LDADD = \ $(CMOCKA_LIBS) \ $(LIBCAPNG_LIBS) \ $(UNICODE_LIBS) \ $(SSSD_LIBS) \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_crypt.la \ $(abs_top_builddir)/libsss_test_common.la \ $(abs_top_builddir)/libsss_cert.la \ $(NULL) usertools_tests_SOURCES = \ test_usertools.c \ ../../../src/util/domain_info_utils.c \ ../../../src/util/safe-format-string.c \ ../../../src/util/usertools.c \ ../../../src/util/string_utils.c \ ../../../src/util/strtonum.c \ ../../../src/util/backup_file.c \ ../../../src/util/atomic_io.c \ ../../../src/util/util.c \ ../../../src/util/util_errors.c \ ../../../src/util/sss_tc_utf8.c \ ../../../src/util/sss_utf8.c \ ../../../src/confdb/confdb.c \ ../../../src/db/sysdb.c \ ../../../src/db/sysdb_upgrade.c \ ../../../src/db/sysdb_autofs.c \ ../../../src/db/sysdb_search.c \ ../../../src/db/sysdb_services.c \ ../../../src/db/sysdb_ops.c \ ../../../src/db/sysdb_views.c \ $(NULL) usertools_tests_CFLAGS = \ $(AM_CFLAGS) \ $(NULL) usertools_tests_LDADD = \ $(CMOCKA_LIBS) \ $(UNICODE_LIBS) \ $(SSSD_LIBS) \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_crypt.la \ $(abs_top_builddir)/libsss_test_common.la \ $(abs_top_builddir)/libsss_cert.la \ $(NULL) responder_common_tests_SOURCES = \ test_responder_common.c \ ../../../src/responder/common/responder_common.c \ ../../../src/responder/common/responder_packet.c \ ../../../src/responder/common/responder_cmd.c \ $(NULL) responder_common_tests_CFLAGS = \ $(AM_CFLAGS) \ $(NULL) responder_common_tests_LDADD = \ $(CMOCKA_LIBS) \ $(UNICODE_LIBS) \ $(SSSD_LIBS) \ $(abs_top_builddir)/libsss_util.la \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_crypt.la \ $(abs_top_builddir)/libsss_test_common.la \ $(NULL) all: all-am .SUFFIXES: .SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tests/cwrap/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign src/tests/cwrap/Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list become_user-tests$(EXEEXT): $(become_user_tests_OBJECTS) $(become_user_tests_DEPENDENCIES) $(EXTRA_become_user_tests_DEPENDENCIES) @rm -f become_user-tests$(EXEEXT) $(AM_V_CCLD)$(become_user_tests_LINK) $(become_user_tests_OBJECTS) $(become_user_tests_LDADD) $(LIBS) ../../../src/responder/common/$(am__dirstamp): @$(MKDIR_P) ../../../src/responder/common @: > ../../../src/responder/common/$(am__dirstamp) ../../../src/responder/common/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../../../src/responder/common/$(DEPDIR) @: > ../../../src/responder/common/$(DEPDIR)/$(am__dirstamp) ../../../src/responder/common/responder_common_tests-responder_common.$(OBJEXT): \ ../../../src/responder/common/$(am__dirstamp) \ ../../../src/responder/common/$(DEPDIR)/$(am__dirstamp) ../../../src/responder/common/responder_common_tests-responder_packet.$(OBJEXT): \ ../../../src/responder/common/$(am__dirstamp) \ ../../../src/responder/common/$(DEPDIR)/$(am__dirstamp) ../../../src/responder/common/responder_common_tests-responder_cmd.$(OBJEXT): \ ../../../src/responder/common/$(am__dirstamp) \ ../../../src/responder/common/$(DEPDIR)/$(am__dirstamp) responder_common-tests$(EXEEXT): $(responder_common_tests_OBJECTS) $(responder_common_tests_DEPENDENCIES) $(EXTRA_responder_common_tests_DEPENDENCIES) @rm -f responder_common-tests$(EXEEXT) $(AM_V_CCLD)$(responder_common_tests_LINK) $(responder_common_tests_OBJECTS) $(responder_common_tests_LDADD) $(LIBS) ../../../src/util/$(am__dirstamp): @$(MKDIR_P) ../../../src/util @: > ../../../src/util/$(am__dirstamp) ../../../src/util/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../../../src/util/$(DEPDIR) @: > ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-server.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-become_user.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-backup_file.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-domain_info_utils.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-atomic_io.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-signal.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-util.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-string_utils.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-strtonum.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-util_errors.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-safe-format-string.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-sss_tc_utf8.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-sss_utf8.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/server_tests-usertools.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/confdb/$(am__dirstamp): @$(MKDIR_P) ../../../src/confdb @: > ../../../src/confdb/$(am__dirstamp) ../../../src/confdb/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../../../src/confdb/$(DEPDIR) @: > ../../../src/confdb/$(DEPDIR)/$(am__dirstamp) ../../../src/confdb/server_tests-confdb.$(OBJEXT): \ ../../../src/confdb/$(am__dirstamp) \ ../../../src/confdb/$(DEPDIR)/$(am__dirstamp) ../../../src/db/$(am__dirstamp): @$(MKDIR_P) ../../../src/db @: > ../../../src/db/$(am__dirstamp) ../../../src/db/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) ../../../src/db/$(DEPDIR) @: > ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/server_tests-sysdb.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/server_tests-sysdb_upgrade.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/server_tests-sysdb_ops.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/server_tests-sysdb_search.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/server_tests-sysdb_autofs.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/server_tests-sysdb_services.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/server_tests-sysdb_views.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) server-tests$(EXEEXT): $(server_tests_OBJECTS) $(server_tests_DEPENDENCIES) $(EXTRA_server_tests_DEPENDENCIES) @rm -f server-tests$(EXEEXT) $(AM_V_CCLD)$(server_tests_LINK) $(server_tests_OBJECTS) $(server_tests_LDADD) $(LIBS) ../../../src/util/usertools_tests-domain_info_utils.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/usertools_tests-safe-format-string.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/usertools_tests-usertools.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/usertools_tests-string_utils.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/usertools_tests-strtonum.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/usertools_tests-backup_file.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/usertools_tests-atomic_io.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/usertools_tests-util.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/usertools_tests-util_errors.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/usertools_tests-sss_tc_utf8.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/util/usertools_tests-sss_utf8.$(OBJEXT): \ ../../../src/util/$(am__dirstamp) \ ../../../src/util/$(DEPDIR)/$(am__dirstamp) ../../../src/confdb/usertools_tests-confdb.$(OBJEXT): \ ../../../src/confdb/$(am__dirstamp) \ ../../../src/confdb/$(DEPDIR)/$(am__dirstamp) ../../../src/db/usertools_tests-sysdb.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/usertools_tests-sysdb_upgrade.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/usertools_tests-sysdb_autofs.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/usertools_tests-sysdb_search.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/usertools_tests-sysdb_services.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/usertools_tests-sysdb_ops.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) ../../../src/db/usertools_tests-sysdb_views.$(OBJEXT): \ ../../../src/db/$(am__dirstamp) \ ../../../src/db/$(DEPDIR)/$(am__dirstamp) usertools-tests$(EXEEXT): $(usertools_tests_OBJECTS) $(usertools_tests_DEPENDENCIES) $(EXTRA_usertools_tests_DEPENDENCIES) @rm -f usertools-tests$(EXEEXT) $(AM_V_CCLD)$(usertools_tests_LINK) $(usertools_tests_OBJECTS) $(usertools_tests_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f ../../../src/confdb/*.$(OBJEXT) -rm -f ../../../src/db/*.$(OBJEXT) -rm -f ../../../src/responder/common/*.$(OBJEXT) -rm -f ../../../src/util/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@../../../src/confdb/$(DEPDIR)/server_tests-confdb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/confdb/$(DEPDIR)/usertools_tests-confdb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/server_tests-sysdb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/server_tests-sysdb_autofs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/server_tests-sysdb_ops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/server_tests-sysdb_search.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/server_tests-sysdb_services.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/server_tests-sysdb_upgrade.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/server_tests-sysdb_views.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/usertools_tests-sysdb.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/usertools_tests-sysdb_autofs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/usertools_tests-sysdb_ops.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/usertools_tests-sysdb_search.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/usertools_tests-sysdb_services.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/usertools_tests-sysdb_upgrade.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/db/$(DEPDIR)/usertools_tests-sysdb_views.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_cmd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-atomic_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-backup_file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-become_user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-domain_info_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-safe-format-string.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-server.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-signal.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-sss_tc_utf8.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-sss_utf8.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-string_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-strtonum.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-usertools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/server_tests-util_errors.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/usertools_tests-atomic_io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/usertools_tests-backup_file.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/usertools_tests-domain_info_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/usertools_tests-safe-format-string.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/usertools_tests-sss_tc_utf8.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/usertools_tests-sss_utf8.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/usertools_tests-string_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/usertools_tests-strtonum.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/usertools_tests-usertools.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/usertools_tests-util.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../../src/util/$(DEPDIR)/usertools_tests-util_errors.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/become_user_tests-test_become_user.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/responder_common_tests-test_responder_common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server_tests-test_server.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usertools_tests-test_usertools.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< become_user_tests-test_become_user.o: test_become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(become_user_tests_CFLAGS) $(CFLAGS) -MT become_user_tests-test_become_user.o -MD -MP -MF $(DEPDIR)/become_user_tests-test_become_user.Tpo -c -o become_user_tests-test_become_user.o `test -f 'test_become_user.c' || echo '$(srcdir)/'`test_become_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/become_user_tests-test_become_user.Tpo $(DEPDIR)/become_user_tests-test_become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_become_user.c' object='become_user_tests-test_become_user.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(become_user_tests_CFLAGS) $(CFLAGS) -c -o become_user_tests-test_become_user.o `test -f 'test_become_user.c' || echo '$(srcdir)/'`test_become_user.c become_user_tests-test_become_user.obj: test_become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(become_user_tests_CFLAGS) $(CFLAGS) -MT become_user_tests-test_become_user.obj -MD -MP -MF $(DEPDIR)/become_user_tests-test_become_user.Tpo -c -o become_user_tests-test_become_user.obj `if test -f 'test_become_user.c'; then $(CYGPATH_W) 'test_become_user.c'; else $(CYGPATH_W) '$(srcdir)/test_become_user.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/become_user_tests-test_become_user.Tpo $(DEPDIR)/become_user_tests-test_become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_become_user.c' object='become_user_tests-test_become_user.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(become_user_tests_CFLAGS) $(CFLAGS) -c -o become_user_tests-test_become_user.obj `if test -f 'test_become_user.c'; then $(CYGPATH_W) 'test_become_user.c'; else $(CYGPATH_W) '$(srcdir)/test_become_user.c'; fi` responder_common_tests-test_responder_common.o: test_responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -MT responder_common_tests-test_responder_common.o -MD -MP -MF $(DEPDIR)/responder_common_tests-test_responder_common.Tpo -c -o responder_common_tests-test_responder_common.o `test -f 'test_responder_common.c' || echo '$(srcdir)/'`test_responder_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/responder_common_tests-test_responder_common.Tpo $(DEPDIR)/responder_common_tests-test_responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_responder_common.c' object='responder_common_tests-test_responder_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -c -o responder_common_tests-test_responder_common.o `test -f 'test_responder_common.c' || echo '$(srcdir)/'`test_responder_common.c responder_common_tests-test_responder_common.obj: test_responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -MT responder_common_tests-test_responder_common.obj -MD -MP -MF $(DEPDIR)/responder_common_tests-test_responder_common.Tpo -c -o responder_common_tests-test_responder_common.obj `if test -f 'test_responder_common.c'; then $(CYGPATH_W) 'test_responder_common.c'; else $(CYGPATH_W) '$(srcdir)/test_responder_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/responder_common_tests-test_responder_common.Tpo $(DEPDIR)/responder_common_tests-test_responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_responder_common.c' object='responder_common_tests-test_responder_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -c -o responder_common_tests-test_responder_common.obj `if test -f 'test_responder_common.c'; then $(CYGPATH_W) 'test_responder_common.c'; else $(CYGPATH_W) '$(srcdir)/test_responder_common.c'; fi` ../../../src/responder/common/responder_common_tests-responder_common.o: ../../../src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -MT ../../../src/responder/common/responder_common_tests-responder_common.o -MD -MP -MF ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_common.Tpo -c -o ../../../src/responder/common/responder_common_tests-responder_common.o `test -f '../../../src/responder/common/responder_common.c' || echo '$(srcdir)/'`../../../src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_common.Tpo ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/responder/common/responder_common.c' object='../../../src/responder/common/responder_common_tests-responder_common.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/responder/common/responder_common_tests-responder_common.o `test -f '../../../src/responder/common/responder_common.c' || echo '$(srcdir)/'`../../../src/responder/common/responder_common.c ../../../src/responder/common/responder_common_tests-responder_common.obj: ../../../src/responder/common/responder_common.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -MT ../../../src/responder/common/responder_common_tests-responder_common.obj -MD -MP -MF ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_common.Tpo -c -o ../../../src/responder/common/responder_common_tests-responder_common.obj `if test -f '../../../src/responder/common/responder_common.c'; then $(CYGPATH_W) '../../../src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/responder/common/responder_common.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_common.Tpo ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_common.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/responder/common/responder_common.c' object='../../../src/responder/common/responder_common_tests-responder_common.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/responder/common/responder_common_tests-responder_common.obj `if test -f '../../../src/responder/common/responder_common.c'; then $(CYGPATH_W) '../../../src/responder/common/responder_common.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/responder/common/responder_common.c'; fi` ../../../src/responder/common/responder_common_tests-responder_packet.o: ../../../src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -MT ../../../src/responder/common/responder_common_tests-responder_packet.o -MD -MP -MF ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_packet.Tpo -c -o ../../../src/responder/common/responder_common_tests-responder_packet.o `test -f '../../../src/responder/common/responder_packet.c' || echo '$(srcdir)/'`../../../src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_packet.Tpo ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/responder/common/responder_packet.c' object='../../../src/responder/common/responder_common_tests-responder_packet.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/responder/common/responder_common_tests-responder_packet.o `test -f '../../../src/responder/common/responder_packet.c' || echo '$(srcdir)/'`../../../src/responder/common/responder_packet.c ../../../src/responder/common/responder_common_tests-responder_packet.obj: ../../../src/responder/common/responder_packet.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -MT ../../../src/responder/common/responder_common_tests-responder_packet.obj -MD -MP -MF ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_packet.Tpo -c -o ../../../src/responder/common/responder_common_tests-responder_packet.obj `if test -f '../../../src/responder/common/responder_packet.c'; then $(CYGPATH_W) '../../../src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/responder/common/responder_packet.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_packet.Tpo ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_packet.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/responder/common/responder_packet.c' object='../../../src/responder/common/responder_common_tests-responder_packet.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/responder/common/responder_common_tests-responder_packet.obj `if test -f '../../../src/responder/common/responder_packet.c'; then $(CYGPATH_W) '../../../src/responder/common/responder_packet.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/responder/common/responder_packet.c'; fi` ../../../src/responder/common/responder_common_tests-responder_cmd.o: ../../../src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -MT ../../../src/responder/common/responder_common_tests-responder_cmd.o -MD -MP -MF ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_cmd.Tpo -c -o ../../../src/responder/common/responder_common_tests-responder_cmd.o `test -f '../../../src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`../../../src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_cmd.Tpo ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/responder/common/responder_cmd.c' object='../../../src/responder/common/responder_common_tests-responder_cmd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/responder/common/responder_common_tests-responder_cmd.o `test -f '../../../src/responder/common/responder_cmd.c' || echo '$(srcdir)/'`../../../src/responder/common/responder_cmd.c ../../../src/responder/common/responder_common_tests-responder_cmd.obj: ../../../src/responder/common/responder_cmd.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -MT ../../../src/responder/common/responder_common_tests-responder_cmd.obj -MD -MP -MF ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_cmd.Tpo -c -o ../../../src/responder/common/responder_common_tests-responder_cmd.obj `if test -f '../../../src/responder/common/responder_cmd.c'; then $(CYGPATH_W) '../../../src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/responder/common/responder_cmd.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_cmd.Tpo ../../../src/responder/common/$(DEPDIR)/responder_common_tests-responder_cmd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/responder/common/responder_cmd.c' object='../../../src/responder/common/responder_common_tests-responder_cmd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(responder_common_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/responder/common/responder_common_tests-responder_cmd.obj `if test -f '../../../src/responder/common/responder_cmd.c'; then $(CYGPATH_W) '../../../src/responder/common/responder_cmd.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/responder/common/responder_cmd.c'; fi` server_tests-test_server.o: test_server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT server_tests-test_server.o -MD -MP -MF $(DEPDIR)/server_tests-test_server.Tpo -c -o server_tests-test_server.o `test -f 'test_server.c' || echo '$(srcdir)/'`test_server.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_tests-test_server.Tpo $(DEPDIR)/server_tests-test_server.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_server.c' object='server_tests-test_server.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o server_tests-test_server.o `test -f 'test_server.c' || echo '$(srcdir)/'`test_server.c server_tests-test_server.obj: test_server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT server_tests-test_server.obj -MD -MP -MF $(DEPDIR)/server_tests-test_server.Tpo -c -o server_tests-test_server.obj `if test -f 'test_server.c'; then $(CYGPATH_W) 'test_server.c'; else $(CYGPATH_W) '$(srcdir)/test_server.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/server_tests-test_server.Tpo $(DEPDIR)/server_tests-test_server.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_server.c' object='server_tests-test_server.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o server_tests-test_server.obj `if test -f 'test_server.c'; then $(CYGPATH_W) 'test_server.c'; else $(CYGPATH_W) '$(srcdir)/test_server.c'; fi` ../../../src/util/server_tests-server.o: ../../../src/util/server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-server.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-server.Tpo -c -o ../../../src/util/server_tests-server.o `test -f '../../../src/util/server.c' || echo '$(srcdir)/'`../../../src/util/server.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-server.Tpo ../../../src/util/$(DEPDIR)/server_tests-server.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/server.c' object='../../../src/util/server_tests-server.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-server.o `test -f '../../../src/util/server.c' || echo '$(srcdir)/'`../../../src/util/server.c ../../../src/util/server_tests-server.obj: ../../../src/util/server.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-server.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-server.Tpo -c -o ../../../src/util/server_tests-server.obj `if test -f '../../../src/util/server.c'; then $(CYGPATH_W) '../../../src/util/server.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/server.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-server.Tpo ../../../src/util/$(DEPDIR)/server_tests-server.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/server.c' object='../../../src/util/server_tests-server.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-server.obj `if test -f '../../../src/util/server.c'; then $(CYGPATH_W) '../../../src/util/server.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/server.c'; fi` ../../../src/util/server_tests-become_user.o: ../../../src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-become_user.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-become_user.Tpo -c -o ../../../src/util/server_tests-become_user.o `test -f '../../../src/util/become_user.c' || echo '$(srcdir)/'`../../../src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-become_user.Tpo ../../../src/util/$(DEPDIR)/server_tests-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/become_user.c' object='../../../src/util/server_tests-become_user.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-become_user.o `test -f '../../../src/util/become_user.c' || echo '$(srcdir)/'`../../../src/util/become_user.c ../../../src/util/server_tests-become_user.obj: ../../../src/util/become_user.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-become_user.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-become_user.Tpo -c -o ../../../src/util/server_tests-become_user.obj `if test -f '../../../src/util/become_user.c'; then $(CYGPATH_W) '../../../src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/become_user.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-become_user.Tpo ../../../src/util/$(DEPDIR)/server_tests-become_user.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/become_user.c' object='../../../src/util/server_tests-become_user.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-become_user.obj `if test -f '../../../src/util/become_user.c'; then $(CYGPATH_W) '../../../src/util/become_user.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/become_user.c'; fi` ../../../src/util/server_tests-backup_file.o: ../../../src/util/backup_file.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-backup_file.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-backup_file.Tpo -c -o ../../../src/util/server_tests-backup_file.o `test -f '../../../src/util/backup_file.c' || echo '$(srcdir)/'`../../../src/util/backup_file.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-backup_file.Tpo ../../../src/util/$(DEPDIR)/server_tests-backup_file.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/backup_file.c' object='../../../src/util/server_tests-backup_file.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-backup_file.o `test -f '../../../src/util/backup_file.c' || echo '$(srcdir)/'`../../../src/util/backup_file.c ../../../src/util/server_tests-backup_file.obj: ../../../src/util/backup_file.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-backup_file.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-backup_file.Tpo -c -o ../../../src/util/server_tests-backup_file.obj `if test -f '../../../src/util/backup_file.c'; then $(CYGPATH_W) '../../../src/util/backup_file.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/backup_file.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-backup_file.Tpo ../../../src/util/$(DEPDIR)/server_tests-backup_file.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/backup_file.c' object='../../../src/util/server_tests-backup_file.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-backup_file.obj `if test -f '../../../src/util/backup_file.c'; then $(CYGPATH_W) '../../../src/util/backup_file.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/backup_file.c'; fi` ../../../src/util/server_tests-domain_info_utils.o: ../../../src/util/domain_info_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-domain_info_utils.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-domain_info_utils.Tpo -c -o ../../../src/util/server_tests-domain_info_utils.o `test -f '../../../src/util/domain_info_utils.c' || echo '$(srcdir)/'`../../../src/util/domain_info_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-domain_info_utils.Tpo ../../../src/util/$(DEPDIR)/server_tests-domain_info_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/domain_info_utils.c' object='../../../src/util/server_tests-domain_info_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-domain_info_utils.o `test -f '../../../src/util/domain_info_utils.c' || echo '$(srcdir)/'`../../../src/util/domain_info_utils.c ../../../src/util/server_tests-domain_info_utils.obj: ../../../src/util/domain_info_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-domain_info_utils.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-domain_info_utils.Tpo -c -o ../../../src/util/server_tests-domain_info_utils.obj `if test -f '../../../src/util/domain_info_utils.c'; then $(CYGPATH_W) '../../../src/util/domain_info_utils.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/domain_info_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-domain_info_utils.Tpo ../../../src/util/$(DEPDIR)/server_tests-domain_info_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/domain_info_utils.c' object='../../../src/util/server_tests-domain_info_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-domain_info_utils.obj `if test -f '../../../src/util/domain_info_utils.c'; then $(CYGPATH_W) '../../../src/util/domain_info_utils.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/domain_info_utils.c'; fi` ../../../src/util/server_tests-atomic_io.o: ../../../src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-atomic_io.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-atomic_io.Tpo -c -o ../../../src/util/server_tests-atomic_io.o `test -f '../../../src/util/atomic_io.c' || echo '$(srcdir)/'`../../../src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-atomic_io.Tpo ../../../src/util/$(DEPDIR)/server_tests-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/atomic_io.c' object='../../../src/util/server_tests-atomic_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-atomic_io.o `test -f '../../../src/util/atomic_io.c' || echo '$(srcdir)/'`../../../src/util/atomic_io.c ../../../src/util/server_tests-atomic_io.obj: ../../../src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-atomic_io.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-atomic_io.Tpo -c -o ../../../src/util/server_tests-atomic_io.obj `if test -f '../../../src/util/atomic_io.c'; then $(CYGPATH_W) '../../../src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/atomic_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-atomic_io.Tpo ../../../src/util/$(DEPDIR)/server_tests-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/atomic_io.c' object='../../../src/util/server_tests-atomic_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-atomic_io.obj `if test -f '../../../src/util/atomic_io.c'; then $(CYGPATH_W) '../../../src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/atomic_io.c'; fi` ../../../src/util/server_tests-signal.o: ../../../src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-signal.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-signal.Tpo -c -o ../../../src/util/server_tests-signal.o `test -f '../../../src/util/signal.c' || echo '$(srcdir)/'`../../../src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-signal.Tpo ../../../src/util/$(DEPDIR)/server_tests-signal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/signal.c' object='../../../src/util/server_tests-signal.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-signal.o `test -f '../../../src/util/signal.c' || echo '$(srcdir)/'`../../../src/util/signal.c ../../../src/util/server_tests-signal.obj: ../../../src/util/signal.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-signal.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-signal.Tpo -c -o ../../../src/util/server_tests-signal.obj `if test -f '../../../src/util/signal.c'; then $(CYGPATH_W) '../../../src/util/signal.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/signal.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-signal.Tpo ../../../src/util/$(DEPDIR)/server_tests-signal.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/signal.c' object='../../../src/util/server_tests-signal.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-signal.obj `if test -f '../../../src/util/signal.c'; then $(CYGPATH_W) '../../../src/util/signal.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/signal.c'; fi` ../../../src/util/server_tests-util.o: ../../../src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-util.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-util.Tpo -c -o ../../../src/util/server_tests-util.o `test -f '../../../src/util/util.c' || echo '$(srcdir)/'`../../../src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-util.Tpo ../../../src/util/$(DEPDIR)/server_tests-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/util.c' object='../../../src/util/server_tests-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-util.o `test -f '../../../src/util/util.c' || echo '$(srcdir)/'`../../../src/util/util.c ../../../src/util/server_tests-util.obj: ../../../src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-util.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-util.Tpo -c -o ../../../src/util/server_tests-util.obj `if test -f '../../../src/util/util.c'; then $(CYGPATH_W) '../../../src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-util.Tpo ../../../src/util/$(DEPDIR)/server_tests-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/util.c' object='../../../src/util/server_tests-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-util.obj `if test -f '../../../src/util/util.c'; then $(CYGPATH_W) '../../../src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/util.c'; fi` ../../../src/util/server_tests-string_utils.o: ../../../src/util/string_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-string_utils.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-string_utils.Tpo -c -o ../../../src/util/server_tests-string_utils.o `test -f '../../../src/util/string_utils.c' || echo '$(srcdir)/'`../../../src/util/string_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-string_utils.Tpo ../../../src/util/$(DEPDIR)/server_tests-string_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/string_utils.c' object='../../../src/util/server_tests-string_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-string_utils.o `test -f '../../../src/util/string_utils.c' || echo '$(srcdir)/'`../../../src/util/string_utils.c ../../../src/util/server_tests-string_utils.obj: ../../../src/util/string_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-string_utils.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-string_utils.Tpo -c -o ../../../src/util/server_tests-string_utils.obj `if test -f '../../../src/util/string_utils.c'; then $(CYGPATH_W) '../../../src/util/string_utils.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/string_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-string_utils.Tpo ../../../src/util/$(DEPDIR)/server_tests-string_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/string_utils.c' object='../../../src/util/server_tests-string_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-string_utils.obj `if test -f '../../../src/util/string_utils.c'; then $(CYGPATH_W) '../../../src/util/string_utils.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/string_utils.c'; fi` ../../../src/util/server_tests-strtonum.o: ../../../src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-strtonum.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-strtonum.Tpo -c -o ../../../src/util/server_tests-strtonum.o `test -f '../../../src/util/strtonum.c' || echo '$(srcdir)/'`../../../src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-strtonum.Tpo ../../../src/util/$(DEPDIR)/server_tests-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/strtonum.c' object='../../../src/util/server_tests-strtonum.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-strtonum.o `test -f '../../../src/util/strtonum.c' || echo '$(srcdir)/'`../../../src/util/strtonum.c ../../../src/util/server_tests-strtonum.obj: ../../../src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-strtonum.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-strtonum.Tpo -c -o ../../../src/util/server_tests-strtonum.obj `if test -f '../../../src/util/strtonum.c'; then $(CYGPATH_W) '../../../src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/strtonum.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-strtonum.Tpo ../../../src/util/$(DEPDIR)/server_tests-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/strtonum.c' object='../../../src/util/server_tests-strtonum.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-strtonum.obj `if test -f '../../../src/util/strtonum.c'; then $(CYGPATH_W) '../../../src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/strtonum.c'; fi` ../../../src/util/server_tests-util_errors.o: ../../../src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-util_errors.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-util_errors.Tpo -c -o ../../../src/util/server_tests-util_errors.o `test -f '../../../src/util/util_errors.c' || echo '$(srcdir)/'`../../../src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-util_errors.Tpo ../../../src/util/$(DEPDIR)/server_tests-util_errors.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/util_errors.c' object='../../../src/util/server_tests-util_errors.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-util_errors.o `test -f '../../../src/util/util_errors.c' || echo '$(srcdir)/'`../../../src/util/util_errors.c ../../../src/util/server_tests-util_errors.obj: ../../../src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-util_errors.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-util_errors.Tpo -c -o ../../../src/util/server_tests-util_errors.obj `if test -f '../../../src/util/util_errors.c'; then $(CYGPATH_W) '../../../src/util/util_errors.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/util_errors.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-util_errors.Tpo ../../../src/util/$(DEPDIR)/server_tests-util_errors.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/util_errors.c' object='../../../src/util/server_tests-util_errors.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-util_errors.obj `if test -f '../../../src/util/util_errors.c'; then $(CYGPATH_W) '../../../src/util/util_errors.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/util_errors.c'; fi` ../../../src/util/server_tests-safe-format-string.o: ../../../src/util/safe-format-string.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-safe-format-string.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-safe-format-string.Tpo -c -o ../../../src/util/server_tests-safe-format-string.o `test -f '../../../src/util/safe-format-string.c' || echo '$(srcdir)/'`../../../src/util/safe-format-string.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-safe-format-string.Tpo ../../../src/util/$(DEPDIR)/server_tests-safe-format-string.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/safe-format-string.c' object='../../../src/util/server_tests-safe-format-string.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-safe-format-string.o `test -f '../../../src/util/safe-format-string.c' || echo '$(srcdir)/'`../../../src/util/safe-format-string.c ../../../src/util/server_tests-safe-format-string.obj: ../../../src/util/safe-format-string.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-safe-format-string.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-safe-format-string.Tpo -c -o ../../../src/util/server_tests-safe-format-string.obj `if test -f '../../../src/util/safe-format-string.c'; then $(CYGPATH_W) '../../../src/util/safe-format-string.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/safe-format-string.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-safe-format-string.Tpo ../../../src/util/$(DEPDIR)/server_tests-safe-format-string.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/safe-format-string.c' object='../../../src/util/server_tests-safe-format-string.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-safe-format-string.obj `if test -f '../../../src/util/safe-format-string.c'; then $(CYGPATH_W) '../../../src/util/safe-format-string.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/safe-format-string.c'; fi` ../../../src/util/server_tests-sss_tc_utf8.o: ../../../src/util/sss_tc_utf8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-sss_tc_utf8.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-sss_tc_utf8.Tpo -c -o ../../../src/util/server_tests-sss_tc_utf8.o `test -f '../../../src/util/sss_tc_utf8.c' || echo '$(srcdir)/'`../../../src/util/sss_tc_utf8.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-sss_tc_utf8.Tpo ../../../src/util/$(DEPDIR)/server_tests-sss_tc_utf8.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/sss_tc_utf8.c' object='../../../src/util/server_tests-sss_tc_utf8.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-sss_tc_utf8.o `test -f '../../../src/util/sss_tc_utf8.c' || echo '$(srcdir)/'`../../../src/util/sss_tc_utf8.c ../../../src/util/server_tests-sss_tc_utf8.obj: ../../../src/util/sss_tc_utf8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-sss_tc_utf8.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-sss_tc_utf8.Tpo -c -o ../../../src/util/server_tests-sss_tc_utf8.obj `if test -f '../../../src/util/sss_tc_utf8.c'; then $(CYGPATH_W) '../../../src/util/sss_tc_utf8.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/sss_tc_utf8.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-sss_tc_utf8.Tpo ../../../src/util/$(DEPDIR)/server_tests-sss_tc_utf8.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/sss_tc_utf8.c' object='../../../src/util/server_tests-sss_tc_utf8.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-sss_tc_utf8.obj `if test -f '../../../src/util/sss_tc_utf8.c'; then $(CYGPATH_W) '../../../src/util/sss_tc_utf8.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/sss_tc_utf8.c'; fi` ../../../src/util/server_tests-sss_utf8.o: ../../../src/util/sss_utf8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-sss_utf8.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-sss_utf8.Tpo -c -o ../../../src/util/server_tests-sss_utf8.o `test -f '../../../src/util/sss_utf8.c' || echo '$(srcdir)/'`../../../src/util/sss_utf8.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-sss_utf8.Tpo ../../../src/util/$(DEPDIR)/server_tests-sss_utf8.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/sss_utf8.c' object='../../../src/util/server_tests-sss_utf8.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-sss_utf8.o `test -f '../../../src/util/sss_utf8.c' || echo '$(srcdir)/'`../../../src/util/sss_utf8.c ../../../src/util/server_tests-sss_utf8.obj: ../../../src/util/sss_utf8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-sss_utf8.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-sss_utf8.Tpo -c -o ../../../src/util/server_tests-sss_utf8.obj `if test -f '../../../src/util/sss_utf8.c'; then $(CYGPATH_W) '../../../src/util/sss_utf8.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/sss_utf8.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-sss_utf8.Tpo ../../../src/util/$(DEPDIR)/server_tests-sss_utf8.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/sss_utf8.c' object='../../../src/util/server_tests-sss_utf8.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-sss_utf8.obj `if test -f '../../../src/util/sss_utf8.c'; then $(CYGPATH_W) '../../../src/util/sss_utf8.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/sss_utf8.c'; fi` ../../../src/util/server_tests-usertools.o: ../../../src/util/usertools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-usertools.o -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-usertools.Tpo -c -o ../../../src/util/server_tests-usertools.o `test -f '../../../src/util/usertools.c' || echo '$(srcdir)/'`../../../src/util/usertools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-usertools.Tpo ../../../src/util/$(DEPDIR)/server_tests-usertools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/usertools.c' object='../../../src/util/server_tests-usertools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-usertools.o `test -f '../../../src/util/usertools.c' || echo '$(srcdir)/'`../../../src/util/usertools.c ../../../src/util/server_tests-usertools.obj: ../../../src/util/usertools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/server_tests-usertools.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/server_tests-usertools.Tpo -c -o ../../../src/util/server_tests-usertools.obj `if test -f '../../../src/util/usertools.c'; then $(CYGPATH_W) '../../../src/util/usertools.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/usertools.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/server_tests-usertools.Tpo ../../../src/util/$(DEPDIR)/server_tests-usertools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/usertools.c' object='../../../src/util/server_tests-usertools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/server_tests-usertools.obj `if test -f '../../../src/util/usertools.c'; then $(CYGPATH_W) '../../../src/util/usertools.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/usertools.c'; fi` ../../../src/confdb/server_tests-confdb.o: ../../../src/confdb/confdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/confdb/server_tests-confdb.o -MD -MP -MF ../../../src/confdb/$(DEPDIR)/server_tests-confdb.Tpo -c -o ../../../src/confdb/server_tests-confdb.o `test -f '../../../src/confdb/confdb.c' || echo '$(srcdir)/'`../../../src/confdb/confdb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/confdb/$(DEPDIR)/server_tests-confdb.Tpo ../../../src/confdb/$(DEPDIR)/server_tests-confdb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/confdb/confdb.c' object='../../../src/confdb/server_tests-confdb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/confdb/server_tests-confdb.o `test -f '../../../src/confdb/confdb.c' || echo '$(srcdir)/'`../../../src/confdb/confdb.c ../../../src/confdb/server_tests-confdb.obj: ../../../src/confdb/confdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/confdb/server_tests-confdb.obj -MD -MP -MF ../../../src/confdb/$(DEPDIR)/server_tests-confdb.Tpo -c -o ../../../src/confdb/server_tests-confdb.obj `if test -f '../../../src/confdb/confdb.c'; then $(CYGPATH_W) '../../../src/confdb/confdb.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/confdb/confdb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/confdb/$(DEPDIR)/server_tests-confdb.Tpo ../../../src/confdb/$(DEPDIR)/server_tests-confdb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/confdb/confdb.c' object='../../../src/confdb/server_tests-confdb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/confdb/server_tests-confdb.obj `if test -f '../../../src/confdb/confdb.c'; then $(CYGPATH_W) '../../../src/confdb/confdb.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/confdb/confdb.c'; fi` ../../../src/db/server_tests-sysdb.o: ../../../src/db/sysdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb.o -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb.Tpo -c -o ../../../src/db/server_tests-sysdb.o `test -f '../../../src/db/sysdb.c' || echo '$(srcdir)/'`../../../src/db/sysdb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb.c' object='../../../src/db/server_tests-sysdb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb.o `test -f '../../../src/db/sysdb.c' || echo '$(srcdir)/'`../../../src/db/sysdb.c ../../../src/db/server_tests-sysdb.obj: ../../../src/db/sysdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb.Tpo -c -o ../../../src/db/server_tests-sysdb.obj `if test -f '../../../src/db/sysdb.c'; then $(CYGPATH_W) '../../../src/db/sysdb.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb.c' object='../../../src/db/server_tests-sysdb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb.obj `if test -f '../../../src/db/sysdb.c'; then $(CYGPATH_W) '../../../src/db/sysdb.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb.c'; fi` ../../../src/db/server_tests-sysdb_upgrade.o: ../../../src/db/sysdb_upgrade.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_upgrade.o -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_upgrade.Tpo -c -o ../../../src/db/server_tests-sysdb_upgrade.o `test -f '../../../src/db/sysdb_upgrade.c' || echo '$(srcdir)/'`../../../src/db/sysdb_upgrade.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_upgrade.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_upgrade.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_upgrade.c' object='../../../src/db/server_tests-sysdb_upgrade.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_upgrade.o `test -f '../../../src/db/sysdb_upgrade.c' || echo '$(srcdir)/'`../../../src/db/sysdb_upgrade.c ../../../src/db/server_tests-sysdb_upgrade.obj: ../../../src/db/sysdb_upgrade.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_upgrade.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_upgrade.Tpo -c -o ../../../src/db/server_tests-sysdb_upgrade.obj `if test -f '../../../src/db/sysdb_upgrade.c'; then $(CYGPATH_W) '../../../src/db/sysdb_upgrade.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_upgrade.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_upgrade.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_upgrade.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_upgrade.c' object='../../../src/db/server_tests-sysdb_upgrade.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_upgrade.obj `if test -f '../../../src/db/sysdb_upgrade.c'; then $(CYGPATH_W) '../../../src/db/sysdb_upgrade.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_upgrade.c'; fi` ../../../src/db/server_tests-sysdb_ops.o: ../../../src/db/sysdb_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_ops.o -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_ops.Tpo -c -o ../../../src/db/server_tests-sysdb_ops.o `test -f '../../../src/db/sysdb_ops.c' || echo '$(srcdir)/'`../../../src/db/sysdb_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_ops.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_ops.c' object='../../../src/db/server_tests-sysdb_ops.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_ops.o `test -f '../../../src/db/sysdb_ops.c' || echo '$(srcdir)/'`../../../src/db/sysdb_ops.c ../../../src/db/server_tests-sysdb_ops.obj: ../../../src/db/sysdb_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_ops.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_ops.Tpo -c -o ../../../src/db/server_tests-sysdb_ops.obj `if test -f '../../../src/db/sysdb_ops.c'; then $(CYGPATH_W) '../../../src/db/sysdb_ops.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_ops.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_ops.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_ops.c' object='../../../src/db/server_tests-sysdb_ops.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_ops.obj `if test -f '../../../src/db/sysdb_ops.c'; then $(CYGPATH_W) '../../../src/db/sysdb_ops.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_ops.c'; fi` ../../../src/db/server_tests-sysdb_search.o: ../../../src/db/sysdb_search.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_search.o -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_search.Tpo -c -o ../../../src/db/server_tests-sysdb_search.o `test -f '../../../src/db/sysdb_search.c' || echo '$(srcdir)/'`../../../src/db/sysdb_search.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_search.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_search.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_search.c' object='../../../src/db/server_tests-sysdb_search.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_search.o `test -f '../../../src/db/sysdb_search.c' || echo '$(srcdir)/'`../../../src/db/sysdb_search.c ../../../src/db/server_tests-sysdb_search.obj: ../../../src/db/sysdb_search.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_search.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_search.Tpo -c -o ../../../src/db/server_tests-sysdb_search.obj `if test -f '../../../src/db/sysdb_search.c'; then $(CYGPATH_W) '../../../src/db/sysdb_search.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_search.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_search.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_search.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_search.c' object='../../../src/db/server_tests-sysdb_search.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_search.obj `if test -f '../../../src/db/sysdb_search.c'; then $(CYGPATH_W) '../../../src/db/sysdb_search.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_search.c'; fi` ../../../src/db/server_tests-sysdb_autofs.o: ../../../src/db/sysdb_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_autofs.o -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_autofs.Tpo -c -o ../../../src/db/server_tests-sysdb_autofs.o `test -f '../../../src/db/sysdb_autofs.c' || echo '$(srcdir)/'`../../../src/db/sysdb_autofs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_autofs.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_autofs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_autofs.c' object='../../../src/db/server_tests-sysdb_autofs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_autofs.o `test -f '../../../src/db/sysdb_autofs.c' || echo '$(srcdir)/'`../../../src/db/sysdb_autofs.c ../../../src/db/server_tests-sysdb_autofs.obj: ../../../src/db/sysdb_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_autofs.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_autofs.Tpo -c -o ../../../src/db/server_tests-sysdb_autofs.obj `if test -f '../../../src/db/sysdb_autofs.c'; then $(CYGPATH_W) '../../../src/db/sysdb_autofs.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_autofs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_autofs.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_autofs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_autofs.c' object='../../../src/db/server_tests-sysdb_autofs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_autofs.obj `if test -f '../../../src/db/sysdb_autofs.c'; then $(CYGPATH_W) '../../../src/db/sysdb_autofs.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_autofs.c'; fi` ../../../src/db/server_tests-sysdb_services.o: ../../../src/db/sysdb_services.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_services.o -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_services.Tpo -c -o ../../../src/db/server_tests-sysdb_services.o `test -f '../../../src/db/sysdb_services.c' || echo '$(srcdir)/'`../../../src/db/sysdb_services.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_services.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_services.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_services.c' object='../../../src/db/server_tests-sysdb_services.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_services.o `test -f '../../../src/db/sysdb_services.c' || echo '$(srcdir)/'`../../../src/db/sysdb_services.c ../../../src/db/server_tests-sysdb_services.obj: ../../../src/db/sysdb_services.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_services.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_services.Tpo -c -o ../../../src/db/server_tests-sysdb_services.obj `if test -f '../../../src/db/sysdb_services.c'; then $(CYGPATH_W) '../../../src/db/sysdb_services.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_services.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_services.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_services.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_services.c' object='../../../src/db/server_tests-sysdb_services.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_services.obj `if test -f '../../../src/db/sysdb_services.c'; then $(CYGPATH_W) '../../../src/db/sysdb_services.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_services.c'; fi` ../../../src/db/server_tests-sysdb_views.o: ../../../src/db/sysdb_views.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_views.o -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_views.Tpo -c -o ../../../src/db/server_tests-sysdb_views.o `test -f '../../../src/db/sysdb_views.c' || echo '$(srcdir)/'`../../../src/db/sysdb_views.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_views.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_views.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_views.c' object='../../../src/db/server_tests-sysdb_views.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_views.o `test -f '../../../src/db/sysdb_views.c' || echo '$(srcdir)/'`../../../src/db/sysdb_views.c ../../../src/db/server_tests-sysdb_views.obj: ../../../src/db/sysdb_views.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/server_tests-sysdb_views.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/server_tests-sysdb_views.Tpo -c -o ../../../src/db/server_tests-sysdb_views.obj `if test -f '../../../src/db/sysdb_views.c'; then $(CYGPATH_W) '../../../src/db/sysdb_views.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_views.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/server_tests-sysdb_views.Tpo ../../../src/db/$(DEPDIR)/server_tests-sysdb_views.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_views.c' object='../../../src/db/server_tests-sysdb_views.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(server_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/server_tests-sysdb_views.obj `if test -f '../../../src/db/sysdb_views.c'; then $(CYGPATH_W) '../../../src/db/sysdb_views.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_views.c'; fi` usertools_tests-test_usertools.o: test_usertools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT usertools_tests-test_usertools.o -MD -MP -MF $(DEPDIR)/usertools_tests-test_usertools.Tpo -c -o usertools_tests-test_usertools.o `test -f 'test_usertools.c' || echo '$(srcdir)/'`test_usertools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/usertools_tests-test_usertools.Tpo $(DEPDIR)/usertools_tests-test_usertools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_usertools.c' object='usertools_tests-test_usertools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o usertools_tests-test_usertools.o `test -f 'test_usertools.c' || echo '$(srcdir)/'`test_usertools.c usertools_tests-test_usertools.obj: test_usertools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT usertools_tests-test_usertools.obj -MD -MP -MF $(DEPDIR)/usertools_tests-test_usertools.Tpo -c -o usertools_tests-test_usertools.obj `if test -f 'test_usertools.c'; then $(CYGPATH_W) 'test_usertools.c'; else $(CYGPATH_W) '$(srcdir)/test_usertools.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/usertools_tests-test_usertools.Tpo $(DEPDIR)/usertools_tests-test_usertools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='test_usertools.c' object='usertools_tests-test_usertools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o usertools_tests-test_usertools.obj `if test -f 'test_usertools.c'; then $(CYGPATH_W) 'test_usertools.c'; else $(CYGPATH_W) '$(srcdir)/test_usertools.c'; fi` ../../../src/util/usertools_tests-domain_info_utils.o: ../../../src/util/domain_info_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-domain_info_utils.o -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-domain_info_utils.Tpo -c -o ../../../src/util/usertools_tests-domain_info_utils.o `test -f '../../../src/util/domain_info_utils.c' || echo '$(srcdir)/'`../../../src/util/domain_info_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-domain_info_utils.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-domain_info_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/domain_info_utils.c' object='../../../src/util/usertools_tests-domain_info_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-domain_info_utils.o `test -f '../../../src/util/domain_info_utils.c' || echo '$(srcdir)/'`../../../src/util/domain_info_utils.c ../../../src/util/usertools_tests-domain_info_utils.obj: ../../../src/util/domain_info_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-domain_info_utils.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-domain_info_utils.Tpo -c -o ../../../src/util/usertools_tests-domain_info_utils.obj `if test -f '../../../src/util/domain_info_utils.c'; then $(CYGPATH_W) '../../../src/util/domain_info_utils.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/domain_info_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-domain_info_utils.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-domain_info_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/domain_info_utils.c' object='../../../src/util/usertools_tests-domain_info_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-domain_info_utils.obj `if test -f '../../../src/util/domain_info_utils.c'; then $(CYGPATH_W) '../../../src/util/domain_info_utils.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/domain_info_utils.c'; fi` ../../../src/util/usertools_tests-safe-format-string.o: ../../../src/util/safe-format-string.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-safe-format-string.o -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-safe-format-string.Tpo -c -o ../../../src/util/usertools_tests-safe-format-string.o `test -f '../../../src/util/safe-format-string.c' || echo '$(srcdir)/'`../../../src/util/safe-format-string.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-safe-format-string.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-safe-format-string.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/safe-format-string.c' object='../../../src/util/usertools_tests-safe-format-string.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-safe-format-string.o `test -f '../../../src/util/safe-format-string.c' || echo '$(srcdir)/'`../../../src/util/safe-format-string.c ../../../src/util/usertools_tests-safe-format-string.obj: ../../../src/util/safe-format-string.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-safe-format-string.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-safe-format-string.Tpo -c -o ../../../src/util/usertools_tests-safe-format-string.obj `if test -f '../../../src/util/safe-format-string.c'; then $(CYGPATH_W) '../../../src/util/safe-format-string.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/safe-format-string.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-safe-format-string.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-safe-format-string.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/safe-format-string.c' object='../../../src/util/usertools_tests-safe-format-string.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-safe-format-string.obj `if test -f '../../../src/util/safe-format-string.c'; then $(CYGPATH_W) '../../../src/util/safe-format-string.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/safe-format-string.c'; fi` ../../../src/util/usertools_tests-usertools.o: ../../../src/util/usertools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-usertools.o -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-usertools.Tpo -c -o ../../../src/util/usertools_tests-usertools.o `test -f '../../../src/util/usertools.c' || echo '$(srcdir)/'`../../../src/util/usertools.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-usertools.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-usertools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/usertools.c' object='../../../src/util/usertools_tests-usertools.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-usertools.o `test -f '../../../src/util/usertools.c' || echo '$(srcdir)/'`../../../src/util/usertools.c ../../../src/util/usertools_tests-usertools.obj: ../../../src/util/usertools.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-usertools.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-usertools.Tpo -c -o ../../../src/util/usertools_tests-usertools.obj `if test -f '../../../src/util/usertools.c'; then $(CYGPATH_W) '../../../src/util/usertools.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/usertools.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-usertools.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-usertools.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/usertools.c' object='../../../src/util/usertools_tests-usertools.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-usertools.obj `if test -f '../../../src/util/usertools.c'; then $(CYGPATH_W) '../../../src/util/usertools.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/usertools.c'; fi` ../../../src/util/usertools_tests-string_utils.o: ../../../src/util/string_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-string_utils.o -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-string_utils.Tpo -c -o ../../../src/util/usertools_tests-string_utils.o `test -f '../../../src/util/string_utils.c' || echo '$(srcdir)/'`../../../src/util/string_utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-string_utils.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-string_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/string_utils.c' object='../../../src/util/usertools_tests-string_utils.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-string_utils.o `test -f '../../../src/util/string_utils.c' || echo '$(srcdir)/'`../../../src/util/string_utils.c ../../../src/util/usertools_tests-string_utils.obj: ../../../src/util/string_utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-string_utils.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-string_utils.Tpo -c -o ../../../src/util/usertools_tests-string_utils.obj `if test -f '../../../src/util/string_utils.c'; then $(CYGPATH_W) '../../../src/util/string_utils.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/string_utils.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-string_utils.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-string_utils.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/string_utils.c' object='../../../src/util/usertools_tests-string_utils.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-string_utils.obj `if test -f '../../../src/util/string_utils.c'; then $(CYGPATH_W) '../../../src/util/string_utils.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/string_utils.c'; fi` ../../../src/util/usertools_tests-strtonum.o: ../../../src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-strtonum.o -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-strtonum.Tpo -c -o ../../../src/util/usertools_tests-strtonum.o `test -f '../../../src/util/strtonum.c' || echo '$(srcdir)/'`../../../src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-strtonum.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/strtonum.c' object='../../../src/util/usertools_tests-strtonum.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-strtonum.o `test -f '../../../src/util/strtonum.c' || echo '$(srcdir)/'`../../../src/util/strtonum.c ../../../src/util/usertools_tests-strtonum.obj: ../../../src/util/strtonum.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-strtonum.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-strtonum.Tpo -c -o ../../../src/util/usertools_tests-strtonum.obj `if test -f '../../../src/util/strtonum.c'; then $(CYGPATH_W) '../../../src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/strtonum.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-strtonum.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-strtonum.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/strtonum.c' object='../../../src/util/usertools_tests-strtonum.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-strtonum.obj `if test -f '../../../src/util/strtonum.c'; then $(CYGPATH_W) '../../../src/util/strtonum.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/strtonum.c'; fi` ../../../src/util/usertools_tests-backup_file.o: ../../../src/util/backup_file.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-backup_file.o -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-backup_file.Tpo -c -o ../../../src/util/usertools_tests-backup_file.o `test -f '../../../src/util/backup_file.c' || echo '$(srcdir)/'`../../../src/util/backup_file.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-backup_file.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-backup_file.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/backup_file.c' object='../../../src/util/usertools_tests-backup_file.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-backup_file.o `test -f '../../../src/util/backup_file.c' || echo '$(srcdir)/'`../../../src/util/backup_file.c ../../../src/util/usertools_tests-backup_file.obj: ../../../src/util/backup_file.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-backup_file.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-backup_file.Tpo -c -o ../../../src/util/usertools_tests-backup_file.obj `if test -f '../../../src/util/backup_file.c'; then $(CYGPATH_W) '../../../src/util/backup_file.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/backup_file.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-backup_file.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-backup_file.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/backup_file.c' object='../../../src/util/usertools_tests-backup_file.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-backup_file.obj `if test -f '../../../src/util/backup_file.c'; then $(CYGPATH_W) '../../../src/util/backup_file.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/backup_file.c'; fi` ../../../src/util/usertools_tests-atomic_io.o: ../../../src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-atomic_io.o -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-atomic_io.Tpo -c -o ../../../src/util/usertools_tests-atomic_io.o `test -f '../../../src/util/atomic_io.c' || echo '$(srcdir)/'`../../../src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-atomic_io.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/atomic_io.c' object='../../../src/util/usertools_tests-atomic_io.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-atomic_io.o `test -f '../../../src/util/atomic_io.c' || echo '$(srcdir)/'`../../../src/util/atomic_io.c ../../../src/util/usertools_tests-atomic_io.obj: ../../../src/util/atomic_io.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-atomic_io.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-atomic_io.Tpo -c -o ../../../src/util/usertools_tests-atomic_io.obj `if test -f '../../../src/util/atomic_io.c'; then $(CYGPATH_W) '../../../src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/atomic_io.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-atomic_io.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-atomic_io.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/atomic_io.c' object='../../../src/util/usertools_tests-atomic_io.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-atomic_io.obj `if test -f '../../../src/util/atomic_io.c'; then $(CYGPATH_W) '../../../src/util/atomic_io.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/atomic_io.c'; fi` ../../../src/util/usertools_tests-util.o: ../../../src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-util.o -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-util.Tpo -c -o ../../../src/util/usertools_tests-util.o `test -f '../../../src/util/util.c' || echo '$(srcdir)/'`../../../src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-util.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/util.c' object='../../../src/util/usertools_tests-util.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-util.o `test -f '../../../src/util/util.c' || echo '$(srcdir)/'`../../../src/util/util.c ../../../src/util/usertools_tests-util.obj: ../../../src/util/util.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-util.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-util.Tpo -c -o ../../../src/util/usertools_tests-util.obj `if test -f '../../../src/util/util.c'; then $(CYGPATH_W) '../../../src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/util.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-util.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-util.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/util.c' object='../../../src/util/usertools_tests-util.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-util.obj `if test -f '../../../src/util/util.c'; then $(CYGPATH_W) '../../../src/util/util.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/util.c'; fi` ../../../src/util/usertools_tests-util_errors.o: ../../../src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-util_errors.o -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-util_errors.Tpo -c -o ../../../src/util/usertools_tests-util_errors.o `test -f '../../../src/util/util_errors.c' || echo '$(srcdir)/'`../../../src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-util_errors.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-util_errors.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/util_errors.c' object='../../../src/util/usertools_tests-util_errors.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-util_errors.o `test -f '../../../src/util/util_errors.c' || echo '$(srcdir)/'`../../../src/util/util_errors.c ../../../src/util/usertools_tests-util_errors.obj: ../../../src/util/util_errors.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-util_errors.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-util_errors.Tpo -c -o ../../../src/util/usertools_tests-util_errors.obj `if test -f '../../../src/util/util_errors.c'; then $(CYGPATH_W) '../../../src/util/util_errors.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/util_errors.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-util_errors.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-util_errors.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/util_errors.c' object='../../../src/util/usertools_tests-util_errors.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-util_errors.obj `if test -f '../../../src/util/util_errors.c'; then $(CYGPATH_W) '../../../src/util/util_errors.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/util_errors.c'; fi` ../../../src/util/usertools_tests-sss_tc_utf8.o: ../../../src/util/sss_tc_utf8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-sss_tc_utf8.o -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-sss_tc_utf8.Tpo -c -o ../../../src/util/usertools_tests-sss_tc_utf8.o `test -f '../../../src/util/sss_tc_utf8.c' || echo '$(srcdir)/'`../../../src/util/sss_tc_utf8.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-sss_tc_utf8.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-sss_tc_utf8.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/sss_tc_utf8.c' object='../../../src/util/usertools_tests-sss_tc_utf8.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-sss_tc_utf8.o `test -f '../../../src/util/sss_tc_utf8.c' || echo '$(srcdir)/'`../../../src/util/sss_tc_utf8.c ../../../src/util/usertools_tests-sss_tc_utf8.obj: ../../../src/util/sss_tc_utf8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-sss_tc_utf8.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-sss_tc_utf8.Tpo -c -o ../../../src/util/usertools_tests-sss_tc_utf8.obj `if test -f '../../../src/util/sss_tc_utf8.c'; then $(CYGPATH_W) '../../../src/util/sss_tc_utf8.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/sss_tc_utf8.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-sss_tc_utf8.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-sss_tc_utf8.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/sss_tc_utf8.c' object='../../../src/util/usertools_tests-sss_tc_utf8.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-sss_tc_utf8.obj `if test -f '../../../src/util/sss_tc_utf8.c'; then $(CYGPATH_W) '../../../src/util/sss_tc_utf8.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/sss_tc_utf8.c'; fi` ../../../src/util/usertools_tests-sss_utf8.o: ../../../src/util/sss_utf8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-sss_utf8.o -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-sss_utf8.Tpo -c -o ../../../src/util/usertools_tests-sss_utf8.o `test -f '../../../src/util/sss_utf8.c' || echo '$(srcdir)/'`../../../src/util/sss_utf8.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-sss_utf8.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-sss_utf8.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/sss_utf8.c' object='../../../src/util/usertools_tests-sss_utf8.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-sss_utf8.o `test -f '../../../src/util/sss_utf8.c' || echo '$(srcdir)/'`../../../src/util/sss_utf8.c ../../../src/util/usertools_tests-sss_utf8.obj: ../../../src/util/sss_utf8.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/util/usertools_tests-sss_utf8.obj -MD -MP -MF ../../../src/util/$(DEPDIR)/usertools_tests-sss_utf8.Tpo -c -o ../../../src/util/usertools_tests-sss_utf8.obj `if test -f '../../../src/util/sss_utf8.c'; then $(CYGPATH_W) '../../../src/util/sss_utf8.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/sss_utf8.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/util/$(DEPDIR)/usertools_tests-sss_utf8.Tpo ../../../src/util/$(DEPDIR)/usertools_tests-sss_utf8.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/util/sss_utf8.c' object='../../../src/util/usertools_tests-sss_utf8.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/util/usertools_tests-sss_utf8.obj `if test -f '../../../src/util/sss_utf8.c'; then $(CYGPATH_W) '../../../src/util/sss_utf8.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/util/sss_utf8.c'; fi` ../../../src/confdb/usertools_tests-confdb.o: ../../../src/confdb/confdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/confdb/usertools_tests-confdb.o -MD -MP -MF ../../../src/confdb/$(DEPDIR)/usertools_tests-confdb.Tpo -c -o ../../../src/confdb/usertools_tests-confdb.o `test -f '../../../src/confdb/confdb.c' || echo '$(srcdir)/'`../../../src/confdb/confdb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/confdb/$(DEPDIR)/usertools_tests-confdb.Tpo ../../../src/confdb/$(DEPDIR)/usertools_tests-confdb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/confdb/confdb.c' object='../../../src/confdb/usertools_tests-confdb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/confdb/usertools_tests-confdb.o `test -f '../../../src/confdb/confdb.c' || echo '$(srcdir)/'`../../../src/confdb/confdb.c ../../../src/confdb/usertools_tests-confdb.obj: ../../../src/confdb/confdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/confdb/usertools_tests-confdb.obj -MD -MP -MF ../../../src/confdb/$(DEPDIR)/usertools_tests-confdb.Tpo -c -o ../../../src/confdb/usertools_tests-confdb.obj `if test -f '../../../src/confdb/confdb.c'; then $(CYGPATH_W) '../../../src/confdb/confdb.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/confdb/confdb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/confdb/$(DEPDIR)/usertools_tests-confdb.Tpo ../../../src/confdb/$(DEPDIR)/usertools_tests-confdb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/confdb/confdb.c' object='../../../src/confdb/usertools_tests-confdb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/confdb/usertools_tests-confdb.obj `if test -f '../../../src/confdb/confdb.c'; then $(CYGPATH_W) '../../../src/confdb/confdb.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/confdb/confdb.c'; fi` ../../../src/db/usertools_tests-sysdb.o: ../../../src/db/sysdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb.o -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb.Tpo -c -o ../../../src/db/usertools_tests-sysdb.o `test -f '../../../src/db/sysdb.c' || echo '$(srcdir)/'`../../../src/db/sysdb.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb.c' object='../../../src/db/usertools_tests-sysdb.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb.o `test -f '../../../src/db/sysdb.c' || echo '$(srcdir)/'`../../../src/db/sysdb.c ../../../src/db/usertools_tests-sysdb.obj: ../../../src/db/sysdb.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb.Tpo -c -o ../../../src/db/usertools_tests-sysdb.obj `if test -f '../../../src/db/sysdb.c'; then $(CYGPATH_W) '../../../src/db/sysdb.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb.c' object='../../../src/db/usertools_tests-sysdb.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb.obj `if test -f '../../../src/db/sysdb.c'; then $(CYGPATH_W) '../../../src/db/sysdb.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb.c'; fi` ../../../src/db/usertools_tests-sysdb_upgrade.o: ../../../src/db/sysdb_upgrade.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_upgrade.o -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_upgrade.Tpo -c -o ../../../src/db/usertools_tests-sysdb_upgrade.o `test -f '../../../src/db/sysdb_upgrade.c' || echo '$(srcdir)/'`../../../src/db/sysdb_upgrade.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_upgrade.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_upgrade.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_upgrade.c' object='../../../src/db/usertools_tests-sysdb_upgrade.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_upgrade.o `test -f '../../../src/db/sysdb_upgrade.c' || echo '$(srcdir)/'`../../../src/db/sysdb_upgrade.c ../../../src/db/usertools_tests-sysdb_upgrade.obj: ../../../src/db/sysdb_upgrade.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_upgrade.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_upgrade.Tpo -c -o ../../../src/db/usertools_tests-sysdb_upgrade.obj `if test -f '../../../src/db/sysdb_upgrade.c'; then $(CYGPATH_W) '../../../src/db/sysdb_upgrade.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_upgrade.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_upgrade.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_upgrade.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_upgrade.c' object='../../../src/db/usertools_tests-sysdb_upgrade.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_upgrade.obj `if test -f '../../../src/db/sysdb_upgrade.c'; then $(CYGPATH_W) '../../../src/db/sysdb_upgrade.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_upgrade.c'; fi` ../../../src/db/usertools_tests-sysdb_autofs.o: ../../../src/db/sysdb_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_autofs.o -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_autofs.Tpo -c -o ../../../src/db/usertools_tests-sysdb_autofs.o `test -f '../../../src/db/sysdb_autofs.c' || echo '$(srcdir)/'`../../../src/db/sysdb_autofs.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_autofs.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_autofs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_autofs.c' object='../../../src/db/usertools_tests-sysdb_autofs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_autofs.o `test -f '../../../src/db/sysdb_autofs.c' || echo '$(srcdir)/'`../../../src/db/sysdb_autofs.c ../../../src/db/usertools_tests-sysdb_autofs.obj: ../../../src/db/sysdb_autofs.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_autofs.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_autofs.Tpo -c -o ../../../src/db/usertools_tests-sysdb_autofs.obj `if test -f '../../../src/db/sysdb_autofs.c'; then $(CYGPATH_W) '../../../src/db/sysdb_autofs.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_autofs.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_autofs.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_autofs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_autofs.c' object='../../../src/db/usertools_tests-sysdb_autofs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_autofs.obj `if test -f '../../../src/db/sysdb_autofs.c'; then $(CYGPATH_W) '../../../src/db/sysdb_autofs.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_autofs.c'; fi` ../../../src/db/usertools_tests-sysdb_search.o: ../../../src/db/sysdb_search.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_search.o -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_search.Tpo -c -o ../../../src/db/usertools_tests-sysdb_search.o `test -f '../../../src/db/sysdb_search.c' || echo '$(srcdir)/'`../../../src/db/sysdb_search.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_search.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_search.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_search.c' object='../../../src/db/usertools_tests-sysdb_search.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_search.o `test -f '../../../src/db/sysdb_search.c' || echo '$(srcdir)/'`../../../src/db/sysdb_search.c ../../../src/db/usertools_tests-sysdb_search.obj: ../../../src/db/sysdb_search.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_search.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_search.Tpo -c -o ../../../src/db/usertools_tests-sysdb_search.obj `if test -f '../../../src/db/sysdb_search.c'; then $(CYGPATH_W) '../../../src/db/sysdb_search.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_search.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_search.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_search.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_search.c' object='../../../src/db/usertools_tests-sysdb_search.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_search.obj `if test -f '../../../src/db/sysdb_search.c'; then $(CYGPATH_W) '../../../src/db/sysdb_search.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_search.c'; fi` ../../../src/db/usertools_tests-sysdb_services.o: ../../../src/db/sysdb_services.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_services.o -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_services.Tpo -c -o ../../../src/db/usertools_tests-sysdb_services.o `test -f '../../../src/db/sysdb_services.c' || echo '$(srcdir)/'`../../../src/db/sysdb_services.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_services.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_services.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_services.c' object='../../../src/db/usertools_tests-sysdb_services.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_services.o `test -f '../../../src/db/sysdb_services.c' || echo '$(srcdir)/'`../../../src/db/sysdb_services.c ../../../src/db/usertools_tests-sysdb_services.obj: ../../../src/db/sysdb_services.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_services.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_services.Tpo -c -o ../../../src/db/usertools_tests-sysdb_services.obj `if test -f '../../../src/db/sysdb_services.c'; then $(CYGPATH_W) '../../../src/db/sysdb_services.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_services.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_services.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_services.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_services.c' object='../../../src/db/usertools_tests-sysdb_services.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_services.obj `if test -f '../../../src/db/sysdb_services.c'; then $(CYGPATH_W) '../../../src/db/sysdb_services.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_services.c'; fi` ../../../src/db/usertools_tests-sysdb_ops.o: ../../../src/db/sysdb_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_ops.o -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_ops.Tpo -c -o ../../../src/db/usertools_tests-sysdb_ops.o `test -f '../../../src/db/sysdb_ops.c' || echo '$(srcdir)/'`../../../src/db/sysdb_ops.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_ops.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_ops.c' object='../../../src/db/usertools_tests-sysdb_ops.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_ops.o `test -f '../../../src/db/sysdb_ops.c' || echo '$(srcdir)/'`../../../src/db/sysdb_ops.c ../../../src/db/usertools_tests-sysdb_ops.obj: ../../../src/db/sysdb_ops.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_ops.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_ops.Tpo -c -o ../../../src/db/usertools_tests-sysdb_ops.obj `if test -f '../../../src/db/sysdb_ops.c'; then $(CYGPATH_W) '../../../src/db/sysdb_ops.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_ops.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_ops.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_ops.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_ops.c' object='../../../src/db/usertools_tests-sysdb_ops.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_ops.obj `if test -f '../../../src/db/sysdb_ops.c'; then $(CYGPATH_W) '../../../src/db/sysdb_ops.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_ops.c'; fi` ../../../src/db/usertools_tests-sysdb_views.o: ../../../src/db/sysdb_views.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_views.o -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_views.Tpo -c -o ../../../src/db/usertools_tests-sysdb_views.o `test -f '../../../src/db/sysdb_views.c' || echo '$(srcdir)/'`../../../src/db/sysdb_views.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_views.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_views.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_views.c' object='../../../src/db/usertools_tests-sysdb_views.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_views.o `test -f '../../../src/db/sysdb_views.c' || echo '$(srcdir)/'`../../../src/db/sysdb_views.c ../../../src/db/usertools_tests-sysdb_views.obj: ../../../src/db/sysdb_views.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -MT ../../../src/db/usertools_tests-sysdb_views.obj -MD -MP -MF ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_views.Tpo -c -o ../../../src/db/usertools_tests-sysdb_views.obj `if test -f '../../../src/db/sysdb_views.c'; then $(CYGPATH_W) '../../../src/db/sysdb_views.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_views.c'; fi` @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_views.Tpo ../../../src/db/$(DEPDIR)/usertools_tests-sysdb_views.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../../../src/db/sysdb_views.c' object='../../../src/db/usertools_tests-sysdb_views.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(usertools_tests_CFLAGS) $(CFLAGS) -c -o ../../../src/db/usertools_tests-sysdb_views.obj `if test -f '../../../src/db/sysdb_views.c'; then $(CYGPATH_W) '../../../src/db/sysdb_views.c'; else $(CYGPATH_W) '$(srcdir)/../../../src/db/sysdb_views.c'; fi` mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? become_user-tests.log: become_user-tests$(EXEEXT) @p='become_user-tests$(EXEEXT)'; \ b='become_user-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) server-tests.log: server-tests$(EXEEXT) @p='server-tests$(EXEEXT)'; \ b='server-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) usertools-tests.log: usertools-tests$(EXEEXT) @p='usertools-tests$(EXEEXT)'; \ b='usertools-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) responder_common-tests.log: responder_common-tests$(EXEEXT) @p='responder_common-tests$(EXEEXT)'; \ b='responder_common-tests'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(SCRIPTS) $(DATA) installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f ../../../src/confdb/$(DEPDIR)/$(am__dirstamp) -rm -f ../../../src/confdb/$(am__dirstamp) -rm -f ../../../src/db/$(DEPDIR)/$(am__dirstamp) -rm -f ../../../src/db/$(am__dirstamp) -rm -f ../../../src/responder/common/$(DEPDIR)/$(am__dirstamp) -rm -f ../../../src/responder/common/$(am__dirstamp) -rm -f ../../../src/util/$(DEPDIR)/$(am__dirstamp) -rm -f ../../../src/util/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ../../../src/confdb/$(DEPDIR) ../../../src/db/$(DEPDIR) ../../../src/responder/common/$(DEPDIR) ../../../src/util/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ../../../src/confdb/$(DEPDIR) ../../../src/db/$(DEPDIR) ../../../src/responder/common/$(DEPDIR) ../../../src/util/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: check-am install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ ctags ctags-am distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile tests: $(check_PROGRAMS) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: sssd-1.13.4/src/tests/cwrap/PaxHeaders.16287/cwrap_test_setup.sh0000644000000000000000000000007412703456111021321 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.048798355 sssd-1.13.4/src/tests/cwrap/cwrap_test_setup.sh0000755002412700241270000000074712703456111023003 0ustar00jhrozekjhrozek00000000000000#!/bin/bash pkg-config --exists nss_wrapper || exit 1 pkg-config --exists uid_wrapper || exit 1 nss_wrapper=$(pkg-config --libs nss_wrapper) uid_wrapper=$(pkg-config --libs uid_wrapper) if [ -z $nss_wrapper -o -z $uid_wrapper ]; then echo "Cannot locate cwrap libraries" exit 2 fi export LD_PRELOAD="$nss_wrapper $uid_wrapper" export NSS_WRAPPER_PASSWD=$CWRAP_TEST_SRCDIR/passwd export NSS_WRAPPER_GROUP=$CWRAP_TEST_SRCDIR/group export UID_WRAPPER=1 export UID_WRAPPER_ROOT=1 sssd-1.13.4/src/tests/cwrap/PaxHeaders.16287/test_become_user.c0000644000000000000000000000007412703456111021065 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.052798369 sssd-1.13.4/src/tests/cwrap/test_become_user.c0000644002412700241270000001133212703456111022534 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat SSSD tests: User switching This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* Yes, a .c file. We need to call static functions during the test */ #include "../../../src/util/become_user.c" #include #include "util/util.h" #include "tests/cmocka/common_mock.h" void test_become_user(void **state) { struct passwd *sssd; errno_t ret; pid_t pid, wpid; int status; /* Must root as root, real or fake */ assert_int_equal(geteuid(), 0); sssd = getpwnam("sssd"); assert_non_null(sssd); pid = fork(); if (pid == 0) { /* Change the UID in a child */ ret = become_user(sssd->pw_uid, sssd->pw_gid); assert_int_equal(ret, EOK); /* Make sure we have the requested UID and GID now and there * are no supplementary groups */ assert_int_equal(geteuid(), sssd->pw_uid); assert_int_equal(getegid(), sssd->pw_gid); assert_int_equal(getuid(), sssd->pw_uid); assert_int_equal(getgid(), sssd->pw_gid); /* Another become_user is a no-op */ ret = become_user(sssd->pw_uid, sssd->pw_gid); assert_int_equal(ret, EOK); assert_int_equal(getgroups(0, NULL), 0); exit(0); } assert_int_not_equal(pid, -1); wpid = waitpid(pid, &status, 0); assert_int_equal(wpid, pid); assert_true(WIFEXITED(status)); assert_int_equal(WEXITSTATUS(status), 0); } void test_switch_user(void **state) { errno_t ret; struct passwd *sssd; TALLOC_CTX *tmp_ctx; struct sss_creds *saved_creds; struct sss_creds *saved_creds2 = NULL; assert_true(leak_check_setup()); check_leaks_push(global_talloc_context); tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); /* Must root as root, real or fake */ assert_int_equal(geteuid(), 0); sssd = getpwnam("sssd"); assert_non_null(sssd); check_leaks_push(tmp_ctx); ret = switch_creds(tmp_ctx, sssd->pw_uid, sssd->pw_gid, 0, NULL, &saved_creds); assert_int_equal(ret, EOK); assert_int_equal(geteuid(), sssd->pw_uid); assert_int_equal(getegid(), sssd->pw_gid); /* Only effective UID is changed.. */ assert_int_equal(getuid(), 0); assert_int_equal(getgid(), 0); assert_non_null(saved_creds); assert_int_equal(saved_creds->uid, 0); assert_int_equal(saved_creds->gid, 0); /* Attempt to restore creds again */ ret = switch_creds(tmp_ctx, sssd->pw_uid, sssd->pw_gid, 0, NULL, &saved_creds2); assert_int_equal(ret, EOK); assert_null(saved_creds2); /* restore root */ ret = restore_creds(saved_creds); assert_int_equal(ret, EOK); assert_int_equal(geteuid(), 0); assert_int_equal(getegid(), 0); assert_int_equal(getuid(), 0); assert_int_equal(getgid(), 0); talloc_free(saved_creds); assert_true(check_leaks_pop(tmp_ctx)); talloc_free(tmp_ctx); assert_true(check_leaks_pop(global_talloc_context)); assert_true(leak_check_teardown()); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test(test_become_user), cmocka_unit_test(test_switch_user), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cwrap/PaxHeaders.16287/test_responder_common.c0000644000000000000000000000007412703456111022146 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.053798373 sssd-1.13.4/src/tests/cwrap/test_responder_common.c0000644002412700241270000001423412703456111023621 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat SSSD tests: User utilities This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "responder/common/responder.h" #include "tests/cmocka/common_mock.h" /* Just to satisfy dependencies */ struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version responder_test_cli_protocol_version[] = { {0, NULL, NULL} }; return responder_test_cli_protocol_version; } void test_uid_csv_to_uid_list(void **state) { TALLOC_CTX *tmp_ctx; errno_t ret; size_t count; uid_t *list; tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); ret = csv_string_to_uid_array(tmp_ctx, "1, 2, 3", false, &count, &list); assert_int_equal(ret, EOK); assert_int_equal(count, 3); assert_int_equal(list[0], 1); assert_int_equal(list[1], 2); assert_int_equal(list[2], 3); talloc_free(list); assert_true(check_leaks_pop(tmp_ctx)); talloc_free(tmp_ctx); } void test_name_csv_to_uid_list(void **state) { TALLOC_CTX *tmp_ctx; errno_t ret; size_t count; uid_t *list; tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); ret = csv_string_to_uid_array(tmp_ctx, "sssd, foobar", true, &count, &list); assert_int_equal(ret, EOK); assert_int_equal(count, 2); assert_int_equal(list[0], 123); assert_int_equal(list[1], 10001); talloc_free(list); assert_true(check_leaks_pop(tmp_ctx)); talloc_free(tmp_ctx); } void test_csv_to_uid_list_neg(void **state) { TALLOC_CTX *tmp_ctx; errno_t ret; size_t count; uid_t *list = NULL; tmp_ctx = talloc_new(global_talloc_context); assert_non_null(tmp_ctx); check_leaks_push(tmp_ctx); ret = csv_string_to_uid_array(tmp_ctx, "nosuchuser", true, &count, &list); assert_int_not_equal(ret, EOK); assert_true(check_leaks_pop(tmp_ctx)); talloc_free(tmp_ctx); } struct create_pipe_ctx { int fd; const char *sock_name; }; static int test_create_pipe_fd_setup(void **state) { struct create_pipe_ctx *ctx; ctx = talloc(global_talloc_context, struct create_pipe_ctx); assert_non_null(ctx); ctx->fd = -1; *state = ctx; return 0; } void check_sock_properties(struct create_pipe_ctx *ctx, mode_t mode) { int ret; int optval; socklen_t optlen; struct stat sbuf; /* Check existence of the file and the permissions */ ret = stat(ctx->sock_name, &sbuf); assert_int_equal(ret, 0); assert_true(S_ISSOCK(sbuf.st_mode)); assert_true((sbuf.st_mode & ~S_IFMT) == mode); /* Check it's a UNIX socket */ optlen = sizeof(optval); ret = getsockopt(ctx->fd, SOL_SOCKET, SO_DOMAIN, &optval, &optlen); assert_int_equal(ret, 0); assert_int_equal(optval, AF_UNIX); optlen = sizeof(optval); ret = getsockopt(ctx->fd, SOL_SOCKET, SO_TYPE, &optval, &optlen); assert_int_equal(ret, 0); assert_int_equal(optval, SOCK_STREAM); /* Make sure this is a listening socket */ optlen = sizeof(optval); ret = getsockopt(ctx->fd, SOL_SOCKET, SO_ACCEPTCONN, &optval, &optlen); assert_int_equal(ret, 0); assert_int_equal(optval, 1); /* Check the right protocol */ optlen = sizeof(optval); ret = getsockopt(ctx->fd, SOL_SOCKET, SO_PROTOCOL, &optval, &optlen); assert_int_equal(ret, 0); assert_int_equal(optval, 0); } void test_create_pipe_fd(void **state) { int ret; struct create_pipe_ctx *ctx; ctx = talloc_get_type(*state, struct create_pipe_ctx); ctx->sock_name = __FUNCTION__; ret = create_pipe_fd(ctx->sock_name, &ctx->fd, 0111); assert_int_equal(ret, EOK); assert_int_not_equal(ctx->fd, -1); check_sock_properties(ctx, 0666); /* Make sure we can overwrite an existing socket */ ret = create_pipe_fd(ctx->sock_name, &ctx->fd, 0000); assert_int_equal(ret, EOK); assert_int_not_equal(ctx->fd, -1); check_sock_properties(ctx, 0777); } static int test_create_pipe_fd_teardown(void **state) { struct create_pipe_ctx *ctx; ctx = talloc_get_type(*state, struct create_pipe_ctx); if (ctx->fd != -1) { unlink(ctx->sock_name); close(ctx->fd); } return 0; } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test(test_uid_csv_to_uid_list), cmocka_unit_test(test_name_csv_to_uid_list), cmocka_unit_test(test_csv_to_uid_list_neg), cmocka_unit_test_setup_teardown(test_create_pipe_fd, test_create_pipe_fd_setup, test_create_pipe_fd_teardown) }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); return cmocka_run_group_tests(tests, NULL, NULL); } sssd-1.13.4/src/tests/cwrap/PaxHeaders.16287/test_server.c0000644000000000000000000000007412703456111020103 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.054798376 sssd-1.13.4/src/tests/cwrap/test_server.c0000644002412700241270000001167112703456111021560 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat SSSD tests: Server instantiation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "util/strtonum.h" #include "tests/cmocka/common_mock.h" static void wait_for_fg_server(pid_t pid) { pid_t wpid; int status; assert_int_not_equal(pid, -1); wpid = waitpid(pid, &status, 0); assert_int_equal(wpid, pid); assert_true(WIFEXITED(status)); assert_int_equal(WEXITSTATUS(status), 0); } static void wait_for_bg_server(const char *pidfile) { int fd; uint32_t tmp; char buf[16]; pid_t pid; int ret; int count; count = 0; do { struct stat sb; count++; if (count > 200) { fail(); break; } ret = stat(pidfile, &sb); usleep(50000); } while (ret != 0); /* read the pidfile */ fd = open(pidfile, O_RDONLY); assert_false(fd < 0); ret = read(fd, buf, sizeof(buf)); close(fd); assert_false(ret <= 0); buf[sizeof(buf) - 1] = '\0'; errno = 0; tmp = strtouint32(buf, NULL, 10); assert_int_not_equal(tmp, 0); assert_int_equal(errno, 0); pid = (pid_t) (tmp); /* Make sure the daemon goes away! */ ret = kill(pid, SIGTERM); fprintf(stderr, "killing %u\n", pid); assert_true(ret == 0); unlink(pidfile); } void test_run_as_root_fg(void **state) { int ret; struct main_context *main_ctx; pid_t pid; /* Must root as root, real or fake */ assert_int_equal(geteuid(), 0); pid = fork(); if (pid == 0) { ret = server_setup(__FUNCTION__, 0, 0, 0, __FUNCTION__, &main_ctx); assert_int_equal(ret, 0); exit(0); } wait_for_fg_server(pid); } void test_run_as_sssd_fg(void **state) { int ret; struct main_context *main_ctx; struct passwd *sssd; pid_t pid; /* Must root as root, real or fake */ assert_int_equal(geteuid(), 0); sssd = getpwnam("sssd"); assert_non_null(sssd); pid = fork(); if (pid == 0) { ret = server_setup(__FUNCTION__, 0, sssd->pw_uid, sssd->pw_gid, __FUNCTION__, &main_ctx); assert_int_equal(ret, 0); exit(0); } wait_for_fg_server(pid); } void test_run_as_root_daemon(void **state) { int ret; struct main_context *main_ctx; pid_t pid; char *pidfile; /* Must root as root, real or fake */ assert_int_equal(geteuid(), 0); pidfile = talloc_asprintf(NULL, "%s/%s.pid", TEST_PID_PATH, __FUNCTION__); /* Make sure there are no leftovers */ unlink(pidfile); pid = fork(); if (pid == 0) { ret = server_setup(__FUNCTION__, FLAGS_PID_FILE, 0, 0, __FUNCTION__, &main_ctx); assert_int_equal(ret, 0); server_loop(main_ctx); exit(0); } wait_for_bg_server(pidfile); talloc_free(pidfile); } int main(int argc, const char *argv[]) { poptContext pc; int opt; int rv; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { cmocka_unit_test(test_run_as_root_fg), cmocka_unit_test(test_run_as_sssd_fg), cmocka_unit_test(test_run_as_root_daemon), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); /* Even though normally the tests should clean up after themselves * they might not after a failed run. Remove the old db to be sure */ tests_set_cwd(); test_dom_suite_cleanup(TEST_DB_PATH, CONFDB_FILE, NULL); test_dom_suite_setup(TEST_DB_PATH); rv = cmocka_run_group_tests(tests, NULL, NULL); if (rv != 0) { test_dom_suite_cleanup(TEST_DB_PATH, CONFDB_FILE, NULL); } return rv; } sssd-1.13.4/src/tests/cwrap/PaxHeaders.16287/group0000644000000000000000000000007412703456111016451 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.049798359 sssd-1.13.4/src/tests/cwrap/group0000644002412700241270000000001412703456111020113 0ustar00jhrozekjhrozek00000000000000sssd:x:123: sssd-1.13.4/src/tests/cwrap/PaxHeaders.16287/Makefile.am0000644000000000000000000000007412703456111017426 xustar0030 atime=1460561764.429758958 30 ctime=1460561776.047798352 sssd-1.13.4/src/tests/cwrap/Makefile.am0000644002412700241270000001060712703456111021101 0ustar00jhrozekjhrozek00000000000000AM_CPPFLAGS = \ -std=gnu99 \ -Wall \ -I$(top_srcdir)/src \ -I. \ -DLOCALEDIR=\"$(localedir)\" \ -DLIBDIR=\"$(libdir)\" \ -DVARDIR=\"$(localstatedir)\" \ -DSSS_STATEDIR=\"$(localstatedir)/lib/sss\" \ -DSYSCONFDIR=\"$(sysconfdir)\" \ $(DBUS_CFLAGS) \ $(GLIB2_CFLAGS) \ $(NULL) TESTS_ENVIRONMENT = \ CWRAP_TEST_SRCDIR=$(abs_srcdir) \ . $(srcdir)/cwrap_test_setup.sh; \ $(AUX_TESTS_ENVIRONMENT) \ $(NULL) dist_noinst_SCRIPTS = \ cwrap_test_setup.sh \ $(NULL) SSSD_LIBS = \ $(TALLOC_LIBS) \ $(TEVENT_LIBS) \ $(POPT_LIBS) \ $(LDB_LIBS) \ $(DBUS_LIBS) \ $(PCRE_LIBS) \ $(INI_CONFIG_LIBS) \ $(COLLECTION_LIBS) \ $(DHASH_LIBS) \ $(SSS_CRYPT_LIBS) \ $(OPENLDAP_LIBS) \ $(TDB_LIBS) dist_noinst_DATA = \ group \ passwd \ $(NULL) check_PROGRAMS = if HAVE_CMOCKA if HAVE_NSS_WRAPPER if HAVE_UID_WRAPPER check_PROGRAMS += \ become_user-tests \ server-tests \ usertools-tests \ responder_common-tests \ $(NULL) endif # HAVE_UID_WRAPPER endif # HAVE_NSS_WRAPPER endif # HAVE_CMOCKA TESTS = $(check_PROGRAMS) become_user_tests_SOURCES = \ test_become_user.c \ $(NULL) become_user_tests_CFLAGS = \ $(AM_CFLAGS) \ $(NULL) become_user_tests_LDADD = \ $(POPT_LIBS) \ $(CMOCKA_LIBS) \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_test_common.la \ $(NULL) server_tests_SOURCES = \ test_server.c \ ../../../src/util/server.c \ ../../../src/util/become_user.c \ ../../../src/util/backup_file.c \ ../../../src/util/domain_info_utils.c \ ../../../src/util/atomic_io.c \ ../../../src/util/signal.c \ ../../../src/util/util.c \ ../../../src/util/string_utils.c \ ../../../src/util/strtonum.c \ ../../../src/util/util_errors.c \ ../../../src/util/safe-format-string.c \ ../../../src/util/sss_tc_utf8.c \ ../../../src/util/sss_utf8.c \ ../../../src/util/usertools.c \ ../../../src/confdb/confdb.c \ ../../../src/db/sysdb.c \ ../../../src/db/sysdb_upgrade.c \ ../../../src/db/sysdb_ops.c \ ../../../src/db/sysdb_search.c \ ../../../src/db/sysdb_autofs.c \ ../../../src/db/sysdb_services.c \ ../../../src/db/sysdb_views.c \ $(NULL) server_tests_CFLAGS = \ $(AM_CFLAGS) \ $(LIBCAPNG_CFLAGS) \ -DTEST_DB_PATH=\"server_tests\" \ -DTEST_PID_PATH=\"server_tests\" \ -DUNIT_TESTING \ $(NULL) server_tests_LDADD = \ $(CMOCKA_LIBS) \ $(LIBCAPNG_LIBS) \ $(UNICODE_LIBS) \ $(SSSD_LIBS) \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_crypt.la \ $(abs_top_builddir)/libsss_test_common.la \ $(abs_top_builddir)/libsss_cert.la \ $(NULL) usertools_tests_SOURCES = \ test_usertools.c \ ../../../src/util/domain_info_utils.c \ ../../../src/util/safe-format-string.c \ ../../../src/util/usertools.c \ ../../../src/util/string_utils.c \ ../../../src/util/strtonum.c \ ../../../src/util/backup_file.c \ ../../../src/util/atomic_io.c \ ../../../src/util/util.c \ ../../../src/util/util_errors.c \ ../../../src/util/sss_tc_utf8.c \ ../../../src/util/sss_utf8.c \ ../../../src/confdb/confdb.c \ ../../../src/db/sysdb.c \ ../../../src/db/sysdb_upgrade.c \ ../../../src/db/sysdb_autofs.c \ ../../../src/db/sysdb_search.c \ ../../../src/db/sysdb_services.c \ ../../../src/db/sysdb_ops.c \ ../../../src/db/sysdb_views.c \ $(NULL) usertools_tests_CFLAGS = \ $(AM_CFLAGS) \ $(NULL) usertools_tests_LDADD = \ $(CMOCKA_LIBS) \ $(UNICODE_LIBS) \ $(SSSD_LIBS) \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_crypt.la \ $(abs_top_builddir)/libsss_test_common.la \ $(abs_top_builddir)/libsss_cert.la \ $(NULL) responder_common_tests_SOURCES =\ test_responder_common.c \ ../../../src/responder/common/responder_common.c \ ../../../src/responder/common/responder_packet.c \ ../../../src/responder/common/responder_cmd.c \ $(NULL) responder_common_tests_CFLAGS = \ $(AM_CFLAGS) \ $(NULL) responder_common_tests_LDADD = \ $(CMOCKA_LIBS) \ $(UNICODE_LIBS) \ $(SSSD_LIBS) \ $(abs_top_builddir)/libsss_util.la \ $(abs_top_builddir)/libsss_debug.la \ $(abs_top_builddir)/libsss_crypt.la \ $(abs_top_builddir)/libsss_test_common.la \ $(NULL) tests: $(check_PROGRAMS) sssd-1.13.4/src/tests/cwrap/PaxHeaders.16287/passwd0000644000000000000000000000007412703456111016616 xustar0030 atime=1460561751.657715651 30 ctime=1460561776.050798362 sssd-1.13.4/src/tests/cwrap/passwd0000644002412700241270000000017012703456111020263 0ustar00jhrozekjhrozek00000000000000sssd:x:123:456:sssd unprivileged user:/:/sbin/nologin foobar:x:10001:10001:User for SSSD testing:/home/foobar:/bin/bash sssd-1.13.4/src/tests/PaxHeaders.16287/sbus_codegen_tests_generated.c0000644000000000000000000000007412703456111022322 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.965794683 sssd-1.13.4/src/tests/sbus_codegen_tests_generated.c0000644002412700241270000005155612703456111024005 0ustar00jhrozekjhrozek00000000000000/* The following definitions are auto-generated from sbus_codegen_tests.xml */ #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_meta.h" #include "sbus/sssd_dbus_invokers.h" #include "sbus_codegen_tests_generated.h" /* invokes a handler with a 'bu' DBus signature */ static int invoke_bu_method(struct sbus_request *dbus_req, void *function_ptr); /* invokes a handler with a 's' DBus signature */ static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr); /* invokes a handler with a 'u' DBus signature */ static int invoke_u_method(struct sbus_request *dbus_req, void *function_ptr); /* invokes a handler with a 'ybnqiuxtdsoayanaqaiauaxatadasao' DBus signature */ static int invoke_ybnqiuxtdsoayanaqaiauaxatadasao_method(struct sbus_request *dbus_req, void *function_ptr); /* arguments for com.planetexpress.Ship.MoveUniverse */ const struct sbus_arg_meta com_planetexpress_Ship_MoveUniverse__in[] = { { "smoothly", "b" }, { "speed_factor", "u" }, { NULL, } }; /* arguments for com.planetexpress.Ship.MoveUniverse */ const struct sbus_arg_meta com_planetexpress_Ship_MoveUniverse__out[] = { { "where_we_crashed", "s" }, { NULL, } }; int com_planetexpress_Ship_MoveUniverse_finish(struct sbus_request *req, const char *arg_where_we_crashed) { return sbus_request_return_and_finish(req, DBUS_TYPE_STRING, &arg_where_we_crashed, DBUS_TYPE_INVALID); } /* arguments for com.planetexpress.Ship.Crash */ const struct sbus_arg_meta com_planetexpress_Ship_crash_now__in[] = { { "where", "s" }, { NULL, } }; int com_planetexpress_Ship_crash_now_finish(struct sbus_request *req) { return sbus_request_return_and_finish(req, DBUS_TYPE_INVALID); } /* methods for com.planetexpress.Ship */ const struct sbus_method_meta com_planetexpress_Ship__methods[] = { { "MoveUniverse", /* name */ com_planetexpress_Ship_MoveUniverse__in, com_planetexpress_Ship_MoveUniverse__out, offsetof(struct com_planetexpress_Ship, MoveUniverse), invoke_bu_method, }, { "Crash", /* name */ com_planetexpress_Ship_crash_now__in, NULL, /* no out_args */ offsetof(struct com_planetexpress_Ship, crash_now), invoke_s_method, }, { "Land", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct com_planetexpress_Ship, Land), NULL, /* no invoker */ }, { NULL, } }; /* arguments for com.planetexpress.Ship.BecameSentient */ const struct sbus_arg_meta com_planetexpress_Ship_BecameSentient__args[] = { { "gender", "s" }, { NULL, } }; /* signals for com.planetexpress.Ship */ const struct sbus_signal_meta com_planetexpress_Ship__signals[] = { { "BecameSentient", /* name */ com_planetexpress_Ship_BecameSentient__args }, { NULL, } }; /* property info for com.planetexpress.Ship */ const struct sbus_property_meta com_planetexpress_Ship__properties[] = { { "Color", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct com_planetexpress_Ship, get_Color), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { NULL, } }; /* interface info for com.planetexpress.Ship */ const struct sbus_interface_meta com_planetexpress_Ship_meta = { "com.planetexpress.Ship", /* name */ com_planetexpress_Ship__methods, com_planetexpress_Ship__signals, com_planetexpress_Ship__properties, sbus_invoke_get_all, /* GetAll invoker */ }; /* arguments for com.planetexpress.Pilot.Blink */ const struct sbus_arg_meta test_pilot_Blink__in[] = { { "duration", "u" }, { NULL, } }; /* arguments for com.planetexpress.Pilot.Blink */ const struct sbus_arg_meta test_pilot_Blink__out[] = { { "crashed", "b" }, { NULL, } }; int test_pilot_Blink_finish(struct sbus_request *req, bool arg_crashed) { dbus_bool_t cast_crashed = arg_crashed; return sbus_request_return_and_finish(req, DBUS_TYPE_BOOLEAN, &cast_crashed, DBUS_TYPE_INVALID); } /* arguments for com.planetexpress.Pilot.Eject */ const struct sbus_arg_meta test_pilot_Eject__in[] = { { "byte", "y" }, { "boolean", "b" }, { "int16", "n" }, { "uint16", "q" }, { "int32", "i" }, { "uint32", "u" }, { "int64", "x" }, { "uint64", "t" }, { "double", "d" }, { "string", "s" }, { "object_path", "o" }, { "byte_array", "ay" }, { "int16_array", "an" }, { "uint16_array", "aq" }, { "int32_array", "ai" }, { "uint32_array", "au" }, { "int64_array", "ax" }, { "uint64_array", "at" }, { "double_array", "ad" }, { "string_array", "as" }, { "object_path_array", "ao" }, { NULL, } }; /* arguments for com.planetexpress.Pilot.Eject */ const struct sbus_arg_meta test_pilot_Eject__out[] = { { "byte", "y" }, { "boolean", "b" }, { "int16", "n" }, { "uint16", "q" }, { "int32", "i" }, { "uint32", "u" }, { "int64", "x" }, { "uint64", "t" }, { "double", "d" }, { "string", "s" }, { "object_path", "o" }, { "byte_array", "ay" }, { "int16_array", "an" }, { "uint16_array", "aq" }, { "int32_array", "ai" }, { "uint32_array", "au" }, { "int64_array", "ax" }, { "uint64_array", "at" }, { "double_array", "ad" }, { "string_array", "as" }, { "object_path_array", "ao" }, { NULL, } }; int test_pilot_Eject_finish(struct sbus_request *req, uint8_t arg_byte, bool arg_boolean, int16_t arg_int16, uint16_t arg_uint16, int32_t arg_int32, uint32_t arg_uint32, int64_t arg_int64, uint64_t arg_uint64, double arg_double, const char *arg_string, const char *arg_object_path, uint8_t arg_byte_array[], int len_byte_array, int16_t arg_int16_array[], int len_int16_array, uint16_t arg_uint16_array[], int len_uint16_array, int32_t arg_int32_array[], int len_int32_array, uint32_t arg_uint32_array[], int len_uint32_array, int64_t arg_int64_array[], int len_int64_array, uint64_t arg_uint64_array[], int len_uint64_array, double arg_double_array[], int len_double_array, const char *arg_string_array[], int len_string_array, const char *arg_object_path_array[], int len_object_path_array) { dbus_bool_t cast_boolean = arg_boolean; return sbus_request_return_and_finish(req, DBUS_TYPE_BYTE, &arg_byte, DBUS_TYPE_BOOLEAN, &cast_boolean, DBUS_TYPE_INT16, &arg_int16, DBUS_TYPE_UINT16, &arg_uint16, DBUS_TYPE_INT32, &arg_int32, DBUS_TYPE_UINT32, &arg_uint32, DBUS_TYPE_INT64, &arg_int64, DBUS_TYPE_UINT64, &arg_uint64, DBUS_TYPE_DOUBLE, &arg_double, DBUS_TYPE_STRING, &arg_string, DBUS_TYPE_OBJECT_PATH, &arg_object_path, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &arg_byte_array, len_byte_array, DBUS_TYPE_ARRAY, DBUS_TYPE_INT16, &arg_int16_array, len_int16_array, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT16, &arg_uint16_array, len_uint16_array, DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &arg_int32_array, len_int32_array, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &arg_uint32_array, len_uint32_array, DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &arg_int64_array, len_int64_array, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &arg_uint64_array, len_uint64_array, DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &arg_double_array, len_double_array, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &arg_string_array, len_string_array, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_object_path_array, len_object_path_array, DBUS_TYPE_INVALID); } /* methods for com.planetexpress.Pilot */ const struct sbus_method_meta test_pilot__methods[] = { { "Blink", /* name */ test_pilot_Blink__in, test_pilot_Blink__out, offsetof(struct test_pilot, Blink), invoke_u_method, }, { "Eject", /* name */ test_pilot_Eject__in, test_pilot_Eject__out, offsetof(struct test_pilot, Eject), invoke_ybnqiuxtdsoayanaqaiauaxatadasao_method, }, { NULL, } }; /* property info for com.planetexpress.Pilot */ const struct sbus_property_meta test_pilot__properties[] = { { "FullName", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE | SBUS_PROPERTY_WRITABLE, offsetof(struct test_pilot, get_FullName), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "byte", /* name */ "y", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_byte), sbus_invoke_get_y, 0, /* not writable */ NULL, /* no invoker */ }, { "boolean", /* name */ "b", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_boolean), sbus_invoke_get_b, 0, /* not writable */ NULL, /* no invoker */ }, { "int16", /* name */ "n", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_int16), sbus_invoke_get_n, 0, /* not writable */ NULL, /* no invoker */ }, { "uint16", /* name */ "q", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_uint16), sbus_invoke_get_q, 0, /* not writable */ NULL, /* no invoker */ }, { "int32", /* name */ "i", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_int32), sbus_invoke_get_i, 0, /* not writable */ NULL, /* no invoker */ }, { "uint32", /* name */ "u", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_uint32), sbus_invoke_get_u, 0, /* not writable */ NULL, /* no invoker */ }, { "int64", /* name */ "x", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_int64), sbus_invoke_get_x, 0, /* not writable */ NULL, /* no invoker */ }, { "uint64", /* name */ "t", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_uint64), sbus_invoke_get_t, 0, /* not writable */ NULL, /* no invoker */ }, { "double", /* name */ "d", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_double), sbus_invoke_get_d, 0, /* not writable */ NULL, /* no invoker */ }, { "string", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_string), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "object_path", /* name */ "o", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_object_path), sbus_invoke_get_o, 0, /* not writable */ NULL, /* no invoker */ }, { "null_string", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_null_string), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "null_path", /* name */ "o", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_null_path), sbus_invoke_get_o, 0, /* not writable */ NULL, /* no invoker */ }, { "byte_array", /* name */ "ay", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_byte_array), sbus_invoke_get_ay, 0, /* not writable */ NULL, /* no invoker */ }, { "int16_array", /* name */ "an", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_int16_array), sbus_invoke_get_an, 0, /* not writable */ NULL, /* no invoker */ }, { "uint16_array", /* name */ "aq", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_uint16_array), sbus_invoke_get_aq, 0, /* not writable */ NULL, /* no invoker */ }, { "int32_array", /* name */ "ai", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_int32_array), sbus_invoke_get_ai, 0, /* not writable */ NULL, /* no invoker */ }, { "uint32_array", /* name */ "au", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_uint32_array), sbus_invoke_get_au, 0, /* not writable */ NULL, /* no invoker */ }, { "int64_array", /* name */ "ax", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_int64_array), sbus_invoke_get_ax, 0, /* not writable */ NULL, /* no invoker */ }, { "uint64_array", /* name */ "at", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_uint64_array), sbus_invoke_get_at, 0, /* not writable */ NULL, /* no invoker */ }, { "double_array", /* name */ "ad", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_double_array), sbus_invoke_get_ad, 0, /* not writable */ NULL, /* no invoker */ }, { "string_array", /* name */ "as", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_string_array), sbus_invoke_get_as, 0, /* not writable */ NULL, /* no invoker */ }, { "object_path_array", /* name */ "ao", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_pilot, get_object_path_array), sbus_invoke_get_ao, 0, /* not writable */ NULL, /* no invoker */ }, { NULL, } }; /* interface info for com.planetexpress.Pilot */ const struct sbus_interface_meta test_pilot_meta = { "com.planetexpress.Pilot", /* name */ test_pilot__methods, NULL, /* no signals */ test_pilot__properties, sbus_invoke_get_all, /* GetAll invoker */ }; /* property info for com.planetexpress.Special */ const struct sbus_property_meta test_special__properties[] = { { "array_dict_sas", /* name */ "a{sas}", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct test_special, get_array_dict_sas), sbus_invoke_get_aDOsasDE, 0, /* not writable */ NULL, /* no invoker */ }, { NULL, } }; /* interface info for com.planetexpress.Special */ const struct sbus_interface_meta test_special_meta = { "com.planetexpress.Special", /* name */ NULL, /* no methods */ NULL, /* no signals */ test_special__properties, sbus_invoke_get_all, /* GetAll invoker */ }; /* invokes a handler with a 'bu' DBus signature */ static int invoke_bu_method(struct sbus_request *dbus_req, void *function_ptr) { dbus_bool_t arg_0; uint32_t arg_1; int (*handler)(struct sbus_request *, void *, bool, uint32_t) = function_ptr; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_BOOLEAN, &arg_0, DBUS_TYPE_UINT32, &arg_1, DBUS_TYPE_INVALID)) { return EOK; /* request handled */ } return (handler)(dbus_req, dbus_req->intf->handler_data, arg_0, arg_1); } /* invokes a handler with a 's' DBus signature */ static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr) { const char * arg_0; int (*handler)(struct sbus_request *, void *, const char *) = function_ptr; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_STRING, &arg_0, DBUS_TYPE_INVALID)) { return EOK; /* request handled */ } return (handler)(dbus_req, dbus_req->intf->handler_data, arg_0); } /* invokes a handler with a 'u' DBus signature */ static int invoke_u_method(struct sbus_request *dbus_req, void *function_ptr) { uint32_t arg_0; int (*handler)(struct sbus_request *, void *, uint32_t) = function_ptr; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_UINT32, &arg_0, DBUS_TYPE_INVALID)) { return EOK; /* request handled */ } return (handler)(dbus_req, dbus_req->intf->handler_data, arg_0); } /* invokes a handler with a 'ybnqiuxtdsoayanaqaiauaxatadasao' DBus signature */ static int invoke_ybnqiuxtdsoayanaqaiauaxatadasao_method(struct sbus_request *dbus_req, void *function_ptr) { uint8_t arg_0; dbus_bool_t arg_1; int16_t arg_2; uint16_t arg_3; int32_t arg_4; uint32_t arg_5; int64_t arg_6; uint64_t arg_7; double arg_8; const char * arg_9; const char * arg_10; uint8_t *arg_11; int len_11; int16_t *arg_12; int len_12; uint16_t *arg_13; int len_13; int32_t *arg_14; int len_14; uint32_t *arg_15; int len_15; int64_t *arg_16; int len_16; uint64_t *arg_17; int len_17; double *arg_18; int len_18; const char * *arg_19; int len_19; const char * *arg_20; int len_20; int (*handler)(struct sbus_request *, void *, uint8_t, bool, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, double, const char *, const char *, uint8_t[], int, int16_t[], int, uint16_t[], int, int32_t[], int, uint32_t[], int, int64_t[], int, uint64_t[], int, double[], int, const char *[], int, const char *[], int) = function_ptr; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_BYTE, &arg_0, DBUS_TYPE_BOOLEAN, &arg_1, DBUS_TYPE_INT16, &arg_2, DBUS_TYPE_UINT16, &arg_3, DBUS_TYPE_INT32, &arg_4, DBUS_TYPE_UINT32, &arg_5, DBUS_TYPE_INT64, &arg_6, DBUS_TYPE_UINT64, &arg_7, DBUS_TYPE_DOUBLE, &arg_8, DBUS_TYPE_STRING, &arg_9, DBUS_TYPE_OBJECT_PATH, &arg_10, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &arg_11, &len_11, DBUS_TYPE_ARRAY, DBUS_TYPE_INT16, &arg_12, &len_12, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT16, &arg_13, &len_13, DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &arg_14, &len_14, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &arg_15, &len_15, DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &arg_16, &len_16, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &arg_17, &len_17, DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &arg_18, &len_18, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &arg_19, &len_19, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_20, &len_20, DBUS_TYPE_INVALID)) { return EOK; /* request handled */ } return (handler)(dbus_req, dbus_req->intf->handler_data, arg_0, arg_1, arg_2, arg_3, arg_4, arg_5, arg_6, arg_7, arg_8, arg_9, arg_10, arg_11, len_11, arg_12, len_12, arg_13, len_13, arg_14, len_14, arg_15, len_15, arg_16, len_16, arg_17, len_17, arg_18, len_18, arg_19, len_19, arg_20, len_20); } sssd-1.13.4/src/tests/PaxHeaders.16287/leak_check.c0000644000000000000000000000007412703456111016473 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.825794209 sssd-1.13.4/src/tests/leak_check.c0000644002412700241270000000710612703456111020146 0ustar00jhrozekjhrozek00000000000000/* SSSD Common utilities for check-based tests using talloc. Authors: Martin Nagy Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "tests/common.h" #include "util/util.h" #include "util/dlinklist.h" TALLOC_CTX *global_talloc_context = NULL; char leak_err_msg[256]; struct size_snapshot { struct size_snapshot *prev; struct size_snapshot *next; TALLOC_CTX *ctx; size_t bytes_allocated; }; static struct size_snapshot *snapshot_stack; #define _set_leak_err_msg(fmt, ...) do { \ snprintf(leak_err_msg, sizeof(leak_err_msg), \ fmt, ##__VA_ARGS__); \ } while(0); const char *check_leaks_err_msg(void) { return leak_err_msg; } static bool check_leaks(TALLOC_CTX *ctx, size_t bytes, const char *location) { size_t bytes_allocated; if (ctx == NULL) { return false; } bytes_allocated = talloc_total_size(ctx); if (bytes_allocated != bytes) { fprintf(stderr, "Leak report for %s:\n", location); talloc_report_full(ctx, stderr); _set_leak_err_msg("%s: memory leaks detected, %zd bytes still allocated", location, bytes_allocated - bytes); return false; } return true; } void check_leaks_push(TALLOC_CTX *ctx) { struct size_snapshot *snapshot; snapshot = talloc(NULL, struct size_snapshot); snapshot->ctx = ctx; snapshot->bytes_allocated = talloc_total_size(ctx); DLIST_ADD(snapshot_stack, snapshot); } bool _check_leaks_pop(TALLOC_CTX *ctx, const char *location) { struct size_snapshot *snapshot; TALLOC_CTX *old_ctx; size_t bytes_allocated; if (ctx == NULL) { return false; } if (snapshot_stack == NULL) { _set_leak_err_msg("%s: trying to pop an empty stack", location); return false; } snapshot = snapshot_stack; DLIST_REMOVE(snapshot_stack, snapshot); old_ctx = snapshot->ctx; bytes_allocated = snapshot->bytes_allocated; if (old_ctx != ctx) { _set_leak_err_msg("Bad push/pop order"); return false; } talloc_zfree(snapshot); return check_leaks(old_ctx, bytes_allocated, location); } bool leak_check_setup(void) { talloc_enable_null_tracking(); global_talloc_context = talloc_new(NULL); if (global_talloc_context == NULL) { _set_leak_err_msg("talloc_new failed"); return false; } check_leaks_push(global_talloc_context); return true; } bool leak_check_teardown(void) { bool res; res = check_leaks_pop(global_talloc_context); if (!res) { _set_leak_err_msg("check_leaks_pop failed in leak_check_teardown"); } if (snapshot_stack != NULL) { _set_leak_err_msg("Exiting with a non-empty stack"); return false; } res = check_leaks(global_talloc_context, 0, __location__); talloc_disable_null_tracking(); talloc_free(global_talloc_context); return res; } sssd-1.13.4/src/tests/PaxHeaders.16287/dlopen-tests.c0000644000000000000000000000007312703456111017042 xustar0030 atime=1460561751.657715651 29 ctime=1460561774.91479451 sssd-1.13.4/src/tests/dlopen-tests.c0000644002412700241270000001342612703456111020520 0ustar00jhrozekjhrozek00000000000000/* SSSD debug-tests.c Authors: Simo Sorce Copyright (C) 2013 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #define _GNU_SOURCE #include #include #include #include #include #include #include "tests/common.h" #define LIBPFX ABS_BUILD_DIR"/.libs/" struct so { const char *name; const char *libs[6]; } so[] = { { "libsss_debug.so", { LIBPFX"libsss_debug.so", NULL } }, { "libsss_semanage.so", { LIBPFX"libsss_semanage.so", NULL } }, { "libipa_hbac.so", { LIBPFX"libipa_hbac.so", NULL } }, { "libsss_idmap.so", { LIBPFX"libsss_idmap.so", NULL } }, { "libsss_nss_idmap.so", { LIBPFX"libsss_nss_idmap.so", NULL } }, { "libnss_sss.so", { LIBPFX"libnss_sss.so", NULL } }, { "pam_sss.so", { LIBPFX"pam_sss.so", NULL } }, #ifdef BUILD_LIBWBCLIENT { "libwbclient.so", { LIBPFX"libwbclient.so", NULL } }, #endif /* BUILD_LIBWBCLIENT */ #ifdef BUILD_IFP { "libsss_simpleifp.so", { LIBPFX"libsss_simpleifp.so", NULL } }, #endif /* BUILD_IFP */ #ifdef BUILD_SUDO { "libsss_sudo.so", { LIBPFX"libsss_sudo.so", NULL } }, #endif #ifdef BUILD_AUTOFS { "libsss_autofs.so", { LIBPFX"libsss_autofs.so", NULL } }, #endif #ifdef HAVE_KRB5_LOCATOR_PLUGIN { "sssd_krb5_locator_plugin.so", { LIBPFX"sssd_krb5_locator_plugin.so", NULL } }, #endif #ifdef HAVE_KRB5_LOCALAUTH_PLUGIN { "sssd_krb5_localauth_plugin.so", { LIBPFX"sssd_krb5_localauth_plugin.so", NULL } }, #endif #ifdef HAVE_PAC_RESPONDER { "sssd_pac_plugin.so", { LIBPFX"sssd_pac_plugin.so", NULL } }, #endif #ifdef HAVE_CIFS_IDMAP_PLUGIN { "cifs_idmap_sss.so", { LIBPFX"cifs_idmap_sss.so", NULL } }, #endif { "memberof.so", { LIBPFX"memberof.so", NULL } }, { "libsss_child.so", { LIBPFX"libsss_util.so", LIBPFX"libsss_child.so", NULL } }, { "libsss_crypt.so", { LIBPFX"libsss_crypt.so", NULL } }, { "libsss_util.so", { LIBPFX"libsss_util.so", NULL } }, { "libsss_simple.so", { LIBPFX"libdlopen_test_providers.so", LIBPFX"libsss_simple.so", NULL } }, #ifdef BUILD_SAMBA { "libsss_ad.so", { LIBPFX"libdlopen_test_providers.so", LIBPFX"libsss_ad.so", NULL } }, { "libsss_ipa.so", { LIBPFX"libdlopen_test_providers.so", LIBPFX"libsss_ipa.so", NULL } }, #endif /* BUILD_SAMBA */ { "libsss_krb5.so", { LIBPFX"libdlopen_test_providers.so", LIBPFX"libsss_krb5.so", NULL } }, { "libsss_krb5_common.so", { LIBPFX"libdlopen_test_providers.so", LIBPFX"libsss_krb5_common.so", NULL } }, { "libsss_ldap.so", { LIBPFX"libdlopen_test_providers.so", LIBPFX"libsss_ldap.so", NULL } }, { "libsss_ldap_common.so", { LIBPFX"libdlopen_test_providers.so", LIBPFX"libsss_ldap_common.so", NULL } }, { "libsss_proxy.so", { LIBPFX"libdlopen_test_providers.so", LIBPFX"libsss_proxy.so", NULL } }, { "libdlopen_test_providers.so", { LIBPFX"libdlopen_test_providers.so", NULL } }, #ifdef HAVE_PYTHON_BINDINGS { "_py2hbac.so", { LIBPFX"_py2hbac.so", NULL } }, { "_py2sss.so", { LIBPFX"_py2sss.so", NULL } }, { "_py2sss_murmur.so", { LIBPFX"_py2sss_murmur.so", NULL } }, { "_py2sss_nss_idmap.so", { LIBPFX"_py2sss_nss_idmap.so", NULL } }, #endif #ifdef HAVE_PYTHON_BINDINGS { "_py3hbac.so", { LIBPFX"_py3hbac.so", NULL } }, { "_py3sss.so", { LIBPFX"_py3sss.so", NULL } }, { "_py3sss_murmur.so", { LIBPFX"_py3sss_murmur.so", NULL } }, { "_py3sss_nss_idmap.so", { LIBPFX"_py3sss_nss_idmap.so", NULL } }, #endif #ifdef HAVE_CONFIG_LIB { "libsss_config.so", { LIBPFX"libsss_config.so", NULL } }, #endif { NULL } }; static bool recursive_dlopen(const char **name, int round, char **errmsg) { void *handle; bool ok; *errmsg = NULL; handle = dlopen(name[round], RTLD_GLOBAL|RTLD_NOW); if (!handle) { if (asprintf(errmsg, "dlopen() failed: %s", dlerror()) == -1) *errmsg = NULL; return false; } round++; if (name[round]) { ok = recursive_dlopen(name, round, errmsg); } else { ok = true; } dlclose(handle); return ok; } START_TEST(test_dlopen_base) { char *errmsg; bool ok; int i; for (i = 0; so[i].name != NULL; i++) { ok = recursive_dlopen(so[i].libs, 0, &errmsg); fail_unless(ok, "Error opening %s: [%s]", so[i].name, errmsg); } } END_TEST Suite *dlopen_suite(void) { Suite *s = suite_create("dlopen"); TCase *tc_dlopen = tcase_create("dlopen"); tcase_add_test(tc_dlopen, test_dlopen_base); tcase_set_timeout(tc_dlopen, 10); suite_add_tcase(s, tc_dlopen); return s; } int main(int argc, const char *argv[]) { int number_failed; Suite *s = dlopen_suite(); SRunner *sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); if (number_failed == 0) return EXIT_SUCCESS; return EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/ad_ldap_opt-tests.c0000644000000000000000000000007312703456111020027 xustar0030 atime=1460561751.655715644 29 ctime=1460561774.90879449 sssd-1.13.4/src/tests/ad_ldap_opt-tests.c0000644002412700241270000000636112703456111021505 0ustar00jhrozekjhrozek00000000000000/* SSSD Tests if AD and LDAP backend options are in sync Authors: Jakub Hrozek Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "providers/ad/ad_common.h" #include "providers/ad/ad_opts.h" #include "providers/ldap/sdap.h" #include "providers/ldap/ldap_opts.h" #include "providers/krb5/krb5_opts.h" #include "providers/krb5/krb5_common.h" #include "tests/common.h" START_TEST(test_compare_opts) { errno_t ret; ret = compare_dp_options(default_basic_opts, SDAP_OPTS_BASIC, ad_def_ldap_opts); fail_unless(ret == EOK, "[%s]", strerror(ret)); ret = compare_dp_options(default_krb5_opts, KRB5_OPTS, ad_def_krb5_opts); fail_unless(ret == EOK, "[%s]", strerror(ret)); } END_TEST START_TEST(test_compare_sdap_attrs) { errno_t ret; /* General Attributes */ ret = compare_sdap_attr_maps(generic_attr_map, SDAP_AT_GENERAL, ad_2008r2_attr_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); /* User Attributes */ ret = compare_sdap_attr_maps(rfc2307_user_map, SDAP_OPTS_USER, ad_2008r2_user_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); /* Group Attributes */ ret = compare_sdap_attr_maps(rfc2307_group_map, SDAP_OPTS_GROUP, ad_2008r2_group_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); /* Netgroup Attributes */ ret = compare_sdap_attr_maps(netgroup_map, SDAP_OPTS_NETGROUP, ad_netgroup_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); /* Service Attributes */ ret = compare_sdap_attr_maps(service_map, SDAP_OPTS_SERVICES, ad_service_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); } END_TEST Suite *ad_ldap_opt_suite (void) { Suite *s = suite_create ("ad_ldap_opt"); TCase *tc_ad_ldap_opt = tcase_create ("ad_ldap_opt"); tcase_add_test (tc_ad_ldap_opt, test_compare_opts); tcase_add_test (tc_ad_ldap_opt, test_compare_sdap_attrs); suite_add_tcase (s, tc_ad_ldap_opt); return s; } int main(void) { int number_failed; tests_set_cwd(); Suite *s = ad_ldap_opt_suite (); SRunner *sr = srunner_create (s); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed (sr); srunner_free (sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/common_dom.c0000644000000000000000000000007412703456111016551 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.824794205 sssd-1.13.4/src/tests/common_dom.c0000644002412700241270000002637212703456111020232 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat SSSD tests: Common utilities for tests that exercise domains This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "tests/common.h" static errno_t mock_confdb(TALLOC_CTX *mem_ctx, const char *tests_path, const char *cdb_file, struct confdb_ctx **_cdb) { TALLOC_CTX *tmp_ctx = NULL; struct confdb_ctx *cdb = NULL; char *cdb_path = NULL; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n")); return ENOMEM; } cdb_path = talloc_asprintf(tmp_ctx, "%s/%s", tests_path, cdb_file); if (cdb_path == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed\n"); ret = ENOMEM; goto done; } /* connect to the confdb */ ret = confdb_init(tmp_ctx, &cdb, cdb_path); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "confdb_init failed: %d\n", ret); goto done; } *_cdb = talloc_steal(mem_ctx, cdb); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t mock_confdb_domain(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, const char *db_path, const char *name, const char *id_provider, struct sss_test_conf_param *params, char **_cdb_path) { TALLOC_CTX *tmp_ctx = NULL; const char *val[2] = {NULL, NULL}; char *cdb_path = NULL; char **array = NULL; char *list = NULL; bool exists = false; errno_t ret; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n")); return ENOMEM; } /* get current domain list */ ret = confdb_get_string(cdb, tmp_ctx, "config/sssd", "domains", NULL, &list); if (ret != EOK) { goto done; } /* check if the domain is already in */ if (list != NULL) { ret = split_on_separator(tmp_ctx, list, ',', true, true, &array, NULL); if (ret != EOK) { goto done; } for (i = 0; array[i] != NULL; i++) { if (strcmp(array[i], name) == 0) { exists = true; break; } } } /* add domain to the list of enabled domains */ if (!exists) { if (list == NULL) { list = talloc_strdup(tmp_ctx, name); } else { list = talloc_asprintf_append(list, ", %s", name); } if (list == NULL) { ret = ENOMEM; goto done; } val[0] = list; ret = confdb_add_param(cdb, true, "config/sssd", "domains", val); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to change domain list [%d]: %s\n", ret, sss_strerror(ret)); goto done; } } /* create domain section */ cdb_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, name); if (cdb_path == NULL) { ret = ENOMEM; goto done; } val[0] = id_provider; ret = confdb_add_param(cdb, true, cdb_path, "id_provider", val); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add id_provider [%d]: %s\n", ret, sss_strerror(ret)); goto done; } if (params != NULL) { for (i = 0; params[i].key != NULL; i++) { val[0] = params[i].value; ret = confdb_add_param(cdb, true, cdb_path, params[i].key, val); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add parameter %s [%d]: " "%s\n", params[i].key, ret, sss_strerror(ret)); goto done; } } } if (_cdb_path != NULL) { *_cdb_path = talloc_steal(mem_ctx, cdb_path); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t mock_domain(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, const char *db_path, const char *name, struct sss_domain_info **_domain) { struct sss_domain_info *domain = NULL; errno_t ret; /* initialize sysdb */ ret = sssd_domain_init(mem_ctx, cdb, name, db_path, &domain); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sssd_domain_init() of %s failed " "[%d]: %s\n", name, ret, sss_strerror(ret)); goto done; } /* init with an AD-style regex to be able to test flat name */ ret = sss_names_init_from_args(domain, "(((?P[^\\\\]+)\\\\(?P.+$))|" \ "((?P[^@]+)@(?P.+$))|" \ "(^(?P[^@\\\\]+)$))", "%1$s@%2$s", &domain->names); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "cannot create names context\n"); goto done; } if (_domain != NULL) { *_domain = domain; } ret = EOK; done: if (ret != EOK) { talloc_free(domain); } return ret; } struct sss_test_ctx * create_multidom_test_ctx(TALLOC_CTX *mem_ctx, const char *tests_path, const char *cdb_file, const char **domains, const char *id_provider, struct sss_test_conf_param *params) { struct sss_domain_info *domain = NULL; struct sss_test_ctx *test_ctx = NULL; char *cdb_path = NULL; errno_t ret; int i; test_ctx = create_ev_test_ctx(mem_ctx); if (test_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "create_ev_test_ctx() failed\n"); goto fail; } ret = mock_confdb(test_ctx, tests_path, cdb_file, &test_ctx->confdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize confdb [%d]: %s\n", ret, sss_strerror(ret)); goto fail; } /* create confdb objects for the domains */ for (i = 0; domains[i] != NULL; i++) { ret = mock_confdb_domain(test_ctx, test_ctx->confdb, tests_path, domains[i], id_provider, params, (cdb_path == NULL ? &cdb_path : NULL)); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize confdb domain " "[%d]: %s\n", ret, sss_strerror(ret)); goto fail; } } /* initialize domain list and sysdb of the domains */ for (i = 0; domains[i] != NULL; i++) { ret = mock_domain(test_ctx, test_ctx->confdb, tests_path, domains[i], (domain == NULL ? &domain : NULL)); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add new domain [%d]: %s\n", ret, sss_strerror(ret)); goto fail; } } /* the first domain we obtained is already head of the complete list */ test_ctx->dom = domain; /* set data from the first domain */ test_ctx->sysdb = test_ctx->dom->sysdb; test_ctx->nctx = test_ctx->dom->names; test_ctx->conf_dom_path = cdb_path; return test_ctx; fail: talloc_free(test_ctx); return NULL; } struct sss_test_ctx * create_dom_test_ctx(TALLOC_CTX *mem_ctx, const char *tests_path, const char *confdb_path, const char *domain_name, const char *id_provider, struct sss_test_conf_param *params) { const char *domains[] = {domain_name, NULL}; return create_multidom_test_ctx(mem_ctx, tests_path, confdb_path, domains, id_provider, params); } void test_multidom_suite_cleanup(const char *tests_path, const char *cdb_file, const char **domains) { TALLOC_CTX *tmp_ctx = NULL; char *cdb_path = NULL; char *sysdb_path = NULL; errno_t ret; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return; } if (cdb_file != NULL) { cdb_path = talloc_asprintf(tmp_ctx, "%s/%s", tests_path, cdb_file); if (cdb_path == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not contruct cdb path\n"); goto done; } errno = 0; ret = unlink(cdb_path); if (ret != 0 && errno != ENOENT) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test config " "ldb file [%d]: (%s)\n", ret, sss_strerror(ret)); } } if (domains != NULL) { for (i = 0; domains[i] != NULL; i++) { if (strcmp(domains[i], LOCAL_SYSDB_FILE) == 0) { /* local domain */ sysdb_path = talloc_asprintf(tmp_ctx, "%s/%s", tests_path, domains[i]); } else { sysdb_path = talloc_asprintf(tmp_ctx, "%s/cache_%s.ldb", tests_path, domains[i]); } if (sysdb_path == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct sysdb path\n"); goto done; } errno = 0; ret = unlink(sysdb_path); if (ret != 0 && errno != ENOENT) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test domain " "ldb file [%d]: (%s)\n", ret, sss_strerror(ret)); } talloc_zfree(sysdb_path); } } errno = 0; ret = rmdir(tests_path); if (ret != 0 && errno != ENOENT) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test dir (%d) (%s)\n", ret, sss_strerror(ret)); } done: talloc_free(tmp_ctx); } void test_dom_suite_cleanup(const char *tests_path, const char *cdb_file, const char *domain) { const char *domains[] = {domain, NULL}; test_multidom_suite_cleanup(tests_path, cdb_file, domains); } struct sss_domain_info *named_domain(TALLOC_CTX *mem_ctx, const char *name, struct sss_domain_info *parent) { struct sss_domain_info *dom = NULL; dom = talloc_zero(mem_ctx, struct sss_domain_info); if (dom == NULL) { return NULL; } dom->name = talloc_strdup(dom, name); if (dom->name == NULL) { talloc_free(dom); return NULL; } dom->parent = parent; return dom; } sssd-1.13.4/src/tests/PaxHeaders.16287/sbus_codegen_tests_generated.h0000644000000000000000000000007412703456111022327 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.966794687 sssd-1.13.4/src/tests/sbus_codegen_tests_generated.h0000644002412700241270000001775112703456111024011 0ustar00jhrozekjhrozek00000000000000/* The following declarations are auto-generated from sbus_codegen_tests.xml */ #ifndef __SBUS_CODEGEN_TESTS_XML__ #define __SBUS_CODEGEN_TESTS_XML__ #include "sbus/sssd_dbus.h" /* ------------------------------------------------------------------------ * DBus Constants * * Various constants of interface and method names mostly for use by clients */ /* constants for com.planetexpress.Ship */ #define COM_PLANETEXPRESS_SHIP "com.planetexpress.Ship" #define COM_PLANETEXPRESS_SHIP_MOVEUNIVERSE "MoveUniverse" #define COM_PLANETEXPRESS_SHIP_CRASH_NOW "Crash" #define COM_PLANETEXPRESS_SHIP_LAND "Land" #define COM_PLANETEXPRESS_SHIP_BECAMESENTIENT "BecameSentient" #define COM_PLANETEXPRESS_SHIP_COLOR "Color" /* constants for com.planetexpress.Pilot */ #define TEST_PILOT "com.planetexpress.Pilot" #define TEST_PILOT_BLINK "Blink" #define TEST_PILOT_EJECT "Eject" #define TEST_PILOT_FULLNAME "FullName" #define TEST_PILOT_BYTE "byte" #define TEST_PILOT_BOOLEAN "boolean" #define TEST_PILOT_INT16 "int16" #define TEST_PILOT_UINT16 "uint16" #define TEST_PILOT_INT32 "int32" #define TEST_PILOT_UINT32 "uint32" #define TEST_PILOT_INT64 "int64" #define TEST_PILOT_UINT64 "uint64" #define TEST_PILOT_DOUBLE "double" #define TEST_PILOT_STRING "string" #define TEST_PILOT_OBJECT_PATH "object_path" #define TEST_PILOT_NULL_STRING "null_string" #define TEST_PILOT_NULL_PATH "null_path" #define TEST_PILOT_BYTE_ARRAY "byte_array" #define TEST_PILOT_INT16_ARRAY "int16_array" #define TEST_PILOT_UINT16_ARRAY "uint16_array" #define TEST_PILOT_INT32_ARRAY "int32_array" #define TEST_PILOT_UINT32_ARRAY "uint32_array" #define TEST_PILOT_INT64_ARRAY "int64_array" #define TEST_PILOT_UINT64_ARRAY "uint64_array" #define TEST_PILOT_DOUBLE_ARRAY "double_array" #define TEST_PILOT_STRING_ARRAY "string_array" #define TEST_PILOT_OBJECT_PATH_ARRAY "object_path_array" /* constants for com.planetexpress.Special */ #define TEST_SPECIAL "com.planetexpress.Special" #define TEST_SPECIAL_ARRAY_DICT_SAS "array_dict_sas" /* ------------------------------------------------------------------------ * DBus handlers * * These structures are filled in by implementors of the different * dbus interfaces to handle method calls. * * Handler functions of type sbus_msg_handler_fn accept raw messages, * other handlers are typed appropriately. If a handler that is * set to NULL is invoked it will result in a * org.freedesktop.DBus.Error.NotSupported error for the caller. * * Handlers have a matching xxx_finish() function (unless the method has * accepts raw messages). These finish functions the * sbus_request_return_and_finish() with the appropriate arguments to * construct a valid reply. Once a finish function has been called, the * @dbus_req it was called with is freed and no longer valid. */ /* vtable for com.planetexpress.Ship */ struct com_planetexpress_Ship { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*MoveUniverse)(struct sbus_request *req, void *data, bool arg_smoothly, uint32_t arg_speed_factor); int (*crash_now)(struct sbus_request *req, void *data, const char *arg_where); sbus_msg_handler_fn Land; void (*get_Color)(struct sbus_request *, void *data, const char **); }; /* finish function for MoveUniverse */ int com_planetexpress_Ship_MoveUniverse_finish(struct sbus_request *req, const char *arg_where_we_crashed); /* finish function for Crash */ int com_planetexpress_Ship_crash_now_finish(struct sbus_request *req); /* vtable for com.planetexpress.Pilot */ struct test_pilot { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*Blink)(struct sbus_request *req, void *data, uint32_t arg_duration); int (*Eject)(struct sbus_request *req, void *data, uint8_t arg_byte, bool arg_boolean, int16_t arg_int16, uint16_t arg_uint16, int32_t arg_int32, uint32_t arg_uint32, int64_t arg_int64, uint64_t arg_uint64, double arg_double, const char *arg_string, const char *arg_object_path, uint8_t arg_byte_array[], int len_byte_array, int16_t arg_int16_array[], int len_int16_array, uint16_t arg_uint16_array[], int len_uint16_array, int32_t arg_int32_array[], int len_int32_array, uint32_t arg_uint32_array[], int len_uint32_array, int64_t arg_int64_array[], int len_int64_array, uint64_t arg_uint64_array[], int len_uint64_array, double arg_double_array[], int len_double_array, const char *arg_string_array[], int len_string_array, const char *arg_object_path_array[], int len_object_path_array); void (*get_FullName)(struct sbus_request *, void *data, const char **); void (*get_byte)(struct sbus_request *, void *data, uint8_t*); void (*get_boolean)(struct sbus_request *, void *data, bool*); void (*get_int16)(struct sbus_request *, void *data, int16_t*); void (*get_uint16)(struct sbus_request *, void *data, uint16_t*); void (*get_int32)(struct sbus_request *, void *data, int32_t*); void (*get_uint32)(struct sbus_request *, void *data, uint32_t*); void (*get_int64)(struct sbus_request *, void *data, int64_t*); void (*get_uint64)(struct sbus_request *, void *data, uint64_t*); void (*get_double)(struct sbus_request *, void *data, double*); void (*get_string)(struct sbus_request *, void *data, const char **); void (*get_object_path)(struct sbus_request *, void *data, const char **); void (*get_null_string)(struct sbus_request *, void *data, const char **); void (*get_null_path)(struct sbus_request *, void *data, const char **); void (*get_byte_array)(struct sbus_request *, void *data, uint8_t**, int *); void (*get_int16_array)(struct sbus_request *, void *data, int16_t**, int *); void (*get_uint16_array)(struct sbus_request *, void *data, uint16_t**, int *); void (*get_int32_array)(struct sbus_request *, void *data, int32_t**, int *); void (*get_uint32_array)(struct sbus_request *, void *data, uint32_t**, int *); void (*get_int64_array)(struct sbus_request *, void *data, int64_t**, int *); void (*get_uint64_array)(struct sbus_request *, void *data, uint64_t**, int *); void (*get_double_array)(struct sbus_request *, void *data, double**, int *); void (*get_string_array)(struct sbus_request *, void *data, const char ***, int *); void (*get_object_path_array)(struct sbus_request *, void *data, const char ***, int *); }; /* finish function for Blink */ int test_pilot_Blink_finish(struct sbus_request *req, bool arg_crashed); /* finish function for Eject */ int test_pilot_Eject_finish(struct sbus_request *req, uint8_t arg_byte, bool arg_boolean, int16_t arg_int16, uint16_t arg_uint16, int32_t arg_int32, uint32_t arg_uint32, int64_t arg_int64, uint64_t arg_uint64, double arg_double, const char *arg_string, const char *arg_object_path, uint8_t arg_byte_array[], int len_byte_array, int16_t arg_int16_array[], int len_int16_array, uint16_t arg_uint16_array[], int len_uint16_array, int32_t arg_int32_array[], int len_int32_array, uint32_t arg_uint32_array[], int len_uint32_array, int64_t arg_int64_array[], int len_int64_array, uint64_t arg_uint64_array[], int len_uint64_array, double arg_double_array[], int len_double_array, const char *arg_string_array[], int len_string_array, const char *arg_object_path_array[], int len_object_path_array); /* vtable for com.planetexpress.Special */ struct test_special { struct sbus_vtable vtable; /* derive from sbus_vtable */ void (*get_array_dict_sas)(struct sbus_request *, void *data, hash_table_t **); }; /* ------------------------------------------------------------------------ * DBus Interface Metadata * * These structure definitions are filled in with the information about * the interfaces, methods, properties and so on. * * The actual definitions are found in the accompanying C file next * to this header. */ /* interface info for com.planetexpress.Ship */ extern const struct sbus_interface_meta com_planetexpress_Ship_meta; /* interface info for com.planetexpress.Pilot */ extern const struct sbus_interface_meta test_pilot_meta; /* interface info for com.planetexpress.Special */ extern const struct sbus_interface_meta test_special_meta; #endif /* __SBUS_CODEGEN_TESTS_XML__ */ sssd-1.13.4/src/tests/PaxHeaders.16287/krb5_child-test.c0000644000000000000000000000007412703456111017405 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.935794582 sssd-1.13.4/src/tests/krb5_child-test.c0000644002412700241270000003601312703456111021057 0ustar00jhrozekjhrozek00000000000000/* SSSD Unit tests - exercise the krb5 child Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "util/util.h" #include "src/tools/tools_util.h" /* Interfaces being tested */ #include "providers/krb5/krb5_auth.h" #include "providers/krb5/krb5_common.h" #include "providers/krb5/krb5_utils.h" #include "providers/krb5/krb5_ccache.h" extern struct dp_option default_krb5_opts[]; static krb5_context krb5_error_ctx; #define KRB5_CHILD_TEST_DEBUG(level, error) KRB5_DEBUG(level, krb5_error_ctx, error) #define CHECK_KRET_L(kret, err, label) do { \ if (kret) { \ KRB5_CHILD_TEST_DEBUG(SSSDBG_OP_FAILURE, kret); \ goto label; \ } \ } while(0) \ struct krb5_child_test_ctx { struct tevent_context *ev; struct krb5child_req *kr; bool done; errno_t child_ret; uint8_t *buf; ssize_t len; struct krb5_child_response *res; }; static errno_t setup_krb5_child_test(TALLOC_CTX *mem_ctx, struct krb5_child_test_ctx **_ctx) { struct krb5_child_test_ctx *ctx; ctx = talloc_zero(mem_ctx, struct krb5_child_test_ctx); if (!ctx) return ENOMEM; ctx->ev = tevent_context_init(ctx); if (ctx->ev == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not init tevent context\n"); talloc_free(ctx); return EFAULT; } *_ctx = ctx; return EOK; } int re_destructor(void *memctx) { struct krb5_ctx *ctx = (struct krb5_ctx *) memctx; if (ctx->illegal_path_re) { pcre_free(ctx->illegal_path_re); ctx->illegal_path_re = NULL; } return 0; } static struct krb5_ctx * create_dummy_krb5_ctx(TALLOC_CTX *mem_ctx, const char *realm) { struct krb5_ctx *krb5_ctx; const char *errstr; int errval; int errpos; int i; errno_t ret; krb5_ctx = talloc_zero(mem_ctx, struct krb5_ctx); if (!krb5_ctx) return NULL; krb5_ctx->illegal_path_re = pcre_compile2(ILLEGAL_PATH_PATTERN, 0, &errval, &errstr, &errpos, NULL); if (krb5_ctx->illegal_path_re == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Invalid Regular Expression pattern at position %d. " "(Error: %d [%s])\n", errpos, errval, errstr); goto fail; } talloc_set_destructor((TALLOC_CTX *) krb5_ctx, re_destructor); /* Kerberos options */ krb5_ctx->opts = talloc_zero_array(krb5_ctx, struct dp_option, KRB5_OPTS); if (!krb5_ctx->opts) goto fail; for (i = 0; i < KRB5_OPTS; i++) { krb5_ctx->opts[i].opt_name = default_krb5_opts[i].opt_name; krb5_ctx->opts[i].type = default_krb5_opts[i].type; krb5_ctx->opts[i].def_val = default_krb5_opts[i].def_val; switch (krb5_ctx->opts[i].type) { case DP_OPT_STRING: ret = dp_opt_set_string(krb5_ctx->opts, i, default_krb5_opts[i].def_val.string); break; case DP_OPT_BLOB: ret = dp_opt_set_blob(krb5_ctx->opts, i, default_krb5_opts[i].def_val.blob); break; case DP_OPT_NUMBER: ret = dp_opt_set_int(krb5_ctx->opts, i, default_krb5_opts[i].def_val.number); break; case DP_OPT_BOOL: ret = dp_opt_set_bool(krb5_ctx->opts, i, default_krb5_opts[i].def_val.boolean); break; } if (ret) goto fail; } ret = dp_opt_set_string(krb5_ctx->opts, KRB5_REALM, realm); if (ret) goto fail; return krb5_ctx; fail: talloc_free(krb5_ctx); return NULL; } static struct pam_data * create_dummy_pam_data(TALLOC_CTX *mem_ctx, const char *user, const char *password) { struct pam_data *pd; const char *authtok; size_t authtok_len; errno_t ret; pd = create_pam_data(mem_ctx); if (!pd) goto fail; pd->cmd = SSS_PAM_AUTHENTICATE; pd->user = talloc_strdup(pd, user); if (!pd->user) goto fail; ret = sss_authtok_set_password(pd->authtok, password, 0); if (ret) goto fail; (void)sss_authtok_get_password(pd->authtok, &authtok, &authtok_len); DEBUG(SSSDBG_FUNC_DATA, "Authtok [%s] len [%d]\n", authtok, (int)authtok_len); return pd; fail: talloc_free(pd); return NULL; } static struct krb5child_req * create_dummy_req(TALLOC_CTX *mem_ctx, const char *user, const char *password, const char *realm, const char *ccname, const char *ccname_template, int timeout) { struct krb5child_req *kr; struct passwd *pwd; errno_t ret; /* The top level child request */ kr = talloc_zero(mem_ctx, struct krb5child_req); if (!kr) return NULL; pwd = getpwnam(user); if (!pwd) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot get info on user [%s]\n", user); goto fail; } kr->uid = pwd->pw_uid; kr->gid = pwd->pw_gid; /* The Kerberos context */ kr->krb5_ctx = create_dummy_krb5_ctx(kr, realm); /* PAM Data structure */ kr->pd = create_dummy_pam_data(kr, user, password); ret = krb5_get_simple_upn(kr, kr->krb5_ctx, NULL, kr->pd->user, NULL, &kr->upn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "krb5_get_simple_upn failed.\n"); goto fail; } /* Override options with what was provided by the user */ if (ccname_template) { ret = dp_opt_set_string(kr->krb5_ctx->opts, KRB5_CCNAME_TMPL, ccname_template); if (ret != EOK) goto fail; } if (timeout) { ret = dp_opt_set_int(kr->krb5_ctx->opts, KRB5_AUTH_TIMEOUT, timeout); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to set value for krb5_auth_timeout\n"); goto fail; } } if (!ccname) { kr->ccname = expand_ccname_template(kr, kr, dp_opt_get_cstring(kr->krb5_ctx->opts, KRB5_CCNAME_TMPL), kr->krb5_ctx->illegal_path_re, true, true); if (!kr->ccname) goto fail; DEBUG(SSSDBG_FUNC_DATA, "ccname [%s] uid [%llu] gid [%llu]\n", kr->ccname, (unsigned long long) kr->uid, (unsigned long long) kr->gid); } else { kr->ccname = talloc_strdup(kr, ccname); } if (!kr->ccname) goto fail; DEBUG(SSSDBG_FUNC_DATA, "ccname [%s] uid [%u] gid [%u]\n", kr->ccname, kr->uid, kr->gid); ret = sss_krb5_precreate_ccache(kr->ccname, kr->uid, kr->gid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "create_ccache_dir failed.\n"); goto fail; } return kr; fail: talloc_free(kr); return NULL; } static void child_done(struct tevent_req *req) { struct krb5_child_test_ctx *ctx = tevent_req_callback_data(req, struct krb5_child_test_ctx); errno_t ret; ret = handle_child_recv(req, ctx, &ctx->buf, &ctx->len); talloc_free(req); ctx->done = true; ctx->child_ret = ret; } static void printtime(krb5_timestamp ts) { krb5_error_code kret; char timestring[BUFSIZ]; char fill = '\0'; #ifdef HAVE_KRB5_TIMESTAMP_TO_SFSTRING kret = krb5_timestamp_to_sfstring(ts, timestring, BUFSIZ, &fill); if (kret) { KRB5_CHILD_TEST_DEBUG(SSSDBG_OP_FAILURE, kret); } printf("%s", timestring); #else printf("%s", ctime(&ts)); #endif /* HAVE_KRB5_TIMESTAMP_TO_SFSTRING */ } static void print_creds(krb5_context kcontext, krb5_creds *cred, const char *defname) { krb5_error_code kret; char *name = NULL; char *sname = NULL; kret = krb5_unparse_name(kcontext, cred->client, &name); CHECK_KRET_L(kret, EIO, done); kret = krb5_unparse_name(kcontext, cred->server, &sname); CHECK_KRET_L(kret, EIO, done); if (!cred->times.starttime) { cred->times.starttime = cred->times.authtime; } printf("\t\t%s\n", sname); printf("\t\tValid from\t"); printtime(cred->times.starttime); printf("\n\t\tValid until\t"); printtime(cred->times.endtime); printf("\n"); if (strcmp(name, defname)) { printf("\t\tfor client %s", name); } done: krb5_free_unparsed_name(kcontext, name); krb5_free_unparsed_name(kcontext, sname); } static errno_t print_ccache(const char *cc) { krb5_cc_cursor cur; krb5_ccache cache = NULL; krb5_error_code kret; krb5_context kcontext = NULL; krb5_principal_data *princ = NULL; krb5_creds creds; char *defname = NULL; int i = 1; errno_t ret = EIO; kret = krb5_init_context(&kcontext); CHECK_KRET_L(kret, EIO, done); kret = krb5_cc_resolve(kcontext, cc, &cache); CHECK_KRET_L(kret, EIO, done); kret = krb5_cc_get_principal(kcontext, cache, &princ); CHECK_KRET_L(kret, EIO, done); kret = krb5_unparse_name(kcontext, princ, &defname); CHECK_KRET_L(kret, EIO, done); printf("\nTicket cache: %s:%s\nDefault principal: %s\n\n", krb5_cc_get_type(kcontext, cache), krb5_cc_get_name(kcontext, cache), defname); kret = krb5_cc_start_seq_get(kcontext, cache, &cur); CHECK_KRET_L(kret, EIO, done); while (!(kret = krb5_cc_next_cred(kcontext, cache, &cur, &creds))) { printf("Ticket #%d:\n", i); print_creds(kcontext, &creds, defname); krb5_free_cred_contents(kcontext, &creds); } kret = krb5_cc_end_seq_get(kcontext, cache, &cur); CHECK_KRET_L(kret, EIO, done); ret = EOK; done: krb5_cc_close(kcontext, cache); krb5_free_unparsed_name(kcontext, defname); krb5_free_principal(kcontext, princ); krb5_free_context(kcontext); return ret; } int main(int argc, const char *argv[]) { int opt; errno_t ret; struct krb5_child_test_ctx *ctx = NULL; struct tevent_req *req; int pc_debug = 0; int pc_timeout = 0; const char *pc_user = NULL;; const char *pc_passwd = NULL;; const char *pc_realm = NULL;; const char *pc_ccname = NULL;; const char *pc_ccname_tp = NULL;; char *password = NULL; bool rm_ccache = true; poptContext pc; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, "The debug level to run with", NULL }, { "user", 'u', POPT_ARG_STRING, &pc_user, 0, "The user to log in as", NULL }, { "password", 'w', POPT_ARG_STRING, &pc_passwd, 0, "The authtok to use", NULL }, { "ask-password", 'W', POPT_ARG_NONE, NULL, 'W', "Ask interactively for authtok", NULL }, { "ccname", 'c', POPT_ARG_STRING, &pc_ccname, 0, "Force usage of a certain credential cache", NULL }, { "ccname-template", 't', POPT_ARG_STRING, &pc_ccname_tp, 0, "Specify the credential cache template", NULL }, { "realm", 'r', POPT_ARG_STRING, &pc_realm, 0, "The Kerberos realm to use", NULL }, { "keep-ccache", 'k', POPT_ARG_NONE, NULL, 'k', "Do not delete the ccache when the tool finishes", NULL }, { "timeout", '\0', POPT_ARG_INT, &pc_timeout, 0, "The timeout for the child, in seconds", NULL }, POPT_TABLEEND }; debug_prg_name = argv[0]; pc = poptGetContext(NULL, argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) > 0) { switch(opt) { case 'W': errno = 0; password = getpass("Enter password:"); if (!password) { return 1; } break; case 'k': rm_ccache = false; break; default: DEBUG(SSSDBG_FATAL_FAILURE, "Unexpected option\n"); return 1; } } DEBUG_CLI_INIT(pc_debug); if (opt != -1) { poptPrintUsage(pc, stderr, 0); fprintf(stderr, "%s", poptStrerror(opt)); return 1; } if (!pc_user) { DEBUG(SSSDBG_FATAL_FAILURE, "Please specify the user\n"); poptPrintUsage(pc, stderr, 0); return 1; } if (!pc_realm) { DEBUG(SSSDBG_FATAL_FAILURE, "Please specify the realm\n"); poptPrintUsage(pc, stderr, 0); return 1; } if (!password && !pc_passwd) { DEBUG(SSSDBG_FATAL_FAILURE, "Password was not provided or asked for\n"); poptPrintUsage(pc, stderr, 0); return 1; } if (pc_ccname && pc_ccname_tp) { DEBUG(SSSDBG_MINOR_FAILURE, "Both ccname and ccname template specified, " "will prefer ccname\n"); } ret = setup_krb5_child_test(NULL, &ctx); if (ret != EOK) { poptPrintUsage(pc, stderr, 0); fprintf(stderr, "%s", poptStrerror(opt)); return 3; } ctx->kr = create_dummy_req(ctx, pc_user, password ? password : pc_passwd, pc_realm, pc_ccname, pc_ccname_tp, pc_timeout); if (!ctx->kr) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot create Kerberos request\n"); ret = 4; goto done; } req = handle_child_send(ctx, ctx->ev, ctx->kr); if (!req) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot create child request\n"); ret = 4; goto done; } tevent_req_set_callback(req, child_done, ctx); while (ctx->done == false) { tevent_loop_once(ctx->ev); } printf("Child returned %d\n", ctx->child_ret); ret = parse_krb5_child_response(ctx, ctx->buf, ctx->len, ctx->kr->pd, 0, &ctx->res); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not parse child response\n"); ret = 5; goto done; } if (!ctx->res->ccname) { fprintf(stderr, "No ccname returned\n"); ret = 6; goto done; } print_ccache(ctx->res->ccname); ret = 0; done: if (rm_ccache && ctx->res && ctx->res->ccname && ctx->kr) { sss_krb5_cc_destroy(ctx->res->ccname, ctx->kr->uid, ctx->kr->gid); } free(password); talloc_free(ctx); poptFreeContext(pc); return ret; } sssd-1.13.4/src/tests/PaxHeaders.16287/sss_config-tests.c0000644000000000000000000000007312703456111017716 xustar0030 atime=1460561751.658715654 29 ctime=1460561774.97379471 sssd-1.13.4/src/tests/sss_config-tests.c0000644002412700241270000005360212703456111021374 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "util/util.h" #include "util/sss_config.h" #include "tests/common.h" #include "tests/common_check.h" #define TEST_SUBDIR "test_sss_config" #define TEST_FILE TEST_SUBDIR "/sss_config_test.conf" #define TEST_FILE_BACKUP TEST_FILE ".augsave" /* input files */ const char *test_orig = "[sssd]\n\ services = nss, pam\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *test_svc_one = "[sssd]\n\ services = nss\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *test_svc_empty = "[sssd]\n\ services =\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *test_svc_missing = "[sssd]\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *test_dom_empty = "[sssd]\n\ services = nss, pam\n\ domains =\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *test_dom_missing = "[sssd]\n\ services = nss, pam\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *test_dom_two = "[sssd]\n\ services = nss, pam\n\ domains = LDAP, IPA\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; /* expected */ const char *exp_debug_level_exist = "[sssd]\n\ services = nss, pam\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0330\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_debug_level_notexist = "[sssd]\n\ services = nss, pam\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n\ [nss]\n\ debug_level=0x0330\n"; const char *exp_svc = "[sssd]\n\ services = nss, pam, pac\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_svc_empty = "[sssd]\n\ services =pac\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_svc_missing = "[sssd]\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ services=pac\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_svc_disable = "[sssd]\n\ services = pam\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_svc_disable_one = "[sssd]\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_svc_disable_empty = "[sssd]\n\ services =\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_svc_disable_missing = "[sssd]\n\ domains = LDAP\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_dom = "[sssd]\n\ services = nss, pam\n\ domains = LDAP, IPA\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_dom_empty = "[sssd]\n\ services = nss, pam\n\ domains =IPA\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_dom_missing = "[sssd]\n\ services = nss, pam\n\ debug_level = 0x0ff0\n\ domains=IPA\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_dom_disable = "[sssd]\n\ services = nss, pam\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_dom_disable_two = "[sssd]\n\ services = nss, pam\n\ domains = IPA\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; const char *exp_dom_disable_empty = "[sssd]\n\ services = nss, pam\n\ domains =\n\ debug_level = 0x0ff0\n\ [domain/LDAP]\n\ debug_level = 0x0ff0\n\ [domain/IPA]\n\ debug_level = 0x0ff0\n"; struct sss_config_ctx *config_ctx; static bool check_file_content(const char *filename, const char *expected) { FILE *file = NULL; size_t i; int c; bool result; file = fopen(filename, "r"); fail_if(file == NULL, "unable to open test file"); i = 0; while ((c = fgetc(file)) != EOF) { if (c != expected[i]) { printf("\nnot match: %d %c == %d %c\n", c, c, expected[i], expected[i]); result = false; goto done; } i++; } if (expected[i] != '\0') { printf("\nnot end: %d %c == %d %c\n", c, c, expected[i], expected[i]); result = false; goto done; } result = true; done: fclose(file); return result; } static void test_setup(const char *configuration) { FILE *file = NULL; size_t ret; file = fopen(TEST_FILE, "w+"); fail_if(file == NULL, "unable to create test file"); ret = fputs(configuration, file); fail_if(ret == EOF, "unable to write test file"); fail_if(fclose(file) != 0, "unable to close test file"); config_ctx = sss_config_open(NULL, TEST_DIR, TEST_FILE); fail_if(config_ctx == NULL, "config_ctx is NULL"); } static void setup(void) { errno_t ret; ret = mkdir(TEST_SUBDIR, S_IRWXU); if (ret != EOK) { ret = errno; fail("unable to create test dir [%d]: %s", ret, strerror(ret)); } ck_leak_check_setup(); } static void teardown(void) { errno_t ret; sss_config_close(&config_ctx); fail_if(config_ctx != NULL, "config_ctx is not NULL"); unlink(TEST_FILE); unlink(TEST_FILE_BACKUP); ret = rmdir(TEST_SUBDIR); if (ret != EOK) { ret = errno; fail("unable to remove test dir [%d]: %s", ret, strerror(ret)); } ck_leak_check_teardown(); } START_TEST(test_sss_config_set_debug_level_exist) { errno_t ret; bool result; test_setup(test_orig); ret = sss_config_set_debug_level(config_ctx, "domain/LDAP", 0x0330); fail_if(ret != EOK, "unable change configuration"); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration"); result = check_file_content(TEST_FILE, exp_debug_level_exist); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_orig); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_set_debug_level_notexist) { errno_t ret; bool result; test_setup(test_orig); ret = sss_config_set_debug_level(config_ctx, "nss", 0x0330); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_debug_level_notexist); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_orig); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_service_enabled) { errno_t ret; bool result; test_setup(test_orig); ret = sss_config_service_is_enabled(config_ctx, "nss", &result); fail_if(ret != EOK, "unable to read configuration [%d]: %s", ret, strerror(ret)); fail_if(result == false, "wrong result"); } END_TEST START_TEST(test_sss_config_service_disabled) { errno_t ret; bool result; test_setup(test_orig); ret = sss_config_service_is_enabled(config_ctx, "pac", &result); fail_if(ret != EOK, "unable to read configuration [%d]: %s", ret, strerror(ret)); fail_if(result == true, "wrong result"); } END_TEST START_TEST(test_sss_config_service_disabled_empty) { errno_t ret; bool result; test_setup(test_svc_empty); ret = sss_config_service_is_enabled(config_ctx, "pac", &result); fail_if(ret != EOK, "unable to read configuration [%d]: %s", ret, strerror(ret)); fail_if(result == true, "wrong result"); } END_TEST START_TEST(test_sss_config_service_disabled_missing) { errno_t ret; bool result; test_setup(test_svc_missing); ret = sss_config_service_is_enabled(config_ctx, "pac", &result); fail_if(ret != EOK, "unable to read configuration [%d]: %s", ret, strerror(ret)); fail_if(result == true, "wrong result"); } END_TEST START_TEST(test_sss_config_service_enable) { errno_t ret; bool result; test_setup(test_orig); ret = sss_config_service_enable(config_ctx, "pac"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_svc); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_orig); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_service_enable_empty) { errno_t ret; bool result; test_setup(test_svc_empty); ret = sss_config_service_enable(config_ctx, "pac"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_svc_empty); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_svc_empty); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_service_enable_missing) { errno_t ret; bool result; test_setup(test_svc_missing); ret = sss_config_service_enable(config_ctx, "pac"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_svc_missing); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_svc_missing); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_service_disable) { errno_t ret; bool result; test_setup(test_orig); ret = sss_config_service_disable(config_ctx, "nss"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_svc_disable); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_orig); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_service_disable_one) { errno_t ret; bool result; test_setup(test_svc_one); ret = sss_config_service_disable(config_ctx, "nss"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_svc_disable_one); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_svc_one); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_service_disable_empty) { errno_t ret; bool result; test_setup(test_svc_empty); ret = sss_config_service_disable(config_ctx, "nss"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_svc_disable_empty); fail_if(result == false, "file does not match"); /* no backup file created */ } END_TEST START_TEST(test_sss_config_service_disable_missing) { errno_t ret; bool result; test_setup(test_svc_missing); ret = sss_config_service_disable(config_ctx, "nss"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_svc_disable_missing); fail_if(result == false, "file does not match"); /* no backup file created */ } END_TEST START_TEST(test_sss_config_domain_enabled) { errno_t ret; bool result; test_setup(test_orig); ret = sss_config_domain_is_enabled(config_ctx, "LDAP", &result); fail_if(ret != EOK, "unable to read configuration [%d]: %s", ret, strerror(ret)); fail_if(result == false, "wrong result"); } END_TEST START_TEST(test_sss_config_domain_disabled) { errno_t ret; bool result; test_setup(test_orig); ret = sss_config_domain_is_enabled(config_ctx, "AD", &result); fail_if(ret != EOK, "unable to read configuration [%d]: %s", ret, strerror(ret)); fail_if(result == true, "wrong result"); } END_TEST START_TEST(test_sss_config_domain_disabled_empty) { errno_t ret; bool result; test_setup(test_dom_empty); ret = sss_config_domain_is_enabled(config_ctx, "LDAP", &result); fail_if(ret != EOK, "unable to read configuration [%d]: %s", ret, strerror(ret)); fail_if(result == true, "wrong result"); } END_TEST START_TEST(test_sss_config_domain_disabled_missing) { errno_t ret; bool result; test_setup(test_dom_missing); ret = sss_config_domain_is_enabled(config_ctx, "LDAP", &result); fail_if(ret != EOK, "unable to read configuration [%d]: %s", ret, strerror(ret)); fail_if(result == true, "wrong result"); } END_TEST START_TEST(test_sss_config_domain_enable) { errno_t ret; bool result; test_setup(test_orig); ret = sss_config_domain_enable(config_ctx, "IPA"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_dom); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_orig); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_domain_enable_empty) { errno_t ret; bool result; test_setup(test_dom_empty); ret = sss_config_domain_enable(config_ctx, "IPA"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_dom_empty); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_dom_empty); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_domain_enable_missing) { errno_t ret; bool result; test_setup(test_dom_missing); ret = sss_config_domain_enable(config_ctx, "IPA"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_dom_missing); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_dom_missing); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_domain_disable) { errno_t ret; bool result; test_setup(test_orig); ret = sss_config_domain_disable(config_ctx, "LDAP"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_dom_disable); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_orig); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_domain_disable_two) { errno_t ret; bool result; test_setup(test_dom_two); ret = sss_config_domain_disable(config_ctx, "LDAP"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_dom_disable_two); fail_if(result == false, "file does not match"); result = check_file_content(TEST_FILE_BACKUP, test_dom_two); fail_if(result == false, "backup file does not match"); } END_TEST START_TEST(test_sss_config_domain_disable_empty) { errno_t ret; bool result; test_setup(test_dom_empty); ret = sss_config_domain_disable(config_ctx, "LDAP"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_dom_disable_empty); fail_if(result == false, "file does not match"); /* no backup file created */ } END_TEST START_TEST(test_sss_config_domain_disable_missing) { errno_t ret; bool result; test_setup(test_dom_missing); ret = sss_config_domain_disable(config_ctx, "LDAP"); fail_if(ret != EOK, "unable change configuration [%d]: %s", ret, strerror(ret)); ret = sss_config_save(config_ctx); fail_if(ret != EOK, "unable save configuration [%d]: %s", ret, strerror(ret)); result = check_file_content(TEST_FILE, exp_dom_disable); fail_if(result == false, "file does not match"); /* no backup file created */ } END_TEST Suite *sss_config_suite(void) { Suite *s = suite_create("sss_config"); TCase *tc = tcase_create("sss_config"); tcase_add_checked_fixture(tc, setup, teardown); tcase_add_test(tc, test_sss_config_set_debug_level_exist); tcase_add_test(tc, test_sss_config_set_debug_level_notexist); tcase_add_test(tc, test_sss_config_service_enabled); tcase_add_test(tc, test_sss_config_service_disabled); tcase_add_test(tc, test_sss_config_service_disabled_empty); tcase_add_test(tc, test_sss_config_service_disabled_missing); tcase_add_test(tc, test_sss_config_service_enable); tcase_add_test(tc, test_sss_config_service_enable_empty); tcase_add_test(tc, test_sss_config_service_enable_missing); tcase_add_test(tc, test_sss_config_service_disable); tcase_add_test(tc, test_sss_config_service_disable_one); tcase_add_test(tc, test_sss_config_service_disable_empty); tcase_add_test(tc, test_sss_config_service_disable_missing); tcase_add_test(tc, test_sss_config_domain_enabled); tcase_add_test(tc, test_sss_config_domain_disabled); tcase_add_test(tc, test_sss_config_domain_disabled_empty); tcase_add_test(tc, test_sss_config_domain_disabled_missing); tcase_add_test(tc, test_sss_config_domain_enable); tcase_add_test(tc, test_sss_config_domain_enable_empty); tcase_add_test(tc, test_sss_config_domain_enable_missing); tcase_add_test(tc, test_sss_config_domain_disable); tcase_add_test(tc, test_sss_config_domain_disable_two); tcase_add_test(tc, test_sss_config_domain_disable_empty); tcase_add_test(tc, test_sss_config_domain_disable_missing); tcase_set_timeout(tc, 60); suite_add_tcase(s, tc); return s; } int main(int argc, const char *argv[]) { int number_failed; tests_set_cwd(); Suite *s = sss_config_suite(); SRunner *sr = srunner_create(s); srunner_run_all(sr, CK_NORMAL); number_failed = srunner_ntests_failed(sr); srunner_free(sr); if (number_failed == 0) { return EXIT_SUCCESS; } return EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/responder_socket_access-tests.c0000644000000000000000000000007312703456111022453 xustar0030 atime=1460561751.658715654 29 ctime=1460561774.96179467 sssd-1.13.4/src/tests/responder_socket_access-tests.c0000644002412700241270000001202512703456111024123 0ustar00jhrozekjhrozek00000000000000/* SSSD - Test for routine to check to access to responder sockets Authors: Sumit Bose Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "tests/common.h" #include "responder/common/responder.h" struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version responder_test_cli_protocol_version[] = { {0, NULL, NULL} }; return responder_test_cli_protocol_version; } struct s2a_data { const char *inp; int exp_ret; size_t exp_count; uid_t *exp_uids; }; struct s2a_data s2a_data[] = { {"1,2,3", 0, 3, (uid_t []){1, 2, 3}}, {"1,2,3, 4,5 , 6 , 7 ", 0, 7, (uid_t []){1, 2, 3, 4, 5, 6, 7}}, {"1", 0, 1, (uid_t []){1}}, {"1, +2,3", 0, 3, (uid_t []){1, 2, 3}}, {"1, -2,3", ERANGE, 0, NULL}, {"1, 2ab, 3, 4", EINVAL, 0, NULL}, {"1,", EINVAL, 0, NULL}, {"", EINVAL, 0, NULL}, {"1, 2, 4294967295", 0, 3, (uid_t []){1, 2, 4294967295U}}, {"1, 2, 4294967296", ERANGE, 0, NULL}, {"1, 2, root, 4, 5", 0, 5, (uid_t []){1, 2, 0, 4, 5}}, {NULL, EINVAL, 0, NULL}, {NULL, -1, 0, NULL} }; START_TEST(resp_str_to_array_test) { int ret; size_t uid_count; uid_t *uids = NULL; size_t c; size_t d; for (c = 0; s2a_data[c].exp_ret != -1; c++) { ret = csv_string_to_uid_array(global_talloc_context, s2a_data[c].inp, true, &uid_count, &uids); fail_unless(ret == s2a_data[c].exp_ret, "csv_string_to_uid_array failed [%d][%s].", ret, strerror(ret)); if (ret == 0) { fail_unless(uid_count == s2a_data[c].exp_count, "Wrong number of values, expected [%d], got [%d].", s2a_data[c].exp_count, uid_count); for (d = 0; d < s2a_data[c].exp_count; d++) { fail_unless(uids[d] == s2a_data[c].exp_uids[d], "Wrong value, expected [%d], got [%d].\n", s2a_data[c].exp_uids[d], uids[d]); } } talloc_free(uids); uids = NULL; } } END_TEST struct uid_check_data { uid_t uid; size_t allowed_uids_count; uid_t *allowed_uids; int exp_ret; }; struct uid_check_data uid_check_data[] = { {1, 3, (uid_t []){1, 2, 3}, 0}, {2, 3, (uid_t []){1, 2, 3}, 0}, {3, 3, (uid_t []){1, 2, 3}, 0}, {4, 3, (uid_t []){1, 2, 3}, EACCES}, {4, 0, NULL, EINVAL}, {0, 0, NULL, -1} }; START_TEST(check_allowed_uids_test) { int ret; size_t c; for (c = 0; uid_check_data[c].exp_ret != -1; c++) { ret = check_allowed_uids(uid_check_data[c].uid, uid_check_data[c].allowed_uids_count, uid_check_data[c].allowed_uids); fail_unless(ret == uid_check_data[c].exp_ret, "check_allowed_uids failed [%d][%s].", ret, strerror(ret)); } } END_TEST Suite *responder_test_suite(void) { Suite *s = suite_create ("Responder socket access"); TCase *tc_utils = tcase_create("Utility test"); tcase_add_test(tc_utils, resp_str_to_array_test); tcase_add_test(tc_utils, check_allowed_uids_test); suite_add_tcase(s, tc_utils); return s; } int main(int argc, const char *argv[]) { int opt; int number_failed; poptContext pc; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); Suite *s = responder_test_suite(); SRunner *sr = srunner_create(s); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed (sr); srunner_free (sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/auth-tests.c0000644000000000000000000000007412703456111016523 xustar0030 atime=1460561751.655715644 30 ctime=1460561774.909794493 sssd-1.13.4/src/tests/auth-tests.c0000644002412700241270000002532012703456111020174 0ustar00jhrozekjhrozek00000000000000/* SSSD Test for local authentication utilities Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "confdb/confdb.h" #include "db/sysdb.h" #include "tests/common.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_FILE "tests_conf.ldb" struct sysdb_test_ctx { struct sysdb_ctx *sysdb; struct confdb_ctx *confdb; struct tevent_context *ev; struct sss_domain_info *domain; }; static int setup_sysdb_tests(struct sysdb_test_ctx **ctx) { struct sysdb_test_ctx *test_ctx; char *conf_db; int ret; const char *val[2]; val[1] = NULL; /* Create tests directory if it doesn't exist */ /* (relative to current dir) */ ret = mkdir(TESTS_PATH, 0775); if (ret == -1 && errno != EEXIST) { fail("Could not create %s directory", TESTS_PATH); return EFAULT; } test_ctx = talloc_zero(NULL, struct sysdb_test_ctx); if (test_ctx == NULL) { fail("Could not allocate memory for test context"); return ENOMEM; } /* Create an event context * It will not be used except in confdb_init and sysdb_init */ test_ctx->ev = tevent_context_init(test_ctx); if (test_ctx->ev == NULL) { fail("Could not create event context"); talloc_free(test_ctx); return EIO; } conf_db = talloc_asprintf(test_ctx, "%s/%s", TESTS_PATH, TEST_CONF_FILE); if (conf_db == NULL) { fail("Out of memory, aborting!"); talloc_free(test_ctx); return ENOMEM; } DEBUG(SSSDBG_MINOR_FAILURE, "CONFDB: %s\n", conf_db); /* Connect to the conf db */ ret = confdb_init(test_ctx, &test_ctx->confdb, conf_db); if (ret != EOK) { fail("Could not initialize connection to the confdb"); talloc_free(test_ctx); return ret; } val[0] = "LOCAL"; ret = confdb_add_param(test_ctx->confdb, true, "config/sssd", "domains", val); if (ret != EOK) { fail("Could not initialize domains placeholder"); talloc_free(test_ctx); return ret; } val[0] = "local"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "id_provider", val); if (ret != EOK) { fail("Could not initialize provider"); talloc_free(test_ctx); return ret; } val[0] = "TRUE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "enumerate", val); if (ret != EOK) { fail("Could not initialize LOCAL domain"); talloc_free(test_ctx); return ret; } val[0] = "TRUE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "cache_credentials", val); if (ret != EOK) { fail("Could not initialize LOCAL domain"); talloc_free(test_ctx); return ret; } ret = sssd_domain_init(test_ctx, test_ctx->confdb, "local", TESTS_PATH, &test_ctx->domain); if (ret != EOK) { fail("Could not initialize connection to the sysdb (%d)", ret); talloc_free(test_ctx); return ret; } test_ctx->sysdb = test_ctx->domain->sysdb; *ctx = test_ctx; return EOK; } static void do_failed_login_test(uint32_t failed_login_attempts, time_t last_failed_login, int offline_failed_login_attempts, int offline_failed_login_delay, int expected_result, int expected_counter, time_t expected_delay) { struct sysdb_test_ctx *test_ctx = NULL; int ret; const char *val[2]; val[1] = NULL; struct ldb_message *ldb_msg; uint32_t returned_failed_login_attempts; time_t delayed_until; /* Setup */ ret = setup_sysdb_tests(&test_ctx); fail_unless(ret == EOK, "Could not set up the test"); val[0] = talloc_asprintf(test_ctx, "%u", offline_failed_login_attempts); fail_unless(val[0] != NULL, "talloc_sprintf failed"); ret = confdb_add_param(test_ctx->confdb, true, "config/pam", CONFDB_PAM_FAILED_LOGIN_ATTEMPTS, val); fail_unless(ret == EOK, "Could not set offline_failed_login_attempts"); val[0] = talloc_asprintf(test_ctx, "%u", offline_failed_login_delay); ret = confdb_add_param(test_ctx->confdb, true, "config/pam", CONFDB_PAM_FAILED_LOGIN_DELAY, val); fail_unless(ret == EOK, "Could not set offline_failed_login_delay"); ldb_msg = ldb_msg_new(test_ctx); fail_unless(ldb_msg != NULL, "ldb_msg_new failed"); ret = ldb_msg_add_fmt(ldb_msg, SYSDB_FAILED_LOGIN_ATTEMPTS, "%u", failed_login_attempts); fail_unless(ret == EOK, "ldb_msg_add_string failed"); ret = ldb_msg_add_fmt(ldb_msg, SYSDB_LAST_FAILED_LOGIN, "%lld", (long long) last_failed_login); fail_unless(ret == EOK, "ldb_msg_add_string failed"); ret = check_failed_login_attempts(test_ctx->confdb, ldb_msg, &returned_failed_login_attempts, &delayed_until); fail_unless(ret == expected_result, "check_failed_login_attempts returned wrong error code, " "expected [%d], got [%d]", expected_result, ret); fail_unless(returned_failed_login_attempts == expected_counter, "check_failed_login_attempts returned wrong number of failed " "login attempts, expected [%d], got [%d]", expected_counter, failed_login_attempts); fail_unless(delayed_until == expected_delay, "check_failed_login_attempts wrong delay, " "expected [%d], got [%d]", expected_delay, delayed_until); talloc_free(test_ctx); } START_TEST(test_failed_login_attempts) { time_t now; /* if offline_failed_login_attempts == 0 a login is never denied */ do_failed_login_test(0, 0, 0, 5, EOK, 0, -1); do_failed_login_test(0, time(NULL), 0, 5, EOK, 0, -1); do_failed_login_test(2, 0, 0, 5, EOK, 2, -1); do_failed_login_test(2, time(NULL), 0, 5, EOK, 2, -1); do_failed_login_test(0, 0, 0, 0, EOK, 0, -1); do_failed_login_test(0, time(NULL), 0, 0, EOK, 0, -1); do_failed_login_test(2, 0, 0, 0, EOK, 2, -1); do_failed_login_test(2, time(NULL), 0, 0, EOK, 2, -1); /* if offline_failed_login_attempts != 0 and * offline_failed_login_delay == 0 a login is denied if the number of * failed attempts >= offline_failed_login_attempts */ do_failed_login_test(0, 0, 2, 0, EOK, 0, -1); do_failed_login_test(0, time(NULL), 2, 0, EOK, 0, -1); do_failed_login_test(2, 0, 2, 0, ERR_AUTH_DENIED, 2, -1); do_failed_login_test(2, time(NULL), 2, 0, ERR_AUTH_DENIED, 2, -1); /* if offline_failed_login_attempts != 0 and * offline_failed_login_delay != 0 a login is denied only if the number of * failed attempts >= offline_failed_login_attempts AND the last failed * login attempt is not longer than offline_failed_login_delay ago */ do_failed_login_test(0, 0, 2, 5, EOK, 0, -1); do_failed_login_test(0, time(NULL), 2, 5, EOK, 0, -1); do_failed_login_test(2, 0, 2, 5, EOK, 0, -1); now = time(NULL); do_failed_login_test(2, now, 2, 5, ERR_AUTH_DENIED, 2, (now + 5 * 60)); } END_TEST Suite *auth_suite (void) { Suite *s = suite_create ("auth"); TCase *tc_auth = tcase_create ("auth"); tcase_add_test (tc_auth, test_failed_login_attempts); tcase_set_timeout(tc_auth, 60); suite_add_tcase (s, tc_auth); return s; } static int clean_db_dir(void) { int ret; ret = unlink(TESTS_PATH"/"TEST_CONF_FILE); if (ret != EOK && errno != ENOENT) { fprintf(stderr, "Could not delete the test config ldb file (%d) (%s)\n", errno, strerror(errno)); return ret; } ret = unlink(TESTS_PATH"/"LOCAL_SYSDB_FILE); if (ret != EOK && errno != ENOENT) { fprintf(stderr, "Could not delete the test config ldb file (%d) (%s)\n", errno, strerror(errno)); return ret; } ret = rmdir(TESTS_PATH); if (ret != EOK && errno != ENOENT) { fprintf(stderr, "Could not delete the test directory (%d) (%s)\n", errno, strerror(errno)); return ret; } return EOK; } int main(int argc, const char *argv[]) { int ret; int opt; int failure_count; poptContext pc; Suite *s = auth_suite (); SRunner *sr = srunner_create (s); struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); ret = clean_db_dir(); if (ret != EOK) { fprintf(stderr, "Could not delete the db directory (%d) (%s)\n", errno, strerror(errno)); return EXIT_FAILURE; } srunner_run_all(sr, CK_ENV); failure_count = srunner_ntests_failed (sr); srunner_free (sr); if (failure_count == 0) { ret = clean_db_dir(); if (ret != EOK) { fprintf(stderr, "Could not delete the db directory (%d) (%s)\n", errno, strerror(errno)); return EXIT_FAILURE; } return EXIT_SUCCESS; } return EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/files-tests.c0000644000000000000000000000007412703456111016664 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.919794527 sssd-1.13.4/src/tests/files-tests.c0000644002412700241270000002250512703456111020337 0ustar00jhrozekjhrozek00000000000000/* * Authors: * Jakub Hrozek * * Copyright (C) 2008 Red Hat * see file 'COPYING' for use and warranty information * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; version 3 or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "tools/tools_util.h" #include "util/util.h" #include "tests/common.h" static char tpl_dir[] = "file-tests-dir-XXXXXX"; static char *dir_path; static char *dst_path; static uid_t uid; static gid_t gid; static TALLOC_CTX *test_ctx = NULL; static void setup_files_test(void) { /* create a temporary directory that we fill with stuff later on */ test_ctx = talloc_new(NULL); dir_path = mkdtemp(talloc_strdup(test_ctx, tpl_dir)); dst_path = mkdtemp(talloc_strdup(test_ctx, tpl_dir)); uid = getuid(); gid = getgid(); } static void teardown_files_test(void) { char *cmd = NULL; int ret; /* OK this is crude but since the functions to remove tree are under test.. */ if (dir_path && test_ctx) { cmd = talloc_asprintf(test_ctx, "/bin/rm -rf %s\n", dir_path); ret = system(cmd); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "Removing [%s] failed.\n", dir_path); } } if (dst_path && test_ctx) { cmd = talloc_asprintf(test_ctx, "/bin/rm -rf %s\n", dst_path); ret = system(cmd); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "Removing [%s] failed.\n", dst_path); } } /* clean up */ talloc_zfree(test_ctx); } static int create_simple_file(const char *name, const char *content) { int fd; ssize_t size; int ret; fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0700); fail_if(fd == -1, "Cannot create simple file\n"); size = write(fd, "abc", 3); fail_if(size == -1, "Cannot write to file\n"); ret = fsync(fd); fail_if(ret == -1, "Cannot sync file\n"); ret = close(fd); fail_if(ret == -1, "Cannot close file\n"); return ret; } START_TEST(test_remove_tree) { int ret; char origpath[PATH_MAX+1]; errno = 0; fail_unless(getcwd(origpath, PATH_MAX) == origpath, "Cannot getcwd\n"); fail_unless(errno == 0, "Cannot getcwd\n"); DEBUG(SSSDBG_FUNC_DATA, "About to delete %s\n", dir_path); /* create a file */ ret = chdir(dir_path); fail_if(ret == -1, "Cannot chdir1\n"); ret = create_simple_file("bar", "bar"); fail_if(ret == -1, "Cannot create file1\n"); /* create a subdir and file inside it */ ret = mkdir("subdir", 0700); fail_if(ret == -1, "Cannot create subdir\n"); ret = chdir("subdir"); fail_if(ret == -1, "Cannot chdir\n"); ret = create_simple_file("foo", "foo"); fail_if(ret == -1, "Cannot create file\n"); /* create another subdir, empty this time */ ret = mkdir("subdir2", 0700); fail_if(ret == -1, "Cannot create subdir\n"); ret = chdir(origpath); fail_if(ret == -1, "Cannot chdir2\n"); /* go back */ ret = chdir(origpath); fail_if(ret == -1, "Cannot chdir\n"); /* and finally wipe it out.. */ ret = remove_tree(dir_path); fail_unless(ret == EOK, "remove_tree failed\n"); /* check if really gone */ ret = access(dir_path, F_OK); fail_unless(ret == -1, "directory still there after remove_tree\n"); } END_TEST START_TEST(test_simple_copy) { int ret; char origpath[PATH_MAX+1]; char *tmp; int fd = -1; errno = 0; fail_unless(getcwd(origpath, PATH_MAX) == origpath, "Cannot getcwd\n"); fail_unless(errno == 0, "Cannot getcwd\n"); /* create a file */ ret = chdir(dir_path); fail_if(ret == -1, "Cannot chdir1\n"); ret = create_simple_file("bar", "bar"); fail_if(ret == -1, "Cannot create file1\n"); /* create a subdir and file inside it */ ret = mkdir("subdir", 0700); fail_if(ret == -1, "Cannot create subdir\n"); ret = chdir("subdir"); fail_if(ret == -1, "Cannot chdir\n"); ret = create_simple_file("foo", "foo"); fail_if(ret == -1, "Cannot create file\n"); /* go back */ ret = chdir(origpath); fail_if(ret == -1, "Cannot chdir\n"); /* and finally copy.. */ DEBUG(SSSDBG_FUNC_DATA, "Will copy from '%s' to '%s'\n", dir_path, dst_path); ret = copy_tree(dir_path, dst_path, 0700, uid, gid); fail_unless(ret == EOK, "copy_tree failed\n"); /* check if really copied */ ret = access(dst_path, F_OK); fail_unless(ret == 0, "destination directory not there\n"); tmp = talloc_asprintf(test_ctx, "%s/bar", dst_path); ret = check_and_open_readonly(tmp, &fd, uid, gid, S_IFREG|S_IRWXU, 0); fail_unless(ret == EOK, "Cannot open %s\n", tmp); close(fd); talloc_free(tmp); } END_TEST START_TEST(test_copy_symlink) { int ret; char origpath[PATH_MAX+1]; char *tmp; struct stat statbuf; errno = 0; fail_unless(getcwd(origpath, PATH_MAX) == origpath, "Cannot getcwd\n"); fail_unless(errno == 0, "Cannot getcwd\n"); /* create a subdir */ ret = chdir(dir_path); fail_if(ret == -1, "Cannot chdir\n"); ret = create_simple_file("footarget", "foo"); fail_if(ret == -1, "Cannot create file\n"); ret = symlink("footarget", "foolink"); fail_if(ret == -1, "Cannot create symlink\n"); /* go back */ ret = chdir(origpath); fail_if(ret == -1, "Cannot chdir\n"); /* and finally copy.. */ DEBUG(SSSDBG_FUNC_DATA, "Will copy from '%s' to '%s'\n", dir_path, dst_path); ret = copy_tree(dir_path, dst_path, 0700, uid, gid); fail_unless(ret == EOK, "copy_tree failed\n"); /* check if really copied */ ret = access(dst_path, F_OK); fail_unless(ret == 0, "destination directory not there\n"); tmp = talloc_asprintf(test_ctx, "%s/foolink", dst_path); ret = lstat(tmp, &statbuf); fail_unless(ret == 0, "cannot stat the symlink %s\n", tmp); fail_unless(S_ISLNK(statbuf.st_mode), "%s not a symlink?\n", tmp); talloc_free(tmp); } END_TEST START_TEST(test_copy_node) { int ret; char origpath[PATH_MAX+1]; char *tmp; errno = 0; fail_unless(getcwd(origpath, PATH_MAX) == origpath, "Cannot getcwd\n"); fail_unless(errno == 0, "Cannot getcwd\n"); /* create a node */ ret = chdir(dir_path); fail_if(ret == -1, "Cannot chdir\n"); ret = mknod("testnode", S_IFIFO | S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, 0); fail_unless(ret == 0, "cannot stat /dev/null: %s", strerror(errno)); /* go back */ ret = chdir(origpath); fail_if(ret == -1, "Cannot chdir\n"); /* and finally copy.. */ DEBUG(SSSDBG_FUNC_DATA, "Will copy from '%s' to '%s'\n", dir_path, dst_path); ret = copy_tree(dir_path, dst_path, 0700, uid, gid); fail_unless(ret == EOK, "copy_tree failed\n"); /* check if really copied and without special files */ ret = access(dst_path, F_OK); fail_unless(ret == 0, "destination directory not there\n"); tmp = talloc_asprintf(test_ctx, "%s/testnode", dst_path); ret = access(tmp, F_OK); fail_unless(ret == -1, "special file %s exists, it shouldn't\n", tmp); talloc_free(tmp); } END_TEST static Suite *files_suite(void) { Suite *s = suite_create("files_suite"); TCase *tc_files = tcase_create("files"); tcase_add_checked_fixture(tc_files, setup_files_test, teardown_files_test); tcase_add_test(tc_files, test_remove_tree); tcase_add_test(tc_files, test_simple_copy); tcase_add_test(tc_files, test_copy_symlink); tcase_add_test(tc_files, test_copy_node); suite_add_tcase(s, tc_files); return s; } int main(int argc, const char *argv[]) { int number_failed; int opt; poptContext pc; int debug = 0; struct poptOption long_options[] = { POPT_AUTOHELP { "debug-level", 'd', POPT_ARG_INT, &debug, 0, "Set debug level", NULL }, POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, (const char **) argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } poptFreeContext(pc); DEBUG_CLI_INIT(debug); tests_set_cwd(); Suite *s = files_suite(); SRunner *sr = srunner_create(s); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed(sr); srunner_free(sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/ipa_ldap_opt-tests.c0000644000000000000000000000007412703456111020215 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.934794578 sssd-1.13.4/src/tests/ipa_ldap_opt-tests.c0000644002412700241270000004423612703456111021675 0ustar00jhrozekjhrozek00000000000000/* SSSD Tests if IPA and LDAP backend options are in sync Authors: Jakub Hrozek Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "providers/ipa/ipa_common.h" #include "providers/ipa/ipa_opts.h" #include "providers/ldap/sdap.h" #include "providers/ldap/ldap_opts.h" #include "providers/krb5/krb5_opts.h" #include "providers/krb5/krb5_common.h" #include "providers/ad/ad_opts.h" #include "providers/dp_dyndns.h" #include "tests/common.h" struct test_domain { const char *domain; const char *basedn; }; struct test_domain test_domains[] = { { "abc", "dc=abc"}, { "a.b.c", "dc=a,dc=b,dc=c"}, { "A.B.C", "dc=a,dc=b,dc=c"}, { NULL, NULL} }; /* Mock parsing search base without overlinking the test */ errno_t sdap_parse_search_base(TALLOC_CTX *mem_ctx, struct dp_option *opts, int class, struct sdap_search_base ***_search_bases) { return EOK; } START_TEST(test_domain_to_basedn) { int ret; int i; TALLOC_CTX *tmp_ctx; char *basedn; tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "talloc_new failed"); ret = domain_to_basedn(tmp_ctx, NULL, &basedn); fail_unless(ret == EINVAL, "domain_to_basedn does not fail with EINVAL if domain is NULL"); ret = domain_to_basedn(tmp_ctx, "abc", NULL); fail_unless(ret == EINVAL, "domain_to_basedn does not fail with EINVAL if basedn is NULL"); for(i=0; test_domains[i].domain != NULL; i++) { ret = domain_to_basedn(tmp_ctx, test_domains[i].domain, &basedn); fail_unless(ret == EOK, "domain_to_basedn failed"); fail_unless(strcmp(basedn, test_domains[i].basedn) == 0, "domain_to_basedn returned wrong basedn, " "get [%s], expected [%s]", basedn, test_domains[i].basedn); talloc_free(basedn); } talloc_free(tmp_ctx); } END_TEST START_TEST(test_compare_opts) { errno_t ret; ret = compare_dp_options(default_basic_opts, SDAP_OPTS_BASIC, ipa_def_ldap_opts); fail_unless(ret == EOK, "[%s]", strerror(ret)); ret = compare_dp_options(default_krb5_opts, KRB5_OPTS, ipa_def_krb5_opts); fail_unless(ret == EOK, "[%s]", strerror(ret)); ret = compare_dp_options(ipa_dyndns_opts, DP_OPT_DYNDNS, ad_dyndns_opts); fail_unless(ret == EOK, "[%s]", strerror(ret)); } END_TEST START_TEST(test_compare_sdap_attrs) { errno_t ret; /* General Attributes */ ret = compare_sdap_attr_maps(generic_attr_map, SDAP_AT_GENERAL, ipa_attr_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); /* User Attributes */ ret = compare_sdap_attr_maps(rfc2307_user_map, SDAP_OPTS_USER, ipa_user_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); /* Group Attributes */ ret = compare_sdap_attr_maps(rfc2307_group_map, SDAP_OPTS_GROUP, ipa_group_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); /* Service Attributes */ ret = compare_sdap_attr_maps(service_map, SDAP_OPTS_SERVICES, ipa_service_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); /* AutoFS Attributes */ ret = compare_sdap_attr_maps(rfc2307_autofs_mobject_map, SDAP_OPTS_AUTOFS_MAP, ipa_autofs_mobject_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); ret = compare_sdap_attr_maps(rfc2307_autofs_entry_map, SDAP_OPTS_AUTOFS_ENTRY, ipa_autofs_entry_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); } END_TEST START_TEST(test_compare_2307_with_2307bis) { errno_t ret; /* User Attributes */ ret = compare_sdap_attr_maps(rfc2307_user_map, SDAP_OPTS_USER, rfc2307bis_user_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); /* Group Attributes */ ret = compare_sdap_attr_maps(rfc2307_group_map, SDAP_OPTS_GROUP, rfc2307bis_group_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); /* AutoFS Attributes */ ret = compare_sdap_attr_maps(rfc2307_autofs_mobject_map, SDAP_OPTS_AUTOFS_MAP, rfc2307bis_autofs_mobject_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); ret = compare_sdap_attr_maps(rfc2307_autofs_entry_map, SDAP_OPTS_AUTOFS_ENTRY, rfc2307bis_autofs_entry_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); } END_TEST static void fail_unless_dp_opt_is_terminator(struct dp_option *o) { fail_unless(o->opt_name == NULL); fail_unless(o->type == 0); fail_unless(o->def_val.string == NULL); fail_unless(o->val.string == NULL); } static void fail_unless_sdap_opt_is_terminator(struct sdap_attr_map *m) { fail_unless(m->name == NULL); fail_unless(m->def_name == NULL); fail_unless(m->sys_name == NULL); fail_unless(m->opt_name == NULL); } START_TEST(test_dp_opt_sentinel) { fail_unless_dp_opt_is_terminator(&default_basic_opts[SDAP_OPTS_BASIC]); fail_unless_dp_opt_is_terminator(&default_krb5_opts[KRB5_OPTS]); fail_unless_dp_opt_is_terminator(&ad_basic_opts[AD_OPTS_BASIC]); fail_unless_dp_opt_is_terminator(&ad_def_ldap_opts[SDAP_OPTS_BASIC]); fail_unless_dp_opt_is_terminator(&ad_def_krb5_opts[KRB5_OPTS]); fail_unless_dp_opt_is_terminator(&ipa_basic_opts[IPA_OPTS_BASIC]); fail_unless_dp_opt_is_terminator(&ipa_def_ldap_opts[SDAP_OPTS_BASIC]); fail_unless_dp_opt_is_terminator(&ipa_def_krb5_opts[KRB5_OPTS]); fail_unless_dp_opt_is_terminator(&ad_dyndns_opts[DP_OPT_DYNDNS]); fail_unless_dp_opt_is_terminator(&ipa_dyndns_opts[DP_OPT_DYNDNS]); } END_TEST START_TEST(test_sdap_opt_sentinel) { fail_unless_sdap_opt_is_terminator(&generic_attr_map[SDAP_AT_GENERAL]); fail_unless_sdap_opt_is_terminator(&gen_ipa_attr_map[SDAP_AT_GENERAL]); fail_unless_sdap_opt_is_terminator(&gen_ad_attr_map[SDAP_AT_GENERAL]); fail_unless_sdap_opt_is_terminator(&ad_2008r2_attr_map[SDAP_AT_GENERAL]); fail_unless_sdap_opt_is_terminator(&ipa_attr_map[SDAP_AT_GENERAL]); fail_unless_sdap_opt_is_terminator(&rfc2307_user_map[SDAP_OPTS_USER]); fail_unless_sdap_opt_is_terminator(&rfc2307bis_user_map[SDAP_OPTS_USER]); fail_unless_sdap_opt_is_terminator(&gen_ad2008r2_user_map[SDAP_OPTS_USER]); fail_unless_sdap_opt_is_terminator(&ad_2008r2_user_map[SDAP_OPTS_USER]); fail_unless_sdap_opt_is_terminator(&ipa_user_map[SDAP_OPTS_USER]); fail_unless_sdap_opt_is_terminator(&rfc2307_group_map[SDAP_OPTS_GROUP]); fail_unless_sdap_opt_is_terminator(&rfc2307bis_group_map[SDAP_OPTS_GROUP]); fail_unless_sdap_opt_is_terminator(&gen_ad2008r2_group_map[SDAP_OPTS_GROUP]); fail_unless_sdap_opt_is_terminator(&ad_2008r2_group_map[SDAP_OPTS_GROUP]); fail_unless_sdap_opt_is_terminator(&ipa_group_map[SDAP_OPTS_GROUP]); fail_unless_sdap_opt_is_terminator(&native_sudorule_map[SDAP_OPTS_SUDO]); fail_unless_sdap_opt_is_terminator(&netgroup_map[SDAP_OPTS_NETGROUP]); fail_unless_sdap_opt_is_terminator(&ad_netgroup_map[SDAP_OPTS_NETGROUP]); fail_unless_sdap_opt_is_terminator(&ipa_netgroup_map[IPA_OPTS_NETGROUP]); fail_unless_sdap_opt_is_terminator(&ipa_host_map[IPA_OPTS_HOST]); fail_unless_sdap_opt_is_terminator(&ipa_hostgroup_map[IPA_OPTS_HOSTGROUP]); fail_unless_sdap_opt_is_terminator(&ipa_selinux_user_map[IPA_OPTS_SELINUX_USERMAP]); fail_unless_sdap_opt_is_terminator(&ipa_view_map[IPA_OPTS_VIEW]); fail_unless_sdap_opt_is_terminator(&ipa_override_map[IPA_OPTS_OVERRIDE]); fail_unless_sdap_opt_is_terminator(&service_map[SDAP_OPTS_SERVICES]); fail_unless_sdap_opt_is_terminator(&ad_service_map[SDAP_OPTS_SERVICES]); fail_unless_sdap_opt_is_terminator(&ipa_service_map[SDAP_OPTS_SERVICES]); fail_unless_sdap_opt_is_terminator(&rfc2307_autofs_mobject_map[SDAP_OPTS_AUTOFS_MAP]); fail_unless_sdap_opt_is_terminator(&rfc2307bis_autofs_mobject_map[SDAP_OPTS_AUTOFS_MAP]); fail_unless_sdap_opt_is_terminator(&ad_autofs_mobject_map[SDAP_OPTS_AUTOFS_MAP]); fail_unless_sdap_opt_is_terminator(&ipa_autofs_mobject_map[SDAP_OPTS_AUTOFS_MAP]); fail_unless_sdap_opt_is_terminator(&rfc2307_autofs_entry_map[SDAP_OPTS_AUTOFS_ENTRY]); fail_unless_sdap_opt_is_terminator(&rfc2307bis_autofs_entry_map[SDAP_OPTS_AUTOFS_ENTRY]); fail_unless_sdap_opt_is_terminator(&ad_autofs_entry_map[SDAP_OPTS_AUTOFS_ENTRY]); fail_unless_sdap_opt_is_terminator(&ipa_autofs_entry_map[SDAP_OPTS_AUTOFS_ENTRY]); } END_TEST START_TEST(test_copy_opts) { errno_t ret; TALLOC_CTX *tmp_ctx; struct dp_option *opts; tmp_ctx = talloc_new(NULL); fail_unless(tmp_ctx != NULL, "talloc_new failed"); ret = dp_copy_defaults(tmp_ctx, ad_def_ldap_opts, SDAP_OPTS_BASIC, &opts); fail_unless(ret == EOK, "[%s]", strerror(ret)); for (int i=0; i < SDAP_OPTS_BASIC; i++) { char *s1, *s2; bool b1, b2; int i1, i2; struct dp_opt_blob bl1, bl2; switch (opts[i].type) { case DP_OPT_STRING: s1 = dp_opt_get_string(opts, i); s2 = opts[i].def_val.string; if (s1 != NULL || s2 != NULL) { fail_unless(strcmp(s1, s2) == 0, "Option %s does not have default value after copy\n", opts[i].opt_name); } break; case DP_OPT_NUMBER: i1 = dp_opt_get_int(opts, i); i2 = opts[i].def_val.number; fail_unless(i1 == i2, "Option %s does not have default value after copy\n", opts[i].opt_name); break; case DP_OPT_BOOL: b1 = dp_opt_get_bool(opts, i); b2 = opts[i].def_val.boolean; fail_unless(b1 == b2, "Option %s does not have default value after copy\n", opts[i].opt_name); break; case DP_OPT_BLOB: bl1 = dp_opt_get_blob(opts, i); bl2 = opts[i].def_val.blob; fail_unless(bl1.length == bl2.length, "Blobs differ in size for option %s\n", opts[i].opt_name); fail_unless(memcmp(bl1.data, bl2.data, bl1.length) == 0, "Blobs differ in value for option %s\n", opts[i].opt_name); } } talloc_free(tmp_ctx); } END_TEST START_TEST(test_copy_sdap_map) { errno_t ret; struct sdap_attr_map *out_map; ret = sdap_copy_map(global_talloc_context, rfc2307_user_map, SDAP_OPTS_USER, &out_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); fail_unless(out_map[SDAP_OPTS_USER].name == NULL); fail_unless(out_map[SDAP_OPTS_USER].def_name == NULL); fail_unless(out_map[SDAP_OPTS_USER].sys_name == NULL); fail_unless(out_map[SDAP_OPTS_USER].opt_name == NULL); talloc_free(out_map); ret = sdap_copy_map(global_talloc_context, rfc2307bis_user_map, SDAP_OPTS_USER, &out_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); fail_unless(out_map[SDAP_OPTS_USER].name == NULL); fail_unless(out_map[SDAP_OPTS_USER].def_name == NULL); fail_unless(out_map[SDAP_OPTS_USER].sys_name == NULL); fail_unless(out_map[SDAP_OPTS_USER].opt_name == NULL); talloc_free(out_map); ret = sdap_copy_map(global_talloc_context, ipa_user_map, SDAP_OPTS_USER, &out_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); fail_unless(out_map[SDAP_OPTS_USER].name == NULL); fail_unless(out_map[SDAP_OPTS_USER].def_name == NULL); fail_unless(out_map[SDAP_OPTS_USER].sys_name == NULL); fail_unless(out_map[SDAP_OPTS_USER].opt_name == NULL); talloc_free(out_map); ret = sdap_copy_map(global_talloc_context, gen_ad2008r2_user_map, SDAP_OPTS_USER, &out_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); fail_unless(out_map[SDAP_OPTS_USER].name == NULL); fail_unless(out_map[SDAP_OPTS_USER].def_name == NULL); fail_unless(out_map[SDAP_OPTS_USER].sys_name == NULL); fail_unless(out_map[SDAP_OPTS_USER].opt_name == NULL); talloc_free(out_map); } END_TEST START_TEST(test_extra_opts) { errno_t ret; char *extra_attrs[] = { discard_const("foo"), discard_const("baz:bar"), NULL }; struct sdap_attr_map *in_map; struct sdap_attr_map *out_map; size_t new_size; ret = sdap_copy_map(global_talloc_context, rfc2307_user_map, SDAP_OPTS_USER, &in_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); ret = sdap_extend_map(global_talloc_context, in_map, SDAP_OPTS_USER, extra_attrs, &out_map, &new_size); fail_unless(ret == EOK, "[%s]", sss_strerror(ret)); /* Two extra and sentinel */ fail_unless(new_size != SDAP_OPTS_USER + 3); /* Foo would be saved to sysdb verbatim */ ck_assert_str_eq(out_map[SDAP_OPTS_USER].name, "foo"); ck_assert_str_eq(out_map[SDAP_OPTS_USER].sys_name, "foo"); /* Bar would be saved to sysdb as baz */ ck_assert_str_eq(out_map[SDAP_OPTS_USER+1].name, "bar"); ck_assert_str_eq(out_map[SDAP_OPTS_USER+1].sys_name, "baz"); fail_unless(out_map[SDAP_OPTS_USER+2].name == NULL); talloc_free(out_map); } END_TEST START_TEST(test_no_extra_opts) { errno_t ret; struct sdap_attr_map *in_map; struct sdap_attr_map *out_map; size_t new_size; ret = sdap_copy_map(global_talloc_context, rfc2307_user_map, SDAP_OPTS_USER, &in_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); ret = sdap_extend_map(global_talloc_context, in_map, SDAP_OPTS_USER, NULL, &out_map, &new_size); fail_unless(ret == EOK, "[%s]", sss_strerror(ret)); /* Attributes and sentinel */ fail_unless(new_size != SDAP_OPTS_USER + 1); fail_unless(out_map[SDAP_OPTS_USER].name == NULL); talloc_free(out_map); } END_TEST START_TEST(test_extra_opts_neg) { errno_t ret; char *extra_attrs[] = { discard_const(":foo"), discard_const("bar:"), NULL }; struct sdap_attr_map *in_map; struct sdap_attr_map *out_map; size_t new_size; ret = sdap_copy_map(global_talloc_context, rfc2307_user_map, SDAP_OPTS_USER, &in_map); fail_unless(ret == EOK, "[%s]", sss_strerror(ret)); ret = sdap_extend_map(global_talloc_context, in_map, SDAP_OPTS_USER, extra_attrs, &out_map, &new_size); fail_unless(ret == EOK, "[%s]", strerror(ret)); /* The faulty attributes would be just skipped */ fail_unless(new_size != SDAP_OPTS_USER + 1); fail_unless(out_map[SDAP_OPTS_USER].name == NULL); talloc_free(out_map); } END_TEST START_TEST(test_extra_opts_dup) { errno_t ret; char *extra_attrs[] = { discard_const("name:foo"), NULL }; struct sdap_attr_map *in_map; struct sdap_attr_map *out_map; size_t new_size; ret = sdap_copy_map(global_talloc_context, rfc2307_user_map, SDAP_OPTS_USER, &in_map); fail_unless(ret == EOK, "[%s]", strerror(ret)); ret = sdap_extend_map(global_talloc_context, in_map, SDAP_OPTS_USER, extra_attrs, &out_map, &new_size); fail_unless(ret == ERR_DUP_EXTRA_ATTR, "[%s]", sss_strerror(ret)); } END_TEST Suite *ipa_ldap_opt_suite (void) { Suite *s = suite_create ("ipa_ldap_opt"); TCase *tc_ipa_ldap_opt = tcase_create ("ipa_ldap_opt"); tcase_add_test (tc_ipa_ldap_opt, test_compare_opts); tcase_add_test (tc_ipa_ldap_opt, test_compare_sdap_attrs); tcase_add_test (tc_ipa_ldap_opt, test_compare_2307_with_2307bis); tcase_add_test (tc_ipa_ldap_opt, test_dp_opt_sentinel); tcase_add_test (tc_ipa_ldap_opt, test_sdap_opt_sentinel); suite_add_tcase (s, tc_ipa_ldap_opt); TCase *tc_ipa_utils = tcase_create ("ipa_utils"); tcase_add_test (tc_ipa_utils, test_domain_to_basedn); suite_add_tcase (s, tc_ipa_utils); TCase *tc_dp_opts = tcase_create ("dp_opts"); tcase_add_test (tc_dp_opts, test_copy_opts); suite_add_tcase (s, tc_dp_opts); TCase *tc_sdap_opts = tcase_create ("sdap_opts"); tcase_add_test (tc_sdap_opts, test_copy_sdap_map); suite_add_tcase (s, tc_sdap_opts); TCase *tc_extra_opts = tcase_create ("extra_opts"); tcase_add_test (tc_extra_opts, test_extra_opts); tcase_add_test (tc_extra_opts, test_no_extra_opts); tcase_add_test (tc_extra_opts, test_extra_opts_neg); tcase_add_test (tc_extra_opts, test_extra_opts_dup); suite_add_tcase (s, tc_extra_opts); return s; } int main(void) { int number_failed; tests_set_cwd(); Suite *s = ipa_ldap_opt_suite (); SRunner *sr = srunner_create (s); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed (sr); srunner_free (sr); return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/strtonum-tests.c0000644000000000000000000000007312703456111017454 xustar0030 atime=1460561751.658715654 29 ctime=1460561775.02379488 sssd-1.13.4/src/tests/strtonum-tests.c0000644002412700241270000003625312703456111021135 0ustar00jhrozekjhrozek00000000000000/* SSSD InfoPipe Copyright (C) Stephen Gallagher 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "util/strtonum.h" #include "tests/common.h" /******************** * Utility routines * ********************/ #define EXPECT_UNSET_ERRNO(error) \ do { \ fail_unless(error == 0, "errno unexpectedly set to %d[%s]", \ error, strerror(error)); \ } while(0) #define CHECK_RESULT(expected, actual) \ do { \ fail_unless(actual == expected, "Expected %ld, got %ld", \ expected, actual); \ } while(0) #define CHECK_ERRNO(expected, actual) \ do { \ fail_unless(actual == expected, "Expected errno %d[%s], got %d[%s]", \ expected, strerror(expected), \ actual, strerror(actual)); \ } while(0) #define CHECK_ENDPTR(expected, actual) \ do { \ fail_unless(actual == expected, "Expected endptr %p, got %p", \ expected, actual); \ } while(0) #define CHECK_ZERO_ENDPTR(endptr) \ do { \ fail_unless(endptr && *endptr == '\0', "Invalid endptr"); \ } while(0) /****************** * strtoint tests * ******************/ /* Base-10 */ START_TEST (test_strtoint32_pos_integer_base_10) { int32_t result; const char *input = "123"; int32_t expected = 123; char *endptr; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtoint32_neg_integer_base_10) { int32_t result; const char *input = "-123"; int32_t expected = -123; char *endptr; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtoint32_pos_integer_intmax_base_10) { int32_t result; const char *input = "2147483647"; int32_t expected = INT32_MAX; char *endptr; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtoint32_neg_integer_intmin_base_10) { int32_t result; const char *input = "-2147483648"; int32_t expected = INT32_MIN; char *endptr; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtoint32_pos_integer_overflow_base_10) { int32_t result; const char *input = "8589934592"; int32_t expected = INT32_MAX; char *endptr; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; CHECK_ERRNO(ERANGE, error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtoint32_pos_integer_underflow_base_10) { int32_t result; const char *input = "-8589934592"; int32_t expected = INT32_MIN; char *endptr; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; CHECK_ERRNO(ERANGE, error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtoint32_mixed_alphanumeric_base_10) { int32_t result; const char *input = "12b13"; int32_t expected = 12; char *endptr; const char *expected_endptr = input+2; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtoint32_alphaonly_base_10) { int32_t result; const char *input = "alpha"; int32_t expected = 0; char *endptr; const char *expected_endptr = input; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtoint32_alphastart_base_10) { int32_t result; const char *input = "alpha12345"; int32_t expected = 0; char *endptr; const char *expected_endptr = input; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtoint32_emptystring_base_10) { int32_t result; const char *input = ""; int32_t expected = 0; char *endptr; const char *expected_endptr = input; errno_t error; result = strtoint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST /******************* * strtouint tests * *******************/ /* Base-10 */ START_TEST (test_strtouint32_pos_integer_base_10) { uint32_t result; const char *input = "123"; uint32_t expected = 123; char *endptr; errno_t error; result = strtouint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint32_neg_integer_base_10) { uint32_t result; const char *input = "-123"; uint32_t expected = UINT32_MAX; char *endptr; errno_t error; result = strtouint32(input, &endptr, 10); error = errno; CHECK_ERRNO(ERANGE, error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint32_pos_integer_uintmax_base_10) { uint32_t result; const char *input = "4294967295"; uint32_t expected = UINT32_MAX; char *endptr; errno_t error; result = strtouint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint32_pos_integer_overflow_base_10) { uint32_t result; const char *input = "8589934592"; uint32_t expected = UINT32_MAX; char *endptr; errno_t error; result = strtouint32(input, &endptr, 10); error = errno; CHECK_ERRNO(ERANGE, error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint32_mixed_alphanumeric_base_10) { uint32_t result; const char *input = "12b13"; uint32_t expected = 12; char *endptr; const char *expected_endptr = input+2; errno_t error; result = strtouint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint32_alphaonly_base_10) { uint32_t result; const char *input = "alpha"; uint32_t expected = 0; char *endptr; const char *expected_endptr = input; errno_t error; result = strtouint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint32_alphastart_base_10) { uint32_t result; const char *input = "alpha12345"; uint32_t expected = 0; char *endptr; const char *expected_endptr = input; errno_t error; result = strtouint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint32_emptystring_base_10) { uint32_t result; const char *input = ""; uint32_t expected = 0; char *endptr; const char *expected_endptr = input; errno_t error; result = strtouint32(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST /* Base-10 */ START_TEST (test_strtouint16_pos_integer_base_10) { uint16_t result; const char *input = "123"; uint16_t expected = 123; char *endptr; errno_t error; result = strtouint16(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint16_neg_integer_base_10) { uint32_t result; const char *input = "-123"; uint32_t expected = UINT16_MAX; char *endptr; errno_t error; result = strtouint16(input, &endptr, 10); error = errno; CHECK_ERRNO(ERANGE, error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint16_pos_integer_uintmax_base_10) { uint32_t result; const char *input = "65535"; uint32_t expected = UINT16_MAX; char *endptr; errno_t error; result = strtouint16(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint16_pos_integer_overflow_base_10) { uint32_t result; const char *input = "131072"; uint32_t expected = UINT16_MAX; char *endptr; errno_t error; result = strtouint16(input, &endptr, 10); error = errno; CHECK_ERRNO(ERANGE, error); CHECK_ZERO_ENDPTR(endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint16_mixed_alphanumeric_base_10) { uint32_t result; const char *input = "12b13"; uint32_t expected = 12; char *endptr; const char *expected_endptr = input+2; errno_t error; result = strtouint16(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint16_alphaonly_base_10) { uint32_t result; const char *input = "alpha"; uint32_t expected = 0; char *endptr; const char *expected_endptr = input; errno_t error; result = strtouint16(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint16_alphastart_base_10) { uint32_t result; const char *input = "alpha12345"; uint32_t expected = 0; char *endptr; const char *expected_endptr = input; errno_t error; result = strtouint16(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST START_TEST (test_strtouint16_emptystring_base_10) { uint32_t result; const char *input = ""; uint32_t expected = 0; char *endptr; const char *expected_endptr = input; errno_t error; result = strtouint16(input, &endptr, 10); error = errno; EXPECT_UNSET_ERRNO(error); CHECK_ENDPTR(expected_endptr, endptr); CHECK_RESULT(expected, result); } END_TEST Suite *create_strtonum_suite(void) { Suite *s = suite_create("strtonum"); TCase *tc_strtoint32 = tcase_create("strtoint32 Tests"); tcase_add_test(tc_strtoint32, test_strtoint32_pos_integer_base_10); tcase_add_test(tc_strtoint32, test_strtoint32_neg_integer_base_10); tcase_add_test(tc_strtoint32, test_strtoint32_pos_integer_intmax_base_10); tcase_add_test(tc_strtoint32, test_strtoint32_neg_integer_intmin_base_10); tcase_add_test(tc_strtoint32, test_strtoint32_pos_integer_overflow_base_10); tcase_add_test(tc_strtoint32, test_strtoint32_pos_integer_underflow_base_10); tcase_add_test(tc_strtoint32, test_strtoint32_mixed_alphanumeric_base_10); tcase_add_test(tc_strtoint32, test_strtoint32_alphaonly_base_10); tcase_add_test(tc_strtoint32, test_strtoint32_alphastart_base_10); tcase_add_test(tc_strtoint32, test_strtoint32_emptystring_base_10); TCase *tc_strtouint32 = tcase_create("strtouint32 Tests"); tcase_add_test(tc_strtouint32, test_strtouint32_pos_integer_base_10); tcase_add_test(tc_strtouint32, test_strtouint32_neg_integer_base_10); tcase_add_test(tc_strtouint32, test_strtouint32_pos_integer_uintmax_base_10); tcase_add_test(tc_strtouint32, test_strtouint32_pos_integer_overflow_base_10); tcase_add_test(tc_strtouint32, test_strtouint32_mixed_alphanumeric_base_10); tcase_add_test(tc_strtouint32, test_strtouint32_alphaonly_base_10); tcase_add_test(tc_strtouint32, test_strtouint32_alphastart_base_10); tcase_add_test(tc_strtouint32, test_strtouint32_emptystring_base_10); TCase *tc_strtouint16 = tcase_create("strtouint16 Tests"); tcase_add_test(tc_strtouint16, test_strtouint16_pos_integer_base_10); tcase_add_test(tc_strtouint16, test_strtouint16_neg_integer_base_10); tcase_add_test(tc_strtouint16, test_strtouint16_pos_integer_uintmax_base_10); tcase_add_test(tc_strtouint16, test_strtouint16_pos_integer_overflow_base_10); tcase_add_test(tc_strtouint16, test_strtouint16_mixed_alphanumeric_base_10); tcase_add_test(tc_strtouint16, test_strtouint16_alphaonly_base_10); tcase_add_test(tc_strtouint16, test_strtouint16_alphastart_base_10); tcase_add_test(tc_strtouint16, test_strtouint16_emptystring_base_10); /* Add all test cases to the suite */ suite_add_tcase(s, tc_strtoint32); suite_add_tcase(s, tc_strtouint32); suite_add_tcase(s, tc_strtouint16); return s; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int failure_count; Suite *strtonum_suite; SRunner *sr; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); strtonum_suite = create_strtonum_suite(); sr = srunner_create(strtonum_suite); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); failure_count = srunner_ntests_failed(sr); srunner_free(sr); return (failure_count==0 ? EXIT_SUCCESS : EXIT_FAILURE); } sssd-1.13.4/src/tests/PaxHeaders.16287/simple_access-tests.c0000644000000000000000000000007212703456111020372 xustar0030 atime=1460561751.658715654 28 ctime=1460561774.9707947 sssd-1.13.4/src/tests/simple_access-tests.c0000644002412700241270000005464712703456111022063 0ustar00jhrozekjhrozek00000000000000/* SSSD Simple access module -- Tests Authors: Sumit Bose Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "confdb/confdb.h" #include "providers/simple/simple_access.h" #include "tests/common.h" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_FILE "tests_conf.ldb" const char *ulist_1[] = {"u1", "u2", NULL}; const char *glist_1[] = {"g1", "g2", NULL}; const char *glist_1_case[] = {"G1", "G2", NULL}; struct simple_test_ctx *test_ctx = NULL; struct simple_test_ctx { struct sysdb_ctx *sysdb; struct confdb_ctx *confdb; struct tevent_context *ev; struct be_ctx *be_ctx; bool done; int error; bool access_granted; struct simple_ctx *ctx; }; static int test_loop(struct simple_test_ctx *tctx) { while (!tctx->done) tevent_loop_once(tctx->ev); return tctx->error; } static void simple_access_check_done(struct tevent_req *req) { struct simple_test_ctx *tctx = tevent_req_callback_data(req, struct simple_test_ctx); tctx->error = simple_access_check_recv(req, &tctx->access_granted); talloc_free(req); tctx->done = true; } void setup_simple(void) { errno_t ret; char *conf_db; const char *val[2]; val[1] = NULL; fail_unless(test_ctx == NULL, "Simple context already initialized."); test_ctx = talloc_zero(NULL, struct simple_test_ctx); fail_unless(test_ctx != NULL, "Cannot create simple test context."); test_ctx->ev = tevent_context_init(test_ctx); fail_unless(test_ctx->ev != NULL, "Cannot create tevent context."); test_ctx->ctx = talloc_zero(test_ctx, struct simple_ctx); fail_unless(test_ctx->ctx != NULL, "Cannot create simple context."); /* Create tests directory if it doesn't exist */ /* (relative to current dir) */ ret = mkdir(TESTS_PATH, 0775); fail_if(ret == -1 && errno != EEXIST, "Could not create %s directory", TESTS_PATH); conf_db = talloc_asprintf(test_ctx, "%s/%s", TESTS_PATH, TEST_CONF_FILE); fail_if(conf_db == NULL, "Out of memory, aborting!"); DEBUG(SSSDBG_TRACE_LIBS, "CONFDB: %s\n", conf_db); /* Connect to the conf db */ ret = confdb_init(test_ctx, &test_ctx->confdb, conf_db); fail_if(ret != EOK, "Could not initialize connection to the confdb"); val[0] = "LOCAL"; ret = confdb_add_param(test_ctx->confdb, true, "config/sssd", "domains", val); fail_if(ret != EOK, "Could not initialize domains placeholder"); val[0] = "local"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "id_provider", val); fail_if(ret != EOK, "Could not initialize provider"); val[0] = "TRUE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "enumerate", val); fail_if(ret != EOK, "Could not initialize LOCAL domain"); val[0] = "TRUE"; ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "cache_credentials", val); fail_if(ret != EOK, "Could not initialize LOCAL domain"); ret = sssd_domain_init(test_ctx, test_ctx->confdb, "local", TESTS_PATH, &test_ctx->ctx->domain); fail_if(ret != EOK, "Could not initialize connection to the sysdb (%d)", ret); test_ctx->sysdb = test_ctx->ctx->domain->sysdb; test_ctx->ctx->domain->case_sensitive = true; test_ctx->ctx->domain->mpg = false; /* Simulate an LDAP domain better */ /* be_ctx */ test_ctx->be_ctx = talloc_zero(test_ctx, struct be_ctx); fail_if(test_ctx->be_ctx == NULL, "Unable to setup be_ctx"); test_ctx->be_ctx->cdb = test_ctx->confdb; test_ctx->be_ctx->ev = test_ctx->ev; test_ctx->be_ctx->conf_path = "config/domain/LOCAL"; test_ctx->be_ctx->domain = test_ctx->ctx->domain; test_ctx->ctx->be_ctx = test_ctx->be_ctx; ret = sss_names_init(test_ctx->ctx->domain, test_ctx->confdb, "LOCAL", &test_ctx->be_ctx->domain->names); fail_if(ret != EOK, "Unable to setup domain names (%d)", ret); } void teardown_simple(void) { int ret; fail_unless(test_ctx != NULL, "Simple context already freed."); ret = talloc_free(test_ctx); test_ctx = NULL; fail_unless(ret == 0, "Cannot free simple context."); } void setup_simple_group(void) { errno_t ret; setup_simple(); /* Add test users u1 and u2 that would be members of test groups * g1 and g2 respectively */ ret = sysdb_add_group(test_ctx->ctx->domain, "pvt", 999, NULL, 0, 0); fail_if(ret != EOK, "Could not add private group %s", strerror(ret)); ret = sysdb_store_user(test_ctx->ctx->domain, "u1", NULL, 123, 999, "u1", "/home/u1", "/bin/bash", NULL, NULL, NULL, -1, 0); fail_if(ret != EOK, "Could not add u1"); ret = sysdb_store_user(test_ctx->ctx->domain, "u2", NULL, 456, 999, "u1", "/home/u1", "/bin/bash", NULL, NULL, NULL, -1, 0); fail_if(ret != EOK, "Could not add u2"); ret = sysdb_store_user(test_ctx->ctx->domain, "u3", NULL, 789, 999, "u1", "/home/u1", "/bin/bash", NULL, NULL, NULL, -1, 0); fail_if(ret != EOK, "Could not add u3"); ret = sysdb_add_group(test_ctx->ctx->domain, "g1", 321, NULL, 0, 0); fail_if(ret != EOK, "Could not add g1"); ret = sysdb_add_group(test_ctx->ctx->domain, "g2", 654, NULL, 0, 0); fail_if(ret != EOK, "Could not add g2"); ret = sysdb_add_group_member(test_ctx->ctx->domain, "g1", "u1", SYSDB_MEMBER_USER, false); fail_if(ret != EOK, "Could not add u1 to g1"); ret = sysdb_add_group_member(test_ctx->ctx->domain, "g2", "u2", SYSDB_MEMBER_USER, false); fail_if(ret != EOK, "Could not add u2 to g2"); } void teardown_simple_group(void) { errno_t ret; ret = sysdb_delete_user(test_ctx->ctx->domain, "u1", 0); fail_if(ret != EOK, "Could not delete u1"); ret = sysdb_delete_user(test_ctx->ctx->domain, "u2", 0); fail_if(ret != EOK, "Could not delete u2"); ret = sysdb_delete_user(test_ctx->ctx->domain, "u3", 0); fail_if(ret != EOK, "Could not delete u3"); ret = sysdb_delete_group(test_ctx->ctx->domain, "g1", 0); fail_if(ret != EOK, "Could not delete g1"); ret = sysdb_delete_group(test_ctx->ctx->domain, "g2", 0); fail_if(ret != EOK, "Could not delete g2"); ret = sysdb_delete_group(test_ctx->ctx->domain, "pvt", 0); fail_if(ret != EOK, "Could not delete pvt"); teardown_simple(); } void setup_simple_init(void) { setup_simple(); } void teardown_simple_init(void) { teardown_simple(); } START_TEST(test_both_empty) { struct tevent_req *req; test_ctx->ctx->allow_users = NULL; test_ctx->ctx->deny_users = NULL; req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u1"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == true, "Access denied while both lists are empty."); } END_TEST START_TEST(test_allow_empty) { struct tevent_req *req; test_ctx->ctx->allow_users = NULL; test_ctx->ctx->deny_users = discard_const(ulist_1); req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u1"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); test_ctx->done = false; fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == false, "Access granted while user is in deny list."); req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u3"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == true, "Access denied while user is not in deny list."); } END_TEST START_TEST(test_deny_empty) { struct tevent_req *req; test_ctx->ctx->allow_users = discard_const(ulist_1); test_ctx->ctx->deny_users = NULL; req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u1"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); test_ctx->done = false; fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == true, "Access denied while user is in allow list."); req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u3"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == false, "Access granted while user is not in allow list."); } END_TEST START_TEST(test_both_set) { struct tevent_req *req; test_ctx->ctx->allow_users = discard_const(ulist_1); test_ctx->ctx->deny_users = discard_const(ulist_1); req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u1"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); test_ctx->done = false; fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == false, "Access granted while user is in deny list."); req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u3"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == false, "Access granted while user is not in allow list."); } END_TEST START_TEST(test_case) { struct tevent_req *req; test_ctx->ctx->allow_users = discard_const(ulist_1); test_ctx->ctx->deny_users = NULL; req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "U1"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); test_ctx->done = false; fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == false, "Access granted for user with different case " "in case-sensitive domain"); test_ctx->ctx->domain->case_sensitive = false; req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "U1"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); test_ctx->done = false; fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == true, "Access denied for user with different case " "in case-sensitive domain"); } END_TEST START_TEST(test_unknown_user) { struct tevent_req *req; test_ctx->ctx->allow_users = discard_const(ulist_1); test_ctx->ctx->deny_users = NULL; req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "foo"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); test_ctx->done = false; fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == false, "Access granted for user not present in domain"); } END_TEST START_TEST(test_group_allow_empty) { struct tevent_req *req; test_ctx->ctx->allow_groups = NULL; test_ctx->ctx->deny_groups = discard_const(glist_1); req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u1"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); test_ctx->done = false; fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == false, "Access granted while group is in deny list."); req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u3"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == true, "Access denied while group is not in deny list."); } END_TEST START_TEST(test_group_deny_empty) { struct tevent_req *req; test_ctx->ctx->allow_groups = discard_const(glist_1); test_ctx->ctx->deny_groups = NULL; req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u1"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); test_ctx->done = false; fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == true, "Access denied while user is in allow list."); req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u3"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == false, "Access granted while user is not in allow list."); } END_TEST START_TEST(test_group_both_set) { struct tevent_req *req; test_ctx->ctx->allow_groups = discard_const(ulist_1); test_ctx->ctx->deny_groups = discard_const(ulist_1); req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u1"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); test_ctx->done = false; fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == false, "Access granted while user is in deny list."); req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u3"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == false, "Access granted while user is not in allow list."); } END_TEST START_TEST(test_group_case) { struct tevent_req *req; test_ctx->ctx->allow_groups = discard_const(glist_1_case); test_ctx->ctx->deny_groups = NULL; req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u1"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); test_ctx->done = false; fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == false, "Access granted for user with different case " "in case-sensitive domain"); test_ctx->ctx->domain->case_sensitive = false; req = simple_access_check_send(test_ctx, test_ctx->ev, test_ctx->ctx, "u1"); fail_unless(test_ctx != NULL, "Cannot create request\n"); tevent_req_set_callback(req, simple_access_check_done, test_ctx); test_loop(test_ctx); test_ctx->done = false; fail_unless(test_ctx->error == EOK, "access_simple_check failed."); fail_unless(test_ctx->access_granted == true, "Access denied for user with different case " "in case-sensitive domain"); } END_TEST static void check_access_list(char **list, const char **values) { int i; fail_if(values == NULL, "List is empty, but it shouldn't be"); for (i = 0; list[i] != NULL; i++) { fail_if(values[i] == NULL, "List contains too many entries"); fail_if(strcmp(list[i], values[i]) != 0, "%s != %s", list[i], values[i]); } fail_if(values[i] != NULL, "List contains fewer entries than expected"); } int sssm_simple_access_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data); START_TEST(test_provider_init) { struct bet_ops *bet_ops = NULL; struct simple_ctx *ctx = NULL; errno_t ret; const char *val[2] = {"user-1, user-2@LOCAL, user with space, " "another space@LOCAL", NULL}; const char *correct[] = {"user-1", "user-2", "user with space", "another space", NULL}; /* allow users */ ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "simple_allow_users", val); fail_if(ret != EOK, "Could not setup allow users list"); /* deny users */ ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "simple_deny_users", val); fail_if(ret != EOK, "Could not setup deny users list"); /* allow groups */ ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "simple_allow_groups", val); fail_if(ret != EOK, "Could not setup allow groups list"); /* deny groups */ ret = confdb_add_param(test_ctx->confdb, true, "config/domain/LOCAL", "simple_deny_groups", val); fail_if(ret != EOK, "Could not setup deny groups list"); ret = sssm_simple_access_init(test_ctx->be_ctx, &bet_ops, (void**)&ctx); fail_if(ret != EOK); DEBUG(SSSDBG_TRACE_FUNC, "Checking allow users list\n"); check_access_list(ctx->allow_users, correct); DEBUG(SSSDBG_TRACE_FUNC, "Checking deny users list\n"); check_access_list(ctx->deny_users, correct); DEBUG(SSSDBG_TRACE_FUNC, "Checking allow groups list\n"); check_access_list(ctx->allow_groups, correct); DEBUG(SSSDBG_TRACE_FUNC, "Checking deny groups list\n"); check_access_list(ctx->deny_groups, correct); } END_TEST Suite *access_simple_suite (void) { Suite *s = suite_create("access_simple"); TCase *tc_allow_deny = tcase_create("user allow/deny"); tcase_add_checked_fixture(tc_allow_deny, setup_simple, teardown_simple); tcase_add_test(tc_allow_deny, test_both_empty); tcase_add_test(tc_allow_deny, test_allow_empty); tcase_add_test(tc_allow_deny, test_deny_empty); tcase_add_test(tc_allow_deny, test_both_set); tcase_add_test(tc_allow_deny, test_case); tcase_add_test(tc_allow_deny, test_unknown_user); suite_add_tcase(s, tc_allow_deny); TCase *tc_grp_allow_deny = tcase_create("group allow/deny"); tcase_add_checked_fixture(tc_grp_allow_deny, setup_simple_group, teardown_simple_group); tcase_add_test(tc_grp_allow_deny, test_group_allow_empty); tcase_add_test(tc_grp_allow_deny, test_group_deny_empty); tcase_add_test(tc_grp_allow_deny, test_group_both_set); tcase_add_test(tc_grp_allow_deny, test_group_case); suite_add_tcase(s, tc_grp_allow_deny); TCase *tc_init = tcase_create("provider init"); tcase_add_checked_fixture(tc_init, setup_simple_init, teardown_simple_init); tcase_add_test(tc_init, test_provider_init); suite_add_tcase(s, tc_init); return s; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int number_failed; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_FILE, LOCAL_SYSDB_FILE); Suite *s = access_simple_suite(); SRunner *sr = srunner_create(s); srunner_run_all(sr, CK_ENV); number_failed = srunner_ntests_failed(sr); srunner_free(sr); if (number_failed == 0) { test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_FILE, LOCAL_SYSDB_FILE); } return (number_failed==0 ? EXIT_SUCCESS : EXIT_FAILURE); } sssd-1.13.4/src/tests/PaxHeaders.16287/resolv-tests.c0000644000000000000000000000007412703456111017074 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.957794656 sssd-1.13.4/src/tests/resolv-tests.c0000644002412700241270000007267512703456111020564 0ustar00jhrozekjhrozek00000000000000/* SSSD Async resolver tests Authors: Martin Nagy Jakub Hrozek Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "tests/common.h" #include "util/util.h" #include "tests/common_check.h" /* Interface under test */ #include "resolv/async_resolv.h" #define RESOLV_DEFAULT_TIMEOUT 6 static int use_net_test; static char *txt_host; static char *srv_host; struct resolv_test_ctx { struct tevent_context *ev; struct resolv_ctx *resolv; enum { TESTING_HOSTNAME, TESTING_TXT, TESTING_SRV, } tested_function; int error; bool done; }; static int setup_resolv_test(int timeout, struct resolv_test_ctx **ctx) { struct resolv_test_ctx *test_ctx; int ret; test_ctx = talloc_zero(global_talloc_context, struct resolv_test_ctx); if (test_ctx == NULL) { fail("Could not allocate memory for test context"); return ENOMEM; } test_ctx->ev = tevent_context_init(test_ctx); if (test_ctx->ev == NULL) { fail("Could not init tevent context"); talloc_free(test_ctx); return EFAULT; } ret = resolv_init(test_ctx, test_ctx->ev, timeout, &test_ctx->resolv); if (ret != EOK) { fail("Could not init resolv context"); talloc_free(test_ctx); return ret; } *ctx = test_ctx; return EOK; } static int test_loop(struct resolv_test_ctx *data) { while (!data->done) tevent_loop_once(data->ev); return data->error; } struct resolv_hostent * test_create_rhostent(TALLOC_CTX *mem_ctx, const char *hostname, const char *address) { struct resolv_hostent *rhostent; int ret; int family; rhostent = talloc_zero(mem_ctx, struct resolv_hostent); if (!rhostent) { return NULL; } rhostent->name = talloc_strdup(rhostent, hostname); rhostent->addr_list = talloc_array(rhostent, struct resolv_addr *, 2); if (!rhostent->name || !rhostent->addr_list) { goto fail; } rhostent->addr_list[0] = talloc_zero(rhostent->addr_list, struct resolv_addr); if (!rhostent->addr_list[0]) { goto fail; } rhostent->addr_list[0]->ipaddr = talloc_array(rhostent->addr_list[0], uint8_t, sizeof(struct in6_addr)); if (!rhostent->addr_list[0]->ipaddr) { goto fail; } family = AF_INET; ret = inet_pton(family, address, rhostent->addr_list[0]->ipaddr); if (ret != 1) { family = AF_INET6; ret = inet_pton(family, address, rhostent->addr_list[0]->ipaddr); if (ret != 1) { goto fail; } } rhostent->addr_list[0]->ttl = RESOLV_DEFAULT_TTL; rhostent->addr_list[1] = NULL; rhostent->family = family; rhostent->aliases = NULL; return rhostent; fail: talloc_free(rhostent); return NULL; } START_TEST(test_copy_hostent) { void *ctx; struct resolv_hostent *rhe; char name[] = "foo.example.com"; char alias_1[] = "bar.example.com"; char alias_2[] = "baz.example.com"; char *aliases[] = { alias_1, alias_2, NULL }; struct in_addr addr_1 = { 1234 }; struct in_addr addr_2 = { 5678 }; int ttl_1 = 12; int ttl_2 = 34; char *addr_list[] = { (char *) &addr_2, (char *) &addr_1, NULL }; struct hostent he = { name, aliases, AF_INET, sizeof(addr_1), addr_list }; struct ares_addrttl attl[] = { { addr_1, ttl_1 }, { addr_2, ttl_2 } }; ctx = talloc_new(global_talloc_context); fail_if(ctx == NULL); ck_leaks_push(ctx); rhe = resolv_copy_hostent_ares(ctx, &he, AF_INET, &attl, 2); fail_if(rhe == NULL); fail_if(strcmp(rhe->name, name)); fail_if(strcmp(rhe->aliases[0], alias_1)); fail_if(strcmp(rhe->aliases[1], alias_2)); fail_if(rhe->aliases[2] != NULL); fail_if(rhe->family != AF_INET); fail_if(memcmp(rhe->addr_list[0]->ipaddr, &addr_1, sizeof(addr_1))); fail_if(rhe->addr_list[0]->ttl != ttl_1); fail_if(memcmp(rhe->addr_list[1]->ipaddr, &addr_2, sizeof(addr_2))); fail_if(rhe->addr_list[1]->ttl != ttl_2); fail_if(rhe->addr_list[2] != NULL); talloc_zfree(rhe); rhe = resolv_copy_hostent(ctx, &he); fail_if(rhe == NULL); fail_if(strcmp(rhe->name, name)); fail_if(strcmp(rhe->aliases[0], alias_1)); fail_if(strcmp(rhe->aliases[1], alias_2)); fail_if(rhe->aliases[2] != NULL); fail_if(rhe->family != AF_INET); fail_if(memcmp(rhe->addr_list[0]->ipaddr, &addr_2, sizeof(addr_1))); fail_if(rhe->addr_list[0]->ttl != RESOLV_DEFAULT_TTL); fail_if(memcmp(rhe->addr_list[1]->ipaddr, &addr_1, sizeof(addr_2))); fail_if(rhe->addr_list[1]->ttl != RESOLV_DEFAULT_TTL); fail_if(rhe->addr_list[2] != NULL); talloc_free(rhe); ck_leaks_pop(ctx); } END_TEST START_TEST(test_address_to_string) { void *ctx; struct resolv_hostent *rhe; char *str_addr; char *ptr_addr; ctx = talloc_new(global_talloc_context); fail_if(ctx == NULL); ck_leaks_push(ctx); rhe = test_create_rhostent(ctx, "www.example.com", "1.2.3.4"); fail_if(rhe == NULL); str_addr = resolv_get_string_address_index(ctx, rhe, 0); fail_if(str_addr == NULL); fail_unless(strcmp(str_addr, "1.2.3.4") == 0, "Unexpected address\n"); talloc_free(str_addr); ptr_addr = resolv_get_string_ptr_address(ctx, rhe->family, rhe->addr_list[0]->ipaddr); fail_if(ptr_addr == NULL); fail_unless(strcmp(ptr_addr, "4.3.2.1.in-addr.arpa.") == 0, "Unexpected PTR address\n"); talloc_free(ptr_addr); talloc_free(rhe); rhe = test_create_rhostent(ctx, "www6.example.com", "2607:f8b0:400c:c03::6a"); fail_if(rhe == NULL); str_addr = resolv_get_string_address_index(ctx, rhe, 0); fail_if(str_addr == NULL); fail_unless(strcmp(str_addr, "2607:f8b0:400c:c03::6a") == 0, "Unexpected address\n"); talloc_free(str_addr); ptr_addr = resolv_get_string_ptr_address(ctx, rhe->family, rhe->addr_list[0]->ipaddr); fail_if(ptr_addr == NULL); fail_unless(strcmp(ptr_addr, "a.6.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.c.0.c.0.0.4.0.b.8.f.7.0.6.2.ip6.arpa.") == 0, "Unexpected PTR address\n"); talloc_free(ptr_addr); talloc_free(rhe); ck_leaks_pop(ctx); } END_TEST static void test_ip_addr(struct tevent_req *req) { int recv_status; int status; struct resolv_hostent *rhostent; int i; struct resolv_test_ctx *test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx); test_ctx->done = true; recv_status = resolv_gethostbyname_recv(req, test_ctx, &status, NULL, &rhostent); talloc_zfree(req); if (recv_status != EOK) { DEBUG(SSSDBG_OP_FAILURE, "resolv_gethostbyname_recv failed: %d\n", recv_status); test_ctx->error = recv_status; return; } DEBUG(SSSDBG_TRACE_LIBS, "resolv_gethostbyname_recv status: %d\n", status); test_ctx->error = ENOENT; for (i = 0; rhostent->addr_list[i]; i++) { char addr_buf[256]; inet_ntop(rhostent->family, rhostent->addr_list[i]->ipaddr, addr_buf, sizeof(addr_buf)); if (strcmp(addr_buf, "127.0.0.1") == 0) { test_ctx->error = EOK; } } talloc_free(rhostent); } START_TEST(test_resolv_ip_addr) { struct resolv_test_ctx *test_ctx; int ret = EOK; struct tevent_req *req; const char *hostname = "127.0.0.1"; ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx); if (ret != EOK) { fail("Could not set up test"); return; } ck_leaks_push(test_ctx); req = resolv_gethostbyname_send(test_ctx, test_ctx->ev, test_ctx->resolv, hostname, IPV4_ONLY, default_host_dbs); DEBUG(SSSDBG_TRACE_LIBS, "Sent resolv_gethostbyname\n"); if (req == NULL) { ret = ENOMEM; } if (ret == EOK) { tevent_req_set_callback(req, test_ip_addr, test_ctx); ret = test_loop(test_ctx); } ck_leaks_pop(test_ctx); fail_unless(ret == EOK); talloc_zfree(test_ctx); } END_TEST static void test_localhost(struct tevent_req *req) { int recv_status; int status; struct resolv_hostent *rhostent; int i; struct resolv_test_ctx *test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx); test_ctx->done = true; recv_status = resolv_gethostbyname_recv(req, test_ctx, &status, NULL, &rhostent); talloc_zfree(req); if (recv_status != EOK) { DEBUG(SSSDBG_OP_FAILURE, "resolv_gethostbyname_recv failed: %d\n", recv_status); test_ctx->error = recv_status; return; } DEBUG(SSSDBG_TRACE_LIBS, "resolv_gethostbyname_recv status: %d\n", status); test_ctx->error = ENOENT; for (i = 0; rhostent->addr_list[i]; i++) { char addr_buf[256]; inet_ntop(rhostent->family, rhostent->addr_list[i]->ipaddr, addr_buf, sizeof(addr_buf)); /* test that localhost resolves to 127.0.0.1 or ::1 */ if (strcmp(addr_buf, "127.0.0.1") == 0 || strcmp(addr_buf, "::1") == 0) { test_ctx->error = EOK; } } talloc_free(rhostent); } START_TEST(test_resolv_localhost) { struct resolv_test_ctx *test_ctx; int ret = EOK; struct tevent_req *req; const char *hostname = "localhost.localdomain"; ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx); if (ret != EOK) { fail("Could not set up test"); return; } ck_leaks_push(test_ctx); req = resolv_gethostbyname_send(test_ctx, test_ctx->ev, test_ctx->resolv, hostname, IPV4_FIRST, default_host_dbs); DEBUG(SSSDBG_TRACE_LIBS, "Sent resolv_gethostbyname\n"); if (req == NULL) { ret = ENOMEM; } if (ret == EOK) { tevent_req_set_callback(req, test_localhost, test_ctx); ret = test_loop(test_ctx); } ck_leaks_pop(test_ctx); fail_unless(ret == EOK); talloc_zfree(test_ctx); } END_TEST static void test_negative(struct tevent_req *req) { int recv_status; int status; struct resolv_hostent *hostent; struct resolv_test_ctx *test_ctx; test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx); test_ctx->done = true; recv_status = resolv_gethostbyname_recv(req, test_ctx, &status, NULL, &hostent); talloc_zfree(req); if (recv_status == EOK) { DEBUG(SSSDBG_TRACE_LIBS, "resolv_gethostbyname_recv succeeded in a negative test\n"); return; } test_ctx->error = status; DEBUG(SSSDBG_OP_FAILURE, "resolv_gethostbyname_recv status: %d: %s\n", status, resolv_strerror(status)); } START_TEST(test_resolv_negative) { int ret = EOK; struct tevent_req *req; const char *hostname = "sssd.foo"; struct resolv_test_ctx *test_ctx; ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx); if (ret != EOK) { fail("Could not set up test"); return; } ck_leaks_push(test_ctx); req = resolv_gethostbyname_send(test_ctx, test_ctx->ev, test_ctx->resolv, hostname, IPV4_FIRST, default_host_dbs); DEBUG(SSSDBG_TRACE_LIBS, "Sent resolv_gethostbyname\n"); if (req == NULL) { ret = ENOMEM; } if (ret == EOK) { tevent_req_set_callback(req, test_negative, test_ctx); ret = test_loop(test_ctx); } ck_leaks_pop(test_ctx); fail_unless(ret != EOK); fail_unless(test_ctx->error == ARES_ENOTFOUND); talloc_zfree(test_ctx); } END_TEST static void test_internet(struct tevent_req *req) { int recv_status; int status; struct resolv_test_ctx *test_ctx; void *tmp_ctx; struct resolv_hostent *rhostent = NULL; struct ares_txt_reply *txt_replies = NULL, *txtptr; struct ares_srv_reply *srv_replies = NULL, *srvptr; int i; test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx); test_ctx->done = true; tmp_ctx = talloc_new(test_ctx); ck_leaks_push(tmp_ctx); switch (test_ctx->tested_function) { case TESTING_HOSTNAME: recv_status = resolv_gethostbyname_recv(req, tmp_ctx, &status, NULL, &rhostent); test_ctx->error = (rhostent->name == NULL) ? ENOENT : EOK; if (test_ctx->error == EOK) { char addr_buf[256]; for (i=0; rhostent->addr_list[i]; i++) { inet_ntop(rhostent->family, rhostent->addr_list[i]->ipaddr, addr_buf, sizeof(addr_buf)); DEBUG(SSSDBG_OP_FAILURE, "Found address %s with TTL %d\n", addr_buf, rhostent->addr_list[i]->ttl); } } break; case TESTING_TXT: recv_status = resolv_gettxt_recv(tmp_ctx, req, &status, NULL, &txt_replies); test_ctx->error = (txt_replies == NULL) ? ENOENT : EOK; for (txtptr = txt_replies; txtptr != NULL; txtptr = txtptr->next) { DEBUG(SSSDBG_OP_FAILURE, "TXT Record: %s\n", txtptr->txt); } break; case TESTING_SRV: recv_status = resolv_getsrv_recv(tmp_ctx, req, &status, NULL, &srv_replies, NULL); test_ctx->error = (srv_replies == NULL) ? ENOENT : EOK; for (srvptr = srv_replies; srvptr != NULL; srvptr = srvptr->next) { DEBUG(SSSDBG_OP_FAILURE, "SRV Record: %d %d %d %s\n", srvptr->weight, srvptr->priority, srvptr->port, srvptr->host); } break; default: recv_status = EINVAL; break; } talloc_zfree(req); fail_if(recv_status != EOK, "The recv function failed: %d", recv_status); DEBUG(SSSDBG_TRACE_LIBS, "recv status: %d\n", status); if (rhostent != NULL) { talloc_free(rhostent); } else if (txt_replies != NULL) { talloc_free(txt_replies); } else if (srv_replies != NULL) { talloc_free(srv_replies); } ck_leaks_pop(tmp_ctx); } START_TEST(test_resolv_internet) { int ret = EOK; struct tevent_req *req; const char *hostname = "redhat.com"; struct resolv_test_ctx *test_ctx; ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx); if (ret != EOK) { fail("Could not set up test"); return; } test_ctx->tested_function = TESTING_HOSTNAME; ck_leaks_push(test_ctx); req = resolv_gethostbyname_send(test_ctx, test_ctx->ev, test_ctx->resolv, hostname, IPV4_FIRST, default_host_dbs); DEBUG(SSSDBG_TRACE_LIBS, "Sent resolv_gethostbyname\n"); if (req == NULL) { ret = ENOMEM; } if (ret == EOK) { tevent_req_set_callback(req, test_internet, test_ctx); ret = test_loop(test_ctx); } fail_unless(ret == EOK); ck_leaks_pop(test_ctx); talloc_zfree(test_ctx); } END_TEST START_TEST(test_resolv_internet_txt) { int ret; struct tevent_req *req; struct resolv_test_ctx *test_ctx; ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx); fail_if(ret != EOK, "Could not set up test"); test_ctx->tested_function = TESTING_TXT; ck_leaks_push(test_ctx); req = resolv_gettxt_send(test_ctx, test_ctx->ev, test_ctx->resolv, txt_host); fail_if(req == NULL, "Function resolv_gettxt_send failed"); tevent_req_set_callback(req, test_internet, test_ctx); ret = test_loop(test_ctx); fail_unless(ret == EOK); ck_leaks_pop(test_ctx); talloc_zfree(test_ctx); } END_TEST START_TEST(test_resolv_internet_srv) { int ret; struct tevent_req *req; struct resolv_test_ctx *test_ctx; ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx); fail_if(ret != EOK, "Could not set up test"); test_ctx->tested_function = TESTING_SRV; ck_leaks_push(test_ctx); req = resolv_getsrv_send(test_ctx, test_ctx->ev, test_ctx->resolv, srv_host); fail_if(req == NULL, "Function resolv_getsrv_send failed"); tevent_req_set_callback(req, test_internet, test_ctx); ret = test_loop(test_ctx); fail_unless(ret == EOK); ck_leaks_pop(test_ctx); talloc_zfree(test_ctx); } END_TEST static void resolv_free_context(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { struct resolv_ctx *rctx = talloc_get_type(ptr, struct resolv_ctx); DEBUG(SSSDBG_TRACE_LIBS, "freeing the context\n"); talloc_free(rctx); } static void resolv_free_done(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { struct resolv_test_ctx *tctx = talloc_get_type(ptr, struct resolv_test_ctx); DEBUG(SSSDBG_TRACE_LIBS, "marking test as done\n"); tctx->error = EOK; tctx->done = true; } START_TEST(test_resolv_free_context) { int ret = EOK; struct tevent_req *req; const char *hostname = "redhat.com"; struct resolv_test_ctx *test_ctx; struct tevent_timer *free_timer, *terminate_timer; struct timeval free_tv, terminate_tv; ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx); if (ret != EOK) { fail("Could not set up test"); return; } req = resolv_gethostbyname_send(test_ctx, test_ctx->ev, test_ctx->resolv, hostname, IPV4_FIRST, default_host_dbs); DEBUG(SSSDBG_TRACE_LIBS, "Sent resolv_gethostbyname\n"); if (req == NULL) { fail("Error calling resolv_gethostbyname_send"); goto done; } gettimeofday(&free_tv, NULL); free_tv.tv_sec += 1; free_tv.tv_usec = 0; terminate_tv.tv_sec = free_tv.tv_sec + 1; terminate_tv.tv_usec = 0; free_timer = tevent_add_timer(test_ctx->ev, test_ctx, free_tv, resolv_free_context, test_ctx->resolv); if (free_timer == NULL) { fail("Error calling tevent_add_timer"); goto done; } terminate_timer = tevent_add_timer(test_ctx->ev, test_ctx, terminate_tv, resolv_free_done, test_ctx); if (terminate_timer == NULL) { fail("Error calling tevent_add_timer"); goto done; } ret = test_loop(test_ctx); fail_unless(ret == EOK); done: talloc_zfree(test_ctx); } END_TEST static void resolv_free_req(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { struct tevent_req *req = talloc_get_type(ptr, struct tevent_req); DEBUG(SSSDBG_TRACE_LIBS, "freeing the request\n"); talloc_free(req); } START_TEST(test_resolv_sort_srv_reply) { int ret; struct ares_srv_reply *replies = NULL; struct ares_srv_reply *r, *prev = NULL; struct resolv_test_ctx *test_ctx; int num_replies = 3; int i; ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx); if (ret != EOK) { fail("Could not set up test"); return; } ck_leaks_push(test_ctx); /* prepare linked list with reversed values */ for (i = 0; ipriority = num_replies-i; r->weight = i; if (!replies) { replies = r; prev = r; } else { prev->next = r; prev = prev->next; } } /* do the sort */ ret = resolv_sort_srv_reply(&replies); fail_if(ret != EOK); /* check if the list is sorted */ prev = NULL; for (i = 1, r = replies; r; r=r->next, i++) { talloc_zfree(prev); prev = r; fail_unless(r->priority == i); } talloc_zfree(prev); /* check if the list is complete */ fail_unless(i-1 == num_replies); /* test if the weighting algorithm runs..not much do * deterministically test here since it is based on * random weight-selection */ replies = NULL; for (i = 0; ipriority = i % 2 + 1; r->weight = i; if (!replies) { replies = r; prev = r; } else { prev->next = r; prev = prev->next; } } /* do the sort */ ret = resolv_sort_srv_reply(&replies); fail_if(ret != EOK); /* clean up */ prev = NULL; for (r = replies; r; r=r->next) { talloc_zfree(prev); prev = r; } talloc_zfree(prev); /* check for leaks */ ck_leaks_pop(test_ctx); talloc_zfree(test_ctx); } END_TEST START_TEST(test_resolv_sort_srv_reply_zero_weight) { int ret; struct ares_srv_reply *replies = NULL; struct ares_srv_reply *r, *prev = NULL; struct resolv_test_ctx *test_ctx; int num_replies = 6; int i; ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx); if (ret != EOK) { fail("Could not set up test"); return; } ck_leaks_push(test_ctx); /* prepare linked list */ for (i = 0; i < num_replies; i++) { r = talloc_zero(test_ctx, struct ares_srv_reply); fail_if(r == NULL); r->priority = 20; r->priority = i <= 3 ? 10 : r->priority; r->priority = i <= 1 ? 0 : r->priority; r->weight = 0; if (replies == NULL) { replies = r; prev = r; } else { prev->next = r; prev = prev->next; } } /* do the sort */ ret = resolv_sort_srv_reply(&replies); fail_if(ret != EOK); /* check if the list contains all values and is sorted */ for (i = 0, r = replies; r != NULL; r = r->next, i++) { if (r->next != NULL) { fail_unless(r->priority <= r->next->priority); } } fail_unless(i == num_replies); /* clean up */ prev = NULL; for (r = replies; r != NULL; r=r->next) { talloc_zfree(prev); prev = r; } talloc_zfree(prev); /* check for leaks */ ck_leaks_pop(test_ctx); talloc_zfree(test_ctx); } END_TEST START_TEST(test_resolv_free_req) { int ret = EOK; struct tevent_req *req; const char *hostname = "redhat.com"; struct resolv_test_ctx *test_ctx; struct tevent_timer *free_timer, *terminate_timer; struct timeval free_tv, terminate_tv; ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx); if (ret != EOK) { fail("Could not set up test"); return; } ck_leaks_push(test_ctx); req = resolv_gethostbyname_send(test_ctx, test_ctx->ev, test_ctx->resolv, hostname, IPV4_FIRST, default_host_dbs); DEBUG(SSSDBG_TRACE_LIBS, "Sent resolv_gethostbyname\n"); if (req == NULL) { fail("Error calling resolv_gethostbyname_send"); goto done; } gettimeofday(&free_tv, NULL); free_tv.tv_sec += 1; free_tv.tv_usec = 0; /* Give enought time for c-ares request to terminate */ terminate_tv.tv_sec = free_tv.tv_sec + 6; terminate_tv.tv_usec = 0; free_timer = tevent_add_timer(test_ctx->ev, test_ctx, free_tv, resolv_free_req, req); if (free_timer == NULL) { fail("Error calling tevent_add_timer"); goto done; } terminate_timer = tevent_add_timer(test_ctx->ev, test_ctx, terminate_tv, resolv_free_done, test_ctx); if (terminate_timer == NULL) { fail("Error calling tevent_add_timer"); goto done; } ret = test_loop(test_ctx); ck_leaks_pop(test_ctx); fail_unless(ret == EOK); done: talloc_zfree(test_ctx); } END_TEST static void test_timeout(struct tevent_req *req) { int recv_status; int status; struct resolv_test_ctx *test_ctx; TALLOC_CTX *tmp_ctx; struct resolv_hostent *rhostent = NULL; test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx); test_ctx->done = true; tmp_ctx = talloc_new(test_ctx); ck_leaks_push(tmp_ctx); fail_unless(test_ctx->tested_function == TESTING_HOSTNAME); recv_status = resolv_gethostbyname_recv(req, tmp_ctx, &status, NULL, &rhostent); talloc_zfree(req); fail_unless(recv_status == ETIMEDOUT); fail_unless(status == ARES_ETIMEOUT); ck_leaks_pop(tmp_ctx); talloc_free(tmp_ctx); } START_TEST(test_resolv_timeout) { struct resolv_test_ctx *test_ctx; errno_t ret; struct tevent_req *req; const char *hostname = "redhat.com"; ret = setup_resolv_test(0, &test_ctx); if (ret != EOK) { fail("Could not set up test"); return; } test_ctx->tested_function = TESTING_HOSTNAME; req = resolv_gethostbyname_send(test_ctx, test_ctx->ev, test_ctx->resolv, hostname, IPV4_FIRST, default_host_dbs); DEBUG(SSSDBG_TRACE_LIBS, "Sent resolv_gethostbyname\n"); if (req == NULL) { ret = ENOMEM; } if (ret == EOK) { tevent_req_set_callback(req, test_timeout, test_ctx); ret = test_loop(test_ctx); } fail_unless(ret == EOK); talloc_zfree(test_ctx); } END_TEST Suite *create_resolv_suite(void) { Suite *s = suite_create("resolv"); TCase *tc_resolv = tcase_create("RESOLV Tests"); tcase_set_timeout(tc_resolv, 8); tcase_add_checked_fixture(tc_resolv, ck_leak_check_setup, ck_leak_check_teardown); /* Do some testing */ tcase_add_test(tc_resolv, test_copy_hostent); tcase_add_test(tc_resolv, test_address_to_string); tcase_add_test(tc_resolv, test_resolv_ip_addr); tcase_add_test(tc_resolv, test_resolv_sort_srv_reply); tcase_add_test(tc_resolv, test_resolv_sort_srv_reply_zero_weight); if (use_net_test) { tcase_add_test(tc_resolv, test_resolv_internet); tcase_add_test(tc_resolv, test_resolv_negative); tcase_add_test(tc_resolv, test_resolv_localhost); tcase_add_test(tc_resolv, test_resolv_timeout); if (txt_host != NULL) { tcase_add_test(tc_resolv, test_resolv_internet_txt); } if (srv_host != NULL) { tcase_add_test(tc_resolv, test_resolv_internet_srv); } } tcase_add_test(tc_resolv, test_resolv_free_context); tcase_add_test(tc_resolv, test_resolv_free_req); /* Add all test cases to the test suite */ suite_add_tcase(s, tc_resolv); return s; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int failure_count; Suite *resolv_suite; SRunner *sr; int debug = 0; struct poptOption long_options[] = { POPT_AUTOHELP { "debug-level", 'd', POPT_ARG_INT, &debug, 0, "Set debug level", NULL }, { "use-net-test", 'n', POPT_ARG_NONE, 0, 'n', "Run tests that need an active internet connection", NULL }, { "txt-host", 't', POPT_ARG_STRING, 0, 't', "Specify the host used for TXT record testing", NULL }, { "srv-host", 's', POPT_ARG_STRING, 0, 's', "Specify the host used for SRV record testing", NULL }, POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { case 'n': use_net_test = 1; break; case 't': txt_host = poptGetOptArg(pc); break; case 's': srv_host = poptGetOptArg(pc); break; default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug); if (!use_net_test) { printf("Network tests disabled. Rerun with the \"-n\" " "option to run the full suite of tests\n"); } tests_set_cwd(); resolv_suite = create_resolv_suite(); sr = srunner_create(resolv_suite); /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */ srunner_run_all(sr, CK_ENV); failure_count = srunner_ntests_failed(sr); srunner_free(sr); return (failure_count==0 ? EXIT_SUCCESS : EXIT_FAILURE); } sssd-1.13.4/src/tests/PaxHeaders.16287/util-tests.c0000644000000000000000000000007412703456111016537 xustar0030 atime=1460561751.658715654 30 ctime=1460561775.056794992 sssd-1.13.4/src/tests/util-tests.c0000644002412700241270000011154312703456111020213 0ustar00jhrozekjhrozek00000000000000/* SSSD util-tests.c Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "util/util.h" #include "util/sss_utf8.h" #include "util/murmurhash3.h" #include "tests/common_check.h" #define FILENAME_TEMPLATE "tests-atomicio-XXXXXX" char *filename; int atio_fd; START_TEST(test_add_string_to_list) { int ret; char **list = NULL; ret = add_string_to_list(NULL, NULL, NULL); fail_unless(ret == EINVAL, "NULL input accepted"); ret = add_string_to_list(global_talloc_context, "ABC", &list); fail_unless(ret == EOK, "Adding string to non-existing list failed."); fail_unless(list != NULL, "No new list created."); fail_unless(list[0] != NULL, "String not added to new list."); fail_unless(strcmp(list[0], "ABC") == 0, "Wrong string added to newly created list."); fail_unless(list[1] == NULL, "Missing terminating NULL in newly created list."); ret = add_string_to_list(global_talloc_context, "DEF", &list); fail_unless(ret == EOK, "Adding string to list failed."); fail_unless(list != NULL, "No list returned."); fail_unless(strcmp(list[0], "ABC") == 0, "Wrong first string in new list."); fail_unless(strcmp(list[1], "DEF") == 0, "Wrong string added to list."); fail_unless(list[2] == NULL, "Missing terminating NULL."); list[0] = NULL; ret = add_string_to_list(global_talloc_context, "ABC", &list); fail_unless(ret == EOK, "Adding string to empty list failed."); fail_unless(list != NULL, "No list returned."); fail_unless(list[0] != NULL, "String not added to empty list."); fail_unless(strcmp(list[0], "ABC") == 0, "Wrong string added to empty list."); fail_unless(list[1] == NULL, "Missing terminating NULL in newly created list."); talloc_free(list); } END_TEST START_TEST(test_string_in_list) { bool is_in; char *empty_list[] = {NULL}; char *list[] = {discard_const("ABC"), discard_const("DEF"), discard_const("GHI"), NULL}; is_in = string_in_list(NULL, NULL, false); fail_unless(!is_in, "NULL string is in NULL list."); is_in = string_in_list(NULL, empty_list, false); fail_unless(!is_in, "NULL string is in empty list."); is_in = string_in_list(NULL, list, false); fail_unless(!is_in, "NULL string is in list."); is_in = string_in_list("ABC", NULL, false); fail_unless(!is_in, "String is in NULL list."); is_in = string_in_list("ABC", empty_list, false); fail_unless(!is_in, "String is in empty list."); is_in = string_in_list("ABC", list, false); fail_unless(is_in, "String is not list."); is_in = string_in_list("abc", list, false); fail_unless(is_in, "String is not case in-sensitive list."); is_in = string_in_list("abc", list, true); fail_unless(!is_in, "Wrong string found in case sensitive list."); is_in = string_in_list("123", list, false); fail_unless(!is_in, "Wrong string found in list."); } END_TEST START_TEST(test_parse_args) { struct pa_testcase { const char *argstr; const char **parsed; }; TALLOC_CTX *test_ctx; int i, ii; int ret; char **parsed; char **only_ret; char **only_exp; char **both; test_ctx = talloc_new(NULL); /* Positive tests */ const char *parsed1[] = { "foo", NULL }; const char *parsed2[] = { "foo", "a", NULL }; const char *parsed3[] = { "foo", "b", NULL }; const char *parsed4[] = { "foo", "a c", NULL }; const char *parsed5[] = { "foo", "a", "d", NULL }; const char *parsed6[] = { "foo", "a", "e", NULL }; const char *parsed7[] = { "foo", "a", "f", NULL }; const char *parsed8[] = { "foo", "a\tg", NULL }; const char *parsed9[] = { "foo", NULL }; const char *parsed10[] = { " ", "foo", "\t", "\\'", NULL }; const char *parsed11[] = { "a", NULL }; struct pa_testcase tc[] = { { "foo", parsed1 }, { "foo a", parsed2 }, { "foo b", parsed3 }, { "foo a\\ c", parsed4 }, { "foo a d ", parsed5 }, { "foo a e ", parsed6 }, { "foo\ta\t \tf \t", parsed7 }, { "foo a\\\tg", parsed8 }, { " foo ", parsed9 }, { "\\ foo \\\t \\' ", parsed10 }, { "a", parsed11 }, { " ", NULL }, { "", NULL }, { " \t ", NULL }, { NULL, NULL } }; for (i=0; tc[i].argstr != NULL; i++) { parsed = parse_args(tc[i].argstr); fail_if(parsed == NULL && tc[i].parsed != NULL, "Could not parse correct %d argument string '%s'\n", i, tc[i].argstr); ret = diff_string_lists(test_ctx, parsed, discard_const(tc[i].parsed), &only_ret, &only_exp, &both); fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret); fail_unless(only_ret[0] == NULL, "The parser returned more data than expected\n"); fail_unless(only_exp[0] == NULL, "The parser returned less data than expected\n"); if (parsed) { int parsed_len; int expected_len; for (parsed_len=0; parsed[parsed_len]; ++parsed_len); for (expected_len=0; tc[i].parsed[expected_len]; ++expected_len); fail_unless(parsed_len == expected_len, "Test %d: length of 1st array [%d] != length of 2nd " "array[%d]\n", i, parsed_len, expected_len); for (ii = 0; parsed[ii]; ii++) free(parsed[ii]); free(parsed); } } talloc_free(test_ctx); } END_TEST START_TEST(test_diff_string_lists) { TALLOC_CTX *test_ctx; char **l1; char **l2; char **l3; char **only_l1; char **only_l2; char **both; int ret; test_ctx = talloc_new(NULL); /* Test with all values returned */ l1 = talloc_array(test_ctx, char *, 4); l1[0] = talloc_strdup(l1, "a"); l1[1] = talloc_strdup(l1, "b"); l1[2] = talloc_strdup(l1, "c"); l1[3] = NULL; l2 = talloc_array(test_ctx, char *, 4); l2[0] = talloc_strdup(l1, "d"); l2[1] = talloc_strdup(l1, "c"); l2[2] = talloc_strdup(l1, "b"); l2[3] = NULL; ret = diff_string_lists(test_ctx, l1, l2, &only_l1, &only_l2, &both); fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret); fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1"); fail_unless(only_l1[1] == NULL, "only_l1 not NULL-terminated"); fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"d\" from only_l2"); fail_unless(only_l2[1] == NULL, "only_l2 not NULL-terminated"); fail_unless(strcmp(both[0], "c") == 0, "Missing \"c\" from both"); fail_unless(strcmp(both[1], "b") == 0, "Missing \"b\" from both"); fail_unless(both[2] == NULL, "both not NULL-terminated"); talloc_zfree(only_l1); talloc_zfree(only_l2); talloc_zfree(both); /* Test with restricted return values */ ret = diff_string_lists(test_ctx, l1, l2, &only_l1, &only_l2, NULL); fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret); fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1"); fail_unless(only_l1[1] == NULL, "only_l1 not NULL-terminated"); fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"d\" from only_l2"); fail_unless(only_l2[1] == NULL, "only_l2 not NULL-terminated"); fail_unless(both == NULL, "Nothing returned to both"); talloc_zfree(only_l1); talloc_zfree(only_l2); talloc_zfree(both); ret = diff_string_lists(test_ctx, l1, l2, &only_l1, NULL, NULL); fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret); fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1"); fail_unless(only_l1[1] == NULL, "only_l1 not NULL-terminated"); fail_unless(only_l2 == NULL, "Nothing returned to only_l2"); fail_unless(both == NULL, "Nothing returned to both"); talloc_zfree(only_l1); talloc_zfree(only_l2); talloc_zfree(both); ret = diff_string_lists(test_ctx, l1, l2, NULL, &only_l2, NULL); fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret); fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"d\" from only_l2"); fail_unless(only_l2[1] == NULL, "only_l2 not NULL-terminated"); fail_unless(only_l1 == NULL, "Nothing returned to only_l1"); fail_unless(both == NULL, "Nothing returned to both"); talloc_zfree(only_l1); talloc_zfree(only_l2); talloc_zfree(both); /* Test with no overlap */ l3 = talloc_array(test_ctx, char *, 4); l3[0] = talloc_strdup(l1, "d"); l3[1] = talloc_strdup(l1, "e"); l3[2] = talloc_strdup(l1, "f"); l3[3] = NULL; ret = diff_string_lists(test_ctx, l1, l3, &only_l1, &only_l2, &both); fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret); fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1"); fail_unless(strcmp(only_l1[1], "b") == 0, "Missing \"b\" from only_l1"); fail_unless(strcmp(only_l1[2], "c") == 0, "Missing \"c\" from only_l1"); fail_unless(only_l1[3] == NULL, "only_l1 not NULL-terminated"); fail_unless(strcmp(only_l2[0], "d") == 0, "Missing \"f\" from only_l2"); fail_unless(strcmp(only_l2[1], "e") == 0, "Missing \"e\" from only_l2"); fail_unless(strcmp(only_l2[2], "f") == 0, "Missing \"d\" from only_l2"); fail_unless(only_l2[3] == NULL, "only_l2 not NULL-terminated"); fail_unless(both[0] == NULL, "both should have zero entries"); talloc_zfree(only_l1); talloc_zfree(only_l2); talloc_zfree(both); /* Test with 100% overlap */ ret = diff_string_lists(test_ctx, l1, l1, &only_l1, &only_l2, &both); fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret); fail_unless(only_l1[0] == NULL, "only_l1 should have zero entries"); fail_unless(only_l2[0] == NULL, "only_l2 should have zero entries"); fail_unless(strcmp(both[0], "a") == 0, "Missing \"a\" from both"); fail_unless(strcmp(both[1], "b") == 0, "Missing \"b\" from both"); fail_unless(strcmp(both[2], "c") == 0, "Missing \"c\" from both"); fail_unless(both[3] == NULL, "both is not NULL-terminated"); talloc_zfree(only_l1); talloc_zfree(only_l2); talloc_zfree(both); /* Test with no second list */ ret = diff_string_lists(test_ctx, l1, NULL, &only_l1, &only_l2, &both); fail_unless(ret == EOK, "diff_string_lists returned error [%d]", ret); fail_unless(strcmp(only_l1[0], "a") == 0, "Missing \"a\" from only_l1"); fail_unless(strcmp(only_l1[1], "b") == 0, "Missing \"b\" from only_l1"); fail_unless(strcmp(only_l1[2], "c") == 0, "Missing \"c\" from only_l1"); fail_unless(only_l1[3] == NULL, "only_l1 not NULL-terminated"); fail_unless(only_l2[0] == NULL, "only_l2 should have zero entries"); fail_unless(both[0] == NULL, "both should have zero entries"); talloc_free(test_ctx); } END_TEST START_TEST(test_sss_filter_sanitize) { errno_t ret; char *sanitized = NULL; TALLOC_CTX *test_ctx = talloc_new(NULL); fail_if (test_ctx == NULL, "Out of memory"); const char no_specials[] = "username"; ret = sss_filter_sanitize(test_ctx, no_specials, &sanitized); fail_unless(ret == EOK, "no_specials error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(no_specials, sanitized)==0, "Expected [%s], got [%s]", no_specials, sanitized); const char has_asterisk[] = "*username"; const char has_asterisk_expected[] = "\\2ausername"; ret = sss_filter_sanitize(test_ctx, has_asterisk, &sanitized); fail_unless(ret == EOK, "has_asterisk error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(has_asterisk_expected, sanitized)==0, "Expected [%s], got [%s]", has_asterisk_expected, sanitized); const char has_lparen[] = "user(name"; const char has_lparen_expected[] = "user\\28name"; ret = sss_filter_sanitize(test_ctx, has_lparen, &sanitized); fail_unless(ret == EOK, "has_lparen error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(has_lparen_expected, sanitized)==0, "Expected [%s], got [%s]", has_lparen_expected, sanitized); const char has_rparen[] = "user)name"; const char has_rparen_expected[] = "user\\29name"; ret = sss_filter_sanitize(test_ctx, has_rparen, &sanitized); fail_unless(ret == EOK, "has_rparen error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(has_rparen_expected, sanitized)==0, "Expected [%s], got [%s]", has_rparen_expected, sanitized); const char has_backslash[] = "username\\"; const char has_backslash_expected[] = "username\\5c"; ret = sss_filter_sanitize(test_ctx, has_backslash, &sanitized); fail_unless(ret == EOK, "has_backslash error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(has_backslash_expected, sanitized)==0, "Expected [%s], got [%s]", has_backslash_expected, sanitized); const char has_all[] = "\\(user)*name"; const char has_all_expected[] = "\\5c\\28user\\29\\2aname"; ret = sss_filter_sanitize(test_ctx, has_all, &sanitized); fail_unless(ret == EOK, "has_all error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(has_all_expected, sanitized)==0, "Expected [%s], got [%s]", has_all_expected, sanitized); /* Input is reused from previous test - "\\(user)*name" */ const char has_all_allow_asterisk_expected[] = "\\5c\\28user\\29*name"; ret = sss_filter_sanitize_ex(test_ctx, has_all, &sanitized, "*"); fail_unless(ret == EOK, "has_all error [%d][%s]", ret, strerror(ret)); fail_unless(strcmp(has_all_allow_asterisk_expected, sanitized)==0, "Expected [%s], got [%s]", has_all_expected, sanitized); talloc_free(test_ctx); } END_TEST START_TEST(test_fd_nonblocking) { int fd; int flags; errno_t ret; fd = open("/dev/null", O_RDONLY); fail_unless(fd > 0); flags = fcntl(fd, F_GETFL, 0); fail_if(flags & O_NONBLOCK); ret = sss_fd_nonblocking(fd); fail_unless(ret == EOK); flags = fcntl(fd, F_GETFL, 0); fail_unless(flags & O_NONBLOCK); close(fd); } END_TEST START_TEST(test_size_t_overflow) { fail_unless(!SIZE_T_OVERFLOW(1, 1), "unexpected overflow"); fail_unless(!SIZE_T_OVERFLOW(SIZE_MAX, 0), "unexpected overflow"); fail_unless(!SIZE_T_OVERFLOW(SIZE_MAX-10, 10), "unexpected overflow"); fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, 1), "overflow not detected"); fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, SIZE_MAX), "overflow not detected"); fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, ULLONG_MAX), "overflow not detected"); fail_unless(SIZE_T_OVERFLOW(SIZE_MAX, -10), "overflow not detected"); } END_TEST START_TEST(test_utf8_lowercase) { const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 }; const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 }; uint8_t *lcase; size_t nlen; lcase = sss_utf8_tolower(munchen_utf8_upcase, strlen((const char *)munchen_utf8_upcase), &nlen); fail_if(strlen((const char *) munchen_utf8_upcase) != nlen); /* This is not true for utf8 strings in general */ fail_if(memcmp(lcase, munchen_utf8_lowcase, nlen)); sss_utf8_free(lcase); } END_TEST START_TEST(test_utf8_talloc_lowercase) { const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 }; const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 }; uint8_t *lcase; size_t nsize; TALLOC_CTX *test_ctx; test_ctx = talloc_new(NULL); fail_if(test_ctx == NULL); lcase = sss_tc_utf8_tolower(test_ctx, munchen_utf8_upcase, strlen((const char *) munchen_utf8_upcase), &nsize); fail_if(memcmp(lcase, munchen_utf8_lowcase, nsize)); talloc_free(test_ctx); } END_TEST START_TEST(test_utf8_talloc_str_lowercase) { const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 }; const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 }; char *lcase; TALLOC_CTX *test_ctx; test_ctx = talloc_new(NULL); fail_if(test_ctx == NULL); lcase = sss_tc_utf8_str_tolower(test_ctx, (const char *) munchen_utf8_upcase); fail_if(memcmp(lcase, munchen_utf8_lowcase, strlen(lcase))); talloc_free(test_ctx); } END_TEST START_TEST(test_utf8_caseeq) { const uint8_t munchen_utf8_upcase[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 }; const uint8_t munchen_utf8_lowcase[] = { 'm', 0xC3, 0xBC, 'n', 'c', 'h', 'e', 'n', 0x0 }; const uint8_t czech_utf8_lowcase[] = { 0xC4, 0x8D, 'e', 'c', 'h', 0x0 }; const uint8_t czech_utf8_upcase[] = { 0xC4, 0x8C, 'e', 'c', 'h', 0x0 }; const uint8_t czech_utf8_lowcase_neg[] = { 0xC4, 0x8E, 'e', 'c', 'h', 0x0 }; errno_t ret; ret = sss_utf8_case_eq(munchen_utf8_upcase, munchen_utf8_lowcase); fail_unless(ret == EOK, "Latin 1 Supplement comparison failed\n"); ret = sss_utf8_case_eq(czech_utf8_upcase, czech_utf8_lowcase); fail_unless(ret == EOK, "Latin Extended A comparison failed\n"); ret = sss_utf8_case_eq(czech_utf8_upcase, czech_utf8_lowcase_neg); fail_if(ret == EOK, "Negative test succeeded\n"); } END_TEST START_TEST(test_utf8_check) { const char *invalid = "ad\351la\357d"; const uint8_t valid[] = { 'M', 0xC3, 0x9C, 'N', 'C', 'H', 'E', 'N', 0x0 }; bool ret; ret = sss_utf8_check(valid, strlen((const char *) valid)); fail_unless(ret == true, "Positive test failed\n"); ret = sss_utf8_check((const uint8_t *) invalid, strlen(invalid)); fail_unless(ret == false, "Negative test succeeded\n"); } END_TEST START_TEST(test_murmurhash3_check) { const char *tests[6] = { "1052800007", "1052800008", "1052800000", "abcdefghijk", "abcdefghili", "abcdefgh000" }; uint32_t results[6]; int i, j; for (i = 0; i< 6; i++) { results[i] = murmurhash3(tests[i], strlen(tests[i]), 0xdeadbeef); for (j = 0; j < i; j++) { fail_if(results[i] == results[j]); } } } END_TEST START_TEST(test_murmurhash3_random) { char test[16]; uint32_t result1; uint32_t result2; unsigned int init_seed; unsigned int seed; size_t len; int i; /* generate a random string so each time we test with different values */ init_seed = time(0); seed = init_seed; /* use also random length (min len = 1) */ len = 1 + rand_r(&seed) % 14; for (i = 0; i < len; i++) { test[i] = 1 + rand_r(&seed) % 254; } test[len] = '\0'; /* null terminate */ fprintf(stdout, "test_murmurhash3_random seed: %u\n", init_seed); result1 = murmurhash3(test, len + 1, init_seed); result2 = murmurhash3(test, len + 1, init_seed); fail_if(result1 != result2); } END_TEST void setup_atomicio(void) { int ret; mode_t old_umask; filename = strdup(FILENAME_TEMPLATE); fail_unless(filename != NULL, "strdup failed"); atio_fd = -1; old_umask = umask(SSS_DFL_X_UMASK); ret = mkstemp(filename); umask(old_umask); fail_unless(ret != -1, "mkstemp failed [%d][%s]", errno, strerror(errno)); atio_fd = ret; } void teardown_atomicio(void) { int ret; if (atio_fd != -1) { ret = close(atio_fd); fail_unless(ret == 0, "close failed [%d][%s]", errno, strerror(errno)); } fail_unless(filename != NULL, "unknown filename"); ret = unlink(filename); free(filename); fail_unless(ret == 0, "unlink failed [%d][%s]", errno, strerror(errno)); } START_TEST(test_atomicio_read_from_file) { const ssize_t bufsize = 64; char buf[64]; int fd; ssize_t numread; errno_t ret; fd = open("/dev/zero", O_RDONLY); fail_if(fd == -1, "Cannot open /dev/zero"); errno = 0; numread = sss_atomic_read_s(fd, buf, bufsize); ret = errno; fail_unless(ret == 0, "Error %d while reading\n", ret); fail_unless(numread == bufsize, "Read %d bytes expected %d\n", numread, bufsize); close(fd); } END_TEST START_TEST(test_atomicio_read_from_small_file) { char wbuf[] = "foobar"; ssize_t wsize = strlen(wbuf)+1; ssize_t numwritten; char rbuf[64]; ssize_t numread; errno_t ret; fail_if(atio_fd < 0, "No fd to test?\n"); errno = 0; numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize); ret = errno; fail_unless(ret == 0, "Error %d while writing\n", ret); fail_unless(numwritten == wsize, "Wrote %d bytes expected %d\n", numwritten, wsize); fsync(atio_fd); lseek(atio_fd, 0, SEEK_SET); errno = 0; numread = sss_atomic_read_s(atio_fd, rbuf, 64); ret = errno; fail_unless(ret == 0, "Error %d while reading\n", ret); fail_unless(numread == numwritten, "Read %d bytes expected %d\n", numread, numwritten); } END_TEST START_TEST(test_atomicio_read_from_large_file) { char wbuf[] = "123456781234567812345678"; ssize_t wsize = strlen(wbuf)+1; ssize_t numwritten; char rbuf[8]; ssize_t numread; ssize_t total; errno_t ret; fail_if(atio_fd < 0, "No fd to test?\n"); errno = 0; numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize); ret = errno; fail_unless(ret == 0, "Error %d while writing\n", ret); fail_unless(numwritten == wsize, "Wrote %d bytes expected %d\n", numwritten, wsize); fsync(atio_fd); lseek(atio_fd, 0, SEEK_SET); total = 0; do { errno = 0; numread = sss_atomic_read_s(atio_fd, rbuf, 8); ret = errno; fail_if(numread == -1, "Read error %d: %s\n", ret, strerror(ret)); total += numread; } while (numread != 0); fail_unless(ret == 0, "Error %d while reading\n", ret); fail_unless(total == numwritten, "Read %d bytes expected %d\n", numread, numwritten); } END_TEST START_TEST(test_atomicio_read_exact_sized_file) { char wbuf[] = "12345678"; ssize_t wsize = strlen(wbuf)+1; ssize_t numwritten; char rbuf[9]; ssize_t numread; errno_t ret; fail_if(atio_fd < 0, "No fd to test?\n"); errno = 0; numwritten = sss_atomic_write_s(atio_fd, wbuf, wsize); ret = errno; fail_unless(ret == 0, "Error %d while writing\n", ret); fail_unless(numwritten == wsize, "Wrote %d bytes expected %d\n", numwritten, wsize); fsync(atio_fd); lseek(atio_fd, 0, SEEK_SET); errno = 0; numread = sss_atomic_read_s(atio_fd, rbuf, 9); ret = errno; fail_unless(ret == 0, "Error %d while reading\n", ret); fail_unless(numread == numwritten, "Read %d bytes expected %d\n", numread, numwritten); fail_unless(rbuf[8] == '\0', "String not NULL terminated?"); fail_unless(strcmp(wbuf, rbuf) == 0, "Read something else than wrote?"); /* We've reached end-of-file, next read must return 0 */ errno = 0; numread = sss_atomic_read_s(atio_fd, rbuf, 9); ret = errno; fail_unless(ret == 0, "Error %d while reading\n", ret); fail_unless(numread == 0, "More data to read?"); } END_TEST START_TEST(test_atomicio_read_from_empty_file) { char buf[64]; int fd; ssize_t numread; errno_t ret; fd = open("/dev/null", O_RDONLY); fail_if(fd == -1, "Cannot open /dev/null"); errno = 0; numread = sss_atomic_read_s(fd, buf, 64); ret = errno; fail_unless(ret == 0, "Error %d while reading\n", ret); fail_unless(numread == 0, "Read %d bytes expected 0\n", numread); close(fd); } END_TEST struct split_data { const char *input; const char **expected_list; bool trim; bool skip_empty; int expected_size; int expected_ret; }; START_TEST(test_split_on_separator) { TALLOC_CTX *mem = global_talloc_context; errno_t ret; char **list = NULL; int size; const char *str_ref; const char *str_out; int i; int a; int num_of_tests; struct split_data sts[] = { { "one,two,three", /* input string */ (const char *[]){"one", "two", "three", NULL}, /* expec. output list */ false, false, /* trim, skip_empty */ 3, 0 /* expec. size, expec. retval */ }, { "one,two,three", (const char *[]){"one", "two", "three", NULL}, true, true, 3, 0 }, { " one, two ,three ", (const char*[]){"one", "two", "three", NULL}, true, true, 3, 0 }, { /* If skip empty is false, single comma means "empty,empty" */ ",", (const char*[]){"", "", NULL, NULL}, false, false, 2, 0 }, { "one, ,", (const char*[]){"one", " ", "NULL", "NULL"}, false, true, 2, 0 }, { ", ,,", (const char*[]){NULL}, true, true, 0, 0 }, { NULL, NULL, false, false, 0, EINVAL }, }; num_of_tests = sizeof(sts) / sizeof(struct split_data); for (a = 0; a < num_of_tests; a++) { ret = split_on_separator(mem, sts[a].input, ',', sts[a].trim, sts[a].skip_empty, &list, &size); fail_unless(ret == sts[a].expected_ret, "split_on_separator failed [%d]: %s\n", ret, strerror(ret)); if (ret) { continue; } fail_unless(size == sts[a].expected_size, "Returned wrong size %d " "(expected %d).\n", size, sts[a].expected_size); for (i = 0; str_ref = sts[a].expected_list[i], str_out = list[i]; i++) { fail_unless(strcmp(str_ref, str_out) == 0, "Expected:%s Got:%s\n", str_ref, str_out); } talloc_free(list); list = NULL; } } END_TEST struct check_ip_test_data { const char *str_ipaddr; uint8_t flags; bool expected_ret; }; START_TEST(test_check_ipv4_addr) { int a; int num_of_tests; int ret; bool bret; struct in_addr addr; struct check_ip_test_data tst_data[] = { { "192.168.100.1", /* input IPv4 address */ 0, /* flags value */ true /* Expected return value */ }, { "224.0.0.22", /* multicast address */ SSS_NO_MULTICAST, false }, { "192.186.0.224", SSS_NO_MULTICAST, true }, { "127.0.0.1", SSS_NO_LOOPBACK, false }, { "169.254.0.11", SSS_NO_LINKLOCAL, false }, { "255.255.255.255", SSS_NO_BROADCAST, false }, { "255.255.255.255", SSS_NO_SPECIAL, false }, { "192.168.254.169", SSS_NO_SPECIAL, true }, }; num_of_tests = sizeof(tst_data) / sizeof(struct check_ip_test_data); for (a = 0; a < num_of_tests; a++) { /* fill sockaddr_in structure */ ret = inet_pton(AF_INET, tst_data[a].str_ipaddr, &addr); fail_if(ret != 1, "inet_pton failed."); bret = check_ipv4_addr(&addr, tst_data[a].flags); fail_unless(bret == tst_data[a].expected_ret, "check_ipv4_addr failed (iteration %d)", a); } } END_TEST START_TEST(test_check_ipv6_addr) { int a; int num_of_tests; int ret; bool bret; struct in6_addr addr; struct check_ip_test_data tst_data[] = { { "fde9:7e3f:1ed3:24a5::4", /* input IPv6 address */ 0, /* flags value */ true /* Expected return value */ }, { "fe80::f2de:f1ff:fefa:67f0", SSS_NO_LINKLOCAL, false }, { "::1", SSS_NO_LOOPBACK, false }, { "ff00::123", SSS_NO_MULTICAST, false }, { "ff00::321", SSS_NO_SPECIAL, false }, }; num_of_tests = sizeof(tst_data) / sizeof(struct check_ip_test_data); for (a = 0; a < num_of_tests; a++) { /* fill sockaddr_in structure */ ret = inet_pton(AF_INET6, tst_data[a].str_ipaddr, &addr); fail_if(ret != 1, "inet_pton failed."); bret = check_ipv6_addr(&addr, tst_data[a].flags); fail_unless(bret == tst_data[a].expected_ret, "check_ipv6_addr failed (iteration %d)", a); } } END_TEST START_TEST(test_is_host_in_domain) { struct { const char *host; const char *domain; bool expected; } data[] = {{"example.com", "example.com", true}, {"client.example.com", "example.com", true}, {"client.child.example.com", "example.com", true}, {"example.com", "child.example.com", false}, {"client.example.com", "child.example.com", false}, {"client.child.example.com", "child.example.com", true}, {"my.com", "example.com", false}, {"myexample.com", "example.com", false}, {NULL, NULL, false}}; bool ret; int i; for (i = 0; data[i].host != NULL; i++) { ret = is_host_in_domain(data[i].host, data[i].domain); fail_if(ret != data[i].expected, "Host: %s, Domain: %s, Expected: %d, " "Got: %d\n", data[i].host, data[i].domain, data[i].expected, ret); } } END_TEST START_TEST(test_known_service) { const char * const * svcs; bool found_nss = false; int i; /* Just make sure we can't find a bogus service and nss * is always available */ svcs = get_known_services(); for (i = 0; svcs[i]; i++) { ck_assert_str_ne(svcs[i], "nosuchservice"); if (strcmp(svcs[i], "nss") == 0) { found_nss = true; } } ck_assert(found_nss == true); } END_TEST static void convert_time_tz(const char* tz) { errno_t ret, ret2; time_t unix_time; const char *orig_tz = NULL; orig_tz = getenv("TZ"); if (orig_tz == NULL) { orig_tz = ""; } if (tz) { ret = setenv("TZ", tz, 1); fail_if(ret == -1); } ret = sss_utc_to_time_t("20140801115742Z", "%Y%m%d%H%M%SZ", &unix_time); /* restore */ if (orig_tz != NULL) { ret2 = setenv("TZ", orig_tz, 1); fail_if(ret2 == -1); } fail_unless(ret == EOK && difftime(1406894262, unix_time) == 0); } START_TEST(test_convert_time) { const char *format = "%Y%m%d%H%M%SZ"; time_t unix_time; errno_t ret; ret = sss_utc_to_time_t("20150127133540P", format, &unix_time); fail_unless(ret == ERR_TIMESPEC_NOT_SUPPORTED); ret = sss_utc_to_time_t("0Z", format, &unix_time); fail_unless(ret == EINVAL); ret = sss_utc_to_time_t("000001010000Z", format, &unix_time); fail_unless(ret == EINVAL); /* test that results are still same no matter what timezone is set */ convert_time_tz(NULL); convert_time_tz("GST-1"); convert_time_tz("GST-2"); } END_TEST START_TEST(test_sss_strerror_err_last) { ck_assert_str_eq(sss_strerror(ERR_LAST), "ERR_LAST"); } END_TEST START_TEST(test_sss_strerror_string_validation) { enum sssd_errors idx; const char *error; size_t len; char last_character; for (idx = ERR_BASE; idx < ERR_LAST; ++idx) { error = sss_strerror(idx); fail_if(error == NULL, "sss_strerror returned NULL for valid index"); len = strlen(error); fail_if(len == 0, "sss_strerror returned empty string"); last_character = error[len - 1]; fail_if(isalpha(last_character) == 0 && last_character != ')', "Error string [%s] must finish with alphabetic character\n", error); } } END_TEST Suite *util_suite(void) { Suite *s = suite_create("util"); TCase *tc_util = tcase_create("util"); tcase_add_checked_fixture(tc_util, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_test (tc_util, test_diff_string_lists); tcase_add_test (tc_util, test_sss_filter_sanitize); tcase_add_test (tc_util, test_size_t_overflow); tcase_add_test (tc_util, test_parse_args); tcase_add_test (tc_util, test_add_string_to_list); tcase_add_test (tc_util, test_string_in_list); tcase_add_test (tc_util, test_split_on_separator); tcase_add_test (tc_util, test_check_ipv4_addr); tcase_add_test (tc_util, test_check_ipv6_addr); tcase_add_test (tc_util, test_is_host_in_domain); tcase_add_test (tc_util, test_known_service); tcase_add_test (tc_util, test_fd_nonblocking); tcase_set_timeout(tc_util, 60); TCase *tc_utf8 = tcase_create("utf8"); tcase_add_test (tc_utf8, test_utf8_lowercase); tcase_add_test (tc_utf8, test_utf8_talloc_lowercase); tcase_add_test (tc_utf8, test_utf8_talloc_str_lowercase); tcase_add_test (tc_utf8, test_utf8_caseeq); tcase_add_test (tc_utf8, test_utf8_check); tcase_set_timeout(tc_utf8, 60); TCase *tc_mh3 = tcase_create("murmurhash3"); tcase_add_test (tc_mh3, test_murmurhash3_check); tcase_add_test (tc_mh3, test_murmurhash3_random); tcase_set_timeout(tc_mh3, 60); TCase *tc_atomicio = tcase_create("atomicio"); tcase_add_checked_fixture (tc_atomicio, setup_atomicio, teardown_atomicio); tcase_add_test(tc_atomicio, test_atomicio_read_from_file); tcase_add_test(tc_atomicio, test_atomicio_read_from_small_file); tcase_add_test(tc_atomicio, test_atomicio_read_from_large_file); tcase_add_test(tc_atomicio, test_atomicio_read_exact_sized_file); tcase_add_test(tc_atomicio, test_atomicio_read_from_empty_file); TCase *tc_convert_time = tcase_create("convert_time"); tcase_add_checked_fixture(tc_convert_time, ck_leak_check_setup, ck_leak_check_teardown); tcase_add_test(tc_convert_time, test_convert_time); TCase *tc_sss_strerror = tcase_create("sss_strerror"); tcase_add_test(tc_sss_strerror, test_sss_strerror_err_last); tcase_add_test(tc_sss_strerror, test_sss_strerror_string_validation); suite_add_tcase (s, tc_util); suite_add_tcase (s, tc_utf8); suite_add_tcase (s, tc_mh3); suite_add_tcase (s, tc_atomicio); suite_add_tcase (s, tc_convert_time); suite_add_tcase (s, tc_sss_strerror); return s; } int main(int argc, const char *argv[]) { int opt; int failure_count; poptContext pc; Suite *s = util_suite(); SRunner *sr = srunner_create (s); struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_CLI_INIT(debug_level); tests_set_cwd(); srunner_run_all(sr, CK_ENV); failure_count = srunner_ntests_failed (sr); srunner_free (sr); if (failure_count == 0) { return EXIT_SUCCESS; } return EXIT_FAILURE; } sssd-1.13.4/src/tests/PaxHeaders.16287/common_check.c0000644000000000000000000000007412703456111017047 xustar0030 atime=1460561751.657715651 30 ctime=1460561774.827794215 sssd-1.13.4/src/tests/common_check.c0000644002412700241270000000226712703456111020525 0ustar00jhrozekjhrozek00000000000000/* SSSD Memory leak/growth checks for check-based tests using talloc. Authors: Martin Nagy Copyright (C) Red Hat, Inc 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "tests/common.h" #include "tests/common_check.h" void ck_leak_check_setup(void) { fail_unless(leak_check_setup() == true, "Cannot set up leaks test: %s\n", check_leaks_err_msg()); } void ck_leak_check_teardown(void) { fail_unless(leak_check_teardown() == true, "Cannot tear down leaks test: %s\n", check_leaks_err_msg()); } sssd-1.13.4/src/tests/PaxHeaders.16287/pyhbac-test.py3.sh0000644000000000000000000000007412703456111017547 xustar0030 atime=1460561751.658715654 30 ctime=1460561774.348792591 sssd-1.13.4/src/tests/pyhbac-test.py3.sh0000755002412700241270000000016012703456111021216 0ustar00jhrozekjhrozek00000000000000#!/bin/sh SCRIPT=$(readlink -f "$0") SCRIPT_PATH=$(dirname "$SCRIPT") exec python3 $SCRIPT_PATH/pyhbac-test.py sssd-1.13.4/src/PaxHeaders.16287/tools0000644000000000000000000000013212703463556014205 xustar0030 mtime=1460561774.991794771 30 atime=1460561776.119798596 30 ctime=1460561774.991794771 sssd-1.13.4/src/tools/0000755002412700241270000000000012703463556015736 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/tools/PaxHeaders.16287/sss_groupadd.c0000644000000000000000000000007412703456111017115 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.975794717 sssd-1.13.4/src/tools/sss_groupadd.c0000644002412700241270000001114612703456111020567 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_groupadd Copyright (C) Jakub Hrozek 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "util/util.h" #include "db/sysdb.h" #include "tools/tools_util.h" #include "tools/sss_sync_ops.h" int main(int argc, const char **argv) { gid_t pc_gid = 0; int pc_debug = SSSDBG_DEFAULT; struct poptOption long_options[] = { POPT_AUTOHELP { "debug",'\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, { "gid", 'g', POPT_ARG_INT, &pc_gid, 0, _("The GID of the group"), NULL }, POPT_TABLEEND }; poptContext pc = NULL; struct tools_ctx *tctx = NULL; int ret = EXIT_SUCCESS; errno_t sret; const char *pc_groupname = NULL; bool in_transaction = false; debug_prg_name = argv[0]; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); ret = EXIT_FAILURE; goto fini; } /* parse params */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "GROUPNAME"); if ((ret = poptGetNextOpt(pc)) < -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } DEBUG_CLI_INIT(pc_debug); /* groupname is an argument, not option */ pc_groupname = poptGetArg(pc); if (pc_groupname == NULL) { BAD_POPT_PARAMS(pc, _("Specify group to add\n"), ret, fini); } CHECK_ROOT(ret, debug_prg_name); ret = init_sss_tools(&tctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "init_sss_tools failed (%d): %s\n", ret, strerror(ret)); if (ret == ENOENT) { ERROR("Error initializing the tools - no local domain\n"); } else { ERROR("Error initializing the tools\n"); } ret = EXIT_FAILURE; goto fini; } /* if the domain was not given as part of FQDN, default to local domain */ ret = parse_name_domain(tctx, pc_groupname); if (ret != EOK) { ERROR("Invalid domain specified in FQDN\n"); ret = EXIT_FAILURE; goto fini; } tctx->octx->gid = pc_gid; /* arguments processed, go on to actual work */ if (id_in_range(tctx->octx->gid, tctx->octx->domain) != EOK) { ERROR("The selected GID is outside the allowed range\n"); ret = EXIT_FAILURE; goto fini; } tctx->error = sysdb_transaction_start(tctx->sysdb); if (tctx->error != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; /* groupadd */ tctx->error = groupadd(tctx->octx); if (tctx->error) { goto done; } tctx->error = sysdb_transaction_commit(tctx->sysdb); if (tctx->error != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; done: if (in_transaction) { sret = sysdb_transaction_cancel(tctx->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } if (tctx->error) { ret = tctx->error; switch (ret) { case ERANGE: ERROR("Could not allocate ID for the group - domain full?\n"); break; case EEXIST: ERROR("A group with the same name or GID already exists\n"); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "sysdb operation failed (%d)[%s]\n", ret, strerror(ret)); ERROR("Transaction error. Could not add group.\n"); break; } ret = EXIT_FAILURE; goto fini; } ret = EXIT_SUCCESS; fini: talloc_free(tctx); poptFreeContext(pc); exit(ret); } sssd-1.13.4/src/tools/PaxHeaders.16287/sss_groupshow.c0000644000000000000000000000007412703456111017345 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.977794724 sssd-1.13.4/src/tools/sss_groupshow.c0000644002412700241270000005452012703456111021022 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_groupshow Copyright (C) Jakub Hrozek 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "db/sysdb.h" #include "util/util.h" #include "tools/tools_util.h" #include "tools/sss_sync_ops.h" #define PADDING_SPACES 4 #define GROUP_SHOW_ATTRS { SYSDB_MEMBEROF, SYSDB_GIDNUM, \ SYSDB_MEMBER, SYSDB_GHOST, SYSDB_NAME, \ NULL } #define GROUP_SHOW_MPG_ATTRS { SYSDB_MEMBEROF, SYSDB_UIDNUM, \ SYSDB_NAME, NULL } struct group_info { const char *name; gid_t gid; bool mpg; const char **user_members; const char **memberofs; struct group_info **group_members; }; /*==================Helper routines to process results================= */ const char *rdn_as_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) { const struct ldb_val *val; val = ldb_dn_get_rdn_val(dn); if (val == NULL) { return NULL; } return ldb_dn_escape_value(mem_ctx, *val);; } static int parse_memberofs(struct ldb_context *ldb, struct ldb_message_element *el, struct group_info *gi) { int i; struct ldb_dn *dn = NULL; gi->memberofs = talloc_array(gi, const char *, el->num_values+1); if (gi->memberofs == NULL) { return ENOMEM; } for (i = 0; i< el->num_values; ++i) { dn = ldb_dn_from_ldb_val(gi, ldb, &(el->values[i])); gi->memberofs[i] = talloc_strdup(gi, rdn_as_string(gi, dn)); talloc_zfree(dn); if (gi->memberofs[i] == NULL) { return ENOMEM; } DEBUG(SSSDBG_TRACE_FUNC, "memberof value: %s\n", gi->memberofs[i]); } gi->memberofs[el->num_values] = NULL; return EOK; } static int parse_members(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct sss_domain_info *domain, struct ldb_message_element *el, const char *parent_name, const char ***user_members, const char ***group_members, int *num_group_members) { struct ldb_dn *user_basedn = NULL, *group_basedn = NULL; struct ldb_dn *parent_dn = NULL; struct ldb_dn *dn = NULL; const char **um = NULL, **gm = NULL; unsigned int um_index = 0, gm_index = 0; TALLOC_CTX *tmp_ctx = NULL; int ret; int i; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { ret = ENOMEM; goto fail; } user_basedn = sysdb_user_base_dn(tmp_ctx, domain); group_basedn = sysdb_group_base_dn(tmp_ctx, domain); if (!user_basedn || !group_basedn) { ret = ENOMEM; goto fail; } um = talloc_array(mem_ctx, const char *, el->num_values+1); gm = talloc_array(mem_ctx, const char *, el->num_values+1); if (!um || !gm) { ret = ENOMEM; goto fail; } for (i = 0; i< el->num_values; ++i) { dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &(el->values[i])); /* user member or group member? */ parent_dn = ldb_dn_get_parent(tmp_ctx, dn); if (ldb_dn_compare_base(parent_dn, user_basedn) == 0) { um[um_index] = rdn_as_string(mem_ctx, dn); if (um[um_index] == NULL) { ret = ENOMEM; goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "User member %s\n", um[um_index]); um_index++; } else if (ldb_dn_compare_base(parent_dn, group_basedn) == 0) { gm[gm_index] = rdn_as_string(mem_ctx, dn); if (gm[gm_index] == NULL) { ret = ENOMEM; goto fail; } if (parent_name && strcmp(gm[gm_index], parent_name) == 0) { DEBUG(SSSDBG_TRACE_FUNC, "Skipping circular nesting for group %s\n", gm[gm_index]); continue; } DEBUG(SSSDBG_TRACE_FUNC, "Group member %s\n", gm[gm_index]); gm_index++; } else { DEBUG(SSSDBG_OP_FAILURE, "Group member not a user nor group: %s\n", ldb_dn_get_linearized(dn)); ret = EIO; goto fail; } talloc_zfree(dn); talloc_zfree(parent_dn); } um[um_index] = NULL; gm[gm_index] = NULL; if (um_index > 0) { um = talloc_realloc(mem_ctx, um, const char *, um_index+1); if (!um) { ret = ENOMEM; goto fail; } } else { talloc_zfree(um); } if (gm_index > 0) { gm = talloc_realloc(mem_ctx, gm, const char *, gm_index+1); if (!gm) { ret = ENOMEM; goto fail; } } else { talloc_zfree(gm); } *user_members = um; if (group_members) *group_members = gm; if (num_group_members) *num_group_members = gm_index; talloc_zfree(tmp_ctx); return EOK; fail: talloc_zfree(um); talloc_zfree(gm); talloc_zfree(tmp_ctx); return ret; } static int process_group(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct ldb_message *msg, struct sss_domain_info *domain, const char *parent_name, struct group_info **info, const char ***group_members, int *num_group_members) { struct ldb_message_element *el; int ret, i, j; int count = 0; struct group_info *gi = NULL; const char **user_members; DEBUG(SSSDBG_TRACE_FUNC, "Found entry %s\n", ldb_dn_get_linearized(msg->dn)); gi = talloc_zero(mem_ctx, struct group_info); if (!gi) { ret = ENOMEM; goto done; } /* mandatory data - name and gid */ gi->name = talloc_strdup(gi, ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL)); gi->gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0); if (gi->gid == 0 || gi->name == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "No name or no GID?\n"); ret = EIO; goto done; } /* list members */ el = ldb_msg_find_element(msg, SYSDB_MEMBER); if (el) { ret = parse_members(gi, ldb, domain, el, parent_name, &gi->user_members, group_members, num_group_members); if (ret != EOK) { goto done; } if (gi->user_members == NULL) { count = 0; } else { for (count = 0; gi->user_members[count]; count++) ; } } el = ldb_msg_find_element(msg, SYSDB_GHOST); if (el) { ret = parse_members(gi, ldb, domain, el, parent_name, &user_members, NULL, NULL); if (ret != EOK) { goto done; } if (user_members != NULL) { i = count; for (count = 0; user_members[count]; count++) ; gi->user_members = talloc_realloc(gi, gi->user_members, const char *, i + count + 1); if (gi->user_members == NULL) { ret = ENOMEM; goto done; } for (j = 0; j < count; j++, i++) { gi->user_members[i] = talloc_steal(gi->user_members, user_members[j]); } gi->user_members[i] = NULL; talloc_zfree(user_members); } } /* list memberofs */ el = ldb_msg_find_element(msg, SYSDB_MEMBEROF); if (el) { ret = parse_memberofs(ldb, el, gi); if (ret != EOK) { goto done; } } *info = gi; return EOK; done: talloc_zfree(gi); return ret; } /*========Find info about a group and recursively about subgroups====== */ int group_show_recurse(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct group_info *root, struct group_info *parent, const char **group_members, const int nmembers, struct group_info ***up_members); static int group_show_trim_memberof(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **memberofs, const char ***_direct); int group_show(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, bool recursive, const char *name, struct group_info **res) { struct group_info *root; static const char *attrs[] = GROUP_SHOW_ATTRS; struct ldb_message *msg = NULL; const char **group_members = NULL; int nmembers = 0; int ret; int i; /* First, search for the root group */ ret = sysdb_search_group_by_name(mem_ctx, domain, name, attrs, &msg); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Search failed: %s (%d)\n", strerror(ret), ret); goto done; } ret = process_group(mem_ctx, sysdb_ctx_get_ldb(sysdb), msg, domain, NULL, &root, &group_members, &nmembers); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Group processing failed: %s (%d)\n", strerror(ret), ret); goto done; } if (!recursive) { if (group_members) { root->group_members = talloc_array(root, struct group_info *, nmembers+1); if (!root->group_members) { ret = ENOMEM; goto done; } for (i = 0; i < nmembers; i++) { root->group_members[i] = talloc_zero(root, struct group_info); if (!root->group_members[i]) { ret = ENOMEM; goto done; } root->group_members[i]->name = talloc_strdup(root, group_members[i]); if (!root->group_members[i]->name) { ret = ENOMEM; goto done; } } root->group_members[nmembers] = NULL; } if (root->memberofs == NULL) { ret = EOK; goto done; } /* if not recursive, only show the direct parent */ ret = group_show_trim_memberof(mem_ctx, domain, root->name, root->memberofs, &root->memberofs); goto done; } if (group_members == NULL) { ret = EOK; goto done; } ret = group_show_recurse(root, sysdb, domain, root, root, group_members, nmembers, &root->group_members); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Recursive search failed: %s (%d)\n", strerror(ret), ret); goto done; } ret = EOK; done: if (ret == EOK) { *res = root; } return ret; } /*=========Nonrecursive search should only show direct parent========== */ static int group_show_trim_memberof(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, const char **memberofs, const char ***_direct) { struct ldb_dn *dn; char *filter; struct ldb_message **msgs; size_t count; const char **direct = NULL; int ndirect = 0; int ret; int i; dn = sysdb_group_dn(mem_ctx, domain, name); if (!dn) { return ENOMEM; } for (i = 0; memberofs[i]; i++) { filter = talloc_asprintf(mem_ctx, "(&(%s=%s)(%s=%s))", SYSDB_NAME, memberofs[i], SYSDB_MEMBER, ldb_dn_get_linearized(dn)); if (!filter) { return ENOMEM; } ret = sysdb_search_groups(mem_ctx, domain, filter, NULL, &count, &msgs); /* ENOENT is OK, the group is just not a direct parent */ if (ret != EOK && ret != ENOENT) { return ret; } if (count > 0) { name = ldb_msg_find_attr_as_string(msgs[0], SYSDB_NAME, NULL); if (!name) { DEBUG(SSSDBG_OP_FAILURE, "Entry %s has no Name Attribute ?!?\n", ldb_dn_get_linearized(msgs[0]->dn)); return EFAULT; } direct = talloc_realloc(mem_ctx, direct, const char *, ndirect + 2); if (!direct) { return ENOMEM; } direct[ndirect] = talloc_strdup(direct, name); if (!direct[ndirect]) { return ENOMEM; } direct[ndirect + 1] = NULL; ndirect++; } } *_direct = direct; return EOK; } /*==================Recursive search for nested groups================= */ int group_show_recurse(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct group_info *root, struct group_info *parent, const char **group_members, const int nmembers, struct group_info ***up_members) { struct group_info **groups; static const char *attrs[] = GROUP_SHOW_ATTRS; struct ldb_message *msg; const char **new_group_members = NULL; int new_nmembers = 0; int ret; int i; groups = talloc_zero_array(root, struct group_info *, nmembers+1); /* trailing NULL */ if (!group_members || !group_members[0]) { return ENOENT; } for (i = 0; i < nmembers; i++) { /* Skip circular groups */ if (strcmp(group_members[i], parent->name) == 0) { continue; } ret = sysdb_search_group_by_name(mem_ctx, domain, group_members[i], attrs, &msg); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Search failed: %s (%d)\n", strerror(ret), ret); return EIO; } ret = process_group(root, sysdb_ctx_get_ldb(sysdb), msg, domain, parent->name, &groups[i], &new_group_members, &new_nmembers); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Group processing failed: %s (%d)\n", strerror(ret), ret); return ret; } /* descend to another level */ if (new_nmembers > 0) { ret = group_show_recurse(mem_ctx, sysdb, domain, root, groups[i], new_group_members, new_nmembers, &parent->group_members); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Recursive search failed: %s (%d)\n", strerror(ret), ret); return ret; } talloc_zfree(new_group_members); } } *up_members = groups; return EOK; } /*==================Get info about MPG================================= */ static int group_show_mpg(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name, struct group_info **res) { const char *attrs[] = GROUP_SHOW_MPG_ATTRS; struct ldb_message *msg; struct group_info *info; int ret; info = talloc_zero(mem_ctx, struct group_info); if (!info) { ret = ENOMEM; goto fail; } ret = sysdb_search_user_by_name(info, domain, name, attrs, &msg); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Search failed: %s (%d)\n", strerror(ret), ret); goto fail; } info->name = talloc_strdup(info, ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL)); info->gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0); if (info->gid == 0 || info->name == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "No name or no GID?\n"); ret = EIO; goto fail; } info->mpg = true; *res = info; return EOK; fail: talloc_zfree(info); return ret; } /*==================The main program=================================== */ static void print_group_info(struct group_info *g, int level) { int i; char padding[512]; char fmt[8]; snprintf(fmt, 8, "%%%ds", level*PADDING_SPACES); snprintf(padding, 512, fmt, ""); printf(_("%1$s%2$sGroup: %3$s\n"), padding, g->mpg ? _("Magic Private ") : "", g->name); printf(_("%1$sGID number: %2$d\n"), padding, g->gid); printf(_("%1$sMember users: "), padding); if (g->user_members) { for (i=0; g->user_members[i]; ++i) { printf("%s%s", i>0 ? "," : "", g->user_members[i]); } } printf(_("\n%1$sIs a member of: "), padding); if (g->memberofs) { for (i=0; g->memberofs[i]; ++i) { printf("%s%s", i>0 ? "," : "", g->memberofs[i]); } } printf(_("\n%1$sMember groups: "), padding); } static void print_recursive(struct group_info **group_members, int level) { int i; if (group_members == NULL) { return; } level++; for (i=0; group_members[i]; ++i) { printf("\n"); print_group_info(group_members[i], level); printf("\n"); print_recursive(group_members[i]->group_members, level); } } int main(int argc, const char **argv) { int ret = EXIT_SUCCESS; int pc_debug = SSSDBG_DEFAULT; bool pc_recursive = false; const char *pc_groupname = NULL; struct tools_ctx *tctx = NULL; struct group_info *root = NULL; int i; poptContext pc = NULL; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, { "recursive", 'R', POPT_ARG_NONE, NULL, 'r', _("Print indirect group members recursively"), NULL }, POPT_TABLEEND }; debug_prg_name = argv[0]; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); ret = EXIT_FAILURE; goto fini; } /* parse ops_ctx */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "GROUPNAME"); while ((ret = poptGetNextOpt(pc)) > 0) { switch (ret) { case 'r': pc_recursive = true; break; } } DEBUG_CLI_INIT(pc_debug); if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } pc_groupname = poptGetArg(pc); if (pc_groupname == NULL) { BAD_POPT_PARAMS(pc, _("Specify group to show\n"), ret, fini); } CHECK_ROOT(ret, debug_prg_name); ret = init_sss_tools(&tctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "init_sss_tools failed (%d): %s\n", ret, strerror(ret)); if (ret == ENOENT) { ERROR("Error initializing the tools - no local domain\n"); } else { ERROR("Error initializing the tools\n"); } ret = EXIT_FAILURE; goto fini; } /* if the domain was not given as part of FQDN, default to local domain */ ret = parse_name_domain(tctx, pc_groupname); if (ret != EOK) { ERROR("Invalid domain specified in FQDN\n"); ret = EXIT_FAILURE; goto fini; } /* The search itself */ ret = group_show(tctx, tctx->sysdb, tctx->local, pc_recursive, tctx->octx->name, &root); /* Also show MPGs */ if (ret == ENOENT) { ret = group_show_mpg(tctx, tctx->local, tctx->octx->name, &root); } /* Process result */ if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb operation failed (%d)[%s]\n", ret, strerror(ret)); switch (ret) { case ENOENT: ERROR("No such group in local domain. " "Printing groups only allowed in local domain.\n"); break; default: ERROR("Internal error. Could not print group.\n"); break; } ret = EXIT_FAILURE; goto fini; } /* print the results */ print_group_info(root, 0); if (pc_recursive) { printf("\n"); print_recursive(root->group_members, 0); } else { if (root->group_members) { for (i=0; root->group_members[i]; ++i) { printf("%s%s", i>0 ? "," : "", root->group_members[i]->name); } } printf("\n"); } fini: talloc_free(tctx); poptFreeContext(pc); exit(ret); } sssd-1.13.4/src/tools/PaxHeaders.16287/sss_signal.c0000644000000000000000000000007412703456111016565 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.985794751 sssd-1.13.4/src/tools/sss_signal.c0000644002412700241270000000203212703456111020231 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "config.h" #include "tools/tools_util.h" int main(int argc, const char **argv) { int ret; ret = signal_sssd(SIGUSR2); if (ret != EOK) { ERROR("Could not signal SSSD. Is SSSD running?\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } sssd-1.13.4/src/tools/PaxHeaders.16287/selinux.c0000644000000000000000000000007412703456111016107 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.646793602 sssd-1.13.4/src/tools/selinux.c0000644002412700241270000000405712703456111017564 0ustar00jhrozekjhrozek00000000000000/* SSSD selinux.c Copyright (C) Jakub Hrozek 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #ifdef HAVE_SELINUX #include #endif #include "tools/tools_util.h" #ifdef HAVE_SELINUX /* * selinux_file_context - Set the security context before any file or * directory creation. * * selinux_file_context () should be called before any creation of file, * symlink, directory, ... * * Callers may have to Reset SELinux to create files with default * contexts: * reset_selinux_file_context(); */ int selinux_file_context(const char *dst_name) { security_context_t scontext = NULL; if (is_selinux_enabled() == 1) { /* Get the default security context for this file */ if (matchpathcon(dst_name, 0, &scontext) < 0) { if (security_getenforce () != 0) { return 1; } } /* Set the security context for the next created file */ if (setfscreatecon(scontext) < 0) { if (security_getenforce() != 0) { return 1; } } freecon(scontext); } return 0; } int reset_selinux_file_context(void) { setfscreatecon(NULL); return EOK; } #else /* HAVE_SELINUX */ int selinux_file_context(const char *dst_name) { return EOK; } int reset_selinux_file_context(void) { return EOK; } #endif /* HAVE_SELINUX */ sssd-1.13.4/src/tools/PaxHeaders.16287/sss_sync_ops.h0000644000000000000000000000007412703456111017152 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.581793381 sssd-1.13.4/src/tools/sss_sync_ops.h0000644002412700241270000000541612703456111020627 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSS_OPS_H__ #define __SSS_OPS_H__ #include "tools/tools_util.h" #include #define DO_LOCK 1 #define DO_UNLOCK 2 /* 0 = not set, pick default */ #define DO_CREATE_HOME 1 #define DO_NOT_CREATE_HOME 2 #define DO_REMOVE_HOME 1 #define DO_NOT_REMOVE_HOME 2 #define DO_FORCE_REMOVAL 1 struct ops_ctx { struct sss_domain_info *domain; char *name; uid_t uid; gid_t gid; char *gecos; char *home; char *shell; int lock; bool create_homedir; bool remove_homedir; mode_t umask; char *skeldir; char *maildir; char **addgroups; char **rmgroups; char *addattr; char *setattr; char *delattr; }; /* default values for add operations */ int useradd_defaults(TALLOC_CTX *mem_ctx, struct confdb_ctx *confdb, struct ops_ctx *data, const char *gecos, const char *homedir, const char *shell, int create_home, const char *skeldir); /* default values for remove operations */ int userdel_defaults(TALLOC_CTX *mem_ctx, struct confdb_ctx *confdb, struct ops_ctx *data, int remove_home); /* synchronous operations */ int useradd(TALLOC_CTX *mem_ctx, struct ops_ctx *data); int userdel(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct ops_ctx *data); int usermod(TALLOC_CTX *mem_ctx, struct ops_ctx *data); int groupadd(struct ops_ctx *data); int groupdel(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct ops_ctx *data); int groupmod(TALLOC_CTX *mem_ctx, struct ops_ctx *data); int sysdb_getpwnam_sync(TALLOC_CTX *mem_ctx, const char *name, struct ops_ctx *out); int sysdb_getgrnam_sync(TALLOC_CTX *mem_ctx, const char *name, struct ops_ctx *out); #endif /* __SSS_OPS_H__ */ sssd-1.13.4/src/tools/PaxHeaders.16287/sss_useradd.c0000644000000000000000000000007412703456111016737 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.989794764 sssd-1.13.4/src/tools/sss_useradd.c0000644002412700241270000002266112703456111020415 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_useradd Copyright (C) Jakub Hrozek 2009 Copyright (C) Simo Sorce 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include "util/util.h" #include "db/sysdb.h" #include "tools/tools_util.h" #include "tools/sss_sync_ops.h" int main(int argc, const char **argv) { uid_t pc_uid = 0; const char *pc_gecos = NULL; const char *pc_home = NULL; char *pc_shell = NULL; int pc_debug = SSSDBG_DEFAULT; int pc_create_home = 0; const char *pc_username = NULL; const char *pc_skeldir = NULL; const char *pc_selinux_user = NULL; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, { "uid", 'u', POPT_ARG_INT, &pc_uid, 0, _("The UID of the user"), NULL }, { "gecos", 'c', POPT_ARG_STRING, &pc_gecos, 0, _("The comment string"), NULL }, { "home", 'h', POPT_ARG_STRING, &pc_home, 0, _("Home directory"), NULL }, { "shell", 's', POPT_ARG_STRING, &pc_shell, 0, _("Login shell"), NULL }, { "groups", 'G', POPT_ARG_STRING, NULL, 'G', _("Groups"), NULL }, { "create-home", 'm', POPT_ARG_NONE, NULL, 'm', _("Create user's directory if it does not exist"), NULL }, { "no-create-home", 'M', POPT_ARG_NONE, NULL, 'M', _("Never create user's directory, overrides config"), NULL }, { "skel", 'k', POPT_ARG_STRING, &pc_skeldir, 0, _("Specify an alternative skeleton directory"), NULL }, { "selinux-user", 'Z', POPT_ARG_STRING, &pc_selinux_user, 0, _("The SELinux user for user's login"), NULL }, POPT_TABLEEND }; poptContext pc = NULL; struct tools_ctx *tctx = NULL; char *groups = NULL; char *badgroup = NULL; int ret; errno_t sret; bool in_transaction = false; debug_prg_name = argv[0]; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); ret = EXIT_FAILURE; goto fini; } /* parse parameters */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "USERNAME"); while ((ret = poptGetNextOpt(pc)) > 0) { switch (ret) { case 'G': groups = poptGetOptArg(pc); if (!groups) { BAD_POPT_PARAMS(pc, _("Specify group to add to\n"), ret, fini); } break; case 'm': pc_create_home = DO_CREATE_HOME; break; case 'M': pc_create_home = DO_NOT_CREATE_HOME; break; } } DEBUG_CLI_INIT(pc_debug); if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } /* username is an argument without --option */ pc_username = poptGetArg(pc); if (pc_username == NULL) { BAD_POPT_PARAMS(pc, _("Specify user to add\n"), ret, fini); } CHECK_ROOT(ret, debug_prg_name); ret = init_sss_tools(&tctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "init_sss_tools failed (%d): %s\n", ret, strerror(ret)); if (ret == ENOENT) { ERROR("Error initializing the tools - no local domain\n"); } else { ERROR("Error initializing the tools\n"); } ret = EXIT_FAILURE; goto fini; } /* if the domain was not given as part of FQDN, default to local domain */ ret = parse_name_domain(tctx, pc_username); if (ret != EOK) { ERROR("Invalid domain specified in FQDN\n"); ret = EXIT_FAILURE; goto fini; } if (groups) { ret = parse_groups(tctx, groups, &tctx->octx->addgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse groups to add the user to\n"); ERROR("Internal error while parsing parameters\n"); ret = EXIT_FAILURE; goto fini; } ret = parse_group_name_domain(tctx, tctx->octx->addgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse FQDN groups to add the user to\n"); ERROR("Groups must be in the same domain as user\n"); ret = EXIT_FAILURE; goto fini; } /* Check group names in the LOCAL domain */ ret = check_group_names(tctx, tctx->octx->addgroups, &badgroup); if (ret != EOK) { ERROR("Cannot find group %1$s in local domain\n", badgroup); ret = EXIT_FAILURE; goto fini; } } tctx->octx->uid = pc_uid; /* * Fills in defaults for ops_ctx user did not specify. */ ret = useradd_defaults(tctx, tctx->confdb, tctx->octx, pc_gecos, pc_home, pc_shell, pc_create_home, pc_skeldir); if (ret != EOK) { ERROR("Cannot set default values\n"); ret = EXIT_FAILURE; goto fini; } /* arguments processed, go on to actual work */ if (id_in_range(tctx->octx->uid, tctx->octx->domain) != EOK) { ERROR("The selected UID is outside the allowed range\n"); ret = EXIT_FAILURE; goto fini; } tctx->error = sysdb_transaction_start(tctx->sysdb); if (tctx->error != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; /* useradd */ tctx->error = useradd(tctx, tctx->octx); if (tctx->error) { goto done; } tctx->error = sysdb_transaction_commit(tctx->sysdb); if (tctx->error) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; /* Set SELinux login context - must be done after transaction is done * b/c libselinux calls getpwnam */ ret = set_seuser(tctx->octx->name, pc_selinux_user, NULL); if (ret != EOK) { ERROR("Cannot set SELinux login context\n"); ret = EXIT_FAILURE; goto fini; } /* Create user's home directory and/or mail spool */ if (tctx->octx->create_homedir) { /* We need to know the UID of the user, if * sysdb did assign it automatically, do a lookup */ if (tctx->octx->uid == 0) { ret = sysdb_getpwnam_sync(tctx, tctx->octx->name, tctx->octx); if (ret != EOK) { ERROR("Cannot get info about the user\n"); ret = EXIT_FAILURE; goto fini; } } ret = create_homedir(tctx->octx->skeldir, tctx->octx->home, tctx->octx->uid, tctx->octx->gid, tctx->octx->umask); if (ret == EEXIST) { ERROR("User's home directory already exists, not copying " "data from skeldir\n"); } else if (ret != EOK) { ERROR("Cannot create user's home directory: %1$s\n", strerror(ret)); ret = EXIT_FAILURE; goto fini; } ret = create_mail_spool(tctx, tctx->octx->name, tctx->octx->maildir, tctx->octx->uid, tctx->octx->gid); if (ret != EOK) { ERROR("Cannot create user's mail spool: %1$s\n", strerror(ret)); DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create user's mail spool: [%d][%s].\n", ret, strerror(ret)); ret = EXIT_FAILURE; goto fini; } } done: if (in_transaction) { sret = sysdb_transaction_cancel(tctx->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } if (tctx->error) { switch (tctx->error) { case ERANGE: ERROR("Could not allocate ID for the user - domain full?\n"); break; case EEXIST: ERROR("A user or group with the same name or ID already exists\n"); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "sysdb operation failed (%d)[%s]\n", tctx->error, strerror(tctx->error)); ERROR("Transaction error. Could not add user.\n"); break; } ret = EXIT_FAILURE; goto fini; } ret = EXIT_SUCCESS; fini: poptFreeContext(pc); talloc_free(tctx); free(groups); exit(ret); } sssd-1.13.4/src/tools/PaxHeaders.16287/sss_groupdel.c0000644000000000000000000000007412703456111017131 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.975794717 sssd-1.13.4/src/tools/sss_groupdel.c0000644002412700241270000001017312703456111020602 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_groupdel Copyright (C) Jakub Hrozek 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "db/sysdb.h" #include "util/util.h" #include "tools/tools_util.h" #include "tools/sss_sync_ops.h" int main(int argc, const char **argv) { int ret = EXIT_SUCCESS; int pc_debug = SSSDBG_DEFAULT; const char *pc_groupname = NULL; struct tools_ctx *tctx = NULL; poptContext pc = NULL; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, POPT_TABLEEND }; debug_prg_name = argv[0]; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); ret = EXIT_FAILURE; goto fini; } /* parse ops_ctx */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "GROUPNAME"); if ((ret = poptGetNextOpt(pc)) < -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } DEBUG_CLI_INIT(pc_debug); pc_groupname = poptGetArg(pc); if (pc_groupname == NULL) { BAD_POPT_PARAMS(pc, _("Specify group to delete\n"), ret, fini); } CHECK_ROOT(ret, debug_prg_name); ret = init_sss_tools(&tctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "init_sss_tools failed (%d): %s\n", ret, strerror(ret)); if (ret == ENOENT) { ERROR("Error initializing the tools - no local domain\n"); } else { ERROR("Error initializing the tools\n"); } ret = EXIT_FAILURE; goto fini; } /* if the domain was not given as part of FQDN, default to local domain */ ret = parse_name_domain(tctx, pc_groupname); if (ret != EOK) { ERROR("Invalid domain specified in FQDN\n"); ret = EXIT_FAILURE; goto fini; } ret = sysdb_getgrnam_sync(tctx, tctx->octx->name, tctx->octx); if (ret != EOK) { /* Error message will be printed in the switch */ goto done; } if ((tctx->octx->gid < tctx->local->id_min) || (tctx->local->id_max && tctx->octx->gid > tctx->local->id_max)) { ERROR("Group %1$s is outside the defined ID range for domain\n", tctx->octx->name); ret = EXIT_FAILURE; goto fini; } /* groupdel */ ret = groupdel(tctx, tctx->sysdb, tctx->octx); if (ret != EOK) { goto done; } /* Delete group from memory cache */ ret = sss_mc_refresh_group(pc_groupname); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); /* Nothing we can do about it */ } ret = EOK; done: if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb operation failed (%d)[%s]\n", ret, strerror(ret)); switch (ret) { case ENOENT: ERROR("No such group in local domain. " "Removing groups only allowed in local domain.\n"); break; default: ERROR("Internal error. Could not remove group.\n"); break; } ret = EXIT_FAILURE; goto fini; } ret = EXIT_SUCCESS; fini: talloc_free(tctx); poptFreeContext(pc); exit(ret); } sssd-1.13.4/src/tools/PaxHeaders.16287/tools_util.c0000644000000000000000000000007412703456111016615 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.644793595 sssd-1.13.4/src/tools/tools_util.c0000644002412700241270000004152212703456111020270 0ustar00jhrozekjhrozek00000000000000/* SSSD tools_utils.c Copyright (C) Jakub Hrozek 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include "config.h" #include "util/util.h" #include "confdb/confdb.h" #include "db/sysdb.h" #include "tools/tools_util.h" #include "tools/sss_sync_ops.h" static int setup_db(struct tools_ctx *ctx) { char *confdb_path; int ret; confdb_path = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE); if (confdb_path == NULL) { return ENOMEM; } /* Connect to the conf db */ ret = confdb_init(ctx, &ctx->confdb, confdb_path); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the confdb\n"); return ret; } ret = sssd_domain_init(ctx, ctx->confdb, "local", DB_PATH, &ctx->local); if (ret != EOK) { SYSDB_VERSION_ERROR(ret); DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the sysdb\n"); return ret; } ctx->sysdb = ctx->local->sysdb; talloc_free(confdb_path); return EOK; } /* * Print poptUsage as well as our error message */ void usage(poptContext pc, const char *error) { size_t lentmp; char nl[2] = ""; poptPrintUsage(pc, stderr, 0); if (error) { lentmp = strlen(error); if ((lentmp > 0) && (error[lentmp - 1] != '\n')) { nl[0]='\n'; nl[1]='\0'; } fprintf(stderr, "%s%s", error, nl); } } int parse_groups(TALLOC_CTX *mem_ctx, const char *optstr, char ***_out) { char **out; char *orig, *n, *o; char delim = ','; unsigned int tokens = 1; int i; orig = talloc_strdup(mem_ctx, optstr); if (!orig) return ENOMEM; n = orig; tokens = 1; while ((n = strchr(n, delim))) { n++; tokens++; } out = talloc_array(mem_ctx, char *, tokens+1); if (!out) { talloc_free(orig); return ENOMEM; } n = o = orig; for (i = 0; i < tokens; i++) { o = n; n = strchr(n, delim); if (!n) { break; } *n = '\0'; n++; out[i] = talloc_strdup(out, o); } out[tokens-1] = talloc_strdup(out, o); out[tokens] = NULL; talloc_free(orig); *_out = out; return EOK; } int parse_group_name_domain(struct tools_ctx *tctx, char **groups) { int i; int ret; char *name = NULL; char *domain = NULL; if (!groups) { return EOK; } for (i = 0; groups[i]; ++i) { ret = sss_parse_name(tctx, tctx->snctx, groups[i], &domain, &name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid name in group list, skipping: [%s] (%d)\n", groups[i], ret); continue; } /* If FQDN is specified, it must be within the same domain as user */ if (domain) { if (strcmp(domain, tctx->octx->domain->name) != 0) { return EINVAL; } /* Use only groupname */ talloc_zfree(groups[i]); groups[i] = talloc_strdup(tctx, name); if (groups[i] == NULL) { return ENOMEM; } } talloc_zfree(name); talloc_zfree(domain); } talloc_zfree(name); talloc_zfree(domain); return EOK; } int parse_name_domain(struct tools_ctx *tctx, const char *fullname) { int ret; char *domain = NULL; ret = sss_parse_name(tctx, tctx->snctx, fullname, &domain, &tctx->octx->name); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot parse full name\n"); return ret; } DEBUG(SSSDBG_FUNC_DATA, "Parsed username: %s\n", tctx->octx->name); if (domain) { DEBUG(SSSDBG_FUNC_DATA, "Parsed domain: %s\n", domain); /* only the local domain, whatever named is allowed in tools */ if (strcasecmp(domain, tctx->local->name) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid domain %s specified in FQDN\n", domain); return EINVAL; } } else { if (tctx->local->fqnames) { DEBUG(SSSDBG_CRIT_FAILURE, "Name '%s' does not seem to be FQDN " "('%s = TRUE' is set)\n", fullname, CONFDB_DOMAIN_FQ); ERROR("Name '%1$s' does not seem to be FQDN " "('%2$s = TRUE' is set)\n", fullname, CONFDB_DOMAIN_FQ); return EINVAL; } } return EOK; } int check_group_names(struct tools_ctx *tctx, char **grouplist, char **badgroup) { int ret; int i; struct ops_ctx *groupinfo; groupinfo = talloc_zero(tctx, struct ops_ctx); if (!groupinfo) { return ENOMEM; } groupinfo->domain = tctx->local; ret = EOK; for (i=0; grouplist[i]; ++i) { ret = sysdb_getgrnam_sync(tctx, grouplist[i], groupinfo); if (ret) { DEBUG(SSSDBG_TRACE_FUNC, "Cannot find group %s, ret: %d\n", grouplist[i], ret); break; } } talloc_zfree(groupinfo); *badgroup = grouplist[i]; return ret; } int id_in_range(uint32_t id, struct sss_domain_info *dom) { if (id && ((id < dom->id_min) || (dom->id_max && id > dom->id_max))) { return ERANGE; } return EOK; } int set_locale(void) { char *c; c = setlocale(LC_ALL, ""); if (c == NULL) { /* If setlocale fails, continue with the default * locale. */ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to set locale\n"); } errno = 0; c = bindtextdomain(PACKAGE, LOCALEDIR); if (c == NULL) { return errno; } errno = 0; c = textdomain(PACKAGE); if (c == NULL) { return errno; } return EOK; } int init_sss_tools(struct tools_ctx **_tctx) { int ret; struct tools_ctx *tctx; tctx = talloc_zero(NULL, struct tools_ctx); if (tctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate memory for tools context\n"); return ENOMEM; } /* Connect to the database */ ret = setup_db(tctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up database\n"); goto fini; } ret = sss_names_init(tctx, tctx->confdb, tctx->local->name, &tctx->snctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up parsing\n"); goto fini; } tctx->octx = talloc_zero(tctx, struct ops_ctx); if (!tctx->octx) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate memory for data context\n"); ERROR("Out of memory\n"); ret = ENOMEM; goto fini; } tctx->octx->domain = tctx->local; *_tctx = tctx; ret = EOK; fini: if (ret != EOK) talloc_free(tctx); return ret; } /* * Check is path is owned by uid * returns 0 - owns * -1 - does not own * >0 - an error occurred, error code */ static int is_owner(uid_t uid, const char *path) { struct stat statres; int ret; ret = stat(path, &statres); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot stat %s: [%d][%s]\n", path, ret, strerror(ret)); return ret; } if (statres.st_uid == uid) { return EOK; } return -1; } static int remove_mail_spool(TALLOC_CTX *mem_ctx, const char *maildir, const char *username, uid_t uid, bool force) { int ret; char *spool_file; spool_file = talloc_asprintf(mem_ctx, "%s/%s", maildir, username); if (spool_file == NULL) { ret = ENOMEM; goto fail; } if (force == false) { /* Check the owner of the mail spool */ ret = is_owner(uid, spool_file); switch (ret) { case 0: break; case -1: DEBUG(SSSDBG_MINOR_FAILURE, "%s not owned by %"SPRIuid", not removing\n", spool_file, uid); ret = EACCES; /* FALLTHROUGH */ default: goto fail; } } ret = unlink(spool_file); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot remove() the spool file %s: [%d][%s]\n", spool_file, ret, strerror(ret)); goto fail; } fail: talloc_free(spool_file); return ret; } int remove_homedir(TALLOC_CTX *mem_ctx, const char *homedir, const char *maildir, const char *username, uid_t uid, bool force) { int ret; ret = remove_mail_spool(mem_ctx, maildir, username, uid, force); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot remove user's mail spool\n"); /* Should this be fatal? I don't think so. Maybe convert to ERROR? */ } if (force == false && is_owner(uid, homedir) == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "Not removing home dir - not owned by user\n"); return EPERM; } /* Remove the tree */ ret = remove_tree(homedir); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot remove homedir %s: %d\n", homedir, ret); return ret; } return EOK; } /* The reason for not putting this into create_homedir * is better granularity when it comes to reporting error * messages and tracebacks in pysss */ int create_mail_spool(TALLOC_CTX *mem_ctx, const char *username, const char *maildir, uid_t uid, gid_t gid) { char *spool_file = NULL; int fd = -1; int ret; spool_file = talloc_asprintf(mem_ctx, "%s/%s", maildir, username); if (spool_file == NULL) { ret = ENOMEM; goto fail; } selinux_file_context(spool_file); fd = open(spool_file, O_CREAT | O_WRONLY | O_EXCL, 0); if (fd < 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot open() the spool file: [%d][%s]\n", ret, strerror(ret)); goto fail; } ret = fchmod(fd, 0600); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot fchmod() the spool file: [%d][%s]\n", ret, strerror(ret)); goto fail; } ret = fchown(fd, uid, gid); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot fchown() the spool file: [%d][%s]\n", ret, strerror(ret)); goto fail; } ret = fsync(fd); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot fsync() the spool file: [%d][%s]\n", ret, strerror(ret)); } fail: if (fd >= 0) { ret = close(fd); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot close() the spool file: [%d][%s]\n", ret, strerror(ret)); } } reset_selinux_file_context(); talloc_free(spool_file); return ret; } int create_homedir(const char *skeldir, const char *homedir, uid_t uid, gid_t gid, mode_t default_umask) { int ret; selinux_file_context(homedir); ret = copy_tree(skeldir, homedir, 0777 & ~default_umask, uid, gid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot populate user's home directory: [%d][%s].\n", ret, strerror(ret)); goto done; } done: reset_selinux_file_context(); return ret; } int run_userdel_cmd(struct tools_ctx *tctx) { int ret, status; char *userdel_cmd = NULL; char *conf_path = NULL; pid_t pid, child_pid; conf_path = talloc_asprintf(tctx, CONFDB_DOMAIN_PATH_TMPL, tctx->local->name); if (!conf_path) { ret = ENOMEM; goto done; } ret = confdb_get_string(tctx->confdb, tctx, conf_path, CONFDB_LOCAL_USERDEL_CMD, NULL, &userdel_cmd); if (ret != EOK || !userdel_cmd) { goto done; } errno = 0; pid = fork(); if (pid == 0) { /* child */ execl(userdel_cmd, userdel_cmd, tctx->octx->name, (char *) NULL); exit(errno); } else { /* parent */ if (pid == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d]: %s\n", ret, strerror(ret)); goto done; } while((child_pid = waitpid(pid, &status, 0)) > 0) { if (WIFEXITED(status)) { ret = WEXITSTATUS(status); if (ret != 0) { DEBUG(SSSDBG_FUNC_DATA, "command [%s] returned nonzero status %d.\n", userdel_cmd, ret); ret = EOK; /* Ignore return code of the command */ goto done; } } else if (WIFSIGNALED(status)) { DEBUG(SSSDBG_FUNC_DATA, "command [%s] was terminated by signal %d.\n", userdel_cmd, WTERMSIG(status)); ret = EIO; goto done; } else if (WIFSTOPPED(status)) { DEBUG(SSSDBG_FUNC_DATA, "command [%s] was stopped by signal %d.\n", userdel_cmd, WSTOPSIG(status)); continue; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unknown status from WAITPID\n"); ret = EIO; goto done; } } if (child_pid == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "waitpid failed\n"); ret = errno; goto done; } } ret = EOK; done: talloc_free(userdel_cmd); talloc_free(conf_path); return ret; } static pid_t parse_pid(const char *strpid) { long value; char *endptr; errno = 0; value = strtol(strpid, &endptr, 10); if ((errno != 0) || (endptr == strpid) || ((*endptr != '\0') && (*endptr != '\n'))) { return 0; } return value; } static errno_t get_sssd_pid(pid_t *out_pid) { int ret; size_t fsize; FILE *pid_file = NULL; char pid_str[MAX_PID_LENGTH] = {'\0'}; *out_pid = 0; errno = 0; pid_file = fopen(SSSD_PIDFILE, "r"); if (pid_file == NULL) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Unable to open pid file \"%s\": %s\n", SSSD_PIDFILE, strerror(ret)); goto done; } fsize = fread(pid_str, sizeof(char), MAX_PID_LENGTH * sizeof(char), pid_file); if (!feof(pid_file)) { /* eof not reached */ ret = ferror(pid_file); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read from file \"%s\": %s\n", SSSD_PIDFILE, strerror(ret)); } else { DEBUG(SSSDBG_CRIT_FAILURE, "File \"%s\" contains invalid pid.\n", SSSD_PIDFILE); } goto done; } if (fsize == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "File \"%s\" contains no pid.\n", SSSD_PIDFILE); ret = EINVAL; goto done; } pid_str[MAX_PID_LENGTH-1] = '\0'; *out_pid = parse_pid(pid_str); if (*out_pid == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "File \"%s\" contains invalid pid.\n", SSSD_PIDFILE); ret = EINVAL; goto done; } ret = EOK; done: if (pid_file != NULL) { fclose(pid_file); } return ret; } errno_t signal_sssd(int signum) { int ret; pid_t pid; ret = get_sssd_pid(&pid); if (ret != EOK) { return ret; } if (kill(pid, signum) != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Could not send signal %d to process %d: %s\n", signum, pid, strerror(errno)); return ret; } return EOK; } sssd-1.13.4/src/tools/PaxHeaders.16287/sss_obfuscate0000644000000000000000000000007412703456111017042 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.354792611 sssd-1.13.4/src/tools/sss_obfuscate0000644002412700241270000000741412703456111020517 0ustar00jhrozekjhrozek00000000000000#!/usr/bin/python from __future__ import print_function import sys from optparse import OptionParser import pysss import SSSDConfig import getpass def parse_options(): parser = OptionParser() parser.set_description("sss_obfuscate converts a given password into \ human-unreadable format and places it into \ appropriate domain section of the SSSD config \ file. The password can be passed in by stdin, \ specified on the command-line or entered \ interactively") parser.add_option("-s", "--stdin", action="store_true", dest="stdin", default=False, help="Read the password from stdin.") parser.add_option("-d", "--domain", dest="domain", default=None, help="The domain to use the password in (mandatory)", metavar="DOMNAME") parser.add_option("-f", "--file", dest="filename", default=None, help="Set input file to FILE (default: Use system " "default, usually /etc/sssd/sssd.conf)", metavar="FILE") (options, args) = parser.parse_args() return options, args def main(): options, args = parse_options() if not options: print("Cannot parse options", file=sys.stderr) return 1 if not options.domain: print("No domain specified", file=sys.stderr) return 1 if not options.stdin: try: pprompt = lambda: (getpass.getpass("Enter password: "), getpass.getpass("Re-enter password: ")) p1, p2 = pprompt() # Work around bug in Python 2.6 if '\x03' in p1 or '\x03' in p2: raise KeyboardInterrupt while p1 != p2: print('Passwords do not match. Try again') p1, p2 = pprompt() # Work around bug in Python 2.6 if '\x03' in p1 or '\x03' in p2: raise KeyboardInterrupt password = p1 except EOFError: print('\nUnexpected end-of-file. Password change aborted', file=sys.stderr) return 1 except KeyboardInterrupt: return 1 else: try: password = sys.stdin.read() except KeyboardInterrupt: return 1 # Obfuscate the password obfobj = pysss.password() obfpwd = obfobj.encrypt(password, obfobj.AES_256) # Save the obfuscated password into the domain try: sssdconfig = SSSDConfig.SSSDConfig() except IOError: print("Cannot read internal configuration files.") return 1 try: sssdconfig.import_config(options.filename) except IOError: print("Permissions error reading config file") return 1 try: domain = sssdconfig.get_domain(options.domain) except SSSDConfig.NoDomainError: print("No such domain %s" % options.domain) return 1 try: domain.set_option('ldap_default_authtok_type', 'obfuscated_password') domain.set_option('ldap_default_authtok', obfpwd) except SSSDConfig.NoOptionError: print("The domain %s does not seem to support the required options" % options.domain) return 1 sssdconfig.save_domain(domain) try: sssdconfig.write() except IOError: # File could not be written print("Could not write to config file. Check that you have the " "appropriate permissions to edit this file.", file=sys.stderr) return 1 return 0 if __name__ == "__main__": ret = main() sys.exit(ret) sssd-1.13.4/src/tools/PaxHeaders.16287/sss_cache.c0000644000000000000000000000007412703456111016353 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.971794704 sssd-1.13.4/src/tools/sss_cache.c0000644002412700241270000006351712703456111020036 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_cache Copyright (C) Jan Zeleny 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "tools/sss_sync_ops.h" #include "db/sysdb.h" #include "db/sysdb_services.h" #include "db/sysdb_autofs.h" #include "db/sysdb_ssh.h" #define INVALIDATE_NONE 0 #define INVALIDATE_USERS 1 #define INVALIDATE_GROUPS 2 #define INVALIDATE_NETGROUPS 4 #define INVALIDATE_SERVICES 8 #define INVALIDATE_AUTOFSMAPS 16 #define INVALIDATE_SSH_HOSTS 32 #ifdef BUILD_AUTOFS #ifdef BUILD_SSH #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \ INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \ INVALIDATE_AUTOFSMAPS | INVALIDATE_SSH_HOSTS ) #else /* BUILD_SSH */ #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \ INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \ INVALIDATE_AUTOFSMAPS ) #endif /* BUILD_SSH */ #else /* BUILD_AUTOFS */ #ifdef BUILD_SSH #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \ INVALIDATE_NETGROUPS | INVALIDATE_SERVICES | \ INVALIDATE_SSH_HOSTS ) #else /* BUILD_SSH */ #define INVALIDATE_EVERYTHING (INVALIDATE_USERS | INVALIDATE_GROUPS | \ INVALIDATE_NETGROUPS | INVALIDATE_SERVICES ) #endif /* BUILD_SSH */ #endif /* BUILD_AUTOFS */ enum sss_cache_entry { TYPE_USER=0, TYPE_GROUP, TYPE_NETGROUP, TYPE_SERVICE, TYPE_AUTOFSMAP, TYPE_SSH_HOST }; static errno_t search_autofsmaps(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs); struct cache_tool_ctx { struct confdb_ctx *confdb; struct sss_domain_info *domains; char *user_filter; char *group_filter; char *netgroup_filter; char *service_filter; char *autofs_filter; char *ssh_host_filter; char *user_name; char *group_name; char *netgroup_name; char *service_name; char *autofs_name; char *ssh_host_name; bool update_user_filter; bool update_group_filter; bool update_netgroup_filter; bool update_service_filter; bool update_autofs_filter; bool update_ssh_host_filter; }; errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain); errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx); static errno_t invalidate_entry(TALLOC_CTX *ctx, struct sss_domain_info *domain, const char *name, int entry_type); static bool invalidate_entries(TALLOC_CTX *ctx, struct sss_domain_info *dinfo, enum sss_cache_entry entry_type, const char *filter, const char *name); static errno_t update_all_filters(struct cache_tool_ctx *tctx, struct sss_domain_info *dinfo); int main(int argc, const char *argv[]) { errno_t ret; struct cache_tool_ctx *tctx = NULL; struct sysdb_ctx *sysdb; bool skipped = true; struct sss_domain_info *dinfo; ret = init_context(argc, argv, &tctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error initializing context for the application\n"); goto done; } for (dinfo = tctx->domains; dinfo; dinfo = get_next_domain(dinfo, SSS_GND_DESCEND)) { if (!IS_SUBDOMAIN(dinfo)) { /* Update list of subdomains for this domain */ ret = sysdb_update_subdomains(dinfo); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to update subdomains for domain %s.\n", dinfo->name); } } sysdb = dinfo->sysdb; /* Update filters for each domain */ ret = update_all_filters(tctx, dinfo); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to update filters.\n"); goto done; } ret = sysdb_transaction_start(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not start the transaction!\n"); goto done; } skipped &= !invalidate_entries(tctx, dinfo, TYPE_USER, tctx->user_filter, tctx->user_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_GROUP, tctx->group_filter, tctx->group_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_NETGROUP, tctx->netgroup_filter, tctx->netgroup_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_SERVICE, tctx->service_filter, tctx->service_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_AUTOFSMAP, tctx->autofs_filter, tctx->autofs_name); skipped &= !invalidate_entries(tctx, dinfo, TYPE_SSH_HOST, tctx->ssh_host_filter, tctx->ssh_host_name); ret = sysdb_transaction_commit(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not commit the transaction!\n"); ret = sysdb_transaction_cancel(sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } } if (skipped == true) { ERROR("No cache object matched the specified search\n"); ret = ENOENT; goto done; } else { ret = sss_memcache_clear_all(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to clear memory cache.\n"); goto done; } } ret = EOK; done: if (tctx) talloc_free(tctx); return ret; } static errno_t update_filter(struct cache_tool_ctx *tctx, struct sss_domain_info *dinfo, char *name, bool update, const char *fmt, bool force_case_sensitivity, char **_filter) { errno_t ret; char *parsed_domain = NULL; char *parsed_name = NULL; TALLOC_CTX *tmp_ctx = NULL; char *use_name = NULL; char *filter; char *sanitized; char *lc_sanitized; if (!name || !update) { /* Nothing to do */ return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n"); return ENOMEM; } ret = sss_parse_name(tmp_ctx, dinfo->names, name, &parsed_domain, &parsed_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_parse_name failed\n"); goto done; } if (parsed_domain != NULL && strcasecmp(dinfo->name, parsed_domain) != 0) { /* We were able to parse the domain from given fqdn, but it * does not match with currently processed domain. */ filter = NULL; ret = EOK; goto done; } if (!dinfo->case_sensitive && !force_case_sensitivity) { use_name = sss_tc_utf8_str_tolower(tmp_ctx, parsed_name); if (!use_name) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); ret = ENOMEM; goto done; } } else { use_name = parsed_name; } if (parsed_domain) { use_name = sss_get_domain_name(tmp_ctx, use_name, dinfo); if (!use_name) { ret = ENOMEM; goto done; } } ret = sss_filter_sanitize_for_dom(tmp_ctx, use_name, dinfo, &sanitized, &lc_sanitized); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to sanitize the given name.\n"); goto done; } if (fmt) { if (!dinfo->case_sensitive && !force_case_sensitivity) { filter = talloc_asprintf(tmp_ctx, "(|(%s=%s)(%s=%s))", SYSDB_NAME_ALIAS, lc_sanitized, SYSDB_NAME_ALIAS, sanitized); } else { filter = talloc_asprintf(tmp_ctx, fmt, SYSDB_NAME, sanitized); } } else { filter = talloc_strdup(tmp_ctx, sanitized); } if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); ret = ENOMEM; goto done; } ret = EOK; done: if (ret == EOK) { talloc_free(*_filter); *_filter = talloc_steal(tctx, filter); } talloc_free(tmp_ctx); return ret; } /* This function updates all filters for specified domain using this * domains regex to parse string into domain and name (if exists). */ static errno_t update_all_filters(struct cache_tool_ctx *tctx, struct sss_domain_info *dinfo) { errno_t ret; /* Update user filter */ ret = update_filter(tctx, dinfo, tctx->user_name, tctx->update_user_filter, "(%s=%s)", false, &tctx->user_filter); if (ret != EOK) { return ret; } /* Update group filter */ ret = update_filter(tctx, dinfo, tctx->group_name, tctx->update_group_filter, "(%s=%s)", false, &tctx->group_filter); if (ret != EOK) { return ret; } /* Update netgroup filter */ ret = update_filter(tctx, dinfo, tctx->netgroup_name, tctx->update_netgroup_filter, "(%s=%s)", false, &tctx->netgroup_filter); if (ret != EOK) { return ret; } /* Update service filter */ ret = update_filter(tctx, dinfo, tctx->service_name, tctx->update_service_filter, "(%s=%s)", false, &tctx->service_filter); if (ret != EOK) { return ret; } /* Update autofs filter */ ret = update_filter(tctx, dinfo, tctx->autofs_name, tctx->update_autofs_filter, "(&(objectclass="SYSDB_AUTOFS_MAP_OC")(%s=%s))", true, &tctx->autofs_filter); if (ret != EOK) { return ret; } /* Update ssh host filter */ ret = update_filter(tctx, dinfo, tctx->ssh_host_name, tctx->update_ssh_host_filter, "(%s=%s)", false, &tctx->ssh_host_filter); if (ret != EOK) { return ret; } return EOK; } static bool invalidate_entries(TALLOC_CTX *ctx, struct sss_domain_info *dinfo, enum sss_cache_entry entry_type, const char *filter, const char *name) { const char *attrs[] = {SYSDB_NAME, NULL}; size_t msg_count; struct ldb_message **msgs; const char *type_string = "unknown"; errno_t ret = EINVAL; int i; const char *c_name; bool iret; if (!filter) return false; switch (entry_type) { case TYPE_USER: type_string = "user"; ret = sysdb_search_users(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_GROUP: type_string = "group"; ret = sysdb_search_groups(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_NETGROUP: type_string = "netgroup"; ret = sysdb_search_netgroups(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_SERVICE: type_string = "service"; ret = sysdb_search_services(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_AUTOFSMAP: type_string = "autofs map"; ret = search_autofsmaps(ctx, dinfo, filter, attrs, &msg_count, &msgs); break; case TYPE_SSH_HOST: type_string = "ssh_host"; #ifdef BUILD_SSH ret = sysdb_search_ssh_hosts(ctx, dinfo, filter, attrs, &msg_count, &msgs); #else /* BUILD_SSH */ ret = ENOSYS; #endif /* BUILD_SSH */ break; } if (ret != EOK) { if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "'%s' %s: Not found in domain '%s'\n", type_string, name ? name : "", dinfo->name); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Searching for %s in domain %s with filter %s failed\n", type_string, dinfo->name, filter); } return false; } iret = true; for (i = 0; i < msg_count; i++) { c_name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL); if (c_name == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Something bad happened, can't find attribute %s\n", SYSDB_NAME); ERROR("Couldn't invalidate %1$s\n", type_string); iret = false; } else { ret = invalidate_entry(ctx, dinfo, c_name, entry_type); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Couldn't invalidate %s %s\n", type_string, c_name); ERROR("Couldn't invalidate %1$s %2$s\n", type_string, c_name); iret = false; } } } talloc_zfree(msgs); return iret; } static errno_t invalidate_entry(TALLOC_CTX *ctx, struct sss_domain_info *domain, const char *name, int entry_type) { struct sysdb_attrs *sys_attrs = NULL; errno_t ret; sys_attrs = sysdb_new_attrs(ctx); if (sys_attrs) { ret = sysdb_attrs_add_time_t(sys_attrs, SYSDB_CACHE_EXPIRE, 1); if (ret == EOK) { switch (entry_type) { case TYPE_USER: /* For users, we also need to reset the initgroups * cache expiry */ ret = sysdb_attrs_add_time_t(sys_attrs, SYSDB_INITGR_EXPIRE, 1); if (ret != EOK) return ret; ret = sysdb_set_user_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_GROUP: ret = sysdb_set_group_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_NETGROUP: ret = sysdb_set_netgroup_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_SERVICE: ret = sysdb_set_service_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_AUTOFSMAP: ret = sysdb_set_autofsmap_attr(domain, name, sys_attrs, SYSDB_MOD_REP); break; case TYPE_SSH_HOST: #ifdef BUILD_SSH ret = sysdb_set_ssh_host_attr(domain, name, sys_attrs, SYSDB_MOD_REP); #else /* BUILD_SSH */ ret = ENOSYS; #endif /* BUILD_SSH */ break; default: return EINVAL; } if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not set entry attributes\n"); } } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add expiration time to attributes\n"); } talloc_zfree(sys_attrs); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Could not create sysdb attributes\n"); ret = ENOMEM; } return ret; } errno_t init_domains(struct cache_tool_ctx *ctx, const char *domain) { char *confdb_path; int ret; struct sss_domain_info *dinfo; confdb_path = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE); if (confdb_path == NULL) { return ENOMEM; } /* Connect to the conf db */ ret = confdb_init(ctx, &ctx->confdb, confdb_path); talloc_free(confdb_path); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the confdb\n"); return ret; } if (domain) { ret = sssd_domain_init(ctx, ctx->confdb, domain, DB_PATH, &ctx->domains); if (ret != EOK) { SYSDB_VERSION_ERROR(ret); DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the sysdb\n"); return ret; } } else { ret = confdb_get_domains(ctx->confdb, &ctx->domains); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize domains\n"); return ret; } ret = sysdb_init(ctx, ctx->domains, false); SYSDB_VERSION_ERROR(ret); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the sysdb\n"); return ret; } } for (dinfo = ctx->domains; dinfo; dinfo = get_next_domain(dinfo, 0)) { ret = sss_names_init(ctx, ctx->confdb, dinfo->name, &dinfo->names); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_names_init() failed\n"); return ret; } } return EOK; } errno_t init_context(int argc, const char *argv[], struct cache_tool_ctx **tctx) { struct cache_tool_ctx *ctx = NULL; int idb = INVALIDATE_NONE; char *user = NULL; char *group = NULL; char *netgroup = NULL; char *service = NULL; char *map = NULL; char *ssh_host = NULL; char *domain = NULL; int debug = SSSDBG_DEFAULT; errno_t ret = EOK; poptContext pc = NULL; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &debug, 0, _("The debug level to run with"), NULL }, { "everything", 'E', POPT_ARG_NONE, NULL, 'e', _("Invalidate all cached entries except for sudo rules"), NULL }, { "user", 'u', POPT_ARG_STRING, &user, 0, _("Invalidate particular user"), NULL }, { "users", 'U', POPT_ARG_NONE, NULL, 'u', _("Invalidate all users"), NULL }, { "group", 'g', POPT_ARG_STRING, &group, 0, _("Invalidate particular group"), NULL }, { "groups", 'G', POPT_ARG_NONE, NULL, 'g', _("Invalidate all groups"), NULL }, { "netgroup", 'n', POPT_ARG_STRING, &netgroup, 0, _("Invalidate particular netgroup"), NULL }, { "netgroups", 'N', POPT_ARG_NONE, NULL, 'n', _("Invalidate all netgroups"), NULL }, { "service", 's', POPT_ARG_STRING, &service, 0, _("Invalidate particular service"), NULL }, { "services", 'S', POPT_ARG_NONE, NULL, 's', _("Invalidate all services"), NULL }, #ifdef BUILD_AUTOFS { "autofs-map", 'a', POPT_ARG_STRING, &map, 0, _("Invalidate particular autofs map"), NULL }, { "autofs-maps", 'A', POPT_ARG_NONE, NULL, 'a', _("Invalidate all autofs maps"), NULL }, #endif /* BUILD_AUTOFS */ #ifdef BUILD_SSH { "ssh-host", 'h', POPT_ARG_STRING, &ssh_host, 0, _("Invalidate particular SSH host"), NULL }, { "ssh-hosts", 'H', POPT_ARG_NONE, NULL, 'h', _("Invalidate all SSH hosts"), NULL }, #endif /* BUILD_SSH */ { "domain", 'd', POPT_ARG_STRING, &domain, 0, _("Only invalidate entries from a particular domain"), NULL }, POPT_TABLEEND }; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); goto fini; } pc = poptGetContext(NULL, argc, argv, long_options, 0); while ((ret = poptGetNextOpt(pc)) > 0) { switch (ret) { case 'u': idb |= INVALIDATE_USERS; break; case 'g': idb |= INVALIDATE_GROUPS; break; case 'n': idb |= INVALIDATE_NETGROUPS; break; case 's': idb |= INVALIDATE_SERVICES; break; case 'a': idb |= INVALIDATE_AUTOFSMAPS; break; case 'h': idb |= INVALIDATE_SSH_HOSTS; break; case 'e': idb = INVALIDATE_EVERYTHING; break; } } DEBUG_CLI_INIT(debug); debug_prg_name = argv[0]; if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } if (idb == INVALIDATE_NONE && !user && !group && !netgroup && !service && !map && !ssh_host) { BAD_POPT_PARAMS(pc, _("Please select at least one object to invalidate\n"), ret, fini); } CHECK_ROOT(ret, debug_prg_name); ctx = talloc_zero(NULL, struct cache_tool_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate memory for tools context\n"); ret = ENOMEM; goto fini; } if (idb & INVALIDATE_USERS) { ctx->user_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_user_filter = false; } else if (user) { ctx->user_name = talloc_strdup(ctx, user); ctx->update_user_filter = true; } if (idb & INVALIDATE_GROUPS) { ctx->group_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_group_filter = false; } else if (group) { ctx->group_name = talloc_strdup(ctx, group); ctx->update_group_filter = true; } if (idb & INVALIDATE_NETGROUPS) { ctx->netgroup_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_netgroup_filter = false; } else if (netgroup) { ctx->netgroup_name = talloc_strdup(ctx, netgroup); ctx->update_netgroup_filter = true; } if (idb & INVALIDATE_SERVICES) { ctx->service_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_service_filter = false; } else if (service) { ctx->service_name = talloc_strdup(ctx, service); ctx->update_service_filter = true; } if (idb & INVALIDATE_AUTOFSMAPS) { ctx->autofs_filter = talloc_asprintf(ctx, "(&(objectclass=%s)(%s=*))", SYSDB_AUTOFS_MAP_OC, SYSDB_NAME); ctx->update_autofs_filter = false; } else if (map) { ctx->autofs_name = talloc_strdup(ctx, map); ctx->update_autofs_filter = true; } if (idb & INVALIDATE_SSH_HOSTS) { ctx->ssh_host_filter = talloc_asprintf(ctx, "(%s=*)", SYSDB_NAME); ctx->update_ssh_host_filter = false; } else if (ssh_host) { ctx->ssh_host_name = talloc_strdup(ctx, ssh_host); ctx->update_ssh_host_filter = true; } if (((idb & INVALIDATE_USERS) && !ctx->user_filter) || ((idb & INVALIDATE_GROUPS) && !ctx->group_filter) || ((idb & INVALIDATE_NETGROUPS) && !ctx->netgroup_filter) || ((idb & INVALIDATE_SERVICES) && !ctx->service_filter) || ((idb & INVALIDATE_AUTOFSMAPS) && !ctx->autofs_filter) || ((idb & INVALIDATE_SSH_HOSTS) && !ctx->ssh_host_filter) || (user && !ctx->user_name) || (group && !ctx->group_name) || (netgroup && !ctx->netgroup_name) || (service && !ctx->service_name) || (map && !ctx->autofs_name) || (ssh_host && !ctx->ssh_host_name)) { DEBUG(SSSDBG_CRIT_FAILURE, "Construction of filters failed\n"); ret = ENOMEM; goto fini; } ret = init_domains(ctx, domain); if (ret != EOK) { if (domain) { ERROR("Could not open domain %1$s. If the domain is a subdomain " "(trusted domain), use fully qualified name instead of " "--domain/-d parameter.\n", domain); } else { ERROR("Could not open available domains\n"); } DEBUG(SSSDBG_OP_FAILURE, "Initialization of sysdb connections failed\n"); goto fini; } ret = EOK; fini: poptFreeContext(pc); free(user); free(group); free(netgroup); free(domain); if (ret != EOK && ctx) { talloc_zfree(ctx); } if (ret == EOK) { *tctx = ctx; } return ret; } static errno_t search_autofsmaps(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *sub_filter, const char **attrs, size_t *msgs_count, struct ldb_message ***msgs) { #ifdef BUILD_AUTOFS return sysdb_search_custom(mem_ctx, domain, sub_filter, AUTOFS_MAP_SUBDIR, attrs, msgs_count, msgs); #else return ENOSYS; #endif /* BUILD_AUTOFS */ } sssd-1.13.4/src/tools/PaxHeaders.16287/sss_debuglevel.c0000644000000000000000000000007412703456111017426 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.974794714 sssd-1.13.4/src/tools/sss_debuglevel.c0000644002412700241270000002220112703456111021072 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "util/util.h" #include "tools/tools_util.h" #include "confdb/confdb.h" #define CHECK(expr, done, msg) do { \ if (expr) { \ ERROR(msg "\n"); \ goto done; \ } \ } while(0) struct debuglevel_tool_ctx { struct confdb_ctx *confdb; char **sections; }; static errno_t set_debug_level(struct debuglevel_tool_ctx *tool_ctx, int debug_to_set, const char *config_file); static errno_t connect_to_confdb(TALLOC_CTX *ctx, struct confdb_ctx **cdb_ctx); static errno_t get_confdb_sections(TALLOC_CTX *ctx, struct confdb_ctx *confdb, char ***output_sections); static int parse_debug_level(const char *strlevel); int main(int argc, const char **argv) { int ret; int pc_debug = SSSDBG_DEFAULT; int debug_to_set = SSSDBG_INVALID; const char *debug_as_string = NULL; const char *config_file = NULL; const char *pc_config_file = NULL; struct debuglevel_tool_ctx *ctx = NULL; struct poptOption long_options[] = { POPT_AUTOHELP {"debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, {"config", 'c', POPT_ARG_STRING, &pc_config_file, 0, _("Specify a non-default config file"), NULL}, POPT_TABLEEND }; poptContext pc = NULL; debug_prg_name = argv[0]; /* parse parameters */ pc = poptGetContext(argv[0], argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "DEBUG_LEVEL_TO_SET"); while((ret = poptGetNextOpt(pc)) != -1) { switch(ret) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(ret)); poptPrintUsage(pc, stderr, 0); ret = EXIT_FAILURE; goto fini; } } DEBUG_CLI_INIT(pc_debug); /* get debug level */ debug_as_string = poptGetArg(pc); if (debug_as_string == NULL) { BAD_POPT_PARAMS(pc, _("Specify debug level you want to set\n"), ret, fini); } /* No more arguments expected. If something follows it is an error. */ if (poptGetArg(pc)) { BAD_POPT_PARAMS(pc, _("Only one argument expected\n"), ret, fini); } /* get config file */ if (pc_config_file) { config_file = talloc_strdup(ctx, pc_config_file); } else { config_file = talloc_strdup(ctx, CONFDB_DEFAULT_CONFIG_FILE); } if (config_file == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); ret = ENOMEM; goto fini; } CHECK_ROOT(ret, debug_prg_name); /* free pc_config_file? */ /* free debug_as_string? */ debug_to_set = parse_debug_level(debug_as_string); CHECK(debug_to_set == SSSDBG_INVALID, fini, "Invalid debug level."); /* allocate context */ ctx = talloc_zero(NULL, struct debuglevel_tool_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate memory for tools context\n"); ret = ENOMEM; goto fini; } ret = connect_to_confdb(ctx, &ctx->confdb); CHECK(ret != EOK, fini, "Could not connect to configuration database."); ret = get_confdb_sections(ctx, ctx->confdb, &ctx->sections); CHECK(ret != EOK, fini, "Could not get all configuration sections."); ret = set_debug_level(ctx, debug_to_set, config_file); CHECK(ret != EOK, fini, "Could not set debug level."); ret = signal_sssd(SIGHUP); CHECK(ret != EOK, fini, "Could not force sssd processes to reload configuration. " "Is sssd running?"); fini: poptFreeContext(pc); talloc_free(ctx); return ret; } errno_t set_debug_level(struct debuglevel_tool_ctx *tool_ctx, int debug_to_set, const char *config_file) { int ret; int err; const char *values[2]; char **section = NULL; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } /* convert debug_to_set to string */ values[0] = talloc_asprintf(tmp_ctx, "0x%.4x", debug_to_set); if (values[0] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate memory for " "debug_to_set to string conversion\n"); ret = ENOMEM; goto done; } values[1] = NULL; /* write to confdb */ for (section = tool_ctx->sections; *section != NULL; section++) { ret = confdb_add_param(tool_ctx->confdb, 1, *section, CONFDB_SERVICE_DEBUG_LEVEL, values); if (ret != EOK) { goto done; } } /* * Change atime and mtime of sssd.conf, * so the configuration can be restored on next start. */ errno = 0; if (utime(config_file, NULL) == -1 ) { err = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Unable to change mtime of \"%s\": %s\n", config_file, strerror(err)); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t connect_to_confdb(TALLOC_CTX *ctx, struct confdb_ctx **cdb_ctx) { int ret; char* confdb_path = NULL; confdb_path = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE); if (confdb_path == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate memory for confdb path\n"); return ENOMEM; } ret = confdb_init(ctx, cdb_ctx, confdb_path); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the confdb\n"); } talloc_free(confdb_path); return ret; } errno_t get_confdb_sections(TALLOC_CTX *ctx, struct confdb_ctx *confdb, char ***output_sections) { int ret; int domain_count = 0; int i = 0; struct sss_domain_info *domain = NULL; struct sss_domain_info *domain_list = NULL; char **sections; const char *known_services[] = { CONFDB_MONITOR_CONF_ENTRY, CONFDB_NSS_CONF_ENTRY, CONFDB_PAM_CONF_ENTRY, CONFDB_PAC_CONF_ENTRY, CONFDB_SSH_CONF_ENTRY, CONFDB_SUDO_CONF_ENTRY, CONFDB_AUTOFS_CONF_ENTRY, CONFDB_IFP_CONF_ENTRY, }; static const int known_services_count = sizeof(known_services) / sizeof(*known_services); TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } /* get domains */ ret = confdb_get_domains(confdb, &domain_list); if (ret != EOK) DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get domain list\n"); for (domain = domain_list; domain; domain = get_next_domain(domain, 0)) { domain_count++; } /* allocate output space */ sections = talloc_array(ctx, char*, domain_count + known_services_count + 1); if (sections == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate memory for sections\n"); ret = ENOMEM; goto fail; } for (i = 0; i < known_services_count; i++) { sections[i] = talloc_strdup(tmp_ctx, known_services[i]); if (sections[i] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); ret = ENOMEM; goto fail; } } for (domain = domain_list; domain; domain = get_next_domain(domain, 0), i++) { sections[i] = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, domain->name); if (sections[i] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n"); ret = ENOMEM; goto fail; } } /* add NULL to the end */ sections[i] = NULL; *output_sections = talloc_steal(ctx, sections); return EOK; fail: talloc_free(tmp_ctx); return ret; } int parse_debug_level(const char *strlevel) { long value; char *endptr; errno = 0; value = strtol(strlevel, &endptr, 0); if ((errno != 0) || (endptr == strlevel) || (*endptr != '\0')) { return SSSDBG_INVALID; } return debug_convert_old_level(value); } sssd-1.13.4/src/tools/PaxHeaders.16287/sss_groupmod.c0000644000000000000000000000007312703456111017143 xustar0030 atime=1460561751.659715658 29 ctime=1460561774.97679472 sssd-1.13.4/src/tools/sss_groupmod.c0000644002412700241270000002114312703456111020614 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_groupmod Copyright (C) Jakub Hrozek 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "util/util.h" #include "db/sysdb.h" #include "tools/tools_util.h" #include "tools/sss_sync_ops.h" int main(int argc, const char **argv) { gid_t pc_gid = 0; int pc_debug = SSSDBG_DEFAULT; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, { "append-group", 'a', POPT_ARG_STRING, NULL, 'a', _("Groups to add this group to"), NULL }, { "remove-group", 'r', POPT_ARG_STRING, NULL, 'r', _("Groups to remove this group from"), NULL }, { "gid", 'g', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_gid, 0, _("The GID of the group"), NULL }, POPT_TABLEEND }; poptContext pc = NULL; struct tools_ctx *tctx = NULL; char *addgroups = NULL, *rmgroups = NULL; int ret; errno_t sret; const char *pc_groupname = NULL; char *badgroup = NULL; bool in_transaction = false; debug_prg_name = argv[0]; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); ret = EXIT_FAILURE; goto fini; } /* parse parameters */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "GROUPNAME"); while ((ret = poptGetNextOpt(pc)) > 0) { switch (ret) { case 'a': addgroups = poptGetOptArg(pc); if (addgroups == NULL) { BAD_POPT_PARAMS(pc, _("Specify group to add to\n"), ret, fini); } break; case 'r': rmgroups = poptGetOptArg(pc); if (rmgroups == NULL) { BAD_POPT_PARAMS(pc, _("Specify group to remove from\n"), ret, fini); } break; } } if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } /* groupname is an argument without --option */ pc_groupname = poptGetArg(pc); if (pc_groupname == NULL) { BAD_POPT_PARAMS(pc, _("Specify group to modify\n"), ret, fini); } DEBUG_CLI_INIT(pc_debug); CHECK_ROOT(ret, debug_prg_name); ret = init_sss_tools(&tctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "init_sss_tools failed (%d): %s\n", ret, strerror(ret)); if (ret == ENOENT) { ERROR("Error initializing the tools - no local domain\n"); } else { ERROR("Error initializing the tools\n"); } ret = EXIT_FAILURE; goto fini; } ret = parse_name_domain(tctx, pc_groupname); if (ret != EOK) { ERROR("Invalid domain specified in FQDN\n"); ret = EXIT_FAILURE; goto fini; } /* check the username to be able to give sensible error message */ ret = sysdb_getgrnam_sync(tctx, tctx->octx->name, tctx->octx); if (ret != EOK) { ERROR("Cannot find group in local domain, " "modifying groups is allowed only in local domain\n"); ret = EXIT_FAILURE; goto fini; } tctx->octx->gid = pc_gid; if (addgroups) { ret = parse_groups(tctx, addgroups, &tctx->octx->addgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse groups to add the group to\n"); ERROR("Internal error while parsing parameters\n"); ret = EXIT_FAILURE; goto fini; } ret = parse_group_name_domain(tctx, tctx->octx->addgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse FQDN groups to add the group to\n"); ERROR("Member groups must be in the same domain as parent group\n"); ret = EXIT_FAILURE; goto fini; } /* Check group names in the LOCAL domain */ ret = check_group_names(tctx, tctx->octx->addgroups, &badgroup); if (ret != EOK) { ERROR("Cannot find group %1$s in local domain, " "only groups in local domain are allowed\n", badgroup); ret = EXIT_FAILURE; goto fini; } } if (rmgroups) { ret = parse_groups(tctx, rmgroups, &tctx->octx->rmgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse groups to remove the group from\n"); ERROR("Internal error while parsing parameters\n"); ret = EXIT_FAILURE; goto fini; } ret = parse_group_name_domain(tctx, tctx->octx->rmgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse FQDN groups to remove the group from\n"); ERROR("Member groups must be in the same domain as parent group\n"); ret = EXIT_FAILURE; goto fini; } /* Check group names in the LOCAL domain */ ret = check_group_names(tctx, tctx->octx->rmgroups, &badgroup); if (ret != EOK) { ERROR("Cannot find group %1$s in local domain, " "only groups in local domain are allowed\n", badgroup); ret = EXIT_FAILURE; goto fini; } } if (id_in_range(tctx->octx->gid, tctx->octx->domain) != EOK) { ERROR("The selected GID is outside the allowed range\n"); ret = EXIT_FAILURE; goto fini; } tctx->error = sysdb_transaction_start(tctx->sysdb); if (tctx->error != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; /* groupmod */ tctx->error = groupmod(tctx, tctx->octx); if (tctx->error) { goto done; } tctx->error = sysdb_transaction_commit(tctx->sysdb); if (tctx->error != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = sss_mc_refresh_group(pc_groupname); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); /* Nothing we can do about it */ } ret = sss_mc_refresh_grouplist(tctx, tctx->octx->addgroups); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); /* Nothing we can do about it */ } ret = sss_mc_refresh_grouplist(tctx, tctx->octx->rmgroups); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); /* Nothing we can do about it */ } done: if (in_transaction) { sret = sysdb_transaction_cancel(tctx->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } if (tctx->error) { ret = tctx->error; DEBUG(SSSDBG_CRIT_FAILURE, "sysdb operation failed (%d)[%s]\n", ret, strerror(ret)); switch (ret) { case ENOENT: ERROR("Could not modify group - check if member group names are correct\n"); break; case EFAULT: ERROR("Could not modify group - check if groupname is correct\n"); break; default: ERROR("Transaction error. Could not modify group.\n"); break; } ret = EXIT_FAILURE; goto fini; } ret = EXIT_SUCCESS; fini: free(addgroups); free(rmgroups); poptFreeContext(pc); talloc_free(tctx); exit(ret); } sssd-1.13.4/src/tools/PaxHeaders.16287/sss_seed.c0000644000000000000000000000007412703456111016230 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.982794741 sssd-1.13.4/src/tools/sss_seed.c0000644002412700241270000005717612703456111017717 0ustar00jhrozekjhrozek00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "db/sysdb.h" #include "tools/tools_util.h" #include "tools/sss_sync_ops.h" #include "confdb/confdb.h" #ifndef BUFSIZE #define BUFSIZE 1024 #endif #ifndef PASS_MAX #define PASS_MAX 64 #endif enum seed_pass_method { PASS_PROMPT, PASS_FILE }; struct user_ctx { char *domain_name; char *name; uid_t uid; gid_t gid; char *gecos; char *home; char *shell; char *password; }; struct seed_ctx { struct confdb_ctx *confdb; struct sss_domain_info *domain; struct sysdb_ctx *sysdb; struct user_ctx *uctx; char *password_file; enum seed_pass_method password_method; bool interact; bool user_cached; }; static int seed_prompt(const char *req) { ssize_t len = 0; size_t i = 0; char *prompt = NULL; int ret = EOK; prompt = talloc_asprintf(NULL, _("Enter %s:"), req); if (prompt == NULL) { ret = ENOMEM; goto done; } while (prompt[i] != '\0') { errno = 0; len = sss_atomic_write_s(STDOUT_FILENO, &prompt[i++], 1); if (len == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write failed [%d][%s].\n", ret, strerror(ret)); goto done; } } done: talloc_free(prompt); return ret; } static int seed_str_input(TALLOC_CTX *mem_ctx, const char *req, char **_input) { char buf[BUFSIZE+1]; size_t len = 0; size_t bytes_read = 0; int ret = EOK; ret = seed_prompt(req); if (ret != EOK) { return ret; } errno = 0; while ((bytes_read = sss_atomic_read_s(STDIN_FILENO, buf+len, 1)) != 0) { if (bytes_read == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret)); return ret; } if (buf[len] == '\n' || len == BUFSIZE) { buf[len] = '\0'; break; } len += bytes_read; } *_input = talloc_strdup(mem_ctx, buf); if (*_input == NULL) { ret = ENOMEM; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to allocate input\n"); } return ret; } static int seed_id_input(const char *req, uid_t *_id_input) { char buf[BUFSIZE+1]; size_t len = 0; size_t bytes_read = 0; char *endptr = NULL; int ret = EOK; ret = seed_prompt(req); if (ret != EOK) { return ret; } errno = 0; while ((bytes_read = sss_atomic_read_s(STDIN_FILENO, buf+len, 1)) != 0) { if (bytes_read == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret)); return ret; } if (buf[len] == '\n' || len == BUFSIZE) { buf[len] = '\0'; break; } len += bytes_read; } if (isdigit(*buf)) { errno = 0; *_id_input = (uid_t)strtoll(buf, &endptr, 10); if (errno != 0) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "strtoll failed on [%s]: [%d][%s].\n", (char *)buf, ret, strerror(ret)); return ret; } if (*endptr != '\0') { DEBUG(SSSDBG_MINOR_FAILURE, "extra characters [%s] after ID [%"SPRIuid"]\n", endptr, *_id_input); } } else { ret = EINVAL; DEBUG(SSSDBG_OP_FAILURE, "Failed to get %s input.\n", req); } return ret; } static int seed_password_input_prompt(TALLOC_CTX *mem_ctx, char **_password) { TALLOC_CTX *tmp_ctx = NULL; char *password = NULL; char *temp = NULL; int ret = EOK; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate temp context\n"); ret = ENOMEM; goto done; } temp = getpass("Enter temporary password:"); if (temp == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get prompted password\n"); ret = EINVAL; goto done; } /* Do not allow empty passwords */ if (strlen(temp) == 0) { ERROR("Empty passwords are not allowed.\n"); ret = EINVAL; goto done; } password = talloc_strdup(tmp_ctx, temp); if (password == NULL) { ret = ENOMEM; goto done; } talloc_set_destructor((TALLOC_CTX *)password, password_destructor); temp = getpass("Enter temporary password again:"); if (temp == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get prompted password\n"); ret = EINVAL; goto done; } if (strncmp(temp,password,strlen(password)) != 0) { ERROR("Passwords do not match\n"); DEBUG(SSSDBG_MINOR_FAILURE, "Provided passwords do not match\n"); ret = EINVAL; goto done; } *_password = talloc_steal(mem_ctx, password); done: talloc_free(tmp_ctx); return ret; } static int seed_password_input_file(TALLOC_CTX *mem_ctx, char *filename, char **_password) { TALLOC_CTX *tmp_ctx = NULL; char *password = NULL; int len = 0; uint8_t buf[PASS_MAX+1]; int fd = -1; int ret = EOK; int valid_i; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate temp context\n"); ret = ENOMEM; goto done; } fd = open(filename, O_RDONLY); if (fd == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to open password file " "[%s] [%d][%s]\n", filename, errno, strerror(errno)); ret = EINVAL; goto done; } errno = 0; len = sss_atomic_read_s(fd, buf, PASS_MAX + 1); if (len == -1) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Failed to read password from file " "[%s] [%d][%s]\n", filename, ret, strerror(ret)); close(fd); goto done; } close(fd); if (len > PASS_MAX) { ERROR("Password file too big.\n"); ret = EINVAL; goto done; } buf[len] = '\0'; /* Only the first line is valid (without '\n'). */ for (valid_i = -1; valid_i + 1 < len; valid_i++) { if (buf[valid_i + 1] == '\n') { buf[valid_i + 1] = '\0'; break; } } /* Do not allow empty passwords. */ if (valid_i < 0) { ERROR("Empty passwords are not allowed.\n"); ret = EINVAL; goto done; } /* valid_i is the last valid index of the password followed by \0. * If characters other than \n occur int the rest of the file, it * is an error. */ for (i = valid_i + 2; i < len; i++) { if (buf[i] != '\n') { ERROR("Multi-line passwords are not allowed.\n"); ret = EINVAL; goto done; } } password = talloc_strdup(tmp_ctx, (char *)buf); if (password == NULL) { ret = ENOMEM; goto done; } *_password = talloc_steal(mem_ctx, password); done: talloc_free(tmp_ctx); return ret; } static int seed_interactive_input(TALLOC_CTX *mem_ctx, struct user_ctx *uctx, struct user_ctx **_uctx) { struct user_ctx *input_uctx = NULL; int ret = EOK; input_uctx = talloc_zero(NULL, struct user_ctx); if (input_uctx == NULL) { ret = ENOMEM; goto done; } if (uctx->name == NULL) { ret = seed_str_input(input_uctx, _("username"), &input_uctx->name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Username interactive input failed.\n"); goto done; } } else { input_uctx->name = talloc_strdup(input_uctx, uctx->name); if (input_uctx->name == NULL) { ret = ENOMEM; goto done; } } if (uctx->uid == 0) { ret = seed_id_input(_("UID"), &input_uctx->uid); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "UID interactive input failed.\n"); goto done; } } else { input_uctx->uid = uctx->uid; } if (uctx->gid == 0) { ret = seed_id_input(_("GID"), &input_uctx->gid); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "GID interactive input failed.\n"); goto done; } } else { input_uctx->gid = uctx->gid; } if (uctx->gecos == NULL) { ret = seed_str_input(input_uctx, _("user comment (gecos)"), &input_uctx->gecos); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Gecos interactive input failed.\n"); goto done; } } else { input_uctx->gecos = talloc_strdup(input_uctx, uctx->gecos); if (input_uctx->gecos == NULL) { ret = ENOMEM; goto done; } } if (uctx->home == NULL) { ret = seed_str_input(input_uctx, _("home directory"), &input_uctx->home); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Home directory interactive input fialed.\n"); goto done; } } else { input_uctx->home = talloc_strdup(input_uctx, uctx->home); if (input_uctx->home == NULL) { ret = ENOMEM; goto done; } } if (uctx->shell == NULL) { ret = seed_str_input(input_uctx, _("user login shell"), &input_uctx->shell); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Shell interactive input failed\n"); goto done; } } else { input_uctx->shell = talloc_strdup(input_uctx, uctx->shell); if (input_uctx->shell == NULL) { ret = ENOMEM; goto done; } } done: if (ret == EOK) { *_uctx = talloc_steal(mem_ctx, input_uctx); } else { ERROR("Interactive input failed.\n"); talloc_zfree(input_uctx); } return ret; } static int seed_init(TALLOC_CTX *mem_ctx, const int argc, const char **argv, struct seed_ctx **_sctx) { TALLOC_CTX *tmp_ctx = NULL; int pc_debug = SSSDBG_DEFAULT; const char *pc_domain = NULL; const char *pc_name = NULL; uid_t pc_uid = 0; gid_t pc_gid = 0; const char *pc_gecos = NULL; const char *pc_home = NULL; const char *pc_shell = NULL; const char *pc_password_file = NULL; struct seed_ctx *sctx = NULL; int ret = EOK; poptContext pc = NULL; struct poptOption options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, { "domain", 'D', POPT_ARG_STRING, &pc_domain, 0, _("Domain"), NULL }, { "username", 'n', POPT_ARG_STRING, &pc_name, 0, _("Username"), NULL}, { "uid", 'u', POPT_ARG_INT, &pc_uid, 0, _("User UID"), NULL }, { "gid", 'g', POPT_ARG_INT, &pc_gid, 0, _("User GID"), NULL }, { "gecos", 'c', POPT_ARG_STRING, &pc_gecos, 0, _("Comment string"), NULL}, { "home", 'h', POPT_ARG_STRING, &pc_home, 0, _("Home directory"), NULL }, { "shell", 's', POPT_ARG_STRING, &pc_shell, 0, _("Login Shell"), NULL }, { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', _("Use interactive mode to enter user data"), NULL }, { "password-file", 'p', POPT_ARG_STRING, &pc_password_file, 0, _("File from which user's password is read " "(default is to prompt for password)"),NULL }, POPT_TABLEEND }; /* init contexts */ tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto fini; } sctx = talloc_zero(tmp_ctx, struct seed_ctx); if (sctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate tools context\n"); ret = ENOMEM; goto fini; } sctx->uctx = talloc_zero(sctx, struct user_ctx); if (sctx->uctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not allocate user data context\n"); ret = ENOMEM; goto fini; } debug_prg_name = argv[0]; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); ret = EINVAL; goto fini; } /* parse arguments */ pc = poptGetContext(NULL, argc, argv, options, 0); if (argc < 2) { poptPrintUsage(pc,stderr,0); ret = EINVAL; goto fini; } poptSetOtherOptionHelp(pc, "[OPTIONS] -D -n "); while ((ret = poptGetNextOpt(pc)) > 0) { switch (ret) { case 'i': DEBUG(SSSDBG_TRACE_INTERNAL, "Interactive mode selected\n"); sctx->interact = true; break; } } if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } DEBUG_CLI_INIT(pc_debug); CHECK_ROOT(ret, argv[0]); /* check username provided */ if (pc_name == NULL) { BAD_POPT_PARAMS(pc, _("Username must be specified\n"), ret, fini); } sctx->uctx->name = talloc_strdup(sctx->uctx, pc_name); if (sctx->uctx->name == NULL) { ret = ENOMEM; goto fini; } /* check domain is provided */ if (pc_domain == NULL) { BAD_POPT_PARAMS(pc, _("Domain must be specified.\n"), ret, fini); } sctx->uctx->domain_name = talloc_strdup(sctx->uctx, pc_domain); if (sctx->uctx->domain_name == NULL) { ret = ENOMEM; goto fini; } poptFreeContext(pc); ret = EOK; /* copy all information provided from popt */ sctx->uctx->uid = pc_uid; sctx->uctx->gid = pc_gid; if (pc_gecos != NULL) { sctx->uctx->gecos = talloc_strdup(sctx->uctx, pc_gecos); if (sctx->uctx->gecos == NULL) { ret = ENOMEM; goto fini; } } if (pc_home != NULL) { sctx->uctx->home = talloc_strdup(sctx->uctx, pc_home); if (sctx->uctx->home == NULL) { ret = ENOMEM; goto fini; } } if (pc_shell != NULL) { sctx->uctx->shell = talloc_strdup(sctx->uctx, pc_shell); if (sctx->uctx->shell == NULL) { ret = ENOMEM; goto fini; } } /* check if password file provided */ if (pc_password_file != NULL) { sctx->password_file = talloc_strdup(sctx, pc_password_file); if (sctx->password_file == NULL) { ret = ENOMEM; goto fini; } sctx->password_method = PASS_FILE; } else { sctx->password_method = PASS_PROMPT; } *_sctx = talloc_steal(mem_ctx, sctx); fini: talloc_free(tmp_ctx); return ret; } static int seed_init_db(TALLOC_CTX *mem_ctx, const char *domain_name, struct confdb_ctx **_confdb, struct sss_domain_info **_domain, struct sysdb_ctx **_sysdb) { TALLOC_CTX *tmp_ctx = NULL; char *confdb_path = NULL; struct confdb_ctx *confdb = NULL; struct sss_domain_info *domain = NULL; int ret = EOK; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } /* setup confdb */ confdb_path = talloc_asprintf(tmp_ctx, "%s/%s", DB_PATH, CONFDB_FILE); if (confdb_path == NULL) { ret = ENOMEM; goto done; } ret = confdb_init(tmp_ctx, &confdb, confdb_path); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the confdb\n"); ERROR("Could not initialize connection to the confdb\n"); goto done; } ret = sssd_domain_init(tmp_ctx, confdb, domain_name, DB_PATH, &domain); if (ret != EOK) { SYSDB_VERSION_ERROR(ret); DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to domain '%s' in sysdb.%s\n", domain_name, ret == ENOENT ? " Domain not found." : ""); ERROR("Could not initialize connection to domain '%1$s' in sysdb.%2$s\n", domain_name, ret == ENOENT ? " Domain not found." : ""); goto done; } *_confdb = talloc_steal(mem_ctx, confdb); *_domain = domain; *_sysdb = domain->sysdb; done: talloc_free(tmp_ctx); return ret; } static int seed_domain_user_info(const char *name, const char *domain_name, struct sss_domain_info *domain, bool *is_cached) { TALLOC_CTX *tmp_ctx = NULL; char *fq_name = NULL; struct passwd *passwd = NULL; struct ldb_result *res = NULL; int ret = EOK; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } fq_name = talloc_asprintf(tmp_ctx, "%s@%s", name, domain_name); if (fq_name == NULL) { ret = ENOMEM; goto done; } errno = 0; passwd = getpwnam(fq_name); if (passwd == NULL) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "getpwnam failed [%d] [%s]\n", ret, strerror(ret)); goto done; } /* look for user in cache */ ret = sysdb_getpwnam(tmp_ctx, domain, name, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't lookup user (%s) in the cache\n", name); goto done; } if (res->count == 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "User (%s) wasn't found in the cache\n", name); *is_cached = false; ret = ENOENT; goto done; } else if (res->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Multiple user (%s) entries were found in the cache\n", name); ret = EINVAL; goto done; } else { DEBUG(SSSDBG_TRACE_INTERNAL, "User found in cache\n"); *is_cached = true; errno = 0; ret = initgroups(fq_name, passwd->pw_gid); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "initgroups failed [%d] [%s]\n", ret, strerror(ret)); goto done; } } done: if (ret == ENOMEM) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to allocate user information\n"); } talloc_zfree(tmp_ctx); return ret; } static int seed_cache_user(struct seed_ctx *sctx) { bool in_transaction = false; int ret = EOK; errno_t sret; ret = sysdb_transaction_start(sctx->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb transaction start failure\n"); goto done; } in_transaction = true; if (sctx->user_cached == false) { ret = sysdb_add_user(sctx->domain, sctx->uctx->name, sctx->uctx->uid, sctx->uctx->gid, sctx->uctx->gecos, sctx->uctx->home, sctx->uctx->shell, NULL, NULL, 0, 0); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to add user to the cache. (%d)[%s]\n", ret, strerror(ret)); ERROR("Failed to create user cache entry\n"); goto done; } } ret = sysdb_cache_password(sctx->domain, sctx->uctx->name, sctx->uctx->password); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to cache password. (%d)[%s]\n", ret, strerror(ret)); ERROR("Failed to cache password\n"); goto done; } ret = sysdb_transaction_commit(sctx->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb transaction commit failure\n"); goto done; } in_transaction = false; done: if (in_transaction == true) { sret = sysdb_transaction_cancel(sctx->sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to cancel transaction\n"); } } return ret; } int main(int argc, const char **argv) { struct seed_ctx *sctx = NULL; struct user_ctx *input_uctx = NULL; int ret = EOK; /* initialize seed context and parse options */ ret = seed_init(sctx, argc, argv, &sctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE,"Seed init failed [%d][%s]\n", ret, strerror(ret)); goto done; } /* set up confdb,sysdb and domain */ ret = seed_init_db(sctx, sctx->uctx->domain_name, &sctx->confdb, &sctx->domain, &sctx->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to initialize db and domain\n"); goto done; } /* get user info from domain */ ret = seed_domain_user_info(sctx->uctx->name, sctx->uctx->domain_name, sctx->domain, &sctx->user_cached); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed lookup of user [%s] in domain [%s]\n", sctx->uctx->name, sctx->uctx->domain_name); } /* interactive mode to fill in user information */ if (sctx->interact == true) { if (sctx->user_cached == true) { ERROR(_("User entry already exists in the cache.\n")); ret = EEXIST; goto done; } else { ret = seed_interactive_input(sctx, sctx->uctx, &input_uctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get seed input.\n"); ret = EINVAL; goto done; } talloc_zfree(sctx->uctx); sctx->uctx = input_uctx; } } if (sctx->user_cached == false) { if (sctx->uctx->uid == 0 || sctx->uctx->gid == 0) { /* require username, UID, and GID to continue */ DEBUG(SSSDBG_MINOR_FAILURE, "Not enough information provided\n"); ERROR("UID and primary GID not provided.\n"); ret = EINVAL; goto done; } } /* password input */ if (sctx->password_method == PASS_FILE) { ret = seed_password_input_file(sctx->uctx, sctx->password_file, &sctx->uctx->password); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Password input failure\n"); goto done; } } else { ret = seed_password_input_prompt(sctx->uctx, &sctx->uctx->password); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Password input failure\n"); goto done; } } /* Add user info and password to sysdb cache */ ret = seed_cache_user(sctx); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to modify cache.\n"); goto done; } else { if (sctx->user_cached == false) { printf(_("User cache entry created for %1$s\n"), sctx->uctx->name); } printf(_("Temporary password added to cache entry for %1$s\n"), sctx->uctx->name); } done: talloc_zfree(sctx); if (ret != EOK) { DEBUG(SSSDBG_TRACE_INTERNAL, "Exit error: [%d] [%s]\n", ret, strerror(ret)); ret = EXIT_FAILURE; } else { ret = EXIT_SUCCESS; } exit(ret); } sssd-1.13.4/src/tools/PaxHeaders.16287/sss_usermod.c0000644000000000000000000000007412703456111016766 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.991794771 sssd-1.13.4/src/tools/sss_usermod.c0000644002412700241270000002652412703456111020446 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_usermod Copyright (C) Jakub Hrozek 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "util/util.h" #include "db/sysdb.h" #include "tools/tools_util.h" #include "tools/sss_sync_ops.h" int main(int argc, const char **argv) { int pc_lock = 0; uid_t pc_uid = 0; gid_t pc_gid = 0; char *pc_gecos = NULL; char *pc_home = NULL; char *pc_shell = NULL; int pc_debug = SSSDBG_DEFAULT; const char *pc_selinux_user = NULL; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, { "uid", 'u', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_uid, 0, _("The UID of the user"), NULL }, { "gid", 'g', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_gid, 0, _("The GID of the user"), NULL }, { "gecos", 'c', POPT_ARG_STRING, &pc_gecos, 0, _("The comment string"), NULL }, { "home", 'h', POPT_ARG_STRING, &pc_home, 0, _("Home directory"), NULL }, { "shell", 's', POPT_ARG_STRING, &pc_shell, 0, _("Login shell"), NULL }, { "append-group", 'a', POPT_ARG_STRING, NULL, 'a', _("Groups to add this user to"), NULL }, { "remove-group", 'r', POPT_ARG_STRING, NULL, 'r', _("Groups to remove this user from"), NULL }, { "lock", 'L', POPT_ARG_NONE, NULL, 'L', _("Lock the account"), NULL }, { "unlock", 'U', POPT_ARG_NONE, NULL, 'U', _("Unlock the account"), NULL }, { "addattr", '\0', POPT_ARG_STRING, NULL, 't' , _("Add an attribute/value pair. The format is attrname=value."), NULL }, { "delattr", '\0', POPT_ARG_STRING, NULL, 'd' , _("Delete an attribute/value pair. The format is attrname=value."), NULL }, { "setattr", '\0', POPT_ARG_STRING, NULL, 's' , _("Set an attribute to a name/value pair. The format is attrname=value. For multi-valued attributes, the command replaces the values already present"), NULL }, { "selinux-user", 'Z', POPT_ARG_STRING, &pc_selinux_user, 0, _("The SELinux user for user's login"), NULL }, POPT_TABLEEND }; poptContext pc = NULL; char *addgroups = NULL, *rmgroups = NULL; char *addattr = NULL, *delattr = NULL, *setattr = NULL; int ret; errno_t sret; const char *pc_username = NULL; struct tools_ctx *tctx = NULL; char *badgroup = NULL; bool in_transaction = false; debug_prg_name = argv[0]; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); ret = EXIT_FAILURE; goto fini; } /* parse parameters */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "USERNAME"); while ((ret = poptGetNextOpt(pc)) > 0) { switch (ret) { case 'a': addgroups = poptGetOptArg(pc); if (addgroups == NULL) { BAD_POPT_PARAMS(pc, _("Specify group to add to\n"), ret, fini); } break; case 'r': rmgroups = poptGetOptArg(pc); if (rmgroups == NULL) { BAD_POPT_PARAMS(pc, _("Specify group to remove from\n"), ret, fini); } break; case 'L': pc_lock = DO_LOCK; break; case 'U': pc_lock = DO_UNLOCK; break; case 't': addattr = poptGetOptArg(pc); if (addattr == NULL) { BAD_POPT_PARAMS(pc, _("Specify the attribute name/value pair(s)\n"), ret, fini); } break; case 'd': delattr = poptGetOptArg(pc); if (delattr == NULL) { BAD_POPT_PARAMS(pc, _("Specify the attribute name/value pair(s)\n"), ret, fini); } break; case 's': setattr = poptGetOptArg(pc); if (setattr == NULL) { BAD_POPT_PARAMS(pc, _("Specify the attribute name/value pair(s)\n"), ret, fini); } break; } } if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } DEBUG_CLI_INIT(pc_debug); /* username is an argument without --option */ pc_username = poptGetArg(pc); if (pc_username == NULL) { BAD_POPT_PARAMS(pc, _("Specify user to modify\n"), ret, fini); } CHECK_ROOT(ret, debug_prg_name); ret = init_sss_tools(&tctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "init_sss_tools failed (%d): %s\n", ret, strerror(ret)); if (ret == ENOENT) { ERROR("Error initializing the tools - no local domain\n"); } else { ERROR("Error initializing the tools\n"); } ret = EXIT_FAILURE; goto fini; } /* if the domain was not given as part of FQDN, default to local domain */ ret = parse_name_domain(tctx, pc_username); if (ret != EOK) { ERROR("Invalid domain specified in FQDN\n"); ret = EXIT_FAILURE; goto fini; } /* check the username to be able to give sensible error message */ ret = sysdb_getpwnam_sync(tctx, tctx->octx->name, tctx->octx); if (ret != EOK) { ERROR("Cannot find user in local domain, " "modifying users is allowed only in local domain\n"); ret = EXIT_FAILURE; goto fini; } if (id_in_range(tctx->octx->uid, tctx->octx->domain) != EOK) { ERROR("The selected UID is outside the allowed range\n"); ret = EXIT_FAILURE; goto fini; } if (addgroups) { ret = parse_groups(tctx, addgroups, &tctx->octx->addgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse groups to add the user to\n"); ERROR("Internal error while parsing parameters\n"); ret = EXIT_FAILURE; goto fini; } ret = parse_group_name_domain(tctx, tctx->octx->addgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse FQDN groups to add the user to\n"); ERROR("Groups must be in the same domain as user\n"); ret = EXIT_FAILURE; goto fini; } /* Check group names in the LOCAL domain */ ret = check_group_names(tctx, tctx->octx->addgroups, &badgroup); if (ret != EOK) { ERROR("Cannot find group %1$s in local domain, " "only groups in local domain are allowed\n", badgroup); ret = EXIT_FAILURE; goto fini; } } if (rmgroups) { ret = parse_groups(tctx, rmgroups, &tctx->octx->rmgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse groups to remove the user from\n"); ERROR("Internal error while parsing parameters\n"); ret = EXIT_FAILURE; goto fini; } ret = parse_group_name_domain(tctx, tctx->octx->rmgroups); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot parse FQDN groups to remove the user from\n"); ERROR("Groups must be in the same domain as user\n"); ret = EXIT_FAILURE; goto fini; } /* Check group names in the LOCAL domain */ ret = check_group_names(tctx, tctx->octx->rmgroups, &badgroup); if (ret != EOK) { ERROR("Cannot find group %1$s in local domain, " "only groups in local domain are allowed\n", badgroup); ret = EXIT_FAILURE; goto fini; } } tctx->octx->gecos = pc_gecos; tctx->octx->home = pc_home; tctx->octx->shell = pc_shell; tctx->octx->uid = pc_uid; tctx->octx->gid = pc_gid; tctx->octx->lock = pc_lock; tctx->octx->addattr = addattr; tctx->octx->delattr = delattr; tctx->octx->setattr = setattr; tctx->error = sysdb_transaction_start(tctx->sysdb); if (tctx->error != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); goto done; } in_transaction = true; /* usermod */ tctx->error = usermod(tctx, tctx->octx); if (tctx->error) { goto done; } tctx->error = sysdb_transaction_commit(tctx->sysdb); if (tctx->error) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = sss_mc_refresh_user(pc_username); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); /* Nothing we can do about it */ } ret = sss_mc_refresh_grouplist(tctx, tctx->octx->addgroups); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); /* Nothing we can do about it */ } ret = sss_mc_refresh_grouplist(tctx, tctx->octx->rmgroups); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); /* Nothing we can do about it */ } /* Set SELinux login context - must be done after transaction is done * b/c libselinux calls getpwnam */ ret = set_seuser(tctx->octx->name, pc_selinux_user, NULL); if (ret != EOK) { ERROR("Cannot set SELinux login context\n"); ret = EXIT_FAILURE; goto fini; } done: if (in_transaction) { sret = sysdb_transaction_cancel(tctx->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n"); } } if (tctx->error) { ret = tctx->error; switch (ret) { case ENOENT: ERROR("Could not modify user - check if group names are correct\n"); break; case EFAULT: ERROR("Could not modify user - user already member of groups?\n"); break; default: ERROR("Transaction error. Could not modify user.\n"); break; } ret = EXIT_FAILURE; goto fini; } ret = EXIT_SUCCESS; fini: free(addgroups); free(rmgroups); poptFreeContext(pc); talloc_free(tctx); exit(ret); } sssd-1.13.4/src/tools/PaxHeaders.16287/sss_userdel.c0000644000000000000000000000007412703456111016753 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.990794768 sssd-1.13.4/src/tools/sss_userdel.c0000644002412700241270000002173512703456111020432 0ustar00jhrozekjhrozek00000000000000/* SSSD sss_userdel Copyright (C) Jakub Hrozek 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include "db/sysdb.h" #include "util/util.h" #include "util/find_uid.h" #include "tools/tools_util.h" #include "tools/sss_sync_ops.h" #ifndef KILL_CMD #define KILL_CMD "killall" #endif #ifndef KILL_CMD_USER_FLAG #define KILL_CMD_USER_FLAG "-u" #endif #ifndef KILL_CMD_SIGNAL_FLAG #define KILL_CMD_SIGNAL_FLAG "-s" #endif #ifndef KILL_CMD_SIGNAL #define KILL_CMD_SIGNAL "SIGKILL" #endif static int is_logged_in(TALLOC_CTX *mem_ctx, uid_t uid) { int ret; hash_key_t key; hash_value_t value; hash_table_t *uid_table; ret = get_uid_table(mem_ctx, &uid_table); if (ret == ENOSYS) return ret; if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot initialize hash table.\n"); return ret; } key.type = HASH_KEY_ULONG; key.ul = (unsigned long) uid; ret = hash_lookup(uid_table, &key, &value); talloc_zfree(uid_table); return ret == HASH_SUCCESS ? EOK : ENOENT; } static int kick_user(struct tools_ctx *tctx) { int ret; int status; pid_t pid, child_pid; tctx->octx->lock = 1; ret = usermod(tctx, tctx->octx); if (ret != EOK) { return ret; } errno = 0; pid = fork(); if (pid == 0) { /* child */ execlp(KILL_CMD, KILL_CMD, KILL_CMD_USER_FLAG, tctx->octx->name, KILL_CMD_SIGNAL_FLAG, KILL_CMD_SIGNAL, (char *) NULL); exit(errno); } else { /* parent */ if (pid == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d]: %s\n", ret, strerror(ret)); return ret; } while((child_pid = waitpid(pid, &status, 0)) > 0) { if (WIFEXITED(status)) { break; } } if (child_pid == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "waitpid failed\n"); return errno; } } return EOK; } int main(int argc, const char **argv) { int ret = EXIT_SUCCESS; struct tools_ctx *tctx = NULL; const char *pc_username = NULL; int pc_debug = SSSDBG_DEFAULT; int pc_remove = 0; int pc_force = 0; int pc_kick = 0; poptContext pc = NULL; struct poptOption long_options[] = { POPT_AUTOHELP { "debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug, 0, _("The debug level to run with"), NULL }, { "remove", 'r', POPT_ARG_NONE, NULL, 'r', _("Remove home directory and mail spool"), NULL }, { "no-remove", 'R', POPT_ARG_NONE, NULL, 'R', _("Do not remove home directory and mail spool"), NULL }, { "force", 'f', POPT_ARG_NONE, NULL, 'f', _("Force removal of files not owned by the user"), NULL }, { "kick", 'k', POPT_ARG_NONE, NULL, 'k', _("Kill users' processes before removing him"), NULL }, POPT_TABLEEND }; debug_prg_name = argv[0]; ret = set_locale(); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_locale failed (%d): %s\n", ret, strerror(ret)); ERROR("Error setting the locale\n"); ret = EXIT_FAILURE; goto fini; } /* parse parameters */ pc = poptGetContext(NULL, argc, argv, long_options, 0); poptSetOtherOptionHelp(pc, "USERNAME"); while ((ret = poptGetNextOpt(pc)) > 0) { switch (ret) { case 'r': pc_remove = DO_REMOVE_HOME; break; case 'R': pc_remove = DO_NOT_REMOVE_HOME; break; case 'f': pc_force = DO_FORCE_REMOVAL; break; case 'k': pc_kick = 1; break; } } DEBUG_CLI_INIT(pc_debug); if (ret != -1) { BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini); } pc_username = poptGetArg(pc); if (pc_username == NULL) { BAD_POPT_PARAMS(pc, _("Specify user to delete\n"), ret, fini); } CHECK_ROOT(ret, debug_prg_name); ret = init_sss_tools(&tctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "init_sss_tools failed (%d): %s\n", ret, strerror(ret)); if (ret == ENOENT) { ERROR("Error initializing the tools - no local domain\n"); } else { ERROR("Error initializing the tools\n"); } ret = EXIT_FAILURE; goto fini; } /* if the domain was not given as part of FQDN, default to local domain */ ret = parse_name_domain(tctx, pc_username); if (ret != EOK) { ERROR("Invalid domain specified in FQDN\n"); ret = EXIT_FAILURE; goto fini; } /* * Fills in defaults for ops_ctx user did not specify. */ ret = userdel_defaults(tctx, tctx->confdb, tctx->octx, pc_remove); if (ret != EOK) { ERROR("Cannot set default values\n"); ret = EXIT_FAILURE; goto fini; } ret = sysdb_getpwnam_sync(tctx, tctx->octx->name, tctx->octx); if (ret != EOK) { /* Error message will be printed in the switch */ goto done; } if ((tctx->octx->uid < tctx->local->id_min) || (tctx->local->id_max && tctx->octx->uid > tctx->local->id_max)) { ERROR("User %1$s is outside the defined ID range for domain\n", tctx->octx->name); ret = EXIT_FAILURE; goto fini; } if (pc_kick) { ret = kick_user(tctx); if (ret != EOK) { tctx->error = ret; goto done; } } /* userdel */ ret = userdel(tctx, tctx->sysdb, tctx->octx); if (ret != EOK) { goto done; } /* Set SELinux login context - must be done after transaction is done * b/c libselinux calls getpwnam */ ret = del_seuser(tctx->octx->name); if (ret != EOK) { ERROR("Cannot reset SELinux login context\n"); ret = EXIT_FAILURE; goto fini; } if (!pc_kick) { ret = is_logged_in(tctx, tctx->octx->uid); switch(ret) { case ENOENT: break; case EOK: ERROR("WARNING: The user (uid %1$lu) was still logged in when " "deleted.\n", (unsigned long) tctx->octx->uid); break; case ENOSYS: ERROR("Cannot determine if the user was logged in on this " "platform"); break; default: ERROR("Error while checking if the user was logged in\n"); break; } } ret = run_userdel_cmd(tctx); if (ret != EOK) { ERROR("The post-delete command failed: %1$s\n", strerror(ret)); goto fini; } /* Delete user from memory cache */ ret = sss_mc_refresh_user(pc_username); if (ret != EOK) { ERROR("NSS request failed (%1$d). Entry might remain in memory " "cache.\n", ret); /* Nothing we can do about it */ } if (tctx->octx->remove_homedir) { ret = remove_homedir(tctx, tctx->octx->home, tctx->octx->maildir, tctx->octx->name, tctx->octx->uid, pc_force); if (ret == EPERM) { ERROR("Not removing home dir - not owned by user\n"); } else if (ret != EOK) { ERROR("Cannot remove homedir: %1$s\n", strerror(ret)); ret = EXIT_FAILURE; goto fini; } } ret = EOK; done: if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb operation failed (%d)[%s]\n", ret, strerror(ret)); switch (ret) { case ENOENT: ERROR("No such user in local domain. " "Removing users only allowed in local domain.\n"); break; default: ERROR("Internal error. Could not remove user.\n"); break; } ret = EXIT_FAILURE; goto fini; } ret = EXIT_SUCCESS; fini: talloc_free(tctx); poptFreeContext(pc); exit(ret); } sssd-1.13.4/src/tools/PaxHeaders.16287/files.c0000644000000000000000000000007412703456111015522 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.645793598 sssd-1.13.4/src/tools/files.c0000644002412700241270000005055012703456111017176 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* * This file incorporates work covered by the following copyright and * permission notice: * * Copyright (c) 1991 - 1994, Julianne Frances Haugh * Copyright (c) 1996 - 2001, Marek Michałkiewicz * Copyright (c) 2003 - 2006, Tomasz Kłoczko * Copyright (c) 2007 - 2008, Nicolas François * * All rights reserved. * * 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. The name of the copyright holders or contributors may not be used to * endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT * HOLDERS 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. */ #include "config.h" #include #include #include #include #include #include #include #include "util/util.h" #include "tools/tools_util.h" struct copy_ctx { const char *src_orig; const char *dst_orig; dev_t src_dev; uid_t uid; gid_t gid; }; static int sss_timeat_set(int dir_fd, const char *path, const struct stat *statp, int flags) { int ret; #ifdef HAVE_UTIMENSAT struct timespec timebuf[2]; timebuf[0] = statp->st_atim; timebuf[1] = statp->st_mtim; ret = utimensat(dir_fd, path, timebuf, flags); #else struct timeval tv[2]; tv[0].tv_sec = statp->st_atime; tv[0].tv_usec = 0; tv[1].tv_sec = statp->st_mtime; tv[1].tv_usec = 0; ret = futimesat(dir_fd, path, tv); #endif if (ret == -1) { return errno; } return EOK; } static int sss_futime_set(int fd, const struct stat *statp) { int ret; #ifdef HAVE_FUTIMENS struct timespec timebuf[2]; timebuf[0] = statp->st_atim; timebuf[1] = statp->st_mtim; ret = futimens(fd, timebuf); #else struct timeval tv[2]; tv[0].tv_sec = statp->st_atime; tv[0].tv_usec = 0; tv[1].tv_sec = statp->st_mtime; tv[1].tv_usec = 0; ret = futimes(fd, tv); #endif if (ret == -1) { return errno; } return EOK; } /* wrapper in order not to create a temporary context in * every iteration */ static int remove_tree_with_ctx(TALLOC_CTX *mem_ctx, int parent_fd, const char *dir_name, dev_t parent_dev); int remove_tree(const char *root) { TALLOC_CTX *tmp_ctx = NULL; int ret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } ret = remove_tree_with_ctx(tmp_ctx, AT_FDCWD, root, 0); talloc_free(tmp_ctx); return ret; } /* * The context is not freed in case of error * because this is a recursive function, will be freed when we * reach the top level remove_tree() again */ static int remove_tree_with_ctx(TALLOC_CTX *mem_ctx, int parent_fd, const char *dir_name, dev_t parent_dev) { struct dirent *result; struct stat statres; DIR *rootdir = NULL; int ret, err; int dir_fd; dir_fd = sss_openat_cloexec(parent_fd, dir_name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW, &ret); if (dir_fd == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot open %s: [%d]: %s\n", dir_name, ret, strerror(ret)); return ret; } rootdir = fdopendir(dir_fd); if (rootdir == NULL) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot open directory: [%d][%s]\n", ret, strerror(ret)); close(dir_fd); goto fail; } while ((result = readdir(rootdir)) != NULL) { if (strcmp(result->d_name, ".") == 0 || strcmp(result->d_name, "..") == 0) { continue; } ret = fstatat(dir_fd, result->d_name, &statres, AT_SYMLINK_NOFOLLOW); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "stat failed: [%d][%s]\n", ret, strerror(ret)); goto fail; } if (S_ISDIR(statres.st_mode)) { /* if directory, recursively descend, but check if on the same FS */ if (parent_dev && parent_dev != statres.st_dev) { DEBUG(SSSDBG_CRIT_FAILURE, "Directory %s is on different filesystem, " "will not follow\n", result->d_name); ret = EFAULT; goto fail; } ret = remove_tree_with_ctx(mem_ctx, dir_fd, result->d_name, statres.st_dev); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Removing subdirectory failed: [%d][%s]\n", ret, strerror(ret)); goto fail; } } else { ret = unlinkat(dir_fd, result->d_name, 0); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Removing file failed: [%d][%s]\n", ret, strerror(ret)); goto fail; } } } ret = closedir(rootdir); rootdir = NULL; if (ret != 0) { ret = errno; goto fail; } ret = unlinkat(parent_fd, dir_name, AT_REMOVEDIR); if (ret == -1) { ret = errno; } ret = EOK; fail: if (rootdir) { /* clean up on abnormal exit but retain return code */ err = closedir(rootdir); if (err) { DEBUG(SSSDBG_CRIT_FAILURE, "closedir failed, bad dirp?\n"); } } return ret; } static char *talloc_readlinkat(TALLOC_CTX *mem_ctx, int dir_fd, const char *filename) { size_t size = 1024; ssize_t nchars; char *buffer; char *new_buffer; buffer = talloc_array(mem_ctx, char, size); if (!buffer) { return NULL; } while (1) { nchars = readlinkat(dir_fd, filename, buffer, size); if (nchars < 0) { talloc_free(buffer); return NULL; } if ((size_t) nchars < size) { /* The buffer was large enough */ break; } /* Try again with a bigger buffer */ size *= 2; new_buffer = talloc_realloc(mem_ctx, buffer, char, size); if (!new_buffer) { talloc_free(buffer); return NULL; } buffer = new_buffer; } /* readlink does not nul-terminate */ buffer[nchars] = '\0'; return buffer; } static int copy_symlink(int src_dir_fd, int dst_dir_fd, const char *file_name, const char *full_path, const struct stat *statp, uid_t uid, gid_t gid) { char *buf; errno_t ret; buf = talloc_readlinkat(NULL, src_dir_fd, file_name); if (!buf) { return ENOMEM; } ret = selinux_file_context(full_path); if (ret != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to set SELinux context for [%s]\n", full_path); /* Not fatal */ } ret = symlinkat(buf, dst_dir_fd, file_name); talloc_free(buf); if (ret == -1) { ret = errno; if (ret == EEXIST) { DEBUG(SSSDBG_MINOR_FAILURE, "symlink pointing to already exists at '%s'\n", full_path); return EOK; } DEBUG(SSSDBG_CRIT_FAILURE, "symlinkat failed: %s\n", strerror(ret)); return ret; } ret = fchownat(dst_dir_fd, file_name, uid, gid, AT_SYMLINK_NOFOLLOW); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fchownat failed: %s\n", strerror(ret)); return ret; } ret = sss_timeat_set(dst_dir_fd, file_name, statp, AT_SYMLINK_NOFOLLOW); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "utimensat failed [%d]: %s\n", ret, strerror(ret)); /* Do not fail */ } return EOK; } /* Copy bytes from input file descriptor ifd into file named * dst_named under directory with dest_dir_fd. Own the new file * by uid/gid */ static int copy_file(int ifd, int dest_dir_fd, const char *file_name, const char *full_path, const struct stat *statp, uid_t uid, gid_t gid) { int ofd = -1; errno_t ret; char buf[1024]; ssize_t cnt, written; ret = selinux_file_context(full_path); if (ret != 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to set SELinux context for [%s]\n", full_path); /* Not fatal */ } /* Start with absolutely restrictive permissions */ ofd = openat(dest_dir_fd, file_name, O_EXCL | O_CREAT | O_WRONLY | O_NOFOLLOW, 0); if (ofd < 0 && errno != EEXIST) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "Cannot open() destination file '%s': [%d][%s].\n", full_path, ret, strerror(ret)); goto done; } while ((cnt = sss_atomic_read_s(ifd, buf, sizeof(buf))) != 0) { if (cnt == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot read() from source file: [%d][%s].\n", ret, strerror(ret)); goto done; } errno = 0; written = sss_atomic_write_s(ofd, buf, cnt); if (written == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Cannot write() to destination file: [%d][%s].\n", ret, strerror(ret)); goto done; } if (written != cnt) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrote %zd bytes, expected %zd\n", written, cnt); goto done; } } /* Set the ownership; permissions are still * restrictive. */ ret = fchown(ofd, uid, gid); if (ret == -1 && errno != EPERM) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "Error changing owner of '%s': %s\n", full_path, strerror(ret)); goto done; } /* Set the desired mode. */ ret = fchmod(ofd, statp->st_mode); if (ret == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "Error changing owner of '%s': %s\n", full_path, strerror(ret)); goto done; } ret = sss_futime_set(ofd, statp); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_futime_set failed [%d]: %s\n", ret, strerror(ret)); /* Do not fail */ } close(ofd); ofd = -1; ret = EOK; done: if (ofd != -1) close(ofd); return ret; } static errno_t copy_dir(struct copy_ctx *cctx, int src_dir_fd, const char *src_dir_path, int dest_parent_fd, const char *dest_dir_name, const char *dest_dir_path, mode_t mode, const struct stat *src_dir_stat); static errno_t copy_entry(struct copy_ctx *cctx, int src_dir_fd, const char *src_dir_path, int dest_dir_fd, const char *dest_dir_path, const char *ent_name) { char *src_ent_path = NULL; char *dest_ent_path = NULL; int ifd = -1; errno_t ret; struct stat st; /* Build the path of the source file or directory and its * corresponding member in the new tree. */ src_ent_path = talloc_asprintf(cctx, "%s/%s", src_dir_path, ent_name); dest_ent_path = talloc_asprintf(cctx, "%s/%s", dest_dir_path, ent_name); if (!src_ent_path || !dest_ent_path) { ret = ENOMEM; goto done; } /* Open the input entry first, then we can fstat() it and be * certain that it is still the same file. O_NONBLOCK protects * us against FIFOs and perhaps side-effects of the open() of a * device file if there ever was one here, and doesn't matter * for regular files or directories. */ ifd = sss_openat_cloexec(src_dir_fd, ent_name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK, &ret); if (ifd == -1 && ret != ELOOP) { /* openat error */ DEBUG(SSSDBG_CRIT_FAILURE, "openat failed on '%s': %s\n", src_ent_path, strerror(ret)); goto done; } else if (ifd == -1 && ret == ELOOP) { /* Should be a symlink.. */ ret = fstatat(src_dir_fd, ent_name, &st, AT_SYMLINK_NOFOLLOW); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fstatat failed on '%s': %s\n", src_ent_path, strerror(ret)); goto done; } /* Handle symlinks */ ret = copy_symlink(src_dir_fd, dest_dir_fd, ent_name, dest_ent_path, &st, cctx->uid, cctx->gid); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot copy '%s' to '%s'\n", src_ent_path, dest_ent_path); } goto done; } ret = fstat(ifd, &st); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "couldn't stat '%s': %s\n", src_ent_path, strerror(ret)); goto done; } if (S_ISDIR(st.st_mode)) { /* If it's a directory, descend into it. */ ret = copy_dir(cctx, ifd, src_ent_path, dest_dir_fd, ent_name, dest_ent_path, st.st_mode & 07777, &st); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Couldn't recursively copy '%s' to '%s': %s\n", src_ent_path, dest_ent_path, strerror(ret)); goto done; } } else if (S_ISREG(st.st_mode)) { /* Copy a regular file */ ret = copy_file(ifd, dest_dir_fd, ent_name, dest_ent_path, &st, cctx->uid, cctx->gid); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Cannot copy '%s' to '%s'\n", src_ent_path, dest_ent_path); goto done; } } else { /* Is a special file */ DEBUG(SSSDBG_FUNC_DATA, "'%s' is a special file, skipping.\n", src_ent_path); } ret = EOK; done: talloc_free(src_ent_path); talloc_free(dest_ent_path); if (ifd != -1) close(ifd); return ret; } static errno_t copy_dir(struct copy_ctx *cctx, int src_dir_fd, const char *src_dir_path, int dest_parent_fd, const char *dest_dir_name, const char *dest_dir_path, mode_t mode, const struct stat *src_dir_stat) { errno_t ret; errno_t dret; int dest_dir_fd = -1; DIR *dir = NULL; struct dirent *ent; if (!dest_dir_path) { return EINVAL; } dir = fdopendir(src_dir_fd); if (dir == NULL) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Error reading '%s': %s\n", src_dir_path, strerror(ret)); goto done; } /* Create the directory. It starts owned by us (presumbaly root), with * fairly restrictive permissions that still allow us to use the * directory. * */ errno = 0; ret = mkdirat(dest_parent_fd, dest_dir_name, S_IRWXU); if (ret == -1 && errno != EEXIST) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Error reading '%s': %s\n", dest_dir_path, strerror(ret)); goto done; } dest_dir_fd = sss_openat_cloexec(dest_parent_fd, dest_dir_name, O_RDONLY | O_DIRECTORY | O_NOFOLLOW, &ret); if (dest_dir_fd == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Error opening '%s': %s\n", dest_dir_path, strerror(ret)); goto done; } while ((ent = readdir(dir)) != NULL) { /* Iterate through each item in the directory. */ /* Skip over self and parent hard links. */ if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { continue; } ret = copy_entry(cctx, src_dir_fd, src_dir_path, dest_dir_fd, dest_dir_path, ent->d_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not copy [%s] to [%s]\n", src_dir_path, dest_dir_path); goto done; } } /* Set the ownership on the directory. Permissions are still * fairly restrictive. */ ret = fchown(dest_dir_fd, cctx->uid, cctx->gid); if (ret == -1 && errno != EPERM) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "Error changing owner of '%s': %s\n", dest_dir_path, strerror(ret)); goto done; } /* Set the desired mode. Do this explicitly to preserve S_ISGID and * other bits. Do this after chown, because chown is permitted to * reset these bits. */ ret = fchmod(dest_dir_fd, mode); if (ret == -1) { ret = errno; DEBUG(SSSDBG_OP_FAILURE, "Error setting mode of '%s': %s\n", dest_dir_path, strerror(ret)); goto done; } sss_futime_set(dest_dir_fd, src_dir_stat); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_futime_set failed [%d]: %s\n", ret, strerror(ret)); /* Do not fail */ } ret = EOK; done: if (dir) { dret = closedir(dir); if (dret != 0) { dret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Failed to close directory: %s.\n", strerror(dret)); } } if (dest_dir_fd != -1) { close(dest_dir_fd); } return ret; } /* NOTE: * For several reasons, including the fact that we copy even special files * (pipes, etc) from the skeleton directory, the skeldir needs to be trusted */ int copy_tree(const char *src_root, const char *dst_root, mode_t mode_root, uid_t uid, gid_t gid) { int ret = EOK; struct copy_ctx *cctx = NULL; int fd = -1; struct stat s_src; fd = sss_open_cloexec(src_root, O_RDONLY | O_DIRECTORY, &ret); if (fd == -1) { goto fail; } ret = fstat(fd, &s_src); if (ret == -1) { ret = errno; goto fail; } cctx = talloc_zero(NULL, struct copy_ctx); if (!cctx) { ret = ENOMEM; goto fail; } cctx->src_orig = src_root; cctx->dst_orig = dst_root; cctx->src_dev = s_src.st_dev; cctx->uid = uid; cctx->gid = gid; ret = copy_dir(cctx, fd, src_root, AT_FDCWD, dst_root, dst_root, mode_root, &s_src); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "copy_dir failed: [%d][%s]\n", ret, strerror(ret)); goto fail; } fail: if (fd != -1) close(fd); reset_selinux_file_context(); talloc_free(cctx); return ret; } sssd-1.13.4/src/tools/PaxHeaders.16287/sss_sync_ops.c0000644000000000000000000000007412703456111017145 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.643793591 sssd-1.13.4/src/tools/sss_sync_ops.c0000644002412700241270000004745512703456111020633 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "db/sysdb.h" #include "tools/sss_sync_ops.h" /* Default settings for user attributes */ #define DFL_SHELL_VAL "/bin/bash" #define DFL_BASEDIR_VAL "/home" #define DFL_CREATE_HOMEDIR true #define DFL_REMOVE_HOMEDIR true #define DFL_UMASK 077 #define DFL_SKEL_DIR "/etc/skel" #define DFL_MAIL_DIR "/var/spool/mail" #define ATTR_NAME_SEP '=' #define ATTR_VAL_SEP ',' #define VAR_CHECK(var, val, attr, msg) do { \ if (var != (val)) { \ DEBUG(SSSDBG_CRIT_FAILURE, msg" attribute: %s\n", attr); \ return val; \ } \ } while(0) static int attr_name_val_split(TALLOC_CTX *mem_ctx, const char *nameval, char **_name, char ***_values, int *_nvals) { char *name; char **values; const char *vals; int nvals; TALLOC_CTX *tmp_ctx; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; vals = strchr(nameval, ATTR_NAME_SEP); if (vals == NULL) { ret = EINVAL; goto done; } name = talloc_strndup(tmp_ctx, nameval, vals-nameval); if (name == NULL) { ret = ENOMEM; goto done; } vals++; ret = split_on_separator(tmp_ctx, vals, ATTR_VAL_SEP, true, true, &values, &nvals); if (ret != EOK) { goto done; } *_name = talloc_steal(mem_ctx, name); *_values = talloc_steal(mem_ctx, values); *_nvals = nvals; ret = EOK; done: talloc_free(tmp_ctx); return ret; } static int attr_op(struct ops_ctx *octx, const char *nameval, int op) { TALLOC_CTX *tmp_ctx; errno_t ret; struct sysdb_attrs *attrs; char *name; char **vals; int nvals; int i; switch(op) { case SYSDB_MOD_ADD: case SYSDB_MOD_DEL: case SYSDB_MOD_REP: break; default: return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; attrs = sysdb_new_attrs(tmp_ctx); if (attrs == NULL) { ret = ENOMEM; goto done; } ret = attr_name_val_split(tmp_ctx, nameval, &name, &vals, &nvals); if (ret != EOK) { goto done; } for (i=0; i < nvals; i++) { ret = sysdb_attrs_add_string(attrs, name, vals[i]); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not add %s to %s\n", vals[i], name); continue; } } ret = sysdb_set_user_attr(octx->domain, octx->name, attrs, op); done: talloc_free(tmp_ctx); return ret; } /* * Generic modify groups member */ static int mod_groups_member(struct sss_domain_info *dom, char **grouplist, struct ldb_dn *member_dn, int optype) { TALLOC_CTX *tmpctx; struct ldb_dn *parent_dn; int ret; int i; tmpctx = talloc_new(NULL); if (!tmpctx) { return ENOMEM; } /* FIXME: add transaction around loop */ for (i = 0; grouplist[i]; i++) { parent_dn = sysdb_group_dn(tmpctx, dom, grouplist[i]); if (!parent_dn) { ret = ENOMEM; goto done; } ret = sysdb_mod_group_member(dom, member_dn, parent_dn, optype); if (ret) { goto done; } } ret = EOK; done: talloc_zfree(tmpctx); return ret; } #define add_to_groups(data, member_dn) \ mod_groups_member(data->domain, data->addgroups, member_dn, \ LDB_FLAG_MOD_ADD) #define remove_from_groups(data, member_dn) \ mod_groups_member(data->domain, data->rmgroups, member_dn, \ LDB_FLAG_MOD_DELETE) /* * Modify a user */ struct user_mod_state { struct sysdb_ctx *sysdb; struct sysdb_attrs *attrs; struct ldb_dn *member_dn; struct ops_ctx *data; }; static int usermod_build_attrs(TALLOC_CTX *mem_ctx, const char *gecos, const char *home, const char *shell, uid_t uid, gid_t gid, int lock, struct sysdb_attrs **_attrs) { int ret; struct sysdb_attrs *attrs; attrs = sysdb_new_attrs(mem_ctx); if (attrs == NULL) { return ENOMEM; } if (shell) { ret = sysdb_attrs_add_string(attrs, SYSDB_SHELL, shell); VAR_CHECK(ret, EOK, SYSDB_SHELL, "Could not add attribute to changeset\n"); } if (home) { ret = sysdb_attrs_add_string(attrs, SYSDB_HOMEDIR, home); VAR_CHECK(ret, EOK, SYSDB_HOMEDIR, "Could not add attribute to changeset\n"); } if (gecos) { ret = sysdb_attrs_add_string(attrs, SYSDB_GECOS, gecos); VAR_CHECK(ret, EOK, SYSDB_GECOS, "Could not add attribute to changeset\n"); } if (uid) { ret = sysdb_attrs_add_long(attrs, SYSDB_UIDNUM, uid); VAR_CHECK(ret, EOK, SYSDB_UIDNUM, "Could not add attribute to changeset\n"); } if (gid) { ret = sysdb_attrs_add_long(attrs, SYSDB_GIDNUM, gid); VAR_CHECK(ret, EOK, SYSDB_GIDNUM, "Could not add attribute to changeset\n"); } if (lock == DO_LOCK) { ret = sysdb_attrs_add_string(attrs, SYSDB_DISABLED, "true"); VAR_CHECK(ret, EOK, SYSDB_DISABLED, "Could not add attribute to changeset\n"); } if (lock == DO_UNLOCK) { /* PAM code checks for 'false' value in SYSDB_DISABLED attribute */ ret = sysdb_attrs_add_string(attrs, SYSDB_DISABLED, "false"); VAR_CHECK(ret, EOK, SYSDB_DISABLED, "Could not add attribute to changeset\n"); } *_attrs = attrs; return EOK; } /* * Public interface for modifying users */ int usermod(TALLOC_CTX *mem_ctx, struct ops_ctx *data) { struct sysdb_attrs *attrs = NULL; struct ldb_dn *member_dn = NULL; int ret; if (data->addgroups || data->rmgroups) { member_dn = sysdb_user_dn(mem_ctx, data->domain, data->name); if (!member_dn) { return ENOMEM; } } ret = usermod_build_attrs(mem_ctx, data->gecos, data->home, data->shell, data->uid, data->gid, data->lock, &attrs); if (ret != EOK) { return ret; } if (attrs->num != 0) { ret = sysdb_set_user_attr(data->domain, data->name, attrs, SYSDB_MOD_REP); if (ret) { return ret; } } if (data->rmgroups != NULL) { ret = remove_from_groups(data, member_dn); if (ret) { return ret; } } if (data->addgroups != NULL) { ret = add_to_groups(data, member_dn); if (ret) { return ret; } } if (data->addattr) { ret = attr_op(data, data->addattr, SYSDB_MOD_ADD); if (ret) { return ret; } } if (data->setattr) { ret = attr_op(data, data->setattr, SYSDB_MOD_REP); if (ret) { return ret; } } if (data->delattr) { ret = attr_op(data, data->delattr, SYSDB_MOD_DEL); if (ret) { return ret; } } flush_nscd_cache(NSCD_DB_PASSWD); flush_nscd_cache(NSCD_DB_GROUP); return EOK; } /* * Public interface for modifying groups */ int groupmod(TALLOC_CTX *mem_ctx, struct ops_ctx *data) { struct sysdb_attrs *attrs = NULL; struct ldb_dn *member_dn = NULL; int ret; if (data->addgroups || data->rmgroups) { member_dn = sysdb_group_dn(mem_ctx, data->domain, data->name); if (!member_dn) { return ENOMEM; } } if (data->gid != 0) { attrs = sysdb_new_attrs(mem_ctx); if (!attrs) { return ENOMEM; } ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, data->gid); if (ret) { return ret; } ret = sysdb_set_group_attr(data->domain, data->name, attrs, SYSDB_MOD_REP); if (ret) { return ret; } } if (data->rmgroups != NULL) { ret = remove_from_groups(data, member_dn); if (ret) { return ret; } } if (data->addgroups != NULL) { ret = add_to_groups(data, member_dn); if (ret) { return ret; } } flush_nscd_cache(NSCD_DB_GROUP); return EOK; } int userdel_defaults(TALLOC_CTX *mem_ctx, struct confdb_ctx *confdb, struct ops_ctx *data, int remove_home) { int ret; char *conf_path; bool dfl_remove_home; conf_path = talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL, data->domain->name); if (!conf_path) { return ENOMEM; } /* remove homedir on user creation? */ if (!remove_home) { ret = confdb_get_bool(confdb, conf_path, CONFDB_LOCAL_REMOVE_HOMEDIR, DFL_REMOVE_HOMEDIR, &dfl_remove_home); if (ret != EOK) { goto done; } data->remove_homedir = dfl_remove_home; } else { data->remove_homedir = (remove_home == DO_REMOVE_HOME); } /* a directory to remove mail spools from */ ret = confdb_get_string(confdb, mem_ctx, conf_path, CONFDB_LOCAL_MAIL_DIR, DFL_MAIL_DIR, &data->maildir); if (ret != EOK) { goto done; } ret = EOK; done: talloc_free(conf_path); return ret; } /* * Default values for add operations */ int useradd_defaults(TALLOC_CTX *mem_ctx, struct confdb_ctx *confdb, struct ops_ctx *data, const char *gecos, const char *homedir, const char *shell, int create_home, const char *skeldir) { int ret; char *basedir = NULL; char *conf_path = NULL; conf_path = talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL, data->domain->name); if (!conf_path) { return ENOMEM; } /* gecos */ data->gecos = talloc_strdup(mem_ctx, gecos ? gecos : data->name); if (!data->gecos) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Gecos: %s\n", data->gecos); /* homedir */ if (homedir) { data->home = talloc_strdup(data, homedir); } else { ret = confdb_get_string(confdb, mem_ctx, conf_path, CONFDB_LOCAL_DEFAULT_BASEDIR, DFL_BASEDIR_VAL, &basedir); if (ret != EOK) { goto done; } data->home = talloc_asprintf(mem_ctx, "%s/%s", basedir, data->name); } if (!data->home) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Homedir: %s\n", data->home); /* default shell */ if (!shell) { ret = confdb_get_string(confdb, mem_ctx, conf_path, CONFDB_LOCAL_DEFAULT_SHELL, DFL_SHELL_VAL, &data->shell); if (ret != EOK) { goto done; } } else { data->shell = talloc_strdup(mem_ctx, shell); if (!data->shell) { ret = ENOMEM; goto done; } } DEBUG(SSSDBG_TRACE_LIBS, "Shell: %s\n", data->shell); /* create homedir on user creation? */ if (!create_home) { ret = confdb_get_bool(confdb, conf_path, CONFDB_LOCAL_CREATE_HOMEDIR, DFL_CREATE_HOMEDIR, &data->create_homedir); if (ret != EOK) { goto done; } } else { data->create_homedir = (create_home == DO_CREATE_HOME); } DEBUG(SSSDBG_TRACE_LIBS, "Auto create homedir: %s\n", data->create_homedir?"True":"False"); /* umask to create homedirs */ ret = confdb_get_int(confdb, conf_path, CONFDB_LOCAL_UMASK, DFL_UMASK, (int *) &data->umask); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Umask: %o\n", data->umask); /* a directory to create mail spools in */ ret = confdb_get_string(confdb, mem_ctx, conf_path, CONFDB_LOCAL_MAIL_DIR, DFL_MAIL_DIR, &data->maildir); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_LIBS, "Mail dir: %s\n", data->maildir); /* skeleton dir */ if (!skeldir) { ret = confdb_get_string(confdb, mem_ctx, conf_path, CONFDB_LOCAL_SKEL_DIR, DFL_SKEL_DIR, &data->skeldir); if (ret != EOK) { goto done; } } else { data->skeldir = talloc_strdup(mem_ctx, skeldir); if (!data->skeldir) { ret = ENOMEM; goto done; } } DEBUG(SSSDBG_TRACE_LIBS, "Skeleton dir: %s\n", data->skeldir); ret = EOK; done: talloc_free(basedir); talloc_free(conf_path); return ret; } /* * Public interface for adding users */ int useradd(TALLOC_CTX *mem_ctx, struct ops_ctx *data) { int ret; ret = sysdb_add_user(data->domain, data->name, data->uid, data->gid, data->gecos, data->home, data->shell, NULL, NULL, 0, 0); if (ret) { goto done; } if (data->addgroups) { struct ldb_dn *member_dn; member_dn = sysdb_user_dn(mem_ctx, data->domain, data->name); if (!member_dn) { ret = ENOMEM; goto done; } ret = add_to_groups(data, member_dn); if (ret) { goto done; } } flush_nscd_cache(NSCD_DB_PASSWD); flush_nscd_cache(NSCD_DB_GROUP); done: return ret; } /* * Public interface for deleting users */ int userdel(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct ops_ctx *data) { struct ldb_dn *user_dn; int ret; user_dn = sysdb_user_dn(mem_ctx, data->domain, data->name); if (!user_dn) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct a user DN\n"); return ENOMEM; } ret = sysdb_delete_entry(sysdb, user_dn, false); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Removing user failed: %s (%d)\n", strerror(ret), ret); } flush_nscd_cache(NSCD_DB_PASSWD); flush_nscd_cache(NSCD_DB_GROUP); return ret; } /* * Public interface for adding groups */ int groupadd(struct ops_ctx *data) { int ret; ret = sysdb_add_group(data->domain, data->name, data->gid, NULL, 0, 0); if (ret == EOK) { flush_nscd_cache(NSCD_DB_GROUP); } return ret; } /* * Public interface for deleting groups */ int groupdel(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct ops_ctx *data) { struct ldb_dn *group_dn; int ret; group_dn = sysdb_group_dn(mem_ctx, data->domain, data->name); if (group_dn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct a group DN\n"); return ENOMEM; } ret = sysdb_delete_entry(sysdb, group_dn, false); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Removing group failed: %s (%d)\n", strerror(ret), ret); } flush_nscd_cache(NSCD_DB_GROUP); return ret; } /* * getpwnam, getgrnam and friends */ int sysdb_getpwnam_sync(TALLOC_CTX *mem_ctx, const char *name, struct ops_ctx *out) { struct ldb_result *res; const char *str; int ret; ret = sysdb_getpwnam(mem_ctx, out->domain, name, &res); if (ret) { return ret; } switch (res->count) { case 0: DEBUG(SSSDBG_CRIT_FAILURE, "No result for sysdb_getpwnam call\n"); return ENOENT; case 1: /* fill ops_ctx */ out->uid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM, 0); out->gid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GIDNUM, 0); str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); out->name = talloc_strdup(out, str); if (out->name == NULL) { return ENOMEM; } str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_GECOS, NULL); out->gecos = talloc_strdup(out, str); if (out->gecos == NULL) { return ENOMEM; } str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_HOMEDIR, NULL); out->home = talloc_strdup(out, str); if (out->home == NULL) { return ENOMEM; } str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SHELL, NULL); out->shell = talloc_strdup(out, str); if (out->shell == NULL) { return ENOMEM; } str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_DISABLED, NULL); if (str == NULL) { out->lock = DO_UNLOCK; } else { if (strcasecmp(str, "true") == 0) { out->lock = DO_LOCK; } else if (strcasecmp(str, "false") == 0) { out->lock = DO_UNLOCK; } else { /* Invalid value */ DEBUG(SSSDBG_OP_FAILURE, "Invalid value for %s attribute: %s\n", SYSDB_DISABLED, str ? str : "NULL"); return EIO; } } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "More than one result for sysdb_getpwnam call\n"); return EIO; } return EOK; } int sysdb_getgrnam_sync(TALLOC_CTX *mem_ctx, const char *name, struct ops_ctx *out) { struct ldb_result *res; const char *str; int ret; ret = sysdb_getgrnam(mem_ctx, out->domain, name, &res); if (ret) { return ret; } switch (res->count) { case 0: DEBUG(SSSDBG_CRIT_FAILURE, "No result for sysdb_getgrnam call\n"); return ENOENT; case 1: /* fill ops_ctx */ out->gid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GIDNUM, 0); str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); out->name = talloc_strdup(out, str); if (out->name == NULL) { return ENOMEM; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "More than one result for sysdb_getgrnam call\n"); return EIO; } return EOK; } sssd-1.13.4/src/tools/PaxHeaders.16287/tools_util.h0000644000000000000000000000007412703456111016622 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.580793378 sssd-1.13.4/src/tools/tools_util.h0000644002412700241270000000700712703456111020275 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Simo Sorce Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __TOOLS_UTIL_H__ #define __TOOLS_UTIL_H__ #include #include "util/util.h" #define SSSD_PIDFILE ""PID_PATH"/sssd.pid" #define MAX_PID_LENGTH 10 #define BAD_POPT_PARAMS(pc, msg, val, label) do { \ usage(pc, msg); \ val = EXIT_FAILURE; \ goto label; \ } while(0) #define CHECK_ROOT(val, prg_name) do { \ val = getuid(); \ if (val != 0) { \ DEBUG(SSSDBG_CRIT_FAILURE, "Running under %d, must be root\n", val); \ ERROR("%1$s must be run as root\n", prg_name); \ val = EXIT_FAILURE; \ goto fini; \ } \ } while(0) struct tools_ctx { struct confdb_ctx *confdb; struct sysdb_ctx *sysdb; struct sss_names_ctx *snctx; struct sss_domain_info *local; struct ops_ctx *octx; bool transaction_done; int error; }; int init_sss_tools(struct tools_ctx **_tctx); void usage(poptContext pc, const char *error); int set_locale(void); int parse_name_domain(struct tools_ctx *tctx, const char *fullname); int id_in_range(uint32_t id, struct sss_domain_info *dom); int parse_groups(TALLOC_CTX *mem_ctx, const char *optstr, char ***_out); int parse_group_name_domain(struct tools_ctx *tctx, char **groups); int check_group_names(struct tools_ctx *tctx, char **grouplist, char **badgroup); int create_homedir(const char *skeldir, const char *homedir, uid_t uid, gid_t gid, mode_t default_umask); int create_mail_spool(TALLOC_CTX *mem_ctx, const char *username, const char *maildir, uid_t uid, gid_t gid); int remove_homedir(TALLOC_CTX *mem_ctx, const char *homedir, const char *maildir, const char *username, uid_t uid, bool force); int run_userdel_cmd(struct tools_ctx *tctx); errno_t signal_sssd(int signum); /* tools_mc_util.c */ errno_t sss_memcache_invalidate(const char *mc_filename); errno_t sss_memcache_clear_all(void); errno_t sss_mc_refresh_user(const char *username); errno_t sss_mc_refresh_group(const char *groupname); errno_t sss_mc_refresh_grouplist(struct tools_ctx *tctx, char **groupnames); /* from files.c */ int remove_tree(const char *root); int copy_tree(const char *src_root, const char *dst_root, mode_t mode_root, uid_t uid, gid_t gid); /* from selinux.c */ int selinux_file_context(const char *dst_name); int reset_selinux_file_context(void); #endif /* __TOOLS_UTIL_H__ */ sssd-1.13.4/src/tools/PaxHeaders.16287/sss_override.c0000644000000000000000000000007412703456111017127 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.980794734 sssd-1.13.4/src/tools/sss_override.c0000644002412700241270000014733112703456111020607 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "db/sysdb.h" #include "tools/common/sss_tools.h" #include "tools/common/sss_colondb.h" #define LOCALVIEW SYSDB_LOCAL_VIEW_NAME #define ORIGNAME "originalName" struct override_user { const char *input_name; const char *orig_name; struct sss_domain_info *domain; const char *name; uid_t uid; gid_t gid; const char *home; const char *shell; const char *gecos; }; struct override_group { const char *input_name; const char *orig_name; struct sss_domain_info *domain; const char *name; gid_t gid; }; static int parse_cmdline(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, struct poptOption *options, const char **_input_name, const char **_orig_name, struct sss_domain_info **_domain) { enum sss_tool_opt require; const char *input_name; const char *orig_name; struct sss_domain_info *domain; int ret; require = options == NULL ? SSS_TOOL_OPT_OPTIONAL : SSS_TOOL_OPT_REQUIRED; ret = sss_tool_popt_ex(cmdline, options, require, NULL, NULL, "NAME", _("Specify name."), &input_name); if (ret != EXIT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command arguments\n"); return ret; } ret = sss_tool_parse_name(tool_ctx, tool_ctx, input_name, &orig_name, &domain); if (ret != EOK) { fprintf(stderr, _("Unable to parse name %s.\n"), input_name); return ret; } *_input_name = input_name; *_orig_name = orig_name; *_domain = domain; return EXIT_SUCCESS; } static int parse_cmdline_user_add(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, struct override_user *user) { struct poptOption options[] = { {"name", 'n', POPT_ARG_STRING, &user->name, 0, _("Override name"), NULL }, {"uid", 'u', POPT_ARG_INT, &user->uid, 0, _("Override uid (non-zero value)"), NULL }, {"gid", 'g', POPT_ARG_INT, &user->gid, 0, _("Override gid (non-zero value)"), NULL }, {"home", 'h', POPT_ARG_STRING, &user->home, 0, _("Override home directory"), NULL }, {"shell", 's', POPT_ARG_STRING, &user->shell, 0, _("Override shell"), NULL }, {"gecos", 'c', POPT_ARG_STRING, &user->gecos, 0, _("Override gecos"), NULL }, POPT_TABLEEND }; return parse_cmdline(cmdline, tool_ctx, options, &user->input_name, &user->orig_name, &user->domain); } static int parse_cmdline_user_del(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, struct override_user *user) { return parse_cmdline(cmdline, tool_ctx, NULL, &user->input_name, &user->orig_name, &user->domain); } static int parse_cmdline_user_show(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, struct override_user *user) { return parse_cmdline(cmdline, tool_ctx, NULL, &user->input_name, &user->orig_name, &user->domain); } static int parse_cmdline_group_add(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, struct override_group *group) { struct poptOption options[] = { {"name", 'n', POPT_ARG_STRING, &group->name, 0, _("Override name"), NULL }, {"gid", 'g', POPT_ARG_INT, &group->gid, 0, _("Override gid"), NULL }, POPT_TABLEEND }; return parse_cmdline(cmdline, tool_ctx, options, &group->input_name, &group->orig_name, &group->domain); } static int parse_cmdline_group_del(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, struct override_group *group) { return parse_cmdline(cmdline, tool_ctx, NULL, &group->input_name, &group->orig_name, &group->domain); } static int parse_cmdline_group_show(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, struct override_group *group) { return parse_cmdline(cmdline, tool_ctx, NULL, &group->input_name, &group->orig_name, &group->domain); } static int parse_cmdline_find(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, struct sss_domain_info **_dom) { struct sss_domain_info *dom; const char *domname = NULL; int ret; struct poptOption options[] = { {"domain", 'd', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &domname, 0, _("Domain name"), NULL }, POPT_TABLEEND }; ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, NULL, NULL, NULL); if (ret != EXIT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command arguments\n"); return ret; } if (domname == NULL) { *_dom = NULL; return EXIT_SUCCESS; } dom = find_domain_by_name(tool_ctx->domains, domname, true); if (dom == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to find domain %s\n", domname); fprintf(stderr, _("Unable to find domain %s\n"), domname); return EXIT_FAILURE; } *_dom = dom; return EXIT_SUCCESS; } static int parse_cmdline_import(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, const char **_file) { int ret; ret = sss_tool_popt_ex(cmdline, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "FILE", "File to import the data from.", _file); if (ret != EXIT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command arguments\n"); return ret; } return EXIT_SUCCESS; } static int parse_cmdline_export(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, const char **_file) { int ret; ret = sss_tool_popt_ex(cmdline, NULL, SSS_TOOL_OPT_OPTIONAL, NULL, NULL, "FILE", "File to export the data to.", _file); if (ret != EXIT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command arguments\n"); return ret; } return EXIT_SUCCESS; } static errno_t prepare_view(struct sss_domain_info *domain) { char *viewname = NULL; errno_t ret; ret = sysdb_get_view_name(NULL, domain->sysdb, &viewname); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_view_name() failed.\n"); return ret; } if (ret == EOK) { if (is_local_view(viewname)) { DEBUG(SSSDBG_TRACE_FUNC, "%s view is already present.\n", viewname); ret = EOK; goto done; } else if (viewname != NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "There already exists view %s. " "Only one view is supported. Nothing to do.\n", viewname); ret = EEXIST; goto done; } } DEBUG(SSSDBG_TRACE_FUNC, "Creating %s view.\n", LOCALVIEW); ret = sysdb_update_view_name(domain->sysdb, LOCALVIEW); if (ret == EOK) { printf("SSSD needs to be restarted for the changes to take effect.\n"); } done: talloc_free(viewname); return ret; } errno_t prepare_view_msg(struct sss_domain_info *domain) { errno_t ret; ret = prepare_view(domain); if (ret == EEXIST) { fprintf(stderr, _("Other than " LOCALVIEW " view already exist " "in domain %s.\n"), domain->name); } else if (ret != EOK) { fprintf(stderr, _("Unable to prepare " LOCALVIEW " view in domain %s.\n"), domain->name); } return ret; } static char *build_anchor(TALLOC_CTX *mem_ctx, const char *obj_dn) { char *anchor; char *safe_dn; errno_t ret; ret = sysdb_dn_sanitize(mem_ctx, obj_dn, &safe_dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_dn_sanitize() failed\n"); return NULL; } anchor = talloc_asprintf(mem_ctx, ":%s:%s", LOCALVIEW, safe_dn); talloc_free(safe_dn); return anchor; } static struct sysdb_attrs *build_attrs(TALLOC_CTX *mem_ctx, const char *name, uid_t uid, gid_t gid, const char *home, const char *shell, const char *gecos) { struct sysdb_attrs *attrs; errno_t ret; attrs = sysdb_new_attrs(mem_ctx); if (attrs == NULL) { return NULL; } if (name != NULL) { ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, name); if (ret != EOK) { goto done; } } if (uid != 0) { ret = sysdb_attrs_add_uint32(attrs, SYSDB_UIDNUM, uid); if (ret != EOK) { goto done; } } if (gid != 0) { ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid); if (ret != EOK) { goto done; } } if (home != NULL) { ret = sysdb_attrs_add_string(attrs, SYSDB_HOMEDIR, home); if (ret != EOK) { goto done; } } if (shell != NULL) { ret = sysdb_attrs_add_string(attrs, SYSDB_SHELL, shell); if (ret != EOK) { goto done; } } if (gecos != NULL) { ret = sysdb_attrs_add_string(attrs, SYSDB_GECOS, gecos); if (ret != EOK) { goto done; } } ret = EOK; done: if (ret != EOK) { talloc_free(attrs); return NULL; } return attrs; } static struct sysdb_attrs *build_user_attrs(TALLOC_CTX *mem_ctx, struct override_user *user) { return build_attrs(mem_ctx, user->name, user->uid, user->gid, user->home, user->shell, user->gecos); } static struct sysdb_attrs *build_group_attrs(TALLOC_CTX *mem_ctx, struct override_group *group) { return build_attrs(mem_ctx, group->name, 0, group->gid, 0, NULL, NULL); } static char *get_fqname(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name) { char *fqname; int fqlen; int check; char *dummy_domain = NULL; int ret; if (domain == NULL || domain->names == NULL) { return NULL; } /* check if the name already contains domain part */ ret = sss_parse_name(mem_ctx, domain->names, name, &dummy_domain, NULL); if (ret == ERR_REGEX_NOMATCH) { DEBUG(SSSDBG_TRACE_FUNC, "sss_parse_name could not parse domain from [%s]. " "Assuming it is not FQDN.\n", name); } else if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "sss_parse_name failed [%d]: %s\n", ret, sss_strerror(ret)); return NULL; } if (dummy_domain != NULL) { talloc_free(dummy_domain); DEBUG(SSSDBG_TRACE_FUNC, "Name is already fully qualified.\n"); fqname = talloc_strdup(mem_ctx, name); if (fqname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); return NULL; } return fqname; } /* Get length. */ fqlen = sss_fqname(NULL, 0, domain->names, domain, name); if (fqlen > 0) { fqlen++; /* \0 */ } else { return NULL; } fqname = talloc_zero_array(mem_ctx, char, fqlen); if (fqname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); return NULL; } check = sss_fqname(fqname, fqlen, domain->names, domain, name); if (check < 0 || check != fqlen - 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate a fully qualified name " "for user [%s] in [%s]! Skipping user.\n", name, domain->name); talloc_free(fqname); return NULL; } return fqname; } static char *get_sysname(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name) { if (domain == NULL || !domain->fqnames) { return talloc_strdup(mem_ctx, name); } return get_fqname(mem_ctx, domain, name); } static struct sss_domain_info * get_object_domain(enum sysdb_member_type type, const char *name, struct sss_domain_info *domain, struct sss_domain_info *domains) { TALLOC_CTX *tmp_ctx; struct sss_domain_info *dom; struct ldb_result *res; const char *strtype; char *sysname; bool check_next; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NULL; } sysname = get_sysname(tmp_ctx, domain, name); if (sysname == NULL) { ret = ENOMEM; goto done; } /* Ensure that the object is in cache. */ switch (type) { case SYSDB_MEMBER_USER: if (getpwnam(sysname) == NULL) { ret = ENOENT; goto done; } break; case SYSDB_MEMBER_GROUP: if (getgrnam(sysname) == NULL) { ret = ENOENT; goto done; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported member type %d\n", type); ret = ERR_INTERNAL; goto done; } /* Find domain if it is unknown. */ if (domain == NULL) { check_next = true; dom = domains; } else { check_next = false; dom = domain; } do { switch (type) { case SYSDB_MEMBER_USER: DEBUG(SSSDBG_TRACE_FUNC, "Trying to find user %s@%s\n", name, dom->name); ret = sysdb_getpwnam(tmp_ctx, dom, name, &res); strtype = "user"; break; case SYSDB_MEMBER_GROUP: DEBUG(SSSDBG_TRACE_FUNC, "Trying to find group %s@%s\n", name, dom->name); ret = sysdb_getgrnam(tmp_ctx, dom, name, &res); strtype = "group"; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported member type %d\n", type); ret = ERR_INTERNAL; goto done; } if (ret == EOK && res->count == 0) { ret = ENOENT; if (check_next) { dom = dom->next; continue; } } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to find %s %s@%s [%d]: %s\n", strtype, name, dom->name, ret, sss_strerror(ret)); goto done; } else if (res->count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "More than one %s found?\n", strtype); ret = ERR_INTERNAL; goto done; } check_next = false; } while (check_next && dom != NULL); if (dom == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No domain match for %s\n", name); ret = ENOENT; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Domain of %s %s is %s\n", strtype, name, dom->name); done: talloc_free(tmp_ctx); if (ret != EOK) { return NULL; } return dom; } static errno_t get_user_domain_msg(struct sss_tool_ctx *tool_ctx, struct override_user *user) { struct sss_domain_info *newdom; const char *domname; newdom = get_object_domain(SYSDB_MEMBER_USER, user->orig_name, user->domain, tool_ctx->domains); if (newdom == NULL) { domname = user->domain == NULL ? "[unknown]" : user->domain->name; fprintf(stderr, _("Unable to find user %s@%s.\n"), user->orig_name, domname); return ENOENT; } user->domain = newdom; return EOK; } static errno_t get_group_domain_msg(struct sss_tool_ctx *tool_ctx, struct override_group *group) { struct sss_domain_info *newdom; const char *domname; newdom = get_object_domain(SYSDB_MEMBER_GROUP, group->orig_name, group->domain, tool_ctx->domains); if (newdom == NULL) { domname = group->domain == NULL ? "[unknown]" : group->domain->name; fprintf(stderr, _("Unable to find group %s@%s.\n"), group->orig_name, domname); return ENOENT; } group->domain = newdom; return EOK; } static errno_t get_object_dn(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, enum sysdb_member_type type, const char *name, struct ldb_dn **_ldb_dn, const char **_str_dn) { TALLOC_CTX *tmp_ctx; struct ldb_dn *ldb_dn; const char *str_dn; errno_t ret; struct ldb_result *res; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } switch (type) { case SYSDB_MEMBER_USER: ret = sysdb_getpwnam(tmp_ctx, domain, name, &res); break; case SYSDB_MEMBER_GROUP: ret = sysdb_getgrnam(tmp_ctx, domain, name, &res); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported member type %d\n", type); ret = ERR_INTERNAL; goto done; } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to look up original object in cache.\n"); goto done; } if (res->count == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Original object not found in cache.\n"); ret = ENOENT; goto done; } else if (res->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "There are multiple object with name [%s] in the cache.\n", name); ret = EINVAL; goto done; } ldb_dn = res->msgs[0]->dn; if (ldb_dn == NULL) { ret = ENOMEM; goto done; } if (_str_dn != NULL) { str_dn = talloc_strdup(tmp_ctx, ldb_dn_get_linearized(ldb_dn)); if (str_dn == NULL) { ret = ENOMEM; goto done; } *_str_dn = talloc_steal(mem_ctx, str_dn); } if (_ldb_dn != NULL) { *_ldb_dn = talloc_steal(mem_ctx, ldb_dn); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t override_object_add(struct sss_domain_info *domain, enum sysdb_member_type type, struct sysdb_attrs *attrs, const char *name) { TALLOC_CTX *tmp_ctx; const char *anchor; struct ldb_dn *ldb_dn; const char *str_dn; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = get_object_dn(tmp_ctx, domain, type, name, &ldb_dn, &str_dn); if (ret != EOK) { goto done; } anchor = build_anchor(tmp_ctx, str_dn); if (anchor == NULL) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_OVERRIDE_ANCHOR_UUID, anchor); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Creating override for %s\n", str_dn); ret = sysdb_store_override(domain, LOCALVIEW, type, attrs, ldb_dn); done: talloc_free(tmp_ctx); return ret; } static errno_t override_fqn(TALLOC_CTX *mem_ctx, struct sss_tool_ctx *tool_ctx, struct sss_domain_info *domain, const char *input, const char **_name) { struct sss_domain_info *dom; errno_t ret; if (input == NULL) { return EOK; } ret = sss_tool_parse_name(mem_ctx, tool_ctx, input, _name, &dom); if (ret == EAGAIN) { DEBUG(SSSDBG_OP_FAILURE, "Unable to find domain from " "fqn %s\n", input); fprintf(stderr, _("Changing domain is not allowed!\n")); ret = EINVAL; } else if (ret == EOK && dom != NULL && dom != domain) { DEBUG(SSSDBG_OP_FAILURE, "Trying to change domain from " "%s to %s, not allowed!\n", domain->name, dom->name); fprintf(stderr, _("Changing domain is not allowed!\n")); ret = EINVAL; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name %s [%d]: %s\n", input, ret, sss_strerror(ret)); } return ret; } static errno_t override_user(struct sss_tool_ctx *tool_ctx, struct override_user *input_user) { TALLOC_CTX *tmp_ctx; struct override_user user; struct sysdb_attrs *attrs; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } user = *input_user; /* We need to parse the name and ensure that domain did not change. */ ret = override_fqn(tmp_ctx, tool_ctx, user.domain, user.name, &user.name); if (ret != EOK) { goto done; } ret = prepare_view_msg(user.domain); if (ret != EOK) { goto done; } attrs = build_user_attrs(tool_ctx, &user); if (attrs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build sysdb attrs.\n"); ret = ENOMEM; goto done; } ret = override_object_add(user.domain, SYSDB_MEMBER_USER, attrs, user.orig_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add override object.\n"); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t override_group(struct sss_tool_ctx *tool_ctx, struct override_group *input_group) { TALLOC_CTX *tmp_ctx; struct override_group group; struct sysdb_attrs *attrs; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } group = *input_group; /* We need to parse the name and ensure that domain did not change. */ ret = override_fqn(tmp_ctx, tool_ctx, group.domain, group.name, &group.name); if (ret != EOK) { goto done; } ret = prepare_view_msg(group.domain); if (ret != EOK) { goto done; } attrs = build_group_attrs(tool_ctx, &group); if (attrs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build sysdb attrs.\n"); ret = ENOMEM; goto done; } ret = override_object_add(group.domain, SYSDB_MEMBER_GROUP, attrs, group.orig_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add override object.\n"); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t override_object_del(struct sss_domain_info *domain, enum sysdb_member_type type, const char *name) { TALLOC_CTX *tmp_ctx; struct ldb_message *msg; struct ldb_dn *override_dn; struct ldb_dn *ldb_dn; const char *str_dn; const char *anchor; errno_t ret; int sret; bool in_transaction = false; struct ldb_context *ldb = sysdb_ctx_get_ldb(domain->sysdb); tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = get_object_dn(tmp_ctx, domain, type, name, &ldb_dn, &str_dn); if (ret != EOK) { goto done; } anchor = build_anchor(tmp_ctx, str_dn); if (anchor == NULL) { ret = ENOMEM; goto done; } override_dn = ldb_dn_new_fmt(tmp_ctx, ldb, SYSDB_TMPL_OVERRIDE, anchor, LOCALVIEW); if (override_dn == NULL) { ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Removing override for %s\n", str_dn); ret = sysdb_transaction_start(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_start() failed.\n"); goto done; } in_transaction = true; ret = sysdb_delete_entry(domain->sysdb, override_dn, true); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_delete_entry() failed.\n"); goto done; } msg = ldb_msg_new(tmp_ctx); if (msg == NULL) { ret = ENOMEM; goto done; } msg->dn = talloc_steal(msg, ldb_dn); if (msg->dn == NULL) { ret = ENOMEM; goto done; } ret = ldb_msg_add_empty(msg, SYSDB_OVERRIDE_DN, LDB_FLAG_MOD_DELETE, NULL); if (ret != LDB_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty() failed\n"); ret = sysdb_error_to_errno(ret); goto done; } ret = ldb_modify(ldb, msg); if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { DEBUG(SSSDBG_OP_FAILURE, "ldb_modify() failed: [%s](%d)[%s]\n", ldb_strerror(ret), ret, ldb_errstring(ldb)); ret = sysdb_error_to_errno(ret); goto done; } ret = sysdb_transaction_commit(domain->sysdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = sysdb_transaction_cancel(domain->sysdb); if (sret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n"); } } talloc_free(tmp_ctx); return ret; } static errno_t append_name(struct sss_domain_info *domain, struct ldb_message *override) { TALLOC_CTX *tmp_ctx; struct ldb_context *ldb = sysdb_ctx_get_ldb(domain->sysdb); struct ldb_dn *dn; struct ldb_message **msgs; const char *attrs[] = {SYSDB_NAME, NULL}; const char *name; const char *fqname; size_t count; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n"); return ENOMEM; } dn = ldb_msg_find_attr_as_dn(ldb, tmp_ctx, override, SYSDB_OVERRIDE_OBJECT_DN); if (dn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing overrideObjectDN?\n"); ret = ERR_INTERNAL; goto done; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, dn, LDB_SCOPE_BASE, NULL, attrs, &count, &msgs); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_search_entry() failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } else if (count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "More than one user found?\n"); ret = ERR_INTERNAL; goto done; } name = ldb_msg_find_attr_as_string(msgs[0], SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Object with no name?\n"); ret = ERR_INTERNAL; goto done; } fqname = get_fqname(tmp_ctx, domain, name); if (fqname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get fqname\n"); ret = ENOMEM; goto done; } ret = ldb_msg_add_string(override, ORIGNAME, fqname); if (ret != LDB_SUCCESS) { ret = sysdb_error_to_errno(ret); DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add attribute to msg\n"); goto done; } talloc_steal(override, fqname); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t list_overrides(TALLOC_CTX *mem_ctx, const char *base_filter, const char *ext_filter, const char **attrs, struct sss_domain_info *domain, size_t *_count, struct ldb_message ***_msgs) { TALLOC_CTX *tmp_ctx; struct ldb_dn *dn; struct ldb_context *ldb = sysdb_ctx_get_ldb(domain->sysdb); size_t count; struct ldb_message **msgs; const char *filter; size_t i; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n"); return ENOMEM; } filter = base_filter; if (ext_filter != NULL) { filter = talloc_asprintf(tmp_ctx, "(&%s%s)", filter, ext_filter); if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed.\n"); ret = ENOMEM; goto done; } } /* Acquire list of override objects. */ dn = ldb_dn_new_fmt(tmp_ctx, ldb, SYSDB_TMPL_VIEW_SEARCH_BASE, LOCALVIEW); if (dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt() failed.\n"); ret = EIO; goto done; } ret = sysdb_search_entry(tmp_ctx, domain->sysdb, dn, LDB_SCOPE_SUBTREE, filter, attrs, &count, &msgs); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_search_entry() failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } /* Amend messages with original name. */ for (i = 0; i < count; i++) { ret = append_name(domain, msgs[i]); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to append name [%d]: %s\n", ret, sss_strerror(ret)); goto done; } } *_msgs = talloc_steal(mem_ctx, msgs); *_count = count; ret = EOK; done: talloc_free(tmp_ctx); return ret; } static struct override_user * list_user_overrides(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *filter) { TALLOC_CTX *tmp_ctx; struct override_user *objs; struct ldb_message **msgs; size_t count; size_t i; errno_t ret; const char *attrs[] = SYSDB_PW_ATTRS; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n"); return NULL; } ret = list_overrides(tmp_ctx, "(objectClass=" SYSDB_OVERRIDE_USER_CLASS ")", filter, attrs, domain, &count, &msgs); if (ret != EOK) { goto done; } objs = talloc_zero_array(tmp_ctx, struct override_user, count + 1); if (objs == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < count; i++) { objs[i].orig_name = ldb_msg_find_attr_as_string(msgs[i], ORIGNAME, NULL); if (objs[i].orig_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing name?!\n"); ret = ERR_INTERNAL; goto done; } objs[i].name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL); objs[i].uid = ldb_msg_find_attr_as_uint(msgs[i], SYSDB_UIDNUM, 0); objs[i].gid = ldb_msg_find_attr_as_uint(msgs[i], SYSDB_GIDNUM, 0); objs[i].home = ldb_msg_find_attr_as_string(msgs[i], SYSDB_HOMEDIR, NULL); objs[i].shell = ldb_msg_find_attr_as_string(msgs[i], SYSDB_SHELL, NULL); objs[i].gecos = ldb_msg_find_attr_as_string(msgs[i], SYSDB_GECOS, NULL); talloc_steal(objs, objs[i].orig_name); talloc_steal(objs, objs[i].name); talloc_steal(objs, objs[i].home); talloc_steal(objs, objs[i].shell); talloc_steal(objs, objs[i].gecos); } talloc_steal(mem_ctx, objs); done: talloc_free(tmp_ctx); if (ret != EOK) { return NULL; } return objs; } static struct override_group * list_group_overrides(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *filter) { TALLOC_CTX *tmp_ctx; struct override_group *objs; struct ldb_message **msgs; size_t count; size_t i; errno_t ret; const char *attrs[] = SYSDB_GRSRC_ATTRS; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n"); return NULL; } ret = list_overrides(tmp_ctx, "(objectClass=" SYSDB_OVERRIDE_GROUP_CLASS ")", filter, attrs, domain, &count, &msgs); if (ret != EOK) { goto done; } objs = talloc_zero_array(tmp_ctx, struct override_group, count + 1); if (objs == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < count; i++) { objs[i].orig_name = ldb_msg_find_attr_as_string(msgs[i], ORIGNAME, NULL); if (objs[i].orig_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing name?!\n"); ret = ERR_INTERNAL; goto done; } objs[i].name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL); objs[i].gid = ldb_msg_find_attr_as_uint(msgs[i], SYSDB_GIDNUM, 0); talloc_steal(objs, objs[i].orig_name); talloc_steal(objs, objs[i].name); } talloc_steal(mem_ctx, objs); done: talloc_free(tmp_ctx); if (ret != EOK) { return NULL; } return objs; } static errno_t user_export(const char *filename, struct sss_domain_info *dom, bool iterate, const char *filter) { TALLOC_CTX *tmp_ctx; struct sss_colondb *db; struct override_user *objs; errno_t ret; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } db = sss_colondb_open(tmp_ctx, SSS_COLONDB_WRITE, filename); if (db == NULL) { fprintf(stderr, _("Unable to open %s.\n"), filename == NULL ? "stdout" : filename); ret = EIO; goto done; } do { objs = list_user_overrides(tmp_ctx, dom, filter); if (objs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get override objects\n"); ret = ENOMEM; goto done; } for (i = 0; objs[i].orig_name != NULL; i++) { /** * Format: orig_name:name:uid:gid:gecos:home:shell */ struct sss_colondb_write_field table[] = { {SSS_COLONDB_STRING, {.str = objs[i].orig_name}}, {SSS_COLONDB_STRING, {.str = objs[i].name}}, {SSS_COLONDB_UINT32, {.uint32 = objs[i].uid}}, {SSS_COLONDB_UINT32, {.uint32 = objs[i].gid}}, {SSS_COLONDB_STRING, {.str = objs[i].gecos}}, {SSS_COLONDB_STRING, {.str = objs[i].home}}, {SSS_COLONDB_STRING, {.str = objs[i].shell}}, {SSS_COLONDB_SENTINEL, {0}} }; ret = sss_colondb_writeline(db, table); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to write line to db\n"); goto done; } } /* All overrides are under the same subtree, so we don't want to * descent into subdomains. */ dom = get_next_domain(dom, false); } while (dom != NULL && iterate); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t group_export(const char *filename, struct sss_domain_info *dom, bool iterate, const char *filter) { TALLOC_CTX *tmp_ctx; struct sss_colondb *db; struct override_group *objs; errno_t ret; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } db = sss_colondb_open(tmp_ctx, SSS_COLONDB_WRITE, filename); if (db == NULL) { fprintf(stderr, _("Unable to open %s.\n"), filename == NULL ? "stdout" : filename); ret = EIO; goto done; } do { objs = list_group_overrides(tmp_ctx, dom, filter); if (objs == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get override objects\n"); ret = ENOMEM; goto done; } for (i = 0; objs[i].orig_name != NULL; i++) { /** * Format: orig_name:name:gid */ struct sss_colondb_write_field table[] = { {SSS_COLONDB_STRING, {.str = objs[i].orig_name}}, {SSS_COLONDB_STRING, {.str = objs[i].name}}, {SSS_COLONDB_UINT32, {.uint32 = objs[i].gid}}, {SSS_COLONDB_SENTINEL, {0}} }; ret = sss_colondb_writeline(db, table); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to write line to db\n"); goto done; } } /* All overrides are under the same subtree, so we don't want to * descent into subdomains. */ dom = get_next_domain(dom, false); } while (dom != NULL && iterate); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static int override_user_add(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { struct override_user user = {NULL}; int ret; ret = parse_cmdline_user_add(cmdline, tool_ctx, &user); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); return EXIT_FAILURE; } ret = get_user_domain_msg(tool_ctx, &user); if (ret != EOK) { return EXIT_FAILURE; } ret = override_user(tool_ctx, &user); if (ret != EOK) { return EXIT_FAILURE; } return EXIT_SUCCESS; } static int override_user_del(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { struct override_user user = {NULL}; int ret; ret = parse_cmdline_user_del(cmdline, tool_ctx, &user); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); return EXIT_FAILURE; } ret = get_user_domain_msg(tool_ctx, &user); if (ret != EOK) { return EXIT_FAILURE; } ret = override_object_del(user.domain, SYSDB_MEMBER_USER, user.orig_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to delete override object.\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } static int override_user_find(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { struct sss_domain_info *dom; bool iterate; errno_t ret; ret = parse_cmdline_find(cmdline, tool_ctx, &dom); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); return EXIT_FAILURE; } if (dom == NULL) { dom = tool_ctx->domains; iterate = true; } else { iterate = false; } ret = user_export(NULL, dom, iterate, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to export users\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } static int override_user_show(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { TALLOC_CTX *tmp_ctx; struct override_user input = {NULL}; const char *dn; char *anchor; const char *filter; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n"); return EXIT_FAILURE; } ret = parse_cmdline_user_show(cmdline, tool_ctx, &input); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); goto done; } ret = get_user_domain_msg(tool_ctx, &input); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get object domain\n"); goto done; } ret = get_object_dn(tmp_ctx, input.domain, SYSDB_MEMBER_USER, input.orig_name, NULL, &dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get object dn\n"); goto done; } anchor = build_anchor(tmp_ctx, dn); if (anchor == NULL) { ret = ENOMEM; goto done; } ret = sss_filter_sanitize(tmp_ctx, anchor, &anchor); if (ret != EOK) { ret = ENOMEM; goto done; } filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_OVERRIDE_ANCHOR_UUID, anchor); if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n"); ret = ENOMEM; goto done; } ret = user_export(NULL, input.domain, false, filter); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to export users\n"); goto done; } ret = EOK; done: talloc_free(tmp_ctx); if (ret != EOK) { return EXIT_FAILURE; } return EXIT_SUCCESS; } static int override_user_import(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { TALLOC_CTX *tmp_ctx; struct sss_colondb *db; const char *filename; struct override_user obj; int linenum = 1; errno_t ret; int rc; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n"); return EXIT_FAILURE; } /** * Format: orig_name:name:uid:gid:gecos:home:shell */ struct sss_colondb_read_field table[] = { {SSS_COLONDB_STRING, {.str = &obj.input_name}}, {SSS_COLONDB_STRING, {.str = &obj.name}}, {SSS_COLONDB_UINT32, {.uint32 = &obj.uid}}, {SSS_COLONDB_UINT32, {.uint32 = &obj.gid}}, {SSS_COLONDB_STRING, {.str = &obj.gecos}}, {SSS_COLONDB_STRING, {.str = &obj.home}}, {SSS_COLONDB_STRING, {.str = &obj.shell}}, {SSS_COLONDB_SENTINEL, {0}} }; ret = parse_cmdline_import(cmdline, tool_ctx, &filename); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); rc = EXIT_FAILURE; goto done; } db = sss_colondb_open(tool_ctx, SSS_COLONDB_READ, filename); if (db == NULL) { fprintf(stderr, _("Unable to open %s.\n"), filename); rc = EXIT_FAILURE; goto done; } while ((ret = sss_colondb_readline(tmp_ctx, db, table)) == EOK) { linenum++; ret = sss_tool_parse_name(tool_ctx, tool_ctx, obj.input_name, &obj.orig_name, &obj.domain); if (ret != EOK) { fprintf(stderr, _("Unable to parse name %s.\n"), obj.input_name); rc = EXIT_FAILURE; goto done; } ret = get_user_domain_msg(tool_ctx, &obj); if (ret != EOK) { rc = EXIT_FAILURE; goto done; } ret = override_user(tool_ctx, &obj); if (ret != EOK) { rc = EXIT_FAILURE; goto done; } talloc_free_children(tmp_ctx); } if (ret != EOF) { fprintf(stderr, _("Invalid format on line %d. " "Use --debug option for more information.\n"), linenum); rc = EXIT_FAILURE; goto done; } rc = EXIT_SUCCESS; done: talloc_free(tmp_ctx); return rc; } static int override_user_export(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { const char *filename; errno_t ret; ret = parse_cmdline_export(cmdline, tool_ctx, &filename); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); return EXIT_FAILURE; } ret = user_export(filename, tool_ctx->domains, true, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to export users\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } static int override_group_add(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { struct override_group group = {NULL}; int ret; ret = parse_cmdline_group_add(cmdline, tool_ctx, &group); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); return EXIT_FAILURE; } ret = get_group_domain_msg(tool_ctx, &group); if (ret != EOK) { return EXIT_FAILURE; } ret = override_group(tool_ctx, &group); if (ret != EOK) { return EXIT_FAILURE; } return EXIT_SUCCESS; } static int override_group_del(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { struct override_group group = {NULL}; int ret; ret = parse_cmdline_group_del(cmdline, tool_ctx, &group); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); return EXIT_FAILURE; } ret = get_group_domain_msg(tool_ctx, &group); if (ret != EOK) { return EXIT_FAILURE; } ret = override_object_del(group.domain, SYSDB_MEMBER_GROUP, group.orig_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to delete override object.\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } static int override_group_find(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { struct sss_domain_info *dom; bool iterate; errno_t ret; ret = parse_cmdline_find(cmdline, tool_ctx, &dom); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); return EXIT_FAILURE; } if (dom == NULL) { dom = tool_ctx->domains; iterate = true; } else { iterate = false; } ret = group_export(NULL, dom, iterate, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to export groups\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } static int override_group_show(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { TALLOC_CTX *tmp_ctx; struct override_group input = {NULL}; const char *dn; char *anchor; const char *filter; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n"); return EXIT_FAILURE; } ret = parse_cmdline_group_show(cmdline, tool_ctx, &input); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); goto done; } ret = get_group_domain_msg(tool_ctx, &input); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get object domain\n"); goto done; } ret = get_object_dn(tmp_ctx, input.domain, SYSDB_MEMBER_GROUP, input.orig_name, NULL, &dn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get object dn\n"); goto done; } anchor = build_anchor(tmp_ctx, dn); if (anchor == NULL) { ret = ENOMEM; goto done; } ret = sss_filter_sanitize(tmp_ctx, anchor, &anchor); if (ret != EOK) { ret = ENOMEM; goto done; } filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_OVERRIDE_ANCHOR_UUID, anchor); if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n"); ret = ENOMEM; goto done; } ret = group_export(NULL, input.domain, false, filter); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to export groups\n"); goto done; } ret = EOK; done: talloc_free(tmp_ctx); if (ret != EOK) { return EXIT_FAILURE; } return EXIT_SUCCESS; } static int override_group_import(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { TALLOC_CTX *tmp_ctx; struct sss_colondb *db; const char *filename; struct override_group obj; int linenum = 1; errno_t ret; int rc; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n"); return EXIT_FAILURE; } /** * Format: orig_name:name:gid */ struct sss_colondb_read_field table[] = { {SSS_COLONDB_STRING, {.str = &obj.input_name}}, {SSS_COLONDB_STRING, {.str = &obj.name}}, {SSS_COLONDB_UINT32, {.uint32 = &obj.gid}}, {SSS_COLONDB_SENTINEL, {0}} }; ret = parse_cmdline_import(cmdline, tool_ctx, &filename); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); rc = EXIT_FAILURE; goto done; } db = sss_colondb_open(tool_ctx, SSS_COLONDB_READ, filename); if (db == NULL) { fprintf(stderr, _("Unable to open %s.\n"), filename); rc = EXIT_FAILURE; goto done; } while ((ret = sss_colondb_readline(tmp_ctx, db, table)) == EOK) { linenum++; ret = sss_tool_parse_name(tool_ctx, tool_ctx, obj.input_name, &obj.orig_name, &obj.domain); if (ret != EOK) { fprintf(stderr, _("Unable to parse name %s.\n"), obj.input_name); rc = EXIT_FAILURE; goto done; } ret = get_group_domain_msg(tool_ctx, &obj); if (ret != EOK) { rc = EXIT_FAILURE; goto done; } ret = override_group(tool_ctx, &obj); if (ret != EOK) { rc = EXIT_FAILURE; goto done; } talloc_free_children(tmp_ctx); } if (ret != EOF) { fprintf(stderr, _("Invalid format on line %d. " "Use --debug option for more information.\n"), linenum); rc = EXIT_FAILURE; goto done; } rc = EXIT_SUCCESS; done: talloc_free(tmp_ctx); return rc; } static int override_group_export(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt) { const char *filename; errno_t ret; ret = parse_cmdline_export(cmdline, tool_ctx, &filename); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command line.\n"); return EXIT_FAILURE; } ret = group_export(filename, tool_ctx->domains, true, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to export groups\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; } int main(int argc, const char **argv) { struct sss_route_cmd commands[] = { {"user-add", override_user_add}, {"user-del", override_user_del}, {"user-find", override_user_find}, {"user-show", override_user_show}, {"user-import", override_user_import}, {"user-export", override_user_export}, {"group-add", override_group_add}, {"group-del", override_group_del}, {"group-find", override_group_find}, {"group-show", override_group_show}, {"group-import", override_group_import}, {"group-export", override_group_export}, {NULL, NULL} }; return sss_tool_main(argc, argv, commands, NULL); } sssd-1.13.4/src/tools/PaxHeaders.16287/common0000644000000000000000000000013212703463556015475 xustar0030 mtime=1460561774.981794738 30 atime=1460561776.119798596 30 ctime=1460561774.981794738 sssd-1.13.4/src/tools/common/0000755002412700241270000000000012703463556017226 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/tools/common/PaxHeaders.16287/sss_tools.h0000644000000000000000000000007412703456111017745 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.600793446 sssd-1.13.4/src/tools/common/sss_tools.h0000644002412700241270000000533312703456111021420 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SSS_TOOLS_H_ #define _SSS_TOOLS_H_ #include #include #include "confdb/confdb.h" struct sss_tool_ctx { struct confdb_ctx *confdb; char *default_domain; struct sss_domain_info *domains; }; struct sss_tool_ctx *sss_tool_init(TALLOC_CTX *mem_ctx, int *argc, const char **argv); struct sss_cmdline; typedef int (*sss_route_fn)(struct sss_cmdline *cmdline, struct sss_tool_ctx *tool_ctx, void *pvt); struct sss_route_cmd { const char *command; sss_route_fn fn; }; int sss_tool_usage(const char *tool_name, struct sss_route_cmd *commands); int sss_tool_route(int argc, const char **argv, struct sss_tool_ctx *tool_ctx, struct sss_route_cmd *commands, void *pvt); typedef int (*sss_popt_fn)(poptContext pc, char option, void *pvt); enum sss_tool_opt { SSS_TOOL_OPT_REQUIRED, SSS_TOOL_OPT_OPTIONAL }; int sss_tool_popt_ex(struct sss_cmdline *cmdline, struct poptOption *options, enum sss_tool_opt require_option, sss_popt_fn popt_fn, void *popt_fn_pvt, const char *free_opt_name, const char *free_opt_help, const char **_free_opt); int sss_tool_popt(struct sss_cmdline *cmdline, struct poptOption *options, enum sss_tool_opt require_option, sss_popt_fn popt_fn, void *popt_fn_pvt); int sss_tool_main(int argc, const char **argv, struct sss_route_cmd *commands, void *pvt); int sss_tool_parse_name(TALLOC_CTX *mem_ctx, struct sss_tool_ctx *tool_ctx, const char *input, const char **_username, struct sss_domain_info **_domain); #endif /* SRC_TOOLS_COMMON_SSS_TOOLS_H_ */ sssd-1.13.4/src/tools/common/PaxHeaders.16287/sss_tools.c0000644000000000000000000000007412703456111017740 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.647793605 sssd-1.13.4/src/tools/common/sss_tools.c0000644002412700241270000003300012703456111021403 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "config.h" #include "util/util.h" #include "confdb/confdb.h" #include "db/sysdb.h" #include "tools/common/sss_tools.h" struct sss_cmdline { const char *exec; /* argv[0] */ const char *command; /* command name */ int argc; /* rest of arguments */ const char **argv; }; static void sss_tool_print_common_opts(void) { fprintf(stderr, _("Common options:\n")); fprintf(stderr, " --debug=INT %s\n", _("Enable debug at level")); } static struct poptOption *sss_tool_common_opts_table(void) { static struct poptOption common_opts[] = { {"debug", '\0', POPT_ARG_INT, NULL, 0, NULL, NULL }, POPT_TABLEEND }; common_opts[0].descrip = _("The debug level to run with"); return common_opts; } static void sss_tool_common_opts(struct sss_tool_ctx *tool_ctx, int *argc, const char **argv) { poptContext pc; int debug = SSSDBG_DEFAULT; int orig_argc = *argc; int opt; struct poptOption options[] = { {"debug", '\0', POPT_ARG_INT | POPT_ARGFLAG_STRIP, &debug, 0, _("The debug level to run with"), NULL }, POPT_TABLEEND }; pc = poptGetContext(argv[0], orig_argc, argv, options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { /* do nothing */ } /* Strip common options from arguments. We will discard_const here, * since it is not worth the trouble to convert it back and forth. */ *argc = poptStrippedArgv(pc, orig_argc, discard_const_p(char *, argv)); DEBUG_CLI_INIT(debug); poptFreeContext(pc); } static errno_t sss_tool_confdb_init(TALLOC_CTX *mem_ctx, struct confdb_ctx **_confdb) { struct confdb_ctx *confdb; char *path; errno_t ret; path = talloc_asprintf(mem_ctx, "%s/%s", DB_PATH, CONFDB_FILE); if (path == NULL) { return ENOMEM; } ret = confdb_init(mem_ctx, &confdb, path); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the confdb\n"); talloc_free(path); return ret; } if (_confdb != NULL) { *_confdb = confdb; } return EOK; } static errno_t sss_tool_domains_init(TALLOC_CTX *mem_ctx, struct confdb_ctx *confdb, struct sss_domain_info **_domains) { struct sss_domain_info *domains; struct sss_domain_info *dom; errno_t ret; ret = confdb_get_domains(confdb, &domains); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup domains [%d]: %s\n", ret, sss_strerror(ret)); return ret; } ret = sysdb_init(mem_ctx, domains, false); SYSDB_VERSION_ERROR(ret); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not initialize connection to the sysdb\n"); return ret; } for (dom = domains; dom != NULL; dom = get_next_domain(dom, SSS_GND_DESCEND)) { if (!IS_SUBDOMAIN(dom)) { /* Get flat name and domain ID (SID) from the cache * if available */ ret = sysdb_master_domain_update(dom); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to update domain %s.\n", dom->name); } /* Update list of subdomains for this domain */ ret = sysdb_update_subdomains(dom); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to update subdomains for domain %s.\n", dom->name); } } } for (dom = domains; dom != NULL; dom = get_next_domain(dom, SSS_GND_DESCEND)) { ret = sss_names_init(mem_ctx, confdb, dom->name, &dom->names); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_names_init() failed\n"); return ret; } } *_domains = domains; return ret; } struct sss_tool_ctx *sss_tool_init(TALLOC_CTX *mem_ctx, int *argc, const char **argv) { struct sss_tool_ctx *tool_ctx; errno_t ret; tool_ctx = talloc_zero(mem_ctx, struct sss_tool_ctx); if (tool_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero() failed\n"); return NULL; } sss_tool_common_opts(tool_ctx, argc, argv); /* Connect to confdb. */ ret = sss_tool_confdb_init(tool_ctx, &tool_ctx->confdb); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open confdb [%d]: %s\n", ret, sss_strerror(ret)); goto done; } /* Setup domains. */ ret = sss_tool_domains_init(tool_ctx, tool_ctx->confdb, &tool_ctx->domains); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup domains [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = confdb_get_string(tool_ctx->confdb, tool_ctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_DEFAULT_DOMAIN, NULL, &tool_ctx->default_domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get the default domain [%d]: %s\n", ret, strerror(ret)); goto done; } ret = EOK; done: if (ret != EOK) { talloc_zfree(tool_ctx); } return tool_ctx; } int sss_tool_usage(const char *tool_name, struct sss_route_cmd *commands) { int i; fprintf(stderr, _("Usage:\n%s COMMAND COMMAND-ARGS\n\n"), tool_name); fprintf(stderr, _("Available commands:\n")); for (i = 0; commands[i].command != NULL; i++) { fprintf(stderr, "* %s\n", commands[i].command); } fprintf(stderr, _("\n")); sss_tool_print_common_opts(); return EXIT_FAILURE; } int sss_tool_route(int argc, const char **argv, struct sss_tool_ctx *tool_ctx, struct sss_route_cmd *commands, void *pvt) { struct sss_cmdline cmdline; const char *cmd; int i; if (commands == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: commands can't be NULL!\n"); return EXIT_FAILURE; } if (argc < 2) { return sss_tool_usage(argv[0], commands); } cmd = argv[1]; for (i = 0; commands[i].command != NULL; i++) { if (strcmp(commands[i].command, cmd) == 0) { cmdline.exec = argv[0]; cmdline.command = argv[1]; cmdline.argc = argc - 2; cmdline.argv = argv + 2; return commands[i].fn(&cmdline, tool_ctx, pvt); } } return sss_tool_usage(argv[0], commands); } static struct poptOption *nonnull_popt_table(struct poptOption *options) { static struct poptOption empty[] = { POPT_TABLEEND }; if (options == NULL) { return empty; } return options; } int sss_tool_popt_ex(struct sss_cmdline *cmdline, struct poptOption *options, enum sss_tool_opt require_option, sss_popt_fn popt_fn, void *popt_fn_pvt, const char *fopt_name, const char *fopt_help, const char **_fopt) { struct poptOption opts_table[] = { {NULL, '\0', POPT_ARG_INCLUDE_TABLE, nonnull_popt_table(options), \ 0, _("Command options:"), NULL }, {NULL, '\0', POPT_ARG_INCLUDE_TABLE, sss_tool_common_opts_table(), \ 0, _("Common options:"), NULL }, POPT_AUTOHELP POPT_TABLEEND }; const char *fopt; char *help; poptContext pc; int ret; /* Create help option string. We always need to append command name since * we use POPT_CONTEXT_KEEP_FIRST. */ if (fopt_name == NULL) { help = talloc_asprintf(NULL, "%s %s %s", cmdline->exec, cmdline->command, _("[OPTIONS...]")); } else { help = talloc_asprintf(NULL, "%s %s %s %s", cmdline->exec, cmdline->command, fopt_name, _("[OPTIONS...]")); } if (help == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n"); return EXIT_FAILURE; } /* Create popt context. This function is supposed to be called on * command argv which does not contain executable (argv[0]), therefore * we need to use KEEP_FIRST that ensures argv[0] is also processed. */ pc = poptGetContext(cmdline->exec, cmdline->argc, cmdline->argv, opts_table, POPT_CONTEXT_KEEP_FIRST); poptSetOtherOptionHelp(pc, help); /* Parse options. Invoke custom function if provided. If no parsing * function is provided, print error on unknown option. */ while ((ret = poptGetNextOpt(pc)) != -1) { if (popt_fn != NULL) { ret = popt_fn(pc, ret, popt_fn_pvt); if (ret != EOK) { ret = EXIT_FAILURE; goto done; } } else { fprintf(stderr, _("Invalid option %s: %s\n\n"), poptBadOption(pc, 0), poptStrerror(ret)); poptPrintHelp(pc, stderr, 0); ret = EXIT_FAILURE; goto done; } } /* Parse free option which is always required if requested. */ fopt = poptGetArg(pc); if (_fopt != NULL) { if (fopt == NULL) { fprintf(stderr, _("Missing option: %s\n\n"), fopt_help); poptPrintHelp(pc, stderr, 0); ret = EXIT_FAILURE; goto done; } /* No more arguments expected. If something follows it is an error. */ if (poptGetArg(pc)) { fprintf(stderr, _("Only one free argument is expected!\n\n")); poptPrintHelp(pc, stderr, 0); ret = EXIT_FAILURE; goto done; } *_fopt = fopt; } else if (_fopt == NULL && fopt != NULL) { /* Unexpected free argument. */ fprintf(stderr, _("Unexpected parameter: %s\n\n"), fopt); poptPrintHelp(pc, stderr, 0); ret = EXIT_FAILURE; goto done; } /* If at least one option is required and not provided, print error. */ if (require_option == SSS_TOOL_OPT_REQUIRED && ((_fopt != NULL && cmdline->argc < 2) || cmdline->argc < 1)) { fprintf(stderr, _("At least one option is required!\n\n")); poptPrintHelp(pc, stderr, 0); ret = EXIT_FAILURE; goto done; } ret = EXIT_SUCCESS; done: poptFreeContext(pc); talloc_free(help); return ret; } int sss_tool_popt(struct sss_cmdline *cmdline, struct poptOption *options, enum sss_tool_opt require_option, sss_popt_fn popt_fn, void *popt_fn_pvt) { return sss_tool_popt_ex(cmdline, options, require_option, popt_fn, popt_fn_pvt, NULL, NULL, NULL); } int sss_tool_main(int argc, const char **argv, struct sss_route_cmd *commands, void *pvt) { struct sss_tool_ctx *tool_ctx; uid_t uid; int ret; uid = getuid(); if (uid != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Running under %d, must be root\n", uid); ERROR("%1$s must be run as root\n", argv[0]); return EXIT_FAILURE; } tool_ctx = sss_tool_init(NULL, &argc, argv); if (tool_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tool context\n"); return EXIT_FAILURE; } ret = sss_tool_route(argc, argv, tool_ctx, commands, pvt); talloc_free(tool_ctx); return ret; } int sss_tool_parse_name(TALLOC_CTX *mem_ctx, struct sss_tool_ctx *tool_ctx, const char *input, const char **_username, struct sss_domain_info **_domain) { char *username = NULL; char *domname = NULL; struct sss_domain_info *domain; int ret; ret = sss_parse_name_for_domains(mem_ctx, tool_ctx->domains, tool_ctx->default_domain, input, &domname, &username); if (ret == EAGAIN) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to find domain. The domain name may " "be a subdomain that was not yet found.\n"); goto done; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name [%d]: %s\n", ret, sss_strerror(ret)); goto done; } domain = find_domain_by_name(tool_ctx->domains, domname, true); *_username = username; *_domain = domain; ret = EOK; done: if (ret != EOK) { talloc_zfree(username); talloc_zfree(domname); } return ret; } sssd-1.13.4/src/tools/common/PaxHeaders.16287/sss_colondb.c0000644000000000000000000000007412703456111020220 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.981794738 sssd-1.13.4/src/tools/common/sss_colondb.c0000644002412700241270000001700212703456111021667 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "util/strtonum.h" #include "tools/common/sss_colondb.h" #define IS_STD_FILE(db) ((db)->file == stdin || (db)->file == stdout) static char *read_field_as_string(char *line, const char **_value) { char *rest; char *value; if (line == NULL || *line == '\n' || *line == '\0') { /* There is nothing else to read. */ rest = NULL; value = NULL; goto done; } if (*line == ':') { /* Special case for empty value. */ *line = '\0'; rest = line + 1; value = NULL; goto done; } /* Value starts at current position. */ value = line; /* Find next field delimiter. */ rest = strchr(line, ':'); if (rest == NULL) { /* There is no more field. Remove \n from the end. */ rest = strchr(line, '\n'); if (rest != NULL) { *rest = '\0'; rest = NULL; } goto done; } /* Remove it and step one character further. */ *rest = '\0'; rest++; done: *_value = value; return rest; } static char *read_field_as_uint32(char *line, uint32_t *_value) { const char *str; char *rest; errno_t ret; rest = read_field_as_string(line, &str); if (str == NULL) { *_value = 0; return rest; } *_value = strtouint32(str, NULL, 10); if (errno != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse number [%d]: %s\n", ret, sss_strerror(ret)); *_value = 0; } return rest; } struct sss_colondb { FILE *file; enum sss_colondb_mode mode; }; errno_t sss_colondb_readline(TALLOC_CTX *mem_ctx, struct sss_colondb *db, struct sss_colondb_read_field *table) { int readchars; size_t linelen = 0; char *line = NULL; char *tcline; char *rest; errno_t ret; int i; if (db->mode != SSS_COLONDB_READ) { return ERR_INTERNAL; } readchars = getline(&line, &linelen, db->file); if (readchars == -1) { /* Nothing was read. */ free(line); line = NULL; if (errno != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read line [%d]: %s\n", ret, sss_strerror(ret)); return ret; } return EOF; } /* Copy line to mem_ctx. */ tcline = talloc_strdup(mem_ctx, line); free(line); line = NULL; if (tcline == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); return ENOMEM; } rest = tcline; for (i = 0; table[i].type != SSS_COLONDB_SENTINEL; i++) { switch (table[i].type) { case SSS_COLONDB_UINT32: rest = read_field_as_uint32(rest, table[i].data.uint32); break; case SSS_COLONDB_STRING: rest = read_field_as_string(rest, table[i].data.str); break; case SSS_COLONDB_SENTINEL: DEBUG(SSSDBG_CRIT_FAILURE, "Trying to process sentinel?!\n"); ret = ERR_INTERNAL; goto done; } if (rest == NULL && table[i + 1].type != SSS_COLONDB_SENTINEL) { DEBUG(SSSDBG_CRIT_FAILURE, "Line contains less values than expected!\n"); ret = EINVAL; goto done; } else if (rest != NULL && table[i + 1].type == SSS_COLONDB_SENTINEL) { DEBUG(SSSDBG_CRIT_FAILURE, "Line contains more values than expected!\n"); ret = EINVAL; goto done; } } ret = EOK; done: if (ret != EOK) { talloc_free(tcline); } return ret; } errno_t sss_colondb_writeline(struct sss_colondb *db, struct sss_colondb_write_field *table) { TALLOC_CTX *tmp_ctx; char *line = NULL; errno_t ret; int i; if (db->mode != SSS_COLONDB_WRITE) { return ERR_INTERNAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n"); return ENOMEM; } line = talloc_strdup(tmp_ctx, ""); if (line == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n"); ret = ENOMEM; goto done; } for (i = 0; table[i].type != SSS_COLONDB_SENTINEL; i++) { switch (table[i].type) { case SSS_COLONDB_UINT32: if (table[i].data.uint32 == 0) { line = talloc_asprintf_append(line, ":"); } else { line = talloc_asprintf_append(line, ":%u", table[i].data.uint32); } break; case SSS_COLONDB_STRING: if (table[i].data.str == NULL) { line = talloc_asprintf_append(line, ":"); } else { line = talloc_asprintf_append(line, ":%s", table[i].data.str); } break; case SSS_COLONDB_SENTINEL: DEBUG(SSSDBG_CRIT_FAILURE, "Trying to process sentinel?!\n"); ret = ERR_INTERNAL; goto done; } if (line == NULL) { ret = ENOMEM; goto done; } } /* Remove starting : */ line++; fprintf(db->file, "%s\n", line); fflush(db->file); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static int sss_colondb_close(void *pvt) { struct sss_colondb *db = talloc_get_type(pvt, struct sss_colondb); if (db->file == NULL || IS_STD_FILE(db)) { return 0; } fclose(db->file); db->file = NULL; return 0; } static FILE *open_db(const char *filename, enum sss_colondb_mode mode) { FILE *fp = NULL; errno_t ret; errno = 0; switch (mode) { case SSS_COLONDB_READ: fp = filename == NULL ? stdin : fopen(filename, "r"); break; case SSS_COLONDB_WRITE: fp = filename == NULL ? stdout : fopen(filename, "w"); break; } if (fp == NULL && filename != NULL) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open file %s [%d]: %s\n", filename, ret, sss_strerror(ret)); } return fp; } struct sss_colondb *sss_colondb_open(TALLOC_CTX *mem_ctx, enum sss_colondb_mode mode, const char *filename) { struct sss_colondb *db; db = talloc_zero(mem_ctx, struct sss_colondb); if (db == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero() failed\n"); return NULL; } db->file = open_db(filename, mode); db->mode = mode; if (db->file == NULL) { talloc_free(db); return NULL; } talloc_set_destructor((TALLOC_CTX *)db, sss_colondb_close); return db; } sssd-1.13.4/src/tools/common/PaxHeaders.16287/sss_colondb.h0000644000000000000000000000007412703456111020225 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.601793449 sssd-1.13.4/src/tools/common/sss_colondb.h0000644002412700241270000000554212703456111021702 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SSS_COLONDB_H_ #define _SSS_COLONDB_H_ #include #include #include #include struct sss_colondb; enum sss_colondb_mode { SSS_COLONDB_READ, SSS_COLONDB_WRITE }; enum sss_colondb_type { SSS_COLONDB_UINT32, SSS_COLONDB_STRING, SSS_COLONDB_SENTINEL }; union sss_colondb_write_data { uint32_t uint32; const char *str; }; union sss_colondb_read_data { uint32_t *uint32; const char **str; }; struct sss_colondb_write_field { enum sss_colondb_type type; union sss_colondb_write_data data; }; struct sss_colondb_read_field { enum sss_colondb_type type; union sss_colondb_read_data data; }; /** * Open colon DB and return connection. * @param[in|out] mem_ctx Memory context. Internal sss_colondb_close() is set * on destructor of this memory context. * @param[in] mode Open mode of db: SSS_COLONDB_READ or SSS_COLONDB_WRITE. * @param[in] filename Name of file. * @return Pointer to structure holding DB connection, or NULL if fail. */ struct sss_colondb *sss_colondb_open(TALLOC_CTX *mem_ctx, enum sss_colondb_mode mode, const char *filename); /** * Read line from colon DB. * @param[in|out] mem_ctx Memory context. * @param[in] db Pointer to structure holding DB connection. * @param[in|out] table Array of expected structure of line. It is expected * that last item has SSS_COLONDB_SENTINEL type. * @return EOK if success, else error code. */ errno_t sss_colondb_readline(TALLOC_CTX *mem_ctx, struct sss_colondb *db, struct sss_colondb_read_field *table); /** * Write line to colon DB. * @param[in] db Pointer to structure holding DB connection. * @param[in] table Array with data. It is expected that last item has * SSS_COLONDB_SENTINEL type. * @return EOK if success, else error code. */ errno_t sss_colondb_writeline(struct sss_colondb *db, struct sss_colondb_write_field *table); #endif /* _SSS_COLONDB_H_ */ sssd-1.13.4/src/tools/PaxHeaders.16287/tools_mc_util.c0000644000000000000000000000007412703456111017274 xustar0030 atime=1460561751.659715658 30 ctime=1460561774.972794707 sssd-1.13.4/src/tools/tools_mc_util.c0000644002412700241270000002360412703456111020750 0ustar00jhrozekjhrozek00000000000000/* SSSD tools_mc_util - interface to the memcache for userspace tools Copyright (C) Red Hat 2013 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "db/sysdb.h" #include "util/util.h" #include "tools/tools_util.h" #include "util/mmap_cache.h" #include "util/sss_cli_cmd.h" #include "sss_client/sss_cli.h" /* This is a copy of sss_mc_set_recycled present in * src/responder/nss/nsssrv_mmap_cache.c. If you modify this function, * you should modify the original function too. */ static errno_t sss_mc_set_recycled(int fd) { uint32_t w = SSS_MC_HEADER_RECYCLED; struct sss_mc_header h; off_t offset; off_t pos; ssize_t written; offset = MC_PTR_DIFF(&h.status, &h); pos = lseek(fd, offset, SEEK_SET); if (pos == -1) { /* What do we do now ? */ return errno; } errno = 0; written = sss_atomic_write_s(fd, (uint8_t *)&w, sizeof(h.status)); if (written == -1) { return errno; } if (written != sizeof(h.status)) { /* Write error */ return EIO; } return EOK; } errno_t sss_memcache_invalidate(const char *mc_filename) { int mc_fd = -1; errno_t ret; errno_t pret; useconds_t t = 50000; int retries = 2; if (!mc_filename) { return EINVAL; } mc_fd = open(mc_filename, O_RDWR); if (mc_fd == -1) { ret = errno; if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC,"Memory cache file %s " "does not exist.\n", mc_filename); return EOK; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to open file %s: %s\n", mc_filename, strerror(ret)); return ret; } } ret = sss_br_lock_file(mc_fd, 0, 1, retries, t); if (ret == EACCES) { DEBUG(SSSDBG_TRACE_FUNC, "File %s already locked by someone else.\n", mc_filename); goto done; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to lock file %s.\n", mc_filename); goto done; } /* Mark the mc file as recycled. */ ret = sss_mc_set_recycled(mc_fd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to mark memory cache file %s " "as recycled.\n", mc_filename); goto done; } ret = EOK; done: if (mc_fd != -1) { /* Closing the file also releases the lock */ close(mc_fd); /* Only unlink the file if invalidation was successful */ if (ret == EOK) { pret = unlink(mc_filename); if (pret == -1) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to unlink file %s. " "Will be unlinked later by sssd_nss.\n", mc_filename); } } } return ret; } static int clear_fastcache(bool *sssd_nss_is_off) { int ret; ret = sss_memcache_invalidate(SSS_NSS_MCACHE_DIR"/passwd"); if (ret != EOK) { if (ret == EACCES) { *sssd_nss_is_off = false; return EOK; } else { return ret; } } ret = sss_memcache_invalidate(SSS_NSS_MCACHE_DIR"/group"); if (ret != EOK) { if (ret == EACCES) { *sssd_nss_is_off = false; return EOK; } else { return ret; } } ret = sss_memcache_invalidate(SSS_NSS_MCACHE_DIR"/initgroups"); if (ret != EOK) { if (ret == EACCES) { *sssd_nss_is_off = false; return EOK; } else { return ret; } } *sssd_nss_is_off = true; return EOK; } static errno_t wait_till_nss_responder_invalidate_cache(void) { struct stat stat_buf = { 0 }; const time_t max_wait = 1000000; /* 1 second */ const time_t step_time = 5000; /* 5 miliseconds */ const size_t steps_count = max_wait / step_time; int ret; for (size_t i = 0; i < steps_count; ++i) { ret = stat(SSS_NSS_MCACHE_DIR "/" CLEAR_MC_FLAG, &stat_buf); if (ret == -1) { ret = errno; if (ret == ENOENT) { /* nss responder has already invalidated memory caches */ return EOK; } DEBUG(SSSDBG_CRIT_FAILURE, "stat failed: %s (%d)\n", sss_strerror(ret), ret); } usleep(step_time); } return EAGAIN; } errno_t sss_memcache_clear_all(void) { errno_t ret; bool sssd_nss_is_off = false; FILE *clear_mc_flag; ret = clear_fastcache(&sssd_nss_is_off); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to clear caches.\n"); return EIO; } if (!sssd_nss_is_off) { /* sssd_nss is running -> signal monitor to invalidate fastcache */ clear_mc_flag = fopen(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG, "w"); if (clear_mc_flag == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create clear_mc_flag file. " "Memory cache will not be cleared.\n"); return EIO; } ret = fclose(clear_mc_flag); if (ret != 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Unable to close file descriptor: %s\n", strerror(ret)); return EIO; } DEBUG(SSSDBG_TRACE_FUNC, "Sending SIGHUP to monitor.\n"); ret = signal_sssd(SIGHUP); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to send SIGHUP to monitor.\n"); return EIO; } ret = wait_till_nss_responder_invalidate_cache(); if (ret != EOK) { ERROR("The fast memory caches was not invalidated by NSS " "responder.\n"); } } return EOK; } enum sss_tools_ent { SSS_TOOLS_USER, SSS_TOOLS_GROUP }; static errno_t sss_mc_refresh_ent(const char *name, enum sss_tools_ent ent) { enum sss_cli_command cmd; struct sss_cli_req_data rd; uint8_t *repbuf = NULL; size_t replen; enum nss_status nret; errno_t ret; cmd = SSS_CLI_NULL; switch (ent) { case SSS_TOOLS_USER: cmd = SSS_NSS_GETPWNAM; break; case SSS_TOOLS_GROUP: cmd = SSS_NSS_GETGRNAM; break; } if (cmd == SSS_CLI_NULL) { DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d][%s] to refresh\n", cmd, sss_cmd2str(cmd)); return EINVAL; } rd.data = name; rd.len = strlen(name) + 1; sss_nss_lock(); nret = sss_nss_make_request(cmd, &rd, &repbuf, &replen, &ret); sss_nss_unlock(); free(repbuf); if (nret != NSS_STATUS_SUCCESS && nret != NSS_STATUS_NOTFOUND) { return EIO; } return EOK; } errno_t sss_mc_refresh_user(const char *username) { return sss_mc_refresh_ent(username, SSS_TOOLS_USER); } errno_t sss_mc_refresh_group(const char *groupname) { return sss_mc_refresh_ent(groupname, SSS_TOOLS_GROUP); } errno_t sss_mc_refresh_nested_group(struct tools_ctx *tctx, const char *name) { errno_t ret; struct ldb_message *msg; struct ldb_message_element *el; const char *attrs[] = { SYSDB_MEMBEROF, SYSDB_NAME, NULL }; size_t i; char *parent_name; ret = sss_mc_refresh_group(name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot refresh group %s from memory cache\n", name); /* try to carry on */ } ret = sysdb_search_group_by_name(tctx, tctx->local, name, attrs, &msg); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Search failed: %s (%d)\n", strerror(ret), ret); return ret; } el = ldb_msg_find_element(msg, SYSDB_MEMBEROF); if (!el || el->num_values == 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "Group %s has no parents\n", name); talloc_free(msg); return EOK; } /* This group is nested. We need to invalidate all its parents, too */ for (i=0; i < el->num_values; i++) { ret = sysdb_group_dn_name(tctx->sysdb, tctx, (const char *) el->values[i].data, &parent_name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Malformed DN [%s]? Skipping\n", (const char *) el->values[i].data); talloc_free(parent_name); continue; } ret = sss_mc_refresh_group(parent_name); talloc_free(parent_name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot refresh group %s from memory cache\n", name); /* try to carry on */ } } talloc_free(msg); return EOK; } errno_t sss_mc_refresh_grouplist(struct tools_ctx *tctx, char **groupnames) { int i; errno_t ret; bool failed = false; if (!groupnames) return EOK; for (i = 0; groupnames[i]; i++) { ret = sss_mc_refresh_nested_group(tctx, groupnames[i]); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot refresh group %s from memory cache\n", groupnames[i]); failed = true; continue; } } return failed ? EIO : EOK; } sssd-1.13.4/src/PaxHeaders.16287/p11_child0000644000000000000000000000013212703463556014611 xustar0030 mtime=1460561774.948794625 30 atime=1460561776.119798596 30 ctime=1460561774.948794625 sssd-1.13.4/src/p11_child/0000755002412700241270000000000012703463556016342 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/p11_child/PaxHeaders.16287/p11_child_nss.c0000644000000000000000000000007412703456111017453 xustar0030 atime=1460561751.643715604 30 ctime=1460561774.948794625 sssd-1.13.4/src/p11_child/p11_child_nss.c0000644002412700241270000005232012703456111021124 0ustar00jhrozekjhrozek00000000000000/* SSSD Helper child to commmunicate with SmartCard via NSS Authors: Sumit Bose Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include #include #include #include #include #include #include #include #include #include "util/child_common.h" #include "providers/dp_backend.h" #include "util/crypto/sss_crypto.h" #include "util/cert.h" enum op_mode { OP_NONE, OP_AUTH, OP_PREAUTH }; enum pin_mode { PIN_NONE, PIN_STDIN, PIN_KEYPAD }; static char *password_passthrough(PK11SlotInfo *slot, PRBool retry, void *arg) { /* give up if 1) no password was supplied, or 2) the password has already * been rejected once by this token. */ if (retry || (arg == NULL)) { return NULL; } return PL_strdup((char *)arg); } int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, enum op_mode mode, const char *pin, bool do_ocsp, char **cert, char **token_name_out) { int ret; SECStatus rv; NSSInitContext *nss_ctx; SECMODModuleList *mod_list; SECMODModuleList *mod_list_item; const char *slot_name; const char *token_name; uint32_t flags = NSS_INIT_READONLY | NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD; NSSInitParameters parameters = { 0 }; parameters.length = sizeof (parameters); PK11SlotInfo *slot = NULL; CK_SLOT_ID slot_id; SECMODModuleID module_id; CERTCertList *cert_list = NULL; CERTCertListNode *cert_list_node; const PK11DefaultArrayEntry friendly_attr = { "Publicly-readable certs", SECMOD_FRIENDLY_FLAG, CKM_INVALID_MECHANISM }; CERTCertDBHandle *handle; unsigned char random_value[128]; SECKEYPrivateKey *priv_key; SECOidTag algtag; SECItem signed_random_value = {0}; SECKEYPublicKey *pub_key; CERTCertificate *found_cert = NULL; PK11SlotList *list = NULL; PK11SlotListElement *le; nss_ctx = NSS_InitContext(nss_db, "", "", SECMOD_DB, ¶meters, flags); if (nss_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "NSS_InitContext failed [%d].\n", PR_GetError()); return EIO; } PK11_SetPasswordFunc(password_passthrough); DEBUG(SSSDBG_TRACE_ALL, "Default Module List:\n"); mod_list = SECMOD_GetDefaultModuleList(); for (mod_list_item = mod_list; mod_list_item != NULL; mod_list_item = mod_list_item->next) { DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n", mod_list_item->module->commonName); DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n", mod_list_item->module->dllName); } DEBUG(SSSDBG_TRACE_ALL, "Dead Module List:\n"); mod_list = SECMOD_GetDeadModuleList(); for (mod_list_item = mod_list; mod_list_item != NULL; mod_list_item = mod_list_item->next) { DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n", mod_list_item->module->commonName); DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n", mod_list_item->module->dllName); } DEBUG(SSSDBG_TRACE_ALL, "DB Module List:\n"); mod_list = SECMOD_GetDBModuleList(); for (mod_list_item = mod_list; mod_list_item != NULL; mod_list_item = mod_list_item->next) { DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n", mod_list_item->module->commonName); DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n", mod_list_item->module->dllName); } if (slot_name_in != NULL) { slot = PK11_FindSlotByName(slot_name_in); if (slot == NULL) { DEBUG(SSSDBG_OP_FAILURE, "PK11_FindSlotByName failed for [%s]: [%d].\n", slot_name_in, PR_GetError()); return EIO; } } else { list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, NULL); if (list == NULL) { DEBUG(SSSDBG_OP_FAILURE, "PK11_GetAllTokens failed.\n"); return EIO; } for (le = list->head; le; le = le->next) { CK_SLOT_INFO slInfo; slInfo.flags = 0; rv = PK11_GetSlotInfo(le->slot, &slInfo); DEBUG(SSSDBG_TRACE_ALL, "Description [%s] Manufacturer [%s] flags [%lu].\n", slInfo.slotDescription, slInfo.manufacturerID, slInfo.flags); if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) { slot = PK11_ReferenceSlot(le->slot); break; } } PK11_FreeSlotList(list); if (slot == NULL) { DEBUG(SSSDBG_OP_FAILURE, "No removable slots found.\n"); return EIO; } } slot_id = PK11_GetSlotID(slot); module_id = PK11_GetModuleID(slot); slot_name = PK11_GetSlotName(slot); token_name = PK11_GetTokenName(slot); DEBUG(SSSDBG_TRACE_ALL, "Found [%s] in slot [%s][%d] of module [%d].\n", token_name, slot_name, (int) slot_id, (int) module_id); if (PK11_IsFriendly(slot)) { DEBUG(SSSDBG_TRACE_ALL, "Token is friendly.\n"); } else { DEBUG(SSSDBG_TRACE_ALL, "Token is NOT friendly.\n"); if (mode == OP_PREAUTH) { DEBUG(SSSDBG_TRACE_ALL, "Trying to switch to friendly to read certificate.\n"); rv = PK11_UpdateSlotAttribute(slot, &friendly_attr, PR_TRUE); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "PK11_UpdateSlotAttribute failed, continue.\n"); } } } /* TODO: check PK11_ProtectedAuthenticationPath() and return the result */ if (mode == OP_AUTH || PK11_NeedLogin(slot)) { DEBUG(SSSDBG_TRACE_ALL, "Login required.\n"); if (pin != NULL) { rv = PK11_Authenticate(slot, PR_FALSE, discard_const(pin)); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "PK11_Authenticate failed: [%d].\n", PR_GetError()); return EIO; } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Login required but no pin available, continue.\n"); } } else { DEBUG(SSSDBG_TRACE_ALL, "Login NOT required.\n"); } cert_list = PK11_ListCertsInSlot(slot); if (cert_list == NULL) { DEBUG(SSSDBG_OP_FAILURE, "PK11_ListCertsInSlot failed: [%d].\n", PR_GetError()); return EIO; } for (cert_list_node = CERT_LIST_HEAD(cert_list); !CERT_LIST_END(cert_list_node, cert_list); cert_list_node = CERT_LIST_NEXT(cert_list_node)) { if (cert_list_node->cert) { DEBUG(SSSDBG_TRACE_ALL, "found cert[%s][%s]\n", cert_list_node->cert->nickname, cert_list_node->cert->subjectName); } else { DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n"); } } rv = CERT_FilterCertListByUsage(cert_list, certUsageSSLClient, PR_FALSE); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListByUsage failed: [%d].\n", PR_GetError()); return EIO; } rv = CERT_FilterCertListForUserCerts(cert_list); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListForUserCerts failed: [%d].\n", PR_GetError()); return EIO; } handle = CERT_GetDefaultCertDB(); if (handle == NULL) { DEBUG(SSSDBG_OP_FAILURE, "CERT_GetDefaultCertDB failed: [%d].\n", PR_GetError()); return EIO; } if (do_ocsp) { rv = CERT_EnableOCSPChecking(handle); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "CERT_EnableOCSPChecking failed: [%d].\n", PR_GetError()); return EIO; } } found_cert = NULL; DEBUG(SSSDBG_TRACE_ALL, "Filtered certificates:\n"); for (cert_list_node = CERT_LIST_HEAD(cert_list); !CERT_LIST_END(cert_list_node, cert_list); cert_list_node = CERT_LIST_NEXT(cert_list_node)) { if (cert_list_node->cert) { DEBUG(SSSDBG_TRACE_ALL, "found cert[%s][%s]\n", cert_list_node->cert->nickname, cert_list_node->cert->subjectName); rv = CERT_VerifyCertificateNow(handle, cert_list_node->cert, PR_TRUE, certificateUsageSSLClient, NULL, NULL); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "Certificate [%s][%s] not valid [%d], skipping.\n", cert_list_node->cert->nickname, cert_list_node->cert->subjectName, PR_GetError()); continue; } if (found_cert == NULL) { found_cert = cert_list_node->cert; } else { DEBUG(SSSDBG_TRACE_ALL, "More than one certificate found, " \ "using just the first one.\n"); } } else { DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n"); } } if (found_cert == NULL) { DEBUG(SSSDBG_TRACE_ALL, "No certificate found.\n"); *cert = NULL; *token_name_out = NULL; ret = EOK; goto done; } if (mode == OP_AUTH) { rv = PK11_GenerateRandom(random_value, sizeof(random_value)); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "PK11_GenerateRandom failed [%d].\n", PR_GetError()); return EIO; } priv_key = PK11_FindPrivateKeyFromCert(slot, found_cert, NULL); if (priv_key == NULL) { DEBUG(SSSDBG_OP_FAILURE, "PK11_FindPrivateKeyFromCert failed [%d]." \ "Maybe pin is missing.\n", PR_GetError()); ret = EIO; goto done; } algtag = SEC_GetSignatureAlgorithmOidTag(priv_key->keyType, SEC_OID_SHA1); if (algtag == SEC_OID_UNKNOWN) { SECKEY_DestroyPrivateKey(priv_key); DEBUG(SSSDBG_OP_FAILURE, "SEC_GetSignatureAlgorithmOidTag failed [%d].\n", PR_GetError()); ret = EIO; goto done; } rv = SEC_SignData(&signed_random_value, random_value, sizeof(random_value), priv_key, algtag); SECKEY_DestroyPrivateKey(priv_key); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "SEC_SignData failed [%d].\n", PR_GetError()); ret = EIO; goto done; } pub_key = CERT_ExtractPublicKey(found_cert); if (pub_key == NULL) { DEBUG(SSSDBG_OP_FAILURE, "CERT_ExtractPublicKey failed [%d].\n", PR_GetError()); ret = EIO; goto done; } rv = VFY_VerifyData(random_value, sizeof(random_value), pub_key, &signed_random_value, algtag, NULL); SECKEY_DestroyPublicKey(pub_key); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "VFY_VerifyData failed [%d].\n", PR_GetError()); ret = EACCES; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Certificate verified and validated.\n"); } *cert = sss_base64_encode(mem_ctx, found_cert->derCert.data, found_cert->derCert.len); if (*cert == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_base64_encode failed.\n"); ret = ENOMEM; goto done; } *token_name_out = talloc_strdup(mem_ctx, token_name); if (*token_name_out == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy slot name.\n"); ret = ENOMEM; goto done; } ret = EOK; done: if (slot != NULL) { PK11_FreeSlot(slot); } if (cert_list != NULL) { CERT_DestroyCertList(cert_list); } PORT_Free(signed_random_value.data); rv = NSS_ShutdownContext(nss_ctx); if (rv != SECSuccess) { DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d].\n", PR_GetError()); } return ret; } static errno_t p11c_recv_data(TALLOC_CTX *mem_ctx, int fd, char **pin) { uint8_t buf[IN_BUF_SIZE]; ssize_t len; errno_t ret; char *str; errno = 0; len = sss_atomic_read_s(fd, buf, IN_BUF_SIZE); if (len == -1) { ret = errno; ret = (ret == 0) ? EINVAL: ret; DEBUG(SSSDBG_CRIT_FAILURE, "read failed [%d][%s].\n", ret, strerror(ret)); return ret; } if (len == 0 || *buf == '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Missing PIN.\n"); return EINVAL; } str = talloc_strndup(mem_ctx, (char *) buf, len); if (str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); return ENOMEM; } if (strlen(str) != len) { DEBUG(SSSDBG_CRIT_FAILURE, "Input contains additional data, only PIN expected.\n"); talloc_free(str); return EINVAL; } *pin = str; return EOK; } int main(int argc, const char *argv[]) { int opt; poptContext pc; int debug_fd = -1; errno_t ret; TALLOC_CTX *main_ctx = NULL; char *cert; enum op_mode mode = OP_NONE; enum pin_mode pin_mode = PIN_NONE; char *pin = NULL; char *slot_name_in = NULL; char *token_name_out = NULL; char *nss_db = NULL; bool do_ocsp = true; char *verify_opts = NULL; struct poptOption long_options[] = { POPT_AUTOHELP {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, _("Debug level"), NULL}, {"debug-timestamps", 0, POPT_ARG_INT, &debug_timestamps, 0, _("Add debug timestamps"), NULL}, {"debug-microseconds", 0, POPT_ARG_INT, &debug_microseconds, 0, _("Show timestamps with microseconds"), NULL}, {"debug-fd", 0, POPT_ARG_INT, &debug_fd, 0, _("An open file descriptor for the debug logs"), NULL}, {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, _("Send the debug output to stderr directly."), NULL }, {"auth", 0, POPT_ARG_NONE, NULL, 'a', _("Run in auth mode"), NULL}, {"pre", 0, POPT_ARG_NONE, NULL, 'p', _("Run in pre-auth mode"), NULL}, {"pin", 0, POPT_ARG_NONE, NULL, 'i', _("Expect PIN on stdin"), NULL}, {"keypad", 0, POPT_ARG_NONE, NULL, 'k', _("Expect PIN on keypad"), NULL}, {"verify", 0, POPT_ARG_STRING, &verify_opts, 0 , _("Tune validation"), NULL}, {"nssdb", 0, POPT_ARG_STRING, &nss_db, 0, _("NSS DB to use"), NULL}, POPT_TABLEEND }; /* Set debug level to invalid value so we can decide if -d 0 was used. */ debug_level = SSSDBG_INVALID; /* * This child can run as root or as sssd user relying on policy kit to * grant access to pcscd. This means that no setuid or setgid bit must be * set on the binary. We still should make sure to run with a restrictive * umask but do not have to make additional precautions like clearing the * environment. This would allow to use e.g. pkcs11-spy.so for further * debugging. */ umask(SSS_DFL_X_UMASK); pc = poptGetContext(argv[0], argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { case 'a': if (mode != OP_NONE) { fprintf(stderr, "\n--auth and --pre are mutually exclusive and " \ "should be only used once.\n\n"); poptPrintUsage(pc, stderr, 0); _exit(-1); } mode = OP_AUTH; break; case 'p': if (mode != OP_NONE) { fprintf(stderr, "\n--auth and --pre are mutually exclusive and " \ "should be only used once.\n\n"); poptPrintUsage(pc, stderr, 0); _exit(-1); } mode = OP_PREAUTH; break; case 'i': if (pin_mode != PIN_NONE) { fprintf(stderr, "\n--pin and --keypad are mutually exclusive " \ "and should be only used once.\n\n"); poptPrintUsage(pc, stderr, 0); _exit(-1); } pin_mode = PIN_STDIN; break; case 'k': if (pin_mode != PIN_NONE) { fprintf(stderr, "\n--pin and --keypad are mutually exclusive " \ "and should be only used once.\n\n"); poptPrintUsage(pc, stderr, 0); _exit(-1); } pin_mode = PIN_KEYPAD; break; default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); _exit(-1); } } if (nss_db == NULL) { fprintf(stderr, "\nMissing NSS DB --nssdb must be specified.\n\n"); poptPrintUsage(pc, stderr, 0); _exit(-1); } if (mode == OP_NONE) { fprintf(stderr, "\nMissing operation mode, " \ "either --auth or --pre must be specified.\n\n"); poptPrintUsage(pc, stderr, 0); _exit(-1); } else if (mode == OP_AUTH && pin_mode == PIN_NONE) { fprintf(stderr, "\nMissing pin mode for authentication, " \ "either --pin or --keypad must be specified.\n"); poptPrintUsage(pc, stderr, 0); _exit(-1); } poptFreeContext(pc); DEBUG_INIT(debug_level); debug_prg_name = talloc_asprintf(NULL, "[sssd[p11_child[%d]]]", getpid()); if (debug_prg_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); goto fail; } if (debug_fd != -1) { ret = set_debug_file_from_fd(debug_fd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n"); } } DEBUG(SSSDBG_TRACE_FUNC, "p11_child started.\n"); DEBUG(SSSDBG_TRACE_INTERNAL, "Running in [%s] mode.\n", mode == OP_AUTH ? "auth" : (mode == OP_PREAUTH ? "pre-auth" : "unknown")); DEBUG(SSSDBG_TRACE_INTERNAL, "Running with effective IDs: [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid()); DEBUG(SSSDBG_TRACE_INTERNAL, "Running with real IDs [%"SPRIuid"][%"SPRIgid"].\n", getuid(), getgid()); main_ctx = talloc_new(NULL); if (main_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new failed.\n"); talloc_free(discard_const(debug_prg_name)); goto fail; } talloc_steal(main_ctx, debug_prg_name); if (verify_opts != NULL) { ret = parse_cert_verify_opts(verify_opts, &do_ocsp); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse verifiy option.\n"); goto fail; } } if (mode == OP_AUTH && pin_mode == PIN_STDIN) { ret = p11c_recv_data(main_ctx, STDIN_FILENO, &pin); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to read pin.\n"); goto fail; } } ret = do_work(main_ctx, nss_db, slot_name_in, mode, pin, do_ocsp, &cert, &token_name_out); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "do_work failed.\n"); goto fail; } if (cert != NULL) { fprintf(stdout, "%s\n", token_name_out); fprintf(stdout, "%s\n", cert); } talloc_free(main_ctx); return EXIT_SUCCESS; fail: DEBUG(SSSDBG_CRIT_FAILURE, "p11_child failed!\n"); close(STDOUT_FILENO); talloc_free(main_ctx); return EXIT_FAILURE; } sssd-1.13.4/src/PaxHeaders.16287/examples0000644000000000000000000000013012703463556014661 xustar0029 mtime=1460561774.62579353 30 atime=1460561776.119798596 29 ctime=1460561774.62579353 sssd-1.13.4/src/examples/0000755002412700241270000000000012703463556016414 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/examples/PaxHeaders.16287/sudo0000644000000000000000000000007412703456111015627 xustar0030 atime=1460561751.634715573 30 ctime=1460561774.376792686 sssd-1.13.4/src/examples/sudo0000644002412700241270000000026512703456111017301 0ustar00jhrozekjhrozek00000000000000#%PAM-1.0 auth required pam_sss.so account required pam_sss.so password required pam_sss.so session optional pam_keyinit.so revoke session required pam_limits.so sssd-1.13.4/src/examples/PaxHeaders.16287/sssd-example.conf0000644000000000000000000000007412703456111020206 xustar0030 atime=1460561751.634715573 30 ctime=1460561774.374792679 sssd-1.13.4/src/examples/sssd-example.conf0000644002412700241270000000356512703456111021666 0ustar00jhrozekjhrozek00000000000000[sssd] config_file_version = 2 services = nss, pam # SSSD will not start if you do not configure any domains. # Add new domain configurations as [domain/] sections, and # then add the list of domains (in the order you want them to be # queried) to the "domains" attribute below and uncomment it. ; domains = LDAP [nss] [pam] # Example LDAP domain ; [domain/LDAP] ; id_provider = ldap ; auth_provider = ldap # ldap_schema can be set to "rfc2307", which stores group member names in the # "memberuid" attribute, or to "rfc2307bis", which stores group member DNs in # the "member" attribute. If you do not know this value, ask your LDAP # administrator. ; ldap_schema = rfc2307 ; ldap_uri = ldap://ldap.mydomain.org ; ldap_search_base = dc=mydomain,dc=org # Note that enabling enumeration will have a moderate performance impact. # Consequently, the default value for enumeration is FALSE. # Refer to the sssd.conf man page for full details. ; enumerate = false # Allow offline logins by locally storing password hashes (default: false). ; cache_credentials = true # An example Active Directory domain. Please note that this configuration # works for AD 2003R2 and AD 2008, because they use pretty much RFC2307bis # compliant attribute names. To support UNIX clients with AD 2003 or older, # you must install Microsoft Services For Unix and map LDAP attributes onto # msSFU30* attribute names. ; [domain/AD] ; id_provider = ldap ; auth_provider = krb5 ; chpass_provider = krb5 ; ; ldap_uri = ldap://your.ad.example.com ; ldap_search_base = dc=example,dc=com ; ldap_schema = rfc2307bis ; ldap_sasl_mech = GSSAPI ; ldap_user_object_class = user ; ldap_group_object_class = group ; ldap_user_home_directory = unixHomeDirectory ; ldap_user_principal = userPrincipalName ; ldap_account_expire_policy = ad ; ldap_force_upper_case_realm = true ; ; krb5_server = your.ad.example.com ; krb5_realm = EXAMPLE.COM sssd-1.13.4/src/examples/PaxHeaders.16287/sssdproxytest0000644000000000000000000000007412703456111017633 xustar0030 atime=1460561751.634715573 30 ctime=1460561774.375792683 sssd-1.13.4/src/examples/sssdproxytest0000644002412700241270000000013012703456111021274 0ustar00jhrozekjhrozek00000000000000#%PAM-1.0 auth irequired pam_ldap.so account required pam_ldap.so sssd-1.13.4/src/examples/PaxHeaders.16287/rwtab.in0000644000000000000000000000007312703456111016400 xustar0030 atime=1460561772.573786573 29 ctime=1460561774.62579353 sssd-1.13.4/src/examples/rwtab.in0000644002412700241270000000003212703456111020043 0ustar00jhrozekjhrozek00000000000000dirs @sharedstatedir@/sss sssd-1.13.4/src/examples/PaxHeaders.16287/logrotate0000644000000000000000000000007312703456111016654 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.376792686 sssd-1.13.4/src/examples/logrotate0000644002412700241270000000035512703456111020327 0ustar00jhrozekjhrozek00000000000000/var/log/sssd/*.log { weekly missingok notifempty sharedscripts rotate 2 compress delaycompress postrotate /bin/kill -HUP `cat /var/run/sssd.pid 2>/dev/null` 2> /dev/null || true endscript } sssd-1.13.4/src/PaxHeaders.16287/m40000644000000000000000000000007412703456111013357 xustar0030 atime=1460561776.119798596 30 ctime=1460561774.381792703 sssd-1.13.4/src/m4/0000755002412700241270000000000012703456111015103 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/m4/PaxHeaders.16287/.dir0000644000000000000000000000007412703456111014213 xustar0030 atime=1460561751.635715576 30 ctime=1460561774.381792703 sssd-1.13.4/src/m4/.dir0000644002412700241270000000000012703456111015650 0ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/PaxHeaders.16287/responder0000644000000000000000000000013212703463556015046 xustar0030 mtime=1460561774.275792344 30 atime=1460561776.119798596 30 ctime=1460561774.275792344 sssd-1.13.4/src/responder/0000755002412700241270000000000012703463556016577 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/responder/PaxHeaders.16287/sudo0000644000000000000000000000013212703463557016021 xustar0030 mtime=1460561775.021794873 30 atime=1460561776.119798596 30 ctime=1460561775.021794873 sssd-1.13.4/src/responder/sudo/0000755002412700241270000000000012703463557017552 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/responder/sudo/PaxHeaders.16287/sudosrv_get_sudorules.c0000644000000000000000000000007412703456111022704 xustar0030 atime=1460561751.652715634 30 ctime=1460561775.019794866 sssd-1.13.4/src/responder/sudo/sudosrv_get_sudorules.c0000644002412700241270000006420712703456111024364 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Jakub Hrozek Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include "util/util.h" #include "db/sysdb_sudo.h" #include "responder/sudo/sudosrv_private.h" #include "providers/data_provider.h" static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx); errno_t sudosrv_get_sudorules(struct sudo_dom_ctx *dctx) { errno_t ret; dctx->check_provider = true; ret = sudosrv_get_user(dctx); if (ret == EAGAIN) { DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up the user info from Data Provider\n"); return EAGAIN; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error looking up user information [%d]: %s\n", ret, strerror(ret)); return ret; } /* OK, got the user from cache. Try to get the rules. */ ret = sudosrv_get_rules(dctx->cmd_ctx); if (ret == EAGAIN) { DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up the sudo rules from Data Provider\n"); return EAGAIN; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error looking up sudo rules [%d]: %s\n", ret, strerror(ret)); return ret; } return EOK; } static void sudosrv_dp_send_acct_req_done(struct tevent_req *req); static void sudosrv_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); static errno_t sudosrv_get_user(struct sudo_dom_ctx *dctx) { TALLOC_CTX *tmp_ctx = NULL; struct sss_domain_info *dom = dctx->domain; struct sudo_cmd_ctx *cmd_ctx = dctx->cmd_ctx; struct cli_ctx *cli_ctx = dctx->cmd_ctx->cli_ctx; struct ldb_result *user; time_t cache_expire = 0; struct tevent_req *dpreq; struct dp_callback_ctx *cb_ctx; const char *original_name = NULL; const char *extra_flag = NULL; const char *search_name = NULL; char *name = NULL; uid_t uid = 0; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } while (dom) { /* if it is a domainless search, skip domains that require fully * qualified names instead */ while (dom && cmd_ctx->check_next && dom->fqnames) { dom = get_next_domain(dom, 0); } if (!dom) break; /* make sure to update the dctx if we changed domain */ dctx->domain = dom; talloc_free(name); name = sss_get_cased_name(tmp_ctx, cmd_ctx->username, dom->case_sensitive); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); ret = ENOMEM; goto done; } name = sss_reverse_replace_space(tmp_ctx, name, cmd_ctx->sudo_ctx->rctx->override_space); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_reverse_replace_whitespaces failed\n"); return ENOMEM; } DEBUG(SSSDBG_FUNC_DATA, "Requesting info about [%s@%s]\n", name, dom->name); ret = sysdb_getpwnam_with_views(dctx, dctx->domain, name, &user); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to make request to our cache!\n"); ret = EIO; goto done; } if (user->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "getpwnam call returned more than one result !?!\n"); ret = EIO; goto done; } if (user->count == 0 && !dctx->check_provider) { /* if a multidomain search, try with next */ if (cmd_ctx->check_next) { dctx->check_provider = true; dom = get_next_domain(dom, 0); if (dom) continue; } DEBUG(SSSDBG_MINOR_FAILURE, "No results for getpwnam call\n"); ret = ENOENT; goto done; } /* One result found, check cache expiry */ if (user->count == 1) { cache_expire = ldb_msg_find_attr_as_uint64(user->msgs[0], SYSDB_CACHE_EXPIRE, 0); } /* If cache miss and we haven't checked DP yet OR the entry is * outdated, go to DP */ if ((user->count == 0 || cache_expire < time(NULL)) && dctx->check_provider) { search_name = cmd_ctx->username; if (is_local_view(dom->view_name)) { /* Search with original name in case of local view. */ if (user->count != 0) { search_name = ldb_msg_find_attr_as_string(user->msgs[0], SYSDB_NAME, NULL); } } else if (DOM_HAS_VIEWS(dom) && (user->count == 0 || ldb_msg_find_attr_as_string(user->msgs[0], OVERRIDE_PREFIX SYSDB_NAME, NULL) != NULL)) { extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; } dpreq = sss_dp_get_account_send(cli_ctx, cli_ctx->rctx, dom, false, SSS_DP_INITGROUPS, search_name, 0, extra_flag); if (!dpreq) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending data provider request\n"); ret = ENOMEM; goto done; } cb_ctx = talloc_zero(cli_ctx, struct dp_callback_ctx); if(!cb_ctx) { talloc_zfree(dpreq); ret = ENOMEM; goto done; } cb_ctx->callback = sudosrv_check_user_dp_callback; cb_ctx->ptr = dctx; cb_ctx->cctx = cli_ctx; cb_ctx->mem_ctx = cli_ctx; tevent_req_set_callback(dpreq, sudosrv_dp_send_acct_req_done, cb_ctx); /* tell caller we are in an async call */ ret = EAGAIN; goto done; } /* check uid */ uid = sss_view_ldb_msg_find_attr_as_uint64(dom, user->msgs[0], SYSDB_UIDNUM, 0); if (uid != cmd_ctx->uid) { /* if a multidomain search, try with next */ if (cmd_ctx->check_next) { dctx->check_provider = true; dom = get_next_domain(dom, 0); if (dom) continue; } DEBUG(SSSDBG_MINOR_FAILURE, "UID does not match\n"); ret = ENOENT; goto done; } /* user is stored in cache, remember cased and original name */ original_name = ldb_msg_find_attr_as_string(user->msgs[0], SYSDB_NAME, NULL); if (original_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "A user with no name?\n"); ret = EFAULT; goto done; } cmd_ctx->cased_username = talloc_move(cmd_ctx, &name); cmd_ctx->orig_username = talloc_strdup(cmd_ctx, original_name); if (cmd_ctx->orig_username == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); ret = ENOMEM; goto done; } /* and set domain */ cmd_ctx->domain = dom; DEBUG(SSSDBG_TRACE_FUNC, "Returning info for user [%s@%s]\n", cmd_ctx->username, dctx->domain->name); ret = EOK; goto done; } ret = ENOENT; done: talloc_free(tmp_ctx); return ret; } static void sudosrv_dp_send_acct_req_done(struct tevent_req *req) { struct dp_callback_ctx *cb_ctx = tevent_req_callback_data(req, struct dp_callback_ctx); errno_t ret; dbus_uint16_t err_maj; dbus_uint32_t err_min; char *err_msg; ret = sss_dp_get_account_recv(cb_ctx->mem_ctx, req, &err_maj, &err_min, &err_msg); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error, killing connection!\n"); talloc_free(cb_ctx->cctx); return; } cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr); } static void sudosrv_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr) { errno_t ret; struct sudo_dom_ctx *dctx = talloc_get_type(ptr, struct sudo_dom_ctx); if (err_maj) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get information from Data Provider\n" "Error: %u, %u, %s\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg); } DEBUG(SSSDBG_TRACE_INTERNAL, "Data Provider returned, check the cache again\n"); dctx->check_provider = false; ret = sudosrv_get_user(dctx); if (ret == EAGAIN) { goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not look up the user [%d]: %s\n", ret, strerror(ret)); sudosrv_cmd_done(dctx->cmd_ctx, ret); return; } DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up sudo rules..\n"); ret = sudosrv_get_rules(dctx->cmd_ctx); if (ret == EAGAIN) { goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error getting sudo rules [%d]: %s\n", ret, strerror(ret)); sudosrv_cmd_done(dctx->cmd_ctx, EIO); return; } done: sudosrv_cmd_done(dctx->cmd_ctx, ret); } static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx, struct sudo_cmd_ctx *cmd_ctx, struct sysdb_attrs ***_rules, uint32_t *_num_rules); static void sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); static void sudosrv_dp_req_done(struct tevent_req *req); static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char **attrs, unsigned int flags, const char *username, uid_t uid, char **groupnames, bool inverse_order, struct sysdb_attrs ***_rules, uint32_t *_count); errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx) { TALLOC_CTX *tmp_ctx = NULL; struct tevent_req *dpreq = NULL; struct dp_callback_ctx *cb_ctx = NULL; char **groupnames = NULL; uint32_t expired_rules_num = 0; struct sysdb_attrs **expired_rules = NULL; errno_t ret; unsigned int flags = SYSDB_SUDO_FILTER_NONE; const char *attrs[] = { SYSDB_NAME, NULL }; if (cmd_ctx->domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Domain is not set!\n"); return EFAULT; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } switch (cmd_ctx->type) { case SSS_SUDO_DEFAULTS: DEBUG(SSSDBG_TRACE_FUNC, "Retrieving default options " "for [%s] from [%s]\n", cmd_ctx->orig_username, cmd_ctx->domain->name); break; case SSS_SUDO_USER: DEBUG(SSSDBG_TRACE_FUNC, "Retrieving rules " "for [%s] from [%s]\n", cmd_ctx->orig_username, cmd_ctx->domain->name); break; } /* Fetch all expired rules: * sudo asks sssd twice - for defaults and for rules. If we refresh all * expired rules for this user and defaults at once we will save one * provider call */ ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->domain, cmd_ctx->orig_username, NULL, &groupnames); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve user info [%d]: %s\n", ret, strerror(ret)); goto done; } flags = SYSDB_SUDO_FILTER_INCLUDE_ALL | SYSDB_SUDO_FILTER_INCLUDE_DFL | SYSDB_SUDO_FILTER_ONLY_EXPIRED | SYSDB_SUDO_FILTER_USERINFO; ret = sudosrv_get_sudorules_query_cache(tmp_ctx, cmd_ctx->domain, attrs, flags, cmd_ctx->orig_username, cmd_ctx->uid, groupnames, cmd_ctx->sudo_ctx->inverse_order, &expired_rules, &expired_rules_num); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve expired sudo rules " "[%d]: %s\n", ret, strerror(ret)); goto done; } cmd_ctx->expired_rules_num = expired_rules_num; if (expired_rules_num > 0) { /* refresh expired rules then continue */ DEBUG(SSSDBG_TRACE_INTERNAL, "Refreshing %d expired rules\n", expired_rules_num); dpreq = sss_dp_get_sudoers_send(tmp_ctx, cmd_ctx->cli_ctx->rctx, cmd_ctx->domain, false, SSS_DP_SUDO_REFRESH_RULES, cmd_ctx->orig_username, expired_rules_num, expired_rules); if (dpreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot issue DP request.\n"); ret = EIO; goto done; } cb_ctx = talloc_zero(tmp_ctx, struct dp_callback_ctx); if (!cb_ctx) { talloc_zfree(dpreq); ret = ENOMEM; goto done; } cb_ctx->callback = sudosrv_get_sudorules_dp_callback; cb_ctx->ptr = cmd_ctx; cb_ctx->cctx = cmd_ctx->cli_ctx; cb_ctx->mem_ctx = cmd_ctx; tevent_req_set_callback(dpreq, sudosrv_dp_req_done, cb_ctx); ret = EAGAIN; } else { /* nothing is expired return what we have in the cache */ DEBUG(SSSDBG_TRACE_INTERNAL, "About to get sudo rules from cache\n"); ret = sudosrv_get_sudorules_from_cache(cmd_ctx, cmd_ctx, &cmd_ctx->rules, &cmd_ctx->num_rules); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to make a request to our cache [%d]: %s\n", ret, strerror(ret)); goto done; } } if (dpreq != NULL) { talloc_steal(cmd_ctx->cli_ctx, dpreq); } if (cb_ctx != NULL) { talloc_steal(cmd_ctx, cb_ctx); } done: talloc_free(tmp_ctx); return ret; } static void sudosrv_dp_req_done(struct tevent_req *req) { struct dp_callback_ctx *cb_ctx = tevent_req_callback_data(req, struct dp_callback_ctx); struct cli_ctx *cli_ctx; errno_t ret; dbus_uint16_t err_maj; dbus_uint32_t err_min; char *err_msg; cli_ctx = talloc_get_type(cb_ctx->cctx, struct cli_ctx); ret = sss_dp_get_sudoers_recv(cb_ctx->mem_ctx, req, &err_maj, &err_min, &err_msg); talloc_free(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error, killing connection!\n"); talloc_free(cli_ctx); return; } cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr); } static void sudosrv_dp_oob_req_done(struct tevent_req *req) { DEBUG(SSSDBG_TRACE_FUNC, "Out of band refresh finished\n"); talloc_free(req); } static void sudosrv_get_sudorules_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr) { struct sudo_cmd_ctx *cmd_ctx = talloc_get_type(ptr, struct sudo_cmd_ctx); struct tevent_req *dpreq = NULL; errno_t ret; if (err_maj) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get information from Data Provider\n" "Error: %u, %u, %s\n" "Will try to return what we have in cache\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg); } DEBUG(SSSDBG_TRACE_INTERNAL, "About to get sudo rules from cache\n"); ret = sudosrv_get_sudorules_from_cache(cmd_ctx, cmd_ctx, &cmd_ctx->rules, &cmd_ctx->num_rules); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to make a request to our cache [%d]: %s\n", ret, strerror(ret)); sudosrv_cmd_done(cmd_ctx, EIO); return; } if (cmd_ctx->expired_rules_num > 0 && err_min == ENOENT) { DEBUG(SSSDBG_TRACE_INTERNAL, "Some expired rules were removed from the server, " "scheduling full refresh out of band\n"); dpreq = sss_dp_get_sudoers_send(cmd_ctx->cli_ctx->rctx, cmd_ctx->cli_ctx->rctx, cmd_ctx->domain, false, SSS_DP_SUDO_FULL_REFRESH, cmd_ctx->orig_username, 0, NULL); if (dpreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot issue DP request.\n"); } else { tevent_req_set_callback(dpreq, sudosrv_dp_oob_req_done, NULL); } } sudosrv_cmd_done(cmd_ctx, ret); } static errno_t sudosrv_get_sudorules_from_cache(TALLOC_CTX *mem_ctx, struct sudo_cmd_ctx *cmd_ctx, struct sysdb_attrs ***_rules, uint32_t *_num_rules) { TALLOC_CTX *tmp_ctx; errno_t ret; char **groupnames = NULL; const char *debug_name = NULL; unsigned int flags = SYSDB_SUDO_FILTER_NONE; struct sysdb_attrs **rules = NULL; uint32_t num_rules = 0; const char *attrs[] = { SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_AT_CN, SYSDB_SUDO_CACHE_AT_USER, SYSDB_SUDO_CACHE_AT_HOST, SYSDB_SUDO_CACHE_AT_COMMAND, SYSDB_SUDO_CACHE_AT_OPTION, SYSDB_SUDO_CACHE_AT_RUNAS, SYSDB_SUDO_CACHE_AT_RUNASUSER, SYSDB_SUDO_CACHE_AT_RUNASGROUP, SYSDB_SUDO_CACHE_AT_NOTBEFORE, SYSDB_SUDO_CACHE_AT_NOTAFTER, SYSDB_SUDO_CACHE_AT_ORDER, NULL }; if (cmd_ctx->domain == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Domain is not set!\n"); return EFAULT; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } switch (cmd_ctx->type) { case SSS_SUDO_USER: debug_name = cmd_ctx->cased_username; ret = sysdb_get_sudo_user_info(tmp_ctx, cmd_ctx->domain, cmd_ctx->orig_username, NULL, &groupnames); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve user info [%d]: %s\n", ret, strerror(ret)); goto done; } flags = SYSDB_SUDO_FILTER_USERINFO | SYSDB_SUDO_FILTER_INCLUDE_ALL; break; case SSS_SUDO_DEFAULTS: debug_name = ""; flags = SYSDB_SUDO_FILTER_INCLUDE_DFL; break; } ret = sudosrv_get_sudorules_query_cache(tmp_ctx, cmd_ctx->domain, attrs, flags, cmd_ctx->orig_username, cmd_ctx->uid, groupnames, cmd_ctx->sudo_ctx->inverse_order, &rules, &num_rules); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve sudo rules [%d]: %s\n", ret, strerror(ret)); goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Returning %d rules for [%s@%s]\n", num_rules, debug_name, cmd_ctx->domain->name); if (_rules != NULL) { *_rules = talloc_steal(mem_ctx, rules); } if (_num_rules != NULL) { *_num_rules = num_rules; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t sort_sudo_rules(struct sysdb_attrs **rules, size_t count, bool higher_wins); static errno_t sudosrv_get_sudorules_query_cache(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char **attrs, unsigned int flags, const char *username, uid_t uid, char **groupnames, bool inverse_order, struct sysdb_attrs ***_rules, uint32_t *_count) { TALLOC_CTX *tmp_ctx; char *filter; errno_t ret; size_t count; struct sysdb_attrs **rules; struct ldb_message **msgs; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) return ENOMEM; ret = sysdb_get_sudo_filter(tmp_ctx, username, uid, groupnames, flags, &filter); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct the search filter [%d]: %s\n", ret, strerror(ret)); goto done; } DEBUG(SSSDBG_FUNC_DATA, "Searching sysdb with [%s]\n", filter); if (IS_SUBDOMAIN(domain)) { /* rules are stored inside parent domain tree */ domain = domain->parent; } ret = sysdb_search_custom(tmp_ctx, domain, filter, SUDORULE_SUBDIR, attrs, &count, &msgs); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up SUDO rules\n"); goto done; } if (ret == ENOENT) { *_rules = NULL; *_count = 0; ret = EOK; goto done; } ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &rules); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not convert ldb message to sysdb_attrs\n"); goto done; } ret = sort_sudo_rules(rules, count, inverse_order); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not sort rules by sudoOrder\n"); goto done; } *_rules = talloc_steal(mem_ctx, rules); *_count = (uint32_t)count; ret = EOK; done: talloc_free(tmp_ctx); return ret; } static int sudo_order_cmp(const void *a, const void *b, bool lower_wins) { struct sysdb_attrs *r1, *r2; uint32_t o1, o2; int ret; r1 = * (struct sysdb_attrs * const *) a; r2 = * (struct sysdb_attrs * const *) b; if (!r1 || !r2) { DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Wrong data?\n"); return 0; } ret = sysdb_attrs_get_uint32_t(r1, SYSDB_SUDO_CACHE_AT_ORDER, &o1); if (ret == ENOENT) { /* man sudoers-ldap: If the sudoOrder attribute is not present, * a value of 0 is assumed */ o1 = 0; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get sudoOrder value\n"); return 0; } ret = sysdb_attrs_get_uint32_t(r2, SYSDB_SUDO_CACHE_AT_ORDER, &o2); if (ret == ENOENT) { /* man sudoers-ldap: If the sudoOrder attribute is not present, * a value of 0 is assumed */ o2 = 0; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get sudoOrder value\n"); return 0; } if (lower_wins) { /* The lowest value takes priority. Original wrong SSSD behaviour. */ if (o1 > o2) { return 1; } else if (o1 < o2) { return -1; } } else { /* The higher value takes priority. Standard LDAP behaviour. */ if (o1 < o2) { return 1; } else if (o1 > o2) { return -1; } } return 0; } static int sudo_order_low_cmp_fn(const void *a, const void *b) { return sudo_order_cmp(a, b, true); } static int sudo_order_high_cmp_fn(const void *a, const void *b) { return sudo_order_cmp(a, b, false); } static errno_t sort_sudo_rules(struct sysdb_attrs **rules, size_t count, bool lower_wins) { if (lower_wins) { DEBUG(SSSDBG_TRACE_FUNC, "Sorting rules with lower-wins logic\n"); qsort(rules, count, sizeof(struct sysdb_attrs *), sudo_order_low_cmp_fn); } else { DEBUG(SSSDBG_TRACE_FUNC, "Sorting rules with higher-wins logic\n"); qsort(rules, count, sizeof(struct sysdb_attrs *), sudo_order_high_cmp_fn); } return EOK; } sssd-1.13.4/src/responder/sudo/PaxHeaders.16287/sudosrv.c0000644000000000000000000000007412703456111017740 xustar0030 atime=1460561751.652715634 30 ctime=1460561775.017794859 sssd-1.13.4/src/responder/sudo/sudosrv.c0000644002412700241270000001724412703456111021417 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "confdb/confdb.h" #include "monitor/monitor_interfaces.h" #include "responder/common/responder.h" #include "responder/common/responder_sbus.h" #include "responder/sudo/sudosrv_private.h" #include "providers/data_provider.h" #include "responder/common/negcache.h" struct mon_cli_iface monitor_sudo_methods = { { &mon_cli_iface_meta, 0 }, .ping = monitor_common_pong, .resInit = monitor_common_res_init, .shutDown = NULL, .goOffline = NULL, .resetOffline = NULL, .rotateLogs = responder_logrotate, .clearMemcache = NULL, .clearEnumCache = NULL, .sysbusReconnect = NULL, }; static struct data_provider_iface sudo_dp_methods = { { &data_provider_iface_meta, 0 }, .RegisterService = NULL, .pamHandler = NULL, .sudoHandler = NULL, .autofsHandler = NULL, .hostHandler = NULL, .getDomains = NULL, .getAccountInfo = NULL, }; static void sudo_dp_reconnect_init(struct sbus_connection *conn, int status, void *pvt) { struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn); int ret; /* Did we reconnect successfully? */ if (status == SBUS_RECONNECT_SUCCESS) { DEBUG(SSSDBG_TRACE_FUNC, "Reconnected to the Data Provider.\n"); /* Identify ourselves to the data provider */ ret = dp_common_send_id(be_conn->conn, DATA_PROVIDER_VERSION, "SUDO"); /* all fine */ if (ret == EOK) { handle_requests_after_reconnect(be_conn->rctx); return; } } /* Failed to reconnect */ DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n", be_conn->domain->name); } int sudo_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb) { struct resp_ctx *rctx; struct sss_cmd_table *sudo_cmds; struct sudo_ctx *sudo_ctx; struct be_conn *iter; int ret; int max_retries; sudo_cmds = get_sudo_cmds(); ret = sss_process_init(mem_ctx, ev, cdb, sudo_cmds, SSS_SUDO_SOCKET_NAME, -1, NULL, -1, CONFDB_SUDO_CONF_ENTRY, SSS_SUDO_SBUS_SERVICE_NAME, SSS_SUDO_SBUS_SERVICE_VERSION, &monitor_sudo_methods, "SUDO", &sudo_dp_methods.vtable, &rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n"); return ret; } sudo_ctx = talloc_zero(rctx, struct sudo_ctx); if (!sudo_ctx) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing sudo_ctx\n"); ret = ENOMEM; goto fail; } ret = sss_ncache_init(rctx, &sudo_ctx->ncache); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing ncache\n"); goto fail; } sudo_ctx->rctx = rctx; sudo_ctx->rctx->pvt_ctx = sudo_ctx; ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_ENTRY_NEG_TIMEOUT, 15, &sudo_ctx->neg_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error getting ncache timeout\n"); goto fail; } sss_ncache_prepopulate(sudo_ctx->ncache, sudo_ctx->rctx->cdb, rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "failed to set ncache for sudo's filter_users\n"); goto fail; } /* Enable automatic reconnection to the Data Provider */ ret = confdb_get_int(sudo_ctx->rctx->cdb, CONFDB_SUDO_CONF_ENTRY, CONFDB_SERVICE_RECON_RETRIES, 3, &max_retries); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up automatic reconnection\n"); goto fail; } for (iter = sudo_ctx->rctx->be_conns; iter; iter = iter->next) { sbus_reconnect_init(iter->conn, max_retries, sudo_dp_reconnect_init, iter); } /* Get sudo_timed option */ ret = confdb_get_bool(sudo_ctx->rctx->cdb, CONFDB_SUDO_CONF_ENTRY, CONFDB_SUDO_TIMED, CONFDB_DEFAULT_SUDO_TIMED, &sudo_ctx->timed); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n", ret, strerror(ret)); goto fail; } /* Get sudo_inverse_order option */ ret = confdb_get_bool(sudo_ctx->rctx->cdb, CONFDB_SUDO_CONF_ENTRY, CONFDB_SUDO_INVERSE_ORDER, CONFDB_DEFAULT_SUDO_INVERSE_ORDER, &sudo_ctx->inverse_order); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n", ret, strerror(ret)); goto fail; } ret = schedule_get_domains_task(rctx, rctx->ev, rctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "SUDO Initialization complete\n"); return EOK; fail: talloc_free(rctx); return ret; } int main(int argc, const char *argv[]) { int opt; poptContext pc; struct main_context *main_ctx; int ret; uid_t uid; gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; umask(DFL_RSP_UMASK); pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_INIT(debug_level); /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_sudo"; ret = server_setup("sssd[sudo]", 0, uid, gid, CONFDB_SUDO_CONF_ENTRY, &main_ctx); if (ret != EOK) { return 2; } ret = die_if_parent_died(); if (ret != EOK) { /* This is not fatal, don't return */ DEBUG(SSSDBG_OP_FAILURE, "Could not set up to exit " "when parent process does\n"); } ret = sudo_process_init(main_ctx, main_ctx->event_ctx, main_ctx->confdb_ctx); if (ret != EOK) { return 3; } /* loop on main */ server_loop(main_ctx); return 0; } sssd-1.13.4/src/responder/sudo/PaxHeaders.16287/sudosrv_query.c0000644000000000000000000000007312703456111021164 xustar0030 atime=1460561751.652715634 29 ctime=1460561775.02079487 sssd-1.13.4/src/responder/sudo/sudosrv_query.c0000644002412700241270000003145412703456111022643 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "responder/sudo/sudosrv_private.h" static int sudosrv_response_append_string(TALLOC_CTX *mem_ctx, const char *str, size_t str_len, uint8_t **_response_body, size_t *_response_len) { size_t response_len = *_response_len; uint8_t *response_body = *_response_body; response_body = talloc_realloc(mem_ctx, response_body, uint8_t, response_len + (str_len * sizeof(char))); if (response_body == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_realloc() failed\n"); return ENOMEM; } memcpy(response_body + response_len, str, str_len); response_len += str_len; *_response_body = response_body; *_response_len = response_len; return EOK; } static int sudosrv_response_append_uint32(TALLOC_CTX *mem_ctx, uint32_t number, uint8_t **_response_body, size_t *_response_len) { size_t response_len = *_response_len; uint8_t *response_body = *_response_body; response_body = talloc_realloc(mem_ctx, response_body, uint8_t, response_len + sizeof(uint32_t)); if (response_body == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_realloc() failed\n"); return ENOMEM; } SAFEALIGN_SET_UINT32(response_body + response_len, number, &response_len); *_response_body = response_body; *_response_len = response_len; return EOK; } static int sudosrv_response_append_attr(TALLOC_CTX *mem_ctx, const char *name, unsigned int values_num, struct ldb_val *values, uint8_t **_response_body, size_t *_response_len) { uint8_t *response_body = *_response_body; size_t response_len = *_response_len; TALLOC_CTX *tmp_ctx = NULL; int i = 0; int ret = EOK; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } /* attr name */ ret = sudosrv_response_append_string(tmp_ctx, name, strlen(name) + 1, &response_body, &response_len); if (ret != EOK) { goto done; } /* values count */ ret = sudosrv_response_append_uint32(tmp_ctx, values_num, &response_body, &response_len); if (ret != EOK) { goto done; } /* values */ for (i = 0; i < values_num; i++) { if (strlen((char*)(values[i].data)) != values[i].length) { DEBUG(SSSDBG_CRIT_FAILURE, "value is not a string\n"); ret = EINVAL; goto done; } ret = sudosrv_response_append_string(tmp_ctx, (const char*)values[i].data, values[i].length + 1, &response_body, &response_len); if (ret != EOK) { goto done; } } *_response_body = talloc_steal(mem_ctx, response_body); *_response_len = response_len; ret = EOK; done: talloc_free(tmp_ctx); return ret; } static int sudosrv_response_append_rule(TALLOC_CTX *mem_ctx, int attrs_num, struct ldb_message_element *attrs, uint8_t **_response_body, size_t *_response_len) { uint8_t *response_body = *_response_body; size_t response_len = *_response_len; TALLOC_CTX *tmp_ctx = NULL; int i = 0; int ret = EOK; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } /* attrs count */ ret = sudosrv_response_append_uint32(tmp_ctx, attrs_num, &response_body, &response_len); if (ret != EOK) { goto done; } /* attrs */ for (i = 0; i < attrs_num; i++) { ret = sudosrv_response_append_attr(tmp_ctx, attrs[i].name, attrs[i].num_values, attrs[i].values, &response_body, &response_len); if (ret != EOK) { goto done; } } *_response_body = talloc_steal(mem_ctx, response_body); *_response_len = response_len; ret = EOK; done: talloc_free(tmp_ctx); return ret; } /* * Response format: * \0... * = ... * = \0\0\0... * * if is not SSS_SUDO_ERROR_OK, the rest of the data is skipped. */ errno_t sudosrv_build_response(TALLOC_CTX *mem_ctx, uint32_t error, uint32_t rules_num, struct sysdb_attrs **rules, uint8_t **_response_body, size_t *_response_len) { uint8_t *response_body = NULL; size_t response_len = 0; TALLOC_CTX *tmp_ctx = NULL; uint32_t i = 0; errno_t ret = EOK; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return ENOMEM; } /* error code */ ret = sudosrv_response_append_uint32(tmp_ctx, error, &response_body, &response_len); if (ret != EOK) { goto fail; } if (error != SSS_SUDO_ERROR_OK) { goto done; } /* domain name - deprecated * TODO: when possible change the protocol */ ret = sudosrv_response_append_string(tmp_ctx, "\0", 1, &response_body, &response_len); if (ret != EOK) { goto fail; } /* rules count */ ret = sudosrv_response_append_uint32(tmp_ctx, rules_num, &response_body, &response_len); if (ret != EOK) { goto fail; } /* rules */ for (i = 0; i < rules_num; i++) { ret = sudosrv_response_append_rule(tmp_ctx, rules[i]->num, rules[i]->a, &response_body, &response_len); if (ret != EOK) { goto fail; } } done: *_response_body = talloc_steal(mem_ctx, response_body); *_response_len = response_len; ret = EOK; fail: talloc_free(tmp_ctx); return ret; } struct sudosrv_parse_query_state { struct resp_ctx *rctx; uid_t uid; char *rawname; }; static void sudosrv_parse_query_done(struct tevent_req *subreq); struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, uint8_t *query_body, size_t query_len) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; struct sudosrv_parse_query_state *state = NULL; size_t offset = 0; size_t rawname_len = 0; char *rawname = NULL; char *domainname = NULL; errno_t ret; /* create request */ req = tevent_req_create(mem_ctx, &state, struct sudosrv_parse_query_state); if (req == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "tevent_req_create() failed\n"); return NULL; } state->rctx = rctx; /* uid */ if (query_len < sizeof(uid_t)) { DEBUG(SSSDBG_CRIT_FAILURE, "Query is too small\n"); ret = EINVAL; goto done; } safealign_memcpy(&state->uid, query_body, sizeof(uid_t), &offset); /* username[@domain] */ rawname = (char*)(query_body + offset); rawname_len = query_len - offset; /* strlen + zero */ if (rawname[rawname_len - 1] != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Username is not zero terminated\n"); ret = EINVAL; goto done; } if (rawname_len < 2) { /* at least one character and zero */ DEBUG(SSSDBG_CRIT_FAILURE, "Query does not contain username\n"); ret = EINVAL; goto done; } if (!sss_utf8_check((uint8_t*)rawname, rawname_len - 1)) { DEBUG(SSSDBG_CRIT_FAILURE, "Supplied data is not valid UTF-8 string\n"); ret = EINVAL; goto done; } /* parse username */ state->rawname = rawname; ret = sss_parse_name_for_domains(state, rctx->domains, rctx->default_domain, state->rawname, &domainname, NULL); if (ret == EAGAIN) { DEBUG(SSSDBG_TRACE_FUNC, "Domain [%s] not found, " "sending subdomain request\n", domainname); subreq = sss_dp_get_domains_send(state, rctx, true, domainname); if (subreq == NULL) { ret = ENOMEM; } else { tevent_req_set_callback(subreq, sudosrv_parse_query_done, req); ret = EAGAIN; } goto done; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid name received [%s]\n", rawname); goto done; } ret = EOK; done: if (ret != EAGAIN) { if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, rctx->ev); } return req; } static void sudosrv_parse_query_done(struct tevent_req *subreq) { struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); ret = sss_dp_get_domains_recv(subreq); talloc_free(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } tevent_req_done(req); } errno_t sudosrv_parse_query_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, uid_t *_uid, char **_username, struct sss_domain_info **_domain) { struct sudosrv_parse_query_state *state = NULL; struct sss_domain_info *domain = NULL; char *username = NULL; char *domainname = NULL; errno_t ret; state = tevent_req_data(req, struct sudosrv_parse_query_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (state->rawname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No query specified?!\n"); return EINVAL; } /* Try to parse username@domain again because if the first call * returned EAGAIN, then username is unset. If we get EAGAIN again, * we will not search for it again. */ ret = sss_parse_name_for_domains(state, state->rctx->domains, state->rctx->default_domain, state->rawname, &domainname, &username); if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Unable to parse domain [%d]: %s\n", ret, strerror(ret)); return ret; } if (username == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No username specified!\n"); return EINVAL; } if (domainname != NULL) { /* mem_ctx because it duplicates only subdomains not domains * so I cannot easily steal it */ domain = responder_get_domain(state->rctx, domainname); if (domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Corresponding domain [%s] has not been " "found\n", domainname); return ENOENT; } } *_uid = state->uid; *_username = talloc_steal(mem_ctx, username); *_domain = domain; /* do not steal on mem_ctx */ return EOK; } sssd-1.13.4/src/responder/sudo/PaxHeaders.16287/sudosrv_private.h0000644000000000000000000000007412703456111021477 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.474793018 sssd-1.13.4/src/responder/sudo/sudosrv_private.h0000644002412700241270000000712312703456111023151 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SUDOSRV_PRIVATE_H_ #define _SUDOSRV_PRIVATE_H_ #include #include #include #include "src/db/sysdb.h" #include "responder/common/responder.h" #define SSS_SUDO_ERROR_OK 0 enum sss_dp_sudo_type { SSS_DP_SUDO_REFRESH_RULES, SSS_DP_SUDO_FULL_REFRESH }; enum sss_sudo_type { SSS_SUDO_DEFAULTS, SSS_SUDO_USER }; struct sudo_ctx { struct resp_ctx *rctx; int neg_timeout; struct sss_nc_ctx *ncache; /* * options */ bool timed; bool inverse_order; }; struct sudo_cmd_ctx { struct cli_ctx *cli_ctx; struct sudo_ctx *sudo_ctx; enum sss_sudo_type type; /* input data */ uid_t uid; char *username; const char *orig_username; const char *cased_username; struct sss_domain_info *domain; bool check_next; uint32_t expired_rules_num; /* output data */ struct sysdb_attrs **rules; uint32_t num_rules; }; struct sudo_dom_ctx { struct sudo_cmd_ctx *cmd_ctx; struct sss_domain_info *domain; bool check_provider; }; struct sudo_dp_request { struct cli_ctx *cctx; struct sss_domain_info *domain; }; struct sss_cmd_table *get_sudo_cmds(void); errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret); errno_t sudosrv_get_sudorules(struct sudo_dom_ctx *dctx); errno_t sudosrv_get_rules(struct sudo_cmd_ctx *cmd_ctx); struct tevent_req *sudosrv_parse_query_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, uint8_t *query_body, size_t query_len); errno_t sudosrv_parse_query_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, uid_t *_uid, char **_username, struct sss_domain_info **_domain); errno_t sudosrv_build_response(TALLOC_CTX *mem_ctx, uint32_t error, uint32_t rules_num, struct sysdb_attrs **rules, uint8_t **_response_body, size_t *_response_len); struct tevent_req * sss_dp_get_sudoers_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, bool fast_reply, enum sss_dp_sudo_type type, const char *name, uint32_t num_rules, struct sysdb_attrs **rules); errno_t sss_dp_get_sudoers_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, dbus_uint16_t *err_maj, dbus_uint32_t *err_min, char **err_msg); #endif /* _SUDOSRV_PRIVATE_H_ */ sssd-1.13.4/src/responder/sudo/PaxHeaders.16287/sudosrv_dp.c0000644000000000000000000000007412703456111020423 xustar0030 atime=1460561751.652715634 30 ctime=1460561775.021794873 sssd-1.13.4/src/responder/sudo/sudosrv_dp.c0000644002412700241270000001415612703456111022101 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Jakub Hrozek Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "sbus/sssd_dbus.h" #include "util/util.h" #include "sbus/sbus_client.h" #include "providers/data_provider.h" #include "responder/common/responder.h" #include "responder/sudo/sudosrv_private.h" #include "db/sysdb.h" struct sss_dp_get_sudoers_info { struct sss_domain_info *dom; bool fast_reply; enum sss_dp_sudo_type type; const char *name; uint32_t num_rules; struct sysdb_attrs **rules; }; static DBusMessage * sss_dp_get_sudoers_msg(void *pvt); struct tevent_req * sss_dp_get_sudoers_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, bool fast_reply, enum sss_dp_sudo_type type, const char *name, uint32_t num_rules, struct sysdb_attrs **rules) { struct tevent_req *req; struct sss_dp_req_state *state; struct sss_dp_get_sudoers_info *info; errno_t ret; char *key = NULL; req = tevent_req_create(mem_ctx, &state, struct sss_dp_req_state); if (!req) { ret = ENOMEM; goto error; } if (!dom) { ret = EINVAL; goto error; } info = talloc_zero(state, struct sss_dp_get_sudoers_info); info->fast_reply = fast_reply; info->type = type; info->name = name; info->dom = dom; info->num_rules = num_rules; info->rules = rules; switch (info->type) { case SSS_DP_SUDO_REFRESH_RULES: key = talloc_asprintf(state, "%d:%u:%s@%s", type, num_rules, name, dom->name); break; case SSS_DP_SUDO_FULL_REFRESH: key = talloc_asprintf(state, "%d:%s", type, dom->name); break; } if (!key) { ret = ENOMEM; goto error; } ret = sss_dp_issue_request(state, rctx, key, dom, sss_dp_get_sudoers_msg, info, req); talloc_free(key); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not issue DP request [%d]: %s\n", ret, strerror(ret)); goto error; } return req; error: tevent_req_error(req, ret); tevent_req_post(req, rctx->ev); return req; } static DBusMessage * sss_dp_get_sudoers_msg(void *pvt) { DBusMessage *msg; DBusMessageIter iter; DBusMessageIter array_iter; dbus_bool_t dbret; errno_t ret; struct sss_dp_get_sudoers_info *info; uint32_t be_type = 0; const char *rule_name = NULL; uint32_t i; info = talloc_get_type(pvt, struct sss_dp_get_sudoers_info); switch (info->type) { case SSS_DP_SUDO_REFRESH_RULES: be_type = BE_REQ_SUDO_RULES; break; case SSS_DP_SUDO_FULL_REFRESH: be_type = BE_REQ_SUDO_FULL; break; } if (info->fast_reply) { be_type |= BE_REQ_FAST; } msg = dbus_message_new_method_call(NULL, DP_PATH, DATA_PROVIDER_IFACE, DATA_PROVIDER_IFACE_SUDOHANDLER); if (msg == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); return NULL; } /* create the message */ DEBUG(SSSDBG_TRACE_FUNC, "Creating SUDOers request for [%s][%u][%s][%u]\n", info->dom->name, be_type, info->name, info->num_rules); dbus_message_iter_init_append(msg, &iter); /* BE TYPE */ dbret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &be_type); if (dbret == FALSE) { goto fail; } /* BE TYPE SPECIFIC */ if (be_type & BE_REQ_SUDO_RULES) { dbret = dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &info->num_rules); if (dbret == FALSE) { goto fail; } dbret = dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array_iter); if (dbret == FALSE) { goto fail; } for (i = 0; i < info->num_rules; i++) { ret = sysdb_attrs_get_string(info->rules[i], SYSDB_NAME, &rule_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not get rule name [%d]: %s\n", ret, strerror(ret)); goto fail; } dbret = dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &rule_name); if (dbret == FALSE) { goto fail; } } dbret = dbus_message_iter_close_container(&iter, &array_iter); if (dbret == FALSE) { goto fail; } } return msg; fail: DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n"); dbus_message_unref(msg); return NULL; } errno_t sss_dp_get_sudoers_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret, char **err_msg) { return sss_dp_req_recv(mem_ctx, req, dp_err, dp_ret, err_msg); } sssd-1.13.4/src/responder/sudo/PaxHeaders.16287/sudosrv_cmd.c0000644000000000000000000000007412703456111020563 xustar0030 atime=1460561751.652715634 30 ctime=1460561775.018794863 sssd-1.13.4/src/responder/sudo/sudosrv_cmd.c0000644002412700241270000002324412703456111022237 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "util/util.h" #include "responder/common/responder.h" #include "responder/common/responder_packet.h" #include "responder/sudo/sudosrv_private.h" #include "db/sysdb_sudo.h" #include "sss_client/sss_cli.h" #include "responder/common/negcache.h" static errno_t sudosrv_cmd_send_reply(struct sudo_cmd_ctx *cmd_ctx, uint8_t *response_body, size_t response_len) { errno_t ret; uint8_t *packet_body = NULL; size_t packet_len = 0; struct cli_ctx *cli_ctx = cmd_ctx->cli_ctx; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; ret = sss_packet_new(cli_ctx->creq, 0, sss_packet_get_cmd(cli_ctx->creq->in), &cli_ctx->creq->out); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create a new packet [%d]; %s\n", ret, strerror(ret)); goto done; } ret = sss_packet_grow(cli_ctx->creq->out, response_len); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create response: %s\n", strerror(ret)); goto done; } sss_packet_get_body(cli_ctx->creq->out, &packet_body, &packet_len); memcpy(packet_body, response_body, response_len); sss_packet_set_error(cli_ctx->creq->out, EOK); sss_cmd_done(cmd_ctx->cli_ctx, cmd_ctx); ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } static errno_t sudosrv_cmd_send_error(TALLOC_CTX *mem_ctx, struct sudo_cmd_ctx *cmd_ctx, uint32_t error) { uint8_t *response_body = NULL; size_t response_len = 0; int ret = EOK; if (error == EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Everything is fine but we are " "returning error?\n"); return EFAULT; } ret = sudosrv_build_response(mem_ctx, error, 0, NULL, &response_body, &response_len); if (ret != EOK) { return ret; } return sudosrv_cmd_send_reply(cmd_ctx, response_body, response_len); } errno_t sudosrv_cmd_done(struct sudo_cmd_ctx *cmd_ctx, int ret) { uint8_t *response_body = NULL; size_t response_len = 0; uint32_t num_rules = cmd_ctx->num_rules; struct sysdb_attrs **rules = cmd_ctx->rules; switch (ret) { case EOK: /* * Parent of cmd_ctx->rules is in-memory cache, we must not talloc_free it! */ if (cmd_ctx->sudo_ctx->timed) { /* filter rules by time */ DEBUG(SSSDBG_TRACE_FUNC, "Applying time restrictions on" "%u rules\n", cmd_ctx->num_rules); ret = sysdb_sudo_filter_rules_by_time(cmd_ctx, cmd_ctx->num_rules, cmd_ctx->rules, 0, &num_rules, &rules); if (ret != EOK) { return EFAULT; } DEBUG(SSSDBG_TRACE_FUNC, "Got %u rules after time filter\n", num_rules); } /* send result */ ret = sudosrv_build_response(cmd_ctx, SSS_SUDO_ERROR_OK, num_rules, rules, &response_body, &response_len); if (ret != EOK) { return EFAULT; } ret = sudosrv_cmd_send_reply(cmd_ctx, response_body, response_len); break; case EAGAIN: /* async processing, just return here */ return EOK; case EFAULT: /* very bad error */ return EFAULT; /* case ENOENT: * - means user not found * - send error ENOENT */ default: /* send error */ ret = sudosrv_cmd_send_error(cmd_ctx, cmd_ctx, ret); break; } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error, killing connection!\n"); talloc_free(cmd_ctx->cli_ctx); return EFAULT; } return EOK; } static void sudosrv_cmd_parse_query_done(struct tevent_req *req); static int sudosrv_cmd(enum sss_sudo_type type, struct cli_ctx *cli_ctx) { struct tevent_req *req = NULL; struct sudo_cmd_ctx *cmd_ctx = NULL; uint8_t *query_body = NULL; size_t query_len = 0; uint32_t protocol = cli_ctx->cli_protocol_version->version; errno_t ret; /* create cmd_ctx */ cmd_ctx = talloc_zero(cli_ctx, struct sudo_cmd_ctx); if (cmd_ctx == NULL) { /* kill the connection here as we have no context for reply */ DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n"); return ENOMEM; } cmd_ctx->domain = NULL; cmd_ctx->cli_ctx = cli_ctx; cmd_ctx->type = type; cmd_ctx->sudo_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct sudo_ctx); if (cmd_ctx->sudo_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "sudo_ctx not set, killing connection!\n"); return EFAULT; } /* if protocol is invalid return */ switch (protocol) { case 0: DEBUG(SSSDBG_FATAL_FAILURE, "Protocol [%d] is not secure. " "SSSD does not allow to use this protocol.\n", protocol); ret = EFAULT; goto done; break; case SSS_SUDO_PROTOCOL_VERSION: DEBUG(SSSDBG_TRACE_INTERNAL, "Using protocol version [%d]\n", protocol); break; default: DEBUG(SSSDBG_FATAL_FAILURE, "Invalid protocol version [%d]!\n", protocol); ret = EFAULT; goto done; } /* parse query */ sss_packet_get_body(cli_ctx->creq->in, &query_body, &query_len); if (query_len <= 0 || query_body == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Query is empty\n"); ret = EINVAL; goto done; } req = sudosrv_parse_query_send(cmd_ctx, cli_ctx->rctx, query_body, query_len); if (req == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(req, sudosrv_cmd_parse_query_done, cmd_ctx); ret = EAGAIN; done: return sudosrv_cmd_done(cmd_ctx, ret); } static void sudosrv_cmd_parse_query_done(struct tevent_req *req) { struct sudo_cmd_ctx *cmd_ctx = NULL; struct sudo_dom_ctx *dom_ctx = NULL; struct sudo_ctx *sudo_ctx = NULL; errno_t ret; cmd_ctx = tevent_req_callback_data(req, struct sudo_cmd_ctx); ret = sudosrv_parse_query_recv(cmd_ctx, req, &cmd_ctx->uid, &cmd_ctx->username, &cmd_ctx->domain); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid query [%d]: %s\n", ret, strerror(ret)); goto done; } cmd_ctx->check_next = cmd_ctx->domain == NULL; switch (cmd_ctx->type) { case SSS_SUDO_DEFAULTS: DEBUG(SSSDBG_FUNC_DATA, "Requesting default options " "for [%s] from [%s]\n", cmd_ctx->username, cmd_ctx->domain ? cmd_ctx->domain->name : ""); break; case SSS_SUDO_USER: DEBUG(SSSDBG_FUNC_DATA, "Requesting rules " "for [%s] from [%s]\n", cmd_ctx->username, cmd_ctx->domain ? cmd_ctx->domain->name : ""); break; } /* create domain ctx */ dom_ctx = talloc_zero(cmd_ctx, struct sudo_dom_ctx); if (dom_ctx == NULL) { ret = ENOMEM; goto done; } dom_ctx->cmd_ctx = cmd_ctx; dom_ctx->domain = cmd_ctx->domain != NULL ? cmd_ctx->domain : cmd_ctx->cli_ctx->rctx->domains; sudo_ctx = talloc_get_type(cmd_ctx->cli_ctx->rctx->pvt_ctx, struct sudo_ctx); ret = sss_ncache_check_user(sudo_ctx->ncache, sudo_ctx->neg_timeout, dom_ctx->domain, cmd_ctx->username); if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "User [%s@%s] filtered out (ncache)\n", cmd_ctx->username, dom_ctx->domain->name); ret = ENOENT; goto done; } ret = sudosrv_get_sudorules(dom_ctx); done: sudosrv_cmd_done(cmd_ctx, ret); } static int sudosrv_cmd_get_sudorules(struct cli_ctx *cli_ctx) { return sudosrv_cmd(SSS_SUDO_USER, cli_ctx); } static int sudosrv_cmd_get_defaults(struct cli_ctx *cli_ctx) { return sudosrv_cmd(SSS_SUDO_DEFAULTS, cli_ctx); } struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version sudo_cli_protocol_version[] = { {1, "2012-05-14", "require uid and domain"}, {0, NULL, NULL} }; return sudo_cli_protocol_version; } struct sss_cmd_table *get_sudo_cmds(void) { static struct sss_cmd_table sudo_cmds[] = { {SSS_GET_VERSION, sss_cmd_get_version}, {SSS_SUDO_GET_SUDORULES, sudosrv_cmd_get_sudorules}, {SSS_SUDO_GET_DEFAULTS, sudosrv_cmd_get_defaults}, {SSS_CLI_NULL, NULL} }; return sudo_cmds; } sssd-1.13.4/src/responder/PaxHeaders.16287/autofs0000644000000000000000000000013212703463556016347 xustar0030 mtime=1460561774.997794792 30 atime=1460561776.119798596 30 ctime=1460561774.997794792 sssd-1.13.4/src/responder/autofs/0000755002412700241270000000000012703463556020100 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/responder/autofs/PaxHeaders.16287/autofs_private.h0000644000000000000000000000007412703456111021622 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.475793022 sssd-1.13.4/src/responder/autofs/autofs_private.h0000644002412700241270000000501212703456111023267 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _AUTOFSSRV_PRIVATE_H_ #define _AUTOFSSRV_PRIVATE_H_ #include "responder/common/responder_sbus.h" #define SSS_AUTOFS_PROTO_VERSION 0x001 struct autofs_ctx { struct resp_ctx *rctx; int neg_timeout; hash_table_t *maps; }; struct autofs_cmd_ctx { struct cli_ctx *cctx; char *mapname; char *key; uint32_t cursor; uint32_t max_entries; bool check_next; }; struct autofs_dom_ctx { struct autofs_cmd_ctx *cmd_ctx; struct sss_domain_info *domain; bool check_provider; /* cache results */ struct ldb_message *map; size_t entry_count; struct ldb_message **entries; struct autofs_map_ctx *map_ctx; }; struct autofs_map_ctx { /* state of the map entry */ bool ready; bool found; /* requests */ struct setent_req_list *reqs; hash_table_t *map_table; char *mapname; /* map entry */ struct ldb_message *map; size_t entry_count; struct ldb_message **entries; }; struct sss_cmd_table *get_autofs_cmds(void); void autofs_map_hash_delete_cb(hash_entry_t *item, hash_destroy_enum deltype, void *pvt); errno_t autofs_orphan_maps(struct autofs_ctx *actx); enum sss_dp_autofs_type { SSS_DP_AUTOFS }; struct tevent_req * sss_dp_get_autofs_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, bool fast_reply, enum sss_dp_autofs_type type, const char *name); errno_t sss_dp_get_autofs_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret, char **err_msg); #endif /* _AUTOFSSRV_PRIVATE_H_ */ sssd-1.13.4/src/responder/autofs/PaxHeaders.16287/autofssrv_dp.c0000644000000000000000000000007412703456111021301 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.997794792 sssd-1.13.4/src/responder/autofs/autofssrv_dp.c0000644002412700241270000001030312703456111022745 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "sbus/sssd_dbus.h" #include "util/util.h" #include "sbus/sbus_client.h" #include "providers/data_provider.h" #include "responder/common/responder.h" #include "responder/autofs/autofs_private.h" struct sss_dp_get_autofs_info { struct sss_domain_info *dom; bool fast_reply; enum sss_dp_autofs_type type; const char *name; }; static DBusMessage * sss_dp_get_autofs_msg(void *pvt); struct tevent_req * sss_dp_get_autofs_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, bool fast_reply, enum sss_dp_autofs_type type, const char *name) { struct tevent_req *req; struct sss_dp_req_state *state; struct sss_dp_get_autofs_info *info; errno_t ret; char *key; req = tevent_req_create(mem_ctx, &state, struct sss_dp_req_state); if (!req) { ret = ENOMEM; goto error; } if (!dom) { ret = EINVAL; goto error; } info = talloc_zero(state, struct sss_dp_get_autofs_info); info->fast_reply = fast_reply; info->type = type; info->name = name; info->dom = dom; key = talloc_asprintf(state, "%d:%s@%s", type, name, dom->name); if (!key) { ret = ENOMEM; goto error; } ret = sss_dp_issue_request(state, rctx, key, dom, sss_dp_get_autofs_msg, info, req); talloc_free(key); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not issue DP request [%d]: %s\n", ret, strerror(ret)); goto error; } return req; error: tevent_req_error(req, ret); tevent_req_post(req, rctx->ev); return req; } static DBusMessage * sss_dp_get_autofs_msg(void *pvt) { DBusMessage *msg; dbus_bool_t dbret; struct sss_dp_get_autofs_info *info; uint32_t be_type = BE_REQ_AUTOFS; char *filter; info = talloc_get_type(pvt, struct sss_dp_get_autofs_info); if (info->fast_reply) { be_type |= BE_REQ_FAST; } filter = talloc_asprintf(info, "mapname=%s", info->name); if (!filter) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); return NULL; } msg = dbus_message_new_method_call(NULL, DP_PATH, DATA_PROVIDER_IFACE, DATA_PROVIDER_IFACE_AUTOFSHANDLER); if (msg == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); return NULL; } /* create the message */ DEBUG(SSSDBG_TRACE_FUNC, "Creating autofs request for [%s][%u][%s]\n", info->dom->name, be_type, filter); dbret = dbus_message_append_args(msg, DBUS_TYPE_UINT32, &be_type, DBUS_TYPE_STRING, &filter, DBUS_TYPE_INVALID); talloc_free(filter); if (!dbret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n"); dbus_message_unref(msg); return NULL; } return msg; } errno_t sss_dp_get_autofs_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret, char **err_msg) { return sss_dp_req_recv(mem_ctx, req, dp_err, dp_ret, err_msg); } sssd-1.13.4/src/responder/autofs/PaxHeaders.16287/autofssrv_cmd.c0000644000000000000000000000007412703456111021441 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.996794788 sssd-1.13.4/src/responder/autofs/autofssrv_cmd.c0000644002412700241270000012360512703456111023117 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2012 Red Hat Autofs responder: commands This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "responder/common/responder.h" #include "responder/common/responder_packet.h" #include "responder/autofs/autofs_private.h" #include "db/sysdb.h" #include "db/sysdb_autofs.h" #include "confdb/confdb.h" static int autofs_cmd_send_error(struct autofs_cmd_ctx *cmdctx, int err) { return sss_cmd_send_error(cmdctx->cctx, err); } static int autofs_cmd_send_empty(struct autofs_cmd_ctx *cmdctx) { return sss_cmd_send_empty(cmdctx->cctx, cmdctx); } static int autofs_cmd_done(struct autofs_cmd_ctx *cmdctx, int ret) { switch (ret) { case EOK: /* all fine, just return here */ break; case ENOENT: ret = autofs_cmd_send_empty(cmdctx); if (ret) { return EFAULT; } break; case EAGAIN: /* async processing, just return here */ break; case EFAULT: /* very bad error */ return EFAULT; default: ret = autofs_cmd_send_error(cmdctx, ret); if (ret) { return EFAULT; } sss_cmd_done(cmdctx->cctx, cmdctx); break; } return EOK; } static errno_t autofs_setent_add_ref(TALLOC_CTX *memctx, struct autofs_map_ctx *map_ctx, struct tevent_req *req) { return setent_add_ref(memctx, map_ctx, &map_ctx->reqs, req); } static void autofs_setent_notify(struct autofs_map_ctx *map_ctx, errno_t ret) { setent_notify(&map_ctx->reqs, ret); } errno_t autofs_orphan_maps(struct autofs_ctx *actx) { int hret; unsigned long mcount; unsigned long i; hash_key_t *maps; if (!actx || !actx->maps) { return EINVAL; } hret = hash_keys(actx->maps, &mcount, &maps); if (hret != HASH_SUCCESS) { return EIO; } for (i = 0; i < mcount; i++) { hret = hash_delete(actx->maps, &maps[i]); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not delete key from hash\n"); continue; } } return EOK; } static errno_t get_autofs_map(struct autofs_ctx *actx, char *mapname, struct autofs_map_ctx **map) { hash_key_t key; hash_value_t value; int hret; key.type = HASH_KEY_STRING; key.str = mapname; hret = hash_lookup(actx->maps, &key, &value); if (hret == HASH_SUCCESS) { *map = talloc_get_type(value.ptr, struct autofs_map_ctx); return EOK; } else if (hret == HASH_ERROR_KEY_NOT_FOUND) { return ENOENT; } DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected error reading from autofs map hash [%d][%s]\n", hret, hash_error_string(hret)); return EIO; } static int autofs_map_hash_remove (TALLOC_CTX *ctx); void autofs_map_hash_delete_cb(hash_entry_t *item, hash_destroy_enum deltype, void *pvt) { struct autofs_map_ctx *map; if (deltype != HASH_ENTRY_DESTROY) { return; } map = talloc_get_type(item->value.ptr, struct autofs_map_ctx); if (!map) { DEBUG(SSSDBG_OP_FAILURE, "Invalid autofs map\n"); return; } /* So that the destructor wouldn't attempt to remove the map from hash * table */ map->map_table = NULL; } static errno_t set_autofs_map(struct autofs_ctx *actx, struct autofs_map_ctx *map) { hash_key_t key; hash_value_t value; int hret; if (map->mapname == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing autofs map name.\n"); return EINVAL; } /* Add this entry to the hash table */ key.type = HASH_KEY_STRING; key.str = map->mapname; value.type = HASH_VALUE_PTR; value.ptr = map; hret = hash_enter(actx->maps, &key, &value); if (hret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add hash table entry for [%s]\n", key.str); DEBUG(SSSDBG_MINOR_FAILURE, "Hash error [%d][%s]\n", hret, hash_error_string(hret)); return EIO; } talloc_steal(actx->maps, map); talloc_set_destructor((TALLOC_CTX *) map, autofs_map_hash_remove); return EOK; } static int autofs_map_hash_remove(TALLOC_CTX *ctx) { int hret; hash_key_t key; struct autofs_map_ctx *map = talloc_get_type(ctx, struct autofs_map_ctx); if (map->map_table == NULL) { DEBUG(SSSDBG_TRACE_LIBS, "autofs map [%s] was already removed\n", map->mapname); return 0; } key.type = HASH_KEY_STRING; key.str = map->mapname; /* Remove the autofs map result object from the lookup table */ hret = hash_delete(map->map_table, &key); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not remove key from table! [%d][%s]\n", hret, hash_error_string(hret)); return -1; } return 0; } static struct tevent_req * setautomntent_send(TALLOC_CTX *mem_ctx, const char *rawname, struct autofs_cmd_ctx *cmdctx); static errno_t setautomntent_recv(struct tevent_req *req); static void sss_autofs_cmd_setautomntent_done(struct tevent_req *req); /* FIXME - file a ticket to have per-responder private * data instead of growing the cli_ctx structure */ static int sss_autofs_cmd_setautomntent(struct cli_ctx *client) { struct autofs_cmd_ctx *cmdctx; uint8_t *body; size_t blen; errno_t ret = EOK; const char *rawname; struct tevent_req *req; DEBUG(SSSDBG_TRACE_INTERNAL, "sss_autofs_cmd_setautomntent\n"); cmdctx = talloc_zero(client, struct autofs_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = client; sss_packet_get_body(client->creq->in, &body, &blen); /* if not terminated fail */ if (body[blen -1] != '\0') { ret = EINVAL; goto done; } /* If the body isn't valid UTF-8, fail */ if (!sss_utf8_check(body, blen -1)) { ret = EINVAL; goto done; } rawname = (const char *)body; DEBUG(SSSDBG_TRACE_FUNC, "Got request for automount map named %s\n", rawname); req = setautomntent_send(cmdctx, rawname, cmdctx); if (!req) { DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error calling setautomntent_send\n"); ret = EIO; goto done; } tevent_req_set_callback(req, sss_autofs_cmd_setautomntent_done, cmdctx); ret = EOK; done: return autofs_cmd_done(cmdctx, ret); } static void sss_autofs_cmd_setautomntent_done(struct tevent_req *req) { struct autofs_cmd_ctx *cmdctx = tevent_req_callback_data(req, struct autofs_cmd_ctx); errno_t ret; errno_t reqret; struct sss_packet *packet; uint8_t *body; size_t blen; DEBUG(SSSDBG_TRACE_INTERNAL, "setautomntent done\n"); reqret = setautomntent_recv(req); talloc_zfree(req); if (reqret != EOK && reqret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_recv failed\n"); autofs_cmd_done(cmdctx, reqret); return; } /* Either we succeeded or no domains were eligible */ ret = sss_packet_new(cmdctx->cctx->creq, 0, sss_packet_get_cmd(cmdctx->cctx->creq->in), &cmdctx->cctx->creq->out); if (ret == EOK) { if (reqret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "setautomntent did not find requested map\n"); /* Notify the caller that this entry wasn't found */ sss_cmd_empty_packet(cmdctx->cctx->creq->out); } else { DEBUG(SSSDBG_TRACE_FUNC, "setautomntent found data\n"); packet = cmdctx->cctx->creq->out; ret = sss_packet_grow(packet, 2*sizeof(uint32_t)); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't grow the packet\n"); talloc_free(cmdctx); return; } sss_packet_get_body(packet, &body, &blen); /* Got some results */ SAFEALIGN_SETMEM_UINT32(body, 1, NULL); /* Reserved padding */ SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL); } sss_cmd_done(cmdctx->cctx, NULL); return; } DEBUG(SSSDBG_CRIT_FAILURE, "Error creating packet\n"); return; } struct setautomntent_state { struct autofs_cmd_ctx *cmdctx; struct autofs_dom_ctx *dctx; char *mapname; struct autofs_map_ctx *map; }; struct setautomntent_lookup_ctx { struct autofs_ctx *actx; struct autofs_dom_ctx *dctx; struct resp_ctx *rctx; struct cli_ctx *cctx; bool returned_to_mainloop; char *mapname; struct autofs_map_ctx *map; }; static errno_t lookup_automntmap_step(struct setautomntent_lookup_ctx *lookup_ctx); static void autofs_map_result_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { struct autofs_map_ctx *map = talloc_get_type(pvt, struct autofs_map_ctx); /* Free the autofs map result context * The destructor for the autofs map will remove itself * from the hash table */ talloc_free(map); } static void set_autofs_map_lifetime(uint32_t lifetime, struct setautomntent_lookup_ctx *lookup_ctx, struct autofs_map_ctx *map) { struct timeval tv; struct tevent_timer *te; tv = tevent_timeval_current_ofs(lifetime, 0); te = tevent_add_timer(lookup_ctx->rctx->ev, lookup_ctx->rctx, tv, autofs_map_result_timeout, map); if (!te) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up life timer for autofs maps. " "Entries may become stale.\n"); } } static errno_t setautomntent_get_autofs_map(struct autofs_ctx *actx, char *mapname, struct autofs_map_ctx **map); static struct tevent_req * setautomntent_send(TALLOC_CTX *mem_ctx, const char *rawname, struct autofs_cmd_ctx *cmdctx) { char *domname; errno_t ret; struct tevent_req *req; struct setautomntent_state *state; struct cli_ctx *client = cmdctx->cctx; struct autofs_dom_ctx *dctx; struct autofs_ctx *actx = talloc_get_type(client->rctx->pvt_ctx, struct autofs_ctx); struct setautomntent_lookup_ctx *lookup_ctx; req = tevent_req_create(mem_ctx, &state, struct setautomntent_state); if (!req) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not create tevent request for setautomntent\n"); return NULL; } state->cmdctx = cmdctx; dctx = talloc_zero(state, struct autofs_dom_ctx); if (!dctx) { DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory\n"); ret = ENOMEM; goto fail; } dctx->cmd_ctx = state->cmdctx; state->dctx = dctx; ret = sss_parse_name_for_domains(state, client->rctx->domains, NULL, rawname, &domname, &state->mapname); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Invalid name received [%s]\n", rawname); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for automount map [%s] from [%s]\n", state->mapname, domname?domname:""); if (domname) { dctx->domain = responder_get_domain(client->rctx, domname); if (!dctx->domain) { ret = EINVAL; goto fail; } client->automntmap_name = talloc_strdup(client, rawname); if (!client->automntmap_name) { ret = ENOMEM; goto fail; } } else { /* this is a multidomain search */ dctx->domain = client->rctx->domains; cmdctx->check_next = true; client->automntmap_name = talloc_strdup(client, state->mapname); if (!client->automntmap_name) { ret = ENOMEM; goto fail; } } dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); /* Is the result context already available? * Check for existing lookups for this map */ ret = setautomntent_get_autofs_map(actx, state->mapname, &state->map); if (ret == EOK) { /* Another process already requested this map * Check whether it's ready for processing. */ if (state->map->ready) { if (state->map->found) { DEBUG(SSSDBG_TRACE_LIBS, "Map %s is ready to be processed\n", state->mapname); tevent_req_done(req); tevent_req_post(req, actx->rctx->ev); return req; } else { DEBUG(SSSDBG_TRACE_LIBS, "Map %s was marked as nonexistent\n", state->mapname); tevent_req_error(req, ENOENT); tevent_req_post(req, actx->rctx->ev); return req; } } /* Result object is still being constructed * Register for notification when it's ready */ DEBUG(SSSDBG_TRACE_LIBS, "Map %s is being looked up, registering for notification\n", state->mapname); ret = autofs_setent_add_ref(state, state->map, req); if (ret != EOK) { goto fail; } /* Will return control below */ } else if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_LIBS, "Map %s needs to be looked up\n", state->mapname); state->map = talloc_zero(actx, struct autofs_map_ctx); if (!state->map) { ret = ENOMEM; goto fail; } dctx->map_ctx = state->map; state->map->mapname = talloc_strdup(state->map, state->mapname); if (!state->map->mapname) { talloc_free(state->map); ret = ENOMEM; goto fail; } state->map->map_table = actx->maps; ret = autofs_setent_add_ref(state, state->map, req); if (ret != EOK) { talloc_free(state->map); goto fail; } ret = set_autofs_map(actx, state->map); if (ret != EOK) { talloc_free(state->map); goto fail; } /* Perform lookup */ lookup_ctx = talloc_zero(state->map, struct setautomntent_lookup_ctx); if (!lookup_ctx) { talloc_free(state->map); ret = ENOMEM; goto fail; } /* Steal the dom_ctx onto the lookup_ctx so it doesn't go out of scope if * this request is canceled while other requests are in-progress. */ lookup_ctx->dctx = talloc_steal(lookup_ctx, state->dctx); lookup_ctx->actx = actx; lookup_ctx->map = state->map; lookup_ctx->rctx = client->rctx; lookup_ctx->mapname = talloc_strdup(lookup_ctx, state->mapname); if (!lookup_ctx->mapname) { talloc_free(state->map); ret = ENOMEM; goto fail; } ret = lookup_automntmap_step(lookup_ctx); if (ret == EAGAIN) { DEBUG(SSSDBG_TRACE_INTERNAL, "lookup_automntmap_step " "is refreshing the cache, re-entering the mainloop\n"); return req; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not get data from cache\n"); talloc_free(state->map); ret = ENOMEM; goto fail; } tevent_req_done(req); tevent_req_post(req, cmdctx->cctx->ev); return req; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected error from get_autofs_map [%d]: %s\n", ret, strerror(ret)); goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, actx->rctx->ev); return req; } static errno_t setautomntent_get_autofs_map(struct autofs_ctx *actx, char *mapname, struct autofs_map_ctx **map) { errno_t ret; if (strcmp(mapname, "auto.master") == 0) { /* Iterate over the hash and remove all maps */ ret = autofs_orphan_maps(actx); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not remove existing maps from hash\n"); } return ENOENT; } return get_autofs_map(actx, mapname, map); } static errno_t lookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx); static errno_t lookup_automntmap_step(struct setautomntent_lookup_ctx *lookup_ctx) { errno_t ret; struct sss_domain_info *dom = lookup_ctx->dctx->domain; struct autofs_dom_ctx *dctx = lookup_ctx->dctx; struct sysdb_ctx *sysdb; struct autofs_map_ctx *map; /* Check each domain for this map name */ while (dom) { if (dom != dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); } /* make sure to update the dctx if we changed domain */ dctx->domain = dom; DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for [%s@%s]\n", lookup_ctx->mapname, dom->name); sysdb = dom->sysdb; if (sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); return EIO; } /* Look into the cache */ talloc_free(dctx->map); ret = sysdb_get_map_byname(dctx, dom, lookup_ctx->mapname, &dctx->map); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Could not check cache\n"); return ret; } else if (ret == ENOENT) { DEBUG(SSSDBG_MINOR_FAILURE, "No automount map [%s] in cache for domain [%s]\n", lookup_ctx->mapname, dom->name); if (!dctx->check_provider) { if (dctx->cmd_ctx->check_next) { DEBUG(SSSDBG_TRACE_INTERNAL, "Moving on to next domain\n"); dom = get_next_domain(dom, 0); continue; } else break; } } ret = get_autofs_map(lookup_ctx->actx, lookup_ctx->mapname, &map); if (ret != EOK) { /* Something really bad happened! */ DEBUG(SSSDBG_CRIT_FAILURE, "Autofs map entry was lost!\n"); return ret; } if (dctx->map == NULL && !dctx->check_provider) { DEBUG(SSSDBG_MINOR_FAILURE, "Autofs map not found, setting negative cache\n"); map->ready = true; map->found = false; set_autofs_map_lifetime(lookup_ctx->actx->neg_timeout, lookup_ctx, map); return ENOENT; } if (dctx->check_provider) { ret = lookup_automntmap_update_cache(lookup_ctx); if (ret == EAGAIN) { DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up automount maps from the DP\n"); return EAGAIN; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Error looking up automount maps [%d]: %s\n", ret, strerror(ret)); return ret; } } /* OK, the map is in cache and valid. * Let's get all members and return it */ ret = sysdb_autofs_entries_by_map(map, dom, map->mapname, &map->entry_count, &map->entries); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Error looking automount map entries [%d]: %s\n", ret, strerror(ret)); map->ready = true; map->found = false; set_autofs_map_lifetime(lookup_ctx->actx->neg_timeout, lookup_ctx, map); return EIO; } map->map = talloc_steal(map, dctx->map); DEBUG(SSSDBG_TRACE_FUNC, "setautomntent done for map %s\n", lookup_ctx->mapname); map->ready = true; map->found = true; set_autofs_map_lifetime(dom->autofsmap_timeout, lookup_ctx, map); return EOK; } map = talloc_zero(lookup_ctx->actx, struct autofs_map_ctx); if (!map) { return ENOMEM; } map->ready = true; map->found = false; map->map_table = lookup_ctx->actx->maps; map->mapname = talloc_strdup(map, lookup_ctx->mapname); if (!map->mapname) { talloc_free(map); return ENOMEM; } ret = set_autofs_map(lookup_ctx->actx, map); if (ret != EOK) { talloc_free(map); return ENOMEM; } set_autofs_map_lifetime(lookup_ctx->actx->neg_timeout, lookup_ctx, map); /* If we've gotten here, then no domain contained this map */ return ENOENT; } static void lookup_automntmap_cache_updated(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); static void autofs_dp_send_map_req_done(struct tevent_req *req); static errno_t lookup_automntmap_update_cache(struct setautomntent_lookup_ctx *lookup_ctx) { errno_t ret; uint64_t cache_expire = 0; struct autofs_dom_ctx *dctx = lookup_ctx->dctx; struct tevent_req *req = NULL; struct dp_callback_ctx *cb_ctx = NULL; if (dctx->map != NULL) { if (strcmp(lookup_ctx->mapname, "auto.master") != 0) { cache_expire = ldb_msg_find_attr_as_uint64(dctx->map, SYSDB_CACHE_EXPIRE, 0); } /* if we have any reply let's check cache validity */ ret = sss_cmd_check_cache(dctx->map, 0, cache_expire); if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Cached entry is valid, returning..\n"); return EOK; } else if (ret != EAGAIN && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Error checking cache: %d\n", ret); goto error; } } /* dont loop forever :-) */ dctx->check_provider = false; /* keep around current data in case backend is offline */ /* FIXME - do this by default */ #if 0 if (dctx->res->count) { dctx->res = talloc_steal(dctx, dctx->res); } #endif req = sss_dp_get_autofs_send(lookup_ctx->cctx, lookup_ctx->rctx, lookup_ctx->dctx->domain, true, SSS_DP_AUTOFS, lookup_ctx->mapname); if (!req) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending data provider request\n"); ret = ENOMEM; goto error; } cb_ctx = talloc_zero(lookup_ctx->dctx, struct dp_callback_ctx); if(!cb_ctx) { talloc_zfree(req); ret = ENOMEM; goto error; } cb_ctx->callback = lookup_automntmap_cache_updated; cb_ctx->ptr = lookup_ctx; cb_ctx->cctx = lookup_ctx->dctx->cmd_ctx->cctx; cb_ctx->mem_ctx = lookup_ctx->dctx; tevent_req_set_callback(req, autofs_dp_send_map_req_done, cb_ctx); return EAGAIN; error: ret = autofs_cmd_send_error(lookup_ctx->dctx->cmd_ctx, ret); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error, killing connection!\n"); talloc_free(lookup_ctx->cctx); return ret; } autofs_cmd_done(lookup_ctx->dctx->cmd_ctx, ret); return EOK; } static void autofs_dp_send_map_req_done(struct tevent_req *req) { struct dp_callback_ctx *cb_ctx = tevent_req_callback_data(req, struct dp_callback_ctx); struct setautomntent_lookup_ctx *lookup_ctx = talloc_get_type(cb_ctx->ptr, struct setautomntent_lookup_ctx); errno_t ret; dbus_uint16_t err_maj; dbus_uint32_t err_min; char *err_msg; ret = sss_dp_get_autofs_recv(cb_ctx->mem_ctx, req, &err_maj, &err_min, &err_msg); talloc_free(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error, killing connection!\n"); talloc_free(lookup_ctx->cctx); return; } cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr); } static void lookup_automntmap_cache_updated(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr) { struct setautomntent_lookup_ctx *lookup_ctx = talloc_get_type(ptr, struct setautomntent_lookup_ctx); struct autofs_dom_ctx *dctx = lookup_ctx->dctx; errno_t ret; if (err_maj) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get information from Data Provider\n" "Error: %u, %u, %s\n" "Will try to return what we have in cache\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg); /* Loop to the next domain if possible */ if (dctx->cmd_ctx->check_next && (dctx->domain = get_next_domain(dctx->domain, 0))) { dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); } } /* ok the backend returned, search to see if we have updated results */ ret = lookup_automntmap_step(lookup_ctx); if (ret != EOK) { if (ret == EAGAIN) { return; } } /* We have results to return */ autofs_setent_notify(lookup_ctx->map, ret); } static errno_t setautomntent_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static errno_t getautomntent_process(struct autofs_cmd_ctx *cmdctx, struct autofs_map_ctx *map, uint32_t cursor, uint32_t max_entries); static void getautomntent_implicit_done(struct tevent_req *req); static errno_t fill_autofs_entry(struct ldb_message *entry, struct sss_packet *packet, size_t *rp); static int sss_autofs_cmd_getautomntent(struct cli_ctx *client) { struct autofs_cmd_ctx *cmdctx; struct autofs_map_ctx *map; struct autofs_ctx *actx; uint8_t *body; size_t blen; errno_t ret; uint32_t namelen; size_t c = 0; struct tevent_req *req; DEBUG(SSSDBG_TRACE_INTERNAL, "sss_autofs_cmd_getautomntent\n"); cmdctx = talloc_zero(client, struct autofs_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = client; actx = talloc_get_type(client->rctx->pvt_ctx, struct autofs_ctx); if (!actx) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing autofs context\n"); return EIO; } /* get autofs map name and index to query */ sss_packet_get_body(client->creq->in, &body, &blen); SAFEALIGN_COPY_UINT32_CHECK(&namelen, body+c, blen, &c); if (namelen == 0 || namelen > blen - c) { ret = EINVAL; goto done; } cmdctx->mapname = (char *) body+c; /* if not null-terminated fail */ if (cmdctx->mapname[namelen] != '\0') { ret = EINVAL; goto done; } /* If the name isn't valid UTF-8, fail */ if (!sss_utf8_check((const uint8_t *) cmdctx->mapname, namelen -1)) { ret = EINVAL; goto done; } SAFEALIGN_COPY_UINT32_CHECK(&cmdctx->cursor, body+c+namelen+1, blen, &c); SAFEALIGN_COPY_UINT32_CHECK(&cmdctx->max_entries, body+c+namelen+1, blen, &c); DEBUG(SSSDBG_TRACE_FUNC, "Requested data of map %s cursor %d max entries %d\n", cmdctx->mapname, cmdctx->cursor, cmdctx->max_entries); ret = get_autofs_map(actx, cmdctx->mapname, &map); if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "Performing implicit setautomntent\n"); req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_send failed\n"); ret = EIO; goto done; } tevent_req_set_callback(req, getautomntent_implicit_done, cmdctx); ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "An unexpected error occurred: [%d][%s]\n", ret, strerror(ret)); goto done; } if (map->ready == false) { DEBUG(SSSDBG_TRACE_FUNC, "Performing implicit setautomntent\n"); req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_send failed\n"); ret = EIO; goto done; } tevent_req_set_callback(req, getautomntent_implicit_done, cmdctx); ret = EOK; goto done; } else if (map->found == false) { DEBUG(SSSDBG_TRACE_FUNC, "negative cache hit\n"); ret = ENOENT; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "returning entries for [%s]\n", map->mapname); ret = getautomntent_process(cmdctx, map, cmdctx->cursor, cmdctx->max_entries); done: return autofs_cmd_done(cmdctx, ret); } static void getautomntent_implicit_done(struct tevent_req *req) { errno_t ret; struct autofs_map_ctx *map; struct autofs_cmd_ctx *cmdctx = tevent_req_callback_data(req, struct autofs_cmd_ctx); struct autofs_ctx *actx = talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct autofs_ctx); ret = setautomntent_recv(req); talloc_zfree(req); if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_recv failed\n"); } else { DEBUG(SSSDBG_MINOR_FAILURE, "No such map\n"); } goto done; } ret = get_autofs_map(actx, cmdctx->mapname, &map); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get map after setautomntent succeeded?\n"); goto done; } if (map->ready == false) { DEBUG(SSSDBG_CRIT_FAILURE, "Map not ready after setautomntent succeeded\n"); goto done; } ret = getautomntent_process(cmdctx, map, cmdctx->cursor, cmdctx->max_entries); done: autofs_cmd_done(cmdctx, ret); return; } static errno_t getautomntent_process(struct autofs_cmd_ctx *cmdctx, struct autofs_map_ctx *map, uint32_t cursor, uint32_t max_entries) { struct cli_ctx *client = cmdctx->cctx; errno_t ret; struct ldb_message *entry; size_t rp; uint32_t i, stop, left, nentries; uint8_t *body; size_t blen; /* create response packet */ ret = sss_packet_new(client->creq, 0, sss_packet_get_cmd(client->creq->in), &client->creq->out); if (ret != EOK) { return ret; } if (!map->map || !map->entries || !map->entries[0] || cursor >= map->entry_count) { DEBUG(SSSDBG_MINOR_FAILURE, "No entries found\n"); ret = sss_cmd_empty_packet(client->creq->out); if (ret != EOK) { return autofs_cmd_done(cmdctx, ret); } goto done; } /* allocate memory for number of entries in the packet */ ret = sss_packet_grow(client->creq->out, sizeof(uint32_t)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot grow packet\n"); goto done; } rp = sizeof(uint32_t); /* We'll write the number of entries here */ left = map->entry_count - cursor; stop = max_entries < left ? max_entries : left; nentries = 0; for (i=0; i < stop; i++) { entry = map->entries[cursor]; cursor++; ret = fill_autofs_entry(entry, client->creq->out, &rp); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot fill entry %d/%d, skipping\n", i, stop); continue; } nentries++; } /* packet grows in fill_autofs_entry, body pointer may change, * thus we have to obtain it here */ sss_packet_get_body(client->creq->out, &body, &blen); rp = 0; SAFEALIGN_SET_UINT32(&body[rp], nentries, &rp); ret = EOK; done: sss_packet_set_error(client->creq->out, ret); sss_cmd_done(client, cmdctx); return EOK; } static errno_t fill_autofs_entry(struct ldb_message *entry, struct sss_packet *packet, size_t *rp) { errno_t ret; const char *key; size_t keylen; const char *value; size_t valuelen; uint8_t *body; size_t blen; size_t len; key = ldb_msg_find_attr_as_string(entry, SYSDB_AUTOFS_ENTRY_KEY, NULL); value = ldb_msg_find_attr_as_string(entry, SYSDB_AUTOFS_ENTRY_VALUE, NULL); if (!key || !value) { DEBUG(SSSDBG_MINOR_FAILURE, "Incomplete entry\n"); return EINVAL; } keylen = 1 + strlen(key); valuelen = 1 + strlen(value); len = sizeof(uint32_t) + sizeof(uint32_t) + keylen + sizeof(uint32_t) + valuelen; ret = sss_packet_grow(packet, len); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot grow packet\n"); return ret; } sss_packet_get_body(packet, &body, &blen); SAFEALIGN_SET_UINT32(&body[*rp], len, rp); SAFEALIGN_SET_UINT32(&body[*rp], keylen, rp); if (keylen == 1) { body[*rp] = '\0'; } else { memcpy(&body[*rp], key, keylen); } *rp += keylen; SAFEALIGN_SET_UINT32(&body[*rp], valuelen, rp); if (valuelen == 1) { body[*rp] = '\0'; } else { memcpy(&body[*rp], value, valuelen); } *rp += valuelen; return EOK; } static errno_t getautomntbyname_process(struct autofs_cmd_ctx *cmdctx, struct autofs_map_ctx *map, const char *key); static void getautomntbyname_implicit_done(struct tevent_req *req); static int sss_autofs_cmd_getautomntbyname(struct cli_ctx *client) { errno_t ret; struct autofs_cmd_ctx *cmdctx; struct autofs_map_ctx *map; struct autofs_ctx *actx; uint8_t *body; size_t blen; uint32_t namelen; uint32_t keylen; size_t c = 0; struct tevent_req *req; DEBUG(SSSDBG_TRACE_INTERNAL, "sss_autofs_cmd_getautomntbyname\n"); cmdctx = talloc_zero(client, struct autofs_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = client; actx = talloc_get_type(client->rctx->pvt_ctx, struct autofs_ctx); if (!actx) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing autofs context\n"); return EIO; } /* get autofs map name and index to query */ sss_packet_get_body(client->creq->in, &body, &blen); /* FIXME - split out a function to get string from \0 */ SAFEALIGN_COPY_UINT32_CHECK(&namelen, body+c, blen, &c); if (namelen == 0 || namelen > blen - c) { ret = EINVAL; goto done; } cmdctx->mapname = (char *) body+c; /* if not null-terminated fail */ if (cmdctx->mapname[namelen] != '\0') { ret = EINVAL; goto done; } /* If the name isn't valid UTF-8, fail */ if (!sss_utf8_check((const uint8_t *) cmdctx->mapname, namelen -1)) { ret = EINVAL; goto done; } c += namelen + 1; /* FIXME - split out a function to get string from \0 */ SAFEALIGN_COPY_UINT32_CHECK(&keylen, body+c, blen, &c); if (keylen == 0 || keylen > blen - c) { ret = EINVAL; goto done; } cmdctx->key = (char *) body+c; /* if not null-terminated fail */ if (cmdctx->key[keylen] != '\0') { ret = EINVAL; goto done; } /* If the key isn't valid UTF-8, fail */ if (!sss_utf8_check((const uint8_t *) cmdctx->key, keylen -1)) { ret = EINVAL; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Requested data of map %s key %s\n", cmdctx->mapname, cmdctx->key); ret = get_autofs_map(actx, cmdctx->mapname, &map); if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "Performing implicit setautomntent\n"); req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_send failed\n"); ret = EIO; goto done; } tevent_req_set_callback(req, getautomntbyname_implicit_done, cmdctx); ret = EOK; goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "An unexpected error occurred: [%d][%s]\n", ret, strerror(ret)); goto done; } if (map->ready == false) { DEBUG(SSSDBG_TRACE_FUNC, "Performing implicit setautomntent\n"); req = setautomntent_send(cmdctx, cmdctx->mapname, cmdctx); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_send failed\n"); ret = EIO; goto done; } tevent_req_set_callback(req, getautomntbyname_implicit_done, cmdctx); ret = EOK; goto done; } else if (map->found == false) { DEBUG(SSSDBG_TRACE_FUNC, "negative cache hit\n"); ret = ENOENT; goto done; } DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up value for [%s] in [%s]\n", cmdctx->key, map->mapname); ret = getautomntbyname_process(cmdctx, map, cmdctx->key); done: return autofs_cmd_done(cmdctx, ret); } static void getautomntbyname_implicit_done(struct tevent_req *req) { errno_t ret; struct autofs_map_ctx *map; struct autofs_cmd_ctx *cmdctx = tevent_req_callback_data(req, struct autofs_cmd_ctx); struct autofs_ctx *actx = talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct autofs_ctx); ret = setautomntent_recv(req); talloc_zfree(req); if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "setautomntent_recv failed\n"); } else { DEBUG(SSSDBG_MINOR_FAILURE, "No such map\n"); } goto done; } ret = get_autofs_map(actx, cmdctx->mapname, &map); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get map after setautomntent succeeded?\n"); goto done; } if (map->ready == false) { DEBUG(SSSDBG_CRIT_FAILURE, "Map not ready after setautomntent succeeded\n"); goto done; } ret = getautomntbyname_process(cmdctx, map, cmdctx->key); done: autofs_cmd_done(cmdctx, ret); return; } static errno_t getautomntbyname_process(struct autofs_cmd_ctx *cmdctx, struct autofs_map_ctx *map, const char *key) { struct cli_ctx *client = cmdctx->cctx; errno_t ret; size_t i; const char *k; const char *value; size_t valuelen; size_t len; uint8_t *body; size_t blen, rp; /* create response packet */ ret = sss_packet_new(client->creq, 0, sss_packet_get_cmd(client->creq->in), &client->creq->out); if (ret != EOK) { return ret; } if (!map->map || !map->entries || !map->entries[0]) { DEBUG(SSSDBG_MINOR_FAILURE, "No entries found\n"); ret = sss_cmd_empty_packet(client->creq->out); if (ret != EOK) { return autofs_cmd_done(cmdctx, ret); } goto done; } for (i=0; i < map->entry_count; i++) { k = ldb_msg_find_attr_as_string(map->entries[i], SYSDB_AUTOFS_ENTRY_KEY, NULL); if (!k) { DEBUG(SSSDBG_MINOR_FAILURE, "Skipping incomplete entry\n"); continue; } if (strcmp(k, key) == 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "Found key [%s]\n", key); break; } } if (i >= map->entry_count) { DEBUG(SSSDBG_MINOR_FAILURE, "No key named [%s] found\n", key); ret = sss_cmd_empty_packet(client->creq->out); if (ret != EOK) { return autofs_cmd_done(cmdctx, ret); } goto done; } value = ldb_msg_find_attr_as_string(map->entries[i], SYSDB_AUTOFS_ENTRY_VALUE, NULL); valuelen = 1 + strlen(value); len = sizeof(uint32_t) + sizeof(uint32_t) + valuelen; ret = sss_packet_grow(client->creq->out, len); if (ret != EOK) { goto done; } sss_packet_get_body(client->creq->out, &body, &blen); rp = 0; SAFEALIGN_SET_UINT32(&body[rp], len, &rp); SAFEALIGN_SET_UINT32(&body[rp], valuelen, &rp); if (valuelen == 1) { body[rp] = '\0'; } else { memcpy(&body[rp], value, valuelen); } rp += valuelen; ret = EOK; done: sss_packet_set_error(client->creq->out, ret); sss_cmd_done(client, cmdctx); return EOK; } static int sss_autofs_cmd_endautomntent(struct cli_ctx *client) { errno_t ret; DEBUG(SSSDBG_TRACE_FUNC, "endautomntent called\n"); /* create response packet */ ret = sss_packet_new(client->creq, 0, sss_packet_get_cmd(client->creq->in), &client->creq->out); if (ret != EOK) { return ret; } sss_cmd_done(client, NULL); return EOK; } struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version autofs_cli_protocol_version[] = { { SSS_AUTOFS_PROTO_VERSION, NULL, NULL } }; return autofs_cli_protocol_version; } struct sss_cmd_table *get_autofs_cmds(void) { static struct sss_cmd_table autofs_cmds[] = { { SSS_GET_VERSION, sss_cmd_get_version }, { SSS_AUTOFS_SETAUTOMNTENT, sss_autofs_cmd_setautomntent }, { SSS_AUTOFS_GETAUTOMNTENT, sss_autofs_cmd_getautomntent }, { SSS_AUTOFS_GETAUTOMNTBYNAME, sss_autofs_cmd_getautomntbyname }, { SSS_AUTOFS_ENDAUTOMNTENT, sss_autofs_cmd_endautomntent }, { SSS_CLI_NULL, NULL} }; return autofs_cmds; } sssd-1.13.4/src/responder/autofs/PaxHeaders.16287/autofssrv.c0000644000000000000000000000007412703456111020616 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.995794785 sssd-1.13.4/src/responder/autofs/autofssrv.c0000644002412700241270000001735712703456111022302 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2012 Red Hat Autofs responder: the responder server This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "confdb/confdb.h" #include "monitor/monitor_interfaces.h" #include "responder/common/responder.h" #include "providers/data_provider.h" #include "responder/autofs/autofs_private.h" static int autofs_clean_hash_table(struct sbus_request *dbus_req, void *data); struct mon_cli_iface monitor_autofs_methods = { { &mon_cli_iface_meta, 0 }, .ping = monitor_common_pong, .resInit = monitor_common_res_init, .shutDown = NULL, .goOffline = NULL, .resetOffline = NULL, .rotateLogs = responder_logrotate, .clearMemcache = NULL, .clearEnumCache = autofs_clean_hash_table, .sysbusReconnect = NULL, }; static struct data_provider_iface autofs_dp_methods = { { &data_provider_iface_meta, 0 }, .RegisterService = NULL, .pamHandler = NULL, .sudoHandler = NULL, .autofsHandler = NULL, .hostHandler = NULL, .getDomains = NULL, .getAccountInfo = NULL, }; static errno_t autofs_get_config(struct autofs_ctx *actx, struct confdb_ctx *cdb) { errno_t ret; ret = confdb_get_int(cdb, CONFDB_AUTOFS_CONF_ENTRY, CONFDB_AUTOFS_MAP_NEG_TIMEOUT, 15, &actx->neg_timeout); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot read %s from configuration [%d]: %s\n", CONFDB_AUTOFS_MAP_NEG_TIMEOUT, ret, strerror(ret)); return ret; } return EOK; } static void autofs_dp_reconnect_init(struct sbus_connection *conn, int status, void *pvt) { struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn); int ret; /* Did we reconnect successfully? */ if (status == SBUS_RECONNECT_SUCCESS) { DEBUG(SSSDBG_TRACE_FUNC, "Reconnected to the Data Provider.\n"); /* Identify ourselves to the data provider */ ret = dp_common_send_id(be_conn->conn, DATA_PROVIDER_VERSION, "autofs"); /* all fine */ if (ret == EOK) { handle_requests_after_reconnect(be_conn->rctx); return; } } /* Failed to reconnect */ DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n", be_conn->domain->name); } static int autofs_clean_hash_table(struct sbus_request *dbus_req, void *data) { struct resp_ctx *rctx = talloc_get_type(data, struct resp_ctx); struct autofs_ctx *actx = talloc_get_type(rctx->pvt_ctx, struct autofs_ctx); errno_t ret; ret = autofs_orphan_maps(actx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not invalidate maps\n"); return ret; } return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } static int autofs_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb) { struct resp_ctx *rctx; struct sss_cmd_table *autofs_cmds; struct autofs_ctx *autofs_ctx; struct be_conn *iter; int ret; int hret; int max_retries; autofs_cmds = get_autofs_cmds(); ret = sss_process_init(mem_ctx, ev, cdb, autofs_cmds, SSS_AUTOFS_SOCKET_NAME, -1, NULL, -1, CONFDB_AUTOFS_CONF_ENTRY, SSS_AUTOFS_SBUS_SERVICE_NAME, SSS_AUTOFS_SBUS_SERVICE_VERSION, &monitor_autofs_methods, "autofs", &autofs_dp_methods.vtable, &rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n"); return ret; } autofs_ctx = talloc_zero(rctx, struct autofs_ctx); if (!autofs_ctx) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing autofs_ctx\n"); ret = ENOMEM; goto fail; } ret = autofs_get_config(autofs_ctx, cdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot read autofs configuration\n"); goto fail; } autofs_ctx->rctx = rctx; autofs_ctx->rctx->pvt_ctx = autofs_ctx; /* Enable automatic reconnection to the Data Provider */ ret = confdb_get_int(autofs_ctx->rctx->cdb, CONFDB_AUTOFS_CONF_ENTRY, CONFDB_SERVICE_RECON_RETRIES, 3, &max_retries); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up automatic reconnection\n"); goto fail; } for (iter = autofs_ctx->rctx->be_conns; iter; iter = iter->next) { sbus_reconnect_init(iter->conn, max_retries, autofs_dp_reconnect_init, iter); } /* Create the lookup table for setautomntent results */ hret = sss_hash_create_ex(autofs_ctx, 10, &autofs_ctx->maps, 0, 0, 0, 0, autofs_map_hash_delete_cb, NULL); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize automount maps hash table\n"); ret = EIO; goto fail; } ret = schedule_get_domains_task(rctx, rctx->ev, rctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "autofs Initialization complete\n"); return EOK; fail: talloc_free(rctx); return ret; } int main(int argc, const char *argv[]) { int opt; poptContext pc; struct main_context *main_ctx; int ret; uid_t uid; gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; /* Set debug level to invalid value so we can decide if -d 0 was used. */ debug_level = SSSDBG_INVALID; umask(DFL_RSP_UMASK); pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_INIT(debug_level); /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_autofs"; ret = server_setup("sssd[autofs]", 0, uid, gid, CONFDB_AUTOFS_CONF_ENTRY, &main_ctx); if (ret != EOK) { return 2; } ret = die_if_parent_died(); if (ret != EOK) { /* This is not fatal, don't return */ DEBUG(SSSDBG_OP_FAILURE, "Could not set up to exit " "when parent process does\n"); } ret = autofs_process_init(main_ctx, main_ctx->event_ctx, main_ctx->confdb_ctx); if (ret != EOK) { return 3; } /* loop on main */ server_loop(main_ctx); return 0; } sssd-1.13.4/src/responder/PaxHeaders.16287/ssh0000644000000000000000000000013212703463557015644 xustar0030 mtime=1460561775.016794856 30 atime=1460561776.119798596 30 ctime=1460561775.016794856 sssd-1.13.4/src/responder/ssh/0000755002412700241270000000000012703463557017375 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/responder/ssh/PaxHeaders.16287/sshsrv_private.h0000644000000000000000000000007412703456111021145 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.480793039 sssd-1.13.4/src/responder/ssh/sshsrv_private.h0000644002412700241270000000365112703456111022621 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _SSHSRV_PRIVATE_H_ #define _SSHSRV_PRIVATE_H_ #include "responder/common/responder.h" #define SSS_SSH_KNOWN_HOSTS_PATH PUBCONF_PATH"/known_hosts" #define SSS_SSH_KNOWN_HOSTS_TEMP_TMPL PUBCONF_PATH"/.known_hosts.XXXXXX" struct ssh_ctx { struct resp_ctx *rctx; struct sss_names_ctx *snctx; bool hash_known_hosts; int known_hosts_timeout; char *ca_db; }; struct ssh_cmd_ctx { struct cli_ctx *cctx; char *name; char *alias; char *domname; bool is_user; struct sss_domain_info *domain; bool check_next; struct ldb_message *result; }; struct sss_cmd_table *get_ssh_cmds(void); struct tevent_req * sss_dp_get_ssh_host_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, bool fast_reply, const char *name, const char *alias); errno_t sss_dp_get_ssh_host_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret, char **err_msg); #endif /* _SSHSRV_PRIVATE_H_ */ sssd-1.13.4/src/responder/ssh/PaxHeaders.16287/sshsrv_dp.c0000644000000000000000000000007412703456111020071 xustar0030 atime=1460561751.652715634 30 ctime=1460561775.015794853 sssd-1.13.4/src/responder/ssh/sshsrv_dp.c0000644002412700241270000001070612703456111021544 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "sbus/sssd_dbus.h" #include "util/util.h" #include "sbus/sbus_client.h" #include "providers/data_provider.h" #include "responder/common/responder.h" #include "responder/ssh/sshsrv_private.h" struct sss_dp_get_ssh_host_info { struct sss_domain_info *dom; bool fast_reply; const char *name; const char *alias; }; static DBusMessage * sss_dp_get_ssh_host_msg(void *pvt); struct tevent_req * sss_dp_get_ssh_host_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, bool fast_reply, const char *name, const char *alias) { errno_t ret; struct tevent_req *req; struct sss_dp_get_ssh_host_info *info; struct sss_dp_req_state *state; char *key; req = tevent_req_create(mem_ctx, &state, struct sss_dp_req_state); if (!req) { ret = ENOMEM; goto error; } if (!dom) { ret = EINVAL; goto error; } info = talloc_zero(state, struct sss_dp_get_ssh_host_info); info->fast_reply = fast_reply; info->name = name; info->alias = alias; info->dom = dom; if (alias) { key = talloc_asprintf(state, "%s:%s@%s", name, alias, dom->name); } else { key = talloc_asprintf(state, "%s@%s", name, dom->name); } if (!key) { ret = ENOMEM; goto error; } ret = sss_dp_issue_request(state, rctx, key, dom, sss_dp_get_ssh_host_msg, info, req); talloc_free(key); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not issue DP request [%d]: %s\n", ret, strerror(ret)); goto error; } return req; error: tevent_req_error(req, ret); tevent_req_post(req, rctx->ev); return req; } static DBusMessage * sss_dp_get_ssh_host_msg(void *pvt) { DBusMessage *msg; dbus_bool_t dbret; struct sss_dp_get_ssh_host_info *info; uint32_t be_type = 0; char *filter; info = talloc_get_type(pvt, struct sss_dp_get_ssh_host_info); if (info->fast_reply) { be_type |= BE_REQ_FAST; } if (info->alias) { filter = talloc_asprintf(info, "name=%s:%s", info->name, info->alias); } else { filter = talloc_asprintf(info, "name=%s", info->name); } if (!filter) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); return NULL; } msg = dbus_message_new_method_call(NULL, DP_PATH, DATA_PROVIDER_IFACE, DATA_PROVIDER_IFACE_HOSTHANDLER); if (msg == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); talloc_free(filter); return NULL; } /* create the message */ DEBUG(SSSDBG_TRACE_FUNC, "Creating SSH host request for [%s][%u][%s]\n", info->dom->name, be_type, filter); dbret = dbus_message_append_args(msg, DBUS_TYPE_UINT32, &be_type, DBUS_TYPE_STRING, &filter, DBUS_TYPE_INVALID); talloc_free(filter); if (!dbret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n"); dbus_message_unref(msg); return NULL; } return msg; } errno_t sss_dp_get_ssh_host_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret, char **err_msg) { return sss_dp_req_recv(mem_ctx, req, dp_err, dp_ret, err_msg); } sssd-1.13.4/src/responder/ssh/PaxHeaders.16287/sshsrv_cmd.c0000644000000000000000000000007412703456111020231 xustar0030 atime=1460561751.652715634 30 ctime=1460561775.016794856 sssd-1.13.4/src/responder/ssh/sshsrv_cmd.c0000644002412700241270000007431212703456111021707 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include "util/util.h" #include "util/crypto/sss_crypto.h" #include "util/sss_ssh.h" #include "util/cert.h" #include "db/sysdb.h" #include "db/sysdb_ssh.h" #include "providers/data_provider.h" #include "responder/common/responder.h" #include "responder/common/responder_packet.h" #include "responder/ssh/sshsrv_private.h" static errno_t ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx); static errno_t ssh_user_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx); static errno_t ssh_cmd_get_user_pubkeys_done(struct ssh_cmd_ctx *cmd_ctx, errno_t ret); int sss_ssh_cmd_get_user_pubkeys(struct cli_ctx *cctx) { errno_t ret; struct ssh_cmd_ctx *cmd_ctx; cmd_ctx = talloc_zero(cctx, struct ssh_cmd_ctx); if (!cmd_ctx) { return ENOMEM; } cmd_ctx->cctx = cctx; cmd_ctx->is_user = true; ret = ssh_cmd_parse_request(cmd_ctx); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Requesting SSH user public keys for [%s] from [%s]\n", cmd_ctx->name, cmd_ctx->domname ? cmd_ctx->domname : ""); if (strcmp(cmd_ctx->name, "root") == 0) { ret = ENOENT; goto done; } if (cmd_ctx->domname) { cmd_ctx->domain = responder_get_domain(cctx->rctx, cmd_ctx->domname); if (!cmd_ctx->domain) { ret = ENOENT; goto done; } } else { cmd_ctx->domain = cctx->rctx->domains; cmd_ctx->check_next = true; } ret = ssh_user_pubkeys_search(cmd_ctx); done: return ssh_cmd_get_user_pubkeys_done(cmd_ctx, ret); } static errno_t ssh_host_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx); static errno_t ssh_cmd_get_host_pubkeys_done(struct ssh_cmd_ctx *cmd_ctx, errno_t ret); static int sss_ssh_cmd_get_host_pubkeys(struct cli_ctx *cctx) { errno_t ret; struct ssh_cmd_ctx *cmd_ctx; cmd_ctx = talloc_zero(cctx, struct ssh_cmd_ctx); if (!cmd_ctx) { return ENOMEM; } cmd_ctx->cctx = cctx; cmd_ctx->is_user = false; ret = ssh_cmd_parse_request(cmd_ctx); if (ret != EOK) { goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Requesting SSH host public keys for [%s][%s] from [%s]\n", cmd_ctx->name, cmd_ctx->alias ? cmd_ctx->alias : "", cmd_ctx->domname ? cmd_ctx->domname : ""); if (cmd_ctx->domname) { cmd_ctx->domain = responder_get_domain(cctx->rctx, cmd_ctx->domname); if (!cmd_ctx->domain) { ret = ENOENT; goto done; } } else { cmd_ctx->domain = cctx->rctx->domains; cmd_ctx->check_next = true; } ret = ssh_host_pubkeys_search(cmd_ctx); done: return ssh_cmd_get_host_pubkeys_done(cmd_ctx, ret); } static void ssh_dp_send_req_done(struct tevent_req *req) { struct dp_callback_ctx *cb_ctx = tevent_req_callback_data(req, struct dp_callback_ctx); errno_t ret; dbus_uint16_t err_maj; dbus_uint32_t err_min; char *err_msg; ret = sss_dp_get_ssh_host_recv(cb_ctx->mem_ctx, req, &err_maj, &err_min, &err_msg); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error, killing connection!\n"); talloc_free(cb_ctx->cctx); return; } cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr); } static errno_t ssh_user_pubkeys_search_next(struct ssh_cmd_ctx *cmd_ctx); static void ssh_user_pubkeys_search_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); static errno_t ssh_user_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx) { struct tevent_req *req; struct dp_callback_ctx *cb_ctx; /* if it is a domainless search, skip domains that require fully * qualified names instead */ while (cmd_ctx->domain && cmd_ctx->check_next && cmd_ctx->domain->fqnames) { cmd_ctx->domain = get_next_domain(cmd_ctx->domain, false); } if (!cmd_ctx->domain) { DEBUG(SSSDBG_OP_FAILURE, "No matching domain found for [%s], fail!\n", cmd_ctx->name); return ENOENT; } /* refresh the user's cache entry */ if (NEED_CHECK_PROVIDER(cmd_ctx->domain->provider)) { req = sss_dp_get_account_send(cmd_ctx, cmd_ctx->cctx->rctx, cmd_ctx->domain, false, SSS_DP_USER, cmd_ctx->name, 0, NULL); if (!req) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending data provider request\n"); return ENOMEM; } cb_ctx = talloc_zero(cmd_ctx, struct dp_callback_ctx); if (!cb_ctx) { talloc_zfree(req); return ENOMEM; } cb_ctx->callback = ssh_user_pubkeys_search_dp_callback; cb_ctx->ptr = cmd_ctx; cb_ctx->cctx = cmd_ctx->cctx; cb_ctx->mem_ctx = cmd_ctx; tevent_req_set_callback(req, ssh_dp_send_req_done, cb_ctx); /* tell caller we are in an async call */ return EAGAIN; } return ssh_user_pubkeys_search_next(cmd_ctx); } static errno_t ssh_user_pubkeys_search_next(struct ssh_cmd_ctx *cmd_ctx) { errno_t ret; const char *attrs[] = { SYSDB_NAME, SYSDB_SSH_PUBKEY, SYSDB_USER_CERT, NULL }; struct ldb_result *res; DEBUG(SSSDBG_TRACE_FUNC, "Requesting SSH user public keys for [%s@%s]\n", cmd_ctx->name, cmd_ctx->domain->name); if (cmd_ctx->domain->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); return EFAULT; } ret = sysdb_get_user_attr_with_views(cmd_ctx, cmd_ctx->domain, cmd_ctx->name, attrs, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); return EIO; } if (res->count > 1) { DEBUG(SSSDBG_FATAL_FAILURE, "User search by name (%s) returned > 1 results!\n", cmd_ctx->name); return EINVAL; } if (!res->count) { /* if a multidomain search, try with next */ if (cmd_ctx->check_next) { cmd_ctx->domain = get_next_domain(cmd_ctx->domain, false); return ssh_user_pubkeys_search(cmd_ctx); } DEBUG(SSSDBG_OP_FAILURE, "No attributes for user [%s] found.\n", cmd_ctx->name); return ENOENT; } cmd_ctx->result = res->msgs[0]; /* one result found */ return EOK; } static void ssh_user_pubkeys_search_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr) { struct ssh_cmd_ctx *cmd_ctx = talloc_get_type(ptr, struct ssh_cmd_ctx); errno_t ret; if (err_maj) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get information from Data Provider\n" "Error: %u, %u, %s\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg); } ret = ssh_user_pubkeys_search_next(cmd_ctx); ssh_cmd_get_user_pubkeys_done(cmd_ctx, ret); } static errno_t ssh_host_pubkeys_search_next(struct ssh_cmd_ctx *cmd_ctx); static void ssh_host_pubkeys_search_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); static errno_t ssh_host_pubkeys_search(struct ssh_cmd_ctx *cmd_ctx) { struct tevent_req *req; struct dp_callback_ctx *cb_ctx; if (!cmd_ctx->domain) { DEBUG(SSSDBG_OP_FAILURE, "No matching domain found for [%s], fail!\n", cmd_ctx->name); return ENOENT; } /* refresh the host's cache entry */ if (NEED_CHECK_PROVIDER(cmd_ctx->domain->provider)) { req = sss_dp_get_ssh_host_send(cmd_ctx, cmd_ctx->cctx->rctx, cmd_ctx->domain, false, cmd_ctx->name, cmd_ctx->alias); if (!req) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending data provider request\n"); return ENOMEM; } cb_ctx = talloc_zero(cmd_ctx, struct dp_callback_ctx); if (!cb_ctx) { talloc_zfree(req); return ENOMEM; } cb_ctx->callback = ssh_host_pubkeys_search_dp_callback; cb_ctx->ptr = cmd_ctx; cb_ctx->cctx = cmd_ctx->cctx; cb_ctx->mem_ctx = cmd_ctx; tevent_req_set_callback(req, ssh_dp_send_req_done, cb_ctx); /* tell caller we are in an async call */ return EAGAIN; } return ssh_host_pubkeys_search_next(cmd_ctx); } static errno_t ssh_host_pubkeys_search_next(struct ssh_cmd_ctx *cmd_ctx) { errno_t ret; struct sysdb_ctx *sysdb; const char *attrs[] = { SYSDB_NAME, SYSDB_SSH_PUBKEY, NULL }; DEBUG(SSSDBG_TRACE_FUNC, "Requesting SSH host public keys for [%s@%s]\n", cmd_ctx->name, cmd_ctx->domain->name); sysdb = cmd_ctx->domain->sysdb; if (sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); return EFAULT; } ret = sysdb_get_ssh_host(cmd_ctx, cmd_ctx->domain, cmd_ctx->name, attrs, &cmd_ctx->result); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); return EIO; } if (ret == ENOENT) { /* if a multidomain search, try with next */ if (cmd_ctx->check_next) { cmd_ctx->domain = get_next_domain(cmd_ctx->domain, false); return ssh_host_pubkeys_search(cmd_ctx); } DEBUG(SSSDBG_OP_FAILURE, "No attributes for host [%s] found.\n", cmd_ctx->name); return ENOENT; } return EOK; } static void ssh_host_pubkeys_search_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr) { struct ssh_cmd_ctx *cmd_ctx = talloc_get_type(ptr, struct ssh_cmd_ctx); errno_t ret; if (err_maj) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get information from Data Provider\n" "Error: %u, %u, %s\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg); } ret = ssh_host_pubkeys_search_next(cmd_ctx); ssh_cmd_get_host_pubkeys_done(cmd_ctx, ret); } static char * ssh_host_pubkeys_format_known_host_plain(TALLOC_CTX *mem_ctx, struct sss_ssh_ent *ent) { TALLOC_CTX *tmp_ctx; errno_t ret; char *name, *pubkey; char *result = NULL; size_t i; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return NULL; } name = talloc_strdup(tmp_ctx, ent->name); if (!name) { goto done; } for (i = 0; i < ent->num_aliases; i++) { name = talloc_asprintf_append(name, ",%s", ent->aliases[i]); if (!name) { goto done; } } result = talloc_strdup(tmp_ctx, ""); if (!result) { goto done; } for (i = 0; i < ent->num_pubkeys; i++) { ret = sss_ssh_format_pubkey(tmp_ctx, &ent->pubkeys[i], &pubkey); if (ret != EOK) { result = NULL; goto done; } result = talloc_asprintf_append(result, "%s %s\n", name, pubkey); if (!result) { goto done; } talloc_free(pubkey); } talloc_steal(mem_ctx, result); done: talloc_free(tmp_ctx); return result; } static char * ssh_host_pubkeys_format_known_host_hashed(TALLOC_CTX *mem_ctx, struct sss_ssh_ent *ent) { TALLOC_CTX *tmp_ctx; errno_t ret; char *name, *pubkey, *saltstr, *hashstr, *result; unsigned char salt[SSS_SHA1_LENGTH], hash[SSS_SHA1_LENGTH]; size_t i, j, k; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return NULL; } result = talloc_strdup(tmp_ctx, ""); if (!result) { goto done; } for (i = 0; i < ent->num_pubkeys; i++) { ret = sss_ssh_format_pubkey(tmp_ctx, &ent->pubkeys[i], &pubkey); if (ret != EOK) { result = NULL; goto done; } for (j = 0; j <= ent->num_aliases; j++) { name = (j == 0 ? ent->name : ent->aliases[j-1]); for (k = 0; k < SSS_SHA1_LENGTH; k++) { salt[k] = rand(); } ret = sss_hmac_sha1(salt, SSS_SHA1_LENGTH, (unsigned char *)name, strlen(name), hash); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_hmac_sha1() failed (%d): %s\n", ret, strerror(ret)); result = NULL; goto done; } saltstr = sss_base64_encode(tmp_ctx, salt, SSS_SHA1_LENGTH); if (!saltstr) { result = NULL; goto done; } hashstr = sss_base64_encode(tmp_ctx, hash, SSS_SHA1_LENGTH); if (!hashstr) { result = NULL; goto done; } result = talloc_asprintf_append(result, "|1|%s|%s %s\n", saltstr, hashstr, pubkey); if (!result) { goto done; } talloc_free(saltstr); talloc_free(hashstr); } talloc_free(pubkey); } talloc_steal(mem_ctx, result); done: talloc_free(tmp_ctx); return result; } static errno_t ssh_host_pubkeys_update_known_hosts(struct ssh_cmd_ctx *cmd_ctx) { TALLOC_CTX *tmp_ctx; errno_t ret; const char *attrs[] = { SYSDB_NAME, SYSDB_NAME_ALIAS, SYSDB_SSH_PUBKEY, NULL }; struct cli_ctx *cctx = cmd_ctx->cctx; struct sss_domain_info *dom = cctx->rctx->domains; struct ssh_ctx *ssh_ctx = (struct ssh_ctx *)cctx->rctx->pvt_ctx; struct sysdb_ctx *sysdb; time_t now = time(NULL); struct ldb_message **hosts; size_t num_hosts, i; struct sss_ssh_ent *ent; int fd = -1; char *filename = NULL; char *entstr; ssize_t wret; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) { return ENOMEM; } if (cmd_ctx->domain) { ret = sysdb_update_ssh_known_host_expire(cmd_ctx->domain, cmd_ctx->name, now, ssh_ctx->known_hosts_timeout); if (ret != EOK && ret != ENOENT) { goto done; } } /* write known_hosts file */ filename = talloc_strdup(tmp_ctx, SSS_SSH_KNOWN_HOSTS_TEMP_TMPL); if (!filename) { ret = ENOMEM; goto done; } fd = sss_unique_file_ex(tmp_ctx, filename, 0133, &ret); if (fd == -1) { filename = NULL; goto done; } for (; dom; dom = get_next_domain(dom, false)) { sysdb = dom->sysdb; if (sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); ret = EFAULT; goto done; } ret = sysdb_get_ssh_known_hosts(tmp_ctx, dom, now, attrs, &hosts, &num_hosts); if (ret != EOK) { if (ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Host search failed for domain [%s]\n", dom->name); } continue; } for (i = 0; i < num_hosts; i++) { ret = sss_ssh_make_ent(tmp_ctx, hosts[i], &ent); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to get SSH host public keys\n"); continue; } if (ssh_ctx->hash_known_hosts) { entstr = ssh_host_pubkeys_format_known_host_hashed(ent, ent); } else { entstr = ssh_host_pubkeys_format_known_host_plain(ent, ent); } if (!entstr) { DEBUG(SSSDBG_OP_FAILURE, "Failed to format known_hosts data for [%s]\n", ent->name); continue; } wret = sss_atomic_write_s(fd, entstr, strlen(entstr)); if (wret == -1) { ret = errno; goto done; } talloc_free(ent); } talloc_free(hosts); } ret = fchmod(fd, 0644); if (ret == -1) { ret = errno; goto done; } ret = rename(filename, SSS_SSH_KNOWN_HOSTS_PATH); if (ret == -1) { ret = errno; goto done; } ret = EOK; done: if (fd != -1) { close(fd); } talloc_free(tmp_ctx); return ret; } static errno_t ssh_cmd_parse_request(struct ssh_cmd_ctx *cmd_ctx) { struct cli_ctx *cctx = cmd_ctx->cctx; struct ssh_ctx *ssh_ctx = talloc_get_type(cctx->rctx->pvt_ctx, struct ssh_ctx); errno_t ret; uint8_t *body; size_t body_len; size_t c = 0; uint32_t flags; uint32_t name_len; char *name; uint32_t alias_len; char *alias = NULL; uint32_t domain_len; char *domain = NULL; sss_packet_get_body(cctx->creq->in, &body, &body_len); SAFEALIGN_COPY_UINT32_CHECK(&flags, body+c, body_len, &c); if (flags & ~(uint32_t)SSS_SSH_REQ_MASK) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid flags received [0x%x]\n", flags); return EINVAL; } SAFEALIGN_COPY_UINT32_CHECK(&name_len, body+c, body_len, &c); if (name_len == 0 || name_len > body_len - c) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid name length\n"); return EINVAL; } name = (char *)(body+c); if (!sss_utf8_check((const uint8_t *)name, name_len-1) || name[name_len-1] != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Name is not valid UTF-8 string\n"); return EINVAL; } c += name_len; if (flags & SSS_SSH_REQ_ALIAS) { SAFEALIGN_COPY_UINT32_CHECK(&alias_len, body+c, body_len, &c); if (alias_len == 0 || alias_len > body_len - c) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid alias length\n"); return EINVAL; } alias = (char *)(body+c); if (!sss_utf8_check((const uint8_t *)alias, alias_len-1) || alias[alias_len-1] != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Alias is not valid UTF-8 string\n"); return EINVAL; } c += alias_len; } if (flags & SSS_SSH_REQ_DOMAIN) { SAFEALIGN_COPY_UINT32_CHECK(&domain_len, body+c, body_len, &c); if (domain_len > 0) { if (domain_len > body_len - c) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid domain length\n"); return EINVAL; } domain = (char *)(body+c); if (!sss_utf8_check((const uint8_t *)domain, domain_len-1) || domain[domain_len-1] != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Domain is not valid UTF-8 string\n"); return EINVAL; } c += domain_len; } DEBUG(SSSDBG_TRACE_FUNC, "Requested domain [%s]\n", domain ? domain : ""); } else { DEBUG(SSSDBG_TRACE_FUNC, "Splitting domain from name [%s]\n", name); ret = sss_parse_name(cmd_ctx, ssh_ctx->snctx, name, &cmd_ctx->domname, &cmd_ctx->name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Invalid name received [%s]\n", name); return ENOENT; } name = cmd_ctx->name; } if (cmd_ctx->is_user && cmd_ctx->domname == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "Parsing name [%s][%s]\n", name, domain ? domain : ""); ret = sss_parse_name_for_domains(cmd_ctx, cctx->rctx->domains, domain, name, &cmd_ctx->domname, &cmd_ctx->name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Invalid name received [%s]\n", name); return ENOENT; } } else { if (cmd_ctx->name == NULL) { cmd_ctx->name = talloc_strdup(cmd_ctx, name); if (!cmd_ctx->name) return ENOMEM; } if (cmd_ctx->domname == NULL && domain != NULL) { cmd_ctx->domname = talloc_strdup(cmd_ctx, domain); if (!cmd_ctx->domname) return ENOMEM; } } if (alias != NULL && strcmp(cmd_ctx->name, alias) != 0) { cmd_ctx->alias = talloc_strdup(cmd_ctx, alias); if (!cmd_ctx->alias) return ENOMEM; } return EOK; } static errno_t decode_and_add_base64_data(struct ssh_cmd_ctx *cmd_ctx, struct ldb_message_element *el, bool cert_data, struct ssh_ctx *ssh_ctx, size_t fqname_len, const char *fqname, size_t *c) { struct cli_ctx *cctx = cmd_ctx->cctx; uint8_t *key; size_t key_len; uint8_t *body; size_t body_len; int ret; size_t d; TALLOC_CTX *tmp_ctx; char *cert_verification_opts; bool do_ocsp = true; if (el == NULL) { DEBUG(SSSDBG_TRACE_ALL, "Mssing element, nothing to do.\n"); return EOK; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } for (d = 0; d < el->num_values; d++) { if (cert_data) { ret = confdb_get_string(cctx->rctx->cdb, tmp_ctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_CERT_VERIFICATION, NULL, &cert_verification_opts); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read p11_child_timeout from confdb: [%d] %s\n", ret, sss_strerror(ret)); return ret; } if (cert_verification_opts != NULL) { ret = parse_cert_verify_opts(cert_verification_opts, &do_ocsp); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse verifiy option.\n"); return ret; } } ret = cert_to_ssh_key(tmp_ctx, ssh_ctx->ca_db, el->values[d].data, el->values[d].length, do_ocsp, &key, &key_len); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "cert_to_ssh_key failed.\n"); return ret; } } else { key = sss_base64_decode(tmp_ctx, (const char *) el->values[d].data, &key_len); if (key == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n"); ret = ENOMEM; goto done; } } ret = sss_packet_grow(cctx->creq->out, 3*sizeof(uint32_t) + key_len + fqname_len); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_packet_grow failed.\n"); goto done; } sss_packet_get_body(cctx->creq->out, &body, &body_len); SAFEALIGN_SET_UINT32(body+(*c), 0, c); SAFEALIGN_SET_UINT32(body+(*c), fqname_len, c); safealign_memcpy(body+(*c), fqname, fqname_len, c); SAFEALIGN_SET_UINT32(body+(*c), key_len, c); safealign_memcpy(body+(*c), key, key_len, c); } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t ssh_cmd_build_reply(struct ssh_cmd_ctx *cmd_ctx) { struct cli_ctx *cctx = cmd_ctx->cctx; errno_t ret; uint8_t *body; size_t body_len; size_t c = 0; struct ldb_message_element *el = NULL; struct ldb_message_element *el_override = NULL; struct ldb_message_element *el_orig = NULL; struct ldb_message_element *el_user_cert = NULL; uint32_t count = 0; const char *name; char *fqname; uint32_t fqname_len; struct ssh_ctx *ssh_ctx = talloc_get_type(cctx->rctx->pvt_ctx, struct ssh_ctx); ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return ret; } el = ldb_msg_find_element(cmd_ctx->result, SYSDB_SSH_PUBKEY); if (el) { count = el->num_values; } el_orig = ldb_msg_find_element(cmd_ctx->result, ORIGINALAD_PREFIX SYSDB_SSH_PUBKEY); if (el_orig) { count = el_orig->num_values; } if (DOM_HAS_VIEWS(cmd_ctx->domain)) { el_override = ldb_msg_find_element(cmd_ctx->result, OVERRIDE_PREFIX SYSDB_SSH_PUBKEY); if (el_override) { count += el_override->num_values; } } el_user_cert = ldb_msg_find_element(cmd_ctx->result, SYSDB_USER_CERT); if (el_user_cert) { /* TODO check if cert is valid */ count += el_user_cert->num_values; } ret = sss_packet_grow(cctx->creq->out, 2*sizeof(uint32_t)); if (ret != EOK) { return ret; } sss_packet_get_body(cctx->creq->out, &body, &body_len); SAFEALIGN_SET_UINT32(body+c, count, &c); SAFEALIGN_SET_UINT32(body+c, 0, &c); if (count == 0) { return EOK; } name = ldb_msg_find_attr_as_string(cmd_ctx->result, SYSDB_NAME, NULL); if (!name) { DEBUG(SSSDBG_OP_FAILURE, "Got unnamed result for [%s@%s]\n", cmd_ctx->name, cmd_ctx->domain->name); return ENOENT; } fqname = talloc_asprintf(cmd_ctx, "%s@%s", name, cmd_ctx->domain->name); if (!fqname) { return ENOMEM; } fqname_len = strlen(fqname)+1; ret = decode_and_add_base64_data(cmd_ctx, el, false, ssh_ctx, fqname_len, fqname, &c); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "decode_and_add_base64_data failed.\n"); return ret; } ret = decode_and_add_base64_data(cmd_ctx, el_orig, false, ssh_ctx, fqname_len, fqname, &c); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "decode_and_add_base64_data failed.\n"); return ret; } ret = decode_and_add_base64_data(cmd_ctx, el_override, false, ssh_ctx, fqname_len, fqname, &c); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "decode_and_add_base64_data failed.\n"); return ret; } ret = decode_and_add_base64_data(cmd_ctx, el_user_cert, true, ssh_ctx, fqname_len, fqname, &c); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "decode_and_add_base64_data failed.\n"); return ret; } return EOK; } static errno_t ssh_cmd_send_error(struct ssh_cmd_ctx *cmd_ctx, errno_t error) { struct cli_ctx *cctx = cmd_ctx->cctx; errno_t ret; ret = sss_cmd_send_error(cctx, error); if (ret != EOK) { return ret; } sss_cmd_done(cctx, cmd_ctx); return EOK; } static errno_t ssh_cmd_send_reply(struct ssh_cmd_ctx *cmd_ctx) { struct cli_ctx *cctx = cmd_ctx->cctx; errno_t ret; /* create response packet */ ret = ssh_cmd_build_reply(cmd_ctx); if (ret != EOK) { return ret; } sss_packet_set_error(cctx->creq->out, EOK); sss_cmd_done(cctx, cmd_ctx); return EOK; } static errno_t ssh_cmd_done(struct ssh_cmd_ctx *cmd_ctx, errno_t ret) { switch (ret) { case EOK: ret = ssh_cmd_send_reply(cmd_ctx); break; case EAGAIN: return EOK; case EFAULT: break; default: ret = ssh_cmd_send_error(cmd_ctx, ret); break; } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error, killing connection!\n"); talloc_free(cmd_ctx->cctx); return EFAULT; } return EOK; } static errno_t ssh_cmd_get_user_pubkeys_done(struct ssh_cmd_ctx *cmd_ctx, errno_t ret) { return ssh_cmd_done(cmd_ctx, ret); } static errno_t ssh_cmd_get_host_pubkeys_done(struct ssh_cmd_ctx *cmd_ctx, errno_t ret) { if (ret == EOK || ret == ENOENT) { ssh_host_pubkeys_update_known_hosts(cmd_ctx); } return ssh_cmd_done(cmd_ctx, ret); } struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version ssh_cli_protocol_version[] = { {0, NULL, NULL} }; return ssh_cli_protocol_version; } struct sss_cmd_table *get_ssh_cmds(void) { static struct sss_cmd_table ssh_cmds[] = { {SSS_GET_VERSION, sss_cmd_get_version}, {SSS_SSH_GET_USER_PUBKEYS, sss_ssh_cmd_get_user_pubkeys}, {SSS_SSH_GET_HOST_PUBKEYS, sss_ssh_cmd_get_host_pubkeys}, {SSS_CLI_NULL, NULL} }; return ssh_cmds; } sssd-1.13.4/src/responder/ssh/PaxHeaders.16287/sshsrv.c0000644000000000000000000000007412703456111017406 xustar0030 atime=1460561751.652715634 30 ctime=1460561775.014794849 sssd-1.13.4/src/responder/ssh/sshsrv.c0000644002412700241270000001713712703456111021066 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Cholasta Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "confdb/confdb.h" #include "monitor/monitor_interfaces.h" #include "responder/common/responder.h" #include "responder/common/responder_sbus.h" #include "responder/ssh/sshsrv_private.h" #include "providers/data_provider.h" struct mon_cli_iface monitor_ssh_methods = { { &mon_cli_iface_meta, 0 }, .ping = monitor_common_pong, .resInit = monitor_common_res_init, .shutDown = NULL, .goOffline = NULL, .resetOffline = NULL, .rotateLogs = responder_logrotate, .clearMemcache = NULL, .clearEnumCache = NULL, .sysbusReconnect = NULL, }; static struct data_provider_iface ssh_dp_methods = { { &data_provider_iface_meta, 0 }, .RegisterService = NULL, .pamHandler = NULL, .sudoHandler = NULL, .autofsHandler = NULL, .hostHandler = NULL, .getDomains = NULL, .getAccountInfo = NULL, }; static void ssh_dp_reconnect_init(struct sbus_connection *conn, int status, void *pvt) { struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn); int ret; /* Did we reconnect successfully? */ if (status == SBUS_RECONNECT_SUCCESS) { DEBUG(SSSDBG_TRACE_FUNC, "Reconnected to the Data Provider.\n"); /* Identify ourselves to the data provider */ ret = dp_common_send_id(be_conn->conn, DATA_PROVIDER_VERSION, "SSH"); /* all fine */ if (ret == EOK) { handle_requests_after_reconnect(be_conn->rctx); return; } } /* Failed to reconnect */ DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n", be_conn->domain->name); } int ssh_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb) { struct resp_ctx *rctx; struct sss_cmd_table *ssh_cmds; struct ssh_ctx *ssh_ctx; struct be_conn *iter; int ret; int max_retries; ssh_cmds = get_ssh_cmds(); ret = sss_process_init(mem_ctx, ev, cdb, ssh_cmds, SSS_SSH_SOCKET_NAME, -1, NULL, -1, CONFDB_SSH_CONF_ENTRY, SSS_SSH_SBUS_SERVICE_NAME, SSS_SSH_SBUS_SERVICE_VERSION, &monitor_ssh_methods, "SSH", &ssh_dp_methods.vtable, &rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n"); return ret; } ssh_ctx = talloc_zero(rctx, struct ssh_ctx); if (!ssh_ctx) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing ssh_ctx\n"); ret = ENOMEM; goto fail; } ssh_ctx->rctx = rctx; ssh_ctx->rctx->pvt_ctx = ssh_ctx; ret = sss_names_init_from_args(ssh_ctx, "(?P[^@]+)@?(?P[^@]*$)", "%1$s@%2$s", &ssh_ctx->snctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing regex data\n"); goto fail; } /* Enable automatic reconnection to the Data Provider */ ret = confdb_get_int(ssh_ctx->rctx->cdb, CONFDB_SSH_CONF_ENTRY, CONFDB_SERVICE_RECON_RETRIES, 3, &max_retries); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up automatic reconnection\n"); goto fail; } for (iter = ssh_ctx->rctx->be_conns; iter; iter = iter->next) { sbus_reconnect_init(iter->conn, max_retries, ssh_dp_reconnect_init, iter); } /* Get responder options */ /* Get ssh_hash_known_hosts option */ ret = confdb_get_bool(ssh_ctx->rctx->cdb, CONFDB_SSH_CONF_ENTRY, CONFDB_SSH_HASH_KNOWN_HOSTS, CONFDB_DEFAULT_SSH_HASH_KNOWN_HOSTS, &ssh_ctx->hash_known_hosts); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n", ret, strerror(ret)); goto fail; } /* Get ssh_known_hosts_timeout option */ ret = confdb_get_int(ssh_ctx->rctx->cdb, CONFDB_SSH_CONF_ENTRY, CONFDB_SSH_KNOWN_HOSTS_TIMEOUT, CONFDB_DEFAULT_SSH_KNOWN_HOSTS_TIMEOUT, &ssh_ctx->known_hosts_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n", ret, strerror(ret)); goto fail; } ret = confdb_get_string(ssh_ctx->rctx->cdb, ssh_ctx, CONFDB_SSH_CONF_ENTRY, CONFDB_SSH_CA_DB, CONFDB_DEFAULT_SSH_CA_DB, &ssh_ctx->ca_db); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Error reading CA DB from confdb (%d) [%s]\n", ret, strerror(ret)); goto fail; } ret = schedule_get_domains_task(rctx, rctx->ev, rctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "SSH Initialization complete\n"); return EOK; fail: talloc_free(rctx); return ret; } int main(int argc, const char *argv[]) { int opt; poptContext pc; struct main_context *main_ctx; int ret; uid_t uid; gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; umask(DFL_RSP_UMASK); pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_INIT(debug_level); /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_ssh"; ret = server_setup("sssd[ssh]", 0, uid, gid, CONFDB_SSH_CONF_ENTRY, &main_ctx); if (ret != EOK) { return 2; } ret = die_if_parent_died(); if (ret != EOK) { /* This is not fatal, don't return */ DEBUG(SSSDBG_OP_FAILURE, "Could not set up to exit " "when parent process does\n"); } ret = ssh_process_init(main_ctx, main_ctx->event_ctx, main_ctx->confdb_ctx); if (ret != EOK) { return 3; } /* loop on main */ server_loop(main_ctx); return 0; } sssd-1.13.4/src/responder/PaxHeaders.16287/nss0000644000000000000000000000013212703463557015652 xustar0030 mtime=1460561775.009794832 30 atime=1460561776.119798596 30 ctime=1460561775.009794832 sssd-1.13.4/src/responder/nss/0000755002412700241270000000000012703463557017403 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/responder/nss/PaxHeaders.16287/nsssrv_services.c0000644000000000000000000000007412703456111021325 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.946794619 sssd-1.13.4/src/responder/nss/nsssrv_services.c0000644002412700241270000015412512703456111023004 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "responder/nss/nsssrv.h" #include "responder/nss/nsssrv_private.h" #include "responder/nss/nsssrv_services.h" #include "responder/common/negcache.h" #include "confdb/confdb.h" #include "db/sysdb.h" #include "db/sysdb_services.h" struct getserv_ctx { uint16_t port; struct tevent_context *ev; struct nss_dom_ctx *dctx; struct sss_domain_info **domains; size_t dom_idx; char *name; char *cased_name; char *proto; char *cased_proto; struct ldb_result *res; }; static errno_t lookup_service_step(struct tevent_req *req); static void lookup_service_done(struct tevent_req *req); #define SVC_NAME_CASED (dom->case_sensitive ? state->name \ : state->cased_name) #define SVC_PROTO_CASED (dom->case_sensitive ? state->proto \ : state->cased_proto) /* Provider Lookup Logic: * Iterate through the available caches. If the cached entry is * present and not expired, return it immediately(*). If it is * present and expired, add it to a list of domains eligible to * be checked. If it is in the negative cache, skip over it and * do not add it to the eligible domain list. * * Once we have searched all of the caches, if the entry has not * been determined to be available, search all domains in order * to see if any of them contain the requested entry. * * (*) Optionally perform a midpoint cache refresh if appropriate. */ static struct tevent_req * getserv_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, uint16_t port, const char *service_name, const char *service_protocol, struct nss_dom_ctx *dctx) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct getserv_ctx *state; struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct cli_ctx *cctx = cmdctx->cctx; struct sss_domain_info *dom; size_t num_domains = 0; size_t dom_idx = 0; struct nss_ctx *nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); time_t now = time(NULL); uint64_t lastUpdate; uint64_t cacheExpire; uint64_t midpoint_refresh; req = tevent_req_create(mem_ctx, &state, struct getserv_ctx); if (!req) return NULL; state->dctx = dctx; for (dom = cctx->rctx->domains; dom; dom = get_next_domain(dom, 0)) { num_domains++; } /* Create an array of domains to check. To save resizes, we'll * assume that all will be checked */ state->domains = talloc_zero_array(state, struct sss_domain_info *, num_domains + 1); if (!state->domains) { ret = ENOMEM; goto immediate; } state->port = port; /* Store both the case-sensitive and lowercased names * in the state object, to avoid recalculating the * lowercase in multiple domains. */ if (service_protocol) { state->proto = talloc_strdup(state, service_protocol); if (!state->proto) { ret = ENOMEM; goto immediate; } state->cased_proto = sss_get_cased_name(state, service_protocol, false); if (!state->cased_proto) { ret = ENOMEM; goto immediate; } } else { state->proto = NULL; state->cased_proto = NULL; } /* If we're looking up by name */ if (service_name) { /* Store both the case-sensitive and lowercased names * in the state object, to avoid recalculating the * lowercase in multiple domains. */ state->name = talloc_strdup(state, service_name); if (!state->name) { ret = ENOMEM; goto immediate; } state->cased_name = sss_get_cased_name(state, service_name, false); if (!state->cased_name) { ret = ENOMEM; goto immediate; } } dom = cctx->rctx->domains; while(dom) { /* if it is a domainless search, skip domains that require fully * qualified names instead */ while (dom && cmdctx->check_next && dom->fqnames) { dom = get_next_domain(dom, 0); } if (!dom) break; if (dom->sysdb == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Critical: Sysdb CTX not found for [%s]!\n", dom->name); ret = EINVAL; goto immediate; } /* If we're looking up by name */ if (service_name) { /* Check the negative cache */ ret = sss_ncache_check_service(nctx->ncache, nctx->neg_timeout, dom, SVC_NAME_CASED, SVC_PROTO_CASED); /* If negatively cached, return we didn't find it */ if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "Service [%s:%s] does not exist in [%s]! " "(negative cache)\n", SVC_NAME_CASED, SVC_PROTO_CASED ? SVC_PROTO_CASED : "", dom->name); /* If this is a multi-domain search, try the next one */ if (cmdctx->check_next) { dom = get_next_domain(dom, 0); } else { /* This was a single-domain search. * exit the loop. Since it was negatively- * cached, don't add it to the eligible * domains list. */ dom = NULL; } continue; } /* Check the cache */ DEBUG(SSSDBG_TRACE_FUNC, "Checking cache for [%s:%s@%s]\n", SVC_NAME_CASED, SVC_PROTO_CASED ? SVC_PROTO_CASED : "", dom->name); ret = sysdb_getservbyname(state, dom, SVC_NAME_CASED, SVC_PROTO_CASED, &state->res); } else { /* Looking up by port */ /* Check the negative cache */ ret = sss_ncache_check_service_port(nctx->ncache, nctx->neg_timeout, dom, port, SVC_PROTO_CASED); /* If negatively cached, return we didn't find it */ if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "Service [%"PRIu16":%s] does not exist in [%s]! " "(negative cache)\n", port, SVC_PROTO_CASED ? SVC_PROTO_CASED : "", dom->name); /* If this is a multi-domain search, try the next one */ if (cmdctx->check_next) { dom = get_next_domain(dom, 0); } else { /* This was a single-domain search. * exit the loop. Since it was negatively- * cached, don't add it to the eligible * domains list. */ dom = NULL; } continue; } /* Check the cache */ DEBUG(SSSDBG_TRACE_FUNC, "Checking cache for [%"PRIu16":%s@%s]\n", port, SVC_PROTO_CASED ? SVC_PROTO_CASED : "", dom->name); ret = sysdb_getservbyport(state, dom, port, SVC_PROTO_CASED, &state->res); } if (ret != EOK && ret != ENOENT) goto immediate; if (ret == ENOENT) { /* Not found in the cache. Add this domain to the * list of eligible domains to check the provider. */ if (NEED_CHECK_PROVIDER(dom->provider)) { state->domains[dom_idx] = dom; dom_idx++; } else { /* No provider to check. Set the negative cache here */ if (state->name) { ret = sss_ncache_set_service_name(nctx->ncache, false, dom, SVC_NAME_CASED, SVC_PROTO_CASED); if (ret != EOK) { /* Failure to set the negative cache is non-fatal. * We'll log an error and continue. */ DEBUG(SSSDBG_MINOR_FAILURE, "Could not set negative cache for [%s][%s]\n", SVC_NAME_CASED, SVC_PROTO_CASED); } } else { ret = sss_ncache_set_service_port(nctx->ncache, false, dom, state->port, SVC_PROTO_CASED); if (ret != EOK) { /* Failure to set the negative cache is non-fatal. * We'll log an error and continue. */ DEBUG(SSSDBG_MINOR_FAILURE, "Could not set negative cache for " "[%"PRIu16"][%s]\n", state->port, SVC_PROTO_CASED); } } } /* If this is a multi-domain search, try the next one */ if (cmdctx->check_next) { dom = get_next_domain(dom, 0); } else { /* This was a single-domain search. * exit the loop. */ dom = NULL; } continue; } /* Found a result. Check its validity */ if (state->res->count > 1) { DEBUG(SSSDBG_OP_FAILURE, "getservby* returned more than one result!\n"); ret = ENOENT; goto immediate; } lastUpdate = ldb_msg_find_attr_as_uint64(state->res->msgs[0], SYSDB_LAST_UPDATE, 0); cacheExpire = ldb_msg_find_attr_as_uint64(state->res->msgs[0], SYSDB_CACHE_EXPIRE, 0); midpoint_refresh = 0; if(nctx->cache_refresh_percent) { midpoint_refresh = lastUpdate + (cacheExpire - lastUpdate)*nctx->cache_refresh_percent/100.0; if (midpoint_refresh - lastUpdate < 10) { /* If the percentage results in an expiration * less than ten seconds after the lastUpdate time, * that's too often we will simply set it to 10s */ midpoint_refresh = lastUpdate+10; } } if (cacheExpire > now) { /* cache still valid */ if (NEED_CHECK_PROVIDER(dom->provider) && midpoint_refresh && midpoint_refresh < now) { /* We're past the cache refresh timeout * We'll return the value from the cache, but we'll also * queue the cache entry for update out-of-band. */ DEBUG(SSSDBG_TRACE_FUNC, "Performing midpoint cache update\n"); /* Update the cache */ subreq = sss_dp_get_account_send(cctx, cctx->rctx, dom, true, SSS_DP_SERVICES, SVC_NAME_CASED, port, NULL); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band data provider " "request\n"); /* This is non-fatal, so we'll continue here */ } /* We don't need to listen for a reply, so we will free the * request here. */ talloc_zfree(subreq); } /* The cache is valid. Return it */ ret = EOK; goto immediate; } else { /* Cache is expired. Add this domain to the * list of eligible domains to check the provider. */ if (NEED_CHECK_PROVIDER(dom->provider)) { state->domains[dom_idx] = dom; dom_idx++; } /* If this is a multi-domain search, try the next one */ if (cmdctx->check_next) { dom = get_next_domain(dom, 0); } else { /* This was a single-domain search. * exit the loop. */ dom = NULL; } } } /* No valid cached entries found and * not found in negative caches. * Iterate through the domains and try * to look the data up. */ state->dom_idx = 0; if (!state->domains[state->dom_idx]) { /* No domains to search. Return ENOENT */ ret = ENOENT; goto immediate; } ret = lookup_service_step(req); if (ret != EOK) goto immediate; return req; immediate: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t lookup_service_step(struct tevent_req *req) { struct getserv_ctx *state = tevent_req_data(req, struct getserv_ctx); struct tevent_req *subreq; struct cli_ctx *cctx = state->dctx->cmdctx->cctx; struct sss_domain_info *dom = state->domains[state->dom_idx]; /* Update the cache */ subreq = sss_dp_get_account_send(req, cctx->rctx, dom, true, SSS_DP_SERVICES, SVC_NAME_CASED, state->port, SVC_PROTO_CASED); if (!subreq) return ENOMEM; tevent_req_set_callback(subreq, lookup_service_done, req); return EOK; } static void lookup_service_done(struct tevent_req *subreq) { errno_t ret; dbus_uint16_t err_maj; dbus_uint32_t err_min; char *err_msg; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct getserv_ctx *state = tevent_req_data(req, struct getserv_ctx); struct cli_ctx *cctx = state->dctx->cmdctx->cctx; struct nss_ctx *nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); struct sss_domain_info *dom = state->domains[state->dom_idx]; ret = sss_dp_get_account_recv(state, subreq, &err_maj, &err_min, &err_msg); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get information from Data Provider\n" "dp_error: [%u], errno: [%u], error_msg: [%s]\n" "Will try to return what we have in cache\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg ? err_msg : "none"); } /* Recheck the cache after the lookup. * We can ignore the expiration values here, because * either we have just updated it or the provider is * offline. Either way, whatever is in the cache should * be returned, if it exists. Otherwise, move to the * next provider. */ if (dom->sysdb == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Critical: Sysdb CTX not found for [%s]!\n", dom->name); ret = EINVAL; goto done; } if (state->name) { DEBUG(SSSDBG_TRACE_FUNC, "Re-checking cache for [%s:%s@%s]\n", SVC_NAME_CASED, SVC_PROTO_CASED ? SVC_PROTO_CASED : "", dom->name); ret = sysdb_getservbyname(state, dom, SVC_NAME_CASED, SVC_PROTO_CASED, &state->res); } else { DEBUG(SSSDBG_TRACE_FUNC, "Re-checking cache for [%"PRIu16":%s@%s]\n", state->port, SVC_PROTO_CASED ? SVC_PROTO_CASED : "", dom->name); ret = sysdb_getservbyport(state, dom, state->port, SVC_PROTO_CASED, &state->res); } if (ret == ENOENT) { /* Nothing in the cache. * Set the negative cache */ if (state->name) { ret = sss_ncache_set_service_name(nctx->ncache, false, dom, SVC_NAME_CASED, SVC_PROTO_CASED); if (ret != EOK) { /* Failure to set the negative cache is non-fatal. * We'll log an error and continue. */ DEBUG(SSSDBG_MINOR_FAILURE, "Could not set negative cache for [%s][%s]\n", SVC_NAME_CASED, SVC_PROTO_CASED); } } else { ret = sss_ncache_set_service_port(nctx->ncache, false, dom, state->port, SVC_PROTO_CASED); if (ret != EOK) { /* Failure to set the negative cache is non-fatal. * We'll log an error and continue. */ DEBUG(SSSDBG_MINOR_FAILURE, "Could not set negative cache for [%"PRIu16"][%s]\n", state->port, SVC_PROTO_CASED); } } /* Need to check other domains */ state->dom_idx++; if (!state->domains[state->dom_idx]) { /* No more domains to search. Return ENOENT */ ret = ENOENT; goto done; } ret = lookup_service_step(req); if (ret != EOK) goto done; /* Set EAGAIN so we will re-enter the mainloop */ ret = EAGAIN; } done: if (ret == EOK) { /* Cache contained results. Return them */ tevent_req_done(req); } else if (ret != EAGAIN) { /* An error occurred, fail the request */ tevent_req_error(req, ret); } /* ret == EAGAIN: Reenter mainloop */ return; } static errno_t getserv_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ldb_result **_res) { struct getserv_ctx *state = tevent_req_data(req, struct getserv_ctx); TEVENT_REQ_RETURN_ON_ERROR(req); *_res = talloc_steal(mem_ctx, state->res); return EOK; } static errno_t fill_service(struct sss_packet *packet, struct sss_domain_info *dom, const char *protocol, struct ldb_message **msgs, unsigned int *count) { errno_t ret; unsigned int msg_count = *count; size_t rzero, rsize, aptr; unsigned int num = 0; unsigned int i, j; uint32_t num_aliases, written_aliases; struct ldb_message *msg; struct ldb_message_element *el; TALLOC_CTX *tmp_ctx = NULL; const char *orig_name; const char *orig_proto; struct sized_string cased_name; struct sized_string cased_proto; uint16_t port; char *tmpstr; uint8_t *body; size_t blen; struct sized_string alias; /* FIXME: Should we account for fully-qualified * service names? */ /* first 2 fields (len and reserved), filled up later */ ret = sss_packet_grow(packet, 2 * sizeof(uint32_t)); if (ret != EOK) goto done; rzero = 2 * sizeof(uint32_t); rsize = 0; for (i = 0; i < msg_count; i++) { talloc_zfree(tmp_ctx); tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; msg = msgs[i]; /* new service */ if (!ldb_msg_check_string_attribute(msg, "objectClass", SYSDB_SVC_CLASS)) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrong object (%s) found on stack!\n", ldb_dn_get_linearized(msg->dn)); continue; } /* new result starts at end of previous result */ rzero += rsize; rsize = 0; /* Get the service name */ orig_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); tmpstr = sss_get_cased_name(tmp_ctx, orig_name, dom->case_preserve); if (tmpstr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not identify service name, skipping\n"); continue; } to_sized_string(&cased_name, tmpstr); /* Get the port */ port = (uint16_t) ldb_msg_find_attr_as_uint(msg, SYSDB_SVC_PORT, 0); if (!port) { DEBUG(SSSDBG_CRIT_FAILURE, "No port for service [%s]. Skipping\n", tmpstr); continue; } /* Get the service protocol. * Use the requested protocol if present, * otherwise take the first protocol returned * by the sysdb. * If more than one is available, select the * first in the message. */ if (protocol) { orig_proto = protocol; } else { el = ldb_msg_find_element(msg, SYSDB_SVC_PROTO); if (el->num_values == 0) { ret = EINVAL; num = 0; goto done; } orig_proto = (const char *)el->values[0].data; } tmpstr = sss_get_cased_name(tmp_ctx, orig_proto, dom->case_preserve); if (tmpstr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_get_cased_name failed, skipping\n"); continue; } to_sized_string(&cased_proto, tmpstr); ret = sss_packet_grow(packet, 2 * sizeof(uint16_t) + sizeof(uint32_t) + cased_name.len + cased_proto.len); if (ret != EOK) { num = 0; goto done; } sss_packet_get_body(packet, &body, &blen); /* Store the port number */ SAFEALIGN_SETMEM_UINT32(&body[rzero + rsize], (uint32_t)htons(port), &rsize); /* Get the aliases */ el = ldb_msg_find_element(msg, SYSDB_NAME_ALIAS); if (!el) { /* No aliases for this user */ num_aliases = 0; } else { num_aliases = el->num_values; } /* We'll store the alias count here */ aptr = rzero+rsize; rsize += sizeof(uint32_t); /* Store the primary name */ safealign_memcpy(&body[rzero + rsize], cased_name.str, cased_name.len, &rsize); /* Store the protocol */ safealign_memcpy(&body[rzero + rsize], cased_proto.str, cased_proto.len, &rsize); written_aliases = 0; for (j = 0; j < num_aliases; j++) { if (sss_string_equal(dom->case_sensitive, (const char *)el->values[j].data, cased_name.str)) { continue; } to_sized_string(&alias, (const char *)el->values[j].data); ret = sss_packet_grow(packet, alias.len); if (ret != EOK) { num = 0; goto done; } sss_packet_get_body(packet, &body, &blen); /* Store the alias */ safealign_memcpy(&body[rzero + rsize], alias.str, alias.len, &rsize); written_aliases++; talloc_zfree(tmpstr); } /* We must not advance rsize here, the data has already been * allocated and skipped earlier when aptr was assigned to. */ SAFEALIGN_SETMEM_UINT32(&body[aptr], written_aliases, NULL); num++; } ret = EOK; done: talloc_free(tmp_ctx); if (ret != EOK ||num == 0) { /* if num is 0 most probably something went wrong, * reset packet and return ENOENT */ sss_packet_set_size(packet, 0); return ENOENT; } /* num results */ SAFEALIGN_COPY_UINT32(body, &num, NULL); /* reserved */ SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL); return ret; } /***************** * getservbyname * *****************/ errno_t parse_getservbyname(TALLOC_CTX *mem_ctx, uint8_t *body, size_t blen, struct sss_domain_info *domains, char *default_domain, char **domain_name, char **service_name, char **service_protocol); static void nss_cmd_getserv_done(struct tevent_req *req); int nss_cmd_getservbyname(struct cli_ctx *cctx) { errno_t ret; struct nss_cmd_ctx *cmdctx; struct nss_dom_ctx *dctx; char *domname; char *service_name; char *service_protocol; uint8_t *body; size_t blen; struct tevent_req *req; cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) return ENOMEM; cmdctx->cctx = cctx; dctx = talloc_zero(cmdctx, struct nss_dom_ctx); if (!dctx) { ret = ENOMEM; goto done; } dctx->cmdctx = cmdctx; /* get service name and protocol */ sss_packet_get_body(cctx->creq->in, &body, &blen); /* if not terminated fail */ if (body[blen -1] != '\0') { ret = EINVAL; goto done; } ret = parse_getservbyname(cmdctx, body, blen, cctx->rctx->domains, cctx->rctx->default_domain, &domname, &service_name, &service_protocol); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not parse request\n"); goto done; } dctx->protocol = service_protocol; DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for service [%s:%s] from [%s]\n", service_name, service_protocol ? service_protocol : "", domname ? domname : ""); if (domname) { dctx->domain = responder_get_domain(cctx->rctx, domname); if (!dctx->domain) { ret = ENOENT; goto done; } } else { /* this is a multidomain search */ dctx->domain = cctx->rctx->domains; cmdctx->check_next = true; } /* Identify if this backend requires a provider check */ dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); /* Ok, find it! */ req = getserv_send(cmdctx, cctx->ev, 0, service_name, service_protocol, dctx); if (!req) { ret = ENOMEM; goto done; } tevent_req_set_callback(req, nss_cmd_getserv_done, dctx); done: return nss_cmd_done(cmdctx, ret); } errno_t parse_getservbyname(TALLOC_CTX *mem_ctx, uint8_t *body, size_t blen, struct sss_domain_info *domains, char *default_domain, char **domain_name, char **service_name, char **service_protocol) { errno_t ret; size_t i, j, namelen; char *rawname; char *domname; char *svc_name; char *protocol; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; /* The raw name is at most one character shorter * than the body length (if the protocol wasn't * specified). Since this is a common case, we'll * just assume the maximum memory size for the * rawname. */ rawname = talloc_array(tmp_ctx, char, blen - 1); if (!rawname) { ret = ENOMEM; goto done; } i = j = 0; /* Copy in the service name */ while (i < (blen - 1) && body[i]) { rawname[j] = body[i]; i++; j++; } if (body[i] != '\0') { /* blen - 1 was reached without hitting * a NULL-terminator. No protocol field * is possible. */ ret = EINVAL; goto done; } rawname[j] = '\0'; i++; namelen = i; j = 0; /* Copy in the protocol */ if (body[i] == '\0') { /* Zero-length protocol * Just set the protocol to NULL */ protocol = NULL; } else { /* The protocol must be no longer than the remaining * body space, after the name was copied. */ protocol = talloc_array(tmp_ctx, char, blen - i); if (!protocol) { ret = ENOMEM; goto done; } while (i < blen && body[i]) { protocol[j] = body[i]; i++; j++; } if (body[i] != '\0') { /* blen was reached without hitting * a NULL-terminator. */ ret = EINVAL; goto done; } protocol[j] = '\0'; if (j != blen - namelen - 1) { DEBUG(SSSDBG_MINOR_FAILURE, "Body longer than the name and protocol\n"); ret = EINVAL; goto done; } } ret = sss_parse_name_for_domains(tmp_ctx, domains, default_domain, rawname, &domname, &svc_name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not split name and domain of [%s]\n", rawname); goto done; } *domain_name = talloc_steal(mem_ctx, domname); *service_name = talloc_steal(mem_ctx, svc_name); *service_protocol = talloc_steal(mem_ctx, protocol); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static void nss_cmd_getserv_done(struct tevent_req *req) { errno_t ret, reqret; unsigned int i; struct nss_dom_ctx *dctx = tevent_req_callback_data(req, struct nss_dom_ctx); struct nss_cmd_ctx *cmdctx = dctx->cmdctx; reqret = getserv_recv(dctx, req, &dctx->res); talloc_zfree(req); if (reqret != EOK && reqret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "getservbyname failed\n"); nss_cmd_done(cmdctx, reqret); return; } /* Either we succeeded or no domains were eligible */ ret = sss_packet_new(cmdctx->cctx->creq, 0, sss_packet_get_cmd(cmdctx->cctx->creq->in), &cmdctx->cctx->creq->out); if (ret == EOK) { if (reqret == ENOENT) { /* Notify the caller that this entry wasn't found */ ret = sss_cmd_empty_packet(cmdctx->cctx->creq->out); } else { i = dctx->res->count; ret = fill_service(cmdctx->cctx->creq->out, dctx->domain, dctx->protocol, dctx->res->msgs, &i); } if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not create response packet: [%s]\n", strerror(ret)); } sss_cmd_done(cmdctx->cctx, cmdctx); return; } DEBUG(SSSDBG_OP_FAILURE, "Error creating packet\n"); } errno_t parse_getservbyport(TALLOC_CTX *mem_ctx, uint8_t *body, size_t blen, uint16_t *service_port, char **service_protocol) { errno_t ret; size_t i, j; size_t port_and_padding_len; uint16_t c, port; char *protocol; TALLOC_CTX *tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; /* Copy in the port */ SAFEALIGN_COPY_UINT16(&c, body, NULL); port = ntohs(c); port_and_padding_len = 2 * sizeof(uint16_t) + sizeof(uint32_t); i = port_and_padding_len; j = 0; /* Copy in the protocol */ if (body[i] == '\0') { /* Zero-length protocol * Just set the protocol to NULL */ protocol = NULL; } else { /* The protocol must be no longer than the remaining * body space. */ protocol = talloc_array(tmp_ctx, char, blen - i); if (!protocol) { ret = ENOMEM; goto done; } while (i < blen && body[i]) { protocol[j] = body[i]; i++; j++; } if (body[i] != '\0') { /* blen was reached without hitting * a NULL-terminator. */ ret = EINVAL; goto done; } protocol[j] = '\0'; if (j != blen - port_and_padding_len - 1) { DEBUG(SSSDBG_MINOR_FAILURE, "Body longer than the name and protocol\n"); ret = EINVAL; goto done; } } *service_port = port; *service_protocol = talloc_steal(mem_ctx, protocol); ret = EOK; done: talloc_free(tmp_ctx); return ret; } /***************** * getservbyport * *****************/ int nss_cmd_getservbyport(struct cli_ctx *cctx) { errno_t ret; struct nss_cmd_ctx *cmdctx; struct nss_dom_ctx *dctx; uint16_t port; char *service_protocol; uint8_t *body; size_t blen; struct tevent_req *req; cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) return ENOMEM; cmdctx->cctx = cctx; dctx = talloc_zero(cmdctx, struct nss_dom_ctx); if (!dctx) { ret = ENOMEM; goto done; } dctx->cmdctx = cmdctx; /* get service port and protocol */ sss_packet_get_body(cctx->creq->in, &body, &blen); /* if not terminated fail */ if (body[blen -1] != '\0') { ret = EINVAL; goto done; } ret = parse_getservbyport(cmdctx, body, blen, &port, &service_protocol); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not parse request\n"); goto done; } dctx->protocol = service_protocol; DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for service on port [%"PRIu16"/%s]\n", port, service_protocol ? service_protocol : ""); /* All port lookups are multidomain searches */ dctx->domain = cctx->rctx->domains; cmdctx->check_next = true; /* Identify if this backend requires a provider check */ dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); /* Ok, find it! */ req = getserv_send(cmdctx, cctx->ev, port, NULL, service_protocol, dctx); if (!req) { ret = ENOMEM; goto done; } tevent_req_set_callback(req, nss_cmd_getserv_done, dctx); done: return nss_cmd_done(cmdctx, ret); } struct setservent_ctx { struct cli_ctx *cctx; struct nss_ctx *nctx; struct nss_dom_ctx *dctx; struct getent_ctx *getent_ctx; }; static errno_t setservent_step(struct setent_step_ctx *step_ctx); static void setservent_step_done(struct tevent_req *req); static struct tevent_req * lookup_servent_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom); static struct tevent_req * setservent_send(TALLOC_CTX *mem_ctx, struct cli_ctx *cctx) { errno_t ret; unsigned int num_domains; struct tevent_req *req; struct setservent_ctx *state; struct sss_domain_info *dom; struct setent_step_ctx *step_ctx; struct nss_ctx *nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); DEBUG(SSSDBG_TRACE_FUNC, "Received setservent request\n"); /* Reset the read pointers */ cctx->svc_dom_idx = 0; cctx->svcent_cur = 0; req = tevent_req_create(mem_ctx, &state, struct setservent_ctx); if (!req) return NULL; state->nctx = nctx; state->cctx = cctx; state->dctx = talloc_zero(state, struct nss_dom_ctx); if (!state->dctx) { ret = ENOMEM; goto immediate; } state->dctx->domain = cctx->rctx->domains; /* Is the result context already available */ if (state->nctx->svcctx) { if (state->nctx->svcctx->ready) { /* All of the necessary data is in place * We can return now, getservent requests will work at this point */ ret = EOK; goto immediate; } else { /* Object is still being constructed * Register for notification when it's * ready. */ ret = nss_setent_add_ref(state, state->nctx->svcctx, req); if (ret != EOK) goto immediate; } return req; } /* Create a new result context * We are creating it on the nss_ctx so that it doesn't * go away if the original request does. We will delete * it when the refcount goes to zero; */ state->nctx->svcctx = talloc_zero(nctx, struct getent_ctx); if (!state->nctx->svcctx) { ret = ENOMEM; goto immediate; } state->getent_ctx = nctx->svcctx; /* Assume that all domains will have results (to avoid having * to reallocate later */ num_domains = 0; for (dom = state->cctx->rctx->domains; dom; dom = get_next_domain(dom, 0)) { num_domains++; } state->nctx->svcctx->doms = talloc_zero_array(state->nctx->svcctx, struct dom_ctx, num_domains); if (!state->nctx->svcctx->doms) { ret = ENOMEM; goto immediate; } /* Add a callback reference for ourselves */ ret = nss_setent_add_ref(state, state->nctx->svcctx, req); if (ret != EOK) { goto immediate; } /* ok, start the searches */ step_ctx = talloc_zero(state->getent_ctx, struct setent_step_ctx); if (!step_ctx) { ret = ENOMEM; goto immediate; } /* Steal the dom_ctx onto the step_ctx so it doesn't go out of scope if * this request is canceled while other requests are in-progress. */ step_ctx->dctx = talloc_steal(step_ctx, state->dctx); step_ctx->nctx = state->nctx; step_ctx->getent_ctx = state->getent_ctx; step_ctx->rctx = cctx->rctx; step_ctx->cctx = cctx; step_ctx->returned_to_mainloop = false; while (step_ctx->dctx->domain) { /* There are more domains to check */ ret = setservent_step(step_ctx); if (ret == EOK) { /* Re-enter the mainloop */ return req; } DEBUG(SSSDBG_CRIT_FAILURE, "Error [%s] requesting info from domain [%s]. Skipping.\n", strerror(ret), step_ctx->dctx->domain->name); step_ctx->dctx->domain = get_next_domain(step_ctx->dctx->domain, 0); } /* All domains failed */ ret = EIO; immediate: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, cctx->rctx->ev); return req; } static errno_t setservent_step(struct setent_step_ctx *step_ctx) { struct tevent_req *req; req = lookup_servent_send(step_ctx, step_ctx->rctx, step_ctx->dctx->domain); if (!req) { return ENOMEM; } tevent_req_set_callback(req, setservent_step_done, step_ctx); return EOK; } struct lookup_servent_ctx { struct resp_ctx *rctx; struct sss_domain_info *dom; struct ldb_result *res; }; static void lookup_servent_done(struct tevent_req *subreq); static void setservent_finalize(struct setent_step_ctx *step_ctx); static struct tevent_req * lookup_servent_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct lookup_servent_ctx *state; struct sysdb_ctx *sysdb; req = tevent_req_create(mem_ctx, &state, struct lookup_servent_ctx); if (!req) return NULL; state->rctx = rctx; state->dom = dom; if (!dom->enumerate) { ret = ENOENT; goto immediate; } if (!(NEED_CHECK_PROVIDER(dom->name))) { /* No provider check required. Just ask the * sysdb. */ sysdb = dom->sysdb; if (sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Sysdb CTX not found for [%s]!\n", dom->name); ret = EINVAL; goto immediate; } ret = sysdb_enumservent(state, dom, &state->res); /* Whatever the result, we're done, so report it */ goto immediate; } /* We need to ask the provider for an enumeration */ /* Update the cache */ subreq = sss_dp_get_account_send(req, rctx, state->dom, true, SSS_DP_SERVICES, NULL, 0, NULL); if (!subreq) { ret = ENOMEM; goto immediate; } tevent_req_set_callback(subreq, lookup_servent_done, req); return req; immediate: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ENOENT); } tevent_req_post(req, rctx->ev); return req; } static void lookup_servent_done(struct tevent_req *subreq) { errno_t ret; dbus_uint16_t dp_err; dbus_uint32_t dp_ret; char *err_msg; struct sysdb_ctx *sysdb; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct lookup_servent_ctx *state = tevent_req_data(req, struct lookup_servent_ctx); ret = sss_dp_get_account_recv(state, subreq, &dp_err, &dp_ret, &err_msg); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get information from Data Provider\n" "dp_error: [%u], errno: [%u], error_msg: [%s]\n" "Will try to return what we have in cache\n", (unsigned int)dp_err, (unsigned int)dp_ret, err_msg ? err_msg : "none"); } /* Check the cache now */ sysdb = state->dom->sysdb; if (sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Sysdb CTX not found for [%s]!\n", state->dom->name); ret = EINVAL; goto done; } ret = sysdb_enumservent(state, state->dom, &state->res); /* Whatever the result, we're done, so report it */ done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } static errno_t lookup_servent_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ldb_result **res) { struct lookup_servent_ctx *state = tevent_req_data(req, struct lookup_servent_ctx); TEVENT_REQ_RETURN_ON_ERROR(req); *res = talloc_steal(mem_ctx, state->res); return EOK; } static void setservent_step_done(struct tevent_req *req) { errno_t ret; struct ldb_result *res = NULL; struct setent_step_ctx *step_ctx = tevent_req_callback_data(req, struct setent_step_ctx); struct nss_dom_ctx *dctx = step_ctx->dctx; struct getent_ctx *svcctx = step_ctx->getent_ctx; ret = lookup_servent_recv(step_ctx, req, &res); talloc_zfree(req); if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "Domain [%s] returned no results\n", dctx->domain->name); } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Error [%s] while retrieving info from domain [%s]. " "Skipping.\n", strerror(ret), dctx->domain->name); /* Continue on */ } else { /* Got some results * Add the retrieved results to the list */ svcctx->doms[svcctx->num].domain = dctx->domain; svcctx->doms[svcctx->num].res = talloc_steal(svcctx->doms, res); svcctx->num++; } step_ctx->dctx->domain = get_next_domain(step_ctx->dctx->domain, 0); while (step_ctx->dctx->domain) { /* There are more domains to check */ ret = setservent_step(step_ctx); if (ret == EOK) { /* Re-enter the mainloop */ return; } DEBUG(SSSDBG_CRIT_FAILURE, "Error [%s] requesting info from domain [%s]. Skipping.\n", strerror(ret), step_ctx->dctx->domain->name); step_ctx->dctx->domain = get_next_domain(step_ctx->dctx->domain, 0); } /* All domains have been checked */ setservent_finalize(step_ctx); } static void setservent_result_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt); static void setservent_finalize(struct setent_step_ctx *step_ctx) { struct nss_ctx *nctx = step_ctx->nctx; struct resp_ctx *rctx = step_ctx->rctx; struct timeval tv; struct tevent_timer *te; /* We've finished all our lookups * The result object is now safe to read. */ nctx->svcctx->ready = true; /* Set up a lifetime timer for this result object * We don't want this result object to outlive the * enum cache refresh timeout */ tv = tevent_timeval_current_ofs(nctx->enum_cache_timeout, 0); te = tevent_add_timer(rctx->ev, nctx->svcctx, tv, setservent_result_timeout, nctx); if (!te) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up life timer for setservent result object. " "Entries may become stale.\n"); } nss_setent_notify_done(nctx->svcctx); } static void setservent_result_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { struct nss_ctx *nctx = talloc_get_type(pvt, struct nss_ctx); DEBUG(SSSDBG_TRACE_FUNC, "setservent result object has expired. Cleaning up.\n"); /* Free the service enumeration context. * If additional getservent requests come in, they will invoke * an implicit setservent and refresh the result object. */ talloc_zfree(nctx->svcctx); } static errno_t setservent_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void nss_cmd_setservent_done(struct tevent_req *req); int nss_cmd_setservent(struct cli_ctx *cctx) { struct nss_cmd_ctx *cmdctx; struct tevent_req *req; errno_t ret = EOK; cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = cctx; req = setservent_send(cmdctx, cctx); if (!req) { DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error calling nss_cmd_setservent_send\n"); ret = EIO; goto done; } tevent_req_set_callback(req, nss_cmd_setservent_done, cmdctx); done: return nss_cmd_done(cmdctx, ret); } static void nss_cmd_setservent_done(struct tevent_req *req) { errno_t ret; struct nss_cmd_ctx *cmdctx = tevent_req_callback_data(req, struct nss_cmd_ctx); ret = setservent_recv(req); talloc_zfree(req); if (ret == EOK || ret == ENOENT) { /* Either we succeeded or no domains * were eligible. * Return an acknowledgment */ ret = sss_packet_new(cmdctx->cctx->creq, 0, sss_packet_get_cmd(cmdctx->cctx->creq->in), &cmdctx->cctx->creq->out); if (ret == EOK) { sss_cmd_done(cmdctx->cctx, cmdctx); return; } } /* Something bad happened. * Return an error */ nss_cmd_done(cmdctx, ret); } static void nss_cmd_implicit_setservent_done(struct tevent_req *req); static errno_t nss_cmd_getservent_immediate(struct nss_cmd_ctx *cmdctx); static errno_t retservent(struct cli_ctx *cctx, int num); int nss_cmd_getservent(struct cli_ctx *cctx) { struct nss_ctx *nctx; struct nss_cmd_ctx *cmdctx; struct tevent_req *req; DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for all services\n"); cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = cctx; /* Save the current index and cursor locations * If we end up calling setservent implicitly, because the response object * expired and has to be recreated, we want to resume from the same * location. */ cmdctx->saved_dom_idx = cctx->svc_dom_idx; cmdctx->saved_cur = cctx->svcent_cur; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); if(!nctx->svcctx || !nctx->svcctx->ready) { /* Make sure we invoke setservent if it hasn't been run or is still * processing from another client */ req = setservent_send(cmdctx, cctx); if (!req) { return EIO; } tevent_req_set_callback(req, nss_cmd_implicit_setservent_done, cmdctx); return EOK; } return nss_cmd_getservent_immediate(cmdctx); } static void nss_cmd_implicit_setservent_done(struct tevent_req *req) { errno_t ret; struct nss_cmd_ctx *cmdctx = tevent_req_callback_data(req, struct nss_cmd_ctx); ret = setservent_recv(req); talloc_zfree(req); /* ENOENT is acceptable, as it just means that there were no entries * to be returned. This will be handled gracefully in retservent * later. */ if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Implicit setservent failed with unexpected error [%d][%s]\n", ret, strerror(ret)); NSS_CMD_FATAL_ERROR(cmdctx); } /* Restore the saved index and cursor locations */ cmdctx->cctx->svc_dom_idx = cmdctx->saved_dom_idx; cmdctx->cctx->svcent_cur = cmdctx->saved_cur; ret = nss_cmd_getservent_immediate(cmdctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Immediate retrieval failed with unexpected error " "[%d][%s]\n", ret, strerror(ret)); NSS_CMD_FATAL_ERROR(cmdctx); } } static errno_t nss_cmd_getservent_immediate(struct nss_cmd_ctx *cmdctx) { struct cli_ctx *cctx = cmdctx->cctx; uint8_t *body; size_t blen; uint32_t num; int ret; /* get max num of entries to return in one call */ sss_packet_get_body(cctx->creq->in, &body, &blen); if (blen != sizeof(uint32_t)) { return EINVAL; } SAFEALIGN_COPY_UINT32(&num, body, NULL); /* create response packet */ ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return ret; } ret = retservent(cctx, num); sss_packet_set_error(cctx->creq->out, ret); sss_cmd_done(cctx, cmdctx); return EOK; } static errno_t retservent(struct cli_ctx *cctx, int num) { struct nss_ctx *nctx; struct getent_ctx *svcctx; struct ldb_message **msgs = NULL; struct dom_ctx *pdom = NULL; unsigned int n = 0; int ret = ENOENT; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); if (!nctx->svcctx) goto none; svcctx = nctx->svcctx; while (ret == ENOENT) { if (cctx->svc_dom_idx >= svcctx->num) break; pdom = &svcctx->doms[cctx->svc_dom_idx]; n = pdom->res->count - cctx->svcent_cur; if (n <= 0 && (cctx->svc_dom_idx+1 < svcctx->num)) { cctx->svc_dom_idx++; pdom = &svcctx->doms[cctx->svc_dom_idx]; n = pdom->res->count; cctx->svcent_cur = 0; } if (!n) break; if (n > num) n = num; msgs = &(pdom->res->msgs[cctx->svcent_cur]); ret = fill_service(cctx->creq->out, pdom->domain, NULL, msgs, &n); cctx->svcent_cur += n; } none: if (ret == ENOENT) { ret = sss_cmd_empty_packet(cctx->creq->out); } return ret; } int nss_cmd_endservent(struct cli_ctx *cctx) { struct nss_ctx *nctx; int ret; DEBUG(SSSDBG_TRACE_FUNC, "Terminating request info for all accounts\n"); nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); /* create response packet */ ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return ret; } if (nctx->svcctx == NULL) goto done; /* Reset the indices so that subsequent requests start at zero */ cctx->svc_dom_idx = 0; cctx->svcent_cur = 0; done: sss_cmd_done(cctx, NULL); return EOK; } sssd-1.13.4/src/responder/nss/PaxHeaders.16287/nsssrv_mmap_cache.c0000644000000000000000000000007412703456111021557 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.947794622 sssd-1.13.4/src/responder/nss/nsssrv_mmap_cache.c0000644002412700241270000012034712703456111023235 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Responder - Mmap Cache Copyright (C) Simo Sorce 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "confdb/confdb.h" #include #include #include "util/mmap_cache.h" #include "responder/nss/nsssrv.h" #include "responder/nss/nsssrv_mmap_cache.h" /* arbitrary (avg of my /etc/passwd) */ #define SSS_AVG_PASSWD_PAYLOAD (MC_SLOT_SIZE * 4) /* short group name and no gids (private user group */ #define SSS_AVG_GROUP_PAYLOAD (MC_SLOT_SIZE * 3) /* average place for 40 supplementary groups + 2 names */ #define SSS_AVG_INITGROUP_PAYLOAD (MC_SLOT_SIZE * 5) #define MC_NEXT_BARRIER(val) ((((val) + 1) & 0x00ffffff) | 0xf0000000) #define MC_RAISE_BARRIER(m) do { \ m->b2 = MC_NEXT_BARRIER(m->b1); \ __sync_synchronize(); \ } while (0) #define MC_LOWER_BARRIER(m) do { \ __sync_synchronize(); \ m->b1 = m->b2; \ } while (0) #define MC_RAISE_INVALID_BARRIER(m) do { \ m->b2 = MC_INVALID_VAL; \ __sync_synchronize(); \ } while (0) struct sss_mc_ctx { char *name; /* mmap cache name */ enum sss_mc_type type; /* mmap cache type */ char *file; /* mmap cache file name */ int fd; /* file descriptor */ uint32_t seed; /* pseudo-random seed to avoid collision attacks */ time_t valid_time_slot; /* maximum time the entry is valid in seconds */ void *mmap_base; /* base address of mmap */ size_t mmap_size; /* total size of mmap */ uint32_t *hash_table; /* hash table address (in mmap) */ uint32_t ht_size; /* size of hash table */ uint8_t *free_table; /* free list bitmaps */ uint32_t ft_size; /* size of free table */ uint32_t next_slot; /* the next slot after last allocation */ uint8_t *data_table; /* data table address (in mmap) */ uint32_t dt_size; /* size of data table */ }; #define MC_FIND_BIT(base, num) \ uint32_t n = (num); \ uint8_t *b = (base) + n / 8; \ uint8_t c = 0x80 >> (n % 8); #define MC_SET_BIT(base, num) do { \ MC_FIND_BIT(base, num) \ *b |= c; \ } while (0) #define MC_CLEAR_BIT(base, num) do { \ MC_FIND_BIT(base, num) \ *b &= ~c; \ } while (0) #define MC_PROBE_BIT(base, num, used) do { \ MC_FIND_BIT(base, num) \ if (*b & c) used = true; \ else used = false; \ } while (0) static inline uint32_t sss_mc_next_slot_with_hash(struct sss_mc_rec *rec, uint32_t hash) { if (rec->hash1 == hash) { return rec->next1; } else if (rec->hash2 == hash) { return rec->next2; } else { /* it should never happen. */ return MC_INVALID_VAL; } } static inline void sss_mc_chain_slot_to_record_with_hash(struct sss_mc_rec *rec, uint32_t hash, uint32_t slot) { /* changing a single uint32_t is atomic, so there is no * need to use barriers in this case */ if (rec->hash1 == hash) { rec->next1 = slot; } else if (rec->hash2 == hash) { rec->next2 = slot; } } /* This function will store corrupted memcache to disk for later * analysis. */ static void sss_mc_save_corrupted(struct sss_mc_ctx *mc_ctx) { int err; int fd = -1; ssize_t written = -1; char *file = NULL; TALLOC_CTX *tmp_ctx; if (mc_ctx == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "Cannot store uninitialized cache. Nothing to do.\n"); return; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n"); return; } file = talloc_asprintf(tmp_ctx, "%s_%s", mc_ctx->file, "corrupted"); if (file == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n"); goto done; } /* We will always store only the last problematic cache state */ fd = creat(file, 0600); if (fd == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to open file '%s' [%d]: %s\n", file, err, strerror(err)); goto done; } written = sss_atomic_write_s(fd, mc_ctx->mmap_base, mc_ctx->mmap_size); if (written != mc_ctx->mmap_size) { if (written == -1) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "write() failed [%d]: %s\n", err, strerror(err)); } else { DEBUG(SSSDBG_CRIT_FAILURE, "write() returned %zd (expected (%zd))\n", written, mc_ctx->mmap_size); } goto done; } sss_log(SSS_LOG_NOTICE, "Stored copy of corrupted mmap cache in file '%s\n'", file); done: if (fd != -1) { close(fd); if (written == -1) { err = unlink(file); if (err != 0) { err = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to remove file '%s': %s.\n", file, strerror(err)); } } } talloc_free(tmp_ctx); } static uint32_t sss_mc_hash(struct sss_mc_ctx *mcc, const char *key, size_t len) { return murmurhash3(key, len, mcc->seed) % MC_HT_ELEMS(mcc->ht_size); } static void sss_mc_add_rec_to_chain(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec, uint32_t hash) { struct sss_mc_rec *cur; uint32_t slot; if (hash > MC_HT_ELEMS(mcc->ht_size)) { /* Invalid hash. This should never happen, but better * return than trying to access out of bounds memory */ return; } slot = mcc->hash_table[hash]; if (slot == MC_INVALID_VAL) { /* no previous record/collision, just add to hash table */ mcc->hash_table[hash] = MC_PTR_TO_SLOT(mcc->data_table, rec); return; } do { cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); if (cur == rec) { /* rec already stored in hash chain */ return; } slot = sss_mc_next_slot_with_hash(cur, hash); } while (slot != MC_INVALID_VAL); /* end of chain, append our record here */ slot = MC_PTR_TO_SLOT(mcc->data_table, rec); sss_mc_chain_slot_to_record_with_hash(cur, hash, slot); } static void sss_mc_rm_rec_from_chain(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec, uint32_t hash) { struct sss_mc_rec *prev = NULL; struct sss_mc_rec *cur = NULL; uint32_t slot; if (hash > MC_HT_ELEMS(mcc->ht_size)) { /* It can happen if rec->hash1 and rec->hash2 was the same. * or it is invalid hash. It is better to return * than trying to access out of bounds memory */ return; } slot = mcc->hash_table[hash]; if (slot == MC_INVALID_VAL) { /* record has already been removed. It may happen if rec->hash1 and * rec->has2 are the same. (It is not very likely). */ return; } cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); if (cur == rec) { mcc->hash_table[hash] = sss_mc_next_slot_with_hash(rec, hash); } else { slot = sss_mc_next_slot_with_hash(cur, hash); while (slot != MC_INVALID_VAL) { prev = cur; cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); if (cur == rec) { slot = sss_mc_next_slot_with_hash(cur, hash); sss_mc_chain_slot_to_record_with_hash(prev, hash, slot); slot = MC_INVALID_VAL; } else { slot = sss_mc_next_slot_with_hash(cur, hash); } } } } static void sss_mc_free_slots(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec) { uint32_t slot; uint32_t num; uint32_t i; slot = MC_PTR_TO_SLOT(mcc->data_table, rec); num = MC_SIZE_TO_SLOTS(rec->len); for (i = 0; i < num; i++) { MC_CLEAR_BIT(mcc->free_table, slot + i); } } static void sss_mc_invalidate_rec(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec) { if (rec->b1 == MC_INVALID_VAL) { /* record already invalid */ return; } /* Remove from hash chains */ /* hash chain 1 */ sss_mc_rm_rec_from_chain(mcc, rec, rec->hash1); /* hash chain 2 */ sss_mc_rm_rec_from_chain(mcc, rec, rec->hash2); /* Clear from free_table */ sss_mc_free_slots(mcc, rec); /* Invalidate record fields */ MC_RAISE_INVALID_BARRIER(rec); memset(rec->data, MC_INVALID_VAL8, ((MC_SLOT_SIZE * MC_SIZE_TO_SLOTS(rec->len)) - sizeof(struct sss_mc_rec))); rec->len = MC_INVALID_VAL32; rec->expire = MC_INVALID_VAL64; rec->next1 = MC_INVALID_VAL32; rec->next2 = MC_INVALID_VAL32; rec->hash1 = MC_INVALID_VAL32; rec->hash2 = MC_INVALID_VAL32; MC_LOWER_BARRIER(rec); } static bool sss_mc_is_valid_rec(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec) { struct sss_mc_rec *self; uint32_t slot; if (((uint8_t *)rec < mcc->data_table) || ((uint8_t *)rec > (mcc->data_table + mcc->dt_size - MC_SLOT_SIZE))) { return false; } if ((rec->b1 == MC_INVALID_VAL) || (rec->b1 != rec->b2)) { return false; } if (!MC_CHECK_RECORD_LENGTH(mcc, rec)) { return false; } if (rec->expire == MC_INVALID_VAL64) { return false; } /* next record can be invalid if there are no next records */ if (rec->hash1 == MC_INVALID_VAL32) { return false; } else { self = NULL; slot = mcc->hash_table[rec->hash1]; while (slot != MC_INVALID_VAL32 && self != rec) { self = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); slot = sss_mc_next_slot_with_hash(self, rec->hash1); } if (self != rec) { return false; } } if (rec->hash2 != MC_INVALID_VAL32) { self = NULL; slot = mcc->hash_table[rec->hash2]; while (slot != MC_INVALID_VAL32 && self != rec) { self = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); slot = sss_mc_next_slot_with_hash(self, rec->hash2); } if (self != rec) { return false; } } /* all tests passed */ return true; } /* FIXME: This is a very simplistic, inefficient, memory allocator, * it will just free the oldest entries regardless of expiration if it * cycled the whole freebits map and found no empty slot */ static errno_t sss_mc_find_free_slots(struct sss_mc_ctx *mcc, int num_slots, uint32_t *free_slot) { struct sss_mc_rec *rec; uint32_t tot_slots; uint32_t cur; uint32_t i; uint32_t t; bool used; tot_slots = mcc->ft_size * 8; /* Try to find a free slot w/o removing anything first */ /* FIXME: is it really worth it ? May be it is easier to * just recycle the next set of slots ? */ if ((mcc->next_slot + num_slots) > tot_slots) { cur = 0; } else { cur = mcc->next_slot; } /* search for enough (num_slots) consecutive zero bits, indicating * consecutive empty slots */ for (i = 0; i < mcc->ft_size; i++) { t = cur / 8; /* if all full in this byte skip directly to the next */ if (mcc->free_table[t] == 0xff) { cur = ((cur + 8) & ~7); if (cur >= tot_slots) { cur = 0; } continue; } /* at least one bit in this byte is marked as empty */ for (t = ((cur + 8) & ~7) ; cur < t; cur++) { MC_PROBE_BIT(mcc->free_table, cur, used); if (!used) break; } /* check if we have enough slots before hitting the table end */ if ((cur + num_slots) > tot_slots) { cur = 0; continue; } /* check if we have at least num_slots empty starting from the first * we found in the previous steps */ for (t = cur + num_slots; cur < t; cur++) { MC_PROBE_BIT(mcc->free_table, cur, used); if (used) break; } if (cur == t) { /* ok found num_slots consecutive free bits */ *free_slot = cur - num_slots; return EOK; } } /* no free slots found, free occupied slots after next_slot */ if ((mcc->next_slot + num_slots) > tot_slots) { cur = 0; } else { cur = mcc->next_slot; } for (i = 0; i < num_slots; i++) { MC_PROBE_BIT(mcc->free_table, cur + i, used); if (used) { /* the first used slot should be a record header, however we * carefully check it is a valid header and hardfail if not */ rec = MC_SLOT_TO_PTR(mcc->data_table, cur + i, struct sss_mc_rec); if (!sss_mc_is_valid_rec(mcc, rec)) { /* this is a fatal error, the caller should probaly just * invalidate the whole cache */ return EFAULT; } /* next loop skip the whole record */ i += MC_SIZE_TO_SLOTS(rec->len) - 1; /* finally invalidate record completely */ sss_mc_invalidate_rec(mcc, rec); } } mcc->next_slot = cur + num_slots; *free_slot = cur; return EOK; } static errno_t sss_mc_get_strs_offset(struct sss_mc_ctx *mcc, size_t *_offset) { switch (mcc->type) { case SSS_MC_PASSWD: *_offset = offsetof(struct sss_mc_pwd_data, strs); return EOK; case SSS_MC_GROUP: *_offset = offsetof(struct sss_mc_grp_data, strs); return EOK; case SSS_MC_INITGROUPS: *_offset = offsetof(struct sss_mc_initgr_data, gids); return EOK; default: DEBUG(SSSDBG_FATAL_FAILURE, "Unknown memory cache type.\n"); return EINVAL; } } static errno_t sss_mc_get_strs_len(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec, size_t *_len) { switch (mcc->type) { case SSS_MC_PASSWD: *_len = ((struct sss_mc_pwd_data *)&rec->data)->strs_len; return EOK; case SSS_MC_GROUP: *_len = ((struct sss_mc_grp_data *)&rec->data)->strs_len; return EOK; case SSS_MC_INITGROUPS: *_len = ((struct sss_mc_initgr_data *)&rec->data)->data_len; return EOK; default: DEBUG(SSSDBG_FATAL_FAILURE, "Unknown memory cache type.\n"); return EINVAL; } } static struct sss_mc_rec *sss_mc_find_record(struct sss_mc_ctx *mcc, struct sized_string *key) { struct sss_mc_rec *rec; uint32_t hash; uint32_t slot; rel_ptr_t name_ptr; char *t_key; size_t strs_offset; size_t strs_len; uint8_t *max_addr; errno_t ret; hash = sss_mc_hash(mcc, key->str, key->len); slot = mcc->hash_table[hash]; if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) { return NULL; } /* Get max address of data table. */ max_addr = mcc->data_table + mcc->dt_size; ret = sss_mc_get_strs_offset(mcc, &strs_offset); if (ret != EOK) { return NULL; } while (slot != MC_INVALID_VAL) { if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) { DEBUG(SSSDBG_FATAL_FAILURE, "Corrupted fastcache. Slot number too big.\n"); sss_mc_save_corrupted(mcc); sss_mmap_cache_reset(mcc); return NULL; } rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); ret = sss_mc_get_strs_len(mcc, rec, &strs_len); if (ret != EOK) { return NULL; } safealign_memcpy(&name_ptr, rec->data, sizeof(rel_ptr_t), NULL); if (key->len > strs_len || (name_ptr + key->len) > (strs_offset + strs_len) || (uint8_t *)rec->data + strs_offset + strs_len > max_addr) { DEBUG(SSSDBG_FATAL_FAILURE, "Corrupted fastcache. name_ptr value is %u.\n", name_ptr); sss_mc_save_corrupted(mcc); sss_mmap_cache_reset(mcc); return NULL; } t_key = (char *)rec->data + name_ptr; if (strcmp(key->str, t_key) == 0) { break; } slot = sss_mc_next_slot_with_hash(rec, hash); } if (slot == MC_INVALID_VAL) { return NULL; } return rec; } static errno_t sss_mc_get_record(struct sss_mc_ctx **_mcc, size_t rec_len, struct sized_string *key, struct sss_mc_rec **_rec) { struct sss_mc_ctx *mcc = *_mcc; struct sss_mc_rec *old_rec = NULL; struct sss_mc_rec *rec; int old_slots; int num_slots; uint32_t base_slot; errno_t ret; int i; num_slots = MC_SIZE_TO_SLOTS(rec_len); old_rec = sss_mc_find_record(mcc, key); if (old_rec) { old_slots = MC_SIZE_TO_SLOTS(old_rec->len); if (old_slots == num_slots) { *_rec = old_rec; return EOK; } /* slot size changed, invalidate record and fall through to get a * fully new record */ sss_mc_invalidate_rec(mcc, old_rec); } /* we are going to use more space, find enough free slots */ ret = sss_mc_find_free_slots(mcc, num_slots, &base_slot); if (ret != EOK) { if (ret == EFAULT) { DEBUG(SSSDBG_CRIT_FAILURE, "Fatal internal mmap cache error, invalidating cache!\n"); (void)sss_mmap_cache_reinit(talloc_parent(mcc), -1, -1, _mcc); } return ret; } rec = MC_SLOT_TO_PTR(mcc->data_table, base_slot, struct sss_mc_rec); /* mark as not valid yet */ MC_RAISE_INVALID_BARRIER(rec); rec->len = rec_len; rec->next1 = MC_INVALID_VAL; rec->next2 = MC_INVALID_VAL; rec->padding = MC_INVALID_VAL; MC_LOWER_BARRIER(rec); /* and now mark slots as used */ for (i = 0; i < num_slots; i++) { MC_SET_BIT(mcc->free_table, base_slot + i); } *_rec = rec; return EOK; } static inline void sss_mmap_set_rec_header(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec, size_t len, int ttl, const char *key1, size_t key1_len, const char *key2, size_t key2_len) { rec->len = len; rec->expire = time(NULL) + ttl; rec->hash1 = sss_mc_hash(mcc, key1, key1_len); rec->hash2 = sss_mc_hash(mcc, key2, key2_len); } static inline void sss_mmap_chain_in_rec(struct sss_mc_ctx *mcc, struct sss_mc_rec *rec) { /* name first */ sss_mc_add_rec_to_chain(mcc, rec, rec->hash1); /* then uid/gid */ sss_mc_add_rec_to_chain(mcc, rec, rec->hash2); } /*************************************************************************** * generic invalidation ***************************************************************************/ static errno_t sss_mmap_cache_invalidate(struct sss_mc_ctx *mcc, struct sized_string *key) { struct sss_mc_rec *rec; if (mcc == NULL) { /* cache not initialized ? */ return EINVAL; } rec = sss_mc_find_record(mcc, key); if (rec == NULL) { /* nothing to invalidate */ return ENOENT; } sss_mc_invalidate_rec(mcc, rec); return EOK; } /*************************************************************************** * passwd map ***************************************************************************/ errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc, struct sized_string *name, struct sized_string *pw, uid_t uid, gid_t gid, struct sized_string *gecos, struct sized_string *homedir, struct sized_string *shell) { struct sss_mc_ctx *mcc = *_mcc; struct sss_mc_rec *rec; struct sss_mc_pwd_data *data; struct sized_string uidkey; char uidstr[11]; size_t data_len; size_t rec_len; size_t pos; int ret; if (mcc == NULL) { /* cache not initialized ? */ return EINVAL; } ret = snprintf(uidstr, 11, "%ld", (long)uid); if (ret > 10) { return EINVAL; } to_sized_string(&uidkey, uidstr); data_len = name->len + pw->len + gecos->len + homedir->len + shell->len; rec_len = sizeof(struct sss_mc_rec) + sizeof(struct sss_mc_pwd_data) + data_len; if (rec_len > mcc->dt_size) { return ENOMEM; } ret = sss_mc_get_record(_mcc, rec_len, name, &rec); if (ret != EOK) { return ret; } data = (struct sss_mc_pwd_data *)rec->data; pos = 0; MC_RAISE_BARRIER(rec); /* header */ sss_mmap_set_rec_header(mcc, rec, rec_len, mcc->valid_time_slot, name->str, name->len, uidkey.str, uidkey.len); /* passwd struct */ data->name = MC_PTR_DIFF(data->strs, data); data->uid = uid; data->gid = gid; data->strs_len = data_len; memcpy(&data->strs[pos], name->str, name->len); pos += name->len; memcpy(&data->strs[pos], pw->str, pw->len); pos += pw->len; memcpy(&data->strs[pos], gecos->str, gecos->len); pos += gecos->len; memcpy(&data->strs[pos], homedir->str, homedir->len); pos += homedir->len; memcpy(&data->strs[pos], shell->str, shell->len); pos += shell->len; MC_LOWER_BARRIER(rec); /* finally chain the rec in the hash table */ sss_mmap_chain_in_rec(mcc, rec); return EOK; } errno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx *mcc, struct sized_string *name) { return sss_mmap_cache_invalidate(mcc, name); } errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid) { struct sss_mc_rec *rec; struct sss_mc_pwd_data *data; uint32_t hash; uint32_t slot; char *uidstr; errno_t ret; if (mcc == NULL) { /* cache not initialized ? */ return EINVAL; } uidstr = talloc_asprintf(NULL, "%ld", (long)uid); if (!uidstr) { return ENOMEM; } hash = sss_mc_hash(mcc, uidstr, strlen(uidstr) + 1); slot = mcc->hash_table[hash]; if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) { ret = ENOENT; goto done; } while (slot != MC_INVALID_VAL) { if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) { DEBUG(SSSDBG_FATAL_FAILURE, "Corrupted fastcache.\n"); sss_mc_save_corrupted(mcc); sss_mmap_cache_reset(mcc); ret = ENOENT; goto done; } rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); data = (struct sss_mc_pwd_data *)(&rec->data); if (uid == data->uid) { break; } slot = sss_mc_next_slot_with_hash(rec, hash); } if (slot == MC_INVALID_VAL) { ret = ENOENT; goto done; } sss_mc_invalidate_rec(mcc, rec); ret = EOK; done: talloc_zfree(uidstr); return ret; } /*************************************************************************** * group map ***************************************************************************/ int sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc, struct sized_string *name, struct sized_string *pw, gid_t gid, size_t memnum, char *membuf, size_t memsize) { struct sss_mc_ctx *mcc = *_mcc; struct sss_mc_rec *rec; struct sss_mc_grp_data *data; struct sized_string gidkey; char gidstr[11]; size_t data_len; size_t rec_len; size_t pos; int ret; if (mcc == NULL) { /* cache not initialized ? */ return EINVAL; } ret = snprintf(gidstr, 11, "%ld", (long)gid); if (ret > 10) { return EINVAL; } to_sized_string(&gidkey, gidstr); data_len = name->len + pw->len + memsize; rec_len = sizeof(struct sss_mc_rec) + sizeof(struct sss_mc_grp_data) + data_len; if (rec_len > mcc->dt_size) { return ENOMEM; } ret = sss_mc_get_record(_mcc, rec_len, name, &rec); if (ret != EOK) { return ret; } data = (struct sss_mc_grp_data *)rec->data; pos = 0; MC_RAISE_BARRIER(rec); /* header */ sss_mmap_set_rec_header(mcc, rec, rec_len, mcc->valid_time_slot, name->str, name->len, gidkey.str, gidkey.len); /* group struct */ data->name = MC_PTR_DIFF(data->strs, data); data->gid = gid; data->members = memnum; data->strs_len = data_len; memcpy(&data->strs[pos], name->str, name->len); pos += name->len; memcpy(&data->strs[pos], pw->str, pw->len); pos += pw->len; memcpy(&data->strs[pos], membuf, memsize); pos += memsize; MC_LOWER_BARRIER(rec); /* finally chain the rec in the hash table */ sss_mmap_chain_in_rec(mcc, rec); return EOK; } errno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx *mcc, struct sized_string *name) { return sss_mmap_cache_invalidate(mcc, name); } errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid) { struct sss_mc_rec *rec; struct sss_mc_grp_data *data; uint32_t hash; uint32_t slot; char *gidstr; errno_t ret; if (mcc == NULL) { /* cache not initialized ? */ return EINVAL; } gidstr = talloc_asprintf(NULL, "%ld", (long)gid); if (!gidstr) { return ENOMEM; } hash = sss_mc_hash(mcc, gidstr, strlen(gidstr) + 1); slot = mcc->hash_table[hash]; if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) { ret = ENOENT; goto done; } while (slot != MC_INVALID_VAL) { if (!MC_SLOT_WITHIN_BOUNDS(slot, mcc->dt_size)) { DEBUG(SSSDBG_FATAL_FAILURE, "Corrupted fastcache.\n"); sss_mc_save_corrupted(mcc); sss_mmap_cache_reset(mcc); ret = ENOENT; goto done; } rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec); data = (struct sss_mc_grp_data *)(&rec->data); if (gid == data->gid) { break; } slot = sss_mc_next_slot_with_hash(rec, hash); } if (slot == MC_INVALID_VAL) { ret = ENOENT; goto done; } sss_mc_invalidate_rec(mcc, rec); ret = EOK; done: talloc_zfree(gidstr); return ret; } errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc, struct sized_string *name, struct sized_string *unique_name, uint32_t num_groups, uint8_t *gids_buf) { struct sss_mc_ctx *mcc = *_mcc; struct sss_mc_rec *rec; struct sss_mc_initgr_data *data; size_t data_len; size_t rec_len; size_t pos; int ret; if (mcc == NULL) { /* cache not initialized ? */ return EINVAL; } /* array of gids + name + unique_name */ data_len = num_groups * sizeof(uint32_t) + name->len + unique_name->len; rec_len = sizeof(struct sss_mc_rec) + sizeof(struct sss_mc_initgr_data) + data_len; if (rec_len > mcc->dt_size) { return ENOMEM; } /* use unique name for searching potential old records */ ret = sss_mc_get_record(_mcc, rec_len, unique_name, &rec); if (ret != EOK) { return ret; } data = (struct sss_mc_initgr_data *)rec->data; pos = 0; MC_RAISE_BARRIER(rec); /* We cannot use two keys for searching in intgroups cache. * Use the first key twice. */ sss_mmap_set_rec_header(mcc, rec, rec_len, mcc->valid_time_slot, name->str, name->len, unique_name->str, unique_name->len); /* initgroups struct */ data->strs_len = name->len + unique_name->len; data->data_len = data_len; data->num_groups = num_groups; memcpy((char *)data->gids + pos, gids_buf, num_groups * sizeof(uint32_t)); pos += num_groups * sizeof(uint32_t); memcpy((char *)data->gids + pos, unique_name->str, unique_name->len); data->strs = data->unique_name = MC_PTR_DIFF((char *)data->gids + pos, data); pos += unique_name->len; memcpy((char *)data->gids + pos, name->str, name->len); data->name = MC_PTR_DIFF((char *)data->gids + pos, data); MC_LOWER_BARRIER(rec); /* finally chain the rec in the hash table */ sss_mmap_chain_in_rec(mcc, rec); return EOK; } errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx *mcc, struct sized_string *name) { return sss_mmap_cache_invalidate(mcc, name); } /*************************************************************************** * initialization ***************************************************************************/ /* Copy of sss_mc_set_recycled is present in the src/tools/tools_mc_util.c. * If you modify this function, you should modify the duplicated function * too. */ static errno_t sss_mc_set_recycled(int fd) { uint32_t w = SSS_MC_HEADER_RECYCLED; struct sss_mc_header h; off_t offset; off_t pos; ssize_t written; offset = MC_PTR_DIFF(&h.status, &h); pos = lseek(fd, offset, SEEK_SET); if (pos == -1) { /* What do we do now ? */ return errno; } errno = 0; written = sss_atomic_write_s(fd, (uint8_t *)&w, sizeof(h.status)); if (written == -1) { return errno; } if (written != sizeof(h.status)) { /* Write error */ return EIO; } return EOK; } /* * When we (re)create a new file we must mark the current file as recycled * so active clients will abandon its use asap. * We unlink the current file and make a new one */ static errno_t sss_mc_create_file(struct sss_mc_ctx *mc_ctx) { mode_t old_mask; int ofd; int ret, uret; useconds_t t = 50000; int retries = 3; ofd = open(mc_ctx->file, O_RDWR); if (ofd != -1) { ret = sss_br_lock_file(ofd, 0, 1, retries, t); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to lock file %s.\n", mc_ctx->file); } ret = sss_mc_set_recycled(ofd); if (ret) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to mark mmap file %s as" " recycled: %d(%s)\n", mc_ctx->file, ret, strerror(ret)); } close(ofd); } else if (errno != ENOENT) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to open old memory cache file %s: %d(%s).\n", mc_ctx->file, ret, strerror(ret)); } errno = 0; ret = unlink(mc_ctx->file); if (ret == -1 && errno != ENOENT) { ret = errno; DEBUG(SSSDBG_TRACE_FUNC, "Failed to rm mmap file %s: %d(%s)\n", mc_ctx->file, ret, strerror(ret)); } /* temporarily relax umask as we need the file to be readable * by everyone for now */ old_mask = umask(0022); errno = 0; mc_ctx->fd = open(mc_ctx->file, O_CREAT | O_EXCL | O_RDWR, 0644); umask(old_mask); if (mc_ctx->fd == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to open mmap file %s: %d(%s)\n", mc_ctx->file, ret, strerror(ret)); return ret; } ret = sss_br_lock_file(mc_ctx->fd, 0, 1, retries, t); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to lock file %s.\n", mc_ctx->file); close(mc_ctx->fd); mc_ctx->fd = -1; /* Report on unlink failures but don't overwrite the errno * from sss_br_lock_file */ errno = 0; uret = unlink(mc_ctx->file); if (uret == -1) { uret = errno; DEBUG(SSSDBG_TRACE_FUNC, "Failed to rm mmap file %s: %d(%s)\n", mc_ctx->file, uret, strerror(uret)); } return ret; } return ret; } static void sss_mc_header_update(struct sss_mc_ctx *mc_ctx, int status) { struct sss_mc_header *h; /* update header using barriers */ h = (struct sss_mc_header *)mc_ctx->mmap_base; MC_RAISE_BARRIER(h); if (status == SSS_MC_HEADER_ALIVE) { /* no reason to update anything else if the file is recycled or * right before reset */ h->hash_table = MC_PTR_DIFF(mc_ctx->hash_table, mc_ctx->mmap_base); h->free_table = MC_PTR_DIFF(mc_ctx->free_table, mc_ctx->mmap_base); h->data_table = MC_PTR_DIFF(mc_ctx->data_table, mc_ctx->mmap_base); h->ht_size = mc_ctx->ht_size; h->ft_size = mc_ctx->ft_size; h->dt_size = mc_ctx->dt_size; h->major_vno = SSS_MC_MAJOR_VNO; h->minor_vno = SSS_MC_MINOR_VNO; h->seed = mc_ctx->seed; h->reserved = 0; } h->status = status; MC_LOWER_BARRIER(h); } static int mc_ctx_destructor(struct sss_mc_ctx *mc_ctx) { int ret; /* Print debug message to logs if munmap() or close() * fail but always return 0 */ if (mc_ctx->mmap_base != NULL) { ret = munmap(mc_ctx->mmap_base, mc_ctx->mmap_size); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unmap old memory cache file." "[%d]: %s\n", ret, strerror(ret)); } } if (mc_ctx->fd != -1) { ret = close(mc_ctx->fd); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to close old memory cache file." "[%d]: %s\n", ret, strerror(ret)); } } return 0; } errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name, enum sss_mc_type type, size_t n_elem, time_t timeout, struct sss_mc_ctx **mcc) { struct sss_mc_ctx *mc_ctx = NULL; unsigned int rseed; int payload; int ret, dret; switch (type) { case SSS_MC_PASSWD: payload = SSS_AVG_PASSWD_PAYLOAD; break; case SSS_MC_GROUP: payload = SSS_AVG_GROUP_PAYLOAD; break; case SSS_MC_INITGROUPS: payload = SSS_AVG_INITGROUP_PAYLOAD; break; default: return EINVAL; } mc_ctx = talloc_zero(mem_ctx, struct sss_mc_ctx); if (!mc_ctx) { return ENOMEM; } mc_ctx->fd = -1; talloc_set_destructor(mc_ctx, mc_ctx_destructor); mc_ctx->name = talloc_strdup(mc_ctx, name); if (!mc_ctx->name) { ret = ENOMEM; goto done; } mc_ctx->type = type; mc_ctx->valid_time_slot = timeout; mc_ctx->file = talloc_asprintf(mc_ctx, "%s/%s", SSS_NSS_MCACHE_DIR, name); if (!mc_ctx->file) { ret = ENOMEM; goto done; } /* elements must always be multiple of 8 to make things easier to handle, * so we increase by the necessary amount if they are not a multiple */ /* We can use MC_ALIGN64 for this */ n_elem = MC_ALIGN64(n_elem); /* hash table is double the size because it will store both forward and * reverse keys (name/uid, name/gid, ..) */ mc_ctx->ht_size = MC_HT_SIZE(n_elem * 2); mc_ctx->dt_size = MC_DT_SIZE(n_elem, payload); mc_ctx->ft_size = MC_FT_SIZE(n_elem); mc_ctx->mmap_size = MC_HEADER_SIZE + MC_ALIGN64(mc_ctx->dt_size) + MC_ALIGN64(mc_ctx->ft_size) + MC_ALIGN64(mc_ctx->ht_size); /* for now ALWAYS create a new file on restart */ ret = sss_mc_create_file(mc_ctx); if (ret) { goto done; } ret = ftruncate(mc_ctx->fd, mc_ctx->mmap_size); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to resize file %s: %d(%s)\n", mc_ctx->file, ret, strerror(ret)); goto done; } mc_ctx->mmap_base = mmap(NULL, mc_ctx->mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, mc_ctx->fd, 0); if (mc_ctx->mmap_base == MAP_FAILED) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to mmap file %s(%zu): %d(%s)\n", mc_ctx->file, mc_ctx->mmap_size, ret, strerror(ret)); goto done; } mc_ctx->data_table = MC_PTR_ADD(mc_ctx->mmap_base, MC_HEADER_SIZE); mc_ctx->free_table = MC_PTR_ADD(mc_ctx->data_table, MC_ALIGN64(mc_ctx->dt_size)); mc_ctx->hash_table = MC_PTR_ADD(mc_ctx->free_table, MC_ALIGN64(mc_ctx->ft_size)); memset(mc_ctx->data_table, 0xff, mc_ctx->dt_size); memset(mc_ctx->free_table, 0x00, mc_ctx->ft_size); memset(mc_ctx->hash_table, 0xff, mc_ctx->ht_size); /* generate a pseudo-random seed. * Needed to fend off dictionary based collision attacks */ rseed = time(NULL) * getpid(); mc_ctx->seed = rand_r(&rseed); sss_mc_header_update(mc_ctx, SSS_MC_HEADER_ALIVE); ret = EOK; done: if (ret) { /* Closing the file descriptor and ummaping the file * from memory is done in the mc_ctx_destructor. */ if (mc_ctx && mc_ctx->file && mc_ctx->fd != -1) { dret = unlink(mc_ctx->file); if (dret == -1) { dret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to rm mmap file %s: %d(%s)\n", mc_ctx->file, dret, strerror(dret)); } } talloc_free(mc_ctx); } else { *mcc = mc_ctx; } return ret; } errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem, time_t timeout, struct sss_mc_ctx **mc_ctx) { errno_t ret; TALLOC_CTX* tmp_ctx = NULL; char *name; enum sss_mc_type type; if (mc_ctx == NULL || (*mc_ctx) == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to re-init uninitialized memory cache.\n"); return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n"); return ENOMEM; } name = talloc_strdup(tmp_ctx, (*mc_ctx)->name); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n"); ret = ENOMEM; goto done; } type = (*mc_ctx)->type; if (n_elem == (size_t)-1) { n_elem = (*mc_ctx)->ft_size * 8; } if (timeout == (time_t)-1) { timeout = (*mc_ctx)->valid_time_slot; } talloc_free(*mc_ctx); /* make sure we do not leave a potentially freed pointer around */ *mc_ctx = NULL; ret = sss_mmap_cache_init(mem_ctx, name, type, n_elem, timeout, mc_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to re-initialize mmap cache.\n"); goto done; } done: talloc_free(tmp_ctx); return ret; } /* Erase all contents of the mmap cache. This will bring the cache * to the same state as if it was just initialized. */ void sss_mmap_cache_reset(struct sss_mc_ctx *mc_ctx) { if (mc_ctx == NULL) { DEBUG(SSSDBG_TRACE_FUNC, "Fastcache not initialized. Nothing to do.\n"); return; } sss_mc_header_update(mc_ctx, SSS_MC_HEADER_UNINIT); /* Reset the mmaped area */ memset(mc_ctx->data_table, 0xff, mc_ctx->dt_size); memset(mc_ctx->free_table, 0x00, mc_ctx->ft_size); memset(mc_ctx->hash_table, 0xff, mc_ctx->ht_size); sss_mc_header_update(mc_ctx, SSS_MC_HEADER_ALIVE); } sssd-1.13.4/src/responder/nss/PaxHeaders.16287/nsssrv_netgroup.h0000644000000000000000000000007412703456111021352 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.460792971 sssd-1.13.4/src/responder/nss/nsssrv_netgroup.h0000644002412700241270000000227212703456111023024 0ustar00jhrozekjhrozek00000000000000/* SSSD nssrv_netgroup.h Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef NSSRV_NETGROUP_H_ #define NSSRV_NETGROUP_H_ #define SSS_COL_NETGR 5000 int nss_cmd_setnetgrent(struct cli_ctx *cctx); int nss_cmd_getnetgrent(struct cli_ctx *cctx); int nss_cmd_endnetgrent(struct cli_ctx *cctx); void netgroup_hash_delete_cb(hash_entry_t *item, hash_destroy_enum deltype, void *pvt); errno_t nss_orphan_netgroups(struct nss_ctx *nctx); #endif /* NSSRV_NETGROUP_H_ */ sssd-1.13.4/src/responder/nss/PaxHeaders.16287/nsssrv.h0000644000000000000000000000007412703456111017427 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.457792961 sssd-1.13.4/src/responder/nss/nsssrv.h0000644002412700241270000000376612703456111021112 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Responder, header file Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __NSSSRV_H__ #define __NSSSRV_H__ #include "config.h" #include #include #include #include #include #include #include "sbus/sssd_dbus.h" #include "responder/common/responder_packet.h" #include "responder/common/responder.h" #include "lib/idmap/sss_idmap.h" #define NSS_PACKET_MAX_RECV_SIZE 1024 struct getent_ctx; struct sss_mc_ctx; struct nss_ctx { struct resp_ctx *rctx; int neg_timeout; struct sss_nc_ctx *ncache; int cache_refresh_percent; int enum_cache_timeout; struct getent_ctx *pctx; struct getent_ctx *gctx; struct getent_ctx *svcctx; hash_table_t *netgroups; bool filter_users_in_groups; char *pwfield; char *override_homedir; char *fallback_homedir; char *homedir_substr; char **allowed_shells; char *override_shell; char **vetoed_shells; char **etc_shells; char *shell_fallback; char *default_shell; struct sss_mc_ctx *pwd_mc_ctx; struct sss_mc_ctx *grp_mc_ctx; struct sss_mc_ctx *initgr_mc_ctx; struct sss_idmap_ctx *idmap_ctx; struct sss_names_ctx *global_names; const char **extra_attributes; }; struct nss_packet; struct sss_cmd_table *get_nss_cmds(void); #endif /* __NSSSRV_H__ */ sssd-1.13.4/src/responder/nss/PaxHeaders.16287/nsssrv_private.h0000644000000000000000000000007412703456111021161 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.459792968 sssd-1.13.4/src/responder/nss/nsssrv_private.h0000644002412700241270000000677512703456111022647 0ustar00jhrozekjhrozek00000000000000/* SSSD nsssrv_private.h Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef NSSSRV_PRIVATE_H_ #define NSSSRV_PRIVATE_H_ #include struct nss_cmd_ctx { struct cli_ctx *cctx; enum sss_cli_command cmd; char *name; const char *normalized_name; bool name_is_upn; uint32_t id; char *secid; bool immediate; bool check_next; bool enum_cached; int saved_dom_idx; int saved_cur; }; struct dom_ctx { struct sss_domain_info *domain; struct ldb_result *res; }; struct getent_ctx { struct dom_ctx *doms; int num; bool ready; struct setent_req_list *reqs; /* Netgroup-specific */ hash_table_t *lookup_table; struct sysdb_netgroup_ctx **entries; char *name; char *domain; bool found; }; struct nss_dom_ctx { struct nss_cmd_ctx *cmdctx; struct sss_domain_info *domain; /* For a case when we are discovering subdomains */ const char *rawname; bool check_provider; /* cache results */ struct ldb_result *res; /* Netgroup-specific */ struct getent_ctx *netgr; /* Service-specific */ const char *protocol; const char *mc_name; }; struct setent_step_ctx { struct nss_ctx *nctx; struct nss_dom_ctx *dctx; struct getent_ctx *getent_ctx; struct resp_ctx *rctx; struct cli_ctx *cctx; bool check_next; bool returned_to_mainloop; /* Netgroup-specific */ char *name; }; #define NSS_CMD_FATAL_ERROR(cctx) do { \ DEBUG(SSSDBG_CRIT_FAILURE,"Fatal error, killing connection!\n"); \ talloc_free(cctx); \ return; \ } while(0) #define NSS_CMD_FATAL_ERROR_CODE(cctx, ret) do { \ DEBUG(SSSDBG_CRIT_FAILURE,"Fatal error, killing connection!\n"); \ talloc_free(cctx); \ return ret; \ } while(0) /* Finish the request */ int nss_cmd_done(struct nss_cmd_ctx *cmdctx, int ret); errno_t nss_setent_add_ref(TALLOC_CTX *memctx, struct getent_ctx *getent_ctx, struct tevent_req *req); void nss_setent_notify_error(struct getent_ctx *getent_ctx, errno_t ret); void nss_setent_notify_done(struct getent_ctx *getent_ctx); errno_t check_cache(struct nss_dom_ctx *dctx, struct nss_ctx *nctx, struct ldb_result *res, enum sss_dp_acct_type req_type, const char *opt_name, uint32_t opt_id, const char *extra, sss_dp_callback_t callback, void *pvt); void nss_update_pw_memcache(struct nss_ctx *nctx); void nss_update_gr_memcache(struct nss_ctx *nctx); void nss_update_initgr_memcache(struct nss_ctx *nctx, const char *name, const char *domain, int gnum, uint32_t *groups); #endif /* NSSSRV_PRIVATE_H_ */ sssd-1.13.4/src/responder/nss/PaxHeaders.16287/nsssrv_netgroup.c0000644000000000000000000000007412703456111021345 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.945794616 sssd-1.13.4/src/responder/nss/nsssrv_netgroup.c0000644002412700241270000010440712703456111023022 0ustar00jhrozekjhrozek00000000000000/* SSSD nsssrv_netgroup.c Authors: Stephen Gallagher Copyright (C) 2010 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "responder/nss/nsssrv.h" #include "responder/nss/nsssrv_private.h" #include "responder/nss/nsssrv_netgroup.h" #include "responder/common/negcache.h" #include "confdb/confdb.h" #include "db/sysdb.h" static errno_t get_netgroup_entry(struct nss_ctx *nctx, char *name, struct getent_ctx **netgr) { hash_key_t key; hash_value_t value; int hret; key.type = HASH_KEY_STRING; key.str = name; hret = hash_lookup(nctx->netgroups, &key, &value); if (hret == HASH_SUCCESS) { *netgr = talloc_get_type(value.ptr, struct getent_ctx); return EOK; } else if (hret == HASH_ERROR_KEY_NOT_FOUND) { return ENOENT; } DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected error reading from netgroup hash [%d][%s]\n", hret, hash_error_string(hret)); return EIO; } static int netgr_hash_remove(TALLOC_CTX *ctx); static errno_t set_netgroup_entry(struct nss_ctx *nctx, struct getent_ctx *netgr) { hash_key_t key; hash_value_t value; int hret; if (netgr->name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing netgroup name.\n"); return EINVAL; } /* Add this entry to the hash table */ key.type = HASH_KEY_STRING; key.str = netgr->name; value.type = HASH_VALUE_PTR; value.ptr = netgr; hret = hash_enter(nctx->netgroups, &key, &value); if (hret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to add hash table entry for [%s]\n", key.str); DEBUG(SSSDBG_CONF_SETTINGS, "Hash error [%d][%s]\n", hret, hash_error_string(hret)); return EIO; } talloc_steal(nctx->netgroups, netgr); talloc_set_destructor((TALLOC_CTX *) netgr, netgr_hash_remove); return EOK; } static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx, const char *rawname, struct nss_cmd_ctx *cmdctx); static void nss_cmd_setnetgrent_done(struct tevent_req *req); int nss_cmd_setnetgrent(struct cli_ctx *client) { struct nss_cmd_ctx *cmdctx; struct tevent_req *req; const char *rawname; uint8_t *body; size_t blen; errno_t ret = EOK; /* Reset the result cursor to zero */ client->netgrent_cur = 0; cmdctx = talloc_zero(client, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = client; /* get netgroup name to query */ sss_packet_get_body(client->creq->in, &body, &blen); /* if not terminated fail */ if (body[blen -1] != '\0') { ret = EINVAL; goto done; } /* If the body isn't valid UTF-8, fail */ if (!sss_utf8_check(body, blen -1)) { ret = EINVAL; goto done; } rawname = (const char *)body; req = setnetgrent_send(cmdctx, rawname, cmdctx); if (!req) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal error calling setnetgrent_send\n"); ret = EIO; goto done; } tevent_req_set_callback(req, nss_cmd_setnetgrent_done, cmdctx); done: return nss_cmd_done(cmdctx, ret); } static int netgr_hash_remove(TALLOC_CTX *ctx) { int hret; hash_key_t key; struct getent_ctx *netgr = talloc_get_type(ctx, struct getent_ctx); if (netgr->lookup_table == NULL) { DEBUG(SSSDBG_TRACE_LIBS, "netgroup [%s] was already removed\n", netgr->name); return EOK; } key.type = HASH_KEY_STRING; key.str = netgr->name; /* Remove the netgroup result object from the lookup table */ hret = hash_delete(netgr->lookup_table, &key); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not remove key [%s] from table! [%d][%s]\n", netgr->name, hret, hash_error_string(hret)); return -1; } return 0; } struct setnetgrent_ctx { struct nss_ctx *nctx; struct nss_cmd_ctx *cmdctx; struct nss_dom_ctx *dctx; char *netgr_shortname; struct getent_ctx *netgr; const char *rawname; }; static errno_t setnetgrent_retry(struct tevent_req *req); static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx); static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx, const char *rawname, struct nss_cmd_ctx *cmdctx) { char *domname; errno_t ret; struct tevent_req *req; struct setnetgrent_ctx *state; struct nss_dom_ctx *dctx; struct cli_ctx *client = cmdctx->cctx; struct nss_ctx *nctx = talloc_get_type(client->rctx->pvt_ctx, struct nss_ctx); req = tevent_req_create(mem_ctx, &state, struct setnetgrent_ctx); if (!req) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not create tevent request for setnetgrent\n"); return NULL; } state->nctx = nctx; state->cmdctx = cmdctx; state->rawname = rawname; state->dctx = talloc_zero(state, struct nss_dom_ctx); if (!state->dctx) { ret = ENOMEM; goto error; } dctx = state->dctx; dctx->cmdctx = state->cmdctx; ret = sss_parse_name_for_domains(state, client->rctx->domains, NULL, rawname, &domname, &state->netgr_shortname); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Invalid name received [%s]\n", rawname); goto error; } DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for netgroup [%s] from [%s]\n", state->netgr_shortname, domname?domname:""); if (domname) { dctx->domain = responder_get_domain(client->rctx, domname); if (!dctx->domain) { ret = EINVAL; goto error; } /* Save the netgroup name for getnetgrent */ client->netgr_name = talloc_strdup(client, state->netgr_shortname); if (!client->netgr_name) { ret = ENOMEM; goto error; } } else { /* this is a multidomain search */ dctx->domain = client->rctx->domains; cmdctx->check_next = true; /* Save the netgroup name for getnetgrent */ client->netgr_name = talloc_strdup(client, rawname); if (!client->netgr_name) { ret = ENOMEM; goto error; } } ret = setnetgrent_retry(req); if (ret != EOK) { if (ret == EAGAIN) { /* We need to reenter the mainloop * We may be refreshing the cache */ return req; } goto error; } return req; error: tevent_req_error(req, ret); tevent_req_post(req, cmdctx->cctx->ev); return req; } static errno_t setnetgrent_retry(struct tevent_req *req) { errno_t ret; struct setent_step_ctx *step_ctx; struct setnetgrent_ctx *state; struct cli_ctx *client; struct nss_ctx *nctx; struct nss_cmd_ctx *cmdctx; struct nss_dom_ctx *dctx; state = tevent_req_data(req, struct setnetgrent_ctx); dctx = state->dctx; cmdctx = state->cmdctx; client = cmdctx->cctx; nctx = talloc_get_type(client->rctx->pvt_ctx, struct nss_ctx); dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); /* Is the result context already available? * Check for existing lookups for this netgroup */ ret = get_netgroup_entry(nctx, client->netgr_name, &state->netgr); if (ret == EOK) { /* Another process already requested this netgroup * Check whether it's ready for processing. */ if (state->netgr->ready) { if (state->netgr->found) { /* Ready to process results */ tevent_req_done(req); } else { tevent_req_error(req, ENOENT); } tevent_req_post(req, nctx->rctx->ev); /* Return EOK, otherwise this will be treated as * an error */ return EOK; } /* Result object is still being constructed * Register for notification when it's ready */ ret = nss_setent_add_ref(state, state->netgr, req); if (ret != EOK) { goto done; } /* Will return control below */ } else if (ret == ENOENT) { /* This is the first attempt to request this netgroup */ state->netgr = talloc_zero(nctx, struct getent_ctx); if (!state->netgr) { ret = ENOMEM; goto done; } dctx->netgr = state->netgr; /* Save the name used for the lookup table * so we can remove it in the destructor */ state->netgr->name = talloc_strdup(state->netgr, client->netgr_name); if (!state->netgr->name) { talloc_free(state->netgr); ret = ENOMEM; goto done; } state->netgr->lookup_table = nctx->netgroups; /* Add a reference for ourselves */ ret = nss_setent_add_ref(state, state->netgr, req); if (ret != EOK) { talloc_free(state->netgr); goto done; } ret = set_netgroup_entry(nctx, state->netgr); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_netgroup_entry failed.\n"); talloc_free(state->netgr); goto done; } /* Perform lookup */ step_ctx = talloc_zero(state->netgr, struct setent_step_ctx); if (!step_ctx) { ret = ENOMEM; goto done; } /* Steal the dom_ctx onto the step_ctx so it doesn't go out of scope if * this request is canceled while other requests are in-progress. */ step_ctx->dctx = talloc_steal(step_ctx, state->dctx); step_ctx->nctx = state->nctx; step_ctx->getent_ctx = state->netgr; step_ctx->rctx = client->rctx; step_ctx->check_next = cmdctx->check_next; step_ctx->name = talloc_strdup(step_ctx, state->netgr->name); if (!step_ctx->name) { ret = ENOMEM; goto done; } ret = lookup_netgr_step(step_ctx); switch (ret) { case EOK: break; case EMSGSIZE: state->netgr->ready = true; ret = ENOENT; /* FALLTHROUGH */ default: goto done; } tevent_req_done(req); tevent_req_post(req, cmdctx->cctx->ev); /* Will return control below */ } else { /* Unexpected error from hash_lookup */ goto done; } ret = EOK; done: return ret; } static void lookup_netgr_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); static void setnetgrent_result_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt); /* Set up a lifetime timer for this result object * We don't want this result object to outlive the * entry cache refresh timeout */ static void set_netgr_lifetime(uint32_t lifetime, struct setent_step_ctx *step_ctx, struct getent_ctx *netgr) { struct timeval tv; struct tevent_timer *te; tv = tevent_timeval_current_ofs(lifetime, 0); te = tevent_add_timer(step_ctx->nctx->rctx->ev, step_ctx->nctx->gctx, tv, setnetgrent_result_timeout, netgr); if (!te) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up life timer for setnetgrent result object. " "Entries may become stale.\n"); } } /* Create dummy netgroup to speed up repeated negative queries */ static errno_t create_negcache_netgr(struct setent_step_ctx *step_ctx) { errno_t ret; struct getent_ctx *netgr; /* Is there already netgroup with such name? */ ret = get_netgroup_entry(step_ctx->nctx, step_ctx->name, &netgr); if (ret != EOK || netgr == NULL) { netgr = talloc_zero(step_ctx->nctx, struct getent_ctx); if (netgr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; goto done; } netgr->entries = NULL; netgr->lookup_table = step_ctx->nctx->netgroups; netgr->name = talloc_strdup(netgr, step_ctx->name); if (netgr->name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } ret = set_netgroup_entry(step_ctx->nctx, netgr); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "set_netgroup_entry failed.\n"); goto done; } } netgr->ready = true; netgr->found = false; set_netgr_lifetime(step_ctx->nctx->neg_timeout, step_ctx, netgr); ret = EOK; done: if (ret != EOK) { talloc_free(netgr); } return ret; } static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx) { errno_t ret; struct sss_domain_info *dom = step_ctx->dctx->domain; struct getent_ctx *netgr; char *name = NULL; uint32_t lifetime; TALLOC_CTX *tmp_ctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } /* Check each domain for this netgroup name */ while (dom) { /* Netgroups are a special case. We have to ignore the * fully-qualified name requirement because memberNisNetgroup * entries do not have fully-qualified components and we need * to be able to always check them. So unlike the other * maps, here we avoid skipping over fully-qualified domains. */ if (dom != step_ctx->dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ step_ctx->dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); } /* make sure to update the dctx if we changed domain */ step_ctx->dctx->domain = dom; name = sss_get_cased_name(tmp_ctx, step_ctx->name, dom->case_sensitive); if (!name) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_get_cased_name failed\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%s@%s]\n", name, dom->name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); ret = EIO; goto done; } /* Look up the netgroup in the cache */ ret = sysdb_getnetgr(step_ctx->dctx, dom, name, &step_ctx->dctx->res); if (ret == EOK) { if (step_ctx->dctx->res->count > 1) { DEBUG(SSSDBG_FATAL_FAILURE, "getnetgr call returned more than one result !?!\n"); ret = EMSGSIZE; goto done; } } else if (ret == ENOENT) { /* This netgroup was not found in this domain */ if (!step_ctx->dctx->check_provider) { if (step_ctx->check_next) { dom = get_next_domain(dom, 0); continue; } else { break; } } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); ret = EIO; goto done; } ret = get_netgroup_entry(step_ctx->nctx, step_ctx->name, &netgr); if (ret != EOK) { /* Something really bad happened! */ DEBUG(SSSDBG_FATAL_FAILURE, "Netgroup entry was lost!\n"); goto done; } /* Convert the result to a list of entries */ ret = sysdb_netgr_to_entries(netgr, step_ctx->dctx->res, &netgr->entries); if (ret == ENOENT) { /* This netgroup was not found in this domain */ DEBUG(SSSDBG_OP_FAILURE, "No results for netgroup %s (domain %s)\n", name, dom->name); if (!step_ctx->dctx->check_provider) { if (step_ctx->check_next) { dom = get_next_domain(dom, 0); continue; } else break; } ret = EOK; } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to convert results into entries\n"); netgr->ready = true; netgr->found = false; set_netgr_lifetime(step_ctx->nctx->neg_timeout, step_ctx, netgr); ret = EIO; goto done; } /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (step_ctx->dctx->check_provider) { ret = check_cache(step_ctx->dctx, step_ctx->nctx, step_ctx->dctx->res, SSS_DP_NETGR, name, 0, NULL, lookup_netgr_dp_callback, step_ctx); if (ret != EOK) { /* May return EAGAIN legitimately to indicate that * we need to reenter the mainloop */ goto done; } } /* Results found */ DEBUG(SSSDBG_TRACE_FUNC, "Returning info for netgroup [%s@%s]\n", name, dom->name); netgr->ready = true; netgr->found = true; if (step_ctx->nctx->cache_refresh_percent) { lifetime = dom->netgroup_timeout * (step_ctx->nctx->cache_refresh_percent / 100.0); } else { lifetime = dom->netgroup_timeout; } if (lifetime < 10) lifetime = 10; set_netgr_lifetime(lifetime, step_ctx, netgr); ret = EOK; goto done; } /* If we've gotten here, then no domain contained this netgroup */ DEBUG(SSSDBG_MINOR_FAILURE, "No matching domain found for [%s], fail!\n", step_ctx->name); ret = create_negcache_netgr(step_ctx); if (ret != EOK) { /* Failure can be ignored, because at worst, there will be a slowdown * at the next lookup */ DEBUG(SSSDBG_TRACE_ALL, "create_negcache_netgr failed with: %d:[%s], ignored.\n", ret, sss_strerror(ret)); } ret = ENOENT; done: talloc_free(tmp_ctx); return ret; } static void lookup_netgr_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr) { struct setent_step_ctx *step_ctx = talloc_get_type(ptr, struct setent_step_ctx); struct nss_dom_ctx *dctx = step_ctx->dctx; struct nss_cmd_ctx *cmdctx = dctx->cmdctx; int ret; if (err_maj) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get information from Data Provider\n" "Error: %u, %u, %s\n" "Will try to return what we have in cache\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg); /* Loop to the next domain if possible */ if (cmdctx->check_next && (dctx->domain = get_next_domain(dctx->domain, 0))) { dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); } } /* ok the backend returned, search to see if we have updated results */ ret = lookup_netgr_step(step_ctx); if (ret == EAGAIN) { return; } /* We have results to return */ if (ret == EOK) { nss_setent_notify_done(dctx->netgr); } else { nss_setent_notify_error(dctx->netgr, ret); } } static void setnetgrent_result_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { struct getent_ctx *netgr = talloc_get_type(pvt, struct getent_ctx); /* Free the netgroup result context * The destructor for the netgroup will remove itself * from the hash table * * If additional getnetgrent() requests come in, they * will invoke an implicit setnetgrent() call and * refresh the result object */ talloc_free(netgr); } static errno_t setnetgrent_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void nss_cmd_setnetgrent_done(struct tevent_req *req) { errno_t reqret; errno_t ret; struct sss_packet *packet; uint8_t *body; size_t blen; struct nss_cmd_ctx *cmdctx = tevent_req_callback_data(req, struct nss_cmd_ctx); reqret = setnetgrent_recv(req); talloc_zfree(req); if (reqret != EOK && reqret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "setnetgrent failed\n"); nss_cmd_done(cmdctx, reqret); return; } /* Either we succeeded or no domains were eligible */ ret = sss_packet_new(cmdctx->cctx->creq, 0, sss_packet_get_cmd(cmdctx->cctx->creq->in), &cmdctx->cctx->creq->out); if (ret == EOK) { if (reqret == ENOENT) { /* Notify the caller that this entry wasn't found */ sss_cmd_empty_packet(cmdctx->cctx->creq->out); } else { packet = cmdctx->cctx->creq->out; ret = sss_packet_grow(packet, 2*sizeof(uint32_t)); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Couldn't grow the packet\n"); NSS_CMD_FATAL_ERROR(cmdctx); } sss_packet_get_body(packet, &body, &blen); /* Got some results. */ SAFEALIGN_SETMEM_UINT32(body, 1, NULL); /* reserved */ SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL); } sss_cmd_done(cmdctx->cctx, cmdctx); return; } DEBUG(SSSDBG_CRIT_FAILURE, "Error creating packet\n"); } static void setnetgrent_implicit_done(struct tevent_req *req); static errno_t nss_cmd_getnetgrent_process(struct nss_cmd_ctx *cmdctx, struct getent_ctx *netgr); int nss_cmd_getnetgrent(struct cli_ctx *client) { errno_t ret; struct nss_ctx *nctx; struct nss_cmd_ctx *cmdctx; struct getent_ctx *netgr; struct tevent_req *req; DEBUG(SSSDBG_CONF_SETTINGS, "Requesting netgroup data\n"); cmdctx = talloc_zero(client, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = client; nctx = talloc_get_type(client->rctx->pvt_ctx, struct nss_ctx); if (!client->netgr_name) { /* Tried to run getnetgrent without a preceding * setnetgrent. There is no way to determine which * netgroup is being requested. */ return nss_cmd_done(cmdctx, EINVAL); } /* Look up the results from the hash */ ret = get_netgroup_entry(nctx, client->netgr_name, &netgr); if (ret == ENOENT) { /* We need to invoke an implicit setnetgrent() to * wait for the result object to become available. */ req = setnetgrent_send(cmdctx, client->netgr_name, cmdctx); if (!req) { return nss_cmd_done(cmdctx, EIO); } tevent_req_set_callback(req, setnetgrent_implicit_done, cmdctx); return EOK; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "An unexpected error occurred: [%d][%s]\n", ret, strerror(ret)); return nss_cmd_done(cmdctx, ret); } /* Hash entry was found. Is it ready? */ if (!netgr->ready) { /* We need to invoke an implicit setnetgrent() to * wait for the result object to become available. */ req = setnetgrent_send(cmdctx, client->netgr_name, cmdctx); if (!req) { return nss_cmd_done(cmdctx, EIO); } tevent_req_set_callback(req, setnetgrent_implicit_done, cmdctx); return EOK; } else if (!netgr->found) { DEBUG(SSSDBG_TRACE_FUNC, "Results for [%s] not found.\n", client->netgr_name); return ENOENT; } DEBUG(SSSDBG_TRACE_FUNC, "Returning results for [%s]\n", client->netgr_name); /* Read the result strings */ ret = nss_cmd_getnetgrent_process(cmdctx, netgr); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed: [%d][%s]\n", ret, strerror(ret)); } return ret; } static void setnetgrent_implicit_done(struct tevent_req *req) { errno_t ret; struct getent_ctx *netgr; struct nss_cmd_ctx *cmdctx = tevent_req_callback_data(req, struct nss_cmd_ctx); struct nss_ctx *nctx = talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct nss_ctx); ret = setnetgrent_recv(req); talloc_zfree(req); /* ENOENT is acceptable, it just means there were no values * to be returned. This will be handled gracefully in * nss_cmd_retnetgrent later */ if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "Implicit setnetgrent failed with unexpected error " "[%d][%s]\n", ret, strerror(ret)); NSS_CMD_FATAL_ERROR(cmdctx); } if (ret == ENOENT) { /* No entries found for this netgroup */ nss_cmd_done(cmdctx, ret); return; } /* Look up the results from the hash */ ret = get_netgroup_entry(nctx, cmdctx->cctx->netgr_name, &netgr); if (ret == ENOENT) { /* Critical error. This should never happen */ DEBUG(SSSDBG_FATAL_FAILURE, "Implicit setnetgrent returned success without creating " "result object.\n"); NSS_CMD_FATAL_ERROR(cmdctx); } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "An unexpected error occurred: [%d][%s]\n", ret, strerror(ret)); NSS_CMD_FATAL_ERROR(cmdctx); } if (!netgr->ready) { /* Critical error. This should never happen */ DEBUG(SSSDBG_FATAL_FAILURE, "Implicit setnetgrent returned success without creating " "result object.\n"); NSS_CMD_FATAL_ERROR(cmdctx); } ret = nss_cmd_getnetgrent_process(cmdctx, netgr); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Immediate retrieval failed with unexpected error " "[%d][%s]\n", ret, strerror(ret)); NSS_CMD_FATAL_ERROR(cmdctx); } } static errno_t nss_cmd_retnetgrent(struct cli_ctx *client, struct sysdb_netgroup_ctx **entries, int num); static errno_t nss_cmd_getnetgrent_process(struct nss_cmd_ctx *cmdctx, struct getent_ctx *netgr) { struct cli_ctx *client = cmdctx->cctx; uint8_t *body; size_t blen; uint32_t num; errno_t ret; /* get max num of entries to return in one call */ sss_packet_get_body(client->creq->in, &body, &blen); if (blen != sizeof(uint32_t)) { return EINVAL; } SAFEALIGN_COPY_UINT32(&num, body, NULL); /* create response packet */ ret = sss_packet_new(client->creq, 0, sss_packet_get_cmd(client->creq->in), &client->creq->out); if (ret != EOK) { return ret; } if (!netgr->entries || netgr->entries[0] == NULL) { /* No entries */ DEBUG(SSSDBG_FUNC_DATA, "No entries found\n"); ret = sss_cmd_empty_packet(client->creq->out); if (ret != EOK) { return nss_cmd_done(cmdctx, ret); } goto done; } ret = nss_cmd_retnetgrent(client, netgr->entries, num); done: sss_packet_set_error(client->creq->out, ret); sss_cmd_done(client, cmdctx); return EOK; } static errno_t nss_cmd_retnetgrent(struct cli_ctx *client, struct sysdb_netgroup_ctx **entries, int count) { size_t len; size_t hostlen = 0; size_t userlen = 0; size_t domainlen = 0; size_t grouplen = 0; uint8_t *body; size_t blen, rp; errno_t ret; struct sss_packet *packet = client->creq->out; int num, start; /* first 2 fields (len and reserved), filled up later */ rp = 2*sizeof(uint32_t); ret = sss_packet_grow(packet, rp); if (ret != EOK) return ret; start = client->netgrent_cur; num = 0; while (entries[client->netgrent_cur] && (client->netgrent_cur - start) < count) { if (entries[client->netgrent_cur]->type == SYSDB_NETGROUP_TRIPLE_VAL) { hostlen = 1; if (entries[client->netgrent_cur]->value.triple.hostname) { hostlen += strlen(entries[client->netgrent_cur]->value.triple.hostname); } userlen = 1; if (entries[client->netgrent_cur]->value.triple.username) { userlen += strlen(entries[client->netgrent_cur]->value.triple.username); } domainlen = 1; if (entries[client->netgrent_cur]->value.triple.domainname) { domainlen += strlen(entries[client->netgrent_cur]->value.triple.domainname); } len = sizeof(uint32_t) + hostlen + userlen + domainlen; ret = sss_packet_grow(packet, len); if (ret != EOK) { return ret; } sss_packet_get_body(packet, &body, &blen); SAFEALIGN_SET_UINT32(&body[rp], SSS_NETGR_REP_TRIPLE, &rp); if (hostlen == 1) { body[rp] = '\0'; } else { memcpy(&body[rp], entries[client->netgrent_cur]->value.triple.hostname, hostlen); } rp += hostlen; if (userlen == 1) { body[rp] = '\0'; } else { memcpy(&body[rp], entries[client->netgrent_cur]->value.triple.username, userlen); } rp += userlen; if (domainlen == 1) { body[rp] = '\0'; } else { memcpy(&body[rp], entries[client->netgrent_cur]->value.triple.domainname, domainlen); } rp += domainlen; } else if (entries[client->netgrent_cur]->type == SYSDB_NETGROUP_GROUP_VAL) { if (entries[client->netgrent_cur]->value.groupname == NULL || entries[client->netgrent_cur]->value.groupname[0] == '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Empty netgroup member. Please check your cache.\n"); continue; } grouplen = 1 + strlen(entries[client->netgrent_cur]->value.groupname); len = sizeof(uint32_t) + grouplen; ret = sss_packet_grow(packet, len); if (ret != EOK) { return ret; } sss_packet_get_body(packet, &body, &blen); SAFEALIGN_SET_UINT32(&body[rp], SSS_NETGR_REP_GROUP, &rp); memcpy(&body[rp], entries[client->netgrent_cur]->value.groupname, grouplen); rp += grouplen; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected value type for netgroup entry. " "Please check your cache.\n"); continue; } num++; client->netgrent_cur++; } sss_packet_get_body(packet, &body, &blen); /* num results */ SAFEALIGN_COPY_UINT32(body, &num, NULL); /* reserved */ SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL); return EOK; } int nss_cmd_endnetgrent(struct cli_ctx *client) { errno_t ret; /* create response packet */ ret = sss_packet_new(client->creq, 0, sss_packet_get_cmd(client->creq->in), &client->creq->out); if (ret != EOK) { return ret; } /* Reset the indices so that subsequent requests start at zero */ client->netgrent_cur = 0; talloc_zfree(client->netgr_name); sss_cmd_done(client, NULL); return EOK; } void netgroup_hash_delete_cb(hash_entry_t *item, hash_destroy_enum deltype, void *pvt) { struct getent_ctx *netgr; if (deltype != HASH_ENTRY_DESTROY) { return; } netgr = talloc_get_type(item->value.ptr, struct getent_ctx); if (!netgr) { DEBUG(SSSDBG_OP_FAILURE, "Invalid netgroup\n"); return; } /* So that the destructor wouldn't attempt to remove the netgroup from hash * table */ netgr->lookup_table = NULL; } errno_t nss_orphan_netgroups(struct nss_ctx *nctx) { int hret; unsigned long mcount; unsigned long i; hash_key_t *netgroups; if (!nctx || !nctx->netgroups) { return EINVAL; } hret = hash_keys(nctx->netgroups, &mcount, &netgroups); if (hret != HASH_SUCCESS) { return EIO; } DEBUG(SSSDBG_TRACE_FUNC, "Removing netgroups from memory cache.\n"); for (i = 0; i < mcount; i++) { /* netgroup entry will be deleted by setnetgrent_result_timeout */ hret = hash_delete(nctx->netgroups, &netgroups[i]); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not delete key from hash\n"); continue; } } return EOK; } sssd-1.13.4/src/responder/nss/PaxHeaders.16287/nsssrv_mmap_cache.h0000644000000000000000000000007412703456111021564 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.463792981 sssd-1.13.4/src/responder/nss/nsssrv_mmap_cache.h0000644002412700241270000000562612703456111023244 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Responder - Mmap Cache Copyright (C) Simo Sorce 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _NSSSRV_MMAP_CACHE_H_ #define _NSSSRV_MMAP_CACHE_H_ #define SSS_MC_CACHE_ELEMENTS 50000 struct sss_mc_ctx; enum sss_mc_type { SSS_MC_NONE = 0, SSS_MC_PASSWD, SSS_MC_GROUP, SSS_MC_INITGROUPS, }; errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name, enum sss_mc_type type, size_t n_elem, time_t valid_time, struct sss_mc_ctx **mcc); errno_t sss_mmap_cache_pw_store(struct sss_mc_ctx **_mcc, struct sized_string *name, struct sized_string *pw, uid_t uid, gid_t gid, struct sized_string *gecos, struct sized_string *homedir, struct sized_string *shell); errno_t sss_mmap_cache_gr_store(struct sss_mc_ctx **_mcc, struct sized_string *name, struct sized_string *pw, gid_t gid, size_t memnum, char *membuf, size_t memsize); errno_t sss_mmap_cache_initgr_store(struct sss_mc_ctx **_mcc, struct sized_string *name, struct sized_string *unique_name, uint32_t num_groups, uint8_t *gids_buf); errno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx *mcc, struct sized_string *name); errno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid); errno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx *mcc, struct sized_string *name); errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid); errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx *mcc, struct sized_string *name); errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem, time_t timeout, struct sss_mc_ctx **mc_ctx); void sss_mmap_cache_reset(struct sss_mc_ctx *mc_ctx); #endif /* _NSSSRV_MMAP_CACHE_H_ */ sssd-1.13.4/src/responder/nss/PaxHeaders.16287/nsssrv.c0000644000000000000000000000007412703456111017422 xustar0030 atime=1460561751.651715631 30 ctime=1460561775.009794832 sssd-1.13.4/src/responder/nss/nsssrv.c0000644002412700241270000004714012703456111021077 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Responder Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "responder/nss/nsssrv.h" #include "responder/nss/nsssrv_private.h" #include "responder/nss/nsssrv_mmap_cache.h" #include "responder/nss/nsssrv_netgroup.h" #include "responder/common/negcache.h" #include "db/sysdb.h" #include "confdb/confdb.h" #include "sbus/sssd_dbus.h" #include "responder/common/responder_packet.h" #include "responder/common/responder.h" #include "responder/common/responder_sbus.h" #include "providers/data_provider.h" #include "monitor/monitor_interfaces.h" #include "sbus/sbus_client.h" #include "util/util_sss_idmap.h" #define DEFAULT_PWFIELD "*" #define DEFAULT_NSS_FD_LIMIT 8192 #define SHELL_REALLOC_INCREMENT 5 #define SHELL_REALLOC_MAX 50 static int nss_clear_memcache(struct sbus_request *dbus_req, void *data); static int nss_clear_netgroup_hash_table(struct sbus_request *dbus_req, void *data); struct mon_cli_iface monitor_nss_methods = { { &mon_cli_iface_meta, 0 }, .ping = monitor_common_pong, .resInit = monitor_common_res_init, .shutDown = NULL, .goOffline = NULL, .resetOffline = NULL, .rotateLogs = responder_logrotate, .clearMemcache = nss_clear_memcache, .clearEnumCache = nss_clear_netgroup_hash_table, .sysbusReconnect = NULL, }; static int nss_clear_memcache(struct sbus_request *dbus_req, void *data) { errno_t ret; int memcache_timeout; struct resp_ctx *rctx = talloc_get_type(data, struct resp_ctx); struct nss_ctx *nctx = (struct nss_ctx*) rctx->pvt_ctx; ret = unlink(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG); if (ret != 0) { ret = errno; if (ret == ENOENT) { DEBUG(SSSDBG_TRACE_FUNC, "CLEAR_MC_FLAG not found. Nothing to do.\n"); goto done; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unlink file: %s.\n", strerror(ret)); return ret; } } /* CLEAR_MC_FLAG removed successfully. Clearing memory caches. */ ret = confdb_get_int(rctx->cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_MEMCACHE_TIMEOUT, 300, &memcache_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to get memory cache entry timeout.\n"); return ret; } /* TODO: read cache sizes from configuration */ DEBUG(SSSDBG_TRACE_FUNC, "Clearing memory caches.\n"); ret = sss_mmap_cache_reinit(nctx, SSS_MC_CACHE_ELEMENTS, (time_t) memcache_timeout, &nctx->pwd_mc_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache invalidation failed\n"); return ret; } ret = sss_mmap_cache_reinit(nctx, SSS_MC_CACHE_ELEMENTS, (time_t) memcache_timeout, &nctx->grp_mc_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache invalidation failed\n"); return ret; } ret = sss_mmap_cache_reinit(nctx, SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, &nctx->initgr_mc_ctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "initgroups mmap cache invalidation failed\n"); return ret; } done: return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } static int nss_clear_netgroup_hash_table(struct sbus_request *dbus_req, void *data) { errno_t ret; struct resp_ctx *rctx = talloc_get_type(data, struct resp_ctx); struct nss_ctx *nctx = (struct nss_ctx*) rctx->pvt_ctx; ret = nss_orphan_netgroups(nctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not invalidate netgroups\n"); return ret; } return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } static errno_t nss_get_etc_shells(TALLOC_CTX *mem_ctx, char ***_shells) { int i = 0; char *sh; char **shells = NULL; TALLOC_CTX *tmp_ctx; errno_t ret; int size; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; shells = talloc_array(tmp_ctx, char *, SHELL_REALLOC_INCREMENT); if (!shells) { ret = ENOMEM; goto done; } size = SHELL_REALLOC_INCREMENT; setusershell(); while ((sh = getusershell())) { shells[i] = talloc_strdup(shells, sh); if (!shells[i]) { endusershell(); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Found shell %s in /etc/shells\n", shells[i]); i++; if (i == size) { size += SHELL_REALLOC_INCREMENT; if (size > SHELL_REALLOC_MAX) { DEBUG(SSSDBG_FATAL_FAILURE, "Reached maximum number of shells [%d]. " "Users may be denied access. " "Please check /etc/shells for sanity\n", SHELL_REALLOC_MAX); break; } shells = talloc_realloc(NULL, shells, char *, size); if (!shells) { ret = ENOMEM; goto done; } } } endusershell(); if (i + 1 < size) { shells = talloc_realloc(NULL, shells, char *, i + 1); if (!shells) { ret = ENOMEM; goto done; } } shells[i] = NULL; *_shells = talloc_move(mem_ctx, &shells); ret = EOK; done: talloc_zfree(tmp_ctx); return ret; } static int nss_get_config(struct nss_ctx *nctx, struct confdb_ctx *cdb) { int ret; char *tmp_str; ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_ENUM_CACHE_TIMEOUT, 120, &nctx->enum_cache_timeout); if (ret != EOK) goto done; ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_ENTRY_NEG_TIMEOUT, 15, &nctx->neg_timeout); if (ret != EOK) goto done; ret = confdb_get_bool(cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_FILTER_USERS_IN_GROUPS, true, &nctx->filter_users_in_groups); if (ret != EOK) goto done; ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_ENTRY_CACHE_NOWAIT_PERCENTAGE, 50, &nctx->cache_refresh_percent); if (ret != EOK) goto done; if (nctx->cache_refresh_percent < 0 || nctx->cache_refresh_percent > 99) { DEBUG(SSSDBG_FATAL_FAILURE, "Configuration error: entry_cache_nowait_percentage is " "invalid. Disabling feature.\n"); nctx->cache_refresh_percent = 0; } ret = sss_ncache_prepopulate(nctx->ncache, cdb, nctx->rctx); if (ret != EOK) { goto done; } ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_PWFIELD, DEFAULT_PWFIELD, &nctx->pwfield); if (ret != EOK) goto done; ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_OVERRIDE_HOMEDIR, NULL, &nctx->override_homedir); if (ret != EOK) goto done; ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_FALLBACK_HOMEDIR, NULL, &nctx->fallback_homedir); if (ret != EOK) goto done; ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_OVERRIDE_SHELL, NULL, &nctx->override_shell); if (ret != EOK && ret != ENOENT) goto done; ret = confdb_get_string_as_list(cdb, nctx, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_ALLOWED_SHELL, &nctx->allowed_shells); if (ret != EOK && ret != ENOENT) goto done; ret = confdb_get_string_as_list(cdb, nctx, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_VETOED_SHELL, &nctx->vetoed_shells); if (ret != EOK && ret != ENOENT) goto done; ret = nss_get_etc_shells(nctx, &nctx->etc_shells); if (ret != EOK) goto done; ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_SHELL_FALLBACK, CONFDB_DEFAULT_SHELL_FALLBACK, &nctx->shell_fallback); if (ret != EOK) goto done; ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_DEFAULT_SHELL, NULL, &nctx->default_shell); if (ret != EOK) goto done; ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_HOMEDIR_SUBSTRING, CONFDB_DEFAULT_HOMEDIR_SUBSTRING, &nctx->homedir_substr); if (ret != EOK) goto done; ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY, CONFDB_IFP_USER_ATTR_LIST, NULL, &tmp_str); if (ret != EOK) goto done; if (tmp_str == NULL) { ret = confdb_get_string(cdb, nctx, CONFDB_IFP_CONF_ENTRY, CONFDB_IFP_USER_ATTR_LIST, NULL, &tmp_str); if (ret != EOK) goto done; } if (tmp_str != NULL) { nctx->extra_attributes = parse_attr_list_ex(nctx, tmp_str, NULL); if (nctx->extra_attributes == NULL) { ret = ENOMEM; goto done; } } ret = 0; done: return ret; } static int nss_update_memcache(struct sbus_request *dbus_req, void *data) { struct resp_ctx *rctx = talloc_get_type(data, struct resp_ctx); struct nss_ctx *nctx = talloc_get_type(rctx->pvt_ctx, struct nss_ctx); nss_update_pw_memcache(nctx); nss_update_gr_memcache(nctx); return EOK; } static int nss_memcache_initgr_check(struct sbus_request *dbus_req, void *data) { struct resp_ctx *rctx = talloc_get_type(data, struct resp_ctx); struct nss_ctx *nctx = talloc_get_type(rctx->pvt_ctx, struct nss_ctx); char *user; char *domain; uint32_t *groups; int gnum; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_STRING, &user, DBUS_TYPE_STRING, &domain, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &groups, &gnum, DBUS_TYPE_INVALID)) { return EOK; /* handled */ } DEBUG(SSSDBG_TRACE_LIBS, "Got request for [%s@%s]\n", user, domain); nss_update_initgr_memcache(nctx, user, domain, gnum, groups); return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } static struct data_provider_rev_iface nss_dp_methods = { { &data_provider_rev_iface_meta, 0 }, .updateCache = nss_update_memcache, .initgrCheck = nss_memcache_initgr_check }; static void nss_dp_reconnect_init(struct sbus_connection *conn, int status, void *pvt) { struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn); int ret; /* Did we reconnect successfully? */ if (status == SBUS_RECONNECT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Reconnected to the Data Provider.\n"); /* Identify ourselves to the data provider */ ret = dp_common_send_id(be_conn->conn, DATA_PROVIDER_VERSION, "NSS"); /* all fine */ if (ret == EOK) { handle_requests_after_reconnect(be_conn->rctx); return; } } /* Failed to reconnect */ DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n", be_conn->domain->name); /* FIXME: kill the frontend and let the monitor restart it ? */ /* nss_shutdown(rctx); */ } int nss_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb) { struct resp_ctx *rctx; struct sss_cmd_table *nss_cmds; struct be_conn *iter; struct nss_ctx *nctx; int memcache_timeout; int ret, max_retries; enum idmap_error_code err; int hret; int fd_limit; nss_cmds = get_nss_cmds(); ret = sss_process_init(mem_ctx, ev, cdb, nss_cmds, SSS_NSS_SOCKET_NAME, -1, NULL, -1, CONFDB_NSS_CONF_ENTRY, NSS_SBUS_SERVICE_NAME, NSS_SBUS_SERVICE_VERSION, &monitor_nss_methods, "NSS", &nss_dp_methods.vtable, &rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n"); return ret; } nctx = talloc_zero(rctx, struct nss_ctx); if (!nctx) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing nss_ctx\n"); ret = ENOMEM; goto fail; } ret = sss_ncache_init(rctx, &nctx->ncache); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing negative cache\n"); goto fail; } nctx->rctx = rctx; nctx->rctx->pvt_ctx = nctx; ret = nss_get_config(nctx, cdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error getting nss config\n"); goto fail; } /* Enable automatic reconnection to the Data Provider */ ret = confdb_get_int(nctx->rctx->cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_SERVICE_RECON_RETRIES, 3, &max_retries); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up automatic reconnection\n"); goto fail; } for (iter = nctx->rctx->be_conns; iter; iter = iter->next) { sbus_reconnect_init(iter->conn, max_retries, nss_dp_reconnect_init, iter); } err = sss_idmap_init(sss_idmap_talloc, nctx, sss_idmap_talloc_free, &nctx->idmap_ctx); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "sss_idmap_init failed.\n"); ret = EFAULT; goto fail; } /* Create the lookup table for netgroup results */ hret = sss_hash_create_ex(nctx, 10, &nctx->netgroups, 0, 0, 0, 0, netgroup_hash_delete_cb, NULL); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize netgroup hash table\n"); ret = EIO; goto fail; } /* create mmap caches */ /* Remove the CLEAR_MC_FLAG file if exists. */ ret = unlink(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG); if (ret != 0 && errno != ENOENT) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unlink file [%s]. This can cause memory cache to " "be purged when next log rotation is requested. %d: %s\n", SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG, ret, strerror(ret)); } ret = confdb_get_int(nctx->rctx->cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_MEMCACHE_TIMEOUT, 300, &memcache_timeout); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get 'memcache_timeout' option from confdb.\n"); goto fail; } /* TODO: read cache sizes from configuration */ ret = sss_mmap_cache_init(nctx, "passwd", SSS_MC_PASSWD, SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, &nctx->pwd_mc_ctx); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n"); } ret = sss_mmap_cache_init(nctx, "group", SSS_MC_GROUP, SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, &nctx->grp_mc_ctx); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n"); } ret = sss_mmap_cache_init(nctx, "initgroups", SSS_MC_INITGROUPS, SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, &nctx->initgr_mc_ctx); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "inigroups mmap cache is DISABLED\n"); } /* Set up file descriptor limits */ ret = confdb_get_int(nctx->rctx->cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_SERVICE_FD_LIMIT, DEFAULT_NSS_FD_LIMIT, &fd_limit); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up file descriptor limit\n"); goto fail; } responder_set_fd_limit(fd_limit); ret = schedule_get_domains_task(rctx, rctx->ev, rctx, nctx->ncache); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); goto fail; } ret = sss_ad_default_names_ctx(nctx, &nctx->global_names); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_ad_default_names_ctx failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "NSS Initialization complete\n"); return EOK; fail: talloc_free(rctx); return ret; } int main(int argc, const char *argv[]) { int opt; poptContext pc; struct main_context *main_ctx; int ret; uid_t uid; gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; umask(DFL_RSP_UMASK); pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_INIT(debug_level); /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_nss"; ret = server_setup("sssd[nss]", 0, uid, gid, CONFDB_NSS_CONF_ENTRY, &main_ctx); if (ret != EOK) return 2; ret = die_if_parent_died(); if (ret != EOK) { /* This is not fatal, don't return */ DEBUG(SSSDBG_OP_FAILURE, "Could not set up to exit when parent process does\n"); } ret = nss_process_init(main_ctx, main_ctx->event_ctx, main_ctx->confdb_ctx); if (ret != EOK) return 3; /* loop on main */ server_loop(main_ctx); return 0; } sssd-1.13.4/src/responder/nss/PaxHeaders.16287/nsssrv_cmd.c0000644000000000000000000000007412703456111020245 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.944794612 sssd-1.13.4/src/responder/nss/nsssrv_cmd.c0000644002412700241270000054426212703456111021731 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Responder Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "util/sss_nss.h" #include "util/sss_cli_cmd.h" #include "responder/nss/nsssrv.h" #include "responder/nss/nsssrv_private.h" #include "responder/nss/nsssrv_netgroup.h" #include "responder/nss/nsssrv_services.h" #include "responder/nss/nsssrv_mmap_cache.h" #include "responder/common/negcache.h" #include "providers/data_provider.h" #include "confdb/confdb.h" #include "db/sysdb.h" #include "sss_client/idmap/sss_nss_idmap.h" #include static int nss_cmd_send_error(struct nss_cmd_ctx *cmdctx, int err) { return sss_cmd_send_error(cmdctx->cctx, err); } static int nss_cmd_send_empty(struct nss_cmd_ctx *cmdctx) { struct cli_ctx *cctx = cmdctx->cctx; return sss_cmd_send_empty(cctx, cmdctx); } int nss_cmd_done(struct nss_cmd_ctx *cmdctx, int ret) { switch (ret) { case EOK: /* all fine, just return here */ break; case ENOENT: ret = nss_cmd_send_empty(cmdctx); if (ret) { return EFAULT; } break; case EAGAIN: /* async processing, just return here */ break; case EFAULT: /* very bad error */ return EFAULT; default: ret = nss_cmd_send_error(cmdctx, ret); if (ret) { return EFAULT; } sss_cmd_done(cmdctx->cctx, cmdctx); break; } return EOK; } /*************************** * Enumeration procedures * ***************************/ errno_t nss_setent_add_ref(TALLOC_CTX *memctx, struct getent_ctx *getent_ctx, struct tevent_req *req) { return setent_add_ref(memctx, getent_ctx, &getent_ctx->reqs, req); } void nss_setent_notify_error(struct getent_ctx *getent_ctx, errno_t ret) { return setent_notify(&getent_ctx->reqs, ret); } void nss_setent_notify_done(struct getent_ctx *getent_ctx) { return setent_notify_done(&getent_ctx->reqs); } struct setent_ctx { struct cli_ctx *client; struct nss_ctx *nctx; struct nss_dom_ctx *dctx; struct getent_ctx *getent_ctx; }; static int nss_reset_negcache(struct resp_ctx *rctx) { struct nss_ctx *nss_ctx; nss_ctx = talloc_get_type(rctx->pvt_ctx, struct nss_ctx); if (nss_ctx == NULL) { return EIO; } return sss_ncache_reset_repopulate_permanent(rctx, nss_ctx->ncache); } /**************************************************************************** * PASSWD db related functions ***************************************************************************/ void nss_update_pw_memcache(struct nss_ctx *nctx) { struct sss_domain_info *dom; struct ldb_result *res; uint64_t exp; struct sized_string key; const char *id; time_t now; int ret; int i; now = time(NULL); for (dom = nctx->rctx->domains; dom; dom = get_next_domain(dom, 0)) { ret = sysdb_enumpwent_with_views(nctx, dom, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to enumerate users for domain [%s]\n", dom->name); continue; } for (i = 0; i < res->count; i++) { exp = ldb_msg_find_attr_as_uint64(res->msgs[i], SYSDB_CACHE_EXPIRE, 0); if (exp >= now) { continue; } /* names require more manipulation (build up fqname conditionally), * but uidNumber is unique and always resolvable too, so we use * that to update the cache, as it points to the same entry */ id = sss_view_ldb_msg_find_attr_as_string(dom, res->msgs[i], SYSDB_UIDNUM, NULL); if (!id) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to find uidNumber in %s.\n", ldb_dn_get_linearized(res->msgs[i]->dn)); continue; } to_sized_string(&key, id); ret = sss_mmap_cache_pw_invalidate(nctx->pwd_mc_ctx, &key); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", ret, strerror(ret)); } ret = sss_mmap_cache_pw_invalidate(nctx->initgr_mc_ctx, &key); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", ret, strerror(ret)); } } talloc_zfree(res); } } static gid_t get_gid_override(struct ldb_message *msg, struct sss_domain_info *dom) { return dom->override_gid ? dom->override_gid : ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0); } static const char *get_homedir_override(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct nss_ctx *nctx, struct sss_domain_info *dom, struct sss_nss_homedir_ctx *homedir_ctx) { const char *homedir; const char *orig_name = homedir_ctx->username; errno_t ret; homedir = sss_view_ldb_msg_find_attr_as_string(dom, msg, SYSDB_HOMEDIR, NULL); homedir_ctx->original = homedir; /* Subdomain users store FQDN in their name attribute */ ret = sss_parse_name_const(mem_ctx, dom->names, orig_name, NULL, &homedir_ctx->username); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not parse [%s] into " "name-value components.\n", orig_name); return NULL; } /* Check to see which homedir_prefix to use. */ if (dom->homedir_substr != NULL) { homedir_ctx->config_homedir_substr = dom->homedir_substr; } else if (nctx->homedir_substr != NULL) { homedir_ctx->config_homedir_substr = nctx->homedir_substr; } /* Check whether we are unconditionally overriding the server * for home directory locations. */ if (dom->override_homedir) { return expand_homedir_template(mem_ctx, dom->override_homedir, homedir_ctx); } else if (nctx->override_homedir) { return expand_homedir_template(mem_ctx, nctx->override_homedir, homedir_ctx); } if (!homedir || *homedir == '\0') { /* In the case of a NULL or empty homedir, check to see if * we have a fallback homedir to use. */ if (dom->fallback_homedir) { return expand_homedir_template(mem_ctx, dom->fallback_homedir, homedir_ctx); } else if (nctx->fallback_homedir) { return expand_homedir_template(mem_ctx, nctx->fallback_homedir, homedir_ctx); } } /* Provider can also return template, try to expand it.*/ return expand_homedir_template(mem_ctx, homedir, homedir_ctx); } static const char *get_shell_override(TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct nss_ctx *nctx, struct sss_domain_info *dom) { const char *user_shell; int i; /* Check whether we are unconditionally overriding the server * for the login shell. */ if (dom->override_shell) { return dom->override_shell; } else if (nctx->override_shell) { return nctx->override_shell; } user_shell = sss_view_ldb_msg_find_attr_as_string(dom, msg, SYSDB_SHELL, NULL); if (!user_shell) { /* Check whether there is a default shell specified */ if (dom->default_shell) { return talloc_strdup(mem_ctx, dom->default_shell); } else if (nctx->default_shell) { return talloc_strdup(mem_ctx, nctx->default_shell); } return NULL; } if (!nctx->allowed_shells && !nctx->vetoed_shells) return talloc_strdup(mem_ctx, user_shell); if (nctx->vetoed_shells) { for (i=0; nctx->vetoed_shells[i]; i++) { if (strcmp(nctx->vetoed_shells[i], user_shell) == 0) { DEBUG(SSSDBG_FUNC_DATA, "The shell '%s' is vetoed. " "Using fallback\n", user_shell); return talloc_strdup(mem_ctx, nctx->shell_fallback); } } } if (nctx->etc_shells) { for (i=0; nctx->etc_shells[i]; i++) { if (strcmp(user_shell, nctx->etc_shells[i]) == 0) { DEBUG(SSSDBG_TRACE_ALL, "Shell %s found in /etc/shells\n", nctx->etc_shells[i]); break; } } if (nctx->etc_shells[i]) { DEBUG(SSSDBG_TRACE_ALL, "Using original shell '%s'\n", user_shell); return talloc_strdup(mem_ctx, user_shell); } } if (nctx->allowed_shells) { if (strcmp(nctx->allowed_shells[0], "*") == 0) { DEBUG(SSSDBG_FUNC_DATA, "The shell '%s' is allowed but does not exist. " "Using fallback\n", user_shell); return talloc_strdup(mem_ctx, nctx->shell_fallback); } else { for (i=0; nctx->allowed_shells[i]; i++) { if (strcmp(nctx->allowed_shells[i], user_shell) == 0) { DEBUG(SSSDBG_FUNC_DATA, "The shell '%s' is allowed but does not exist. " "Using fallback\n", user_shell); return talloc_strdup(mem_ctx, nctx->shell_fallback); } } } } DEBUG(SSSDBG_FUNC_DATA, "The shell '%s' is not allowed and does not exist.\n", user_shell); return talloc_strdup(mem_ctx, NOLOGIN_SHELL); } static int fill_pwent(struct sss_packet *packet, struct sss_domain_info *dom, struct nss_ctx *nctx, bool filter_users, bool pw_mmap_cache, struct ldb_message **msgs, int *count) { struct ldb_message *msg; uint8_t *body; const char *upn; const char *tmpstr; const char *orig_name; struct sized_string name; struct sized_string gecos; struct sized_string homedir; struct sized_string shell; struct sized_string pwfield; struct sized_string fullname; uint32_t uid; uint32_t gid; size_t rsize, rp, blen; int fq_len = 0; int i, ret, num; bool add_domain = (!IS_SUBDOMAIN(dom) && dom->fqnames); const char *domain = dom->name; bool packet_initialized = false; int ncret; TALLOC_CTX *tmp_ctx = NULL; struct sss_nss_homedir_ctx homedir_ctx; to_sized_string(&pwfield, nctx->pwfield); rp = 2*sizeof(uint32_t); num = 0; for (i = 0; i < *count; i++) { talloc_zfree(tmp_ctx); tmp_ctx = talloc_new(NULL); msg = msgs[i]; upn = ldb_msg_find_attr_as_string(msg, SYSDB_UPN, NULL); if (DOM_HAS_VIEWS(dom)) { orig_name = ldb_msg_find_attr_as_string(msg, OVERRIDE_PREFIX SYSDB_NAME, NULL); if (orig_name != NULL && IS_SUBDOMAIN(dom)) { /* Override names are not fully qualified */ add_domain = true; } gid = ldb_msg_find_attr_as_uint64(msg, OVERRIDE_PREFIX SYSDB_GIDNUM, 0); } else { orig_name = NULL; gid = 0; } if (orig_name == NULL) { orig_name = ldb_msg_find_attr_as_string(msg, SYSDB_DEFAULT_OVERRIDE_NAME, NULL); if (orig_name == NULL) { orig_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); } } uid = sss_view_ldb_msg_find_attr_as_uint64(dom, msg, SYSDB_UIDNUM, 0); if (gid == 0) { gid = get_gid_override(msg, dom); } if (!orig_name || !uid || !gid) { DEBUG(SSSDBG_OP_FAILURE, "Incomplete user object for %s[%llu]! Skipping\n", orig_name?orig_name:"", (unsigned long long int)uid); continue; } if (filter_users) { ncret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout, dom, orig_name); if (ncret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "User [%s@%s] filtered out! (negative cache)\n", orig_name, domain); continue; } } if (!packet_initialized) { /* first 2 fields (len and reserved), filled up later */ ret = sss_packet_grow(packet, 2*sizeof(uint32_t)); if (ret != EOK) return ret; packet_initialized = true; } tmpstr = sss_get_cased_name(tmp_ctx, orig_name, dom->case_preserve); if (tmpstr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_get_cased_name failed, skipping\n"); continue; } tmpstr = sss_replace_space(tmp_ctx, tmpstr, nctx->rctx->override_space); if (tmpstr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_replace_space failed, skipping\n"); continue; } to_sized_string(&name, tmpstr); tmpstr = sss_view_ldb_msg_find_attr_as_string(dom, msg, SYSDB_GECOS, NULL); if (!tmpstr) { to_sized_string(&gecos, ""); } else { to_sized_string(&gecos, tmpstr); } ZERO_STRUCT(homedir_ctx); homedir_ctx.username = name.str; homedir_ctx.uid = uid; homedir_ctx.domain = dom->name; homedir_ctx.upn = upn; tmpstr = get_homedir_override(tmp_ctx, msg, nctx, dom, &homedir_ctx); if (!tmpstr) { to_sized_string(&homedir, "/"); } else { to_sized_string(&homedir, tmpstr); } tmpstr = get_shell_override(tmp_ctx, msg, nctx, dom); if (!tmpstr) { to_sized_string(&shell, ""); } else { to_sized_string(&shell, tmpstr); } rsize = 2 * sizeof(uint32_t) + name.len + gecos.len + homedir.len + shell.len + pwfield.len; if (add_domain) { fq_len = sss_fqname(NULL, 0, dom->names, dom, name.str); if (fq_len >= 0) { fq_len += 1; rsize -= name.len; rsize += fq_len; } else { fq_len = 0; } } ret = sss_packet_grow(packet, rsize); if (ret != EOK) { num = 0; goto done; } sss_packet_get_body(packet, &body, &blen); SAFEALIGN_SET_UINT32(&body[rp], uid, &rp); SAFEALIGN_SET_UINT32(&body[rp], gid, &rp); if (add_domain) { ret = sss_fqname((char *) &body[rp], fq_len, dom->names, dom, name.str); if (ret < 0 || ret != fq_len - 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate a fully qualified name for user " "[%s] in [%s]! Skipping user.\n", name.str, domain); continue; } } else { memcpy(&body[rp], name.str, name.len); } to_sized_string(&fullname, (const char *)&body[rp]); rp += fullname.len; memcpy(&body[rp], pwfield.str, pwfield.len); rp += pwfield.len; memcpy(&body[rp], gecos.str, gecos.len); rp += gecos.len; memcpy(&body[rp], homedir.str, homedir.len); rp += homedir.len; memcpy(&body[rp], shell.str, shell.len); rp += shell.len; num++; if (pw_mmap_cache && nctx->pwd_mc_ctx) { ret = sss_mmap_cache_pw_store(&nctx->pwd_mc_ctx, &fullname, &pwfield, uid, gid, &gecos, &homedir, &shell); if (ret != EOK && ret != ENOMEM) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store user %s(%s) in mmap cache!\n", name.str, domain); } } } talloc_zfree(tmp_ctx); done: *count = i; /* if there are no results just return ENOENT, * let the caller decide if this is the last packet or not */ if (!packet_initialized) return ENOENT; sss_packet_get_body(packet, &body, &blen); SAFEALIGN_COPY_UINT32(body, &num, NULL); /* num results */ SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL); /* reserved */ return EOK; } static int nss_cmd_getpw_send_reply(struct nss_dom_ctx *dctx, bool filter) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct cli_ctx *cctx = cmdctx->cctx; struct nss_ctx *nctx; int ret; int i; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return EFAULT; } i = dctx->res->count; ret = fill_pwent(cctx->creq->out, dctx->domain, nctx, filter, true, dctx->res->msgs, &i); if (ret) { return ret; } sss_packet_set_error(cctx->creq->out, EOK); sss_cmd_done(cctx, cmdctx); return EOK; } static bool is_refreshed_on_bg(enum sss_dp_acct_type req_type, uint32_t refresh_expired_interval) { if (refresh_expired_interval == 0) { return false; } switch (req_type) { case SSS_DP_NETGR: case SSS_DP_USER: case SSS_DP_GROUP: return true; default: return false; } return false; } static void nsssrv_dp_send_acct_req_done(struct tevent_req *req); static void get_dp_name_and_id(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, enum sss_dp_acct_type req_type, const char *opt_name, uint32_t opt_id, const char **_name, uint32_t *_id) { TALLOC_CTX *tmp_ctx; struct ldb_result *res = NULL; const char *attr; const char *name; uint32_t id; errno_t ret; /* First set the same values to make things easier. */ *_name = opt_name; *_id = opt_id; if (!DOM_HAS_VIEWS(dom) || !is_local_view(dom->view_name)) { DEBUG(SSSDBG_TRACE_FUNC, "Not a LOCAL view, continuing with " "provided values.\n"); return; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return; } if (opt_name != NULL) { switch (req_type) { case SSS_DP_USER: case SSS_DP_INITGROUPS: ret = sysdb_getpwnam_with_views(tmp_ctx, dom, opt_name, &res); if (ret != EOK) { DEBUG(SSSDBG_CONF_SETTINGS, "sysdb_getpwnam_with_views() failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } break; case SSS_DP_GROUP: ret = sysdb_getgrnam_with_views(tmp_ctx, dom, opt_name, &res); if (ret != EOK) { DEBUG(SSSDBG_CONF_SETTINGS, "sysdb_getgrnam_with_views() failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } break; default: goto done; } if (res == NULL || res->count != 1) { /* This should not happen with LOCAL view and overridden value. */ DEBUG(SSSDBG_TRACE_FUNC, "Entry is missing?! Continuing with " "provided values.\n"); goto done; } name = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL\n"); goto done; } *_name = talloc_steal(mem_ctx, name); } else if (opt_id != 0) { switch (req_type) { case SSS_DP_USER: ret = sysdb_getpwuid_with_views(tmp_ctx, dom, opt_id, &res); if (ret != EOK) { DEBUG(SSSDBG_CONF_SETTINGS, "sysdb_getpwuid_with_views() failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } attr = SYSDB_UIDNUM; break; case SSS_DP_GROUP: ret = sysdb_getgrgid_with_views(tmp_ctx, dom, opt_id, &res); if (ret != EOK) { DEBUG(SSSDBG_CONF_SETTINGS, "sysdb_getgrgid_with_views() failed [%d]: %s\n", ret, sss_strerror(ret)); goto done; } attr = SYSDB_GIDNUM; break; default: goto done; } if (res == NULL || res->count != 1) { /* This should not happen with LOCAL view and overridden value. */ DEBUG(SSSDBG_TRACE_FUNC, "Entry is missing?! Continuing with " "provided values.\n"); goto done; } id = ldb_msg_find_attr_as_uint64(res->msgs[0], attr, 0); if (id == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0\n"); goto done; } *_id = id; } done: talloc_free(tmp_ctx); } /* FIXME: do not check res->count, but get in a msgs and check in parent */ errno_t check_cache(struct nss_dom_ctx *dctx, struct nss_ctx *nctx, struct ldb_result *res, enum sss_dp_acct_type req_type, const char *opt_name, uint32_t opt_id, const char *extra, sss_dp_callback_t callback, void *pvt) { errno_t ret; struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct cli_ctx *cctx = cmdctx->cctx; struct tevent_req *req = NULL; struct dp_callback_ctx *cb_ctx = NULL; uint64_t cacheExpire = 0; const char *name = opt_name; uint32_t id = opt_id; /* when searching for a user or netgroup, more than one reply is a * db error */ if ((req_type == SSS_DP_USER || req_type == SSS_DP_NETGR) && (res->count > 1)) { DEBUG(SSSDBG_CRIT_FAILURE, "getpwXXX call returned more than one result! DB Corrupted?\n"); return ENOENT; } /* In case of local view we have to always contant DP with the original * name or id. */ get_dp_name_and_id(dctx->cmdctx, dctx->domain, req_type, opt_name, opt_id, &name, &id); /* if we have any reply let's check cache validity */ if (res->count > 0) { bool refreshed_on_bg; uint32_t bg_refresh_interval = dctx->domain->refresh_expired_interval; if (req_type == SSS_DP_INITGROUPS) { cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_INITGR_EXPIRE, 0); } else { cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_CACHE_EXPIRE, 0); } /* Check if background refresh is enabled for this entry */ refreshed_on_bg = is_refreshed_on_bg(req_type, bg_refresh_interval); /* if we have any reply let's check cache validity */ ret = sss_cmd_check_cache(res->msgs[0], nctx->cache_refresh_percent, cacheExpire); if (ret == EOK || (ret == EAGAIN && refreshed_on_bg)) { DEBUG(SSSDBG_TRACE_FUNC, "Cached entry is valid, returning..\n"); return EOK; } else if (ret != EAGAIN && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Error checking cache: %d\n", ret); goto error; } } else { /* No replies */ ret = ENOENT; } /* EAGAIN (off band) or ENOENT (cache miss) -> check cache */ if (ret == EAGAIN) { /* No callback required * This was an out-of-band update. We'll return EOK * so the calling function can return the cached entry * immediately. */ DEBUG(SSSDBG_TRACE_FUNC, "Performing midpoint cache update on [%s]\n", name); req = sss_dp_get_account_send(cctx, cctx->rctx, dctx->domain, true, req_type, name, id, extra); if (!req) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band data provider " "request\n"); /* This is non-fatal, so we'll continue here */ } else { DEBUG(SSSDBG_TRACE_FUNC, "Updating cache out-of-band\n"); } /* We don't need to listen for a reply, so we will free the * request here. */ talloc_zfree(req); } else { /* This is a cache miss. Or the cache is expired. * We need to get the updated user information before returning it. */ /* dont loop forever :-) */ dctx->check_provider = false; /* keep around current data in case backend is offline */ if (res->count) { dctx->res = talloc_steal(dctx, res); } req = sss_dp_get_account_send(cctx, cctx->rctx, dctx->domain, true, req_type, name, id, extra); if (!req) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending data provider request\n"); ret = ENOMEM; goto error; } cb_ctx = talloc_zero(dctx, struct dp_callback_ctx); if(!cb_ctx) { talloc_zfree(req); ret = ENOMEM; goto error; } cb_ctx->callback = callback; cb_ctx->ptr = pvt; cb_ctx->cctx = dctx->cmdctx->cctx; cb_ctx->mem_ctx = dctx; tevent_req_set_callback(req, nsssrv_dp_send_acct_req_done, cb_ctx); return EAGAIN; } return EOK; error: ret = nss_cmd_send_error(cmdctx, ret); if (ret != EOK) { NSS_CMD_FATAL_ERROR_CODE(cctx, ret); } sss_cmd_done(cctx, cmdctx); return EOK; } static void nsssrv_dp_send_acct_req_done(struct tevent_req *req) { struct dp_callback_ctx *cb_ctx = tevent_req_callback_data(req, struct dp_callback_ctx); errno_t ret; dbus_uint16_t err_maj; dbus_uint32_t err_min; char *err_msg; ret = sss_dp_get_account_recv(cb_ctx->mem_ctx, req, &err_maj, &err_min, &err_msg); talloc_zfree(req); if (ret != EOK) { NSS_CMD_FATAL_ERROR(cb_ctx->cctx); } cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr); } static int delete_entry_from_memcache(struct sss_domain_info *dom, char *name, struct sss_mc_ctx *mc_ctx, enum sss_mc_type type) { TALLOC_CTX *tmp_ctx = NULL; struct sized_string delete_name; char *fqdn = NULL; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n"); return ENOMEM; } if (dom->fqnames) { fqdn = sss_tc_fqname(tmp_ctx, dom->names, dom, name); if (fqdn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory.\n"); ret = ENOMEM; goto done; } to_sized_string(&delete_name, fqdn); } else { to_sized_string(&delete_name, name); } switch (type) { case SSS_MC_PASSWD: ret = sss_mmap_cache_pw_invalidate(mc_ctx, &delete_name); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", ret, strerror(ret)); goto done; } break; case SSS_MC_GROUP: ret = sss_mmap_cache_gr_invalidate(mc_ctx, &delete_name); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", ret, strerror(ret)); goto done; } break; case SSS_MC_INITGROUPS: ret = sss_mmap_cache_initgr_invalidate(mc_ctx, &delete_name); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", ret, strerror(ret)); goto done; } break; default: ret = EINVAL; goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static void nss_cmd_getby_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); /* search for a user. * Returns: * ENOENT, if user is definitely not found * EAGAIN, if user is being fetched from backend via async operations * EOK, if found * anything else on a fatal error */ static int nss_cmd_getpwnam_search(struct nss_dom_ctx *dctx) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct sss_domain_info *dom = dctx->domain; struct cli_ctx *cctx = cmdctx->cctx; char *name = NULL; struct nss_ctx *nctx; int ret; static const char *user_attrs[] = SYSDB_PW_ATTRS; struct ldb_message *msg; const char *extra_flag = NULL; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); while (dom) { /* if it is a domainless search, skip domains that require fully * qualified names instead */ while (dom && cmdctx->check_next && dom->fqnames && !cmdctx->name_is_upn) { dom = get_next_domain(dom, 0); } if (!dom) break; if (dom != dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); } /* make sure to update the dctx if we changed domain */ dctx->domain = dom; talloc_free(name); name = sss_get_cased_name(cmdctx, cmdctx->name, dom->case_sensitive); if (!name) return ENOMEM; name = sss_reverse_replace_space(dctx, name, nctx->rctx->override_space); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_reverse_replace_space failed\n"); return ENOMEM; } /* verify this user has not yet been negatively cached, * or has been permanently filtered */ ret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout, dom, name); /* if neg cached, return we didn't find it */ if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "User [%s] does not exist in [%s]! (negative cache)\n", name, dom->name); /* if a multidomain search, try with next */ if (cmdctx->check_next) { if (cmdctx->name_is_upn) { dom = get_next_domain(dom, SSS_GND_DESCEND); } else { dom = get_next_domain(dom, 0); } continue; } /* There are no further domains or this was a * fully-qualified user request. */ return ENOENT; } DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%s@%s]\n", name, dom->name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); return EIO; } if (cmdctx->name_is_upn) { ret = sysdb_search_user_by_upn(cmdctx, dom, name, user_attrs, &msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn failed.\n"); return ret; } dctx->res = talloc_zero(cmdctx, struct ldb_result); if (dctx->res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } if (ret == ENOENT) { dctx->res->count = 0; dctx->res->msgs = NULL; ret = EOK; } else { dctx->res->count = 1; dctx->res->msgs = talloc_array(dctx->res, struct ldb_message *, 1); if (dctx->res->msgs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); return ENOMEM; } dctx->res->msgs[0] = talloc_steal(dctx->res->msgs, msg); } } else { ret = sysdb_getpwnam_with_views(cmdctx, dom, name, &dctx->res); } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); return EIO; } if (dctx->res->count > 1) { DEBUG(SSSDBG_FATAL_FAILURE, "getpwnam call returned more than one result !?!\n"); sss_log(SSS_LOG_ERR, "More users have the same name [%s@%s] in SSSD cache. " "SSSD will not work correctly.\n", name, dom->name); return ENOENT; } if (dctx->res->count == 0 && !dctx->check_provider) { /* set negative cache only if not result of cache check */ ret = sss_ncache_set_user(nctx->ncache, false, dom, name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s@%s\n", name, dom->name); } /* if a multidomain search, try with next */ if (cmdctx->check_next) { if (cmdctx->name_is_upn) { dom = get_next_domain(dom, SSS_GND_DESCEND); } else { dom = get_next_domain(dom, 0); } if (dom) continue; } DEBUG(SSSDBG_OP_FAILURE, "No results for getpwnam call\n"); /* User not found in ldb -> delete user from memory cache. */ ret = delete_entry_from_memcache(dctx->domain, name, nctx->pwd_mc_ctx, SSS_MC_PASSWD); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Deleting user from memcache failed.\n"); } ret = delete_entry_from_memcache(dctx->domain, name, nctx->initgr_mc_ctx, SSS_MC_INITGROUPS); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Deleting user from memcache failed.\n"); } return ENOENT; } /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (dctx->check_provider) { if (cmdctx->name_is_upn) { extra_flag = EXTRA_NAME_IS_UPN; } else if (DOM_HAS_VIEWS(dom) && (dctx->res->count == 0 || ldb_msg_find_attr_as_string(dctx->res->msgs[0], OVERRIDE_PREFIX SYSDB_NAME, NULL) != NULL)) { extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; } else { extra_flag = NULL; } ret = check_cache(dctx, nctx, dctx->res, SSS_DP_USER, name, 0, extra_flag, nss_cmd_getby_dp_callback, dctx); if (ret != EOK) { /* Anything but EOK means we should reenter the mainloop * because we may be refreshing the cache */ return ret; } } /* One result found */ DEBUG(SSSDBG_TRACE_FUNC, "Returning info for user [%s@%s]\n", name, dom->name); return EOK; } DEBUG(SSSDBG_MINOR_FAILURE, "No matching domain found for [%s], fail!\n", cmdctx->name); return ENOENT; } static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx); static int nss_cmd_getgr_send_reply(struct nss_dom_ctx *dctx, bool filter); static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx); static int nss_cmd_initgr_send_reply(struct nss_dom_ctx *dctx); static int nss_cmd_getpwuid_search(struct nss_dom_ctx *dctx); static int nss_cmd_getgrgid_search(struct nss_dom_ctx *dctx); static errno_t nss_cmd_getbysid_search(struct nss_dom_ctx *dctx); static errno_t nss_cmd_getbysid_send_reply(struct nss_dom_ctx *dctx); static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx); static int nss_cmd_assume_upn(struct nss_dom_ctx *dctx) { int ret; if (dctx->domain == NULL) { dctx->domain = dctx->cmdctx->cctx->rctx->domains; dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); dctx->cmdctx->check_next = true; dctx->cmdctx->name = talloc_strdup(dctx->cmdctx, dctx->rawname); dctx->cmdctx->name_is_upn = true; if (dctx->cmdctx->name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); return ENOMEM; } } switch (dctx->cmdctx->cmd) { case SSS_NSS_GETPWNAM: ret = nss_cmd_getpwnam_search(dctx); if (ret == EOK) { ret = nss_cmd_getpw_send_reply(dctx, false); } break; case SSS_NSS_INITGR: ret = nss_cmd_initgroups_search(dctx); if (ret == EOK) { ret = nss_cmd_initgr_send_reply(dctx); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command [%d][%s].\n", dctx->cmdctx->cmd, sss_cmd2str(dctx->cmdctx->cmd)); ret = EINVAL; } return ret; } static void nss_cmd_getby_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr) { struct nss_dom_ctx *dctx = talloc_get_type(ptr, struct nss_dom_ctx); struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct cli_ctx *cctx = cmdctx->cctx; int ret; uint32_t gnd_flags; struct nss_ctx *nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); if (err_maj) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get information from Data Provider\n" "Error: %u, %u, %s\n" "Will try to return what we have in cache\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg); if ((dctx->res && dctx->res->count == 1) || (dctx->cmdctx->cmd == SSS_NSS_INITGR && dctx->res && dctx->res->count != 0)) { switch (dctx->cmdctx->cmd) { case SSS_NSS_GETPWNAM: ret = nss_cmd_getpw_send_reply(dctx, false); break; case SSS_NSS_GETGRNAM: ret = nss_cmd_getgr_send_reply(dctx, false); break; case SSS_NSS_INITGR: ret = nss_cmd_initgr_send_reply(dctx); break; case SSS_NSS_GETPWUID: ret = nss_cmd_getpw_send_reply(dctx, true); break; case SSS_NSS_GETGRGID: ret = nss_cmd_getgr_send_reply(dctx, true); break; case SSS_NSS_GETNAMEBYSID: case SSS_NSS_GETIDBYSID: case SSS_NSS_GETSIDBYNAME: case SSS_NSS_GETORIGBYNAME: case SSS_NSS_GETSIDBYID: ret = nss_cmd_getbysid_send_reply(dctx); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command [%d][%s].\n", dctx->cmdctx->cmd, sss_cmd2str(dctx->cmdctx->cmd)); ret = EINVAL; } goto done; } /* Since subdomain users and groups are fully qualified they are * typically not subject of multi-domain searches. But since POSIX * ID do not contain a domain name we have to descend to subdomains * here. */ switch (dctx->cmdctx->cmd) { case SSS_NSS_GETPWUID: ret = sss_ncache_set_uid(nctx->ncache, false, dctx->domain, cmdctx->id); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negative cache for UID %"PRIu32"\n", cmdctx->id); } gnd_flags = SSS_GND_DESCEND; break; case SSS_NSS_GETGRGID: ret = sss_ncache_set_gid(nctx->ncache, false, dctx->domain, cmdctx->id); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negative cache for GID %"PRIu32"\n", cmdctx->id); } gnd_flags = SSS_GND_DESCEND; break; case SSS_NSS_GETSIDBYID: ret = sss_ncache_set_uid(nctx->ncache, false, dctx->domain, cmdctx->id); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negative cache for UID %"PRIu32"\n", cmdctx->id); } ret = sss_ncache_set_gid(nctx->ncache, false, dctx->domain, cmdctx->id); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negative cache for GID %"PRIu32"\n", cmdctx->id); } gnd_flags = SSS_GND_DESCEND; break; default: /* Do not descend to subdomains */ gnd_flags = 0; } /* no previous results, just loop to next domain if possible */ if (cmdctx->check_next && get_next_domain(dctx->domain, gnd_flags)) { dctx->domain = get_next_domain(dctx->domain, gnd_flags); dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); } else { /* nothing available */ ret = ENOENT; goto done; } } /* ok the backend returned, search to see if we have updated results */ switch (dctx->cmdctx->cmd) { case SSS_NSS_GETPWNAM: ret = nss_cmd_getpwnam_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getpw_send_reply(dctx, false); } break; case SSS_NSS_GETGRNAM: ret = nss_cmd_getgrnam_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getgr_send_reply(dctx, false); } break; case SSS_NSS_INITGR: ret = nss_cmd_initgroups_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_initgr_send_reply(dctx); } break; case SSS_NSS_GETPWUID: ret = nss_cmd_getpwuid_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getpw_send_reply(dctx, true); } break; case SSS_NSS_GETGRGID: ret = nss_cmd_getgrgid_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getgr_send_reply(dctx, true); } break; case SSS_NSS_GETNAMEBYSID: case SSS_NSS_GETIDBYSID: ret = nss_cmd_getbysid_search(dctx); if (ret == EOK) { ret = nss_cmd_getbysid_send_reply(dctx); } break; case SSS_NSS_GETSIDBYNAME: case SSS_NSS_GETORIGBYNAME: ret = nss_cmd_getsidby_search(dctx); if (ret == EOK) { ret = nss_cmd_getbysid_send_reply(dctx); } break; case SSS_NSS_GETSIDBYID: ret = nss_cmd_getsidby_search(dctx); if (ret == EOK) { ret = nss_cmd_getbysid_send_reply(dctx); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command [%d][%s].\n", dctx->cmdctx->cmd, sss_cmd2str(dctx->cmdctx->cmd)); ret = EINVAL; } done: if (ret == ENOENT && (dctx->cmdctx->cmd == SSS_NSS_GETPWNAM || dctx->cmdctx->cmd == SSS_NSS_INITGR) && dctx->rawname != NULL && strchr(dctx->rawname, '@') != NULL) { /* assume Kerberos principal */ ret = nss_cmd_assume_upn(dctx); } ret = nss_cmd_done(cmdctx, ret); if (ret) { NSS_CMD_FATAL_ERROR(cctx); } } static int nss_check_name_of_well_known_sid(struct nss_cmd_ctx *cmdctx, const char *full_name) { char *wk_name = NULL; char *wk_dom_name = NULL; const char *wk_sid; int ret; struct sized_string sid; uint8_t *body; size_t blen; struct cli_ctx *cctx; struct nss_ctx *nss_ctx; size_t pctr = 0; nss_ctx = talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct nss_ctx); ret = sss_parse_name(cmdctx, nss_ctx->global_names, full_name, &wk_dom_name, &wk_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_parse_name failed.\n"); return ret; } if (wk_dom_name == NULL || wk_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Unable to split [%s] in name and domain part. " \ "Skipping check for well-known name.\n", full_name); return ENOENT; } ret = name_to_well_known_sid(wk_dom_name, wk_name, &wk_sid); talloc_free(wk_dom_name); talloc_free(wk_name); if (ret != EOK) { DEBUG(SSSDBG_TRACE_ALL, "Name [%s] is not the name of a " \ "Well-Known SID.\n", full_name); return ret; } to_sized_string(&sid, wk_sid); cctx = cmdctx->cctx; ret = sss_packet_new(cctx->creq, sid.len + 3 * sizeof(uint32_t), sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return ENOMEM; } sss_packet_get_body(cctx->creq->out, &body, &blen); SAFEALIGN_SETMEM_UINT32(body, 1, &pctr); /* num results */ SAFEALIGN_SETMEM_UINT32(body + pctr, 0, &pctr); /* reserved */ SAFEALIGN_SETMEM_UINT32(body + pctr, SSS_ID_TYPE_GID, &pctr); memcpy(&body[pctr], sid.str, sid.len); sss_packet_set_error(cctx->creq->out, EOK); sss_cmd_done(cctx, cmdctx); return EOK; } static int nss_cmd_getbynam(enum sss_cli_command cmd, struct cli_ctx *cctx); static void nss_cmd_getbynam_done(struct tevent_req *req); static int nss_cmd_getpwnam(struct cli_ctx *cctx) { return nss_cmd_getbynam(SSS_NSS_GETPWNAM, cctx); } static int nss_cmd_getbynam(enum sss_cli_command cmd, struct cli_ctx *cctx) { struct tevent_req *req; struct nss_cmd_ctx *cmdctx; struct nss_dom_ctx *dctx; const char *rawname; char *domname; uint8_t *body; size_t blen; int ret; switch(cmd) { case SSS_NSS_GETPWNAM: case SSS_NSS_GETGRNAM: case SSS_NSS_INITGR: case SSS_NSS_GETSIDBYNAME: case SSS_NSS_GETORIGBYNAME: break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command type [%d][%s].\n", cmd, sss_cmd2str(cmd)); return EINVAL; } cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = cctx; cmdctx->cmd = cmd; dctx = talloc_zero(cmdctx, struct nss_dom_ctx); if (!dctx) { ret = ENOMEM; goto done; } dctx->cmdctx = cmdctx; /* get user name to query */ sss_packet_get_body(cctx->creq->in, &body, &blen); /* if not terminated fail */ if (body[blen -1] != '\0') { ret = EINVAL; goto done; } /* If the body isn't valid UTF-8, fail */ if (!sss_utf8_check(body, blen -1)) { ret = EINVAL; goto done; } rawname = (const char *)body; dctx->mc_name = rawname; DEBUG(SSSDBG_TRACE_FUNC, "Running command [%d][%s] with input [%s].\n", cmd, sss_cmd2str(dctx->cmdctx->cmd), rawname); if (dctx->cmdctx->cmd == SSS_NSS_GETSIDBYNAME) { ret = nss_check_name_of_well_known_sid(cmdctx, rawname); if (ret != ENOENT) { if (ret == EOK) { DEBUG(SSSDBG_TRACE_ALL, "Name [%s] is the name of a " \ "Well-Known SID.\n", rawname); } else { DEBUG(SSSDBG_OP_FAILURE, "nss_check_name_of_well_known_sid failed.\n"); } goto done; } } /* We need to attach to subdomain request, if the first one is not * finished yet. We may not be able to lookup object in AD otherwise. */ if (cctx->rctx->get_domains_last_call.tv_sec == 0) { req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, NULL); if (req == NULL) { ret = ENOMEM; } else { dctx->rawname = rawname; tevent_req_set_callback(req, nss_cmd_getbynam_done, dctx); ret = EAGAIN; } goto done; } domname = NULL; ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, cctx->rctx->default_domain, rawname, &domname, &cmdctx->name); if (ret == EAGAIN) { req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, domname); if (req == NULL) { ret = ENOMEM; } else { dctx->rawname = rawname; tevent_req_set_callback(req, nss_cmd_getbynam_done, dctx); ret = EAGAIN; } goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Invalid name received [%s]\n", rawname); ret = ENOENT; goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%s] from [%s]\n", cmdctx->name, domname?domname:""); if (domname) { dctx->domain = responder_get_domain(cctx->rctx, domname); if (!dctx->domain) { ret = ENOENT; goto done; } } else { /* this is a multidomain search */ dctx->rawname = rawname; dctx->domain = cctx->rctx->domains; cmdctx->check_next = true; if (cctx->rctx->get_domains_last_call.tv_sec == 0) { req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, false, NULL); if (req == NULL) { ret = ENOMEM; } else { tevent_req_set_callback(req, nss_cmd_getbynam_done, dctx); ret = EAGAIN; } goto done; } } dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); /* ok, find it ! */ switch (dctx->cmdctx->cmd) { case SSS_NSS_GETPWNAM: ret = nss_cmd_getpwnam_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getpw_send_reply(dctx, false); } else if (ret == ENOENT && dctx->rawname != NULL && strchr(dctx->rawname, '@') != NULL) { /* assume Kerberos principal */ ret = nss_cmd_assume_upn(dctx); } break; case SSS_NSS_GETGRNAM: ret = nss_cmd_getgrnam_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getgr_send_reply(dctx, false); } break; case SSS_NSS_INITGR: ret = nss_cmd_initgroups_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_initgr_send_reply(dctx); } else if (ret == ENOENT && dctx->rawname != NULL && strchr(dctx->rawname, '@') != NULL) { /* assume Kerberos principal */ ret = nss_cmd_assume_upn(dctx); } break; case SSS_NSS_GETSIDBYNAME: case SSS_NSS_GETORIGBYNAME: ret = nss_cmd_getsidby_search(dctx); if (ret == EOK) { ret = nss_cmd_getbysid_send_reply(dctx); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command [%d][%s].\n", dctx->cmdctx->cmd, sss_cmd2str(dctx->cmdctx->cmd)); ret = EINVAL; } done: return nss_cmd_done(cmdctx, ret); } static void nss_cmd_getbynam_done(struct tevent_req *req) { struct nss_dom_ctx *dctx = tevent_req_callback_data(req, struct nss_dom_ctx); struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct cli_ctx *cctx = cmdctx->cctx; char *domname = NULL; const char *rawname = dctx->rawname; errno_t ret; ret = sss_dp_get_domains_recv(req); talloc_free(req); if (ret != EOK) { goto done; } ret = sss_parse_name_for_domains(cmdctx, cctx->rctx->domains, cctx->rctx->default_domain, rawname, &domname, &cmdctx->name); if (ret == EAGAIN && (dctx->cmdctx->cmd == SSS_NSS_GETPWNAM || dctx->cmdctx->cmd == SSS_NSS_INITGR)) { /* assume Kerberos principal */ ret = nss_cmd_assume_upn(dctx); goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Invalid name received [%s]\n", rawname); ret = ENOENT; goto done; } ret = nss_reset_negcache(cctx->rctx); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot reset negcache records\n"); /* Not fatal */ } DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for [%s] from [%s]\n", cmdctx->name, domname?domname:""); if (domname) { dctx->domain = responder_get_domain(cctx->rctx, domname); if (dctx->domain == NULL) { ret = ENOENT; goto done; } } else { /* this is a multidomain search */ dctx->domain = cctx->rctx->domains; cmdctx->check_next = true; } dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); /* ok, find it ! */ switch (dctx->cmdctx->cmd) { case SSS_NSS_GETPWNAM: ret = nss_cmd_getpwnam_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getpw_send_reply(dctx, false); } else if (ret == ENOENT && dctx->rawname != NULL && strchr(dctx->rawname, '@') != NULL) { /* assume Kerberos principal */ ret = nss_cmd_assume_upn(dctx); } break; case SSS_NSS_GETGRNAM: ret = nss_cmd_getgrnam_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getgr_send_reply(dctx, false); } break; case SSS_NSS_INITGR: ret = nss_cmd_initgroups_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_initgr_send_reply(dctx); } else if (ret == ENOENT && dctx->rawname != NULL && strchr(dctx->rawname, '@') != NULL) { /* assume Kerberos principal */ ret = nss_cmd_assume_upn(dctx); } break; case SSS_NSS_GETSIDBYNAME: case SSS_NSS_GETORIGBYNAME: ret = nss_cmd_getsidby_search(dctx); if (ret == EOK) { ret = nss_cmd_getbysid_send_reply(dctx); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command [%d][%s].\n", dctx->cmdctx->cmd, sss_cmd2str(dctx->cmdctx->cmd)); ret = EINVAL; } done: nss_cmd_done(cmdctx, ret); } /* search for a uid. * Returns: * ENOENT, if uid is definitely not found * EAGAIN, if uid is being fetched from backend via async operations * EOK, if found * anything else on a fatal error */ static int nss_cmd_getpwuid_search(struct nss_dom_ctx *dctx) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct sss_domain_info *dom = dctx->domain; struct cli_ctx *cctx = cmdctx->cctx; struct nss_ctx *nctx; int ret; int err; const char *extra_flag = NULL; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); while (dom) { /* check that the uid is valid for this domain */ if ((dom->id_min && (cmdctx->id < dom->id_min)) || (dom->id_max && (cmdctx->id > dom->id_max))) { DEBUG(SSSDBG_CONF_SETTINGS, "Uid [%"PRIu32"] does not exist in domain [%s]! " "(id out of range)\n", cmdctx->id, dom->name); if (cmdctx->check_next) { dom = get_next_domain(dom, SSS_GND_DESCEND); continue; } ret = ENOENT; goto done; } if (dom != dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); } /* make sure to update the dctx if we changed domain */ dctx->domain = dom; DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%"PRIu32"@%s]\n", cmdctx->id, dom->name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); ret = EIO; goto done; } ret = sysdb_getpwuid_with_views(cmdctx, dom, cmdctx->id, &dctx->res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); ret = EIO; goto done; } if (dctx->res->count > 1) { DEBUG(SSSDBG_FATAL_FAILURE, "getpwuid call returned more than one result !?!\n"); sss_log(SSS_LOG_ERR, "More users have the same UID [%"PRIu32"] in directory " "server. SSSD will not work correctly.\n", cmdctx->id); ret = ENOENT; goto done; } if (dctx->res->count == 0 && !dctx->check_provider) { /* if a multidomain search, try with next */ if (cmdctx->check_next) { dom = get_next_domain(dom, SSS_GND_DESCEND); continue; } /* set negative cache only if not result of cache check */ DEBUG(SSSDBG_MINOR_FAILURE, "No results for getpwuid call\n"); ret = ENOENT; goto done; } /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (dctx->check_provider) { if (DOM_HAS_VIEWS(dom) && (dctx->res->count == 0 || ldb_msg_find_attr_as_uint64(dctx->res->msgs[0], OVERRIDE_PREFIX SYSDB_UIDNUM, 0) != 0)) { extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; } else { extra_flag = NULL; } ret = check_cache(dctx, nctx, dctx->res, SSS_DP_USER, NULL, cmdctx->id, extra_flag, nss_cmd_getby_dp_callback, dctx); if (ret != EOK) { /* Anything but EOK means we should reenter the mainloop * because we may be refreshing the cache */ goto done; } } /* One result found */ DEBUG(SSSDBG_TRACE_FUNC, "Returning info for uid [%"PRIu32"@%s]\n", cmdctx->id, dom->name); ret = EOK; goto done; } /* All domains were tried and none had the entry. */ ret = ENOENT; done: if (ret == ENOENT) { /* The entry was not found, need to set result in negative cache */ err = sss_ncache_set_uid(nctx->ncache, false, NULL, cmdctx->id); if (err != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negative cache for UID %"PRIu32"\n", cmdctx->id); } } DEBUG(SSSDBG_MINOR_FAILURE, "No matching domain found for [%"PRIu32"]\n", cmdctx->id); return ret; } static int nss_cmd_getgrgid_search(struct nss_dom_ctx *dctx); static int nss_cmd_getbyid(enum sss_cli_command cmd, struct cli_ctx *cctx); static void nss_cmd_getbyid_done(struct tevent_req *req); static int nss_cmd_getpwuid(struct cli_ctx *cctx) { return nss_cmd_getbyid(SSS_NSS_GETPWUID, cctx); } static int nss_cmd_getbyid(enum sss_cli_command cmd, struct cli_ctx *cctx) { struct nss_cmd_ctx *cmdctx; struct nss_dom_ctx *dctx; struct nss_ctx *nctx; uint8_t *body; size_t blen; int ret; struct tevent_req *req; switch (cmd) { case SSS_NSS_GETPWUID: case SSS_NSS_GETGRGID: case SSS_NSS_GETSIDBYID: break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command type [%d][%s].\n", cmd, sss_cmd2str(cmd)); return EINVAL; } nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = cctx; cmdctx->cmd = cmd; dctx = talloc_zero(cmdctx, struct nss_dom_ctx); if (!dctx) { ret = ENOMEM; goto done; } dctx->cmdctx = cmdctx; /* get id to query */ sss_packet_get_body(cctx->creq->in, &body, &blen); if (blen != sizeof(uint32_t)) { ret = EINVAL; goto done; } SAFEALIGN_COPY_UINT32(&cmdctx->id, body, NULL); DEBUG(SSSDBG_TRACE_FUNC, "Running command [%d][%s] with id [%"PRIu32"].\n", dctx->cmdctx->cmd, sss_cmd2str(dctx->cmdctx->cmd), cmdctx->id); switch(dctx->cmdctx->cmd) { case SSS_NSS_GETPWUID: ret = sss_ncache_check_uid(nctx->ncache, nctx->neg_timeout, NULL, cmdctx->id); if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "Uid [%"PRIu32"] does not exist! (negative cache)\n", cmdctx->id); ret = ENOENT; goto done; } break; case SSS_NSS_GETGRGID: ret = sss_ncache_check_gid(nctx->ncache, nctx->neg_timeout, NULL, cmdctx->id); if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "Gid [%"PRIu32"] does not exist! (negative cache)\n", cmdctx->id); ret = ENOENT; goto done; } break; case SSS_NSS_GETSIDBYID: ret = sss_ncache_check_uid(nctx->ncache, nctx->neg_timeout, NULL, cmdctx->id); if (ret != EEXIST) { ret = sss_ncache_check_gid(nctx->ncache, nctx->neg_timeout, NULL, cmdctx->id); } if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "Id [%"PRIu32"] does not exist! (negative cache)\n", cmdctx->id); ret = ENOENT; goto done; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command [%d][%s].\n", dctx->cmdctx->cmd, sss_cmd2str(dctx->cmdctx->cmd)); ret = EINVAL; goto done; } /* id searches are always multidomain */ dctx->domain = cctx->rctx->domains; cmdctx->check_next = true; dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); if (cctx->rctx->get_domains_last_call.tv_sec == 0) { req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, false, NULL); if (req == NULL) { ret = ENOMEM; } else { tevent_req_set_callback(req, nss_cmd_getbyid_done, dctx); ret = EAGAIN; } goto done; } /* ok, find it ! */ switch(dctx->cmdctx->cmd) { case SSS_NSS_GETPWUID: ret = nss_cmd_getpwuid_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getpw_send_reply(dctx, true); } break; case SSS_NSS_GETGRGID: ret = nss_cmd_getgrgid_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getgr_send_reply(dctx, true); } break; case SSS_NSS_GETSIDBYID: ret = nss_cmd_getsidby_search(dctx); if (ret == EOK) { ret = nss_cmd_getbysid_send_reply(dctx); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command [%d][%s].\n", dctx->cmdctx->cmd, sss_cmd2str(dctx->cmdctx->cmd)); ret = EINVAL; } done: return nss_cmd_done(cmdctx, ret); } static void nss_cmd_getbyid_done(struct tevent_req *req) { struct nss_dom_ctx *dctx = tevent_req_callback_data(req, struct nss_dom_ctx); struct nss_cmd_ctx *cmdctx = dctx->cmdctx; errno_t ret; ret = sss_dp_get_domains_recv(req); talloc_free(req); if (ret != EOK) { goto done; } ret = nss_reset_negcache(cmdctx->cctx->rctx); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot reset negcache records\n"); /* Not fatal */ } /* ok, find it ! */ switch(dctx->cmdctx->cmd) { case SSS_NSS_GETPWUID: ret = nss_cmd_getpwuid_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getpw_send_reply(dctx, true); } break; case SSS_NSS_GETGRGID: ret = nss_cmd_getgrgid_search(dctx); if (ret == EOK) { /* we have results to return */ ret = nss_cmd_getgr_send_reply(dctx, true); } break; case SSS_NSS_GETNAMEBYSID: case SSS_NSS_GETIDBYSID: ret = responder_get_domain_by_id(cmdctx->cctx->rctx, cmdctx->secid, &dctx->domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot find domain for SID [%s].\n", cmdctx->secid); ret = ENOENT; goto done; } dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); ret = nss_cmd_getbysid_search(dctx); if (ret == EOK) { ret = nss_cmd_getbysid_send_reply(dctx); } break; case SSS_NSS_GETSIDBYID: ret = nss_cmd_getsidby_search(dctx); if (ret == EOK) { ret = nss_cmd_getbysid_send_reply(dctx); } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command [%d][%s].\n", dctx->cmdctx->cmd, sss_cmd2str(dctx->cmdctx->cmd)); ret = EINVAL; } done: nss_cmd_done(cmdctx, ret); } /* to keep it simple at this stage we are retrieving the * full enumeration again for each request for each process * and we also block on setpwent() for the full time needed * to retrieve the data. And endpwent() frees all the data. * Next steps are: * - use an nsssrv wide cache with data already structured * so that it can be immediately returned (see nscd way) * - use mutexes so that setpwent() can return immediately * even if the data is still being fetched * - make getpwent() wait on the mutex * * Alternatively: * - use a smarter search mechanism that keeps track of the * last user searched and return the next X users doing * an alphabetic sort and starting from the user following * the last returned user. */ static int nss_cmd_getpwent_immediate(struct nss_cmd_ctx *cmdctx); struct tevent_req * nss_cmd_setpwent_send(TALLOC_CTX *mem_ctx, struct cli_ctx *client); static void nss_cmd_setpwent_done(struct tevent_req *req); static int nss_cmd_setpwent(struct cli_ctx *cctx) { struct nss_cmd_ctx *cmdctx; struct tevent_req *req; errno_t ret = EOK; cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = cctx; req = nss_cmd_setpwent_send(cmdctx, cctx); if (!req) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal error calling nss_cmd_setpwent_send\n"); ret = EIO; goto done; } tevent_req_set_callback(req, nss_cmd_setpwent_done, cmdctx); done: return nss_cmd_done(cmdctx, ret); } static errno_t nss_cmd_setpwent_step(struct setent_step_ctx *step_ctx); struct tevent_req *nss_cmd_setpwent_send(TALLOC_CTX *mem_ctx, struct cli_ctx *client) { errno_t ret; struct nss_ctx *nctx; struct tevent_req *req; struct setent_ctx *state; struct sss_domain_info *dom; struct setent_step_ctx *step_ctx; DEBUG(SSSDBG_CONF_SETTINGS, "Received setpwent request\n"); nctx = talloc_get_type(client->rctx->pvt_ctx, struct nss_ctx); /* Reset the read pointers */ client->pwent_dom_idx = 0; client->pwent_cur = 0; req = tevent_req_create(mem_ctx, &state, struct setent_ctx); if (!req) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not create tevent request for setpwent\n"); return NULL; } state->nctx = nctx; state->client = client; state->dctx = talloc_zero(state, struct nss_dom_ctx); if (!state->dctx) { ret = ENOMEM; goto error; } /* check if enumeration is enabled in any domain */ for (dom = client->rctx->domains; dom; dom = get_next_domain(dom, SSS_GND_DESCEND)) { if (dom->enumerate == true) break; } state->dctx->domain = dom; if (state->dctx->domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Enumeration disabled on all domains!\n"); ret = ENOENT; goto error; } state->dctx->check_provider = NEED_CHECK_PROVIDER(state->dctx->domain->provider); /* Is the result context already available */ if (state->nctx->pctx) { if (state->nctx->pctx->ready) { /* All of the necessary data is in place * We can return now, getpwent requests will work at this point */ tevent_req_done(req); tevent_req_post(req, state->nctx->rctx->ev); } else { /* Object is still being constructed * Register for notification when it's * ready. */ ret = nss_setent_add_ref(state, state->nctx->pctx, req); if (ret != EOK) { talloc_free(req); return NULL; } } return req; } /* Create a new result context * We are creating it on the nss_ctx so that it doesn't * go away if the original request does. We will delete * it when the refcount goes to zero; */ state->nctx->pctx = talloc_zero(nctx, struct getent_ctx); if (!state->nctx->pctx) { ret = ENOMEM; goto error; } state->getent_ctx = nctx->pctx; /* Add a callback reference for ourselves */ ret = nss_setent_add_ref(state, state->nctx->pctx, req); if (ret) goto error; /* ok, start the searches */ step_ctx = talloc_zero(state->getent_ctx, struct setent_step_ctx); if (!step_ctx) { ret = ENOMEM; goto error; } /* Steal the dom_ctx onto the step_ctx so it doesn't go out of scope if * this request is canceled while other requests are in-progress. */ step_ctx->dctx = talloc_steal(step_ctx, state->dctx); step_ctx->nctx = state->nctx; step_ctx->getent_ctx = state->getent_ctx; step_ctx->rctx = client->rctx; step_ctx->cctx = client; step_ctx->returned_to_mainloop = false; ret = nss_cmd_setpwent_step(step_ctx); if (ret != EOK && ret != EAGAIN) goto error; if (ret == EOK) { tevent_req_post(req, client->rctx->ev); } return req; error: tevent_req_error(req, ret); tevent_req_post(req, client->rctx->ev); return req; } static void nss_cmd_setpwent_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); static void setpwent_result_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt); /* nss_cmd_setpwent_step returns * EOK if everything is done and the request needs to be posted explicitly * EAGAIN if the caller can safely return to the main loop */ static errno_t nss_cmd_setpwent_step(struct setent_step_ctx *step_ctx) { errno_t ret; struct sss_domain_info *dom = step_ctx->dctx->domain; struct resp_ctx *rctx = step_ctx->rctx; struct nss_dom_ctx *dctx = step_ctx->dctx; struct getent_ctx *pctx = step_ctx->getent_ctx; struct nss_ctx *nctx = step_ctx->nctx; struct ldb_result *res; struct timeval tv; struct tevent_timer *te; struct tevent_req *dpreq; struct dp_callback_ctx *cb_ctx; while (dom) { while (dom && dom->enumerate == false) { dom = get_next_domain(dom, SSS_GND_DESCEND); } if (!dom) break; if (dom != dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); } /* make sure to update the dctx if we changed domain */ dctx->domain = dom; DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for domain [%s]\n", dom->name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); return EIO; } /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (dctx->check_provider) { step_ctx->returned_to_mainloop = true; /* Only do this once per provider */ dctx->check_provider = false; dpreq = sss_dp_get_account_send(step_ctx, rctx, dctx->domain, true, SSS_DP_USER, NULL, 0, NULL); if (!dpreq) { DEBUG(SSSDBG_MINOR_FAILURE, "Enum Cache refresh for domain [%s] failed." " Trying to return what we have in cache!\n", dom->name); } else { cb_ctx = talloc_zero(step_ctx, struct dp_callback_ctx); if(!cb_ctx) { talloc_zfree(dpreq); return ENOMEM; } cb_ctx->callback = nss_cmd_setpwent_dp_callback; cb_ctx->ptr = step_ctx; cb_ctx->cctx = step_ctx->cctx; cb_ctx->mem_ctx = step_ctx; tevent_req_set_callback(dpreq, nsssrv_dp_send_acct_req_done, cb_ctx); return EAGAIN; } } ret = sysdb_enumpwent_with_views(dctx, dom, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Enum from cache failed, skipping domain [%s]\n", dom->name); dom = get_next_domain(dom, SSS_GND_DESCEND); continue; } if (res->count == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Domain [%s] has no users, skipping.\n", dom->name); dom = get_next_domain(dom, SSS_GND_DESCEND); continue; } nctx->pctx->doms = talloc_realloc(pctx, pctx->doms, struct dom_ctx, pctx->num +1); if (!pctx->doms) { talloc_free(pctx); nctx->pctx = NULL; return ENOMEM; } nctx->pctx->doms[pctx->num].domain = dctx->domain; nctx->pctx->doms[pctx->num].res = talloc_steal(pctx->doms, res); nctx->pctx->num++; /* do not reply until all domain searches are done */ dom = get_next_domain(dom, SSS_GND_DESCEND); } /* We've finished all our lookups * The result object is now safe to read. */ nctx->pctx->ready = true; /* Set up a lifetime timer for this result object * We don't want this result object to outlive the * enum cache refresh timeout */ tv = tevent_timeval_current_ofs(nctx->enum_cache_timeout, 0); te = tevent_add_timer(rctx->ev, nctx->pctx, tv, setpwent_result_timeout, nctx); if (!te) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up life timer for setpwent result object. " "Entries may become stale.\n"); } /* Notify the waiting clients */ nss_setent_notify_done(nctx->pctx); if (step_ctx->returned_to_mainloop) { return EAGAIN; } else { return EOK; } } static void setpwent_result_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { struct nss_ctx *nctx = talloc_get_type(pvt, struct nss_ctx); DEBUG(SSSDBG_CRIT_FAILURE, "setpwent result object has expired. Cleaning up.\n"); /* Free the passwd enumeration context. * If additional getpwent requests come in, they will invoke * an implicit setpwent and refresh the result object. */ talloc_zfree(nctx->pctx); } static void nss_cmd_setpwent_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr) { struct setent_step_ctx *step_ctx = talloc_get_type(ptr, struct setent_step_ctx); int ret; if (err_maj) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get information from Data Provider\n" "Error: %u, %u, %s\n" "Will try to return what we have in cache\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg); } ret = nss_cmd_setpwent_step(step_ctx); if (ret != EOK && ret != EAGAIN) { /* Notify any waiting processes of failure */ nss_setent_notify_error(step_ctx->nctx->pctx, ret); } } static errno_t nss_cmd_setpwent_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void nss_cmd_setpwent_done(struct tevent_req *req) { errno_t ret; struct nss_cmd_ctx *cmdctx = tevent_req_callback_data(req, struct nss_cmd_ctx); ret = nss_cmd_setpwent_recv(req); talloc_zfree(req); if (ret == EOK || ret == ENOENT) { /* Either we succeeded or no domains were eligible */ ret = sss_packet_new(cmdctx->cctx->creq, 0, sss_packet_get_cmd(cmdctx->cctx->creq->in), &cmdctx->cctx->creq->out); if (ret == EOK) { sss_cmd_done(cmdctx->cctx, cmdctx); return; } } /* Something bad happened */ nss_cmd_done(cmdctx, ret); } static void nss_cmd_implicit_setpwent_done(struct tevent_req *req); static int nss_cmd_getpwent(struct cli_ctx *cctx) { struct nss_ctx *nctx; struct nss_cmd_ctx *cmdctx; struct tevent_req *req; DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for all accounts\n"); cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = cctx; /* Save the current index and cursor locations * If we end up calling setpwent implicitly, because the response object * expired and has to be recreated, we want to resume from the same * location. */ cmdctx->saved_dom_idx = cctx->pwent_dom_idx; cmdctx->saved_cur = cctx->pwent_cur; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); if(!nctx->pctx || !nctx->pctx->ready) { /* Make sure we invoke setpwent if it hasn't been run or is still * processing from another client */ req = nss_cmd_setpwent_send(cctx, cctx); if (!req) { return EIO; } tevent_req_set_callback(req, nss_cmd_implicit_setpwent_done, cmdctx); return EOK; } return nss_cmd_getpwent_immediate(cmdctx); } static int nss_cmd_retpwent(struct cli_ctx *cctx, int num); static int nss_cmd_getpwent_immediate(struct nss_cmd_ctx *cmdctx) { struct cli_ctx *cctx = cmdctx->cctx; uint8_t *body; size_t blen; uint32_t num; int ret; /* get max num of entries to return in one call */ sss_packet_get_body(cctx->creq->in, &body, &blen); if (blen != sizeof(uint32_t)) { return EINVAL; } SAFEALIGN_COPY_UINT32(&num, body, NULL); /* create response packet */ ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return ret; } ret = nss_cmd_retpwent(cctx, num); sss_packet_set_error(cctx->creq->out, ret); sss_cmd_done(cctx, cmdctx); return EOK; } static int nss_cmd_retpwent(struct cli_ctx *cctx, int num) { struct nss_ctx *nctx; struct getent_ctx *pctx; struct ldb_message **msgs = NULL; struct dom_ctx *pdom = NULL; int n = 0; int ret = ENOENT; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); if (!nctx->pctx) goto none; pctx = nctx->pctx; while (ret == ENOENT) { if (cctx->pwent_dom_idx >= pctx->num) break; pdom = &pctx->doms[cctx->pwent_dom_idx]; n = pdom->res->count - cctx->pwent_cur; if (n <= 0 && (cctx->pwent_dom_idx+1 < pctx->num)) { cctx->pwent_dom_idx++; pdom = &pctx->doms[cctx->pwent_dom_idx]; n = pdom->res->count; cctx->pwent_cur = 0; } if (!n) break; if (n < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Negative difference" "[%d - %d = %d]\n", pdom->res->count, cctx->pwent_cur, n); DEBUG(SSSDBG_CRIT_FAILURE, "Domain: %d (total %d)\n", cctx->pwent_dom_idx, pctx->num); break; } if (n > num) n = num; msgs = &(pdom->res->msgs[cctx->pwent_cur]); ret = fill_pwent(cctx->creq->out, pdom->domain, nctx, true, false, msgs, &n); cctx->pwent_cur += n; } none: if (ret == ENOENT) { ret = sss_cmd_empty_packet(cctx->creq->out); } return ret; } static void nss_cmd_implicit_setpwent_done(struct tevent_req *req) { errno_t ret; struct nss_cmd_ctx *cmdctx = tevent_req_callback_data(req, struct nss_cmd_ctx); ret = nss_cmd_setpwent_recv(req); talloc_zfree(req); /* ENOENT is acceptable, as it just means that there were no entries * to be returned. This will be handled gracefully in nss_cmd_retpwent * later. */ if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "Implicit setpwent failed with unexpected error [%d][%s]\n", ret, strerror(ret)); NSS_CMD_FATAL_ERROR(cmdctx); } /* Restore the saved index and cursor locations */ cmdctx->cctx->pwent_dom_idx = cmdctx->saved_dom_idx; cmdctx->cctx->pwent_cur = cmdctx->saved_cur; ret = nss_cmd_getpwent_immediate(cmdctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Immediate retrieval failed with unexpected error " "[%d][%s]\n", ret, strerror(ret)); NSS_CMD_FATAL_ERROR(cmdctx); } } static int nss_cmd_endpwent(struct cli_ctx *cctx) { struct nss_ctx *nctx; int ret; DEBUG(SSSDBG_CONF_SETTINGS, "Terminating request info for all accounts\n"); nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); /* create response packet */ ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return ret; } if (nctx->pctx == NULL) goto done; /* Reset the indices so that subsequent requests start at zero */ cctx->pwent_dom_idx = 0; cctx->pwent_cur = 0; done: sss_cmd_done(cctx, NULL); return EOK; } /**************************************************************************** * GROUP db related functions ***************************************************************************/ void nss_update_gr_memcache(struct nss_ctx *nctx) { struct sss_domain_info *dom; struct ldb_result *res; uint64_t exp; struct sized_string key; const char *id; time_t now; int ret; int i; now = time(NULL); for (dom = nctx->rctx->domains; dom; dom = get_next_domain(dom, 0)) { ret = sysdb_enumgrent_with_views(nctx, dom, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to enumerate users for domain [%s]\n", dom->name); continue; } for (i = 0; i < res->count; i++) { exp = ldb_msg_find_attr_as_uint64(res->msgs[i], SYSDB_CACHE_EXPIRE, 0); if (exp >= now) { continue; } /* names require more manipulation (build up fqname conditionally), * but uidNumber is unique and always resolvable too, so we use * that to update the cache, as it points to the same entry */ id = sss_view_ldb_msg_find_attr_as_string(dom, res->msgs[i], SYSDB_GIDNUM, NULL); if (!id) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to find gidNumber in %s.\n", ldb_dn_get_linearized(res->msgs[i]->dn)); continue; } to_sized_string(&key, id); ret = sss_mmap_cache_gr_invalidate(nctx->grp_mc_ctx, &key); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", ret, strerror(ret)); } } talloc_zfree(res); } } #define GID_ROFFSET 0 #define MNUM_ROFFSET sizeof(uint32_t) #define STRS_ROFFSET 2*sizeof(uint32_t) static int parse_member(TALLOC_CTX *mem_ctx, struct sss_domain_info *group_dom, const char *member, struct sss_domain_info **_member_dom, struct sized_string *_name, bool *_add_domain) { errno_t ret; char *username; char *domname; const char *use_member; struct sss_domain_info *member_dom; bool add_domain; ret = sss_parse_name(mem_ctx, group_dom->names, member, &domname, &username); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not parse [%s] into " "name-value components.\n", member); return ret; } add_domain = (!IS_SUBDOMAIN(group_dom) && group_dom->fqnames); use_member = member; member_dom = group_dom; if (IS_SUBDOMAIN(group_dom) == false && domname != NULL) { /* The group is stored in the parent domain, but the member comes from. * a subdomain. No need to add the domain component, it's already * present in the memberuid/ghost attribute */ add_domain = false; } if (IS_SUBDOMAIN(group_dom) == true && domname == NULL) { /* The group is stored in a subdomain, but the member comes * from the parent domain. Need to add the domain component * of the parent domain */ add_domain = true; use_member = username; member_dom = group_dom->parent; } to_sized_string(_name, use_member); *_add_domain = add_domain; *_member_dom = member_dom; return EOK; } static int fill_members(struct sss_packet *packet, struct sss_domain_info *dom, struct nss_ctx *nctx, struct ldb_message_element *el, size_t *_rzero, size_t *_rsize, int *_memnum) { int i, ret = EOK; int memnum = *_memnum; size_t rzero= *_rzero; size_t rsize = *_rsize; const char *tmpstr; struct sized_string name; TALLOC_CTX *tmp_ctx = NULL; int nlen = 0; uint8_t *body; size_t blen; const char *domain = dom->name; bool add_domain; struct sss_domain_info *member_dom; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } sss_packet_get_body(packet, &body, &blen); for (i = 0; i < el->num_values; i++) { tmpstr = sss_get_cased_name(tmp_ctx, (char *)el->values[i].data, dom->case_preserve); if (tmpstr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_get_cased_name failed, skipping\n"); continue; } tmpstr = sss_replace_space(tmp_ctx, tmpstr, nctx->rctx->override_space); if (tmpstr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_replace_space failed\n"); ret = ENOMEM; goto done; } if (nctx->filter_users_in_groups) { ret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout, dom, tmpstr); if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "Group [%s] member [%s@%s] filtered out!" " (negative cache)\n", (char *)&body[rzero+STRS_ROFFSET], tmpstr, domain); continue; } } ret = parse_member(tmp_ctx, dom, tmpstr, &member_dom, &name, &add_domain); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not process member %s, skipping\n", tmpstr); continue; } if (add_domain) { nlen = sss_fqname(NULL, 0, member_dom->names, member_dom, name.str); if (nlen >= 0) { nlen += 1; } else { /* Other failures caught below */ nlen = 0; } } else { nlen = name.len; } ret = sss_packet_grow(packet, nlen); if (ret != EOK) { goto done; } sss_packet_get_body(packet, &body, &blen); if (add_domain) { ret = sss_fqname((char *)&body[rzero + rsize], nlen, member_dom->names, member_dom, name.str); if (ret < 0 || ret != nlen - 1) { DEBUG(SSSDBG_OP_FAILURE, "Failed to generate a fully qualified name" " for member [%s@%s] of group [%s]!" " Skipping\n", name.str, domain, (char *)&body[rzero+STRS_ROFFSET]); /* reclaim space */ ret = sss_packet_shrink(packet, nlen); if (ret != EOK) { goto done; } continue; } } else { memcpy(&body[rzero + rsize], name.str, name.len); } rsize += nlen; memnum++; } ret = 0; done: *_memnum = memnum; *_rzero = rzero; *_rsize = rsize; talloc_zfree(tmp_ctx); return ret; } static int fill_grent(struct sss_packet *packet, struct sss_domain_info *dom, struct nss_ctx *nctx, bool filter_groups, bool gr_mmap_cache, struct ldb_message **msgs, int *count) { struct ldb_message *msg; struct ldb_message_element *el; uint8_t *body; size_t blen; uint32_t gid; const char *tmpstr; const char *orig_name = NULL; struct sized_string name; struct sized_string pwfield; struct sized_string fullname; int fq_len = 0; int i = 0; int ret, num, memnum; size_t rzero, rsize; bool add_domain = (!IS_SUBDOMAIN(dom) && dom->fqnames); const char *domain = dom->name; TALLOC_CTX *tmp_ctx = NULL; to_sized_string(&pwfield, nctx->pwfield); num = 0; /* first 2 fields (len and reserved), filled up later */ ret = sss_packet_grow(packet, 2*sizeof(uint32_t)); if (ret != EOK) { goto done; } sss_packet_get_body(packet, &body, &blen); rzero = 2*sizeof(uint32_t); rsize = 0; for (i = 0; i < *count; i++) { talloc_zfree(tmp_ctx); tmp_ctx = talloc_new(NULL); msg = msgs[i]; /* new group */ if (!ldb_msg_check_string_attribute(msg, "objectClass", SYSDB_GROUP_CLASS)) { DEBUG(SSSDBG_CRIT_FAILURE, "Wrong object (%s) found on stack!\n", ldb_dn_get_linearized(msg->dn)); continue; } /* new result starts at end of previous result */ rzero += rsize; rsize = 0; /* find group name/gid */ /* start with an empty name for each iteration */ orig_name = NULL; if (DOM_HAS_VIEWS(dom)) { orig_name = ldb_msg_find_attr_as_string(msg, OVERRIDE_PREFIX SYSDB_NAME, NULL); if (orig_name != NULL && IS_SUBDOMAIN(dom)) { /* Override names are not fully qualified */ add_domain = true; } } if (orig_name == NULL) { orig_name = ldb_msg_find_attr_as_string(msg, SYSDB_DEFAULT_OVERRIDE_NAME, NULL); if (orig_name == NULL) { orig_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); } } gid = sss_view_ldb_msg_find_attr_as_uint64(dom, msg, SYSDB_GIDNUM, 0); if (!orig_name || !gid) { DEBUG(SSSDBG_OP_FAILURE, "Incomplete group object for %s[%llu]! Skipping\n", orig_name?orig_name:"", (unsigned long long int)gid); continue; } if (filter_groups) { ret = sss_ncache_check_group(nctx->ncache, nctx->neg_timeout, dom, orig_name); if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "Group [%s@%s] filtered out! (negative cache)\n", orig_name, domain); continue; } } tmpstr = sss_get_cased_name(tmp_ctx, orig_name, dom->case_preserve); if (tmpstr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_get_cased_name failed, skipping\n"); continue; } tmpstr = sss_replace_space(tmp_ctx, tmpstr, nctx->rctx->override_space); if (tmpstr == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_replace_space failed, skipping\n"); continue; } to_sized_string(&name, tmpstr); /* fill in gid and name and set pointer for number of members */ rsize = STRS_ROFFSET + name.len + pwfield.len; /* name\0x\0 */ if (add_domain) { fq_len = sss_fqname(NULL, 0, dom->names, dom, name.str); if (fq_len >= 0) { fq_len += 1; rsize -= name.len; rsize += fq_len; } else { /* Other failures caught below */ fq_len = 0; } } ret = sss_packet_grow(packet, rsize); if (ret != EOK) { num = 0; goto done; } sss_packet_get_body(packet, &body, &blen); /* 0-3: 32bit number gid */ SAFEALIGN_SET_UINT32(&body[rzero+GID_ROFFSET], gid, NULL); /* 4-7: 32bit unsigned number of members */ SAFEALIGN_SET_UINT32(&body[rzero+MNUM_ROFFSET], 0, NULL); /* 8-X: sequence of strings (name, passwd, mem..) */ if (add_domain) { ret = sss_fqname((char *)&body[rzero+STRS_ROFFSET], fq_len, dom->names, dom, name.str); if (ret < 0 || ret != fq_len - 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to generate a fully qualified name for" " group [%s] in [%s]! Skipping\n", name.str, domain); /* reclaim space */ ret = sss_packet_shrink(packet, rsize); if (ret != EOK) { num = 0; goto done; } rsize = 0; continue; } } else { memcpy(&body[rzero+STRS_ROFFSET], name.str, name.len); } to_sized_string(&fullname, (const char *)&body[rzero+STRS_ROFFSET]); /* group passwd field */ memcpy(&body[rzero+STRS_ROFFSET + fullname.len], pwfield.str, pwfield.len); memnum = 0; if (!dom->ignore_group_members) { el = sss_view_ldb_msg_find_element(dom, msg, SYSDB_MEMBERUID); if (el) { ret = fill_members(packet, dom, nctx, el, &rzero, &rsize, &memnum); if (ret != EOK) { num = 0; goto done; } sss_packet_get_body(packet, &body, &blen); } el = ldb_msg_find_element(msg, SYSDB_GHOST); if (el) { if (DOM_HAS_VIEWS(dom) && !is_local_view(dom->view_name) && el->num_values != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Domain has a view [%s] but group [%s] still has " \ "ghost members.\n", dom->view_name, orig_name); num = 0; goto done; } ret = fill_members(packet, dom, nctx, el, &rzero, &rsize, &memnum); if (ret != EOK) { num = 0; goto done; } sss_packet_get_body(packet, &body, &blen); } } if (memnum) { /* set num of members */ SAFEALIGN_SET_UINT32(&body[rzero+MNUM_ROFFSET], memnum, NULL); } num++; if (gr_mmap_cache && nctx->grp_mc_ctx) { /* body was reallocated, so fullname might be pointing to * where body used to be, not where it is */ to_sized_string(&fullname, (const char *)&body[rzero+STRS_ROFFSET]); ret = sss_mmap_cache_gr_store(&nctx->grp_mc_ctx, &fullname, &pwfield, gid, memnum, (char *)&body[rzero] + STRS_ROFFSET + fullname.len + pwfield.len, rsize - STRS_ROFFSET - fullname.len - pwfield.len); if (ret != EOK && ret != ENOMEM) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store group %s(%s) in mmap cache!\n", name.str, domain); } } continue; } talloc_zfree(tmp_ctx); done: *count = i; if (num == 0) { /* if num is 0 most probably something went wrong, * reset packet and return ENOENT */ ret = sss_packet_set_size(packet, 0); if (ret != EOK) return ret; return ENOENT; } SAFEALIGN_COPY_UINT32(body, &num, NULL); /* num results */ SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL); /* reserved */ return EOK; } static int nss_cmd_getgr_send_reply(struct nss_dom_ctx *dctx, bool filter) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct cli_ctx *cctx = cmdctx->cctx; struct nss_ctx *nctx; int ret; int i; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return EFAULT; } i = dctx->res->count; ret = fill_grent(cctx->creq->out, dctx->domain, nctx, filter, true, dctx->res->msgs, &i); if (ret) { return ret; } sss_packet_set_error(cctx->creq->out, EOK); sss_cmd_done(cctx, cmdctx); return EOK; } /* search for a group. * Returns: * ENOENT, if group is definitely not found * EAGAIN, if group is being fetched from backend via async operations * EOK, if found * anything else on a fatal error */ static int nss_cmd_getgrnam_search(struct nss_dom_ctx *dctx) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct sss_domain_info *dom = dctx->domain; struct cli_ctx *cctx = cmdctx->cctx; char *name = NULL; struct nss_ctx *nctx; int ret; const char *extra_flag = NULL; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); while (dom) { /* if it is a domainless search, skip domains that require fully * qualified names instead */ while (dom && cmdctx->check_next && dom->fqnames) { dom = get_next_domain(dom, 0); } if (!dom) break; if (dom != dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); } /* make sure to update the dctx if we changed domain */ dctx->domain = dom; talloc_free(name); name = sss_get_cased_name(dctx, cmdctx->name, dom->case_sensitive); if (!name) return ENOMEM; name = sss_reverse_replace_space(dctx, name, nctx->rctx->override_space); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_reverse_replace_space failed\n"); return ENOMEM; } /* verify this group has not yet been negatively cached, * or has been permanently filtered */ ret = sss_ncache_check_group(nctx->ncache, nctx->neg_timeout, dom, name); /* if neg cached, return we didn't find it */ if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "Group [%s] does not exist in [%s]! (negative cache)\n", name, dom->name); /* if a multidomain search, try with next */ if (cmdctx->check_next) { dom = get_next_domain(dom, 0); continue; } /* There are no further domains or this was a * fully-qualified user request. */ return ENOENT; } DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%s@%s]\n", name, dom->name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); return EIO; } ret = sysdb_getgrnam_with_views(cmdctx, dom, name, &dctx->res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); return EIO; } if (dctx->res->count > 1) { DEBUG(SSSDBG_FATAL_FAILURE, "getgrnam call returned more than one result !?!\n"); sss_log(SSS_LOG_ERR, "More groups have the same name [%s@%s] in SSSD cache. " "SSSD will not work correctly.\n", name, dom->name); return ENOENT; } if (dctx->res->count == 0 && !dctx->check_provider) { /* set negative cache only if not result of cache check */ ret = sss_ncache_set_group(nctx->ncache, false, dom, name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s@%s\n", name, dom->name); } /* if a multidomain search, try with next */ if (cmdctx->check_next) { dom = get_next_domain(dom, 0); if (dom) continue; } DEBUG(SSSDBG_OP_FAILURE, "No results for getgrnam call\n"); /* Group not found in ldb -> delete group from memory cache. */ ret = delete_entry_from_memcache(dctx->domain, name, nctx->grp_mc_ctx, SSS_MC_GROUP); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Deleting group from memcache failed.\n"); } return ENOENT; } /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (dctx->check_provider) { if (DOM_HAS_VIEWS(dom) && (dctx->res->count == 0 || ldb_msg_find_attr_as_string(dctx->res->msgs[0], OVERRIDE_PREFIX SYSDB_NAME, NULL) != NULL)) { extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; } else { extra_flag = NULL; } ret = check_cache(dctx, nctx, dctx->res, SSS_DP_GROUP, name, 0, extra_flag, nss_cmd_getby_dp_callback, dctx); if (ret != EOK) { /* Anything but EOK means we should reenter the mainloop * because we may be refreshing the cache */ return ret; } } /* One result found */ DEBUG(SSSDBG_TRACE_FUNC, "Returning info for group [%s@%s]\n", name, dom->name); return EOK; } DEBUG(SSSDBG_MINOR_FAILURE, "No matching domain found for [%s], fail!\n", cmdctx->name); return ENOENT; } static int nss_cmd_getgrnam(struct cli_ctx *cctx) { return nss_cmd_getbynam(SSS_NSS_GETGRNAM, cctx); } /* search for a gid. * Returns: * ENOENT, if gid is definitely not found * EAGAIN, if gid is being fetched from backend via async operations * EOK, if found * anything else on a fatal error */ static int nss_cmd_getgrgid_search(struct nss_dom_ctx *dctx) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct sss_domain_info *dom = dctx->domain; struct cli_ctx *cctx = cmdctx->cctx; struct nss_ctx *nctx; int ret; int err; const char *extra_flag = NULL; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); while (dom) { /* check that the gid is valid for this domain */ if ((dom->id_min && (cmdctx->id < dom->id_min)) || (dom->id_max && (cmdctx->id > dom->id_max))) { DEBUG(SSSDBG_CONF_SETTINGS, "Gid [%"PRIu32"] does not exist in domain [%s]! " "(id out of range)\n", cmdctx->id, dom->name); if (cmdctx->check_next) { dom = get_next_domain(dom, SSS_GND_DESCEND); continue; } ret = ENOENT; goto done; } if (dom != dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); } /* make sure to update the dctx if we changed domain */ dctx->domain = dom; DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%"PRIu32"@%s]\n", cmdctx->id, dom->name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); ret = EIO; goto done; } ret = sysdb_getgrgid_with_views(cmdctx, dom, cmdctx->id, &dctx->res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); ret = EIO; goto done; } if (dctx->res->count > 1) { DEBUG(SSSDBG_FATAL_FAILURE, "getgrgid call returned more than one result !?!\n"); sss_log(SSS_LOG_ERR, "More groups have the same GID [%"PRIu32"] in directory " "server. SSSD will not work correctly.\n", cmdctx->id); ret = ENOENT; goto done; } if (dctx->res->count == 0 && !dctx->check_provider) { /* if a multidomain search, try with next */ if (cmdctx->check_next) { dom = get_next_domain(dom, SSS_GND_DESCEND); continue; } /* set negative cache only if not result of cache check */ DEBUG(SSSDBG_MINOR_FAILURE, "No results for getgrgid call\n"); ret = ENOENT; goto done; } /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (dctx->check_provider) { if (DOM_HAS_VIEWS(dom) && (dctx->res->count == 0 || ldb_msg_find_attr_as_uint64(dctx->res->msgs[0], OVERRIDE_PREFIX SYSDB_GIDNUM, 0) != 0)) { extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; } else { extra_flag = NULL; } ret = check_cache(dctx, nctx, dctx->res, SSS_DP_GROUP, NULL, cmdctx->id, extra_flag, nss_cmd_getby_dp_callback, dctx); if (ret != EOK) { /* Anything but EOK means we should reenter the mainloop * because we may be refreshing the cache */ goto done; } } /* One result found */ DEBUG(SSSDBG_TRACE_FUNC, "Returning info for gid [%"PRIu32"@%s]\n", cmdctx->id, dom->name); /* Success. Break from the loop and return EOK */ ret = EOK; goto done; } /* All domains were tried and none had the entry. */ ret = ENOENT; done: if (ret == ENOENT) { /* The entry was not found, need to set result in negative cache */ err = sss_ncache_set_gid(nctx->ncache, false, NULL, cmdctx->id); if (err != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negative cache for GID %"PRIu32"\n", cmdctx->id); } } DEBUG(SSSDBG_MINOR_FAILURE, "No matching domain found for [%"PRIu32"]\n", cmdctx->id); return ret; } static int nss_cmd_getgrgid(struct cli_ctx *cctx) { return nss_cmd_getbyid(SSS_NSS_GETGRGID, cctx); } /* to keep it simple at this stage we are retrieving the * full enumeration again for each request for each process * and we also block on setgrent() for the full time needed * to retrieve the data. And endgrent() frees all the data. * Next steps are: * - use and nsssrv wide cache with data already structured * so that it can be immediately returned (see nscd way) * - use mutexes so that setgrent() can return immediately * even if the data is still being fetched * - make getgrent() wait on the mutex */ struct tevent_req *nss_cmd_setgrent_send(TALLOC_CTX *mem_ctx, struct cli_ctx *client); static void nss_cmd_setgrent_done(struct tevent_req *req); static int nss_cmd_setgrent(struct cli_ctx *cctx) { struct nss_cmd_ctx *cmdctx; struct tevent_req *req; errno_t ret = EOK; cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = cctx; req = nss_cmd_setgrent_send(cmdctx, cctx); if (!req) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal error calling nss_cmd_setgrent_send\n"); ret = EIO; goto done; } tevent_req_set_callback(req, nss_cmd_setgrent_done, cmdctx); done: return nss_cmd_done(cmdctx, ret); } static errno_t nss_cmd_setgrent_step(struct setent_step_ctx *step_ctx); struct tevent_req *nss_cmd_setgrent_send(TALLOC_CTX *mem_ctx, struct cli_ctx *client) { errno_t ret; struct nss_ctx *nctx; struct tevent_req *req; struct setent_ctx *state; struct sss_domain_info *dom; struct setent_step_ctx *step_ctx; DEBUG(SSSDBG_CONF_SETTINGS, "Received setgrent request\n"); nctx = talloc_get_type(client->rctx->pvt_ctx, struct nss_ctx); /* Reset the read pointers */ client->grent_dom_idx = 0; client->grent_cur = 0; req = tevent_req_create(mem_ctx, &state, struct setent_ctx); if (!req) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not create tevent request for setgrent\n"); return NULL; } state->nctx = nctx; state->client = client; state->dctx = talloc_zero(state, struct nss_dom_ctx); if (!state->dctx) { ret = ENOMEM; goto error; } /* check if enumeration is enabled in any domain */ for (dom = client->rctx->domains; dom; dom = get_next_domain(dom, SSS_GND_DESCEND)) { if (dom->enumerate == true) break; } state->dctx->domain = dom; if (state->dctx->domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Enumeration disabled on all domains!\n"); ret = ENOENT; goto error; } state->dctx->check_provider = NEED_CHECK_PROVIDER(state->dctx->domain->provider); /* Is the result context already available */ if (state->nctx->gctx) { if (state->nctx->gctx->ready) { /* All of the necessary data is in place * We can return now, getgrent requests will work at this point */ tevent_req_done(req); tevent_req_post(req, state->nctx->rctx->ev); } else { /* Object is still being constructed * Register for notification when it's * ready. */ ret = nss_setent_add_ref(state, state->nctx->gctx, req); if (ret != EOK) { talloc_free(req); return NULL; } } return req; } /* Create a new result context * We are creating it on the nss_ctx so that it doesn't * go away if the original request does. We will delete * it when the refcount goes to zero; */ state->nctx->gctx = talloc_zero(nctx, struct getent_ctx); if (!state->nctx->gctx) { ret = ENOMEM; goto error; } state->getent_ctx = nctx->gctx; /* Add a callback reference for ourselves */ ret = nss_setent_add_ref(state, state->nctx->gctx, req); if (ret) goto error; /* ok, start the searches */ step_ctx = talloc_zero(state->getent_ctx, struct setent_step_ctx); if (!step_ctx) { ret = ENOMEM; goto error; } /* Steal the dom_ctx onto the step_ctx so it doesn't go out of scope if * this request is canceled while other requests are in-progress. */ step_ctx->dctx = talloc_steal(step_ctx, state->dctx); step_ctx->nctx = state->nctx; step_ctx->getent_ctx = state->getent_ctx; step_ctx->rctx = client->rctx; step_ctx->cctx = client; step_ctx->returned_to_mainloop = false; ret = nss_cmd_setgrent_step(step_ctx); if (ret != EOK && ret != EAGAIN) goto error; if (ret == EOK) { tevent_req_post(req, client->rctx->ev); } return req; error: tevent_req_error(req, ret); tevent_req_post(req, client->rctx->ev); return req; } static void nss_cmd_setgrent_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); static void setgrent_result_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt); /* nss_cmd_setgrent_step returns * EOK if everything is done and the request needs to be posted explicitly * EAGAIN if the caller can safely return to the main loop */ static errno_t nss_cmd_setgrent_step(struct setent_step_ctx *step_ctx) { errno_t ret; struct sss_domain_info *dom = step_ctx->dctx->domain; struct resp_ctx *rctx = step_ctx->rctx; struct nss_dom_ctx *dctx = step_ctx->dctx; struct getent_ctx *gctx = step_ctx->getent_ctx; struct nss_ctx *nctx = step_ctx->nctx; struct ldb_result *res; struct timeval tv; struct tevent_timer *te; struct tevent_req *dpreq; struct dp_callback_ctx *cb_ctx; while (dom) { while (dom && dom->enumerate == false) { dom = get_next_domain(dom, SSS_GND_DESCEND); } if (!dom) break; if (dom != dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); } /* make sure to update the dctx if we changed domain */ dctx->domain = dom; DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for domain [%s]\n", dom->name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); return EIO; } /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (dctx->check_provider) { step_ctx->returned_to_mainloop = true; /* Only do this once per provider */ dctx->check_provider = false; dpreq = sss_dp_get_account_send(step_ctx, rctx, dctx->domain, true, SSS_DP_GROUP, NULL, 0, NULL); if (!dpreq) { DEBUG(SSSDBG_MINOR_FAILURE, "Enum Cache refresh for domain [%s] failed." " Trying to return what we have in cache!\n", dom->name); } else { cb_ctx = talloc_zero(step_ctx, struct dp_callback_ctx); if(!cb_ctx) { talloc_zfree(dpreq); return ENOMEM; } cb_ctx->callback = nss_cmd_setgrent_dp_callback; cb_ctx->ptr = step_ctx; cb_ctx->cctx = step_ctx->cctx; cb_ctx->mem_ctx = step_ctx; tevent_req_set_callback(dpreq, nsssrv_dp_send_acct_req_done, cb_ctx); return EAGAIN; } } ret = sysdb_enumgrent_with_views(dctx, dom, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Enum from cache failed, skipping domain [%s]\n", dom->name); dom = get_next_domain(dom, SSS_GND_DESCEND); continue; } if (res->count == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Domain [%s] has no groups, skipping.\n", dom->name); dom = get_next_domain(dom, SSS_GND_DESCEND); continue; } nctx->gctx->doms = talloc_realloc(gctx, gctx->doms, struct dom_ctx, gctx->num +1); if (!gctx->doms) { talloc_free(gctx); nctx->gctx = NULL; return ENOMEM; } nctx->gctx->doms[gctx->num].domain = dctx->domain; nctx->gctx->doms[gctx->num].res = talloc_steal(gctx->doms, res); nctx->gctx->num++; /* do not reply until all domain searches are done */ dom = get_next_domain(dom, SSS_GND_DESCEND); } /* We've finished all our lookups * The result object is now safe to read. */ nctx->gctx->ready = true; /* Set up a lifetime timer for this result object * We don't want this result object to outlive the * enum cache refresh timeout */ tv = tevent_timeval_current_ofs(nctx->enum_cache_timeout, 0); te = tevent_add_timer(rctx->ev, nctx->gctx, tv, setgrent_result_timeout, nctx); if (!te) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not set up life timer for setgrent result object. " "Entries may become stale.\n"); } /* Notify the waiting clients */ nss_setent_notify_done(nctx->gctx); if (step_ctx->returned_to_mainloop) { return EAGAIN; } else { return EOK; } } static void setgrent_result_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt) { struct nss_ctx *nctx = talloc_get_type(pvt, struct nss_ctx); DEBUG(SSSDBG_CRIT_FAILURE, "setgrent result object has expired. Cleaning up.\n"); /* Free the group enumeration context. * If additional getgrent requests come in, they will invoke * an implicit setgrent and refresh the result object. */ talloc_zfree(nctx->gctx); } static void nss_cmd_setgrent_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr) { struct setent_step_ctx *step_ctx = talloc_get_type(ptr, struct setent_step_ctx); int ret; if (err_maj) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get information from Data Provider\n" "Error: %u, %u, %s\n" "Will try to return what we have in cache\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg); } ret = nss_cmd_setgrent_step(step_ctx); if (ret != EOK && ret != EAGAIN) { /* Notify any waiting processes of failure */ nss_setent_notify_error(step_ctx->nctx->gctx, ret); } } static errno_t nss_cmd_setgrent_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void nss_cmd_setgrent_done(struct tevent_req *req) { errno_t ret; struct nss_cmd_ctx *cmdctx = tevent_req_callback_data(req, struct nss_cmd_ctx); ret = nss_cmd_setgrent_recv(req); talloc_zfree(req); if (ret == EOK || ret == ENOENT) { /* Either we succeeded or no domains were eligible */ ret = sss_packet_new(cmdctx->cctx->creq, 0, sss_packet_get_cmd(cmdctx->cctx->creq->in), &cmdctx->cctx->creq->out); if (ret == EOK) { sss_cmd_done(cmdctx->cctx, cmdctx); return; } } /* Something bad happened */ nss_cmd_done(cmdctx, ret); } static int nss_cmd_retgrent(struct cli_ctx *cctx, int num) { struct nss_ctx *nctx; struct getent_ctx *gctx; struct ldb_message **msgs = NULL; struct dom_ctx *gdom = NULL; int n = 0; int ret = ENOENT; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); if (!nctx->gctx) goto none; gctx = nctx->gctx; while (ret == ENOENT) { if (cctx->grent_dom_idx >= gctx->num) break; gdom = &gctx->doms[cctx->grent_dom_idx]; n = gdom->res->count - cctx->grent_cur; if (n <= 0 && (cctx->grent_dom_idx+1 < gctx->num)) { cctx->grent_dom_idx++; gdom = &gctx->doms[cctx->grent_dom_idx]; n = gdom->res->count; cctx->grent_cur = 0; } if (!n) break; if (n > num) n = num; msgs = &(gdom->res->msgs[cctx->grent_cur]); ret = fill_grent(cctx->creq->out, gdom->domain, nctx, true, false, msgs, &n); cctx->grent_cur += n; } none: if (ret == ENOENT) { ret = sss_cmd_empty_packet(cctx->creq->out); } return ret; } static int nss_cmd_getgrent_immediate(struct nss_cmd_ctx *cmdctx) { struct cli_ctx *cctx = cmdctx->cctx; uint8_t *body; size_t blen; uint32_t num; int ret; /* get max num of entries to return in one call */ sss_packet_get_body(cctx->creq->in, &body, &blen); if (blen != sizeof(uint32_t)) { return EINVAL; } SAFEALIGN_COPY_UINT32(&num, body, NULL); /* create response packet */ ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return ret; } ret = nss_cmd_retgrent(cctx, num); sss_packet_set_error(cctx->creq->out, ret); sss_cmd_done(cctx, cmdctx); return EOK; } static void nss_cmd_implicit_setgrent_done(struct tevent_req *req); static int nss_cmd_getgrent(struct cli_ctx *cctx) { struct nss_ctx *nctx; struct nss_cmd_ctx *cmdctx; struct tevent_req *req; DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for all groups\n"); cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = cctx; /* Save the current index and cursor locations * If we end up calling setgrent implicitly, because the response object * expired and has to be recreated, we want to resume from the same * location. */ cmdctx->saved_dom_idx = cctx->grent_dom_idx; cmdctx->saved_cur = cctx->grent_cur; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); if(!nctx->gctx || !nctx->gctx->ready) { /* Make sure we invoke setgrent if it hasn't been run or is still * processing from another client */ req = nss_cmd_setgrent_send(cctx, cctx); if (!req) { return EIO; } tevent_req_set_callback(req, nss_cmd_implicit_setgrent_done, cmdctx); return EOK; } return nss_cmd_getgrent_immediate(cmdctx); } static void nss_cmd_implicit_setgrent_done(struct tevent_req *req) { errno_t ret; struct nss_cmd_ctx *cmdctx = tevent_req_callback_data(req, struct nss_cmd_ctx); ret = nss_cmd_setgrent_recv(req); talloc_zfree(req); /* ENOENT is acceptable, as it just means that there were no entries * to be returned. This will be handled gracefully in nss_cmd_retpwent * later. */ if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_FATAL_FAILURE, "Implicit setgrent failed with unexpected error [%d][%s]\n", ret, strerror(ret)); NSS_CMD_FATAL_ERROR(cmdctx); } /* Restore the saved index and cursor locations */ cmdctx->cctx->grent_dom_idx = cmdctx->saved_dom_idx; cmdctx->cctx->grent_cur = cmdctx->saved_cur; ret = nss_cmd_getgrent_immediate(cmdctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Immediate retrieval failed with unexpected error " "[%d][%s]\n", ret, strerror(ret)); NSS_CMD_FATAL_ERROR(cmdctx); } } static int nss_cmd_endgrent(struct cli_ctx *cctx) { struct nss_ctx *nctx; int ret; DEBUG(SSSDBG_CONF_SETTINGS, "Terminating request info for all groups\n"); nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); /* create response packet */ ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return ret; } if (nctx->gctx == NULL) goto done; /* Reset the indices so that subsequent requests start at zero */ cctx->grent_dom_idx = 0; cctx->grent_cur = 0; done: sss_cmd_done(cctx, NULL); return EOK; } void nss_update_initgr_memcache(struct nss_ctx *nctx, const char *name, const char *domain, int gnum, uint32_t *groups) { TALLOC_CTX *tmp_ctx = NULL; struct sss_domain_info *dom; struct ldb_result *res; struct sized_string delete_name; bool changed = false; uint32_t id; uint32_t gids[gnum]; int ret; int i, j; for (dom = nctx->rctx->domains; dom; dom = get_next_domain(dom, 0)) { if (strcasecmp(dom->name, domain) == 0) { break; } } if (dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Unknown domain (%s) requested by provider\n", domain); return; } tmp_ctx = talloc_new(NULL); ret = sysdb_initgroups(tmp_ctx, dom, name, &res); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache! [%d][%s]\n", ret, strerror(ret)); goto done; } /* copy, we need the original intact in case we need to invalidate * all the original groups */ memcpy(gids, groups, gnum * sizeof(uint32_t)); if (ret == ENOENT || res->count == 0) { /* The user is gone. Invalidate the mc record */ to_sized_string(&delete_name, name); ret = sss_mmap_cache_pw_invalidate(nctx->pwd_mc_ctx, &delete_name); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", ret, strerror(ret)); } /* Also invalidate his groups */ changed = true; } else { /* we skip the first entry, it's the user itself */ for (i = 0; i < res->count; i++) { id = ldb_msg_find_attr_as_uint(res->msgs[i], SYSDB_GIDNUM, 0); if (id == 0) { /* probably non-posix group, skip */ continue; } for (j = 0; j < gnum; j++) { if (gids[j] == id) { gids[j] = 0; break; } } if (j >= gnum) { /* we couldn't find a match, this means the groups have * changed after the refresh */ changed = true; break; } } if (!changed) { for (j = 0; j < gnum; j++) { if (gids[j] != 0) { /* we found an un-cleared groups, this means the groups * have changed after the refresh (some got deleted) */ changed = true; break; } } } } if (changed) { char *fq_name = sss_tc_fqname(tmp_ctx, dom->names, dom, name); if (!fq_name) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not create fq name\n"); goto done; } for (i = 0; i < gnum; i++) { id = groups[i]; ret = sss_mmap_cache_gr_invalidate_gid(nctx->grp_mc_ctx, id); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", ret, strerror(ret)); } } to_sized_string(&delete_name, fq_name); ret = sss_mmap_cache_initgr_invalidate(nctx->initgr_mc_ctx, &delete_name); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Internal failure in memory cache code: %d [%s]\n", ret, strerror(ret)); } } done: talloc_free(tmp_ctx); } /* FIXME: what about mpg, should we return the user's GID ? */ /* FIXME: should we filter out GIDs ? */ static int fill_initgr(struct sss_packet *packet, struct sss_domain_info *dom, struct ldb_result *res, struct nss_ctx *nctx, const char *mc_name, const char *name) { uint8_t *body; size_t blen; gid_t gid; int ret, i; uint32_t num; size_t bindex; int skipped = 0; const char *posix; gid_t orig_primary_gid; struct sized_string rawname; uint8_t *gids; if (res->count == 0) { return ENOENT; } /* one less, the first one is the user entry */ num = res->count -1; ret = sss_packet_grow(packet, (2 + res->count) * sizeof(uint32_t)); if (ret != EOK) { return ret; } sss_packet_get_body(packet, &body, &blen); orig_primary_gid = sss_view_ldb_msg_find_attr_as_uint64(dom, res->msgs[0], SYSDB_PRIMARY_GROUP_GIDNUM, 0); /* If the GID of the original primary group is available but equal to the * current primary GID it must not be added. */ if (orig_primary_gid != 0) { gid = sss_view_ldb_msg_find_attr_as_uint64(dom, res->msgs[0], SYSDB_GIDNUM, 0); if (orig_primary_gid == gid) { orig_primary_gid = 0; } } /* 0-3: 32bit unsigned number of results * 4-7: 32bit unsigned (reserved/padding) */ bindex = 2 * sizeof(uint32_t); gids = body + bindex; /* skip first entry, it's the user entry */ for (i = 0; i < num; i++) { gid = sss_view_ldb_msg_find_attr_as_uint64(dom, res->msgs[i + 1], SYSDB_GIDNUM, 0); posix = ldb_msg_find_attr_as_string(res->msgs[i + 1], SYSDB_POSIX, NULL); if (!gid) { if (posix && strcmp(posix, "FALSE") == 0) { skipped++; continue; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Incomplete group object for initgroups! Aborting\n"); return EFAULT; } } SAFEALIGN_COPY_UINT32(body + bindex, &gid, &bindex); /* do not add the GID of the original primary group is the user is * already and explicit member of the group. */ if (orig_primary_gid == gid) { orig_primary_gid = 0; } } if (orig_primary_gid != 0) { SAFEALIGN_COPY_UINT32(body + bindex, &orig_primary_gid, &bindex); num++; } SAFEALIGN_SETMEM_UINT32(body, num - skipped, NULL); /* num results */ SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL); /* reserved */ blen = bindex; ret = sss_packet_set_size(packet, blen); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set packet size to value:%zu\n", blen); return ret; } if (nctx->initgr_mc_ctx) { struct sized_string unique_name; char *fq_name = sss_tc_fqname(packet, dom->names, dom, name); if (!fq_name) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not create fq name\n"); return ENOMEM; } to_sized_string(&rawname, mc_name); to_sized_string(&unique_name, fq_name); ret = sss_mmap_cache_initgr_store(&nctx->initgr_mc_ctx, &rawname, &unique_name, num - skipped, gids); if (ret != EOK && ret != ENOMEM) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store user %s(%s) in mmap cache!\n", rawname.str, dom->name); } } return EOK; } static int nss_cmd_initgr_send_reply(struct nss_dom_ctx *dctx) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct cli_ctx *cctx = cmdctx->cctx; struct nss_ctx *nctx; int ret; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return EFAULT; } ret = fill_initgr(cctx->creq->out, dctx->domain, dctx->res, nctx, dctx->mc_name, cmdctx->normalized_name); if (ret) { return ret; } sss_packet_set_error(cctx->creq->out, EOK); sss_cmd_done(cctx, cmdctx); return EOK; } static int nss_cmd_initgroups_search(struct nss_dom_ctx *dctx) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct sss_domain_info *dom = dctx->domain; struct cli_ctx *cctx = cmdctx->cctx; char *name = NULL; struct nss_ctx *nctx; int ret; static const char *user_attrs[] = SYSDB_PW_ATTRS; struct ldb_message *msg; const char *sysdb_name; size_t c; const char *extra_flag = NULL; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); while (dom) { /* if it is a domainless search, skip domains that require fully * qualified names instead */ while (dom && cmdctx->check_next && dom->fqnames && !cmdctx->name_is_upn) { dom = get_next_domain(dom, 0); } if (!dom) break; if (dom != dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); } /* make sure to update the dctx if we changed domain */ dctx->domain = dom; talloc_zfree(cmdctx->normalized_name); name = sss_get_cased_name(dctx, cmdctx->name, dom->case_sensitive); if (!name) return ENOMEM; name = sss_reverse_replace_space(cmdctx, name, nctx->rctx->override_space); /* save name so it can be used in initgr reply */ cmdctx->normalized_name = name; if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_reverse_replace_space failed\n"); return ENOMEM; } /* verify this user has not yet been negatively cached, * or has been permanently filtered */ ret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout, dom, name); /* if neg cached, return we didn't find it */ if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "User [%s] does not exist in [%s]! (negative cache)\n", name, dom->name); /* if a multidomain search, try with next */ if (cmdctx->check_next) { dom = get_next_domain(dom, 0); continue; } /* There are no further domains or this was a * fully-qualified user request. */ return ENOENT; } DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%s@%s]\n", name, dom->name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); return EIO; } if (cmdctx->name_is_upn) { ret = sysdb_search_user_by_upn(cmdctx, dom, name, user_attrs, &msg); if (ret == ENOENT) { dctx->res = talloc_zero(cmdctx, struct ldb_result); if (dctx->res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } dctx->res->count = 0; dctx->res->msgs = NULL; ret = EOK; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn failed.\n"); return ret; } else { sysdb_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); if (sysdb_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Sysdb entry does not have a name.\n"); return EINVAL; } ret = sysdb_initgroups(cmdctx, dom, sysdb_name, &dctx->res); if (ret == EOK && DOM_HAS_VIEWS(dom)) { for (c = 0; c < dctx->res->count; c++) { ret = sysdb_add_overrides_to_object(dom, dctx->res->msgs[c], NULL, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n"); return ret; } } } } } else { ret = sysdb_initgroups_with_views(cmdctx, dom, name, &dctx->res); } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache! [%d][%s]\n", ret, strerror(ret)); return EIO; } if (dctx->res->count == 0 && !dctx->check_provider) { /* set negative cache only if not result of cache check */ ret = sss_ncache_set_user(nctx->ncache, false, dom, name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s@%s\n", name, dom->name); } /* if a multidomain search, try with next */ if (cmdctx->check_next) { dom = get_next_domain(dom, 0); if (dom) continue; } DEBUG(SSSDBG_OP_FAILURE, "No results for initgroups call\n"); return ENOENT; } /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (dctx->check_provider) { if (cmdctx->name_is_upn) { extra_flag = EXTRA_NAME_IS_UPN; } else if (DOM_HAS_VIEWS(dom) && (dctx->res->count == 0 || ldb_msg_find_attr_as_string(dctx->res->msgs[0], OVERRIDE_PREFIX SYSDB_NAME, NULL) != NULL)) { extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; } else { extra_flag = NULL; } ret = check_cache(dctx, nctx, dctx->res, SSS_DP_INITGROUPS, name, 0, extra_flag, nss_cmd_getby_dp_callback, dctx); if (ret != EOK) { /* Anything but EOK means we should reenter the mainloop * because we may be refreshing the cache */ return ret; } } DEBUG(SSSDBG_TRACE_FUNC, "Initgroups for [%s@%s] completed\n", name, dom->name); return EOK; } DEBUG(SSSDBG_MINOR_FAILURE, "No matching domain found for [%s], fail!\n", cmdctx->name); return ENOENT; } /* for now, if we are online, try to always query the backend */ static int nss_cmd_initgroups(struct cli_ctx *cctx) { return nss_cmd_getbynam(SSS_NSS_INITGR, cctx); } static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct sss_domain_info *dom = dctx->domain; struct cli_ctx *cctx = cmdctx->cctx; struct sysdb_ctx *sysdb; struct nss_ctx *nctx; int ret; int err; const char *default_attrs[] = {SYSDB_NAME, SYSDB_OBJECTCLASS, SYSDB_SID_STR, ORIGINALAD_PREFIX SYSDB_NAME, ORIGINALAD_PREFIX SYSDB_UIDNUM, ORIGINALAD_PREFIX SYSDB_GIDNUM, ORIGINALAD_PREFIX SYSDB_GECOS, ORIGINALAD_PREFIX SYSDB_HOMEDIR, ORIGINALAD_PREFIX SYSDB_SHELL, SYSDB_UPN, SYSDB_DEFAULT_OVERRIDE_NAME, SYSDB_AD_ACCOUNT_EXPIRES, SYSDB_AD_USER_ACCOUNT_CONTROL, SYSDB_SSH_PUBKEY, SYSDB_ORIG_DN, SYSDB_ORIG_MEMBEROF, SYSDB_DEFAULT_ATTRS, NULL}; const char **attrs; bool user_found = false; bool group_found = false; struct ldb_message *msg = NULL; char *sysdb_name = NULL; char *name = NULL; char *req_name; uint32_t req_id; enum sss_dp_acct_type req_type; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); while (dom) { if (cmdctx->cmd == SSS_NSS_GETSIDBYID) { /* check that the uid is valid for this domain */ if ((dom->id_min && (cmdctx->id < dom->id_min)) || (dom->id_max && (cmdctx->id > dom->id_max))) { DEBUG(SSSDBG_TRACE_FUNC, "Uid [%"PRIu32"] does not exist in domain [%s]! " "(id out of range)\n", cmdctx->id, dom->name); if (cmdctx->check_next) { dom = get_next_domain(dom, SSS_GND_DESCEND); continue; } ret = ENOENT; goto done; } } else { /* if it is a domainless search, skip domains that require fully * qualified names instead */ while (dom && cmdctx->check_next && dom->fqnames) { dom = get_next_domain(dom, 0); } if (!dom) break; } if (dom != dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); } /* make sure to update the dctx if we changed domain */ dctx->domain = dom; if (cmdctx->cmd == SSS_NSS_GETSIDBYID) { DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for [%"PRIu32"@%s]\n", cmdctx->id, dom->name); ret = sss_ncache_check_uid(nctx->ncache, nctx->neg_timeout, dom, cmdctx->id); if (ret == EEXIST) { ret = sss_ncache_check_gid(nctx->ncache, nctx->neg_timeout, dom, cmdctx->id); if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "ID [%"PRIu32"] does not exist in [%s]! (negative cache)\n", cmdctx->id, dom->name); /* if a multidomain search, try with next, including * sub-domains */ if (cmdctx->check_next) { dom = get_next_domain(dom, SSS_GND_DESCEND); continue; } /* There are no further domains. */ ret = ENOENT; goto done; } } } else { talloc_free(name); talloc_zfree(sysdb_name); name = sss_get_cased_name(cmdctx, cmdctx->name, dom->case_sensitive); if (name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_get_cased_name failed.\n"); ret = ENOMEM; goto done; } name = sss_reverse_replace_space(dctx, name, nctx->rctx->override_space); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_reverse_replace_space failed\n"); ret = ENOMEM; goto done; } /* For subdomains a fully qualified name is needed for * sysdb_search_user_by_name and sysdb_search_group_by_name. */ if (IS_SUBDOMAIN(dom)) { sysdb_name = sss_tc_fqname(cmdctx, dom->names, dom, name); if (sysdb_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } } /* verify this name has not yet been negatively cached, as user * and groupm, or has been permanently filtered */ ret = sss_ncache_check_user(nctx->ncache, nctx->neg_timeout, dom, name); if (ret == EEXIST) { ret = sss_ncache_check_group(nctx->ncache, nctx->neg_timeout, dom, name); if (ret == EEXIST) { /* if neg cached, return we didn't find it */ DEBUG(SSSDBG_TRACE_FUNC, "SID [%s] does not exist in [%s]! (negative cache)\n", name, dom->name); /* if a multidomain search, try with next */ if (cmdctx->check_next) { dom = get_next_domain(dom, 0); continue; } /* There are no further domains or this was a * fully-qualified user request. */ ret = ENOENT; goto done; } } DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for [%s@%s]\n", name, dom->name); } sysdb = dom->sysdb; if (sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); ret = EIO; goto done; } attrs = default_attrs; if (cmdctx->cmd == SSS_NSS_GETORIGBYNAME && nctx->extra_attributes != NULL) { ret = add_strings_lists(cmdctx, default_attrs, nctx->extra_attributes, false, discard_const(&attrs)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_strings_lists failed.\n"); goto done; } } if (cmdctx->cmd == SSS_NSS_GETSIDBYID) { ret = sysdb_search_user_by_uid(cmdctx, dom, cmdctx->id, attrs, &msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); ret = EIO; goto done; } if (ret == EOK) { user_found = true; } else { talloc_free(msg); ret = sysdb_search_group_by_gid(cmdctx, dom, cmdctx->id, attrs, &msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); ret = EIO; goto done; } if (ret == EOK) { group_found = true; } } } else { ret = sysdb_search_user_by_name(cmdctx, dom, sysdb_name ? sysdb_name : name, attrs, &msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); ret = EIO; goto done; } if (ret == EOK) { user_found = true; } else { talloc_free(msg); ret = sysdb_search_group_by_name(cmdctx, dom, sysdb_name ? sysdb_name : name, attrs, &msg); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); ret = EIO; goto done; } if (ret == EOK) { group_found = true; } } } dctx->res = talloc_zero(cmdctx, struct ldb_result); if (dctx->res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); ret = ENOMEM; goto done; } if (user_found || group_found) { dctx->res->count = 1; dctx->res->msgs = talloc_array(dctx->res, struct ldb_message *, 1); if (dctx->res->msgs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } dctx->res->msgs[0] = talloc_steal(dctx->res, msg); } if (dctx->res->count == 0 && !dctx->check_provider) { if (cmdctx->cmd == SSS_NSS_GETSIDBYNAME || cmdctx->cmd == SSS_NSS_GETORIGBYNAME) { ret = sss_ncache_set_user(nctx->ncache, false, dom, name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s@%s\n", name, dom->name); } ret = sss_ncache_set_group(nctx->ncache, false, dom, name); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for %s@%s\n", name, dom->name); } } /* if a multidomain search, try with next */ if (cmdctx->check_next) { dom = get_next_domain(dom, SSS_GND_DESCEND); continue; } DEBUG(SSSDBG_OP_FAILURE, "No matching user or group found.\n"); ret = ENOENT; goto done; } /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (dctx->check_provider) { if (cmdctx->cmd == SSS_NSS_GETSIDBYID) { req_name = NULL; req_id = cmdctx->id; } else { req_name = name; req_id = 0; } if (user_found) { req_type = SSS_DP_USER; } else if (group_found) { req_type = SSS_DP_GROUP; } else { req_type = SSS_DP_USER_AND_GROUP; } ret = check_cache(dctx, nctx, dctx->res, req_type, req_name, req_id, NULL, nss_cmd_getby_dp_callback, dctx); if (ret != EOK) { /* Anything but EOK means we should reenter the mainloop * because we may be refreshing the cache */ goto done; } } /* One result found */ if (cmdctx->cmd == SSS_NSS_GETSIDBYID) { DEBUG(SSSDBG_TRACE_FUNC, "Returning info for id [%"PRIu32"@%s]\n", cmdctx->id, dom->name); } else { DEBUG(SSSDBG_TRACE_FUNC, "Returning info for user/group [%s@%s]\n", name, dom->name); } /* Success. Break from the loop and return EOK */ ret = EOK; goto done; } /* All domains were tried and none had the entry. */ ret = ENOENT; done: if (ret == ENOENT) { /* The entry was not found, need to set result in negative cache */ if (cmdctx->cmd == SSS_NSS_GETSIDBYID) { DEBUG(SSSDBG_MINOR_FAILURE, "No matching domain found for [%"PRIu32"], fail!\n", cmdctx->id); err = sss_ncache_set_uid(nctx->ncache, false, NULL, cmdctx->id); if (err != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negative cache for UID %"PRIu32"\n", cmdctx->id); } err = sss_ncache_set_gid(nctx->ncache, false, NULL, cmdctx->id); if (err != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negative cache for GID %"PRIu32"\n", cmdctx->id); } } else { DEBUG(SSSDBG_MINOR_FAILURE, "No matching domain found for [%s], fail!\n", cmdctx->name); } } return ret; } static errno_t nss_cmd_getbysid_search(struct nss_dom_ctx *dctx) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct sss_domain_info *dom = dctx->domain; struct cli_ctx *cctx = cmdctx->cctx; struct sysdb_ctx *sysdb; struct nss_ctx *nctx; int ret; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); DEBUG(SSSDBG_TRACE_FUNC, "Requesting info for [%s@%s]\n", cmdctx->secid, dom->name); sysdb = dom->sysdb; if (sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this " \ "domain!\n"); return EIO; } /* verify this user has not yet been negatively cached, * or has been permanently filtered */ ret = sss_ncache_check_sid(nctx->ncache, nctx->neg_timeout, cmdctx->secid); if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "SID [%s] does not exist! (negative cache)\n", cmdctx->secid); return ENOENT; } ret = sysdb_search_object_by_sid(cmdctx, dom, cmdctx->secid, NULL, &dctx->res); if (ret == ENOENT) { if (!dctx->check_provider) { DEBUG(SSSDBG_OP_FAILURE, "No results for getbysid call.\n"); /* set negative cache only if not result of cache check */ ret = sss_ncache_set_sid(nctx->ncache, false, cmdctx->secid); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negative cache for %s\n", cmdctx->secid); } return ENOENT; } dctx->res = talloc_zero(cmdctx, struct ldb_result); if (dctx->res == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } /* Fall through and call the backend */ } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); return EIO; } if (dctx->res->count > 1) { DEBUG(SSSDBG_FATAL_FAILURE, "getbysid call returned more than one " \ "result !?!\n"); return ENOENT; } /* if this is a caching provider (or if we haven't checked the cache * yet) then verify that the cache is uptodate */ if (dctx->check_provider) { ret = check_cache(dctx, nctx, dctx->res, SSS_DP_SECID, cmdctx->secid, 0, NULL, nss_cmd_getby_dp_callback, dctx); if (ret != EOK) { /* Anything but EOK means we should reenter the mainloop * because we may be refreshing the cache */ return ret; } } /* One result found */ DEBUG(SSSDBG_TRACE_FUNC, "Returning info for sid [%s@%s]\n", cmdctx->secid, dom->name); return EOK; } static errno_t find_sss_id_type(struct ldb_message *msg, bool mpg, enum sss_id_type *id_type) { size_t c; struct ldb_message_element *el; struct ldb_val *val = NULL; el = ldb_msg_find_element(msg, SYSDB_OBJECTCLASS); if (el == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Objectclass attribute not found.\n"); return EINVAL; } for (c = 0; c < el->num_values; c++) { val = &(el->values[c]); if (strncasecmp(SYSDB_USER_CLASS, (char *)val->data, val->length) == 0) { break; } } if (c == el->num_values) { *id_type = SSS_ID_TYPE_GID; } else { if (mpg) { *id_type = SSS_ID_TYPE_BOTH; } else { *id_type = SSS_ID_TYPE_UID; } } return EOK; } static errno_t fill_sid(struct sss_packet *packet, enum sss_id_type id_type, struct ldb_message *msg) { int ret; const char *sid_str; struct sized_string sid; uint8_t *body; size_t blen; size_t pctr = 0; sid_str = ldb_msg_find_attr_as_string(msg, SYSDB_SID_STR, NULL); if (sid_str == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing SID.\n"); return EINVAL; } to_sized_string(&sid, sid_str); ret = sss_packet_grow(packet, sid.len + 3* sizeof(uint32_t)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_packet_grow failed.\n"); return ret; } sss_packet_get_body(packet, &body, &blen); SAFEALIGN_SETMEM_UINT32(body, 1, &pctr); /* Num results */ SAFEALIGN_SETMEM_UINT32(body + pctr, 0, &pctr); /* reserved */ SAFEALIGN_COPY_UINT32(body + pctr, &id_type, &pctr); memcpy(&body[pctr], sid.str, sid.len); return EOK; } static errno_t process_attr_list(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char **attr_list, struct sized_string **_keys, struct sized_string **_vals, size_t *array_size, size_t *sum, size_t *found) { size_t c; size_t d; struct sized_string *keys; struct sized_string *vals; struct ldb_val *val; struct ldb_message_element *el; keys = *_keys; vals = *_vals; for (c = 0; attr_list[c] != NULL; c++) { el = ldb_msg_find_element(msg, attr_list[c]); if (el != NULL && el->num_values > 0) { if (el->num_values > 1) { *array_size += el->num_values; keys = talloc_realloc(mem_ctx, keys, struct sized_string, *array_size); vals = talloc_realloc(mem_ctx, vals, struct sized_string, *array_size); if (keys == NULL || vals == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); return ENOMEM; } } for (d = 0; d < el->num_values; d++) { to_sized_string(&keys[*found], attr_list[c]); *sum += keys[*found].len; val = &(el->values[d]); if (val == NULL || val->data == NULL || val->data[val->length] != '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected attribute value found for [%s].\n", attr_list[c]); return EINVAL; } to_sized_string(&vals[*found], (const char *)val->data); *sum += vals[*found].len; (*found)++; } } } *_keys = keys; *_vals = vals; return EOK; } static errno_t fill_orig(struct sss_packet *packet, struct resp_ctx *rctx, enum sss_id_type id_type, struct ldb_message *msg) { int ret; TALLOC_CTX *tmp_ctx; uint8_t *body; size_t blen; size_t pctr = 0; size_t c; size_t sum; size_t found; size_t array_size; size_t extra_attrs_count = 0; const char **extra_attrs_list = NULL; const char *orig_attr_list[] = {SYSDB_SID_STR, ORIGINALAD_PREFIX SYSDB_NAME, ORIGINALAD_PREFIX SYSDB_UIDNUM, ORIGINALAD_PREFIX SYSDB_GIDNUM, ORIGINALAD_PREFIX SYSDB_HOMEDIR, ORIGINALAD_PREFIX SYSDB_GECOS, ORIGINALAD_PREFIX SYSDB_SHELL, SYSDB_UPN, SYSDB_DEFAULT_OVERRIDE_NAME, SYSDB_AD_ACCOUNT_EXPIRES, SYSDB_AD_USER_ACCOUNT_CONTROL, SYSDB_SSH_PUBKEY, SYSDB_ORIG_DN, SYSDB_ORIG_MEMBEROF, NULL}; struct sized_string *keys; struct sized_string *vals; struct nss_ctx *nctx; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } nctx = talloc_get_type(rctx->pvt_ctx, struct nss_ctx); if (nctx->extra_attributes != NULL) { extra_attrs_list = nctx->extra_attributes; for(extra_attrs_count = 0; extra_attrs_list[extra_attrs_count] != NULL; extra_attrs_count++); } array_size = sizeof(orig_attr_list) + extra_attrs_count; keys = talloc_array(tmp_ctx, struct sized_string, array_size); vals = talloc_array(tmp_ctx, struct sized_string, array_size); if (keys == NULL || vals == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } sum = 0; found = 0; ret = process_attr_list(tmp_ctx, msg, orig_attr_list, &keys, &vals, &array_size, &sum, &found); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "process_attr_list failed.\n"); goto done; } if (extra_attrs_count != 0) { ret = process_attr_list(tmp_ctx, msg, extra_attrs_list, &keys, &vals, &array_size, &sum, &found); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "process_attr_list failed.\n"); goto done; } } ret = sss_packet_grow(packet, sum + 3 * sizeof(uint32_t)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_packet_grow failed.\n"); goto done; } sss_packet_get_body(packet, &body, &blen); SAFEALIGN_SETMEM_UINT32(body, 1, &pctr); /* Num results */ SAFEALIGN_SETMEM_UINT32(body + pctr, 0, &pctr); /* reserved */ SAFEALIGN_COPY_UINT32(body + pctr, &id_type, &pctr); for (c = 0; c < found; c++) { memcpy(&body[pctr], keys[c].str, keys[c].len); pctr+= keys[c].len; memcpy(&body[pctr], vals[c].str, vals[c].len); pctr+= vals[c].len; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t fill_name(struct sss_packet *packet, struct sss_domain_info *dom, enum sss_id_type id_type, bool apply_no_view, struct ldb_message *msg) { int ret; TALLOC_CTX *tmp_ctx = NULL; const char *orig_name = NULL; const char *cased_name; const char *fq_name; struct sized_string name; bool add_domain = (!IS_SUBDOMAIN(dom) && dom->fqnames); uint8_t *body; size_t blen; size_t pctr = 0; if (apply_no_view) { orig_name = ldb_msg_find_attr_as_string(msg, ORIGINALAD_PREFIX SYSDB_NAME, NULL); } else { if (DOM_HAS_VIEWS(dom)) { orig_name = ldb_msg_find_attr_as_string(msg, OVERRIDE_PREFIX SYSDB_NAME, NULL); if (orig_name != NULL && IS_SUBDOMAIN(dom)) { /* Override names are un-qualified */ add_domain = true; } } } if (orig_name == NULL) { orig_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); } if (orig_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing name.\n"); return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } cased_name= sss_get_cased_name(tmp_ctx, orig_name, dom->case_sensitive); if (cased_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_get_cased_name failed.\n"); ret = ENOMEM; goto done; } if (add_domain) { fq_name = sss_tc_fqname(tmp_ctx, dom->names, dom, cased_name); if (fq_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } to_sized_string(&name, fq_name); } else { to_sized_string(&name, cased_name); } ret = sss_packet_grow(packet, name.len + 3 * sizeof(uint32_t)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_packet_grow failed.\n"); goto done; } sss_packet_get_body(packet, &body, &blen); SAFEALIGN_SETMEM_UINT32(body, 1, &pctr); /* Num results */ SAFEALIGN_SETMEM_UINT32(body + pctr, 0, &pctr); /* reserved */ SAFEALIGN_COPY_UINT32(body + pctr, &id_type, &pctr); memcpy(&body[pctr], name.str, name.len); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t fill_id(struct sss_packet *packet, enum sss_id_type id_type, struct ldb_message *msg) { int ret; uint8_t *body; size_t blen; size_t pctr = 0; uint64_t tmp_id; uint32_t id; if (id_type == SSS_ID_TYPE_GID) { tmp_id = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0); } else { tmp_id = ldb_msg_find_attr_as_uint64(msg, SYSDB_UIDNUM, 0); } if (tmp_id == 0 || tmp_id >= UINT32_MAX) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid POSIX ID.\n"); return EINVAL; } id = (uint32_t) tmp_id; ret = sss_packet_grow(packet, 4 * sizeof(uint32_t)); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_packet_grow failed.\n"); return ret; } sss_packet_get_body(packet, &body, &blen); SAFEALIGN_SETMEM_UINT32(body, 1, &pctr); /* Num results */ SAFEALIGN_SETMEM_UINT32(body + pctr, 0, &pctr); /* reserved */ SAFEALIGN_COPY_UINT32(body + pctr, &id_type, &pctr); SAFEALIGN_COPY_UINT32(body + pctr, &id, &pctr); return EOK; } static errno_t nss_cmd_getbysid_send_reply(struct nss_dom_ctx *dctx) { struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct cli_ctx *cctx = cmdctx->cctx; int ret; enum sss_id_type id_type; if (dctx->res->count > 1) { return EINVAL; } else if (dctx->res->count == 0) { return ENOENT; } ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return EFAULT; } ret = find_sss_id_type(dctx->res->msgs[0], dctx->domain->mpg, &id_type); if (ret != 0) { DEBUG(SSSDBG_OP_FAILURE, "find_sss_id_type failed.\n"); return ret; } switch(cmdctx->cmd) { case SSS_NSS_GETNAMEBYSID: ret = fill_name(cctx->creq->out, dctx->domain, id_type, true, dctx->res->msgs[0]); break; case SSS_NSS_GETIDBYSID: ret = fill_id(cctx->creq->out, id_type, dctx->res->msgs[0]); break; case SSS_NSS_GETSIDBYNAME: case SSS_NSS_GETSIDBYID: ret = fill_sid(cctx->creq->out, id_type, dctx->res->msgs[0]); break; case SSS_NSS_GETORIGBYNAME: ret = fill_orig(cctx->creq->out, cctx->rctx, id_type, dctx->res->msgs[0]); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported request type.\n"); return EINVAL; } if (ret != EOK) { return ret; } sss_packet_set_error(cctx->creq->out, EOK); sss_cmd_done(cctx, cmdctx); return EOK; } static int nss_check_well_known_sid(struct nss_cmd_ctx *cmdctx) { const char *wk_name; const char *wk_dom_name; int ret; char *fq_name = NULL; struct sized_string name; uint8_t *body; size_t blen; struct cli_ctx *cctx; struct nss_ctx *nss_ctx; size_t pctr = 0; ret = well_known_sid_to_name(cmdctx->secid, &wk_dom_name, &wk_name); if (ret != EOK) { DEBUG(SSSDBG_TRACE_ALL, "SID [%s] is not a Well-Known SID.\n", cmdctx->secid); return ret; } if (cmdctx->cmd != SSS_NSS_GETNAMEBYSID) { DEBUG(SSSDBG_TRACE_ALL, "Well-Known SIDs can only be translated to names.\n"); return EINVAL; } if (wk_dom_name != NULL) { nss_ctx = talloc_get_type(cmdctx->cctx->rctx->pvt_ctx, struct nss_ctx); fq_name = sss_tc_fqname2(cmdctx, nss_ctx->global_names, wk_dom_name, wk_dom_name, wk_name); if (fq_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_tc_fqname2 failed.\n"); return ENOMEM; } to_sized_string(&name, fq_name); } else { to_sized_string(&name, wk_name); } cctx = cmdctx->cctx; ret = sss_packet_new(cctx->creq, name.len + 3 * sizeof(uint32_t), sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { talloc_free(fq_name); return ENOMEM; } sss_packet_get_body(cctx->creq->out, &body, &blen); SAFEALIGN_SETMEM_UINT32(body, 1, &pctr); /* num results */ SAFEALIGN_SETMEM_UINT32(body + pctr, 0, &pctr); /* reserved */ SAFEALIGN_SETMEM_UINT32(body + pctr, SSS_ID_TYPE_GID, &pctr); memcpy(&body[pctr], name.str, name.len); sss_packet_set_error(cctx->creq->out, EOK); sss_cmd_done(cctx, cmdctx); return EOK; } static int nss_cmd_getbysid(enum sss_cli_command cmd, struct cli_ctx *cctx) { struct tevent_req *req; struct nss_cmd_ctx *cmdctx; struct nss_dom_ctx *dctx; const char *sid_str; uint8_t *body; size_t blen; int ret; struct nss_ctx *nctx; enum idmap_error_code err; uint8_t *bin_sid = NULL; size_t bin_sid_length; if (cmd != SSS_NSS_GETNAMEBYSID && cmd != SSS_NSS_GETIDBYSID) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command type [%d][%s].\n", cmd, sss_cmd2str(cmd)); return EINVAL; } cmdctx = talloc_zero(cctx, struct nss_cmd_ctx); if (!cmdctx) { return ENOMEM; } cmdctx->cctx = cctx; cmdctx->cmd = cmd; dctx = talloc_zero(cmdctx, struct nss_dom_ctx); if (!dctx) { ret = ENOMEM; goto done; } dctx->cmdctx = cmdctx; /* get SID to query */ sss_packet_get_body(cctx->creq->in, &body, &blen); /* if not terminated fail */ if (body[blen -1] != '\0') { ret = EINVAL; goto done; } sid_str = (const char *) body; nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx); /* If the body isn't a SID, fail */ err = sss_idmap_sid_to_bin_sid(nctx->idmap_ctx, sid_str, &bin_sid, &bin_sid_length); sss_idmap_free_bin_sid(nctx->idmap_ctx, bin_sid); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_sid_to_bin_sid failed for [%s].\n", body); ret = EINVAL; goto done; } DEBUG(SSSDBG_TRACE_FUNC, "Running command [%d][%s] with SID [%s].\n", dctx->cmdctx->cmd, sss_cmd2str(dctx->cmdctx->cmd), sid_str); cmdctx->secid = talloc_strdup(cmdctx, sid_str); if (cmdctx->secid == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } ret = nss_check_well_known_sid(cmdctx); if (ret != ENOENT) { if (ret == EOK) { DEBUG(SSSDBG_TRACE_ALL, "SID [%s] is a Well-Known SID.\n", cmdctx->secid); } else { DEBUG(SSSDBG_OP_FAILURE, "nss_check_well_known_sid failed.\n"); } goto done; } ret = responder_get_domain_by_id(cctx->rctx, cmdctx->secid, &dctx->domain); if (ret == EAGAIN || ret == ENOENT) { req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, NULL); if (req == NULL) { ret = ENOMEM; } else { dctx->rawname = sid_str; tevent_req_set_callback(req, nss_cmd_getbyid_done, dctx); ret = EAGAIN; } goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "responder_get_domain_by_id failed.\n"); goto done; } DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%s] from [%s]\n", cmdctx->secid, dctx->domain->name); dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider); /* ok, find it ! */ ret = nss_cmd_getbysid_search(dctx); if (ret == EOK) { ret = nss_cmd_getbysid_send_reply(dctx); } done: return nss_cmd_done(cmdctx, ret); } static int nss_cmd_getsidbyname(struct cli_ctx *cctx) { return nss_cmd_getbynam(SSS_NSS_GETSIDBYNAME, cctx); } static int nss_cmd_getsidbyid(struct cli_ctx *cctx) { return nss_cmd_getbyid(SSS_NSS_GETSIDBYID, cctx); } static int nss_cmd_getnamebysid(struct cli_ctx *cctx) { return nss_cmd_getbysid(SSS_NSS_GETNAMEBYSID, cctx); } static int nss_cmd_getidbysid(struct cli_ctx *cctx) { return nss_cmd_getbysid(SSS_NSS_GETIDBYSID, cctx); } static int nss_cmd_getorigbyname(struct cli_ctx *cctx) { return nss_cmd_getbynam(SSS_NSS_GETORIGBYNAME, cctx); } struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version nss_cli_protocol_version[] = { {1, "2008-09-05", "initial version, \\0 terminated strings"}, {0, NULL, NULL} }; return nss_cli_protocol_version; } static struct sss_cmd_table nss_cmds[] = { {SSS_GET_VERSION, sss_cmd_get_version}, {SSS_NSS_GETPWNAM, nss_cmd_getpwnam}, {SSS_NSS_GETPWUID, nss_cmd_getpwuid}, {SSS_NSS_SETPWENT, nss_cmd_setpwent}, {SSS_NSS_GETPWENT, nss_cmd_getpwent}, {SSS_NSS_ENDPWENT, nss_cmd_endpwent}, {SSS_NSS_GETGRNAM, nss_cmd_getgrnam}, {SSS_NSS_GETGRGID, nss_cmd_getgrgid}, {SSS_NSS_SETGRENT, nss_cmd_setgrent}, {SSS_NSS_GETGRENT, nss_cmd_getgrent}, {SSS_NSS_ENDGRENT, nss_cmd_endgrent}, {SSS_NSS_INITGR, nss_cmd_initgroups}, {SSS_NSS_SETNETGRENT, nss_cmd_setnetgrent}, {SSS_NSS_GETNETGRENT, nss_cmd_getnetgrent}, {SSS_NSS_ENDNETGRENT, nss_cmd_endnetgrent}, {SSS_NSS_GETSERVBYNAME, nss_cmd_getservbyname}, {SSS_NSS_GETSERVBYPORT, nss_cmd_getservbyport}, {SSS_NSS_SETSERVENT, nss_cmd_setservent}, {SSS_NSS_GETSERVENT, nss_cmd_getservent}, {SSS_NSS_ENDSERVENT, nss_cmd_endservent}, {SSS_NSS_GETSIDBYNAME, nss_cmd_getsidbyname}, {SSS_NSS_GETSIDBYID, nss_cmd_getsidbyid}, {SSS_NSS_GETNAMEBYSID, nss_cmd_getnamebysid}, {SSS_NSS_GETIDBYSID, nss_cmd_getidbysid}, {SSS_NSS_GETORIGBYNAME, nss_cmd_getorigbyname}, {SSS_CLI_NULL, NULL} }; struct sss_cmd_table *get_nss_cmds(void) { return nss_cmds; } sssd-1.13.4/src/responder/nss/PaxHeaders.16287/nsssrv_services.h0000644000000000000000000000007412703456111021332 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.462792978 sssd-1.13.4/src/responder/nss/nsssrv_services.h0000644002412700241270000000210012703456111022772 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2012 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef NSSSRV_SERVICES_H_ #define NSSSRV_SERVICES_H_ int nss_cmd_getservbyname(struct cli_ctx *cctx); int nss_cmd_getservbyport(struct cli_ctx *cctx); int nss_cmd_setservent(struct cli_ctx *cctx); int nss_cmd_getservent(struct cli_ctx *cctx); int nss_cmd_endservent(struct cli_ctx *cctx); #endif /* NSSSRV_SERVICES_H_ */ sssd-1.13.4/src/responder/PaxHeaders.16287/pac0000644000000000000000000000013212703463557015612 xustar0030 mtime=1460561775.012794843 30 atime=1460561776.119798596 30 ctime=1460561775.012794843 sssd-1.13.4/src/responder/pac/0000755002412700241270000000000012703463557017343 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/responder/pac/PaxHeaders.16287/pacsrv_utils.c0000644000000000000000000000007412703456111020542 xustar0030 atime=1460561751.651715631 30 ctime=1460561775.012794843 sssd-1.13.4/src/responder/pac/pacsrv_utils.c0000644002412700241270000003431612703456111022220 0ustar00jhrozekjhrozek00000000000000/* SSSD PAC Responder - utility finctions Copyright (C) Sumit Bose 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "responder/pac/pacsrv.h" errno_t get_sids_from_pac(TALLOC_CTX *mem_ctx, struct pac_ctx *pac_ctx, struct PAC_LOGON_INFO *logon_info, char **_user_sid_str, char **_primary_group_sid_str, hash_table_t **_sid_table) { int ret; size_t s; struct netr_SamInfo3 *info3; struct sss_domain_info *user_dom; struct sss_domain_info *group_dom; char *sid_str = NULL; char *msid_str = NULL; char *user_dom_sid_str = NULL; size_t user_dom_sid_str_len; enum idmap_error_code err; hash_table_t *sid_table = NULL; hash_key_t key; hash_value_t value; char *rid_start; struct ldb_result *msg = NULL; char *user_sid_str = NULL; char *primary_group_sid_str = NULL; if (pac_ctx == NULL || logon_info == NULL || _sid_table == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing parameter.\n"); return EINVAL; } info3 = &logon_info->info3; ret = sss_hash_create(mem_ctx, info3->sidcount + info3->base.groups.count + 2, &sid_table); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); goto done; } key.type = HASH_KEY_STRING; value.type = HASH_VALUE_ULONG; err = sss_idmap_smb_sid_to_sid(pac_ctx->idmap_ctx, info3->base.domain_sid, &user_dom_sid_str); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_smb_sid_to_sid failed.\n"); ret = EFAULT; goto done; } ret = responder_get_domain_by_id(pac_ctx->rctx, user_dom_sid_str, &user_dom); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "responder_get_domain_by_id failed.\n"); ret = EINVAL; goto done; } user_dom_sid_str_len = strlen(user_dom_sid_str); sid_str = talloc_zero_size(mem_ctx, user_dom_sid_str_len + 12); if (sid_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n"); ret = ENOMEM; goto done; } rid_start = sid_str + user_dom_sid_str_len; memcpy(sid_str, user_dom_sid_str, user_dom_sid_str_len); memset(rid_start, '\0', 12); ret = snprintf(rid_start, 12, "-%lu", (unsigned long) info3->base.rid); if (ret < 0 || ret > 12) { DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); ret = EIO; goto done; } user_sid_str = talloc_strdup(mem_ctx, sid_str); if (user_sid_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } key.str = sid_str; value.ul = 0; ret = sysdb_search_object_by_sid(mem_ctx, user_dom, sid_str, NULL, &msg); if (ret == EOK && msg->count == 1) { value.ul = ldb_msg_find_attr_as_uint64(msg->msgs[0], SYSDB_UIDNUM, 0); } talloc_zfree(msg); ret = hash_enter(sid_table, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", ret, hash_error_string(ret)); ret = EIO; goto done; } memset(rid_start, '\0', 12); ret = snprintf(rid_start, 12, "-%lu", (unsigned long) info3->base.primary_gid); if (ret < 0 || ret > 12) { DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); ret = EIO; goto done; } primary_group_sid_str = talloc_strdup(mem_ctx, sid_str); if (primary_group_sid_str == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } key.str = sid_str; value.ul = 0; ret = sysdb_search_object_by_sid(mem_ctx, user_dom, sid_str, NULL, &msg); if (ret == EOK && msg->count == 1) { value.ul = ldb_msg_find_attr_as_uint64(msg->msgs[0], SYSDB_GIDNUM, 0); } talloc_zfree(msg); ret = hash_enter(sid_table, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", ret, hash_error_string(ret)); ret = EIO; goto done; } for (s = 0; s < info3->base.groups.count; s++) { memset(rid_start, '\0', 12); ret = snprintf(rid_start, 12, "-%lu", (unsigned long) info3->base.groups.rids[s].rid); if (ret < 0 || ret > 12) { DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); ret = EIO; goto done; } key.str = sid_str; value.ul = 0; ret = sysdb_search_object_by_sid(mem_ctx, user_dom, sid_str, NULL, &msg); if (ret == EOK && msg->count == 1) { value.ul = ldb_msg_find_attr_as_uint64(msg->msgs[0], SYSDB_GIDNUM, 0); } talloc_zfree(msg); ret = hash_enter(sid_table, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", ret, hash_error_string(ret)); ret = EIO; goto done; } } for(s = 0; s < info3->sidcount; s++) { err = sss_idmap_smb_sid_to_sid(pac_ctx->idmap_ctx, info3->sids[s].sid, &msid_str); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_smb_sid_to_sid failed.\n"); ret = EFAULT; goto done; } key.str = msid_str; value.ul = 0; ret = responder_get_domain_by_id(pac_ctx->rctx, msid_str, &group_dom); if (ret == EOK) { ret = sysdb_search_object_by_sid(mem_ctx, group_dom, msid_str, NULL, &msg); if (ret == EOK && msg->count == 1 ) { value.ul = ldb_msg_find_attr_as_uint64(msg->msgs[0], SYSDB_GIDNUM, 0); } talloc_zfree(msg); } ret = hash_enter(sid_table, &key, &value); sss_idmap_free_sid(pac_ctx->idmap_ctx, msid_str); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", ret, hash_error_string(ret)); ret = EIO; goto done; } } ret = EOK; done: talloc_free(sid_str); sss_idmap_free_sid(pac_ctx->idmap_ctx, user_dom_sid_str); if (ret == EOK) { *_sid_table = sid_table; *_user_sid_str = user_sid_str; *_primary_group_sid_str = primary_group_sid_str; } else { hash_destroy(sid_table); talloc_free(user_sid_str); talloc_free(primary_group_sid_str); } return ret; } /** * Extract the PAC logon data from an NDR blob. */ errno_t get_data_from_pac(TALLOC_CTX *mem_ctx, uint8_t *pac_blob, size_t pac_len, struct PAC_LOGON_INFO **_logon_info) { DATA_BLOB blob; struct ndr_pull *ndr_pull; struct PAC_DATA *pac_data; enum ndr_err_code ndr_err; size_t c; int ret; blob.data = pac_blob; blob.length = pac_len; ndr_pull = ndr_pull_init_blob(&blob, mem_ctx); if (ndr_pull == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_init_blob failed.\n"); return ENOMEM; } ndr_pull->flags |= LIBNDR_FLAG_REF_ALLOC; /* FIXME: is this really needed ? */ pac_data = talloc_zero(mem_ctx, struct PAC_DATA); if (pac_data == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } ndr_err = ndr_pull_PAC_DATA(ndr_pull, NDR_SCALARS|NDR_BUFFERS, pac_data); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_PAC_DATA failed [%d]\n", ndr_err); return EBADMSG; } for(c = 0; c < pac_data->num_buffers; c++) { if (pac_data->buffers[c].type == PAC_TYPE_LOGON_INFO) { *_logon_info = pac_data->buffers[c].info->logon_info.info; return EOK; } } ret = EINVAL; talloc_free(pac_data); return ret; } /** * Fill up the passwd struct with data from the PAC logon info */ errno_t get_pwd_from_pac(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, char *user_sid_str, char *primary_group_sid_str, hash_table_t *sid_table, struct PAC_LOGON_INFO *logon_info, struct passwd **_pwd, struct sysdb_attrs **_attrs) { struct passwd *pwd = NULL; struct sysdb_attrs *attrs = NULL; struct netr_SamBaseInfo *base_info; int ret; char *lname; char *uc_realm; char *upn; hash_key_t key; hash_value_t value; struct sss_nss_homedir_ctx homedir_ctx; pwd = talloc_zero(mem_ctx, struct passwd); if (pwd == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); return ENOMEM; } base_info = &logon_info->info3.base; if (base_info->account_name.size == 0) { DEBUG(SSSDBG_OP_FAILURE, "Missing account name in PAC.\n"); ret = EINVAL; goto done; } if (base_info->rid == 0) { DEBUG(SSSDBG_OP_FAILURE, "Missing user RID in PAC.\n"); ret = EINVAL; goto done; } /* To be compatible with winbind based lookups we have to use lower * case names only, effectively making the domain case-insenvitive. */ lname = sss_tc_utf8_str_tolower(pwd, base_info->account_name.string); if (lname == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_tc_utf8_str_tolower failed.\n"); ret = ENOMEM; goto done; } /* Subdomain use fully qualified names */ pwd->pw_name = sss_get_domain_name(pwd, lname, dom); if (!pwd->pw_name) { DEBUG(SSSDBG_OP_FAILURE, "talloc_sprintf failed.\n"); ret = ENOMEM; goto done; } key.type = HASH_KEY_STRING; key.str = user_sid_str; ret = hash_lookup(sid_table, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_lookup failed.\n"); ret = EIO; goto done; } if (value.type != HASH_VALUE_ULONG) { DEBUG(SSSDBG_OP_FAILURE, "Wrong value type.\n"); ret = EIO; goto done; } pwd->pw_uid = value.ul; if (IS_SUBDOMAIN(dom) || dom->mpg) { pwd->pw_gid = 0; /* We use MPGs for sub-domains */ } else { key.type = HASH_KEY_STRING; key.str = primary_group_sid_str; ret = hash_lookup(sid_table, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_lookup failed.\n"); ret = EIO; goto done; } if (value.type != HASH_VALUE_ULONG) { DEBUG(SSSDBG_OP_FAILURE, "Wrong value type.\n"); ret = EIO; goto done; } pwd->pw_gid = value.ul; } if (base_info->full_name.size != 0) { pwd->pw_gecos = talloc_strdup(pwd, base_info->full_name.string); if (pwd->pw_gecos == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } else { DEBUG(SSSDBG_OP_FAILURE, "Missing full name in PAC, gecos field will by empty.\n"); } /* Check if there is a special homedir template for sub-domains. If not a * fallback will be added by the NSS responder. */ if (IS_SUBDOMAIN(dom) && dom->subdomain_homedir) { ZERO_STRUCT(homedir_ctx); homedir_ctx.username = lname; homedir_ctx.uid = pwd->pw_uid; homedir_ctx.domain = dom->name; homedir_ctx.flatname = dom->flat_name; homedir_ctx.config_homedir_substr = dom->homedir_substr; pwd->pw_dir = expand_homedir_template(pwd, dom->subdomain_homedir, &homedir_ctx); if (pwd->pw_dir == NULL) { ret = ENOMEM; goto done; } } pwd->pw_shell = NULL; /* Using default */ attrs = sysdb_new_attrs(mem_ctx); if (attrs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); ret = ENOMEM; goto done; } uc_realm = get_uppercase_realm(mem_ctx, dom->name); if (uc_realm == NULL) { DEBUG(SSSDBG_OP_FAILURE, "get_uppercase_realm failed.\n"); ret = ENOMEM; goto done; } upn = talloc_asprintf(mem_ctx, "%s@%s", lname, uc_realm); talloc_free(uc_realm); if (upn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, upn); talloc_free(upn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } ret = sysdb_attrs_add_lc_name_alias(attrs, pwd->pw_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_lc_name_alias failed.\n"); goto done; } ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, user_sid_str); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } *_pwd = pwd; *_attrs = attrs; ret = EOK; done: if (ret != EOK) { talloc_free(pwd); } return ret; } sssd-1.13.4/src/responder/pac/PaxHeaders.16287/pacsrv.h0000644000000000000000000000007412703456111017327 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.471793008 sssd-1.13.4/src/responder/pac/pacsrv.h0000644002412700241270000000501212703456111020774 0ustar00jhrozekjhrozek00000000000000/* SSSD PAC Responder, header file Copyright (C) Sumit Bose 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __PACSRV_H__ #define __PACSRV_H__ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include #include "sbus/sssd_dbus.h" #include "responder/common/responder_packet.h" #include "responder/common/responder.h" #include "responder/common/responder_sbus.h" #include "lib/idmap/sss_idmap.h" #include "util/sss_nss.h" #include "db/sysdb.h" #define PAC_PACKET_MAX_RECV_SIZE 1024 struct getent_ctx; struct dom_sid; struct pac_ctx { struct resp_ctx *rctx; struct sss_idmap_ctx *idmap_ctx; struct dom_sid *my_dom_sid; struct local_mapping_ranges *range_map; }; struct grp_info { char *orig_dn; struct ldb_dn *dn; }; struct sss_cmd_table *get_pac_cmds(void); errno_t get_sids_from_pac(TALLOC_CTX *mem_ctx, struct pac_ctx *pac_ctx, struct PAC_LOGON_INFO *logon_info, char **_user_sid_str, char **_primary_group_sid_str, hash_table_t **_sid_table); errno_t get_data_from_pac(TALLOC_CTX *mem_ctx, uint8_t *pac_blob, size_t pac_len, struct PAC_LOGON_INFO **_logon_info); errno_t get_pwd_from_pac(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, char *user_sid_str, char *primary_group_sid_str, hash_table_t *sid_table, struct PAC_LOGON_INFO *logon_info, struct passwd **_pwd, struct sysdb_attrs **_attrs); #endif /* __PACSRV_H__ */ sssd-1.13.4/src/responder/pac/PaxHeaders.16287/pacsrv_cmd.c0000644000000000000000000000007412703456111020145 xustar0030 atime=1460561751.651715631 30 ctime=1460561775.011794839 sssd-1.13.4/src/responder/pac/pacsrv_cmd.c0000644002412700241270000010712212703456111021617 0ustar00jhrozekjhrozek00000000000000/* SSSD PAC Responder Copyright (C) Sumit Bose 2012 Jan Zeleny 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "responder/pac/pacsrv.h" #include "confdb/confdb.h" static errno_t pac_cmd_done(struct cli_ctx *cctx, int cmd_ret) { int ret; if (cmd_ret == EAGAIN) { /* async processing, just return here */ return EOK; } ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_packet_new failed [%d][%s].\n", ret, strerror(ret)); return ret; } sss_packet_set_error(cctx->creq->out, cmd_ret); sss_cmd_done(cctx, NULL); return EOK; } struct pac_req_ctx { struct cli_ctx *cctx; struct pac_ctx *pac_ctx; const char *domain_name; const char *user_name; struct sss_domain_info *dom; struct PAC_LOGON_INFO *logon_info; struct dom_sid2 *domain_sid; size_t del_grp_count; struct grp_info *del_grp_list; size_t add_sid_count; char **add_sids; hash_table_t *sid_table; char *user_sid_str; char *user_dom_sid_str; char *primary_group_sid_str; }; static errno_t pac_resolve_sids_next(struct pac_req_ctx *pr_ctx); static void pac_lookup_sids_done(struct tevent_req *req); static struct tevent_req *pac_lookup_sids_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct pac_req_ctx *pr_ctx, struct pac_ctx *pac_ctx, hash_table_t *sid_table); static errno_t pac_lookup_sids_recv(struct tevent_req *req); static void pac_add_user_next(struct pac_req_ctx *pr_ctx); static void pac_get_domains_done(struct tevent_req *req); static errno_t pac_user_get_grp_info(TALLOC_CTX *mem_ctx, struct pac_req_ctx *pr_ctx, size_t *_del_grp_count, struct grp_info **_del_grp_list, size_t *_add_sid_count, char ***_add_sids); static errno_t save_pac_user(struct pac_req_ctx *pr_ctx); static void pac_get_group_done(struct tevent_req *subreq); static errno_t pac_save_memberships_next(struct tevent_req *req); static errno_t pac_store_membership(struct pac_req_ctx *pr_ctx, struct ldb_dn *user_dn, const char *grp_sid_str, struct sss_domain_info *grp_dom); struct tevent_req *pac_save_memberships_send(struct pac_req_ctx *pr_ctx); static void pac_save_memberships_done(struct tevent_req *req); static errno_t pac_add_pac_user(struct cli_ctx *cctx) { int ret; uint8_t *body; size_t blen; struct pac_req_ctx *pr_ctx; struct tevent_req *req; enum idmap_error_code err; sss_packet_get_body(cctx->creq->in, &body, &blen); pr_ctx = talloc_zero(cctx, struct pac_req_ctx); if (pr_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } pr_ctx->cctx = cctx; pr_ctx->pac_ctx = talloc_get_type(cctx->rctx->pvt_ctx, struct pac_ctx); if (pr_ctx->pac_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Cannot find pac responder context.\n"); return EINVAL; } ret = get_data_from_pac(pr_ctx, body, blen, &pr_ctx->logon_info); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_data_from_pac failed.\n"); goto done; } pr_ctx->domain_name = pr_ctx->logon_info->info3.base.logon_domain.string; if (pr_ctx->domain_name == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "No domain name in PAC\n"); ret = EINVAL; goto done; } if (pr_ctx->logon_info->info3.base.account_name.string == NULL) { ret = EINVAL; DEBUG(SSSDBG_FATAL_FAILURE, "Missing account name in PAC.\n"); goto done; } /* To be compatible with winbind based lookups we have to use lower case * names only, effectively making the domain case-insenvitive. */ pr_ctx->user_name = sss_tc_utf8_str_tolower(pr_ctx, pr_ctx->logon_info->info3.base.account_name.string); if (pr_ctx->user_name == NULL) { ret = ENOMEM; DEBUG(SSSDBG_FATAL_FAILURE, "sss_tc_utf8_str_tolower failed.\n"); goto done; } err = sss_idmap_smb_sid_to_sid(pr_ctx->pac_ctx->idmap_ctx, pr_ctx->logon_info->info3.base.domain_sid, &pr_ctx->user_dom_sid_str); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_smb_sid_to_sid failed.\n"); ret = EFAULT; goto done; } talloc_steal(pr_ctx, pr_ctx->user_dom_sid_str); ret = responder_get_domain_by_id(cctx->rctx, pr_ctx->user_dom_sid_str, &pr_ctx->dom); if (ret == EAGAIN || ret == ENOENT) { req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, pr_ctx->domain_name); if (req == NULL) { ret = ENOMEM; } else { tevent_req_set_callback(req, pac_get_domains_done, pr_ctx); ret = EAGAIN; } goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "responder_get_domain_by_id failed.\n"); goto done; } ret = pac_resolve_sids_next(pr_ctx); done: if (ret != EAGAIN) { talloc_free(pr_ctx); } return pac_cmd_done(cctx, ret); } static void pac_get_domains_done(struct tevent_req *req) { struct pac_req_ctx *pr_ctx = tevent_req_callback_data(req, struct pac_req_ctx); struct cli_ctx *cctx = pr_ctx->cctx; int ret; ret = sss_dp_get_domains_recv(req); talloc_free(req); if (ret != EOK) { goto done; } ret = responder_get_domain_by_id(cctx->rctx, pr_ctx->user_dom_sid_str, &pr_ctx->dom); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Corresponding domain [%s] has not been " "found\n", pr_ctx->user_dom_sid_str); ret = ENOENT; goto done; } ret = pac_resolve_sids_next(pr_ctx); done: if (ret != EAGAIN) { talloc_free(pr_ctx); } pac_cmd_done(cctx, ret); } static errno_t pac_resolve_sids_next(struct pac_req_ctx *pr_ctx) { int ret; struct tevent_req *req; ret = get_sids_from_pac(pr_ctx, pr_ctx->pac_ctx, pr_ctx->logon_info, &pr_ctx->user_sid_str, &pr_ctx->primary_group_sid_str, &pr_ctx->sid_table); if (ret != 0) { DEBUG(SSSDBG_OP_FAILURE, "get_sids_from_pac failed.\n"); return ret; } req = pac_lookup_sids_send(pr_ctx, pr_ctx->cctx->ev, pr_ctx, pr_ctx->pac_ctx, pr_ctx->sid_table); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "pac_lookup_sids_send failed.\n"); return ENOMEM; } tevent_req_set_callback(req, pac_lookup_sids_done, pr_ctx); ret = EAGAIN; return ret; } static void pac_lookup_sids_done(struct tevent_req *req) { struct pac_req_ctx *pr_ctx = tevent_req_callback_data(req, struct pac_req_ctx); struct cli_ctx *cctx = pr_ctx->cctx; errno_t ret; unsigned long count; hash_entry_t *entries; hash_key_t key; hash_value_t value; size_t c; struct sss_domain_info *dom; uint64_t id; struct ldb_result *msg; ret = pac_lookup_sids_recv(req); talloc_zfree(req); if (ret != EOK) { talloc_free(pr_ctx); pac_cmd_done(cctx, ret); return; } key.type = HASH_KEY_STRING; value.type = HASH_VALUE_ULONG; ret = hash_entries(pr_ctx->sid_table, &count, &entries); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_entries failed [%d][%s].\n", ret, hash_error_string(ret)); talloc_free(pr_ctx); pac_cmd_done(cctx, ret); return; } for (c = 0; c < count; c++) { if (entries[c].value.ul == 0) { ret =responder_get_domain_by_id(cctx->rctx, entries[c].key.str, &dom); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "No domain found for SID [%s].\n", entries[c].key.str); continue; } msg = NULL; ret = sysdb_search_object_by_sid(pr_ctx, dom, entries[c].key.str, NULL, &msg); if (ret == ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "No entry found for SID [%s].\n", entries[c].key.str); continue; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_object_by_sid failed.\n"); continue; } if (msg->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "More then one result returned " \ "for SID [%s].\n", entries[c].key.str); talloc_free(msg); pac_cmd_done(cctx, EINVAL); return; } id = ldb_msg_find_attr_as_uint64(msg->msgs[0], SYSDB_UIDNUM, 0); if (id == 0) { id = ldb_msg_find_attr_as_uint64(msg->msgs[0], SYSDB_GIDNUM, 0); } if (id == 0) { DEBUG(SSSDBG_OP_FAILURE, "No ID found in entry.\n"); talloc_free(msg); continue; } key.str = entries[c].key.str; value.ul = id; ret = hash_enter(pr_ctx->sid_table, &key, &value); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", ret, hash_error_string(ret)); continue; } talloc_free(msg); } } pac_add_user_next(pr_ctx); } static void pac_add_user_next(struct pac_req_ctx *pr_ctx) { int ret; struct tevent_req *req; struct cli_ctx *cctx = pr_ctx->cctx; ret = save_pac_user(pr_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "save_pac_user failed.\n"); goto done; } ret = pac_user_get_grp_info(pr_ctx, pr_ctx, &pr_ctx->del_grp_count, &pr_ctx->del_grp_list, &pr_ctx->add_sid_count, &pr_ctx->add_sids); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "pac_user_get_grp_info failed.\n"); goto done; } req = pac_save_memberships_send(pr_ctx); if (req == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(req, pac_save_memberships_done, pr_ctx); ret = EAGAIN; done: if (ret != EAGAIN) { talloc_free(pr_ctx); } pac_cmd_done(cctx, ret); } static errno_t pac_user_get_grp_info(TALLOC_CTX *mem_ctx, struct pac_req_ctx *pr_ctx, size_t *_del_grp_count, struct grp_info **_del_grp_list, size_t *_add_sid_count, char ***_add_sids) { struct sysdb_ctx *sysdb; int ret; TALLOC_CTX *tmp_ctx = NULL; struct ldb_result *res = NULL; size_t c; const char *tmp_str; size_t add_sid_count = 0; char **add_sids = NULL; size_t del_idx; size_t del_grp_count = 0; struct grp_info *del_grp_list = NULL; const char *cur_sid; hash_key_t key; hash_value_t value; struct hash_iter_context_t *iter = NULL; hash_entry_t *entry; sysdb = pr_ctx->dom->sysdb; if (sysdb == NULL) { ret = EINVAL; DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); goto done; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); goto done; } ret = sysdb_initgroups(tmp_ctx, pr_ctx->dom, pr_ctx->user_name, &res); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_initgroups failed.\n"); goto done; } if (res->count == 0) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_initgroups did not found [%s].\n", pr_ctx->user_name); ret = ENOENT; goto done; } /* First result is the user entry then the groups follow */ if (res->count > 1) { del_grp_count = res->count - 1; del_grp_list = talloc_zero_array(tmp_ctx, struct grp_info, del_grp_count); if (del_grp_list == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } del_idx = 0; key.type = HASH_KEY_STRING; for (c = 0; c < (res->count - 1); c++) { cur_sid = ldb_msg_find_attr_as_string(res->msgs[c + 1], SYSDB_SID_STR, NULL); if (cur_sid == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing SID in group entry.\n"); ret = EINVAL; goto done; } key.str = discard_const(cur_sid); ret = hash_lookup(pr_ctx->sid_table, &key, &value); if (ret == HASH_SUCCESS) { DEBUG(SSSDBG_TRACE_ALL, "User [%s] already member of group " \ "with SID [%s].\n", pr_ctx->user_name, cur_sid); ret = hash_delete(pr_ctx->sid_table, &key); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Failed to remove hash entry.\n"); ret = EIO; goto done; } } else if (ret == HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_TRACE_INTERNAL, "Group with SID [%s] is not in " \ "the PAC anymore, membership " \ "must be removed.\n", cur_sid); tmp_str = ldb_msg_find_attr_as_string(res->msgs[c + 1], SYSDB_ORIG_DN, NULL); if (tmp_str != NULL) { del_grp_list[del_idx].orig_dn = talloc_strdup(del_grp_list, tmp_str); if (del_grp_list[del_idx].orig_dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } } del_grp_list[del_idx].dn = ldb_dn_copy(del_grp_list, res->msgs[c + 1]->dn); if (del_grp_list[del_idx].dn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_copy failed.\n"); ret = ENOMEM; goto done; } del_idx++; } } del_grp_count = del_idx; } add_sid_count = hash_count(pr_ctx->sid_table); if (add_sid_count > 0) { add_sids = talloc_array(tmp_ctx, char *, add_sid_count); if (add_sids == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } iter = new_hash_iter_context(pr_ctx->sid_table); c = 0; while ((entry = iter->next(iter)) != NULL) { if (strcmp(entry->key.str, pr_ctx->user_sid_str) != 0) { add_sids[c] = talloc_strdup(add_sids, entry->key.str); if (add_sids[c] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_ALL, "SID [%s] added to add_sids " \ "list.\n", entry->key.str); c++; } } add_sid_count = c; } *_del_grp_count = del_grp_count; *_del_grp_list = talloc_steal(mem_ctx, del_grp_list); *_add_sid_count = add_sid_count; *_add_sids = talloc_steal(mem_ctx, add_sids); ret = EOK; done: talloc_free(iter); talloc_free(tmp_ctx); return ret; } static errno_t save_pac_user(struct pac_req_ctx *pr_ctx) { struct sysdb_ctx *sysdb; int ret; const char *attrs[] = {SYSDB_NAME, SYSDB_NAME_ALIAS, SYSDB_UIDNUM, SYSDB_GIDNUM, SYSDB_GECOS, SYSDB_HOMEDIR, SYSDB_SHELL, SYSDB_ORIG_DN, SYSDB_CACHEDPWD, NULL}; struct ldb_message *msg; struct passwd *pwd = NULL; TALLOC_CTX *tmp_ctx = NULL; struct sysdb_attrs *user_attrs = NULL; sysdb = pr_ctx->dom->sysdb; if (sysdb == NULL) { ret = EINVAL; DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); goto done; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); goto done; } ret = get_pwd_from_pac(tmp_ctx, pr_ctx->dom, pr_ctx->user_sid_str, pr_ctx->primary_group_sid_str, pr_ctx->sid_table, pr_ctx->logon_info, &pwd, &user_attrs); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_pwd_from_pac failed.\n"); goto done; } ret = sysdb_search_user_by_uid(tmp_ctx, pr_ctx->dom, pwd->pw_uid, attrs, &msg); if (ret == ENOENT) { if (pwd->pw_gid == 0 && !pr_ctx->dom->mpg) { DEBUG(SSSDBG_CRIT_FAILURE, "Primary group RID from the PAC " "cannot be translated into a GID for " "user [%s]. Typically this happens " "when UIDs and GIDs are read from AD " "and the primary AD group does not " "have a GID assigned. Make sure the " "user is created by the ID provider " "before GSSAPI based authentication " "is used in this case.\n", pwd->pw_name); ret = EINVAL; goto done; } ret = sysdb_store_user(pr_ctx->dom, pwd->pw_name, NULL, pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell, NULL, user_attrs, NULL, pr_ctx->dom->user_timeout, 0); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_user failed [%d][%s].\n", ret, strerror(ret)); goto done; } } else if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_id failed.\n"); goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } struct pac_save_memberships_state { size_t sid_iter; struct ldb_dn *user_dn; struct pac_req_ctx *pr_ctx; }; static errno_t pac_save_memberships_delete(struct pac_save_memberships_state *state); struct tevent_req *pac_save_memberships_send(struct pac_req_ctx *pr_ctx) { struct pac_save_memberships_state *state; struct sss_domain_info *dom = pr_ctx->dom; struct tevent_req *req; errno_t ret; char *dom_name = NULL; struct ldb_message *msg; req = tevent_req_create(pr_ctx, &state, struct pac_save_memberships_state); if (req == NULL) { return NULL; } state->sid_iter = 0; dom_name = sss_get_domain_name(state, pr_ctx->user_name, dom); if (dom_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_sprintf failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_search_user_by_name(state, dom, dom_name, NULL, &msg); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_name failed " \ "[%d][%s].\n", ret, strerror(ret)); goto done; } state->user_dn = msg->dn; state->pr_ctx = pr_ctx; ret = pac_save_memberships_delete(state); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "pac_save_memberships_delete failed.\n"); goto done; } ret = pac_save_memberships_next(req); if (ret == EOK) { tevent_req_done(req); tevent_req_post(req, pr_ctx->cctx->ev); } done: talloc_free(dom_name); if (ret != EOK && ret != EAGAIN) { tevent_req_error(req, ret); tevent_req_post(req, pr_ctx->cctx->ev); } return req; } static errno_t pac_save_memberships_delete(struct pac_save_memberships_state *state) { int ret; int sret; size_t c; struct pac_req_ctx *pr_ctx; bool in_transaction = false; TALLOC_CTX *tmp_ctx; struct sysdb_attrs *user_attrs = NULL; pr_ctx = state->pr_ctx; if (pr_ctx->del_grp_count == 0) { return EOK; } if (pr_ctx->del_grp_list == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing group list.\n"); return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } ret = sysdb_transaction_start(pr_ctx->dom->sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_start failed.\n"); goto done; } in_transaction = true; for (c = 0; c < pr_ctx->del_grp_count; c++) { /* If there is a failure for one group we still try to remove the * remaining groups. */ ret = sysdb_mod_group_member(pr_ctx->dom, state->user_dn, pr_ctx->del_grp_list[c].dn, LDB_FLAG_MOD_DELETE); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_mod_group_member failed for " \ "user [%s] and group[%s].\n", ldb_dn_get_linearized(state->user_dn), ldb_dn_get_linearized( pr_ctx->del_grp_list[c].dn)); continue; } if (pr_ctx->del_grp_list[c].orig_dn != NULL) { user_attrs = sysdb_new_attrs(tmp_ctx); if (user_attrs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); continue; } ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF, pr_ctx->del_grp_list[c].orig_dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); continue; } ret = sysdb_set_entry_attr(pr_ctx->dom->sysdb, state->user_dn, user_attrs, LDB_FLAG_MOD_DELETE); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_entry_attr failed.\n"); continue; } talloc_free(user_attrs); } } ret = sysdb_transaction_commit(pr_ctx->dom->sysdb); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_commit failed.\n"); goto done; } in_transaction = false; ret = EOK; done: if (in_transaction) { sret = sysdb_transaction_cancel(pr_ctx->dom->sysdb); if (sret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_cancel failed.\n"); } } talloc_free(tmp_ctx); return ret; } static errno_t pac_save_memberships_next(struct tevent_req *req) { errno_t ret; char *sid; struct sss_domain_info *grp_dom; struct tevent_req *subreq; struct pac_save_memberships_state *state; struct pac_req_ctx *pr_ctx; state = tevent_req_data(req, struct pac_save_memberships_state); pr_ctx = state->pr_ctx; if (pr_ctx->add_sid_count == 0) { return EOK; } if (pr_ctx->add_sids == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing list of SIDs.\n"); return EINVAL; } while (state->sid_iter < pr_ctx->add_sid_count) { sid = pr_ctx->add_sids[state->sid_iter]; ret = responder_get_domain_by_id(pr_ctx->pac_ctx->rctx, sid, &grp_dom); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "responder_get_domain_by_id failed, " \ "will try next group\n"); state->sid_iter++; continue; } ret = pac_store_membership(state->pr_ctx, state->user_dn, sid, grp_dom); if (ret == EOK) { state->sid_iter++; continue; } else if (ret == ENOENT) { subreq = sss_dp_get_account_send(state, pr_ctx->cctx->rctx, grp_dom, true, SSS_DP_SECID, sid, 0, NULL); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, pac_get_group_done, req); return EAGAIN; } else { DEBUG(SSSDBG_OP_FAILURE, "pac_store_membership failed, " "trying next group.\n"); state->sid_iter++; continue; } } ret = EOK; done: return ret; } static void pac_get_group_done(struct tevent_req *subreq) { struct tevent_req *req; struct pac_save_memberships_state *state; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct pac_save_memberships_state); errno_t ret; dbus_uint16_t err_maj; dbus_uint32_t err_min; char *err_msg; char *sid; struct sss_domain_info *grp_dom; struct pac_req_ctx *pr_ctx = state->pr_ctx; ret = sss_dp_get_account_recv(req, subreq, &err_maj, &err_min, &err_msg); talloc_zfree(subreq); talloc_zfree(err_msg); if (ret != EOK) { goto error; } sid = pr_ctx->add_sids[state->sid_iter]; ret = responder_get_domain_by_id(pr_ctx->pac_ctx->rctx,sid, &grp_dom); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "responder_get_domain_by_id failed.\n"); goto error; } ret = pac_store_membership(state->pr_ctx, state->user_dn, sid, grp_dom); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "pac_store_membership failed, " "trying next group.\n"); } state->sid_iter++; ret = pac_save_memberships_next(req); if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { goto error; } return; error: tevent_req_error(req, ret); } static errno_t pac_store_membership(struct pac_req_ctx *pr_ctx, struct ldb_dn *user_dn, const char *grp_sid_str, struct sss_domain_info *grp_dom) { TALLOC_CTX *tmp_ctx; struct sysdb_attrs *user_attrs; struct ldb_result *group; errno_t ret; const char *orig_group_dn; const char *group_attrs[] = { SYSDB_ORIG_DN, SYSDB_OBJECTCLASS, NULL }; const char *oc; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = sysdb_search_object_by_sid(tmp_ctx, grp_dom, grp_sid_str, group_attrs, &group); if (ret == ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Unexpected number of groups returned.\n"); goto done; } else if (ret != EOK) { DEBUG(SSSDBG_TRACE_INTERNAL, "sysdb_search_object_by_sid for SID [%s] failed [%d][%s].\n", grp_sid_str, ret, strerror(ret)); goto done; } if (group->count != 1) { DEBUG(SSSDBG_OP_FAILURE, "Unexpected number of groups returned.\n"); ret = EINVAL; goto done; } oc = ldb_msg_find_attr_as_string(group->msgs[0], SYSDB_OBJECTCLASS, NULL); if (oc == NULL || strcmp(oc, SYSDB_GROUP_CLASS) != 0) { DEBUG(SSSDBG_OP_FAILURE, "Return object does not have group " \ "objectclass.\n"); ret = EINVAL; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Adding user [%s] to group [%s][%s].\n", ldb_dn_get_linearized(user_dn), grp_sid_str, ldb_dn_get_linearized(group->msgs[0]->dn)); ret = sysdb_mod_group_member(grp_dom, user_dn, group->msgs[0]->dn, LDB_FLAG_MOD_ADD); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_mod_group_member failed user [%s] " \ "group [%s].\n", ldb_dn_get_linearized(user_dn), ldb_dn_get_linearized(group->msgs[0]->dn)); goto done; } orig_group_dn = ldb_msg_find_attr_as_string(group->msgs[0], SYSDB_ORIG_DN, NULL); if (orig_group_dn != NULL) { DEBUG(SSSDBG_TRACE_ALL, "Adding original group DN [%s] to user [%s].\n", orig_group_dn, ldb_dn_get_linearized(user_dn)); user_attrs = sysdb_new_attrs(tmp_ctx); if (user_attrs == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); ret = ENOMEM; goto done; } ret = sysdb_attrs_add_string(user_attrs, SYSDB_ORIG_MEMBEROF, orig_group_dn); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_string failed.\n"); goto done; } ret = sysdb_set_entry_attr(pr_ctx->dom->sysdb, user_dn, user_attrs, LDB_FLAG_MOD_ADD); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_entry_attr failed.\n"); goto done; } } else { DEBUG(SSSDBG_MINOR_FAILURE, "Original DN not available for group " \ "[%s][%s].\n", grp_sid_str, ldb_dn_get_linearized(group->msgs[0]->dn)); } done: talloc_free(tmp_ctx); return ret; } static errno_t pac_save_memberships_recv(struct tevent_req *subreq) { TEVENT_REQ_RETURN_ON_ERROR(subreq); return EOK; } static void pac_save_memberships_done(struct tevent_req *req) { struct pac_req_ctx *pr_ctx = tevent_req_callback_data(req, struct pac_req_ctx); struct cli_ctx *cctx = pr_ctx->cctx; errno_t ret; ret = pac_save_memberships_recv(req); talloc_zfree(req); talloc_free(pr_ctx); pac_cmd_done(cctx, ret); } struct pac_lookup_sids_state { struct pac_ctx *pac_ctx; struct pac_req_ctx *pr_ctx; hash_table_t *sid_table; struct hash_iter_context_t *iter; }; static errno_t pac_lookup_sids_next(struct tevent_req *req); static void pac_lookup_sids_next_done(struct tevent_req *subreq); static struct tevent_req *pac_lookup_sids_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct pac_req_ctx *pr_ctx, struct pac_ctx *pac_ctx, hash_table_t *sid_table) { struct tevent_req *req; struct pac_lookup_sids_state *state; int ret; req = tevent_req_create(mem_ctx, &state, struct pac_lookup_sids_state); if (req == NULL) { return NULL; } state->pac_ctx = pac_ctx; state->pr_ctx = pr_ctx; state->sid_table = sid_table; state->iter = talloc_steal(state, new_hash_iter_context(state->sid_table)); ret = pac_lookup_sids_next(req); if (ret != EAGAIN) { if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); } return req; } static errno_t pac_lookup_sids_next(struct tevent_req *req) { struct pac_lookup_sids_state *state; state = tevent_req_data(req, struct pac_lookup_sids_state); hash_entry_t *entry; struct tevent_req *subreq; struct sss_domain_info *dom; int ret; while ((entry = state->iter->next(state->iter)) != NULL) { if (entry->value.ul == 0) { ret = responder_get_domain_by_id(state->pac_ctx->rctx, entry->key.str, &dom); if (ret == EOK && dom != NULL) { subreq = sss_dp_get_account_send(state, state->pr_ctx->cctx->rctx, dom, true, SSS_DP_SECID, entry->key.str, 0, NULL); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, pac_lookup_sids_next_done, req); return EAGAIN; } } } return EOK; } static void pac_lookup_sids_next_done(struct tevent_req *subreq) { struct tevent_req *req; req = tevent_req_callback_data(subreq, struct tevent_req); errno_t ret; dbus_uint16_t err_maj; dbus_uint32_t err_min; char *err_msg; ret = sss_dp_get_account_recv(req, subreq, &err_maj, &err_min, &err_msg); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get information from Data Provider\n" "dp_error: [%u], errno: [%u], error_msg: [%s]\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg ? err_msg : "none"); } talloc_zfree(subreq); talloc_zfree(err_msg); /* Errors during individual lookups are ignored. */ ret = pac_lookup_sids_next(req); if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } static errno_t pac_lookup_sids_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version pac_cli_protocol_version[] = { {1, "2011-04-12", "initial version"}, {0, NULL, NULL} }; return pac_cli_protocol_version; } static struct sss_cmd_table pac_cmds[] = { {SSS_GET_VERSION, sss_cmd_get_version}, {SSS_PAC_ADD_PAC_USER, pac_add_pac_user}, {SSS_CLI_NULL, NULL} }; struct sss_cmd_table *get_pac_cmds(void) { return pac_cmds; } sssd-1.13.4/src/responder/pac/PaxHeaders.16287/pacsrv.c0000644000000000000000000000007412703456111017322 xustar0030 atime=1460561751.651715631 30 ctime=1460561775.010794836 sssd-1.13.4/src/responder/pac/pacsrv.c0000644002412700241270000001757412703456111021007 0ustar00jhrozekjhrozek00000000000000/* SSSD PAC Responder Copyright (C) Sumit Bose 2011 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "responder/pac/pacsrv.h" #include "db/sysdb.h" #include "confdb/confdb.h" #include "sbus/sssd_dbus.h" #include "responder/common/responder_packet.h" #include "responder/common/responder.h" #include "providers/data_provider.h" #include "monitor/monitor_interfaces.h" #include "sbus/sbus_client.h" #include "util/util_sss_idmap.h" #define SSS_PAC_PIPE_NAME "pac" #define DEFAULT_PAC_FD_LIMIT 8192 #define DEFAULT_ALLOWED_UIDS "0" struct mon_cli_iface monitor_pac_methods = { { &mon_cli_iface_meta, 0 }, .ping = monitor_common_pong, .resInit = monitor_common_res_init, .shutDown = NULL, .goOffline = NULL, .resetOffline = NULL, .rotateLogs = responder_logrotate, .clearMemcache = NULL, .clearEnumCache = NULL, .sysbusReconnect = NULL, }; static struct data_provider_iface pac_dp_methods = { { &data_provider_iface_meta, 0 }, .RegisterService = NULL, .pamHandler = NULL, .sudoHandler = NULL, .autofsHandler = NULL, .hostHandler = NULL, .getDomains = NULL, .getAccountInfo = NULL, }; /* TODO: check if this can be made generic for all responders */ static void pac_dp_reconnect_init(struct sbus_connection *conn, int status, void *pvt) { struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn); int ret; /* Did we reconnect successfully? */ if (status == SBUS_RECONNECT_SUCCESS) { DEBUG(SSSDBG_OP_FAILURE, "Reconnected to the Data Provider.\n"); /* Identify ourselves to the data provider */ ret = dp_common_send_id(be_conn->conn, DATA_PROVIDER_VERSION, "PAC"); /* all fine */ if (ret == EOK) { handle_requests_after_reconnect(be_conn->rctx); return; } } /* Failed to reconnect */ DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n", be_conn->domain->name); /* FIXME: kill the frontend and let the monitor restart it ? */ /* nss_shutdown(rctx); */ } int pac_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb) { struct resp_ctx *rctx; struct sss_cmd_table *pac_cmds; struct be_conn *iter; struct pac_ctx *pac_ctx; int ret, max_retries; enum idmap_error_code err; int fd_limit; char *uid_str; pac_cmds = get_pac_cmds(); ret = sss_process_init(mem_ctx, ev, cdb, pac_cmds, SSS_PAC_SOCKET_NAME, -1, NULL, -1, CONFDB_PAC_CONF_ENTRY, PAC_SBUS_SERVICE_NAME, PAC_SBUS_SERVICE_VERSION, &monitor_pac_methods, "PAC", &pac_dp_methods.vtable, &rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n"); return ret; } pac_ctx = talloc_zero(rctx, struct pac_ctx); if (!pac_ctx) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing pac_ctx\n"); ret = ENOMEM; goto fail; } pac_ctx->rctx = rctx; pac_ctx->rctx->pvt_ctx = pac_ctx; ret = confdb_get_string(pac_ctx->rctx->cdb, pac_ctx->rctx, CONFDB_PAC_CONF_ENTRY, CONFDB_SERVICE_ALLOWED_UIDS, DEFAULT_ALLOWED_UIDS, &uid_str); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get allowed UIDs.\n"); goto fail; } ret = csv_string_to_uid_array(pac_ctx->rctx, uid_str, true, &pac_ctx->rctx->allowed_uids_count, &pac_ctx->rctx->allowed_uids); talloc_free(uid_str); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set allowed UIDs.\n"); goto fail; } /* Enable automatic reconnection to the Data Provider */ ret = confdb_get_int(pac_ctx->rctx->cdb, CONFDB_PAC_CONF_ENTRY, CONFDB_SERVICE_RECON_RETRIES, 3, &max_retries); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up automatic reconnection\n"); goto fail; } for (iter = pac_ctx->rctx->be_conns; iter; iter = iter->next) { sbus_reconnect_init(iter->conn, max_retries, pac_dp_reconnect_init, iter); } err = sss_idmap_init(sss_idmap_talloc, pac_ctx, sss_idmap_talloc_free, &pac_ctx->idmap_ctx); if (err != IDMAP_SUCCESS) { DEBUG(SSSDBG_FATAL_FAILURE, "sss_idmap_init failed.\n"); ret = EFAULT; goto fail; } /* Set up file descriptor limits */ ret = confdb_get_int(pac_ctx->rctx->cdb, CONFDB_PAC_CONF_ENTRY, CONFDB_SERVICE_FD_LIMIT, DEFAULT_PAC_FD_LIMIT, &fd_limit); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up file descriptor limit\n"); goto fail; } responder_set_fd_limit(fd_limit); ret = schedule_get_domains_task(rctx, rctx->ev, rctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "PAC Initialization complete\n"); return EOK; fail: talloc_free(rctx); return ret; } int main(int argc, const char *argv[]) { int opt; poptContext pc; struct main_context *main_ctx; int ret; uid_t uid; gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; /* Set debug level to invalid value so we can decide if -d 0 was used. */ debug_level = SSSDBG_INVALID; umask(DFL_RSP_UMASK); pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_INIT(debug_level); /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_pac"; ret = server_setup("sssd[pac]", 0, uid, gid, CONFDB_PAC_CONF_ENTRY, &main_ctx); if (ret != EOK) return 2; ret = die_if_parent_died(); if (ret != EOK) { /* This is not fatal, don't return */ DEBUG(SSSDBG_OP_FAILURE, "Could not set up to exit when parent process does\n"); } ret = pac_process_init(main_ctx, main_ctx->event_ctx, main_ctx->confdb_ctx); if (ret != EOK) return 3; /* loop on main */ server_loop(main_ctx); return 0; } sssd-1.13.4/src/responder/PaxHeaders.16287/ifp0000644000000000000000000000013212703463557015625 xustar0030 mtime=1460561775.060795005 30 atime=1460561776.119798596 30 ctime=1460561775.060795005 sssd-1.13.4/src/responder/ifp/0000755002412700241270000000000012703463557017356 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_components.h0000644000000000000000000000007412703456111021067 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.484793052 sssd-1.13.4/src/responder/ifp/ifp_components.h0000644002412700241270000000604112703456111022537 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _IFP_COMPONENTS_H_ #define _IFP_COMPONENTS_H_ #include "responder/ifp/ifp_iface_generated.h" #include "responder/ifp/ifp_private.h" #define IFP_PATH_COMPONENTS IFP_PATH "/Components" #define IFP_PATH_COMPONENTS_TREE IFP_PATH_COMPONENTS SBUS_SUBTREE_SUFFIX /* org.freedesktop.sssd.infopipe */ int ifp_list_components(struct sbus_request *dbus_req, void *data); int ifp_list_responders(struct sbus_request *dbus_req, void *data); int ifp_list_backends(struct sbus_request *dbus_req, void *data); int ifp_find_monitor(struct sbus_request *dbus_req, void *data); int ifp_find_responder_by_name(struct sbus_request *dbus_req, void *data, const char *arg_name); int ifp_find_backend_by_name(struct sbus_request *dbus_req, void *data, const char *arg_name); /* org.freedesktop.sssd.infopipe.Components */ int ifp_component_enable(struct sbus_request *dbus_req, void *data); int ifp_component_disable(struct sbus_request *dbus_req, void *data); int ifp_component_change_debug_level(struct sbus_request *dbus_req, void *data, uint32_t arg_new_level); int ifp_component_change_debug_level_tmp(struct sbus_request *dbus_req, void *data, uint32_t arg_new_level); void ifp_component_get_name(struct sbus_request *dbus_req, void *data, const char **_out); void ifp_component_get_debug_level(struct sbus_request *dbus_req, void *data, uint32_t *_out); void ifp_component_get_enabled(struct sbus_request *dbus_req, void *data, bool *_out); void ifp_component_get_type(struct sbus_request *dbus_req, void *data, const char **_out); /* org.freedesktop.sssd.infopipe.Components.Backends */ void ifp_backend_get_providers(struct sbus_request *dbus_req, void *data, const char ***_out, int *_out_len); #endif /* _IFP_COMPONENTS_H_ */ sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_components.c0000644000000000000000000000007412703456111021062 xustar0030 atime=1460561751.650715627 30 ctime=1460561775.005794819 sssd-1.13.4/src/responder/ifp/ifp_components.c0000644002412700241270000006366612703456111022552 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "config.h" #include "confdb/confdb.h" #include "util/util.h" #include "responder/common/responder.h" #include "responder/ifp/ifp_components.h" #ifdef HAVE_CONFIG_LIB #include "util/sss_config.h" #endif #define PATH_MONITOR IFP_PATH_COMPONENTS "/monitor" #define PATH_RESPONDERS IFP_PATH_COMPONENTS "/Responders" #define PATH_BACKENDS IFP_PATH_COMPONENTS "/Backends" enum component_type { COMPONENT_MONITOR, COMPONENT_RESPONDER, COMPONENT_BACKEND }; static bool responder_exists(const char *name) { const char * const *svc = get_known_services(); int i; for (i = 0; svc[i] != NULL; i++) { if (strcmp(svc[i], name) == 0) { return true; } } return false; } static bool backend_exists(struct confdb_ctx *confdb, const char *name) { char **names = NULL; errno_t ret; int i; ret = confdb_list_all_domain_names(NULL, confdb, &names); if (ret != EOK) { return false; } for (i = 0; names[i] != NULL; i++) { if (strcmp(names[i], name) == 0) { return true; } } return false; } static errno_t check_and_get_component_from_path(TALLOC_CTX *mem_ctx, struct confdb_ctx *confdb, const char *path, enum component_type *_type, char **_name) { enum component_type type; char *name = NULL; errno_t ret; if (confdb == NULL || path == NULL) { return EINVAL; } if (strcmp(path, PATH_MONITOR) == 0) { type = COMPONENT_MONITOR; name = talloc_strdup(mem_ctx, "monitor"); if (name == NULL) { ret = ENOMEM; goto done; } } else { name = sbus_opath_get_object_name(mem_ctx, path, PATH_RESPONDERS); if (name != NULL) { type = COMPONENT_RESPONDER; } else { name = sbus_opath_get_object_name(mem_ctx, path, PATH_BACKENDS); if (name != NULL) { type = COMPONENT_BACKEND; } else { ret = EINVAL; goto done; } } } if (strchr(name, '/') != NULL) { ret = EINVAL; goto done; } switch (type) { case COMPONENT_MONITOR: /* noop */ break; case COMPONENT_RESPONDER: if (!responder_exists(name)) { ret = ENOENT; goto done; } break; case COMPONENT_BACKEND: if (!backend_exists(confdb, name)) { ret = ENOENT; goto done; } break; } if (_type != NULL) { *_type = type; } if (_name != NULL) { *_name = name; } ret = EOK; done: if (ret != EOK) { talloc_free(name); } return ret; } static errno_t change_debug_level_tmp(struct confdb_ctx *confdb, const char *name, enum component_type type, uint32_t level) { TALLOC_CTX *tmp_ctx = NULL; const char *confdb_path = NULL; const char **values = NULL; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } switch (type) { case COMPONENT_MONITOR: confdb_path = CONFDB_MONITOR_CONF_ENTRY; break; case COMPONENT_RESPONDER: confdb_path = talloc_asprintf(tmp_ctx, CONFDB_SERVICE_PATH_TMPL, name); break; case COMPONENT_BACKEND: confdb_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, name); break; } if (confdb_path == NULL) { ret = ENOMEM; goto done; } values = talloc_zero_array(tmp_ctx, const char*, 2); if (values == NULL) { ret = ENOMEM; goto done; } values[0] = talloc_asprintf(tmp_ctx, "0x%.4x", level); if (values[0] == NULL) { ret = ENOMEM; goto done; } ret = confdb_add_param(confdb, true, confdb_path, CONFDB_SERVICE_DEBUG_LEVEL, values); if (ret != EOK) { goto done; } /* reload the configuration */ if (kill(getppid(), SIGHUP) != 0) { ret = errno; goto done; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } static errno_t list_responders(TALLOC_CTX *mem_ctx, const char ***_list, int *_num) { const char **list = NULL; const char * const *svc = get_known_services(); errno_t ret; int num; int i; for (num = 0; svc[num] != NULL; num++); list = talloc_array(mem_ctx, const char*, num); if (list == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < num; i++) { list[i] = sbus_opath_compose(list, PATH_RESPONDERS, svc[i]); if (list[i] == NULL) { ret = ENOMEM; goto done; } } *_num = num; *_list = list; ret = EOK; done: if (ret != EOK) { talloc_free(list); } return ret; } static errno_t list_backends(TALLOC_CTX *mem_ctx, struct confdb_ctx *confdb, const char ***_list, int *_num) { TALLOC_CTX *tmp_ctx = NULL; const char **list = NULL; char **names = NULL; errno_t ret; int num; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = confdb_list_all_domain_names(tmp_ctx, confdb, &names); if (ret != EOK) { goto done; } for (num = 0; names[num] != NULL; num++); list = talloc_array(tmp_ctx, const char*, num); if (list == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < num; i++) { list[i] = sbus_opath_compose(list, PATH_BACKENDS, names[i]); if (list[i] == NULL) { ret = ENOMEM; goto done; } } *_num = num; *_list = talloc_steal(mem_ctx, list); ret = EOK; done: talloc_free(tmp_ctx); return ret; } int ifp_list_components(struct sbus_request *dbus_req, void *data) { struct ifp_ctx *ctx = NULL; DBusError *error = NULL; const char **responders = NULL; const char **backends = NULL; const char **result = NULL; int num_responders; int num_backends; int num; int i; errno_t ret; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); ret = EINVAL; goto done; } ret = list_responders(dbus_req, &responders, &num_responders); if (ret != EOK) { goto done; } ret = list_backends(dbus_req, ctx->rctx->cdb, &backends, &num_backends); if (ret != EOK) { goto done; } num = num_responders + num_backends + 1; result = talloc_array(dbus_req, const char*, num); if (result == NULL) { ret = ENOMEM; goto done; } result[0] = PATH_MONITOR; for (i = 0; i < num_responders; i++) { result[i + 1] = talloc_steal(result, responders[i]); } for (i = 0; i < num_backends; i++) { result[i + num_responders + 1] = talloc_steal(result, backends[i]); } ret = EOK; done: if (ret != EOK) { error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret)); return sbus_request_fail_and_finish(dbus_req, error); } return iface_ifp_ListComponents_finish(dbus_req, result, num); } int ifp_list_responders(struct sbus_request *dbus_req, void *data) { DBusError *error = NULL; const char **result = NULL; int num; errno_t ret; ret = list_responders(dbus_req, &result, &num); if (ret != EOK) { error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret)); return sbus_request_fail_and_finish(dbus_req, error); } return iface_ifp_ListResponders_finish(dbus_req, result, num); } int ifp_list_backends(struct sbus_request *dbus_req, void *data) { struct ifp_ctx *ctx = NULL; DBusError *error = NULL; const char **result = NULL; int num; errno_t ret; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); ret = EINVAL; goto done; } ret = list_backends(dbus_req, ctx->rctx->cdb, &result, &num); done: if (ret != EOK) { error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret)); return sbus_request_fail_and_finish(dbus_req, error); } return iface_ifp_ListBackends_finish(dbus_req, result, num); } int ifp_find_monitor(struct sbus_request *dbus_req, void *data) { return iface_ifp_FindMonitor_finish(dbus_req, PATH_MONITOR); } int ifp_find_responder_by_name(struct sbus_request *dbus_req, void *data, const char *arg_name) { DBusError *error = NULL; const char *result = NULL; if (responder_exists(arg_name)) { result = sbus_opath_compose(dbus_req, PATH_RESPONDERS, arg_name); if (result == NULL) { return sbus_request_fail_and_finish(dbus_req, NULL); } } else { error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "Responder \"%s\" does not exist", arg_name); return sbus_request_fail_and_finish(dbus_req, error); } return iface_ifp_FindResponderByName_finish(dbus_req, result); } int ifp_find_backend_by_name(struct sbus_request *dbus_req, void *data, const char *arg_name) { struct ifp_ctx *ctx = NULL; DBusError *error = NULL; const char *result = NULL; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s\n", strerror(EINVAL)); return sbus_request_fail_and_finish(dbus_req, error); } if (backend_exists(ctx->rctx->cdb, arg_name)) { result = sbus_opath_compose(dbus_req, PATH_BACKENDS, arg_name); if (result == NULL) { return sbus_request_fail_and_finish(dbus_req, NULL); } } else { error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "Backend \"%s\" does not exist", arg_name); return sbus_request_fail_and_finish(dbus_req, error); } return iface_ifp_FindBackendByName_finish(dbus_req, result); } int ifp_component_enable(struct sbus_request *dbus_req, void *data) { #ifndef HAVE_CONFIG_LIB return sbus_request_fail_and_finish(dbus_req, sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL)); #else struct ifp_ctx *ctx = NULL; DBusError *error = NULL; const char *path = dbus_message_get_path(dbus_req->message); char *name = NULL; enum component_type type; struct sss_config_ctx *config_ctx = NULL; errno_t ret; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); ret = EINVAL; goto done; } ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb, path, &type, &name); if (ret != EOK) { goto done; } config_ctx = sss_config_open(dbus_req, NULL, CONFDB_DEFAULT_CONFIG_FILE); if (config_ctx == NULL) { ret = ENOMEM; goto done; } switch (type) { case COMPONENT_MONITOR: error = sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL); goto done; break; case COMPONENT_RESPONDER: ret = sss_config_service_enable(config_ctx, name); break; case COMPONENT_BACKEND: ret = sss_config_domain_enable(config_ctx, name); break; } if (ret != EOK) { goto done; } ret = sss_config_save(config_ctx); if (ret != EOK) { goto done; } done: sss_config_close(&config_ctx); if (ret == ENOMEM) { return sbus_request_fail_and_finish(dbus_req, NULL); } else if (error != NULL) { return sbus_request_fail_and_finish(dbus_req, error); } else if (ret != EOK) { error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret)); return sbus_request_fail_and_finish(dbus_req, error); } return iface_ifp_components_Enable_finish(dbus_req); #endif } int ifp_component_disable(struct sbus_request *dbus_req, void *data) { #ifndef HAVE_CONFIG_LIB return sbus_request_fail_and_finish(dbus_req, sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL)); #else struct ifp_ctx *ctx = NULL; DBusError *error = NULL; const char *path = dbus_message_get_path(dbus_req->message); char *name = NULL; enum component_type type; struct sss_config_ctx *config_ctx = NULL; errno_t ret; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); ret = EINVAL; goto done; } ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb, path, &type, &name); if (ret != EOK) { goto done; } config_ctx = sss_config_open(dbus_req, NULL, CONFDB_DEFAULT_CONFIG_FILE); if (config_ctx == NULL) { ret = ENOMEM; goto done; } switch (type) { case COMPONENT_MONITOR: error = sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL); goto done; break; case COMPONENT_RESPONDER: ret = sss_config_service_disable(config_ctx, name); break; case COMPONENT_BACKEND: ret = sss_config_domain_disable(config_ctx, name); break; } if (ret != EOK) { goto done; } ret = sss_config_save(config_ctx); if (ret != EOK) { goto done; } done: sss_config_close(&config_ctx); if (ret == ENOMEM) { return sbus_request_fail_and_finish(dbus_req, NULL); } else if (error != NULL) { return sbus_request_fail_and_finish(dbus_req, error); } else if (ret != EOK) { error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret)); return sbus_request_fail_and_finish(dbus_req, error); } return iface_ifp_components_Disable_finish(dbus_req); #endif } int ifp_component_change_debug_level(struct sbus_request *dbus_req, void *data, uint32_t arg_new_level) { #ifndef HAVE_CONFIG_LIB return sbus_request_fail_and_finish(dbus_req, sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL)); #else struct ifp_ctx *ctx = NULL; DBusError *error = NULL; const char *path = dbus_message_get_path(dbus_req->message); char *name = NULL; enum component_type type; struct sss_config_ctx *config_ctx = NULL; const char *section = NULL; errno_t ret; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); ret = EINVAL; goto done; } ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb, path, &type, &name); if (ret != EOK) { goto done; } switch (type) { case COMPONENT_MONITOR: section = "sssd"; break; case COMPONENT_RESPONDER: section = name; break; case COMPONENT_BACKEND: section = talloc_asprintf(dbus_req, "domain/%s", name); break; } if (section == NULL) { ret = ENOMEM; goto done; } config_ctx = sss_config_open(dbus_req, NULL, CONFDB_DEFAULT_CONFIG_FILE); if (config_ctx == NULL) { ret = ENOMEM; goto done; } ret = sss_config_set_debug_level(config_ctx, section, arg_new_level); if (ret != EOK) { goto done; } ret = sss_config_save(config_ctx); if (ret != EOK) { goto done; } ret = change_debug_level_tmp(ctx->rctx->cdb, name, type, arg_new_level); if (ret != EOK) { goto done; } done: sss_config_close(&config_ctx); if (ret == ENOMEM) { return sbus_request_fail_and_finish(dbus_req, NULL); } else if (ret != EOK) { error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret)); return sbus_request_fail_and_finish(dbus_req, error); } return iface_ifp_components_ChangeDebugLevel_finish(dbus_req); #endif } int ifp_component_change_debug_level_tmp(struct sbus_request *dbus_req, void *data, uint32_t arg_new_level) { struct ifp_ctx *ctx = NULL; DBusError *error = NULL; char *name = NULL; enum component_type type; errno_t ret; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); ret = EINVAL; goto done; } ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb, dbus_req->path, &type, &name); if (ret != EOK) { goto done; } ret = change_debug_level_tmp(ctx->rctx->cdb, name, type, arg_new_level); if (ret != EOK) { goto done; } /* Touch configuration file to make sure debug level is reloaded. */ if (utime(CONFDB_DEFAULT_CONFIG_FILE, NULL) == -1) { ret = errno; goto done; } ret = EOK; done: if (ret != EOK) { error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret)); return sbus_request_fail_and_finish(dbus_req, error); } return iface_ifp_components_ChangeDebugLevelTemporarily_finish(dbus_req); } void ifp_component_get_name(struct sbus_request *dbus_req, void *data, const char **_out) { struct ifp_ctx *ctx = NULL; char *name = NULL; errno_t ret; *_out = NULL; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); return; } ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb, dbus_req->path, NULL, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n", ret, strerror(ret)); return; } *_out = name; } void ifp_component_get_debug_level(struct sbus_request *dbus_req, void *data, uint32_t *_out) { struct ifp_ctx *ctx = NULL; const char *confdb_path = NULL; char *name = NULL; enum component_type type; int level; errno_t ret; *_out = 0; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); return; } ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb, dbus_req->path, &type, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n", ret, strerror(ret)); return; } switch (type) { case COMPONENT_MONITOR: confdb_path = CONFDB_MONITOR_CONF_ENTRY; break; case COMPONENT_RESPONDER: confdb_path = talloc_asprintf(dbus_req, CONFDB_SERVICE_PATH_TMPL, name); break; case COMPONENT_BACKEND: confdb_path = talloc_asprintf(dbus_req, CONFDB_DOMAIN_PATH_TMPL, name); break; } if (confdb_path == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n"); return; } ret = confdb_get_int(ctx->rctx->cdb, confdb_path, CONFDB_SERVICE_DEBUG_LEVEL, SSSDBG_DEFAULT, &level); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve configuration option" "[%d]: %s\n", ret, strerror(ret)); return; } *_out = level; } void ifp_component_get_enabled(struct sbus_request *dbus_req, void *data, bool *_out) { struct ifp_ctx *ctx = NULL; const char *param = NULL; char **values = NULL; char *name = NULL; enum component_type type; errno_t ret; int i; *_out = false; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); return; } ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb, dbus_req->path, &type, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n", ret, strerror(ret)); return; } switch (type) { case COMPONENT_MONITOR: *_out = true; return; case COMPONENT_RESPONDER: param = CONFDB_MONITOR_ACTIVE_SERVICES; break; case COMPONENT_BACKEND: param = CONFDB_MONITOR_ACTIVE_DOMAINS; break; } ret = confdb_get_string_as_list(ctx->rctx->cdb, dbus_req, CONFDB_MONITOR_CONF_ENTRY, param, &values); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve configuration option" "[%d]: %s\n", ret, strerror(ret)); return; } for (i = 0; values[i] != NULL; i++) { if (strcmp(values[i], name) == 0) { *_out = true; return; } } } void ifp_component_get_type(struct sbus_request *dbus_req, void *data, const char **_out) { struct ifp_ctx *ctx = NULL; enum component_type type; errno_t ret; *_out = NULL; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); return; } ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb, dbus_req->path, &type, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n", ret, strerror(ret)); return; } switch (type) { case COMPONENT_MONITOR: *_out = "monitor"; break; case COMPONENT_RESPONDER: *_out = "responder"; break; case COMPONENT_BACKEND: *_out = "backend"; break; } } void ifp_backend_get_providers(struct sbus_request *dbus_req, void *data, const char ***_out, int *_out_len) { TALLOC_CTX *tmp_ctx = NULL; struct ifp_ctx *ctx = NULL; const char *confdb_path = NULL; char *name = NULL; enum component_type type; const char **out = NULL; char *value = NULL; static const char *providers[] = {CONFDB_DOMAIN_ID_PROVIDER, CONFDB_DOMAIN_AUTH_PROVIDER, CONFDB_DOMAIN_ACCESS_PROVIDER, CONFDB_DOMAIN_CHPASS_PROVIDER, CONFDB_DOMAIN_SUDO_PROVIDER, CONFDB_DOMAIN_AUTOFS_PROVIDER, CONFDB_DOMAIN_SELINUX_PROVIDER, CONFDB_DOMAIN_HOSTID_PROVIDER, CONFDB_DOMAIN_SUBDOMAINS_PROVIDER}; int num_providers = sizeof(providers) / sizeof(providers[0]); errno_t ret; int i; int j; *_out = NULL; *_out_len = 0; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return; } ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); return; } ret = check_and_get_component_from_path(tmp_ctx, ctx->rctx->cdb, dbus_req->path, &type, &name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n", ret, strerror(ret)); return; } if (type != COMPONENT_BACKEND) { return; } confdb_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, name); if (confdb_path == NULL) { return; } out = talloc_zero_array(tmp_ctx, const char*, num_providers); if (out == NULL) { return; } j = 0; for (i = 0; i < num_providers; i++) { ret = confdb_get_string(ctx->rctx->cdb, tmp_ctx, confdb_path, providers[i], NULL, &value); if (ret != EOK) { return; } if (value == NULL) { continue; } out[j] = talloc_asprintf(out, "%s=%s", providers[i], value); if (out[j] == NULL) { return; } j++; } *_out = talloc_steal(dbus_req, out); *_out_len = j; talloc_free(tmp_ctx); return; } sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifpsrv_cmd.c0000644000000000000000000000007412703456111020173 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.930794565 sssd-1.13.4/src/responder/ifp/ifpsrv_cmd.c0000644002412700241270000005150212703456111021645 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat InfoPipe responder: the responder commands This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "db/sysdb.h" #include "responder/ifp/ifp_private.h" #include "responder/common/responder_cache_req.h" struct ifp_attr_req { const char *name; const char **attrs; int nattrs; struct ifp_req *ireq; }; static struct tevent_req * ifp_user_get_attr_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, enum sss_dp_acct_type search_type, const char *inp, const char **attrs); static errno_t ifp_user_get_attr_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ldb_result **_res, struct sss_domain_info **_domain); static void ifp_user_get_attr_process(struct tevent_req *req); static errno_t ifp_user_get_attr_handle_reply(struct sss_domain_info *domain, struct ifp_req *ireq, const char **attrs, struct ldb_result *res); static errno_t ifp_user_get_attr_unpack_msg(struct ifp_attr_req *attr_req); int ifp_user_get_attr(struct sbus_request *dbus_req, void *data) { errno_t ret; struct ifp_req *ireq; struct ifp_ctx *ifp_ctx; struct ifp_attr_req *attr_req; struct tevent_req *req; DEBUG(SSSDBG_IMPORTANT_INFO, "GetUserAttr is deprecated, please consider " "switching to org.freedesktop.sssd.infopipe.Users.User interface\n"); ifp_ctx = talloc_get_type(data, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } ret = ifp_req_create(dbus_req, ifp_ctx, &ireq); if (ret != EOK) { return ifp_req_create_handle_failure(dbus_req, ret); } attr_req = talloc_zero(ireq, struct ifp_attr_req); if (attr_req == NULL) { return sbus_request_finish(dbus_req, NULL); } attr_req->ireq = ireq; ret = ifp_user_get_attr_unpack_msg(attr_req); if (ret != EOK) { return ret; /* handled internally */ } DEBUG(SSSDBG_FUNC_DATA, "Looking up attributes of user [%s] on behalf of %"PRIi64"\n", attr_req->name, ireq->dbus_req->client); req = ifp_user_get_attr_send(ireq, ifp_ctx->rctx, ifp_ctx->ncache, ifp_ctx->neg_timeout, SSS_DP_USER, attr_req->name, attr_req->attrs); if (req == NULL) { return sbus_request_finish(dbus_req, NULL); } tevent_req_set_callback(req, ifp_user_get_attr_process, attr_req); return EOK; } static errno_t ifp_user_get_attr_unpack_msg(struct ifp_attr_req *attr_req) { bool parsed; char **attrs; int nattrs; int i, ai; const char **whitelist = attr_req->ireq->ifp_ctx->user_whitelist; parsed = sbus_request_parse_or_finish(attr_req->ireq->dbus_req, DBUS_TYPE_STRING, &attr_req->name, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &attrs, &nattrs, DBUS_TYPE_INVALID); if (parsed == false) { DEBUG(SSSDBG_OP_FAILURE, "Could not parse arguments\n"); return EOK; /* handled */ } /* Copy the attributes to maintain memory hierarchy with talloc */ attr_req->attrs = talloc_zero_array(attr_req, const char *, nattrs+1); if (attr_req->attrs == NULL) { return ENOMEM; } ai = 0; for (i = 0; i < nattrs; i++) { if (ifp_attr_allowed(whitelist, attrs[i]) == false) { DEBUG(SSSDBG_MINOR_FAILURE, "Attribute %s not present in the whitelist, skipping\n", attrs[i]); continue; } attr_req->attrs[ai] = talloc_strdup(attr_req->attrs, attrs[i]); if (attr_req->attrs[ai] == NULL) { return ENOMEM; } ai++; } return EOK; } static void ifp_user_get_attr_process(struct tevent_req *req) { struct ifp_attr_req *attr_req; errno_t ret; struct ldb_result *res = NULL; struct sss_domain_info *dom = NULL; attr_req = tevent_req_callback_data(req, struct ifp_attr_req); ret = ifp_user_get_attr_recv(attr_req, req, &res, &dom); talloc_zfree(req); if (ret == ENOENT) { sbus_request_fail_and_finish(attr_req->ireq->dbus_req, sbus_error_new(attr_req->ireq->dbus_req, DBUS_ERROR_FAILED, "No such user\n")); return; } else if (ret != EOK) { sbus_request_fail_and_finish(attr_req->ireq->dbus_req, sbus_error_new(attr_req->ireq->dbus_req, DBUS_ERROR_FAILED, "Failed to read user attribute\n")); return; } ret = ifp_user_get_attr_handle_reply(dom, attr_req->ireq, attr_req->attrs, res); if (ret != EOK) { sbus_request_fail_and_finish(attr_req->ireq->dbus_req, sbus_error_new(attr_req->ireq->dbus_req, DBUS_ERROR_FAILED, "Failed to build a reply\n")); return; } } static errno_t ifp_user_get_attr_replace_space(TALLOC_CTX *mem_ctx, struct ldb_message_element *el, const char sub) { int i; for (i = 0; i < el->num_values; i++) { el->values[i].data = (uint8_t *) sss_replace_space(mem_ctx, (const char *) el->values[i].data, sub); if (el->values[i].data == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_replace_space failed, skipping\n"); return ENOMEM; } } return EOK; } static errno_t ifp_user_get_attr_handle_reply(struct sss_domain_info *domain, struct ifp_req *ireq, const char **attrs, struct ldb_result *res) { errno_t ret; dbus_bool_t dbret; DBusMessage *reply; DBusMessageIter iter; DBusMessageIter iter_dict; struct ldb_message_element *el; int ai; /* Construct a reply */ reply = dbus_message_new_method_return(ireq->dbus_req->message); if (!reply) { return sbus_request_finish(ireq->dbus_req, NULL); } dbus_message_iter_init_append(reply, &iter); dbret = dbus_message_iter_open_container( &iter, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &iter_dict); if (!dbret) { return sbus_request_finish(ireq->dbus_req, NULL); } if (res->count > 0) { for (ai = 0; attrs[ai]; ai++) { el = sss_view_ldb_msg_find_element(domain, res->msgs[0], attrs[ai]); if (el == NULL || el->num_values == 0) { DEBUG(SSSDBG_MINOR_FAILURE, "Attribute %s not present or has no values\n", attrs[ai]); continue; } /* Normalize white space in user names */ if (ireq->ifp_ctx->rctx->override_space != '\0' && strcmp(attrs[ai], SYSDB_NAME) == 0) { ret = ifp_user_get_attr_replace_space(ireq, el, ireq->ifp_ctx->rctx->override_space); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot normalize %s\n", attrs[ai]); continue; } } ret = ifp_add_ldb_el_to_dict(&iter_dict, el); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot add attribute %s to message\n", attrs[ai]); continue; } } } dbret = dbus_message_iter_close_container(&iter, &iter_dict); if (!dbret) { return sbus_request_finish(ireq->dbus_req, NULL); } return sbus_request_finish(ireq->dbus_req, reply); } static void ifp_user_get_groups_process(struct tevent_req *req); static errno_t ifp_user_get_groups_reply(struct sss_domain_info *domain, struct ifp_req *ireq, struct ldb_result *res); int ifp_user_get_groups(struct sbus_request *dbus_req, void *data, const char *arg_user) { struct ifp_req *ireq; struct ifp_ctx *ifp_ctx; struct ifp_attr_req *group_req; struct tevent_req *req; errno_t ret; ifp_ctx = talloc_get_type(data, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } ret = ifp_req_create(dbus_req, ifp_ctx, &ireq); if (ret != EOK) { return ifp_req_create_handle_failure(dbus_req, ret); } group_req = talloc_zero(ireq, struct ifp_attr_req); if (group_req == NULL) { return sbus_request_finish(dbus_req, NULL); } group_req->ireq = ireq; group_req->name = arg_user; group_req->attrs = talloc_zero_array(group_req, const char *, 2); if (group_req->attrs == NULL) { return sbus_request_finish(dbus_req, NULL); } group_req->attrs[0] = talloc_strdup(group_req->attrs, SYSDB_MEMBEROF); if (group_req->attrs[0] == NULL) { return sbus_request_finish(dbus_req, NULL); } DEBUG(SSSDBG_FUNC_DATA, "Looking up groups of user [%s] on behalf of %"PRIi64"\n", group_req->name, group_req->ireq->dbus_req->client); req = ifp_user_get_attr_send(ireq, ifp_ctx->rctx, ifp_ctx->ncache, ifp_ctx->neg_timeout, SSS_DP_INITGROUPS, group_req->name, group_req->attrs); if (req == NULL) { return sbus_request_finish(dbus_req, NULL); } tevent_req_set_callback(req, ifp_user_get_groups_process, group_req); return EOK; } static void ifp_user_get_groups_process(struct tevent_req *req) { struct ifp_attr_req *group_req; errno_t ret; struct ldb_result *res; struct sss_domain_info *dom; group_req = tevent_req_callback_data(req, struct ifp_attr_req); ret = ifp_user_get_attr_recv(group_req, req, &res, &dom); talloc_zfree(req); if (ret == ENOENT) { sbus_request_fail_and_finish(group_req->ireq->dbus_req, sbus_error_new(group_req->ireq->dbus_req, DBUS_ERROR_FAILED, "No such user\n")); return; } else if (ret != EOK) { sbus_request_fail_and_finish(group_req->ireq->dbus_req, sbus_error_new(group_req->ireq->dbus_req, DBUS_ERROR_FAILED, "Failed to read attribute\n")); return; } ret = ifp_user_get_groups_reply(dom, group_req->ireq, res); if (ret != EOK) { sbus_request_fail_and_finish(group_req->ireq->dbus_req, sbus_error_new(group_req->ireq->dbus_req, DBUS_ERROR_FAILED, "Failed to build a reply\n")); return; } } static errno_t ifp_user_get_groups_reply(struct sss_domain_info *domain, struct ifp_req *ireq, struct ldb_result *res) { int i, num; const char *name; const char **groupnames; const char *tmpstr; /* one less, the first one is the user entry */ num = res->count - 1; groupnames = talloc_zero_array(ireq, const char *, num); if (groupnames == NULL) { return sbus_request_finish(ireq->dbus_req, NULL); } for (i = 0; i < num; i++) { name = sss_view_ldb_msg_find_attr_as_string(domain, res->msgs[i + 1], SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Skipping a group with no name\n"); continue; } if (ireq->ifp_ctx->rctx->override_space != '\0') { tmpstr = sss_replace_space(ireq, name, ireq->ifp_ctx->rctx->override_space); if (tmpstr == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot normalize %s\n", name); continue; } } else { tmpstr = name; } groupnames[i] = sss_get_cased_name(groupnames, tmpstr, domain->case_preserve); if (groupnames[i] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_get_cased_name failed, skipping\n"); continue; } DEBUG(SSSDBG_TRACE_FUNC, "Adding group %s\n", groupnames[i]); } return iface_ifp_GetUserGroups_finish(ireq->dbus_req, groupnames, num); } struct ifp_user_get_attr_state { const char *inp; const char **attrs; struct ldb_result *res; enum sss_dp_acct_type search_type; char *name; char *domname; struct sss_domain_info *dom; bool check_next; bool check_provider; struct resp_ctx *rctx; struct sss_nc_ctx *ncache; int neg_timeout; }; static void ifp_user_get_attr_lookup(struct tevent_req *subreq); static void ifp_user_get_attr_done(struct tevent_req *subreq); static struct tevent_req * ifp_user_get_attr_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, enum sss_dp_acct_type search_type, const char *inp, const char **attrs) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct ifp_user_get_attr_state *state; req = tevent_req_create(mem_ctx, &state, struct ifp_user_get_attr_state); if (req == NULL) { return NULL; } state->inp = inp; state->attrs = attrs; state->rctx = rctx; state->ncache = ncache; state->neg_timeout = neg_timeout; state->search_type = search_type; subreq = sss_parse_inp_send(req, rctx, inp); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, ifp_user_get_attr_lookup, req); ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); } return req; } static void ifp_user_get_attr_lookup(struct tevent_req *subreq) { struct ifp_user_get_attr_state *state = NULL; struct cache_req_input *input = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ifp_user_get_attr_state); ret = sss_parse_inp_recv(subreq, state, &state->name, &state->domname); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } switch (state->search_type) { case SSS_DP_USER: input = cache_req_input_create(state, CACHE_REQ_USER_BY_NAME, state->name, 0, NULL); break; case SSS_DP_INITGROUPS: input = cache_req_input_create(state, CACHE_REQ_INITGROUPS, state->name, 0, NULL); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported search type [%d]!\n", state->search_type); tevent_req_error(req, ERR_INTERNAL); return; } if (input == NULL) { tevent_req_error(req, ENOMEM); return; } subreq = cache_req_send(state, state->rctx->ev, state->rctx, state->ncache, state->neg_timeout, 0, state->domname, input); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, ifp_user_get_attr_done, req); } static void ifp_user_get_attr_done(struct tevent_req *subreq) { struct ifp_user_get_attr_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ifp_user_get_attr_state); ret = cache_req_recv(state, subreq, &state->res, &state->dom, NULL); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } if (state->search_type == SSS_DP_USER) { /* throw away the result and perform attr search */ talloc_zfree(state->res); ret = sysdb_get_user_attr_with_views(state, state->dom, state->name, state->attrs, &state->res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_get_user_attr_with_views() " "failed [%d]: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); return; } else if (state->res->count == 0) { tevent_req_error(req, ENOENT); return; } else if (state->res->count != 1) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_get_user_attr_with_views() " "returned more than one result!\n"); tevent_req_error(req, ENOENT); return; } } tevent_req_done(req); } static errno_t ifp_user_get_attr_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ldb_result **_res, struct sss_domain_info **_domain) { struct ifp_user_get_attr_state *state = tevent_req_data(req, struct ifp_user_get_attr_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (state->res == NULL) { /* Did the request end with success but with no data? */ return ENOENT; } if (_res) { *_res = talloc_steal(mem_ctx, state->res); } if (_domain) { *_domain = state->dom; } return EOK; } struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version ssh_cli_protocol_version[] = { {0, NULL, NULL} }; return ssh_cli_protocol_version; } /* This is a throwaway method to ease the review of the patch. * It will be removed later */ int ifp_ping(struct sbus_request *dbus_req, void *data) { struct ifp_ctx *ifp_ctx = talloc_get_type(data, struct ifp_ctx); static const char *pong = "PONG"; const char *request; DBusError dberr; errno_t ret; struct ifp_req *ifp_req; if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } ret = ifp_req_create(dbus_req, ifp_ctx, &ifp_req); if (ret != EOK) { return ifp_req_create_handle_failure(dbus_req, ret); } if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_STRING, &request, DBUS_TYPE_INVALID)) { return EOK; /* handled */ } DEBUG(SSSDBG_CONF_SETTINGS, "Got request for [%s]\n", request); if (strcasecmp(request, "ping") != 0) { dbus_error_init(&dberr); dbus_set_error_const(&dberr, DBUS_ERROR_INVALID_ARGS, "Ping() only accepts ping as a param\n"); return sbus_request_fail_and_finish(dbus_req, &dberr); } return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_STRING, &pong, DBUS_TYPE_INVALID); } sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_domains.c0000644000000000000000000000007412703456111020327 xustar0030 atime=1460561751.650715627 30 ctime=1460561775.004794815 sssd-1.13.4/src/responder/ifp/ifp_domains.c0000644002412700241270000003572612703456111022013 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "db/sysdb.h" #include "util/util.h" #include "confdb/confdb.h" #include "responder/common/responder.h" #include "responder/ifp/ifp_domains.h" #define RETURN_DOM_PROP_AS_STRING(dbus_req, pvt_data, out, property) do { \ struct sss_domain_info *__dom; \ \ *(out) = NULL; \ \ __dom = get_domain_info_from_req((dbus_req), (pvt_data)); \ if (__dom == NULL) { \ return; \ } \ \ *(out) = __dom->property; \ } while (0) static void ifp_list_domains_process(struct tevent_req *req); int ifp_list_domains(struct sbus_request *dbus_req, void *data) { struct ifp_ctx *ifp_ctx; struct ifp_req *ireq; struct tevent_req *req; DBusError *error; errno_t ret; ifp_ctx = talloc_get_type(data, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "Invalid ifp context!"); return sbus_request_fail_and_finish(dbus_req, error); } ret = ifp_req_create(dbus_req, ifp_ctx, &ireq); if (ret != EOK) { error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", sss_strerror(ret)); return sbus_request_fail_and_finish(dbus_req, error); } req = sss_dp_get_domains_send(ireq, ifp_ctx->rctx, false, NULL); if (req == NULL) { return sbus_request_finish(ireq->dbus_req, NULL); } tevent_req_set_callback(req, ifp_list_domains_process, ireq); return EOK; } static void ifp_list_domains_process(struct tevent_req *req) { struct sss_domain_info *dom; struct ifp_req *ireq; const char **paths; char *p; DBusError *error; size_t num_domains; size_t pi; errno_t ret; ireq = tevent_req_callback_data(req, struct ifp_req); ret = sss_dp_get_domains_recv(req); talloc_free(req); if (ret != EOK) { error = sbus_error_new(ireq->dbus_req, DBUS_ERROR_FAILED, "Failed to refresh domain objects\n"); sbus_request_fail_and_finish(ireq->dbus_req, error); return; } ret = sysdb_master_domain_update(ireq->ifp_ctx->rctx->domains); if (ret != EOK) { error = sbus_error_new(ireq->dbus_req, DBUS_ERROR_FAILED, "Failed to refresh subdomain list\n"); sbus_request_fail_and_finish(ireq->dbus_req, error); return; } num_domains = 0; for (dom = ireq->ifp_ctx->rctx->domains; dom != NULL; dom = get_next_domain(dom, SSS_GND_DESCEND)) { num_domains++; } paths = talloc_zero_array(ireq, const char *, num_domains); if (paths == NULL) { sbus_request_finish(ireq->dbus_req, NULL); return; } pi = 0; for (dom = ireq->ifp_ctx->rctx->domains; dom != NULL; dom = get_next_domain(dom, SSS_GND_DESCEND)) { p = sbus_opath_compose(ireq, IFP_PATH_DOMAINS, dom->name); if (p == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not create path for dom %s, skipping\n", dom->name); continue; } paths[pi] = p; pi++; } ret = iface_ifp_ListDomains_finish(ireq->dbus_req, paths, num_domains); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not finish request!\n"); } } struct ifp_get_domain_state { const char *name; struct ifp_req *ireq; }; static void ifp_find_domain_by_name_process(struct tevent_req *req); int ifp_find_domain_by_name(struct sbus_request *dbus_req, void *data, const char *arg_name) { struct ifp_ctx *ifp_ctx; struct ifp_req *ireq; struct tevent_req *req; struct ifp_get_domain_state *state; DBusError *error; errno_t ret; ifp_ctx = talloc_get_type(data, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "Invalid ifp context!"); return sbus_request_fail_and_finish(dbus_req, error); } ret = ifp_req_create(dbus_req, ifp_ctx, &ireq); if (ret != EOK) { error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", sss_strerror(ret)); return sbus_request_fail_and_finish(dbus_req, error); } state = talloc_zero(ireq, struct ifp_get_domain_state); if (state == NULL) { return sbus_request_finish(dbus_req, NULL); } state->name = arg_name; state->ireq = ireq; req = sss_dp_get_domains_send(ireq, ifp_ctx->rctx, false, NULL); if (req == NULL) { return sbus_request_finish(dbus_req, NULL); } tevent_req_set_callback(req, ifp_find_domain_by_name_process, state); return EOK; } static void ifp_find_domain_by_name_process(struct tevent_req *req) { errno_t ret; struct ifp_req *ireq; struct ifp_get_domain_state *state; struct sss_domain_info *iter; const char *path; DBusError *error; state = tevent_req_callback_data(req, struct ifp_get_domain_state); ireq = state->ireq; ret = sss_dp_get_domains_recv(req); talloc_free(req); if (ret != EOK) { error = sbus_error_new(ireq->dbus_req, DBUS_ERROR_FAILED, "Failed to refresh domain objects\n"); sbus_request_fail_and_finish(ireq->dbus_req, error); return; } ret = sysdb_master_domain_update(ireq->ifp_ctx->rctx->domains); if (ret != EOK) { error = sbus_error_new(ireq->dbus_req, DBUS_ERROR_FAILED, "Failed to refresh subdomain list\n"); sbus_request_fail_and_finish(ireq->dbus_req, error); return; } /* Reply with the domain that was asked for */ for (iter = ireq->ifp_ctx->rctx->domains; iter != NULL; iter = get_next_domain(iter, SSS_GND_DESCEND)) { if (strcasecmp(iter->name, state->name) == 0) { break; } } if (iter == NULL) { error = sbus_error_new(ireq->dbus_req, DBUS_ERROR_FAILED, "No such domain\n"); sbus_request_fail_and_finish(ireq->dbus_req, error); return; } path = sbus_opath_compose(ireq, IFP_PATH_DOMAINS, iter->name); if (path == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not create path for domain %s, skipping\n", iter->name); sbus_request_finish(ireq->dbus_req, NULL); return; } ret = iface_ifp_FindDomainByName_finish(ireq->dbus_req, path); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not finish request!\n"); } } static struct sss_domain_info * get_domain_info_from_req(struct sbus_request *dbus_req, void *data) { struct ifp_ctx *ctx = NULL; struct sss_domain_info *domains = NULL; struct sss_domain_info *iter = NULL; char *name = NULL; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return NULL; } name = sbus_opath_get_object_name(dbus_req, dbus_req->path, IFP_PATH_DOMAINS); if (name == NULL) { return NULL; } DEBUG(SSSDBG_TRACE_INTERNAL, "Looking for domain %s\n", name); domains = ctx->rctx->domains; for (iter = domains; iter != NULL; iter = get_next_domain(iter, SSS_GND_DESCEND)) { if (strcasecmp(iter->name, name) == 0) { break; } } talloc_free(name); return iter; } static void get_server_list(struct sbus_request *dbus_req, void *data, const char ***_out, int *_out_len, bool backup) { static const char *srv[] = {"_srv_"}; struct sss_domain_info *dom = NULL; struct ifp_ctx *ctx = NULL; const char *conf_path = NULL; const char *option = NULL; const char **out = NULL; char **servers = NULL; int num_servers; errno_t ret; int i; *_out = NULL; *_out_len = 0; dom = get_domain_info_from_req(dbus_req, data); if (dom == NULL) { return; } if (dom->parent != NULL) { /* subdomains are not present in configuration */ ret = ENOENT; goto done; } ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n"); ret = ENOMEM; goto done; } conf_path = talloc_asprintf(dbus_req, CONFDB_DOMAIN_PATH_TMPL, dom->name); if (conf_path == NULL) { ret = ENOMEM; goto done; } /* TODO: replace hardcoded values with option names from the provider */ if (strcasecmp(dom->provider, "ldap") == 0) { option = backup == false ? "ldap_uri" : "ldap_backup_uri"; } else if (strcasecmp(dom->provider, "ipa") == 0) { option = backup == false ? "ipa_server" : "ipa_backup_server"; } else if (strcasecmp(dom->provider, "ad") == 0) { option = backup == false ? "ad_server" : "ad_backup_server"; } else { ret = EINVAL; goto done; } ret = confdb_get_string_as_list(ctx->rctx->cdb, dbus_req, conf_path, option, &servers); if (ret != EOK) { goto done; } for (num_servers = 0; servers[num_servers] != NULL; num_servers++); if (num_servers == 0) { ret = ENOENT; goto done; } out = talloc_zero_array(dbus_req, const char*, num_servers); if (out == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < num_servers; i++) { out[i] = talloc_steal(out, servers[i]); } *_out = out; *_out_len = num_servers; ret = EOK; done: if (ret == ENOENT) { *_out = srv; *_out_len = 1; } return; } void ifp_dom_get_name(struct sbus_request *dbus_req, void *data, const char **_out) { RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, name); } void ifp_dom_get_provider(struct sbus_request *dbus_req, void *data, const char **_out) { RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, provider); } void ifp_dom_get_primary_servers(struct sbus_request *dbus_req, void *data, const char ***_out, int *_out_len) { get_server_list(dbus_req, data, _out, _out_len, false); } void ifp_dom_get_backup_servers(struct sbus_request *dbus_req, void *data, const char ***_out, int *_out_len) { get_server_list(dbus_req, data, _out, _out_len, true); } void ifp_dom_get_min_id(struct sbus_request *dbus_req, void *data, uint32_t *_out) { struct sss_domain_info *dom; *_out = 1; dom = get_domain_info_from_req(dbus_req, data); if (dom == NULL) { return; } *_out = dom->id_min; } void ifp_dom_get_max_id(struct sbus_request *dbus_req, void *data, uint32_t *_out) { struct sss_domain_info *dom; *_out = 0; dom = get_domain_info_from_req(dbus_req, data); if (dom == NULL) { return; } *_out = dom->id_max; } void ifp_dom_get_realm(struct sbus_request *dbus_req, void *data, const char **_out) { RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, realm); } void ifp_dom_get_forest(struct sbus_request *dbus_req, void *data, const char **_out) { RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, forest); } void ifp_dom_get_login_format(struct sbus_request *dbus_req, void *data, const char **_out) { RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, names->re_pattern); } void ifp_dom_get_fqdn_format(struct sbus_request *dbus_req, void *data, const char **_out) { RETURN_DOM_PROP_AS_STRING(dbus_req, data, _out, names->fq_fmt); } void ifp_dom_get_enumerable(struct sbus_request *dbus_req, void *data, bool *_out) { struct sss_domain_info *dom; *_out = false; dom = get_domain_info_from_req(dbus_req, data); if (dom == NULL) { return; } *_out = dom->enumerate; } void ifp_dom_get_use_fqdn(struct sbus_request *dbus_req, void *data, bool *_out) { struct sss_domain_info *dom; *_out = false; dom = get_domain_info_from_req(dbus_req, data); if (dom == NULL) { return; } *_out = dom->fqnames; } void ifp_dom_get_subdomain(struct sbus_request *dbus_req, void *data, bool *_out) { struct sss_domain_info *dom; *_out = false; dom = get_domain_info_from_req(dbus_req, data); if (dom == NULL) { return; } *_out = dom->parent ? true : false; } void ifp_dom_get_parent_domain(struct sbus_request *dbus_req, void *data, const char **_out) { struct sss_domain_info *dom; *_out = NULL; dom = get_domain_info_from_req(dbus_req, data); if (dom == NULL) { return; } if (dom->parent == NULL) { *_out = "/"; return; } *_out = sbus_opath_compose(dbus_req, IFP_PATH_DOMAINS, dom->parent->name); } sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_groups.c0000644000000000000000000000007412703456111020214 xustar0030 atime=1460561751.651715631 30 ctime=1460561775.007794826 sssd-1.13.4/src/responder/ifp/ifp_groups.c0000644002412700241270000006535112703456111021675 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/util.h" #include "db/sysdb.h" #include "util/strtonum.h" #include "sbus/sssd_dbus_errors.h" #include "responder/common/responder.h" #include "responder/common/responder_cache_req.h" #include "responder/ifp/ifp_groups.h" #include "responder/ifp/ifp_users.h" #include "responder/ifp/ifp_cache.h" char * ifp_groups_build_path_from_msg(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_message *msg) { const char *gid; gid = ldb_msg_find_attr_as_string(msg, SYSDB_GIDNUM, NULL); if (gid == NULL) { return NULL; } return sbus_opath_compose(mem_ctx, IFP_PATH_GROUPS, domain->name, gid); } static errno_t ifp_groups_decompose_path(struct sss_domain_info *domains, const char *path, struct sss_domain_info **_domain, gid_t *_gid) { char **parts = NULL; struct sss_domain_info *domain; gid_t gid; errno_t ret; ret = sbus_opath_decompose_exact(NULL, path, IFP_PATH_GROUPS, 2, &parts); if (ret != EOK) { return ret; } domain = find_domain_by_name(domains, parts[0], false); if (domain == NULL) { ret = ERR_DOMAIN_NOT_FOUND; goto done; } gid = strtouint32(parts[1], NULL, 10); ret = errno; if (ret != EOK) { goto done; } *_domain = domain; *_gid = gid; done: talloc_free(parts); return ret; } static int ifp_groups_list_copy(struct ifp_list_ctx *list_ctx, struct ldb_result *result) { size_t copy_count, i; copy_count = ifp_list_ctx_remaining_capacity(list_ctx, result->count); for (i = 0; i < copy_count; i++) { list_ctx->paths[list_ctx->path_count + i] = \ ifp_groups_build_path_from_msg(list_ctx->paths, list_ctx->dom, result->msgs[i]); if (list_ctx->paths[list_ctx->path_count + i] == NULL) { return ENOMEM; } } list_ctx->path_count += copy_count; return EOK; } static void ifp_groups_find_by_name_done(struct tevent_req *req); int ifp_groups_find_by_name(struct sbus_request *sbus_req, void *data, const char *name) { struct ifp_ctx *ctx; struct tevent_req *req; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } req = cache_req_group_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx, ctx->ncache, ctx->neg_timeout, 0, NULL, name); if (req == NULL) { return ENOMEM; } tevent_req_set_callback(req, ifp_groups_find_by_name_done, sbus_req); return EOK; } static void ifp_groups_find_by_name_done(struct tevent_req *req) { DBusError *error; struct sbus_request *sbus_req; struct sss_domain_info *domain; struct ldb_result *result; char *object_path; errno_t ret; sbus_req = tevent_req_callback_data(req, struct sbus_request); ret = cache_req_group_by_name_recv(sbus_req, req, &result, &domain, NULL); talloc_zfree(req); if (ret == ENOENT) { error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND, "Group not found"); goto done; } else if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "group [%d]: %s\n", ret, sss_strerror(ret)); goto done; } object_path = ifp_groups_build_path_from_msg(sbus_req, domain, result->msgs[0]); if (object_path == NULL) { error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, "Failed to compose object path"); goto done; } ret = EOK; done: if (ret != EOK) { sbus_request_fail_and_finish(sbus_req, error); return; } iface_ifp_groups_FindByName_finish(sbus_req, object_path); return; } static void ifp_groups_find_by_id_done(struct tevent_req *req); int ifp_groups_find_by_id(struct sbus_request *sbus_req, void *data, uint32_t id) { struct ifp_ctx *ctx; struct tevent_req *req; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } req = cache_req_group_by_id_send(sbus_req, ctx->rctx->ev, ctx->rctx, ctx->ncache, ctx->neg_timeout, 0, NULL, id); if (req == NULL) { return ENOMEM; } tevent_req_set_callback(req, ifp_groups_find_by_id_done, sbus_req); return EOK; } static void ifp_groups_find_by_id_done(struct tevent_req *req) { DBusError *error; struct sbus_request *sbus_req; struct sss_domain_info *domain; struct ldb_result *result; char *object_path; errno_t ret; sbus_req = tevent_req_callback_data(req, struct sbus_request); ret = cache_req_group_by_id_recv(sbus_req, req, &result, &domain); talloc_zfree(req); if (ret == ENOENT) { error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND, "Group not found"); goto done; } else if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "group [%d]: %s\n", ret, sss_strerror(ret)); goto done; } object_path = ifp_groups_build_path_from_msg(sbus_req, domain, result->msgs[0]); if (object_path == NULL) { error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, "Failed to compose object path"); goto done; } done: if (ret != EOK) { sbus_request_fail_and_finish(sbus_req, error); return; } iface_ifp_groups_FindByID_finish(sbus_req, object_path); return; } static int ifp_groups_list_by_name_step(struct ifp_list_ctx *list_ctx); static void ifp_groups_list_by_name_done(struct tevent_req *req); static void ifp_groups_list_by_name_reply(struct ifp_list_ctx *list_ctx); int ifp_groups_list_by_name(struct sbus_request *sbus_req, void *data, const char *filter, uint32_t limit) { struct ifp_ctx *ctx; struct ifp_list_ctx *list_ctx; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } list_ctx = ifp_list_ctx_new(sbus_req, ctx, filter, limit); if (list_ctx == NULL) { return ENOMEM; } return ifp_groups_list_by_name_step(list_ctx); } static int ifp_groups_list_by_name_step(struct ifp_list_ctx *list_ctx) { struct tevent_req *req; req = cache_req_group_by_filter_send(list_ctx, list_ctx->ctx->rctx->ev, list_ctx->ctx->rctx, list_ctx->dom->name, list_ctx->filter); if (req == NULL) { return ENOMEM; } tevent_req_set_callback(req, ifp_groups_list_by_name_done, list_ctx); return EOK; } static void ifp_groups_list_by_name_done(struct tevent_req *req) { DBusError *error; struct ifp_list_ctx *list_ctx; struct sbus_request *sbus_req; struct ldb_result *result; struct sss_domain_info *domain; errno_t ret; list_ctx = tevent_req_callback_data(req, struct ifp_list_ctx); sbus_req = list_ctx->sbus_req; ret = cache_req_group_by_name_recv(sbus_req, req, &result, &domain, NULL); talloc_zfree(req); if (ret != EOK && ret != ENOENT) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "groups by filter [%d]: %s\n", ret, sss_strerror(ret)); sbus_request_fail_and_finish(sbus_req, error); return; } ret = ifp_groups_list_copy(list_ctx, result); if (ret != EOK) { error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, "Failed to copy domain result"); sbus_request_fail_and_finish(sbus_req, error); return; } list_ctx->dom = get_next_domain(list_ctx->dom, SSS_GND_DESCEND); if (list_ctx->dom == NULL) { return ifp_groups_list_by_name_reply(list_ctx); } ret = ifp_groups_list_by_name_step(list_ctx); if (ret != EOK) { error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, "Failed to start next-domain search"); sbus_request_fail_and_finish(sbus_req, error); return; } } static void ifp_groups_list_by_name_reply(struct ifp_list_ctx *list_ctx) { iface_ifp_groups_ListByDomainAndName_finish(list_ctx->sbus_req, list_ctx->paths, list_ctx->path_count); } static void ifp_groups_list_by_domain_and_name_done(struct tevent_req *req); int ifp_groups_list_by_domain_and_name(struct sbus_request *sbus_req, void *data, const char *domain, const char *filter, uint32_t limit) { struct tevent_req *req; struct ifp_ctx *ctx; struct ifp_list_ctx *list_ctx; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } list_ctx = ifp_list_ctx_new(sbus_req, ctx, filter, limit); if (list_ctx == NULL) { return ENOMEM; } req = cache_req_group_by_filter_send(list_ctx, ctx->rctx->ev, ctx->rctx, domain, filter); if (req == NULL) { return ENOMEM; } tevent_req_set_callback(req, ifp_groups_list_by_domain_and_name_done, list_ctx); return EOK; } static void ifp_groups_list_by_domain_and_name_done(struct tevent_req *req) { DBusError *error; struct ifp_list_ctx *list_ctx; struct sbus_request *sbus_req; struct ldb_result *result; struct sss_domain_info *domain; errno_t ret; list_ctx = tevent_req_callback_data(req, struct ifp_list_ctx); sbus_req = list_ctx->sbus_req; ret = cache_req_user_by_name_recv(sbus_req, req, &result, &domain, NULL); talloc_zfree(req); if (ret == ENOENT) { error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND, "User not found by filter"); goto done; } else if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "groups by filter [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = ifp_groups_list_copy(list_ctx, result); if (ret != EOK) { error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, "Failed to copy domain result"); goto done; } done: if (ret != EOK) { sbus_request_fail_and_finish(sbus_req, error); return; } iface_ifp_groups_ListByDomainAndName_finish(sbus_req, list_ctx->paths, list_ctx->path_count); return; } static errno_t ifp_groups_group_get(struct sbus_request *sbus_req, void *data, gid_t *_gid, struct sss_domain_info **_domain, struct ldb_message **_group) { struct ifp_ctx *ctx; struct sss_domain_info *domain; struct ldb_result *res; uid_t gid; errno_t ret; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } ret = ifp_groups_decompose_path(ctx->rctx->domains, sbus_req->path, &domain, &gid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to decompose object path" "[%s] [%d]: %s\n", sbus_req->path, ret, sss_strerror(ret)); return ret; } if (_group != NULL) { ret = sysdb_getgrgid_with_views(sbus_req, domain, gid, &res); if (ret == EOK && res->count == 0) { *_group = NULL; ret = ENOENT; } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup group %u@%s [%d]: %s\n", gid, domain->name, ret, sss_strerror(ret)); } else { *_group = res->msgs[0]; } } if (ret == EOK || ret == ENOENT) { if (_gid != NULL) { *_gid = gid; } if (_domain != NULL) { *_domain = domain; } } return ret; } struct resolv_ghosts_state { struct tevent_context *ev; struct sbus_request *sbus_req; struct ifp_ctx *ctx; void *data; struct sss_domain_info *domain; const char **ghosts; int index; }; static void resolv_ghosts_group_done(struct tevent_req *subreq); static errno_t resolv_ghosts_step(struct tevent_req *req); static void resolv_ghosts_done(struct tevent_req *subreq); static struct tevent_req *resolv_ghosts_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sbus_request *sbus_req, void *data) { struct resolv_ghosts_state *state; struct sss_domain_info *domain; struct tevent_req *req; struct tevent_req *subreq; struct ldb_message *group; struct ifp_ctx *ctx; const char *name; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct resolv_ghosts_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n")); return NULL; } ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); ret = ERR_INTERNAL; goto immediately; } state->ev = ev; state->sbus_req = sbus_req; state->ctx = ctx; state->data = data; ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group); if (ret != EOK) { goto immediately; } name = ldb_msg_find_attr_as_string(group, SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Group name is empty!\n"); ret = ERR_INTERNAL; goto immediately; } subreq = cache_req_group_by_name_send(state, ev, ctx->rctx, ctx->ncache, ctx->neg_timeout, 0, domain->name, name); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, resolv_ghosts_group_done, req); return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void resolv_ghosts_group_done(struct tevent_req *subreq) { struct resolv_ghosts_state *state; struct ldb_message_element *el; struct ldb_message *group; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct resolv_ghosts_state); ret = ifp_groups_group_get(state->sbus_req, state->data, NULL, &state->domain, &group); if (ret != EOK) { goto done; } el = ldb_msg_find_element(group, SYSDB_GHOST); if (el == NULL) { ret = ENOMEM; goto done; } if (el->num_values == 0) { ret = EOK; goto done; } state->ghosts = sss_ldb_el_to_string_list(state, el); if (state->ghosts == NULL) { ret = ENOMEM; goto done; } state->index = 0; ret = resolv_ghosts_step(req); done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } errno_t resolv_ghosts_step(struct tevent_req *req) { struct resolv_ghosts_state *state; struct tevent_req *subreq; state = tevent_req_data(req, struct resolv_ghosts_state); if (state->ghosts[state->index] == NULL) { return EOK; } subreq = cache_req_user_by_name_send(state, state->ev, state->ctx->rctx, state->ctx->ncache, state->ctx->neg_timeout, 0, state->domain->name, state->ghosts[state->index]); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, resolv_ghosts_done, req); state->index++; return EAGAIN; } static void resolv_ghosts_done(struct tevent_req *subreq) { struct resolv_ghosts_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct resolv_ghosts_state); ret = cache_req_user_by_name_recv(state, subreq, NULL, NULL, NULL); talloc_zfree(subreq); if (ret != EOK) { goto done; } ret = resolv_ghosts_step(req); done: if (ret == EOK) { tevent_req_done(req); } else if (ret != EAGAIN) { tevent_req_error(req, ret); } } static errno_t resolv_ghosts_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void ifp_groups_group_update_member_list_done(struct tevent_req *req); int ifp_groups_group_update_member_list(struct sbus_request *sbus_req, void *data) { struct tevent_req *subreq; struct ifp_ctx *ctx; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } subreq = resolv_ghosts_send(sbus_req, ctx->rctx->ev, sbus_req, data); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, ifp_groups_group_update_member_list_done, sbus_req); return EOK; } static void ifp_groups_group_update_member_list_done(struct tevent_req *subreq) { DBusError *error; struct sbus_request *sbus_req; errno_t ret; sbus_req = tevent_req_callback_data(subreq, struct sbus_request); ret = resolv_ghosts_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Unable to resolve ghost members [%d]: %s\n", ret, sss_strerror(ret)); sbus_request_fail_and_finish(sbus_req, error); return; } iface_ifp_groups_group_UpdateMemberList_finish(sbus_req); return; } void ifp_groups_group_get_name(struct sbus_request *sbus_req, void *data, const char **_out) { struct ldb_message *msg; struct sss_domain_info *domain; errno_t ret; ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &msg); if (ret != EOK) { *_out = NULL; return; } *_out = sss_view_ldb_msg_find_attr_as_string(domain, msg, SYSDB_NAME, NULL); return; } void ifp_groups_group_get_gid_number(struct sbus_request *sbus_req, void *data, uint32_t *_out) { struct ldb_message *msg; struct sss_domain_info *domain; errno_t ret; ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &msg); if (ret != EOK) { *_out = 0; return; } *_out = sss_view_ldb_msg_find_attr_as_uint64(domain, msg, SYSDB_GIDNUM, 0); return; } static errno_t ifp_groups_group_get_members(TALLOC_CTX *mem_ctx, struct sbus_request *sbus_req, void *data, const char ***_users, int *_num_users, const char ***_groups, int *_num_groups) { TALLOC_CTX *tmp_ctx; struct sss_domain_info *domain; struct ldb_message *group; struct ldb_message **members; size_t num_members; const char *class; const char **users; const char **groups; int num_users; int num_groups; int i; errno_t ret; const char *attrs[] = {SYSDB_OBJECTCLASS, SYSDB_UIDNUM, SYSDB_GIDNUM, NULL}; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group); if (ret != EOK) { goto done; } ret = sysdb_asq_search(tmp_ctx, domain, group->dn, NULL, SYSDB_MEMBER, attrs, &num_members, &members); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to perform ASQ search [%d]: %s\n", ret, sss_strerror(ret)); goto done; } if (num_members == 0) { users = NULL; groups = NULL; num_users = 0; num_groups = 0; ret = EOK; goto done; } users = talloc_zero_array(tmp_ctx, const char *, num_members + 1); if (users == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); ret = ENOMEM; goto done; } groups = talloc_zero_array(tmp_ctx, const char *, num_members + 1); if (groups == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); ret = ENOMEM; goto done; } num_users = 0; num_groups = 0; for (i = 0; i < num_members; i++) { class = ldb_msg_find_attr_as_string(members[i], SYSDB_OBJECTCLASS, NULL); if (class == NULL) { ret = ERR_INTERNAL; goto done; } if (strcmp(class, SYSDB_USER_CLASS) == 0) { users[num_users] = ifp_users_build_path_from_msg(users, domain, members[i]); if (users[num_users] == NULL) { ret = ENOMEM; goto done; } num_users++; } else if (strcmp(class, SYSDB_GROUP_CLASS) == 0) { groups[num_groups] = ifp_groups_build_path_from_msg(groups, domain, members[i]); if (groups[num_groups] == NULL) { ret = ENOMEM; goto done; } num_groups++; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected object class %s\n", class); ret = ERR_INTERNAL; goto done; } } ret = EOK; done: if (ret == EOK) { if (_users != NULL) { *_users = talloc_steal(mem_ctx, users); } if (_num_users != NULL) { *_num_users = num_users; } if (_groups != NULL) { *_groups = talloc_steal(mem_ctx, groups); } if (_num_groups != NULL) { *_num_groups = num_groups; } } talloc_free(tmp_ctx); return ret; } void ifp_groups_group_get_users(struct sbus_request *sbus_req, void *data, const char ***_out, int *_size) { errno_t ret; *_out = NULL; *_size = 0; ret = ifp_groups_group_get_members(sbus_req, sbus_req, data, _out, _size, NULL, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to acquire groups members\n"); } } void ifp_groups_group_get_groups(struct sbus_request *sbus_req, void *data, const char ***_out, int *_size) { errno_t ret; *_out = NULL; *_size = 0; ret = ifp_groups_group_get_members(sbus_req, sbus_req, data, NULL, NULL, _out, _size); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to acquire groups members\n"); } } int ifp_cache_list_group(struct sbus_request *sbus_req, void *data) { return ifp_cache_list(sbus_req, data, IFP_CACHE_GROUP); } int ifp_cache_list_by_domain_group(struct sbus_request *sbus_req, void *data, const char *domain) { return ifp_cache_list_by_domain(sbus_req, data, domain, IFP_CACHE_GROUP); } int ifp_cache_object_store_group(struct sbus_request *sbus_req, void *data) { DBusError *error; struct sss_domain_info *domain; struct ldb_message *group; errno_t ret; ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group); if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "group [%d]: %s\n", ret, sss_strerror(ret)); return sbus_request_fail_and_finish(sbus_req, error); } /* The request is finished inside. */ return ifp_cache_object_store(sbus_req, domain, group->dn); } int ifp_cache_object_remove_group(struct sbus_request *sbus_req, void *data) { DBusError *error; struct sss_domain_info *domain; struct ldb_message *group; errno_t ret; ret = ifp_groups_group_get(sbus_req, data, NULL, &domain, &group); if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "group [%d]: %s\n", ret, sss_strerror(ret)); return sbus_request_fail_and_finish(sbus_req, error); } /* The request is finished inside. */ return ifp_cache_object_remove(sbus_req, domain, group->dn); } sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_iface_generated.c0000644000000000000000000000007412703456111021762 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.931794568 sssd-1.13.4/src/responder/ifp/ifp_iface_generated.c0000644002412700241270000011021012703456111023424 0ustar00jhrozekjhrozek00000000000000/* The following definitions are auto-generated from ifp_iface.xml */ #include "util/util.h" #include "sbus/sssd_dbus.h" #include "sbus/sssd_dbus_meta.h" #include "sbus/sssd_dbus_invokers.h" #include "ifp_iface_generated.h" /* invokes a handler with a 's' DBus signature */ static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr); /* invokes a handler with a 'u' DBus signature */ static int invoke_u_method(struct sbus_request *dbus_req, void *function_ptr); /* invokes a handler with a 'su' DBus signature */ static int invoke_su_method(struct sbus_request *dbus_req, void *function_ptr); /* invokes a handler with a 'ssu' DBus signature */ static int invoke_ssu_method(struct sbus_request *dbus_req, void *function_ptr); /* arguments for org.freedesktop.sssd.infopipe.ListComponents */ const struct sbus_arg_meta iface_ifp_ListComponents__out[] = { { "components", "ao" }, { NULL, } }; int iface_ifp_ListComponents_finish(struct sbus_request *req, const char *arg_components[], int len_components) { return sbus_request_return_and_finish(req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_components, len_components, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.ListResponders */ const struct sbus_arg_meta iface_ifp_ListResponders__out[] = { { "responders", "ao" }, { NULL, } }; int iface_ifp_ListResponders_finish(struct sbus_request *req, const char *arg_responders[], int len_responders) { return sbus_request_return_and_finish(req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_responders, len_responders, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.ListBackends */ const struct sbus_arg_meta iface_ifp_ListBackends__out[] = { { "backends", "ao" }, { NULL, } }; int iface_ifp_ListBackends_finish(struct sbus_request *req, const char *arg_backends[], int len_backends) { return sbus_request_return_and_finish(req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_backends, len_backends, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.FindMonitor */ const struct sbus_arg_meta iface_ifp_FindMonitor__out[] = { { "monitor", "o" }, { NULL, } }; int iface_ifp_FindMonitor_finish(struct sbus_request *req, const char *arg_monitor) { return sbus_request_return_and_finish(req, DBUS_TYPE_OBJECT_PATH, &arg_monitor, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.FindResponderByName */ const struct sbus_arg_meta iface_ifp_FindResponderByName__in[] = { { "name", "s" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.FindResponderByName */ const struct sbus_arg_meta iface_ifp_FindResponderByName__out[] = { { "responder", "o" }, { NULL, } }; int iface_ifp_FindResponderByName_finish(struct sbus_request *req, const char *arg_responder) { return sbus_request_return_and_finish(req, DBUS_TYPE_OBJECT_PATH, &arg_responder, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.FindBackendByName */ const struct sbus_arg_meta iface_ifp_FindBackendByName__in[] = { { "name", "s" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.FindBackendByName */ const struct sbus_arg_meta iface_ifp_FindBackendByName__out[] = { { "backend", "o" }, { NULL, } }; int iface_ifp_FindBackendByName_finish(struct sbus_request *req, const char *arg_backend) { return sbus_request_return_and_finish(req, DBUS_TYPE_OBJECT_PATH, &arg_backend, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.GetUserAttr */ const struct sbus_arg_meta iface_ifp_GetUserAttr__in[] = { { "user", "s" }, { "attr", "as" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.GetUserAttr */ const struct sbus_arg_meta iface_ifp_GetUserAttr__out[] = { { "values", "a{sv}" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.GetUserGroups */ const struct sbus_arg_meta iface_ifp_GetUserGroups__in[] = { { "user", "s" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.GetUserGroups */ const struct sbus_arg_meta iface_ifp_GetUserGroups__out[] = { { "values", "as" }, { NULL, } }; int iface_ifp_GetUserGroups_finish(struct sbus_request *req, const char *arg_values[], int len_values) { return sbus_request_return_and_finish(req, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &arg_values, len_values, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.FindDomainByName */ const struct sbus_arg_meta iface_ifp_FindDomainByName__in[] = { { "name", "s" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.FindDomainByName */ const struct sbus_arg_meta iface_ifp_FindDomainByName__out[] = { { "domain", "o" }, { NULL, } }; int iface_ifp_FindDomainByName_finish(struct sbus_request *req, const char *arg_domain) { return sbus_request_return_and_finish(req, DBUS_TYPE_OBJECT_PATH, &arg_domain, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.ListDomains */ const struct sbus_arg_meta iface_ifp_ListDomains__out[] = { { "domain", "ao" }, { NULL, } }; int iface_ifp_ListDomains_finish(struct sbus_request *req, const char *arg_domain[], int len_domain) { return sbus_request_return_and_finish(req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_domain, len_domain, DBUS_TYPE_INVALID); } /* methods for org.freedesktop.sssd.infopipe */ const struct sbus_method_meta iface_ifp__methods[] = { { "Ping", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct iface_ifp, Ping), NULL, /* no invoker */ }, { "ListComponents", /* name */ NULL, /* no in_args */ iface_ifp_ListComponents__out, offsetof(struct iface_ifp, ListComponents), NULL, /* no invoker */ }, { "ListResponders", /* name */ NULL, /* no in_args */ iface_ifp_ListResponders__out, offsetof(struct iface_ifp, ListResponders), NULL, /* no invoker */ }, { "ListBackends", /* name */ NULL, /* no in_args */ iface_ifp_ListBackends__out, offsetof(struct iface_ifp, ListBackends), NULL, /* no invoker */ }, { "FindMonitor", /* name */ NULL, /* no in_args */ iface_ifp_FindMonitor__out, offsetof(struct iface_ifp, FindMonitor), NULL, /* no invoker */ }, { "FindResponderByName", /* name */ iface_ifp_FindResponderByName__in, iface_ifp_FindResponderByName__out, offsetof(struct iface_ifp, FindResponderByName), invoke_s_method, }, { "FindBackendByName", /* name */ iface_ifp_FindBackendByName__in, iface_ifp_FindBackendByName__out, offsetof(struct iface_ifp, FindBackendByName), invoke_s_method, }, { "GetUserAttr", /* name */ iface_ifp_GetUserAttr__in, iface_ifp_GetUserAttr__out, offsetof(struct iface_ifp, GetUserAttr), NULL, /* no invoker */ }, { "GetUserGroups", /* name */ iface_ifp_GetUserGroups__in, iface_ifp_GetUserGroups__out, offsetof(struct iface_ifp, GetUserGroups), invoke_s_method, }, { "FindDomainByName", /* name */ iface_ifp_FindDomainByName__in, iface_ifp_FindDomainByName__out, offsetof(struct iface_ifp, FindDomainByName), invoke_s_method, }, { "ListDomains", /* name */ NULL, /* no in_args */ iface_ifp_ListDomains__out, offsetof(struct iface_ifp, ListDomains), NULL, /* no invoker */ }, { NULL, } }; /* interface info for org.freedesktop.sssd.infopipe */ const struct sbus_interface_meta iface_ifp_meta = { "org.freedesktop.sssd.infopipe", /* name */ iface_ifp__methods, NULL, /* no signals */ NULL, /* no properties */ sbus_invoke_get_all, /* GetAll invoker */ }; int iface_ifp_components_Enable_finish(struct sbus_request *req) { return sbus_request_return_and_finish(req, DBUS_TYPE_INVALID); } int iface_ifp_components_Disable_finish(struct sbus_request *req) { return sbus_request_return_and_finish(req, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.Components.ChangeDebugLevel */ const struct sbus_arg_meta iface_ifp_components_ChangeDebugLevel__in[] = { { "new_level", "u" }, { NULL, } }; int iface_ifp_components_ChangeDebugLevel_finish(struct sbus_request *req) { return sbus_request_return_and_finish(req, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.Components.ChangeDebugLevelTemporarily */ const struct sbus_arg_meta iface_ifp_components_ChangeDebugLevelTemporarily__in[] = { { "new_level", "u" }, { NULL, } }; int iface_ifp_components_ChangeDebugLevelTemporarily_finish(struct sbus_request *req) { return sbus_request_return_and_finish(req, DBUS_TYPE_INVALID); } /* methods for org.freedesktop.sssd.infopipe.Components */ const struct sbus_method_meta iface_ifp_components__methods[] = { { "Enable", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct iface_ifp_components, Enable), NULL, /* no invoker */ }, { "Disable", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct iface_ifp_components, Disable), NULL, /* no invoker */ }, { "ChangeDebugLevel", /* name */ iface_ifp_components_ChangeDebugLevel__in, NULL, /* no out_args */ offsetof(struct iface_ifp_components, ChangeDebugLevel), invoke_u_method, }, { "ChangeDebugLevelTemporarily", /* name */ iface_ifp_components_ChangeDebugLevelTemporarily__in, NULL, /* no out_args */ offsetof(struct iface_ifp_components, ChangeDebugLevelTemporarily), invoke_u_method, }, { NULL, } }; /* property info for org.freedesktop.sssd.infopipe.Components */ const struct sbus_property_meta iface_ifp_components__properties[] = { { "name", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_components, get_name), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "debug_level", /* name */ "u", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_components, get_debug_level), sbus_invoke_get_u, 0, /* not writable */ NULL, /* no invoker */ }, { "enabled", /* name */ "b", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_components, get_enabled), sbus_invoke_get_b, 0, /* not writable */ NULL, /* no invoker */ }, { "type", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_components, get_type), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "providers", /* name */ "as", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_components, get_providers), sbus_invoke_get_as, 0, /* not writable */ NULL, /* no invoker */ }, { NULL, } }; /* interface info for org.freedesktop.sssd.infopipe.Components */ const struct sbus_interface_meta iface_ifp_components_meta = { "org.freedesktop.sssd.infopipe.Components", /* name */ iface_ifp_components__methods, NULL, /* no signals */ iface_ifp_components__properties, sbus_invoke_get_all, /* GetAll invoker */ }; /* property info for org.freedesktop.sssd.infopipe.Domains */ const struct sbus_property_meta iface_ifp_domains__properties[] = { { "name", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_name), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "provider", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_provider), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "primary_servers", /* name */ "as", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_primary_servers), sbus_invoke_get_as, 0, /* not writable */ NULL, /* no invoker */ }, { "backup_servers", /* name */ "as", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_backup_servers), sbus_invoke_get_as, 0, /* not writable */ NULL, /* no invoker */ }, { "min_id", /* name */ "u", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_min_id), sbus_invoke_get_u, 0, /* not writable */ NULL, /* no invoker */ }, { "max_id", /* name */ "u", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_max_id), sbus_invoke_get_u, 0, /* not writable */ NULL, /* no invoker */ }, { "realm", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_realm), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "forest", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_forest), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "login_format", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_login_format), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "fully_qualified_name_format", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_fully_qualified_name_format), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "enumerable", /* name */ "b", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_enumerable), sbus_invoke_get_b, 0, /* not writable */ NULL, /* no invoker */ }, { "use_fully_qualified_names", /* name */ "b", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_use_fully_qualified_names), sbus_invoke_get_b, 0, /* not writable */ NULL, /* no invoker */ }, { "subdomain", /* name */ "b", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_subdomain), sbus_invoke_get_b, 0, /* not writable */ NULL, /* no invoker */ }, { "parent_domain", /* name */ "o", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_domains, get_parent_domain), sbus_invoke_get_o, 0, /* not writable */ NULL, /* no invoker */ }, { NULL, } }; /* interface info for org.freedesktop.sssd.infopipe.Domains */ const struct sbus_interface_meta iface_ifp_domains_meta = { "org.freedesktop.sssd.infopipe.Domains", /* name */ NULL, /* no methods */ NULL, /* no signals */ iface_ifp_domains__properties, sbus_invoke_get_all, /* GetAll invoker */ }; /* arguments for org.freedesktop.sssd.infopipe.Cache.List */ const struct sbus_arg_meta iface_ifp_cache_List__out[] = { { "result", "ao" }, { NULL, } }; int iface_ifp_cache_List_finish(struct sbus_request *req, const char *arg_result[], int len_result) { return sbus_request_return_and_finish(req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_result, len_result, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.Cache.ListByDomain */ const struct sbus_arg_meta iface_ifp_cache_ListByDomain__in[] = { { "domain_name", "s" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.Cache.ListByDomain */ const struct sbus_arg_meta iface_ifp_cache_ListByDomain__out[] = { { "result", "ao" }, { NULL, } }; int iface_ifp_cache_ListByDomain_finish(struct sbus_request *req, const char *arg_result[], int len_result) { return sbus_request_return_and_finish(req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_result, len_result, DBUS_TYPE_INVALID); } /* methods for org.freedesktop.sssd.infopipe.Cache */ const struct sbus_method_meta iface_ifp_cache__methods[] = { { "List", /* name */ NULL, /* no in_args */ iface_ifp_cache_List__out, offsetof(struct iface_ifp_cache, List), NULL, /* no invoker */ }, { "ListByDomain", /* name */ iface_ifp_cache_ListByDomain__in, iface_ifp_cache_ListByDomain__out, offsetof(struct iface_ifp_cache, ListByDomain), invoke_s_method, }, { NULL, } }; /* interface info for org.freedesktop.sssd.infopipe.Cache */ const struct sbus_interface_meta iface_ifp_cache_meta = { "org.freedesktop.sssd.infopipe.Cache", /* name */ iface_ifp_cache__methods, NULL, /* no signals */ NULL, /* no properties */ sbus_invoke_get_all, /* GetAll invoker */ }; /* arguments for org.freedesktop.sssd.infopipe.Cache.Object.Store */ const struct sbus_arg_meta iface_ifp_cache_object_Store__out[] = { { "result", "b" }, { NULL, } }; int iface_ifp_cache_object_Store_finish(struct sbus_request *req, bool arg_result) { dbus_bool_t cast_result = arg_result; return sbus_request_return_and_finish(req, DBUS_TYPE_BOOLEAN, &cast_result, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.Cache.Object.Remove */ const struct sbus_arg_meta iface_ifp_cache_object_Remove__out[] = { { "result", "b" }, { NULL, } }; int iface_ifp_cache_object_Remove_finish(struct sbus_request *req, bool arg_result) { dbus_bool_t cast_result = arg_result; return sbus_request_return_and_finish(req, DBUS_TYPE_BOOLEAN, &cast_result, DBUS_TYPE_INVALID); } /* methods for org.freedesktop.sssd.infopipe.Cache.Object */ const struct sbus_method_meta iface_ifp_cache_object__methods[] = { { "Store", /* name */ NULL, /* no in_args */ iface_ifp_cache_object_Store__out, offsetof(struct iface_ifp_cache_object, Store), NULL, /* no invoker */ }, { "Remove", /* name */ NULL, /* no in_args */ iface_ifp_cache_object_Remove__out, offsetof(struct iface_ifp_cache_object, Remove), NULL, /* no invoker */ }, { NULL, } }; /* interface info for org.freedesktop.sssd.infopipe.Cache.Object */ const struct sbus_interface_meta iface_ifp_cache_object_meta = { "org.freedesktop.sssd.infopipe.Cache.Object", /* name */ iface_ifp_cache_object__methods, NULL, /* no signals */ NULL, /* no properties */ sbus_invoke_get_all, /* GetAll invoker */ }; /* arguments for org.freedesktop.sssd.infopipe.Users.FindByName */ const struct sbus_arg_meta iface_ifp_users_FindByName__in[] = { { "name", "s" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.Users.FindByName */ const struct sbus_arg_meta iface_ifp_users_FindByName__out[] = { { "result", "o" }, { NULL, } }; int iface_ifp_users_FindByName_finish(struct sbus_request *req, const char *arg_result) { return sbus_request_return_and_finish(req, DBUS_TYPE_OBJECT_PATH, &arg_result, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.Users.FindByID */ const struct sbus_arg_meta iface_ifp_users_FindByID__in[] = { { "id", "u" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.Users.FindByID */ const struct sbus_arg_meta iface_ifp_users_FindByID__out[] = { { "result", "o" }, { NULL, } }; int iface_ifp_users_FindByID_finish(struct sbus_request *req, const char *arg_result) { return sbus_request_return_and_finish(req, DBUS_TYPE_OBJECT_PATH, &arg_result, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.Users.FindByCertificate */ const struct sbus_arg_meta iface_ifp_users_FindByCertificate__in[] = { { "pem_cert", "s" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.Users.FindByCertificate */ const struct sbus_arg_meta iface_ifp_users_FindByCertificate__out[] = { { "result", "o" }, { NULL, } }; int iface_ifp_users_FindByCertificate_finish(struct sbus_request *req, const char *arg_result) { return sbus_request_return_and_finish(req, DBUS_TYPE_OBJECT_PATH, &arg_result, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.Users.ListByName */ const struct sbus_arg_meta iface_ifp_users_ListByName__in[] = { { "name_filter", "s" }, { "limit", "u" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.Users.ListByName */ const struct sbus_arg_meta iface_ifp_users_ListByName__out[] = { { "result", "ao" }, { NULL, } }; int iface_ifp_users_ListByName_finish(struct sbus_request *req, const char *arg_result[], int len_result) { return sbus_request_return_and_finish(req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_result, len_result, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.Users.ListByDomainAndName */ const struct sbus_arg_meta iface_ifp_users_ListByDomainAndName__in[] = { { "domain_name", "s" }, { "name_filter", "s" }, { "limit", "u" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.Users.ListByDomainAndName */ const struct sbus_arg_meta iface_ifp_users_ListByDomainAndName__out[] = { { "result", "ao" }, { NULL, } }; int iface_ifp_users_ListByDomainAndName_finish(struct sbus_request *req, const char *arg_result[], int len_result) { return sbus_request_return_and_finish(req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_result, len_result, DBUS_TYPE_INVALID); } /* methods for org.freedesktop.sssd.infopipe.Users */ const struct sbus_method_meta iface_ifp_users__methods[] = { { "FindByName", /* name */ iface_ifp_users_FindByName__in, iface_ifp_users_FindByName__out, offsetof(struct iface_ifp_users, FindByName), invoke_s_method, }, { "FindByID", /* name */ iface_ifp_users_FindByID__in, iface_ifp_users_FindByID__out, offsetof(struct iface_ifp_users, FindByID), invoke_u_method, }, { "FindByCertificate", /* name */ iface_ifp_users_FindByCertificate__in, iface_ifp_users_FindByCertificate__out, offsetof(struct iface_ifp_users, FindByCertificate), invoke_s_method, }, { "ListByName", /* name */ iface_ifp_users_ListByName__in, iface_ifp_users_ListByName__out, offsetof(struct iface_ifp_users, ListByName), invoke_su_method, }, { "ListByDomainAndName", /* name */ iface_ifp_users_ListByDomainAndName__in, iface_ifp_users_ListByDomainAndName__out, offsetof(struct iface_ifp_users, ListByDomainAndName), invoke_ssu_method, }, { NULL, } }; /* interface info for org.freedesktop.sssd.infopipe.Users */ const struct sbus_interface_meta iface_ifp_users_meta = { "org.freedesktop.sssd.infopipe.Users", /* name */ iface_ifp_users__methods, NULL, /* no signals */ NULL, /* no properties */ sbus_invoke_get_all, /* GetAll invoker */ }; int iface_ifp_users_user_UpdateGroupsList_finish(struct sbus_request *req) { return sbus_request_return_and_finish(req, DBUS_TYPE_INVALID); } /* methods for org.freedesktop.sssd.infopipe.Users.User */ const struct sbus_method_meta iface_ifp_users_user__methods[] = { { "UpdateGroupsList", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct iface_ifp_users_user, UpdateGroupsList), NULL, /* no invoker */ }, { NULL, } }; /* property info for org.freedesktop.sssd.infopipe.Users.User */ const struct sbus_property_meta iface_ifp_users_user__properties[] = { { "name", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_users_user, get_name), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "uidNumber", /* name */ "u", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_users_user, get_uidNumber), sbus_invoke_get_u, 0, /* not writable */ NULL, /* no invoker */ }, { "gidNumber", /* name */ "u", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_users_user, get_gidNumber), sbus_invoke_get_u, 0, /* not writable */ NULL, /* no invoker */ }, { "gecos", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_users_user, get_gecos), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "homeDirectory", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_users_user, get_homeDirectory), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "loginShell", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_users_user, get_loginShell), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "groups", /* name */ "ao", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_users_user, get_groups), sbus_invoke_get_ao, 0, /* not writable */ NULL, /* no invoker */ }, { "extraAttributes", /* name */ "a{sas}", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_users_user, get_extraAttributes), sbus_invoke_get_aDOsasDE, 0, /* not writable */ NULL, /* no invoker */ }, { NULL, } }; /* interface info for org.freedesktop.sssd.infopipe.Users.User */ const struct sbus_interface_meta iface_ifp_users_user_meta = { "org.freedesktop.sssd.infopipe.Users.User", /* name */ iface_ifp_users_user__methods, NULL, /* no signals */ iface_ifp_users_user__properties, sbus_invoke_get_all, /* GetAll invoker */ }; /* arguments for org.freedesktop.sssd.infopipe.Groups.FindByName */ const struct sbus_arg_meta iface_ifp_groups_FindByName__in[] = { { "name", "s" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.Groups.FindByName */ const struct sbus_arg_meta iface_ifp_groups_FindByName__out[] = { { "result", "o" }, { NULL, } }; int iface_ifp_groups_FindByName_finish(struct sbus_request *req, const char *arg_result) { return sbus_request_return_and_finish(req, DBUS_TYPE_OBJECT_PATH, &arg_result, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.Groups.FindByID */ const struct sbus_arg_meta iface_ifp_groups_FindByID__in[] = { { "id", "u" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.Groups.FindByID */ const struct sbus_arg_meta iface_ifp_groups_FindByID__out[] = { { "result", "o" }, { NULL, } }; int iface_ifp_groups_FindByID_finish(struct sbus_request *req, const char *arg_result) { return sbus_request_return_and_finish(req, DBUS_TYPE_OBJECT_PATH, &arg_result, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.Groups.ListByName */ const struct sbus_arg_meta iface_ifp_groups_ListByName__in[] = { { "name_filter", "s" }, { "limit", "u" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.Groups.ListByName */ const struct sbus_arg_meta iface_ifp_groups_ListByName__out[] = { { "result", "ao" }, { NULL, } }; int iface_ifp_groups_ListByName_finish(struct sbus_request *req, const char *arg_result[], int len_result) { return sbus_request_return_and_finish(req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_result, len_result, DBUS_TYPE_INVALID); } /* arguments for org.freedesktop.sssd.infopipe.Groups.ListByDomainAndName */ const struct sbus_arg_meta iface_ifp_groups_ListByDomainAndName__in[] = { { "domain_name", "s" }, { "name_filter", "s" }, { "limit", "u" }, { NULL, } }; /* arguments for org.freedesktop.sssd.infopipe.Groups.ListByDomainAndName */ const struct sbus_arg_meta iface_ifp_groups_ListByDomainAndName__out[] = { { "result", "ao" }, { NULL, } }; int iface_ifp_groups_ListByDomainAndName_finish(struct sbus_request *req, const char *arg_result[], int len_result) { return sbus_request_return_and_finish(req, DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &arg_result, len_result, DBUS_TYPE_INVALID); } /* methods for org.freedesktop.sssd.infopipe.Groups */ const struct sbus_method_meta iface_ifp_groups__methods[] = { { "FindByName", /* name */ iface_ifp_groups_FindByName__in, iface_ifp_groups_FindByName__out, offsetof(struct iface_ifp_groups, FindByName), invoke_s_method, }, { "FindByID", /* name */ iface_ifp_groups_FindByID__in, iface_ifp_groups_FindByID__out, offsetof(struct iface_ifp_groups, FindByID), invoke_u_method, }, { "ListByName", /* name */ iface_ifp_groups_ListByName__in, iface_ifp_groups_ListByName__out, offsetof(struct iface_ifp_groups, ListByName), invoke_su_method, }, { "ListByDomainAndName", /* name */ iface_ifp_groups_ListByDomainAndName__in, iface_ifp_groups_ListByDomainAndName__out, offsetof(struct iface_ifp_groups, ListByDomainAndName), invoke_ssu_method, }, { NULL, } }; /* interface info for org.freedesktop.sssd.infopipe.Groups */ const struct sbus_interface_meta iface_ifp_groups_meta = { "org.freedesktop.sssd.infopipe.Groups", /* name */ iface_ifp_groups__methods, NULL, /* no signals */ NULL, /* no properties */ sbus_invoke_get_all, /* GetAll invoker */ }; int iface_ifp_groups_group_UpdateMemberList_finish(struct sbus_request *req) { return sbus_request_return_and_finish(req, DBUS_TYPE_INVALID); } /* methods for org.freedesktop.sssd.infopipe.Groups.Group */ const struct sbus_method_meta iface_ifp_groups_group__methods[] = { { "UpdateMemberList", /* name */ NULL, /* no in_args */ NULL, /* no out_args */ offsetof(struct iface_ifp_groups_group, UpdateMemberList), NULL, /* no invoker */ }, { NULL, } }; /* property info for org.freedesktop.sssd.infopipe.Groups.Group */ const struct sbus_property_meta iface_ifp_groups_group__properties[] = { { "name", /* name */ "s", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_groups_group, get_name), sbus_invoke_get_s, 0, /* not writable */ NULL, /* no invoker */ }, { "gidNumber", /* name */ "u", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_groups_group, get_gidNumber), sbus_invoke_get_u, 0, /* not writable */ NULL, /* no invoker */ }, { "users", /* name */ "ao", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_groups_group, get_users), sbus_invoke_get_ao, 0, /* not writable */ NULL, /* no invoker */ }, { "groups", /* name */ "ao", /* type */ SBUS_PROPERTY_READABLE, offsetof(struct iface_ifp_groups_group, get_groups), sbus_invoke_get_ao, 0, /* not writable */ NULL, /* no invoker */ }, { NULL, } }; /* interface info for org.freedesktop.sssd.infopipe.Groups.Group */ const struct sbus_interface_meta iface_ifp_groups_group_meta = { "org.freedesktop.sssd.infopipe.Groups.Group", /* name */ iface_ifp_groups_group__methods, NULL, /* no signals */ iface_ifp_groups_group__properties, sbus_invoke_get_all, /* GetAll invoker */ }; /* invokes a handler with a 'ssu' DBus signature */ static int invoke_ssu_method(struct sbus_request *dbus_req, void *function_ptr) { const char * arg_0; const char * arg_1; uint32_t arg_2; int (*handler)(struct sbus_request *, void *, const char *, const char *, uint32_t) = function_ptr; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_STRING, &arg_0, DBUS_TYPE_STRING, &arg_1, DBUS_TYPE_UINT32, &arg_2, DBUS_TYPE_INVALID)) { return EOK; /* request handled */ } return (handler)(dbus_req, dbus_req->intf->handler_data, arg_0, arg_1, arg_2); } /* invokes a handler with a 's' DBus signature */ static int invoke_s_method(struct sbus_request *dbus_req, void *function_ptr) { const char * arg_0; int (*handler)(struct sbus_request *, void *, const char *) = function_ptr; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_STRING, &arg_0, DBUS_TYPE_INVALID)) { return EOK; /* request handled */ } return (handler)(dbus_req, dbus_req->intf->handler_data, arg_0); } /* invokes a handler with a 'u' DBus signature */ static int invoke_u_method(struct sbus_request *dbus_req, void *function_ptr) { uint32_t arg_0; int (*handler)(struct sbus_request *, void *, uint32_t) = function_ptr; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_UINT32, &arg_0, DBUS_TYPE_INVALID)) { return EOK; /* request handled */ } return (handler)(dbus_req, dbus_req->intf->handler_data, arg_0); } /* invokes a handler with a 'su' DBus signature */ static int invoke_su_method(struct sbus_request *dbus_req, void *function_ptr) { const char * arg_0; uint32_t arg_1; int (*handler)(struct sbus_request *, void *, const char *, uint32_t) = function_ptr; if (!sbus_request_parse_or_finish(dbus_req, DBUS_TYPE_STRING, &arg_0, DBUS_TYPE_UINT32, &arg_1, DBUS_TYPE_INVALID)) { return EOK; /* request handled */ } return (handler)(dbus_req, dbus_req->intf->handler_data, arg_0, arg_1); } sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifpsrv_util.c0000644000000000000000000000007412703456111020405 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.932794571 sssd-1.13.4/src/responder/ifp/ifpsrv_util.c0000644002412700241270000002220112703456111022051 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Stephen Gallagher Copyright (C) 2013 Red Hat InfoPipe responder: Utility functions This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "db/sysdb.h" #include "responder/ifp/ifp_private.h" #define IFP_USER_DEFAULT_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \ SYSDB_GIDNUM, SYSDB_GECOS, \ SYSDB_HOMEDIR, SYSDB_SHELL, \ "groups", \ NULL} errno_t ifp_req_create(struct sbus_request *dbus_req, struct ifp_ctx *ifp_ctx, struct ifp_req **_ifp_req) { struct ifp_req *ireq = NULL; errno_t ret; if (ifp_ctx->sysbus == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Responder not connected to sysbus!\n"); return EINVAL; } ireq = talloc_zero(dbus_req, struct ifp_req); if (ireq == NULL) { return ENOMEM; } ireq->ifp_ctx = ifp_ctx; ireq->dbus_req = dbus_req; if (dbus_req->client == -1) { /* We got a sysbus message but couldn't identify the * caller? Bail out! */ DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Received a message without a known caller!\n"); ret = EACCES; goto done; } ret = check_allowed_uids(dbus_req->client, ifp_ctx->rctx->allowed_uids_count, ifp_ctx->rctx->allowed_uids); if (ret == EACCES) { DEBUG(SSSDBG_MINOR_FAILURE, "User %"PRIi64" not in ACL\n", dbus_req->client); goto done; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot check if user %"PRIi64" is present in ACL\n", dbus_req->client); goto done; } *_ifp_req = ireq; ret = EOK; done: if (ret != EOK) { talloc_free(ireq); } return ret; } int ifp_req_create_handle_failure(struct sbus_request *dbus_req, errno_t err) { if (err == EACCES) { return sbus_request_fail_and_finish(dbus_req, sbus_error_new(dbus_req, DBUS_ERROR_ACCESS_DENIED, "User %"PRIi64" not in ACL\n", dbus_req->client)); } return sbus_request_fail_and_finish(dbus_req, sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "Cannot create IFP request\n")); } errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict, struct ldb_message_element *el) { DBusMessageIter iter_dict_entry; DBusMessageIter iter_dict_val; DBusMessageIter iter_array; dbus_bool_t dbret; unsigned int i; if (el == NULL) { return EINVAL; } dbret = dbus_message_iter_open_container(iter_dict, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict_entry); if (!dbret) { return ENOMEM; } /* Start by appending the key */ dbret = dbus_message_iter_append_basic(&iter_dict_entry, DBUS_TYPE_STRING, &(el->name)); if (!dbret) { return ENOMEM; } dbret = dbus_message_iter_open_container(&iter_dict_entry, DBUS_TYPE_VARIANT, DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, &iter_dict_val); if (!dbret) { return ENOMEM; } /* Open container for values */ dbret = dbus_message_iter_open_container(&iter_dict_val, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &iter_array); if (!dbret) { return ENOMEM; } /* Now add all the values */ for (i = 0; i < el->num_values; i++) { DEBUG(SSSDBG_TRACE_FUNC, "element [%s] has value [%s]\n", el->name, (const char *) el->values[i].data); dbret = dbus_message_iter_append_basic(&iter_array, DBUS_TYPE_STRING, &(el->values[i].data)); if (!dbret) { return ENOMEM; } } dbret = dbus_message_iter_close_container(&iter_dict_val, &iter_array); if (!dbret) { return ENOMEM; } dbret = dbus_message_iter_close_container(&iter_dict_entry, &iter_dict_val); if (!dbret) { return ENOMEM; } dbret = dbus_message_iter_close_container(iter_dict, &iter_dict_entry); if (!dbret) { return ENOMEM; } return EOK; } bool ifp_attr_allowed(const char *whitelist[], const char *attr) { size_t i; if (whitelist == NULL) { return false; } for (i = 0; whitelist[i]; i++) { if (strcasecmp(whitelist[i], attr) == 0) { break; } } return (whitelist[i]) ? true : false; } const char ** ifp_parse_user_attr_list(TALLOC_CTX *mem_ctx, const char *csv) { static const char *defaults[] = IFP_USER_DEFAULT_ATTRS; return parse_attr_list_ex(mem_ctx, csv, defaults); } const char ** ifp_get_user_extra_attributes(TALLOC_CTX *mem_ctx, struct ifp_ctx *ifp_ctx) { TALLOC_CTX *tmp_ctx = NULL; const char *std[] = IFP_USER_DEFAULT_ATTRS; const char **whitelist = ifp_ctx->user_whitelist; const char **extra; bool found; int extra_num; int i, j; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return NULL; } for (i = 0; whitelist[i] != NULL; i++) { /* Just count number of attributes in whitelist. */ } extra = talloc_zero_array(tmp_ctx, const char *, i + 1); if (extra == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); goto fail; } extra_num = 0; for (i = 0; whitelist[i] != NULL; i++) { found = false; for (j = 0; std[j] != NULL; j++) { if (strcmp(whitelist[i], std[j]) == 0) { found = true; break; } } if (!found) { extra[extra_num] = talloc_strdup(extra, whitelist[i]); if (extra[extra_num] == NULL) { goto fail; } extra_num++; } } extra = talloc_realloc(tmp_ctx, extra, const char *, extra_num + 1); if (extra == NULL) { goto fail; } talloc_steal(mem_ctx, extra); talloc_free(tmp_ctx); return extra; fail: talloc_free(tmp_ctx); return NULL; } bool ifp_is_user_attr_allowed(struct ifp_ctx *ifp_ctx, const char *attr) { return ifp_attr_allowed(ifp_ctx->user_whitelist, attr); } static uint32_t ifp_list_limit(struct ifp_ctx *ctx, uint32_t limit) { if (limit == 0) { return ctx->wildcard_limit; } else if (ctx->wildcard_limit) { return MIN(ctx->wildcard_limit, limit); } else { return limit; } } struct ifp_list_ctx *ifp_list_ctx_new(struct sbus_request *sbus_req, struct ifp_ctx *ctx, const char *filter, uint32_t limit) { struct ifp_list_ctx *list_ctx; list_ctx = talloc_zero(sbus_req, struct ifp_list_ctx); if (list_ctx == NULL) { return NULL; } list_ctx->sbus_req = sbus_req; list_ctx->limit = ifp_list_limit(ctx, limit); list_ctx->ctx = ctx; list_ctx->dom = ctx->rctx->domains; list_ctx->filter = filter; list_ctx->paths = talloc_zero_array(list_ctx, const char *, limit); if (list_ctx->paths == NULL) { talloc_free(list_ctx); return NULL; } return list_ctx; } size_t ifp_list_ctx_remaining_capacity(struct ifp_list_ctx *list_ctx, size_t entries) { size_t capacity = list_ctx->limit - list_ctx->path_count; if (capacity < entries) { DEBUG(SSSDBG_MINOR_FAILURE, "IFP list request has limit of %"PRIu32" entries but back end " "returned %zu entries\n", list_ctx->limit, entries); return capacity; } else { return entries; } } sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_iface_generated.h0000644000000000000000000000007412703456111021767 xustar0030 atime=1460561751.651715631 30 ctime=1460561775.001794805 sssd-1.13.4/src/responder/ifp/ifp_iface_generated.h0000644002412700241270000004056312703456111023446 0ustar00jhrozekjhrozek00000000000000/* The following declarations are auto-generated from ifp_iface.xml */ #ifndef __IFP_IFACE_XML__ #define __IFP_IFACE_XML__ #include "sbus/sssd_dbus.h" /* ------------------------------------------------------------------------ * DBus Constants * * Various constants of interface and method names mostly for use by clients */ /* constants for org.freedesktop.sssd.infopipe */ #define IFACE_IFP "org.freedesktop.sssd.infopipe" #define IFACE_IFP_PING "Ping" #define IFACE_IFP_LISTCOMPONENTS "ListComponents" #define IFACE_IFP_LISTRESPONDERS "ListResponders" #define IFACE_IFP_LISTBACKENDS "ListBackends" #define IFACE_IFP_FINDMONITOR "FindMonitor" #define IFACE_IFP_FINDRESPONDERBYNAME "FindResponderByName" #define IFACE_IFP_FINDBACKENDBYNAME "FindBackendByName" #define IFACE_IFP_GETUSERATTR "GetUserAttr" #define IFACE_IFP_GETUSERGROUPS "GetUserGroups" #define IFACE_IFP_FINDDOMAINBYNAME "FindDomainByName" #define IFACE_IFP_LISTDOMAINS "ListDomains" /* constants for org.freedesktop.sssd.infopipe.Components */ #define IFACE_IFP_COMPONENTS "org.freedesktop.sssd.infopipe.Components" #define IFACE_IFP_COMPONENTS_ENABLE "Enable" #define IFACE_IFP_COMPONENTS_DISABLE "Disable" #define IFACE_IFP_COMPONENTS_CHANGEDEBUGLEVEL "ChangeDebugLevel" #define IFACE_IFP_COMPONENTS_CHANGEDEBUGLEVELTEMPORARILY "ChangeDebugLevelTemporarily" #define IFACE_IFP_COMPONENTS_NAME "name" #define IFACE_IFP_COMPONENTS_DEBUG_LEVEL "debug_level" #define IFACE_IFP_COMPONENTS_ENABLED "enabled" #define IFACE_IFP_COMPONENTS_TYPE "type" #define IFACE_IFP_COMPONENTS_PROVIDERS "providers" /* constants for org.freedesktop.sssd.infopipe.Domains */ #define IFACE_IFP_DOMAINS "org.freedesktop.sssd.infopipe.Domains" #define IFACE_IFP_DOMAINS_NAME "name" #define IFACE_IFP_DOMAINS_PROVIDER "provider" #define IFACE_IFP_DOMAINS_PRIMARY_SERVERS "primary_servers" #define IFACE_IFP_DOMAINS_BACKUP_SERVERS "backup_servers" #define IFACE_IFP_DOMAINS_MIN_ID "min_id" #define IFACE_IFP_DOMAINS_MAX_ID "max_id" #define IFACE_IFP_DOMAINS_REALM "realm" #define IFACE_IFP_DOMAINS_FOREST "forest" #define IFACE_IFP_DOMAINS_LOGIN_FORMAT "login_format" #define IFACE_IFP_DOMAINS_FULLY_QUALIFIED_NAME_FORMAT "fully_qualified_name_format" #define IFACE_IFP_DOMAINS_ENUMERABLE "enumerable" #define IFACE_IFP_DOMAINS_USE_FULLY_QUALIFIED_NAMES "use_fully_qualified_names" #define IFACE_IFP_DOMAINS_SUBDOMAIN "subdomain" #define IFACE_IFP_DOMAINS_PARENT_DOMAIN "parent_domain" /* constants for org.freedesktop.sssd.infopipe.Cache */ #define IFACE_IFP_CACHE "org.freedesktop.sssd.infopipe.Cache" #define IFACE_IFP_CACHE_LIST "List" #define IFACE_IFP_CACHE_LISTBYDOMAIN "ListByDomain" /* constants for org.freedesktop.sssd.infopipe.Cache.Object */ #define IFACE_IFP_CACHE_OBJECT "org.freedesktop.sssd.infopipe.Cache.Object" #define IFACE_IFP_CACHE_OBJECT_STORE "Store" #define IFACE_IFP_CACHE_OBJECT_REMOVE "Remove" /* constants for org.freedesktop.sssd.infopipe.Users */ #define IFACE_IFP_USERS "org.freedesktop.sssd.infopipe.Users" #define IFACE_IFP_USERS_FINDBYNAME "FindByName" #define IFACE_IFP_USERS_FINDBYID "FindByID" #define IFACE_IFP_USERS_FINDBYCERTIFICATE "FindByCertificate" #define IFACE_IFP_USERS_LISTBYNAME "ListByName" #define IFACE_IFP_USERS_LISTBYDOMAINANDNAME "ListByDomainAndName" /* constants for org.freedesktop.sssd.infopipe.Users.User */ #define IFACE_IFP_USERS_USER "org.freedesktop.sssd.infopipe.Users.User" #define IFACE_IFP_USERS_USER_UPDATEGROUPSLIST "UpdateGroupsList" #define IFACE_IFP_USERS_USER_NAME "name" #define IFACE_IFP_USERS_USER_UIDNUMBER "uidNumber" #define IFACE_IFP_USERS_USER_GIDNUMBER "gidNumber" #define IFACE_IFP_USERS_USER_GECOS "gecos" #define IFACE_IFP_USERS_USER_HOMEDIRECTORY "homeDirectory" #define IFACE_IFP_USERS_USER_LOGINSHELL "loginShell" #define IFACE_IFP_USERS_USER_GROUPS "groups" #define IFACE_IFP_USERS_USER_EXTRAATTRIBUTES "extraAttributes" /* constants for org.freedesktop.sssd.infopipe.Groups */ #define IFACE_IFP_GROUPS "org.freedesktop.sssd.infopipe.Groups" #define IFACE_IFP_GROUPS_FINDBYNAME "FindByName" #define IFACE_IFP_GROUPS_FINDBYID "FindByID" #define IFACE_IFP_GROUPS_LISTBYNAME "ListByName" #define IFACE_IFP_GROUPS_LISTBYDOMAINANDNAME "ListByDomainAndName" /* constants for org.freedesktop.sssd.infopipe.Groups.Group */ #define IFACE_IFP_GROUPS_GROUP "org.freedesktop.sssd.infopipe.Groups.Group" #define IFACE_IFP_GROUPS_GROUP_UPDATEMEMBERLIST "UpdateMemberList" #define IFACE_IFP_GROUPS_GROUP_NAME "name" #define IFACE_IFP_GROUPS_GROUP_GIDNUMBER "gidNumber" #define IFACE_IFP_GROUPS_GROUP_USERS "users" #define IFACE_IFP_GROUPS_GROUP_GROUPS "groups" /* ------------------------------------------------------------------------ * DBus handlers * * These structures are filled in by implementors of the different * dbus interfaces to handle method calls. * * Handler functions of type sbus_msg_handler_fn accept raw messages, * other handlers are typed appropriately. If a handler that is * set to NULL is invoked it will result in a * org.freedesktop.DBus.Error.NotSupported error for the caller. * * Handlers have a matching xxx_finish() function (unless the method has * accepts raw messages). These finish functions the * sbus_request_return_and_finish() with the appropriate arguments to * construct a valid reply. Once a finish function has been called, the * @dbus_req it was called with is freed and no longer valid. */ /* vtable for org.freedesktop.sssd.infopipe */ struct iface_ifp { struct sbus_vtable vtable; /* derive from sbus_vtable */ sbus_msg_handler_fn Ping; int (*ListComponents)(struct sbus_request *req, void *data); int (*ListResponders)(struct sbus_request *req, void *data); int (*ListBackends)(struct sbus_request *req, void *data); int (*FindMonitor)(struct sbus_request *req, void *data); int (*FindResponderByName)(struct sbus_request *req, void *data, const char *arg_name); int (*FindBackendByName)(struct sbus_request *req, void *data, const char *arg_name); sbus_msg_handler_fn GetUserAttr; int (*GetUserGroups)(struct sbus_request *req, void *data, const char *arg_user); int (*FindDomainByName)(struct sbus_request *req, void *data, const char *arg_name); int (*ListDomains)(struct sbus_request *req, void *data); }; /* finish function for ListComponents */ int iface_ifp_ListComponents_finish(struct sbus_request *req, const char *arg_components[], int len_components); /* finish function for ListResponders */ int iface_ifp_ListResponders_finish(struct sbus_request *req, const char *arg_responders[], int len_responders); /* finish function for ListBackends */ int iface_ifp_ListBackends_finish(struct sbus_request *req, const char *arg_backends[], int len_backends); /* finish function for FindMonitor */ int iface_ifp_FindMonitor_finish(struct sbus_request *req, const char *arg_monitor); /* finish function for FindResponderByName */ int iface_ifp_FindResponderByName_finish(struct sbus_request *req, const char *arg_responder); /* finish function for FindBackendByName */ int iface_ifp_FindBackendByName_finish(struct sbus_request *req, const char *arg_backend); /* finish function for GetUserGroups */ int iface_ifp_GetUserGroups_finish(struct sbus_request *req, const char *arg_values[], int len_values); /* finish function for FindDomainByName */ int iface_ifp_FindDomainByName_finish(struct sbus_request *req, const char *arg_domain); /* finish function for ListDomains */ int iface_ifp_ListDomains_finish(struct sbus_request *req, const char *arg_domain[], int len_domain); /* vtable for org.freedesktop.sssd.infopipe.Components */ struct iface_ifp_components { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*Enable)(struct sbus_request *req, void *data); int (*Disable)(struct sbus_request *req, void *data); int (*ChangeDebugLevel)(struct sbus_request *req, void *data, uint32_t arg_new_level); int (*ChangeDebugLevelTemporarily)(struct sbus_request *req, void *data, uint32_t arg_new_level); void (*get_name)(struct sbus_request *, void *data, const char **); void (*get_debug_level)(struct sbus_request *, void *data, uint32_t*); void (*get_enabled)(struct sbus_request *, void *data, bool*); void (*get_type)(struct sbus_request *, void *data, const char **); void (*get_providers)(struct sbus_request *, void *data, const char ***, int *); }; /* finish function for Enable */ int iface_ifp_components_Enable_finish(struct sbus_request *req); /* finish function for Disable */ int iface_ifp_components_Disable_finish(struct sbus_request *req); /* finish function for ChangeDebugLevel */ int iface_ifp_components_ChangeDebugLevel_finish(struct sbus_request *req); /* finish function for ChangeDebugLevelTemporarily */ int iface_ifp_components_ChangeDebugLevelTemporarily_finish(struct sbus_request *req); /* vtable for org.freedesktop.sssd.infopipe.Domains */ struct iface_ifp_domains { struct sbus_vtable vtable; /* derive from sbus_vtable */ void (*get_name)(struct sbus_request *, void *data, const char **); void (*get_provider)(struct sbus_request *, void *data, const char **); void (*get_primary_servers)(struct sbus_request *, void *data, const char ***, int *); void (*get_backup_servers)(struct sbus_request *, void *data, const char ***, int *); void (*get_min_id)(struct sbus_request *, void *data, uint32_t*); void (*get_max_id)(struct sbus_request *, void *data, uint32_t*); void (*get_realm)(struct sbus_request *, void *data, const char **); void (*get_forest)(struct sbus_request *, void *data, const char **); void (*get_login_format)(struct sbus_request *, void *data, const char **); void (*get_fully_qualified_name_format)(struct sbus_request *, void *data, const char **); void (*get_enumerable)(struct sbus_request *, void *data, bool*); void (*get_use_fully_qualified_names)(struct sbus_request *, void *data, bool*); void (*get_subdomain)(struct sbus_request *, void *data, bool*); void (*get_parent_domain)(struct sbus_request *, void *data, const char **); }; /* vtable for org.freedesktop.sssd.infopipe.Cache */ struct iface_ifp_cache { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*List)(struct sbus_request *req, void *data); int (*ListByDomain)(struct sbus_request *req, void *data, const char *arg_domain_name); }; /* finish function for List */ int iface_ifp_cache_List_finish(struct sbus_request *req, const char *arg_result[], int len_result); /* finish function for ListByDomain */ int iface_ifp_cache_ListByDomain_finish(struct sbus_request *req, const char *arg_result[], int len_result); /* vtable for org.freedesktop.sssd.infopipe.Cache.Object */ struct iface_ifp_cache_object { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*Store)(struct sbus_request *req, void *data); int (*Remove)(struct sbus_request *req, void *data); }; /* finish function for Store */ int iface_ifp_cache_object_Store_finish(struct sbus_request *req, bool arg_result); /* finish function for Remove */ int iface_ifp_cache_object_Remove_finish(struct sbus_request *req, bool arg_result); /* vtable for org.freedesktop.sssd.infopipe.Users */ struct iface_ifp_users { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*FindByName)(struct sbus_request *req, void *data, const char *arg_name); int (*FindByID)(struct sbus_request *req, void *data, uint32_t arg_id); int (*FindByCertificate)(struct sbus_request *req, void *data, const char *arg_pem_cert); int (*ListByName)(struct sbus_request *req, void *data, const char *arg_name_filter, uint32_t arg_limit); int (*ListByDomainAndName)(struct sbus_request *req, void *data, const char *arg_domain_name, const char *arg_name_filter, uint32_t arg_limit); }; /* finish function for FindByName */ int iface_ifp_users_FindByName_finish(struct sbus_request *req, const char *arg_result); /* finish function for FindByID */ int iface_ifp_users_FindByID_finish(struct sbus_request *req, const char *arg_result); /* finish function for FindByCertificate */ int iface_ifp_users_FindByCertificate_finish(struct sbus_request *req, const char *arg_result); /* finish function for ListByName */ int iface_ifp_users_ListByName_finish(struct sbus_request *req, const char *arg_result[], int len_result); /* finish function for ListByDomainAndName */ int iface_ifp_users_ListByDomainAndName_finish(struct sbus_request *req, const char *arg_result[], int len_result); /* vtable for org.freedesktop.sssd.infopipe.Users.User */ struct iface_ifp_users_user { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*UpdateGroupsList)(struct sbus_request *req, void *data); void (*get_name)(struct sbus_request *, void *data, const char **); void (*get_uidNumber)(struct sbus_request *, void *data, uint32_t*); void (*get_gidNumber)(struct sbus_request *, void *data, uint32_t*); void (*get_gecos)(struct sbus_request *, void *data, const char **); void (*get_homeDirectory)(struct sbus_request *, void *data, const char **); void (*get_loginShell)(struct sbus_request *, void *data, const char **); void (*get_groups)(struct sbus_request *, void *data, const char ***, int *); void (*get_extraAttributes)(struct sbus_request *, void *data, hash_table_t **); }; /* finish function for UpdateGroupsList */ int iface_ifp_users_user_UpdateGroupsList_finish(struct sbus_request *req); /* vtable for org.freedesktop.sssd.infopipe.Groups */ struct iface_ifp_groups { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*FindByName)(struct sbus_request *req, void *data, const char *arg_name); int (*FindByID)(struct sbus_request *req, void *data, uint32_t arg_id); int (*ListByName)(struct sbus_request *req, void *data, const char *arg_name_filter, uint32_t arg_limit); int (*ListByDomainAndName)(struct sbus_request *req, void *data, const char *arg_domain_name, const char *arg_name_filter, uint32_t arg_limit); }; /* finish function for FindByName */ int iface_ifp_groups_FindByName_finish(struct sbus_request *req, const char *arg_result); /* finish function for FindByID */ int iface_ifp_groups_FindByID_finish(struct sbus_request *req, const char *arg_result); /* finish function for ListByName */ int iface_ifp_groups_ListByName_finish(struct sbus_request *req, const char *arg_result[], int len_result); /* finish function for ListByDomainAndName */ int iface_ifp_groups_ListByDomainAndName_finish(struct sbus_request *req, const char *arg_result[], int len_result); /* vtable for org.freedesktop.sssd.infopipe.Groups.Group */ struct iface_ifp_groups_group { struct sbus_vtable vtable; /* derive from sbus_vtable */ int (*UpdateMemberList)(struct sbus_request *req, void *data); void (*get_name)(struct sbus_request *, void *data, const char **); void (*get_gidNumber)(struct sbus_request *, void *data, uint32_t*); void (*get_users)(struct sbus_request *, void *data, const char ***, int *); void (*get_groups)(struct sbus_request *, void *data, const char ***, int *); }; /* finish function for UpdateMemberList */ int iface_ifp_groups_group_UpdateMemberList_finish(struct sbus_request *req); /* ------------------------------------------------------------------------ * DBus Interface Metadata * * These structure definitions are filled in with the information about * the interfaces, methods, properties and so on. * * The actual definitions are found in the accompanying C file next * to this header. */ /* interface info for org.freedesktop.sssd.infopipe */ extern const struct sbus_interface_meta iface_ifp_meta; /* interface info for org.freedesktop.sssd.infopipe.Components */ extern const struct sbus_interface_meta iface_ifp_components_meta; /* interface info for org.freedesktop.sssd.infopipe.Domains */ extern const struct sbus_interface_meta iface_ifp_domains_meta; /* interface info for org.freedesktop.sssd.infopipe.Cache */ extern const struct sbus_interface_meta iface_ifp_cache_meta; /* interface info for org.freedesktop.sssd.infopipe.Cache.Object */ extern const struct sbus_interface_meta iface_ifp_cache_object_meta; /* interface info for org.freedesktop.sssd.infopipe.Users */ extern const struct sbus_interface_meta iface_ifp_users_meta; /* interface info for org.freedesktop.sssd.infopipe.Users.User */ extern const struct sbus_interface_meta iface_ifp_users_user_meta; /* interface info for org.freedesktop.sssd.infopipe.Groups */ extern const struct sbus_interface_meta iface_ifp_groups_meta; /* interface info for org.freedesktop.sssd.infopipe.Groups.Group */ extern const struct sbus_interface_meta iface_ifp_groups_group_meta; #endif /* __IFP_IFACE_XML__ */ sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/org.freedesktop.sssd.infopipe.conf0000644000000000000000000000007412703456111024426 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.355792615 sssd-1.13.4/src/responder/ifp/org.freedesktop.sssd.infopipe.conf0000644002412700241270000000343012703456111026075 0ustar00jhrozekjhrozek00000000000000 sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_users.c0000644000000000000000000000007412703456111020036 xustar0030 atime=1460561751.651715631 30 ctime=1460561775.006794822 sssd-1.13.4/src/responder/ifp/ifp_users.c0000644002412700241270000007145112703456111021515 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include "db/sysdb.h" #include "util/util.h" #include "util/strtonum.h" #include "util/cert.h" #include "sbus/sssd_dbus_errors.h" #include "responder/common/responder.h" #include "responder/common/responder_cache_req.h" #include "responder/ifp/ifp_users.h" #include "responder/ifp/ifp_groups.h" #include "responder/ifp/ifp_cache.h" char * ifp_users_build_path_from_msg(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_message *msg) { const char *uid; uid = ldb_msg_find_attr_as_string(msg, SYSDB_UIDNUM, NULL); if (uid == NULL) { return NULL; } return sbus_opath_compose(mem_ctx, IFP_PATH_USERS, domain->name, uid); } static errno_t ifp_users_decompose_path(struct sss_domain_info *domains, const char *path, struct sss_domain_info **_domain, uid_t *_uid) { char **parts = NULL; struct sss_domain_info *domain; uid_t uid; errno_t ret; ret = sbus_opath_decompose_exact(NULL, path, IFP_PATH_USERS, 2, &parts); if (ret != EOK) { return ret; } domain = find_domain_by_name(domains, parts[0], false); if (domain == NULL) { ret = ERR_DOMAIN_NOT_FOUND; goto done; } uid = strtouint32(parts[1], NULL, 10); ret = errno; if (ret != EOK) { goto done; } *_domain = domain; *_uid = uid; done: talloc_free(parts); return ret; } static void ifp_users_find_by_name_done(struct tevent_req *req); int ifp_users_find_by_name(struct sbus_request *sbus_req, void *data, const char *name) { struct ifp_ctx *ctx; struct tevent_req *req; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } req = cache_req_user_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx, ctx->ncache, ctx->neg_timeout, 0, NULL, name); if (req == NULL) { return ENOMEM; } tevent_req_set_callback(req, ifp_users_find_by_name_done, sbus_req); return EOK; } static void ifp_users_find_by_name_done(struct tevent_req *req) { DBusError *error; struct sbus_request *sbus_req; struct sss_domain_info *domain; struct ldb_result *result; char *object_path; errno_t ret; sbus_req = tevent_req_callback_data(req, struct sbus_request); ret = cache_req_user_by_name_recv(sbus_req, req, &result, &domain, NULL); talloc_zfree(req); if (ret == ENOENT) { error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND, "User not found"); goto done; } else if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "user [%d]: %s\n", ret, sss_strerror(ret)); goto done; } object_path = ifp_users_build_path_from_msg(sbus_req, domain, result->msgs[0]); if (object_path == NULL) { error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, "Failed to compose object path"); goto done; } ret = EOK; done: if (ret != EOK) { sbus_request_fail_and_finish(sbus_req, error); return; } iface_ifp_users_FindByName_finish(sbus_req, object_path); return; } static void ifp_users_find_by_id_done(struct tevent_req *req); int ifp_users_find_by_id(struct sbus_request *sbus_req, void *data, uint32_t id) { struct ifp_ctx *ctx; struct tevent_req *req; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } req = cache_req_user_by_id_send(sbus_req, ctx->rctx->ev, ctx->rctx, ctx->ncache, ctx->neg_timeout, 0, NULL, id); if (req == NULL) { return ENOMEM; } tevent_req_set_callback(req, ifp_users_find_by_id_done, sbus_req); return EOK; } static void ifp_users_find_by_id_done(struct tevent_req *req) { DBusError *error; struct sbus_request *sbus_req; struct sss_domain_info *domain; struct ldb_result *result; char *object_path; errno_t ret; sbus_req = tevent_req_callback_data(req, struct sbus_request); ret = cache_req_user_by_id_recv(sbus_req, req, &result, &domain); talloc_zfree(req); if (ret == ENOENT) { error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND, "User not found"); goto done; } else if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "user [%d]: %s\n", ret, sss_strerror(ret)); goto done; } object_path = ifp_users_build_path_from_msg(sbus_req, domain, result->msgs[0]); if (object_path == NULL) { error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, "Failed to compose object path"); goto done; } done: if (ret != EOK) { sbus_request_fail_and_finish(sbus_req, error); return; } iface_ifp_users_FindByID_finish(sbus_req, object_path); return; } static void ifp_users_find_by_cert_done(struct tevent_req *req); int ifp_users_find_by_cert(struct sbus_request *sbus_req, void *data, const char *pem_cert) { struct ifp_ctx *ctx; struct tevent_req *req; int ret; char *derb64; DBusError *error; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } ret = sss_cert_pem_to_derb64(sbus_req, pem_cert, &derb64); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_cert_pem_to_derb64 failed.\n"); if (ret == ENOMEM) { return ret; } error = sbus_error_new(sbus_req, DBUS_ERROR_INVALID_ARGS, "Invalid certificate format"); sbus_request_fail_and_finish(sbus_req, error); /* the connection is already terminated with an error message, hence * we have to return EOK to not terminate the connection twice. */ return EOK; } req = cache_req_user_by_cert_send(sbus_req, ctx->rctx->ev, ctx->rctx, ctx->ncache, ctx->neg_timeout, 0, NULL, derb64); if (req == NULL) { return ENOMEM; } tevent_req_set_callback(req, ifp_users_find_by_cert_done, sbus_req); return EOK; } static void ifp_users_find_by_cert_done(struct tevent_req *req) { DBusError *error; struct sbus_request *sbus_req; struct sss_domain_info *domain; struct ldb_result *result; char *object_path; errno_t ret; sbus_req = tevent_req_callback_data(req, struct sbus_request); ret = cache_req_user_by_cert_recv(sbus_req, req, &result, &domain, NULL); talloc_zfree(req); if (ret == ENOENT) { error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND, "User not found"); goto done; } else if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "user [%d]: %s\n", ret, sss_strerror(ret)); goto done; } object_path = ifp_users_build_path_from_msg(sbus_req, domain, result->msgs[0]); if (object_path == NULL) { error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, "Failed to compose object path"); goto done; } done: if (ret != EOK) { sbus_request_fail_and_finish(sbus_req, error); return; } iface_ifp_users_FindByCertificate_finish(sbus_req, object_path); return; } static int ifp_users_list_copy(struct ifp_list_ctx *list_ctx, struct ldb_result *result) { size_t copy_count, i; copy_count = ifp_list_ctx_remaining_capacity(list_ctx, result->count); for (i = 0; i < copy_count; i++) { list_ctx->paths[list_ctx->path_count + i] = \ ifp_users_build_path_from_msg(list_ctx->paths, list_ctx->dom, result->msgs[i]); if (list_ctx->paths[list_ctx->path_count + i] == NULL) { return ENOMEM; } } list_ctx->path_count += copy_count; return EOK; } static int ifp_users_list_by_name_step(struct ifp_list_ctx *list_ctx); static void ifp_users_list_by_name_done(struct tevent_req *req); static void ifp_users_list_by_name_reply(struct ifp_list_ctx *list_ctx); int ifp_users_list_by_name(struct sbus_request *sbus_req, void *data, const char *filter, uint32_t limit) { struct ifp_ctx *ctx; struct ifp_list_ctx *list_ctx; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } list_ctx = ifp_list_ctx_new(sbus_req, ctx, filter, limit); if (list_ctx == NULL) { return ENOMEM; } return ifp_users_list_by_name_step(list_ctx); } static int ifp_users_list_by_name_step(struct ifp_list_ctx *list_ctx) { struct tevent_req *req; req = cache_req_user_by_filter_send(list_ctx, list_ctx->ctx->rctx->ev, list_ctx->ctx->rctx, list_ctx->dom->name, list_ctx->filter); if (req == NULL) { return ENOMEM; } tevent_req_set_callback(req, ifp_users_list_by_name_done, list_ctx); return EOK; } static void ifp_users_list_by_name_done(struct tevent_req *req) { DBusError *error; struct ifp_list_ctx *list_ctx; struct sbus_request *sbus_req; struct ldb_result *result; struct sss_domain_info *domain; errno_t ret; list_ctx = tevent_req_callback_data(req, struct ifp_list_ctx); sbus_req = list_ctx->sbus_req; ret = cache_req_user_by_name_recv(sbus_req, req, &result, &domain, NULL); talloc_zfree(req); if (ret != EOK && ret != ENOENT) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "users by filter [%d]: %s\n", ret, sss_strerror(ret)); sbus_request_fail_and_finish(sbus_req, error); return; } ret = ifp_users_list_copy(list_ctx, result); if (ret != EOK) { error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, "Failed to copy domain result"); sbus_request_fail_and_finish(sbus_req, error); return; } list_ctx->dom = get_next_domain(list_ctx->dom, SSS_GND_DESCEND); if (list_ctx->dom == NULL) { return ifp_users_list_by_name_reply(list_ctx); } ret = ifp_users_list_by_name_step(list_ctx); if (ret != EOK) { error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, "Failed to start next-domain search"); sbus_request_fail_and_finish(sbus_req, error); return; } } static void ifp_users_list_by_name_reply(struct ifp_list_ctx *list_ctx) { iface_ifp_users_ListByName_finish(list_ctx->sbus_req, list_ctx->paths, list_ctx->path_count); } static void ifp_users_list_by_domain_and_name_done(struct tevent_req *req); int ifp_users_list_by_domain_and_name(struct sbus_request *sbus_req, void *data, const char *domain, const char *filter, uint32_t limit) { struct tevent_req *req; struct ifp_ctx *ctx; struct ifp_list_ctx *list_ctx; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } list_ctx = ifp_list_ctx_new(sbus_req, ctx, filter, limit); if (list_ctx == NULL) { return ENOMEM; } req = cache_req_user_by_filter_send(list_ctx, ctx->rctx->ev, ctx->rctx, domain, filter); if (req == NULL) { return ENOMEM; } tevent_req_set_callback(req, ifp_users_list_by_domain_and_name_done, list_ctx); return EOK; } static void ifp_users_list_by_domain_and_name_done(struct tevent_req *req) { DBusError *error; struct ifp_list_ctx *list_ctx; struct sbus_request *sbus_req; struct ldb_result *result; struct sss_domain_info *domain; errno_t ret; size_t copy_count, i; list_ctx = tevent_req_callback_data(req, struct ifp_list_ctx); sbus_req = list_ctx->sbus_req; ret = cache_req_user_by_name_recv(sbus_req, req, &result, &domain, NULL); talloc_zfree(req); if (ret == ENOENT) { error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND, "User not found by filter"); goto done; } else if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "users by filter [%d]: %s\n", ret, sss_strerror(ret)); goto done; } copy_count = ifp_list_ctx_remaining_capacity(list_ctx, result->count); for (i = 0; i < copy_count; i++) { list_ctx->paths[i] = ifp_users_build_path_from_msg(list_ctx->paths, list_ctx->dom, result->msgs[i]); if (list_ctx->paths[i] == NULL) { error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL, "Failed to compose object path"); goto done; } } list_ctx->path_count += copy_count; done: if (ret != EOK) { sbus_request_fail_and_finish(sbus_req, error); return; } iface_ifp_users_ListByDomainAndName_finish(sbus_req, list_ctx->paths, list_ctx->path_count); return; } static errno_t ifp_users_user_get(struct sbus_request *sbus_req, struct ifp_ctx *ifp_ctx, uid_t *_uid, struct sss_domain_info **_domain, struct ldb_message **_user) { struct sss_domain_info *domain; struct ldb_result *res; uid_t uid; errno_t ret; ret = ifp_users_decompose_path(ifp_ctx->rctx->domains, sbus_req->path, &domain, &uid); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to decompose object path" "[%s] [%d]: %s\n", sbus_req->path, ret, sss_strerror(ret)); return ret; } if (_user != NULL) { ret = sysdb_getpwuid_with_views(sbus_req, domain, uid, &res); if (ret == EOK && res->count == 0) { *_user = NULL; ret = ENOENT; } if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup user %u@%s [%d]: %s\n", uid, domain->name, ret, sss_strerror(ret)); } else { *_user = res->msgs[0]; } } if (ret == EOK || ret == ENOENT) { if (_uid != NULL) { *_uid = uid; } if (_domain != NULL) { *_domain = domain; } } return ret; } static void ifp_users_get_as_string(struct sbus_request *sbus_req, void *data, const char *attr, const char **_out) { struct ifp_ctx *ifp_ctx; struct ldb_message *msg; struct sss_domain_info *domain; errno_t ret; *_out = NULL; ifp_ctx = talloc_get_type(data, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return; } if (!ifp_is_user_attr_allowed(ifp_ctx, attr)) { DEBUG(SSSDBG_TRACE_ALL, "Attribute %s is not allowed\n", attr); return; } ret = ifp_users_user_get(sbus_req, ifp_ctx, NULL, &domain, &msg); if (ret != EOK) { return; } *_out = sss_view_ldb_msg_find_attr_as_string(domain, msg, attr, NULL); return; } static void ifp_users_get_as_uint32(struct sbus_request *sbus_req, void *data, const char *attr, uint32_t *_out) { struct ifp_ctx *ifp_ctx; struct ldb_message *msg; struct sss_domain_info *domain; errno_t ret; *_out = 0; ifp_ctx = talloc_get_type(data, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return; } if (!ifp_is_user_attr_allowed(ifp_ctx, attr)) { DEBUG(SSSDBG_TRACE_ALL, "Attribute %s is not allowed\n", attr); return; } ret = ifp_users_user_get(sbus_req, ifp_ctx, NULL, &domain, &msg); if (ret != EOK) { return; } *_out = sss_view_ldb_msg_find_attr_as_uint64(domain, msg, attr, 0); return; } static void ifp_users_user_update_groups_list_done(struct tevent_req *req); int ifp_users_user_update_groups_list(struct sbus_request *sbus_req, void *data) { struct tevent_req *req; struct ifp_ctx *ctx; struct sss_domain_info *domain; const char *username; struct ldb_message *user; errno_t ret; ctx = talloc_get_type(data, struct ifp_ctx); if (ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } ret = ifp_users_user_get(sbus_req, data, NULL, &domain, &user); if (ret != EOK) { return ret; } username = ldb_msg_find_attr_as_string(user, SYSDB_NAME, NULL); if (username == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "User name is empty!\n"); return ERR_INTERNAL; } req = cache_req_initgr_by_name_send(sbus_req, ctx->rctx->ev, ctx->rctx, ctx->ncache, ctx->neg_timeout, 0, domain->name, username); if (req == NULL) { return ENOMEM; } tevent_req_set_callback(req, ifp_users_user_update_groups_list_done, sbus_req); return EOK; } static void ifp_users_user_update_groups_list_done(struct tevent_req *req) { DBusError *error; struct sbus_request *sbus_req; errno_t ret; sbus_req = tevent_req_callback_data(req, struct sbus_request); ret = cache_req_initgr_by_name_recv(sbus_req, req, NULL, NULL, NULL); talloc_zfree(req); if (ret == ENOENT) { error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND, "User not found"); goto done; } else if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "user [%d]: %s\n", ret, sss_strerror(ret)); goto done; } done: if (ret != EOK) { sbus_request_fail_and_finish(sbus_req, error); return; } iface_ifp_users_user_UpdateGroupsList_finish(sbus_req); return; } void ifp_users_user_get_name(struct sbus_request *sbus_req, void *data, const char **_out) { ifp_users_get_as_string(sbus_req, data, SYSDB_NAME, _out); } void ifp_users_user_get_uid_number(struct sbus_request *sbus_req, void *data, uint32_t *_out) { ifp_users_get_as_uint32(sbus_req, data, SYSDB_UIDNUM, _out); } void ifp_users_user_get_gid_number(struct sbus_request *sbus_req, void *data, uint32_t *_out) { ifp_users_get_as_uint32(sbus_req, data, SYSDB_GIDNUM, _out); } void ifp_users_user_get_gecos(struct sbus_request *sbus_req, void *data, const char **_out) { ifp_users_get_as_string(sbus_req, data, SYSDB_GECOS, _out); } void ifp_users_user_get_home_directory(struct sbus_request *sbus_req, void *data, const char **_out) { ifp_users_get_as_string(sbus_req, data, SYSDB_HOMEDIR, _out); } void ifp_users_user_get_login_shell(struct sbus_request *sbus_req, void *data, const char **_out) { ifp_users_get_as_string(sbus_req, data, SYSDB_SHELL, _out); } void ifp_users_user_get_groups(struct sbus_request *sbus_req, void *data, const char ***_out, int *_size) { struct ifp_ctx *ifp_ctx; struct sss_domain_info *domain; const char *username; struct ldb_message *user; struct ldb_result *res; const char **out; int num_groups; gid_t gid; errno_t ret; int i; *_out = NULL; *_size = 0; ifp_ctx = talloc_get_type(data, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return; } if (!ifp_is_user_attr_allowed(ifp_ctx, "groups")) { DEBUG(SSSDBG_TRACE_ALL, "Attribute %s is not allowed\n", SYSDB_MEMBEROF); return; } ret = ifp_users_user_get(sbus_req, ifp_ctx, NULL, &domain, &user); if (ret != EOK) { return; } username = ldb_msg_find_attr_as_string(user, SYSDB_NAME, NULL); if (username == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "User name is empty!\n"); return; } /* Run initgroups. */ ret = sysdb_initgroups_with_views(sbus_req, domain, username, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get groups for %s@%s [%d]: %s\n", username, domain->name, ret, sss_strerror(ret)); return; } if (res->count == 0) { return; } out = talloc_zero_array(sbus_req, const char *, res->count); if (out == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); return; } num_groups = 0; for (i = 0; i < res->count; i++) { gid = sss_view_ldb_msg_find_attr_as_uint64(domain, res->msgs[i], SYSDB_GIDNUM, 0); if (gid == 0) { continue; } out[num_groups] = ifp_groups_build_path_from_msg(out, domain, res->msgs[i]); if (out[num_groups] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "ifp_groups_build_path() failed\n"); return; } num_groups++; } *_out = out; *_size = num_groups; } void ifp_users_user_get_extra_attributes(struct sbus_request *sbus_req, void *data, hash_table_t **_out) { struct ifp_ctx *ifp_ctx; struct sss_domain_info *domain; struct ldb_message **user; struct ldb_message_element *el; struct ldb_dn *basedn; size_t count; uid_t uid; const char *filter; const char **extra; hash_table_t *table; hash_key_t key; hash_value_t value; const char **values; errno_t ret; int hret; int i; *_out = NULL; ifp_ctx = talloc_get_type(data, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return; } extra = ifp_get_user_extra_attributes(sbus_req, ifp_ctx); if (extra == NULL || extra[0] == NULL) { DEBUG(SSSDBG_TRACE_ALL, "No extra attributes to return\n"); return; } ret = ifp_users_user_get(sbus_req, data, &uid, &domain, NULL); if (ret != EOK) { return; } basedn = sysdb_user_base_dn(sbus_req, domain); if (basedn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_user_base_dn() failed\n"); return; } filter = talloc_asprintf(sbus_req, "(&(%s=%s)(%s=%u))", SYSDB_OBJECTCLASS, SYSDB_USER_CLASS, SYSDB_UIDNUM, uid); if (filter == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n"); return; } ret = sysdb_search_entry(sbus_req, domain->sysdb, basedn, LDB_SCOPE_ONELEVEL, filter, extra, &count, &user); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup user [%d]: %s\n", ret, sss_strerror(ret)); return; } if (count == 0) { DEBUG(SSSDBG_TRACE_FUNC, "User %u not found!\n", uid); return; } else if (count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "More than one entry found!\n"); return; } ret = sss_hash_create(sbus_req, 10, &table); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table!\n"); return; } /* Read each extra attribute. */ for (i = 0; extra[i] != NULL; i++) { el = ldb_msg_find_element(user[0], extra[i]); if (el == NULL) { DEBUG(SSSDBG_TRACE_ALL, "Attribute %s not found, skipping...\n", extra[i]); continue; } values = sss_ldb_el_to_string_list(table, el); if (values == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_ldb_el_to_string_list() failed\n"); return; } key.type = HASH_KEY_STRING; key.str = talloc_strdup(table, extra[i]); if (key.str == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); return; } value.type = HASH_VALUE_PTR; value.ptr = values; hret = hash_enter(table, &key, &value); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to insert entry " "into hash table: %d\n", hret); return; } } *_out = table; } int ifp_cache_list_user(struct sbus_request *sbus_req, void *data) { return ifp_cache_list(sbus_req, data, IFP_CACHE_USER); } int ifp_cache_list_by_domain_user(struct sbus_request *sbus_req, void *data, const char *domain) { return ifp_cache_list_by_domain(sbus_req, data, domain, IFP_CACHE_USER); } int ifp_cache_object_store_user(struct sbus_request *sbus_req, void *data) { DBusError *error; struct sss_domain_info *domain; struct ldb_message *user; errno_t ret; ret = ifp_users_user_get(sbus_req, data, NULL, &domain, &user); if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "user [%d]: %s\n", ret, sss_strerror(ret)); return sbus_request_fail_and_finish(sbus_req, error); } /* The request is finished inside. */ return ifp_cache_object_store(sbus_req, domain, user->dn); } int ifp_cache_object_remove_user(struct sbus_request *sbus_req, void *data) { DBusError *error; struct sss_domain_info *domain; struct ldb_message *user; errno_t ret; ret = ifp_users_user_get(sbus_req, data, NULL, &domain, &user); if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch " "user [%d]: %s\n", ret, sss_strerror(ret)); return sbus_request_fail_and_finish(sbus_req, error); } /* The request is finished inside. */ return ifp_cache_object_remove(sbus_req, domain, user->dn); } sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_cache.h0000644000000000000000000000007412703456111017745 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.489793069 sssd-1.13.4/src/responder/ifp/ifp_cache.h0000644002412700241270000000373212703456111021421 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IFP_CACHE_H_ #define IFP_CACHE_H_ #include "responder/common/responder.h" #include "responder/ifp/ifp_iface_generated.h" enum ifp_cache_type { IFP_CACHE_USER, IFP_CACHE_GROUP }; errno_t ifp_cache_list_domains(TALLOC_CTX *mem_ctx, struct sss_domain_info *domains, enum ifp_cache_type type, const char ***_paths, int *_num_paths); /* org.freedesktop-sssd-infopipe.Cache */ int ifp_cache_list(struct sbus_request *sbus_req, void *data, enum ifp_cache_type type); int ifp_cache_list_by_domain(struct sbus_request *sbus_req, void *data, const char *domain, enum ifp_cache_type type); /* org.freedesktop-sssd-infopipe.Cache.Object */ int ifp_cache_object_store(struct sbus_request *sbus_req, struct sss_domain_info *domain, struct ldb_dn *dn); int ifp_cache_object_remove(struct sbus_request *sbus_req, struct sss_domain_info *domain, struct ldb_dn *dn); #endif /* IFP_CACHE_H_ */ sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_iface.c0000644000000000000000000000007412703456111017744 xustar0030 atime=1460561751.651715631 30 ctime=1460561775.002794809 sssd-1.13.4/src/responder/ifp/ifp_iface.c0000644002412700241270000001425212703456111021417 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "sbus/sssd_dbus.h" #include "responder/ifp/ifp_iface_generated.h" #include "responder/ifp/ifp_domains.h" #include "responder/ifp/ifp_components.h" #include "responder/ifp/ifp_users.h" #include "responder/ifp/ifp_groups.h" struct iface_ifp iface_ifp = { { &iface_ifp_meta, 0 }, .Ping = ifp_ping, /* components */ .ListComponents = ifp_list_components, .ListResponders = ifp_list_responders, .ListBackends = ifp_list_backends, .FindMonitor = ifp_find_monitor, .FindResponderByName = ifp_find_responder_by_name, .FindBackendByName = ifp_find_backend_by_name, .GetUserAttr = ifp_user_get_attr, .GetUserGroups = ifp_user_get_groups, .ListDomains = ifp_list_domains, .FindDomainByName = ifp_find_domain_by_name, }; struct iface_ifp_components iface_ifp_components = { { &iface_ifp_components_meta, 0 }, .Enable = ifp_component_enable, .Disable = ifp_component_disable, .ChangeDebugLevel = ifp_component_change_debug_level, .ChangeDebugLevelTemporarily = ifp_component_change_debug_level_tmp, .get_name = ifp_component_get_name, .get_debug_level = ifp_component_get_debug_level, .get_enabled = ifp_component_get_enabled, .get_type = ifp_component_get_type, /* FIXME: This should be part of Components.Backends interface, onece * SSSD supports multiple interfaces per object path. */ .get_providers = ifp_backend_get_providers }; struct iface_ifp_domains iface_ifp_domains = { { &iface_ifp_domains_meta, 0 }, .get_name = ifp_dom_get_name, .get_provider = ifp_dom_get_provider, .get_primary_servers = ifp_dom_get_primary_servers, .get_backup_servers = ifp_dom_get_backup_servers, .get_min_id = ifp_dom_get_min_id, .get_max_id = ifp_dom_get_max_id, .get_realm = ifp_dom_get_realm, .get_forest = ifp_dom_get_forest, .get_login_format = ifp_dom_get_login_format, .get_fully_qualified_name_format = ifp_dom_get_fqdn_format, .get_enumerable = ifp_dom_get_enumerable, .get_use_fully_qualified_names = ifp_dom_get_use_fqdn, .get_subdomain = ifp_dom_get_subdomain, .get_parent_domain = ifp_dom_get_parent_domain }; struct iface_ifp_users iface_ifp_users = { { &iface_ifp_users_meta, 0 }, .FindByName = ifp_users_find_by_name, .FindByID = ifp_users_find_by_id, .FindByCertificate = ifp_users_find_by_cert, .ListByName = ifp_users_list_by_name, .ListByDomainAndName = ifp_users_list_by_domain_and_name }; struct iface_ifp_users_user iface_ifp_users_user = { { &iface_ifp_users_user_meta, 0 }, .UpdateGroupsList = ifp_users_user_update_groups_list, .get_name = ifp_users_user_get_name, .get_uidNumber = ifp_users_user_get_uid_number, .get_gidNumber = ifp_users_user_get_gid_number, .get_gecos = ifp_users_user_get_gecos, .get_homeDirectory = ifp_users_user_get_home_directory, .get_loginShell = ifp_users_user_get_login_shell, .get_groups = ifp_users_user_get_groups, .get_extraAttributes = ifp_users_user_get_extra_attributes }; struct iface_ifp_groups iface_ifp_groups = { { &iface_ifp_groups_meta, 0 }, .FindByName = ifp_groups_find_by_name, .FindByID = ifp_groups_find_by_id, .ListByName = ifp_groups_list_by_name, .ListByDomainAndName = ifp_groups_list_by_domain_and_name }; struct iface_ifp_groups_group iface_ifp_groups_group = { { &iface_ifp_groups_group_meta, 0 }, .UpdateMemberList = ifp_groups_group_update_member_list, .get_name = ifp_groups_group_get_name, .get_gidNumber = ifp_groups_group_get_gid_number, .get_users = ifp_groups_group_get_users, .get_groups = ifp_groups_group_get_groups }; struct iface_ifp_cache iface_ifp_cache_user = { { &iface_ifp_cache_meta, 0 }, .List = ifp_cache_list_user, .ListByDomain = ifp_cache_list_by_domain_user }; struct iface_ifp_cache_object iface_ifp_cache_object_user = { { &iface_ifp_cache_object_meta, 0 }, .Store = ifp_cache_object_store_user, .Remove = ifp_cache_object_remove_user }; struct iface_ifp_cache iface_ifp_cache_group = { { &iface_ifp_cache_meta, 0 }, .List = ifp_cache_list_group, .ListByDomain = ifp_cache_list_by_domain_group }; struct iface_ifp_cache_object iface_ifp_cache_object_group = { { &iface_ifp_cache_object_meta, 0 }, .Store = ifp_cache_object_store_group, .Remove = ifp_cache_object_remove_group }; struct iface_map { const char *path; struct sbus_vtable *vtable; }; static struct iface_map iface_map[] = { { IFP_PATH, &iface_ifp.vtable }, { IFP_PATH_DOMAINS_TREE, &iface_ifp_domains.vtable }, { IFP_PATH_COMPONENTS_TREE, &iface_ifp_components.vtable }, { IFP_PATH_USERS, &iface_ifp_users.vtable }, { IFP_PATH_USERS, &iface_ifp_cache_user.vtable }, { IFP_PATH_USERS_TREE, &iface_ifp_users_user.vtable }, { IFP_PATH_USERS_TREE, &iface_ifp_cache_object_user.vtable }, { IFP_PATH_GROUPS, &iface_ifp_groups.vtable }, { IFP_PATH_GROUPS, &iface_ifp_cache_group.vtable }, { IFP_PATH_GROUPS_TREE, &iface_ifp_groups_group.vtable }, { IFP_PATH_GROUPS_TREE, &iface_ifp_cache_object_group.vtable }, { NULL, NULL }, }; errno_t ifp_register_sbus_interface(struct sbus_connection *conn, void *pvt) { errno_t ret; int i; for (i = 0; iface_map[i].path != NULL; i++) { ret = sbus_conn_register_iface(conn, iface_map[i].vtable, iface_map[i].path, pvt); if (ret != EOK) { return ret; } } return EOK; } sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifpsrv.c0000644000000000000000000000007412703456111017350 xustar0030 atime=1460561751.651715631 30 ctime=1460561775.000794802 sssd-1.13.4/src/responder/ifp/ifpsrv.c0000644002412700241270000003221212703456111021017 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Copyright (C) 2013 Red Hat InfoPipe responder: the responder server This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "util/strtonum.h" #include "sbus/sssd_dbus.h" #include "monitor/monitor_interfaces.h" #include "confdb/confdb.h" #include "responder/ifp/ifp_private.h" #include "responder/ifp/ifp_domains.h" #include "responder/ifp/ifp_components.h" #include "responder/common/responder_sbus.h" #define DEFAULT_ALLOWED_UIDS "0" static int ifp_sysbus_reconnect(struct sbus_request *dbus_req, void *data); struct mon_cli_iface monitor_ifp_methods = { { &mon_cli_iface_meta, 0 }, .ping = monitor_common_pong, .resInit = monitor_common_res_init, .shutDown = NULL, .goOffline = NULL, .resetOffline = NULL, .rotateLogs = responder_logrotate, .sysbusReconnect = ifp_sysbus_reconnect, }; static struct data_provider_iface ifp_dp_methods = { { &data_provider_iface_meta, 0 }, .RegisterService = NULL, .pamHandler = NULL, .sudoHandler = NULL, .autofsHandler = NULL, .hostHandler = NULL, .getDomains = NULL, .getAccountInfo = NULL, }; struct sss_cmd_table *get_ifp_cmds(void) { static struct sss_cmd_table ifp_cmds[] = { { SSS_GET_VERSION, sss_cmd_get_version }, { SSS_CLI_NULL, NULL} }; return ifp_cmds; } static void ifp_dp_reconnect_init(struct sbus_connection *conn, int status, void *pvt) { struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn); int ret; /* Did we reconnect successfully? */ if (status == SBUS_RECONNECT_SUCCESS) { DEBUG(SSSDBG_TRACE_FUNC, "Reconnected to the Data Provider.\n"); /* Identify ourselves to the data provider */ ret = dp_common_send_id(be_conn->conn, DATA_PROVIDER_VERSION, "InfoPipe"); /* all fine */ if (ret == EOK) { handle_requests_after_reconnect(be_conn->rctx); return; } } /* Failed to reconnect */ DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n", be_conn->domain->name); } static errno_t sysbus_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *dbus_name, void *pvt, struct sysbus_ctx **sysbus) { DBusError dbus_error; DBusConnection *conn = NULL; struct sysbus_ctx *system_bus = NULL; errno_t ret; system_bus = talloc_zero(mem_ctx, struct sysbus_ctx); if (system_bus == NULL) { return ENOMEM; } dbus_error_init(&dbus_error); /* Connect to the well-known system bus */ conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_error); if (conn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to connect to D-BUS system bus: [%s]\n", dbus_error.message); ret = ERR_NO_SYSBUS; goto fail; } dbus_connection_set_exit_on_disconnect(conn, FALSE); ret = dbus_bus_request_name(conn, dbus_name, /* We want exclusive access */ DBUS_NAME_FLAG_DO_NOT_QUEUE, &dbus_error); if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { /* We were unable to register on the system bus */ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to request name on the system bus: [%s]\n", dbus_error.message); ret = EIO; goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "Listening on %s\n", dbus_name); /* Integrate with tevent loop */ ret = sbus_init_connection(system_bus, ev, conn, SBUS_CONN_TYPE_SYSBUS, &system_bus->conn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not integrate D-BUS into mainloop.\n"); goto fail; } ret = ifp_register_sbus_interface(system_bus->conn, pvt); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not register interfaces\n"); goto fail; } ifp_register_nodes(pvt, system_bus->conn); *sysbus = system_bus; return EOK; fail: if (dbus_error_is_set(&dbus_error)) { DEBUG(SSSDBG_OP_FAILURE, "DBus error message: %s\n", dbus_error.message); dbus_error_free(&dbus_error); } if (conn) dbus_connection_unref(conn); talloc_free(system_bus); return ret; } static int ifp_sysbus_reconnect(struct sbus_request *dbus_req, void *data) { struct resp_ctx *rctx = talloc_get_type(data, struct resp_ctx); struct ifp_ctx *ifp_ctx = (struct ifp_ctx*) rctx->pvt_ctx; errno_t ret; DEBUG(SSSDBG_TRACE_FUNC, "Attempting to reconnect to the system bus\n"); if (ifp_ctx->sysbus) { DEBUG(SSSDBG_TRACE_LIBS, "Already connected to sysbus\n"); goto done; } /* Connect to the D-BUS system bus and set up methods */ ret = sysbus_init(ifp_ctx, ifp_ctx->rctx->ev, IFACE_IFP, ifp_ctx, &ifp_ctx->sysbus); if (ret == ERR_NO_SYSBUS) { DEBUG(SSSDBG_MINOR_FAILURE, "The system bus is not available..\n"); goto done; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to connect to the system message bus\n"); return ret; } DEBUG(SSSDBG_TRACE_LIBS, "Reconnected to the system bus!\n"); done: return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } int ifp_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb) { struct resp_ctx *rctx; struct sss_cmd_table *ifp_cmds; struct ifp_ctx *ifp_ctx; struct be_conn *iter; int ret; int max_retries; char *uid_str; char *attr_list_str; char *wildcard_limit_str; ifp_cmds = get_ifp_cmds(); ret = sss_process_init(mem_ctx, ev, cdb, ifp_cmds, NULL, -1, NULL, -1, CONFDB_IFP_CONF_ENTRY, SSS_IFP_SBUS_SERVICE_NAME, SSS_IFP_SBUS_SERVICE_VERSION, &monitor_ifp_methods, "InfoPipe", &ifp_dp_methods.vtable, &rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n"); return ret; } ifp_ctx = talloc_zero(rctx, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing ifp_ctx\n"); ret = ENOMEM; goto fail; } ifp_ctx->rctx = rctx; ifp_ctx->rctx->pvt_ctx = ifp_ctx; ret = sss_names_init_from_args(ifp_ctx, "(?P[^@]+)@?(?P[^@]*$)", "%1$s@%2$s", &ifp_ctx->snctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing regex data\n"); goto fail; } ret = confdb_get_string(ifp_ctx->rctx->cdb, ifp_ctx->rctx, CONFDB_IFP_CONF_ENTRY, CONFDB_SERVICE_ALLOWED_UIDS, DEFAULT_ALLOWED_UIDS, &uid_str); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get allowed UIDs.\n"); goto fail; } ret = csv_string_to_uid_array(ifp_ctx->rctx, uid_str, true, &ifp_ctx->rctx->allowed_uids_count, &ifp_ctx->rctx->allowed_uids); talloc_free(uid_str); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set allowed UIDs.\n"); goto fail; } /* Set up the negative cache */ ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_ENTRY_NEG_TIMEOUT, 15, &ifp_ctx->neg_timeout); if (ret != EOK) { goto fail; } ret = sss_ncache_init(rctx, &ifp_ctx->ncache); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "fatal error initializing negcache\n"); goto fail; } ret = confdb_get_string(ifp_ctx->rctx->cdb, ifp_ctx->rctx, CONFDB_IFP_CONF_ENTRY, CONFDB_IFP_USER_ATTR_LIST, NULL, &attr_list_str); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get user attribute list.\n"); goto fail; } ifp_ctx->user_whitelist = ifp_parse_user_attr_list(ifp_ctx, attr_list_str); talloc_free(attr_list_str); if (ifp_ctx->user_whitelist == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse the allowed attribute list\n"); goto fail; } /* Enable automatic reconnection to the Data Provider */ ret = confdb_get_int(ifp_ctx->rctx->cdb, CONFDB_IFP_CONF_ENTRY, CONFDB_SERVICE_RECON_RETRIES, 3, &max_retries); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up automatic reconnection\n"); goto fail; } /* A bit convoluted way until we have a confdb_get_uint32 */ ret = confdb_get_string(ifp_ctx->rctx->cdb, ifp_ctx->rctx, CONFDB_IFP_CONF_ENTRY, CONFDB_IFP_WILDCARD_LIMIT, NULL, /* no limit by default */ &wildcard_limit_str); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to retrieve limit for a wildcard search\n"); goto fail; } if (wildcard_limit_str) { ifp_ctx->wildcard_limit = strtouint32(wildcard_limit_str, NULL, 10); ret = errno; if (ret != EOK) { goto fail; } } for (iter = ifp_ctx->rctx->be_conns; iter; iter = iter->next) { sbus_reconnect_init(iter->conn, max_retries, ifp_dp_reconnect_init, iter); } /* Connect to the D-BUS system bus and set up methods */ ret = sysbus_init(ifp_ctx, ifp_ctx->rctx->ev, IFACE_IFP, ifp_ctx, &ifp_ctx->sysbus); if (ret == ERR_NO_SYSBUS) { DEBUG(SSSDBG_MINOR_FAILURE, "The system bus is not available..\n"); /* Explicitly ignore, the D-Bus daemon will start us */ } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to connect to the system message bus\n"); talloc_free(ifp_ctx); return EIO; } ret = schedule_get_domains_task(rctx, rctx->ev, rctx, NULL); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "InfoPipe Initialization complete\n"); return EOK; fail: talloc_free(rctx); return ret; } int main(int argc, const char *argv[]) { int opt; poptContext pc; struct main_context *main_ctx; int ret; uid_t uid; gid_t gid; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; umask(DFL_RSP_UMASK); pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_INIT(debug_level); /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_ifp"; ret = server_setup("sssd[ifp]", 0, 0, 0, CONFDB_IFP_CONF_ENTRY, &main_ctx); if (ret != EOK) return 2; ret = die_if_parent_died(); if (ret != EOK) { /* This is not fatal, don't return */ DEBUG(SSSDBG_MINOR_FAILURE, "Could not set up to exit when parent process does\n"); } ret = ifp_process_init(main_ctx, main_ctx->event_ctx, main_ctx->confdb_ctx); if (ret != EOK) return 3; /* loop on main */ server_loop(main_ctx); return 0; } sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_cache.c0000644000000000000000000000007412703456111017740 xustar0030 atime=1460561751.650715627 30 ctime=1460561775.007794826 sssd-1.13.4/src/responder/ifp/ifp_cache.c0000644002412700241270000002243312703456111021413 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "db/sysdb.h" #include "util/util.h" #include "responder/common/responder.h" #include "responder/ifp/ifp_cache.h" #include "responder/ifp/ifp_users.h" #include "responder/ifp/ifp_groups.h" #include "responder/ifp/ifp_iface_generated.h" static struct ldb_dn * ifp_cache_build_base_dn(TALLOC_CTX *mem_ctx, enum ifp_cache_type type, struct sss_domain_info *domain) { struct ldb_dn *base_dn = NULL; switch (type) { case IFP_CACHE_USER: base_dn = sysdb_user_base_dn(mem_ctx, domain); break; case IFP_CACHE_GROUP: base_dn = sysdb_group_base_dn(mem_ctx, domain); break; } return base_dn; } static char * ifp_cache_build_path(TALLOC_CTX *mem_ctx, enum ifp_cache_type type, struct sss_domain_info *domain, struct ldb_message *msg) { char *path = NULL; switch (type) { case IFP_CACHE_USER: path = ifp_users_build_path_from_msg(mem_ctx, domain, msg); break; case IFP_CACHE_GROUP: path = ifp_groups_build_path_from_msg(mem_ctx, domain, msg); break; } return path; } static const char * ifp_cache_object_class(enum ifp_cache_type type) { const char *class = NULL; switch (type) { case IFP_CACHE_USER: class = SYSDB_USER_CLASS; break; case IFP_CACHE_GROUP: class = SYSDB_GROUP_CLASS; break; } return class; } static errno_t ifp_cache_get_cached_objects(TALLOC_CTX *mem_ctx, enum ifp_cache_type type, struct sss_domain_info *domain, const char ***_paths, int *_num_paths) { TALLOC_CTX *tmp_ctx; struct ldb_dn *base_dn; struct ldb_result *result; const char *class = ifp_cache_object_class(type); const char **paths; errno_t ret; int ldb_ret; int i; const char *attrs[] = {SYSDB_OBJECTCLASS, SYSDB_UIDNUM, SYSDB_GIDNUM, NULL}; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } base_dn = ifp_cache_build_base_dn(tmp_ctx, type, domain); if (base_dn == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create base dn\n"); ret = ENOMEM; goto done; } ldb_ret = ldb_search(sysdb_ctx_get_ldb(domain->sysdb), tmp_ctx, &result, base_dn, LDB_SCOPE_SUBTREE, attrs, "(&(objectClass=%s)(%s=TRUE))", class, SYSDB_IFP_CACHED); if (ldb_ret != LDB_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to search the cache\n"); ret = sysdb_error_to_errno(ldb_ret); goto done; } paths = talloc_zero_array(tmp_ctx, const char *, result->count + 1); if (paths == NULL) { ret = ENOMEM; goto done; } for (i = 0; i < result->count; i++) { paths[i] = ifp_cache_build_path(paths, type, domain, result->msgs[i]); if (paths[i] == NULL) { ret = ENOMEM; goto done; } } *_paths = talloc_steal(mem_ctx, paths); *_num_paths = result->count; ret = EOK; done: talloc_free(tmp_ctx); return ret; } errno_t ifp_cache_list_domains(TALLOC_CTX *mem_ctx, struct sss_domain_info *domains, enum ifp_cache_type type, const char ***_paths, int *_num_paths) { TALLOC_CTX *tmp_ctx; struct sss_domain_info *domain; const char **tmp_paths; int num_tmp_paths; const char **paths; int num_paths; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } domain = domains; num_paths = 0; paths = NULL; while (domain != NULL) { ret = ifp_cache_get_cached_objects(tmp_ctx, type, domain, &tmp_paths, &num_tmp_paths); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build object list " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = add_strings_lists(tmp_ctx, paths, tmp_paths, true, discard_const(&paths)); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build object list " "[%d]: %s\n", ret, sss_strerror(ret)); goto done; } num_paths += num_tmp_paths; domain = get_next_domain(domain, SSS_GND_DESCEND); } if (_paths != NULL) { *_paths = talloc_steal(mem_ctx, paths); } if (_num_paths != NULL) { *_num_paths = num_paths; } ret = EOK; done: talloc_free(tmp_ctx); return ret; } int ifp_cache_list(struct sbus_request *sbus_req, void *data, enum ifp_cache_type type) { DBusError *error; struct ifp_ctx *ifp_ctx; const char **paths; int num_paths; errno_t ret; ifp_ctx = talloc_get_type(data, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } ret = ifp_cache_list_domains(sbus_req, ifp_ctx->rctx->domains, type, &paths, &num_paths); if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Unable to build object list [%d]: %s\n", ret, sss_strerror(ret)); return sbus_request_fail_and_finish(sbus_req, error); } iface_ifp_cache_List_finish(sbus_req, paths, num_paths); return EOK; } int ifp_cache_list_by_domain(struct sbus_request *sbus_req, void *data, const char *domainname, enum ifp_cache_type type) { DBusError *error; struct sss_domain_info *domain; struct ifp_ctx *ifp_ctx; const char **paths; int num_paths; errno_t ret; ifp_ctx = talloc_get_type(data, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); return ERR_INTERNAL; } domain = find_domain_by_name(ifp_ctx->rctx->domains, domainname, true); if (domain == NULL) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Unknown domain"); return sbus_request_fail_and_finish(sbus_req, error); } ret = ifp_cache_get_cached_objects(sbus_req, type, domain, &paths, &num_paths); if (ret != EOK) { error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Unable to build " "object list [%d]: %s\n", ret, sss_strerror(ret)); return sbus_request_fail_and_finish(sbus_req, error); } iface_ifp_cache_ListByDomain_finish(sbus_req, paths, num_paths); return EOK; } static errno_t ifp_cache_object_set(struct sss_domain_info *domain, struct ldb_dn *dn, bool value) { struct sysdb_attrs *attrs; errno_t ret; attrs = sysdb_new_attrs(NULL); if (attrs == NULL) { return ENOMEM; } ret = sysdb_attrs_add_bool(attrs, SYSDB_IFP_CACHED, value); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add attribute [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = sysdb_set_entry_attr(domain->sysdb, dn, attrs, SYSDB_MOD_REP); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to modify entry [%d]: %s\n", ret, sss_strerror(ret)); goto done; } ret = EOK; done: talloc_free(attrs); return ret; } int ifp_cache_object_store(struct sbus_request *sbus_req, struct sss_domain_info *domain, struct ldb_dn *dn) { errno_t ret; ret = ifp_cache_object_set(domain, dn, true); if (ret == EOK) { iface_ifp_cache_object_Store_finish(sbus_req, true); } else { iface_ifp_cache_object_Store_finish(sbus_req, false); } return EOK; } int ifp_cache_object_remove(struct sbus_request *sbus_req, struct sss_domain_info *domain, struct ldb_dn *dn) { errno_t ret; ret = ifp_cache_object_set(domain, dn, false); if (ret == EOK) { iface_ifp_cache_object_Remove_finish(sbus_req, true); } else { iface_ifp_cache_object_Remove_finish(sbus_req, false); } return EOK; } sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_iface_nodes.c0000644000000000000000000000007412703456111021134 xustar0030 atime=1460561751.651715631 30 ctime=1460561775.003794812 sssd-1.13.4/src/responder/ifp/ifp_iface_nodes.c0000644002412700241270000000700212703456111022602 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "sbus/sssd_dbus.h" #include "responder/ifp/ifp_iface_generated.h" #include "responder/ifp/ifp_users.h" #include "responder/ifp/ifp_groups.h" #include "responder/ifp/ifp_cache.h" static const char ** nodes_ifp(TALLOC_CTX *mem_ctx, const char *path, void *data) { static const char *nodes[] = {"Users", "Groups", NULL}; return nodes; } static const char ** nodes_cached_objects(TALLOC_CTX *mem_ctx, void *data, enum ifp_cache_type type, const char *prefix) { TALLOC_CTX *tmp_ctx; struct ifp_ctx *ifp_ctx; const char **paths; const char **nodes; const char *node; int num_paths; errno_t ret; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); return NULL; } ifp_ctx = talloc_get_type(data, struct ifp_ctx); if (ifp_ctx == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n"); goto fail; } ret = ifp_cache_list_domains(tmp_ctx, ifp_ctx->rctx->domains, type, &paths, &num_paths); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain cache objects list " "[%d]: %s\n", ret, sss_strerror(ret)); goto fail; } nodes = talloc_zero_array(tmp_ctx, const char *, num_paths + 1); if (nodes == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); goto fail; } for (i = 0; i < num_paths; i++) { node = sbus_opath_strip_prefix(paths[i], prefix); nodes[i] = talloc_strdup(nodes, node); if (nodes[i] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n"); goto fail; } } talloc_steal(mem_ctx, nodes); talloc_free(tmp_ctx); return nodes; fail: talloc_free(tmp_ctx); return NULL; } static const char ** nodes_users(TALLOC_CTX *mem_ctx, const char *path, void *data) { return nodes_cached_objects(mem_ctx, data, IFP_CACHE_USER, IFP_PATH_USERS "/"); } static const char ** nodes_groups(TALLOC_CTX *mem_ctx, const char *path, void *data) { return nodes_cached_objects(mem_ctx, data, IFP_CACHE_GROUP, IFP_PATH_GROUPS "/"); } struct nodes_map { const char *path; sbus_nodes_fn fn; }; static struct nodes_map nodes_map[] = { { IFP_PATH, nodes_ifp }, { IFP_PATH_USERS, nodes_users }, { IFP_PATH_GROUPS, nodes_groups }, { NULL, NULL} }; void ifp_register_nodes(struct ifp_ctx *ctx, struct sbus_connection *conn) { int i; for (i = 0; nodes_map[i].path != NULL; i++) { sbus_conn_register_nodes(conn, nodes_map[i].path, nodes_map[i].fn, ctx); } } sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_domains.h0000644000000000000000000000007412703456111020334 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.483793049 sssd-1.13.4/src/responder/ifp/ifp_domains.h0000644002412700241270000000664012703456111022011 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IFP_DOMAINS_H_ #define IFP_DOMAINS_H_ #include "responder/ifp/ifp_iface_generated.h" #include "responder/ifp/ifp_private.h" #define IFP_PATH_DOMAINS IFP_PATH "/Domains" #define IFP_PATH_DOMAINS_TREE IFP_PATH_DOMAINS SBUS_SUBTREE_SUFFIX /* org.freedesktop.sssd.infopipe */ int ifp_list_domains(struct sbus_request *dbus_req, void *data); int ifp_find_domain_by_name(struct sbus_request *dbus_req, void *data, const char *arg_name); /* org.freedesktop.sssd.infopipe.Domains */ void ifp_dom_get_name(struct sbus_request *dbus_req, void *data, const char **_out); void ifp_dom_get_provider(struct sbus_request *dbus_req, void *data, const char **_out); void ifp_dom_get_primary_servers(struct sbus_request *dbus_req, void *data, const char ***_out, int *_out_len); void ifp_dom_get_backup_servers(struct sbus_request *dbus_req, void *data, const char ***_out, int *_out_len); void ifp_dom_get_min_id(struct sbus_request *dbus_req, void *data, uint32_t *_out); void ifp_dom_get_max_id(struct sbus_request *dbus_req, void *data, uint32_t *_out); void ifp_dom_get_realm(struct sbus_request *dbus_req, void *data, const char **_out); void ifp_dom_get_forest(struct sbus_request *dbus_req, void *data, const char **_out); void ifp_dom_get_login_format(struct sbus_request *dbus_req, void *data, const char **_out); void ifp_dom_get_fqdn_format(struct sbus_request *dbus_req, void *data, const char **_out); void ifp_dom_get_enumerable(struct sbus_request *dbus_req, void *data, bool *_out); void ifp_dom_get_use_fqdn(struct sbus_request *dbus_req, void *data, bool *_out); void ifp_dom_get_subdomain(struct sbus_request *dbus_req, void *data, bool *_out); void ifp_dom_get_parent_domain(struct sbus_request *dbus_req, void *data, const char **_out); #endif /* IFP_DOMAINS_H_ */ sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/org.freedesktop.sssd.infopipe.service0000644000000000000000000000013212703463554025145 xustar0030 mtime=1460561772.849787508 30 atime=1460561773.961791279 30 ctime=1460561774.356792618 sssd-1.13.4/src/responder/ifp/org.freedesktop.sssd.infopipe.service0000644002412700241270000000015112703463554026616 0ustar00jhrozekjhrozek00000000000000[D-BUS Service] Name=org.freedesktop.sssd.infopipe Exec=${exec_prefix}/libexec/sssd/sss_signal User=root sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_iface.xml0000644000000000000000000000007412703456111020322 xustar0030 atime=1460561751.651715631 30 ctime=1460561775.060795005 sssd-1.13.4/src/responder/ifp/ifp_iface.xml0000644002412700241270000002026412703456111021775 0ustar00jhrozekjhrozek00000000000000 sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_users.h0000644000000000000000000000007412703456111020043 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.487793063 sssd-1.13.4/src/responder/ifp/ifp_users.h0000644002412700241270000001033112703456111021510 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IFP_USERS_H_ #define IFP_USERS_H_ #include "responder/ifp/ifp_iface_generated.h" #include "responder/ifp/ifp_private.h" #define IFP_PATH_USERS "/org/freedesktop/sssd/infopipe/Users" #define IFP_PATH_USERS_TREE IFP_PATH_USERS SBUS_SUBTREE_SUFFIX /* Utility functions */ char * ifp_users_build_path_from_msg(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_message *msg); /* org.freedesktop.sssd.infopipe.Users */ int ifp_users_find_by_name(struct sbus_request *sbus_req, void *data, const char *name); int ifp_users_find_by_id(struct sbus_request *sbus_req, void *data, uint32_t id); int ifp_users_find_by_cert(struct sbus_request *sbus_req, void *data, const char *pem_cert); int ifp_users_list_by_name(struct sbus_request *sbus_req, void *data, const char *filter, uint32_t limit); int ifp_users_list_by_domain_and_name(struct sbus_request *sbus_req, void *data, const char *domain, const char *filter, uint32_t limit); /* org.freedesktop.sssd.infopipe.Users.User */ int ifp_users_user_update_groups_list(struct sbus_request *req, void *data); void ifp_users_user_get_name(struct sbus_request *sbus_req, void *data, const char **_out); void ifp_users_user_get_uid_number(struct sbus_request *sbus_req, void *data, uint32_t *_out); void ifp_users_user_get_gid_number(struct sbus_request *sbus_req, void *data, uint32_t *_out); void ifp_users_user_get_gecos(struct sbus_request *sbus_req, void *data, const char **_out); void ifp_users_user_get_home_directory(struct sbus_request *sbus_req, void *data, const char **_out); void ifp_users_user_get_login_shell(struct sbus_request *sbus_req, void *data, const char **_out); void ifp_users_user_get_groups(struct sbus_request *sbus_req, void *data, const char ***_out, int *_size); void ifp_users_user_get_extra_attributes(struct sbus_request *sbus_req, void *data, hash_table_t **_out); /* org.freedesktop.sssd.infopipe.Cache */ int ifp_cache_list_user(struct sbus_request *sbus_req, void *data); int ifp_cache_list_by_domain_user(struct sbus_request *sbus_req, void *data, const char *domain); /* org.freedesktop.sssd.infopipe.Cache.Object */ int ifp_cache_object_store_user(struct sbus_request *sbus_req, void *data); int ifp_cache_object_remove_user(struct sbus_request *sbus_req, void *data); #endif /* IFP_USERS_H_ */ sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/org.freedesktop.sssd.infopipe.service.in0000644000000000000000000000007412703456111025546 xustar0030 atime=1460561772.847787501 30 ctime=1460561774.632793554 sssd-1.13.4/src/responder/ifp/org.freedesktop.sssd.infopipe.service.in0000644002412700241270000000013712703456111027216 0ustar00jhrozekjhrozek00000000000000[D-BUS Service] Name=org.freedesktop.sssd.infopipe Exec=@libexecdir@/sssd/sss_signal User=root sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_groups.h0000644000000000000000000000007412703456111020221 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.488793066 sssd-1.13.4/src/responder/ifp/ifp_groups.h0000644002412700241270000000676312703456111021704 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2015 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef IFP_GROUPS_H_ #define IFP_GROUPS_H_ #include "responder/ifp/ifp_iface_generated.h" #include "responder/ifp/ifp_private.h" #define IFP_PATH_GROUPS "/org/freedesktop/sssd/infopipe/Groups" #define IFP_PATH_GROUPS_TREE IFP_PATH_GROUPS SBUS_SUBTREE_SUFFIX /* Utility functions */ char * ifp_groups_build_path_from_msg(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, struct ldb_message *msg); /* org.freedesktop.sssd.infopipe.Groups */ int ifp_groups_find_by_name(struct sbus_request *sbus_req, void *data, const char *name); int ifp_groups_find_by_id(struct sbus_request *sbus_req, void *data, uint32_t id); int ifp_groups_list_by_name(struct sbus_request *sbus_req, void *data, const char *filter, uint32_t limit); int ifp_groups_list_by_domain_and_name(struct sbus_request *sbus_req, void *data, const char *domain, const char *filter, uint32_t limit); /* org.freedesktop.sssd.infopipe.Groups.Group */ int ifp_groups_group_update_member_list(struct sbus_request *sbus_req, void *data); void ifp_groups_group_get_name(struct sbus_request *sbus_req, void *data, const char **_out); void ifp_groups_group_get_gid_number(struct sbus_request *sbus_req, void *data, uint32_t *_out); void ifp_groups_group_get_users(struct sbus_request *sbus_req, void *data, const char ***_out, int *_size); void ifp_groups_group_get_groups(struct sbus_request *sbus_req, void *data, const char ***_out, int *_size); /* org.freedesktop.sssd.infopipe.Cache */ int ifp_cache_list_group(struct sbus_request *sbus_req, void *data); int ifp_cache_list_by_domain_group(struct sbus_request *sbus_req, void *data, const char *domain); /* org.freedesktop.sssd.infopipe.Cache.Object */ int ifp_cache_object_store_group(struct sbus_request *sbus_req, void *data); int ifp_cache_object_remove_group(struct sbus_request *sbus_req, void *data); #endif /* IFP_GROUPS_H_ */ sssd-1.13.4/src/responder/ifp/PaxHeaders.16287/ifp_private.h0000644000000000000000000000007412703456111020354 xustar0030 atime=1460561751.651715631 30 ctime=1460561774.481793042 sssd-1.13.4/src/responder/ifp/ifp_private.h0000644002412700241270000000657512703456111022040 0ustar00jhrozekjhrozek00000000000000/* Authors: Jakub Hrozek Stephen Gallagher Copyright (C) 2013 Red Hat InfoPipe responder: A private header This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _IFPSRV_PRIVATE_H_ #define _IFPSRV_PRIVATE_H_ #include "responder/common/responder.h" #include "responder/common/negcache.h" #include "providers/data_provider.h" #include "responder/ifp/ifp_iface_generated.h" #define IFP_PATH "/org/freedesktop/sssd/infopipe" struct sysbus_ctx { struct sbus_connection *conn; char *introspect_xml; }; struct ifp_ctx { struct resp_ctx *rctx; struct sss_names_ctx *snctx; struct sss_nc_ctx *ncache; int neg_timeout; struct sysbus_ctx *sysbus; const char **user_whitelist; uint32_t wildcard_limit; }; errno_t ifp_register_sbus_interface(struct sbus_connection *conn, void *handler_data); void ifp_register_nodes(struct ifp_ctx *ctx, struct sbus_connection *conn); /* This is a throwaway method to ease the review of the patch. * It will be removed later */ int ifp_ping(struct sbus_request *dbus_req, void *data); int ifp_user_get_attr(struct sbus_request *dbus_req, void *data); int ifp_user_get_groups(struct sbus_request *req, void *data, const char *arg_user); /* == Utility functions == */ struct ifp_req { struct sbus_request *dbus_req; struct ifp_ctx *ifp_ctx; }; errno_t ifp_req_create(struct sbus_request *dbus_req, struct ifp_ctx *ifp_ctx, struct ifp_req **_ifp_req); /* Returns an appropriate DBus error for specific ifp_req_create failures */ int ifp_req_create_handle_failure(struct sbus_request *dbus_req, errno_t err); errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict, struct ldb_message_element *el); const char ** ifp_parse_user_attr_list(TALLOC_CTX *mem_ctx, const char *conf_str); const char ** ifp_get_user_extra_attributes(TALLOC_CTX *mem_ctx, struct ifp_ctx *ifp_ctx); bool ifp_attr_allowed(const char *whitelist[], const char *attr); bool ifp_is_user_attr_allowed(struct ifp_ctx *ifp_ctx, const char *attr); /* Used for list calls */ struct ifp_list_ctx { struct sbus_request *sbus_req; const char *filter; uint32_t limit; struct sss_domain_info *dom; struct ifp_ctx *ctx; const char **paths; size_t path_count; }; struct ifp_list_ctx *ifp_list_ctx_new(struct sbus_request *sbus_req, struct ifp_ctx *ctx, const char *filter, uint32_t limit); size_t ifp_list_ctx_remaining_capacity(struct ifp_list_ctx *list_ctx, size_t entries); #endif /* _IFPSRV_PRIVATE_H_ */ sssd-1.13.4/src/responder/PaxHeaders.16287/pam0000644000000000000000000000013212703463557015624 xustar0030 mtime=1460561775.013794846 30 atime=1460561776.119798596 30 ctime=1460561775.013794846 sssd-1.13.4/src/responder/pam/0000755002412700241270000000000012703463557017355 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/responder/pam/PaxHeaders.16287/pam_helpers.c0000644000000000000000000000007412703456111020335 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.952794639 sssd-1.13.4/src/responder/pam/pam_helpers.c0000644002412700241270000001057512703456111022014 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "src/responder/pam/pam_helpers.h" struct pam_initgr_table_ctx { hash_table_t *id_table; char *name; }; static void pam_initgr_cache_remove(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt); errno_t pam_initgr_cache_set(struct tevent_context *ev, hash_table_t *id_table, char *name, long timeout) { errno_t ret; hash_key_t key; hash_value_t val; int hret; struct tevent_timer *te; struct timeval tv; struct pam_initgr_table_ctx *table_ctx; table_ctx = talloc_zero(id_table, struct pam_initgr_table_ctx); if (!table_ctx) return ENOMEM; table_ctx->id_table = id_table; table_ctx->name = talloc_strdup(table_ctx, name); if (!table_ctx->name) { ret = ENOMEM; goto done; } key.type = HASH_KEY_STRING; key.str = name; /* The value isn't relevant, since we're using * a timer to remove the entry. */ val.type = HASH_VALUE_UNDEF; hret = hash_enter(id_table, &key, &val); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not update initgr cache for [%s]: [%s]\n", name, hash_error_string(hret)); ret = EIO; goto done; } else { DEBUG(SSSDBG_TRACE_INTERNAL, "[%s] added to PAM initgroup cache\n", name); } /* Create a timer event to remove the entry from the cache */ tv = tevent_timeval_current_ofs(timeout, 0); te = tevent_add_timer(ev, table_ctx, tv, pam_initgr_cache_remove, table_ctx); if (!te) { ret = ENOMEM; goto done; } ret = EOK; done: if (ret != EOK) { talloc_free(table_ctx); } return ret; } static void pam_initgr_cache_remove(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { int hret; hash_key_t key; struct pam_initgr_table_ctx *table_ctx = talloc_get_type(pvt, struct pam_initgr_table_ctx); key.type = HASH_KEY_STRING; key.str = table_ctx->name; hret = hash_delete(table_ctx->id_table, &key); if (hret != HASH_SUCCESS && hret != HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_MINOR_FAILURE, "Could not clear [%s] from initgr cache: [%s]\n", table_ctx->name, hash_error_string(hret)); } else { DEBUG(SSSDBG_TRACE_INTERNAL, "[%s] removed from PAM initgroup cache\n", table_ctx->name); } talloc_free(table_ctx); } errno_t pam_initgr_check_timeout(hash_table_t *id_table, char *name) { hash_key_t key; hash_value_t val; int hret; key.type = HASH_KEY_STRING; key.str = name; hret = hash_lookup(id_table, &key, &val); if (hret != HASH_SUCCESS && hret != HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_TRACE_ALL, "Error searching user [%s] in PAM cache.\n", name); return EIO; } else if (hret == HASH_ERROR_KEY_NOT_FOUND) { DEBUG(SSSDBG_TRACE_ALL, "User [%s] not found in PAM cache.\n", name); return ENOENT; } /* If there's a value here, then the cache * entry is still valid. */ DEBUG(SSSDBG_TRACE_INTERNAL, "User [%s] found in PAM cache.\n", name); return EOK; } sssd-1.13.4/src/responder/pam/PaxHeaders.16287/pamsrv_dp.c0000644000000000000000000000007412703456111020031 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.953794643 sssd-1.13.4/src/responder/pam/pamsrv_dp.c0000644002412700241270000001200512703456111021476 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Responder - Data Provider Interfaces Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "responder/common/responder_packet.h" #include "providers/data_provider.h" #include "sbus/sbus_client.h" #include "responder/pam/pamsrv.h" static void pam_dp_process_reply(DBusPendingCall *pending, void *ptr) { DBusError dbus_error; DBusMessage* msg; int ret; int type; struct pam_auth_req *preq = NULL; struct pam_auth_dp_req *pdp_req; pdp_req = talloc_get_type(ptr, struct pam_auth_dp_req); preq = pdp_req->preq; talloc_free(pdp_req); dbus_error_init(&dbus_error); msg = dbus_pending_call_steal_reply(pending); /* Check if the client still exists. If not, simply free all the resources * and quit */ if (preq == NULL) { DEBUG(SSSDBG_MINOR_FAILURE, "Client already disconnected\n"); dbus_pending_call_unref(pending); dbus_message_unref(msg); return; } /* Sanity-check of message validity */ if (msg == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Severe error. A reply callback was called but no reply was" "received and no timeout occurred\n"); preq->pd->pam_status = PAM_SYSTEM_ERR; goto done; } type = dbus_message_get_type(msg); switch (type) { case DBUS_MESSAGE_TYPE_METHOD_RETURN: ret = dp_unpack_pam_response(msg, preq->pd, &dbus_error); if (!ret) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse reply.\n"); preq->pd->pam_status = PAM_SYSTEM_ERR; goto done; } DEBUG(SSSDBG_FUNC_DATA, "received: [%d (%s)][%s]\n", preq->pd->pam_status, pam_strerror(NULL, preq->pd->pam_status), preq->pd->domain); break; case DBUS_MESSAGE_TYPE_ERROR: DEBUG(SSSDBG_FATAL_FAILURE, "Reply error.\n"); preq->pd->pam_status = PAM_SYSTEM_ERR; break; default: DEBUG(SSSDBG_FATAL_FAILURE, "Default... what now?.\n"); preq->pd->pam_status = PAM_SYSTEM_ERR; } done: dbus_pending_call_unref(pending); dbus_message_unref(msg); preq->callback(preq); } static int pdp_req_destructor(struct pam_auth_dp_req *pdp_req) { if (pdp_req && pdp_req->preq) { /* If there is still a client waiting, reset the * spy */ pdp_req->preq->dpreq_spy = NULL; } return 0; } int pam_dp_send_req(struct pam_auth_req *preq, int timeout) { struct pam_data *pd = preq->pd; struct be_conn *be_conn; DBusMessage *msg; dbus_bool_t ret; int res; struct pam_auth_dp_req *pdp_req; /* double check dp_ctx has actually been initialized. * in some pathological cases it may happen that nss starts up before * dp connection code is actually able to establish a connection. */ res = sss_dp_get_domain_conn(preq->cctx->rctx, preq->domain->conn_name, &be_conn); if (res != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "The Data Provider connection for %s is not available!" " This maybe a bug, it shouldn't happen!\n", preq->domain->conn_name); return EIO; } msg = dbus_message_new_method_call(NULL, DP_PATH, DATA_PROVIDER_IFACE, DATA_PROVIDER_IFACE_PAMHANDLER); if (msg == NULL) { DEBUG(SSSDBG_FATAL_FAILURE,"Out of memory?!\n"); return ENOMEM; } DEBUG(SSSDBG_CONF_SETTINGS, "Sending request with the following data:\n"); DEBUG_PAM_DATA(SSSDBG_CONF_SETTINGS, pd); ret = dp_pack_pam_request(msg, pd); if (!ret) { DEBUG(SSSDBG_CRIT_FAILURE,"Failed to build message\n"); return EIO; } pdp_req = talloc(preq->cctx->rctx, struct pam_auth_dp_req); if (pdp_req == NULL) { return ENOMEM; } pdp_req->preq = preq; preq->dpreq_spy = pdp_req; talloc_set_destructor(pdp_req, pdp_req_destructor); res = sbus_conn_send(be_conn->conn, msg, timeout, pam_dp_process_reply, pdp_req, NULL); dbus_message_unref(msg); return res; } sssd-1.13.4/src/responder/pam/PaxHeaders.16287/pamsrv_cmd.c0000644000000000000000000000007412703456111020171 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.950794632 sssd-1.13.4/src/responder/pam/pamsrv_cmd.c0000644002412700241270000017634412703456111021657 0ustar00jhrozekjhrozek00000000000000/* SSSD PAM Responder Copyright (C) Simo Sorce 2009 Copyright (C) Sumit Bose 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "util/auth_utils.h" #include "db/sysdb.h" #include "confdb/confdb.h" #include "responder/common/responder_packet.h" #include "responder/common/responder.h" #include "responder/common/negcache.h" #include "providers/data_provider.h" #include "responder/pam/pamsrv.h" #include "responder/pam/pam_helpers.h" #include "responder/common/responder_cache_req.h" #include "db/sysdb.h" enum pam_verbosity { PAM_VERBOSITY_NO_MESSAGES = 0, PAM_VERBOSITY_IMPORTANT, PAM_VERBOSITY_INFO, PAM_VERBOSITY_DEBUG }; #define DEFAULT_PAM_VERBOSITY PAM_VERBOSITY_IMPORTANT static errno_t pam_null_last_online_auth_with_curr_token(struct sss_domain_info *domain, const char *username); static errno_t pam_get_last_online_auth_with_curr_token(struct sss_domain_info *domain, const char *name, uint64_t *_value); static void pam_reply(struct pam_auth_req *preq); static errno_t pack_user_info_msg(TALLOC_CTX *mem_ctx, const char *user_error_message, size_t *resp_len, uint8_t **_resp) { uint32_t resp_type = SSS_PAM_USER_INFO_ACCOUNT_EXPIRED; size_t err_len; uint8_t *resp; size_t p; err_len = strlen(user_error_message); *resp_len = 2 * sizeof(uint32_t) + err_len; resp = talloc_size(mem_ctx, *resp_len); if (resp == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed.\n"); return ENOMEM; } p = 0; SAFEALIGN_SET_UINT32(&resp[p], resp_type, &p); SAFEALIGN_SET_UINT32(&resp[p], err_len, &p); safealign_memcpy(&resp[p], user_error_message, err_len, &p); if (p != *resp_len) { DEBUG(SSSDBG_FATAL_FAILURE, "Size mismatch\n"); } *_resp = resp; return EOK; } static void inform_user(struct pam_data* pd, const char *pam_message) { size_t msg_len; uint8_t *msg; errno_t ret; ret = pack_user_info_msg(pd, pam_message, &msg_len, &msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pack_user_info_account_expired failed.\n"); } else { ret = pam_add_response(pd, SSS_PAM_USER_INFO, msg_len, msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } } } static bool is_domain_requested(struct pam_data *pd, const char *domain_name) { int i; /* If none specific domains got requested via pam, all domains are allowed. * Which mimics the default/original behaviour. */ if (!pd->requested_domains) { return true; } for (i = 0; pd->requested_domains[i]; i++) { if (strcasecmp(domain_name, pd->requested_domains[i])) { continue; } return true; } return false; } static int extract_authtok_v2(struct sss_auth_token *tok, size_t data_size, uint8_t *body, size_t blen, size_t *c) { uint32_t auth_token_type; uint32_t auth_token_length; uint8_t *auth_token_data; int ret = EOK; if (data_size < sizeof(uint32_t) || *c+data_size > blen || SIZE_T_OVERFLOW(*c, data_size)) return EINVAL; SAFEALIGN_COPY_UINT32_CHECK(&auth_token_type, &body[*c], blen, c); auth_token_length = data_size - sizeof(uint32_t); auth_token_data = body+(*c); switch (auth_token_type) { case SSS_AUTHTOK_TYPE_EMPTY: sss_authtok_set_empty(tok); break; case SSS_AUTHTOK_TYPE_PASSWORD: if (auth_token_length == 0) { sss_authtok_set_empty(tok); } else { ret = sss_authtok_set_password(tok, (const char *)auth_token_data, auth_token_length); } break; case SSS_AUTHTOK_TYPE_2FA: ret = sss_authtok_set(tok, SSS_AUTHTOK_TYPE_2FA, auth_token_data, auth_token_length); break; case SSS_AUTHTOK_TYPE_SC_PIN: ret = sss_authtok_set_sc_pin(tok, (const char *) auth_token_data, auth_token_length); break; case SSS_AUTHTOK_TYPE_SC_KEYPAD: sss_authtok_set_sc_keypad(tok); break; default: return EINVAL; } *c += auth_token_length; return ret; } static int extract_string(char **var, size_t size, uint8_t *body, size_t blen, size_t *c) { uint8_t *str; if (*c+size > blen || SIZE_T_OVERFLOW(*c, size)) return EINVAL; str = body+(*c); if (str[size-1]!='\0') return EINVAL; /* If the string isn't valid UTF-8, fail */ if (!sss_utf8_check(str, size-1)) { return EINVAL; } *c += size; *var = (char *) str; return EOK; } static int extract_uint32_t(uint32_t *var, size_t size, uint8_t *body, size_t blen, size_t *c) { if (size != sizeof(uint32_t) || *c+size > blen || SIZE_T_OVERFLOW(*c, size)) return EINVAL; SAFEALIGN_COPY_UINT32_CHECK(var, &body[*c], blen, c); return EOK; } static int pd_set_primary_name(const struct ldb_message *msg,struct pam_data *pd) { const char *name; name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); if (!name) { DEBUG(SSSDBG_CRIT_FAILURE, "A user with no name?\n"); return EIO; } if (strcmp(pd->user, name)) { DEBUG(SSSDBG_TRACE_FUNC, "User's primary name is %s\n", name); talloc_free(pd->user); pd->user = talloc_strdup(pd, name); if (!pd->user) return ENOMEM; } return EOK; } static int pam_parse_in_data_v2(struct pam_data *pd, uint8_t *body, size_t blen) { size_t c; uint32_t type; uint32_t size; int ret; uint32_t start; uint32_t terminator; char *requested_domains; if (blen < 4*sizeof(uint32_t)+2) { DEBUG(SSSDBG_CRIT_FAILURE, "Received data is invalid.\n"); return EINVAL; } SAFEALIGN_COPY_UINT32(&start, body, NULL); SAFEALIGN_COPY_UINT32(&terminator, body + blen - sizeof(uint32_t), NULL); if (start != SSS_START_OF_PAM_REQUEST || terminator != SSS_END_OF_PAM_REQUEST) { DEBUG(SSSDBG_CRIT_FAILURE, "Received data is invalid.\n"); return EINVAL; } c = sizeof(uint32_t); do { SAFEALIGN_COPY_UINT32_CHECK(&type, &body[c], blen, &c); if (type == SSS_END_OF_PAM_REQUEST) { if (c != blen) return EINVAL; } else { SAFEALIGN_COPY_UINT32_CHECK(&size, &body[c], blen, &c); /* the uint32_t end maker SSS_END_OF_PAM_REQUEST does not count to * the remaining buffer */ if (size > (blen - c - sizeof(uint32_t))) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid data size.\n"); return EINVAL; } switch(type) { case SSS_PAM_ITEM_USER: ret = extract_string(&pd->logon_name, size, body, blen, &c); if (ret != EOK) return ret; break; case SSS_PAM_ITEM_SERVICE: ret = extract_string(&pd->service, size, body, blen, &c); if (ret != EOK) return ret; break; case SSS_PAM_ITEM_TTY: ret = extract_string(&pd->tty, size, body, blen, &c); if (ret != EOK) return ret; break; case SSS_PAM_ITEM_RUSER: ret = extract_string(&pd->ruser, size, body, blen, &c); if (ret != EOK) return ret; break; case SSS_PAM_ITEM_RHOST: ret = extract_string(&pd->rhost, size, body, blen, &c); if (ret != EOK) return ret; break; case SSS_PAM_ITEM_REQUESTED_DOMAINS: ret = extract_string(&requested_domains, size, body, blen, &c); if (ret != EOK) return ret; ret = split_on_separator(pd, requested_domains, ',', true, true, &pd->requested_domains, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse requested_domains list!\n"); return ret; } break; case SSS_PAM_ITEM_CLI_PID: ret = extract_uint32_t(&pd->cli_pid, size, body, blen, &c); if (ret != EOK) return ret; break; case SSS_PAM_ITEM_AUTHTOK: ret = extract_authtok_v2(pd->authtok, size, body, blen, &c); if (ret != EOK) return ret; break; case SSS_PAM_ITEM_NEWAUTHTOK: ret = extract_authtok_v2(pd->newauthtok, size, body, blen, &c); if (ret != EOK) return ret; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Ignoring unknown data type [%d].\n", type); c += size; } } } while(c < blen); return EOK; } static int pam_parse_in_data_v3(struct pam_data *pd, uint8_t *body, size_t blen) { int ret; ret = pam_parse_in_data_v2(pd, body, blen); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_parse_in_data_v2 failed.\n"); return ret; } if (pd->cli_pid == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing client PID.\n"); return EINVAL; } return EOK; } static int extract_authtok_v1(struct sss_auth_token *tok, uint8_t *body, size_t blen, size_t *c) { uint32_t auth_token_type; uint32_t auth_token_length; uint8_t *auth_token_data; int ret = EOK; SAFEALIGN_COPY_UINT32_CHECK(&auth_token_type, &body[*c], blen, c); SAFEALIGN_COPY_UINT32_CHECK(&auth_token_length, &body[*c], blen, c); auth_token_data = body+(*c); switch (auth_token_type) { case SSS_AUTHTOK_TYPE_EMPTY: sss_authtok_set_empty(tok); break; case SSS_AUTHTOK_TYPE_PASSWORD: ret = sss_authtok_set_password(tok, (const char *)auth_token_data, auth_token_length); break; default: return EINVAL; } *c += auth_token_length; return ret; } static int pam_parse_in_data(struct pam_data *pd, uint8_t *body, size_t blen) { size_t start; size_t end; size_t last; int ret; last = blen - 1; end = 0; /* user name */ for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; pd->logon_name = (char *) &body[start]; for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; pd->service = (char *) &body[start]; for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; pd->tty = (char *) &body[start]; for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; pd->ruser = (char *) &body[start]; for (start = end; end < last; end++) if (body[end] == '\0') break; if (body[end++] != '\0') return EINVAL; pd->rhost = (char *) &body[start]; ret = extract_authtok_v1(pd->authtok, body, blen, &end); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid auth token\n"); return ret; } ret = extract_authtok_v1(pd->newauthtok, body, blen, &end); if (ret) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid new auth token\n"); return ret; } DEBUG_PAM_DATA(SSSDBG_CONF_SETTINGS, pd); return EOK; } /*=Save-Last-Login-State===================================================*/ static errno_t set_last_login(struct pam_auth_req *preq) { struct sysdb_attrs *attrs; errno_t ret; attrs = sysdb_new_attrs(preq); if (!attrs) { ret = ENOMEM; goto fail; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_ONLINE_AUTH, time(NULL)); if (ret != EOK) { goto fail; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_ONLINE_AUTH_WITH_CURR_TOKEN, time(NULL)); if (ret != EOK) { goto fail; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_LOGIN, time(NULL)); if (ret != EOK) { goto fail; } ret = sysdb_set_user_attr(preq->domain, preq->pd->user, attrs, SYSDB_MOD_REP); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "set_last_login failed.\n"); preq->pd->pam_status = PAM_SYSTEM_ERR; goto fail; } else { preq->pd->last_auth_saved = true; } preq->callback(preq); return EOK; fail: return ret; } static errno_t filter_responses(struct confdb_ctx *cdb, struct response_data *resp_list) { int ret; struct response_data *resp; uint32_t user_info_type; int64_t expire_date; int pam_verbosity; ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_VERBOSITY, DEFAULT_PAM_VERBOSITY, &pam_verbosity); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read PAM verbosity, not fatal.\n"); pam_verbosity = DEFAULT_PAM_VERBOSITY; } resp = resp_list; while(resp != NULL) { if (resp->type == SSS_PAM_USER_INFO) { if (resp->len < sizeof(uint32_t)) { DEBUG(SSSDBG_CRIT_FAILURE, "User info entry is too short.\n"); return EINVAL; } if (pam_verbosity == PAM_VERBOSITY_NO_MESSAGES) { resp->do_not_send_to_client = true; resp = resp->next; continue; } memcpy(&user_info_type, resp->data, sizeof(uint32_t)); resp->do_not_send_to_client = false; switch (user_info_type) { case SSS_PAM_USER_INFO_OFFLINE_AUTH: if (resp->len != sizeof(uint32_t) + sizeof(int64_t)) { DEBUG(SSSDBG_CRIT_FAILURE, "User info offline auth entry is " "too short.\n"); return EINVAL; } memcpy(&expire_date, resp->data + sizeof(uint32_t), sizeof(int64_t)); if ((expire_date == 0 && pam_verbosity < PAM_VERBOSITY_INFO) || (expire_date > 0 && pam_verbosity < PAM_VERBOSITY_IMPORTANT)) { resp->do_not_send_to_client = true; } break; default: DEBUG(SSSDBG_TRACE_LIBS, "User info type [%d] not filtered.\n", user_info_type); } } else if (resp->type & SSS_SERVER_INFO) { resp->do_not_send_to_client = true; } resp = resp->next; } return EOK; } static void pam_reply_delay(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct pam_auth_req *preq; DEBUG(SSSDBG_CONF_SETTINGS, "pam_reply_delay get called.\n"); preq = talloc_get_type(pvt, struct pam_auth_req); pam_reply(preq); } static errno_t get_password_for_cache_auth(struct sss_auth_token *authtok, const char **password) { int ret; size_t pw_len; const char *fa2; size_t fa2_len; switch (sss_authtok_get_type(authtok)) { case SSS_AUTHTOK_TYPE_PASSWORD: ret = sss_authtok_get_password(authtok, password, NULL); break; case SSS_AUTHTOK_TYPE_2FA: ret = sss_authtok_get_2fa(authtok, password, &pw_len, &fa2, &fa2_len); break; default: DEBUG(SSSDBG_FATAL_FAILURE, "Unsupported auth token type [%d].\n", sss_authtok_get_type(authtok)); ret = EINVAL; } if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get password.\n"); return ret; } return EOK; } static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd); static void pam_handle_cached_login(struct pam_auth_req *preq, int ret, time_t expire_date, time_t delayed_until, bool cached_auth); static void pam_reply(struct pam_auth_req *preq) { struct cli_ctx *cctx; uint8_t *body; size_t blen; int ret; int32_t resp_c; int32_t resp_size; struct response_data *resp; int p; struct timeval tv; struct tevent_timer *te; struct pam_data *pd; struct pam_ctx *pctx; uint32_t user_info_type; time_t exp_date = -1; time_t delay_until = -1; char* pam_account_expired_message; char* pam_account_locked_message; int pam_verbosity; pd = preq->pd; cctx = preq->cctx; pctx = talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_VERBOSITY, DEFAULT_PAM_VERBOSITY, &pam_verbosity); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read PAM verbosity, not fatal.\n"); pam_verbosity = DEFAULT_PAM_VERBOSITY; } DEBUG(SSSDBG_FUNC_DATA, "pam_reply called with result [%d]: %s.\n", pd->pam_status, pam_strerror(NULL, pd->pam_status)); if (pd->pam_status == PAM_AUTHINFO_UNAVAIL || preq->use_cached_auth) { switch(pd->cmd) { case SSS_PAM_AUTHENTICATE: if ((preq->domain != NULL) && (preq->domain->cache_credentials == true) && (pd->offline_auth == false)) { const char *password = NULL; bool use_cached_auth; /* backup value of preq->use_cached_auth*/ use_cached_auth = preq->use_cached_auth; /* set to false to avoid entering this branch when pam_reply() * is recursively called from pam_handle_cached_login() */ preq->use_cached_auth = false; /* do auth with offline credentials */ pd->offline_auth = true; if (preq->domain->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for domain" " [%s]!\n", preq->domain->name); goto done; } ret = get_password_for_cache_auth(pd->authtok, &password); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "get_password_and_type_for_cache_auth failed.\n"); goto done; } ret = sysdb_cache_auth(preq->domain, pd->user, password, pctx->rctx->cdb, false, &exp_date, &delay_until); pam_handle_cached_login(preq, ret, exp_date, delay_until, use_cached_auth); return; } break; case SSS_PAM_CHAUTHTOK_PRELIM: case SSS_PAM_CHAUTHTOK: DEBUG(SSSDBG_FUNC_DATA, "Password change not possible while offline.\n"); pd->pam_status = PAM_AUTHTOK_ERR; user_info_type = SSS_PAM_USER_INFO_OFFLINE_CHPASS; ret = pam_add_response(pd, SSS_PAM_USER_INFO, sizeof(uint32_t), (const uint8_t *) &user_info_type); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); goto done; } break; /* TODO: we need the pam session cookie here to make sure that cached * authentication was successful */ case SSS_PAM_SETCRED: case SSS_PAM_ACCT_MGMT: case SSS_PAM_OPEN_SESSION: case SSS_PAM_CLOSE_SESSION: DEBUG(SSSDBG_OP_FAILURE, "Assuming offline authentication setting status for " "pam call %d to PAM_SUCCESS.\n", pd->cmd); pd->pam_status = PAM_SUCCESS; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unknown PAM call [%d].\n", pd->cmd); pd->pam_status = PAM_MODULE_UNKNOWN; } } if (pd->pam_status == PAM_SUCCESS && pd->cmd == SSS_PAM_CHAUTHTOK) { ret = pam_null_last_online_auth_with_curr_token(preq->domain, pd->user); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_null_last_online_auth_with_curr_token failed: " "%s [%d].\n", sss_strerror(ret), ret); goto done; } } if (pd->response_delay > 0) { ret = gettimeofday(&tv, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "gettimeofday failed [%d][%s].\n", errno, strerror(errno)); goto done; } tv.tv_sec += pd->response_delay; tv.tv_usec = 0; pd->response_delay = 0; te = tevent_add_timer(cctx->ev, cctx, tv, pam_reply_delay, preq); if (te == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add event pam_reply_delay.\n"); goto done; } return; } /* If this was a successful login, save the lastLogin time */ if (pd->cmd == SSS_PAM_AUTHENTICATE && pd->pam_status == PAM_SUCCESS && preq->domain->cache_credentials && !pd->offline_auth && !pd->last_auth_saved && NEED_CHECK_PROVIDER(preq->domain->provider)) { ret = set_last_login(preq); if (ret != EOK) { goto done; } return; } ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { goto done; } /* Account expiration warning is printed for sshd. If pam_verbosity * is equal or above PAM_VERBOSITY_INFO then all services are informed * about account expiration. */ if (pd->pam_status == PAM_ACCT_EXPIRED && ((pd->service != NULL && strcasecmp(pd->service, "sshd") == 0) || pam_verbosity >= PAM_VERBOSITY_INFO)) { ret = confdb_get_string(pctx->rctx->cdb, pd, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_ACCOUNT_EXPIRED_MESSAGE, "", &pam_account_expired_message); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get expiration message: %d:[%s].\n", ret, sss_strerror(ret)); goto done; } inform_user(pd, pam_account_expired_message); } if (pd->account_locked) { ret = confdb_get_string(pctx->rctx->cdb, pd, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_ACCOUNT_LOCKED_MESSAGE, "", &pam_account_locked_message); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get expiration message: %d:[%s].\n", ret, sss_strerror(ret)); goto done; } inform_user(pd, pam_account_locked_message); } ret = filter_responses(pctx->rctx->cdb, pd->resp_list); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "filter_responses failed, not fatal.\n"); } if (pd->domain != NULL) { ret = pam_add_response(pd, SSS_PAM_DOMAIN_NAME, strlen(pd->domain)+1, (uint8_t *) pd->domain); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); goto done; } } resp_c = 0; resp_size = 0; resp = pd->resp_list; while(resp != NULL) { if (!resp->do_not_send_to_client) { resp_c++; resp_size += resp->len; } resp = resp->next; } ret = sss_packet_grow(cctx->creq->out, sizeof(int32_t) + sizeof(int32_t) + resp_c * 2* sizeof(int32_t) + resp_size); if (ret != EOK) { goto done; } sss_packet_get_body(cctx->creq->out, &body, &blen); DEBUG(SSSDBG_FUNC_DATA, "blen: %zu\n", blen); p = 0; memcpy(&body[p], &pd->pam_status, sizeof(int32_t)); p += sizeof(int32_t); memcpy(&body[p], &resp_c, sizeof(int32_t)); p += sizeof(int32_t); resp = pd->resp_list; while(resp != NULL) { if (!resp->do_not_send_to_client) { memcpy(&body[p], &resp->type, sizeof(int32_t)); p += sizeof(int32_t); memcpy(&body[p], &resp->len, sizeof(int32_t)); p += sizeof(int32_t); memcpy(&body[p], resp->data, resp->len); p += resp->len; } resp = resp->next; } done: sss_cmd_done(cctx, preq); } static void pam_dom_forwarder(struct pam_auth_req *preq); static void pam_handle_cached_login(struct pam_auth_req *preq, int ret, time_t expire_date, time_t delayed_until, bool use_cached_auth) { uint32_t resp_type; size_t resp_len; uint8_t *resp; int64_t dummy; preq->pd->pam_status = cached_login_pam_status(ret); switch (preq->pd->pam_status) { case PAM_SUCCESS: resp_type = SSS_PAM_USER_INFO_OFFLINE_AUTH; resp_len = sizeof(uint32_t) + sizeof(int64_t); resp = talloc_size(preq->pd, resp_len); if (resp == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed, cannot prepare user info.\n"); } else { memcpy(resp, &resp_type, sizeof(uint32_t)); dummy = (int64_t) expire_date; memcpy(resp+sizeof(uint32_t), &dummy, sizeof(int64_t)); ret = pam_add_response(preq->pd, SSS_PAM_USER_INFO, resp_len, (const uint8_t *) resp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } } break; case PAM_PERM_DENIED: if (delayed_until >= 0) { resp_type = SSS_PAM_USER_INFO_OFFLINE_AUTH_DELAYED; resp_len = sizeof(uint32_t) + sizeof(int64_t); resp = talloc_size(preq->pd, resp_len); if (resp == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "talloc_size failed, cannot prepare user info.\n"); } else { memcpy(resp, &resp_type, sizeof(uint32_t)); dummy = (int64_t) delayed_until; memcpy(resp+sizeof(uint32_t), &dummy, sizeof(int64_t)); ret = pam_add_response(preq->pd, SSS_PAM_USER_INFO, resp_len, (const uint8_t *) resp); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "pam_add_response failed.\n"); } } } break; case PAM_AUTH_ERR: /* Was this attempt to authenticate from cache? */ if (use_cached_auth) { /* Don't try cached authentication again, try online check. */ DEBUG(SSSDBG_FUNC_DATA, "Cached authentication failed for: %s\n", preq->pd->user); preq->cached_auth_failed = true; pam_dom_forwarder(preq); return; } break; default: DEBUG(SSSDBG_TRACE_LIBS, "cached login returned: %d\n", preq->pd->pam_status); } pam_reply(preq); return; } static void pam_forwarder_cb(struct tevent_req *req); static void pam_forwarder_cert_cb(struct tevent_req *req); static void pam_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); static int pam_check_user_search(struct pam_auth_req *preq); static int pam_check_user_done(struct pam_auth_req *preq, int ret); /* TODO: we should probably return some sort of cookie that is set in the * PAM_ENVIRONMENT, so that we can save performing some calls and cache * data. */ static errno_t pam_forwarder_parse_data(struct cli_ctx *cctx, struct pam_data *pd) { uint8_t *body; size_t blen; errno_t ret; uint32_t terminator; sss_packet_get_body(cctx->creq->in, &body, &blen); if (blen >= sizeof(uint32_t)) { SAFEALIGN_COPY_UINT32(&terminator, body + blen - sizeof(uint32_t), NULL); if (terminator != SSS_END_OF_PAM_REQUEST) { DEBUG(SSSDBG_CRIT_FAILURE, "Received data not terminated.\n"); ret = EINVAL; goto done; } } switch (cctx->cli_protocol_version->version) { case 1: ret = pam_parse_in_data(pd, body, blen); break; case 2: ret = pam_parse_in_data_v2(pd, body, blen); break; case 3: ret = pam_parse_in_data_v3(pd, body, blen); break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Illegal protocol version [%d].\n", cctx->cli_protocol_version->version); ret = EINVAL; } if (ret != EOK) { goto done; } if (pd->logon_name != NULL) { ret = sss_parse_name_for_domains(pd, cctx->rctx->domains, cctx->rctx->default_domain, pd->logon_name, &pd->domain, &pd->user); } else { /* Only SSS_PAM_PREAUTH request may have a missing name, e.g. if the * name is determined with the help of a certificate */ if (pd->cmd == SSS_PAM_PREAUTH && may_do_cert_auth(talloc_get_type(cctx->rctx->pvt_ctx, struct pam_ctx), pd)) { ret = EOK; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Missing logon name in PAM request.\n"); ret = ERR_NO_CREDS; goto done; } } DEBUG_PAM_DATA(SSSDBG_CONF_SETTINGS, pd); done: return ret; } static int pam_auth_req_destructor(struct pam_auth_req *preq) { if (preq && preq->dpreq_spy) { /* If there is still a request pending, tell the spy * the client is going away */ preq->dpreq_spy->preq = NULL; } return 0; } static bool is_uid_trusted(uint32_t uid, size_t trusted_uids_count, uid_t *trusted_uids) { size_t i; /* root is always trusted */ if (uid == 0) { return true; } /* All uids are allowed */ if (trusted_uids_count == 0) { return true; } for(i = 0; i < trusted_uids_count; i++) { if (trusted_uids[i] == uid) { return true; } } return false; } static bool is_domain_public(char *name, char **public_dom_names, size_t public_dom_names_count) { size_t i; for(i=0; i < public_dom_names_count; i++) { if (strcasecmp(name, public_dom_names[i]) == 0) { return true; } } return false; } static errno_t check_cert(TALLOC_CTX *mctx, struct tevent_context *ev, struct pam_ctx *pctx, struct pam_auth_req *preq, struct pam_data *pd) { int p11_child_timeout; const int P11_CHILD_TIMEOUT_DEFAULT = 10; char *cert_verification_opts; errno_t ret; struct tevent_req *req; ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_P11_CHILD_TIMEOUT, P11_CHILD_TIMEOUT_DEFAULT, &p11_child_timeout); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read p11_child_timeout from confdb: [%d]: %s\n", ret, sss_strerror(ret)); return ret; } ret = confdb_get_string(pctx->rctx->cdb, mctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_CERT_VERIFICATION, NULL, &cert_verification_opts); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to read certificate_verification from confdb: [%d]: %s\n", ret, sss_strerror(ret)); return ret; } req = pam_check_cert_send(mctx, ev, pctx->p11_child_debug_fd, pctx->nss_db, p11_child_timeout, cert_verification_opts, pd); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "pam_check_cert_send failed.\n"); return ENOMEM; } tevent_req_set_callback(req, pam_forwarder_cert_cb, preq); return EAGAIN; } static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd) { struct sss_domain_info *dom; struct pam_auth_req *preq; struct pam_data *pd; int ret; errno_t ncret; struct pam_ctx *pctx = talloc_get_type(cctx->rctx->pvt_ctx, struct pam_ctx); struct tevent_req *req; preq = talloc_zero(cctx, struct pam_auth_req); if (!preq) { return ENOMEM; } talloc_set_destructor(preq, pam_auth_req_destructor); preq->cctx = cctx; preq->pd = create_pam_data(preq); if (!preq->pd) { talloc_free(preq); return ENOMEM; } pd = preq->pd; preq->is_uid_trusted = is_uid_trusted(cctx->client_euid, pctx->trusted_uids_count, pctx->trusted_uids); if (!preq->is_uid_trusted) { DEBUG(SSSDBG_MINOR_FAILURE, "uid %"PRIu32" is not trusted.\n", cctx->client_euid); } pd->cmd = pam_cmd; pd->priv = cctx->priv; ret = pam_forwarder_parse_data(cctx, pd); if (ret == EAGAIN) { req = sss_dp_get_domains_send(cctx->rctx, cctx->rctx, true, pd->domain); if (req == NULL) { ret = ENOMEM; } else { tevent_req_set_callback(req, pam_forwarder_cb, preq); ret = EAGAIN; } goto done; } else if (ret != EOK) { goto done; } if (pd->user != NULL) { /* now check user is valid */ if (pd->domain) { preq->domain = responder_get_domain(cctx->rctx, pd->domain); if (!preq->domain) { ret = ENOENT; goto done; } ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout, preq->domain, pd->user); if (ncret == EEXIST) { /* User found in the negative cache */ ret = ENOENT; goto done; } } else { for (dom = preq->cctx->rctx->domains; dom; dom = get_next_domain(dom, 0)) { if (dom->fqnames) continue; ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout, dom, pd->user); if (ncret == ENOENT) { /* User not found in the negative cache * Proceed with PAM actions */ break; } /* Try the next domain */ DEBUG(SSSDBG_TRACE_FUNC, "User [%s@%s] filtered out (negative cache). " "Trying next domain.\n", pd->user, dom->name); } if (!dom) { ret = ENOENT; goto done; } preq->domain = dom; } } if (may_do_cert_auth(pctx, pd)) { ret = check_cert(cctx, cctx->ev, pctx, preq, pd); /* Finish here */ goto done; } if (preq->domain->provider == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Domain [%s] has no auth provider.\n", preq->domain->name); ret = EINVAL; goto done; } preq->check_provider = NEED_CHECK_PROVIDER(preq->domain->provider); ret = pam_check_user_search(preq); if (ret == EOK) { pam_dom_forwarder(preq); } done: return pam_check_user_done(preq, ret); } static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req); static void pam_forwarder_cert_cb(struct tevent_req *req) { struct pam_auth_req *preq = tevent_req_callback_data(req, struct pam_auth_req); struct cli_ctx *cctx = preq->cctx; struct pam_data *pd; errno_t ret = EOK; char *cert; struct pam_ctx *pctx = talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); ret = pam_check_cert_recv(req, preq, &cert, &preq->token_name); talloc_free(req); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_cert request failed.\n"); goto done; } pd = preq->pd; if (cert == NULL) { if (pd->logon_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No certificate found and no logon name given, " \ "authentication not possible.\n");; ret = ENOENT; } else { if (pd->cmd == SSS_PAM_AUTHENTICATE) { DEBUG(SSSDBG_CRIT_FAILURE, "No certificate returned, authentication failed.\n"); ret = ENOENT; } else { ret = pam_check_user_search(preq); if (ret == EOK) { pam_dom_forwarder(preq); } } } goto done; } req = cache_req_user_by_cert_send(preq, cctx->ev, cctx->rctx, pctx->ncache, pctx->neg_timeout, 0, NULL, cert); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "cache_req_user_by_cert_send failed.\n"); ret = ENOMEM; goto done; } tevent_req_set_callback(req, pam_forwarder_lookup_by_cert_done, preq); return; done: pam_check_user_done(preq, ret); } static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) { int ret; struct ldb_result *res; struct sss_domain_info *domain; struct pam_auth_req *preq = tevent_req_callback_data(req, struct pam_auth_req); const char *cert_user; ret = cache_req_user_by_cert_recv(preq, req, &res, &domain, NULL); talloc_zfree(req); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "cache_req_user_by_cert request failed.\n"); goto done; } if (ret == EOK && res->count > 1) { DEBUG(SSSDBG_CRIT_FAILURE, "Search by certificate returned more than one result.\n"); ret = EINVAL; goto done; } if (ret == EOK) { if (preq->domain == NULL) { preq->domain = domain; } preq->cert_user_obj = talloc_steal(preq, res->msgs[0]); if (preq->pd->logon_name == NULL) { cert_user = ldb_msg_find_attr_as_string(preq->cert_user_obj, SYSDB_NAME, NULL); if (cert_user == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Certificate user object has not name.\n"); ret = ENOENT; goto done; } DEBUG(SSSDBG_FUNC_DATA, "Found certificate user [%s].\n", cert_user); ret = add_pam_cert_response(preq->pd, cert_user, preq->token_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_pam_cert_response failed.\n"); } preq->pd->domain = talloc_strdup(preq->pd, domain->name); if (preq->pd->domain == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } preq->pd->pam_status = PAM_SUCCESS; pam_reply(preq); return; } } else { if (preq->pd->logon_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing logon name and no certificate user found.\n"); ret = ENOENT; goto done; } } ret = pam_check_user_search(preq); if (ret == EOK) { pam_dom_forwarder(preq); } done: pam_check_user_done(preq, ret); } static void pam_forwarder_cb(struct tevent_req *req) { struct pam_auth_req *preq = tevent_req_callback_data(req, struct pam_auth_req); struct cli_ctx *cctx = preq->cctx; struct pam_data *pd; errno_t ret = EOK; struct pam_ctx *pctx = talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); ret = sss_dp_get_domains_recv(req); talloc_free(req); if (ret != EOK) { goto done; } pd = preq->pd; ret = pam_forwarder_parse_data(cctx, pd); if (ret == EAGAIN) { if (strchr(preq->pd->logon_name, '@') == NULL) { goto done; } /* Assuming Kerberos principal */ preq->domain = preq->cctx->rctx->domains; preq->check_provider = NEED_CHECK_PROVIDER(preq->domain->provider); preq->pd->user = talloc_strdup(preq->pd, preq->pd->logon_name); if (preq->pd->user == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); ret = ENOMEM; goto done; } preq->pd->name_is_upn = true; preq->pd->domain = NULL; } else if (ret != EOK) { ret = EINVAL; goto done; } if (preq->pd->domain) { preq->domain = responder_get_domain(cctx->rctx, preq->pd->domain); if (preq->domain == NULL) { ret = ENOENT; goto done; } } if (may_do_cert_auth(pctx, pd)) { ret = check_cert(cctx, cctx->ev, pctx, preq, pd); /* Finish here */ goto done; } ret = pam_check_user_search(preq); if (ret == EOK) { pam_dom_forwarder(preq); } done: pam_check_user_done(preq, ret); } static void pam_dp_send_acct_req_done(struct tevent_req *req); static int pam_check_user_search(struct pam_auth_req *preq) { struct sss_domain_info *dom = preq->domain; char *name = NULL; time_t cacheExpire; int ret; struct tevent_req *dpreq; struct dp_callback_ctx *cb_ctx; struct pam_ctx *pctx = talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); static const char *user_attrs[] = SYSDB_PW_ATTRS; struct ldb_message *msg; struct ldb_result *res; while (dom) { /* if it is a domainless search, skip domains that require fully * qualified names instead */ while (dom && !preq->pd->domain && !preq->pd->name_is_upn && dom->fqnames) { dom = get_next_domain(dom, 0); } if (!dom) break; if (dom != preq->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ preq->check_provider = NEED_CHECK_PROVIDER(dom->provider); } /* make sure to update the preq if we changed domain */ preq->domain = dom; talloc_free(name); name = sss_get_cased_name(preq, preq->pd->user, dom->case_sensitive); if (!name) { return ENOMEM; } name = sss_reverse_replace_space(preq, name, pctx->rctx->override_space); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "sss_reverse_replace_space failed\n"); return ENOMEM; } /* Refresh the user's cache entry on any PAM query * We put a timeout in the client context so that we limit * the number of updates within a reasonable timeout */ if (preq->check_provider) { ret = pam_initgr_check_timeout(pctx->id_table, preq->pd->logon_name); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_OP_FAILURE, "Could not look up initgroup timout\n"); return EIO; } else if (ret == ENOENT) { /* Call provider first */ break; } /* Entry is still valid, get it from the sysdb */ } DEBUG(SSSDBG_CONF_SETTINGS, "Requesting info for [%s@%s]\n", name, dom->name); if (dom->sysdb == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); preq->pd->pam_status = PAM_SYSTEM_ERR; return EFAULT; } if (preq->pd->name_is_upn) { ret = sysdb_search_user_by_upn(preq, dom, name, user_attrs, &msg); } else { ret = sysdb_getpwnam_with_views(preq, dom, name, &res); if (res->count > 1) { DEBUG(SSSDBG_FATAL_FAILURE, "getpwnam call returned more than one result !?!\n"); sss_log(SSS_LOG_ERR, "More users have the same name [%s@%s] in SSSD cache. " "SSSD will not work correctly.\n", name, dom->name); return ENOENT; } else if (res->count == 0) { ret = ENOENT; } else { msg = res->msgs[0]; } } if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache!\n"); return EIO; } if (ret == ENOENT) { if (preq->check_provider == false) { /* set negative cache only if not result of cache check */ ret = sss_ncache_set_user(pctx->ncache, false, dom, name); if (ret != EOK) { /* Should not be fatal, just slower next time */ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set ncache for [%s@%s]\n", name, dom->name); } } /* if a multidomain search, try with next */ if (!preq->pd->domain) { dom = get_next_domain(dom, 0); continue; } DEBUG(SSSDBG_OP_FAILURE, "No results for getpwnam call\n"); /* TODO: store negative cache ? */ return ENOENT; } /* One result found */ /* if we need to check the remote account go on */ if (preq->check_provider) { cacheExpire = ldb_msg_find_attr_as_uint64(msg, SYSDB_CACHE_EXPIRE, 0); if (cacheExpire < time(NULL)) { break; } } DEBUG(SSSDBG_TRACE_FUNC, "Returning info for user [%s@%s]\n", name, dom->name); /* We might have searched by alias. Pass on the primary name */ ret = pd_set_primary_name(msg, preq->pd); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not canonicalize username\n"); return ret; } return EOK; } if (!dom) { /* Ensure that we don't try to check a provider without a domain, * since this will cause a NULL-dereference below. */ preq->check_provider = false; } if (preq->check_provider) { /* dont loop forever :-) */ preq->check_provider = false; dpreq = sss_dp_get_account_send(preq, preq->cctx->rctx, dom, false, SSS_DP_INITGROUPS, name, 0, preq->pd->name_is_upn ? EXTRA_NAME_IS_UPN : NULL); if (!dpreq) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending data provider request\n"); return ENOMEM; } cb_ctx = talloc_zero(preq, struct dp_callback_ctx); if(!cb_ctx) { talloc_zfree(dpreq); return ENOMEM; } cb_ctx->callback = pam_check_user_dp_callback; cb_ctx->ptr = preq; cb_ctx->cctx = preq->cctx; cb_ctx->mem_ctx = preq; tevent_req_set_callback(dpreq, pam_dp_send_acct_req_done, cb_ctx); /* tell caller we are in an async call */ return EAGAIN; } DEBUG(SSSDBG_MINOR_FAILURE, "No matching domain found for [%s], fail!\n", preq->pd->user); return ENOENT; } static void pam_dp_send_acct_req_done(struct tevent_req *req) { struct dp_callback_ctx *cb_ctx = tevent_req_callback_data(req, struct dp_callback_ctx); errno_t ret; dbus_uint16_t err_maj; dbus_uint32_t err_min; char *err_msg; ret = sss_dp_get_account_recv(cb_ctx->mem_ctx, req, &err_maj, &err_min, &err_msg); talloc_zfree(req); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Fatal error, killing connection!\n"); talloc_free(cb_ctx->cctx); return; } cb_ctx->callback(err_maj, err_min, err_msg, cb_ctx->ptr); } static int pam_check_user_done(struct pam_auth_req *preq, int ret) { switch (ret) { case EOK: break; case EAGAIN: /* performing async request, just return */ break; case ENOENT: preq->pd->pam_status = PAM_USER_UNKNOWN; pam_reply(preq); break; case ERR_NO_CREDS: preq->pd->pam_status = PAM_CRED_INSUFFICIENT; pam_reply(preq); break; default: preq->pd->pam_status = PAM_SYSTEM_ERR; pam_reply(preq); break; } return EOK; } static void pam_check_user_dp_callback(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr) { struct pam_auth_req *preq = talloc_get_type(ptr, struct pam_auth_req); int ret; struct pam_ctx *pctx = talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); if (err_maj) { DEBUG(SSSDBG_OP_FAILURE, "Unable to get information from Data Provider\n" "Error: %u, %u, %s\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg); } ret = pam_check_user_search(preq); if (ret == EOK) { /* Make sure we don't go to the ID provider too often */ ret = pam_initgr_cache_set(pctx->rctx->ev, pctx->id_table, preq->pd->logon_name, pctx->id_timeout); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not save initgr timestamp. " "Proceeding with PAM actions\n"); /* This is non-fatal, we'll just end up going to the * data provider again next time. */ } pam_dom_forwarder(preq); } ret = pam_check_user_done(preq, ret); if (ret) { preq->pd->pam_status = PAM_SYSTEM_ERR; pam_reply(preq); } } static errno_t pam_is_last_online_login_fresh(struct sss_domain_info *domain, const char* user, struct confdb_ctx *cdb, int cached_auth_timeout, bool *_result) { errno_t ret; bool result; uint64_t last_login; ret = pam_get_last_online_auth_with_curr_token(domain, user, &last_login); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_get_last_online_auth_with_curr_token failed: %s:[%d]\n", sss_strerror(ret), ret); goto done; } result = time(NULL) < (last_login + cached_auth_timeout); ret = EOK; done: if (ret == EOK) { *_result = result; } return ret; } static bool pam_is_cmd_cachable(int cmd) { bool is_cachable; switch(cmd) { case SSS_PAM_AUTHENTICATE: is_cachable = true; break; default: is_cachable = false; } return is_cachable; } static bool pam_is_authtok_cachable(struct sss_auth_token *authtok) { enum sss_authtok_type type; bool cachable = false; type = sss_authtok_get_type(authtok); if (type == SSS_AUTHTOK_TYPE_PASSWORD) { cachable = true; } else { DEBUG(SSSDBG_TRACE_LIBS, "Authentication token can't be cached\n"); } return cachable; } static bool pam_can_user_cache_auth(struct confdb_ctx *cdb, struct sss_domain_info *domain, int pam_cmd, struct sss_auth_token *authtok, const char* user, bool cached_auth_failed) { errno_t ret; bool result = false; if (!cached_auth_failed /* don't try cached auth again */ && domain->cache_credentials && domain->cached_auth_timeout > 0 && pam_is_authtok_cachable(authtok) && pam_is_cmd_cachable(pam_cmd)) { ret = pam_is_last_online_login_fresh(domain, user, cdb, domain->cached_auth_timeout, &result); if (ret != EOK) { /* non-critical, consider fail as 'non-fresh value' */ DEBUG(SSSDBG_MINOR_FAILURE, "pam_is_last_online_login_fresh failed: %s:[%d]\n", sss_strerror(ret), ret); } } return result; } static void pam_dom_forwarder(struct pam_auth_req *preq) { int ret; struct pam_ctx *pctx = talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); const char *cert_user; if (!preq->pd->domain) { preq->pd->domain = preq->domain->name; } /* Untrusted users can access only public domains. */ if (!preq->is_uid_trusted && !is_domain_public(preq->pd->domain, pctx->public_domains, pctx->public_domains_count)) { DEBUG(SSSDBG_MINOR_FAILURE, "Untrusted user %"PRIu32" cannot access non-public domain %s.\n", preq->cctx->client_euid, preq->pd->domain); preq->pd->pam_status = PAM_PERM_DENIED; pam_reply(preq); return; } /* skip this domain if not requested and the user is trusted * as untrusted users can't request a domain */ if (preq->is_uid_trusted && !is_domain_requested(preq->pd, preq->pd->domain)) { preq->pd->pam_status = PAM_USER_UNKNOWN; pam_reply(preq); return; } if (pam_can_user_cache_auth(pctx->rctx->cdb, preq->domain, preq->pd->cmd, preq->pd->authtok, preq->pd->user, preq->cached_auth_failed)) { preq->use_cached_auth = true; pam_reply(preq); return; } if (may_do_cert_auth(pctx, preq->pd) && preq->cert_user_obj != NULL) { /* Check if user matches certificate user */ cert_user = ldb_msg_find_attr_as_string(preq->cert_user_obj, SYSDB_NAME, NULL); if (cert_user == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Certificate user object has not name.\n"); preq->pd->pam_status = PAM_USER_UNKNOWN; pam_reply(preq); return; } /* pam_check_user_search() calls pd_set_primary_name() is the search * was successful, so pd->user contains the canonical name as well */ if (strcmp(cert_user, preq->pd->user) == 0) { preq->pd->pam_status = PAM_SUCCESS; if (preq->pd->cmd == SSS_PAM_PREAUTH) { ret = add_pam_cert_response(preq->pd, cert_user, preq->token_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "add_pam_cert_response failed.\n"); preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL; } } preq->callback = pam_reply; pam_reply(preq); return; } else { if (preq->pd->cmd == SSS_PAM_PREAUTH) { DEBUG(SSSDBG_TRACE_FUNC, "User and certificate user do not match, " \ "continue with other authentication methods.\n"); } else { DEBUG(SSSDBG_CRIT_FAILURE, "User and certificate user do not match.\n"); preq->pd->pam_status = PAM_AUTH_ERR; pam_reply(preq); return; } } } if (!NEED_CHECK_PROVIDER(preq->domain->provider) ) { preq->callback = pam_reply; ret = LOCAL_pam_handler(preq); } else { preq->callback = pam_reply; ret = pam_dp_send_req(preq, SSS_CLI_SOCKET_TIMEOUT/2); DEBUG(SSSDBG_CONF_SETTINGS, "pam_dp_send_req returned %d\n", ret); } if (ret != EOK) { preq->pd->pam_status = PAM_SYSTEM_ERR; pam_reply(preq); } } static int pam_cmd_authenticate(struct cli_ctx *cctx) { DEBUG(SSSDBG_CONF_SETTINGS, "entering pam_cmd_authenticate\n"); return pam_forwarder(cctx, SSS_PAM_AUTHENTICATE); } static int pam_cmd_setcred(struct cli_ctx *cctx) { DEBUG(SSSDBG_CONF_SETTINGS, "entering pam_cmd_setcred\n"); return pam_forwarder(cctx, SSS_PAM_SETCRED); } static int pam_cmd_acct_mgmt(struct cli_ctx *cctx) { DEBUG(SSSDBG_CONF_SETTINGS, "entering pam_cmd_acct_mgmt\n"); return pam_forwarder(cctx, SSS_PAM_ACCT_MGMT); } static int pam_cmd_open_session(struct cli_ctx *cctx) { DEBUG(SSSDBG_CONF_SETTINGS, "entering pam_cmd_open_session\n"); return pam_forwarder(cctx, SSS_PAM_OPEN_SESSION); } static int pam_cmd_close_session(struct cli_ctx *cctx) { DEBUG(SSSDBG_CONF_SETTINGS, "entering pam_cmd_close_session\n"); return pam_forwarder(cctx, SSS_PAM_CLOSE_SESSION); } static int pam_cmd_chauthtok(struct cli_ctx *cctx) { DEBUG(SSSDBG_CONF_SETTINGS, "entering pam_cmd_chauthtok\n"); return pam_forwarder(cctx, SSS_PAM_CHAUTHTOK); } static int pam_cmd_chauthtok_prelim(struct cli_ctx *cctx) { DEBUG(SSSDBG_CONF_SETTINGS, "entering pam_cmd_chauthtok_prelim\n"); return pam_forwarder(cctx, SSS_PAM_CHAUTHTOK_PRELIM); } static int pam_cmd_preauth(struct cli_ctx *cctx) { DEBUG(SSSDBG_CONF_SETTINGS, "entering pam_cmd_preauth\n"); return pam_forwarder(cctx, SSS_PAM_PREAUTH); } struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version pam_cli_protocol_version[] = { {3, "2009-09-14", "make cli_pid mandatory"}, {2, "2009-05-12", "new format "}, {1, "2008-09-05", "initial version, \\0 terminated strings"}, {0, NULL, NULL} }; return pam_cli_protocol_version; } struct sss_cmd_table *get_pam_cmds(void) { static struct sss_cmd_table sss_cmds[] = { {SSS_GET_VERSION, sss_cmd_get_version}, {SSS_PAM_AUTHENTICATE, pam_cmd_authenticate}, {SSS_PAM_SETCRED, pam_cmd_setcred}, {SSS_PAM_ACCT_MGMT, pam_cmd_acct_mgmt}, {SSS_PAM_OPEN_SESSION, pam_cmd_open_session}, {SSS_PAM_CLOSE_SESSION, pam_cmd_close_session}, {SSS_PAM_CHAUTHTOK, pam_cmd_chauthtok}, {SSS_PAM_CHAUTHTOK_PRELIM, pam_cmd_chauthtok_prelim}, {SSS_PAM_PREAUTH, pam_cmd_preauth}, {SSS_CLI_NULL, NULL} }; return sss_cmds; } errno_t pam_set_last_online_auth_with_curr_token(struct sss_domain_info *domain, const char *username, uint64_t value) { TALLOC_CTX *tmp_ctx; struct sysdb_attrs *attrs; int ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } attrs = sysdb_new_attrs(tmp_ctx); if (attrs == NULL) { ret = ENOMEM; goto done; } ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_ONLINE_AUTH_WITH_CURR_TOKEN, value); if (ret != EOK) { goto done; } ret = sysdb_set_user_attr(domain, username, attrs, SYSDB_MOD_REP); if (ret != EOK) { goto done; } done: if (ret != EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, sss_strerror(ret)); } talloc_zfree(tmp_ctx); return ret; } static errno_t pam_null_last_online_auth_with_curr_token(struct sss_domain_info *domain, const char *username) { return pam_set_last_online_auth_with_curr_token(domain, username, 0); } static errno_t pam_get_last_online_auth_with_curr_token(struct sss_domain_info *domain, const char *name, uint64_t *_value) { TALLOC_CTX *tmp_ctx = NULL; const char *attrs[] = { SYSDB_LAST_ONLINE_AUTH_WITH_CURR_TOKEN, NULL }; struct ldb_message *ldb_msg; uint64_t value; errno_t ret; if (name == NULL || *name == '\0') { DEBUG(SSSDBG_CRIT_FAILURE, "Missing user name.\n"); ret = EINVAL; goto done; } if (domain->sysdb == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing sysdb db context.\n"); ret = EINVAL; goto done; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { ret = ENOMEM; goto done; } ret = sysdb_search_user_by_name(tmp_ctx, domain, name, attrs, &ldb_msg); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_search_user_by_name failed [%d][%s].\n", ret, strerror(ret)); goto done; } /* Check offline_auth_cache_timeout */ value = ldb_msg_find_attr_as_uint64(ldb_msg, SYSDB_LAST_ONLINE_AUTH_WITH_CURR_TOKEN, 0); ret = EOK; done: if (ret == EOK) { *_value = value; } talloc_free(tmp_ctx); return ret; } sssd-1.13.4/src/responder/pam/PaxHeaders.16287/pamsrv.h0000644000000000000000000000007412703456111017353 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.454792951 sssd-1.13.4/src/responder/pam/pamsrv.h0000644002412700241270000000604712703456111021031 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Sumit Bose Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __PAMSRV_H__ #define __PAMSRV_H__ #include #include "util/util.h" #include "sbus/sssd_dbus.h" #include "responder/common/responder.h" struct pam_auth_req; typedef void (pam_dp_callback_t)(struct pam_auth_req *preq); struct pam_ctx { struct resp_ctx *rctx; struct sss_nc_ctx *ncache; int neg_timeout; time_t id_timeout; hash_table_t *id_table; size_t trusted_uids_count; uid_t *trusted_uids; /* List of domains that are accessible even for untrusted users. */ char **public_domains; int public_domains_count; bool cert_auth; int p11_child_debug_fd; char *nss_db; }; struct pam_auth_dp_req { struct pam_auth_req *preq; }; struct pam_auth_req { struct cli_ctx *cctx; struct sss_domain_info *domain; struct pam_data *pd; pam_dp_callback_t *callback; bool is_uid_trusted; bool check_provider; void *data; bool use_cached_auth; /* whether cached authentication was tried and failed */ bool cached_auth_failed; struct pam_auth_dp_req *dpreq_spy; struct ldb_message *cert_user_obj; char *token_name; }; struct sss_cmd_table *get_pam_cmds(void); int pam_dp_send_req(struct pam_auth_req *preq, int timeout); int LOCAL_pam_handler(struct pam_auth_req *preq); errno_t p11_child_init(struct pam_ctx *pctx); struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int child_debug_fd, const char *nss_db, time_t timeout, const char *verify_opts, struct pam_data *pd); errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **cert, char **token_name); errno_t add_pam_cert_response(struct pam_data *pd, const char *user, const char *token_name); bool may_do_cert_auth(struct pam_ctx *pctx, struct pam_data *pd); errno_t pam_set_last_online_auth_with_curr_token(struct sss_domain_info *domain, const char *username, uint64_t value); #endif /* __PAMSRV_H__ */ sssd-1.13.4/src/responder/pam/PaxHeaders.16287/pamsrv_p11.c0000644000000000000000000000007412703456111020027 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.951794636 sssd-1.13.4/src/responder/pam/pamsrv_p11.c0000644002412700241270000003677612703456111021521 0ustar00jhrozekjhrozek00000000000000/* SSSD PAM Responder - certificate realted requests Copyright (C) Sumit Bose 2015 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" #include "providers/data_provider.h" #include "util/child_common.h" #include "util/strtonum.h" #include "responder/pam/pamsrv.h" #ifndef SSSD_LIBEXEC_PATH #error "SSSD_LIBEXEC_PATH not defined" #endif /* SSSD_LIBEXEC_PATH */ #define P11_CHILD_LOG_FILE "p11_child" #define P11_CHILD_PATH SSSD_LIBEXEC_PATH"/p11_child" errno_t p11_child_init(struct pam_ctx *pctx) { return child_debug_init(P11_CHILD_LOG_FILE, &pctx->p11_child_debug_fd); } bool may_do_cert_auth(struct pam_ctx *pctx, struct pam_data *pd) { size_t c; const char *sc_services[] = { "login", "su", "su-l", "gdm-smartcard", "gdm-password", "kdm", "sudo", "sudo-i", "gnome-screensaver", NULL }; if (!pctx->cert_auth) { return false; } if (pd->cmd != SSS_PAM_PREAUTH && pd->cmd != SSS_PAM_AUTHENTICATE) { return false; } if (pd->cmd == SSS_PAM_AUTHENTICATE && sss_authtok_get_type(pd->authtok) != SSS_AUTHTOK_TYPE_SC_PIN && sss_authtok_get_type(pd->authtok) != SSS_AUTHTOK_TYPE_SC_KEYPAD) { return false; } /* TODO: make services configurable */ if (pd->service == NULL || *pd->service == '\0') { return false; } for (c = 0; sc_services[c] != NULL; c++) { if (strcmp(pd->service, sc_services[c]) == 0) { break; } } if (sc_services[c] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Smartcard authentication for service [%s] not supported.\n", pd->service); return false; } return true; } static errno_t get_p11_child_write_buffer(TALLOC_CTX *mem_ctx, struct pam_data *pd, uint8_t **_buf, size_t *_len) { int ret; uint8_t *buf; size_t len; const char *pin = NULL; if (pd == NULL || pd->authtok == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing authtok.\n"); return EINVAL; } switch (sss_authtok_get_type(pd->authtok)) { case SSS_AUTHTOK_TYPE_SC_PIN: ret = sss_authtok_get_sc_pin(pd->authtok, &pin, &len); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_sc_pin failed.\n"); return ret; } if (pin == NULL || len == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing PIN.\n"); return EINVAL; } buf = talloc_size(mem_ctx, len); if (buf == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); return ENOMEM; } safealign_memcpy(buf, pin, len, NULL); break; case SSS_AUTHTOK_TYPE_SC_KEYPAD: /* Nothing to send */ len = 0; buf = NULL; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported authtok type [%d].\n", sss_authtok_get_type(pd->authtok)); return EINVAL; } *_len = len; *_buf = buf; return EOK; } static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, ssize_t buf_len, char **_cert, char **_token_name) { int ret; TALLOC_CTX *tmp_ctx = NULL; uint8_t *p; uint8_t *pn; char *cert = NULL; char *token_name = NULL; if (buf_len < 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Error occurred while reading data from p11_child.\n"); return EIO; } if (buf_len == 0) { DEBUG(SSSDBG_TRACE_LIBS, "No certificate found.\n"); ret = EOK; goto done; } p = memchr(buf, '\n', buf_len); if (p == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing new-line in p11_child response.\n"); return EINVAL; } if (p == buf) { DEBUG(SSSDBG_OP_FAILURE, "Missing counter in p11_child response.\n"); return EINVAL; } tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); return ENOMEM; } token_name = talloc_strndup(tmp_ctx, (char*) buf, (p - buf)); if (token_name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); ret = ENOMEM; goto done; } p++; pn = memchr(p, '\n', buf_len - (p - buf)); if (pn == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Missing new-line in p11_child response.\n"); ret = EINVAL; goto done; } if (pn == p) { DEBUG(SSSDBG_OP_FAILURE, "Missing cert in p11_child response.\n"); ret = EINVAL; goto done; } cert = talloc_strndup(tmp_ctx, (char *) p, (pn - p)); if(cert == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); ret = ENOMEM; goto done; } DEBUG(SSSDBG_TRACE_ALL, "Found cert [%s].\n", cert); ret = EOK; done: if (ret == EOK) { *_token_name = talloc_steal(mem_ctx, token_name); *_cert = talloc_steal(mem_ctx, cert); } talloc_free(tmp_ctx); return ret; } struct pam_check_cert_state { int child_status; struct sss_child_ctx_old *child_ctx; struct tevent_timer *timeout_handler; struct tevent_context *ev; int write_to_child_fd; int read_from_child_fd; char *cert; char *token_name; }; static void p11_child_write_done(struct tevent_req *subreq); static void p11_child_done(struct tevent_req *subreq); static void p11_child_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt); struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, int child_debug_fd, const char *nss_db, time_t timeout, const char *verify_opts, struct pam_data *pd) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct pam_check_cert_state *state; pid_t child_pid; struct timeval tv; int pipefd_to_child[2]; int pipefd_from_child[2]; const char *extra_args[7] = { NULL }; uint8_t *write_buf = NULL; size_t write_buf_len = 0; size_t arg_c; req = tevent_req_create(mem_ctx, &state, struct pam_check_cert_state); if (req == NULL) { return NULL; } if (nss_db == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing NSS DB.\n"); ret = EINVAL; goto done; } /* extra_args are added in revers order */ arg_c = 0; extra_args[arg_c++] = nss_db; extra_args[arg_c++] = "--nssdb"; if (verify_opts != NULL) { extra_args[arg_c++] = verify_opts; extra_args[arg_c++] = "--verify"; } if (pd->cmd == SSS_PAM_AUTHENTICATE) { extra_args[arg_c++] = "--auth"; switch (sss_authtok_get_type(pd->authtok)) { case SSS_AUTHTOK_TYPE_SC_PIN: extra_args[arg_c++] = "--pin"; break; case SSS_AUTHTOK_TYPE_SC_KEYPAD: extra_args[arg_c++] = "--keypad"; break; default: DEBUG(SSSDBG_OP_FAILURE, "Unsupported authtok type.\n"); ret = EINVAL; goto done; } } else if (pd->cmd == SSS_PAM_PREAUTH) { extra_args[arg_c++] = "--pre"; } else { DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected PAM command [%d}.\n", pd->cmd); ret = EINVAL; goto done; } state->ev = ev; state->child_status = EFAULT; state->read_from_child_fd = -1; state->write_to_child_fd = -1; state->cert = NULL; state->token_name = NULL; ret = pipe(pipefd_from_child); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", ret, strerror(ret)); goto done; } ret = pipe(pipefd_to_child); if (ret == -1) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "pipe failed [%d][%s].\n", ret, strerror(ret)); goto done; } if (child_debug_fd == -1) { child_debug_fd = STDERR_FILENO; } child_pid = fork(); if (child_pid == 0) { /* child */ ret = exec_child_ex(state, pipefd_to_child, pipefd_from_child, P11_CHILD_PATH, child_debug_fd, extra_args, false, STDIN_FILENO, STDOUT_FILENO); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec p11 child: [%d][%s].\n", ret, strerror(ret)); goto done; } } else if (child_pid > 0) { /* parent */ state->read_from_child_fd = pipefd_from_child[0]; close(pipefd_from_child[1]); sss_fd_nonblocking(state->read_from_child_fd); state->write_to_child_fd = pipefd_to_child[1]; close(pipefd_to_child[0]); sss_fd_nonblocking(state->write_to_child_fd); /* Set up SIGCHLD handler */ ret = child_handler_setup(ev, child_pid, NULL, NULL, &state->child_ctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not set up child handlers [%d]: %s\n", ret, sss_strerror(ret)); ret = ERR_P11_CHILD; goto done; } /* Set up timeout handler */ tv = tevent_timeval_current_ofs(timeout, 0); state->timeout_handler = tevent_add_timer(ev, req, tv, p11_child_timeout, req); if(state->timeout_handler == NULL) { ret = ERR_P11_CHILD; goto done; } if (pd->cmd == SSS_PAM_AUTHENTICATE) { ret = get_p11_child_write_buffer(state, pd, &write_buf, &write_buf_len); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_p11_child_write_buffer failed.\n"); goto done; } } if (write_buf_len != 0) { subreq = write_pipe_send(state, ev, write_buf, write_buf_len, state->write_to_child_fd); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "write_pipe_send failed.\n"); ret = ERR_P11_CHILD; goto done; } tevent_req_set_callback(subreq, p11_child_write_done, req); } else { subreq = read_pipe_send(state, ev, state->read_from_child_fd); if (subreq == NULL) { DEBUG(SSSDBG_OP_FAILURE, "read_pipe_send failed.\n"); ret = ERR_P11_CHILD; goto done; } tevent_req_set_callback(subreq, p11_child_done, req); } /* Now either wait for the timeout to fire or the child * to finish */ } else { /* error */ ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n", ret, sss_strerror(ret)); goto done; } ret = EOK; done: if (ret != EOK) { tevent_req_error(req, ret); tevent_req_post(req, ev); } return req; } static void p11_child_write_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct pam_check_cert_state *state = tevent_req_data(req, struct pam_check_cert_state); int ret; ret = write_pipe_recv(subreq); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } close(state->write_to_child_fd); state->write_to_child_fd = -1; subreq = read_pipe_send(state, state->ev, state->read_from_child_fd); if (subreq == NULL) { tevent_req_error(req, ENOMEM); return; } tevent_req_set_callback(subreq, p11_child_done, req); } static void p11_child_done(struct tevent_req *subreq) { uint8_t *buf; ssize_t buf_len; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct pam_check_cert_state *state = tevent_req_data(req, struct pam_check_cert_state); int ret; talloc_zfree(state->timeout_handler); ret = read_pipe_recv(subreq, state, &buf, &buf_len); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } close(state->read_from_child_fd); state->read_from_child_fd = -1; ret = parse_p11_child_response(state, buf, buf_len, &state->cert, &state->token_name); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "parse_p11_child_respose failed.\n"); tevent_req_error(req, ret); return; } tevent_req_done(req); return; } static void p11_child_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *pvt) { struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); struct pam_check_cert_state *state = tevent_req_data(req, struct pam_check_cert_state); DEBUG(SSSDBG_CRIT_FAILURE, "Timeout reached for p11_child.\n"); child_handler_destroy(state->child_ctx); state->child_ctx = NULL; state->child_status = ETIMEDOUT; tevent_req_error(req, ERR_P11_CHILD); } errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **cert, char **token_name) { struct pam_check_cert_state *state = tevent_req_data(req, struct pam_check_cert_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (cert != NULL) { *cert = talloc_steal(mem_ctx, state->cert); } if (token_name != NULL) { *token_name = talloc_steal(mem_ctx, state->token_name); } return EOK; } errno_t add_pam_cert_response(struct pam_data *pd, const char *user, const char *token_name) { uint8_t *msg = NULL; size_t user_len; size_t msg_len; size_t slot_len; int ret; if (user == NULL || token_name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing mandatory user or slot name.\n"); return EINVAL; } user_len = strlen(user) + 1; slot_len = strlen(token_name) + 1; msg_len = user_len + slot_len; msg = talloc_zero_size(pd, msg_len); if (msg == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n"); return ENOMEM; } memcpy(msg, user, user_len); memcpy(msg + user_len, token_name, slot_len); ret = pam_add_response(pd, SSS_PAM_CERT_INFO, msg_len, msg); talloc_free(msg); return ret; } sssd-1.13.4/src/responder/pam/PaxHeaders.16287/pam_LOCAL_domain.c0000644000000000000000000000007412703456111021054 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.954794646 sssd-1.13.4/src/responder/pam/pam_LOCAL_domain.c0000644002412700241270000002614712703456111022535 0ustar00jhrozekjhrozek00000000000000/* SSSD PAM e credentials Copyright (C) Sumit Bose 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/util.h" #include "db/sysdb.h" #include "util/crypto/sss_crypto.h" #include "providers/data_provider.h" #include "responder/pam/pamsrv.h" #define NULL_CHECK_OR_JUMP(var, msg, ret, err, label) do { \ if (var == NULL) { \ DEBUG(SSSDBG_CRIT_FAILURE, msg); \ ret = (err); \ goto label; \ } \ } while(0) #define NEQ_CHECK_OR_JUMP(var, val, msg, ret, err, label) do { \ if (var != (val)) { \ DEBUG(SSSDBG_CRIT_FAILURE, msg); \ ret = (err); \ goto label; \ } \ } while(0) struct LOCAL_request { struct tevent_context *ev; struct sysdb_ctx *dbctx; struct sss_domain_info *domain; struct sysdb_attrs *mod_attrs; struct ldb_result *res; int error; struct pam_auth_req *preq; }; static void prepare_reply(struct LOCAL_request *lreq) { struct pam_data *pd; pd = lreq->preq->pd; if (lreq->error != EOK && pd->pam_status == PAM_SUCCESS) pd->pam_status = PAM_SYSTEM_ERR; lreq->preq->callback(lreq->preq); } static void do_successful_login(struct LOCAL_request *lreq) { int ret; lreq->mod_attrs = sysdb_new_attrs(lreq); NULL_CHECK_OR_JUMP(lreq->mod_attrs, ("sysdb_new_attrs failed.\n"), lreq->error, ENOMEM, done); ret = sysdb_attrs_add_long(lreq->mod_attrs, SYSDB_LAST_LOGIN, (long)time(NULL)); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); ret = sysdb_attrs_add_long(lreq->mod_attrs, SYSDB_FAILED_LOGIN_ATTEMPTS, 0L); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); ret = sysdb_set_user_attr(lreq->domain, lreq->preq->pd->user, lreq->mod_attrs, SYSDB_MOD_REP); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_set_user_attr failed.\n"), lreq->error, ret, done); done: return; } static void do_failed_login(struct LOCAL_request *lreq) { int ret; int failedLoginAttempts; struct pam_data *pd; pd = lreq->preq->pd; pd->pam_status = PAM_AUTH_ERR; /* TODO: maybe add more inteligent delay calculation */ pd->response_delay = 3; lreq->mod_attrs = sysdb_new_attrs(lreq); NULL_CHECK_OR_JUMP(lreq->mod_attrs, ("sysdb_new_attrs failed.\n"), lreq->error, ENOMEM, done); ret = sysdb_attrs_add_long(lreq->mod_attrs, SYSDB_LAST_FAILED_LOGIN, (long)time(NULL)); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); failedLoginAttempts = ldb_msg_find_attr_as_int(lreq->res->msgs[0], SYSDB_FAILED_LOGIN_ATTEMPTS, 0); failedLoginAttempts++; ret = sysdb_attrs_add_long(lreq->mod_attrs, SYSDB_FAILED_LOGIN_ATTEMPTS, (long)failedLoginAttempts); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); ret = sysdb_set_user_attr(lreq->domain, lreq->preq->pd->user, lreq->mod_attrs, SYSDB_MOD_REP); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_set_user_attr failed.\n"), lreq->error, ret, done); done: return; } static void do_pam_acct_mgmt(struct LOCAL_request *lreq) { const char *disabled; struct pam_data *pd; pd = lreq->preq->pd; disabled = ldb_msg_find_attr_as_string(lreq->res->msgs[0], SYSDB_DISABLED, NULL); if ((disabled != NULL) && (strncasecmp(disabled, "false",5) != 0) && (strncasecmp(disabled, "no",2) != 0) ) { pd->pam_status = PAM_PERM_DENIED; } } static void do_pam_chauthtok(struct LOCAL_request *lreq) { int ret; const char *password; char *salt; char *new_hash; struct pam_data *pd; pd = lreq->preq->pd; ret = sss_authtok_get_password(pd->newauthtok, &password, NULL); if (ret) { /* TODO: should we allow null passwords via a config option ? */ if (ret == ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Empty passwords are not allowed!\n"); } lreq->error = EINVAL; goto done; } ret = s3crypt_gen_salt(lreq, &salt); NEQ_CHECK_OR_JUMP(ret, EOK, ("Salt generation failed.\n"), lreq->error, ret, done); DEBUG(SSSDBG_CONF_SETTINGS, "Using salt [%s]\n", salt); ret = s3crypt_sha512(lreq, password, salt, &new_hash); NEQ_CHECK_OR_JUMP(ret, EOK, ("Hash generation failed.\n"), lreq->error, ret, done); DEBUG(SSSDBG_CONF_SETTINGS, "New hash [%s]\n", new_hash); lreq->mod_attrs = sysdb_new_attrs(lreq); NULL_CHECK_OR_JUMP(lreq->mod_attrs, ("sysdb_new_attrs failed.\n"), lreq->error, ENOMEM, done); ret = sysdb_attrs_add_string(lreq->mod_attrs, SYSDB_PWD, new_hash); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_string failed.\n"), lreq->error, ret, done); ret = sysdb_attrs_add_long(lreq->mod_attrs, "lastPasswordChange", (long)time(NULL)); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_attrs_add_long failed.\n"), lreq->error, ret, done); ret = sysdb_set_user_attr(lreq->domain, lreq->preq->pd->user, lreq->mod_attrs, SYSDB_MOD_REP); NEQ_CHECK_OR_JUMP(ret, EOK, ("sysdb_set_user_attr failed.\n"), lreq->error, ret, done); done: sss_authtok_set_empty(pd->newauthtok); } int LOCAL_pam_handler(struct pam_auth_req *preq) { struct LOCAL_request *lreq; static const char *attrs[] = {SYSDB_NAME, SYSDB_PWD, SYSDB_DISABLED, SYSDB_LAST_LOGIN, "lastPasswordChange", "accountExpires", SYSDB_FAILED_LOGIN_ATTEMPTS, "passwordHint", "passwordHistory", SYSDB_LAST_FAILED_LOGIN, NULL}; struct ldb_result *res; const char *username = NULL; const char *pwdhash = NULL; char *new_hash = NULL; const char *password; struct pam_data *pd = preq->pd; int ret; DEBUG(SSSDBG_CONF_SETTINGS, "LOCAL pam handler.\n"); lreq = talloc_zero(preq, struct LOCAL_request); if (!lreq) { return ENOMEM; } lreq->dbctx = preq->domain->sysdb; if (lreq->dbctx == NULL) { DEBUG(SSSDBG_FATAL_FAILURE, "Fatal: Sysdb CTX not found for this domain!\n"); talloc_free(lreq); return ENOENT; } lreq->domain = preq->domain; lreq->ev = preq->cctx->ev; lreq->preq = preq; pd->pam_status = PAM_SUCCESS; ret = sysdb_get_user_attr(lreq, preq->domain, preq->pd->user, attrs, &res); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_get_user_attr failed.\n"); talloc_free(lreq); return ret; } if (res->count < 1) { DEBUG(SSSDBG_CONF_SETTINGS, "No user found with filter ["SYSDB_PWNAM_FILTER"]\n", pd->user, pd->user, pd->user); pd->pam_status = PAM_USER_UNKNOWN; goto done; } else if (res->count > 1) { DEBUG(SSSDBG_CONF_SETTINGS, "More than one object found with filter ["SYSDB_PWNAM_FILTER"]\n", pd->user, pd->user, pd->user); lreq->error = EFAULT; goto done; } username = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); if (strcmp(username, pd->user) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Expected username [%s] get [%s].\n", pd->user, username); lreq->error = EINVAL; goto done; } lreq->res = res; switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: case SSS_PAM_CHAUTHTOK: case SSS_PAM_CHAUTHTOK_PRELIM: if ((pd->cmd == SSS_PAM_CHAUTHTOK || pd->cmd == SSS_PAM_CHAUTHTOK_PRELIM) && lreq->preq->cctx->priv == 1) { /* TODO: maybe this is a candiate for an explicit audit message. */ DEBUG(SSSDBG_CONF_SETTINGS, "allowing root to reset a password.\n"); break; } ret = sss_authtok_get_password(pd->authtok, &password, NULL); NEQ_CHECK_OR_JUMP(ret, EOK, ("Failed to get password.\n"), lreq->error, ret, done); pwdhash = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_PWD, NULL); NULL_CHECK_OR_JUMP(pwdhash, ("No password stored.\n"), lreq->error, LDB_ERR_NO_SUCH_ATTRIBUTE, done); DEBUG(SSSDBG_CONF_SETTINGS, "user: [%s], password hash: [%s]\n", username, pwdhash); ret = s3crypt_sha512(lreq, password, pwdhash, &new_hash); NEQ_CHECK_OR_JUMP(ret, EOK, ("nss_sha512_crypt failed.\n"), lreq->error, ret, done); DEBUG(SSSDBG_CONF_SETTINGS, "user: [%s], new hash: [%s]\n", username, new_hash); if (strcmp(new_hash, pwdhash) != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Passwords do not match.\n"); do_failed_login(lreq); goto done; } break; } switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: do_successful_login(lreq); break; case SSS_PAM_CHAUTHTOK: do_pam_chauthtok(lreq); break; case SSS_PAM_ACCT_MGMT: do_pam_acct_mgmt(lreq); break; case SSS_PAM_SETCRED: break; case SSS_PAM_OPEN_SESSION: break; case SSS_PAM_CLOSE_SESSION: break; case SSS_PAM_CHAUTHTOK_PRELIM: break; default: lreq->error = EINVAL; DEBUG(SSSDBG_CRIT_FAILURE, "Unknown PAM task [%d].\n", pd->cmd); } done: sss_authtok_set_empty(pd->newauthtok); sss_authtok_set_empty(pd->authtok); prepare_reply(lreq); return EOK; } sssd-1.13.4/src/responder/pam/PaxHeaders.16287/pamsrv.c0000644000000000000000000000007412703456111017346 xustar0030 atime=1460561751.652715634 30 ctime=1460561775.013794846 sssd-1.13.4/src/responder/pam/pamsrv.c0000644002412700241270000003146012703456111021021 0ustar00jhrozekjhrozek00000000000000/* SSSD PAM Responder Copyright (C) Simo Sorce 2009 Copyright (C) Sumit Bose 2009 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "db/sysdb.h" #include "confdb/confdb.h" #include "sbus/sssd_dbus.h" #include "responder/common/responder_packet.h" #include "providers/data_provider.h" #include "monitor/monitor_interfaces.h" #include "sbus/sbus_client.h" #include "responder/pam/pamsrv.h" #include "responder/common/negcache.h" #include "responder/common/responder_sbus.h" #define DEFAULT_PAM_FD_LIMIT 8192 #define ALL_UIDS_ALLOWED "all" #define ALL_DOMAIMS_ARE_PUBLIC "all" #define NO_DOMAIMS_ARE_PUBLIC "none" #define DEFAULT_ALLOWED_UIDS ALL_UIDS_ALLOWED #define DEFAULT_PAM_CERT_AUTH false #define DEFAULT_PAM_CERT_DB_PATH SYSCONFDIR"/pki/nssdb" struct mon_cli_iface monitor_pam_methods = { { &mon_cli_iface_meta, 0 }, .ping = monitor_common_pong, .resInit = monitor_common_res_init, .shutDown = NULL, .goOffline = NULL, .resetOffline = NULL, .rotateLogs = responder_logrotate, .clearMemcache = NULL, .clearEnumCache = NULL, .sysbusReconnect = NULL, }; static struct data_provider_iface pam_dp_methods = { { &data_provider_iface_meta, 0 }, .RegisterService = NULL, .pamHandler = NULL, .sudoHandler = NULL, .autofsHandler = NULL, .hostHandler = NULL, .getDomains = NULL, .getAccountInfo = NULL, }; static void pam_dp_reconnect_init(struct sbus_connection *conn, int status, void *pvt) { struct be_conn *be_conn = talloc_get_type(pvt, struct be_conn); int ret; /* Did we reconnect successfully? */ if (status == SBUS_RECONNECT_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Reconnected to the Data Provider.\n"); /* Identify ourselves to the data provider */ ret = dp_common_send_id(be_conn->conn, DATA_PROVIDER_VERSION, "PAM"); /* all fine */ if (ret == EOK) { handle_requests_after_reconnect(be_conn->rctx); return; } } /* Handle failure */ DEBUG(SSSDBG_FATAL_FAILURE, "Could not reconnect to %s provider.\n", be_conn->domain->name); /* FIXME: kill the frontend and let the monitor restart it ? */ /* pam_shutdown(rctx); */ } static errno_t get_trusted_uids(struct pam_ctx *pctx) { char *uid_str; errno_t ret; ret = confdb_get_string(pctx->rctx->cdb, pctx->rctx, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_TRUSTED_USERS, DEFAULT_ALLOWED_UIDS, &uid_str); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get allowed UIDs.\n"); goto done; } if (strcmp(uid_str, ALL_UIDS_ALLOWED) == 0) { DEBUG(SSSDBG_TRACE_FUNC, "All UIDs are allowed.\n"); pctx->trusted_uids_count = 0; } else { ret = csv_string_to_uid_array(pctx->rctx, uid_str, true, &pctx->trusted_uids_count, &pctx->trusted_uids); } talloc_free(uid_str); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set allowed UIDs.\n"); goto done; } done: return ret; } static errno_t get_public_domains(TALLOC_CTX *mem_ctx, struct pam_ctx *pctx) { char *domains_str = NULL; errno_t ret; ret = confdb_get_string(pctx->rctx->cdb, pctx->rctx, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_PUBLIC_DOMAINS, NO_DOMAIMS_ARE_PUBLIC, &domains_str); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get allowed UIDs.\n"); goto done; } if (strcmp(domains_str, ALL_DOMAIMS_ARE_PUBLIC) == 0) { /* all */ /* copy all domains */ ret = get_dom_names(mem_ctx, pctx->rctx->domains, &pctx->public_domains, &pctx->public_domains_count); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "get_dom_names failed.\n"); goto done; } } else if (strcmp(domains_str, NO_DOMAIMS_ARE_PUBLIC) == 0) { /* none */ pctx->public_domains = NULL; pctx->public_domains_count = 0; } else { ret = split_on_separator(mem_ctx, domains_str, ',', true, false, &pctx->public_domains, &pctx->public_domains_count); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "split_on_separator failed [%d][%s].\n", ret, strerror(ret)); goto done; } } ret = EOK; done: talloc_free(domains_str); return ret; } static int pam_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb, int pipe_fd, int priv_pipe_fd) { struct resp_ctx *rctx; struct sss_cmd_table *pam_cmds; struct be_conn *iter; struct pam_ctx *pctx; int ret, max_retries; int id_timeout; int fd_limit; pam_cmds = get_pam_cmds(); ret = sss_process_init(mem_ctx, ev, cdb, pam_cmds, SSS_PAM_SOCKET_NAME, pipe_fd, SSS_PAM_PRIV_SOCKET_NAME, priv_pipe_fd, CONFDB_PAM_CONF_ENTRY, SSS_PAM_SBUS_SERVICE_NAME, SSS_PAM_SBUS_SERVICE_VERSION, &monitor_pam_methods, "PAM", &pam_dp_methods.vtable, &rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "sss_process_init() failed\n"); return ret; } pctx = talloc_zero(rctx, struct pam_ctx); if (!pctx) { ret = ENOMEM; goto done; } pctx->rctx = rctx; pctx->rctx->pvt_ctx = pctx; ret = get_trusted_uids(pctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "get_trusted_uids failed: %d:[%s].\n", ret, sss_strerror(ret)); goto done; } ret = get_public_domains(pctx, pctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "get_public_domains failed: %d:[%s].\n", ret, sss_strerror(ret)); goto done; } /* Enable automatic reconnection to the Data Provider */ /* FIXME: "retries" is too generic, either get it from a global config * or specify these retries are about the sbus connections to DP */ ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_SERVICE_RECON_RETRIES, 3, &max_retries); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up automatic reconnection\n"); goto done; } for (iter = pctx->rctx->be_conns; iter; iter = iter->next) { sbus_reconnect_init(iter->conn, max_retries, pam_dp_reconnect_init, iter); } /* Set up the negative cache */ ret = confdb_get_int(cdb, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_ENTRY_NEG_TIMEOUT, 15, &pctx->neg_timeout); if (ret != EOK) goto done; /* Set up the PAM identity timeout */ ret = confdb_get_int(cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_ID_TIMEOUT, 5, &id_timeout); if (ret != EOK) goto done; pctx->id_timeout = (size_t)id_timeout; ret = sss_ncache_init(pctx, &pctx->ncache); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing negative cache\n"); goto done; } ret = sss_ncache_prepopulate(pctx->ncache, cdb, pctx->rctx); if (ret != EOK) { goto done; } /* Create table for initgroup lookups */ ret = sss_hash_create(pctx, 10, &pctx->id_table); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not create initgroups hash table: [%s]\n", strerror(ret)); goto done; } /* Set up file descriptor limits */ ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_SERVICE_FD_LIMIT, DEFAULT_PAM_FD_LIMIT, &fd_limit); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to set up file descriptor limit\n"); goto done; } responder_set_fd_limit(fd_limit); ret = schedule_get_domains_task(rctx, rctx->ev, rctx, pctx->ncache); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "schedule_get_domains_tasks failed.\n"); goto done; } /* Check if certificate based authentication is enabled */ ret = confdb_get_bool(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_CERT_AUTH, DEFAULT_PAM_CERT_AUTH, &pctx->cert_auth); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to determine get cert db path.\n"); goto done; } pctx->p11_child_debug_fd = -1; if (pctx->cert_auth) { ret = p11_child_init(pctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "p11_child_init failed.\n"); goto done; } ret = confdb_get_string(pctx->rctx->cdb, pctx, CONFDB_PAM_CONF_ENTRY, CONFDB_PAM_CERT_DB_PATH, DEFAULT_PAM_CERT_DB_PATH, &pctx->nss_db); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to determine if certificate based authentication is " \ "enabled or not.\n"); goto done; } } ret = EOK; done: if (ret != EOK) { talloc_free(rctx); } return ret; } int main(int argc, const char *argv[]) { int opt; poptContext pc; struct main_context *main_ctx; int ret; uid_t uid; gid_t gid; int pipe_fd; int priv_pipe_fd; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_MAIN_OPTS SSSD_SERVER_OPTS(uid, gid) POPT_TABLEEND }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ debug_level = SSSDBG_INVALID; umask(DFL_RSP_UMASK); pc = poptGetContext(argv[0], argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } poptFreeContext(pc); DEBUG_INIT(debug_level); /* set up things like debug, signals, daemonization, etc... */ debug_log_file = "sssd_pam"; /* Crate pipe file descriptors here before privileges are dropped * in server_setup() */ ret = create_pipe_fd(SSS_PAM_SOCKET_NAME, &pipe_fd, 0111); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "create_pipe_fd failed [%d]: %s.\n", ret, sss_strerror(ret)); return 2; } ret = create_pipe_fd(SSS_PAM_PRIV_SOCKET_NAME, &priv_pipe_fd, 0177); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "create_pipe_fd failed (priviledged pipe) [%d]: %s.\n", ret, sss_strerror(ret)); return 2; } ret = server_setup("sssd[pam]", 0, uid, gid, CONFDB_PAM_CONF_ENTRY, &main_ctx); if (ret != EOK) return 2; ret = die_if_parent_died(); if (ret != EOK) { /* This is not fatal, don't return */ DEBUG(SSSDBG_OP_FAILURE, "Could not set up to exit when parent process does\n"); } ret = pam_process_init(main_ctx, main_ctx->event_ctx, main_ctx->confdb_ctx, pipe_fd, priv_pipe_fd); if (ret != EOK) return 3; /* loop on main */ server_loop(main_ctx); return 0; } sssd-1.13.4/src/responder/pam/PaxHeaders.16287/pam_helpers.h0000644000000000000000000000007412703456111020342 xustar0030 atime=1460561751.652715634 30 ctime=1460561774.456792957 sssd-1.13.4/src/responder/pam/pam_helpers.h0000644002412700241270000000244612703456111022017 0ustar00jhrozekjhrozek00000000000000/* SSSD Authors: Stephen Gallagher Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef PAM_HELPERS_H_ #define PAM_HELPERS_H_ #include "util/util.h" errno_t pam_initgr_cache_set(struct tevent_context *ev, hash_table_t *id_table, char *name, long timeout); /* Returns EOK if the cache is still valid * Returns ENOENT if the user is not found or is expired * May report other errors if the hash lookup fails. */ errno_t pam_initgr_check_timeout(hash_table_t *id_table, char *name); #endif /* PAM_HELPERS_H_ */ sssd-1.13.4/src/responder/PaxHeaders.16287/common0000644000000000000000000000013212703463556016336 xustar0030 mtime=1460561774.998794795 30 atime=1460561776.119798596 30 ctime=1460561774.998794795 sssd-1.13.4/src/responder/common/0000755002412700241270000000000012703463556020067 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/responder/common/PaxHeaders.16287/responder.h0000644000000000000000000000007312703456111020556 xustar0030 atime=1460561751.650715627 29 ctime=1460561774.44879293 sssd-1.13.4/src/responder/common/responder.h0000644002412700241270000002360412703456111022233 0ustar00jhrozekjhrozek00000000000000/* SSSD SSS Client Responder, header file Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSS_RESPONDER_H__ #define __SSS_RESPONDER_H__ #include "config.h" #include #include #include #include #include #include #include #include #include "sbus/sssd_dbus.h" #include "responder/common/negcache.h" #include "sss_client/sss_cli.h" extern hash_table_t *dp_requests; /* we want default permissions on created files to be very strict, * so set our umask to 0177 */ #define DFL_RSP_UMASK 0177 /* if there is a provider other than the special local */ #define NEED_CHECK_PROVIDER(provider) \ (provider != NULL && strcmp(provider, "local") != 0) /* needed until nsssrv.h is updated */ struct cli_request { /* original request from the wire */ struct sss_packet *in; /* reply data */ struct sss_packet *out; }; struct cli_protocol_version { uint32_t version; const char *date; const char *description; }; struct resp_ctx; struct be_conn { struct be_conn *next; struct be_conn *prev; struct resp_ctx *rctx; const char *cli_name; struct sss_domain_info *domain; char *sbus_address; struct sbus_connection *conn; }; struct resp_ctx { struct tevent_context *ev; struct tevent_fd *lfde; int lfd; struct tevent_fd *priv_lfde; int priv_lfd; struct confdb_ctx *cdb; const char *sock_name; const char *priv_sock_name; struct sbus_connection *mon_conn; struct be_conn *be_conns; struct sss_domain_info *domains; int domains_timeout; int client_idle_timeout; struct sss_cmd_table *sss_cmds; const char *sss_pipe_name; const char *confdb_service_path; hash_table_t *dp_request_table; struct timeval get_domains_last_call; size_t allowed_uids_count; uid_t *allowed_uids; char *default_domain; char override_space; void *pvt_ctx; bool shutting_down; }; struct cli_ctx { struct tevent_context *ev; struct resp_ctx *rctx; int cfd; struct tevent_fd *cfde; struct sockaddr_un addr; struct cli_request *creq; struct cli_protocol_version *cli_protocol_version; int priv; int32_t client_euid; int32_t client_egid; int32_t client_pid; int pwent_dom_idx; int pwent_cur; int grent_dom_idx; int grent_cur; int svc_dom_idx; int svcent_cur; char *netgr_name; int netgrent_cur; char *automntmap_name; struct tevent_timer *idle; }; struct sss_cmd_table { enum sss_cli_command cmd; int (*fn)(struct cli_ctx *cctx); }; /* from generated code */ struct mon_cli_iface; /* * responder_common.c * * NOTE: We would like to use more strong typing for the @dp_vtable argument * but can't since it accepts either a struct data_provider_iface * or struct data_provider_rev_iface. So pass the base struct: sbus_vtable */ int sss_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb, struct sss_cmd_table sss_cmds[], const char *sss_pipe_name, int pipe_fd, const char *sss_priv_pipe_name, int priv_pipe_fd, const char *confdb_service_path, const char *svc_name, uint16_t svc_version, struct mon_cli_iface *monitor_intf, const char *cli_name, struct sbus_vtable *dp_intf, struct resp_ctx **responder_ctx); int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain, struct be_conn **_conn); struct sss_domain_info * responder_get_domain(struct resp_ctx *rctx, const char *domain); errno_t responder_get_domain_by_id(struct resp_ctx *rctx, const char *id, struct sss_domain_info **_ret_dom); int create_pipe_fd(const char *sock_name, int *_fd, mode_t umaskval); /* responder_cmd.c */ int sss_cmd_empty_packet(struct sss_packet *packet); int sss_cmd_send_empty(struct cli_ctx *cctx, TALLOC_CTX *freectx); int sss_cmd_send_error(struct cli_ctx *cctx, int err); void sss_cmd_done(struct cli_ctx *cctx, void *freectx); int sss_cmd_get_version(struct cli_ctx *cctx); int sss_cmd_execute(struct cli_ctx *cctx, enum sss_cli_command cmd, struct sss_cmd_table *sss_cmds); struct cli_protocol_version *register_cli_protocol_version(void); struct setent_req_list; /* A facility for notifying setent requests */ struct tevent_req *setent_get_req(struct setent_req_list *sl); errno_t setent_add_ref(TALLOC_CTX *memctx, void *pvt, struct setent_req_list **list, struct tevent_req *req); void setent_notify(struct setent_req_list **list, errno_t err); void setent_notify_done(struct setent_req_list **list); errno_t sss_cmd_check_cache(struct ldb_message *msg, int cache_refresh_percent, uint64_t cache_expire); typedef void (*sss_dp_callback_t)(uint16_t err_maj, uint32_t err_min, const char *err_msg, void *ptr); struct dp_callback_ctx { sss_dp_callback_t callback; void *ptr; void *mem_ctx; struct cli_ctx *cctx; }; void handle_requests_after_reconnect(struct resp_ctx *rctx); int responder_logrotate(struct sbus_request *dbus_req, void *data); /* Each responder-specific request must create a constructor * function that creates a DBus Message that would be sent to * the back end */ typedef DBusMessage * (dbus_msg_constructor)(void *); /* * This function is indended for consumption by responders to create * responder-specific requests such as sss_dp_get_account_send for * downloading account data. * * Issues a new back end request based on strkey if not already running * or registers a callback that is called when an existing request finishes. */ errno_t sss_dp_issue_request(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, const char *strkey, struct sss_domain_info *dom, dbus_msg_constructor msg_create, void *pvt, struct tevent_req *nreq); /* Every provider specific request uses this structure as the tevent_req * "state" structure. */ struct sss_dp_req_state { dbus_uint16_t dp_err; dbus_uint32_t dp_ret; char *err_msg; }; /* The _recv functions of provider specific requests usually need to * only call sss_dp_req_recv() to get return codes from back end */ errno_t sss_dp_req_recv(TALLOC_CTX *mem_ctx, struct tevent_req *sidereq, dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret, char **err_msg); /* Send a request to the data provider * Once this function is called, the communication * with the data provider will always run to * completion. Freeing the returned tevent_req will * cancel the notification of completion, but not * the data provider action. */ enum sss_dp_acct_type { SSS_DP_USER = 1, SSS_DP_GROUP, SSS_DP_INITGROUPS, SSS_DP_NETGR, SSS_DP_SERVICES, SSS_DP_SECID, SSS_DP_USER_AND_GROUP, SSS_DP_CERT, SSS_DP_WILDCARD_USER, SSS_DP_WILDCARD_GROUP, }; struct tevent_req * sss_dp_get_account_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, bool fast_reply, enum sss_dp_acct_type type, const char *opt_name, uint32_t opt_id, const char *extra); errno_t sss_dp_get_account_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, dbus_uint16_t *err_maj, dbus_uint32_t *err_min, char **err_msg); bool sss_utf8_check(const uint8_t *s, size_t n); void responder_set_fd_limit(rlim_t fd_limit); #define GET_DOMAINS_DEFAULT_TIMEOUT 60 struct tevent_req *sss_dp_get_domains_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, bool force, const char *hint); errno_t sss_dp_get_domains_recv(struct tevent_req *req); errno_t schedule_get_domains_task(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *optional_ncache); errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *csv_string, bool allow_sss_loop, size_t *_uid_count, uid_t **_uids); errno_t check_allowed_uids(uid_t uid, size_t allowed_uids_count, uid_t *allowed_uids); struct tevent_req * sss_parse_inp_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, const char *rawinp); errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **_name, char **_domname); const char **parse_attr_list_ex(TALLOC_CTX *mem_ctx, const char *conf_str, const char **defaults); #endif /* __SSS_RESPONDER_H__ */ sssd-1.13.4/src/responder/common/PaxHeaders.16287/responder_cmd.c0000644000000000000000000000007412703456111021375 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.925794548 sssd-1.13.4/src/responder/common/responder_cmd.c0000644002412700241270000001753112703456111023053 0ustar00jhrozekjhrozek00000000000000/* SSSD SSS Client Responder, command parser Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "db/sysdb.h" #include "util/util.h" #include "responder/common/responder.h" #include "responder/common/responder_packet.h" int sss_cmd_send_error(struct cli_ctx *cctx, int err) { int ret; /* create response packet */ ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create new packet: %d\n", ret); return ret; } sss_packet_set_error(cctx->creq->out, err); return EOK; } int sss_cmd_empty_packet(struct sss_packet *packet) { uint8_t *body; size_t blen; int ret; ret = sss_packet_grow(packet, 2*sizeof(uint32_t)); if (ret != EOK) return ret; sss_packet_get_body(packet, &body, &blen); /* num results */ SAFEALIGN_SETMEM_UINT32(body, 0, NULL); /* reserved */ SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), 0, NULL); return EOK; } int sss_cmd_send_empty(struct cli_ctx *cctx, TALLOC_CTX *freectx) { int ret; /* create response packet */ ret = sss_packet_new(cctx->creq, 0, sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return ret; } ret = sss_cmd_empty_packet(cctx->creq->out); if (ret != EOK) { return ret; } sss_packet_set_error(cctx->creq->out, EOK); sss_cmd_done(cctx, freectx); return EOK; } void sss_cmd_done(struct cli_ctx *cctx, void *freectx) { /* now that the packet is in place, unlock queue * making the event writable */ TEVENT_FD_WRITEABLE(cctx->cfde); /* free all request related data through the talloc hierarchy */ talloc_free(freectx); } int sss_cmd_get_version(struct cli_ctx *cctx) { uint8_t *req_body; size_t req_blen; uint8_t *body; size_t blen; int ret; uint32_t client_version; uint32_t protocol_version; int i; static struct cli_protocol_version *cli_protocol_version = NULL; cctx->cli_protocol_version = NULL; if (cli_protocol_version == NULL) { cli_protocol_version = register_cli_protocol_version(); } if (cli_protocol_version != NULL) { cctx->cli_protocol_version = &cli_protocol_version[0]; sss_packet_get_body(cctx->creq->in, &req_body, &req_blen); if (req_blen == sizeof(uint32_t)) { memcpy(&client_version, req_body, sizeof(uint32_t)); DEBUG(SSSDBG_FUNC_DATA, "Received client version [%d].\n", client_version); i=0; while(cli_protocol_version[i].version>0) { if (cli_protocol_version[i].version == client_version) { cctx->cli_protocol_version = &cli_protocol_version[i]; break; } i++; } } } /* create response packet */ ret = sss_packet_new(cctx->creq, sizeof(uint32_t), sss_packet_get_cmd(cctx->creq->in), &cctx->creq->out); if (ret != EOK) { return ret; } sss_packet_get_body(cctx->creq->out, &body, &blen); protocol_version = (cctx->cli_protocol_version != NULL) ? cctx->cli_protocol_version->version : 0; SAFEALIGN_COPY_UINT32(body, &protocol_version, NULL); DEBUG(SSSDBG_FUNC_DATA, "Offered version [%d].\n", protocol_version); sss_cmd_done(cctx, NULL); return EOK; } int sss_cmd_execute(struct cli_ctx *cctx, enum sss_cli_command cmd, struct sss_cmd_table *sss_cmds) { int i; for (i = 0; sss_cmds[i].cmd != SSS_CLI_NULL; i++) { if (cmd == sss_cmds[i].cmd) { return sss_cmds[i].fn(cctx); } } return EINVAL; } struct setent_req_list { struct setent_req_list *prev; struct setent_req_list *next; /* Need to modify the list from a talloc destructor */ struct setent_req_list **head; void *pvt; struct tevent_req *req; }; struct tevent_req * setent_get_req(struct setent_req_list *sl) { return sl->req; } int setent_remove_ref(TALLOC_CTX *ctx) { struct setent_req_list *entry = talloc_get_type(ctx, struct setent_req_list); DLIST_REMOVE(*(entry->head), entry); return 0; } errno_t setent_add_ref(TALLOC_CTX *memctx, void *pvt, struct setent_req_list **list, struct tevent_req *req) { struct setent_req_list *entry; entry = talloc_zero(memctx, struct setent_req_list); if (!entry) { return ENOMEM; } entry->req = req; entry->pvt = pvt; DLIST_ADD_END(*list, entry, struct setent_req_list *); entry->head = list; talloc_set_destructor((TALLOC_CTX *)entry, setent_remove_ref); return EOK; } void setent_notify(struct setent_req_list **list, errno_t err) { struct setent_req_list *reql; /* Notify the waiting clients */ while ((reql = *list) != NULL) { /* Each tevent_req_done() call will free * the request, removing it from the list. */ if (err == EOK) { tevent_req_done(reql->req); } else { tevent_req_error(reql->req, err); } if (reql == *list) { /* The consumer failed to free the * request. Log a bug and continue. */ DEBUG(SSSDBG_FATAL_FAILURE, "BUG: a callback did not free its request. " "May leak memory\n"); /* Skip to the next since a memory leak is non-fatal */ *list = (*list)->next; } } } void setent_notify_done(struct setent_req_list **list) { return setent_notify(list, EOK); } /* * Return values: * EOK - cache hit * EAGAIN - cache hit, but schedule off band update * ENOENT - cache miss */ errno_t sss_cmd_check_cache(struct ldb_message *msg, int cache_refresh_percent, uint64_t cache_expire) { uint64_t lastUpdate; uint64_t midpoint_refresh = 0; time_t now; now = time(NULL); lastUpdate = ldb_msg_find_attr_as_uint64(msg, SYSDB_LAST_UPDATE, 0); midpoint_refresh = 0; if(cache_refresh_percent) { midpoint_refresh = lastUpdate + (cache_expire - lastUpdate)*cache_refresh_percent/100.0; if (midpoint_refresh - lastUpdate < 10) { /* If the percentage results in an expiration * less than ten seconds after the lastUpdate time, * that's too often we will simply set it to 10s */ midpoint_refresh = lastUpdate+10; } } if (cache_expire > now) { /* cache still valid */ if (midpoint_refresh && midpoint_refresh < now) { /* We're past the cache refresh timeout * We'll return the value from the cache, but we'll also * queue the cache entry for update out-of-band. */ return EAGAIN; } else { /* Cache is still valid. */ return EOK; } } /* Cache needs to be updated */ return ENOENT; } sssd-1.13.4/src/responder/common/PaxHeaders.16287/responder_dp.c0000644000000000000000000000007412703456111021235 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.999794799 sssd-1.13.4/src/responder/common/responder_dp.c0000644002412700241270000006240212703456111022710 0ustar00jhrozekjhrozek00000000000000/* Authors: Simo Sorce Stephen Gallagher Copyright (C) 2009 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include "util/util.h" #include "responder/common/responder_packet.h" #include "responder/common/responder.h" #include "providers/data_provider.h" #include "sbus/sbus_client.h" struct sss_dp_req; struct sss_dp_callback { struct sss_dp_callback *prev; struct sss_dp_callback *next; struct tevent_req *req; struct sss_dp_req *sdp_req; }; struct sss_dp_req { struct resp_ctx *rctx; struct tevent_context *ev; DBusPendingCall *pending_reply; hash_key_t *key; struct sss_dp_callback *cb_list; dbus_uint16_t dp_err; dbus_uint32_t dp_ret; char *err_msg; }; static int sss_dp_callback_destructor(void *ptr) { struct sss_dp_callback *cb = talloc_get_type(ptr, struct sss_dp_callback); DLIST_REMOVE(cb->sdp_req->cb_list, cb); return EOK; } static int sss_dp_req_destructor(void *ptr) { struct sss_dp_callback *cb; struct sss_dp_req *sdp_req = talloc_get_type(ptr, struct sss_dp_req); struct sss_dp_req_state *state; int hret; /* Cancel Dbus pending reply if still pending */ if (sdp_req->pending_reply) { dbus_pending_call_cancel(sdp_req->pending_reply); sdp_req->pending_reply = NULL; } /* Do not call callbacks if the responder is shutting down, because * the top level responder context (pam_ctx, sudo_ctx, ...) may be * already semi-freed and we may end up accessing freed memory. */ if (sdp_req->rctx->shutting_down) { return 0; } /* If there are callbacks that haven't been invoked, return * an error now. */ while ((cb = sdp_req->cb_list) != NULL) { state = tevent_req_data(cb->req, struct sss_dp_req_state); state->dp_err = DP_ERR_FATAL; state->dp_ret = EIO; /* tevent_req_done/error will free cb */ tevent_req_error(cb->req, EIO); /* Freeing the cb removes it from the cb_list. * Therefore, the cb_list should now be pointing * at a new callback. If it's not, it means the * callback handler didn't free cb and may leak * memory. Be paranoid and protect against this * situation. */ if (cb == sdp_req->cb_list) { DEBUG(SSSDBG_FATAL_FAILURE, "BUG: a callback did not free its request. " "May leak memory\n"); /* Skip to the next since a memory leak is non-fatal */ sdp_req->cb_list = sdp_req->cb_list->next; } } /* Destroy the hash entry */ DEBUG(SSSDBG_TRACE_FUNC, "Deleting request: [%s]\n", sdp_req->key->str); hret = hash_delete(sdp_req->rctx->dp_request_table, sdp_req->key); if (hret != HASH_SUCCESS) { /* This should never happen */ DEBUG(SSSDBG_TRACE_INTERNAL, "BUG: Could not clear [%d:%lu:%s] from request queue: [%s]\n", sdp_req->key->type, sdp_req->key->ul, sdp_req->key->str, hash_error_string(hret)); return -1; } return 0; } static void sss_dp_req_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval t, void *ptr) { /* ptr is a pointer to sidereq */ /* Just free it to kill all waiting requests when the timeout fires */ talloc_zfree(ptr); } void handle_requests_after_reconnect(struct resp_ctx *rctx) { int ret; hash_value_t *values; unsigned long count, i; struct sss_dp_req *sdp_req; if (!rctx->dp_request_table) { DEBUG(SSSDBG_TRACE_LIBS, "No requests to handle after reconnect\n"); return; } ret = hash_values(rctx->dp_request_table, &count, &values); if (ret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "hash_values failed, " "not all request might be handled after reconnect.\n"); return; } DEBUG(SSSDBG_TRACE_LIBS, "Will handle %lu requests after reconnect\n", count); for (i=0; itype = HASH_KEY_STRING; key->str = talloc_asprintf(key, "%p:%s", msg_create, strkey); if (!key->str) { ret = ENOMEM; goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "Issuing request for [%s]\n", key->str); /* Check the hash for existing references to this request */ hret = hash_lookup(rctx->dp_request_table, key, &value); switch (hret) { case HASH_SUCCESS: /* Request already in progress */ DEBUG(SSSDBG_TRACE_FUNC, "Identical request in progress: [%s]\n", key->str); break; case HASH_ERROR_KEY_NOT_FOUND: /* No such request in progress * Create a new request */ msg = msg_create(pvt); if (!msg) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create D-Bus message\n"); ret = EIO; goto fail; } value.type = HASH_VALUE_PTR; sidereq = sss_dp_internal_get_send(rctx, key, dom, msg); dbus_message_unref(msg); if (!sidereq) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot send D-Bus message\n"); ret = EIO; goto fail; } tevent_req_set_callback(sidereq, sss_dp_req_done, NULL); /* add timeout handling so we do not hang forever should something * go worng in the provider. Use 2 sec less than the idle timeout to * give it a chance to reply to the client before closing the * connection. */ tv = tevent_timeval_current_ofs(rctx->client_idle_timeout - 2, 0); te = tevent_add_timer(rctx->ev, sidereq, tv, sss_dp_req_timeout, sidereq); if (!te) { /* Nothing much we can do */ DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); ret = ENOMEM; goto fail; } /* We should now be able to find the sdp_req in the hash table */ hret = hash_lookup(rctx->dp_request_table, key, &value); if (hret != HASH_SUCCESS) { /* Something must have gone wrong with creating the request */ DEBUG(SSSDBG_CRIT_FAILURE, "The request has disappeared?\n"); ret = EIO; goto fail; } break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Could not query request list (%s)\n", hash_error_string(hret)); ret = EIO; goto fail; } /* Register this request for results */ sdp_req = talloc_get_type(value.ptr, struct sss_dp_req); if (!sdp_req) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not retrieve DP request context\n"); ret = EIO; goto fail; } cb = talloc_zero(mem_ctx, struct sss_dp_callback); if (!cb) { ret = ENOMEM; goto fail; } cb->req = nreq; cb->sdp_req = sdp_req; /* Add it to the list of requests to call */ DLIST_ADD_END(sdp_req->cb_list, cb, struct sss_dp_callback *); talloc_set_destructor((TALLOC_CTX *)cb, sss_dp_callback_destructor); ret = EOK; fail: talloc_free(tmp_ctx); return ret; } static void sss_dp_req_done(struct tevent_req *sidereq) { /* Nothing to do here. The callbacks have already been invoked */ talloc_zfree(sidereq); } errno_t sss_dp_req_recv(TALLOC_CTX *mem_ctx, struct tevent_req *sidereq, dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret, char **err_msg) { struct sss_dp_req_state *state = tevent_req_data(sidereq, struct sss_dp_req_state); enum tevent_req_state TRROEstate; uint64_t TRROEerr; *dp_err = state->dp_err; *dp_ret = state->dp_ret; *err_msg = talloc_steal(mem_ctx, state->err_msg); if (tevent_req_is_error(sidereq, &TRROEstate, &TRROEerr)) { if (TRROEstate == TEVENT_REQ_USER_ERROR) { *dp_err = DP_ERR_FATAL; *dp_ret = TRROEerr; } else { return EIO; } } return EOK; } /* Send a request to the data provider * Once this function is called, the communication * with the data provider will always run to * completion. Freeing the returned tevent_req will * cancel the notification of completion, but not * the data provider action. */ static DBusMessage *sss_dp_get_account_msg(void *pvt); struct sss_dp_account_info { struct sss_domain_info *dom; bool fast_reply; enum sss_dp_acct_type type; const char *opt_name; const char *extra; uint32_t opt_id; }; struct tevent_req * sss_dp_get_account_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, bool fast_reply, enum sss_dp_acct_type type, const char *opt_name, uint32_t opt_id, const char *extra) { errno_t ret; struct tevent_req *req; struct sss_dp_account_info *info; struct sss_dp_req_state *state; char *key; req = tevent_req_create(mem_ctx, &state, struct sss_dp_req_state); if (!req) { return NULL; } /* either, or, not both */ if (opt_name && opt_id) { ret = EINVAL; goto error; } if (!dom) { ret = EINVAL; goto error; } info = talloc_zero(state, struct sss_dp_account_info); info->fast_reply = fast_reply; info->type = type; info->opt_name = opt_name; info->opt_id = opt_id; info->extra = extra; info->dom = dom; if (opt_name) { if (extra) { key = talloc_asprintf(state, "%d:%s:%s@%s", type, opt_name, extra, dom->name); } else { key = talloc_asprintf(state, "%d:%s@%s", type, opt_name, dom->name); } } else if (opt_id) { if (extra) { key = talloc_asprintf(state, "%d:%d:%s@%s", type, opt_id, extra, dom->name); } else { key = talloc_asprintf(state, "%d:%d@%s", type, opt_id, dom->name); } } else { key = talloc_asprintf(state, "%d:*@%s", type, dom->name); } if (!key) { ret = ENOMEM; goto error; } ret = sss_dp_issue_request(state, rctx, key, dom, sss_dp_get_account_msg, info, req); talloc_free(key); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not issue DP request [%d]: %s\n", ret, strerror(ret)); goto error; } return req; error: tevent_req_error(req, ret); tevent_req_post(req, rctx->ev); return req; } static DBusMessage * sss_dp_get_account_msg(void *pvt) { DBusMessage *msg; dbus_bool_t dbret; struct sss_dp_account_info *info; uint32_t be_type; uint32_t attrs = BE_ATTR_CORE; char *filter; info = talloc_get_type(pvt, struct sss_dp_account_info); switch (info->type) { case SSS_DP_USER: case SSS_DP_WILDCARD_USER: be_type = BE_REQ_USER; break; case SSS_DP_GROUP: case SSS_DP_WILDCARD_GROUP: be_type = BE_REQ_GROUP; break; case SSS_DP_INITGROUPS: be_type = BE_REQ_INITGROUPS; break; case SSS_DP_NETGR: be_type = BE_REQ_NETGROUP; break; case SSS_DP_SERVICES: be_type = BE_REQ_SERVICES; break; case SSS_DP_SECID: be_type = BE_REQ_BY_SECID; break; case SSS_DP_USER_AND_GROUP: be_type = BE_REQ_USER_AND_GROUP; break; case SSS_DP_CERT: be_type = BE_REQ_BY_CERT; break; } if (info->fast_reply) { be_type |= BE_REQ_FAST; } if (info->opt_name) { if (info->type == SSS_DP_SECID) { if (info->extra) { filter = talloc_asprintf(info, "%s=%s:%s", DP_SEC_ID, info->opt_name, info->extra); } else { filter = talloc_asprintf(info, "%s=%s", DP_SEC_ID, info->opt_name); } } else if (info->type == SSS_DP_CERT) { if (info->extra) { filter = talloc_asprintf(info, "%s=%s:%s", DP_CERT, info->opt_name, info->extra); } else { filter = talloc_asprintf(info, "%s=%s", DP_CERT, info->opt_name); } } else if (info->type == SSS_DP_WILDCARD_USER || info->type == SSS_DP_WILDCARD_GROUP) { if (info->extra) { filter = talloc_asprintf(info, "%s=%s:%s", DP_WILDCARD, info->opt_name, info->extra); } else { filter = talloc_asprintf(info, "%s=%s", DP_WILDCARD, info->opt_name); } } else { if (info->extra) { filter = talloc_asprintf(info, "name=%s:%s", info->opt_name, info->extra); } else { filter = talloc_asprintf(info, "name=%s", info->opt_name); } } } else if (info->opt_id) { if (info->extra) { filter = talloc_asprintf(info, "idnumber=%u:%s", info->opt_id, info->extra); } else { filter = talloc_asprintf(info, "idnumber=%u", info->opt_id); } } else { filter = talloc_strdup(info, ENUM_INDICATOR); } if (!filter) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); return NULL; } msg = dbus_message_new_method_call(NULL, DP_PATH, DATA_PROVIDER_IFACE, DATA_PROVIDER_IFACE_GETACCOUNTINFO); if (msg == NULL) { talloc_free(filter); DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); return NULL; } /* create the message */ DEBUG(SSSDBG_TRACE_FUNC, "Creating request for [%s][%#x][%s][%d][%s]\n", info->dom->name, be_type, be_req2str(be_type), attrs, filter); dbret = dbus_message_append_args(msg, DBUS_TYPE_UINT32, &be_type, DBUS_TYPE_UINT32, &attrs, DBUS_TYPE_STRING, &filter, DBUS_TYPE_STRING, &info->dom->name, DBUS_TYPE_INVALID); talloc_free(filter); if (!dbret) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n"); dbus_message_unref(msg); return NULL; } return msg; } errno_t sss_dp_get_account_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret, char **err_msg) { return sss_dp_req_recv(mem_ctx, req, dp_err, dp_ret, err_msg); } struct dp_internal_get_state { struct resp_ctx *rctx; struct sss_domain_info *dom; struct sss_dp_req *sdp_req; DBusPendingCall *pending_reply; }; static void sss_dp_internal_get_done(DBusPendingCall *pending, void *ptr); static struct tevent_req * sss_dp_internal_get_send(struct resp_ctx *rctx, hash_key_t *key, struct sss_domain_info *dom, DBusMessage *msg) { errno_t ret; int hret; struct tevent_req *req; struct dp_internal_get_state *state; struct be_conn *be_conn; hash_value_t value; /* Internal requests need to be allocated on the responder context * so that they don't go away if a client disconnects. The worst- * case scenario here is that the cache is updated without any * client expecting a response. */ req = tevent_req_create(rctx, &state, struct dp_internal_get_state); if (!req) return NULL; state->rctx = rctx; state->dom = dom; state->sdp_req = talloc_zero(state, struct sss_dp_req); if (!state->sdp_req) { ret = ENOMEM; goto error; } state->sdp_req->rctx = rctx; state->sdp_req->ev = rctx->ev; /* Copy the key to use when calling the destructor * It needs to be a copy because the original request * might be freed if it no longer cares about the reply. */ state->sdp_req->key = talloc_steal(state->sdp_req, key); /* double check dp_ctx has actually been initialized. * in some pathological cases it may happen that nss starts up before * dp connection code is actually able to establish a connection. */ ret = sss_dp_get_domain_conn(rctx, dom->conn_name, &be_conn); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "BUG: The Data Provider connection for %s is not available!\n", dom->name); ret = EIO; goto error; } ret = sbus_conn_send(be_conn->conn, msg, SSS_CLI_SOCKET_TIMEOUT / 2, sss_dp_internal_get_done, req, &state->sdp_req->pending_reply); if (ret != EOK) { /* * Critical Failure * We can't communicate on this connection */ DEBUG(SSSDBG_CRIT_FAILURE, "D-BUS send failed.\n"); ret = EIO; goto error; } /* Add this sdp_req to the hash table */ value.type = HASH_VALUE_PTR; value.ptr = state->sdp_req; DEBUG(SSSDBG_TRACE_FUNC, "Entering request [%s]\n", key->str); hret = hash_enter(rctx->dp_request_table, key, &value); if (hret != HASH_SUCCESS) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not store request query (%s)\n", hash_error_string(hret)); ret = EIO; goto error; } talloc_set_destructor((TALLOC_CTX *)state->sdp_req, sss_dp_req_destructor); return req; error: tevent_req_error(req, ret); tevent_req_post(req, rctx->ev); return req; } static void sss_dp_internal_get_done(DBusPendingCall *pending, void *ptr) { int ret; struct tevent_req *req; struct sss_dp_req *sdp_req; struct sss_dp_callback *cb; struct dp_internal_get_state *state; struct sss_dp_req_state *cb_state; req = talloc_get_type(ptr, struct tevent_req); state = tevent_req_data(req, struct dp_internal_get_state); sdp_req = state->sdp_req; /* prevent trying to cancel a reply that we already received */ sdp_req->pending_reply = NULL; ret = sss_dp_get_reply(pending, &sdp_req->dp_err, &sdp_req->dp_ret, &sdp_req->err_msg); if (ret != EOK) { if (ret == ETIME) { sdp_req->dp_err = DP_ERR_TIMEOUT; sdp_req->dp_ret = ret; sdp_req->err_msg = talloc_strdup(sdp_req, "Request timed out"); } else { sdp_req->dp_err = DP_ERR_FATAL; sdp_req->dp_ret = ret; sdp_req->err_msg = talloc_strdup(sdp_req, "Failed to get reply from Data Provider"); } } /* Check whether we need to issue any callbacks */ while ((cb = sdp_req->cb_list) != NULL) { cb_state = tevent_req_data(cb->req, struct sss_dp_req_state); cb_state->dp_err = sdp_req->dp_err; cb_state->dp_ret = sdp_req->dp_ret; cb_state->err_msg = talloc_strdup(cb_state, sdp_req->err_msg); /* Don't bother checking for NULL. If it fails due to ENOMEM, * we can't really handle it anyway. */ /* tevent_req_done/error will free cb */ if (ret == EOK) { tevent_req_done(cb->req); } else { tevent_req_error(cb->req, ret); } /* Freeing the cb removes it from the cb_list. * Therefore, the cb_list should now be pointing * at a new callback. If it's not, it means the * callback handler didn't free cb and may leak * memory. Be paranoid and protect against this * situation. */ if (cb == sdp_req->cb_list) { DEBUG(SSSDBG_FATAL_FAILURE, "BUG: a callback did not free its request. " "May leak memory\n"); /* Skip to the next since a memory leak is non-fatal */ sdp_req->cb_list = sdp_req->cb_list->next; } } /* We're done with this request. Free the sdp_req * This will clean up the hash table entry as well */ talloc_zfree(sdp_req); /* Free the sidereq to free the rest of the memory allocated with the * internal dp request. */ if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } } sssd-1.13.4/src/responder/common/PaxHeaders.16287/responder_common.c0000644000000000000000000000007412703456111022122 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.927794554 sssd-1.13.4/src/responder/common/responder_common.c0000644002412700241270000007477012703456111023610 0ustar00jhrozekjhrozek00000000000000/* SSSD Common Responder methods Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "util/util.h" #include "util/strtonum.h" #include "db/sysdb.h" #include "confdb/confdb.h" #include "sbus/sssd_dbus.h" #include "responder/common/responder.h" #include "responder/common/responder_packet.h" #include "providers/data_provider.h" #include "monitor/monitor_interfaces.h" #include "sbus/sbus_client.h" static errno_t set_close_on_exec(int fd) { int v; int ferr; errno_t error; /* Get the current flags for this file descriptor */ v = fcntl(fd, F_GETFD, 0); errno = 0; /* Set the close-on-exec flags on this fd */ ferr = fcntl(fd, F_SETFD, v | FD_CLOEXEC); if (ferr < 0) { error = errno; DEBUG(SSSDBG_FATAL_FAILURE, "Unable to set fd close-on-exec: [%d][%s]\n", error, strerror(error)); return error; } return EOK; } static int client_destructor(struct cli_ctx *ctx) { errno_t ret; if ((ctx->cfd > 0) && close(ctx->cfd) < 0) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "Failed to close fd [%d]: [%s]\n", ctx->cfd, strerror(ret)); } DEBUG(SSSDBG_TRACE_INTERNAL, "Terminated client [%p][%d]\n", ctx, ctx->cfd); return 0; } static errno_t get_client_cred(struct cli_ctx *cctx) { cctx->client_euid = -1; cctx->client_egid = -1; cctx->client_pid = -1; #ifdef HAVE_UCRED int ret; struct ucred client_cred; socklen_t client_cred_len = sizeof(client_cred); ret = getsockopt(cctx->cfd, SOL_SOCKET, SO_PEERCRED, &client_cred, &client_cred_len); if (ret != EOK) { ret = errno; DEBUG(SSSDBG_CRIT_FAILURE, "getsock failed [%d][%s].\n", ret, strerror(ret)); return ret; } if (client_cred_len != sizeof(struct ucred)) { DEBUG(SSSDBG_CRIT_FAILURE, "getsockopt returned unexpected message size.\n"); return ENOMSG; } cctx->client_euid = client_cred.uid; cctx->client_egid = client_cred.gid; cctx->client_pid = client_cred.pid; DEBUG(SSSDBG_TRACE_ALL, "Client creds: euid[%d] egid[%d] pid[%d].\n", cctx->client_euid, cctx->client_egid, cctx->client_pid); #endif return EOK; } errno_t check_allowed_uids(uid_t uid, size_t allowed_uids_count, uid_t *allowed_uids) { size_t c; if (allowed_uids == NULL) { return EINVAL; } for (c = 0; c < allowed_uids_count; c++) { if (uid == allowed_uids[c]) { return EOK; } } return EACCES; } errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *csv_string, bool allow_sss_loop, size_t *_uid_count, uid_t **_uids) { int ret; size_t c; char **list = NULL; int list_size; uid_t *uids = NULL; char *endptr; ret = split_on_separator(mem_ctx, csv_string, ',', true, false, &list, &list_size); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "split_on_separator failed [%d][%s].\n", ret, strerror(ret)); goto done; } uids = talloc_array(mem_ctx, uint32_t, list_size); if (uids == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); ret = ENOMEM; goto done; } if (allow_sss_loop) { ret = unsetenv("_SSS_LOOPS"); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to unset _SSS_LOOPS, getpwnam " "might not find sssd users.\n"); } } for (c = 0; c < list_size; c++) { errno = 0; if (*list[c] == '\0') { DEBUG(SSSDBG_OP_FAILURE, "Empty list item.\n"); ret = EINVAL; goto done; } uids[c] = strtouint32(list[c], &endptr, 10); if (errno != 0 || *endptr != '\0') { ret = errno; if (ret == ERANGE) { DEBUG(SSSDBG_OP_FAILURE, "List item [%s] is out of range.\n", list[c]); goto done; } ret = sss_user_by_name_or_uid(list[c], &uids[c], NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "List item [%s] is neither a valid " "UID nor a user name which could be " "resolved by getpwnam().\n", list[c]); sss_log(SSS_LOG_WARNING, "List item [%s] is neither a valid " "UID nor a user name which could be " "resolved by getpwnam().\n", list[c]); goto done; } } } *_uid_count = list_size; *_uids = uids; ret = EOK; done: if(setenv("_SSS_LOOPS", "NO", 0) != 0) { DEBUG(SSSDBG_OP_FAILURE, "Failed to set _SSS_LOOPS.\n"); } talloc_free(list); if (ret != EOK) { talloc_free(uids); } return ret; } static void client_send(struct cli_ctx *cctx) { int ret; ret = sss_packet_send(cctx->creq->out, cctx->cfd); if (ret == EAGAIN) { /* not all data was sent, loop again */ return; } if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to send data, aborting client!\n"); talloc_free(cctx); return; } /* ok all sent */ TEVENT_FD_NOT_WRITEABLE(cctx->cfde); TEVENT_FD_READABLE(cctx->cfde); talloc_free(cctx->creq); cctx->creq = NULL; return; } static int client_cmd_execute(struct cli_ctx *cctx, struct sss_cmd_table *sss_cmds) { enum sss_cli_command cmd; cmd = sss_packet_get_cmd(cctx->creq->in); return sss_cmd_execute(cctx, cmd, sss_cmds); } static void client_recv(struct cli_ctx *cctx) { int ret; if (!cctx->creq) { cctx->creq = talloc_zero(cctx, struct cli_request); if (!cctx->creq) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to alloc request, aborting client!\n"); talloc_free(cctx); return; } } if (!cctx->creq->in) { ret = sss_packet_new(cctx->creq, SSS_PACKET_MAX_RECV_SIZE, 0, &cctx->creq->in); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to alloc request, aborting client!\n"); talloc_free(cctx); return; } } ret = sss_packet_recv(cctx->creq->in, cctx->cfd); switch (ret) { case EOK: /* do not read anymore */ TEVENT_FD_NOT_READABLE(cctx->cfde); /* execute command */ ret = client_cmd_execute(cctx, cctx->rctx->sss_cmds); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to execute request, aborting client!\n"); talloc_free(cctx); } /* past this point cctx can be freed at any time by callbacks * in case of error, do not use it */ return; case EAGAIN: /* need to read still some data, loop again */ break; case EINVAL: DEBUG(SSSDBG_TRACE_FUNC, "Invalid data from client, closing connection!\n"); talloc_free(cctx); break; case ENODATA: DEBUG(SSSDBG_FUNC_DATA, "Client disconnected!\n"); talloc_free(cctx); break; default: DEBUG(SSSDBG_TRACE_FUNC, "Failed to read request, aborting client!\n"); talloc_free(cctx); } return; } static errno_t reset_idle_timer(struct cli_ctx *cctx); static void client_fd_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *ptr) { errno_t ret; struct cli_ctx *cctx = talloc_get_type(ptr, struct cli_ctx); /* Always reset the idle timer on any activity */ ret = reset_idle_timer(cctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not create idle timer for client. " "This connection may not auto-terminate\n"); /* Non-fatal, continue */ } if (flags & TEVENT_FD_READ) { client_recv(cctx); return; } if (flags & TEVENT_FD_WRITE) { client_send(cctx); return; } } struct accept_fd_ctx { struct resp_ctx *rctx; bool is_private; }; static void idle_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *data); static void accept_fd_handler(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *ptr) { /* accept and attach new event handler */ struct accept_fd_ctx *accept_ctx = talloc_get_type(ptr, struct accept_fd_ctx); struct resp_ctx *rctx = accept_ctx->rctx; struct cli_ctx *cctx; socklen_t len; struct stat stat_buf; int ret; int fd = accept_ctx->is_private ? rctx->priv_lfd : rctx->lfd; int client_fd; if (accept_ctx->is_private) { ret = stat(rctx->priv_sock_name, &stat_buf); if (ret == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "stat on privileged pipe failed: [%d][%s].\n", errno, strerror(errno)); return; } if ( ! (stat_buf.st_uid == 0 && stat_buf.st_gid == 0 && (stat_buf.st_mode&(S_IFSOCK|S_IRUSR|S_IWUSR)) == stat_buf.st_mode)) { DEBUG(SSSDBG_CRIT_FAILURE, "privileged pipe has an illegal status.\n"); /* TODO: what is the best response to this condition? Terminate? */ return; } } cctx = talloc_zero(rctx, struct cli_ctx); if (!cctx) { struct sockaddr_un addr; DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory trying to setup client context%s!\n", accept_ctx->is_private ? " on privileged pipe": ""); /* accept and close to signal the client we have a problem */ memset(&addr, 0, sizeof(addr)); len = sizeof(addr); client_fd = accept(fd, (struct sockaddr *)&addr, &len); if (client_fd == -1) { return; } close(client_fd); return; } len = sizeof(cctx->addr); cctx->cfd = accept(fd, (struct sockaddr *)&cctx->addr, &len); if (cctx->cfd == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "Accept failed [%s]\n", strerror(errno)); talloc_free(cctx); return; } cctx->priv = accept_ctx->is_private; ret = get_client_cred(cctx); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "get_client_cred failed, " "client cred may not be available.\n"); } if (rctx->allowed_uids_count != 0) { if (cctx->client_euid == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "allowed_uids configured, " \ "but platform does not support " \ "reading peer credential from the " \ "socket. Access denied.\n"); close(cctx->cfd); talloc_free(cctx); return; } ret = check_allowed_uids(cctx->client_euid, rctx->allowed_uids_count, rctx->allowed_uids); if (ret != EOK) { if (ret == EACCES) { DEBUG(SSSDBG_CRIT_FAILURE, "Access denied for uid [%d].\n", cctx->client_euid); } else { DEBUG(SSSDBG_OP_FAILURE, "check_allowed_uids failed.\n"); } close(cctx->cfd); talloc_free(cctx); return; } } cctx->cfde = tevent_add_fd(ev, cctx, cctx->cfd, TEVENT_FD_READ, client_fd_handler, cctx); if (!cctx->cfde) { close(cctx->cfd); talloc_free(cctx); DEBUG(SSSDBG_OP_FAILURE, "Failed to queue client handler%s\n", accept_ctx->is_private ? " on privileged pipe" : ""); return; } cctx->ev = ev; cctx->rctx = rctx; talloc_set_destructor(cctx, client_destructor); /* Set up the idle timer */ ret = reset_idle_timer(cctx); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Could not create idle timer for client. " "This connection may not auto-terminate\n"); /* Non-fatal, continue */ } DEBUG(SSSDBG_TRACE_FUNC, "Client connected%s!\n", accept_ctx->is_private ? " to privileged pipe" : ""); return; } static errno_t reset_idle_timer(struct cli_ctx *cctx) { struct timeval tv = tevent_timeval_current_ofs(cctx->rctx->client_idle_timeout, 0); talloc_zfree(cctx->idle); cctx->idle = tevent_add_timer(cctx->ev, cctx, tv, idle_handler, cctx); if (!cctx->idle) return ENOMEM; DEBUG(SSSDBG_TRACE_ALL, "Idle timer re-set for client [%p][%d]\n", cctx, cctx->cfd); return EOK; } static void idle_handler(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *data) { /* This connection is idle. Terminate it */ struct cli_ctx *cctx = talloc_get_type(data, struct cli_ctx); DEBUG(SSSDBG_TRACE_INTERNAL, "Terminating idle client [%p][%d]\n", cctx, cctx->cfd); /* The cli_ctx destructor will handle the rest */ talloc_free(cctx); } static int sss_dp_init(struct resp_ctx *rctx, struct sbus_vtable *dp_intf, const char *cli_name, struct sss_domain_info *domain) { struct be_conn *be_conn; int ret; be_conn = talloc_zero(rctx, struct be_conn); if (!be_conn) return ENOMEM; be_conn->cli_name = cli_name; be_conn->domain = domain; be_conn->rctx = rctx; /* Set up SBUS connection to the monitor */ ret = dp_get_sbus_address(be_conn, &be_conn->sbus_address, domain->name); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not locate DP address.\n"); return ret; } ret = sbus_client_init(rctx, rctx->ev, be_conn->sbus_address, &be_conn->conn); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to connect to monitor services.\n"); return ret; } ret = sbus_conn_register_iface(be_conn->conn, dp_intf, DP_PATH, rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to export data provider.\n"); return ret; } DLIST_ADD_END(rctx->be_conns, be_conn, struct be_conn *); /* Identify ourselves to the DP */ ret = dp_common_send_id(be_conn->conn, DATA_PROVIDER_VERSION, cli_name); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to identify to the DP!\n"); return ret; } return EOK; } int create_pipe_fd(const char *sock_name, int *_fd, mode_t umaskval) { struct sockaddr_un addr; mode_t orig_umaskval; errno_t ret; int fd; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { return EIO; } orig_umaskval = umask(umaskval); ret = sss_fd_nonblocking(fd); if (ret != EOK) { goto done; } ret = set_close_on_exec(fd); if (ret != EOK) { goto done; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, sock_name, sizeof(addr.sun_path) - 1); addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; /* make sure we have no old sockets around */ ret = unlink(sock_name); if (ret != 0 && errno != ENOENT) { ret = errno; DEBUG(SSSDBG_MINOR_FAILURE, "Cannot remove old socket (errno=%d), bind might fail!\n", ret); } if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to bind on socket '%s'\n", sock_name); ret = EIO; goto done; } if (listen(fd, 10) == -1) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to listen on socket '%s'\n", sock_name); ret = EIO; goto done; } ret = EOK; done: /* restore previous umask value */ umask(orig_umaskval); if (ret == EOK) { *_fd = fd; } else { close(fd); } return ret; } /* create a unix socket and listen to it */ static int set_unix_socket(struct resp_ctx *rctx) { errno_t ret; struct accept_fd_ctx *accept_ctx; /* for future use */ #if 0 char *default_pipe; int ret; default_pipe = talloc_asprintf(rctx, "%s/%s", PIPE_PATH, rctx->sss_pipe_name); if (!default_pipe) { return ENOMEM; } ret = confdb_get_string(rctx->cdb, rctx, rctx->confdb_socket_path, "unixSocket", default_pipe, &rctx->sock_name); if (ret != EOK) { talloc_free(default_pipe); return ret; } talloc_free(default_pipe); default_pipe = talloc_asprintf(rctx, "%s/private/%s", PIPE_PATH, rctx->sss_pipe_name); if (!default_pipe) { return ENOMEM; } ret = confdb_get_string(rctx->cdb, rctx, rctx->confdb_socket_path, "privUnixSocket", default_pipe, &rctx->priv_sock_name); if (ret != EOK) { talloc_free(default_pipe); return ret; } talloc_free(default_pipe); #endif if (rctx->sock_name != NULL ) { /* Set the umask so that permissions are set right on the socket. * It must be readable and writable by anybody on the system. */ if (rctx->lfd == -1) { ret = create_pipe_fd(rctx->sock_name, &rctx->lfd, 0111); if (ret != EOK) { return ret; } } accept_ctx = talloc_zero(rctx, struct accept_fd_ctx); if(!accept_ctx) goto failed; accept_ctx->rctx = rctx; accept_ctx->is_private = false; rctx->lfde = tevent_add_fd(rctx->ev, rctx, rctx->lfd, TEVENT_FD_READ, accept_fd_handler, accept_ctx); if (!rctx->lfde) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to queue handler on pipe\n"); goto failed; } } if (rctx->priv_sock_name != NULL ) { /* create privileged pipe */ if (rctx->priv_lfd == -1) { ret = create_pipe_fd(rctx->priv_sock_name, &rctx->priv_lfd, 0177); if (ret != EOK) { goto failed; } } accept_ctx = talloc_zero(rctx, struct accept_fd_ctx); if(!accept_ctx) goto failed; accept_ctx->rctx = rctx; accept_ctx->is_private = true; rctx->priv_lfde = tevent_add_fd(rctx->ev, rctx, rctx->priv_lfd, TEVENT_FD_READ, accept_fd_handler, accept_ctx); if (!rctx->priv_lfde) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to queue handler on privileged pipe\n"); goto failed; } } return EOK; failed: close(rctx->lfd); close(rctx->priv_lfd); return EIO; } static int sss_responder_ctx_destructor(void *ptr) { struct resp_ctx *rctx = talloc_get_type(ptr, struct resp_ctx); /* mark that we are shutting down the responder, so it is propagated * into underlying contexts that are freed right before rctx */ DEBUG(SSSDBG_TRACE_FUNC, "Responder is being shut down\n"); rctx->shutting_down = true; return 0; } int sss_process_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct confdb_ctx *cdb, struct sss_cmd_table sss_cmds[], const char *sss_pipe_name, int pipe_fd, const char *sss_priv_pipe_name, int priv_pipe_fd, const char *confdb_service_path, const char *svc_name, uint16_t svc_version, struct mon_cli_iface *monitor_intf, const char *cli_name, struct sbus_vtable *dp_intf, struct resp_ctx **responder_ctx) { struct resp_ctx *rctx; struct sss_domain_info *dom; int ret; char *tmp = NULL; rctx = talloc_zero(mem_ctx, struct resp_ctx); if (!rctx) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing resp_ctx\n"); return ENOMEM; } rctx->ev = ev; rctx->cdb = cdb; rctx->sss_cmds = sss_cmds; rctx->sock_name = sss_pipe_name; rctx->priv_sock_name = sss_priv_pipe_name; rctx->lfd = pipe_fd; rctx->priv_lfd = priv_pipe_fd; rctx->confdb_service_path = confdb_service_path; rctx->shutting_down = false; talloc_set_destructor((TALLOC_CTX*)rctx, sss_responder_ctx_destructor); ret = confdb_get_int(rctx->cdb, rctx->confdb_service_path, CONFDB_RESPONDER_CLI_IDLE_TIMEOUT, CONFDB_RESPONDER_CLI_IDLE_DEFAULT_TIMEOUT, &rctx->client_idle_timeout); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot get the client idle timeout [%d]: %s\n", ret, strerror(ret)); goto fail; } /* Ensure that the client timeout is at least ten seconds */ if (rctx->client_idle_timeout < 10) { rctx->client_idle_timeout = 10; } ret = confdb_get_int(rctx->cdb, rctx->confdb_service_path, CONFDB_RESPONDER_GET_DOMAINS_TIMEOUT, GET_DOMAINS_DEFAULT_TIMEOUT, &rctx->domains_timeout); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannnot get the default domain timeout [%d]: %s\n", ret, strerror(ret)); goto fail; } if (rctx->domains_timeout < 0) { DEBUG(SSSDBG_CONF_SETTINGS, "timeout can't be set to negative value, setting default\n"); rctx->domains_timeout = GET_DOMAINS_DEFAULT_TIMEOUT; } ret = confdb_get_domains(rctx->cdb, &rctx->domains); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error setting up domain map\n"); goto fail; } ret = confdb_get_string(rctx->cdb, rctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_DEFAULT_DOMAIN, NULL, &rctx->default_domain); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannnot get the default domain [%d]: %s\n", ret, strerror(ret)); goto fail; } ret = confdb_get_string(rctx->cdb, rctx, CONFDB_MONITOR_CONF_ENTRY, CONFDB_MONITOR_OVERRIDE_SPACE, NULL, &tmp); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannnot get the space substitution character [%d]: %s\n", ret, strerror(ret)); goto fail; } if (tmp != NULL) { if (strlen(tmp) > 1) { DEBUG(SSSDBG_MINOR_FAILURE, "Option %s is longer than 1 character " "only the first character %c will be used\n", CONFDB_MONITOR_OVERRIDE_SPACE, tmp[0]); } rctx->override_space = tmp[0]; } ret = sss_monitor_init(rctx, rctx->ev, monitor_intf, svc_name, svc_version, rctx, &rctx->mon_conn); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error setting up message bus\n"); goto fail; } for (dom = rctx->domains; dom; dom = get_next_domain(dom, 0)) { ret = sss_names_init(rctx->cdb, rctx->cdb, dom->name, &dom->names); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing regex data for domain: %s\n", dom->name); goto fail; } /* skip local domain, it doesn't have a backend */ if (strcasecmp(dom->provider, "local") == 0) { continue; } ret = sss_dp_init(rctx, dp_intf, cli_name, dom); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error setting up backend connector\n"); goto fail; } } ret = sysdb_init(rctx, rctx->domains, false); if (ret != EOK) { SYSDB_VERSION_ERROR_DAEMON(ret); DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing resp_ctx\n"); goto fail; } /* after all initializations we are ready to listen on our socket */ ret = set_unix_socket(rctx); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "fatal error initializing socket\n"); goto fail; } /* Create DP request table */ ret = sss_hash_create(rctx, 30, &rctx->dp_request_table); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Could not create hash table for the request queue\n"); goto fail; } DEBUG(SSSDBG_TRACE_FUNC, "Responder Initialization complete\n"); *responder_ctx = rctx; return EOK; fail: talloc_free(rctx); return ret; } int sss_dp_get_domain_conn(struct resp_ctx *rctx, const char *domain, struct be_conn **_conn) { struct be_conn *iter; if (!rctx->be_conns) return ENOENT; for (iter = rctx->be_conns; iter; iter = iter->next) { if (strcasecmp(domain, iter->domain->name) == 0) break; } if (!iter) return ENOENT; *_conn = iter; return EOK; } struct sss_domain_info * responder_get_domain(struct resp_ctx *rctx, const char *name) { struct sss_domain_info *dom; struct sss_domain_info *ret_dom = NULL; for (dom = rctx->domains; dom; dom = get_next_domain(dom, SSS_GND_DESCEND)) { if (sss_domain_get_state(dom) == DOM_DISABLED) { continue; } if (strcasecmp(dom->name, name) == 0 || (dom->flat_name != NULL && strcasecmp(dom->flat_name, name) == 0)) { ret_dom = dom; break; } } if (!ret_dom) { DEBUG(SSSDBG_OP_FAILURE, "Unknown domain [%s]\n", name); } return ret_dom; } errno_t responder_get_domain_by_id(struct resp_ctx *rctx, const char *id, struct sss_domain_info **_ret_dom) { struct sss_domain_info *dom; struct sss_domain_info *ret_dom = NULL; size_t id_len; size_t dom_id_len; int ret; if (id == NULL || _ret_dom == NULL) { return EINVAL; } id_len = strlen(id); for (dom = rctx->domains; dom; dom = get_next_domain(dom, SSS_GND_DESCEND)) { if (sss_domain_get_state(dom) == DOM_DISABLED || dom->domain_id == NULL) { continue; } dom_id_len = strlen(dom->domain_id); if ((id_len >= dom_id_len) && strncasecmp(dom->domain_id, id, dom_id_len) == 0) { if (IS_SUBDOMAIN(dom) && ((time(NULL) - dom->parent->subdomains_last_checked.tv_sec) > rctx->domains_timeout)) { DEBUG(SSSDBG_TRACE_FUNC, "Domain entry with id [%s] " \ "is expired.\n", id); ret = EAGAIN; goto done; } ret_dom = dom; break; } } if (ret_dom == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Unknown domain id [%s], checking for " "possible subdomains!\n", id); ret = ENOENT; } else { *_ret_dom = ret_dom; ret = EOK; } done: return ret; } int responder_logrotate(struct sbus_request *dbus_req, void *data) { errno_t ret; struct resp_ctx *rctx = talloc_get_type(data, struct resp_ctx); ret = server_common_rotate_logs(rctx->cdb, rctx->confdb_service_path); if (ret != EOK) return ret; return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); } void responder_set_fd_limit(rlim_t fd_limit) { struct rlimit current_limit, new_limit; int limret; /* First, let's see if we have permission to just set * the value as-is. */ new_limit.rlim_cur = fd_limit; new_limit.rlim_max = fd_limit; limret = setrlimit(RLIMIT_NOFILE, &new_limit); if (limret == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Maximum file descriptors set to [%"SPRIrlim"]\n", new_limit.rlim_cur); return; } /* We couldn't set the soft and hard limits to this * value. Let's see how high we CAN set it. */ /* Determine the maximum hard limit */ limret = getrlimit(RLIMIT_NOFILE, ¤t_limit); if (limret == 0) { DEBUG(SSSDBG_TRACE_INTERNAL, "Current fd limit: [%"SPRIrlim"]\n", current_limit.rlim_cur); /* Choose the lesser of the requested and the hard limit */ if (current_limit.rlim_max < fd_limit) { new_limit.rlim_cur = current_limit.rlim_max; } else { new_limit.rlim_cur = fd_limit; } new_limit.rlim_max = current_limit.rlim_max; limret = setrlimit(RLIMIT_NOFILE, &new_limit); if (limret == 0) { DEBUG(SSSDBG_CONF_SETTINGS, "Maximum file descriptors set to [%"SPRIrlim"]\n", new_limit.rlim_cur); } else { DEBUG(SSSDBG_CRIT_FAILURE, "Could not set new fd limits. Proceeding with " "[%"SPRIrlim"]\n", current_limit.rlim_cur); } } else { DEBUG(SSSDBG_CRIT_FAILURE, "Could not determine fd limits. " "Proceeding with system values\n"); } } sssd-1.13.4/src/responder/common/PaxHeaders.16287/responder_get_domains.c0000644000000000000000000000007312703456111023122 xustar0030 atime=1460561751.650715627 29 ctime=1460561774.95879466 sssd-1.13.4/src/responder/common/responder_get_domains.c0000644002412700241270000004010412703456111024571 0ustar00jhrozekjhrozek00000000000000/* Authors: Jan Zeleny Copyright (C) 2011 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "responder/common/responder.h" #include "providers/data_provider.h" #include "db/sysdb.h" /* ========== Get subdomains for a domain ================= */ static DBusMessage *sss_dp_get_domains_msg(void *pvt); struct sss_dp_domains_info { struct sss_domain_info *dom; const char *hint; }; static struct tevent_req * get_subdomains_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, const char *hint) { errno_t ret; struct tevent_req *req; struct sss_dp_req_state *state; struct sss_dp_domains_info *info; char *key; req = tevent_req_create(mem_ctx, &state, struct sss_dp_req_state); if (req == NULL) { return NULL; } info = talloc_zero(state, struct sss_dp_domains_info); if (!info) { ret = ENOMEM; goto fail; } info->hint = hint; info->dom = dom; key = talloc_asprintf(state, "domains@%s", dom->name); if (key == NULL) { ret = ENOMEM; goto fail; } ret = sss_dp_issue_request(state, rctx, key, dom, sss_dp_get_domains_msg, info, req); talloc_free(key); if (ret != EOK) { ret = EIO; goto fail; } return req; fail: tevent_req_error(req, ret); tevent_req_post(req, rctx->ev); return req; } static DBusMessage * sss_dp_get_domains_msg(void *pvt) { struct sss_dp_domains_info *info; DBusMessage *msg = NULL; dbus_bool_t dbret; info = talloc_get_type(pvt, struct sss_dp_domains_info); msg = dbus_message_new_method_call(NULL, DP_PATH, DATA_PROVIDER_IFACE, DATA_PROVIDER_IFACE_GETDOMAINS); if (msg == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); return NULL; } DEBUG(SSSDBG_TRACE_FUNC, "Sending get domains request for [%s][%s]\n", info->dom->name, info->hint); /* Send the hint argument to provider as well. This will * be useful for some cases of transitional trust where * the server might not know all trusted domains */ dbret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &info->hint, DBUS_TYPE_INVALID); if (!dbret) { DEBUG(SSSDBG_OP_FAILURE ,"Failed to build message\n"); dbus_message_unref(msg); return NULL; } return msg; } static errno_t get_next_domain_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, dbus_uint16_t *dp_err, dbus_uint32_t *dp_ret, char **err_msg) { return sss_dp_req_recv(mem_ctx, req, dp_err, dp_ret, err_msg); } /* ====== Iterate over all domains, searching for their subdomains ======= */ static errno_t process_subdomains(struct sss_domain_info *dom); static void set_time_of_last_request(struct resp_ctx *rctx); static errno_t check_last_request(struct resp_ctx *rctx, const char *hint); struct sss_dp_get_domains_state { struct resp_ctx *rctx; struct sss_domain_info *dom; const char *hint; }; static void sss_dp_get_domains_process(struct tevent_req *subreq); struct tevent_req *sss_dp_get_domains_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, bool force, const char *hint) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct sss_dp_get_domains_state *state; req = tevent_req_create(mem_ctx, &state, struct sss_dp_get_domains_state); if (req == NULL) { return NULL; } if (rctx->domains == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "No domains configured.\n"); ret = EINVAL; goto immediately; } if (!force) { ret = check_last_request(rctx, hint); if (ret == EOK) { DEBUG(SSSDBG_TRACE_FUNC, "Last call was too recent, nothing to do!\n"); goto immediately; } else if (ret != EAGAIN) { DEBUG(SSSDBG_TRACE_FUNC, "check_domain_request failed with [%d][%s]\n", ret, strerror(ret)); goto immediately; } } state->rctx = rctx; if (hint != NULL) { state->hint = hint; } else { state->hint = talloc_strdup(state, ""); if (state->hint == NULL) { ret = ENOMEM; goto immediately; } } state->dom = rctx->domains; while(state->dom != NULL && !NEED_CHECK_PROVIDER(state->dom->provider)) { state->dom = get_next_domain(state->dom, 0); } if (state->dom == NULL) { /* All domains were local */ ret = EOK; goto immediately; } subreq = get_subdomains_send(req, rctx, state->dom, state->hint); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, sss_dp_get_domains_process, req); return req; immediately: if (ret == EOK) { set_time_of_last_request(rctx); tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, rctx->ev); return req; } static void sss_dp_get_domains_process(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sss_dp_get_domains_state *state = tevent_req_data(req, struct sss_dp_get_domains_state); dbus_uint16_t dp_err; dbus_uint32_t dp_ret; char *err_msg; ret = get_next_domain_recv(req, subreq, &dp_err, &dp_ret, &err_msg); talloc_zfree(subreq); if (ret != EOK) { goto fail; } ret = process_subdomains(state->dom); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "process_subdomains failed, " "trying next domain.\n"); goto fail; } /* Advance to the next domain */ state->dom = get_next_domain(state->dom, 0); /* Skip local domains */ while(state->dom != NULL && !NEED_CHECK_PROVIDER(state->dom->provider)) { state->dom = get_next_domain(state->dom, 0); } if (state->dom == NULL) { /* All domains were local */ set_time_of_last_request(state->rctx); tevent_req_done(req); return; } subreq = get_subdomains_send(req, state->rctx, state->dom, state->hint); if (subreq == NULL) { ret = ENOMEM; goto fail; } tevent_req_set_callback(subreq, sss_dp_get_domains_process, req); return; fail: tevent_req_error(req, ret); return; } static errno_t process_subdomains(struct sss_domain_info *domain) { int ret; if (domain->realm == NULL || domain->flat_name == NULL || domain->domain_id == NULL) { ret = sysdb_master_domain_update(domain); if (ret != EOK) { DEBUG(SSSDBG_FUNC_DATA, "sysdb_master_domain_get_info " \ "failed.\n"); goto done; } } /* Retrieve all subdomains of this domain from sysdb * and create their struct sss_domain_info representations */ ret = sysdb_update_subdomains(domain); if (ret != EOK) { DEBUG(SSSDBG_FUNC_DATA, "sysdb_update_subdomains failed.\n"); goto done; } errno = 0; ret = gettimeofday(&domain->subdomains_last_checked, NULL); if (ret == -1) { ret = errno; goto done; } ret = EOK; done: if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Failed to update sub-domains " "of domain [%s].\n", domain->name); } return ret; } errno_t sss_dp_get_domains_recv(struct tevent_req *req) { TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; } static void set_time_of_last_request(struct resp_ctx *rctx) { int ret; errno = 0; ret = gettimeofday(&rctx->get_domains_last_call, NULL); if (ret == -1) { ret = errno; DEBUG(SSSDBG_TRACE_FUNC, "gettimeofday failed [%d][%s].\n", ret, strerror(ret)); } } static errno_t check_last_request(struct resp_ctx *rctx, const char *hint) { struct sss_domain_info *dom; time_t now = time(NULL); time_t diff; diff = now - rctx->get_domains_last_call.tv_sec; if (diff >= rctx->domains_timeout) { /* Timeout, expired, fetch domains again */ return EAGAIN; } if (hint != NULL) { for (dom = rctx->domains; dom; dom = get_next_domain(dom, SSS_GND_DESCEND)) { if (!IS_SUBDOMAIN(dom)) { diff = now - dom->subdomains_last_checked.tv_sec; /* not a subdomain */ continue; } if (strcasecmp(dom->name, hint) == 0) { if (diff >= rctx->domains_timeout) { /* Timeout, expired, fetch domains again */ return EAGAIN; } } } } return EOK; } struct get_domains_state { struct resp_ctx *rctx; struct sss_nc_ctx *optional_ncache; }; static void get_domains_at_startup_done(struct tevent_req *req) { int ret; struct get_domains_state *state; state = tevent_req_callback_data(req, struct get_domains_state); ret = sss_dp_get_domains_recv(req); talloc_free(req); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_dp_get_domains request failed.\n"); } if (state->optional_ncache != NULL) { ret = sss_ncache_reset_repopulate_permanent(state->rctx, state->optional_ncache); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "sss_dp_get_domains request failed.\n"); } } talloc_free(state); return; } static void get_domains_at_startup(struct tevent_context *ev, struct tevent_immediate *imm, void *pvt) { struct tevent_req *req; struct get_domains_state *state; state = talloc_get_type(pvt, struct get_domains_state); req = sss_dp_get_domains_send(state, state->rctx, true, NULL); if (req == NULL) { DEBUG(SSSDBG_OP_FAILURE, "sss_dp_get_domains_send failed.\n"); talloc_free(state); return; } tevent_req_set_callback(req, get_domains_at_startup_done, state); return; } errno_t schedule_get_domains_task(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *optional_ncache) { struct tevent_immediate *imm; struct get_domains_state *state; state = talloc(mem_ctx, struct get_domains_state); if (state == NULL) { return ENOMEM; } state->rctx = rctx; state->optional_ncache = optional_ncache; imm = tevent_create_immediate(mem_ctx); if (imm == NULL) { DEBUG(SSSDBG_OP_FAILURE, "tevent_create_immediate failed.\n"); talloc_free(state); return ENOMEM; } tevent_schedule_immediate(imm, ev, get_domains_at_startup, state); return EOK; } struct sss_parse_inp_state { struct resp_ctx *rctx; const char *rawinp; char *name; char *domname; errno_t error; }; static void sss_parse_inp_done(struct tevent_req *subreq); struct tevent_req * sss_parse_inp_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, const char *rawinp) { errno_t ret; struct tevent_req *req; struct tevent_req *subreq; struct sss_parse_inp_state *state; req = tevent_req_create(mem_ctx, &state, struct sss_parse_inp_state); if (req == NULL) { return NULL; } state->rawinp = rawinp; state->rctx = rctx; /* If the subdomains haven't been checked yet, we need to always * attach to the post-startup subdomain request and only then parse * the input. Otherwise, we might not be able to parse input with a * flat domain name specifier */ if (rctx->get_domains_last_call.tv_sec > 0) { ret = sss_parse_name_for_domains(state, rctx->domains, rctx->default_domain, rawinp, &state->domname, &state->name); if (ret == EOK) { /* Was able to use cached domains */ goto done; } else if (ret != EAGAIN) { DEBUG(SSSDBG_OP_FAILURE, "Invalid name received [%s]\n", rawinp); ret = ERR_INPUT_PARSE; goto done; } } /* EAGAIN - check the DP for subdomains */ DEBUG(SSSDBG_FUNC_DATA, "Requesting info for [%s] from [%s]\n", state->name, state->domname ? state->domname : ""); /* We explicitly use force=false here. This request should decide itself * if it's time to re-use the cached subdomain list or refresh. If the * caller needs to specify the 'force' parameter, they should use the * sss_dp_get_domains_send() request itself */ subreq = sss_dp_get_domains_send(state, rctx, false, state->domname); if (subreq == NULL) { ret = ENOMEM; goto done; } tevent_req_set_callback(subreq, sss_parse_inp_done, req); return req; done: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, rctx->ev); return req; } static void sss_parse_inp_done(struct tevent_req *subreq) { errno_t ret; struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct sss_parse_inp_state *state = tevent_req_data(req, struct sss_parse_inp_state); ret = sss_dp_get_domains_recv(subreq); talloc_free(subreq); if (ret != EOK) { tevent_req_error(req, ret); return; } state->error = ERR_OK; ret = sss_parse_name_for_domains(state, state->rctx->domains, state->rctx->default_domain, state->rawinp, &state->domname, &state->name); if (ret == EAGAIN && state->domname != NULL && state->name == NULL) { DEBUG(SSSDBG_OP_FAILURE, "Unknown domain in [%s]\n", state->rawinp); state->error = ERR_DOMAIN_NOT_FOUND; } else if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Invalid name received [%s]\n", state->rawinp); state->error = ERR_INPUT_PARSE; } if (state->error != ERR_OK) { tevent_req_error(req, state->error); return; } /* Was able to parse the name now */ tevent_req_done(req); } errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **_name, char **_domname) { struct sss_parse_inp_state *state = tevent_req_data(req, struct sss_parse_inp_state); if (state->error != ERR_DOMAIN_NOT_FOUND) { TEVENT_REQ_RETURN_ON_ERROR(req); } if (_name) { *_name = talloc_steal(mem_ctx, state->name); } if (_domname) { *_domname = talloc_steal(mem_ctx, state->domname); } return state->error; } sssd-1.13.4/src/responder/common/PaxHeaders.16287/responder_sbus.h0000644000000000000000000000007312703456111021612 xustar0030 atime=1460561751.650715627 29 ctime=1460561774.45179294 sssd-1.13.4/src/responder/common/responder_sbus.h0000644002412700241270000000264012703456111023264 0ustar00jhrozekjhrozek00000000000000/* SSSD SSS Client Responder, common header file Copyright (C) Red Hat, 2012 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSS_RESPONDER_SBUS_H__ #define __SSS_RESPONDER_SBUS_H__ #define NSS_SBUS_SERVICE_NAME "nss" #define NSS_SBUS_SERVICE_VERSION 0x0001 #define SSS_PAM_SBUS_SERVICE_NAME "pam" #define SSS_PAM_SBUS_SERVICE_VERSION 0x0001 #define SSS_SUDO_SBUS_SERVICE_NAME "sudo" #define SSS_SUDO_SBUS_SERVICE_VERSION 0x0001 #define SSS_AUTOFS_SBUS_SERVICE_NAME "autofs" #define SSS_AUTOFS_SBUS_SERVICE_VERSION 0x0001 #define SSS_SSH_SBUS_SERVICE_NAME "ssh" #define SSS_SSH_SBUS_SERVICE_VERSION 0x0001 #define SSS_IFP_SBUS_SERVICE_NAME "ifp" #define SSS_IFP_SBUS_SERVICE_VERSION 0x0001 #define PAC_SBUS_SERVICE_NAME "pac" #define PAC_SBUS_SERVICE_VERSION 0x0001 #endif /* __SSS_RESPONDER_SBUS_H__ */ sssd-1.13.4/src/responder/common/PaxHeaders.16287/responder_packet.c0000644000000000000000000000007412703456111022101 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.925794548 sssd-1.13.4/src/responder/common/responder_packet.c0000644002412700241270000001651712703456111023562 0ustar00jhrozekjhrozek00000000000000/* SSSD SSS Client Responder, command parser Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include "util/util.h" #include "responder/common/responder_packet.h" #define SSSSRV_PACKET_MEM_SIZE 512 struct sss_packet { size_t memsize; /* Structure of the buffer: * Bytes Content * --------------------------------- * 0-15 packet header * 0-3 packet length (uint32_t) * 4-7 command type (uint32_t) * 8-11 status (uint32_t) * 12-15 reserved * 16+ packet body */ uint8_t *buffer; /* io pointer */ size_t iop; }; /* Offsets to data in sss_packet's buffer */ #define SSS_PACKET_LEN_OFFSET 0 #define SSS_PACKET_CMD_OFFSET sizeof(uint32_t) #define SSS_PACKET_ERR_OFFSET (2*(sizeof(uint32_t))) #define SSS_PACKET_BODY_OFFSET (4*(sizeof(uint32_t))) static void sss_packet_set_len(struct sss_packet *packet, uint32_t len); static void sss_packet_set_cmd(struct sss_packet *packet, enum sss_cli_command cmd); static uint32_t sss_packet_get_len(struct sss_packet *packet); /* * Allocate a new packet structure * * - if size is defined use it otherwise the default packet will be * SSSSRV_PACKET_MEM_SIZE bytes. */ int sss_packet_new(TALLOC_CTX *mem_ctx, size_t size, enum sss_cli_command cmd, struct sss_packet **rpacket) { struct sss_packet *packet; packet = talloc(mem_ctx, struct sss_packet); if (!packet) return ENOMEM; if (size) { int n = (size + SSS_NSS_HEADER_SIZE) % SSSSRV_PACKET_MEM_SIZE; packet->memsize = (n + 1) * SSSSRV_PACKET_MEM_SIZE; } else { packet->memsize = SSSSRV_PACKET_MEM_SIZE; } packet->buffer = talloc_size(packet, packet->memsize); if (!packet->buffer) { talloc_free(packet); return ENOMEM; } memset(packet->buffer, 0, SSS_NSS_HEADER_SIZE); sss_packet_set_len(packet, size + SSS_NSS_HEADER_SIZE); sss_packet_set_cmd(packet, cmd); packet->iop = 0; *rpacket = packet; return EOK; } /* grows a packet size only in SSSSRV_PACKET_MEM_SIZE chunks */ int sss_packet_grow(struct sss_packet *packet, size_t size) { size_t totlen, len; uint8_t *newmem; uint32_t packet_len; if (size == 0) { return EOK; } totlen = packet->memsize; packet_len = sss_packet_get_len(packet); len = packet_len + size; /* make sure we do not overflow */ if (totlen < len) { int n = len / SSSSRV_PACKET_MEM_SIZE + 1; totlen += n * SSSSRV_PACKET_MEM_SIZE; if (totlen < len) { return EINVAL; } } if (totlen > packet->memsize) { newmem = talloc_realloc_size(packet, packet->buffer, totlen); if (!newmem) { return ENOMEM; } packet->memsize = totlen; /* re-set pointers if realloc had to move memory */ if (newmem != packet->buffer) { packet->buffer = newmem; } } packet_len += size; sss_packet_set_len(packet, packet_len); return 0; } /* reclaim backet previously resrved space in the packet * usually done in functione recovering from not fatal erros */ int sss_packet_shrink(struct sss_packet *packet, size_t size) { size_t newlen; size_t oldlen = sss_packet_get_len(packet); if (size > oldlen) return EINVAL; newlen = oldlen - size; if (newlen < SSS_NSS_HEADER_SIZE) return EINVAL; sss_packet_set_len(packet, newlen); return 0; } int sss_packet_set_size(struct sss_packet *packet, size_t size) { size_t newlen; newlen = SSS_NSS_HEADER_SIZE + size; /* make sure we do not overflow */ if (packet->memsize < newlen) return EINVAL; sss_packet_set_len(packet, newlen); return 0; } int sss_packet_recv(struct sss_packet *packet, int fd) { size_t rb; size_t len; void *buf; buf = (uint8_t *)packet->buffer + packet->iop; if (packet->iop > 4) len = sss_packet_get_len(packet) - packet->iop; else len = packet->memsize - packet->iop; /* check for wrapping */ if (len > packet->memsize) { return EINVAL; } errno = 0; rb = recv(fd, buf, len, 0); if (rb == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { return EAGAIN; } else { return errno; } } if (rb == 0) { return ENODATA; } if (sss_packet_get_len(packet) > packet->memsize) { return EINVAL; } packet->iop += rb; if (packet->iop < 4) { return EAGAIN; } if (packet->iop < sss_packet_get_len(packet)) { return EAGAIN; } return EOK; } int sss_packet_send(struct sss_packet *packet, int fd) { size_t rb; size_t len; void *buf; if (!packet) { /* No packet object to write to? */ return EINVAL; } buf = packet->buffer + packet->iop; len = sss_packet_get_len(packet) - packet->iop; errno = 0; rb = send(fd, buf, len, 0); if (rb == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) { return EAGAIN; } else { return errno; } } if (rb == 0) { return EIO; } packet->iop += rb; if (packet->iop < sss_packet_get_len(packet)) { return EAGAIN; } return EOK; } enum sss_cli_command sss_packet_get_cmd(struct sss_packet *packet) { uint32_t cmd; SAFEALIGN_COPY_UINT32(&cmd, packet->buffer + SSS_PACKET_CMD_OFFSET, NULL); return (enum sss_cli_command)cmd; } uint32_t sss_packet_get_status(struct sss_packet *packet) { uint32_t status; SAFEALIGN_COPY_UINT32(&status, packet->buffer + SSS_PACKET_ERR_OFFSET, NULL); return status; } void sss_packet_get_body(struct sss_packet *packet, uint8_t **body, size_t *blen) { *body = packet->buffer + SSS_PACKET_BODY_OFFSET; *blen = sss_packet_get_len(packet) - SSS_NSS_HEADER_SIZE; } void sss_packet_set_error(struct sss_packet *packet, int error) { SAFEALIGN_SETMEM_UINT32(packet->buffer + SSS_PACKET_ERR_OFFSET, error, NULL); } static void sss_packet_set_len(struct sss_packet *packet, uint32_t len) { SAFEALIGN_SETMEM_UINT32(packet->buffer + SSS_PACKET_LEN_OFFSET, len, NULL); } static void sss_packet_set_cmd(struct sss_packet *packet, enum sss_cli_command cmd) { SAFEALIGN_SETMEM_UINT32(packet->buffer + SSS_PACKET_CMD_OFFSET, cmd, NULL); } static uint32_t sss_packet_get_len(struct sss_packet *packet) { uint32_t len; SAFEALIGN_COPY_UINT32(&len, packet->buffer + SSS_PACKET_LEN_OFFSET, NULL); return len; } sssd-1.13.4/src/responder/common/PaxHeaders.16287/responder_utils.c0000644000000000000000000000007412703456111021772 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.932794571 sssd-1.13.4/src/responder/common/responder_utils.c0000644002412700241270000001006612703456111023444 0ustar00jhrozekjhrozek00000000000000 /* SSSD Common Responder utility functions Copyright (C) Sumit Bose 2014 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "util/util.h" static inline bool attr_in_list(const char **list, size_t nlist, const char *str) { size_t i; for (i = 0; i < nlist; i++) { if (strcasecmp(list[i], str) == 0) { break; } } return (i < nlist) ? true : false; } const char **parse_attr_list_ex(TALLOC_CTX *mem_ctx, const char *conf_str, const char **defaults) { TALLOC_CTX *tmp_ctx; errno_t ret; const char **list = NULL; const char **res = NULL; int list_size; char **conf_list = NULL; int conf_list_size = 0; const char **allow = NULL; const char **deny = NULL; int ai = 0, di = 0, li = 0; int i; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return NULL; } if (conf_str) { ret = split_on_separator(tmp_ctx, conf_str, ',', true, true, &conf_list, &conf_list_size); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Cannot parse attribute ACL list %s: %d\n", conf_str, ret); goto done; } allow = talloc_zero_array(tmp_ctx, const char *, conf_list_size); deny = talloc_zero_array(tmp_ctx, const char *, conf_list_size); if (allow == NULL || deny == NULL) { goto done; } } for (i = 0; i < conf_list_size; i++) { switch (conf_list[i][0]) { case '+': allow[ai] = conf_list[i] + 1; ai++; continue; case '-': deny[di] = conf_list[i] + 1; di++; continue; default: DEBUG(SSSDBG_CRIT_FAILURE, "ACL values must start with " "either '+' (allow) or '-' (deny), got '%s'\n", conf_list[i]); goto done; } } /* Assume the output will have to hold defaults and all the configured, * values, resize later */ list_size = 0; if (defaults != NULL) { while (defaults[list_size]) { list_size++; } } list_size += conf_list_size; list = talloc_zero_array(tmp_ctx, const char *, list_size + 1); if (list == NULL) { goto done; } /* Start by copying explicitly allowed attributes */ for (i = 0; i < ai; i++) { /* if the attribute is explicitly denied, skip it */ if (attr_in_list(deny, di, allow[i])) { continue; } list[li] = talloc_strdup(list, allow[i]); if (list[li] == NULL) { goto done; } li++; DEBUG(SSSDBG_TRACE_INTERNAL, "Added allowed attr %s to whitelist\n", allow[i]); } /* Add defaults */ if (defaults != NULL) { for (i = 0; defaults[i]; i++) { /* if the attribute is explicitly denied, skip it */ if (attr_in_list(deny, di, defaults[i])) { continue; } list[li] = talloc_strdup(list, defaults[i]); if (list[li] == NULL) { goto done; } li++; DEBUG(SSSDBG_TRACE_INTERNAL, "Added default attr %s to whitelist\n", defaults[i]); } } res = talloc_steal(mem_ctx, list); done: talloc_free(tmp_ctx); return res; } sssd-1.13.4/src/responder/common/PaxHeaders.16287/responder_cache_req.c0000644000000000000000000000007412703456111022544 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.928794558 sssd-1.13.4/src/responder/common/responder_cache_req.c0000644002412700241270000012413712703456111024223 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "util/util.h" #include "db/sysdb.h" #include "responder/common/responder_cache_req.h" #include "providers/data_provider.h" static errno_t updated_users_by_filter(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_filter, time_t since, struct ldb_result **_res) { int ret; char *recent_filter; recent_filter = talloc_asprintf(mem_ctx, "(%s>=%lu)", SYSDB_LAST_UPDATE, since); ret = sysdb_enumpwent_filter_with_views(mem_ctx, domain, name_filter, recent_filter, _res); talloc_free(recent_filter); return ret; } static errno_t updated_groups_by_filter(TALLOC_CTX *mem_ctx, struct sss_domain_info *domain, const char *name_filter, time_t since, struct ldb_result **_res) { int ret; char *recent_filter; recent_filter = talloc_asprintf(mem_ctx, "(%s>=%lu)", SYSDB_LAST_UPDATE, since); ret = sysdb_enumgrent_filter_with_views(mem_ctx, domain, name_filter, recent_filter, _res); talloc_free(recent_filter); return ret; } struct cache_req_input { enum cache_req_type type; /* Provided input. */ const char *orig_name; uint32_t id; const char *cert; /* Parsed name or UPN. */ const char *name; /* Data Provider request type resolved from @type. * FIXME: This is currently needed for data provider calls. We should * refactor responder_dp.c to get rid of this member. */ enum sss_dp_acct_type dp_type; /* Domain related informations. */ struct sss_domain_info *domain; /* Name sanitized according to domain rules such as case sensitivity and * replacement of space character. This needs to be set up for each * domain separately. */ const char *dom_objname; /* Fully qualified object name used in debug messages. */ const char *debug_fqn; /* Time when the request started. Useful for by-filter lookups */ time_t req_start; }; struct cache_req_input * cache_req_input_create(TALLOC_CTX *mem_ctx, enum cache_req_type type, const char *name, uint32_t id, const char *cert) { struct cache_req_input *input; input = talloc_zero(mem_ctx, struct cache_req_input); if (input == NULL) { return NULL; } input->type = type; input->req_start = time(NULL); /* Check that input parameters match selected type. */ switch (input->type) { case CACHE_REQ_USER_BY_NAME: case CACHE_REQ_USER_BY_UPN: case CACHE_REQ_GROUP_BY_NAME: case CACHE_REQ_USER_BY_FILTER: case CACHE_REQ_GROUP_BY_FILTER: case CACHE_REQ_INITGROUPS: case CACHE_REQ_INITGROUPS_BY_UPN: if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL!\n"); goto fail; } input->orig_name = talloc_strdup(input, name); if (input->orig_name == NULL) { goto fail; } break; case CACHE_REQ_USER_BY_CERT: if (cert == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: certificate cannot be NULL!\n"); goto fail; } input->cert = talloc_strdup(input, cert); if (input->cert == NULL) { goto fail; } break; case CACHE_REQ_USER_BY_ID: case CACHE_REQ_GROUP_BY_ID: if (id == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0!\n"); goto fail; } input->id = id; break; } /* Resolve Data Provider request type. */ switch (type) { case CACHE_REQ_USER_BY_NAME: case CACHE_REQ_USER_BY_UPN: case CACHE_REQ_USER_BY_ID: input->dp_type = SSS_DP_USER; break; case CACHE_REQ_GROUP_BY_NAME: case CACHE_REQ_GROUP_BY_ID: input->dp_type = SSS_DP_GROUP; break; case CACHE_REQ_INITGROUPS: case CACHE_REQ_INITGROUPS_BY_UPN: input->dp_type = SSS_DP_INITGROUPS; break; case CACHE_REQ_USER_BY_CERT: input->dp_type = SSS_DP_CERT; break; case CACHE_REQ_USER_BY_FILTER: input->dp_type = SSS_DP_WILDCARD_USER; break; case CACHE_REQ_GROUP_BY_FILTER: input->dp_type = SSS_DP_WILDCARD_GROUP; break; } return input; fail: talloc_free(input); return NULL; } static errno_t cache_req_input_set_name(struct cache_req_input *input, const char *name) { const char *dup_name; dup_name = talloc_strdup(input, name); if (dup_name == NULL) { return ENOMEM; } talloc_zfree(input->name); input->name = dup_name; return EOK; } static errno_t cache_req_input_set_domain(struct cache_req_input *input, struct sss_domain_info *domain, struct resp_ctx *rctx) { TALLOC_CTX *tmp_ctx = NULL; const char *name = NULL; const char *debug_fqn = NULL; errno_t ret; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { return ENOMEM; } talloc_zfree(input->dom_objname); talloc_zfree(input->debug_fqn); switch (input->type) { case CACHE_REQ_USER_BY_NAME: case CACHE_REQ_USER_BY_UPN: case CACHE_REQ_GROUP_BY_NAME: case CACHE_REQ_USER_BY_FILTER: case CACHE_REQ_GROUP_BY_FILTER: case CACHE_REQ_INITGROUPS: case CACHE_REQ_INITGROUPS_BY_UPN: if (input->name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: input->name is NULL?\n"); ret = ERR_INTERNAL; goto done; } name = sss_get_cased_name(tmp_ctx, input->name, domain->case_sensitive); if (name == NULL) { ret = ENOMEM; goto done; } name = sss_reverse_replace_space(tmp_ctx, name, rctx->override_space); if (name == NULL) { ret = ENOMEM; goto done; } debug_fqn = talloc_asprintf(tmp_ctx, "%s@%s", name, domain->name); if (debug_fqn == NULL) { ret = ENOMEM; goto done; } break; case CACHE_REQ_USER_BY_ID: debug_fqn = talloc_asprintf(tmp_ctx, "UID:%d@%s", input->id, domain->name); if (debug_fqn == NULL) { ret = ENOMEM; goto done; } break; case CACHE_REQ_GROUP_BY_ID: debug_fqn = talloc_asprintf(tmp_ctx, "GID:%d@%s", input->id, domain->name); if (debug_fqn == NULL) { ret = ENOMEM; goto done; } break; case CACHE_REQ_USER_BY_CERT: /* certificates might be quite long, only use the last 10 charcters * for logging */ debug_fqn = talloc_asprintf(tmp_ctx, "CERT:%s@%s", get_last_x_chars(input->cert, 10), domain->name); if (debug_fqn == NULL) { ret = ENOMEM; goto done; } break; } input->domain = domain; input->dom_objname = talloc_steal(input, name); input->debug_fqn = talloc_steal(input, debug_fqn); ret = EOK; done: talloc_free(tmp_ctx); return ret; } static bool cache_req_input_is_upn(struct cache_req_input *input) { switch (input->type) { case CACHE_REQ_USER_BY_UPN: case CACHE_REQ_INITGROUPS_BY_UPN: return true; default: return false; } } static bool cache_req_input_assume_upn(struct cache_req_input *input) { errno_t ret; bool bret; if (input->orig_name == NULL || strchr(input->orig_name, '@') == NULL) { return false; } switch (input->type) { case CACHE_REQ_USER_BY_NAME: input->type = CACHE_REQ_USER_BY_UPN; bret = true; break; case CACHE_REQ_INITGROUPS: input->type = CACHE_REQ_INITGROUPS_BY_UPN; bret = true; break; default: bret = false; break; } if (bret == true) { ret = cache_req_input_set_name(input, input->orig_name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "cache_req_input_set_orig_name() failed\n"); return false; } DEBUG(SSSDBG_TRACE_FUNC, "Assuming UPN %s\n", input->orig_name); } return bret; } static errno_t cache_req_check_ncache(struct cache_req_input *input, struct sss_nc_ctx *ncache, int neg_timeout) { errno_t ret = ERR_INTERNAL; switch (input->type) { case CACHE_REQ_USER_BY_NAME: case CACHE_REQ_USER_BY_UPN: case CACHE_REQ_INITGROUPS: case CACHE_REQ_INITGROUPS_BY_UPN: ret = sss_ncache_check_user(ncache, neg_timeout, input->domain, input->dom_objname); break; case CACHE_REQ_GROUP_BY_NAME: ret = sss_ncache_check_group(ncache, neg_timeout, input->domain, input->dom_objname); break; case CACHE_REQ_USER_BY_ID: ret = sss_ncache_check_uid(ncache, neg_timeout, NULL, input->id); break; case CACHE_REQ_GROUP_BY_ID: ret = sss_ncache_check_gid(ncache, neg_timeout, NULL, input->id); break; case CACHE_REQ_USER_BY_CERT: ret = sss_ncache_check_cert(ncache, neg_timeout, input->cert); break; case CACHE_REQ_USER_BY_FILTER: case CACHE_REQ_GROUP_BY_FILTER: ret = EOK; break; } if (ret == EEXIST) { DEBUG(SSSDBG_TRACE_FUNC, "[%s] does not exist (negative cache)\n", input->debug_fqn); } return ret; } static void cache_req_add_to_ncache(struct cache_req_input *input, struct sss_nc_ctx *ncache) { errno_t ret = ERR_INTERNAL; switch (input->type) { case CACHE_REQ_USER_BY_NAME: case CACHE_REQ_USER_BY_UPN: case CACHE_REQ_INITGROUPS: case CACHE_REQ_INITGROUPS_BY_UPN: ret = sss_ncache_set_user(ncache, false, input->domain, input->dom_objname); break; case CACHE_REQ_GROUP_BY_NAME: ret = sss_ncache_set_group(ncache, false, input->domain, input->dom_objname); break; case CACHE_REQ_USER_BY_FILTER: case CACHE_REQ_GROUP_BY_FILTER: /* Nothing to do, adding a wildcard request to ncache doesn't * make sense */ case CACHE_REQ_USER_BY_ID: case CACHE_REQ_GROUP_BY_ID: case CACHE_REQ_USER_BY_CERT: /* Nothing to do. Those types must be unique among all domains so * the don't contain domain part. Therefore they must be set only * if all domains are search and the entry is not found. */ ret = EOK; break; } if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for [%s] [%d]: %s\n", input->debug_fqn, ret, sss_strerror(ret)); /* not fatal */ } return; } static void cache_req_add_to_ncache_global(struct cache_req_input *input, struct sss_nc_ctx *ncache) { errno_t ret = ERR_INTERNAL; switch (input->type) { case CACHE_REQ_USER_BY_FILTER: case CACHE_REQ_GROUP_BY_FILTER: /* Nothing to do, adding a wildcard request to ncache doesn't * make sense */ case CACHE_REQ_USER_BY_NAME: case CACHE_REQ_USER_BY_UPN: case CACHE_REQ_GROUP_BY_NAME: case CACHE_REQ_INITGROUPS: case CACHE_REQ_INITGROUPS_BY_UPN: /* Nothing to do. Those types are already in ncache for selected * domains. */ ret = EOK; break; case CACHE_REQ_USER_BY_ID: ret = sss_ncache_set_uid(ncache, false, NULL, input->id); break; case CACHE_REQ_GROUP_BY_ID: ret = sss_ncache_set_gid(ncache, false, NULL, input->id); break; case CACHE_REQ_USER_BY_CERT: ret = sss_ncache_set_cert(ncache, false, input->cert); break; } if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for [%s] [%d]: %s\n", input->debug_fqn, ret, sss_strerror(ret)); /* not fatal */ } return; } static errno_t cache_req_get_object(TALLOC_CTX *mem_ctx, struct cache_req_input *input, struct ldb_result **_result) { struct ldb_result *result = NULL; bool one_item_only = false; errno_t ret = ERR_INTERNAL; DEBUG(SSSDBG_FUNC_DATA, "Requesting info for [%s]\n", input->debug_fqn); switch (input->type) { case CACHE_REQ_USER_BY_NAME: one_item_only = true; ret = sysdb_getpwnam_with_views(mem_ctx, input->domain, input->dom_objname, &result); break; case CACHE_REQ_USER_BY_UPN: one_item_only = true; ret = sysdb_getpwupn(mem_ctx, input->domain, input->dom_objname, &result); break; case CACHE_REQ_USER_BY_ID: one_item_only = true; ret = sysdb_getpwuid_with_views(mem_ctx, input->domain, input->id, &result); break; case CACHE_REQ_GROUP_BY_NAME: one_item_only = true; ret = sysdb_getgrnam_with_views(mem_ctx, input->domain, input->dom_objname, &result); break; case CACHE_REQ_GROUP_BY_ID: one_item_only = true; ret = sysdb_getgrgid_with_views(mem_ctx, input->domain, input->id, &result); break; case CACHE_REQ_INITGROUPS: one_item_only = false; ret = sysdb_initgroups_with_views(mem_ctx, input->domain, input->dom_objname, &result); break; case CACHE_REQ_INITGROUPS_BY_UPN: one_item_only = false; ret = sysdb_initgroups_by_upn(mem_ctx, input->domain, input->dom_objname, &result); break; case CACHE_REQ_USER_BY_CERT: one_item_only = true; ret = sysdb_search_user_by_cert(mem_ctx, input->domain, input->cert, &result); break; case CACHE_REQ_USER_BY_FILTER: one_item_only = false; ret = updated_users_by_filter(mem_ctx, input->domain, input->dom_objname, input->req_start, &result); break; case CACHE_REQ_GROUP_BY_FILTER: one_item_only = false; ret = updated_groups_by_filter(mem_ctx, input->domain, input->dom_objname, input->req_start, &result); break; } if (ret != EOK) { goto done; } else if (result->count == 0) { ret = ENOENT; goto done; } else if (one_item_only && result->count > 1) { ret = ERR_INTERNAL; DEBUG(SSSDBG_CRIT_FAILURE, "Multiple objects were found when" "sysdb search expected only one!\n"); goto done; } *_result = result; done: return ret; } /* Return true if the request bypasses cache or false if the cache_req * code can leverage sysdb for this request. */ static bool cache_req_bypass_cache(struct cache_req_input *input) { if (input->type == CACHE_REQ_USER_BY_FILTER || input->type == CACHE_REQ_GROUP_BY_FILTER) { return true; } return false; } static errno_t cache_req_expiration_status(struct cache_req_input *input, struct ldb_result *result, time_t cache_refresh_percent) { time_t expire; if (result == NULL || result->count == 0 || cache_req_bypass_cache(input)) { return ENOENT; } if (input->type == CACHE_REQ_INITGROUPS) { expire = ldb_msg_find_attr_as_uint64(result->msgs[0], SYSDB_INITGR_EXPIRE, 0); } else { expire = ldb_msg_find_attr_as_uint64(result->msgs[0], SYSDB_CACHE_EXPIRE, 0); } return sss_cmd_check_cache(result->msgs[0], cache_refresh_percent, expire); } static void cache_req_dpreq_params(TALLOC_CTX *mem_ctx, struct cache_req_input *input, struct ldb_result *result, const char **_string, uint32_t *_id, const char **_flag) { struct ldb_result *user = NULL; const char *name = NULL; uint32_t id = 0; errno_t ret; *_id = input->id; *_string = input->dom_objname; *_flag = NULL; if (cache_req_input_is_upn(input)) { *_flag = EXTRA_NAME_IS_UPN; return; } if (input->type == CACHE_REQ_USER_BY_CERT) { *_string = input->cert; return; } if (!DOM_HAS_VIEWS(input->domain)) { return; } /* We must search with views. */ if (result == NULL || result->count == 0) { *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; return; } /* If domain has views we will try to user original values instead of the * overridden ones. This is a must for the LOCAL view since we can't look * it up otherwise. But it is also a shortcut for non-local views where * we will not fail over to the overridden value. */ switch (input->type) { case CACHE_REQ_USER_BY_NAME: case CACHE_REQ_GROUP_BY_NAME: name = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL\n"); } break; case CACHE_REQ_USER_BY_ID: id = ldb_msg_find_attr_as_uint64(result->msgs[0], SYSDB_UIDNUM, 0); if (id == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0\n"); } break; case CACHE_REQ_GROUP_BY_ID: id = ldb_msg_find_attr_as_uint64(result->msgs[0], SYSDB_GIDNUM, 0); if (id == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0\n"); } break; case CACHE_REQ_INITGROUPS: ret = sysdb_getpwnam_with_views(NULL, input->domain, input->dom_objname, &user); if (ret != EOK || user == NULL || user->count != 1) { /* Case where the user is not found has been already handled. If * this is not OK, it is an error. */ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to match initgroups user " "[%d]: %s\n", ret, sss_strerror(ret)); break; } name = ldb_msg_find_attr_as_string(user->msgs[0], SYSDB_NAME, NULL); if (name == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL\n"); break; } talloc_steal(mem_ctx, name); talloc_free(user); break; default: return; } /* Now we have the original name and id. We don't have to search with * views unless some error occurred. */ if (name == NULL && id == 0) { *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW; return; } *_string = talloc_steal(mem_ctx, name); *_id = id; } struct cache_req_cache_state { /* input data */ struct tevent_context *ev; struct resp_ctx *rctx; struct sss_nc_ctx *ncache; int neg_timeout; int cache_refresh_percent; struct cache_req_input *input; /* output data */ struct ldb_result *result; }; static errno_t cache_req_cache_search(struct tevent_req *req); static errno_t cache_req_cache_check(struct tevent_req *req); static void cache_req_cache_done(struct tevent_req *subreq); static struct tevent_req *cache_req_cache_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, struct cache_req_input *input) { struct cache_req_cache_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct cache_req_cache_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n")); return NULL; } state->ev = ev; state->rctx = rctx; state->ncache = ncache; state->neg_timeout = neg_timeout; state->cache_refresh_percent = cache_refresh_percent; state->input = input; /* Check negative cache first. */ ret = cache_req_check_ncache(state->input, state->ncache, state->neg_timeout); if (ret == EEXIST) { ret = ENOENT; goto immediately; } /* We will first search the cache. If we get cache miss or the entry * is expired we will contact data provider and then search again. */ ret = cache_req_cache_search(req); if (ret != EAGAIN) { goto immediately; } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static errno_t cache_req_cache_search(struct tevent_req *req) { struct cache_req_cache_state *state = NULL; errno_t ret; state = tevent_req_data(req, struct cache_req_cache_state); ret = cache_req_get_object(state, state->input, &state->result); if (ret != EOK && ret != ENOENT) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache " "[%d]: %s\n", ret, sss_strerror(ret)); return ret; } /* Verify that the cache is up to date. */ ret = cache_req_cache_check(req); if (req != EOK) { return ret; } /* One result found */ DEBUG(SSSDBG_TRACE_FUNC, "Returning info for [%s]\n", state->input->debug_fqn); return EOK; } static errno_t cache_req_cache_check(struct tevent_req *req) { struct cache_req_cache_state *state = NULL; struct tevent_req *subreq = NULL; const char *extra_flag = NULL; const char *search_str; uint32_t search_id; errno_t ret; state = tevent_req_data(req, struct cache_req_cache_state); cache_req_dpreq_params(state, state->input, state->result, &search_str, &search_id, &extra_flag); ret = cache_req_expiration_status(state->input, state->result, state->cache_refresh_percent); switch (ret) { case EOK: DEBUG(SSSDBG_TRACE_FUNC, "Cached entry is valid, returning...\n"); return EOK; case EAGAIN: /* Out of band update. The calling function will return the cached * entry immediately. No callback is required. */ DEBUG(SSSDBG_TRACE_FUNC, "Performing midpoint cache update\n"); subreq = sss_dp_get_account_send(state, state->rctx, state->input->domain, true, state->input->dp_type, search_str, search_id, extra_flag); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band " "data provider request\n"); /* This is non-fatal, so we'll continue here */ } else { DEBUG(SSSDBG_TRACE_FUNC, "Updating cache out-of-band\n"); } return EOK; case ENOENT: /* Cache miss or the cache is expired. We need to get the updated * information before returning it. */ subreq = sss_dp_get_account_send(state, state->rctx, state->input->domain, true, state->input->dp_type, search_str, search_id, extra_flag); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending data provider request\n"); return ENOMEM; } tevent_req_set_callback(subreq, cache_req_cache_done, req); return EAGAIN; default: /* error */ DEBUG(SSSDBG_CRIT_FAILURE, "Error checking cache [%d]: %s\n", ret, sss_strerror(ret)); return ret; } } static void cache_req_cache_done(struct tevent_req *subreq) { struct cache_req_cache_state *state = NULL; struct tevent_req *req = NULL; char *err_msg = NULL; dbus_uint16_t err_maj; dbus_uint32_t err_min; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct cache_req_cache_state); ret = sss_dp_get_account_recv(state, subreq, &err_maj, &err_min, &err_msg); talloc_zfree(subreq); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "Could not get account info [%d]: %s\n", ret, sss_strerror(ret)); } if (err_maj) { DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get information from Data Provider\n" "Error: %u, %u, %s\n" "Will try to return what we have in cache\n", (unsigned int)err_maj, (unsigned int)err_min, err_msg); } /* Get result from cache again. */ ret = cache_req_get_object(state, state->input, &state->result); if (ret == ENOENT) { cache_req_add_to_ncache(state->input, state->ncache); ret = ENOENT; } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache " "[%d]: %s\n", ret, sss_strerror(ret)); } if (ret != EOK) { tevent_req_error(req, ret); return; } /* One result found */ DEBUG(SSSDBG_TRACE_FUNC, "Returning info for [%s]\n", state->input->debug_fqn); tevent_req_done(req); } static errno_t cache_req_cache_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ldb_result **_result) { struct cache_req_cache_state *state = NULL; state = tevent_req_data(req, struct cache_req_cache_state); TEVENT_REQ_RETURN_ON_ERROR(req); *_result = talloc_steal(mem_ctx, state->result); return EOK; } struct cache_req_state { /* input data */ struct tevent_context *ev; struct resp_ctx *rctx; struct sss_nc_ctx *ncache; int neg_timeout; int cache_refresh_percent; struct cache_req_input *input; /* work data */ struct ldb_result *result; struct sss_domain_info *domain; struct sss_domain_info *selected_domain; bool check_next; }; static void cache_req_input_parsed(struct tevent_req *subreq); static errno_t cache_req_select_domains(struct tevent_req *req, const char *domain); static errno_t cache_req_next_domain(struct tevent_req *req); static void cache_req_done(struct tevent_req *subreq); struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, struct cache_req_input *input) { struct cache_req_state *state = NULL; struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct cache_req_state); if (req == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n")); return NULL; } state->ev = ev; state->rctx = rctx; state->ncache = ncache; state->neg_timeout = neg_timeout; state->cache_refresh_percent = cache_refresh_percent; state->input = input; if (state->input->orig_name != NULL && domain == NULL) { /* Parse input name first, since it may contain domain name. */ subreq = sss_parse_inp_send(state, rctx, input->orig_name); if (subreq == NULL) { ret = ENOMEM; goto immediately; } tevent_req_set_callback(subreq, cache_req_input_parsed, req); } else { if (input->orig_name != NULL) { ret = cache_req_input_set_name(input, input->orig_name); if (ret != EOK) { goto immediately; } } ret = cache_req_select_domains(req, domain); if (ret != EAGAIN) { goto immediately; } } return req; immediately: if (ret == EOK) { tevent_req_done(req); } else { tevent_req_error(req, ret); } tevent_req_post(req, ev); return req; } static void cache_req_input_parsed(struct tevent_req *subreq) { struct tevent_req *req; struct cache_req_state *state; char *name; char *domain; errno_t ret; bool maybe_upn; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct cache_req_state); ret = sss_parse_inp_recv(subreq, state, &name, &domain); switch (ret) { case EOK: ret = cache_req_input_set_name(state->input, name); if (ret != EOK) { tevent_req_error(req, ret); return; } break; case ERR_DOMAIN_NOT_FOUND: maybe_upn = cache_req_input_assume_upn(state->input); if (!maybe_upn) { tevent_req_error(req, ret); return; } domain = NULL; break; default: tevent_req_error(req, ret); return; } ret = cache_req_select_domains(req, domain); if (ret != EAGAIN) { tevent_req_error(req, ret); return; } } static errno_t cache_req_select_domains(struct tevent_req *req, const char *domain) { struct cache_req_state *state = NULL; state = tevent_req_data(req, struct cache_req_state); if (domain != NULL) { /* single-domain search */ state->domain = responder_get_domain(state->rctx, domain); if (state->domain == NULL) { return ERR_DOMAIN_NOT_FOUND; } state->check_next = false; } else { /* multi-domain search */ state->domain = state->rctx->domains; state->check_next = true; } return cache_req_next_domain(req); } static errno_t cache_req_next_domain(struct tevent_req *req) { struct cache_req_state *state = NULL; struct tevent_req *subreq = NULL; errno_t ret; state = tevent_req_data(req, struct cache_req_state); while (state->domain != NULL) { /* If it is a domainless search, skip domains that require fully * qualified names instead. */ while (state->domain != NULL && state->check_next && state->domain->fqnames && state->input->type != CACHE_REQ_USER_BY_CERT && !cache_req_input_is_upn(state->input)) { state->domain = get_next_domain(state->domain, 0); } state->selected_domain = state->domain; if (state->domain == NULL) { break; } ret = cache_req_input_set_domain(state->input, state->domain, state->rctx); if (ret != EOK) { return ret; } subreq = cache_req_cache_send(state, state->ev, state->rctx, state->ncache, state->neg_timeout, state->cache_refresh_percent, state->input); if (subreq == NULL) { return ENOMEM; } tevent_req_set_callback(subreq, cache_req_done, req); /* we will continue with the following domain the next time */ if (state->check_next) { if (cache_req_input_is_upn(state->input) || state->input->type == CACHE_REQ_USER_BY_CERT ) { state->domain = get_next_domain(state->domain, SSS_GND_DESCEND); } else { state->domain = get_next_domain(state->domain, 0); } } return EAGAIN; } /* If the object searched has to be unique among all maintained domains, * we have to add it into negative cache here when all domains have * been searched. */ cache_req_add_to_ncache_global(state->input, state->ncache); return ENOENT; } static void cache_req_done(struct tevent_req *subreq) { struct cache_req_state *state = NULL; struct tevent_req *req = NULL; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct cache_req_state); ret = cache_req_cache_recv(state, subreq, &state->result); talloc_zfree(subreq); if (ret == EOK) { tevent_req_done(req); return; } if (state->check_next == false) { if (ret == ENOENT && cache_req_input_assume_upn(state->input)) { /* search by upn now */ cache_req_select_domains(req, NULL); return; } tevent_req_error(req, ret); return; } ret = cache_req_next_domain(req); if (ret != EAGAIN) { tevent_req_error(req, ret); } return; } errno_t cache_req_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ldb_result **_result, struct sss_domain_info **_domain, char **_name) { struct cache_req_state *state = NULL; char *name; state = tevent_req_data(req, struct cache_req_state); TEVENT_REQ_RETURN_ON_ERROR(req); if (_name != NULL) { if (state->input->dom_objname == NULL) { *_name = NULL; } else { name = talloc_strdup(mem_ctx, state->input->name); if (name == NULL) { return ENOMEM; } *_name = name; } } if (_result != NULL) { *_result = talloc_steal(mem_ctx, state->result); } if (_domain != NULL) { *_domain = state->selected_domain; } return EOK; } static struct tevent_req * cache_req_steal_input_and_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, struct cache_req_input *input) { struct tevent_req *req; req = cache_req_send(mem_ctx, ev, rctx, ncache, neg_timeout, cache_refresh_percent, domain, input); if (req == NULL) { talloc_zfree(input); } talloc_steal(req, input); return req; } struct tevent_req * cache_req_user_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, const char *name) { struct cache_req_input *input; input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_NAME, name, 0, NULL); if (input == NULL) { return NULL; } return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache, neg_timeout, cache_refresh_percent, domain, input); } struct tevent_req * cache_req_user_by_id_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, uid_t uid) { struct cache_req_input *input; input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_ID, NULL, uid, NULL); if (input == NULL) { return NULL; } return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache, neg_timeout, cache_refresh_percent, domain, input); } struct tevent_req * cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, const char *pem_cert) { struct cache_req_input *input; input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_CERT, NULL, 0, pem_cert); if (input == NULL) { return NULL; } return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache, neg_timeout, cache_refresh_percent, domain, input); } struct tevent_req * cache_req_group_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, const char *name) { struct cache_req_input *input; input = cache_req_input_create(mem_ctx, CACHE_REQ_GROUP_BY_NAME, name, 0, NULL); if (input == NULL) { return NULL; } return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache, neg_timeout, cache_refresh_percent, domain, input); } struct tevent_req * cache_req_group_by_id_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, gid_t gid) { struct cache_req_input *input; input = cache_req_input_create(mem_ctx, CACHE_REQ_GROUP_BY_ID, NULL, gid, NULL); if (input == NULL) { return NULL; } return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache, neg_timeout, cache_refresh_percent, domain, input); } struct tevent_req * cache_req_initgr_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, const char *name) { struct cache_req_input *input; input = cache_req_input_create(mem_ctx, CACHE_REQ_INITGROUPS, name, 0, NULL); if (input == NULL) { return NULL; } return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache, neg_timeout, cache_refresh_percent, domain, input); } struct tevent_req * cache_req_user_by_filter_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, const char *domain, const char *filter) { struct cache_req_input *input; input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_FILTER, filter, 0, NULL); if (input == NULL) { return NULL; } return cache_req_steal_input_and_send(mem_ctx, ev, rctx, NULL, 0, 0, domain, input); } struct tevent_req * cache_req_group_by_filter_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, const char *domain, const char *filter) { struct cache_req_input *input; input = cache_req_input_create(mem_ctx, CACHE_REQ_GROUP_BY_FILTER, filter, 0, NULL); if (input == NULL) { return NULL; } return cache_req_steal_input_and_send(mem_ctx, ev, rctx, NULL, 0, 0, domain, input); } sssd-1.13.4/src/responder/common/PaxHeaders.16287/negcache.c0000644000000000000000000000007412703456111020306 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.926794551 sssd-1.13.4/src/responder/common/negcache.c0000644002412700241270000006506512703456111021771 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Responder Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "util/util.h" #include "confdb/confdb.h" #include "responder/common/responder.h" #include "responder/common/negcache.h" #include #include #include "tdb.h" #define NC_ENTRY_PREFIX "NCE/" #define NC_USER_PREFIX NC_ENTRY_PREFIX"USER" #define NC_GROUP_PREFIX NC_ENTRY_PREFIX"GROUP" #define NC_NETGROUP_PREFIX NC_ENTRY_PREFIX"NETGR" #define NC_SERVICE_PREFIX NC_ENTRY_PREFIX"SERVICE" #define NC_UID_PREFIX NC_ENTRY_PREFIX"UID" #define NC_GID_PREFIX NC_ENTRY_PREFIX"GID" #define NC_SID_PREFIX NC_ENTRY_PREFIX"SID" #define NC_CERT_PREFIX NC_ENTRY_PREFIX"CERT" struct sss_nc_ctx { struct tdb_context *tdb; }; typedef int (*ncache_set_byname_fn_t)(struct sss_nc_ctx *, bool, const char *, const char *); static int sss_ncache_set_ent(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, const char *name, ncache_set_byname_fn_t setter); static int string_to_tdb_data(char *str, TDB_DATA *ret) { if (!str || !ret) return EINVAL; ret->dptr = (uint8_t *)str; ret->dsize = strlen(str)+1; return EOK; } int sss_ncache_init(TALLOC_CTX *memctx, struct sss_nc_ctx **_ctx) { struct sss_nc_ctx *ctx; ctx = talloc_zero(memctx, struct sss_nc_ctx); if (!ctx) return ENOMEM; errno = 0; /* open a memory only tdb with default hash size */ ctx->tdb = tdb_open("memcache", 0, TDB_INTERNAL, O_RDWR|O_CREAT, 0); if (!ctx->tdb) return errno; *_ctx = ctx; return EOK; }; static int sss_ncache_check_str(struct sss_nc_ctx *ctx, char *str, int ttl) { TDB_DATA key; TDB_DATA data; unsigned long long int timestamp; bool expired = false; char *ep; int ret; DEBUG(SSSDBG_TRACE_INTERNAL, "Checking negative cache for [%s]\n", str); data.dptr = NULL; ret = string_to_tdb_data(str, &key); if (ret != EOK) goto done; data = tdb_fetch(ctx->tdb, key); if (!data.dptr) { ret = ENOENT; goto done; } if (ttl == -1) { /* a negative ttl means: never expires */ ret = EEXIST; goto done; } errno = 0; timestamp = strtoull((const char *)data.dptr, &ep, 10); if (errno != 0 || *ep != '\0') { /* Malformed entry, remove it and return no entry */ expired = true; goto done; } if (timestamp == 0) { /* a 0 timestamp means this is a permanent entry */ ret = EEXIST; goto done; } if (timestamp + ttl >= time(NULL)) { /* still valid */ ret = EEXIST; goto done; } expired = true; done: if (expired) { /* expired, remove and return no entry */ tdb_delete(ctx->tdb, key); ret = ENOENT; } free(data.dptr); return ret; } static int sss_ncache_set_str(struct sss_nc_ctx *ctx, char *str, bool permanent) { TDB_DATA key; TDB_DATA data; char *timest; int ret; ret = string_to_tdb_data(str, &key); if (ret != EOK) return ret; if (permanent) { timest = talloc_strdup(ctx, "0"); } else { timest = talloc_asprintf(ctx, "%llu", (unsigned long long int)time(NULL)); } if (!timest) return ENOMEM; ret = string_to_tdb_data(timest, &data); if (ret != EOK) goto done; DEBUG(SSSDBG_TRACE_FUNC, "Adding [%s] to negative cache%s\n", str, permanent?" permanently":""); ret = tdb_store(ctx->tdb, key, data, TDB_REPLACE); if (ret != 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Negative cache failed to set entry: [%s]\n", tdb_errorstr(ctx->tdb)); ret = EFAULT; } done: talloc_free(timest); return ret; } static int sss_ncache_check_user_int(struct sss_nc_ctx *ctx, int ttl, const char *domain, const char *name) { char *str; int ret; if (!name || !*name) return EINVAL; str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name); if (!str) return ENOMEM; ret = sss_ncache_check_str(ctx, str, ttl); talloc_free(str); return ret; } static int sss_ncache_check_group_int(struct sss_nc_ctx *ctx, int ttl, const char *domain, const char *name) { char *str; int ret; if (!name || !*name) return EINVAL; str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name); if (!str) return ENOMEM; ret = sss_ncache_check_str(ctx, str, ttl); talloc_free(str); return ret; } static int sss_ncache_check_netgr_int(struct sss_nc_ctx *ctx, int ttl, const char *domain, const char *name) { char *str; int ret; if (!name || !*name) return EINVAL; str = talloc_asprintf(ctx, "%s/%s/%s", NC_NETGROUP_PREFIX, domain, name); if (!str) return ENOMEM; ret = sss_ncache_check_str(ctx, str, ttl); talloc_free(str); return ret; } static int sss_ncache_check_service_int(struct sss_nc_ctx *ctx, int ttl, const char *domain, const char *name) { char *str; int ret; if (!name || !*name) return EINVAL; str = talloc_asprintf(ctx, "%s/%s/%s", NC_SERVICE_PREFIX, domain, name); if (!str) return ENOMEM; ret = sss_ncache_check_str(ctx, str, ttl); talloc_free(str); return ret; } typedef int (*ncache_check_byname_fn_t)(struct sss_nc_ctx *, int, const char *, const char *); static int sss_cache_check_ent(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, const char *name, ncache_check_byname_fn_t checker) { char *lower; errno_t ret; if (dom->case_sensitive == false) { lower = sss_tc_utf8_str_tolower(ctx, name); if (!lower) return ENOMEM; ret = checker(ctx, ttl, dom->name, lower); talloc_free(lower); } else { ret = checker(ctx, ttl, dom->name, name); } return ret; } int sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, const char *name) { return sss_cache_check_ent(ctx, ttl, dom, name, sss_ncache_check_user_int); } int sss_ncache_check_group(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, const char *name) { return sss_cache_check_ent(ctx, ttl, dom, name, sss_ncache_check_group_int); } int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, const char *name) { return sss_cache_check_ent(ctx, ttl, dom, name, sss_ncache_check_netgr_int); } static int sss_ncache_set_service_int(struct sss_nc_ctx *ctx, bool permanent, const char *domain, const char *name) { char *str; int ret; if (!name || !*name) return EINVAL; str = talloc_asprintf(ctx, "%s/%s/%s", NC_SERVICE_PREFIX, domain, name); if (!str) return ENOMEM; ret = sss_ncache_set_str(ctx, str, permanent); talloc_free(str); return ret; } int sss_ncache_set_service_name(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, const char *name, const char *proto) { int ret; char *service_and_protocol = talloc_asprintf(ctx, "%s:%s", name, proto ? proto : ""); if (!service_and_protocol) return ENOMEM; ret = sss_ncache_set_ent(ctx, permanent, dom, service_and_protocol, sss_ncache_set_service_int); talloc_free(service_and_protocol); return ret; } int sss_ncache_check_service(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, const char *name, const char *proto) { int ret; char *service_and_protocol = talloc_asprintf(ctx, "%s:%s", name, proto ? proto : ""); if (!service_and_protocol) return ENOMEM; ret = sss_cache_check_ent(ctx, ttl, dom, service_and_protocol, sss_ncache_check_service_int); talloc_free(service_and_protocol); return ret; } int sss_ncache_set_service_port(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, uint16_t port, const char *proto) { int ret; char *service_and_protocol = talloc_asprintf(ctx, "%ul:%s", port, proto ? proto : ""); if (!service_and_protocol) return ENOMEM; ret = sss_ncache_set_ent(ctx, permanent, dom, service_and_protocol, sss_ncache_set_service_int); talloc_free(service_and_protocol); return ret; } int sss_ncache_check_service_port(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, uint16_t port, const char *proto) { int ret; char *service_and_protocol = talloc_asprintf(ctx, "%ul:%s", port, proto ? proto : ""); if (!service_and_protocol) return ENOMEM; ret = sss_cache_check_ent(ctx, ttl, dom, service_and_protocol, sss_ncache_check_service_int); talloc_free(service_and_protocol); return ret; } int sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, uid_t uid) { char *str; int ret; if (dom != NULL) { str = talloc_asprintf(ctx, "%s/%s/%"SPRIuid, NC_UID_PREFIX, dom->name, uid); } else { str = talloc_asprintf(ctx, "%s/%"SPRIuid, NC_UID_PREFIX, uid); } if (!str) return ENOMEM; ret = sss_ncache_check_str(ctx, str, ttl); talloc_free(str); return ret; } int sss_ncache_check_gid(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, gid_t gid) { char *str; int ret; if (dom != NULL) { str = talloc_asprintf(ctx, "%s/%s/%"SPRIgid, NC_GID_PREFIX, dom->name, gid); } else { str = talloc_asprintf(ctx, "%s/%"SPRIgid, NC_GID_PREFIX, gid); } if (!str) return ENOMEM; ret = sss_ncache_check_str(ctx, str, ttl); talloc_free(str); return ret; } int sss_ncache_check_sid(struct sss_nc_ctx *ctx, int ttl, const char *sid) { char *str; int ret; str = talloc_asprintf(ctx, "%s/%s", NC_SID_PREFIX, sid); if (!str) return ENOMEM; ret = sss_ncache_check_str(ctx, str, ttl); talloc_free(str); return ret; } int sss_ncache_check_cert(struct sss_nc_ctx *ctx, int ttl, const char *cert) { char *str; int ret; str = talloc_asprintf(ctx, "%s/%s", NC_CERT_PREFIX, cert); if (!str) return ENOMEM; ret = sss_ncache_check_str(ctx, str, ttl); talloc_free(str); return ret; } static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, bool permanent, const char *domain, const char *name) { char *str; int ret; if (!name || !*name) return EINVAL; str = talloc_asprintf(ctx, "%s/%s/%s", NC_USER_PREFIX, domain, name); if (!str) return ENOMEM; ret = sss_ncache_set_str(ctx, str, permanent); talloc_free(str); return ret; } static int sss_ncache_set_group_int(struct sss_nc_ctx *ctx, bool permanent, const char *domain, const char *name) { char *str; int ret; if (!name || !*name) return EINVAL; str = talloc_asprintf(ctx, "%s/%s/%s", NC_GROUP_PREFIX, domain, name); if (!str) return ENOMEM; ret = sss_ncache_set_str(ctx, str, permanent); talloc_free(str); return ret; } static int sss_ncache_set_netgr_int(struct sss_nc_ctx *ctx, bool permanent, const char *domain, const char *name) { char *str; int ret; if (!name || !*name) return EINVAL; str = talloc_asprintf(ctx, "%s/%s/%s", NC_NETGROUP_PREFIX, domain, name); if (!str) return ENOMEM; ret = sss_ncache_set_str(ctx, str, permanent); talloc_free(str); return ret; } static int sss_ncache_set_ent(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, const char *name, ncache_set_byname_fn_t setter) { char *lower; errno_t ret; if (dom->case_sensitive == false) { lower = sss_tc_utf8_str_tolower(ctx, name); if (!lower) return ENOMEM; ret = setter(ctx, permanent, dom->name, lower); talloc_free(lower); } else { ret = setter(ctx, permanent, dom->name, name); } return ret; } int sss_ncache_set_user(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, const char *name) { return sss_ncache_set_ent(ctx, permanent, dom, name, sss_ncache_set_user_int); } int sss_ncache_set_group(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, const char *name) { return sss_ncache_set_ent(ctx, permanent, dom, name, sss_ncache_set_group_int); } int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, const char *name) { return sss_ncache_set_ent(ctx, permanent, dom, name, sss_ncache_set_netgr_int); } int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, uid_t uid) { char *str; int ret; if (dom != NULL) { str = talloc_asprintf(ctx, "%s/%s/%"SPRIuid, NC_UID_PREFIX, dom->name, uid); } else { str = talloc_asprintf(ctx, "%s/%"SPRIuid, NC_UID_PREFIX, uid); } if (!str) return ENOMEM; ret = sss_ncache_set_str(ctx, str, permanent); talloc_free(str); return ret; } int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, gid_t gid) { char *str; int ret; if (dom != NULL) { str = talloc_asprintf(ctx, "%s/%s/%"SPRIgid, NC_GID_PREFIX, dom->name, gid); } else { str = talloc_asprintf(ctx, "%s/%"SPRIgid, NC_GID_PREFIX, gid); } if (!str) return ENOMEM; ret = sss_ncache_set_str(ctx, str, permanent); talloc_free(str); return ret; } int sss_ncache_set_sid(struct sss_nc_ctx *ctx, bool permanent, const char *sid) { char *str; int ret; str = talloc_asprintf(ctx, "%s/%s", NC_SID_PREFIX, sid); if (!str) return ENOMEM; ret = sss_ncache_set_str(ctx, str, permanent); talloc_free(str); return ret; } int sss_ncache_set_cert(struct sss_nc_ctx *ctx, bool permanent, const char *cert) { char *str; int ret; str = talloc_asprintf(ctx, "%s/%s", NC_CERT_PREFIX, cert); if (!str) return ENOMEM; ret = sss_ncache_set_str(ctx, str, permanent); talloc_free(str); return ret; } static int delete_permanent(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) { unsigned long long int timestamp; bool remove_key = false; char *ep; if (strncmp((char *)key.dptr, NC_ENTRY_PREFIX, sizeof(NC_ENTRY_PREFIX) - 1) != 0) { /* not interested in this key */ return 0; } errno = 0; timestamp = strtoull((const char *)data.dptr, &ep, 10); if (errno != 0 || *ep != '\0') { /* Malformed entry, remove it */ remove_key = true; goto done; } if (timestamp == 0) { /* a 0 timestamp means this is a permanent entry */ remove_key = true; } done: if (remove_key) { return tdb_delete(tdb, key); } return 0; } int sss_ncache_reset_permanent(struct sss_nc_ctx *ctx) { int ret; ret = tdb_traverse(ctx->tdb, delete_permanent, NULL); if (ret < 0) return EIO; return EOK; } errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, struct confdb_ctx *cdb, struct resp_ctx *rctx) { errno_t ret; bool filter_set = false; char **filter_list = NULL; char *name = NULL; struct sss_domain_info *dom = NULL; struct sss_domain_info *domain_list = rctx->domains; char *domainname = NULL; char *conf_path = NULL; TALLOC_CTX *tmpctx = talloc_new(NULL); int i; /* Populate domain-specific negative cache entries */ for (dom = domain_list; dom; dom = get_next_domain(dom, 0)) { conf_path = talloc_asprintf(tmpctx, CONFDB_DOMAIN_PATH_TMPL, dom->name); if (!conf_path) { ret = ENOMEM; goto done; } talloc_zfree(filter_list); ret = confdb_get_string_as_list(cdb, tmpctx, conf_path, CONFDB_NSS_FILTER_USERS, &filter_list); if (ret == ENOENT) continue; if (ret != EOK) goto done; filter_set = true; for (i = 0; (filter_list && filter_list[i]); i++) { ret = sss_parse_name_for_domains(tmpctx, domain_list, rctx->default_domain, filter_list[i], &domainname, &name); if (ret == EAGAIN) { DEBUG(SSSDBG_MINOR_FAILURE, "cannot add [%s] to negcache because the required or " "default domain are not known yet\n", filter_list[i]); } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid name in filterUsers list: [%s] (%d)\n", filter_list[i], ret); continue; } if (domainname && strcmp(domainname, dom->name)) { DEBUG(SSSDBG_CRIT_FAILURE, "Mismatch between domain name (%s) and name " "set in FQN (%s), skipping user %s\n", dom->name, domainname, name); continue; } ret = sss_ncache_set_user(ncache, true, dom, name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store permanent user filter for [%s]" " (%d [%s])\n", filter_list[i], ret, strerror(ret)); continue; } } } ret = confdb_get_string_as_list(cdb, tmpctx, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_FILTER_USERS, &filter_list); if (ret == ENOENT) { if (!filter_set) { filter_list = talloc_array(tmpctx, char *, 2); if (!filter_list) { ret = ENOMEM; goto done; } filter_list[0] = talloc_strdup(tmpctx, "root"); if (!filter_list[0]) { ret = ENOMEM; goto done; } filter_list[1] = NULL; } } else if (ret != EOK) goto done; for (i = 0; (filter_list && filter_list[i]); i++) { ret = sss_parse_name_for_domains(tmpctx, domain_list, rctx->default_domain, filter_list[i], &domainname, &name); if (ret == EAGAIN) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot add [%s] to negcache because the required or " "default domain are not known yet\n", filter_list[i]); } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid name in filterUsers list: [%s] (%d)\n", filter_list[i], ret); continue; } if (domainname) { dom = responder_get_domain(rctx, domainname); if (!dom) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid domain name [%s]\n", domainname); continue; } ret = sss_ncache_set_user(ncache, true, dom, name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store permanent user filter for [%s]" " (%d [%s])\n", filter_list[i], ret, strerror(ret)); continue; } } else { for (dom = domain_list; dom; dom = get_next_domain(dom, 0)) { ret = sss_ncache_set_user(ncache, true, dom, name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store permanent user filter for" " [%s:%s] (%d [%s])\n", dom->name, filter_list[i], ret, strerror(ret)); continue; } } } } filter_set = false; for (dom = domain_list; dom; dom = get_next_domain(dom, 0)) { conf_path = talloc_asprintf(tmpctx, CONFDB_DOMAIN_PATH_TMPL, dom->name); if (!conf_path) { ret = ENOMEM; goto done; } talloc_zfree(filter_list); ret = confdb_get_string_as_list(cdb, tmpctx, conf_path, CONFDB_NSS_FILTER_GROUPS, &filter_list); if (ret == ENOENT) continue; if (ret != EOK) goto done; filter_set = true; for (i = 0; (filter_list && filter_list[i]); i++) { ret = sss_parse_name(tmpctx, dom->names, filter_list[i], &domainname, &name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid name in filterGroups list: [%s] (%d)\n", filter_list[i], ret); continue; } if (domainname && strcmp(domainname, dom->name)) { DEBUG(SSSDBG_CRIT_FAILURE, "Mismatch between domain name (%s) and name " "set in FQN (%s), skipping group %s\n", dom->name, domainname, name); continue; } ret = sss_ncache_set_group(ncache, true, dom, name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store permanent group filter for [%s]" " (%d [%s])\n", filter_list[i], ret, strerror(ret)); continue; } } } ret = confdb_get_string_as_list(cdb, tmpctx, CONFDB_NSS_CONF_ENTRY, CONFDB_NSS_FILTER_GROUPS, &filter_list); if (ret == ENOENT) { if (!filter_set) { filter_list = talloc_array(tmpctx, char *, 2); if (!filter_list) { ret = ENOMEM; goto done; } filter_list[0] = talloc_strdup(tmpctx, "root"); if (!filter_list[0]) { ret = ENOMEM; goto done; } filter_list[1] = NULL; } } else if (ret != EOK) goto done; for (i = 0; (filter_list && filter_list[i]); i++) { ret = sss_parse_name_for_domains(tmpctx, domain_list, rctx->default_domain, filter_list[i], &domainname, &name); if (ret == EAGAIN) { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot add [%s] to negcache because the required or " "default domain are not known yet\n", filter_list[i]); } else if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid name in filterGroups list: [%s] (%d)\n", filter_list[i], ret); continue; } if (domainname) { dom = responder_get_domain(rctx, domainname); if (!dom) { DEBUG(SSSDBG_CRIT_FAILURE, "Invalid domain name [%s]\n", domainname); continue; } ret = sss_ncache_set_group(ncache, true, dom, name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store permanent group filter for" " [%s] (%d [%s])\n", filter_list[i], ret, strerror(ret)); continue; } } else { for (dom = domain_list; dom; dom = get_next_domain(dom, 0)) { ret = sss_ncache_set_group(ncache, true, dom, name); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to store permanent group filter for" " [%s:%s] (%d [%s])\n", dom->name, filter_list[i], ret, strerror(ret)); continue; } } } } ret = EOK; done: talloc_free(tmpctx); return ret; } /* Reset permanent negcache after checking the domains */ errno_t sss_ncache_reset_repopulate_permanent(struct resp_ctx *rctx, struct sss_nc_ctx *ncache) { int ret; ret = sss_ncache_reset_permanent(ncache); if (ret == EOK) { ret = sss_ncache_prepopulate(ncache, rctx->cdb, rctx); } return ret; } sssd-1.13.4/src/responder/common/PaxHeaders.16287/responder_cache_req.h0000644000000000000000000000007412703456111022551 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.453792947 sssd-1.13.4/src/responder/common/responder_cache_req.h0000644002412700241270000001460512703456111024226 0ustar00jhrozekjhrozek00000000000000/* Authors: Pavel Březina Copyright (C) 2014 Red Hat This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef RESPONDER_CACHE_H_ #define RESPONDER_CACHE_H_ #include #include #include "db/sysdb.h" #include "responder/common/responder.h" #include "responder/common/negcache.h" enum cache_req_type { CACHE_REQ_USER_BY_NAME, CACHE_REQ_USER_BY_UPN, CACHE_REQ_USER_BY_ID, CACHE_REQ_GROUP_BY_NAME, CACHE_REQ_GROUP_BY_ID, CACHE_REQ_INITGROUPS, CACHE_REQ_INITGROUPS_BY_UPN, CACHE_REQ_USER_BY_CERT, CACHE_REQ_USER_BY_FILTER, CACHE_REQ_GROUP_BY_FILTER }; struct cache_req_input; struct cache_req_input * cache_req_input_create(TALLOC_CTX *mem_ctx, enum cache_req_type type, const char *name, uint32_t id, const char *cert); /** * Currently only SSS_DP_USER and SSS_DP_INITGROUPS are supported. * * @todo support other request types */ struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, struct cache_req_input *input); errno_t cache_req_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ldb_result **_result, struct sss_domain_info **_domain, char **_name); struct tevent_req * cache_req_user_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, const char *name); #define cache_req_user_by_name_recv(mem_ctx, req, _result, _domain, _name) \ cache_req_recv(mem_ctx, req, _result, _domain, _name) struct tevent_req * cache_req_user_by_id_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, uid_t uid); #define cache_req_user_by_id_recv(mem_ctx, req, _result, _domain) \ cache_req_recv(mem_ctx, req, _result, _domain, NULL) struct tevent_req * cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, const char *pem_cert); #define cache_req_user_by_cert_recv(mem_ctx, req, _result, _domain, _name) \ cache_req_recv(mem_ctx, req, _result, _domain, _name) struct tevent_req * cache_req_group_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, const char *name); #define cache_req_group_by_name_recv(mem_ctx, req, _result, _domain, _name) \ cache_req_recv(mem_ctx, req, _result, _domain, _name) struct tevent_req * cache_req_group_by_id_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, gid_t gid); #define cache_req_group_by_id_recv(mem_ctx, req, _result, _domain) \ cache_req_recv(mem_ctx, req, _result, _domain, NULL) struct tevent_req * cache_req_initgr_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, struct sss_nc_ctx *ncache, int neg_timeout, int cache_refresh_percent, const char *domain, const char *name); #define cache_req_initgr_by_name_recv(mem_ctx, req, _result, _domain, _name) \ cache_req_recv(mem_ctx, req, _result, _domain, _name) struct tevent_req * cache_req_user_by_filter_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, const char *domain, const char *filter); #define cache_req_user_by_filter_recv(mem_ctx, req, _result, _domain) \ cache_req_recv(mem_ctx, req, _result, _domain, NULL) struct tevent_req * cache_req_group_by_filter_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct resp_ctx *rctx, const char *domain, const char *filter); #define cache_req_group_by_filter_recv(mem_ctx, req, _result, _domain) \ cache_req_recv(mem_ctx, req, _result, _domain, NULL) #endif /* RESPONDER_CACHE_H_ */ sssd-1.13.4/src/responder/common/PaxHeaders.16287/responder_packet.h0000644000000000000000000000007412703456111022106 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.449792934 sssd-1.13.4/src/responder/common/responder_packet.h0000644002412700241270000000317012703456111023556 0ustar00jhrozekjhrozek00000000000000/* SSSD SSS Client Responder, header file Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __SSSSRV_PACKET_H__ #define __SSSSRV_PACKET_H__ #include "sss_client/sss_cli.h" #define SSS_PACKET_MAX_RECV_SIZE 1024 struct sss_packet; int sss_packet_new(TALLOC_CTX *mem_ctx, size_t size, enum sss_cli_command cmd, struct sss_packet **rpacket); int sss_packet_grow(struct sss_packet *packet, size_t size); int sss_packet_shrink(struct sss_packet *packet, size_t size); int sss_packet_set_size(struct sss_packet *packet, size_t size); int sss_packet_recv(struct sss_packet *packet, int fd); int sss_packet_send(struct sss_packet *packet, int fd); enum sss_cli_command sss_packet_get_cmd(struct sss_packet *packet); uint32_t sss_packet_get_status(struct sss_packet *packet); void sss_packet_get_body(struct sss_packet *packet, uint8_t **body, size_t *blen); void sss_packet_set_error(struct sss_packet *packet, int error); #endif /* __SSSSRV_PACKET_H__ */ sssd-1.13.4/src/responder/common/PaxHeaders.16287/negcache.h0000644000000000000000000000007412703456111020313 xustar0030 atime=1460561751.650715627 30 ctime=1460561774.472793012 sssd-1.13.4/src/responder/common/negcache.h0000644002412700241270000001031412703456111021761 0ustar00jhrozekjhrozek00000000000000/* SSSD NSS Responder Copyright (C) Simo Sorce 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef _NSS_NEG_CACHE_H_ #define _NSS_NEG_CACHE_H_ struct sss_nc_ctx; /* init the in memory negative cache */ int sss_ncache_init(TALLOC_CTX *memctx, struct sss_nc_ctx **_ctx); /* check if the user is expired according to the passed in time to live */ int sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, const char *name); int sss_ncache_check_group(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, const char *name); int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, const char *name); int sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, uid_t uid); int sss_ncache_check_gid(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, gid_t gid); int sss_ncache_check_sid(struct sss_nc_ctx *ctx, int ttl, const char *sid); int sss_ncache_check_cert(struct sss_nc_ctx *ctx, int ttl, const char *cert); int sss_ncache_check_service(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, const char *name, const char *proto); int sss_ncache_check_service_port(struct sss_nc_ctx *ctx, int ttl, struct sss_domain_info *dom, uint16_t port, const char *proto); /* add a new neg-cache entry setting the timestamp to "now" unless * "permanent" is set to true, in which case the timestamps is set to 0 * and the negative cache never expires (used to permanently filter out * users and groups) */ int sss_ncache_set_user(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, const char *name); int sss_ncache_set_group(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, const char *name); int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, const char *name); int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, uid_t uid); int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, gid_t gid); int sss_ncache_set_sid(struct sss_nc_ctx *ctx, bool permanent, const char *sid); int sss_ncache_set_cert(struct sss_nc_ctx *ctx, bool permanent, const char *cert); int sss_ncache_set_service_name(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, const char *name, const char *proto); int sss_ncache_set_service_port(struct sss_nc_ctx *ctx, bool permanent, struct sss_domain_info *dom, uint16_t port, const char *proto); int sss_ncache_reset_permanent(struct sss_nc_ctx *ctx); struct resp_ctx; /* Set up the negative cache with values from filter_users and * filter_groups in the sssd.conf */ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, struct confdb_ctx *cdb, struct resp_ctx *rctx); /* Flush the negcache and then repopulate */ errno_t sss_ncache_reset_repopulate_permanent(struct resp_ctx *rctx, struct sss_nc_ctx *ncache); #endif /* _NSS_NEG_CACHE_H_ */ sssd-1.13.4/src/PaxHeaders.16287/config0000644000000000000000000000013212703463556014312 xustar0030 mtime=1460561774.623793524 30 atime=1460561776.119798596 30 ctime=1460561774.623793524 sssd-1.13.4/src/config/0000755002412700241270000000000012703463556016043 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/config/PaxHeaders.16287/SSSDConfigTest.py0000644000000000000000000000007412703456111017475 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.336792551 sssd-1.13.4/src/config/SSSDConfigTest.py0000755002412700241270000022374212703456111021161 0ustar00jhrozekjhrozek00000000000000#!/usr/bin/env python ''' Created on Sep 18, 2009 @author: sgallagh ''' import unittest import os import shutil import tempfile from stat import * import sys srcdir = os.getenv('srcdir') if srcdir: sys.path.insert(0, "./src/config") srcdir = srcdir + "/src/config" else: srcdir = "." import SSSDConfig def create_temp_dir(): test_dir = os.environ.get('SSS_TEST_DIR') or "." return tempfile.mkdtemp(dir=test_dir) class SSSDConfigTestValid(unittest.TestCase): def setUp(self): self.tmp_dir = create_temp_dir() def tearDown(self): shutil.rmtree(self.tmp_dir) def testServices(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf") # Validate services services = sssdconfig.list_services() self.assertTrue('sssd' in services) self.assertTrue('nss' in services) self.assertTrue('pam' in services) #Verify service attributes sssd_service = sssdconfig.get_service('sssd') service_opts = sssd_service.list_options() self.assertTrue('services' in service_opts.keys()) service_list = sssd_service.get_option('services') self.assertTrue('nss' in service_list) self.assertTrue('pam' in service_list) self.assertTrue('domains' in service_opts) self.assertTrue('reconnection_retries' in service_opts) del sssdconfig sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.new_config() sssdconfig.delete_service('sssd') new_sssd_service = sssdconfig.new_service('sssd'); new_options = new_sssd_service.list_options(); self.assertTrue('debug_level' in new_options) self.assertEquals(new_options['debug_level'][0], int) self.assertTrue('command' in new_options) self.assertEquals(new_options['command'][0], str) self.assertTrue('reconnection_retries' in new_options) self.assertEquals(new_options['reconnection_retries'][0], int) self.assertTrue('services' in new_options) self.assertEquals(new_options['debug_level'][0], int) self.assertTrue('domains' in new_options) self.assertEquals(new_options['domains'][0], list) self.assertEquals(new_options['domains'][1], str) self.assertTrue('sbus_timeout' in new_options) self.assertEquals(new_options['sbus_timeout'][0], int) self.assertTrue('re_expression' in new_options) self.assertEquals(new_options['re_expression'][0], str) self.assertTrue('full_name_format' in new_options) self.assertEquals(new_options['full_name_format'][0], str) self.assertTrue('default_domain_suffix' in new_options) self.assertEquals(new_options['default_domain_suffix'][0], str) del sssdconfig def testDomains(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf") #Validate domain list domains = sssdconfig.list_domains() self.assertTrue('LOCAL' in domains) self.assertTrue('LDAP' in domains) self.assertTrue('PROXY' in domains) self.assertTrue('IPA' in domains) #Verify domain attributes ipa_domain = sssdconfig.get_domain('IPA') domain_opts = ipa_domain.list_options() self.assertTrue('debug_level' in domain_opts.keys()) self.assertTrue('id_provider' in domain_opts.keys()) self.assertTrue('auth_provider' in domain_opts.keys()) del sssdconfig def testListProviders(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.new_config() junk_domain = sssdconfig.new_domain('junk') providers = junk_domain.list_providers() self.assertTrue('ldap' in providers.keys()) def testCreateNewLocalConfig(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.new_config() local_domain = sssdconfig.new_domain('LOCAL') local_domain.add_provider('local', 'id') local_domain.set_option('debug_level', 1) local_domain.set_option('default_shell', '/bin/tcsh') local_domain.set_active(True) sssdconfig.save_domain(local_domain) of = self.tmp_dir + '/testCreateNewLocalConfig.conf' #Ensure the output file doesn't exist try: os.unlink(of) except: pass #Write out the file sssdconfig.write(of) #Verify that the output file has the correct permissions mode = os.stat(of)[ST_MODE] #Output files should not be readable or writable by #non-owners, and should not be executable by anyone self.assertFalse(S_IMODE(mode) & 0o177) # try to import saved configuration file config = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") config.import_config(configfile=of) #Remove the output file os.unlink(of) def testCreateNewLDAPConfig(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.new_config() ldap_domain = sssdconfig.new_domain('LDAP') ldap_domain.add_provider('ldap', 'id') ldap_domain.set_option('debug_level', 1) ldap_domain.set_active(True) sssdconfig.save_domain(ldap_domain) of = self.tmp_dir + '/testCreateNewLDAPConfig.conf' #Ensure the output file doesn't exist try: os.unlink(of) except: pass #Write out the file sssdconfig.write(of) #Verify that the output file has the correct permissions mode = os.stat(of)[ST_MODE] #Output files should not be readable or writable by #non-owners, and should not be executable by anyone self.assertFalse(S_IMODE(mode) & 0o177) # try to import saved configuration file config = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") config.import_config(configfile=of) #Remove the output file os.unlink(of) def testModifyExistingConfig(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf") ldap_domain = sssdconfig.get_domain('LDAP') ldap_domain.set_option('debug_level', 3) ldap_domain.remove_provider('auth') ldap_domain.add_provider('krb5', 'auth') ldap_domain.set_active(True) sssdconfig.save_domain(ldap_domain) of = self.tmp_dir + '/testModifyExistingConfig.conf' #Ensure the output file doesn't exist try: os.unlink(of) except: pass #Write out the file sssdconfig.write(of) #Verify that the output file has the correct permissions mode = os.stat(of)[ST_MODE] #Output files should not be readable or writable by #non-owners, and should not be executable by anyone self.assertFalse(S_IMODE(mode) & 0o177) #Remove the output file os.unlink(of) def testSpaces(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf") ldap_domain = sssdconfig.get_domain('LDAP') self.assertEqual(ldap_domain.get_option('auth_provider'), 'ldap') self.assertEqual(ldap_domain.get_option('id_provider'), 'ldap') class SSSDConfigTestInvalid(unittest.TestCase): def setUp(self): pass def tearDown(self): pass def testBadBool(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.import_config(srcdir + "/testconfigs/sssd-invalid-badbool.conf") self.assertRaises(TypeError, sssdconfig.get_domain,'IPA') class SSSDConfigTestSSSDService(unittest.TestCase): def setUp(self): self.schema = SSSDConfig.SSSDConfigSchema(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") def tearDown(self): pass def testInit(self): # Positive test service = SSSDConfig.SSSDService('sssd', self.schema) # Type Error test # Name is not a string self.assertRaises(TypeError, SSSDConfig.SSSDService, 3, self.schema) # TypeError test # schema is not an SSSDSchema self.assertRaises(TypeError, SSSDConfig.SSSDService, '3', self) # ServiceNotRecognizedError test self.assertRaises(SSSDConfig.ServiceNotRecognizedError, SSSDConfig.SSSDService, 'ssd', self.schema) def testListOptions(self): service = SSSDConfig.SSSDService('sssd', self.schema) options = service.list_options() control_list = [ 'services', 'domains', 'timeout', 'force_timeout', 'sbus_timeout', 're_expression', 'full_name_format', 'krb5_rcache_dir', 'user', 'default_domain_suffix', 'debug_level', 'debug_timestamps', 'debug_microseconds', 'debug_to_files', 'command', 'reconnection_retries', 'fd_limit', 'client_idle_timeout', 'description', 'certificate_verification'] self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) self.assertTrue(type(options['reconnection_retries']) == tuple, "Option values should be a tuple") self.assertTrue(options['reconnection_retries'][0] == int, "reconnection_retries should require an int. " + "list_options is requiring a %s" % options['reconnection_retries'][0]) self.assertTrue(options['reconnection_retries'][1] == None, "reconnection_retries should not require a subtype. " + "list_options is requiring a %s" % options['reconnection_retries'][1]) self.assertTrue(options['reconnection_retries'][3] == None, "reconnection_retries should have no default") self.assertTrue(type(options['services']) == tuple, "Option values should be a tuple") self.assertTrue(options['services'][0] == list, "services should require an list. " + "list_options is requiring a %s" % options['services'][0]) self.assertTrue(options['services'][1] == str, "services should require a subtype of str. " + "list_options is requiring a %s" % options['services'][1]) def testListMandatoryOptions(self): service = SSSDConfig.SSSDService('sssd', self.schema) options = service.list_mandatory_options() control_list = [ 'services', 'domains'] self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) self.assertTrue(type(options['services']) == tuple, "Option values should be a tuple") self.assertTrue(options['services'][0] == list, "services should require an list. " + "list_options is requiring a %s" % options['services'][0]) self.assertTrue(options['services'][1] == str, "services should require a subtype of str. " + "list_options is requiring a %s" % options['services'][1]) def testSetOption(self): service = SSSDConfig.SSSDService('sssd', self.schema) # Positive test - Exactly right service.set_option('debug_level', 2) self.assertEqual(service.get_option('debug_level'), 2) # Positive test - Allow converting "safe" values service.set_option('debug_level', '2') self.assertEqual(service.get_option('debug_level'), 2) # Positive test - Remove option if value is None service.set_option('debug_level', None) self.assertTrue('debug_level' not in service.options.keys()) # Negative test - Nonexistent Option self.assertRaises(SSSDConfig.NoOptionError, service.set_option, 'nosuchoption', 1) # Negative test - Incorrect type self.assertRaises(TypeError, service.set_option, 'debug_level', 'two') def testGetOption(self): service = SSSDConfig.SSSDService('sssd', self.schema) # Positive test - List of values self.assertEqual(service.get_option('services'), ['nss', 'pam']) # Negative Test - Bad Option self.assertRaises(SSSDConfig.NoOptionError, service.get_option, 'nosuchoption') def testGetAllOptions(self): service = SSSDConfig.SSSDService('sssd', self.schema) #Positive test options = service.get_all_options() control_list = ['services'] self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) def testRemoveOption(self): service = SSSDConfig.SSSDService('sssd', self.schema) # Positive test - Remove an option that exists self.assertEqual(service.get_option('services'), ['nss', 'pam']) service.remove_option('services') self.assertRaises(SSSDConfig.NoOptionError, service.get_option, 'debug_level') # Positive test - Remove an option that doesn't exist self.assertRaises(SSSDConfig.NoOptionError, service.get_option, 'nosuchentry') service.remove_option('nosuchentry') class SSSDConfigTestSSSDDomain(unittest.TestCase): def setUp(self): self.schema = SSSDConfig.SSSDConfigSchema(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") def tearDown(self): pass def testInit(self): # Positive Test domain = SSSDConfig.SSSDDomain('mydomain', self.schema) # Negative Test - Name not a string self.assertRaises(TypeError, SSSDConfig.SSSDDomain, 2, self.schema) # Negative Test - Schema is not an SSSDSchema self.assertRaises(TypeError, SSSDConfig.SSSDDomain, 'mydomain', self) def testGetName(self): # Positive Test domain = SSSDConfig.SSSDDomain('mydomain', self.schema) self.assertEqual(domain.get_name(), 'mydomain') def testSetActive(self): #Positive Test domain = SSSDConfig.SSSDDomain('mydomain', self.schema) # Should default to inactive self.assertFalse(domain.active) domain.set_active(True) self.assertTrue(domain.active) domain.set_active(False) self.assertFalse(domain.active) def testListOptions(self): domain = SSSDConfig.SSSDDomain('sssd', self.schema) # First test default options options = domain.list_options() control_list = [ 'description', 'debug_level', 'debug_timestamps', 'min_id', 'max_id', 'timeout', 'force_timeout', 'offline_timeout', 'try_inotify', 'command', 'enumerate', 'cache_credentials', 'cache_credentials_minimal_first_factor_length', 'store_legacy_passwords', 'use_fully_qualified_names', 'ignore_group_members', 'filter_users', 'filter_groups', 'entry_cache_timeout', 'entry_cache_user_timeout', 'entry_cache_group_timeout', 'entry_cache_netgroup_timeout', 'entry_cache_service_timeout', 'entry_cache_autofs_timeout', 'entry_cache_sudo_timeout', 'entry_cache_ssh_host_timeout', 'refresh_expired_interval', 'lookup_family_order', 'account_cache_expiration', 'dns_resolver_timeout', 'dns_discovery_domain', 'dyndns_update', 'dyndns_ttl', 'dyndns_iface', 'dyndns_refresh_interval', 'dyndns_update_ptr', 'dyndns_force_tcp', 'dyndns_auth', 'dyndns_server', 'subdomain_enumerate', 'override_gid', 'case_sensitive', 'override_homedir', 'fallback_homedir', 'homedir_substring', 'override_shell', 'default_shell', 'pwd_expiration_warning', 'id_provider', 'auth_provider', 'access_provider', 'chpass_provider', 'sudo_provider', 'autofs_provider', 'session_provider', 'hostid_provider', 'subdomains_provider', 'realmd_tags', 'subdomain_refresh_interval', 'subdomain_inherit', 'cached_auth_timeout'] self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) self.assertTrue(type(options['max_id']) == tuple, "Option values should be a tuple") self.assertTrue(options['max_id'][0] == int, "max_id should require an int. " + "list_options is requiring a %s" % options['max_id'][0]) self.assertTrue(options['max_id'][1] == None, "max_id should not require a subtype. " + "list_options is requiring a %s" % options['max_id'][1]) # Add a provider and verify that the new options appear domain.add_provider('local', 'id') control_list.extend( ['default_shell', 'base_directory', 'create_homedir', 'remove_homedir', 'homedir_umask', 'skel_dir', 'mail_dir', 'userdel_cmd']) options = domain.list_options() self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) # Add a provider that has global options and verify that # The new options appear. domain.add_provider('krb5', 'auth') backup_list = control_list[:] control_list.extend( ['krb5_server', 'krb5_backup_server', 'krb5_realm', 'krb5_kpasswd', 'krb5_backup_kpasswd', 'krb5_ccachedir', 'krb5_ccname_template', 'krb5_keytab', 'krb5_validate', 'krb5_store_password_if_offline', 'krb5_auth_timeout', 'krb5_renewable_lifetime', 'krb5_lifetime', 'krb5_renew_interval', 'krb5_use_fast', 'krb5_fast_principal', 'krb5_canonicalize', 'krb5_use_enterprise_principal', 'krb5_use_kdcinfo', 'krb5_map_user']) options = domain.list_options() self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) control_list.extend(['krb5_kdcip']) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) # Remove the auth domain and verify that the options # revert to the backup_list domain.remove_provider('auth') options = domain.list_options() self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in backup_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in backup_list, 'Option [%s] unexpectedly found' % option) def testListMandatoryOptions(self): domain = SSSDConfig.SSSDDomain('sssd', self.schema) # First test default options options = domain.list_mandatory_options() control_list = ['id_provider'] self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) # Add a provider that has global options and verify that # The new options appear. domain.add_provider('krb5', 'auth') backup_list = control_list[:] control_list.extend(['krb5_realm']) options = domain.list_mandatory_options() self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) # Remove the auth domain and verify that the options # revert to the backup_list domain.remove_provider('auth') options = domain.list_mandatory_options() self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in backup_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in backup_list, 'Option [%s] unexpectedly found' % option) def testListProviders(self): domain = SSSDConfig.SSSDDomain('sssd', self.schema) control_provider_dict = { 'ipa': ['id', 'auth', 'access', 'chpass', 'sudo', 'autofs', 'session', 'hostid', 'subdomains'], 'ad': ['id', 'auth', 'access', 'chpass', 'sudo', 'autofs', 'subdomains'], 'local': ['id', 'auth', 'chpass'], 'ldap': ['id', 'auth', 'access', 'chpass', 'sudo', 'autofs'], 'krb5': ['auth', 'access', 'chpass'], 'proxy': ['id', 'auth', 'chpass'], 'simple': ['access'], 'permit': ['access'], 'deny': ['access']} providers = domain.list_providers() # Ensure that all of the expected defaults are there for provider in control_provider_dict.keys(): for ptype in control_provider_dict[provider]: self.assertTrue(provider in providers) self.assertTrue(ptype in providers[provider]) for provider in providers.keys(): for ptype in providers[provider]: self.assertTrue(provider in control_provider_dict) self.assertTrue(ptype in control_provider_dict[provider]) def testListProviderOptions(self): domain = SSSDConfig.SSSDDomain('sssd', self.schema) # Test looking up a specific provider type options = domain.list_provider_options('krb5', 'auth') control_list = [ 'krb5_server', 'krb5_backup_server', 'krb5_kdcip', 'krb5_realm', 'krb5_kpasswd', 'krb5_backup_kpasswd', 'krb5_ccachedir', 'krb5_ccname_template', 'krb5_keytab', 'krb5_validate', 'krb5_store_password_if_offline', 'krb5_auth_timeout', 'krb5_renewable_lifetime', 'krb5_lifetime', 'krb5_renew_interval', 'krb5_use_fast', 'krb5_fast_principal', 'krb5_canonicalize', 'krb5_use_enterprise_principal', 'krb5_use_kdcinfo', 'krb5_map_user'] self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) #Test looking up all provider values options = domain.list_provider_options('krb5') control_list.extend(['krb5_kpasswd']) self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) def testAddProvider(self): domain = SSSDConfig.SSSDDomain('sssd', self.schema) # Positive Test domain.add_provider('local', 'id') # Negative Test - No such backend type self.assertRaises(SSSDConfig.NoSuchProviderError, domain.add_provider, 'nosuchbackend', 'auth') # Negative Test - No such backend subtype self.assertRaises(SSSDConfig.NoSuchProviderSubtypeError, domain.add_provider, 'ldap', 'nosuchsubtype') # Negative Test - Try to add a second provider of the same type self.assertRaises(SSSDConfig.ProviderSubtypeInUse, domain.add_provider, 'ldap', 'id') def testRemoveProvider(self): domain = SSSDConfig.SSSDDomain('sssd', self.schema) # First test default options options = domain.list_options() control_list = [ 'description', 'debug_level', 'debug_timestamps', 'min_id', 'max_id', 'timeout', 'force_timeout', 'offline_timeout', 'try_inotify', 'command', 'enumerate', 'cache_credentials', 'cache_credentials_minimal_first_factor_length', 'store_legacy_passwords', 'use_fully_qualified_names', 'ignore_group_members', 'filter_users', 'filter_groups', 'entry_cache_timeout', 'entry_cache_user_timeout', 'entry_cache_group_timeout', 'entry_cache_netgroup_timeout', 'entry_cache_service_timeout', 'entry_cache_autofs_timeout', 'entry_cache_sudo_timeout', 'entry_cache_ssh_host_timeout', 'refresh_expired_interval', 'account_cache_expiration', 'lookup_family_order', 'dns_resolver_timeout', 'dns_discovery_domain', 'dyndns_update', 'dyndns_ttl', 'dyndns_iface', 'dyndns_refresh_interval', 'dyndns_update_ptr', 'dyndns_force_tcp', 'dyndns_auth', 'dyndns_server', 'subdomain_enumerate', 'override_gid', 'case_sensitive', 'override_homedir', 'fallback_homedir', 'homedir_substring', 'override_shell', 'default_shell', 'pwd_expiration_warning', 'id_provider', 'auth_provider', 'access_provider', 'chpass_provider', 'sudo_provider', 'autofs_provider', 'session_provider', 'hostid_provider', 'subdomains_provider', 'realmd_tags', 'subdomain_refresh_interval', 'subdomain_inherit', 'cached_auth_timeout'] self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) self.assertTrue(type(options['max_id']) == tuple, "Option values should be a tuple") self.assertTrue(options['max_id'][0] == int, "config_file_version should require an int. " + "list_options is requiring a %s" % options['max_id'][0]) self.assertTrue(options['max_id'][1] == None, "config_file_version should not require a subtype. " + "list_options is requiring a %s" % options['max_id'][1]) # Add a provider and verify that the new options appear domain.add_provider('local', 'id') control_list.extend( ['default_shell', 'base_directory', 'create_homedir', 'remove_homedir', 'homedir_umask', 'skel_dir', 'mail_dir', 'userdel_cmd']) options = domain.list_options() self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) # Add a provider that has global options and verify that # The new options appear. domain.add_provider('krb5', 'auth') backup_list = control_list[:] control_list.extend( ['krb5_server', 'krb5_backup_server', 'krb5_kdcip', 'krb5_realm', 'krb5_kpasswd', 'krb5_backup_kpasswd', 'krb5_ccachedir', 'krb5_ccname_template', 'krb5_keytab', 'krb5_validate', 'krb5_store_password_if_offline', 'krb5_auth_timeout', 'krb5_renewable_lifetime', 'krb5_lifetime', 'krb5_renew_interval', 'krb5_use_fast', 'krb5_fast_principal', 'krb5_canonicalize', 'krb5_use_enterprise_principal', 'krb5_use_kdcinfo', 'krb5_map_user']) options = domain.list_options() self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in control_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in control_list, 'Option [%s] unexpectedly found' % option) # Remove the local ID provider and add an LDAP one # LDAP ID providers can also use the krb5_realm domain.remove_provider('id') self.assertFalse('id_provider' in domain.options) domain.add_provider('ldap', 'id') # Set the krb5_realm option and the ldap_uri option domain.set_option('krb5_realm', 'EXAMPLE.COM') domain.set_option('ldap_uri', 'ldap://ldap.example.com') self.assertEquals(domain.get_option('krb5_realm'), 'EXAMPLE.COM') self.assertEquals(domain.get_option('ldap_uri'), 'ldap://ldap.example.com') # Remove the LDAP provider and verify that krb5_realm remains domain.remove_provider('id') self.assertEquals(domain.get_option('krb5_realm'), 'EXAMPLE.COM') self.assertFalse('ldap_uri' in domain.options) # Put the LOCAL provider back domain.add_provider('local', 'id') # Remove the auth domain and verify that the options # revert to the backup_list domain.remove_provider('auth') self.assertFalse('auth_provider' in domain.options) options = domain.list_options() self.assertTrue(type(options) == dict, "Options should be a dictionary") # Ensure that all of the expected defaults are there for option in backup_list: self.assertTrue(option in options.keys(), "Option [%s] missing" % option) # Ensure that there aren't any unexpected options listed for option in options.keys(): self.assertTrue(option in backup_list, 'Option [%s] unexpectedly found' % option) # Ensure that the krb5_realm option is now gone self.assertFalse('krb5_realm' in domain.options) # Test removing nonexistent provider - Real domain.remove_provider('id') self.assertFalse('id_provider' in domain.options) # Test removing nonexistent provider - Bad backend type # Should pass without complaint domain.remove_provider('id') self.assertFalse('id_provider' in domain.options) # Test removing nonexistent provider - Bad provider type # Should pass without complaint domain.remove_provider('nosuchprovider') self.assertFalse('nosuchprovider_provider' in domain.options) def testGetOption(self): domain = SSSDConfig.SSSDDomain('sssd', self.schema) # Negative Test - Try to get valid option that is not set self.assertRaises(SSSDConfig.NoOptionError, domain.get_option, 'max_id') # Positive Test - Set the above option and get it domain.set_option('max_id', 10000) self.assertEqual(domain.get_option('max_id'), 10000) # Negative Test - Try yo get invalid option self.assertRaises(SSSDConfig.NoOptionError, domain.get_option, 'nosuchoption') def testSetOption(self): domain = SSSDConfig.SSSDDomain('sssd', self.schema) # Positive Test domain.set_option('max_id', 10000) self.assertEqual(domain.get_option('max_id'), 10000) # Positive Test - Remove option if value is None domain.set_option('max_id', None) self.assertTrue('max_id' not in domain.get_all_options().keys()) # Negative Test - invalid option self.assertRaises(SSSDConfig.NoOptionError, domain.set_option, 'nosuchoption', 1) # Negative Test - incorrect type self.assertRaises(TypeError, domain.set_option, 'max_id', 'a string') # Positive Test - Coax options to appropriate type domain.set_option('max_id', '10000') self.assertEqual(domain.get_option('max_id'), 10000) domain.set_option('max_id', 30.2) self.assertEqual(domain.get_option('max_id'), 30) def testRemoveOption(self): domain = SSSDConfig.SSSDDomain('sssd', self.schema) # Positive test - Remove unset but valid option self.assertFalse('max_id' in domain.get_all_options().keys()) domain.remove_option('max_id') self.assertFalse('max_id' in domain.get_all_options().keys()) # Positive test - Remove unset and unknown option self.assertFalse('nosuchoption' in domain.get_all_options().keys()) domain.remove_option('nosuchoption') self.assertFalse('nosuchoption' in domain.get_all_options().keys()) def testSetName(self): domain = SSSDConfig.SSSDDomain('sssd', self.schema) # Positive test - Change the name once domain.set_name('sssd2'); self.assertEqual(domain.get_name(), 'sssd2') self.assertEqual(domain.oldname, 'sssd') # Positive test - Change the name a second time domain.set_name('sssd3') self.assertEqual(domain.get_name(), 'sssd3') self.assertEqual(domain.oldname, 'sssd') # Negative test - try setting the name to a non-string self.assertRaises(TypeError, domain.set_name, 4) class SSSDConfigTestSSSDConfig(unittest.TestCase): def setUp(self): self.tmp_dir = create_temp_dir() def tearDown(self): shutil.rmtree(self.tmp_dir) def testInit(self): # Positive test sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - No Such File self.assertRaises(IOError, SSSDConfig.SSSDConfig, "nosuchfile.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Schema is not parsable self.assertRaises(SSSDConfig.ParsingError, SSSDConfig.SSSDConfig, srcdir + "/testconfigs/noparse.api.conf", srcdir + "/etc/sssd.api.d") def testImportConfig(self): # Positive Test sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf") # Verify that all sections were imported control_list = [ 'sssd', 'nss', 'pam', 'sudo', 'domain/PROXY', 'domain/IPA', 'domain/LOCAL', 'domain/LDAP', 'domain/INVALIDPROVIDER', 'domain/INVALIDOPTION', ] for section in control_list: self.assertTrue(sssdconfig.has_section(section), "Section [%s] missing" % section) for section in sssdconfig.sections(): self.assertTrue(section['name'] in control_list) # Verify that all options were imported for a section control_list = [ 'services', 'reconnection_retries', 'domains', 'debug_timestamps', 'config_file_version'] for option in control_list: self.assertTrue(sssdconfig.has_option('sssd', option), "Option [%s] missing from [sssd]" % option) for option in sssdconfig.options('sssd'): if option['type'] in ('empty', 'comment'): continue self.assertTrue(option['name'] in control_list, "Option [%s] unexpectedly found" % option) #TODO: Check the types and values of the settings # Negative Test - Missing config file sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") self.assertRaises(IOError, sssdconfig.import_config, "nosuchfile.conf") # Negative Test - Invalid config file sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") self.assertRaises(SSSDConfig.ParsingError, sssdconfig.import_config, srcdir + "/testconfigs/sssd-invalid.conf") # Negative Test - Invalid config file version sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") self.assertRaises(SSSDConfig.ParsingError, sssdconfig.import_config, srcdir + "/testconfigs/sssd-badversion.conf") # Negative Test - Already initialized sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf") self.assertRaises(SSSDConfig.AlreadyInitializedError, sssdconfig.import_config, srcdir + "/testconfigs/sssd-valid.conf") def testImportConfigNoVersion(self): # Positive Test sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.import_config( srcdir + "/testconfigs/sssd-noversion.conf" ) # Validate services services = sssdconfig.list_services() self.assertTrue('sssd' in services) self.assertTrue('nss' in services) self.assertTrue('pam' in services) self.assertTrue('dp' in services) #Verify service attributes sssd_service = sssdconfig.get_service('sssd') service_opts = sssd_service.list_options() self.assertTrue('services' in service_opts.keys()) service_list = sssd_service.get_option('services') self.assertTrue('nss' in service_list) self.assertTrue('pam' in service_list) self.assertTrue('reconnection_retries' in service_opts) #Validate domain list domains = sssdconfig.list_domains() self.assertTrue('LOCAL' in domains) self.assertTrue('LDAP' in domains) self.assertTrue('PROXY' in domains) self.assertTrue('IPA' in domains) # Verify domain attributes ipa_domain = sssdconfig.get_domain('IPA') domain_opts = ipa_domain.list_options() self.assertTrue('debug_level' in domain_opts.keys()) self.assertTrue('id_provider' in domain_opts.keys()) self.assertTrue('auth_provider' in domain_opts.keys()) # Verify domain attributes proxy_domain = sssdconfig.get_domain('PROXY') domain_opts = proxy_domain.list_options() self.assertTrue('debug_level' in domain_opts.keys()) self.assertTrue('id_provider' in domain_opts.keys()) self.assertTrue('auth_provider' in domain_opts.keys()) # Verify domain attributes local_domain = sssdconfig.get_domain('LOCAL') domain_opts = local_domain.list_options() self.assertTrue('debug_level' in domain_opts.keys()) self.assertTrue('id_provider' in domain_opts.keys()) self.assertTrue('auth_provider' in domain_opts.keys()) # Verify domain attributes ldap_domain = sssdconfig.get_domain('LDAP') domain_opts = ldap_domain.list_options() self.assertTrue('debug_level' in domain_opts.keys()) self.assertTrue('id_provider' in domain_opts.keys()) self.assertTrue('auth_provider' in domain_opts.keys()) domain_control_list = [ 'cache_credentials', 'id_provider', 'auth_provider', 'access_provider', 'default_shell', 'fallback_homedir', 'cache_credentials', 'use_fully_qualified_names', ] ad_domain = sssdconfig.get_domain("ad.example.com") for option in ad_domain.get_all_options(): self.assertTrue(option in domain_control_list) negative_domain_control_list = [ 'ad_server', 'ldap_id_mapping', 'ldap_sasl_authid', ] for option in ad_domain.get_all_options(): self.assertFalse(option in negative_domain_control_list) def testNewConfig(self): # Positive Test sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") sssdconfig.new_config() # Check that the defaults were set control_list = [ 'sssd', 'nss', 'pam', 'sudo', 'autofs', 'ssh', 'pac', 'ifp'] for section in control_list: self.assertTrue(sssdconfig.has_section(section), "Section [%s] missing" % section) for section in sssdconfig.sections(): self.assertTrue(section['name'] in control_list) control_list = ['services'] for option in control_list: self.assertTrue(sssdconfig.has_option('sssd', option), "Option [%s] missing from [sssd]" % option) for option in sssdconfig.options('sssd'): if option['type'] in ('empty', 'comment'): continue self.assertTrue(option['name'] in control_list, "Option [%s] unexpectedly found" % option) # Negative Test - Already Initialized self.assertRaises(SSSDConfig.AlreadyInitializedError, sssdconfig.new_config) def testWrite(self): #TODO Write tests to compare output files pass def testListActiveServices(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not Initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_active_services) # Positive Test sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf') control_list = [ 'nss', 'pam'] active_services = sssdconfig.list_active_services() self.assertTrue(isinstance(active_services, list)) for service in control_list: self.assertTrue(service in active_services, "Service [%s] missing" % service) for service in active_services: self.assertTrue(service in control_list, "Service [%s] unexpectedly found" % service) def testListInactiveServices(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not Initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_inactive_services) # Positive Test sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf') control_list = [ 'sssd', 'sudo'] inactive_services = sssdconfig.list_inactive_services() for service in control_list: self.assertTrue(service in inactive_services, "Service [%s] missing" % service) for service in inactive_services: self.assertTrue(service in control_list, "Service [%s] unexpectedly found" % service) def testListServices(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - sssdconfig not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_services) sssdconfig.new_config() control_list = [ 'sssd', 'pam', 'nss', 'sudo', 'autofs', 'ssh', 'pac', 'ifp'] service_list = sssdconfig.list_services() for service in control_list: self.assertTrue(service in service_list, "Service [%s] missing" % service) for service in service_list: self.assertTrue(service in control_list, "Service [%s] unexpectedly found" % service) def testGetService(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.get_service, 'sssd') sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf') service = sssdconfig.get_service('sssd') self.assertTrue(isinstance(service, SSSDConfig.SSSDService)) # Verify the contents of this service self.assertEqual(type(service.get_option('debug_timestamps')), bool) self.assertFalse(service.get_option('debug_timestamps')) # Negative Test - No such service self.assertRaises(SSSDConfig.NoServiceError, sssdconfig.get_service, 'nosuchservice') # Positive test - Service with invalid option loads # but ignores the invalid option service = sssdconfig.get_service('pam') self.assertFalse('nosuchoption' in service.options) def testNewService(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.new_service, 'sssd') sssdconfig.new_config() # Positive Test # First need to remove the existing service sssdconfig.delete_service('sssd') service = sssdconfig.new_service('sssd') self.failUnless(service.get_name() in sssdconfig.list_services()) # TODO: check that the values of this new service # are set to the defaults from the schema def testDeleteService(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.delete_service, 'sssd') sssdconfig.new_config() # Positive Test service = sssdconfig.delete_service('sssd') def testSaveService(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") new_service = SSSDConfig.SSSDService('sssd', sssdconfig.schema) # Negative Test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.save_service, new_service) # Positive Test sssdconfig.new_config() sssdconfig.save_service(new_service) # TODO: check that all entries were saved correctly (change a few) # Negative Test - Type Error self.assertRaises(TypeError, sssdconfig.save_service, self) def testActivateService(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") service_name = 'sudo' # Negative test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.activate_service, service_name) sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf") # Positive test - Activate an inactive service self.assertTrue(service_name in sssdconfig.list_services()) self.assertFalse(service_name in sssdconfig.list_active_services()) self.assertTrue(service_name in sssdconfig.list_inactive_services()) sssdconfig.activate_service(service_name) self.assertTrue(service_name in sssdconfig.list_services()) self.assertTrue(service_name in sssdconfig.list_active_services()) self.assertFalse(service_name in sssdconfig.list_inactive_services()) # Positive test - Activate an active service # This should succeed sssdconfig.activate_service(service_name) self.assertTrue(service_name in sssdconfig.list_services()) self.assertTrue(service_name in sssdconfig.list_active_services()) self.assertFalse(service_name in sssdconfig.list_inactive_services()) # Negative test - Invalid service name self.assertRaises(SSSDConfig.NoServiceError, sssdconfig.activate_service, 'nosuchservice') # Negative test - Invalid service name type self.assertRaises(SSSDConfig.NoServiceError, sssdconfig.activate_service, self) def testDeactivateService(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") service_name = 'pam' # Negative test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.activate_service, service_name) sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf") # Positive test -Deactivate an active service self.assertTrue(service_name in sssdconfig.list_services()) self.assertTrue(service_name in sssdconfig.list_active_services()) self.assertFalse(service_name in sssdconfig.list_inactive_services()) sssdconfig.deactivate_service(service_name) self.assertTrue(service_name in sssdconfig.list_services()) self.assertFalse(service_name in sssdconfig.list_active_services()) self.assertTrue(service_name in sssdconfig.list_inactive_services()) # Positive test - Deactivate an inactive service # This should succeed sssdconfig.deactivate_service(service_name) self.assertTrue(service_name in sssdconfig.list_services()) self.assertFalse(service_name in sssdconfig.list_active_services()) self.assertTrue(service_name in sssdconfig.list_inactive_services()) # Negative test - Invalid service name self.assertRaises(SSSDConfig.NoServiceError, sssdconfig.activate_service, 'nosuchservice') # Negative test - Invalid service name type self.assertRaises(SSSDConfig.NoServiceError, sssdconfig.activate_service, self) def testListActiveDomains(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not Initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_active_domains) # Positive Test sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf') control_list = [ 'IPA', 'LOCAL'] active_domains = sssdconfig.list_active_domains() self.assertTrue(isinstance(active_domains, list)) for domain in control_list: self.assertTrue(domain in active_domains, "Domain [%s] missing" % domain) for domain in active_domains: self.assertTrue(domain in control_list, "Domain [%s] unexpectedly found" % domain) def testListInactiveDomains(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not Initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_inactive_domains) # Positive Test sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf') control_list = [ 'PROXY', 'LDAP', 'INVALIDPROVIDER', 'INVALIDOPTION', ] inactive_domains = sssdconfig.list_inactive_domains() for domain in control_list: self.assertTrue(domain in inactive_domains, "Domain [%s] missing" % domain) for domain in inactive_domains: self.assertTrue(domain in control_list, "Domain [%s] unexpectedly found" % domain) def testListDomains(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not Initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_domains) # Positive Test sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf') control_list = [ 'IPA', 'LOCAL', 'PROXY', 'LDAP', 'INVALIDPROVIDER', 'INVALIDOPTION', ] domains = sssdconfig.list_domains() for domain in control_list: self.assertTrue(domain in domains, "Domain [%s] missing" % domain) for domain in domains: self.assertTrue(domain in control_list, "Domain [%s] unexpectedly found" % domain) def testGetDomain(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.get_domain, 'sssd') sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf') domain = sssdconfig.get_domain('IPA') self.assertTrue(isinstance(domain, SSSDConfig.SSSDDomain)) self.assertTrue(domain.active) domain = sssdconfig.get_domain('LDAP') self.assertTrue(isinstance(domain, SSSDConfig.SSSDDomain)) self.assertFalse(domain.active) # TODO verify the contents of this domain self.assertTrue(domain.get_option('ldap_id_use_start_tls')) # Negative Test - No such domain self.assertRaises(SSSDConfig.NoDomainError, sssdconfig.get_domain, 'nosuchdomain') # Positive Test - Domain with unknown provider # Expected result: Domain is imported, but does not contain the # unknown provider entry domain = sssdconfig.get_domain('INVALIDPROVIDER') self.assertFalse('chpass_provider' in domain.options) # Positive Test - Domain with unknown option # Expected result: Domain is imported, but does not contain the # unknown option entry domain = sssdconfig.get_domain('INVALIDOPTION') self.assertFalse('nosuchoption' in domain.options) def testNewDomain(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.new_domain, 'example.com') sssdconfig.new_config() # Positive Test domain = sssdconfig.new_domain('example.com') self.assertTrue(isinstance(domain, SSSDConfig.SSSDDomain)) self.failUnless(domain.get_name() in sssdconfig.list_domains()) self.failUnless(domain.get_name() in sssdconfig.list_inactive_domains()) # TODO: check that the values of this new domain # are set to the defaults from the schema def testDeleteDomain(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.delete_domain, 'IPA') # Positive Test sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf') self.assertTrue('IPA' in sssdconfig.list_domains()) self.assertTrue('IPA' in sssdconfig.list_active_domains()) self.assertTrue(sssdconfig.has_section('domain/IPA')) sssdconfig.delete_domain('IPA') self.assertFalse('IPA' in sssdconfig.list_domains()) self.assertFalse('IPA' in sssdconfig.list_active_domains()) self.assertFalse(sssdconfig.has_section('domain/IPA')) def testSaveDomain(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") # Negative Test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.save_domain, 'IPA') # Positive Test sssdconfig.new_config() domain = sssdconfig.new_domain('example.com') domain.add_provider('ldap', 'id') domain.set_option('ldap_uri', 'ldap://ldap.example.com') domain.set_active(True) sssdconfig.save_domain(domain) self.assertTrue('example.com' in sssdconfig.list_domains()) self.assertTrue('example.com' in sssdconfig.list_active_domains()) self.assertEqual(sssdconfig.get('domain/example.com', 'ldap_uri'), 'ldap://ldap.example.com') # Negative Test - Type Error self.assertRaises(TypeError, sssdconfig.save_domain, self) # Positive test - Change the domain name and save it domain.set_name('example.com2') self.assertEqual(domain.name,'example.com2') self.assertEqual(domain.oldname,'example.com') sssdconfig.save_domain(domain) self.assertTrue('example.com2' in sssdconfig.list_domains()) self.assertTrue('example.com2' in sssdconfig.list_active_domains()) self.assertTrue(sssdconfig.has_section('domain/example.com2')) self.assertEqual(sssdconfig.get('domain/example.com2', 'ldap_uri'), 'ldap://ldap.example.com') self.assertFalse('example.com' in sssdconfig.list_domains()) self.assertFalse('example.com' in sssdconfig.list_active_domains()) self.assertFalse('example.com' in sssdconfig.list_inactive_domains()) self.assertFalse(sssdconfig.has_section('domain/example.com')) self.assertEquals(domain.oldname, None) # Positive test - Set the domain inactive and save it activelist = sssdconfig.list_active_domains() inactivelist = sssdconfig.list_inactive_domains() domain.set_active(False) sssdconfig.save_domain(domain) self.assertFalse('example.com2' in sssdconfig.list_active_domains()) self.assertTrue('example.com2' in sssdconfig.list_inactive_domains()) self.assertEquals(len(sssdconfig.list_active_domains()), len(activelist)-1) self.assertEquals(len(sssdconfig.list_inactive_domains()), len(inactivelist)+1) # Positive test - Set the domain active and save it activelist = sssdconfig.list_active_domains() inactivelist = sssdconfig.list_inactive_domains() domain.set_active(True) sssdconfig.save_domain(domain) self.assertTrue('example.com2' in sssdconfig.list_active_domains()) self.assertFalse('example.com2' in sssdconfig.list_inactive_domains()) self.assertEquals(len(sssdconfig.list_active_domains()), len(activelist)+1) self.assertEquals(len(sssdconfig.list_inactive_domains()), len(inactivelist)-1) # Positive test - Set the domain inactive and save it activelist = sssdconfig.list_active_domains() inactivelist = sssdconfig.list_inactive_domains() sssdconfig.deactivate_domain(domain.get_name()) self.assertFalse('example.com2' in sssdconfig.list_active_domains()) self.assertTrue('example.com2' in sssdconfig.list_inactive_domains()) self.assertEquals(len(sssdconfig.list_active_domains()), len(activelist)-1) self.assertEquals(len(sssdconfig.list_inactive_domains()), len(inactivelist)+1) # Positive test - Set the domain active and save it activelist = sssdconfig.list_active_domains() inactivelist = sssdconfig.list_inactive_domains() sssdconfig.activate_domain(domain.get_name()) self.assertTrue('example.com2' in sssdconfig.list_active_domains()) self.assertFalse('example.com2' in sssdconfig.list_inactive_domains()) self.assertEquals(len(sssdconfig.list_active_domains()), len(activelist)+1) self.assertEquals(len(sssdconfig.list_inactive_domains()), len(inactivelist)-1) # Positive test - Ensure that saved domains retain values domain.set_option('ldap_krb5_init_creds', True) domain.set_option('ldap_id_use_start_tls', False) domain.set_option('ldap_user_search_base', 'cn=accounts, dc=example, dc=com') self.assertTrue(domain.get_option('ldap_krb5_init_creds')) self.assertFalse(domain.get_option('ldap_id_use_start_tls')) self.assertEqual(domain.get_option('ldap_user_search_base'), 'cn=accounts, dc=example, dc=com') sssdconfig.save_domain(domain) of = self.tmp_dir + '/testSaveDomain.out' #Ensure the output file doesn't exist try: os.unlink(of) except: pass #Write out the file sssdconfig.write(of) #Verify that the output file has the correct permissions mode = os.stat(of)[ST_MODE] #Output files should not be readable or writable by #non-owners, and should not be executable by anyone self.assertFalse(S_IMODE(mode) & 0o177) #Remove the output file os.unlink(of) domain2 = sssdconfig.get_domain('example.com2') self.assertTrue(domain2.get_option('ldap_krb5_init_creds')) self.assertFalse(domain2.get_option('ldap_id_use_start_tls')) def testActivateDomain(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") domain_name = 'PROXY' # Negative test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.activate_domain, domain_name) sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf") # Positive test - Activate an inactive domain self.assertTrue(domain_name in sssdconfig.list_domains()) self.assertFalse(domain_name in sssdconfig.list_active_domains()) self.assertTrue(domain_name in sssdconfig.list_inactive_domains()) sssdconfig.activate_domain('PROXY') self.assertTrue(domain_name in sssdconfig.list_domains()) self.assertTrue(domain_name in sssdconfig.list_active_domains()) self.assertFalse(domain_name in sssdconfig.list_inactive_domains()) # Positive test - Activate an active domain # This should succeed sssdconfig.activate_domain('PROXY') self.assertTrue(domain_name in sssdconfig.list_domains()) self.assertTrue(domain_name in sssdconfig.list_active_domains()) self.assertFalse(domain_name in sssdconfig.list_inactive_domains()) # Negative test - Invalid domain name self.assertRaises(SSSDConfig.NoDomainError, sssdconfig.activate_domain, 'nosuchdomain') # Negative test - Invalid domain name type self.assertRaises(SSSDConfig.NoDomainError, sssdconfig.activate_domain, self) def testDeactivateDomain(self): sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf", srcdir + "/etc/sssd.api.d") domain_name = 'IPA' # Negative test - Not initialized self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.activate_domain, domain_name) sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf") # Positive test -Deactivate an active domain self.assertTrue(domain_name in sssdconfig.list_domains()) self.assertTrue(domain_name in sssdconfig.list_active_domains()) self.assertFalse(domain_name in sssdconfig.list_inactive_domains()) sssdconfig.deactivate_domain(domain_name) self.assertTrue(domain_name in sssdconfig.list_domains()) self.assertFalse(domain_name in sssdconfig.list_active_domains()) self.assertTrue(domain_name in sssdconfig.list_inactive_domains()) # Positive test - Deactivate an inactive domain # This should succeed sssdconfig.deactivate_domain(domain_name) self.assertTrue(domain_name in sssdconfig.list_domains()) self.assertFalse(domain_name in sssdconfig.list_active_domains()) self.assertTrue(domain_name in sssdconfig.list_inactive_domains()) # Negative test - Invalid domain name self.assertRaises(SSSDConfig.NoDomainError, sssdconfig.activate_domain, 'nosuchdomain') # Negative test - Invalid domain name type self.assertRaises(SSSDConfig.NoDomainError, sssdconfig.activate_domain, self) if __name__ == "__main__": error = 0 suite = unittest.TestLoader().loadTestsFromTestCase(SSSDConfigTestSSSDService) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x1 suite = unittest.TestLoader().loadTestsFromTestCase(SSSDConfigTestSSSDDomain) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x2 suite = unittest.TestLoader().loadTestsFromTestCase(SSSDConfigTestSSSDConfig) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x4 suite = unittest.TestLoader().loadTestsFromTestCase(SSSDConfigTestValid) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x8 suite = unittest.TestLoader().loadTestsFromTestCase(SSSDConfigTestInvalid) res = unittest.TextTestRunner().run(suite) if not res.wasSuccessful(): error |= 0x10 sys.exit(error) sssd-1.13.4/src/config/PaxHeaders.16287/SSSDConfigTest.py3.sh0000644000000000000000000000007412703456111020171 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.338792557 sssd-1.13.4/src/config/SSSDConfigTest.py3.sh0000755002412700241270000000016312703456111021643 0ustar00jhrozekjhrozek00000000000000#!/bin/sh SCRIPT=$(readlink -f "$0") SCRIPT_PATH=$(dirname "$SCRIPT") exec python3 $SCRIPT_PATH/SSSDConfigTest.py sssd-1.13.4/src/config/PaxHeaders.16287/testconfigs0000644000000000000000000000013212703463556016642 xustar0030 mtime=1460561774.361792635 30 atime=1460561776.119798596 30 ctime=1460561774.361792635 sssd-1.13.4/src/config/testconfigs/0000755002412700241270000000000012703463556020373 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/config/testconfigs/PaxHeaders.16287/sssd-badversion.conf0000644000000000000000000000007412703456111022666 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.359792628 sssd-1.13.4/src/config/testconfigs/sssd-badversion.conf0000644002412700241270000000123212703456111024333 0ustar00jhrozekjhrozek00000000000000[nss] nss_filter_groups = root nss_entry_negative_timeout = 15 debug_level = 0 nss_filter_users_in_groups = true nss_filter_users = root nss_entry_cache_no_wait_timeout = 60 nss_entry_cache_timeout = 600 nss_enum_cache_timeout = 120 [sssd] services = nss, pam reconnection_retries = 3 domains = LOCAL, IPA config_file_version = 1 [domain/PROXY] id_provider = proxy auth_provider = proxy debug_level = 0 [domain/IPA] id_provider = ldap auth_provider = krb5 debug_level = 0 [domain/LOCAL] id_provider = local auth_provider = local debug_level = 0 [domain/LDAP] id_provider = ldap auth_provider = ldap debug_level = 0 [pam] debug_level = 0 [dp] debug_level = 0 sssd-1.13.4/src/config/testconfigs/PaxHeaders.16287/noparse.api.conf0000644000000000000000000000007412703456111021777 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.358792625 sssd-1.13.4/src/config/testconfigs/noparse.api.conf0000644002412700241270000000017712703456111023453 0ustar00jhrozekjhrozek00000000000000# Format: # option = type, subtype[, default] [service] # Options available to all services debug_level = int, None, 0 commandsssd-1.13.4/src/config/testconfigs/PaxHeaders.16287/sssd-noversion.conf0000644000000000000000000000007312703456111022553 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.359792628 sssd-1.13.4/src/config/testconfigs/sssd-noversion.conf0000644002412700241270000000241312703456111024223 0ustar00jhrozekjhrozek00000000000000[nss] nss_filter_groups = root nss_entry_negative_timeout = 15 debug_level = 0 nss_filter_users_in_groups = true nss_filter_users = root nss_entry_cache_no_wait_timeout = 60 nss_entry_cache_timeout = 600 nss_enum_cache_timeout = 120 [sssd] services = nss, pam reconnection_retries = 3 domains = LOCAL, IPA [domain/PROXY] id_provider = proxy auth_provider = proxy debug_level = 0 [domain/IPA] id_provider = ldap auth_provider = krb5 debug_level = 0 [domain/LOCAL] id_provider = local auth_provider = local debug_level = 0 [domain/LDAP] id_provider = ldap auth_provider = ldap debug_level = 0 [pam] debug_level = 0 [dp] debug_level = 0 [domain/ad.example.com] cache_credentials = true id_provider = ad auth_provider = ad access_provider = ad # Uncomment if service discovery is not working # ad_server = server.ad.example.com # Uncomment if you want to use POSIX UIDs and GIDs set on the AD side # ldap_id_mapping = False # Comment out if the users have the shell and home dir set on the AD side default_shell = /bin/bash fallback_homedir = /home/%d/%u # Uncomment and adjust if the default principal SHORTNAME$@REALM is not available # ldap_sasl_authid = host/client.ad.example.com@AD.EXAMPLE.COM # Comment out if you prefer to user shortnames. use_fully_qualified_names = True sssd-1.13.4/src/config/testconfigs/PaxHeaders.16287/sssd-invalid.conf0000644000000000000000000000007412703456111022160 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.360792632 sssd-1.13.4/src/config/testconfigs/sssd-invalid.conf0000644002412700241270000000005012703456111023622 0ustar00jhrozekjhrozek00000000000000[sssd] services config_file_version = 2 sssd-1.13.4/src/config/testconfigs/PaxHeaders.16287/sssd-valid.conf0000644000000000000000000000007312703456111021630 xustar0029 atime=1460561751.63371557 30 ctime=1460561774.357792622 sssd-1.13.4/src/config/testconfigs/sssd-valid.conf0000644002412700241270000000210612703456111023277 0ustar00jhrozekjhrozek00000000000000[nss] nss_filter_groups = root nss_entry_negative_timeout = 15 debug_level = 0 nss_filter_users_in_groups = true nss_filter_users = root nss_entry_cache_no_wait_timeout = 60 nss_entry_cache_timeout = 600 nss_enum_cache_timeout = 120 [sssd] services = nss, pam reconnection_retries = 3 domains = LOCAL, IPA config_file_version = 2 debug_timestamps = False [domain/PROXY] id_provider = proxy auth_provider = proxy debug_level = 0 [domain/IPA] id_provider = ldap auth_provider = krb5 debug_level = 0xFF0 [domain/LOCAL] id_provider = local auth_provider = local debug_level = 0 [domain/LDAP] ldap_id_use_start_tls = true id_provider = ldap auth_provider=ldap debug_level = 0 # Domain containing an invalid provider [domain/INVALIDPROVIDER] ldap_id_use_start_tls = true id_provider = ldap auth_provider=ldap debug_level = 0 chpass_provider = chpass # Domain containing an invalid option [domain/INVALIDOPTION] ldap_id_use_start_tls = true id_provider = ldap auth_provider=ldap debug_level = 0 nosuchoption = True [pam] debug_level = 0 nosuchoption = True [sudo] debug_level = 0 sssd-1.13.4/src/config/testconfigs/PaxHeaders.16287/sssd-invalid-badbool.conf0000644000000000000000000000007412703456111023560 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.361792635 sssd-1.13.4/src/config/testconfigs/sssd-invalid-badbool.conf0000644002412700241270000000127012703456111025227 0ustar00jhrozekjhrozek00000000000000[nss] nss_filter_groups = root nss_entry_negative_timeout = 15 debug_level = 0 nss_filter_users_in_groups = true nss_filter_users = root nss_entry_cache_no_wait_timeout = 60 nss_entry_cache_timeout = 600 nss_enum_cache_timeout = 120 [sssd] services = nss, pam reconnection_retries = 3 domains = LOCAL, IPA config_file_version = 2 [domain/PROXY] id_provider = proxy auth_provider = proxy debug_level = 0 [domain/IPA] id_provider = ldap ldap_id_use_start_tls = Fal auth_provider = krb5 debug_level = 0 [domain/LOCAL] id_provider = local auth_provider = local debug_level = 0 [domain/LDAP] id_provider = ldap auth_provider=ldap debug_level = 0 [pam] debug_level = 0 [dp] debug_level = 0 sssd-1.13.4/src/config/PaxHeaders.16287/setup.py0000644000000000000000000000013112703463554016076 xustar0030 mtime=1460561772.836787464 30 atime=1460561773.959791272 29 ctime=1460561774.33379254 sssd-1.13.4/src/config/setup.py0000644002412700241270000000176212703463554017561 0ustar00jhrozekjhrozek00000000000000# Authors: # Stephen Gallagher # # Copyright (C) 2009 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ Python-level packaging using distutils. """ from distutils.core import setup setup( name='SSSDConfig', version='1.13.4', license='GPLv3+', url='http://fedorahosted.org/sssd', packages=['SSSDConfig'], ) sssd-1.13.4/src/config/PaxHeaders.16287/SSSDConfigTest.py2.sh0000644000000000000000000000007412703456111020170 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.337792554 sssd-1.13.4/src/config/SSSDConfigTest.py2.sh0000755002412700241270000000016312703456111021642 0ustar00jhrozekjhrozek00000000000000#!/bin/sh SCRIPT=$(readlink -f "$0") SCRIPT_PATH=$(dirname "$SCRIPT") exec python2 $SCRIPT_PATH/SSSDConfigTest.py sssd-1.13.4/src/config/PaxHeaders.16287/SSSDConfig0000644000000000000000000000013012703463556016212 xustar0029 mtime=1460561774.62279352 30 atime=1460561776.119798596 29 ctime=1460561774.62279352 sssd-1.13.4/src/config/SSSDConfig/0000755002412700241270000000000012703463556017745 5ustar00jhrozekjhrozek00000000000000sssd-1.13.4/src/config/SSSDConfig/PaxHeaders.16287/ipachangeconf.py0000644000000000000000000000007412703456111021422 xustar0030 atime=1460561751.632715566 30 ctime=1460561774.334792544 sssd-1.13.4/src/config/SSSDConfig/ipachangeconf.py0000644002412700241270000004542112703456111023077 0ustar00jhrozekjhrozek00000000000000# # ipachangeconf - configuration file manipulation classes and functions # partially based on authconfig code # Copyright (c) 1999-2007 Red Hat, Inc. # Author: Simo Sorce # # This is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 only # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import fcntl import os import string import time import shutil import re def openLocked(filename, perms, create = True): fd = -1 flags = os.O_RDWR if create: flags = flags | os.O_CREAT try: fd = os.open(filename, flags, perms) fcntl.lockf(fd, fcntl.LOCK_EX) except OSError as err: errno, strerr = err.args if fd != -1: try: os.close(fd) except OSError: pass raise IOError(errno, strerr) return os.fdopen(fd, "r+") #TODO: add subsection as a concept # (ex. REALM.NAME = { foo = x bar = y } ) #TODO: put section delimiters as separating element of the list # so that we can process multiple sections in one go #TODO: add a comment all but provided options as a section option class IPAChangeConf: def __init__(self, name): self.progname = name self.indent = ("","","") self.assign = (" = ","=") self.dassign = self.assign[0] self.comment = ("#",) self.dcomment = self.comment[0] self.eol = ("\n",) self.deol = self.eol[0] self.sectnamdel = ("[","]") self.subsectdel = ("{","}") self.backup_suffix = ".ipabkp" def setProgName(self, name): self.progname = name def setIndent(self, indent): if type(indent) is tuple: self.indent = indent elif type(indent) is str: self.indent = (indent, ) else: raise ValueError('Indent must be a list of strings') def setOptionAssignment(self, assign): if type(assign) is tuple: self.assign = assign else: self.assign = (assign, ) self.dassign = self.assign[0] def setCommentPrefix(self, comment): if type(comment) is tuple: self.comment = comment else: self.comment = (comment, ) self.dcomment = self.comment[0] def setEndLine(self, eol): if type(eol) is tuple: self.eol = eol else: self.eol = (eol, ) self.deol = self.eol[0] def setSectionNameDelimiters(self, delims): self.sectnamdel = delims def setSubSectionDelimiters(self, delims): self.subsectdel = delims def matchComment(self, line): for v in self.comment: if line.lstrip().startswith(v): return line.lstrip()[len(v):] return False def matchEmpty(self, line): if line.strip() == "": return True return False def matchSection(self, line): cl = "".join(line.strip().split()) if len(self.sectnamdel) != 2: return False if not cl.startswith(self.sectnamdel[0]): return False if not cl.endswith(self.sectnamdel[1]): return False return cl[len(self.sectnamdel[0]):-len(self.sectnamdel[1])] def matchSubSection(self, line): if self.matchComment(line): return False parts = line.split(self.dassign, 1) if len(parts) < 2: return False if parts[1].strip() == self.subsectdel[0]: return parts[0].strip() return False def matchSubSectionEnd(self, line): if self.matchComment(line): return False if line.strip() == self.subsectdel[1]: return True return False def getSectionLine(self, section): if len(self.sectnamdel) != 2: return section return self.sectnamdel[0]+section+self.sectnamdel[1]+self.deol def dump(self, options, level=0): output = "" if level >= len(self.indent): level = len(self.indent)-1 for o in options: if o['type'] == "section": output += self.sectnamdel[0]+o['name']+self.sectnamdel[1]+self.deol output += self.dump(o['value'], level+1) continue if o['type'] == "subsection": output += self.indent[level]+o['name']+self.dassign+self.subsectdel[0]+self.deol output += self.dump(o['value'], level+1) output += self.indent[level]+self.subsectdel[1]+self.deol continue if o['type'] == "option": output += self.indent[level]+o['name']+self.dassign+o['value']+self.deol continue if o['type'] == "comment": output += self.dcomment+o['value']+self.deol continue if o['type'] == "empty": output += self.deol continue raise SyntaxError('Unknown type: ['+o['type']+']') return output def parseLine(self, line): if self.matchEmpty(line): return {'name':'empty', 'type':'empty'} value = self.matchComment(line) if value: return {'name':'comment', 'type':'comment', 'value':value.rstrip()} parts = line.split(self.dassign, 1) if len(parts) < 2: raise SyntaxError('Syntax Error: Unknown line format') return {'name':parts[0].strip(), 'type':'option', 'value':parts[1].rstrip()} def findOpts(self, opts, type, name, exclude_sections=False): num = 0 for o in opts: if o['type'] == type and o['name'] == name: return (num, o) if exclude_sections and (o['type'] == "section" or o['type'] == "subsection"): return (num, None) num += 1 return (num, None) def commentOpts(self, inopts, level = 0): opts = [] if level >= len(self.indent): level = len(self.indent)-1 for o in inopts: if o['type'] == 'section': no = self.commentOpts(o['value'], level+1) val = self.dcomment+self.sectnamdel[0]+o['name']+self.sectnamdel[1] opts.append({'name':'comment', 'type':'comment', 'value':val}) for n in no: opts.append(n) continue if o['type'] == 'subsection': no = self.commentOpts(o['value'], level+1) val = self.indent[level]+o['name']+self.dassign+self.subsectdel[0] opts.append({'name':'comment', 'type':'comment', 'value':val}) for n in no: opts.append(n) val = self.indent[level]+self.subsectdel[1] opts.append({'name':'comment', 'type':'comment', 'value':val}) continue if o['type'] == 'option': val = self.indent[level]+o['name']+self.dassign+o['value'] opts.append({'name':'comment', 'type':'comment', 'value':val}) continue if o['type'] == 'comment': opts.append(o) continue if o['type'] == 'empty': opts.append({'name':'comment', 'type':'comment', 'value':''}) continue raise SyntaxError('Unknown type: ['+o['type']+']') return opts def mergeOld(self, oldopts, newopts): opts = [] for o in oldopts: if o['type'] == "section" or o['type'] == "subsection": (num, no) = self.findOpts(newopts, o['type'], o['name']) if not no: opts.append(o) continue if no['action'] == "set": mo = self.mergeOld(o['value'], no['value']) opts.append({'name':o['name'], 'type':o['type'], 'value':mo}) continue if no['action'] == "comment": co = self.commentOpts(o['value']) for c in co: opts.append(c) continue if no['action'] == "remove": continue raise SyntaxError('Unknown action: ['+no['action']+']') if o['type'] == "comment" or o['type'] == "empty": opts.append(o) continue if o['type'] == "option": (num, no) = self.findOpts(newopts, 'option', o['name'], True) if not no: opts.append(o) continue if no['action'] == 'comment' or no['action'] == 'remove': if no['value'] != None and o['value'] != no['value']: opts.append(o) continue if no['action'] == 'comment': opts.append({'name':'comment', 'type':'comment', 'value':self.dcomment+o['name']+self.dassign+o['value']}) continue if no['action'] == 'set': opts.append(no) continue raise SyntaxError('Unknown action: ['+o['action']+']') raise SyntaxError('Unknown type: ['+o['type']+']') return opts def mergeNew(self, opts, newopts): cline = 0 for no in newopts: if no['type'] == "section" or no['type'] == "subsection": (num, o) = self.findOpts(opts, no['type'], no['name']) if not o: if no['action'] == 'set': opts.append(no) continue if no['action'] == "set": self.mergeNew(o['value'], no['value']) continue cline = num+1 continue if no['type'] == "option": (num, o) = self.findOpts(opts, no['type'], no['name'], True) if not o: if no['action'] == 'set': opts.append(no) continue cline = num+1 continue if no['type'] == "comment" or no['type'] == "empty": opts.insert(cline, no) cline += 1 continue raise SyntaxError('Unknown type: ['+no['type']+']') def merge(self, oldopts, newopts): #Use a two pass strategy #First we create a new opts tree from oldopts removing/commenting # the options as indicated by the contents of newopts #Second we fill in the new opts tree with options as indicated # in the newopts tree (this is becaus eentire (sub)sections may # exist in the newopts that do not exist in oldopts) opts = self.mergeOld(oldopts, newopts) self.mergeNew(opts, newopts) return opts #TODO: Make parse() recursive? def parse(self, f): opts = [] sectopts = [] section = None subsectopts = [] subsection = None curopts = opts fatheropts = opts # Read in the old file. for line in f: # It's a section start. value = self.matchSection(line) if value: if section is not None: opts.append({'name':section, 'type':'section', 'value':sectopts}) sectopts = [] curopts = sectopts fatheropts = sectopts section = value continue # It's a subsection start. value = self.matchSubSection(line) if value: if subsection is not None: raise SyntaxError('nested subsections are not supported yet') subsectopts = [] curopts = subsectopts subsection = value continue value = self.matchSubSectionEnd(line) if value: if subsection is None: raise SyntaxError('Unmatched end subsection terminator found') fatheropts.append({'name':subsection, 'type':'subsection', 'value':subsectopts}) subsection = None curopts = fatheropts continue # Copy anything else as is. curopts.append(self.parseLine(line)) #Add last section if any if len(sectopts) is not 0: opts.append({'name':section, 'type':'section', 'value':sectopts}) return opts # Write settings to configuration file # file is a path # options is a set of dictionaries in the form: # [{'name': 'foo', 'value': 'bar', 'action': 'set/comment'}] # section is a section name like 'global' def changeConf(self, file, newopts): autosection = False savedsection = None done = False output = "" f = None try: #Do not catch an unexisting file error, we want to fail in that case shutil.copy2(file, file+self.backup_suffix) f = openLocked(file, 0o644) oldopts = self.parse(f) options = self.merge(oldopts, newopts) output = self.dump(options) # Write it out and close it. f.seek(0) f.truncate(0) f.write(output) finally: try: if f: f.close() except IOError: pass return True # Write settings to new file, backup old # file is a path # options is a set of dictionaries in the form: # [{'name': 'foo', 'value': 'bar', 'action': 'set/comment'}] # section is a section name like 'global' def newConf(self, file, options): autosection = False savedsection = None done = False output = "" f = None try: try: shutil.copy2(file, file+self.backup_suffix) except IOError as err: if err.errno == 2: # The orign file did not exist pass f = openLocked(file, 0o644) # Trunkate f.seek(0) f.truncate(0) output = self.dump(options) f.write(output) finally: try: if f: f.close() except IOError: pass return True # A SSSD-specific subclass of IPAChangeConf class SSSDChangeConf(IPAChangeConf): OPTCRE = re.compile( r'(?P